MegaModifier.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. using UnityEngine;
  2. public enum MegaWeightChannel
  3. {
  4. Red,
  5. Green,
  6. Blue,
  7. Alpha,
  8. None,
  9. }
  10. public enum MegaModChannel
  11. {
  12. None = 0,
  13. Verts = 1,
  14. UV = 2,
  15. UV1 = 4,
  16. UV2 = 8,
  17. Normals = 16,
  18. Tris = 32,
  19. Col = 64,
  20. Selection = 128,
  21. All = 32767,
  22. }
  23. [RequireComponent(typeof(MegaModifyObject))]
  24. public class MegaModifier : MonoBehaviour
  25. {
  26. [HideInInspector]
  27. public bool ModEnabled = true;
  28. [HideInInspector]
  29. public bool DisplayGizmo = true;
  30. [HideInInspector]
  31. public int Order = -1;
  32. [HideInInspector]
  33. public Vector3 Offset = Vector3.zero;
  34. [HideInInspector]
  35. public Vector3 gizmoPos = Vector3.zero;
  36. [HideInInspector]
  37. public Vector3 gizmoRot = Vector3.zero;
  38. [HideInInspector]
  39. public Vector3 gizmoScale = Vector3.one;
  40. [HideInInspector]
  41. public Color gizCol1 = Color.yellow;
  42. [HideInInspector]
  43. public Color gizCol2 = Color.green;
  44. [HideInInspector]
  45. [System.NonSerialized]
  46. public Matrix4x4 tm = new Matrix4x4();
  47. [System.NonSerialized]
  48. public Matrix4x4 invtm = new Matrix4x4();
  49. [HideInInspector]
  50. public MegaBox3 bbox = new MegaBox3();
  51. [HideInInspector]
  52. public Vector3[] corners = new Vector3[8];
  53. //[HideInInspector]
  54. //public bool useWeights = false;
  55. //[HideInInspector]
  56. //public MegaWeightChannel weightChannel = MegaWeightChannel.Red;
  57. [HideInInspector]
  58. public int steps = 50; // How many steps for the gizmo boxes
  59. // new for mt
  60. [HideInInspector]
  61. public Vector3[] verts;
  62. [HideInInspector]
  63. public Vector3[] sverts;
  64. [HideInInspector]
  65. public bool valid;
  66. [HideInInspector]
  67. public float[] selection;
  68. [HideInInspector]
  69. public MegaModifier instance; // For groups this is the mod to use will be same type
  70. public bool limitchandisplay = false;
  71. public int startchannel = 0;
  72. public int displaychans = 10;
  73. #if UNITY_4_3 || UNITY_4_5 || UNITY_4_6 || UNITY_5_0 || UNITY_5_1 || UNITY_5 || UNITY_2017 || UNITY_2018 || UNITY_2019 || UNITY_2020
  74. public bool useUndo = false;
  75. #else
  76. public bool useUndo = true;
  77. #endif
  78. [HideInInspector]
  79. public string Label = "";
  80. [HideInInspector]
  81. public int MaxLOD = 0;
  82. public virtual MegaModChannel ChannelsReq() { return MegaModChannel.Verts; }
  83. public virtual MegaModChannel ChannelsChanged() { return MegaModChannel.Verts; }
  84. public virtual float GizmoSize() { return bbox.Radius() * 0.05f; }
  85. public virtual void ModStart(MegaModifiers ms) { }
  86. public virtual void ModUpdate() { }
  87. public virtual bool ModLateUpdate(MegaModContext mc) { return true; } // TODO: Do we need mc now?
  88. public virtual Vector3 Map(int i, Vector3 p) { return p; }
  89. public virtual void ShowGUI() { }
  90. public virtual string ModName() { return "Missing Name"; }
  91. public virtual bool InitMod(MegaModifiers mc) { return true; }
  92. public virtual bool Prepare(MegaModContext mc) { return true; }
  93. public virtual void ModEnd(MegaModifiers ms) { }
  94. public virtual string GetHelpURL() { return "?page_id=377"; }
  95. public virtual void PrepareMT(MegaModifiers mc, int cores) { }
  96. public virtual void DoneMT(MegaModifiers mc) {}
  97. public virtual void SetValues(MegaModifier mod) {}
  98. public virtual bool CanThread() { return true; }
  99. // Used for copying and prefabs
  100. public virtual void Copy(MegaModifier dst)
  101. {
  102. dst.Label = Label;
  103. dst.MaxLOD = MaxLOD;
  104. dst.ModEnabled = ModEnabled;
  105. dst.DisplayGizmo = DisplayGizmo;
  106. dst.Order = Order;
  107. dst.Offset = Offset;
  108. dst.gizmoPos = gizmoPos;
  109. dst.gizmoRot = gizmoRot;
  110. dst.gizmoScale = gizmoScale;
  111. dst.gizCol1 = gizCol1;
  112. dst.gizCol2 = gizCol2;
  113. }
  114. public virtual void PostCopy(MegaModifier dst)
  115. {
  116. }
  117. public virtual void DoWork(MegaModifiers mc, int index, int start, int end, int cores)
  118. {
  119. //if ( useWeights )
  120. if ( selection != null )
  121. {
  122. DoWorkWeighted(mc, index, start, end, cores);
  123. return;
  124. }
  125. for ( int i = start; i < end; i++ )
  126. sverts[i] = Map(i, verts[i]);
  127. }
  128. public virtual void DoWorkWeighted(MegaModifiers mc, int index, int start, int end, int cores)
  129. {
  130. for ( int i = start; i < end; i++ )
  131. {
  132. Vector3 p = verts[i];
  133. float w = selection[i]; //[(int)weightChannel];
  134. if ( w > 0.001f )
  135. {
  136. Vector3 mp = Map(i, verts[i]);
  137. sverts[i].x = p.x + (mp.x - p.x) * w;
  138. sverts[i].y = p.y + (mp.y - p.y) * w;
  139. sverts[i].z = p.z + (mp.z - p.z) * w;
  140. }
  141. else
  142. sverts[i] = p; //verts[i];
  143. }
  144. }
  145. // This is never called
  146. void Awake()
  147. {
  148. MegaModifyObject modobj = (MegaModifyObject)gameObject.GetComponent<MegaModifyObject>();
  149. if ( modobj != null )
  150. modobj.ModReset(this);
  151. }
  152. void Reset()
  153. {
  154. MegaModifyObject modobj = (MegaModifyObject)gameObject.GetComponent<MegaModifyObject>();
  155. if ( modobj != null )
  156. modobj.ModReset(this);
  157. }
  158. [ContextMenu("Help")]
  159. public void Help()
  160. {
  161. Application.OpenURL("http://www.west-racing.com/mf/" + GetHelpURL());
  162. }
  163. [ContextMenu("Reset Offset")]
  164. public void ResetOffset()
  165. {
  166. Offset = Vector3.zero;
  167. }
  168. Vector3 GetCentre()
  169. {
  170. MegaModifyObject modobj = (MegaModifyObject)gameObject.GetComponent<MegaModifyObject>();
  171. if ( modobj != null && modobj.cachedMesh != null )
  172. return modobj.cachedMesh.bounds.center;
  173. return Vector3.zero;
  174. }
  175. [ContextMenu("Reset GizmoPos")]
  176. public void ResetGizmoPos()
  177. {
  178. gizmoPos = Vector3.zero;
  179. }
  180. [ContextMenu("Reset GizmoRot")]
  181. public void ResetGizmoRot()
  182. {
  183. gizmoRot = Vector3.zero;
  184. }
  185. [ContextMenu("Reset GizmoScale")]
  186. public void ResetGizmoScale()
  187. {
  188. gizmoScale = Vector3.one;
  189. }
  190. [ContextMenu("Center Offset")]
  191. public void CentreOffset()
  192. {
  193. Offset = -GetCentre();
  194. }
  195. [ContextMenu("Center GizmoPos")]
  196. public void CentreGizmoPos()
  197. {
  198. gizmoPos = -GetCentre();
  199. }
  200. // TODO: This is wrong, Offset should be 0
  201. public void SetModMesh(Mesh ms)
  202. {
  203. if ( ms != null )
  204. {
  205. Bounds b = ms.bounds;
  206. //Offset = -b.center;
  207. bbox.min = b.center - b.extents;
  208. bbox.max = b.center + b.extents;
  209. verts = ms.vertices;
  210. MeshChanged();
  211. }
  212. }
  213. public virtual void MeshChanged()
  214. {
  215. }
  216. public void SetTM()
  217. {
  218. tm = Matrix4x4.identity;
  219. Quaternion rot = Quaternion.Euler(-gizmoRot);
  220. tm.SetTRS(gizmoPos + Offset, rot, gizmoScale);
  221. invtm = tm.inverse;
  222. }
  223. public void SetTM(Vector3 off)
  224. {
  225. tm = Matrix4x4.identity;
  226. Quaternion rot = Quaternion.Euler(-gizmoRot);
  227. tm.SetTRS(gizmoPos + off, rot, gizmoScale);
  228. invtm = tm.inverse;
  229. }
  230. public void SetAxis(Matrix4x4 tmAxis)
  231. {
  232. Matrix4x4 itm = tmAxis.inverse;
  233. tm = tmAxis * tm;
  234. invtm = invtm * itm;
  235. }
  236. public virtual void Modify(ref Vector3[] sverts, ref Vector3[] verts)
  237. {
  238. for ( int i = 0; i < verts.Length; i++ )
  239. sverts[i] = Map(i, verts[i]);
  240. }
  241. public virtual void Modify(Vector3[] sverts, Vector3[] verts)
  242. {
  243. for ( int i = 0; i < verts.Length; i++ )
  244. sverts[i] = Map(i, verts[i]);
  245. }
  246. public virtual void Modify(MegaModifiers mc)
  247. {
  248. if ( verts != null )
  249. {
  250. for ( int i = 0; i < verts.Length; i++ )
  251. sverts[i] = Map(i, verts[i]);
  252. }
  253. }
  254. // Weighted version
  255. // Only be here if weights are being used
  256. public virtual void ModifyWeighted(MegaModifiers mc)
  257. {
  258. for ( int i = 0; i < verts.Length; i++ )
  259. {
  260. Vector3 p = verts[i];
  261. float w = mc.selection[i];
  262. if ( w > 0.001f )
  263. {
  264. Vector3 mp = Map(i, verts[i]);
  265. sverts[i].x = p.x + (mp.x - p.x) * w;
  266. sverts[i].y = p.y + (mp.y - p.y) * w;
  267. sverts[i].z = p.z + (mp.z - p.z) * w;
  268. }
  269. else
  270. sverts[i] = verts[i];
  271. }
  272. }
  273. public void DrawEdge(Vector3 p1, Vector3 p2)
  274. {
  275. Vector3 last = Map(-1, p1);
  276. Vector3 pos = Vector3.zero;
  277. for ( int i = 1; i <= steps; i++ )
  278. {
  279. pos = p1 + ((p2 - p1) * ((float)i / (float)steps));
  280. pos = Map(-1, pos);
  281. if ( (i & 4) == 0 )
  282. Gizmos.color = gizCol1;
  283. else
  284. Gizmos.color = gizCol2;
  285. Gizmos.DrawLine(last, pos);
  286. last = pos;
  287. }
  288. Gizmos.color = gizCol1;
  289. }
  290. public void DrawEdgeCol(Vector3 p1, Vector3 p2)
  291. {
  292. Vector3 last = Map(-1, p1);
  293. Vector3 pos = Vector3.zero;
  294. for ( int i = 1; i <= steps; i++ )
  295. {
  296. pos = p1 + ((p2 - p1) * ((float)i / (float)steps));
  297. pos = Map(-1, pos);
  298. Gizmos.DrawLine(last, pos);
  299. last = pos;
  300. }
  301. }
  302. // TODO: If we draw like warps do we know if we are the current edited script?
  303. public virtual void DrawGizmo(MegaModContext context)
  304. {
  305. tm = Matrix4x4.identity;
  306. MegaMatrix.Translate(ref tm, context.Offset);
  307. invtm = tm.inverse;
  308. if ( !Prepare(context) )
  309. return;
  310. Vector3 min = context.bbox.min;
  311. Vector3 max = context.bbox.max;
  312. Matrix4x4 gtm = Matrix4x4.identity;
  313. Vector3 pos = gizmoPos;
  314. pos.x = -pos.x;
  315. pos.y = -pos.y;
  316. pos.z = -pos.z;
  317. Vector3 scl = gizmoScale;
  318. scl.x = 1.0f - (scl.x - 1.0f);
  319. scl.y = 1.0f - (scl.y - 1.0f);
  320. gtm.SetTRS(pos, Quaternion.Euler(gizmoRot), scl);
  321. // put sourceObj into context
  322. if ( context.mod.sourceObj != null )
  323. Gizmos.matrix = context.mod.sourceObj.transform.localToWorldMatrix * gtm;
  324. else
  325. Gizmos.matrix = context.go.transform.localToWorldMatrix * gtm;
  326. //Gizmos.color = ModCol(); //Color.yellow;
  327. corners[0] = new Vector3(min.x, min.y, min.z);
  328. corners[1] = new Vector3(min.x, max.y, min.z);
  329. corners[2] = new Vector3(max.x, max.y, min.z);
  330. corners[3] = new Vector3(max.x, min.y, min.z);
  331. corners[4] = new Vector3(min.x, min.y, max.z);
  332. corners[5] = new Vector3(min.x, max.y, max.z);
  333. corners[6] = new Vector3(max.x, max.y, max.z);
  334. corners[7] = new Vector3(max.x, min.y, max.z);
  335. DrawEdge(corners[0], corners[1]);
  336. DrawEdge(corners[1], corners[2]);
  337. DrawEdge(corners[2], corners[3]);
  338. DrawEdge(corners[3], corners[0]);
  339. DrawEdge(corners[4], corners[5]);
  340. DrawEdge(corners[5], corners[6]);
  341. DrawEdge(corners[6], corners[7]);
  342. DrawEdge(corners[7], corners[4]);
  343. DrawEdge(corners[0], corners[4]);
  344. DrawEdge(corners[1], corners[5]);
  345. DrawEdge(corners[2], corners[6]);
  346. DrawEdge(corners[3], corners[7]);
  347. ExtraGizmo(context);
  348. }
  349. public virtual void ExtraGizmo(MegaModContext mc)
  350. {
  351. }
  352. public void DrawFromTo(MegaAxis axis, float from, float to, MegaModContext mc)
  353. {
  354. Vector3 min = mc.bbox.min;
  355. Vector3 max = mc.bbox.max;
  356. switch ( axis )
  357. {
  358. case MegaAxis.X:
  359. corners[0] = new Vector3(-from, min.y, min.z);
  360. corners[1] = new Vector3(-from, max.y, min.z);
  361. corners[2] = new Vector3(-from, max.y, max.z);
  362. corners[3] = new Vector3(-from, min.y, max.z);
  363. corners[4] = new Vector3(-to, min.y, min.z);
  364. corners[5] = new Vector3(-to, max.y, min.z);
  365. corners[6] = new Vector3(-to, max.y, max.z);
  366. corners[7] = new Vector3(-to, min.y, max.z);
  367. break;
  368. case MegaAxis.Y:
  369. corners[0] = new Vector3(min.x, min.y, -from);
  370. corners[1] = new Vector3(min.x, max.y, -from);
  371. corners[2] = new Vector3(max.x, max.y, -from);
  372. corners[3] = new Vector3(max.x, min.y, -from);
  373. corners[4] = new Vector3(min.x, min.y, -to);
  374. corners[5] = new Vector3(min.x, max.y, -to);
  375. corners[6] = new Vector3(max.x, max.y, -to);
  376. corners[7] = new Vector3(max.x, min.y, -to);
  377. break;
  378. case MegaAxis.Z:
  379. corners[0] = new Vector3(min.x, from, min.z);
  380. corners[1] = new Vector3(min.x, from, max.z);
  381. corners[2] = new Vector3(max.x, from, max.z);
  382. corners[3] = new Vector3(max.x, from, min.z);
  383. corners[4] = new Vector3(min.x, to, min.z);
  384. corners[5] = new Vector3(min.x, to, max.z);
  385. corners[6] = new Vector3(max.x, to, max.z);
  386. corners[7] = new Vector3(max.x, to, min.z);
  387. break;
  388. }
  389. Color c = Color.red;
  390. c.a = gizCol1.a;
  391. Gizmos.color = c;
  392. Vector3 offset = Vector3.zero; //mc.Offset;
  393. DrawEdgeCol(corners[0] - offset, corners[1] - offset);
  394. DrawEdgeCol(corners[1] - offset, corners[2] - offset);
  395. DrawEdgeCol(corners[2] - offset, corners[3] - offset);
  396. DrawEdgeCol(corners[3] - offset, corners[0] - offset);
  397. c = Color.green;
  398. c.a = gizCol1.a;
  399. Gizmos.color = c;
  400. DrawEdgeCol(corners[4] - offset, corners[5] - offset);
  401. DrawEdgeCol(corners[5] - offset, corners[6] - offset);
  402. DrawEdgeCol(corners[6] - offset, corners[7] - offset);
  403. DrawEdgeCol(corners[7] - offset, corners[4] - offset);
  404. }
  405. void OnDrawGizmosSelected()
  406. {
  407. }
  408. }