DynamicClothBone.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. namespace SpriteViewer
  5. {
  6. public class DynamicClothBone : MonoBehaviour
  7. {
  8. public static float InvSqrtFast(Vector3 f_vSrc)
  9. {
  10. float num = f_vSrc.x * f_vSrc.x + f_vSrc.y * f_vSrc.y + f_vSrc.z * f_vSrc.z;
  11. float num2 = 0.5f * num;
  12. int num3 = (int)num;
  13. num3 = 1597463174 - (num3 >> 1);
  14. num = (float)num3;
  15. num *= 1.5f - num2 * num * num;
  16. return 1f / num;
  17. }
  18. public Vertex[] vertices
  19. {
  20. get
  21. {
  22. return this._vertices;
  23. }
  24. }
  25. public Triangle[] triangles
  26. {
  27. get
  28. {
  29. return this._triangles;
  30. }
  31. }
  32. private void Start()
  33. {
  34. this._gridSize = this.gridSize * this.SimScale;
  35. int num = this._gridSize * this._gridSize;
  36. int num2 = (this._gridSize - 1) * this._gridSize * 2;
  37. num2 += (this._gridSize - 1) * (this._gridSize - 1) * 2;
  38. num2 += (this._gridSize - 2) * this._gridSize * 2;
  39. this._particles = new ClothParticle[num];
  40. this._springs = new ClothSpring[num2];
  41. this.InitMesh();
  42. this.UpdateParameters();
  43. this._Reset();
  44. }
  45. private void UpdateParameters()
  46. {
  47. this._gravity = this.Gravity * (float)this.SimScale;
  48. this._StretchStiffness = this.StretchStiffness * this.clothScale;
  49. this._BendStiffness = 1f * this.clothScale;
  50. this._mass = this.mass * (float)this.SimScale;
  51. }
  52. private void InitMesh()
  53. {
  54. int num = this._gridSize * this._gridSize * 2;
  55. this._triangles = new Triangle[num];
  56. int num2 = this._gridSize * this._gridSize;
  57. this._vertices = new Vertex[num2];
  58. int num3 = 0;
  59. for (int i = 0; i < this._gridSize - 1; i++)
  60. {
  61. for (int j = 0; j < this._gridSize - 1; j++)
  62. {
  63. int c = i * this._gridSize + j;
  64. int num4 = i * this._gridSize + j + 1;
  65. int a = (i + 1) * this._gridSize + j;
  66. int b = (i + 1) * this._gridSize + j + 1;
  67. this._triangles[num3].A = a;
  68. this._triangles[num3].B = num4;
  69. this._triangles[num3].C = c;
  70. num3++;
  71. this._triangles[num3].A = a;
  72. this._triangles[num3].B = b;
  73. this._triangles[num3].C = num4;
  74. num3++;
  75. }
  76. }
  77. for (int k = 0; k < this._gridSize; k++)
  78. {
  79. for (int l = 0; l < this._gridSize; l++)
  80. {
  81. int num5 = k * this._gridSize + l;
  82. this._vertices[num5].uv = new Vector2((float)l / (float)this._gridSize, (float)k / (float)this._gridSize);
  83. }
  84. }
  85. }
  86. public void _Reset()
  87. {
  88. for (int i = 0; i < this._gridSize; i++)
  89. {
  90. for (int j = 0; j < this._gridSize; j++)
  91. {
  92. float num = (float)j / (float)(this._gridSize - 1) - 0.5f;
  93. float num2 = (float)i / (float)(this._gridSize - 1) - 0.5f;
  94. int num3 = i * this._gridSize + j;
  95. this._particles[num3].currentPosition = new Vector3(this.clothScale * num, 8.5f, this.clothScale * num2);
  96. this._particles[num3].currentVelocity = Vector3.zero;
  97. this._particles[num3].defaultLocalPosition = this._particles[num3].currentPosition + base.transform.position;
  98. this._particles[num3].inverseMass = 1f / this._mass;
  99. this._particles[num3].pinned = false;
  100. this._particles[num3].tension = Vector3.zero;
  101. }
  102. }
  103. float magnitude = (this._particles[0].currentPosition - this._particles[1].currentPosition).magnitude;
  104. this._particles[0].pinned = true;
  105. this._particles[this._gridSize - 1].pinned = true;
  106. this._particles[this._gridSize * (this._gridSize - 1)].pinned = true;
  107. this._particles[this._gridSize * this._gridSize - 1].pinned = true;
  108. int num4 = 0;
  109. for (int k = 0; k < this._gridSize; k++)
  110. {
  111. for (int l = 0; l < this._gridSize - 1; l++)
  112. {
  113. this._springs[num4] = new ClothSpring(k * this._gridSize + l, k * this._gridSize + l + 1, magnitude, this._StretchStiffness);
  114. num4++;
  115. }
  116. }
  117. for (int m = 0; m < this._gridSize - 1; m++)
  118. {
  119. for (int n = 0; n < this._gridSize; n++)
  120. {
  121. this._springs[num4] = new ClothSpring(m * this._gridSize + n, (m + 1) * this._gridSize + n, magnitude, this._StretchStiffness);
  122. num4++;
  123. }
  124. }
  125. for (int num5 = 0; num5 < this._gridSize - 1; num5++)
  126. {
  127. for (int num6 = 0; num6 < this._gridSize - 1; num6++)
  128. {
  129. this._springs[num4] = new ClothSpring(num5 * this._gridSize + num6, (num5 + 1) * this._gridSize + num6 + 1, magnitude * (float)Math.Sqrt(2.0), this._BendStiffness);
  130. num4++;
  131. }
  132. }
  133. for (int num7 = 0; num7 < this._gridSize - 1; num7++)
  134. {
  135. for (int num8 = 1; num8 < this._gridSize; num8++)
  136. {
  137. this._springs[num4] = new ClothSpring(num7 * this._gridSize + num8, (num7 + 1) * this._gridSize + num8 - 1, magnitude * (float)Math.Sqrt(2.0), this._BendStiffness);
  138. num4++;
  139. }
  140. }
  141. for (int num9 = 0; num9 < this._gridSize; num9++)
  142. {
  143. for (int num10 = 0; num10 < this._gridSize - 2; num10++)
  144. {
  145. this._springs[num4] = new ClothSpring(num9 * this._gridSize + num10, num9 * this._gridSize + num10 + 2, magnitude * 2f, this._BendStiffness);
  146. num4++;
  147. }
  148. }
  149. for (int num11 = 0; num11 < this._gridSize - 2; num11++)
  150. {
  151. for (int num12 = 0; num12 < this._gridSize; num12++)
  152. {
  153. this._springs[num4] = new ClothSpring(num11 * this._gridSize + num12, (num11 + 2) * this._gridSize + num12, magnitude * 2f, this._BendStiffness);
  154. num4++;
  155. }
  156. }
  157. this.UpdateMesh();
  158. }
  159. private static Vector3 CalculateNormal(Vector3 VA, Vector3 VB, Vector3 VC)
  160. {
  161. Vector3 lhs = VB - VA;
  162. Vector3 rhs = VC - VA;
  163. Vector3 result = Vector3.Cross(lhs, rhs);
  164. result.Normalize();
  165. return result;
  166. }
  167. private void UpdateMesh()
  168. {
  169. for (int i = 0; i < this._triangles.Length; i++)
  170. {
  171. Triangle triangle = this._triangles[i];
  172. Vector3 position = this.vertices[triangle.A].position;
  173. Vector3 position2 = this.vertices[triangle.B].position;
  174. Vector3 position3 = this.vertices[triangle.C].position;
  175. this._triangles[i].normal = DynamicClothBone.CalculateNormal(position, position2, position3);
  176. }
  177. for (int j = 0; j < this._gridSize; j++)
  178. {
  179. for (int k = 0; k < this._gridSize; k++)
  180. {
  181. int num = j * this._gridSize + k;
  182. Vector3 vector = Vector3.zero;
  183. int num2 = 0;
  184. for (int l = 0; l <= 1; l++)
  185. {
  186. for (int m = 0; m <= 1; m++)
  187. {
  188. if (m + k < this._gridSize && l + j < this._gridSize)
  189. {
  190. int num3 = (j + l) * this._gridSize + (k + m) * 2;
  191. vector += this._triangles[num3].normal;
  192. num3++;
  193. vector += this._triangles[num3].normal;
  194. num2 += 2;
  195. }
  196. }
  197. }
  198. vector /= (float)num2;
  199. this._vertices[num].normal = vector;
  200. }
  201. }
  202. for (int n = 0; n < this._gridSize; n++)
  203. {
  204. for (int num4 = 0; num4 < this._gridSize; num4++)
  205. {
  206. int num5 = n * this._gridSize + num4;
  207. this._vertices[num5].position = this._particles[num5].currentPosition;
  208. }
  209. }
  210. }
  211. private void Update()
  212. {
  213. for (int i = 0; i < this._particles.Length; i++)
  214. {
  215. if (this._particles[i].pinned)
  216. {
  217. this._particles[i].currentPosition = base.transform.position + this._particles[i].defaultLocalPosition;
  218. this._particles[i].nextVelocity = Vector3.zero;
  219. }
  220. }
  221. }
  222. private void LateUpdate()
  223. {
  224. float unscaledDeltaTime = Time.unscaledDeltaTime;
  225. if (unscaledDeltaTime <= 0f)
  226. {
  227. return;
  228. }
  229. this._timeSinceLastUpdate += unscaledDeltaTime;
  230. bool flag = false;
  231. float d = this.minimumPhysicsDelta;
  232. while (this._timeSinceLastUpdate > this.minimumPhysicsDelta)
  233. {
  234. this._timeSinceLastUpdate -= this.minimumPhysicsDelta;
  235. flag = true;
  236. for (int i = 0; i < this._springs.Length; i++)
  237. {
  238. Vector3 vector = this._particles[this._springs[i].P1].currentPosition - this._particles[this._springs[i].P2].currentPosition;
  239. float magnitude = vector.magnitude;
  240. float num = magnitude - this._springs[i]._NaturalLength;
  241. float num2 = this._springs[i]._Stiffness * (num * this._springs[i]._InverseLength);
  242. vector *= num2 / magnitude;
  243. ClothParticle[] particles = this._particles;
  244. int p = this._springs[i].P2;
  245. particles[p].tension = particles[p].tension + vector;
  246. ClothParticle[] particles2 = this._particles;
  247. int p2 = this._springs[i].P1;
  248. particles2[p2].tension = particles2[p2].tension - vector;
  249. }
  250. for (int j = 0; j < this._particles.Length; j++)
  251. {
  252. if (this._particles[j].pinned)
  253. {
  254. this._particles[j].nextPosition = this._particles[j].currentPosition;
  255. this._particles[j].nextVelocity = Vector3.zero;
  256. }
  257. else
  258. {
  259. Vector3 vector2 = this._gravity + this._particles[j].tension;
  260. Vector3 a = vector2 * this._particles[j].inverseMass;
  261. this._particles[j].nextVelocity = this._particles[j].currentVelocity + a * d;
  262. ClothParticle[] particles3 = this._particles;
  263. int num3 = j;
  264. particles3[num3].nextVelocity = particles3[num3].nextVelocity * this.dampFactor;
  265. vector2 = this._particles[j].nextVelocity * d;
  266. this._particles[j].nextPosition = this._particles[j].currentPosition + vector2;
  267. for (int k = 0; k < this._colliders.Count; k++)
  268. {
  269. Vector3 a2 = this._particles[j].nextPosition - this._colliders[k].Position;
  270. float num4 = this._colliders[k].Radius * 1.08f;
  271. if (a2.sqrMagnitude < num4 * num4)
  272. {
  273. a2.Normalize();
  274. a2 *= num4;
  275. this._particles[j].nextPosition = a2 + this._colliders[k].Position;
  276. this._particles[j].nextVelocity = Vector3.zero;
  277. break;
  278. }
  279. }
  280. }
  281. }
  282. for (int l = 0; l < this._particles.Length; l++)
  283. {
  284. this._particles[l].currentPosition = this._particles[l].nextPosition;
  285. this._particles[l].currentVelocity = this._particles[l].nextVelocity;
  286. this._particles[l].tension = Vector3.zero;
  287. }
  288. }
  289. if (flag)
  290. {
  291. this.UpdateMesh();
  292. }
  293. }
  294. public void AddCollider(Vector3 position, float radius)
  295. {
  296. ClothCollider item = new ClothCollider(position, radius);
  297. this._colliders.Add(item);
  298. }
  299. public void UnpinParticle(int index)
  300. {
  301. this._particles[index].pinned = false;
  302. }
  303. private void OnValidate()
  304. {
  305. if (Application.isPlaying && this._particles != null && this._springs != null && this._triangles != null)
  306. {
  307. this.UpdateParameters();
  308. this._Reset();
  309. }
  310. }
  311. private void OnDrawGizmosSelected()
  312. {
  313. if (this._particles != null)
  314. {
  315. for (int i = 0; i < this._particles.Length; i++)
  316. {
  317. Gizmos.DrawWireSphere(this._particles[i].currentPosition, 0.01f);
  318. }
  319. }
  320. }
  321. public int SimScale = 1;
  322. public float minimumPhysicsDelta = 0.01f;
  323. public float clothScale = 20f;
  324. public float StretchStiffness = 2.5f;
  325. private float _StretchStiffness;
  326. public float BendStiffness = 1f;
  327. private float _BendStiffness;
  328. public float mass = 0.01f;
  329. private float _mass;
  330. public float dampFactor = 0.9f;
  331. public int gridSize = 13;
  332. private int _gridSize;
  333. private ClothSpring[] _springs;
  334. private ClothParticle[] _particles;
  335. private float _timeSinceLastUpdate;
  336. public Vector3 Gravity = new Vector3(0f, -0.98f, 0f);
  337. private Vector3 _gravity;
  338. private List<ClothCollider> _colliders = new List<ClothCollider>();
  339. private Vertex[] _vertices;
  340. private Triangle[] _triangles;
  341. }
  342. }