Cloth Simulation

Cloth simulation with gravity, wind, and collision detection.

Cloth simulation is a rather complex task to accomplish. For this project specifically, an entire physics engine was built from scratch to simulate gravity, spring movement, and wind motion.

The cloth was built from 2500 particles, each with its own mass, position, and velocity.

typedef struct Particle {

int blocked;
float fMass; // Total mass
Vector vPosition; // Position
Vector vVelocity; // Velocity
float fSpeed; // Speed (magnitude of the velocity)
Vector vForces; // Total force acting on the particle
float fRadius; // Particle radius used for collision detection
Vector vGravity; // Gravity force vector

} Particle;

Each particle is connected to 3 springs, which interconnects all the springs to each other, ultimately creating a 50 x 50 mesh.

The physics engine itself is composed of vector math to calculate surface normals, magnitude, cross products, dot products, and euclidean distances.

i.e.

 float magnitude (Vector v) {

float mag = 0;
float x = pow(v.x,2);
float y = pow(v.y,2);
float z = pow(v.z,2);
float add = x + y + z;
float sqroot = sqrt(add);
return sqroot;

}

/*
* Function that finds the surface normal with 3 particles in space
*/

Vector findSurfaceNormal(Particle p1, Particle p2, Particle p3) {

Vector V;
Vector W;
Vector N;
Vector A;

V = subtractVectors(p2.vPosition,p1.vPosition);
W = subtractVectors(p3.vPosition,p1.vPosition);

N.x = (V.y * W.z) – (V.z * W.y);
N.y = (V.z * W.x) – (V.x * W.z);
N.z = (V.x * W.y) – (V.y * W.x);

return N;

}

Spring forces are calculated with F = -kx and the gravitational pull needs to be adjusted according to how the mesh is set up. It’s very difficult to fine tune each variable.

All spring constants, gravitational pulls, and wind forces need to be applied to each particle in the mesh.

Collision detection is handled at the end of the simulation. We need to consider the distance between the center of the ball and each particle in the cloth. If the distance between the center and the particle is less than or equal to the radius, then we have a collision and the particle must be pushed to the top of the ball.

Cube Explosion

This cube explosion is achieved by implementing a simple vector struct that requires a x, y, z coordinates and a variable for direction. Each particle in the cube explosion has randomized x, y, z constants which determine the direction in which the particle will travel in a straight line.

i.e.

typedef struct Vector {

float x;
float y;
float z;
int direction;

} Vector;

typedef struct Particle {

Vector vPosition; // Position in space

} Particle;

10,000 particles were used for the explosion and all particles originate at the center of the cube. Particles move at a constant velocity and gradually fade into the darkness over time.