void Character::addRandomForce(float _f) { mForceTimer = _f; for(int i=0; i<mPhysics.numberOfParticles(); i++) { Physics::Particle3D *p = mPhysics.getParticle(i); if(p->isFree()) p->addVelocity(Vec3f(Rand::randFloat(-_f, _f), Rand::randFloat(-_f, _f), Rand::randFloat(-_f, _f))); } }
CharacterPoint::CharacterPoint( Vec3f _pos, MSA::Physics::World3D * _physics, int _pID ) { mParticleID = _pID; mPhysic = _physics; mParticle = NULL; mParent = NULL; mEndOfLine = true; mActive = false; mParticleControllerID = -1; mStandBondID = -1; savePosition = _pos; mPosition = _pos; mAnimPos = mPosition; mSpacers.clear(); mChilds.clear(); mBondIDs.clear(); Physics::Particle3D* p = mPhysic->makeParticle(_pos); p->setMass(4.0f)->setBounce(0.5f)->setRadius(5.0f)->enableCollision()->makeFree(); setParticle(); calcShellRadius(); mSuperParent = NULL; }
void unlockRandomParticles() { for(int i=0; i<physics.numberOfParticles(); i++) { Physics::Particle3D *p = physics.getParticle(i); p->makeFree(); } mouseNode.makeFixed(); }
void addRandomForce(float f) { forceTimer = f; for(int i=0; i<physics.numberOfParticles(); i++) { Physics::Particle3D *p = physics.getParticle(i); if(p->isFree()) p->addVelocity(Vec3f(ofRandom(-f, f), ofRandom(-f, f), ofRandom(-f, f))); } }
void lockRandomParticles() { for(int i=0; i<physics.numberOfParticles(); i++) { Physics::Particle3D *p = physics.getParticle(i); if(ofRandom(0, 100) < FIX_PROBABILITY) p->makeFixed(); else p->makeFree(); } mouseNode.makeFixed(); }
void initScene() { // clear all particles and springs etc physics.clear(); // you can add your own particles to the physics system physics.addParticle(&mouseNode); mouseNode.makeFixed(); mouseNode.setMass(MIN_MASS); mouseNode.moveTo(Vec3f(0, 0, 0)); mouseNode.setRadius(NODE_MAX_RADIUS); // or tell the system to create and add particles physics.makeParticle(Vec3f(-width/4, 0, -width/4), MIN_MASS)->makeFixed(); // create a node in top left back and fix physics.makeParticle(Vec3f( width/4, 0, -width/4), MIN_MASS)->makeFixed(); // create a node in top right back and fix physics.makeParticle(Vec3f(-width/4, 0, width/4), MIN_MASS)->makeFixed(); // create a node in top left front and fix physics.makeParticle(Vec3f( width/4, 0, width/4), MIN_MASS)->makeFixed(); // create a node in top right front and fix }
void addRandomParticle() { float posX = ofRandom(-width/2, width/2); float posY = ofRandom(0, height); float posZ = ofRandom(-width/2, width/2); float mass = ofRandom(MIN_MASS, MAX_MASS); float bounce = ofRandom(MIN_BOUNCE, MAX_BOUNCE); float radius = ofMap(mass, MIN_MASS, MAX_MASS, NODE_MIN_RADIUS, NODE_MAX_RADIUS); // physics.makeParticle returns a particle pointer so you can customize it Physics::Particle3D *p = physics.makeParticle(Vec3f(posX, posY, posZ)); // and set a bunch of properties (you don't have to set all of them, there are defaults) p->setMass(mass)->setBounce(bounce)->setRadius(radius)->enableCollision()->makeFree(); // add an attraction to the mouseNode if(mouseAttract) physics.makeAttraction(&mouseNode, p, ofRandom(MIN_ATTRACTION, MAX_ATTRACTION)); }
//-------------------------------------------------------------- void testApp::mouseMoved(int x, int y ) { static int oldMouseX = -10000; static int oldMouseY = -10000; int velX = x - oldMouseX; int velY = y - oldMouseY; if(doMouseXY) mouseNode.moveBy(Vec3f(velX, velY, 0)); if(doMouseYZ) mouseNode.moveBy(Vec3f(velX, 0, velY)); oldMouseX = x; oldMouseY = y; }
//-------------------------------------------------------------- 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); }
void killRandomParticle() { Physics::Particle3D *p = physics.getParticle(floor(ofRandom(0, physics.numberOfParticles()))); if(p && p != &mouseNode) p->kill(); }