MegaModifyGroup.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487
  1. using UnityEngine;
  2. using System;
  3. using System.Collections.Generic;
  4. [System.Serializable]
  5. public class MegaModifierTarget
  6. {
  7. public Vector3[] verts;
  8. public Vector3[] sverts;
  9. public Vector2[] uvs;
  10. public Vector2[] suvs;
  11. public Mesh mesh;
  12. public Mesh cachedMesh;
  13. public Vector4[] tangents;
  14. public Vector3[] tan1;
  15. public Vector3[] tan2;
  16. public MeshCollider meshCol;
  17. public GameObject go;
  18. public MegaBox3 bbox;
  19. public Vector3 Offset;
  20. }
  21. // This should be the only one we need with just a single target for normal use
  22. #if true //false
  23. //[AddComponentMenu("Modifiers/Modify Group")]
  24. [ExecuteInEditMode]
  25. public class MegaModifyGroup : MegaModifyObject
  26. {
  27. public List<MegaModifierTarget> targets = new List<MegaModifierTarget>();
  28. private static int CompareOrder(MegaModifier m1, MegaModifier m2)
  29. {
  30. return m1.Order - m2.Order;
  31. }
  32. [ContextMenu("Resort")]
  33. public override void Resort()
  34. {
  35. BuildList();
  36. }
  37. [ContextMenu("Help")]
  38. public override void Help()
  39. {
  40. Application.OpenURL("http://www.west-racing.com/mf/?page_id=444");
  41. }
  42. // Will need to save start transform as well for reset on any objects that have a transform update
  43. [ContextMenu("Reset Group Info")]
  44. public void GroupResetMeshInfo()
  45. {
  46. //Debug.Log("reset");
  47. for ( int i = 0; i < targets.Count; i++ )
  48. {
  49. //Debug.Log("1");
  50. if ( targets[i].cachedMesh == null )
  51. {
  52. //Debug.Log("2");
  53. targets[i].cachedMesh = (Mesh)Mesh.Instantiate(GetMesh(targets[i].go));
  54. }
  55. }
  56. GroupReStart1(false);
  57. for ( int i = 0; i < targets.Count; i++ )
  58. {
  59. if ( targets[i].mesh != null )
  60. {
  61. targets[i].mesh.vertices = verts; //_verts; // mesh.vertices = GetVerts(true);
  62. targets[i].mesh.uv = uvs; //GetUVs(true);
  63. if ( recalcnorms )
  64. targets[i].mesh.RecalculateNormals();
  65. if ( recalcbounds )
  66. targets[i].mesh.RecalculateBounds();
  67. }
  68. }
  69. }
  70. void ResetOld()
  71. {
  72. for ( int i = 0; i < targets.Count; i++ )
  73. {
  74. if ( targets[i].cachedMesh == null )
  75. targets[i].cachedMesh = (Mesh)Mesh.Instantiate(GetMesh(targets[i].go));
  76. }
  77. BuildList();
  78. GroupReStart1(true);
  79. }
  80. void Update()
  81. {
  82. if ( UpdateMode == MegaUpdateMode.Update )
  83. GroupModify();
  84. }
  85. void LateUpdate()
  86. {
  87. if ( UpdateMode == MegaUpdateMode.LateUpdate )
  88. GroupModify();
  89. }
  90. void SetTarget(MegaModifierTarget target)
  91. {
  92. InitVertSource();
  93. }
  94. // TODO: Gizmo/bounds box is for whole group now
  95. public void GroupModify()
  96. {
  97. //print("groupmod");
  98. if ( Enabled && mods != null )
  99. {
  100. dirtyChannels = MegaModChannel.None;
  101. //if ( GrabVerts )
  102. //{
  103. //if ( sverts.Length < mesh.vertexCount )
  104. //sverts = new Vector3[mesh.vertexCount];
  105. //verts = mesh.vertices;
  106. //}
  107. int um = UpdateMesh;
  108. modContext.mod = this;
  109. foreach ( MegaModifierTarget target in targets )
  110. {
  111. if ( target.go )
  112. {
  113. modContext.Offset = target.Offset;
  114. modContext.bbox = target.bbox;
  115. SetTarget(target);
  116. UpdateMesh = um;
  117. foreach ( MegaModifier mod in mods )
  118. {
  119. if ( mod != null && mod.ModEnabled )
  120. {
  121. if ( (mod.ChannelsReq() & MegaModChannel.Verts) != 0 ) // should be changed
  122. {
  123. Debug.Log("set verts");
  124. mod.verts = GetSourceVerts(target);
  125. mod.sverts = GetDestVerts(target);
  126. }
  127. // Setting up the context basically
  128. mod.Offset = target.Offset;
  129. mod.bbox = target.bbox;
  130. mod.SetTM(mod.Offset);
  131. //if ( mod.ModLateUpdate(this) )
  132. if ( mod.ModLateUpdate(modContext) )
  133. {
  134. //verts = GetSourceVerts(target);
  135. //sverts = GetDestVerts(target);
  136. if ( UpdateMesh < 1 )
  137. {
  138. Debug.Log("a");
  139. mod.Modify(this); //sverts, verts);
  140. UpdateMesh = 1;
  141. }
  142. else
  143. {
  144. //Debug.Log("b");
  145. mod.Modify(this); //sverts, verts);
  146. }
  147. dirtyChannels |= mod.ChannelsChanged();
  148. mod.ModEnd(this);
  149. }
  150. }
  151. }
  152. if ( UpdateMesh == 1 )
  153. {
  154. SetMesh(target, ref target.sverts);
  155. UpdateMesh = 0;
  156. }
  157. else
  158. {
  159. if ( UpdateMesh == 0 )
  160. {
  161. SetMesh(target, ref target.verts);
  162. UpdateMesh = -1; // Dont need to set verts again until a mod is enabled
  163. }
  164. }
  165. }
  166. }
  167. }
  168. }
  169. public void SetMesh(MegaModifierTarget target, ref Vector3[] _verts)
  170. {
  171. if ( (dirtyChannels & MegaModChannel.Verts) != 0 )
  172. target.mesh.vertices = _verts; // mesh.vertices = GetVerts(true);
  173. if ( (dirtyChannels & MegaModChannel.UV) != 0 )
  174. target.mesh.uv = suvs; //GetUVs(true);
  175. if ( recalcnorms )
  176. target.mesh.RecalculateNormals();
  177. if ( recalcTangents )
  178. BuildTangents(target);
  179. if ( recalcbounds )
  180. target.mesh.RecalculateBounds();
  181. if ( recalcCollider )
  182. {
  183. if ( target.meshCol == null )
  184. target.meshCol = GetComponent<MeshCollider>();
  185. if ( target.meshCol != null )
  186. {
  187. target.meshCol.sharedMesh = null;
  188. target.meshCol.sharedMesh = target.mesh;
  189. //bool con = meshCol.convex;
  190. //meshCol.convex = con;
  191. }
  192. }
  193. }
  194. // Plop into modifiertarget class
  195. void BuildTangents(MegaModifierTarget target)
  196. {
  197. if ( uvs == null )
  198. return;
  199. int triangleCount = target.mesh.triangles.Length;
  200. int vertexCount = target.mesh.vertices.Length;
  201. if ( target.tan1 == null || target.tan1.Length != vertexCount )
  202. target.tan1 = new Vector3[vertexCount];
  203. if ( target.tan2 == null || target.tan2.Length != vertexCount )
  204. target.tan2 = new Vector3[vertexCount];
  205. if ( target.tangents == null || target.tangents.Length != vertexCount )
  206. target.tangents = new Vector4[vertexCount];
  207. Vector3[] norms = target.mesh.normals;
  208. int[] tris = target.mesh.triangles;
  209. for ( int a = 0; a < triangleCount; a += 3 )
  210. {
  211. long i1 = tris[a];
  212. long i2 = tris[a + 1];
  213. long i3 = tris[a + 2];
  214. Vector3 v1 = verts[i1];
  215. Vector3 v2 = verts[i2];
  216. Vector3 v3 = verts[i3];
  217. Vector2 w1 = uvs[i1];
  218. Vector2 w2 = uvs[i2];
  219. Vector2 w3 = uvs[i3];
  220. float x1 = v2.x - v1.x;
  221. float x2 = v3.x - v1.x;
  222. float y1 = v2.y - v1.y;
  223. float y2 = v3.y - v1.y;
  224. float z1 = v2.z - v1.z;
  225. float z2 = v3.z - v1.z;
  226. float s1 = w2.x - w1.x;
  227. float s2 = w3.x - w1.x;
  228. float t1 = w2.y - w1.y;
  229. float t2 = w3.y - w1.y;
  230. float r = 1.0f / (s1 * t2 - s2 * t1);
  231. Vector3 sdir = new Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r);
  232. Vector3 tdir = new Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r);
  233. target.tan1[i1] += sdir;
  234. target.tan1[i2] += sdir;
  235. target.tan1[i3] += sdir;
  236. target.tan2[i1] += tdir;
  237. target.tan2[i2] += tdir;
  238. target.tan2[i3] += tdir;
  239. }
  240. for ( int a = 0; a < vertexCount; a++ )
  241. {
  242. Vector3 n = norms[a];
  243. Vector3 t = target.tan1[a];
  244. Vector3.OrthoNormalize(ref n, ref t);
  245. target.tangents[a].x = t.x;
  246. target.tangents[a].y = t.y;
  247. target.tangents[a].z = t.z;
  248. target.tangents[a].w = (Vector3.Dot(Vector3.Cross(n, t), target.tan2[a]) < 0.0f) ? -1.0f : 1.0f;
  249. }
  250. target.mesh.tangents = target.tangents;
  251. }
  252. Mesh GetMesh(GameObject go)
  253. {
  254. if ( go )
  255. {
  256. MeshFilter filter = (MeshFilter)go.GetComponentInChildren<MeshFilter>();
  257. if ( filter != null )
  258. return filter.sharedMesh;
  259. SkinnedMeshRenderer skin = (SkinnedMeshRenderer)go.GetComponentInChildren<SkinnedMeshRenderer>();
  260. if ( skin != null )
  261. return skin.sharedMesh;
  262. }
  263. return null;
  264. }
  265. Mesh GetMesh1(GameObject go)
  266. {
  267. if ( go )
  268. {
  269. MeshFilter filter = (MeshFilter)go.GetComponentInChildren<MeshFilter>();
  270. if ( filter != null )
  271. return filter.mesh;
  272. SkinnedMeshRenderer skin = (SkinnedMeshRenderer)go.GetComponentInChildren<SkinnedMeshRenderer>();
  273. if ( skin != null )
  274. return skin.sharedMesh;
  275. }
  276. return null;
  277. }
  278. public void GroupReStart1(bool force)
  279. {
  280. for ( int i = 0; i < targets.Count; i++ )
  281. {
  282. if ( force || targets[i].mesh == null )
  283. targets[i].mesh = GetMesh1(targets[i].go);
  284. // Do we use mesh anymore
  285. if ( targets[i].mesh != null ) // was mesh
  286. {
  287. bbox = targets[i].cachedMesh.bounds; // Need to expand box
  288. targets[i].sverts = new Vector3[targets[i].cachedMesh.vertexCount];
  289. targets[i].verts = targets[i].cachedMesh.vertices;
  290. targets[i].uvs = targets[i].cachedMesh.uv;
  291. targets[i].suvs = new Vector2[targets[i].cachedMesh.uv.Length];
  292. }
  293. }
  294. // common to modobj
  295. mods = GetComponents<MegaModifier>();
  296. Array.Sort(mods, CompareOrder);
  297. foreach ( MegaModifier mod in mods )
  298. {
  299. if ( mod != null )
  300. {
  301. mod.ModStart(this); // Some mods like push error if we dont do this, put in error check and disable
  302. }
  303. }
  304. UpdateMesh = -1;
  305. }
  306. // We may need to recalc bound box every frame
  307. // Need add and remove targets
  308. public void AddTarget(GameObject go)
  309. {
  310. }
  311. public void RemoveTarget(GameObject go)
  312. {
  313. }
  314. // Need to put bbox into modcontext not use modifier one
  315. void Start()
  316. {
  317. Transform[] objs = (Transform[])gameObject.GetComponentsInChildren<Transform>(true);
  318. targets = new List<MegaModifierTarget>(objs.Length);
  319. for ( int i = 0; i < objs.Length; i++ )
  320. {
  321. MegaModifierTarget target = new MegaModifierTarget();
  322. target.go = objs[i].gameObject;
  323. Mesh ms = GetMesh(target.go);
  324. if ( ms != null )
  325. {
  326. target.cachedMesh = (Mesh)Mesh.Instantiate(ms);
  327. }
  328. targets.Add(target);
  329. }
  330. GroupReStart1(false);
  331. }
  332. [ContextMenu("Recalc Bounds")]
  333. public void TestBounds()
  334. {
  335. for ( int i = 0; i < mods.Length; i++ )
  336. {
  337. GroupModReset(mods[i]);
  338. }
  339. }
  340. // Needs to be an override for ModReset
  341. public void GroupModReset(MegaModifier m)
  342. {
  343. if ( m != null )
  344. {
  345. int i;
  346. for ( i = 0; i < targets.Count; i++ )
  347. {
  348. GameObject targ = targets[i].go;
  349. Bounds b = new Bounds();
  350. Mesh cm = targets[i].cachedMesh;
  351. if ( cm != null )
  352. b = cm.bounds;
  353. for ( int t = 0; t < targets.Count; t++ )
  354. {
  355. Mesh ms = targets[t].cachedMesh;
  356. if ( t != i && ms != null )
  357. {
  358. Vector3 pos = targets[t].go.transform.position;
  359. pos = targ.transform.InverseTransformPoint(pos);
  360. Bounds mb = new Bounds(pos, targets[t].cachedMesh.bounds.size);
  361. b.Encapsulate(mb);
  362. }
  363. }
  364. targets[i].bbox.min = b.min;
  365. targets[i].bbox.max = b.max;
  366. targets[i].Offset = -b.center;
  367. }
  368. }
  369. }
  370. void OnDrawGizmosSelected()
  371. {
  372. modContext.mod = this;
  373. if ( GlobalDisplay && DrawGizmos && Enabled )
  374. {
  375. foreach ( MegaModifierTarget target in targets )
  376. {
  377. modContext.Offset = target.Offset;
  378. modContext.bbox = target.bbox;
  379. modContext.go = target.go;
  380. foreach ( MegaModifier mod in mods )
  381. {
  382. if ( mod != null )
  383. {
  384. if ( mod.ModEnabled && mod.DisplayGizmo )
  385. mod.DrawGizmo(modContext);
  386. }
  387. }
  388. }
  389. }
  390. }
  391. }
  392. #endif