MegaWrapEditor.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
  1. using UnityEngine;
  2. using UnityEditor;
  3. using System.Collections.Generic;
  4. //public class MegaTriangle
  5. //{
  6. // public int t;
  7. // public Vector3 a, b, c;
  8. // public Bounds bounds;
  9. // public MegaTriangle(Vector3 a, Vector3 b, Vector3 c, Vector3 dir, int t)
  10. // {
  11. // this.t = t;
  12. // this.a = a;
  13. // this.b = b;
  14. // this.c = c;
  15. // //Vector3 cross = Vector3.Cross(b - a, c - a);
  16. // Vector3 min = Vector3.Min(Vector3.Min(a, b), c);
  17. // Vector3 max = Vector3.Max(Vector3.Max(a, b), c);
  18. // bounds.SetMinMax(min, max);
  19. // }
  20. // public void Barycentric(Vector3 p, out float u, out float v, out float w)
  21. // {
  22. // Vector3 v0 = b - a, v1 = c - a, v2 = p - a;
  23. // float d00 = Vector3.Dot(v0, v0);
  24. // float d01 = Vector3.Dot(v0, v1);
  25. // float d11 = Vector3.Dot(v1, v1);
  26. // float d20 = Vector3.Dot(v2, v0);
  27. // float d21 = Vector3.Dot(v2, v1);
  28. // float denom = 1f / (d00 * d11 - d01 * d01);
  29. // v = (d11 * d20 - d01 * d21) * denom;
  30. // w = (d00 * d21 - d01 * d20) * denom;
  31. // u = 1.0f - v - w;
  32. // }
  33. //}
  34. //public class MegaVoxel
  35. //{
  36. // public class Voxel_t
  37. // {
  38. // public Vector3 position;
  39. // public List<MegaTriangle> tris;
  40. // public Voxel_t()
  41. // {
  42. // position = Vector3.zero;
  43. // tris = new List<MegaTriangle>();
  44. // }
  45. // }
  46. // public static void GetGridIndex(Vector3 p, out int x, out int y, out int z, float unit)
  47. // {
  48. // x = (int)((p.x - start.x) / unit);
  49. // y = (int)((p.y - start.y) / unit);
  50. // z = (int)((p.z - start.z) / unit);
  51. // }
  52. // public static Voxel_t[,,] volume;
  53. // public static int width;
  54. // public static int height;
  55. // public static int depth;
  56. // static Vector3 start;
  57. // public static void Voxelize(Vector3[] vertices, int[] indices, Bounds bounds, int resolution, out float unit)
  58. // {
  59. // float maxLength = Mathf.Max(bounds.size.x, Mathf.Max(bounds.size.y, bounds.size.z));
  60. // unit = maxLength / resolution;
  61. // float hunit = unit * 0.5f;
  62. // start = bounds.min - new Vector3(hunit, hunit, hunit);
  63. // Vector3 end = bounds.max + new Vector3(hunit, hunit, hunit);
  64. // Vector3 size = end - start;
  65. // width = Mathf.CeilToInt(size.x / unit);
  66. // height = Mathf.CeilToInt(size.y / unit);
  67. // depth = Mathf.CeilToInt(size.z / unit);
  68. // volume = new Voxel_t[width, height, depth];
  69. // Bounds[,,] boxes = new Bounds[width, height, depth];
  70. // Vector3 voxelSize = Vector3.one * unit;
  71. // for (int x = 0; x < width; x++)
  72. // {
  73. // for (int y = 0; y < height; y++)
  74. // {
  75. // for (int z = 0; z < depth; z++)
  76. // {
  77. // Vector3 p = new Vector3(x, y, z) * unit + start;
  78. // Bounds aabb = new Bounds(p, voxelSize);
  79. // boxes[x, y, z] = aabb;
  80. // volume[x, y, z] = new Voxel_t();
  81. // }
  82. // }
  83. // }
  84. // Vector3 direction = Vector3.forward;
  85. // for (int i = 0, n = indices.Length; i < n; i += 3)
  86. // {
  87. // MegaTriangle tri = new MegaTriangle(vertices[indices[i]], vertices[indices[i + 1]], vertices[indices[i + 2]], direction, i);
  88. // Vector3 min = tri.bounds.min - start;
  89. // Vector3 max = tri.bounds.max - start;
  90. // int iminX = (int)(min.x / unit), iminY = (int)(min.y / unit), iminZ = (int)(min.z / unit);
  91. // int imaxX = (int)(max.x / unit), imaxY = (int)(max.y / unit), imaxZ = (int)(max.z / unit);
  92. // iminX = Mathf.Clamp(iminX, 0, width - 1);
  93. // iminY = Mathf.Clamp(iminY, 0, height - 1);
  94. // iminZ = Mathf.Clamp(iminZ, 0, depth - 1);
  95. // imaxX = Mathf.Clamp(imaxX, 0, width - 1);
  96. // imaxY = Mathf.Clamp(imaxY, 0, height - 1);
  97. // imaxZ = Mathf.Clamp(imaxZ, 0, depth - 1);
  98. // for (int x = iminX; x <= imaxX; x++)
  99. // {
  100. // for (int y = iminY; y <= imaxY; y++)
  101. // {
  102. // for (int z = iminZ; z <= imaxZ; z++)
  103. // {
  104. // if (Intersects(tri, boxes[x, y, z]))
  105. // {
  106. // Voxel_t voxel = volume[x, y, z];
  107. // voxel.position = boxes[x, y, z].center;
  108. // voxel.tris.Add(tri);
  109. // volume[x, y, z] = voxel;
  110. // }
  111. // }
  112. // }
  113. // }
  114. // }
  115. // }
  116. // public static bool Intersects(MegaTriangle tri, Bounds aabb)
  117. // {
  118. // float p0, p1, p2, r;
  119. // Vector3 center = aabb.center, extents = aabb.max - center;
  120. // Vector3 v0 = tri.a - center,
  121. // v1 = tri.b - center,
  122. // v2 = tri.c - center;
  123. // Vector3 f0 = v1 - v0,
  124. // f1 = v2 - v1,
  125. // f2 = v0 - v2;
  126. // Vector3 a00 = new Vector3(0, -f0.z, f0.y),
  127. // a01 = new Vector3(0, -f1.z, f1.y),
  128. // a02 = new Vector3(0, -f2.z, f2.y),
  129. // a10 = new Vector3(f0.z, 0, -f0.x),
  130. // a11 = new Vector3(f1.z, 0, -f1.x),
  131. // a12 = new Vector3(f2.z, 0, -f2.x),
  132. // a20 = new Vector3(-f0.y, f0.x, 0),
  133. // a21 = new Vector3(-f1.y, f1.x, 0),
  134. // a22 = new Vector3(-f2.y, f2.x, 0);
  135. // // Test axis a00
  136. // p0 = Vector3.Dot(v0, a00);
  137. // p1 = Vector3.Dot(v1, a00);
  138. // p2 = Vector3.Dot(v2, a00);
  139. // r = extents.y * Mathf.Abs(f0.z) + extents.z * Mathf.Abs(f0.y);
  140. // if (Mathf.Max(-Mathf.Max(p0, p1, p2), Mathf.Min(p0, p1, p2)) > r)
  141. // return false;
  142. // // Test axis a01
  143. // p0 = Vector3.Dot(v0, a01);
  144. // p1 = Vector3.Dot(v1, a01);
  145. // p2 = Vector3.Dot(v2, a01);
  146. // r = extents.y * Mathf.Abs(f1.z) + extents.z * Mathf.Abs(f1.y);
  147. // if (Mathf.Max(-Mathf.Max(p0, p1, p2), Mathf.Min(p0, p1, p2)) > r)
  148. // return false;
  149. // // Test axis a02
  150. // p0 = Vector3.Dot(v0, a02);
  151. // p1 = Vector3.Dot(v1, a02);
  152. // p2 = Vector3.Dot(v2, a02);
  153. // r = extents.y * Mathf.Abs(f2.z) + extents.z * Mathf.Abs(f2.y);
  154. // if (Mathf.Max(-Mathf.Max(p0, p1, p2), Mathf.Min(p0, p1, p2)) > r)
  155. // return false;
  156. // // Test axis a10
  157. // p0 = Vector3.Dot(v0, a10);
  158. // p1 = Vector3.Dot(v1, a10);
  159. // p2 = Vector3.Dot(v2, a10);
  160. // r = extents.x * Mathf.Abs(f0.z) + extents.z * Mathf.Abs(f0.x);
  161. // if (Mathf.Max(-Mathf.Max(p0, p1, p2), Mathf.Min(p0, p1, p2)) > r)
  162. // return false;
  163. // // Test axis a11
  164. // p0 = Vector3.Dot(v0, a11);
  165. // p1 = Vector3.Dot(v1, a11);
  166. // p2 = Vector3.Dot(v2, a11);
  167. // r = extents.x * Mathf.Abs(f1.z) + extents.z * Mathf.Abs(f1.x);
  168. // if (Mathf.Max(-Mathf.Max(p0, p1, p2), Mathf.Min(p0, p1, p2)) > r)
  169. // return false;
  170. // // Test axis a12
  171. // p0 = Vector3.Dot(v0, a12);
  172. // p1 = Vector3.Dot(v1, a12);
  173. // p2 = Vector3.Dot(v2, a12);
  174. // r = extents.x * Mathf.Abs(f2.z) + extents.z * Mathf.Abs(f2.x);
  175. // if (Mathf.Max(-Mathf.Max(p0, p1, p2), Mathf.Min(p0, p1, p2)) > r)
  176. // return false;
  177. // // Test axis a20
  178. // p0 = Vector3.Dot(v0, a20);
  179. // p1 = Vector3.Dot(v1, a20);
  180. // p2 = Vector3.Dot(v2, a20);
  181. // r = extents.x * Mathf.Abs(f0.y) + extents.y * Mathf.Abs(f0.x);
  182. // if (Mathf.Max(-Mathf.Max(p0, p1, p2), Mathf.Min(p0, p1, p2)) > r)
  183. // return false;
  184. // // Test axis a21
  185. // p0 = Vector3.Dot(v0, a21);
  186. // p1 = Vector3.Dot(v1, a21);
  187. // p2 = Vector3.Dot(v2, a21);
  188. // r = extents.x * Mathf.Abs(f1.y) + extents.y * Mathf.Abs(f1.x);
  189. // if (Mathf.Max(-Mathf.Max(p0, p1, p2), Mathf.Min(p0, p1, p2)) > r)
  190. // return false;
  191. // // Test axis a22
  192. // p0 = Vector3.Dot(v0, a22);
  193. // p1 = Vector3.Dot(v1, a22);
  194. // p2 = Vector3.Dot(v2, a22);
  195. // r = extents.x * Mathf.Abs(f2.y) + extents.y * Mathf.Abs(f2.x);
  196. // if (Mathf.Max(-Mathf.Max(p0, p1, p2), Mathf.Min(p0, p1, p2)) > r)
  197. // return false;
  198. // if (Mathf.Max(v0.x, v1.x, v2.x) < -extents.x || Mathf.Min(v0.x, v1.x, v2.x) > extents.x)
  199. // return false;
  200. // if (Mathf.Max(v0.y, v1.y, v2.y) < -extents.y || Mathf.Min(v0.y, v1.y, v2.y) > extents.y)
  201. // return false;
  202. // if (Mathf.Max(v0.z, v1.z, v2.z) < -extents.z || Mathf.Min(v0.z, v1.z, v2.z) > extents.z)
  203. // return false;
  204. // Vector3 normal = Vector3.Cross(f1, f0).normalized;
  205. // Plane pl = new Plane(normal, Vector3.Dot(normal, tri.a));
  206. // return Intersects(pl, aabb);
  207. // }
  208. // public static bool Intersects(Plane pl, Bounds aabb)
  209. // {
  210. // Vector3 center = aabb.center;
  211. // Vector3 extents = aabb.max - center;
  212. // float r = extents.x * Mathf.Abs(pl.normal.x) + extents.y * Mathf.Abs(pl.normal.y) + extents.z * Mathf.Abs(pl.normal.z);
  213. // float s = Vector3.Dot(pl.normal, center) - pl.distance;
  214. // return Mathf.Abs(s) <= r;
  215. // }
  216. //}
  217. [CanEditMultipleObjects, CustomEditor(typeof(MegaWrap))]
  218. public class MegaWrapEditor : Editor
  219. {
  220. public override void OnInspectorGUI()
  221. {
  222. MegaWrap mod = (MegaWrap)target;
  223. #if !UNITY_5 && !UNITY_2017 && !UNITY_2018 && !UNITY_2019 && !UNITY_2020
  224. EditorGUIUtility.LookLikeControls();
  225. #endif
  226. mod.WrapEnabled = EditorGUILayout.Toggle("Enabled", mod.WrapEnabled);
  227. mod.target = (MegaModifyObject)EditorGUILayout.ObjectField("Target", mod.target, typeof(MegaModifyObject), true);
  228. float max = 1.0f;
  229. if ( mod.target )
  230. max = mod.target.bbox.size.magnitude;
  231. mod.maxdist = EditorGUILayout.Slider("Max Dist", mod.maxdist, 0.0f, max); //2.0f); //mod.maxdist);
  232. if ( mod.maxdist < 0.0f )
  233. mod.maxdist = 0.0f;
  234. mod.maxpoints = EditorGUILayout.IntField("Max Points", mod.maxpoints); //mod.maxdist);
  235. if ( mod.maxpoints < 1 )
  236. mod.maxpoints = 1;
  237. Color col = GUI.backgroundColor;
  238. EditorGUILayout.BeginHorizontal();
  239. if ( mod.bindverts == null )
  240. {
  241. GUI.backgroundColor = Color.red;
  242. if ( GUILayout.Button("Map") )
  243. Attach(mod.target);
  244. }
  245. else
  246. {
  247. GUI.backgroundColor = Color.green;
  248. if ( GUILayout.Button("ReMap") )
  249. Attach(mod.target);
  250. }
  251. GUI.backgroundColor = col;
  252. if ( GUILayout.Button("Reset") )
  253. mod.ResetMesh();
  254. EditorGUILayout.EndHorizontal();
  255. if ( GUI.changed )
  256. EditorUtility.SetDirty(mod);
  257. mod.gap = EditorGUILayout.FloatField("Gap", mod.gap);
  258. mod.shrink = EditorGUILayout.Slider("Shrink", mod.shrink, 0.0f, 1.0f);
  259. mod.size = EditorGUILayout.Slider("Size", mod.size, 0.001f, 0.04f);
  260. if ( mod.bindverts != null )
  261. mod.vertindex = EditorGUILayout.IntSlider("Vert Index", mod.vertindex, 0, mod.bindverts.Length - 1);
  262. mod.offset = EditorGUILayout.Vector3Field("Offset", mod.offset);
  263. mod.NormalMethod = (MegaNormalMethod)EditorGUILayout.EnumPopup("Normal Method", mod.NormalMethod);
  264. #if UNITY_5 || UNITY_2017 || UNITY_2018 || UNITY_2019 || UNITY_2020
  265. mod.UseBakedMesh = EditorGUILayout.Toggle("Use Baked Mesh", mod.UseBakedMesh);
  266. #endif
  267. if ( mod.bindverts == null || mod.target == null )
  268. EditorGUILayout.LabelField("Object not wrapped");
  269. else
  270. EditorGUILayout.LabelField("UnMapped", mod.nomapcount.ToString());
  271. if ( GUI.changed )
  272. EditorUtility.SetDirty(mod);
  273. }
  274. public void OnSceneGUI()
  275. {
  276. DisplayDebug();
  277. }
  278. void DisplayDebug()
  279. {
  280. MegaWrap mod = (MegaWrap)target;
  281. if ( mod.target )
  282. {
  283. if ( mod.bindverts != null && mod.bindverts.Length > 0 )
  284. {
  285. if ( mod.targetIsSkin && !mod.sourceIsSkin )
  286. {
  287. Color col = Color.black;
  288. Handles.matrix = Matrix4x4.identity;
  289. MegaBindVert bv = mod.bindverts[mod.vertindex];
  290. for ( int i = 0; i < bv.verts.Count; i++ )
  291. {
  292. MegaBindInf bi = bv.verts[i];
  293. float w = bv.verts[i].weight / bv.weight;
  294. if ( w > 0.5f )
  295. col = Color.Lerp(Color.green, Color.red, (w - 0.5f) * 2.0f);
  296. else
  297. col = Color.Lerp(Color.blue, Color.green, w * 2.0f);
  298. Handles.color = col;
  299. Vector3 p = (mod.skinnedVerts[bv.verts[i].i0] + mod.skinnedVerts[bv.verts[i].i1] + mod.skinnedVerts[bv.verts[i].i2]) / 3.0f; //tm.MultiplyPoint(mod.vr[i].cpos);
  300. MegaHandles.DotCap(i, p, Quaternion.identity, mod.size); //0.01f);
  301. Vector3 p0 = mod.skinnedVerts[bi.i0];
  302. Vector3 p1 = mod.skinnedVerts[bi.i1];
  303. Vector3 p2 = mod.skinnedVerts[bi.i2];
  304. Vector3 cp = mod.GetCoordMine(p0, p1, p2, bi.bary);
  305. Handles.color = Color.gray;
  306. Handles.DrawLine(p, cp);
  307. Vector3 norm = mod.FaceNormal(p0, p1, p2);
  308. Vector3 cp1 = cp + (((bi.dist * mod.shrink) + mod.gap) * norm.normalized);
  309. Handles.color = Color.green;
  310. Handles.DrawLine(cp, cp1);
  311. }
  312. }
  313. else
  314. {
  315. Color col = Color.black;
  316. Matrix4x4 tm = mod.target.transform.localToWorldMatrix;
  317. Handles.matrix = tm; //Matrix4x4.identity;
  318. MegaBindVert bv = mod.bindverts[mod.vertindex];
  319. for ( int i = 0; i < bv.verts.Count; i++ )
  320. {
  321. MegaBindInf bi = bv.verts[i];
  322. float w = bv.verts[i].weight / bv.weight;
  323. if ( w > 0.5f )
  324. col = Color.Lerp(Color.green, Color.red, (w - 0.5f) * 2.0f);
  325. else
  326. col = Color.Lerp(Color.blue, Color.green, w * 2.0f);
  327. Handles.color = col;
  328. Vector3 p = (mod.target.sverts[bv.verts[i].i0] + mod.target.sverts[bv.verts[i].i1] + mod.target.sverts[bv.verts[i].i2]) / 3.0f; //tm.MultiplyPoint(mod.vr[i].cpos);
  329. MegaHandles.DotCap(i, p, Quaternion.identity, mod.size); //0.01f);
  330. Vector3 p0 = mod.target.sverts[bi.i0];
  331. Vector3 p1 = mod.target.sverts[bi.i1];
  332. Vector3 p2 = mod.target.sverts[bi.i2];
  333. Vector3 cp = mod.GetCoordMine(p0, p1, p2, bi.bary);
  334. Handles.color = Color.gray;
  335. Handles.DrawLine(p, cp);
  336. Vector3 norm = mod.FaceNormal(p0, p1, p2);
  337. Vector3 cp1 = cp + (((bi.dist * mod.shrink) + mod.gap) * norm.normalized);
  338. Handles.color = Color.green;
  339. Handles.DrawLine(cp, cp1);
  340. }
  341. }
  342. // Show unmapped verts
  343. Handles.color = Color.yellow;
  344. for ( int i = 0; i < mod.bindverts.Length; i++ )
  345. {
  346. if ( mod.bindverts[i].weight == 0.0f )
  347. {
  348. Vector3 pv1 = mod.freeverts[i];
  349. MegaHandles.DotCap(0, pv1, Quaternion.identity, mod.size); //0.01f);
  350. }
  351. }
  352. }
  353. if ( mod.verts != null && mod.verts.Length > mod.vertindex )
  354. {
  355. Handles.color = Color.red;
  356. Handles.matrix = mod.transform.localToWorldMatrix;
  357. Vector3 pv = mod.verts[mod.vertindex];
  358. MegaHandles.DotCap(0, pv, Quaternion.identity, mod.size); //0.01f);
  359. }
  360. }
  361. }
  362. void Attach(MegaModifyObject modobj)
  363. {
  364. MegaWrap mod = (MegaWrap)target;
  365. mod.targetIsSkin = false;
  366. mod.sourceIsSkin = false;
  367. if ( mod.mesh && mod.startverts != null )
  368. mod.mesh.vertices = mod.startverts;
  369. if ( modobj == null )
  370. {
  371. mod.bindverts = null;
  372. return;
  373. }
  374. mod.nomapcount = 0;
  375. if ( mod.mesh )
  376. mod.mesh.vertices = mod.startverts;
  377. MeshFilter mf = mod.GetComponent<MeshFilter>();
  378. Mesh srcmesh = null;
  379. if ( mf != null )
  380. {
  381. //skinned = false;
  382. srcmesh = mf.sharedMesh;
  383. }
  384. else
  385. {
  386. SkinnedMeshRenderer smesh = (SkinnedMeshRenderer)mod.GetComponent(typeof(SkinnedMeshRenderer));
  387. if ( smesh != null )
  388. {
  389. //skinned = true;
  390. srcmesh = smesh.sharedMesh;
  391. mod.sourceIsSkin = true;
  392. }
  393. }
  394. if ( srcmesh == null )
  395. {
  396. Debug.LogWarning("No Mesh found on the target object, make sure target has a mesh and MegaFiers modifier attached!");
  397. return;
  398. }
  399. if ( mod.mesh == null )
  400. mod.mesh = mod.CloneMesh(srcmesh); //mf.mesh);
  401. if ( mf )
  402. mf.mesh = mod.mesh;
  403. else
  404. {
  405. SkinnedMeshRenderer smesh = (SkinnedMeshRenderer)mod.GetComponent(typeof(SkinnedMeshRenderer));
  406. smesh.sharedMesh = mod.mesh;
  407. }
  408. if ( mod.sourceIsSkin == false )
  409. {
  410. SkinnedMeshRenderer tmesh = (SkinnedMeshRenderer)modobj.GetComponent(typeof(SkinnedMeshRenderer));
  411. if ( tmesh != null )
  412. {
  413. mod.targetIsSkin = true;
  414. if ( !mod.sourceIsSkin )
  415. {
  416. Mesh sm = tmesh.sharedMesh;
  417. mod.bindposes = sm.bindposes;
  418. mod.boneweights = sm.boneWeights;
  419. mod.bones = tmesh.bones;
  420. mod.skinnedVerts = sm.vertices; //new Vector3[sm.vertexCount];
  421. }
  422. }
  423. }
  424. if ( mod.targetIsSkin )
  425. {
  426. if ( mod.boneweights == null || mod.boneweights.Length == 0 )
  427. mod.targetIsSkin = false;
  428. }
  429. mod.neededVerts.Clear();
  430. mod.verts = mod.mesh.vertices;
  431. mod.startverts = mod.mesh.vertices;
  432. mod.freeverts = new Vector3[mod.startverts.Length];
  433. Vector3[] baseverts = modobj.verts; //basemesh.vertices;
  434. int[] basefaces = modobj.tris; //basemesh.triangles;
  435. mod.bindverts = new MegaBindVert[mod.verts.Length];
  436. // matrix to get vertex into local space of target
  437. Matrix4x4 tm = mod.transform.localToWorldMatrix * modobj.transform.worldToLocalMatrix;
  438. List<MegaCloseFace> closefaces = new List<MegaCloseFace>();
  439. Vector3 p0 = Vector3.zero;
  440. Vector3 p1 = Vector3.zero;
  441. Vector3 p2 = Vector3.zero;
  442. Vector3[] tverts = new Vector3[mod.target.sverts.Length];
  443. for ( int i = 0; i < tverts.Length; i++ )
  444. {
  445. if ( mod.targetIsSkin && !mod.sourceIsSkin )
  446. tverts[i] = modobj.transform.InverseTransformPoint(mod.GetSkinPos(i));
  447. else
  448. tverts[i] = baseverts[i];
  449. }
  450. EditorUtility.ClearProgressBar();
  451. float unit = 0.0f;
  452. mod.target.mesh.RecalculateBounds();
  453. MegaVoxel.Voxelize(tverts, basefaces, mod.target.mesh.bounds, 16, out unit);
  454. //Vector3 min = mod.target.mesh.bounds.min;
  455. for ( int i = 0; i < mod.verts.Length; i++ )
  456. {
  457. MegaBindVert bv = new MegaBindVert();
  458. mod.bindverts[i] = bv;
  459. Vector3 p = tm.MultiplyPoint(mod.verts[i]);
  460. p = mod.transform.TransformPoint(mod.verts[i]);
  461. p = modobj.transform.InverseTransformPoint(p);
  462. mod.freeverts[i] = p;
  463. closefaces.Clear();
  464. int gx = 0;
  465. int gy = 0;
  466. int gz = 0;
  467. MegaVoxel.GetGridIndex(p, out gx, out gy, out gz, unit);
  468. for ( int x = gx - 1; x <= gx + 1; x++ )
  469. {
  470. if ( x >= 0 && x < MegaVoxel.width )
  471. {
  472. for ( int y = gy - 1; y <= gy + 1; y++ )
  473. {
  474. if ( y >= 0 && y < MegaVoxel.height )
  475. {
  476. for ( int z = gz - 1; z <= gz + 1; z++ )
  477. {
  478. if ( z >= 0 && z < MegaVoxel.depth )
  479. {
  480. List<MegaTriangle> tris = MegaVoxel.volume[x, y, z].tris;
  481. for ( int t = 0; t < tris.Count; t++ )
  482. {
  483. float dist = mod.GetDistance(p, tris[t].a, tris[t].b, tris[t].c);
  484. if ( Mathf.Abs(dist) < mod.maxdist )
  485. {
  486. MegaCloseFace cf = new MegaCloseFace();
  487. cf.dist = Mathf.Abs(dist);
  488. cf.face = tris[t].t;
  489. bool inserted = false;
  490. for ( int k = 0; k < closefaces.Count; k++ )
  491. {
  492. if ( cf.dist < closefaces[k].dist )
  493. {
  494. closefaces.Insert(k, cf);
  495. inserted = true;
  496. break;
  497. }
  498. }
  499. if ( !inserted )
  500. closefaces.Add(cf);
  501. }
  502. }
  503. }
  504. }
  505. }
  506. }
  507. }
  508. }
  509. float tweight = 0.0f;
  510. int maxp = mod.maxpoints;
  511. if ( maxp == 0 )
  512. maxp = closefaces.Count;
  513. for ( int j = 0; j < maxp; j++ )
  514. {
  515. if ( j < closefaces.Count )
  516. {
  517. int t = closefaces[j].face;
  518. p0 = tverts[basefaces[t]];
  519. p1 = tverts[basefaces[t + 1]];
  520. p2 = tverts[basefaces[t + 2]];
  521. Vector3 normal = mod.FaceNormal(p0, p1, p2);
  522. float dist = closefaces[j].dist; //GetDistance(p, p0, p1, p2);
  523. MegaBindInf bi = new MegaBindInf();
  524. bi.dist = mod.GetPlaneDistance(p, p0, p1, p2); //dist;
  525. bi.face = t;
  526. bi.i0 = basefaces[t];
  527. bi.i1 = basefaces[t + 1];
  528. bi.i2 = basefaces[t + 2];
  529. bi.bary = mod.CalcBary(p, p0, p1, p2);
  530. bi.weight = 1.0f / (1.0f + dist);
  531. bi.area = normal.magnitude * 0.5f; //CalcArea(baseverts[basefaces[t]], baseverts[basefaces[t + 1]], baseverts[basefaces[t + 2]]); // Could calc once at start
  532. tweight += bi.weight;
  533. bv.verts.Add(bi);
  534. }
  535. }
  536. if ( mod.maxpoints > 0 && mod.maxpoints < bv.verts.Count )
  537. bv.verts.RemoveRange(mod.maxpoints, bv.verts.Count - mod.maxpoints);
  538. // Only want to calculate skin vertices we use
  539. if ( !mod.sourceIsSkin && mod.targetIsSkin )
  540. {
  541. for ( int fi = 0; fi < bv.verts.Count; fi++ )
  542. {
  543. if ( !mod.neededVerts.Contains(bv.verts[fi].i0) )
  544. mod.neededVerts.Add(bv.verts[fi].i0);
  545. if ( !mod.neededVerts.Contains(bv.verts[fi].i1) )
  546. mod.neededVerts.Add(bv.verts[fi].i1);
  547. if ( !mod.neededVerts.Contains(bv.verts[fi].i2) )
  548. mod.neededVerts.Add(bv.verts[fi].i2);
  549. }
  550. }
  551. if ( tweight == 0.0f )
  552. {
  553. mod.nomapcount++;
  554. break;
  555. }
  556. bv.weight = tweight;
  557. }
  558. }
  559. }