test.cpp
C++ source for Cloth Simulation, 256 lines. Raw file
/*
Cloth Physics
www.lewpen.com
*/
#define WIN32_LEAN_AND_MEAN
#include <math.h>
#include "qe_ogl.h"
double x[64][64], y[64][64], z[64][64];
double nx[64][64], ny[64][64], nz[64][64];
int spheres = 5;
double ssx[5], ssy[5], ssz[5], ssr[5];
double sx[5], sy[5], sz[5], sr[5];
double dist[5][5];
BOOL DrawMe = FALSE;
double r1=0, r2=0;
double a = 0;
double sphere_x[16][16];
double sphere_y[16][16];
double sphere_z[16][16];
void Sphere(double sx, double sy, double sz, double sr)
{
int i, j;
double x, y, z;
for(j=0; j<16; j++) for(i=0; i<16; i++) {
x = sr*sin(i*3.14159/16);
y = sr*cos(i*3.14159/16);
z = 0;
// Rotate about y axis
double nx = z*sin(j*3.14159/8) + x*cos(j*3.14159/8);
double ny = y;
double nz = z*cos(j*3.14159/8) - x*sin(j*3.14159/8);
sphere_x[j][i] = sx+nx;
sphere_y[j][i] = sy+ny;
sphere_z[j][i] = sz+nz;
}
double r, g, b;
int ii, jj;
for(j=0; j<16; j++) for(i=0; i<16; i++) {
ii = (i+1)&15;
jj = (j+1)&15;
if(((i^j)&1) == 0) {
r = 1.0; g = 1.0; b = 1.0;
} else {
r = 1.0; g = 0.0; b = 0.0;
}
glBegin(GL_TRIANGLE_STRIP);
glColor3f(r, g, b);
glVertex3f(sphere_x[ j][ i], sphere_y[ j][ i], sphere_z[ j][ i]);
glVertex3f(sphere_x[ j][ii], sphere_y[ j][ii], sphere_z[ j][ii]);
glVertex3f(sphere_x[jj][ i], sphere_y[jj][ i], sphere_z[jj][ i]);
glVertex3f(sphere_x[jj][ii], sphere_y[jj][ii], sphere_z[jj][ii]);
glEnd();
}
}
void Initialise()
{
int i, j;
for(j=0; j<32; j++) for(i=0; i<32; i++) {
x[j][i] = (i-16)*0.1;
y[j][i] = 1.5;
z[j][i] = (j-16)*0.1;
}
for(j=0; j<5; j++) for(i=0; i<5; i++) {
dist[j][i] = sqrt((2-i)*(2-i) + (2-j)*(2-j));
}
ssx[0] = 0.9; ssy[0] = -0.7; ssz[0] = 0.9; ssr[0] = 0.5;
ssx[1] = 0.2; ssy[1] = -0.4; ssz[1] = -0.8; ssr[1] = 0.5;
ssx[2] = -0.4; ssy[2] = -0.3; ssz[2] = 0.6; ssr[2] = 0.5;
ssx[3] = -0.3; ssy[3] = -1.7; ssz[3] = -0.7; ssr[3] = 0.5;
ssx[4] = -0.6; ssy[4] = -1.2; ssz[4] = -0.3; ssr[4] = 0.5;
spheres = 5;
}
void GameDraw()
{
int i, j, ii, jj, k, kk;
double r, g, b;
double d, dd;
// Move spheres
for(i=0; i<5; i++) {
sx[i] = ssx[i];
sy[i] = ssy[i];
sz[i] = ssz[i];
sr[i] = ssr[i];
}
a ++;
sy[0] = ssy[0] - 1.16*cos(-a*3.14159*0.0007722-0.5947);
sy[1] = ssy[1] - 1.67*cos(-a*3.14159*0.0006224+0.1344);
sy[2] = ssy[2] - 1.42*sin(-a*3.14159*0.0004629+0.6143);
sy[3] = ssy[3] + 1.55*cos(-a*3.14159*0.0003726-0.8941);
sy[4] = ssy[4] - 1.71*cos(-a*3.14159*0.0001722-0.7228);
// Move cloth
double mx, my, mz;
double vx, vy, vz;
for(k=0; k<15; k++) {
for(j=0; j<32; j++) {
for(i=0; i<32; i++) {
mx = 0; my = -0.001; mz = 0;
for(jj=j-1; jj<=j+1; jj++) if(jj>=0 && jj<32) {
for(ii=i-1; ii<=i+1; ii++) if(ii>=0 && ii<32) if(ii != i || jj != j) {
vx = x[jj][ii] - x[j][i];
vy = y[jj][ii] - y[j][i];
vz = z[jj][ii] - z[j][i];
d = vx*vx+vy*vy+vz*vz;
dd = 0.03 * (sqrt(d)-0.1*dist[2+jj-j][2+ii-i])/(d);
mx += vx*dd;
my += vy*dd;
mz += vz*dd;
}
}
nx[j][i] = x[j][i] + mx; ny[j][i] = y[j][i] + my; nz[j][i] = z[j][i] + mz;
// Floor collision
if(ny[j][i] < -2.999) ny[j][i] = -2.999;
// Sphere collision
for(kk = 0; kk<spheres; kk++) {
d = (nx[j][i]-sx[kk])*(nx[j][i]-sx[kk]) + (ny[j][i]-sy[kk])*(ny[j][i]-sy[kk]) + (nz[j][i]-sz[kk])*(nz[j][i]-sz[kk]);
if(d < sr[kk]*sr[kk]) {
d = sr[kk]/sqrt(d);
nx[j][i] = (nx[j][i]-sx[kk])*d + sx[kk];
ny[j][i] = (ny[j][i]-sy[kk])*d + sy[kk];
nz[j][i] = (nz[j][i]-sz[kk])*d + sz[kk];
}
}
}
}
for(j=0; j<32; j++) for(i=0; i<32; i++) {
x[j][i] = nx[j][i];
y[j][i] = ny[j][i];
z[j][i] = nz[j][i];
}
}
// Draw spheres
for(k = 0; k<spheres; k++) {
Sphere(sx[k], sy[k], sz[k], sr[k]-0.01);
}
// Draw floor
for(j=0; j<8; j++) {
for(i=0; i<8; i++) {
if(((i^j)&1) == 0) {
r = 0.9; g = 0.9; b = 0.9;
} else {
r = 0.1; g = 0.1; b = 0.1;
}
glBegin(GL_TRIANGLE_STRIP);
glColor3f(r, g, b);
glVertex3f(0.5*(i-4), -3, 0.5*(j-4));
glVertex3f(0.5*(i-3), -3, 0.5*(j-4));
glVertex3f(0.5*(i-4), -3, 0.5*(j-3));
glVertex3f(0.5*(i-3), -3, 0.5*(j-3));
glEnd();
}
}
// Draw cloth
for(j=0; j<31; j++) {
for(i=0; i<31; i++) {
if(((i^j)&1) == 0) {
r = 1.0; g = 1.0; b = 0.0;
} else {
r = 0.0; g = 0.0; b = 1.0;
}
glBegin(GL_TRIANGLE_STRIP);
glColor3f(r, g, b); glVertex3f(x[j ][i ], y[j ][i ], z[j ][i ]);
glColor3f(r, g, b); glVertex3f(x[j ][i+1], y[j ][i+1], z[j ][i+1]);
glColor3f(r, g, b); glVertex3f(x[j+1][i ], y[j+1][i ], z[j+1][i ]);
glColor3f(r, g, b); glVertex3f(x[j+1][i+1], y[j+1][i+1], z[j+1][i+1]);
glEnd();
}
}
}
void GameMain()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.f, 0.f, -5.f);
glRotatef(-r2*0.2, 1.0, 0.0, 0.0);
glRotatef(-r1*0.2, 0.0, 1.0, 0.0);
GameDraw();
SwapBuffers (gl_dc);
}