u32 wsScene::addPrimitive(wsPrimitive* myPrimitive) { wsAssert(numPrimitives < WS_MAX_PRIMITIVES, "Cannot add another primitive to the scene. Maximum already reached."); primitives[numPrimitives] = myPrimitive; #if WS_PHYSICS_BACKEND == WS_BACKEND_BULLET switch (myPrimitive->getType()) { case WS_PRIM_TYPE_PLANE: { wsPlane* plane = (wsPlane*)myPrimitive; vec4 data = plane->getPosData(); btCollisionShape* planeShape = wsNew(btStaticPlaneShape, btStaticPlaneShape(btVector3(data.x, data.y, data.z), data.w)); btDefaultMotionState* planeState = wsNew(btDefaultMotionState, btDefaultMotionState(btTransform(btQuaternion(0.0f, 0.0f, 0.0f, 1.0f), btVector3(0.0f, 0.0f, 0.0f)))); btRigidBody::btRigidBodyConstructionInfo planeRigidBodyCI(0, planeState, planeShape, btVector3(0,0,0)); btRigidBody* groundRigidBody = wsNew(btRigidBody, btRigidBody(planeRigidBodyCI)); physicsWorld->addRigidBody(groundRigidBody, myPrimitive->getCollisionClass(), collisionClasses[(u32)wsLog2(myPrimitive->getCollisionClass())]); } break; case WS_PRIM_TYPE_CUBE: { wsCube* cube = (wsCube*)myPrimitive; vec4 dimensions = cube->getDimensions(); vec4 pos = cube->getPos(); quat rot = cube->getRot(); btCollisionShape* cubeShape = wsNew(btBoxShape, btBoxShape(btVector3(dimensions.x/2.0f, dimensions.y/2.0f, dimensions.z/2.0f))); btDefaultMotionState* cubeState = wsNew(btDefaultMotionState, btDefaultMotionState(btTransform(btQuaternion(rot.x, rot.y, rot.z, rot.w), btVector3(pos.x, pos.y, pos.z)))); btRigidBody::btRigidBodyConstructionInfo cubeRigidBodyCI(0, cubeState, cubeShape, btVector3(0, 0, 0)); btRigidBody* cubeRigidBody = wsNew(btRigidBody, btRigidBody(cubeRigidBodyCI)); physicsWorld->addRigidBody(cubeRigidBody, myPrimitive->getCollisionClass(), collisionClasses[(u32)wsLog2(myPrimitive->getCollisionClass())]); } break; default: break; } #endif return numPrimitives++; }
// MAIN FUNCTION int main(int argc, char **argv) { bool init = false; // Initialize glut glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowSize(w, h); // Name and create the Window glutCreateWindow("Dope Lighting Demo"); // Now that the window is created the GL context is fully set up // Because of that we can now initialize GLEW to prepare work with shaders GLenum status = glewInit(); if( status != GLEW_OK) { std::cerr << "[F] GLEW NOT INITIALIZED: "; std::cerr << glewGetErrorString(status) << std::endl; return -1; } // Set all of the callbacks to GLUT that we need glutDisplayFunc(render);// Called when its time to display glutReshapeFunc(reshape);// Called if the window is resized glutIdleFunc(update);// Called if there is nothing else to do glutKeyboardFunc(keyboard);// Called if there is keyboard input glutMouseFunc(mouse);//Called if there is mouse input glutSpecialFunc(ArrowKeys); int index = glutCreateMenu(Menu1); glutAddMenuEntry("Rotate Clockwise", 1); glutAddMenuEntry("Rotate Counterclockwise", 2); glutAddMenuEntry("Don't Rotate", 3); glutCreateMenu(Menu2); glutAddSubMenu("Rotation options", index); glutAddMenuEntry("Exit Program", 2); glutAttachMenu(GLUT_RIGHT_BUTTON); srand(getDT()); // add menus manageMenus( false ); ////////////////////////////////////////////////////////////////////////// //create brodphase btBroadphaseInterface* broadphase = new btDbvtBroadphase(); //create collision configuration btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration(); //create a dispatcher btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration); //create a solver btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver; //create the physics world dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration); //set the gravity dynamicsWorld->setGravity(btVector3(0, -10, 0)); //create a game board which the objects will be on btCollisionShape* ground = new btStaticPlaneShape(btVector3(0, 1, 0), 1); btCollisionShape* wallOne = new btStaticPlaneShape(btVector3(-1, 0, 0), 1); btCollisionShape* wallTwo = new btStaticPlaneShape(btVector3(1, 0, 0), 1); btCollisionShape* wallThree = new btStaticPlaneShape(btVector3(0, 0, 1), 1); btCollisionShape* wallFour = new btStaticPlaneShape(btVector3(0, 0, -1), 1); //create sphere and set radius to 1 btCollisionShape* sphere = new btSphereShape(1); //create cube and set extents to 0.5 each btCollisionShape* cube = new btBoxShape(btVector3(0.5,0.5,0.5)); //create a cylinder and set radius of each axis to 1.0 btCollisionShape* cylinder = new btCylinderShape(btVector3(1.0,1.0,1.0)); /*----------------------this is the gameboard--------------------------------*/ // After we create collision shapes we have to se the default motion state // for the ground btDefaultMotionState* groundMotionState = NULL; groundMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(0, -1, 0))); //here we construct the ground using the motion state and shape btRigidBody::btRigidBodyConstructionInfo groundRigidBodyCI(0, groundMotionState, ground, btVector3(0, 0, 0)); btRigidBody* groundRigidBody = new btRigidBody(groundRigidBodyCI); //display dynamic body in our world dynamicsWorld->addRigidBody(groundRigidBody); ////make the first wall btDefaultMotionState* wallOneMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(5.6, 0, 0))); //here we construct the first wall using the motion state and shape btRigidBody::btRigidBodyConstructionInfo wallOneRigidBodyCI(0, wallOneMotionState, wallOne, btVector3(0, 0, 0)); btRigidBody* wallOneRigidBody = new btRigidBody(wallOneRigidBodyCI); //display dynamic body in our world dynamicsWorld->addRigidBody(wallOneRigidBody); ////make the second wall btDefaultMotionState* wallTwoMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(-5.6, 0, 0))); //here we construct the second wall using the motion state and shape btRigidBody::btRigidBodyConstructionInfo wallTwoRigidBodyCI(0, wallTwoMotionState, wallTwo, btVector3(0, 0, 0)); btRigidBody* wallTwoRigidBody = new btRigidBody(wallTwoRigidBodyCI); //display dynamic body in our world dynamicsWorld->addRigidBody(wallTwoRigidBody); ////make the third wall FRONTBACK btDefaultMotionState* wallThreeMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(0, 0, -5.6))); //here we construct the third wall using the motion state and shape btRigidBody::btRigidBodyConstructionInfo wallThreeRigidBodyCI(0, wallThreeMotionState, wallThree, btVector3(0, 0, 0)); btRigidBody* wallThreeRigidBody = new btRigidBody(wallThreeRigidBodyCI); //display dynamic body in our world dynamicsWorld->addRigidBody(wallThreeRigidBody); ////make the fouth wall FRONTBACK btDefaultMotionState* wallFourMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(0, 0, 5.6))); //here we construct the fourth wall using the motion state and shape btRigidBody::btRigidBodyConstructionInfo wallFourRigidBodyCI(0, wallFourMotionState, wallFour, btVector3(0, 0, 0)); btRigidBody* wallFourRigidBody = new btRigidBody(wallFourRigidBodyCI); //display dynamic body in our world dynamicsWorld->addRigidBody(wallFourRigidBody); /*-----------------------------------------------------------------------------*/ /*----------------------this is the sphere--------------------------------*/ // After we create collision shapes we have to se the default motion state // for the sphere btDefaultMotionState* sphereMotionState = NULL; sphereMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(2, 1, 0))); // the sphere must have a mass btScalar mass = 1; //we need the inertia of the sphere and we need to calculate it btVector3 sphereInertia(0, 0, 0); sphere->calculateLocalInertia(mass, sphereInertia); //Here we construct the sphere with a mass, motion state, and inertia btRigidBody::btRigidBodyConstructionInfo sphereRigidBodyCI(mass, sphereMotionState, sphere, sphereInertia); rigidBodySphere = new btRigidBody(sphereRigidBodyCI); rigidBodySphere->setActivationState(DISABLE_DEACTIVATION); //display dynamic body in our world dynamicsWorld->addRigidBody(rigidBodySphere); /*-----------------------------------------------------------------------------*/ /*----------------------this is the cube--------------------------------*/ // After we create collision shapes we have to se the default motion state // for the cube btDefaultMotionState* cubeMotionState = NULL; cubeMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(0, 1, 0))); //the cube must have a mass mass = 0; //we need the inertia of the cube and we need to calculate it btVector3 cubeInertia(0, 0, 0); cube->calculateLocalInertia(mass, cubeInertia); //Here we construct the cube with a mass, motion state, and inertia btRigidBody::btRigidBodyConstructionInfo cubeRigidBodyCI(mass, cubeMotionState, sphere, sphereInertia); rigidBodyCube = new btRigidBody(cubeRigidBodyCI); // this is where we make a static object (like the cube) into a kinematic object rigidBodyCube->setCollisionFlags(rigidBodyCube->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); rigidBodyCube->setActivationState(DISABLE_DEACTIVATION); //display dynamic body in our world dynamicsWorld->addRigidBody(rigidBodyCube); /*-----------------------------------------------------------------------------*/ /*----------------------this is the cylinder--------------------------------*/ // After we create collision shapes we have to se the default motion state // for the cylinder btDefaultMotionState* cylinderMotionState = NULL; cylinderMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(1, 20, 1))); //the cylinder must have a mass mass = 1; //we need the inertia of the cylinder and we need to calculate it btVector3 cylinderInertia(0, 0, 0); cylinder->calculateLocalInertia(mass, cylinderInertia); //Here we construct the cylinder with a mass, motion state, and inertia btRigidBody::btRigidBodyConstructionInfo cylinderRigidBodyCI(mass, cylinderMotionState, cylinder, sphereInertia); rigidBodyCylinder = new btRigidBody(cylinderRigidBodyCI); rigidBodyCylinder->setActivationState(DISABLE_DEACTIVATION); //display dynamic body in our world dynamicsWorld->addRigidBody(rigidBodyCylinder); /*-----------------------------------------------------------------------------*/ ///////////////////////////////////////////////////////////////////////////// // Initialize all of our resources(shaders, geometry) // pass default planet info if not given one if( argc != 3 ) { init = initialize( defaultInfo ); } // or, pass planet info given from command line argument else { init = initialize( argv[1] ); } // if initialized, begin glut main loop if(init) { t1 = std::chrono::high_resolution_clock::now(); glutMainLoop(); } // remove menus manageMenus( true ); //////////// clean up and end program // delete the pointers dynamicsWorld->removeRigidBody(groundRigidBody); delete groundRigidBody->getMotionState(); delete groundRigidBody; dynamicsWorld->removeRigidBody(rigidBodySphere); delete rigidBodySphere->getMotionState(); delete rigidBodySphere; dynamicsWorld->removeRigidBody(rigidBodyCube); delete rigidBodyCube->getMotionState(); delete rigidBodyCube; dynamicsWorld->removeRigidBody(rigidBodyCylinder); delete rigidBodyCylinder->getMotionState(); delete rigidBodyCylinder; dynamicsWorld->removeRigidBody(wallOneRigidBody); delete wallOneRigidBody->getMotionState(); delete wallOneRigidBody; dynamicsWorld->removeRigidBody(wallTwoRigidBody); delete wallTwoRigidBody->getMotionState(); delete wallTwoRigidBody; dynamicsWorld->removeRigidBody(wallThreeRigidBody); delete wallThreeRigidBody->getMotionState(); delete wallThreeRigidBody; dynamicsWorld->removeRigidBody(wallFourRigidBody); delete wallFourRigidBody->getMotionState(); delete wallFourRigidBody; delete ground; delete wallOne; delete wallTwo; delete wallThree; delete wallFour; delete sphere; delete cube; delete cylinder; delete dynamicsWorld; delete solver; delete collisionConfiguration; delete dispatcher; delete broadphase; cleanUp(); return 0; }