//-------------------------------------------------------------- void ofxBulletBox::create( btDiscreteDynamicsWorld* a_world, btTransform a_bt_tr, float a_mass, float a_sizeX, float a_sizeY, float a_sizeZ ) { if(!_bInited || _shape == NULL) { ofxBulletBaseShape::create( a_world, (btCollisionShape*)ofBtGetBoxCollisionShape( a_sizeX, a_sizeY, a_sizeZ ), a_bt_tr, a_mass ); } else { ofxBulletBaseShape::create( a_world, _shape, a_bt_tr, a_mass ); } setData( new ofxBulletUserData() ); }
//-------------------------------------------------------------- void testApp::setup() { ofSetFrameRate(60); ofSetVerticalSync(true); ofBackground( 10, 10, 10); camera.setPosition(ofVec3f(0, -3.f, -40.f)); camera.lookAt(ofVec3f(0, 0, 0), ofVec3f(0, -1, 0)); //camera.cacheMatrices(true); world.setup(); world.enableGrabbing(); world.setCamera(&camera); world.setGravity( ofVec3f(0, 25., 0) ); ofVec3f startLoc; ofPoint dimens; boundsWidth = 30.; float hwidth = boundsWidth*.5; float depth = 2.; float hdepth = depth*.5; boundsShape = new ofxBulletCustomShape(); boundsShape->create(world.world, ofVec3f(0, 0, 0), 10.); for(int i = 0; i < 6; i++) { bounds.push_back( new ofxBulletBox() ); if(i == 0) { // ground // startLoc.set( 0., hwidth+hdepth, 0. ); dimens.set(boundsWidth, depth, boundsWidth); } else if (i == 1) { // back wall // startLoc.set(0, 0, hwidth+hdepth); dimens.set(boundsWidth, boundsWidth, depth); } else if (i == 2) { // right wall // startLoc.set(hwidth+hdepth, 0, 0.); dimens.set(depth, boundsWidth, boundsWidth); } else if (i == 3) { // left wall // startLoc.set(-hwidth-hdepth, 0, 0.); dimens.set(depth, boundsWidth, boundsWidth); } else if (i == 4) { // ceiling // startLoc.set(0, -hwidth-hdepth, 0.); dimens.set(boundsWidth, depth, boundsWidth); } else if (i == 5) { // front wall // startLoc.set(0, 0, -hwidth-hdepth); dimens.set(boundsWidth, boundsWidth, depth); } btBoxShape* boxShape = ofBtGetBoxCollisionShape( dimens.x, dimens.y, dimens.z ); boundsShape->addShape( boxShape, startLoc ); bounds[i]->create( world.world, startLoc, 0., dimens.x, dimens.y, dimens.z ); bounds[i]->setProperties(.25, .95); bounds[i]->add(); } bDropBox = false; // can only see components and compound if bDrawDebug is true bDrawDebug = true; // this model is huge! scale it down ofVec3f scale(.0009, .0009, .0009); // 3D logo by Lauren Licherdell | http://www.laurenlicherdell.com/ // assimpModel.loadModel("OFlogo.dae", true); assimpModel.setScale(scale.x, scale.y, scale.z); assimpModel.setPosition(0, 0, 0); ofQuaternion startRot = ofQuaternion(1., 0., 0., PI); for (int i = 0; i < 1; i++) { logos.push_back( new ofxBulletCustomShape() ); startLoc = ofVec3f( ofRandom(-5, 5), ofRandom(0, -hwidth+5), ofRandom(-5, 5) ); if(i == 0) { for(int i = 0; i < /*assimpModel.getNumMeshes()*/1; i++) { logos[i]->addMesh(assimpModel.getMesh(i), scale, true); } } else { logos[i]->init( (btCompoundShape*)logos[0]->getCollisionShape(), logos[0]->getCentroid() ); } logos[i]->create( world.world, startLoc, startRot, 3. ); logos[i]->add(); } // let's make an object for the light to follow // shapes.push_back( new ofxBulletSphere() ); ((ofxBulletSphere*)shapes[0])->create(world.world, ofVec3f(0, -hwidth+5, -5), .15f, 2.); ((ofxBulletSphere*)shapes[0])->setSphereResolution( 10 ); ((ofxBulletSphere*)shapes[0])->setActivationState( DISABLE_DEACTIVATION ); shapes[0]->add(); // add components as separate objects bool addComponents = true; // add compound object bool addCompound = true; for ( int i=0; i<assimpModel.getNumMeshes(); i++ ) { ofLogNotice("testApp") << "assimp mesh " << i; // now decompose the model ofLogNotice("testApp") << "decomposing mesh, this could take a while, turn on verbose logging to see progress"; vector<pair<btVector3,btConvexHullShape*> > components = ofxBulletConvexDecomposer::decompose( assimpModel.getMesh(i), btVector3(scale.x, scale.y, scale.z) ); btTransform transform; transform.setIdentity(); if ( addComponents ) { transform.setOrigin( btVector3( i*2, 0, 0 ) ); vector<ofxBulletBaseRigidShape*> componentShapes = ofxBulletConvexDecomposer::createAndAddShapesForComponents( world.world, transform, components ); for ( int i=0; i<componentShapes.size(); i++ ) shapes.push_back(componentShapes[i]); } // create a compound from the parts if ( addCompound ) { transform.setIdentity(); transform.setOrigin( btVector3( i*2, 2, 0 ) ); ofxBulletCustomShape* custom = ofxBulletConvexDecomposer::createAndAddCustomShape( world.world, transform, components ); shapes.push_back(custom); } } ofSetSmoothLighting(true); light.setAmbientColor(ofColor(.0, .0, .0)); light.setDiffuseColor(ofColor(.0, .0, .0)); light.setSpecularColor(ofColor(255, .1, .1)); logoMat.setAmbientColor(ofFloatColor(0, 0, 0)); logoMat.setDiffuseColor(ofFloatColor(150, 0, 150)); logoMat.setSpecularColor(ofFloatColor(220, 0, 220)); logoMat.setShininess(40); boundsMat.setAmbientColor(ofFloatColor(10, 9, 10)); boundsMat.setDiffuseColor(ofFloatColor(12, 10, 12)); boundsMat.setSpecularColor(ofFloatColor(1, 1, 1)); boundsMat.setShininess(10); shapesMat.setShininess(80); }
//-------------------------------------------------------------- void testApp::setup() { ofSetFrameRate(60); ofSetVerticalSync(true); ofBackground( 10, 10, 10); camera.setPosition(ofVec3f(0, -3.f, -40.f)); camera.lookAt(ofVec3f(0, 0, 0), ofVec3f(0, -1, 0)); //camera.cacheMatrices(true); world.setup(); world.enableGrabbing(); world.setCamera(&camera); world.setGravity( ofVec3f(0, 25., 0) ); ofVec3f startLoc; ofPoint dimens; boundsWidth = 30.; float hwidth = boundsWidth*.5; float depth = 2.; float hdepth = depth*.5; boundsShape = new ofxBulletCustomShape(); boundsShape->create(world.world, ofVec3f(0, 0, 0), 10.); for(int i = 0; i < 6; i++) { bounds.push_back( new ofxBulletBox() ); if(i == 0) { // ground // startLoc.set( 0., hwidth+hdepth, 0. ); dimens.set(boundsWidth, depth, boundsWidth); } else if (i == 1) { // back wall // startLoc.set(0, 0, hwidth+hdepth); dimens.set(boundsWidth, boundsWidth, depth); } else if (i == 2) { // right wall // startLoc.set(hwidth+hdepth, 0, 0.); dimens.set(depth, boundsWidth, boundsWidth); } else if (i == 3) { // left wall // startLoc.set(-hwidth-hdepth, 0, 0.); dimens.set(depth, boundsWidth, boundsWidth); } else if (i == 4) { // ceiling // startLoc.set(0, -hwidth-hdepth, 0.); dimens.set(boundsWidth, depth, boundsWidth); } else if (i == 5) { // front wall // startLoc.set(0, 0, -hwidth-hdepth); dimens.set(boundsWidth, boundsWidth, depth); } btBoxShape* boxShape = ofBtGetBoxCollisionShape( dimens.x, dimens.y, dimens.z ); boundsShape->addShape( boxShape, startLoc ); bounds[i]->create( world.world, startLoc, 0., dimens.x, dimens.y, dimens.z ); bounds[i]->setProperties(.25, .95); bounds[i]->add(); } bDropBox = false; bDrawDebug = false; // this model is huge! scale it down ofVec3f scale(.0009, .0009, .0009); // 3D logo by Lauren Licherdell | http://www.laurenlicherdell.com/ // assimpModel.loadModel("OFlogo.dae", false); assimpModel.setScale(scale.x, scale.y, scale.z); assimpModel.setPosition(0, 0, 0); logoMesh = assimpModel.getMesh(0); float blobScale = 5; blobModel.loadModel("blob.dae", false ); blobModel.setPosition(0,0,0); blobMesh = blobModel.getMesh(1); ofMesh blobMesh_wobbly = blobModel.getMesh(0); MeshHelper::scaleMesh( blobMesh, blobScale ); MeshHelper::scaleMesh( blobMesh_wobbly, blobScale ); // don't need to scale any more blobScale = 1; MeshHelper::fuseNeighbours( blobMesh ); MeshHelper::fuseNeighbours( blobMesh_wobbly ); blobMesh_attachIndexEnd = blobMesh.getNumVertices(); MeshHelper::appendMesh( blobMesh, blobMesh_wobbly, true ); float blobMass = 3.f; ofQuaternion startRot = ofQuaternion(1., 0., 0., PI); // let's make an object for the light to follow // shapes.push_back( new ofxBulletSphere() ); ((ofxBulletSphere*)shapes[0])->create(world.world, ofVec3f(0, -hwidth+5, -5), .15f, 2.); ((ofxBulletSphere*)shapes[0])->setSphereResolution( 10 ); ((ofxBulletSphere*)shapes[0])->setActivationState( DISABLE_DEACTIVATION ); shapes[0]->add(); for (int i = 0; i < 0; i++) { logos.push_back( new ofxBulletCustomShape() ); startLoc = ofVec3f( ofRandom(-5, 5), ofRandom(0, -hwidth+5), ofRandom(-5, 5) ); if(i == 0) { for(int i = 0; i < assimpModel.getNumMeshes(); i++) { logos[i]->addMesh(assimpModel.getMesh(i), scale, true); } } else { logos[i]->init( (btCompoundShape*)logos[0]->getCollisionShape(), logos[0]->getCentroid() ); } logos[i]->create( world.world, startLoc, startRot, 3. ); logos[i]->add(); } for ( int i=0; i<0; i++ ) { shapes.push_back( new ofxBulletCapsule() ); startLoc = ofVec3f( ofRandom(-5, 5), ofRandom(0, -hwidth+5), ofRandom(-5, 5) ); float mass = 1.0f; float radius = 1.f; float height = 2.f; ((ofxBulletCapsule*)shapes.back())->create( world.world, startLoc, mass, radius, height ); ((ofxBulletCapsule*)shapes.back())->setActivationState( DISABLE_DEACTIVATION ); shapes.back()->add(); } for ( int i=0; i<1; i++ ) { softShapes.push_back( new ofxBulletBaseSoftShape() ); //startLoc = ofVec3f( ofRandom(-5, 5), ofRandom(0, -hwidth+5), ofRandom(-5, 5) ); startLoc = ofVec3f(0,0,0); /* ofBuffer faceFile = ofBufferFromFile( "blob.1.face" ); ofBuffer nodeFile = ofBufferFromFile( "blob.1.node" ); ofBuffer eleFile = ofBufferFromFile( "blob.1.ele" ); float tetraMass = 0.3f; float tetraScale = 5; softShapes.back()->createFromTetraBuffer( world.world, eleFile, faceFile, nodeFile, ofGetBtTransformFromVec3f(startLoc), tetraMass, tetraScale );*/ softShapes.back()->createFromOfMesh( world.world, blobMesh, ofGetBtTransformFromVec3f(startLoc), blobMass, blobScale ); softShapes.back()->setPressure( 10.f ); softShapes.back()->setDamping( 0.01f ); softShapes.back()->add(); blobShape = softShapes.back(); } ofSetSmoothLighting(true); float lightScale = 0.1f; light.setAmbientColor(ofColor(.0, .0, .0)); light.setDiffuseColor(ofColor(128*lightScale, 128*lightScale, 128*lightScale)); light.setSpecularColor(ofColor(192*lightScale, 180*lightScale, 180*lightScale )); light.setAttenuation(0, 0.5, 0); float keyScale = 0.5f; keyLight.setPosition( -15, -10, -40 ); keyLight.setAmbientColor(ofColor(.0, .0, .0)); keyLight.setDiffuseColor(ofColor(192*keyScale, 192*keyScale, 128*keyScale)); keyLight.setSpecularColor(ofColor(192*keyScale, 180*keyScale, 180*keyScale )); // keyLight.setAttenuation(0,1,0); float fillScale = 0.3f; fillLight.setPosition( 15, 20, -40 ); fillLight.setAmbientColor(ofColor(.0, .0, .0)); fillLight.setDiffuseColor(ofColor(192*fillScale, 128*fillScale, 128*fillScale)); fillLight.setSpecularColor(ofColor(192*fillScale, 180*fillScale, 180*fillScale )); // keyLight.setAttenuation(0,1,0); logoMat.setAmbientColor(ofFloatColor(0, 0, 0)); logoMat.setDiffuseColor(ofFloatColor(150, 0, 150)); logoMat.setSpecularColor(ofFloatColor(220, 0, 220)); logoMat.setShininess(40); boundsMat.setAmbientColor(ofFloatColor(10, 9, 10)); boundsMat.setDiffuseColor(ofFloatColor(12, 10, 12)); boundsMat.setSpecularColor(ofFloatColor(1, 1, 1)); boundsMat.setShininess(10); shapesMat.setShininess(80); }
//-------------------------------------------------------------- void ofApp::setup() { ofSetFrameRate(60); ofSetVerticalSync(true); ofBackground( 10, 10, 10); camera.setPosition(ofVec3f(0, -3.f, -40.f)); camera.lookAt(ofVec3f(0, 0, 0), ofVec3f(0, -1, 0)); world.setup(); world.enableGrabbing(); world.setCamera(&camera); world.setGravity( ofVec3f(0, 25., 0) ); ofVec3f startLoc; ofPoint dimens; boundsWidth = 30.; float hwidth = boundsWidth*.5; float depth = 2.; float hdepth = depth*.5; boundsShape = new ofxBulletCustomShape(); boundsShape->create(world.world, ofVec3f(0, 0, 0), 10.); for(int i = 0; i < 6; i++) { bounds.push_back( new ofxBulletBox() ); if(i == 0) { // ground // startLoc.set( 0., hwidth+hdepth, 0. ); dimens.set(boundsWidth, depth, boundsWidth); } else if (i == 1) { // back wall // startLoc.set(0, 0, hwidth+hdepth); dimens.set(boundsWidth, boundsWidth, depth); } else if (i == 2) { // right wall // startLoc.set(hwidth+hdepth, 0, 0.); dimens.set(depth, boundsWidth, boundsWidth); } else if (i == 3) { // left wall // startLoc.set(-hwidth-hdepth, 0, 0.); dimens.set(depth, boundsWidth, boundsWidth); } else if (i == 4) { // ceiling // startLoc.set(0, -hwidth-hdepth, 0.); dimens.set(boundsWidth, depth, boundsWidth); } else if (i == 5) { // front wall // startLoc.set(0, 0, -hwidth-hdepth); dimens.set(boundsWidth, boundsWidth, depth); } btBoxShape* boxShape = ofBtGetBoxCollisionShape( dimens.x, dimens.y, dimens.z ); boundsShape->addShape( boxShape, startLoc ); bounds[i]->create( world.world, startLoc, 0., dimens.x, dimens.y, dimens.z ); bounds[i]->setProperties(.25, .95); bounds[i]->add(); } bDropBox = false; bDrawDebug = false; // this model is huge! scale it down //ofVec3f scale(.0009, .0009, .0009); ofVec3f scale(.09, .09, .09); // 3D logo by Lauren Licherdell | http://www.laurenlicherdell.com/ // model2.loadModel("OFlogo.dae", false); //change true to false (do not optimize model, see https://github.com/openframeworks/openFrameworks/issues/4994) model2.setScale(scale.x, scale.y, scale.z); model2.setPosition(0, 0, 0); assimpModel.loadModel("grip.dae", false); //change true to false (do not optimize model, see https://github.com/openframeworks/openFrameworks/issues/4994) assimpModel.setScale(scale.x, scale.y, scale.z); assimpModel.setPosition(0, 0, 0); ofQuaternion startRot = ofQuaternion(1., 0., 0., PI); logos.resize( 5 ); //number of logos for (int i = 0; i < logos.size(); i++) { logos[i] = new ofxBulletCustomShape(); startLoc = ofVec3f( ofRandom(-5, 5), ofRandom(0, -hwidth+5), ofRandom(-5, 5) ); if(i == 0) { for(int i = 0; i < assimpModel.getNumMeshes(); i++) { logos[i]->addMesh(assimpModel.getMesh(i), scale, true); } } else { logos[i]->init( (btCompoundShape*)logos[0]->getCollisionShape(), logos[0]->getCentroid() ); } logos[i]->create( world.world, startLoc, startRot, 3. ); logos[i]->add(); } // let's make an object for the light to follow // shapes.push_back( new ofxBulletSphere() ); ((ofxBulletSphere*)shapes[0])->create(world.world, ofVec3f(0, -hwidth+5, -5), .15f, 2.); ((ofxBulletSphere*)shapes[0])->setActivationState( DISABLE_DEACTIVATION ); shapes[0]->add(); logoMat.setAmbientColor(ofFloatColor(0, 0, 0)); logoMat.setDiffuseColor(ofFloatColor(150, 0, 150)); logoMat.setSpecularColor(ofFloatColor(220, 0, 220)); logoMat.setShininess(40); // boundsMat.setAmbientColor(ofFloatColor(10, 9, 10)); //boundsMat.setDiffuseColor(ofFloatColor(12, 10, 12)); // boundsMat.setSpecularColor(ofFloatColor(1, 1, 1)); boundsMat.setShininess(10); shapesMat.setShininess(80); }
//-------------------------------------------------------------- void testApp::setup() { ofSetFrameRate(60); ofSetVerticalSync(true); ofBackground( 10, 10, 10); camera.setPosition(ofVec3f(0, -4.f, -40.f)); camera.lookAt(ofVec3f(0, 0, 0), ofVec3f(0, -1, 0)); camera.cacheMatrices(true); world.setup(); // enables mouse Pick events // world.enableGrabbing(); ofAddListener(world.MOUSE_PICK_EVENT, this, &testApp::mousePickEvent); world.enableCollisionEvents(); ofAddListener(world.COLLISION_EVENT, this, &testApp::onCollision); world.setCamera(&camera); world.setGravity( ofVec3f(0, 25., 0) ); int ii = 0; // let's make a shape that all of the rigid bodies use, since it is faster // // though all of the spheres will be the same radius // sphereShape = ofBtGetSphereCollisionShape(2.5); for (int i = 0; i < 4; i++) { shapes.push_back( new ofxBulletSphere() ); ii = shapes.size()-1; ((ofxBulletSphere*)shapes[ii])->init(sphereShape); // no need to pass radius, since we already created it in the sphereShape // ((ofxBulletSphere*)shapes[ii])->create(world.world, ofVec3f(ofRandom(-3, 3), ofRandom(-2, 2), ofRandom(-1, 1)), 0.1); shapes[ii]->setActivationState( DISABLE_DEACTIVATION ); shapes[ii]->add(); bColliding.push_back( false ); } // now lets add some boxes // boxShape = ofBtGetBoxCollisionShape(2.65, 2.65, 2.65); for (int i = 0; i < 4; i++) { shapes.push_back( new ofxBulletBox() ); ii = shapes.size()-1; ((ofxBulletBox*)shapes[ii])->init(boxShape); ((ofxBulletBox*)shapes[ii])->create(world.world, ofVec3f(ofRandom(-3, 3), ofRandom(-2, 2), ofRandom(-1, 1)), 0.2); shapes[ii]->setActivationState( DISABLE_DEACTIVATION ); shapes[ii]->add(); bColliding.push_back( false ); } ofVec3f startLoc; ofPoint dimens; boundsWidth = 30.; float hwidth = boundsWidth*.5; float depth = 2.; float hdepth = depth*.5; for(int i = 0; i < 6; i++) { bounds.push_back( new ofxBulletBox() ); if(i == 0) { // ground // startLoc.set( 0., hwidth+hdepth, 0. ); dimens.set(boundsWidth, depth, boundsWidth); } else if (i == 1) { // back wall // startLoc.set(0, 0, hwidth+hdepth); dimens.set(boundsWidth, boundsWidth, depth); } else if (i == 2) { // right wall // startLoc.set(hwidth+hdepth, 0, 0.); dimens.set(depth, boundsWidth, boundsWidth); } else if (i == 3) { // left wall // startLoc.set(-hwidth-hdepth, 0, 0.); dimens.set(depth, boundsWidth, boundsWidth); } else if (i == 4) { // ceiling // startLoc.set(0, -hwidth-hdepth, 0.); dimens.set(boundsWidth, depth, boundsWidth); } else if (i == 5) { // front wall // startLoc.set(0, 0, -hwidth-hdepth); dimens.set(boundsWidth, boundsWidth, depth); } bounds[i]->create( world.world, startLoc, 0., dimens.x, dimens.y, dimens.z ); bounds[i]->setProperties(.25, .95); bounds[i]->add(); } mousePickIndex = -1; bDrawDebug = false; bRenderShapes = true; bAddCenterAttract = true; bSpacebar = false; }
//-------------------------------------------------------------- void ofxBulletBox::init(float a_sizeX, float a_sizeY, float a_sizeZ) { _shape = (btCollisionShape*)ofBtGetBoxCollisionShape( a_sizeX, a_sizeY, a_sizeZ ); _bInited = true; }