/// <summary> /// Calculate every particle's force /// </summary> void CalForce() { Vector3 dragVector; // Reset force that apply on the particle for (int i = 0; i < _particles.Count; i++) { _particles[i].m_force.Set(0, 0, 0); } // Deal with gravity and resistance for (int i = 0; i < _particles.Count; i++) { ParticleProperty particle = _particles[i]; if (particle.m_blocked) { continue; } // Gravity particle.m_force += Physics.gravity * particle.m_mass; // Air drag force dragVector = -particle.m_velocity; dragVector.Normalize(); particle.m_force += dragVector * particle.m_velocity.sqrMagnitude * m_DragCoef; // Wind force particle.m_force += m_WindForce; } // Deal with spring force for (int i = 0; i < _springs.Count; i++) { ParticleProperty startParticle = _springs[i].m_startParticle; ParticleProperty endParticle = _springs[i].m_endParticle; Vector3 distance = endParticle.m_position - startParticle.m_position; Vector3 relateVelocity = endParticle.m_velocity - startParticle.m_velocity; float deltLength = distance.magnitude - _springs[i].m_initLength; float springForce = _springs[i].m_kConstant * deltLength; distance.Normalize(); Vector3 springForceVector = distance * springForce + (_springs[i].m_dampConstant * Vector3.Dot(relateVelocity, distance)) * distance; if (!startParticle.m_blocked) { startParticle.m_force += springForceVector; } if (!endParticle.m_blocked) { endParticle.m_force -= springForceVector; } } }
private void Start() { _particles = new List <ParticleProperty>(m_segmentNum + 1); _springs = new List <SpringProperty>(m_segmentNum); // Initialize particles Vector3 deltVector = (m_endPoint - m_startPoint) / m_segmentNum; for (int i = 0; i < m_segmentNum + 1; i++) { ParticleProperty particle = Instantiate <ParticleProperty>(m_particlePrefab); particle.m_position = m_startPoint + deltVector * i; particle.m_velocity = Vector3.zero; particle.m_acceleration = Vector3.zero; particle.m_force = Vector3.zero; particle.m_blocked = false; _particles.Add(particle); } _particles[0].m_blocked = true; // The first particle is blocked. // Initialize springs float initLength = deltVector.magnitude; for (int i = 0; i < m_segmentNum; i++) { SpringProperty spring = Instantiate <SpringProperty>(m_springPrefab); spring.m_startParticle = _particles[i]; spring.m_endParticle = _particles[i + 1]; spring.m_initLength = initLength; _springs.Add(spring); } // Init render property _mesh = new Mesh(); _mesh.MarkDynamic(); _meshFilter = GetComponent <MeshFilter>(); _normals = new List <Vector3>(new Vector3[(m_segmentNum + 1) * 2]); _uvs = new List <Vector2>(new Vector2[(m_segmentNum + 1) * 2]); _vertices = new List <Vector3>(new Vector3[(m_segmentNum + 1) * 2]); _triangles = new int[m_segmentNum * 6]; _meshFilter.mesh = _mesh; }