MegaWrapEditor.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  1. using UnityEngine;
  2. using UnityEditor;
  3. using System.Collections.Generic;
  4. [CanEditMultipleObjects, CustomEditor(typeof(MegaWrap))]
  5. public class MegaWrapEditor : Editor
  6. {
  7. public override void OnInspectorGUI()
  8. {
  9. MegaWrap mod = (MegaWrap)target;
  10. #if !UNITY_5 && !UNITY_2017 && !UNITY_2018 && !UNITY_2019 && !UNITY_2020
  11. EditorGUIUtility.LookLikeControls();
  12. #endif
  13. mod.WrapEnabled = EditorGUILayout.Toggle("Enabled", mod.WrapEnabled);
  14. mod.target = (MegaModifyObject)EditorGUILayout.ObjectField("Target", mod.target, typeof(MegaModifyObject), true);
  15. float max = 1.0f;
  16. if ( mod.target )
  17. max = mod.target.bbox.size.magnitude;
  18. mod.maxdist = EditorGUILayout.Slider("Max Dist", mod.maxdist, 0.0f, max); //2.0f); //mod.maxdist);
  19. if ( mod.maxdist < 0.0f )
  20. mod.maxdist = 0.0f;
  21. mod.maxpoints = EditorGUILayout.IntField("Max Points", mod.maxpoints); //mod.maxdist);
  22. if ( mod.maxpoints < 1 )
  23. mod.maxpoints = 1;
  24. Color col = GUI.backgroundColor;
  25. EditorGUILayout.BeginHorizontal();
  26. if ( mod.bindverts == null )
  27. {
  28. GUI.backgroundColor = Color.red;
  29. if ( GUILayout.Button("Map") )
  30. Attach(mod.target);
  31. }
  32. else
  33. {
  34. GUI.backgroundColor = Color.green;
  35. if ( GUILayout.Button("ReMap") )
  36. Attach(mod.target);
  37. }
  38. GUI.backgroundColor = col;
  39. if ( GUILayout.Button("Reset") )
  40. mod.ResetMesh();
  41. EditorGUILayout.EndHorizontal();
  42. if ( GUI.changed )
  43. EditorUtility.SetDirty(mod);
  44. mod.gap = EditorGUILayout.FloatField("Gap", mod.gap);
  45. mod.shrink = EditorGUILayout.Slider("Shrink", mod.shrink, 0.0f, 1.0f);
  46. mod.size = EditorGUILayout.Slider("Size", mod.size, 0.001f, 0.04f);
  47. if ( mod.bindverts != null )
  48. mod.vertindex = EditorGUILayout.IntSlider("Vert Index", mod.vertindex, 0, mod.bindverts.Length - 1);
  49. mod.offset = EditorGUILayout.Vector3Field("Offset", mod.offset);
  50. mod.NormalMethod = (MegaNormalMethod)EditorGUILayout.EnumPopup("Normal Method", mod.NormalMethod);
  51. #if UNITY_5 || UNITY_2017 || UNITY_2018 || UNITY_2019 || UNITY_2020
  52. mod.UseBakedMesh = EditorGUILayout.Toggle("Use Baked Mesh", mod.UseBakedMesh);
  53. #endif
  54. if ( mod.bindverts == null || mod.target == null )
  55. EditorGUILayout.LabelField("Object not wrapped");
  56. else
  57. EditorGUILayout.LabelField("UnMapped", mod.nomapcount.ToString());
  58. if ( GUI.changed )
  59. EditorUtility.SetDirty(mod);
  60. }
  61. public void OnSceneGUI()
  62. {
  63. DisplayDebug();
  64. }
  65. void DisplayDebug()
  66. {
  67. MegaWrap mod = (MegaWrap)target;
  68. if ( mod.target )
  69. {
  70. if ( mod.bindverts != null && mod.bindverts.Length > 0 )
  71. {
  72. if ( mod.targetIsSkin && !mod.sourceIsSkin )
  73. {
  74. Color col = Color.black;
  75. Handles.matrix = Matrix4x4.identity;
  76. MegaBindVert bv = mod.bindverts[mod.vertindex];
  77. for ( int i = 0; i < bv.verts.Count; i++ )
  78. {
  79. MegaBindInf bi = bv.verts[i];
  80. float w = bv.verts[i].weight / bv.weight;
  81. if ( w > 0.5f )
  82. col = Color.Lerp(Color.green, Color.red, (w - 0.5f) * 2.0f);
  83. else
  84. col = Color.Lerp(Color.blue, Color.green, w * 2.0f);
  85. Handles.color = col;
  86. 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);
  87. MegaHandles.DotCap(i, p, Quaternion.identity, mod.size); //0.01f);
  88. Vector3 p0 = mod.skinnedVerts[bi.i0];
  89. Vector3 p1 = mod.skinnedVerts[bi.i1];
  90. Vector3 p2 = mod.skinnedVerts[bi.i2];
  91. Vector3 cp = mod.GetCoordMine(p0, p1, p2, bi.bary);
  92. Handles.color = Color.gray;
  93. Handles.DrawLine(p, cp);
  94. Vector3 norm = mod.FaceNormal(p0, p1, p2);
  95. Vector3 cp1 = cp + (((bi.dist * mod.shrink) + mod.gap) * norm.normalized);
  96. Handles.color = Color.green;
  97. Handles.DrawLine(cp, cp1);
  98. }
  99. }
  100. else
  101. {
  102. Color col = Color.black;
  103. Matrix4x4 tm = mod.target.transform.localToWorldMatrix;
  104. Handles.matrix = tm; //Matrix4x4.identity;
  105. MegaBindVert bv = mod.bindverts[mod.vertindex];
  106. for ( int i = 0; i < bv.verts.Count; i++ )
  107. {
  108. MegaBindInf bi = bv.verts[i];
  109. float w = bv.verts[i].weight / bv.weight;
  110. if ( w > 0.5f )
  111. col = Color.Lerp(Color.green, Color.red, (w - 0.5f) * 2.0f);
  112. else
  113. col = Color.Lerp(Color.blue, Color.green, w * 2.0f);
  114. Handles.color = col;
  115. 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);
  116. MegaHandles.DotCap(i, p, Quaternion.identity, mod.size); //0.01f);
  117. Vector3 p0 = mod.target.sverts[bi.i0];
  118. Vector3 p1 = mod.target.sverts[bi.i1];
  119. Vector3 p2 = mod.target.sverts[bi.i2];
  120. Vector3 cp = mod.GetCoordMine(p0, p1, p2, bi.bary);
  121. Handles.color = Color.gray;
  122. Handles.DrawLine(p, cp);
  123. Vector3 norm = mod.FaceNormal(p0, p1, p2);
  124. Vector3 cp1 = cp + (((bi.dist * mod.shrink) + mod.gap) * norm.normalized);
  125. Handles.color = Color.green;
  126. Handles.DrawLine(cp, cp1);
  127. }
  128. }
  129. // Show unmapped verts
  130. Handles.color = Color.yellow;
  131. for ( int i = 0; i < mod.bindverts.Length; i++ )
  132. {
  133. if ( mod.bindverts[i].weight == 0.0f )
  134. {
  135. Vector3 pv1 = mod.freeverts[i];
  136. MegaHandles.DotCap(0, pv1, Quaternion.identity, mod.size); //0.01f);
  137. }
  138. }
  139. }
  140. if ( mod.verts != null && mod.verts.Length > mod.vertindex )
  141. {
  142. Handles.color = Color.red;
  143. Handles.matrix = mod.transform.localToWorldMatrix;
  144. Vector3 pv = mod.verts[mod.vertindex];
  145. MegaHandles.DotCap(0, pv, Quaternion.identity, mod.size); //0.01f);
  146. }
  147. }
  148. }
  149. void Attach(MegaModifyObject modobj)
  150. {
  151. MegaWrap mod = (MegaWrap)target;
  152. mod.targetIsSkin = false;
  153. mod.sourceIsSkin = false;
  154. if ( mod.mesh && mod.startverts != null )
  155. mod.mesh.vertices = mod.startverts;
  156. if ( modobj == null )
  157. {
  158. mod.bindverts = null;
  159. return;
  160. }
  161. mod.nomapcount = 0;
  162. if ( mod.mesh )
  163. mod.mesh.vertices = mod.startverts;
  164. MeshFilter mf = mod.GetComponent<MeshFilter>();
  165. Mesh srcmesh = null;
  166. if ( mf != null )
  167. {
  168. //skinned = false;
  169. srcmesh = mf.sharedMesh;
  170. }
  171. else
  172. {
  173. SkinnedMeshRenderer smesh = (SkinnedMeshRenderer)mod.GetComponent(typeof(SkinnedMeshRenderer));
  174. if ( smesh != null )
  175. {
  176. //skinned = true;
  177. srcmesh = smesh.sharedMesh;
  178. mod.sourceIsSkin = true;
  179. }
  180. }
  181. if ( srcmesh == null )
  182. {
  183. Debug.LogWarning("No Mesh found on the target object, make sure target has a mesh and MegaFiers modifier attached!");
  184. return;
  185. }
  186. if ( mod.mesh == null )
  187. mod.mesh = mod.CloneMesh(srcmesh); //mf.mesh);
  188. if ( mf )
  189. mf.mesh = mod.mesh;
  190. else
  191. {
  192. SkinnedMeshRenderer smesh = (SkinnedMeshRenderer)mod.GetComponent(typeof(SkinnedMeshRenderer));
  193. smesh.sharedMesh = mod.mesh;
  194. }
  195. if ( mod.sourceIsSkin == false )
  196. {
  197. SkinnedMeshRenderer tmesh = (SkinnedMeshRenderer)modobj.GetComponent(typeof(SkinnedMeshRenderer));
  198. if ( tmesh != null )
  199. {
  200. mod.targetIsSkin = true;
  201. if ( !mod.sourceIsSkin )
  202. {
  203. Mesh sm = tmesh.sharedMesh;
  204. mod.bindposes = sm.bindposes;
  205. mod.boneweights = sm.boneWeights;
  206. mod.bones = tmesh.bones;
  207. mod.skinnedVerts = sm.vertices; //new Vector3[sm.vertexCount];
  208. }
  209. }
  210. }
  211. if ( mod.targetIsSkin )
  212. {
  213. if ( mod.boneweights == null || mod.boneweights.Length == 0 )
  214. mod.targetIsSkin = false;
  215. }
  216. mod.neededVerts.Clear();
  217. mod.verts = mod.mesh.vertices;
  218. mod.startverts = mod.mesh.vertices;
  219. mod.freeverts = new Vector3[mod.startverts.Length];
  220. Vector3[] baseverts = modobj.verts; //basemesh.vertices;
  221. int[] basefaces = modobj.tris; //basemesh.triangles;
  222. mod.bindverts = new MegaBindVert[mod.verts.Length];
  223. // matrix to get vertex into local space of target
  224. Matrix4x4 tm = mod.transform.localToWorldMatrix * modobj.transform.worldToLocalMatrix;
  225. List<MegaCloseFace> closefaces = new List<MegaCloseFace>();
  226. Vector3 p0 = Vector3.zero;
  227. Vector3 p1 = Vector3.zero;
  228. Vector3 p2 = Vector3.zero;
  229. Vector3[] tverts = new Vector3[mod.target.sverts.Length];
  230. for ( int i = 0; i < tverts.Length; i++ )
  231. {
  232. if ( mod.targetIsSkin && !mod.sourceIsSkin )
  233. tverts[i] = modobj.transform.InverseTransformPoint(mod.GetSkinPos(i));
  234. else
  235. tverts[i] = baseverts[i];
  236. }
  237. EditorUtility.ClearProgressBar();
  238. float unit = 0.0f;
  239. mod.target.mesh.RecalculateBounds();
  240. MegaVoxel.Voxelize(tverts, basefaces, mod.target.mesh.bounds, 16, out unit);
  241. //Vector3 min = mod.target.mesh.bounds.min;
  242. for ( int i = 0; i < mod.verts.Length; i++ )
  243. {
  244. MegaBindVert bv = new MegaBindVert();
  245. mod.bindverts[i] = bv;
  246. Vector3 p = tm.MultiplyPoint(mod.verts[i]);
  247. p = mod.transform.TransformPoint(mod.verts[i]);
  248. p = modobj.transform.InverseTransformPoint(p);
  249. mod.freeverts[i] = p;
  250. closefaces.Clear();
  251. int gx = 0;
  252. int gy = 0;
  253. int gz = 0;
  254. MegaVoxel.GetGridIndex(p, out gx, out gy, out gz, unit);
  255. for ( int x = gx - 1; x <= gx + 1; x++ )
  256. {
  257. if ( x >= 0 && x < MegaVoxel.width )
  258. {
  259. for ( int y = gy - 1; y <= gy + 1; y++ )
  260. {
  261. if ( y >= 0 && y < MegaVoxel.height )
  262. {
  263. for ( int z = gz - 1; z <= gz + 1; z++ )
  264. {
  265. if ( z >= 0 && z < MegaVoxel.depth )
  266. {
  267. List<MegaTriangle> tris = MegaVoxel.volume[x, y, z].tris;
  268. for ( int t = 0; t < tris.Count; t++ )
  269. {
  270. float dist = mod.GetDistance(p, tris[t].a, tris[t].b, tris[t].c);
  271. if ( Mathf.Abs(dist) < mod.maxdist )
  272. {
  273. MegaCloseFace cf = new MegaCloseFace();
  274. cf.dist = Mathf.Abs(dist);
  275. cf.face = tris[t].t;
  276. bool inserted = false;
  277. for ( int k = 0; k < closefaces.Count; k++ )
  278. {
  279. if ( cf.dist < closefaces[k].dist )
  280. {
  281. closefaces.Insert(k, cf);
  282. inserted = true;
  283. break;
  284. }
  285. }
  286. if ( !inserted )
  287. closefaces.Add(cf);
  288. }
  289. }
  290. }
  291. }
  292. }
  293. }
  294. }
  295. }
  296. float tweight = 0.0f;
  297. int maxp = mod.maxpoints;
  298. if ( maxp == 0 )
  299. maxp = closefaces.Count;
  300. for ( int j = 0; j < maxp; j++ )
  301. {
  302. if ( j < closefaces.Count )
  303. {
  304. int t = closefaces[j].face;
  305. p0 = tverts[basefaces[t]];
  306. p1 = tverts[basefaces[t + 1]];
  307. p2 = tverts[basefaces[t + 2]];
  308. Vector3 normal = mod.FaceNormal(p0, p1, p2);
  309. float dist = closefaces[j].dist; //GetDistance(p, p0, p1, p2);
  310. MegaBindInf bi = new MegaBindInf();
  311. bi.dist = mod.GetPlaneDistance(p, p0, p1, p2); //dist;
  312. bi.face = t;
  313. bi.i0 = basefaces[t];
  314. bi.i1 = basefaces[t + 1];
  315. bi.i2 = basefaces[t + 2];
  316. bi.bary = mod.CalcBary(p, p0, p1, p2);
  317. bi.weight = 1.0f / (1.0f + dist);
  318. bi.area = normal.magnitude * 0.5f; //CalcArea(baseverts[basefaces[t]], baseverts[basefaces[t + 1]], baseverts[basefaces[t + 2]]); // Could calc once at start
  319. tweight += bi.weight;
  320. bv.verts.Add(bi);
  321. }
  322. }
  323. if ( mod.maxpoints > 0 && mod.maxpoints < bv.verts.Count )
  324. bv.verts.RemoveRange(mod.maxpoints, bv.verts.Count - mod.maxpoints);
  325. // Only want to calculate skin vertices we use
  326. if ( !mod.sourceIsSkin && mod.targetIsSkin )
  327. {
  328. for ( int fi = 0; fi < bv.verts.Count; fi++ )
  329. {
  330. if ( !mod.neededVerts.Contains(bv.verts[fi].i0) )
  331. mod.neededVerts.Add(bv.verts[fi].i0);
  332. if ( !mod.neededVerts.Contains(bv.verts[fi].i1) )
  333. mod.neededVerts.Add(bv.verts[fi].i1);
  334. if ( !mod.neededVerts.Contains(bv.verts[fi].i2) )
  335. mod.neededVerts.Add(bv.verts[fi].i2);
  336. }
  337. }
  338. if ( tweight == 0.0f )
  339. {
  340. mod.nomapcount++;
  341. break;
  342. }
  343. bv.weight = tweight;
  344. }
  345. }
  346. }