MegaWrapRef.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504
  1. using UnityEngine;
  2. using System.Collections.Generic;
  3. [ExecuteInEditMode]
  4. public class MegaWrapRef : MonoBehaviour
  5. {
  6. public float gap = 0.0f;
  7. public float shrink = 1.0f;
  8. public Vector3[] skinnedVerts;
  9. public Mesh mesh = null;
  10. public Vector3 offset = Vector3.zero;
  11. public bool targetIsSkin = false;
  12. public bool sourceIsSkin = false;
  13. public int nomapcount = 0;
  14. public Matrix4x4[] bindposes;
  15. public Transform[] bones;
  16. public float size = 0.01f;
  17. public int vertindex = 0;
  18. public Vector3[] verts;
  19. public MegaModifyObject target;
  20. public float maxdist = 0.25f;
  21. public int maxpoints = 4;
  22. public bool WrapEnabled = true;
  23. public MegaWrap source;
  24. public MegaNormalMethod NormalMethod = MegaNormalMethod.Unity;
  25. //struct MegaCloseFace
  26. //{
  27. //public int face;
  28. //public float dist;
  29. //}
  30. [ContextMenu("Help")]
  31. public void Help()
  32. {
  33. Application.OpenURL("http://www.west-racing.com/mf/?page_id=3709");
  34. }
  35. Vector4 Plane(Vector3 v1, Vector3 v2, Vector3 v3)
  36. {
  37. Vector3 normal = Vector4.zero;
  38. normal.x = (v2.y - v1.y) * (v3.z - v1.z) - (v2.z - v1.z) * (v3.y - v1.y);
  39. normal.y = (v2.z - v1.z) * (v3.x - v1.x) - (v2.x - v1.x) * (v3.z - v1.z);
  40. normal.z = (v2.x - v1.x) * (v3.y - v1.y) - (v2.y - v1.y) * (v3.x - v1.x);
  41. normal = normal.normalized;
  42. return new Vector4(normal.x, normal.y, normal.z, -Vector3.Dot(v2, normal));
  43. }
  44. float PlaneDist(Vector3 p, Vector4 plane)
  45. {
  46. Vector3 n = plane;
  47. return Vector3.Dot(n, p) + plane.w;
  48. }
  49. float GetDistance(Vector3 p, Vector3 p0, Vector3 p1, Vector3 p2)
  50. {
  51. return MegaNearestPointTest.DistPoint3Triangle3Dbl(p, p0, p1, p2);
  52. }
  53. float GetPlaneDistance(Vector3 p, Vector3 p0, Vector3 p1, Vector3 p2)
  54. {
  55. Vector4 pl = Plane(p0, p1, p2);
  56. return PlaneDist(p, pl);
  57. }
  58. public Vector3 MyBary(Vector3 p, Vector3 p0, Vector3 p1, Vector3 p2)
  59. {
  60. Vector3 bary = Vector3.zero;
  61. Vector3 normal = FaceNormal(p0, p1, p2);
  62. float areaABC = Vector3.Dot(normal, Vector3.Cross((p1 - p0), (p2 - p0)));
  63. float areaPBC = Vector3.Dot(normal, Vector3.Cross((p1 - p), (p2 - p)));
  64. float areaPCA = Vector3.Dot(normal, Vector3.Cross((p2 - p), (p0 - p)));
  65. bary.x = areaPBC / areaABC; // alpha
  66. bary.y = areaPCA / areaABC; // beta
  67. bary.z = 1.0f - bary.x - bary.y; // gamma
  68. return bary;
  69. }
  70. public Vector3 MyBary1(Vector3 p, Vector3 a, Vector3 b, Vector3 c)
  71. {
  72. Vector3 v0 = b - a, v1 = c - a, v2 = p - a;
  73. float d00 = Vector3.Dot(v0, v0);
  74. float d01 = Vector3.Dot(v0, v1);
  75. float d11 = Vector3.Dot(v1, v1);
  76. float d20 = Vector3.Dot(v2, v0);
  77. float d21 = Vector3.Dot(v2, v1);
  78. float denom = d00 * d11 - d01 * d01;
  79. float w = (d11 * d20 - d01 * d21) / denom;
  80. float v = (d00 * d21 - d01 * d20) / denom;
  81. float u = 1.0f - v - w;
  82. return new Vector3(u, v, w);
  83. }
  84. public Vector3 CalcBary(Vector3 p, Vector3 p0, Vector3 p1, Vector3 p2)
  85. {
  86. return MyBary(p, p0, p1, p2);
  87. }
  88. public float CalcArea(Vector3 p0, Vector3 p1, Vector3 p2)
  89. {
  90. Vector3 e1 = p1 - p0;
  91. Vector3 e2 = p2 - p0;
  92. Vector3 e3 = Vector3.Cross(e1, e2);
  93. return 0.5f * e3.magnitude;
  94. }
  95. public Vector3 FaceNormal(Vector3 p0, Vector3 p1, Vector3 p2)
  96. {
  97. Vector3 e1 = p1 - p0;
  98. Vector3 e2 = p2 - p0;
  99. return Vector3.Cross(e1, e2);
  100. }
  101. static void CopyBlendShapes(Mesh mesh1, Mesh clonemesh)
  102. {
  103. #if UNITY_5_3 || UNITY_5_4 || UNITY_5_5 || UNITY_5_6 || UNITY_2017 || UNITY_2018 || UNITY_2019 || UNITY_2020
  104. int bcount = mesh1.blendShapeCount; //GetBlendShapeFrameCount();
  105. Vector3[] deltaverts = new Vector3[mesh1.vertexCount];
  106. Vector3[] deltanorms = new Vector3[mesh1.vertexCount];
  107. Vector3[] deltatans = new Vector3[mesh1.vertexCount];
  108. for ( int j = 0; j < bcount; j++ )
  109. {
  110. int frames = mesh1.GetBlendShapeFrameCount(j);
  111. string bname = mesh1.GetBlendShapeName(j);
  112. for ( int f = 0; f < frames; f++ )
  113. {
  114. mesh1.GetBlendShapeFrameVertices(j, f, deltaverts, deltanorms, deltatans);
  115. float weight = mesh1.GetBlendShapeFrameWeight(j, f);
  116. clonemesh.AddBlendShapeFrame(bname, weight, deltaverts, deltanorms, deltatans);
  117. }
  118. }
  119. #endif
  120. }
  121. Mesh CloneMesh(Mesh m)
  122. {
  123. Mesh clonemesh = new Mesh();
  124. clonemesh.vertices = m.vertices;
  125. #if UNITY_5_0 || UNITY_5_1 || UNITY_5 || UNITY_2017 || UNITY_2018 || UNITY_2019 || UNITY_2020
  126. clonemesh.uv2 = m.uv2;
  127. clonemesh.uv3 = m.uv3;
  128. clonemesh.uv4 = m.uv4;
  129. #else
  130. clonemesh.uv1 = m.uv1;
  131. clonemesh.uv2 = m.uv2;
  132. #endif
  133. clonemesh.uv = m.uv;
  134. clonemesh.normals = m.normals;
  135. clonemesh.tangents = m.tangents;
  136. clonemesh.colors = m.colors;
  137. clonemesh.subMeshCount = m.subMeshCount;
  138. for ( int s = 0; s < m.subMeshCount; s++ )
  139. clonemesh.SetTriangles(m.GetTriangles(s), s);
  140. CopyBlendShapes(m, clonemesh);
  141. clonemesh.boneWeights = m.boneWeights;
  142. clonemesh.bindposes = m.bindposes;
  143. clonemesh.name = m.name; // + "_copy";
  144. clonemesh.RecalculateBounds();
  145. return clonemesh;
  146. }
  147. [ContextMenu("Reset Mesh")]
  148. public void ResetMesh()
  149. {
  150. if ( mesh && source )
  151. {
  152. mesh.vertices = source.startverts;
  153. mesh.RecalculateBounds();
  154. RecalcNormals();
  155. }
  156. target = null;
  157. }
  158. public void Attach(MegaModifyObject modobj)
  159. {
  160. targetIsSkin = false;
  161. sourceIsSkin = false;
  162. nomapcount = 0;
  163. MeshFilter mf = GetComponent<MeshFilter>();
  164. Mesh srcmesh = null;
  165. if ( mf != null )
  166. srcmesh = mf.mesh;
  167. else
  168. {
  169. SkinnedMeshRenderer smesh = (SkinnedMeshRenderer)GetComponent(typeof(SkinnedMeshRenderer));
  170. if ( smesh != null )
  171. {
  172. srcmesh = smesh.sharedMesh;
  173. sourceIsSkin = true;
  174. }
  175. }
  176. if ( mesh == null )
  177. mesh = CloneMesh(srcmesh); //mf.mesh);
  178. if ( mf )
  179. mf.mesh = mesh;
  180. else
  181. {
  182. SkinnedMeshRenderer smesh = (SkinnedMeshRenderer)GetComponent(typeof(SkinnedMeshRenderer));
  183. smesh.sharedMesh = mesh;
  184. }
  185. if ( sourceIsSkin == false )
  186. {
  187. SkinnedMeshRenderer tmesh = (SkinnedMeshRenderer)modobj.GetComponent(typeof(SkinnedMeshRenderer));
  188. if ( tmesh != null )
  189. {
  190. targetIsSkin = true;
  191. if ( !sourceIsSkin )
  192. {
  193. Mesh sm = tmesh.sharedMesh;
  194. bindposes = sm.bindposes;
  195. bones = tmesh.bones;
  196. skinnedVerts = sm.vertices; //new Vector3[sm.vertexCount];
  197. }
  198. }
  199. }
  200. verts = mesh.vertices;
  201. }
  202. void LateUpdate()
  203. {
  204. DoUpdate();
  205. }
  206. Vector3 GetSkinPos(MegaWrap src, int i)
  207. {
  208. Vector3 pos = target.sverts[i];
  209. Vector3 bpos = bindposes[src.boneweights[i].boneIndex0].MultiplyPoint(pos);
  210. Vector3 p = bones[src.boneweights[i].boneIndex0].TransformPoint(bpos) * src.boneweights[i].weight0;
  211. bpos = bindposes[src.boneweights[i].boneIndex1].MultiplyPoint(pos);
  212. p += bones[src.boneweights[i].boneIndex1].TransformPoint(bpos) * src.boneweights[i].weight1;
  213. bpos = bindposes[src.boneweights[i].boneIndex2].MultiplyPoint(pos);
  214. p += bones[src.boneweights[i].boneIndex2].TransformPoint(bpos) * src.boneweights[i].weight2;
  215. bpos = bindposes[src.boneweights[i].boneIndex3].MultiplyPoint(pos);
  216. p += bones[src.boneweights[i].boneIndex3].TransformPoint(bpos) * src.boneweights[i].weight3;
  217. return p;
  218. }
  219. public Vector3 GetCoordMine(Vector3 A, Vector3 B, Vector3 C, Vector3 bary)
  220. {
  221. Vector3 p = Vector3.zero;
  222. p.x = (bary.x * A.x) + (bary.y * B.x) + (bary.z * C.x);
  223. p.y = (bary.x * A.y) + (bary.y * B.y) + (bary.z * C.y);
  224. p.z = (bary.x * A.z) + (bary.y * B.z) + (bary.z * C.z);
  225. return p;
  226. }
  227. void DoUpdate()
  228. {
  229. if ( source == null || WrapEnabled == false || target == null || source.bindverts == null ) //|| bindposes == null )
  230. return;
  231. if ( targetIsSkin && source.neededVerts != null && source.neededVerts.Count > 0 )
  232. {
  233. if ( source.boneweights == null )
  234. {
  235. SkinnedMeshRenderer tmesh = (SkinnedMeshRenderer)target.GetComponent(typeof(SkinnedMeshRenderer));
  236. if ( tmesh != null )
  237. {
  238. if ( !sourceIsSkin )
  239. {
  240. Mesh sm = tmesh.sharedMesh;
  241. bindposes = sm.bindposes;
  242. source.boneweights = sm.boneWeights;
  243. }
  244. }
  245. }
  246. for ( int i = 0; i < source.neededVerts.Count; i++ )
  247. skinnedVerts[source.neededVerts[i]] = GetSkinPos(source, source.neededVerts[i]);
  248. }
  249. Vector3 p = Vector3.zero;
  250. if ( targetIsSkin && !sourceIsSkin )
  251. {
  252. for ( int i = 0; i < source.bindverts.Length; i++ )
  253. {
  254. if ( source.bindverts[i].verts.Count > 0 )
  255. {
  256. p = Vector3.zero;
  257. for ( int j = 0; j < source.bindverts[i].verts.Count; j++ )
  258. {
  259. MegaBindInf bi = source.bindverts[i].verts[j];
  260. Vector3 p0 = skinnedVerts[bi.i0];
  261. Vector3 p1 = skinnedVerts[bi.i1];
  262. Vector3 p2 = skinnedVerts[bi.i2];
  263. Vector3 cp = GetCoordMine(p0, p1, p2, bi.bary);
  264. Vector3 norm = FaceNormal(p0, p1, p2);
  265. cp += ((bi.dist * shrink) + gap) * norm.normalized;
  266. p += cp * (bi.weight / source.bindverts[i].weight);
  267. }
  268. verts[i] = transform.InverseTransformPoint(p) + offset;
  269. }
  270. }
  271. }
  272. else
  273. {
  274. for ( int i = 0; i < source.bindverts.Length; i++ )
  275. {
  276. if ( source.bindverts[i].verts.Count > 0 )
  277. {
  278. p = Vector3.zero;
  279. for ( int j = 0; j < source.bindverts[i].verts.Count; j++ )
  280. {
  281. MegaBindInf bi = source.bindverts[i].verts[j];
  282. Vector3 p0 = target.sverts[bi.i0];
  283. Vector3 p1 = target.sverts[bi.i1];
  284. Vector3 p2 = target.sverts[bi.i2];
  285. Vector3 cp = GetCoordMine(p0, p1, p2, bi.bary);
  286. Vector3 norm = FaceNormal(p0, p1, p2);
  287. cp += ((bi.dist * shrink) + gap) * norm.normalized;
  288. p += cp * (bi.weight / source.bindverts[i].weight);
  289. }
  290. }
  291. else
  292. p = source.freeverts[i]; //startverts[i];
  293. p = target.transform.TransformPoint(p);
  294. verts[i] = transform.InverseTransformPoint(p) + offset;
  295. }
  296. }
  297. mesh.vertices = verts;
  298. RecalcNormals();
  299. mesh.RecalculateBounds();
  300. }
  301. [HideInInspector]
  302. public MegaNormMap[] mapping;
  303. [HideInInspector]
  304. public int[] tris;
  305. [HideInInspector]
  306. public Vector3[] facenorms;
  307. [HideInInspector]
  308. public Vector3[] norms;
  309. int[] FindFacesUsing(Vector3 p, Vector3 n)
  310. {
  311. List<int> faces = new List<int>();
  312. Vector3 v = Vector3.zero;
  313. for ( int i = 0; i < tris.Length; i += 3 )
  314. {
  315. v = verts[tris[i]];
  316. if ( v.x == p.x && v.y == p.y && v.z == p.z )
  317. {
  318. if ( n.Equals(norms[tris[i]]) )
  319. faces.Add(i / 3);
  320. }
  321. else
  322. {
  323. v = verts[tris[i + 1]];
  324. if ( v.x == p.x && v.y == p.y && v.z == p.z )
  325. {
  326. if ( n.Equals(norms[tris[i + 1]]) )
  327. faces.Add(i / 3);
  328. }
  329. else
  330. {
  331. v = verts[tris[i + 2]];
  332. if ( v.x == p.x && v.y == p.y && v.z == p.z )
  333. {
  334. if ( n.Equals(norms[tris[i + 2]]) )
  335. faces.Add(i / 3);
  336. }
  337. }
  338. }
  339. }
  340. return faces.ToArray();
  341. }
  342. // Should call this from inspector when we change to mega
  343. public void BuildNormalMapping(Mesh mesh, bool force)
  344. {
  345. if ( mapping == null || mapping.Length == 0 || force )
  346. {
  347. // so for each normal we have a vertex, so find all faces that share that vertex
  348. tris = mesh.triangles;
  349. norms = mesh.normals;
  350. facenorms = new Vector3[tris.Length / 3];
  351. mapping = new MegaNormMap[verts.Length];
  352. for ( int i = 0; i < verts.Length; i++ )
  353. {
  354. mapping[i] = new MegaNormMap();
  355. mapping[i].faces = FindFacesUsing(verts[i], norms[i]);
  356. }
  357. }
  358. }
  359. public void RecalcNormals()
  360. {
  361. if ( NormalMethod == MegaNormalMethod.Unity ) //|| mapping == null )
  362. mesh.RecalculateNormals();
  363. else
  364. {
  365. if ( mapping == null )
  366. BuildNormalMapping(mesh, false);
  367. RecalcNormals(mesh, verts);
  368. }
  369. }
  370. public void RecalcNormals(Mesh ms, Vector3[] _verts)
  371. {
  372. int index = 0;
  373. Vector3 v30 = Vector3.zero;
  374. Vector3 v31 = Vector3.zero;
  375. Vector3 v32 = Vector3.zero;
  376. Vector3 va = Vector3.zero;
  377. Vector3 vb = Vector3.zero;
  378. for ( int f = 0; f < tris.Length; f += 3 )
  379. {
  380. v30 = _verts[tris[f]];
  381. v31 = _verts[tris[f + 1]];
  382. v32 = _verts[tris[f + 2]];
  383. va.x = v31.x - v30.x;
  384. va.y = v31.y - v30.y;
  385. va.z = v31.z - v30.z;
  386. vb.x = v32.x - v31.x;
  387. vb.y = v32.y - v31.y;
  388. vb.z = v32.z - v31.z;
  389. v30.x = va.y * vb.z - va.z * vb.y;
  390. v30.y = va.z * vb.x - va.x * vb.z;
  391. v30.z = va.x * vb.y - va.y * vb.x;
  392. // Uncomment this if you dont want normals weighted by poly size
  393. //float l = v30.x * v30.x + v30.y * v30.y + v30.z * v30.z;
  394. //l = 1.0f / Mathf.Sqrt(l);
  395. //v30.x *= l;
  396. //v30.y *= l;
  397. //v30.z *= l;
  398. facenorms[index++] = v30;
  399. }
  400. for ( int n = 0; n < norms.Length; n++ )
  401. {
  402. if ( mapping[n].faces.Length > 0 )
  403. {
  404. Vector3 norm = facenorms[mapping[n].faces[0]];
  405. for ( int i = 1; i < mapping[n].faces.Length; i++ )
  406. {
  407. v30 = facenorms[mapping[n].faces[i]];
  408. norm.x += v30.x;
  409. norm.y += v30.y;
  410. norm.z += v30.z;
  411. }
  412. float l = norm.x * norm.x + norm.y * norm.y + norm.z * norm.z;
  413. l = 1.0f / Mathf.Sqrt(l);
  414. norm.x *= l;
  415. norm.y *= l;
  416. norm.z *= l;
  417. norms[n] = norm;
  418. }
  419. else
  420. norms[n] = Vector3.up;
  421. }
  422. ms.normals = norms;
  423. }
  424. }