////////////////////////////////////////////////////////////////////////// //! build a box ////////////////////////////////////////////////////////////////////////// void buildBox(void) { Vec3f Lengths((Real32)(rand()%2)+1.0, (Real32)(rand()%2)+1.0, (Real32)(rand()%2)+1.0); Matrix m; //create OpenSG mesh GeometryRefPtr box; NodeRefPtr boxNode = makeBox(Lengths.x(), Lengths.y(), Lengths.z(), 1, 1, 1); box = dynamic_cast<Geometry*>(boxNode->getCore()); SimpleMaterialRefPtr box_mat = SimpleMaterial::create(); box_mat->setAmbient(Color3f(0.0,0.0,0.0)); box_mat->setDiffuse(Color3f(0.0,1.0 ,0.0)); box->setMaterial(box_mat); TransformRefPtr boxTrans; NodeRefPtr boxTransNode = makeCoredNode<Transform>(&boxTrans); m.setIdentity(); Real32 randX = (Real32)(rand()%10)-5.0; Real32 randY = (Real32)(rand()%10)-5.0; m.setTranslate(randX, randY, 10.0); boxTrans->setMatrix(m); //create ODE data PhysicsBodyRefPtr boxBody = PhysicsBody::create(physicsWorld); boxBody->setPosition(Vec3f(randX, randY, 10.0)); boxBody->setBoxMass(1.0, Lengths.x(), Lengths.y(), Lengths.z()); //std::cout << "mass: " << boxBody->getMass() << std::endl //<< "massCenterOfGravity: " << boxBody->getMassCenterOfGravity().x() << ", " << boxBody->getMassCenterOfGravity().y() << ", " << boxBody->getMassCenterOfGravity().z() << std::endl //<< "massInertiaTensor: " << std::endl //<< boxBody->getMassInertiaTensor()[0][0] << " "<< boxBody->getMassInertiaTensor()[0][1] << " "<< boxBody->getMassInertiaTensor()[0][2] << " " << boxBody->getMassInertiaTensor()[0][3] << std::endl //<< boxBody->getMassInertiaTensor()[1][0] << " "<< boxBody->getMassInertiaTensor()[1][1] << " "<< boxBody->getMassInertiaTensor()[1][2] << " " << boxBody->getMassInertiaTensor()[1][3] << std::endl //<< boxBody->getMassInertiaTensor()[2][0] << " "<< boxBody->getMassInertiaTensor()[2][1] << " "<< boxBody->getMassInertiaTensor()[2][2] << " " << boxBody->getMassInertiaTensor()[2][3] << std::endl //<< boxBody->getMassInertiaTensor()[3][0] << " "<< boxBody->getMassInertiaTensor()[3][1] << " "<< boxBody->getMassInertiaTensor()[3][2] << " " << boxBody->getMassInertiaTensor()[3][3] << std::endl //<< std::endl; PhysicsBoxGeomRefPtr boxGeom = PhysicsBoxGeom::create(); boxGeom->setBody(boxBody); boxGeom->setSpace(physicsSpace); boxGeom->setLengths(Lengths); //add attachments boxNode->addAttachment(boxGeom); boxTransNode->addAttachment(boxBody); boxTransNode->addChild(boxNode); //add to SceneGraph spaceGroupNode->addChild(boxTransNode); commitChanges(); }
////////////////////////////////////////////////////////////////////////// //! trimesh defined by filenode will be loaded ////////////////////////////////////////////////////////////////////////// void buildTriMesh(void) { NodeRefPtr tri = cloneTree(TriGeometryBase); if(tri!=NULL) { GeometryRefPtr triGeo = dynamic_cast<Geometry*>(tri->getCore()); Matrix m; SimpleMaterialRefPtr tri_mat = SimpleMaterial::create(); tri_mat->setAmbient(Color3f(0.1,0.1,0.2)); tri_mat->setDiffuse(Color3f(1.0,0.1,0.7)); triGeo->setMaterial(tri_mat); TransformRefPtr triTrans; NodeRefPtr triTransNode = makeCoredNode<Transform>(&triTrans); m.setIdentity(); Real32 randX = (Real32)(rand()%10)-5.0; Real32 randY = (Real32)(rand()%10)-5.0; m.setTranslate(randX, randY, 18.0); triTrans->setMatrix(m); //create ODE data Vec3f GeometryBounds(calcMinGeometryBounds(triGeo)); PhysicsBodyRefPtr triBody = PhysicsBody::create(physicsWorld); triBody->setPosition(Vec3f(randX, randY, 18.0)); triBody->setLinearDamping(0.0001); triBody->setAngularDamping(0.0001); triBody->setBoxMass(1.0,GeometryBounds.x(), GeometryBounds.y(), GeometryBounds.z()); PhysicsGeomRefPtr triGeom; if(true) { triGeom = PhysicsTriMeshGeom::create(); triGeom->setBody(triBody); //add geom to space for collision triGeom->setSpace(physicsSpace); //set the geometryNode to fill the ode-triMesh NodeRefPtr TorusGeometryNode(makeTorus(0.55, 1.05, 6, 6)); dynamic_pointer_cast<PhysicsTriMeshGeom>(triGeom)->setGeometryNode(TorusGeometryNode); } //add attachments tri->addAttachment(triGeom); triTransNode->addAttachment(triBody); //add to SceneGraph triTransNode->addChild(tri); spaceGroupNode->addChild(triTransNode); } else { SLOG << "Could not read MeshData!" << endLog; } commitChanges(); }
////////////////////////////////////////////////////////////////////////// //! build a ship ////////////////////////////////////////////////////////////////////////// PhysicsBodyRefPtr buildShip(Vec3f Dimensions, Pnt3f Position) { Real32 Radius(osgMax(Dimensions.x(), Dimensions.y())/2.0f); Real32 Length(Dimensions.z() - 2.0f*Radius); Matrix m; //create OpenSG mesh GeometryRefPtr box; NodeRefPtr boxNode = makeBox(Dimensions.x(), Dimensions.y(), Dimensions.z(), 1, 1, 1); box = dynamic_cast<Geometry*>(boxNode->getCore()); SimpleMaterialRefPtr box_mat = SimpleMaterial::create(); box_mat->setAmbient(Color3f(0.0,0.0,0.0)); box_mat->setDiffuse(Color3f(1.0,1.0 ,0.0)); box->setMaterial(box_mat); TransformRefPtr boxTrans; NodeRefPtr boxTransNode = makeCoredNode<Transform>(&boxTrans); m.setIdentity(); m.setTranslate(Position - Vec3f(0.0f,0.0f,0.5f*Dimensions.z())); boxTrans->setMatrix(m); for(UInt32 i(0) ; i<box->getPositions()->size() ; ++i) { box->getPositions()->setValue<Pnt3f>(box->getPositions()->getValue<Pnt3f>(i) + Vec3f(0.0,0.0,Dimensions.z()/2.0f),i); } //create ODE data PhysicsBodyRefPtr CapsuleBody = PhysicsBody::create(physicsWorld); CapsuleBody->setPosition(Vec3f(Position - Vec3f(0.0f,0.0f,0.5f*Dimensions.z()))); CapsuleBody->setLinearDamping(0.01); CapsuleBody->setMaxAngularSpeed(0.0); CapsuleBody->setCapsuleMass(1.0,3,Radius, Length); PhysicsCapsuleGeomRefPtr CapsuleGeom = PhysicsCapsuleGeom::create(); CapsuleGeom->setBody(CapsuleBody); CapsuleGeom->setOffsetPosition(Vec3f(0.0f,0.0f,0.5f*Dimensions.z())); CapsuleGeom->setSpace(hashSpace); CapsuleGeom->setRadius(Radius); CapsuleGeom->setLength(Length); //add attachments boxNode->addAttachment(CapsuleGeom); boxTransNode->addAttachment(CapsuleBody); boxTransNode->addChild(boxNode); //add to SceneGraph spaceGroupNode->addChild(boxTransNode); commitChanges(); return CapsuleBody; }
////////////////////////////////////////////////////////////////////////// //! build a character ////////////////////////////////////////////////////////////////////////// PhysicsBodyRefPtr buildCharacter(Vec3f Dimensions, Pnt3f Position, Node* const spaceGroupNode, PhysicsWorld* const physicsWorld, PhysicsHashSpace* const physicsSpace ) { Real32 Radius(osgMax(Dimensions.x(), Dimensions.y())/2.0f); Real32 Length(Dimensions.z() - 2.0f*Radius); Matrix m; //create OpenSG mesh GeometryRefPtr box; //NodeRefPtr characterNode = makeBox(Dimensions.x(), Dimensions.y(), Dimensions.z(), 1, 1, 1); NodeRefPtr characterNode = SceneFileHandler::the()->read("Data/Jack.osb"); if(characterNode == NULL) { characterNode = makeBox(Dimensions.x(), Dimensions.y(), Dimensions.z(), 1, 1, 1); } box = dynamic_cast<Geometry*>(characterNode->getCore()); TransformRefPtr boxTrans; NodeRefPtr boxTransNode = makeCoredNode<Transform>(&boxTrans); m.setIdentity(); m.setTranslate(Position); boxTrans->setMatrix(m); //create ODE data PhysicsBodyRefPtr boxBody = PhysicsBody::create(physicsWorld); boxBody->setPosition(Vec3f(Position)); //boxBody->setLinearDamping(0.001); //boxBody->setAngularDamping(0.001); boxBody->setMaxAngularSpeed(0.0); boxBody->setCapsuleMass(1.0,3,Radius, Length); PhysicsCapsuleGeomRefPtr CapsuleGeom = PhysicsCapsuleGeom::create(); CapsuleGeom->setBody(boxBody); CapsuleGeom->setSpace(physicsSpace); CapsuleGeom->setRadius(Radius); CapsuleGeom->setLength(Length); //add attachments characterNode->addAttachment(CapsuleGeom); boxTransNode->addAttachment(boxBody); boxTransNode->addChild(characterNode); //add to SceneGraph spaceGroupNode->addChild(boxTransNode); commitChanges(); return boxBody; }
////////////////////////////////////////////////////////////////////////// //! build a sphere ////////////////////////////////////////////////////////////////////////// void buildSphere(void) { Real32 Radius((Real32)(rand()%2)*0.5+0.5); Matrix m; //create OpenSG mesh GeometryRefPtr sphere; NodeRefPtr sphereNode = makeSphere(2, Radius); sphere = dynamic_cast<Geometry*>(sphereNode->getCore()); SimpleMaterialRefPtr sphere_mat = SimpleMaterial::create(); sphere_mat->setAmbient(Color3f(0.0,0.0,0.0)); sphere_mat->setDiffuse(Color3f(0.0,0.0,1.0)); sphere->setMaterial(sphere_mat); TransformRefPtr sphereTrans; NodeRefPtr sphereTransNode = makeCoredNode<Transform>(&sphereTrans); m.setIdentity(); Real32 randX = (Real32)(rand()%10)-5.0; Real32 randY = (Real32)(rand()%10)-5.0; m.setTranslate(randX, randY, 10.0); sphereTrans->setMatrix(m); //create ODE data PhysicsBodyRefPtr sphereBody = PhysicsBody::create(physicsWorld); sphereBody->setPosition(Vec3f(randX, randY, 10.0)); sphereBody->setAngularDamping(0.0001); sphereBody->setSphereMass(1.0,Radius); PhysicsSphereGeomRefPtr sphereGeom = PhysicsSphereGeom::create(); sphereGeom->setBody(sphereBody); sphereGeom->setSpace(physicsSpace); sphereGeom->setRadius(Radius); //add attachments sphereNode->addAttachment(sphereGeom); sphereTransNode->addAttachment(sphereBody); sphereTransNode->addChild(sphereNode); //add to SceneGraph spaceGroupNode->addChild(sphereTransNode); commitChanges(); }
virtual void update(const UpdateEventUnrecPtr e) { ForceOnCharacter.setValues(0.0,0.0,0.0); Real32 PushForce(10000.0); Real32 Speed(20.0); if(_IsUpKeyDown) { ForceOnCharacter += Vec3f(0.0, PushForce, 0.0); } if(_IsDownKeyDown) { ForceOnCharacter += Vec3f(0.0, -PushForce, 0.0); } if(_IsLeftKeyDown) { ForceOnCharacter += Vec3f(-PushForce, 0.0, 0.0); } if(_IsRightKeyDown) { ForceOnCharacter += Vec3f(PushForce, 0.0, 0.0); } if(ForceOnCharacter != Vec3f(0.0,0.0,0.0)) { ShipBody->setEnable(true); } if(ForceOnCharacter.x() !=0.0) { ShipMotor->setFMax(osgAbs(ForceOnCharacter.x())); ShipMotor->setVel(osgSgn(ForceOnCharacter.x())*Speed); } else { ShipMotor->setFMax(0.0); ShipMotor->setVel(0.0); } if(ForceOnCharacter.y() !=0.0) { ShipMotor->setFMax2(osgAbs(ForceOnCharacter.y())); ShipMotor->setVel2(osgSgn(ForceOnCharacter.y())*Speed); } else { ShipMotor->setFMax2(0.0); ShipMotor->setVel2(0.0); } if(ForceOnCharacter.z() !=0.0) { ShipMotor->setFMax3(osgAbs(ForceOnCharacter.z())); ShipMotor->setVel3(osgSgn(ForceOnCharacter.z())*Speed); } else { ShipMotor->setFMax3(0.0); ShipMotor->setVel3(0.0); } }
////////////////////////////////////////////////////////////////////////// //! build a box ////////////////////////////////////////////////////////////////////////// PhysicsBodyRefPtr buildBox(Vec3f Dimensions, Pnt3f Position) { Matrix m; //create OpenSG mesh GeometryRefPtr box; NodeRefPtr boxNode = makeBox(Dimensions.x(), Dimensions.y(), Dimensions.z(), 1, 1, 1); box = dynamic_cast<Geometry*>(boxNode->getCore()); SimpleMaterialRefPtr box_mat = SimpleMaterial::create(); box_mat->setAmbient(Color3f(0.0,0.0,0.0)); box_mat->setDiffuse(Color3f(0.0,1.0 ,1.0)); box->setMaterial(box_mat); TransformRefPtr boxTrans; NodeRefPtr boxTransNode = makeCoredNode<Transform>(&boxTrans); m.setIdentity(); m.setTranslate(Position); boxTrans->setMatrix(m); //create ODE data PhysicsBodyRefPtr boxBody = PhysicsBody::create(physicsWorld); boxBody->setPosition(Vec3f(Position)); boxBody->setLinearDamping(0.001); boxBody->setAngularDamping(0.001); boxBody->setBoxMass(1.0,Dimensions.x(), Dimensions.y(), Dimensions.z()); PhysicsBoxGeomRefPtr boxGeom = PhysicsBoxGeom::create(); boxGeom->setBody(boxBody); boxGeom->setSpace(hashSpace); boxGeom->setLengths(Dimensions); //add attachments boxNode->addAttachment(boxGeom); boxTransNode->addAttachment(boxBody); boxTransNode->addChild(boxNode); //add to SceneGraph spaceGroupNode->addChild(boxTransNode); commitChanges(); return boxBody; }
PhysicsLMotorJointRefPtr buildMotor(PhysicsBodyRefPtr ship) { //Create LMotor Joint PhysicsLMotorJointRefPtr TutorialLMotorJoint = PhysicsLMotorJoint::create(ship->getWorld()); TutorialLMotorJoint->setFirstBody(ship); TutorialLMotorJoint->setSecondBody(NULL); TutorialLMotorJoint->setNumAxes(3); TutorialLMotorJoint->setAxis1Properties(Vec3f(1.0,0.0,0.0),1); TutorialLMotorJoint->setAxis2Properties(Vec3f(0.0,1.0,0.0),1); TutorialLMotorJoint->setAxis3Properties(Vec3f(0.0,0.0,1.0),1); return TutorialLMotorJoint; }
// Initialize GLUT & OpenSG and set up the rootNode int main(int argc, char **argv) { // OSG init osgInit(argc,argv); { // Set up Window WindowEventProducerRecPtr TutorialWindow = createNativeWindow(); TutorialWindow->initWindow(); // Create the SimpleSceneManager helper SimpleSceneManager sceneManager; TutorialWindow->setDisplayCallback(boost::bind(display, &sceneManager)); TutorialWindow->setReshapeCallback(boost::bind(reshape, _1, &sceneManager)); // Tell the Manager what to manage sceneManager.setWindow(TutorialWindow); //Attach to events TutorialWindow->connectMousePressed(boost::bind(mousePressed, _1, &sceneManager)); TutorialWindow->connectMouseReleased(boost::bind(mouseReleased, _1, &sceneManager)); TutorialWindow->connectMouseMoved(boost::bind(mouseMoved, _1, &sceneManager)); TutorialWindow->connectMouseDragged(boost::bind(mouseDragged, _1, &sceneManager)); TutorialWindow->connectMouseWheelMoved(boost::bind(mouseWheelMoved, _1, &sceneManager)); TutorialWindow->connectKeyReleased(boost::bind(keyReleased, _1)); //Make Main Scene Node NodeRefPtr scene = makeCoredNode<Group>(); setName(scene, "scene"); NodeRecPtr rootNode = Node::create(); setName(rootNode, "rootNode"); ComponentTransformRefPtr Trans = ComponentTransform::create(); rootNode->setCore(Trans); rootNode->addChild(scene); //Light Beacon Matrix LightTransformMat; LightTransformMat.setTranslate(Vec3f(50.0,0.0,100.0)); TransformRefPtr LightTransform = Transform::create(); LightTransform->setMatrix(LightTransformMat); NodeRefPtr TutorialLightBeacon = Node::create(); TutorialLightBeacon->setCore(LightTransform); //Light Node PointLightRefPtr TutorialLight = PointLight::create(); TutorialLight->setBeacon(TutorialLightBeacon); NodeRefPtr TutorialLightNode = Node::create(); TutorialLightNode->setCore(TutorialLight); scene->addChild(TutorialLightNode); scene->addChild(TutorialLightBeacon); //Setup Physics Scene PhysicsWorldRecPtr physicsWorld = PhysicsWorld::create(); physicsWorld->setWorldContactSurfaceLayer(0.005); physicsWorld->setAutoDisableFlag(1); physicsWorld->setAutoDisableTime(0.75); physicsWorld->setWorldContactMaxCorrectingVel(100.0); physicsWorld->setGravity(Vec3f(0.0, 0.0, -9.81)); PhysicsHashSpaceRecPtr physicsSpace = PhysicsHashSpace::create(); //Setup the default collision parameters CollisionContactParametersRefPtr DefaultCollisionParams = CollisionContactParameters::createEmpty(); DefaultCollisionParams->setMode(dContactApprox1); DefaultCollisionParams->setMu(1.0); DefaultCollisionParams->setMu2(0.0); DefaultCollisionParams->setBounce(0.0); DefaultCollisionParams->setBounceSpeedThreshold(0.0); DefaultCollisionParams->setSoftCFM(0.1); DefaultCollisionParams->setSoftERP(0.2); DefaultCollisionParams->setMotion1(0.0); DefaultCollisionParams->setMotion2(0.0); DefaultCollisionParams->setMotionN(0.0); DefaultCollisionParams->setSlip1(0.0); DefaultCollisionParams->setSlip2(0.0); physicsSpace->setDefaultCollisionParameters(DefaultCollisionParams); PhysicsHandlerRecPtr physHandler = PhysicsHandler::create(); physHandler->setWorld(physicsWorld); physHandler->pushToSpaces(physicsSpace); physHandler->setUpdateNode(rootNode); physHandler->attachUpdateProducer(TutorialWindow); rootNode->addAttachment(physHandler); rootNode->addAttachment(physicsWorld); rootNode->addAttachment(physicsSpace); /************************************************************************/ /* create spaces, geoms and bodys */ /************************************************************************/ //create a group for our space GroupRefPtr spaceGroup; NodeRecPtr spaceGroupNode = makeCoredNode<Group>(&spaceGroup); //create the ground terrain GeometryRefPtr TerrainGeo = buildTerrain(Vec2f(400.0,400.0),25,25); //and its Material SimpleMaterialRefPtr TerrainMat = SimpleMaterial::create(); TerrainMat->setAmbient(Color3f(0.3,0.5,0.3)); TerrainMat->setDiffuse(Color3f(0.5,0.9,0.5)); TerrainGeo->setMaterial(TerrainMat); NodeRefPtr TerrainNode = Node::create(); TerrainNode->setCore(TerrainGeo); //create ODE data PhysicsGeomRefPtr TerrainODEGeom = PhysicsTriMeshGeom::create(); //add geom to space for collision TerrainODEGeom->setSpace(physicsSpace); //set the geometryNode to fill the ode-triMesh dynamic_pointer_cast<PhysicsTriMeshGeom>(TerrainODEGeom)->setGeometryNode(TerrainNode); //add attachments //add Attachments to nodes... spaceGroupNode->addAttachment(physicsSpace); spaceGroupNode->addChild(TerrainNode); TerrainNode->addAttachment(TerrainODEGeom); TutorialLightNode->addChild(spaceGroupNode); //Create Character PhysicsBodyRefPtr CharacterPhysicsBody = buildCharacter(Vec3f(5.0,5.0,10.0), Pnt3f((Real32)(rand()%100)-50.0,(Real32)(rand()%100)-50.0,25.0), spaceGroupNode, physicsWorld, physicsSpace); PhysicsLMotorJointRefPtr CharacterMover = buildMover(CharacterPhysicsBody); TutorialWindow->connectKeyPressed(boost::bind(keyPressed, _1, spaceGroupNode.get(), physicsWorld.get(), physicsSpace.get())); TutorialWindow->connectUpdate(boost::bind(handleUpdate, _1, CharacterPhysicsBody.get(), CharacterMover.get())); // tell the manager what to manage sceneManager.setRoot (rootNode); // show the whole rootNode sceneManager.showAll(); Vec2f WinSize(TutorialWindow->getDesktopSize() * 0.85f); Pnt2f WinPos((TutorialWindow->getDesktopSize() - WinSize) *0.5); TutorialWindow->openWindow(WinPos, WinSize, "03CharacterTerrain"); //Enter main Loop TutorialWindow->mainLoop(); } osgExit(); return 0; }