Work in progress on field/ball interaction

This commit is contained in:
Philip Rosedale 2012-11-12 17:31:07 -08:00
parent 642c81beae
commit 7dbac3fbc9
4 changed files with 46 additions and 21 deletions

View file

@ -89,12 +89,12 @@ Hand myHand(HAND_RADIUS,
glm::vec3(0,1,1)); // My hand (used to manipulate things in world) glm::vec3(0,1,1)); // My hand (used to manipulate things in world)
glm::vec3 box(WORLD_SIZE,WORLD_SIZE,WORLD_SIZE); glm::vec3 box(WORLD_SIZE,WORLD_SIZE,WORLD_SIZE);
ParticleSystem balls(10, ParticleSystem balls(1000,
box, box,
false, // Wrap? false, // Wrap?
0.0, // Noise 0.02, // Noise
0.3, // Size scale 0.3, // Size scale
0.0 // Gravity 0.0 // Gravity
); );
@ -112,7 +112,7 @@ ParticleSystem balls(10,
#define RENDER_FRAME_MSECS 10 #define RENDER_FRAME_MSECS 10
#define SLEEP 0 #define SLEEP 0
#define NUM_TRIS 200000 #define NUM_TRIS 10
struct { struct {
float vertices[NUM_TRIS * 3]; float vertices[NUM_TRIS * 3];
// float normals [NUM_TRIS * 3]; // float normals [NUM_TRIS * 3];
@ -616,7 +616,7 @@ void display(void)
if (display_hand) myHand.render(); if (display_hand) myHand.render();
// balls.render(); balls.render();
// Render the world box // Render the world box
render_world_box(); render_world_box();
@ -781,7 +781,7 @@ void idle(void)
field_simulate(1.f/FPS); field_simulate(1.f/FPS);
myHead.simulate(1.f/FPS); myHead.simulate(1.f/FPS);
myHand.simulate(1.f/FPS); myHand.simulate(1.f/FPS);
// balls.simulate(1.f/FPS); balls.simulate(1.f/FPS);
if (!step_on) glutPostRedisplay(); if (!step_on) glutPostRedisplay();
last_frame = check; last_frame = check;

View file

@ -27,7 +27,7 @@ ParticleSystem::ParticleSystem(int num,
int i, element; int i, element;
bounds = box; bounds = box;
count = num; count = num;
wrapBounds = wrap; wrapBounds = false;
noise = noiselevel; noise = noiselevel;
gravity = setgravity; gravity = setgravity;
scale = setscale; scale = setscale;
@ -38,6 +38,11 @@ ParticleSystem::ParticleSystem(int num,
particles[i].position.y = randFloat()*box.y; particles[i].position.y = randFloat()*box.y;
particles[i].position.z = randFloat()*box.z; particles[i].position.z = randFloat()*box.z;
// Constrain to a small box in center
//particles[i].position.x = randFloat()+box.x/2.0;
//particles[i].position.y = randFloat()+box.y/2.0;
//particles[i].position.z = randFloat()+box.z/2.0;
particles[i].velocity.x = 0; particles[i].velocity.x = 0;
particles[i].velocity.y = 0; particles[i].velocity.y = 0;
particles[i].velocity.z = 0; particles[i].velocity.z = 0;
@ -45,7 +50,7 @@ ParticleSystem::ParticleSystem(int num,
particles[i].parent = 0; particles[i].parent = 0;
particles[i].link *= 0; particles[i].link *= 0;
element = rand()%NUM_ELEMENTS; element = 1; //rand()%NUM_ELEMENTS;
particles[i].element = element; particles[i].element = element;
if (element == 0) particles[i].color = color0; if (element == 0) particles[i].color = color0;
@ -53,7 +58,7 @@ ParticleSystem::ParticleSystem(int num,
else if (element == 2) particles[i].color = color2; else if (element == 2) particles[i].color = color2;
else if (element == 3) particles[i].color = color3; else if (element == 3) particles[i].color = color3;
particles[i].radius = radii[element]*scale; particles[i].radius = 0.10; //radii[element]*scale;
particles[i].isColliding = false; particles[i].isColliding = false;
@ -79,10 +84,10 @@ void ParticleSystem::render() {
for (unsigned int i = 0; i < count; ++i) { for (unsigned int i = 0; i < count; ++i) {
glPushMatrix(); glPushMatrix();
glTranslatef(particles[i].position.x, particles[i].position.y, particles[i].position.z); glTranslatef(particles[i].position.x, particles[i].position.y, particles[i].position.z);
if (particles[i].isColliding) glColor3f(particles[i].color.x * 0.7, if (particles[i].numSprung == 0) glColor3f(1,1,1);
particles[i].color.y * 0.7, else if (particles[i].numSprung == 1) glColor3f(0,1,0);
particles[i].color.z * 0.7); else if (particles[i].numSprung == 2) glColor3f(1,1,0);
else glColor3f(particles[i].color.x, particles[i].color.y, particles[i].color.z); else if (particles[i].numSprung >= 3) glColor3f(1,0,0);
glutSolidSphere(particles[i].radius, 15, 15); glutSolidSphere(particles[i].radius, 15, 15);
glPopMatrix(); glPopMatrix();
} }
@ -110,20 +115,27 @@ void ParticleSystem::simulate (float deltaTime) {
particles[i].velocity.y -= gravity*deltaTime; particles[i].velocity.y -= gravity*deltaTime;
// Drag: decay velocity // Drag: decay velocity
particles[i].velocity *= 0.99; const float CONSTANT_DAMPING = 0.1;
particles[i].velocity *= (1.f - CONSTANT_DAMPING*deltaTime);
// Add velocity from field // Add velocity from field
//Field::addTo(particles[i].velocity); //Field::addTo(particles[i].velocity);
//particles[i].velocity += Field::valueAt(particles[i].position); //particles[i].velocity += Field::valueAt(particles[i].position);
// Add noise // Add noise
const float RAND_VEL = 3.0; const float RAND_VEL = 0.05;
if (noise) { if (noise) {
if (randFloat() < noise*deltaTime) { if (1) {
particles[i].velocity += glm::vec3((randFloat() - 0.5)*RAND_VEL, particles[i].velocity += glm::vec3((randFloat() - 0.5)*RAND_VEL,
(randFloat() - 0.5)*RAND_VEL, (randFloat() - 0.5)*RAND_VEL,
(randFloat() - 0.5)*RAND_VEL); (randFloat() - 0.5)*RAND_VEL);
} }
if (randFloat() < noise*deltaTime) {
particles[i].velocity += glm::vec3((randFloat() - 0.5)*RAND_VEL*100,
(randFloat() - 0.5)*RAND_VEL*100,
(randFloat() - 0.5)*RAND_VEL*100);
}
} }
} else { } else {
particles[i].position = particles[particles[i].parent].position + particles[i].link; particles[i].position = particles[particles[i].parent].position + particles[i].link;
@ -137,11 +149,14 @@ void ParticleSystem::simulate (float deltaTime) {
// Check for collision with other balls // Check for collision with other balls
float separation; float separation;
const float HARD_SPHERE_FORCE = 100.0; const float HARD_SPHERE_FORCE = 100.0;
const float SPRING_FORCE = 0.1; const float SPRING_FORCE = 10.0;
float spring_length = 3*radii[1]; const float SPRING_DAMPING = 0.5;
float spring_length = 0.5; //2*radii[1];
float spring_range = spring_length * 1.2;
float contact; float contact;
particles[i].isColliding = false; particles[i].isColliding = false;
particles[i].numSprung = 0;
for (j = 0; j < count; j++) { for (j = 0; j < count; j++) {
if ((j != i) && if ((j != i) &&
@ -150,14 +165,17 @@ void ParticleSystem::simulate (float deltaTime) {
contact = particles[i].radius + particles[j].radius; contact = particles[i].radius + particles[j].radius;
// Hard Sphere Scattering // Hard Sphere Scattering
if (separation < contact) { if (separation < contact) {
particles[i].velocity += glm::normalize(particles[i].position - particles[j].position)*deltaTime*HARD_SPHERE_FORCE*(contact - separation); particles[i].velocity += glm::normalize(particles[i].position - particles[j].position)*deltaTime*HARD_SPHERE_FORCE*(contact - separation);
particles[i].isColliding = true; particles[i].isColliding = true;
} }
// Spring Action // Spring Action
if ((particles[i].element == 1) && (separation < spring_length*2)) { if ((particles[i].element == 1) && (separation < spring_range)) {
particles[i].velocity += glm::normalize(particles[i].position - particles[j].position)*deltaTime*SPRING_FORCE*(spring_length - separation); particles[i].velocity += glm::normalize(particles[i].position - particles[j].position)*deltaTime*SPRING_FORCE*(spring_length - separation);
particles[i].velocity *= (1.f - SPRING_DAMPING*deltaTime);
particles[i].numSprung++;
} }
// Link! // Link!
@ -194,14 +212,20 @@ void ParticleSystem::simulate (float deltaTime) {
// Bounce at bounds // Bounce at bounds
if (particles[i].position.x > bounds.x if (particles[i].position.x > bounds.x
|| particles[i].position.x < 0.f) { || particles[i].position.x < 0.f) {
if (particles[i].position.x > bounds.x) particles[i].position.x = bounds.x;
else particles[i].position.x = 0.f;
particles[i].velocity.x *= -1; particles[i].velocity.x *= -1;
} }
if (particles[i].position.y > bounds.y if (particles[i].position.y > bounds.y
|| particles[i].position.y < 0.f) { || particles[i].position.y < 0.f) {
if (particles[i].position.y > bounds.y) particles[i].position.y = bounds.y;
else particles[i].position.y = 0.f;
particles[i].velocity.y *= -1; particles[i].velocity.y *= -1;
} }
if (particles[i].position.z > bounds.z if (particles[i].position.z > bounds.z
|| particles[i].position.z < 0.f) { || particles[i].position.z < 0.f) {
if (particles[i].position.z > bounds.z) particles[i].position.z = bounds.z;
else particles[i].position.z = 0.f;
particles[i].velocity.z *= -1; particles[i].velocity.z *= -1;
} }
} }

View file

@ -34,6 +34,7 @@ private:
int parent; int parent;
float radius; float radius;
bool isColliding; bool isColliding;
int numSprung;
} *particles; } *particles;
unsigned int count; unsigned int count;