MegaRubber.cs 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. using UnityEngine;
  2. using System.Collections.Generic;
  3. public enum MegaRubberType
  4. {
  5. Custom,
  6. SoftRubber,
  7. HardRubber,
  8. Jelly,
  9. SoftLatex
  10. }
  11. [System.Serializable]
  12. public class VertexRubber
  13. {
  14. public Vector3 pos;
  15. public Vector3 cpos;
  16. public Vector3 force;
  17. public Vector3 acc;
  18. public Vector3 vel;
  19. public int[] indices;
  20. public float weight;
  21. public float stiff;
  22. public VertexRubber(Vector3 v_target, float w, float s) { pos = v_target; weight = w; stiff = s; }
  23. }
  24. [AddComponentMenu("Modifiers/Rubber")]
  25. public class MegaRubber : MegaModifier
  26. {
  27. public override string ModName() { return "Rubber"; }
  28. public override string GetHelpURL() { return "?page_id=1254"; }
  29. // From other system
  30. public MegaRubberType Presets = MegaRubberType.Custom;
  31. public MegaWeightChannel channel = MegaWeightChannel.Red;
  32. public MegaWeightChannel stiffchannel = MegaWeightChannel.None;
  33. public Vector3 Intensity = Vector3.one;
  34. public float gravity = 0.0f;
  35. public float mass = 1.0f;
  36. public Vector3 stiffness = new Vector3(0.2f, 0.2f, 0.2f);
  37. public Vector3 damping = new Vector3(0.7f, 0.7f, 0.7f);
  38. public float threshold = 0.0f;
  39. public float size = 0.001f;
  40. public bool showweights = true;
  41. float oomass;
  42. float grav;
  43. bool defined = false;
  44. public VertexRubber[] vr;
  45. int[] notmoved;
  46. public Transform target;
  47. [ContextMenu("Reset Physics")]
  48. public void ResetPhysics()
  49. {
  50. MegaModifiers mod = GetComponent<MegaModifiers>();
  51. if ( mod )
  52. Init(mod);
  53. }
  54. int[] FindVerts(Vector3[] vts, Vector3 p)
  55. {
  56. List<int> indices = new List<int>();
  57. for ( int i = 0; i < vts.Length; i++ )
  58. {
  59. if ( p.x == vts[i].x && p.y == vts[i].y && p.z == vts[i].z )
  60. indices.Add(i);
  61. }
  62. return indices.ToArray();
  63. }
  64. bool HavePoint(Vector3[] vts, List<int> points, Vector3 p)
  65. {
  66. for ( int i = 0; i < points.Count; i++ )
  67. {
  68. if ( p.x == vts[points[i]].x && p.y == vts[points[i]].y && p.z == vts[points[i]].z )
  69. return true;
  70. }
  71. return false;
  72. }
  73. void Init(MegaModifiers mod)
  74. {
  75. if ( mod.verts == null )
  76. return;
  77. List<int> noweights = new List<int>();
  78. List<int> ActiveVertex = new List<int>();
  79. int wc = (int)channel;
  80. for ( int i = 0; i < mod.verts.Length; i++ )
  81. {
  82. // Dont add if we have already
  83. if ( channel == MegaWeightChannel.None || mod.cols == null || mod.cols.Length == 0 )
  84. {
  85. //if ( !HavePoint(mod.verts, ActiveVertex, mod.verts[i]) )
  86. //ActiveVertex.Add(i);
  87. }
  88. else
  89. {
  90. if ( mod.cols[i][wc] > threshold )
  91. {
  92. if ( !HavePoint(mod.verts, ActiveVertex, mod.verts[i]) )
  93. ActiveVertex.Add(i);
  94. }
  95. else
  96. noweights.Add(i);
  97. }
  98. }
  99. notmoved = noweights.ToArray();
  100. if ( ActiveVertex.Count > 0 )
  101. {
  102. vr = new VertexRubber[ActiveVertex.Count];
  103. for ( int i = 0; i < ActiveVertex.Count; i++ )
  104. {
  105. int ref_index = (int)ActiveVertex[i];
  106. float stiff = 1.0f;
  107. if ( stiffchannel != MegaWeightChannel.None && mod.cols != null && mod.cols.Length > 0 )
  108. {
  109. stiff = mod.cols[ref_index][(int)stiffchannel];
  110. }
  111. float intens = (mod.cols[ref_index][wc] - threshold) / (1.0f - threshold);
  112. vr[i] = new VertexRubber(transform.TransformPoint(mod.verts[ref_index]), intens, stiff);
  113. vr[i].indices = FindVerts(mod.verts, mod.verts[ref_index]);
  114. }
  115. }
  116. else
  117. vr = null;
  118. defined = true;
  119. }
  120. public override bool ModLateUpdate(MegaModContext mc)
  121. {
  122. if ( weightsChanged )
  123. {
  124. ResetPhysics();
  125. weightsChanged = false;
  126. }
  127. return Prepare(mc);
  128. }
  129. public override bool Prepare(MegaModContext mc)
  130. {
  131. if ( target )
  132. {
  133. tm = target.worldToLocalMatrix * transform.localToWorldMatrix;
  134. invtm = tm.inverse; //target.worldToLocalMatrix;
  135. }
  136. else
  137. {
  138. tm = transform.localToWorldMatrix;
  139. invtm = transform.worldToLocalMatrix;
  140. }
  141. oomass = 1.0f / mass;
  142. grav = gravity * 0.1f;
  143. if ( !defined )
  144. Init(mc.mod);
  145. if ( vr != null )
  146. return true;
  147. return false;
  148. }
  149. public override void Modify(MegaModifiers mc)
  150. {
  151. UpdateVerts(0, vr.Length);
  152. for ( int i = 0; i < notmoved.Length; i++ )
  153. sverts[notmoved[i]] = verts[notmoved[i]];
  154. }
  155. public void SetTarget(Transform target)
  156. {
  157. if ( target )
  158. {
  159. tm = target.worldToLocalMatrix * transform.localToWorldMatrix;
  160. invtm = tm.inverse; //target.worldToLocalMatrix;
  161. }
  162. else
  163. {
  164. tm = transform.localToWorldMatrix;
  165. invtm = transform.worldToLocalMatrix;
  166. }
  167. InitVerts(0, vr.Length);
  168. }
  169. void InitVerts(int start, int end)
  170. {
  171. for ( int i = start; i < end; i++ )
  172. {
  173. int ix = vr[i].indices[0];
  174. Vector3 vp = verts[ix];
  175. Vector3 v3_target = tm.MultiplyPoint(vp);
  176. VertexRubber v = vr[i];
  177. v.vel = Vector3.zero;
  178. v.pos = v3_target;
  179. }
  180. }
  181. void UpdateVerts(int start, int end)
  182. {
  183. Vector3 p = Vector3.zero;
  184. for ( int i = start; i < end; i++ )
  185. {
  186. int ix = vr[i].indices[0];
  187. Vector3 vp = verts[ix];
  188. Vector3 v3_target = tm.MultiplyPoint(vp);
  189. VertexRubber v = vr[i];
  190. v.force.x = (v3_target.x - v.pos.x) * stiffness.x * v.stiff;
  191. v.acc.x = v.force.x * oomass;
  192. v.vel.x = damping.x * (v.vel.x + v.acc.x);
  193. v.pos.x += v.vel.x; // * t;
  194. v.force.y = (v3_target.y - v.pos.y) * stiffness.y * v.stiff;
  195. v.force.y -= grav;
  196. v.acc.y = v.force.y * oomass;
  197. v.vel.y = damping.y * (v.vel.y + v.acc.y);
  198. v.pos.y += v.vel.y; // * t;
  199. v.force.z = (v3_target.z - v.pos.z) * stiffness.z * v.stiff;
  200. v.acc.z = v.force.z * oomass;
  201. v.vel.z = damping.z * (v.vel.z + v.acc.z);
  202. v.pos.z += v.vel.z; // * t;
  203. v3_target = invtm.MultiplyPoint(vr[i].pos);
  204. p.x = vp.x + ((v3_target.x - vp.x) * v.weight * Intensity.x);
  205. p.y = vp.y + ((v3_target.y - vp.y) * v.weight * Intensity.y);
  206. p.z = vp.z + ((v3_target.z - vp.z) * v.weight * Intensity.z);
  207. v.cpos = p;
  208. for ( int v1 = 0; v1 < vr[i].indices.Length; v1++ )
  209. {
  210. int ix1 = vr[i].indices[v1];
  211. sverts[ix1] = p;
  212. }
  213. }
  214. }
  215. public void ChangeMaterial()
  216. {
  217. switch ( Presets )
  218. {
  219. case MegaRubberType.HardRubber:
  220. gravity = 0.0f;
  221. mass = 8.0f;
  222. stiffness = new Vector3(0.5f, 0.5f, 0.5f);
  223. damping = new Vector3(0.9f, 0.9f, 0.9f);
  224. Intensity = new Vector3(0.5f, 0.5f, 0.5f);
  225. break;
  226. case MegaRubberType.Jelly:
  227. gravity = 0.0f;
  228. mass = 1.0f;
  229. stiffness = new Vector3(0.95f, 0.95f, 0.95f);
  230. damping = new Vector3(0.95f, 0.95f, 0.95f);
  231. Intensity = Vector3.one;
  232. break;
  233. case MegaRubberType.SoftRubber:
  234. gravity = 0.0f;
  235. mass = 2.0f;
  236. stiffness = new Vector3(0.5f, 0.5f, 0.5f);
  237. damping = new Vector3(0.85f, 0.85f, 0.85f);
  238. Intensity = Vector3.one;
  239. break;
  240. case MegaRubberType.SoftLatex:
  241. gravity = 1.0f;
  242. mass = 0.9f;
  243. stiffness = new Vector3(0.3f, 0.3f, 0.3f);
  244. damping = new Vector3(0.25f, 0.25f, 0.25f);
  245. Intensity = Vector3.one;
  246. break;
  247. }
  248. }
  249. public void ChangeChannel()
  250. {
  251. MegaModifiers mod = GetComponent<MegaModifiers>();
  252. if ( mod )
  253. Init(mod);
  254. }
  255. // Threaded
  256. public override void DoWork(MegaModifiers mc, int index, int start, int end, int cores)
  257. {
  258. ModifyCompressedMT(mc, index, cores);
  259. }
  260. public void ModifyCompressedMT(MegaModifiers mc, int tindex, int cores)
  261. {
  262. int step = notmoved.Length / cores;
  263. int startvert = (tindex * step);
  264. int endvert = startvert + step;
  265. if ( tindex == cores - 1 )
  266. endvert = notmoved.Length;
  267. if ( notmoved != null )
  268. {
  269. for ( int i = startvert; i < endvert; i++ )
  270. {
  271. int index = notmoved[i];
  272. sverts[index] = verts[index];
  273. }
  274. }
  275. step = vr.Length / cores;
  276. startvert = (tindex * step);
  277. endvert = startvert + step;
  278. if ( tindex == cores - 1 )
  279. endvert = vr.Length;
  280. UpdateVerts(startvert, endvert);
  281. }
  282. bool weightsChanged = false;
  283. MegaModifiers mods = null;
  284. MegaModifiers GetMod()
  285. {
  286. if ( mods == null )
  287. mods = GetComponent<MegaModifiers>();
  288. return mods;
  289. }
  290. public void UpdateCols(int first, Color[] newcols)
  291. {
  292. GetMod();
  293. if ( mods )
  294. mods.UpdateCols(first, newcols);
  295. weightsChanged = true;
  296. }
  297. public void UpdateCol(int i, Color col)
  298. {
  299. GetMod();
  300. if ( mods )
  301. mods.UpdateCol(i, col);
  302. weightsChanged = true;
  303. }
  304. public void UpdateCols(Color[] newcols)
  305. {
  306. GetMod();
  307. if ( mods )
  308. mods.UpdateCols(newcols);
  309. weightsChanged = true;
  310. }
  311. }