//-------------------------------------------------------------- void testApp::keyPressed (int key){ switch(key) { case 'a': toggleMouseAttract(); break; case 'p': for(int i=0; i<100; i++) addRandomParticle(); break; case 'P': for(int i=0; i<100; i++) killRandomParticle(); break; case 's': addRandomSpring(); break; case 'S': killRandomSpring(); break; case 'c': physics.isCollisionEnabled() ? physics.disableCollision() : physics.enableCollision(); break; case 'C': killRandomConstraint(); break; case 'r': doRender ^= true; break; case 'f': addRandomForce(FORCE_AMOUNT); break; case 'F': addRandomForce(FORCE_AMOUNT * 3); break; case 'l': lockRandomParticles(); break; case 'u': unlockRandomParticles(); break; case ' ': initScene(); break; case 'x': doMouseXY = true; break; case 'z': doMouseYZ = true; break; case ']': rotSpeed += 0.01f; break; case '[': rotSpeed -= 0.01f; break; case '+': mouseNode.setMass(mouseNode.getMass() +0.1); break; case '-': mouseNode.setMass(mouseNode.getMass() -0.1); break; case 'm': mouseNode.hasCollision() ? mouseNode.disableCollision() : mouseNode.enableCollision(); } }
//-------------------------------------------------------------- void testApp::draw() { if(doRender) { ofEnableAlphaBlending(); glEnable(GL_DEPTH_TEST); glPushMatrix(); glTranslatef(width/2, 0, -width / 3); // center scene static float rot = 0; glRotatef(rot, 0, 1, 0); // rotate scene rot += rotSpeed; // slowly increase rotation (to get a good 3D view) if(forceTimer) { float translateMax = forceTimer; glTranslatef(ofRandom(-translateMax, translateMax), ofRandom(-translateMax, translateMax), ofRandom(-translateMax, translateMax)); forceTimer--; } glDisable(GL_LIGHTING); glBegin(GL_QUADS); // draw right wall glColor3f(.9, 0.9, 0.9); glVertex3f(width/2, height+1, width/2); glColor3f(1, 1, 1); glVertex3f(width/2, -height, width/2); glColor3f(0.95, 0.95, 0.95); glVertex3f(width/2, -height, -width/2); glColor3f(.85, 0.85, 0.85); glVertex3f(width/2, height+1, -width/2); // back wall glColor3f(.9, 0.9, 0.9); glVertex3f(width/2, height+1, -width/2); glColor3f(1, 1, 1); glVertex3f(width/2, -height, -width/2); glColor3f(0.95, 0.95, 0.95); glVertex3f(-width/2, -height, -width/2); glColor3f(.85, 0.85, 0.85); glVertex3f(-width/2, height+1, -width/2); // left wall glColor3f(.9, 0.9, 0.9); glVertex3f(-width/2, height+1, -width/2); glColor3f(1, 1, 1); glVertex3f(-width/2, -height, -width/2); glColor3f(0.95, 0.95, 0.95); glVertex3f(-width/2, -height, width/2); glColor3f(.85, 0.85, 0.85); glVertex3f(-width/2, height+1, width/2); // front wall glColor3f(0.95, 0.95, 0.95); glVertex3f(width/2, -height, width/2); glColor3f(.85, 0.85, 0.85); glVertex3f(width/2, height+1, width/2); glColor3f(.9, 0.9, 0.9); glVertex3f(-width/2, height+1, width/2); glColor3f(1, 1, 1); glVertex3f(-width/2, -height, width/2); // floor glColor3f(.8, 0.8, 0.8); glVertex3f(width/2, height+1, width/2); glVertex3f(width/2, height+1, -width/2); glVertex3f(-width/2, height+1, -width/2); glVertex3f(-width/2, height+1, width/2); glEnd(); // glEnable(GL_LIGHTING); // draw springs glColor4f(0.5, 0.5, 0.5, 0.5); for(int i=0; i<physics.numberOfSprings(); i++) { Physics::Spring3D *spring = (Physics::Spring3D *) physics.getSpring(i); Physics::Particle3D *a = spring->getOneEnd(); Physics::Particle3D *b = spring->getTheOtherEnd(); Vec3f vec = b->getPosition() - a->getPosition(); float dist = vec.length(); float angle = acos( vec.z / dist ) * RAD_TO_DEG; if(vec.z <= 0 ) angle = -angle; float rx = -vec.y * vec.z; float ry = vec.x * vec.z; glPushMatrix(); glTranslatef(a->getPosition().x, a->getPosition().y, a->getPosition().z); glRotatef(angle, rx, ry, 0.0); float size = ofMap(spring->getStrength(), SPRING_MIN_STRENGTH, SPRING_MAX_STRENGTH, SPRING_MIN_WIDTH, SPRING_MAX_WIDTH); glScalef(size, size, dist); glTranslatef(0, 0, 0.5); glutSolidCube(1); glPopMatrix(); } // draw particles glAlphaFunc(GL_GREATER, 0.5); ofEnableNormalizedTexCoords(); ballImage.getTextureReference().bind(); for(int i=0; i<physics.numberOfParticles(); i++) { Physics::Particle3D *p = physics.getParticle(i); if(p->isFixed()) glColor4f(1, 0, 0, 1); else glColor4f(1, 1, 1, 1); glEnable(GL_ALPHA_TEST); // draw ball glPushMatrix(); glTranslatef(p->getPosition().x, p->getPosition().y, p->getPosition().z); glRotatef(180-rot, 0, 1, 0); glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex2f(-p->getRadius(), -p->getRadius()); glTexCoord2f(1, 0); glVertex2f(p->getRadius(), -p->getRadius()); glTexCoord2f(1, 1); glVertex2f(p->getRadius(), p->getRadius()); glTexCoord2f(0, 1); glVertex2f(-p->getRadius(), p->getRadius()); glEnd(); glPopMatrix(); glDisable(GL_ALPHA_TEST); float alpha = ofMap(p->getPosition().y, -height * 1.5, height, 0, 1); if(alpha>0) { glPushMatrix(); glTranslatef(p->getPosition().x, height, p->getPosition().z); glRotatef(-90, 1, 0, 0); glColor4f(0, 0, 0, alpha * alpha * alpha * alpha); // ofCircle(0, 0, p->getRadius()); float r = p->getRadius() * alpha; glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex2f(-r, -r); glTexCoord2f(1, 0); glVertex2f(r, -r); glTexCoord2f(1, 1); glVertex2f(r, r); glTexCoord2f(0, 1); glVertex2f(-r, r); glEnd(); glPopMatrix(); } } ballImage.getTextureReference().unbind(); ofDisableNormalizedTexCoords(); glPopMatrix(); } glDisable(GL_BLEND); glDisable(GL_DEPTH_TEST); glDisable(GL_LIGHTING); glColor4f(0, 0, 0, 1); drawString( " FPS: " + ofToString(ofGetFrameRate(), 2) + " | Number of particles: " + ofToString(physics.numberOfParticles(), 2) + " | Number of springs: " + ofToString(physics.numberOfSprings(), 2) + " | Mouse Mass: " + ofToString(mouseNode.getMass(), 2) , 20, 15); }