MegaHoseNew.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970
  1. using UnityEngine;
  2. [ExecuteInEditMode]
  3. [AddComponentMenu("MegaShapes/Hose New")]
  4. [RequireComponent(typeof(MeshFilter)), RequireComponent(typeof(MeshRenderer))]
  5. public class MegaHoseNew : MonoBehaviour
  6. {
  7. public bool freecreate = true;
  8. public bool updatemesh = true;
  9. //Matrix4x4 S = Matrix4x4.identity;
  10. const float HalfIntMax = 16383.5f;
  11. const float PIover2 = 1.570796327f;
  12. const float EPSILON = 0.0001f;
  13. public MegaSpline hosespline = new MegaSpline();
  14. Mesh mesh;
  15. public Vector3[] verts = new Vector3[1];
  16. public Vector2[] uvs = new Vector2[1];
  17. public int[] faces = new int[1];
  18. public Vector3[] normals;
  19. public bool optimize = false;
  20. public bool calctangents = false;
  21. public bool recalcCollider = false;
  22. public bool calcnormals = false;
  23. public bool capends = true;
  24. public GameObject custnode2;
  25. public GameObject custnode;
  26. public Vector3 offset = Vector3.zero;
  27. public Vector3 offset1 = Vector3.zero;
  28. public Vector3 rotate = Vector3.zero;
  29. public Vector3 rotate1 = Vector3.zero;
  30. public Vector3 scale = Vector3.one;
  31. public Vector3 scale1 = Vector3.one;
  32. public int endsmethod = 0;
  33. public float noreflength = 1.0f;
  34. public int segments = 45;
  35. public MegaHoseSmooth smooth = MegaHoseSmooth.SMOOTHALL;
  36. public MegaHoseType wiretype = MegaHoseType.Round;
  37. public float rnddia = 0.2f;
  38. public int rndsides = 8;
  39. public float rndrot = 0.0f;
  40. public float rectwidth = 0.2f;
  41. public float rectdepth = 0.2f;
  42. public float rectfillet = 0.0f;
  43. public int rectfilletsides = 0;
  44. public float rectrotangle = 0.0f;
  45. public float dsecwidth = 0.2f;
  46. public float dsecdepth = 0.2f;
  47. public float dsecfillet = 0.0f;
  48. public int dsecfilletsides = 0;
  49. public int dsecrndsides = 4;
  50. public float dsecrotangle = 0.0f;
  51. public bool mapmemapme = true;
  52. public bool flexon = false;
  53. public float flexstart = 0.1f;
  54. public float flexstop = 0.9f;
  55. public int flexcycles = 5;
  56. public float flexdiameter = -0.2f;
  57. public float tension1 = 10.0f;
  58. public float tension2 = 10.0f;
  59. public bool usebulgecurve = false;
  60. public AnimationCurve bulge = new AnimationCurve(new Keyframe(0, 0), new Keyframe(1, 0));
  61. public float bulgeamount = 1.0f;
  62. public float bulgeoffset = 0.0f;
  63. public Vector2 uvscale = Vector2.one;
  64. public bool animatebulge = false;
  65. public float bulgespeed = 0.0f;
  66. public float minbulge = -1.0f;
  67. public float maxbulge = 2.0f;
  68. public bool usesizecurve = false;
  69. public AnimationCurve size = new AnimationCurve(new Keyframe(0, 1), new Keyframe(1, 1));
  70. public bool displayspline = true;
  71. bool visible = true;
  72. public bool InvisibleUpdate = false;
  73. public bool dolateupdate = false;
  74. [ContextMenu("Help")]
  75. public void Help()
  76. {
  77. Application.OpenURL("http://www.west-racing.com/mf/?page_id=3436");
  78. }
  79. void Awake()
  80. {
  81. updatemesh = true;
  82. rebuildcross = true;
  83. Rebuild();
  84. }
  85. void Reset()
  86. {
  87. Rebuild();
  88. }
  89. void OnBecameVisible()
  90. {
  91. visible = true;
  92. }
  93. void OnBecameInvisible()
  94. {
  95. visible = false;
  96. }
  97. public void SetEndTarget(int end, GameObject target)
  98. {
  99. if ( end == 0 )
  100. {
  101. custnode = target;
  102. }
  103. else
  104. {
  105. custnode2 = target;
  106. }
  107. updatemesh = true;
  108. }
  109. public void Rebuild()
  110. {
  111. MeshFilter mf = GetComponent<MeshFilter>();
  112. if ( mf != null )
  113. {
  114. Mesh mesh = mf.sharedMesh; //Utils.GetMesh(gameObject);
  115. if ( mesh == null )
  116. {
  117. mesh = new Mesh();
  118. mf.sharedMesh = mesh;
  119. }
  120. if ( mesh != null )
  121. {
  122. BuildMesh();
  123. }
  124. //updatemesh = false;
  125. }
  126. }
  127. void MakeSaveVertex(int NvertsPerRing, int nfillets, int nsides, MegaHoseType wtype)
  128. {
  129. if ( wtype == MegaHoseType.Round )
  130. {
  131. //Debug.Log("Verts " + NvertsPerRing);
  132. float ang = (Mathf.PI * 2.0f) / (float)(NvertsPerRing - 1);
  133. float diar = rnddia;
  134. diar *= 0.5f;
  135. for ( int i = 0; i < NvertsPerRing; i++ )
  136. {
  137. float u = (float)(i + 1) * ang;
  138. SaveVertex[i] = new Vector3(diar * (float)Mathf.Cos(u), diar * (float)Mathf.Sin(u), 0.0f);
  139. }
  140. }
  141. else
  142. {
  143. if ( wtype == MegaHoseType.Rectangle )
  144. {
  145. int savevertcnt = 0;
  146. int qtrverts = 1 + nfillets;
  147. int hlfverts = 2 * qtrverts;
  148. int thrverts = qtrverts + hlfverts;
  149. float Wr = rectwidth * 0.5f;
  150. float Dr = rectdepth * 0.5f;
  151. float Zfr = rectfillet;
  152. if ( Zfr < 0.0f )
  153. Zfr = 0.0f;
  154. if ( nfillets > 0 )
  155. {
  156. float WmZ = Wr - Zfr, DmZ = Dr - Zfr;
  157. float ZmW = -WmZ, ZmD = -DmZ;
  158. SaveVertex[0] = new Vector3(Wr , DmZ, 0.0f);
  159. SaveVertex[nfillets] = new Vector3(WmZ, Dr , 0.0f);
  160. SaveVertex[qtrverts] = new Vector3(ZmW, Dr , 0.0f);
  161. SaveVertex[qtrverts + nfillets] = new Vector3(-Wr, DmZ, 0.0f);
  162. SaveVertex[hlfverts] = new Vector3(-Wr, ZmD, 0.0f);
  163. SaveVertex[hlfverts + nfillets] = new Vector3(ZmW, -Dr, 0.0f);
  164. SaveVertex[thrverts] = new Vector3(WmZ, -Dr, 0.0f);
  165. SaveVertex[thrverts + nfillets] = new Vector3(Wr , ZmD, 0.0f);
  166. if ( nfillets > 1 )
  167. {
  168. float ang = PIover2 / (float)nfillets;
  169. savevertcnt = 1;
  170. for ( int i = 0; i < nfillets - 1; i++ )
  171. {
  172. float u = (float)(i + 1) * ang;
  173. float cu = Zfr * Mathf.Cos(u), su = Zfr * Mathf.Sin(u);
  174. SaveVertex[savevertcnt] = new Vector3(WmZ + cu, DmZ + su, 0.0f);
  175. SaveVertex[savevertcnt + qtrverts] = new Vector3(ZmW - su, DmZ + cu, 0.0f);
  176. SaveVertex[savevertcnt + hlfverts] = new Vector3(ZmW - cu, ZmD - su, 0.0f);
  177. SaveVertex[savevertcnt + thrverts] = new Vector3(WmZ + su, ZmD - cu, 0.0f);
  178. savevertcnt++;
  179. }
  180. }
  181. SaveVertex[SaveVertex.Length - 1] = SaveVertex[0];
  182. }
  183. else
  184. {
  185. if ( smooth == MegaHoseSmooth.SMOOTHNONE )
  186. {
  187. SaveVertex[savevertcnt++] = new Vector3(Wr, Dr, 0.0f);
  188. SaveVertex[savevertcnt++] = new Vector3(-Wr, Dr, 0.0f);
  189. SaveVertex[savevertcnt++] = new Vector3(-Wr, Dr, 0.0f);
  190. SaveVertex[savevertcnt++] = new Vector3(-Wr, -Dr, 0.0f);
  191. SaveVertex[savevertcnt++] = new Vector3(-Wr, -Dr, 0.0f);
  192. SaveVertex[savevertcnt++] = new Vector3(Wr, -Dr, 0.0f);
  193. SaveVertex[savevertcnt++] = new Vector3(Wr, -Dr, 0.0f);
  194. SaveVertex[savevertcnt++] = new Vector3(Wr, Dr, 0.0f);
  195. }
  196. else
  197. {
  198. SaveVertex[savevertcnt++] = new Vector3(Wr, Dr, 0.0f);
  199. SaveVertex[savevertcnt++] = new Vector3(-Wr, Dr, 0.0f);
  200. SaveVertex[savevertcnt++] = new Vector3(-Wr, -Dr, 0.0f);
  201. SaveVertex[savevertcnt++] = new Vector3(Wr, -Dr, 0.0f);
  202. SaveVertex[savevertcnt++] = new Vector3(Wr, Dr, 0.0f);
  203. }
  204. }
  205. }
  206. else
  207. {
  208. int savevertcnt = 0;
  209. float sang = Mathf.PI / (float)nsides;
  210. float Wr = dsecwidth * 0.5f;
  211. float Dr = dsecdepth * 0.5f;
  212. float Zfr = dsecfillet;
  213. if ( Zfr < 0.0f )
  214. Zfr = 0.0f;
  215. float LeftCenter = Dr-Wr;
  216. if ( nfillets > 0 )
  217. {
  218. float DmZ = Dr-Zfr,
  219. ZmD = -DmZ,
  220. WmZ = Wr-Zfr;
  221. int oneqtrverts = 1 + nfillets;
  222. int threeqtrverts = oneqtrverts + 1 + nsides;
  223. SaveVertex[0] = new Vector3(Wr , DmZ, 0.0f);
  224. SaveVertex[nfillets] = new Vector3(WmZ, Dr , 0.0f);
  225. SaveVertex[oneqtrverts] = new Vector3(LeftCenter, Dr, 0.0f);
  226. SaveVertex[oneqtrverts + nsides] = new Vector3(LeftCenter, -Dr, 0.0f);
  227. SaveVertex[threeqtrverts] = new Vector3(WmZ, -Dr , 0.0f);
  228. SaveVertex[threeqtrverts + nfillets] = new Vector3(Wr, ZmD, 0.0f);
  229. if ( nfillets > 1 )
  230. {
  231. float ang = PIover2 / (float)nfillets;
  232. savevertcnt = 1;
  233. for ( int i = 0; i < nfillets - 1; i++ )
  234. {
  235. float u = (float)(i + 1) * ang;
  236. float cu = Zfr * Mathf.Cos(u);
  237. float su = Zfr * Mathf.Sin(u);
  238. SaveVertex[savevertcnt] = new Vector3(WmZ + cu, DmZ + su, 0.0f);
  239. SaveVertex[savevertcnt+threeqtrverts] = new Vector3(WmZ + su, ZmD - cu, 0.0f);
  240. savevertcnt++;
  241. }
  242. }
  243. savevertcnt = 1 + oneqtrverts;
  244. for ( int i = 0; i < nsides - 1; i++ )
  245. {
  246. float u = (float)(i + 1) * sang;
  247. float cu = Dr * Mathf.Cos(u);
  248. float su = Dr * Mathf.Sin(u);
  249. SaveVertex[savevertcnt] = new Vector3(LeftCenter - su, cu, 0.0f);
  250. savevertcnt++;
  251. }
  252. }
  253. else
  254. {
  255. SaveVertex[savevertcnt] = new Vector3(Wr, Dr, 0.0f);
  256. savevertcnt++;
  257. SaveVertex[savevertcnt] = new Vector3(LeftCenter, Dr, 0.0f);
  258. savevertcnt++;
  259. for ( int i = 0; i < nsides - 1; i++ )
  260. {
  261. float u = (float)(i + 1) * sang;
  262. float cu = Dr * Mathf.Cos(u);
  263. float su = Dr * Mathf.Sin(u);
  264. SaveVertex[savevertcnt] = new Vector3(LeftCenter - su, cu, 0.0f);
  265. savevertcnt++;
  266. }
  267. SaveVertex[savevertcnt] = new Vector3(LeftCenter, -Dr, 0.0f);
  268. savevertcnt++;
  269. SaveVertex[savevertcnt] = new Vector3(Wr, -Dr, 0.0f);
  270. savevertcnt++;
  271. }
  272. SaveVertex[SaveVertex.Length - 1] = SaveVertex[0];
  273. }
  274. }
  275. // UVs
  276. float dist = 0.0f;
  277. Vector3 last = Vector3.zero;
  278. for ( int i = 0; i < NvertsPerRing; i++ )
  279. {
  280. if ( i > 0 )
  281. dist += (SaveVertex[i] - last).magnitude;
  282. SaveUV[i] = new Vector2(0.0f, dist * uvscale.y);
  283. last = SaveVertex[i];
  284. }
  285. for ( int i = 0; i < NvertsPerRing; i++ )
  286. SaveUV[i].y /= dist;
  287. float rotangle = 0.0f;
  288. switch ( wtype )
  289. {
  290. case MegaHoseType.Round: rotangle = rndrot; break;
  291. case MegaHoseType.Rectangle: rotangle = rectrotangle; break;
  292. case MegaHoseType.DSection: rotangle = dsecrotangle; break;
  293. }
  294. if ( rotangle != 0.0f )
  295. {
  296. rotangle *= Mathf.Deg2Rad;
  297. float cosu = Mathf.Cos(rotangle);
  298. float sinu = Mathf.Sin(rotangle);
  299. for ( int m = 0; m < NvertsPerRing; m++ )
  300. {
  301. float tempx = SaveVertex[m].x * cosu - SaveVertex[m].y * sinu;
  302. float tempy = SaveVertex[m].x * sinu + SaveVertex[m].y * cosu;
  303. SaveVertex[m].x = tempx;
  304. SaveVertex[m].y = tempy;
  305. }
  306. }
  307. // Normals
  308. if ( calcnormals )
  309. {
  310. for ( int i = 0; i < NvertsPerRing; i++ )
  311. {
  312. int ii = (i + 1) % NvertsPerRing;
  313. Vector3 delta = (SaveVertex[ii] - SaveVertex[i]).normalized;
  314. SaveNormals[i] = new Vector3(delta.y, -delta.x, 0.0f);
  315. }
  316. }
  317. }
  318. void FixHoseFillet()
  319. {
  320. float width = rectwidth;
  321. float height = rectdepth;
  322. float fillet = rectfillet;
  323. float hh = 0.5f * Mathf.Abs(height);
  324. float ww = 0.5f * Mathf.Abs(width);
  325. float maxf = (hh > ww ? ww : hh);
  326. if ( fillet > maxf )
  327. rectfillet = maxf;
  328. }
  329. float RND11()
  330. {
  331. float num = Random.Range(0.0f, 32768.0f) - HalfIntMax;
  332. return (num / HalfIntMax);
  333. }
  334. void Mult1X3(Vector3 A, Matrix4x4 B, ref Vector3 C)
  335. {
  336. C[0] = A[0] * B[0, 0] + A[1] * B[0, 1] + A[2] * B[0, 2];
  337. C[1] = A[0] * B[1, 0] + A[1] * B[1, 1] + A[2] * B[1, 2];
  338. C[2] = A[0] * B[2, 0] + A[1] * B[2, 1] + A[2] * B[2, 2];
  339. }
  340. void Mult1X4(Vector4 A, Matrix4x4 B, ref Vector4 C)
  341. {
  342. C[0] = A[0] * B[0, 0] + A[1] * B[0, 1] + A[2] * B[0, 2] + A[3] * B[0, 3];
  343. C[1] = A[0] * B[1, 0] + A[1] * B[1, 1] + A[2] * B[1, 2] + A[3] * B[1, 3];
  344. C[2] = A[0] * B[2, 0] + A[1] * B[2, 1] + A[2] * B[2, 2] + A[3] * B[2, 3];
  345. C[3] = A[0] * B[3, 0] + A[1] * B[3, 1] + A[2] * B[3, 2] + A[3] * B[3, 3];
  346. }
  347. void SetUpRotation(Vector3 Q, Vector3 W, float Theta, ref Matrix4x4 Rq)
  348. {
  349. float ww1,ww2,ww3,w12,w13,w23,CosTheta,SinTheta,MinCosTheta;
  350. Vector3 temp = Vector3.zero;
  351. Matrix4x4 R = Matrix4x4.identity;
  352. ww1 = W[0] * W[0];
  353. ww2 = W[1] * W[1];
  354. ww3 = W[2] * W[2];
  355. w12 = W[0] * W[1];
  356. w13 = W[0] * W[2];
  357. w23 = W[1] * W[2];
  358. CosTheta = Mathf.Cos(Theta);
  359. MinCosTheta = 1.0f - CosTheta;
  360. SinTheta = Mathf.Sin(Theta);
  361. R[0, 0] = ww1 + (1.0f - ww1) * CosTheta;
  362. R[1, 0] = w12 * MinCosTheta + W[2] * SinTheta;
  363. R[2, 0] = w13 * MinCosTheta - W[1] * SinTheta;
  364. R[0, 1] = w12 * MinCosTheta - W[2] * SinTheta;
  365. R[1, 1] = ww2 + (1.0f - ww2) * CosTheta;
  366. R[2, 1] = w23 * MinCosTheta + W[0] * SinTheta;
  367. R[0, 2] = w13 * MinCosTheta + W[1] * SinTheta;
  368. R[1, 2] = w23 * MinCosTheta - W[0] * SinTheta;
  369. R[2, 2] = ww3 + (1.0f - ww3) * CosTheta;
  370. Mult1X3(Q, R, ref temp);
  371. Rq.SetColumn(0, R.GetColumn(0));
  372. Rq.SetColumn(1, R.GetColumn(1));
  373. Rq.SetColumn(2, R.GetColumn(2));
  374. Rq[0, 3] = Q[0] - temp.x;
  375. Rq[1, 3] = Q[1] - temp.y;
  376. Rq[2, 3] = Q[2] - temp.z;
  377. Rq[3, 0] = Rq[3, 1] = Rq[3, 2] = 0.0f;
  378. Rq[3, 3] = 1.0f;
  379. }
  380. void RotateOnePoint(ref Vector3 Pin, Vector3 Q, Vector3 W, float Theta)
  381. {
  382. Matrix4x4 Rq = Matrix4x4.identity;
  383. Vector4 Pout = Vector3.zero;
  384. Vector4 Pby4;
  385. SetUpRotation(Q, W, Theta, ref Rq);
  386. Pby4 = Pin;
  387. Pby4[3] = 1.0f;
  388. Mult1X4(Pby4, Rq, ref Pout);
  389. Pin = Pout;
  390. }
  391. Vector3 endp1 = Vector3.zero;
  392. Vector3 endp2 = Vector3.zero;
  393. Vector3 endr1 = Vector3.zero;
  394. Vector3 endr2 = Vector3.zero;
  395. public Vector3[] SaveVertex;
  396. public Vector2[] SaveUV;
  397. public Vector3[] SaveNormals;
  398. public bool rebuildcross = true;
  399. public int NvertsPerRing = 0;
  400. public int Nverts = 0;
  401. void Update()
  402. {
  403. if ( animatebulge )
  404. {
  405. if ( Application.isPlaying )
  406. bulgeoffset += bulgespeed * Time.deltaTime;
  407. if ( bulgeoffset > maxbulge )
  408. bulgeoffset -= maxbulge - minbulge;
  409. if ( bulgeoffset < minbulge )
  410. bulgeoffset += maxbulge - minbulge;
  411. updatemesh = true;
  412. }
  413. if ( custnode )
  414. {
  415. if ( custnode.transform.position != endp1 )
  416. {
  417. endp1 = custnode.transform.position;
  418. updatemesh = true;
  419. }
  420. if ( custnode.transform.eulerAngles != endr1 )
  421. {
  422. endr1 = custnode.transform.eulerAngles;
  423. updatemesh = true;
  424. }
  425. }
  426. if ( custnode2 )
  427. {
  428. if ( custnode2.transform.position != endp2 )
  429. {
  430. endp2 = custnode2.transform.position;
  431. updatemesh = true;
  432. }
  433. if ( custnode2.transform.eulerAngles != endr2 )
  434. {
  435. endr2 = custnode2.transform.eulerAngles;
  436. updatemesh = true;
  437. }
  438. }
  439. if ( !dolateupdate )
  440. {
  441. if ( visible || InvisibleUpdate )
  442. {
  443. // Check transforms so we dont update unless we have to
  444. if ( updatemesh ) //|| Application.isEditor )
  445. {
  446. updatemesh = false;
  447. BuildMesh();
  448. }
  449. }
  450. }
  451. }
  452. void LateUpdate()
  453. {
  454. if ( dolateupdate )
  455. {
  456. if ( visible || InvisibleUpdate )
  457. {
  458. // Check transforms so we dont update unless we have to
  459. if ( updatemesh ) //|| Application.isEditor )
  460. {
  461. updatemesh = false;
  462. BuildMesh();
  463. }
  464. }
  465. }
  466. }
  467. public Vector3 up = Vector3.up;
  468. Vector3 starty = Vector3.zero;
  469. public Matrix4x4 Tlocal = Matrix4x4.identity;
  470. void CalcSpline()
  471. {
  472. Vector3 startvec, endvec, startpoint, endpoint; //, endy;
  473. starty = custnode.transform.up; //TlocalInvNT.MultiplyPoint(starty);
  474. Quaternion rot1 = custnode.transform.rotation * Quaternion.Euler(rotate);
  475. Quaternion rot2 = custnode2.transform.rotation * Quaternion.Euler(rotate1);
  476. startvec = tension1 * (rot1 * Vector3.forward);
  477. endvec = tension2 * (rot2 * Vector3.forward);
  478. startpoint = transform.worldToLocalMatrix.MultiplyPoint3x4(custnode.transform.position + custnode.transform.TransformDirection(offset)); //Vector3.zero;
  479. endpoint = transform.worldToLocalMatrix.MultiplyPoint3x4(custnode2.transform.position + custnode2.transform.TransformDirection(offset1));
  480. hosespline.knots[0].p = startpoint;
  481. hosespline.knots[0].invec = startpoint - startvec;
  482. hosespline.knots[0].outvec = startpoint + startvec;
  483. hosespline.knots[1].p = endpoint;
  484. hosespline.knots[1].invec = endpoint + endvec;
  485. hosespline.knots[1].outvec = endpoint - endvec;
  486. hosespline.CalcLength(); //10);
  487. }
  488. Matrix4x4 wtm1;
  489. public Matrix4x4 GetSplineMat(MegaSpline spline, float alpha, bool interp, ref Vector3 lastup)
  490. {
  491. int k = -1;
  492. Vector3 ps = spline.InterpCurve3D(alpha, interp, ref k);
  493. alpha += 0.01f; // TODO: Tangent value
  494. if ( spline.closed )
  495. alpha = alpha % 1.0f;
  496. Vector3 ps1 = spline.InterpCurve3D(alpha, interp, ref k);
  497. Vector3 ps2;
  498. ps1.x = ps2.x = ps1.x - ps.x;
  499. ps1.y = ps2.y = ps1.y - ps.y;
  500. ps1.z = ps2.z = ps1.z - ps.z;
  501. MegaMatrix.SetTR(ref wtm1, ps, Quaternion.LookRotation(ps1, lastup)); //locup));
  502. // calc new up value
  503. ps2 = ps2.normalized;
  504. Vector3 cross = Vector3.Cross(ps2, lastup);
  505. lastup = Vector3.Cross(cross, ps2);
  506. return wtm1;
  507. }
  508. // we only need to build the savevertex and uvs if mesh def changes, else we can keep the uvs
  509. void BuildMesh()
  510. {
  511. if ( !mesh )
  512. {
  513. mesh = GetComponent<MeshFilter>().sharedMesh;
  514. if ( mesh == null )
  515. {
  516. updatemesh = true;
  517. return;
  518. }
  519. }
  520. if ( hosespline.knots.Count == 0 )
  521. {
  522. hosespline.AddKnot(Vector3.zero, Vector3.zero, Vector3.zero);
  523. hosespline.AddKnot(Vector3.zero, Vector3.zero, Vector3.zero);
  524. }
  525. FixHoseFillet();
  526. bool createfree = freecreate;
  527. if ( (!createfree) && ((!custnode) || (!custnode2)) )
  528. createfree = true;
  529. if ( custnode && custnode2 )
  530. createfree = false;
  531. float Lf = 0.0f;
  532. Tlocal = Matrix4x4.identity;
  533. starty = Vector3.zero;
  534. if ( createfree )
  535. Lf = noreflength;
  536. else
  537. {
  538. starty = custnode.transform.up; //Vector3.up;
  539. CalcSpline();
  540. Lf = Vector3.Distance(custnode.transform.position, custnode2.transform.position);
  541. }
  542. MegaHoseType wtype = wiretype;
  543. int Segs = segments;
  544. if ( Segs < 3 )
  545. Segs = 3;
  546. if ( rebuildcross )
  547. {
  548. rebuildcross = false;
  549. int nfillets = 0;
  550. int nsides = 0;
  551. if ( wtype == MegaHoseType.Round )
  552. {
  553. NvertsPerRing = rndsides;
  554. if ( NvertsPerRing < 3 )
  555. NvertsPerRing = 3;
  556. }
  557. else
  558. {
  559. if ( wtype == MegaHoseType.Rectangle )
  560. {
  561. nfillets = rectfilletsides;
  562. if ( nfillets < 0 )
  563. nfillets = 0;
  564. if ( smooth == MegaHoseSmooth.SMOOTHNONE )
  565. NvertsPerRing = (nfillets > 0 ? 8 + 4 * (nfillets - 1) : 8);
  566. else
  567. NvertsPerRing = (nfillets > 0 ? 8 + 4 * (nfillets - 1) : 4); //4);
  568. }
  569. else
  570. {
  571. nfillets = dsecfilletsides;
  572. if ( nfillets < 0 )
  573. nfillets = 0;
  574. nsides = dsecrndsides;
  575. if ( nsides < 2 )
  576. nsides = 2;
  577. int nsm1 = nsides - 1;
  578. NvertsPerRing = (nfillets > 0 ? 6 + nsm1 + 2 * (nfillets - 1): 4 + nsm1);
  579. }
  580. }
  581. NvertsPerRing++;
  582. int NfacesPerEnd,NfacesPerRing,Nfaces = 0;
  583. //MegaHoseSmooth SMOOTH = smooth;
  584. Nverts = (Segs + 1) * (NvertsPerRing + 1); // + 2;
  585. if ( capends )
  586. Nverts += 2;
  587. NfacesPerEnd = NvertsPerRing;
  588. NfacesPerRing = 6 * NvertsPerRing;
  589. Nfaces = Segs * NfacesPerRing; // + 2 * NfacesPerEnd;
  590. if ( capends )
  591. {
  592. Nfaces += 2 * NfacesPerEnd;
  593. }
  594. if ( SaveVertex == null || SaveVertex.Length != NvertsPerRing )
  595. {
  596. SaveVertex = new Vector3[NvertsPerRing];
  597. SaveUV = new Vector2[NvertsPerRing];
  598. }
  599. if ( calcnormals )
  600. {
  601. if ( SaveNormals == null || SaveNormals.Length != NvertsPerRing )
  602. SaveNormals = new Vector3[NvertsPerRing];
  603. }
  604. MakeSaveVertex(NvertsPerRing, nfillets, nsides, wtype);
  605. if ( verts == null || verts.Length != Nverts )
  606. {
  607. verts = new Vector3[Nverts];
  608. uvs = new Vector2[Nverts];
  609. faces = new int[Nfaces * 3];
  610. }
  611. if ( calcnormals && (normals == null || normals.Length != Nverts) )
  612. normals = new Vector3[Nverts];
  613. }
  614. if ( Nverts == 0 )
  615. return;
  616. bool mapmenow = mapmemapme;
  617. int thisvert = 0;
  618. int last = Nverts - 1;
  619. int last2 = last - 1;
  620. int lastvpr = NvertsPerRing; // - 1;
  621. int maxseg = Segs + 1;
  622. float flexhere;
  623. float dadjust;
  624. float flexlen;
  625. float flex1 = flexstart;
  626. float flex2 = flexstop;
  627. int flexn = flexcycles;
  628. float flexd = flexdiameter;
  629. Vector3 ThisPosition;
  630. Vector2 uv = Vector2.zero;
  631. Matrix4x4 RingTM = Matrix4x4.identity;
  632. Matrix4x4 invRingTM = Matrix4x4.identity;
  633. Vector3 lastup = starty;
  634. float sizeadj = 1.0f;
  635. for ( int i = 0; i < maxseg; i++ )
  636. {
  637. float incr = (float)i / (float)Segs;
  638. if ( createfree )
  639. ThisPosition = new Vector3(0.0f, 0.0f, Lf * incr);
  640. else
  641. {
  642. int k = 0;
  643. ThisPosition = hosespline.InterpCurve3D(incr, true, ref k);
  644. }
  645. RingTM = GetSplineMat(hosespline, incr, true, ref lastup);
  646. if ( !createfree )
  647. RingTM = Tlocal * RingTM;
  648. if ( calcnormals )
  649. {
  650. invRingTM = RingTM;
  651. MegaMatrix.NoTrans(ref invRingTM);
  652. }
  653. if ( (incr > flex1) && (incr < flex2) && flexon )
  654. {
  655. flexlen = flex2 - flex1;
  656. if ( flexlen < 0.01f )
  657. flexlen = 0.01f;
  658. flexhere = (incr - flex1) / flexlen;
  659. float ang = (float)flexn * flexhere * (Mathf.PI * 2.0f) + PIover2;
  660. dadjust = 1.0f + flexd * (1.0f - Mathf.Sin(ang)); //(float)flexn * flexhere * (Mathf.PI * 2.0f) + PIover2));
  661. }
  662. else
  663. dadjust = 0.0f;
  664. if ( usebulgecurve )
  665. {
  666. if ( dadjust == 0.0f )
  667. dadjust = 1.0f + (bulge.Evaluate(incr + bulgeoffset) * bulgeamount);
  668. else
  669. dadjust += bulge.Evaluate(incr + bulgeoffset) * bulgeamount;
  670. }
  671. if ( usesizecurve )
  672. {
  673. sizeadj = size.Evaluate(incr);
  674. }
  675. uv.x = 0.999999f * incr * uvscale.x;
  676. for ( int j = 0; j < NvertsPerRing; j++ )
  677. {
  678. int jj = j; // % NvertsPerRing;
  679. if ( mapmenow )
  680. {
  681. uv.y = SaveUV[jj].y;
  682. uvs[thisvert] = uv; //new Vector2(0.999999f * incr * uvscale.x, SaveUV[jj].y);
  683. }
  684. if ( dadjust != 0.0f )
  685. verts[thisvert] = RingTM.MultiplyPoint(sizeadj * dadjust * SaveVertex[jj]);
  686. else
  687. verts[thisvert] = RingTM.MultiplyPoint(sizeadj * SaveVertex[jj]);
  688. if ( calcnormals )
  689. normals[thisvert] = invRingTM.MultiplyPoint(SaveNormals[jj]).normalized; //.MultiplyPoint(-SaveNormals[jj]);
  690. thisvert++;
  691. }
  692. if ( mapmenow )
  693. {
  694. //uvs[Nverts + i] = new Vector2(0.999999f * incr, 0.999f);
  695. }
  696. if ( capends )
  697. {
  698. if ( i == 0 )
  699. {
  700. verts[last2] = (createfree ? ThisPosition : Tlocal.MultiplyPoint(ThisPosition));
  701. if ( mapmenow )
  702. uvs[last2] = Vector3.zero;
  703. }
  704. else
  705. {
  706. if ( i == Segs )
  707. {
  708. verts[last] = createfree ? ThisPosition : Tlocal.MultiplyPoint(ThisPosition);
  709. if ( mapmenow )
  710. {
  711. uvs[last] = Vector3.zero;
  712. }
  713. }
  714. }
  715. }
  716. }
  717. // Now, set up the faces
  718. int thisface = 0, v1, v2, v3, v4;
  719. v3 = last2;
  720. if ( capends )
  721. {
  722. for ( int i = 0; i < NvertsPerRing - 1; i++ )
  723. {
  724. v1 = i;
  725. v2 = (i < lastvpr ? v1 + 1 : v1 - lastvpr);
  726. //v5 = (i < lastvpr ? v2 : Nverts);
  727. faces[thisface++] = v2;
  728. faces[thisface++] = v1;
  729. faces[thisface++] = v3;
  730. }
  731. }
  732. int ringnum = NvertsPerRing; // + 1;
  733. for ( int i = 0; i < Segs; i++ )
  734. {
  735. for ( int j = 0; j < NvertsPerRing - 1; j++ )
  736. {
  737. v1 = i * ringnum + j;
  738. v2 = v1 + 1; //(j < lastvpr? v1 + 1 : v1 - lastvpr);
  739. v4 = v1 + ringnum;
  740. v3 = v2 + ringnum;
  741. faces[thisface++] = v1;
  742. faces[thisface++] = v2;
  743. faces[thisface++] = v3;
  744. faces[thisface++] = v1;
  745. faces[thisface++] = v3;
  746. faces[thisface++] = v4;
  747. }
  748. }
  749. int basevert = Segs * ringnum; //NvertsPerRing;
  750. v3 = Nverts - 1;
  751. if ( capends )
  752. {
  753. for ( int i = 0; i < NvertsPerRing - 1; i++ )
  754. {
  755. v1 = i + basevert;
  756. v2 = (i < lastvpr? v1 + 1 : v1 - lastvpr);
  757. //v5 = (i < lastvpr? v2 : Nverts + Segs);
  758. faces[thisface++] = v1;
  759. faces[thisface++] = v2;
  760. faces[thisface++] = v3;
  761. }
  762. }
  763. mesh.Clear();
  764. mesh.subMeshCount = 1;
  765. mesh.vertices = verts;
  766. mesh.uv = uvs;
  767. mesh.triangles = faces;
  768. if ( calcnormals )
  769. mesh.normals = normals;
  770. else
  771. mesh.RecalculateNormals();
  772. mesh.RecalculateBounds();
  773. #if UNITY_5_5 || UNITY_5_6 || UNITY_2017 || UNITY_2018 || UNITY_2019 || UNITY_2020
  774. #else
  775. if ( optimize )
  776. mesh.Optimize();
  777. #endif
  778. if ( calctangents )
  779. {
  780. MegaUtils.BuildTangents(mesh);
  781. }
  782. if ( recalcCollider )
  783. {
  784. if ( meshCol == null )
  785. meshCol = GetComponent<MeshCollider>();
  786. if ( meshCol != null )
  787. {
  788. meshCol.sharedMesh = null;
  789. meshCol.sharedMesh = mesh;
  790. //bool con = meshCol.convex;
  791. //meshCol.convex = con;
  792. }
  793. }
  794. }
  795. public void CalcMatrix(ref Matrix4x4 mat, float incr)
  796. {
  797. mat = Tlocal; // * RingTM;
  798. }
  799. MeshCollider meshCol;
  800. static float findmappos(float curpos)
  801. {
  802. float mappos;
  803. return (mappos = ((mappos = curpos) < 0.0f ? 0.0f : (mappos > 1.0f ? 1.0f : mappos)));
  804. }
  805. void DisplayNormals()
  806. {
  807. }
  808. public Vector3 GetPosition(float alpha)
  809. {
  810. Matrix4x4 RingTM = transform.localToWorldMatrix * Tlocal;
  811. int k = 0;
  812. return RingTM.MultiplyPoint(hosespline.InterpCurve3D(alpha, true, ref k));
  813. }
  814. }