private void ComputeColliders() { // Get colliders GameObject[] collidersGO = GameObject.FindGameObjectsWithTag("SPHCollider"); SPHCollider[] colliders = new SPHCollider[collidersGO.Length]; for (int i = 0; i < colliders.Length; i++) { colliders[i].Init(collidersGO[i].transform); } for (int i = 0; i < particles.Length; i++) { for (int j = 0; j < colliders.Length; j++) { // Check collision Vector3 penetrationNormal; Vector3 penetrationPosition; float penetrationLength; if (Intersect(colliders[j], particles[i].position, parameters[particles[i].parameterID].particleRadius, out penetrationNormal, out penetrationPosition, out penetrationLength)) { particles[i].velocity = DampVelocity(colliders[j], particles[i].velocity, penetrationNormal, 1.0f - parameters[particles[i].parameterID].particleDrag); particles[i].position = penetrationPosition - penetrationNormal * Mathf.Abs(penetrationLength); } } } }
private static Vector3 DampVelocity(SPHCollider collider, float3 velocity, float3 penetrationNormal, float drag) { float3 newVelocity = math.dot(velocity, penetrationNormal) * penetrationNormal * BOUND_DAMPING + math.dot(velocity, collider.right) * collider.right * drag + math.dot(velocity, collider.up) * collider.up * drag; newVelocity = math.dot(newVelocity, new float3(0, 0, 1)) * new float3(0, 0, 1) + math.dot(newVelocity, new float3(1, 0, 0)) * new float3(1, 0, 0) + math.dot(newVelocity, new float3(0, 1, 0)) * new float3(0, 1, 0); return newVelocity; }
private static Vector3 DampVelocity(SPHCollider collider, Vector3 velocity, Vector3 penetrationNormal, float drag) { Vector3 newVelocity = Vector3.Dot(velocity, penetrationNormal) * penetrationNormal * BOUND_DAMPING + Vector3.Dot(velocity, collider.right) * collider.right * drag + Vector3.Dot(velocity, collider.up) * collider.up * drag; newVelocity = Vector3.Dot(newVelocity, Vector3.forward) * Vector3.forward + Vector3.Dot(newVelocity, Vector3.right) * Vector3.right + Vector3.Dot(newVelocity, Vector3.up) * Vector3.up; return(newVelocity); }
private static bool Intersect(SPHCollider collider, Vector3 position, float radius, out Vector3 penetrationNormal, out Vector3 penetrationPosition, out float penetrationLength) { Vector3 colliderProjection = collider.position - position; penetrationNormal = Vector3.Cross(collider.right, collider.up); penetrationLength = Mathf.Abs(Vector3.Dot(colliderProjection, penetrationNormal)) - (radius / 2.0f); penetrationPosition = collider.position - colliderProjection; return(penetrationLength < 0.0f && Mathf.Abs(Vector3.Dot(colliderProjection, collider.right)) < collider.scale.x && Mathf.Abs(Vector3.Dot(colliderProjection, collider.up)) < collider.scale.y); }
private static bool Intersect(SPHCollider collider, float3 position, float radius, out float3 penetrationNormal, out float3 penetrationPosition, out float penetrationLength) { float3 colliderProjection = collider.position - position; penetrationNormal = math.cross(collider.right, collider.up); penetrationLength = math.abs(math.dot(colliderProjection, penetrationNormal)) - (radius / 2.0f); penetrationPosition = collider.position - colliderProjection; return(penetrationLength < 0.0f && math.abs(math.dot(colliderProjection, collider.right)) < collider.scale.x && math.abs(math.dot(colliderProjection, collider.up)) < collider.scale.y); }
void UpdateColliders() { // Get colliders GameObject[] collidersGO = GameObject.FindGameObjectsWithTag("SPHCollider"); if (collidersArray == null || collidersArray.Length != collidersGO.Length) { collidersArray = new SPHCollider[collidersGO.Length]; if (collidersBuffer != null) { collidersBuffer.Dispose(); } collidersBuffer = new ComputeBuffer(collidersArray.Length, SIZE_SPHCOLLIDER); } for (int i = 0; i < collidersArray.Length; i++) { collidersArray[i] = new SPHCollider(collidersGO[i].transform); } collidersBuffer.SetData(collidersArray); shader.SetBuffer(kernelComputeColliders, "colliders", collidersBuffer); }