MegaWrap.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856
  1. using UnityEngine;
  2. using System.Collections.Generic;
  3. [System.Serializable]
  4. public class MegaBindInf
  5. {
  6. public float dist;
  7. public int face;
  8. public int i0;
  9. public int i1;
  10. public int i2;
  11. public Vector3 bary;
  12. public float weight;
  13. public float area;
  14. }
  15. [System.Serializable]
  16. public class MegaBindVert
  17. {
  18. public float weight;
  19. public List<MegaBindInf> verts = new List<MegaBindInf>();
  20. }
  21. public struct MegaCloseFace
  22. {
  23. public int face;
  24. public float dist;
  25. }
  26. [ExecuteInEditMode]
  27. public class MegaWrap : MonoBehaviour
  28. {
  29. public float gap = 0.0f;
  30. public float shrink = 1.0f;
  31. public List<int> neededVerts = new List<int>();
  32. public Vector3[] skinnedVerts;
  33. public Mesh mesh = null;
  34. public Vector3 offset = Vector3.zero;
  35. public bool targetIsSkin = false;
  36. public bool sourceIsSkin = false;
  37. public int nomapcount = 0;
  38. public Matrix4x4[] bindposes;
  39. public BoneWeight[] boneweights;
  40. public Transform[] bones;
  41. public float size = 0.01f;
  42. public int vertindex = 0;
  43. public Vector3[] freeverts; // position for any vert with no attachments
  44. public Vector3[] startverts;
  45. public Vector3[] verts;
  46. public MegaBindVert[] bindverts;
  47. public MegaModifyObject target;
  48. public float maxdist = 0.25f;
  49. public int maxpoints = 4;
  50. public bool WrapEnabled = true;
  51. public MegaNormalMethod NormalMethod = MegaNormalMethod.Unity;
  52. #if UNITY_5 || UNITY_2017 || UNITY_2018 || UNITY_2019 || UNITY_2020
  53. public bool UseBakedMesh = true;
  54. #endif
  55. [ContextMenu("Help")]
  56. public void Help()
  57. {
  58. Application.OpenURL("http://www.west-racing.com/mf/?page_id=3709");
  59. }
  60. Vector4 Plane(Vector3 v1, Vector3 v2, Vector3 v3)
  61. {
  62. Vector3 normal = Vector4.zero;
  63. normal.x = (v2.y - v1.y) * (v3.z - v1.z) - (v2.z - v1.z) * (v3.y - v1.y);
  64. normal.y = (v2.z - v1.z) * (v3.x - v1.x) - (v2.x - v1.x) * (v3.z - v1.z);
  65. normal.z = (v2.x - v1.x) * (v3.y - v1.y) - (v2.y - v1.y) * (v3.x - v1.x);
  66. normal = normal.normalized;
  67. return new Vector4(normal.x, normal.y, normal.z, -Vector3.Dot(v2, normal));
  68. }
  69. float PlaneDist(Vector3 p, Vector4 plane)
  70. {
  71. Vector3 n = plane;
  72. return Vector3.Dot(n, p) + plane.w;
  73. }
  74. public float GetDistance(Vector3 p, Vector3 p0, Vector3 p1, Vector3 p2)
  75. {
  76. return MegaNearestPointTest.DistPoint3Triangle3Dbl(p, p0, p1, p2);
  77. }
  78. public float GetPlaneDistance(Vector3 p, Vector3 p0, Vector3 p1, Vector3 p2)
  79. {
  80. Vector4 pl = Plane(p0, p1, p2);
  81. return PlaneDist(p, pl);
  82. }
  83. public Vector3 MyBary(Vector3 p, Vector3 p0, Vector3 p1, Vector3 p2)
  84. {
  85. Vector3 bary = Vector3.zero;
  86. Vector3 normal = FaceNormal(p0, p1, p2);
  87. float areaABC = Vector3.Dot(normal, Vector3.Cross((p1 - p0), (p2 - p0)));
  88. float areaPBC = Vector3.Dot(normal, Vector3.Cross((p1 - p), (p2 - p)));
  89. float areaPCA = Vector3.Dot(normal, Vector3.Cross((p2 - p), (p0 - p)));
  90. bary.x = areaPBC / areaABC; // alpha
  91. bary.y = areaPCA / areaABC; // beta
  92. bary.z = 1.0f - bary.x - bary.y; // gamma
  93. return bary;
  94. }
  95. public Vector3 MyBary1(Vector3 p, Vector3 a, Vector3 b, Vector3 c)
  96. {
  97. Vector3 v0 = b - a, v1 = c - a, v2 = p - a;
  98. float d00 = Vector3.Dot(v0, v0);
  99. float d01 = Vector3.Dot(v0, v1);
  100. float d11 = Vector3.Dot(v1, v1);
  101. float d20 = Vector3.Dot(v2, v0);
  102. float d21 = Vector3.Dot(v2, v1);
  103. float denom = d00 * d11 - d01 * d01;
  104. float w = (d11 * d20 - d01 * d21) / denom;
  105. float v = (d00 * d21 - d01 * d20) / denom;
  106. float u = 1.0f - v - w;
  107. return new Vector3(u, v, w);
  108. }
  109. public Vector3 CalcBary(Vector3 p, Vector3 p0, Vector3 p1, Vector3 p2)
  110. {
  111. return MyBary(p, p0, p1, p2);
  112. }
  113. public float CalcArea(Vector3 p0, Vector3 p1, Vector3 p2)
  114. {
  115. Vector3 e1 = p1 - p0;
  116. Vector3 e2 = p2 - p0;
  117. Vector3 e3 = Vector3.Cross(e1, e2);
  118. return 0.5f * e3.magnitude;
  119. }
  120. Vector3 e11 = Vector3.zero;
  121. Vector3 e22 = Vector3.zero;
  122. Vector3 cr = Vector3.zero;
  123. public Vector3 FaceNormal(Vector3 p0, Vector3 p1, Vector3 p2)
  124. {
  125. //Vector3 e1 = p1 - p0;
  126. //Vector3 e2 = p2 - p0;
  127. e11.x = p1.x - p0.x;
  128. e11.y = p1.y - p0.y;
  129. e11.z = p1.z - p0.z;
  130. e22.x = p2.x - p0.x;
  131. e22.y = p2.y - p0.y;
  132. e22.z = p2.z - p0.z;
  133. //Vector3 e2 = p2 - p0;
  134. cr.x = e11.y * e22.z - e22.y * e11.z;
  135. cr.y = -(e11.x * e22.z - e22.x * e11.z); // * -1;
  136. cr.z = e11.x * e22.y - e22.x * e11.y;
  137. return cr; //Vector3.Cross(e11, e22);
  138. }
  139. static void CopyBlendShapes(Mesh mesh1, Mesh clonemesh)
  140. {
  141. #if UNITY_5_3 || UNITY_5_4 || UNITY_5_5 || UNITY_5_6 || UNITY_2017 || UNITY_2018 || UNITY_2019 || UNITY_2020
  142. int bcount = mesh1.blendShapeCount; //GetBlendShapeFrameCount();
  143. Vector3[] deltaverts = new Vector3[mesh1.vertexCount];
  144. Vector3[] deltanorms = new Vector3[mesh1.vertexCount];
  145. Vector3[] deltatans = new Vector3[mesh1.vertexCount];
  146. for ( int j = 0; j < bcount; j++ )
  147. {
  148. int frames = mesh1.GetBlendShapeFrameCount(j);
  149. string bname = mesh1.GetBlendShapeName(j);
  150. for ( int f = 0; f < frames; f++ )
  151. {
  152. mesh1.GetBlendShapeFrameVertices(j, f, deltaverts, deltanorms, deltatans);
  153. float weight = mesh1.GetBlendShapeFrameWeight(j, f);
  154. clonemesh.AddBlendShapeFrame(bname, weight, deltaverts, deltanorms, deltatans);
  155. }
  156. }
  157. #endif
  158. }
  159. public Mesh CloneMesh(Mesh m)
  160. {
  161. Mesh clonemesh = new Mesh();
  162. clonemesh.vertices = m.vertices;
  163. #if UNITY_5_0 || UNITY_5_1 || UNITY_5 || UNITY_2017 || UNITY_2018 || UNITY_2019 || UNITY_2020
  164. clonemesh.uv2 = m.uv2;
  165. clonemesh.uv3 = m.uv3;
  166. clonemesh.uv4 = m.uv4;
  167. #else
  168. clonemesh.uv1 = m.uv1;
  169. clonemesh.uv2 = m.uv2;
  170. #endif
  171. clonemesh.uv = m.uv;
  172. clonemesh.normals = m.normals;
  173. clonemesh.tangents = m.tangents;
  174. clonemesh.colors = m.colors;
  175. clonemesh.subMeshCount = m.subMeshCount;
  176. for ( int s = 0; s < m.subMeshCount; s++ )
  177. clonemesh.SetTriangles(m.GetTriangles(s), s);
  178. CopyBlendShapes(m, clonemesh);
  179. clonemesh.boneWeights = m.boneWeights;
  180. clonemesh.bindposes = m.bindposes;
  181. clonemesh.name = m.name; // + "_copy";
  182. clonemesh.RecalculateBounds();
  183. return clonemesh;
  184. }
  185. [ContextMenu("Reset Mesh")]
  186. public void ResetMesh()
  187. {
  188. if ( mesh )
  189. {
  190. mesh.vertices = startverts;
  191. mesh.RecalculateBounds();
  192. RecalcNormals();
  193. //mesh.RecalculateNormals();
  194. }
  195. target = null;
  196. bindverts = null;
  197. }
  198. public void SetMesh()
  199. {
  200. MeshFilter mf = GetComponent<MeshFilter>();
  201. Mesh srcmesh = null;
  202. if ( mf != null )
  203. srcmesh = mf.sharedMesh;
  204. else
  205. {
  206. SkinnedMeshRenderer smesh = (SkinnedMeshRenderer)GetComponent(typeof(SkinnedMeshRenderer));
  207. if ( smesh != null )
  208. srcmesh = smesh.sharedMesh;
  209. }
  210. if ( srcmesh != null )
  211. {
  212. mesh = CloneMesh(srcmesh);
  213. if ( mf )
  214. mf.sharedMesh = mesh;
  215. else
  216. {
  217. SkinnedMeshRenderer smesh = (SkinnedMeshRenderer)GetComponent(typeof(SkinnedMeshRenderer));
  218. smesh.sharedMesh = mesh;
  219. }
  220. }
  221. }
  222. public void Attach(MegaModifyObject modobj)
  223. {
  224. targetIsSkin = false;
  225. sourceIsSkin = false;
  226. if ( mesh && startverts != null )
  227. mesh.vertices = startverts;
  228. if ( modobj == null )
  229. {
  230. bindverts = null;
  231. return;
  232. }
  233. nomapcount = 0;
  234. if ( mesh )
  235. mesh.vertices = startverts;
  236. MeshFilter mf = GetComponent<MeshFilter>();
  237. Mesh srcmesh = null;
  238. if ( mf != null )
  239. {
  240. //skinned = false;
  241. srcmesh = mf.mesh;
  242. }
  243. else
  244. {
  245. SkinnedMeshRenderer smesh = (SkinnedMeshRenderer)GetComponent(typeof(SkinnedMeshRenderer));
  246. if ( smesh != null )
  247. {
  248. //skinned = true;
  249. srcmesh = smesh.sharedMesh;
  250. sourceIsSkin = true;
  251. }
  252. }
  253. if ( srcmesh == null )
  254. {
  255. Debug.LogWarning("No Mesh found on the target object, make sure target has a mesh and MegaFiers modifier attached!");
  256. return;
  257. }
  258. if ( mesh == null )
  259. mesh = CloneMesh(srcmesh); //mf.mesh);
  260. if ( mf )
  261. mf.mesh = mesh;
  262. else
  263. {
  264. SkinnedMeshRenderer smesh = (SkinnedMeshRenderer)GetComponent(typeof(SkinnedMeshRenderer));
  265. smesh.sharedMesh = mesh;
  266. }
  267. if ( sourceIsSkin == false )
  268. {
  269. SkinnedMeshRenderer tmesh = (SkinnedMeshRenderer)modobj.GetComponent(typeof(SkinnedMeshRenderer));
  270. if ( tmesh != null )
  271. {
  272. targetIsSkin = true;
  273. if ( !sourceIsSkin )
  274. {
  275. Mesh sm = tmesh.sharedMesh;
  276. bindposes = sm.bindposes;
  277. boneweights = sm.boneWeights;
  278. bones = tmesh.bones;
  279. skinnedVerts = sm.vertices; //new Vector3[sm.vertexCount];
  280. }
  281. }
  282. }
  283. if ( targetIsSkin )
  284. {
  285. if ( boneweights == null || boneweights.Length == 0 )
  286. targetIsSkin = false;
  287. }
  288. neededVerts.Clear();
  289. verts = mesh.vertices;
  290. startverts = mesh.vertices;
  291. freeverts = new Vector3[startverts.Length];
  292. Vector3[] baseverts = modobj.verts; //basemesh.vertices;
  293. int[] basefaces = modobj.tris; //basemesh.triangles;
  294. bindverts = new MegaBindVert[verts.Length];
  295. // matrix to get vertex into local space of target
  296. Matrix4x4 tm = transform.localToWorldMatrix * modobj.transform.worldToLocalMatrix;
  297. List<MegaCloseFace> closefaces = new List<MegaCloseFace>();
  298. Vector3 p0 = Vector3.zero;
  299. Vector3 p1 = Vector3.zero;
  300. Vector3 p2 = Vector3.zero;
  301. for ( int i = 0; i < verts.Length; i++ )
  302. {
  303. MegaBindVert bv = new MegaBindVert();
  304. bindverts[i] = bv;
  305. Vector3 p = tm.MultiplyPoint(verts[i]);
  306. p = transform.TransformPoint(verts[i]);
  307. p = modobj.transform.InverseTransformPoint(p);
  308. freeverts[i] = p;
  309. closefaces.Clear();
  310. for ( int t = 0; t < basefaces.Length; t += 3 )
  311. {
  312. if ( targetIsSkin && !sourceIsSkin )
  313. {
  314. p0 = modobj.transform.InverseTransformPoint(GetSkinPos(basefaces[t]));
  315. p1 = modobj.transform.InverseTransformPoint(GetSkinPos(basefaces[t + 1]));
  316. p2 = modobj.transform.InverseTransformPoint(GetSkinPos(basefaces[t + 2]));
  317. }
  318. else
  319. {
  320. p0 = baseverts[basefaces[t]];
  321. p1 = baseverts[basefaces[t + 1]];
  322. p2 = baseverts[basefaces[t + 2]];
  323. }
  324. float dist = GetDistance(p, p0, p1, p2);
  325. if ( Mathf.Abs(dist) < maxdist )
  326. {
  327. MegaCloseFace cf = new MegaCloseFace();
  328. cf.dist = Mathf.Abs(dist);
  329. cf.face = t;
  330. bool inserted = false;
  331. for ( int k = 0; k < closefaces.Count; k++ )
  332. {
  333. if ( cf.dist < closefaces[k].dist )
  334. {
  335. closefaces.Insert(k, cf);
  336. inserted = true;
  337. break;
  338. }
  339. }
  340. if ( !inserted )
  341. closefaces.Add(cf);
  342. }
  343. }
  344. float tweight = 0.0f;
  345. int maxp = maxpoints;
  346. if ( maxp == 0 )
  347. maxp = closefaces.Count;
  348. for ( int j = 0; j < maxp; j++ )
  349. {
  350. if ( j < closefaces.Count )
  351. {
  352. int t = closefaces[j].face;
  353. if ( targetIsSkin && !sourceIsSkin )
  354. {
  355. p0 = modobj.transform.InverseTransformPoint(GetSkinPos(basefaces[t]));
  356. p1 = modobj.transform.InverseTransformPoint(GetSkinPos(basefaces[t + 1]));
  357. p2 = modobj.transform.InverseTransformPoint(GetSkinPos(basefaces[t + 2]));
  358. }
  359. else
  360. {
  361. p0 = baseverts[basefaces[t]];
  362. p1 = baseverts[basefaces[t + 1]];
  363. p2 = baseverts[basefaces[t + 2]];
  364. }
  365. Vector3 normal = FaceNormal(p0, p1, p2);
  366. float dist = closefaces[j].dist; //GetDistance(p, p0, p1, p2);
  367. MegaBindInf bi = new MegaBindInf();
  368. bi.dist = GetPlaneDistance(p, p0, p1, p2); //dist;
  369. bi.face = t;
  370. bi.i0 = basefaces[t];
  371. bi.i1 = basefaces[t + 1];
  372. bi.i2 = basefaces[t + 2];
  373. bi.bary = CalcBary(p, p0, p1, p2);
  374. bi.weight = 1.0f / (1.0f + dist);
  375. bi.area = normal.magnitude * 0.5f; //CalcArea(baseverts[basefaces[t]], baseverts[basefaces[t + 1]], baseverts[basefaces[t + 2]]); // Could calc once at start
  376. tweight += bi.weight;
  377. bv.verts.Add(bi);
  378. }
  379. }
  380. if ( maxpoints > 0 && maxpoints < bv.verts.Count )
  381. bv.verts.RemoveRange(maxpoints, bv.verts.Count - maxpoints);
  382. // Only want to calculate skin vertices we use
  383. if ( !sourceIsSkin && targetIsSkin )
  384. {
  385. for ( int fi = 0; fi < bv.verts.Count; fi++ )
  386. {
  387. if ( !neededVerts.Contains(bv.verts[fi].i0) )
  388. neededVerts.Add(bv.verts[fi].i0);
  389. if ( !neededVerts.Contains(bv.verts[fi].i1) )
  390. neededVerts.Add(bv.verts[fi].i1);
  391. if ( !neededVerts.Contains(bv.verts[fi].i2) )
  392. neededVerts.Add(bv.verts[fi].i2);
  393. }
  394. }
  395. if ( tweight == 0.0f )
  396. nomapcount++;
  397. bv.weight = tweight;
  398. }
  399. }
  400. void LateUpdate()
  401. {
  402. DoUpdate();
  403. }
  404. public Vector3 GetSkinPos(int i)
  405. {
  406. Vector3 pos = target.sverts[i];
  407. Vector3 bpos = bindposes[boneweights[i].boneIndex0].MultiplyPoint(pos);
  408. Vector3 p = bones[boneweights[i].boneIndex0].TransformPoint(bpos) * boneweights[i].weight0;
  409. bpos = bindposes[boneweights[i].boneIndex1].MultiplyPoint(pos);
  410. p += bones[boneweights[i].boneIndex1].TransformPoint(bpos) * boneweights[i].weight1;
  411. bpos = bindposes[boneweights[i].boneIndex2].MultiplyPoint(pos);
  412. p += bones[boneweights[i].boneIndex2].TransformPoint(bpos) * boneweights[i].weight2;
  413. bpos = bindposes[boneweights[i].boneIndex3].MultiplyPoint(pos);
  414. p += bones[boneweights[i].boneIndex3].TransformPoint(bpos) * boneweights[i].weight3;
  415. return p;
  416. }
  417. Vector3 gcp = Vector3.zero;
  418. public Vector3 GetCoordMine(Vector3 A, Vector3 B, Vector3 C, Vector3 bary)
  419. {
  420. //Vector3 p = Vector3.zero;
  421. gcp.x = (bary.x * A.x) + (bary.y * B.x) + (bary.z * C.x);
  422. gcp.y = (bary.x * A.y) + (bary.y * B.y) + (bary.z * C.y);
  423. gcp.z = (bary.x * A.z) + (bary.y * B.z) + (bary.z * C.z);
  424. return gcp;
  425. }
  426. SkinnedMeshRenderer tmesh;
  427. #if UNITY_5 || UNITY_2017 || UNITY_2018 || UNITY_2019 || UNITY_2020
  428. Mesh bakedmesh = null;
  429. #endif
  430. void DoUpdate()
  431. {
  432. if ( WrapEnabled == false || target == null || bindverts == null ) //|| bindposes == null )
  433. return;
  434. if ( mesh == null )
  435. SetMesh();
  436. if ( mesh == null )
  437. return;
  438. if ( targetIsSkin && neededVerts != null && neededVerts.Count > 0 ) //|| (targetIsSkin && boneweights == null) )
  439. {
  440. if ( boneweights == null || tmesh == null )
  441. {
  442. tmesh = (SkinnedMeshRenderer)target.GetComponent(typeof(SkinnedMeshRenderer));
  443. if ( tmesh != null )
  444. {
  445. if ( !sourceIsSkin )
  446. {
  447. Mesh sm = tmesh.sharedMesh;
  448. bindposes = sm.bindposes;
  449. bones = tmesh.bones;
  450. boneweights = sm.boneWeights;
  451. }
  452. }
  453. }
  454. #if UNITY_5 || UNITY_2017 || UNITY_2018 || UNITY_2019 || UNITY_2020
  455. if ( tmesh == null )
  456. tmesh = (SkinnedMeshRenderer)target.GetComponent(typeof(SkinnedMeshRenderer));
  457. if ( UseBakedMesh )
  458. {
  459. if ( bakedmesh == null )
  460. bakedmesh = new Mesh();
  461. tmesh.BakeMesh(bakedmesh);
  462. skinnedVerts = bakedmesh.vertices;
  463. }
  464. else
  465. {
  466. for ( int i = 0; i < neededVerts.Count; i++ )
  467. skinnedVerts[neededVerts[i]] = GetSkinPos(neededVerts[i]);
  468. }
  469. #else
  470. for ( int i = 0; i < neededVerts.Count; i++ )
  471. skinnedVerts[neededVerts[i]] = GetSkinPos(neededVerts[i]);
  472. #endif
  473. }
  474. Matrix4x4 stm = Matrix4x4.identity;
  475. Vector3 p = Vector3.zero;
  476. if ( targetIsSkin && !sourceIsSkin )
  477. {
  478. #if UNITY_5 || UNITY_2017 || UNITY_2018 || UNITY_2019 || UNITY_2020
  479. if ( UseBakedMesh )
  480. stm = transform.worldToLocalMatrix * target.transform.localToWorldMatrix; // * transform.worldToLocalMatrix;
  481. else
  482. stm = transform.worldToLocalMatrix; // * target.transform.localToWorldMatrix; // * transform.worldToLocalMatrix;
  483. #else
  484. stm = transform.worldToLocalMatrix; // * target.transform.localToWorldMatrix; // * transform.worldToLocalMatrix;
  485. #endif
  486. for ( int i = 0; i < bindverts.Length; i++ )
  487. {
  488. if ( bindverts[i].verts.Count > 0 )
  489. {
  490. p = Vector3.zero;
  491. float oow = 1.0f / bindverts[i].weight;
  492. int cnt = bindverts[i].verts.Count;
  493. for ( int j = 0; j < cnt; j++ )
  494. {
  495. MegaBindInf bi = bindverts[i].verts[j];
  496. Vector3 p0 = skinnedVerts[bi.i0];
  497. Vector3 p1 = skinnedVerts[bi.i1];
  498. Vector3 p2 = skinnedVerts[bi.i2];
  499. Vector3 cp = GetCoordMine(p0, p1, p2, bi.bary);
  500. Vector3 norm = FaceNormal(p0, p1, p2);
  501. float sq = 1.0f / Mathf.Sqrt(norm.x * norm.x + norm.y * norm.y + norm.z * norm.z);
  502. float d = (bi.dist * shrink) + gap;
  503. //cp += d * norm.x;
  504. cp.x += d * norm.x * sq;
  505. cp.y += d * norm.y * sq;
  506. cp.z += d * norm.z * sq;
  507. float bw = bi.weight * oow;
  508. if ( j == 0 )
  509. {
  510. p.x = cp.x * bw;
  511. p.y = cp.y * bw;
  512. p.z = cp.z * bw;
  513. }
  514. else
  515. {
  516. p.x += cp.x * bw;
  517. p.y += cp.y * bw;
  518. p.z += cp.z * bw;
  519. }
  520. //cp += ((bi.dist * shrink) + gap) * norm.normalized;
  521. //p += cp * (bi.weight / bindverts[i].weight);
  522. }
  523. Vector3 pp = stm.MultiplyPoint3x4(p);
  524. verts[i].x = pp.x + offset.x;
  525. verts[i].y = pp.y + offset.y;
  526. verts[i].z = pp.z + offset.z;
  527. //verts[i] = transform.InverseTransformPoint(p) + offset;
  528. }
  529. }
  530. }
  531. else
  532. {
  533. stm = transform.worldToLocalMatrix * target.transform.localToWorldMatrix; // * transform.worldToLocalMatrix;
  534. //Matrix4x4 tm = target.transform.localToWorldMatrix;
  535. for ( int i = 0; i < bindverts.Length; i++ )
  536. {
  537. if ( bindverts[i].verts.Count > 0 )
  538. {
  539. p = Vector3.zero;
  540. float oow = 1.0f / bindverts[i].weight;
  541. for ( int j = 0; j < bindverts[i].verts.Count; j++ )
  542. {
  543. MegaBindInf bi = bindverts[i].verts[j];
  544. Vector3 p0 = target.sverts[bi.i0];
  545. Vector3 p1 = target.sverts[bi.i1];
  546. Vector3 p2 = target.sverts[bi.i2];
  547. Vector3 cp = GetCoordMine(p0, p1, p2, bi.bary);
  548. Vector3 norm = FaceNormal(p0, p1, p2);
  549. float sq = 1.0f / Mathf.Sqrt(norm.x * norm.x + norm.y * norm.y + norm.z * norm.z);
  550. float d = (bi.dist * shrink) + gap;
  551. //cp += d * norm.x;
  552. cp.x += d * norm.x * sq;
  553. cp.y += d * norm.y * sq;
  554. cp.z += d * norm.z * sq;
  555. float bw = bi.weight * oow;
  556. if ( j == 0 )
  557. {
  558. p.x = cp.x * bw;
  559. p.y = cp.y * bw;
  560. p.z = cp.z * bw;
  561. }
  562. else
  563. {
  564. p.x += cp.x * bw;
  565. p.y += cp.y * bw;
  566. p.z += cp.z * bw;
  567. }
  568. //cp += ((bi.dist * shrink) + gap) * norm.normalized;
  569. //p += cp * (bi.weight / bindverts[i].weight);
  570. }
  571. }
  572. else
  573. p = freeverts[i]; //startverts[i];
  574. Vector3 pp = stm.MultiplyPoint3x4(p);
  575. verts[i].x = pp.x + offset.x;
  576. verts[i].y = pp.y + offset.y;
  577. verts[i].z = pp.z + offset.z;
  578. //p = target.transform.TransformPoint(p);
  579. //verts[i] = transform.InverseTransformPoint(p) + offset;
  580. }
  581. }
  582. mesh.vertices = verts;
  583. RecalcNormals();
  584. mesh.RecalculateBounds();
  585. }
  586. public MegaNormMap[] mapping;
  587. public int[] tris;
  588. public Vector3[] facenorms;
  589. public Vector3[] norms;
  590. int[] FindFacesUsing(Vector3 p, Vector3 n)
  591. {
  592. List<int> faces = new List<int>();
  593. Vector3 v = Vector3.zero;
  594. for ( int i = 0; i < tris.Length; i += 3 )
  595. {
  596. v = verts[tris[i]];
  597. if ( v.x == p.x && v.y == p.y && v.z == p.z )
  598. {
  599. if ( n.Equals(norms[tris[i]]) )
  600. faces.Add(i / 3);
  601. }
  602. else
  603. {
  604. v = verts[tris[i + 1]];
  605. if ( v.x == p.x && v.y == p.y && v.z == p.z )
  606. {
  607. if ( n.Equals(norms[tris[i + 1]]) )
  608. faces.Add(i / 3);
  609. }
  610. else
  611. {
  612. v = verts[tris[i + 2]];
  613. if ( v.x == p.x && v.y == p.y && v.z == p.z )
  614. {
  615. if ( n.Equals(norms[tris[i + 2]]) )
  616. faces.Add(i / 3);
  617. }
  618. }
  619. }
  620. }
  621. return faces.ToArray();
  622. }
  623. // Should call this from inspector when we change to mega
  624. public void BuildNormalMapping(Mesh mesh, bool force)
  625. {
  626. if ( mapping == null || mapping.Length == 0 || force )
  627. {
  628. // so for each normal we have a vertex, so find all faces that share that vertex
  629. tris = mesh.triangles;
  630. norms = mesh.normals;
  631. facenorms = new Vector3[tris.Length / 3];
  632. mapping = new MegaNormMap[verts.Length];
  633. for ( int i = 0; i < verts.Length; i++ )
  634. {
  635. mapping[i] = new MegaNormMap();
  636. mapping[i].faces = FindFacesUsing(verts[i], norms[i]);
  637. }
  638. }
  639. }
  640. public void RecalcNormals()
  641. {
  642. if ( NormalMethod == MegaNormalMethod.Unity ) //|| mapping == null )
  643. mesh.RecalculateNormals();
  644. else
  645. {
  646. if ( mapping == null )
  647. BuildNormalMapping(mesh, false);
  648. RecalcNormals(mesh, verts);
  649. }
  650. }
  651. public void RecalcNormals(Mesh ms, Vector3[] _verts)
  652. {
  653. int index = 0;
  654. Vector3 v30 = Vector3.zero;
  655. Vector3 v31 = Vector3.zero;
  656. Vector3 v32 = Vector3.zero;
  657. Vector3 va = Vector3.zero;
  658. Vector3 vb = Vector3.zero;
  659. for ( int f = 0; f < tris.Length; f += 3 )
  660. {
  661. v30 = _verts[tris[f]];
  662. v31 = _verts[tris[f + 1]];
  663. v32 = _verts[tris[f + 2]];
  664. va.x = v31.x - v30.x;
  665. va.y = v31.y - v30.y;
  666. va.z = v31.z - v30.z;
  667. vb.x = v32.x - v31.x;
  668. vb.y = v32.y - v31.y;
  669. vb.z = v32.z - v31.z;
  670. v30.x = va.y * vb.z - va.z * vb.y;
  671. v30.y = va.z * vb.x - va.x * vb.z;
  672. v30.z = va.x * vb.y - va.y * vb.x;
  673. // Uncomment this if you dont want normals weighted by poly size
  674. //float l = v30.x * v30.x + v30.y * v30.y + v30.z * v30.z;
  675. //l = 1.0f / Mathf.Sqrt(l);
  676. //v30.x *= l;
  677. //v30.y *= l;
  678. //v30.z *= l;
  679. facenorms[index++] = v30;
  680. }
  681. for ( int n = 0; n < norms.Length; n++ )
  682. {
  683. if ( mapping[n].faces.Length > 0 )
  684. {
  685. Vector3 norm = facenorms[mapping[n].faces[0]];
  686. for ( int i = 1; i < mapping[n].faces.Length; i++ )
  687. {
  688. v30 = facenorms[mapping[n].faces[i]];
  689. norm.x += v30.x;
  690. norm.y += v30.y;
  691. norm.z += v30.z;
  692. }
  693. float l = norm.x * norm.x + norm.y * norm.y + norm.z * norm.z;
  694. l = 1.0f / Mathf.Sqrt(l);
  695. norm.x *= l;
  696. norm.y *= l;
  697. norm.z *= l;
  698. norms[n] = norm;
  699. }
  700. else
  701. norms[n] = Vector3.up;
  702. }
  703. ms.normals = norms;
  704. }
  705. }