123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377 |
- using System;
- using System.Collections.Generic;
- using UnityEngine;
- namespace SpriteViewer
- {
- public class DynamicClothBone : MonoBehaviour
- {
- public static float InvSqrtFast(Vector3 f_vSrc)
- {
- float num = f_vSrc.x * f_vSrc.x + f_vSrc.y * f_vSrc.y + f_vSrc.z * f_vSrc.z;
- float num2 = 0.5f * num;
- int num3 = (int)num;
- num3 = 1597463174 - (num3 >> 1);
- num = (float)num3;
- num *= 1.5f - num2 * num * num;
- return 1f / num;
- }
- public Vertex[] vertices
- {
- get
- {
- return this._vertices;
- }
- }
- public Triangle[] triangles
- {
- get
- {
- return this._triangles;
- }
- }
- private void Start()
- {
- this._gridSize = this.gridSize * this.SimScale;
- int num = this._gridSize * this._gridSize;
- int num2 = (this._gridSize - 1) * this._gridSize * 2;
- num2 += (this._gridSize - 1) * (this._gridSize - 1) * 2;
- num2 += (this._gridSize - 2) * this._gridSize * 2;
- this._particles = new ClothParticle[num];
- this._springs = new ClothSpring[num2];
- this.InitMesh();
- this.UpdateParameters();
- this._Reset();
- }
- private void UpdateParameters()
- {
- this._gravity = this.Gravity * (float)this.SimScale;
- this._StretchStiffness = this.StretchStiffness * this.clothScale;
- this._BendStiffness = 1f * this.clothScale;
- this._mass = this.mass * (float)this.SimScale;
- }
- private void InitMesh()
- {
- int num = this._gridSize * this._gridSize * 2;
- this._triangles = new Triangle[num];
- int num2 = this._gridSize * this._gridSize;
- this._vertices = new Vertex[num2];
- int num3 = 0;
- for (int i = 0; i < this._gridSize - 1; i++)
- {
- for (int j = 0; j < this._gridSize - 1; j++)
- {
- int c = i * this._gridSize + j;
- int num4 = i * this._gridSize + j + 1;
- int a = (i + 1) * this._gridSize + j;
- int b = (i + 1) * this._gridSize + j + 1;
- this._triangles[num3].A = a;
- this._triangles[num3].B = num4;
- this._triangles[num3].C = c;
- num3++;
- this._triangles[num3].A = a;
- this._triangles[num3].B = b;
- this._triangles[num3].C = num4;
- num3++;
- }
- }
- for (int k = 0; k < this._gridSize; k++)
- {
- for (int l = 0; l < this._gridSize; l++)
- {
- int num5 = k * this._gridSize + l;
- this._vertices[num5].uv = new Vector2((float)l / (float)this._gridSize, (float)k / (float)this._gridSize);
- }
- }
- }
- public void _Reset()
- {
- for (int i = 0; i < this._gridSize; i++)
- {
- for (int j = 0; j < this._gridSize; j++)
- {
- float num = (float)j / (float)(this._gridSize - 1) - 0.5f;
- float num2 = (float)i / (float)(this._gridSize - 1) - 0.5f;
- int num3 = i * this._gridSize + j;
- this._particles[num3].currentPosition = new Vector3(this.clothScale * num, 8.5f, this.clothScale * num2);
- this._particles[num3].currentVelocity = Vector3.zero;
- this._particles[num3].defaultLocalPosition = this._particles[num3].currentPosition + base.transform.position;
- this._particles[num3].inverseMass = 1f / this._mass;
- this._particles[num3].pinned = false;
- this._particles[num3].tension = Vector3.zero;
- }
- }
- float magnitude = (this._particles[0].currentPosition - this._particles[1].currentPosition).magnitude;
- this._particles[0].pinned = true;
- this._particles[this._gridSize - 1].pinned = true;
- this._particles[this._gridSize * (this._gridSize - 1)].pinned = true;
- this._particles[this._gridSize * this._gridSize - 1].pinned = true;
- int num4 = 0;
- for (int k = 0; k < this._gridSize; k++)
- {
- for (int l = 0; l < this._gridSize - 1; l++)
- {
- this._springs[num4] = new ClothSpring(k * this._gridSize + l, k * this._gridSize + l + 1, magnitude, this._StretchStiffness);
- num4++;
- }
- }
- for (int m = 0; m < this._gridSize - 1; m++)
- {
- for (int n = 0; n < this._gridSize; n++)
- {
- this._springs[num4] = new ClothSpring(m * this._gridSize + n, (m + 1) * this._gridSize + n, magnitude, this._StretchStiffness);
- num4++;
- }
- }
- for (int num5 = 0; num5 < this._gridSize - 1; num5++)
- {
- for (int num6 = 0; num6 < this._gridSize - 1; num6++)
- {
- this._springs[num4] = new ClothSpring(num5 * this._gridSize + num6, (num5 + 1) * this._gridSize + num6 + 1, magnitude * (float)Math.Sqrt(2.0), this._BendStiffness);
- num4++;
- }
- }
- for (int num7 = 0; num7 < this._gridSize - 1; num7++)
- {
- for (int num8 = 1; num8 < this._gridSize; num8++)
- {
- this._springs[num4] = new ClothSpring(num7 * this._gridSize + num8, (num7 + 1) * this._gridSize + num8 - 1, magnitude * (float)Math.Sqrt(2.0), this._BendStiffness);
- num4++;
- }
- }
- for (int num9 = 0; num9 < this._gridSize; num9++)
- {
- for (int num10 = 0; num10 < this._gridSize - 2; num10++)
- {
- this._springs[num4] = new ClothSpring(num9 * this._gridSize + num10, num9 * this._gridSize + num10 + 2, magnitude * 2f, this._BendStiffness);
- num4++;
- }
- }
- for (int num11 = 0; num11 < this._gridSize - 2; num11++)
- {
- for (int num12 = 0; num12 < this._gridSize; num12++)
- {
- this._springs[num4] = new ClothSpring(num11 * this._gridSize + num12, (num11 + 2) * this._gridSize + num12, magnitude * 2f, this._BendStiffness);
- num4++;
- }
- }
- this.UpdateMesh();
- }
- private static Vector3 CalculateNormal(Vector3 VA, Vector3 VB, Vector3 VC)
- {
- Vector3 lhs = VB - VA;
- Vector3 rhs = VC - VA;
- Vector3 result = Vector3.Cross(lhs, rhs);
- result.Normalize();
- return result;
- }
- private void UpdateMesh()
- {
- for (int i = 0; i < this._triangles.Length; i++)
- {
- Triangle triangle = this._triangles[i];
- Vector3 position = this.vertices[triangle.A].position;
- Vector3 position2 = this.vertices[triangle.B].position;
- Vector3 position3 = this.vertices[triangle.C].position;
- this._triangles[i].normal = DynamicClothBone.CalculateNormal(position, position2, position3);
- }
- for (int j = 0; j < this._gridSize; j++)
- {
- for (int k = 0; k < this._gridSize; k++)
- {
- int num = j * this._gridSize + k;
- Vector3 vector = Vector3.zero;
- int num2 = 0;
- for (int l = 0; l <= 1; l++)
- {
- for (int m = 0; m <= 1; m++)
- {
- if (m + k < this._gridSize && l + j < this._gridSize)
- {
- int num3 = (j + l) * this._gridSize + (k + m) * 2;
- vector += this._triangles[num3].normal;
- num3++;
- vector += this._triangles[num3].normal;
- num2 += 2;
- }
- }
- }
- vector /= (float)num2;
- this._vertices[num].normal = vector;
- }
- }
- for (int n = 0; n < this._gridSize; n++)
- {
- for (int num4 = 0; num4 < this._gridSize; num4++)
- {
- int num5 = n * this._gridSize + num4;
- this._vertices[num5].position = this._particles[num5].currentPosition;
- }
- }
- }
- private void Update()
- {
- for (int i = 0; i < this._particles.Length; i++)
- {
- if (this._particles[i].pinned)
- {
- this._particles[i].currentPosition = base.transform.position + this._particles[i].defaultLocalPosition;
- this._particles[i].nextVelocity = Vector3.zero;
- }
- }
- }
- private void LateUpdate()
- {
- float unscaledDeltaTime = Time.unscaledDeltaTime;
- if (unscaledDeltaTime <= 0f)
- {
- return;
- }
- this._timeSinceLastUpdate += unscaledDeltaTime;
- bool flag = false;
- float d = this.minimumPhysicsDelta;
- while (this._timeSinceLastUpdate > this.minimumPhysicsDelta)
- {
- this._timeSinceLastUpdate -= this.minimumPhysicsDelta;
- flag = true;
- for (int i = 0; i < this._springs.Length; i++)
- {
- Vector3 vector = this._particles[this._springs[i].P1].currentPosition - this._particles[this._springs[i].P2].currentPosition;
- float magnitude = vector.magnitude;
- float num = magnitude - this._springs[i]._NaturalLength;
- float num2 = this._springs[i]._Stiffness * (num * this._springs[i]._InverseLength);
- vector *= num2 / magnitude;
- ClothParticle[] particles = this._particles;
- int p = this._springs[i].P2;
- particles[p].tension = particles[p].tension + vector;
- ClothParticle[] particles2 = this._particles;
- int p2 = this._springs[i].P1;
- particles2[p2].tension = particles2[p2].tension - vector;
- }
- for (int j = 0; j < this._particles.Length; j++)
- {
- if (this._particles[j].pinned)
- {
- this._particles[j].nextPosition = this._particles[j].currentPosition;
- this._particles[j].nextVelocity = Vector3.zero;
- }
- else
- {
- Vector3 vector2 = this._gravity + this._particles[j].tension;
- Vector3 a = vector2 * this._particles[j].inverseMass;
- this._particles[j].nextVelocity = this._particles[j].currentVelocity + a * d;
- ClothParticle[] particles3 = this._particles;
- int num3 = j;
- particles3[num3].nextVelocity = particles3[num3].nextVelocity * this.dampFactor;
- vector2 = this._particles[j].nextVelocity * d;
- this._particles[j].nextPosition = this._particles[j].currentPosition + vector2;
- for (int k = 0; k < this._colliders.Count; k++)
- {
- Vector3 a2 = this._particles[j].nextPosition - this._colliders[k].Position;
- float num4 = this._colliders[k].Radius * 1.08f;
- if (a2.sqrMagnitude < num4 * num4)
- {
- a2.Normalize();
- a2 *= num4;
- this._particles[j].nextPosition = a2 + this._colliders[k].Position;
- this._particles[j].nextVelocity = Vector3.zero;
- break;
- }
- }
- }
- }
- for (int l = 0; l < this._particles.Length; l++)
- {
- this._particles[l].currentPosition = this._particles[l].nextPosition;
- this._particles[l].currentVelocity = this._particles[l].nextVelocity;
- this._particles[l].tension = Vector3.zero;
- }
- }
- if (flag)
- {
- this.UpdateMesh();
- }
- }
- public void AddCollider(Vector3 position, float radius)
- {
- ClothCollider item = new ClothCollider(position, radius);
- this._colliders.Add(item);
- }
- public void UnpinParticle(int index)
- {
- this._particles[index].pinned = false;
- }
- private void OnValidate()
- {
- if (Application.isPlaying && this._particles != null && this._springs != null && this._triangles != null)
- {
- this.UpdateParameters();
- this._Reset();
- }
- }
- private void OnDrawGizmosSelected()
- {
- if (this._particles != null)
- {
- for (int i = 0; i < this._particles.Length; i++)
- {
- Gizmos.DrawWireSphere(this._particles[i].currentPosition, 0.01f);
- }
- }
- }
- public int SimScale = 1;
- public float minimumPhysicsDelta = 0.01f;
- public float clothScale = 20f;
- public float StretchStiffness = 2.5f;
- private float _StretchStiffness;
- public float BendStiffness = 1f;
- private float _BendStiffness;
- public float mass = 0.01f;
- private float _mass;
- public float dampFactor = 0.9f;
- public int gridSize = 13;
- private int _gridSize;
- private ClothSpring[] _springs;
- private ClothParticle[] _particles;
- private float _timeSinceLastUpdate;
- public Vector3 Gravity = new Vector3(0f, -0.98f, 0f);
- private Vector3 _gravity;
- private List<ClothCollider> _colliders = new List<ClothCollider>();
- private Vertex[] _vertices;
- private Triangle[] _triangles;
- }
- }
|