From 43370aaa4fe48cfd9f1736b08226c3c11a45fbde Mon Sep 17 00:00:00 2001 From: ejcoumans Date: Mon, 11 Sep 2006 05:31:22 +0000 Subject: [PATCH] first step in refactoring/cleaning up demos --- Demos/BspDemo/BspDemo.cpp | 1253 ++++---------- Demos/CcdPhysicsDemo/CcdPhysicsDemo.cpp | 989 ++--------- Demos/CcdPhysicsDemo/CcdPhysicsDemo.h | 35 + Demos/ColladaDemo/BspConverter.cpp | 282 ---- Demos/ColladaDemo/BspLoader.cpp | 713 -------- Demos/ColladaDemo/BspLoader.h | 304 ---- Demos/ColladaDemo/ColladaDemo.cpp | 1497 +---------------- .../{BspConverter.h => ColladaDemo.h} | 32 +- Demos/CollisionDemo/CollisionDemo.cpp | 83 +- Demos/CollisionDemo/CollisionDemo.h | 36 + .../CollisionInterfaceDemo.cpp | 89 +- .../CollisionInterfaceDemo.h | 35 + Demos/ConcaveDemo/ConcaveDemo.h | 36 + Demos/ConcaveDemo/ConcavePhysicsDemo.cpp | 357 +--- Demos/ConstraintDemo/ConstraintDemo.cpp | 340 +--- Demos/ConstraintDemo/ConstraintDemo.h | 36 + .../ContinuousConvexCollision.h | 36 + .../ContinuousConvexCollisionDemo.cpp | 80 +- .../ConvexDecompositionDemo.cpp | 943 +---------- .../ConvexDecompositionDemo.h | 38 + .../LinearConvexCastDemo.cpp | 74 +- .../GjkConvexCastDemo/LinearConvexCastDemo.h | 36 + Demos/OpenGL/DemoApplication.cpp | 894 ++++++++++ Demos/OpenGL/DemoApplication.h | 170 ++ Demos/OpenGL/GL_ShapeDrawer.cpp | 16 +- Demos/OpenGL/GlutStuff.cpp | 395 +---- Demos/OpenGL/GlutStuff.h | 20 +- Demos/Raytracer/Raytracer.cpp | 72 +- Demos/Raytracer/Raytracer.h | 36 + Demos/SimplexDemo/SimplexDemo.cpp | 70 +- Demos/SimplexDemo/SimplexDemo.h | 36 + Demos/VehicleDemo/VehicleDemo.cpp | 913 ++-------- Demos/VehicleDemo/VehicleDemo.h | 51 + 33 files changed, 2449 insertions(+), 7548 deletions(-) create mode 100644 Demos/CcdPhysicsDemo/CcdPhysicsDemo.h delete mode 100644 Demos/ColladaDemo/BspConverter.cpp delete mode 100644 Demos/ColladaDemo/BspLoader.cpp delete mode 100644 Demos/ColladaDemo/BspLoader.h rename Demos/ColladaDemo/{BspConverter.h => ColladaDemo.h} (51%) create mode 100644 Demos/CollisionDemo/CollisionDemo.h create mode 100644 Demos/CollisionInterfaceDemo/CollisionInterfaceDemo.h create mode 100644 Demos/ConcaveDemo/ConcaveDemo.h create mode 100644 Demos/ConstraintDemo/ConstraintDemo.h create mode 100644 Demos/ContinuousConvexCollision/ContinuousConvexCollision.h create mode 100644 Demos/ConvexDecompositionDemo/ConvexDecompositionDemo.h create mode 100644 Demos/GjkConvexCastDemo/LinearConvexCastDemo.h create mode 100644 Demos/OpenGL/DemoApplication.cpp create mode 100644 Demos/OpenGL/DemoApplication.h create mode 100644 Demos/Raytracer/Raytracer.h create mode 100644 Demos/SimplexDemo/SimplexDemo.h create mode 100644 Demos/VehicleDemo/VehicleDemo.h diff --git a/Demos/BspDemo/BspDemo.cpp b/Demos/BspDemo/BspDemo.cpp index 4acbb9d5b..462cdbf98 100644 --- a/Demos/BspDemo/BspDemo.cpp +++ b/Demos/BspDemo/BspDemo.cpp @@ -1,950 +1,305 @@ -/* -Bullet Continuous Collision Detection and Physics Library -Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ - -This software is provided 'as-is', without any express or implied warranty. -In no event will the authors be held liable for any damages arising from the use of this software. -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it freely, -subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. -2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. -3. This notice may not be removed or altered from any source distribution. -*/ - -#include "CcdPhysicsEnvironment.h" -#include "CcdPhysicsController.h" - -//#include "GL_LineSegmentShape.h" -#include "CollisionShapes/BoxShape.h" -#include "CollisionShapes/SphereShape.h" -#include "CollisionShapes/CylinderShape.h" -#include "CollisionShapes/ConeShape.h" -#include "CollisionShapes/StaticPlaneShape.h" -#include "CollisionShapes/ConvexHullShape.h" -#include "CollisionShapes/TriangleMesh.h" -#include "CollisionShapes/ConvexTriangleMeshShape.h" -#include "CollisionShapes/TriangleMeshShape.h" -#include "CollisionShapes/TriangleIndexVertexArray.h" -#include "CollisionShapes/CompoundShape.h" - - -extern SimdVector3 gCameraUp; -extern int gForwardAxis; - -#include "CollisionShapes/Simplex1to4Shape.h" -#include "CollisionShapes/EmptyShape.h" - -#include "Dynamics/RigidBody.h" -#include "CollisionDispatch/CollisionDispatcher.h" -#include "BroadphaseCollision/SimpleBroadphase.h" -#include "BroadphaseCollision/AxisSweep3.h" -#include "ConstraintSolver/Point2PointConstraint.h" -#include "ConstraintSolver/HingeConstraint.h" - -#include "quickprof.h" -#include "IDebugDraw.h" - -#include "GLDebugDrawer.h" - - -#define QUAKE_BSP_IMPORTING 1 - -#ifdef QUAKE_BSP_IMPORTING -#include "BspLoader.h" -#include "BspConverter.h" -#endif //QUAKE_BSP_IMPORTING - - -#include "PHY_Pro.h" -#include "BMF_Api.h" -#include //printf debugging - -float deltaTime = 1.f/60.f; -float bulletSpeed = 40.f; - -#ifdef WIN32 -#if _MSC_VER >= 1310 -//only use SIMD Hull code under Win32 -#define USE_HULL 1 -#include "NarrowPhaseCollision/Hull.h" -#endif //_MSC_VER -#endif //WIN32 - - -#ifdef WIN32 //needed for glut.h -#include -#endif -//think different -#if defined(__APPLE__) && !defined (VMDMESA) -#include -#include -#include -#else -#include -#endif -#include "GL_ShapeDrawer.h" - -#include "GlutStuff.h" - - -extern float eye[3]; -extern int glutScreenWidth; -extern int glutScreenHeight; - - - -int numObjects = 0; - -const int maxNumObjects = 450; - -SimdTransform startTransforms[maxNumObjects]; - - -DefaultMotionState ms[maxNumObjects]; -CcdPhysicsController* physObjects[maxNumObjects] = {0,0,0,0}; - -CcdPhysicsEnvironment* physicsEnvironmentPtr = 0; - - -#define CUBE_HALF_EXTENTS 1 -#define EXTRA_HEIGHT -20.f - - -CollisionShape* gShapePtr[maxNumObjects];//1 rigidbody has 1 shape (no re-use of shapes) - -//////////////////////////////////// - -///Very basic import -CcdPhysicsController* CreatePhysicsObject(bool isDynamic, float mass, const SimdTransform& startTransform,CollisionShape* shape) -{ - - startTransforms[numObjects] = startTransform; - - PHY_ShapeProps shapeProps; - - shapeProps.m_do_anisotropic = false; - shapeProps.m_do_fh = false; - shapeProps.m_do_rot_fh = false; - shapeProps.m_friction_scaling[0] = 1.; - shapeProps.m_friction_scaling[1] = 1.; - shapeProps.m_friction_scaling[2] = 1.; - - shapeProps.m_inertia = 1.f; - shapeProps.m_lin_drag = 0.2f; - shapeProps.m_ang_drag = 0.1f; - shapeProps.m_mass = 10.0f; - - PHY_MaterialProps materialProps; - materialProps.m_friction = 10.5f; - materialProps.m_restitution = 0.0f; - - CcdConstructionInfo ccdObjectCi; - ccdObjectCi.m_friction = 0.5f; - - ccdObjectCi.m_linearDamping = shapeProps.m_lin_drag; - ccdObjectCi.m_angularDamping = shapeProps.m_ang_drag; - - SimdTransform tr; - tr.setIdentity(); - - int i = numObjects; - { - gShapePtr[i] = shape; - - shapeProps.m_shape = gShapePtr[i]; - shapeProps.m_shape->SetMargin(0.05f); - - SimdQuaternion orn = startTransform.getRotation(); - - - ms[i].setWorldOrientation(orn[0],orn[1],orn[2],orn[3]); - ms[i].setWorldPosition(startTransform.getOrigin().getX(),startTransform.getOrigin().getY(),startTransform.getOrigin().getZ()); - - ccdObjectCi.m_MotionState = &ms[i]; - ccdObjectCi.m_gravity = SimdVector3(0,-9.8,0); - ccdObjectCi.m_localInertiaTensor =SimdVector3(0,0,0); - if (!isDynamic) - { - shapeProps.m_mass = 0.f; - ccdObjectCi.m_mass = shapeProps.m_mass; - ccdObjectCi.m_collisionFlags = CollisionObject::isStatic; - } - else - { - shapeProps.m_mass = mass; - ccdObjectCi.m_mass = shapeProps.m_mass; - ccdObjectCi.m_collisionFlags = 0; - } - - - SimdVector3 localInertia(0.f,0.f,0.f); - - if (isDynamic) - { - gShapePtr[i]->CalculateLocalInertia(shapeProps.m_mass,localInertia); - } - - ccdObjectCi.m_localInertiaTensor = localInertia; - ccdObjectCi.m_collisionShape = gShapePtr[i]; - - - physObjects[i]= new CcdPhysicsController( ccdObjectCi); - - // Only do CCD if motion in one timestep (1.f/60.f) exceeds CUBE_HALF_EXTENTS - physObjects[i]->GetRigidBody()->m_ccdSquareMotionTreshold = 0.f; - - //Experimental: better estimation of CCD Time of Impact: - //physObjects[i]->GetRigidBody()->m_ccdSweptShereRadius = 0.5*CUBE_HALF_EXTENTS; - - physicsEnvironmentPtr->addCcdPhysicsController( physObjects[i]); - - } - - //return newly created PhysicsController - return physObjects[numObjects++]; -} - - - -///BspToBulletConverter extends the BspConverter to convert to Bullet datastructures -class BspToBulletConverter : public BspConverter -{ -public: - - virtual void AddConvexVerticesCollider(std::vector& vertices, bool isEntity, const SimdVector3& entityTargetLocation) - { - ///perhaps we can do something special with entities (isEntity) - ///like adding a collision Triggering (as example) - - if (vertices.size() > 0) - { - bool isDynamic = false; - float mass = 0.f; - SimdTransform startTransform; - //can use a shift - startTransform.setIdentity(); - startTransform.setOrigin(SimdVector3(0,0,-10.f)); - //this create an internal copy of the vertices - CollisionShape* shape = new ConvexHullShape(&vertices[0],vertices.size()); - - CreatePhysicsObject(isDynamic, mass, startTransform,shape); - } - } -}; - - - - - -//////////////////////////////////// - - - -GLDebugDrawer debugDrawer; - -char* makeExeToBspFilename(const char* lpCmdLine); -char* getLastFileName(); - - -int main(int argc,char** argv) -{ - - char* bspfilename = "BspDemo.bsp"; - - printf("argc=%i\n",argc); - { - for (int i=0;i1) - { - bspfilename = argv[1]; - } - - gCameraUp = SimdVector3(0,0,1); - gForwardAxis = 1; - - ///Setup a Physics Simulation Environment - CollisionDispatcher* dispatcher = new CollisionDispatcher(); - SimdVector3 worldAabbMin(-10000,-10000,-10000); - SimdVector3 worldAabbMax(10000,10000,10000); - OverlappingPairCache* broadphase = new AxisSweep3(worldAabbMin,worldAabbMax); - //BroadphaseInterface* broadphase = new SimpleBroadphase(); - physicsEnvironmentPtr = new CcdPhysicsEnvironment(dispatcher,broadphase); - physicsEnvironmentPtr->setDeactivationTime(2.f); - physicsEnvironmentPtr->setGravity(0,0,-10); - physicsEnvironmentPtr->setDebugDrawer(&debugDrawer); - - - -#ifdef QUAKE_BSP_IMPORTING - - void* memoryBuffer = 0; - - FILE* file = fopen(bspfilename,"r"); - if (!file) - { - //try again other path, - //sight... visual studio leaves the current working directory in the projectfiles folder - //instead of executable folder. who wants this default behaviour?!? - bspfilename = "../../BspDemo.bsp"; - file = fopen(bspfilename,"r"); - } - if (file) - { - BspLoader bspLoader; - int size=0; - if (fseek(file, 0, SEEK_END) || (size = ftell(file)) == EOF || fseek(file, 0, SEEK_SET)) { /* File operations denied? ok, just close and return failure */ - printf("Error: cannot get filesize from %s\n", bspfilename); - } else - { - //how to detect file size? - memoryBuffer = malloc(size+1); - fread(memoryBuffer,1,size,file); - bspLoader.LoadBSPFile( memoryBuffer); - - BspToBulletConverter bsp2bullet; - float bspScaling = 0.1f; - bsp2bullet.convertBsp(bspLoader,bspScaling); - - } - fclose(file); - } - -#endif - - - - - clientResetScene(); - - setCameraDistance(22.f); - - return glutmain(argc, argv,640,480,"Bullet Quake BSP Physics Viewer http://bullet.sourceforge.net"); -} - -//to be implemented by the demo -void renderme() -{ - debugDrawer.SetDebugMode(getDebugMode()); - - - - float m[16]; - int i; - - - if (getDebugMode() & IDebugDraw::DBG_DisableBulletLCP) - { - //don't use Bullet, use quickstep - physicsEnvironmentPtr->setSolverType(0); - } else - { - //Bullet LCP solver - physicsEnvironmentPtr->setSolverType(1); - } - - if (getDebugMode() & IDebugDraw::DBG_EnableCCD) - { - physicsEnvironmentPtr->setCcdMode(3); - } else - { - physicsEnvironmentPtr->setCcdMode(0); - } - - - bool isSatEnabled = (getDebugMode() & IDebugDraw::DBG_EnableSatComparison); - - physicsEnvironmentPtr->EnableSatCollisionDetection(isSatEnabled); - - - - for (i=0;iGetRigidBody()->GetActivationState() == 1) //active - { - if (i & 1) - { - wireColor += SimdVector3 (1.f,0.f,0.f); - } else - { - wireColor += SimdVector3 (.5f,0.f,0.f); - } - } - if (physObjects[i]->GetRigidBody()->GetActivationState() == 2) //ISLAND_SLEEPING - { - if (i & 1) - { - wireColor += SimdVector3 (0.f,1.f, 0.f); - } else - { - wireColor += SimdVector3 (0.f,0.5f,0.f); - } - } - - char extraDebug[125]; - - sprintf(extraDebug,"islandId=%i, Body=%i, ShapeType=%s",physObjects[i]->GetRigidBody()->m_islandTag1,physObjects[i]->GetRigidBody()->m_debugBodyId,physObjects[i]->GetRigidBody()->GetCollisionShape()->GetName()); - physObjects[i]->GetRigidBody()->GetCollisionShape()->SetExtraDebugInfo(extraDebug); - GL_ShapeDrawer::DrawOpenGL(m,physObjects[i]->GetRigidBody()->GetCollisionShape(),wireColor,getDebugMode()); - - ///this block is just experimental code to show some internal issues with replacing shapes on the fly. - if (getDebugMode()!=0 && (i>0)) - { - if (physObjects[i]->GetRigidBody()->GetCollisionShape()->GetShapeType() == EMPTY_SHAPE_PROXYTYPE) - { - physObjects[i]->GetRigidBody()->SetCollisionShape(gShapePtr[1]); - - //remove the persistent collision pairs that were created based on the previous shape - - BroadphaseProxy* bpproxy = physObjects[i]->GetRigidBody()->m_broadphaseHandle; - - physicsEnvironmentPtr->GetBroadphase()->CleanProxyFromPairs(bpproxy); - - SimdVector3 newinertia; - SimdScalar newmass = 10.f; - physObjects[i]->GetRigidBody()->GetCollisionShape()->CalculateLocalInertia(newmass,newinertia); - physObjects[i]->GetRigidBody()->setMassProps(newmass,newinertia); - physObjects[i]->GetRigidBody()->updateInertiaTensor(); - - } - - } - - - } - - if (!(getDebugMode() & IDebugDraw::DBG_NoHelpText)) - { - - float xOffset = 10.f; - float yStart = 20.f; - - float yIncr = -2.f; - - SimdVector3 offset(xOffset,0,0); - SimdVector3 up = gCameraUp; - char buf[124]; - - glColor3f(0, 0, 0); - -#ifdef USE_QUICKPROF - - - if ( getDebugMode() & IDebugDraw::DBG_ProfileTimings) - { - static int counter = 0; - counter++; - std::map::iterator iter; - for (iter = Profiler::mProfileBlocks.begin(); iter != Profiler::mProfileBlocks.end(); ++iter) - { - char blockTime[128]; - sprintf(blockTime, "%s: %lf",&((*iter).first[0]),Profiler::getBlockTime((*iter).first, Profiler::BLOCK_CYCLE_SECONDS));//BLOCK_TOTAL_PERCENT)); - glRasterPos3f(xOffset,yStart,0); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),blockTime); - yStart += yIncr; - - } - } -#endif //USE_QUICKPROF - //profiling << Profiler::createStatsString(Profiler::BLOCK_TOTAL_PERCENT); - //<< std::endl; - - - SimdVector3 textPos = offset + up*yStart; - glRasterPos3f(textPos.getX(),textPos.getY(),textPos.getZ()); - sprintf(buf,"leftmouse to pick"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - - yStart += yIncr; - textPos = offset + up*yStart; - glRasterPos3f(textPos.getX(),textPos.getY(),textPos.getZ()); - sprintf(buf,"rightmouse or . to shoot box"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - textPos = offset + up*yStart; - glRasterPos3f(textPos.getX(),textPos.getY(),textPos.getZ()); - sprintf(buf,"space to reset"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - textPos = offset + up*yStart; - glRasterPos3f(textPos.getX(),textPos.getY(),textPos.getZ()); - - sprintf(buf,"cursor keys and z,x to navigate"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - textPos = offset + up*yStart ; - glRasterPos3f(textPos.getX(),textPos.getY(),textPos.getZ()); - - sprintf(buf,"i to toggle simulation, s single step"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - textPos = offset + up*yStart ; - glRasterPos3f(textPos.getX(),textPos.getY(),textPos.getZ()); - - sprintf(buf,"q to quit"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - textPos = offset + up*yStart ; - glRasterPos3f(textPos.getX(),textPos.getY(),textPos.getZ()); - - sprintf(buf,"d to toggle deactivation"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - textPos = offset + up*yStart ; - glRasterPos3f(textPos.getX(),textPos.getY(),textPos.getZ()); - - sprintf(buf,"a to draw temporal AABBs"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - - textPos = offset + up*yStart ; - glRasterPos3f(textPos.getX(),textPos.getY(),textPos.getZ()); - sprintf(buf,"c to show contact points (wireframe more)"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - - textPos = offset + up*yStart ; - glRasterPos3f(textPos.getX(),textPos.getY(),textPos.getZ()); - - - sprintf(buf,"h to toggle help text"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - bool useBulletLCP = !(getDebugMode() & IDebugDraw::DBG_DisableBulletLCP); - - bool useCCD = (getDebugMode() & IDebugDraw::DBG_EnableCCD); - - textPos = offset + up*yStart ; - glRasterPos3f(textPos.getX(),textPos.getY(),textPos.getZ()); - - - sprintf(buf,"m Bullet GJK = %i",!isSatEnabled); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - textPos = offset + up*yStart ; - glRasterPos3f(textPos.getX(),textPos.getY(),textPos.getZ()); - - sprintf(buf,"n Bullet LCP = %i",useBulletLCP); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - textPos = offset + up*yStart ; - glRasterPos3f(textPos.getX(),textPos.getY(),textPos.getZ()); - - sprintf(buf,"1 CCD mode (adhoc) = %i",useCCD); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - textPos = offset + up*yStart ; - glRasterPos3f(textPos.getX(),textPos.getY(),textPos.getZ()); - - sprintf(buf,"+- shooting speed = %10.2f",bulletSpeed); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - } - -} - -void clientMoveAndDisplay() -{ - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - physicsEnvironmentPtr->proceedDeltaTime(0.f,deltaTime); - - renderme(); - - glFlush(); - glutSwapBuffers(); - -} - - - -void clientDisplay(void) { - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - - physicsEnvironmentPtr->UpdateAabbs(deltaTime); - - renderme(); - - - glFlush(); - glutSwapBuffers(); -} - - - -///make this positive to show stack falling from a distance -///this shows the penalty tresholds in action, springy/spungy look - -void clientResetScene() -{ - for (int i=0;isetPosition(startTransforms[i].getOrigin().getX(),startTransforms[i].getOrigin().getY(),startTransforms[i].getOrigin().getZ()); - physObjects[i]->SetLinearVelocity(0,0,0,0); - physObjects[i]->SetAngularVelocity(0,0,0,0); - SimdQuaternion orn; - startTransforms[i].getBasis().getRotation(orn); - physObjects[i]->setOrientation(orn.x(),orn.y(),orn.z(),orn[3]); - - } - - //delete and reload, or keep transforms ready? -} - - - -void shootBox(const SimdVector3& destination) -{ - - bool isDynamic = true; - float mass = 1.f; - SimdTransform startTransform; - startTransform.setIdentity(); - startTransform.setOrigin(SimdVector3(eye[0],eye[1],eye[2])); - CollisionShape* boxShape = new BoxShape(SimdVector3(1.f,1.f,1.f)); - - CreatePhysicsObject(isDynamic, mass, startTransform,boxShape); - - int i = numObjects-1; - - - - SimdVector3 linVel(destination[0]-eye[0],destination[1]-eye[1],destination[2]-eye[2]); - linVel.normalize(); - linVel*=bulletSpeed; - - physObjects[i]->setPosition(eye[0],eye[1],eye[2]); - physObjects[i]->setOrientation(0,0,0,1); - physObjects[i]->SetLinearVelocity(linVel[0],linVel[1],linVel[2],false); - physObjects[i]->SetAngularVelocity(0,0,0,false); -} - -void clientSpecialKeyboard(int key, int x, int y) +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "CcdPhysicsEnvironment.h" +#include "CcdPhysicsController.h" + +//#include "GL_LineSegmentShape.h" +#include "CollisionShapes/BoxShape.h" +#include "CollisionShapes/SphereShape.h" +#include "CollisionShapes/CylinderShape.h" +#include "CollisionShapes/ConeShape.h" +#include "CollisionShapes/StaticPlaneShape.h" +#include "CollisionShapes/ConvexHullShape.h" +#include "CollisionShapes/TriangleMesh.h" +#include "CollisionShapes/ConvexTriangleMeshShape.h" +#include "CollisionShapes/TriangleMeshShape.h" +#include "CollisionShapes/TriangleIndexVertexArray.h" +#include "CollisionShapes/CompoundShape.h" + + + +#include "CollisionShapes/Simplex1to4Shape.h" +#include "CollisionShapes/EmptyShape.h" + +#include "Dynamics/RigidBody.h" +#include "CollisionDispatch/CollisionDispatcher.h" +#include "BroadphaseCollision/SimpleBroadphase.h" +#include "BroadphaseCollision/AxisSweep3.h" +#include "ConstraintSolver/Point2PointConstraint.h" +#include "ConstraintSolver/HingeConstraint.h" + +#include "quickprof.h" +#include "IDebugDraw.h" + +#include "GLDebugDrawer.h" + + +#define QUAKE_BSP_IMPORTING 1 + +#ifdef QUAKE_BSP_IMPORTING +#include "BspLoader.h" +#include "BspConverter.h" +#endif //QUAKE_BSP_IMPORTING + +#include "PHY_Pro.h" +#include "BMF_Api.h" +#include //printf debugging + +float deltaTime = 1.f/60.f; +#include "BspDemo.h" +#include "GL_ShapeDrawer.h" +#include "GlutStuff.h" + + + + +#define CUBE_HALF_EXTENTS 1 +#define EXTRA_HEIGHT -20.f + + + +///BspToBulletConverter extends the BspConverter to convert to Bullet datastructures +class BspToBulletConverter : public BspConverter { - defaultSpecialKeyboard(key,x,y); -} - -void clientKeyboard(unsigned char key, int x, int y) -{ - - if (key == '.') - { - shootBox(SimdVector3(0,0,0)); - } - - if (key == '+') - { - bulletSpeed += 10.f; - } - if (key == '-') - { - bulletSpeed -= 10.f; - } - - defaultKeyboard(key, x, y); -} - -int gPickingConstraintId = 0; -SimdVector3 gOldPickingPos; -float gOldPickingDist = 0.f; -RigidBody* pickedBody = 0;//for deactivation state - - - -SimdVector3 GetRayTo(int x,int y) -{ - float top = 1.f; - float bottom = -1.f; - float nearPlane = 1.f; - float tanFov = (top-bottom)*0.5f / nearPlane; - float fov = 2.0 * atanf (tanFov); - - SimdVector3 rayFrom(eye[0],eye[1],eye[2]); - SimdVector3 rayForward = -rayFrom; - rayForward.normalize(); - float farPlane = 600.f; - rayForward*= farPlane; - - SimdVector3 rightOffset; - SimdVector3 vertical = gCameraUp; - - SimdVector3 hor; - hor = rayForward.cross(vertical); - hor.normalize(); - vertical = hor.cross(rayForward); - vertical.normalize(); - - float tanfov = tanf(0.5f*fov); - hor *= 2.f * farPlane * tanfov; - vertical *= 2.f * farPlane * tanfov; - SimdVector3 rayToCenter = rayFrom + rayForward; - SimdVector3 dHor = hor * 1.f/float(glutScreenWidth); - SimdVector3 dVert = vertical * 1.f/float(glutScreenHeight); - SimdVector3 rayTo = rayToCenter - 0.5f * hor + 0.5f * vertical; - rayTo += x * dHor; - rayTo -= y * dVert; - return rayTo; -} -void clientMouseFunc(int button, int state, int x, int y) -{ - //printf("button %i, state %i, x=%i,y=%i\n",button,state,x,y); - //button 0, state 0 means left mouse down - - SimdVector3 rayTo = GetRayTo(x,y); - - switch (button) - { - case 2: - { - if (state==0) - { - shootBox(rayTo); - } - break; - }; - case 1: - { - if (state==0) - { - //apply an impulse - if (physicsEnvironmentPtr) - { - float hit[3]; - float normal[3]; - PHY_IPhysicsController* hitObj = physicsEnvironmentPtr->rayTest(0,eye[0],eye[1],eye[2],rayTo.getX(),rayTo.getY(),rayTo.getZ(),hit[0],hit[1],hit[2],normal[0],normal[1],normal[2]); - if (hitObj) - { - CcdPhysicsController* physCtrl = static_cast(hitObj); - RigidBody* body = physCtrl->GetRigidBody(); - if (body) - { - body->SetActivationState(ACTIVE_TAG); - SimdVector3 impulse = rayTo; - impulse.normalize(); - float impulseStrength = 10.f; - impulse *= impulseStrength; - SimdVector3 relPos( - hit[0] - body->getCenterOfMassPosition().getX(), - hit[1] - body->getCenterOfMassPosition().getY(), - hit[2] - body->getCenterOfMassPosition().getZ()); - - body->applyImpulse(impulse,relPos); - } - - } - - } - - } else - { - - } - break; - } - case 0: - { - if (state==0) - { - //add a point to point constraint for picking - if (physicsEnvironmentPtr) - { - float hit[3]; - float normal[3]; - PHY_IPhysicsController* hitObj = physicsEnvironmentPtr->rayTest(0,eye[0],eye[1],eye[2],rayTo.getX(),rayTo.getY(),rayTo.getZ(),hit[0],hit[1],hit[2],normal[0],normal[1],normal[2]); - if (hitObj) - { - - CcdPhysicsController* physCtrl = static_cast(hitObj); - RigidBody* body = physCtrl->GetRigidBody(); - - if (body && !body->IsStatic()) - { - pickedBody = body; - pickedBody->SetActivationState(DISABLE_DEACTIVATION); - - SimdVector3 pickPos(hit[0],hit[1],hit[2]); - - SimdVector3 localPivot = body->getCenterOfMassTransform().inverse() * pickPos; - - gPickingConstraintId = physicsEnvironmentPtr->createConstraint(physCtrl,0,PHY_POINT2POINT_CONSTRAINT, - localPivot.getX(), - localPivot.getY(), - localPivot.getZ(), - 0,0,0); - //printf("created constraint %i",gPickingConstraintId); - - //save mouse position for dragging - gOldPickingPos = rayTo; - - - SimdVector3 eyePos(eye[0],eye[1],eye[2]); - - gOldPickingDist = (pickPos-eyePos).length(); - - Point2PointConstraint* p2p = static_cast(physicsEnvironmentPtr->getConstraintById(gPickingConstraintId)); - if (p2p) - { - //very weak constraint for picking - p2p->m_setting.m_tau = 0.1f; - } - } - } - } - } else - { - if (gPickingConstraintId && physicsEnvironmentPtr) - { - physicsEnvironmentPtr->removeConstraint(gPickingConstraintId); - //printf("removed constraint %i",gPickingConstraintId); - gPickingConstraintId = 0; - pickedBody->ForceActivationState(ACTIVE_TAG); - pickedBody->m_deactivationTime = 0.f; - pickedBody = 0; - - - } - } - - break; - - } - default: - { - } - } - -} - -void clientMotionFunc(int x,int y) -{ - - if (gPickingConstraintId && physicsEnvironmentPtr) - { - - //move the constraint pivot - - Point2PointConstraint* p2p = static_cast(physicsEnvironmentPtr->getConstraintById(gPickingConstraintId)); - if (p2p) - { - //keep it at the same picking distance - - SimdVector3 newRayTo = GetRayTo(x,y); - SimdVector3 eyePos(eye[0],eye[1],eye[2]); - SimdVector3 dir = newRayTo-eyePos; - dir.normalize(); - dir *= gOldPickingDist; - - SimdVector3 newPos = eyePos + dir; - p2p->SetPivotB(newPos); - } - - } -} - -//some code that de-mangles the windows filename passed in as argument -char cleaned_filename[512]; -char* getLastFileName() -{ - return cleaned_filename; -} -char* makeExeToBspFilename(const char* lpCmdLine) -{ - - - // We might get a windows-style path on the command line, this can mess up the DOM which expects - // all paths to be URI's. This block of code does some conversion to try and make the input - // compliant without breaking the ability to accept a properly formatted URI. Right now this only - // displays the first filename - const char *in = lpCmdLine; - char* out = cleaned_filename; - *out = NULL; - // If the first character is a ", skip it (filenames with spaces in them are quoted) - if(*in == '\"') - { - in++; - } - if(*(in+1) == ':') - { - // Second character is a :, assume we have a path with a drive letter and add a slash at the beginning - *(out++) = '/'; - } - int i; - for(i =0; i<512; i++) - { - //if we get '.' we stop as well, unless it's the first character. Then we add .bsp as extension - // If we hit a null or a quote, stop copying. This will get just the first filename. - if(i && (*in == '.')) - break; - - // If we hit a null or a quote, stop copying. This will get just the first filename. - if(*in == NULL || *in == '\"') - break; - // Copy while swapping backslashes for forward ones - if(*in == '\\') - { - *out = '/'; - } - else - { - *out = *in; - } - in++; - out++; - } - *(out++) = '.'; - *(out++) = 'b'; - *(out++) = 's'; - *(out++) = 'p'; - *(out++) = 0; - - return cleaned_filename; -} + DemoApplication* m_demoApp; + +public: + + BspToBulletConverter(DemoApplication* demoApp) + :m_demoApp(demoApp) + { + } + + virtual void AddConvexVerticesCollider(std::vector& vertices, bool isEntity, const SimdVector3& entityTargetLocation) + { + ///perhaps we can do something special with entities (isEntity) + ///like adding a collision Triggering (as example) + + if (vertices.size() > 0) + { + bool isDynamic = false; + float mass = 0.f; + SimdTransform startTransform; + //can use a shift + startTransform.setIdentity(); + startTransform.setOrigin(SimdVector3(0,0,-10.f)); + //this create an internal copy of the vertices + CollisionShape* shape = new ConvexHullShape(&vertices[0],vertices.size()); + + m_demoApp->LocalCreatePhysicsObject(isDynamic, mass, startTransform,shape); + } + } +}; + + + + + +//////////////////////////////////// + + + +GLDebugDrawer debugDrawer; + +char* makeExeToBspFilename(const char* lpCmdLine); +char* getLastFileName(); + + +int main(int argc,char** argv) +{ + + BspDemo* bspDemo = new BspDemo(); + + char* bspfilename = "BspDemo.bsp"; + + printf("argc=%i\n",argc); + { + for (int i=0;i1) + { + bspfilename = argv[1]; + } + + bspDemo->initPhysics(bspfilename); + + bspDemo->setCameraDistance(22.f); + + return glutmain(argc, argv,640,480,"Bullet Quake BSP Physics Viewer http://bullet.sourceforge.net",bspDemo); +} + +void BspDemo::initPhysics(char* bspfilename) +{ + + + m_cameraUp = SimdVector3(0,0,1); + m_forwardAxis = 1; + + ///Setup a Physics Simulation Environment + CollisionDispatcher* dispatcher = new CollisionDispatcher(); + SimdVector3 worldAabbMin(-10000,-10000,-10000); + SimdVector3 worldAabbMax(10000,10000,10000); + OverlappingPairCache* broadphase = new AxisSweep3(worldAabbMin,worldAabbMax); + //BroadphaseInterface* broadphase = new SimpleBroadphase(); + m_physicsEnvironmentPtr = new CcdPhysicsEnvironment(dispatcher,broadphase); + m_physicsEnvironmentPtr->setDeactivationTime(2.f); + m_physicsEnvironmentPtr->setGravity(0,0,-10); + m_physicsEnvironmentPtr->setDebugDrawer(&debugDrawer); + + + +#ifdef QUAKE_BSP_IMPORTING + + void* memoryBuffer = 0; + + FILE* file = fopen(bspfilename,"r"); + if (!file) + { + //try again other path, + //sight... visual studio leaves the current working directory in the projectfiles folder + //instead of executable folder. who wants this default behaviour?!? + bspfilename = "../../BspDemo.bsp"; + file = fopen(bspfilename,"r"); + } + if (file) + { + BspLoader bspLoader; + int size=0; + if (fseek(file, 0, SEEK_END) || (size = ftell(file)) == EOF || fseek(file, 0, SEEK_SET)) { /* File operations denied? ok, just close and return failure */ + printf("Error: cannot get filesize from %s\n", bspfilename); + } else + { + //how to detect file size? + memoryBuffer = malloc(size+1); + fread(memoryBuffer,1,size,file); + bspLoader.LoadBSPFile( memoryBuffer); + + BspToBulletConverter bsp2bullet(this); + float bspScaling = 0.1f; + bsp2bullet.convertBsp(bspLoader,bspScaling); + + } + fclose(file); + } + +#endif + + + + + clientResetScene(); + +} + + +void BspDemo::clientMoveAndDisplay() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + m_physicsEnvironmentPtr->proceedDeltaTime(0.f,deltaTime); + + renderme(); + + glFlush(); + glutSwapBuffers(); + +} + + + +void BspDemo::displayCallback(void) { + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + + m_physicsEnvironmentPtr->UpdateAabbs(deltaTime); + + renderme(); + + + glFlush(); + glutSwapBuffers(); +} + + + + + + +//some code that de-mangles the windows filename passed in as argument +char cleaned_filename[512]; +char* getLastFileName() +{ + return cleaned_filename; +} +char* makeExeToBspFilename(const char* lpCmdLine) +{ + + + // We might get a windows-style path on the command line, this can mess up the DOM which expects + // all paths to be URI's. This block of code does some conversion to try and make the input + // compliant without breaking the ability to accept a properly formatted URI. Right now this only + // displays the first filename + const char *in = lpCmdLine; + char* out = cleaned_filename; + *out = NULL; + // If the first character is a ", skip it (filenames with spaces in them are quoted) + if(*in == '\"') + { + in++; + } + if(*(in+1) == ':') + { + // Second character is a :, assume we have a path with a drive letter and add a slash at the beginning + *(out++) = '/'; + } + int i; + for(i =0; i<512; i++) + { + //if we get '.' we stop as well, unless it's the first character. Then we add .bsp as extension + // If we hit a null or a quote, stop copying. This will get just the first filename. + if(i && (*in == '.')) + break; + + // If we hit a null or a quote, stop copying. This will get just the first filename. + if(*in == NULL || *in == '\"') + break; + // Copy while swapping backslashes for forward ones + if(*in == '\\') + { + *out = '/'; + } + else + { + *out = *in; + } + in++; + out++; + } + *(out++) = '.'; + *(out++) = 'b'; + *(out++) = 's'; + *(out++) = 'p'; + *(out++) = 0; + + return cleaned_filename; +} diff --git a/Demos/CcdPhysicsDemo/CcdPhysicsDemo.cpp b/Demos/CcdPhysicsDemo/CcdPhysicsDemo.cpp index 13f418f41..cb293a48c 100644 --- a/Demos/CcdPhysicsDemo/CcdPhysicsDemo.cpp +++ b/Demos/CcdPhysicsDemo/CcdPhysicsDemo.cpp @@ -57,30 +57,8 @@ subject to the following restrictions: #include //printf debugging float deltaTime = 1.f/60.f; -float bulletSpeed = 40.f; - -#ifdef WIN32 -#if _MSC_VER >= 1310 -//only use SIMD Hull code under Win32 -#define USE_HULL 1 -#include "NarrowPhaseCollision/Hull.h" -#endif //_MSC_VER -#endif //WIN32 - - -#ifdef WIN32 //needed for glut.h -#include -#endif - -//think different -#if defined(__APPLE__) && !defined (VMDMESA) -#include -#include -#include -#else -#include -#endif +#include "CcdPhysicsDemo.h" #include "GL_ShapeDrawer.h" #include "GlutStuff.h" @@ -105,14 +83,12 @@ const int numObjects = 120; const int maxNumObjects = 32760; -MyMotionState ms[maxNumObjects]; -CcdPhysicsController* physObjects[maxNumObjects] = {0,0,0,0}; int shapeIndex[maxNumObjects]; #ifdef USE_PARALLEL_DISPATCHER -ParallelPhysicsEnvironment* physicsEnvironmentPtr = 0; +ParallelPhysicsEnvironment* m_physicsEnvironmentPtr = 0; #else -CcdPhysicsEnvironment* physicsEnvironmentPtr = 0; +CcdPhysicsEnvironment* m_physicsEnvironmentPtr = 0; #endif #define CUBE_HALF_EXTENTS 1 @@ -160,6 +136,117 @@ GLDebugDrawer debugDrawer; int main(int argc,char** argv) { + CcdPhysicsDemo* ccdDemo = new CcdPhysicsDemo(); + + ccdDemo->initPhysics(); + + ccdDemo->setCameraDistance(26.f); + + return glutmain(argc, argv,640,480,"Bullet Physics Demo. http://www.continuousphysics.com/Bullet/phpBB2/",ccdDemo); +} + + + +void CcdPhysicsDemo::clientMoveAndDisplay() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + + + if (m_physicsEnvironmentPtr) + m_physicsEnvironmentPtr->proceedDeltaTime(0.f,deltaTime); + +#ifdef USE_QUICKPROF + Profiler::beginBlock("render"); +#endif //USE_QUICKPROF + + renderme(); + +#ifdef USE_QUICKPROF + Profiler::endBlock("render"); +#endif + glFlush(); + glutSwapBuffers(); + +} + + + +void CcdPhysicsDemo::displayCallback(void) { + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + if (m_physicsEnvironmentPtr) + { + m_physicsEnvironmentPtr->UpdateAabbs(deltaTime); + //draw contactpoints + m_physicsEnvironmentPtr->CallbackTriggers(); + } + + renderme(); + + + glFlush(); + glutSwapBuffers(); +} + + + +///make this positive to show stack falling from a distance +///this shows the penalty tresholds in action, springy/spungy look + +void CcdPhysicsDemo::clientResetScene() +{ + + + int i; + int numObjects = m_physicsEnvironmentPtr->GetNumControllers(); + + for (i=0;i0) + { + CcdPhysicsController* ctrl = m_physicsEnvironmentPtr->GetPhysicsController(i); + + if ((getDebugMode() & IDebugDraw::DBG_NoHelpText)) + { + if (ctrl->GetRigidBody()->GetCollisionShape()->GetShapeType() != SPHERE_SHAPE_PROXYTYPE) + { + ctrl->GetRigidBody()->SetCollisionShape(shapePtr[2]); + } else + { + ctrl->GetRigidBody()->SetCollisionShape(shapePtr[1]); + } + + BroadphaseProxy* bpproxy = ctrl->GetRigidBody()->m_broadphaseHandle; + m_physicsEnvironmentPtr->GetBroadphase()->CleanProxyFromPairs(bpproxy); + } + + //stack them + int colsize = 10; + int row = (i*CUBE_HALF_EXTENTS*2)/(colsize*2*CUBE_HALF_EXTENTS); + int row2 = row; + int col = (i)%(colsize)-colsize/2; + + + if (col>3) + { + col=11; + row2 |=1; + } + ctrl->setPosition(col*2*CUBE_HALF_EXTENTS + (row2%2)*CUBE_HALF_EXTENTS, + row*2*CUBE_HALF_EXTENTS+CUBE_HALF_EXTENTS+EXTRA_HEIGHT,0); + ctrl->setOrientation(0,0,0,1); + ctrl->SetLinearVelocity(0,0,0,false); + ctrl->SetAngularVelocity(0,0,0,false); + } + } +} + + +void CcdPhysicsDemo::initPhysics() +{ CollisionDispatcher* dispatcher = new CollisionDispatcher(); ParallelIslandDispatcher* dispatcher2 = new ParallelIslandDispatcher(); @@ -171,92 +258,18 @@ int main(int argc,char** argv) //OverlappingPairCache* broadphase = new SimpleBroadphase(maxProxies,maxOverlap); #ifdef USE_PARALLEL_DISPATCHER - physicsEnvironmentPtr = new ParallelPhysicsEnvironment(dispatcher2,broadphase); + m_physicsEnvironmentPtr = new ParallelPhysicsEnvironment(dispatcher2,broadphase); #else - physicsEnvironmentPtr = new CcdPhysicsEnvironment(dispatcher,broadphase); + m_physicsEnvironmentPtr = new CcdPhysicsEnvironment(dispatcher,broadphase); #endif - physicsEnvironmentPtr->setDeactivationTime(2.f); + m_physicsEnvironmentPtr->setDeactivationTime(2.f); + + m_physicsEnvironmentPtr->setGravity(0,-10,0); + + m_physicsEnvironmentPtr->setDebugDrawer(&debugDrawer); - physicsEnvironmentPtr->setGravity(0,-10,0);//0,0);//-10,0); int i; -//#define USE_TRIMESH_GROUND 1 -#ifdef USE_TRIMESH_GROUND - - -const float TRIANGLE_SIZE=20.f; - - //create a triangle-mesh ground - int vertStride = sizeof(SimdVector3); - int indexStride = 3*sizeof(int); - - const int NUM_VERTS_X = 50; - const int NUM_VERTS_Y = 50; - const int totalVerts = NUM_VERTS_X*NUM_VERTS_Y; - - const int totalTriangles = 2*(NUM_VERTS_X-1)*(NUM_VERTS_Y-1); - - SimdVector3* gVertices = new SimdVector3[totalVerts]; - int* gIndices = new int[totalTriangles*3]; - - - - for ( i=0;iSetMargin(0.05f); - - + CollisionShape* shape = shapePtr[shapeIndex[i]]; + shape->SetMargin(0.05f); bool isDyna = i>0; - //if (i==1) - // isDyna=false; - if (0)//i==1) - { - SimdQuaternion orn(0,0,0.1*SIMD_HALF_PI); - ms[i].setWorldOrientation(orn.x(),orn.y(),orn.z(),orn[3]); - } - - - if (i>0) - { - - switch (i) - { - case 1: - { - ms[i].setWorldPosition(0,10,0); - //for testing, rotate the ground cube so the stack has to recover a bit - - break; - } - case 2: - { - ms[i].setWorldPosition(0,8,2); - break; - } - default: - ms[i].setWorldPosition(0,i*CUBE_HALF_EXTENTS*2 - CUBE_HALF_EXTENTS,0); - } - - float quatIma0,quatIma1,quatIma2,quatReal; - SimdQuaternion quat; - SimdVector3 axis(0,0,1); - SimdScalar angle=0.5f; - - quat.setRotation(axis,angle); - - ms[i].setWorldOrientation(quat.getX(),quat.getY(),quat.getZ(),quat[3]); - - - - } else - { - ms[i].setWorldPosition(0,-10+EXTRA_HEIGHT,0); - - } - - ccdObjectCi.m_MotionState = &ms[i]; - ccdObjectCi.m_gravity = SimdVector3(0,0,0); - ccdObjectCi.m_localInertiaTensor =SimdVector3(0,0,0); - if (!isDyna) - { - shapeProps.m_mass = 0.f; - ccdObjectCi.m_mass = shapeProps.m_mass; - ccdObjectCi.m_collisionFlags = CollisionObject::isStatic; - - ccdObjectCi.m_collisionFilterGroup = CcdConstructionInfo::StaticFilter; - ccdObjectCi.m_collisionFilterMask = CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::StaticFilter; - } - else - { - shapeProps.m_mass = 1.f; - ccdObjectCi.m_mass = shapeProps.m_mass; - ccdObjectCi.m_collisionFlags = 0; - - } - - - SimdVector3 localInertia(0.f,0.f,0.f); - if (shapeIndex[i]) - { - if (shapePtr[shapeIndex[i]]->GetShapeType() == EMPTY_SHAPE_PROXYTYPE) - { - //take inertia from first shape - shapePtr[1]->CalculateLocalInertia(shapeProps.m_mass,localInertia); - } else - { - shapePtr[shapeIndex[i]]->CalculateLocalInertia(shapeProps.m_mass,localInertia); - } - - } - ccdObjectCi.m_localInertiaTensor = localInertia; + SimdTransform trans; + trans.setIdentity(); - ccdObjectCi.m_collisionShape = shapePtr[shapeIndex[i]]; + trans.setOrigin(SimdVector3(0,-30+i*CUBE_HALF_EXTENTS*2,0)); + float mass = 1.f; - - physObjects[i]= new CcdPhysicsController( ccdObjectCi); + if (!isDyna) + mass = 0.f; + + CcdPhysicsController* ctrl = LocalCreatePhysicsObject(isDyna,mass,trans,shape); // Only do CCD if motion in one timestep (1.f/60.f) exceeds CUBE_HALF_EXTENTS - physObjects[i]->GetRigidBody()->m_ccdSquareMotionTreshold = CUBE_HALF_EXTENTS; + ctrl->GetRigidBody()->m_ccdSquareMotionTreshold = CUBE_HALF_EXTENTS; //Experimental: better estimation of CCD Time of Impact: - physObjects[i]->GetRigidBody()->m_ccdSweptShereRadius = 0.2*CUBE_HALF_EXTENTS; - - physicsEnvironmentPtr->addCcdPhysicsController( physObjects[i]); - - if (i==1) - { - //physObjects[i]->SetAngularVelocity(0,0,-2,true); - } - - physicsEnvironmentPtr->setDebugDrawer(&debugDrawer); + ctrl->GetRigidBody()->m_ccdSweptShereRadius = 0.2*CUBE_HALF_EXTENTS; + } clientResetScene(); - physicsEnvironmentPtr->SyncMotionStates(0.f); - if (createConstraint) - { - //physObjects[i]->SetAngularVelocity(0,0,-2,true); - int constraintId; - - float pivotX=CUBE_HALF_EXTENTS, - pivotY=CUBE_HALF_EXTENTS, - pivotZ=CUBE_HALF_EXTENTS; - float axisX=0,axisY=1,axisZ=0; - - - constraintId =physicsEnvironmentPtr->createConstraint( - physObjects[1], - //0, - physObjects[2], - ////PHY_POINT2POINT_CONSTRAINT, - PHY_GENERIC_6DOF_CONSTRAINT,//can leave any of the 6 degree of freedom 'free' or 'locked' - //PHY_LINEHINGE_CONSTRAINT, - pivotX,pivotY,pivotZ, - axisX,axisY,axisZ - ); - - } + m_physicsEnvironmentPtr->SyncMotionStates(0.f); +} - setCameraDistance(26.f); - - return glutmain(argc, argv,640,480,"Bullet Physics Demo. http://www.continuousphysics.com/Bullet/phpBB2/"); -} - -//to be implemented by the demo -void renderme() -{ - debugDrawer.SetDebugMode(getDebugMode()); - - //render the hinge axis - if (createConstraint) - { - SimdVector3 color(1,0,0); - SimdVector3 dirLocal(0,1,0); - SimdVector3 pivotInA(CUBE_HALF_EXTENTS,-CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS); - SimdVector3 pivotInB(-CUBE_HALF_EXTENTS,-CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS); - SimdVector3 from = physObjects[1]->GetRigidBody()->getCenterOfMassTransform()(pivotInA); - SimdVector3 fromB = physObjects[2]->GetRigidBody()->getCenterOfMassTransform()(pivotInB); - SimdVector3 dirWorldA = physObjects[1]->GetRigidBody()->getCenterOfMassTransform().getBasis() * dirLocal ; - SimdVector3 dirWorldB = physObjects[2]->GetRigidBody()->getCenterOfMassTransform().getBasis() * dirLocal ; - debugDrawer.DrawLine(from,from+dirWorldA,color); - debugDrawer.DrawLine(fromB,fromB+dirWorldB,color); - } - - float m[16]; - int i; - - - if (getDebugMode() & IDebugDraw::DBG_DisableBulletLCP) - { - //don't use Bullet, use quickstep - physicsEnvironmentPtr->setSolverType(0); - } else - { - //Bullet LCP solver - physicsEnvironmentPtr->setSolverType(1); - } - - if (getDebugMode() & IDebugDraw::DBG_EnableCCD) - { - physicsEnvironmentPtr->setCcdMode(3); - } else - { - physicsEnvironmentPtr->setCcdMode(0); - } - - - bool isSatEnabled = (getDebugMode() & IDebugDraw::DBG_EnableSatComparison); - - physicsEnvironmentPtr->EnableSatCollisionDetection(isSatEnabled); - - -#ifdef USE_HULL - //some testing code for SAT - if (isSatEnabled) - { - for (int s=0;sIsPolyhedral()) - { - PolyhedralConvexShape* polyhedron = static_cast(shape); - if (!polyhedron->m_optionalHull) - { - //first convert vertices in 'Point3' format - int numPoints = polyhedron->GetNumVertices(); - Point3* points = new Point3[numPoints+1]; - //first 4 points should not be co-planar, so add central point to satisfy MakeHull - points[0] = Point3(0.f,0.f,0.f); - - SimdVector3 vertex; - for (int p=0;pGetVertex(p,vertex); - points[p+1] = Point3(vertex.getX(),vertex.getY(),vertex.getZ()); - } - - Hull* hull = Hull::MakeHull(numPoints+1,points); - polyhedron->m_optionalHull = hull; - } - - } - } - - } -#endif //USE_HULL - - - for (i=0;iGetRigidBody()->GetActivationState() == 1) //active - { - if (i & 1) - { - wireColor += SimdVector3 (1.f,0.f,0.f); - } else - { - wireColor += SimdVector3 (.5f,0.f,0.f); - } - } - if (physObjects[i]->GetRigidBody()->GetActivationState() == 2) //ISLAND_SLEEPING - { - if (i & 1) - { - wireColor += SimdVector3 (0.f,1.f, 0.f); - } else - { - wireColor += SimdVector3 (0.f,0.5f,0.f); - } - } - - char extraDebug[125]; - sprintf(extraDebug,"islId, Body=%i , %i",physObjects[i]->GetRigidBody()->m_islandTag1,physObjects[i]->GetRigidBody()->m_debugBodyId); - physObjects[i]->GetRigidBody()->GetCollisionShape()->SetExtraDebugInfo(extraDebug); - - float vec[16]; - SimdTransform ident; - ident.setIdentity(); - ident.getOpenGLMatrix(vec); - glPushMatrix(); - - glLoadMatrixf(vec); - - GL_ShapeDrawer::DrawOpenGL(m,physObjects[i]->GetRigidBody()->GetCollisionShape(),wireColor,getDebugMode()); - - glPopMatrix(); - - ///this block is just experimental code to show some internal issues with replacing shapes on the fly. - if (getDebugMode()!=0 && (i>0)) - { - if (physObjects[i]->GetRigidBody()->GetCollisionShape()->GetShapeType() == EMPTY_SHAPE_PROXYTYPE) - { - physObjects[i]->GetRigidBody()->SetCollisionShape(shapePtr[1]); - - //remove the persistent collision pairs that were created based on the previous shape - - BroadphaseProxy* bpproxy = physObjects[i]->GetRigidBody()->m_broadphaseHandle; - - physicsEnvironmentPtr->GetBroadphase()->CleanProxyFromPairs(bpproxy); - - SimdVector3 newinertia; - SimdScalar newmass = 10.f; - physObjects[i]->GetRigidBody()->GetCollisionShape()->CalculateLocalInertia(newmass,newinertia); - physObjects[i]->GetRigidBody()->setMassProps(newmass,newinertia); - physObjects[i]->GetRigidBody()->updateInertiaTensor(); - - } - - } - - - } - - if (!(getDebugMode() & IDebugDraw::DBG_NoHelpText)) - { - - float xOffset = 10.f; - float yStart = 20.f; - - float yIncr = -2.f; - - char buf[124]; - - glColor3f(0, 0, 0); - -#ifdef USE_QUICKPROF - - - if ( getDebugMode() & IDebugDraw::DBG_ProfileTimings) - { - static int counter = 0; - counter++; - std::map::iterator iter; - for (iter = Profiler::mProfileBlocks.begin(); iter != Profiler::mProfileBlocks.end(); ++iter) - { - char blockTime[128]; - sprintf(blockTime, "%s: %lf",&((*iter).first[0]),Profiler::getBlockTime((*iter).first, Profiler::BLOCK_CYCLE_SECONDS));//BLOCK_TOTAL_PERCENT)); - glRasterPos3f(xOffset,yStart,0); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),blockTime); - yStart += yIncr; - - } - } -#endif //USE_QUICKPROF - //profiling << Profiler::createStatsString(Profiler::BLOCK_TOTAL_PERCENT); - //<< std::endl; - - - - glRasterPos3f(xOffset,yStart,0); - sprintf(buf,"mouse to interact"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - glRasterPos3f(xOffset,yStart,0); - sprintf(buf,"space to reset"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - glRasterPos3f(xOffset,yStart,0); - sprintf(buf,"cursor keys and z,x to navigate"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - glRasterPos3f(xOffset,yStart,0); - sprintf(buf,"i to toggle simulation, s single step"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - glRasterPos3f(xOffset,yStart,0); - sprintf(buf,"q to quit"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - glRasterPos3f(xOffset,yStart,0); - sprintf(buf,"d to toggle deactivation"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - glRasterPos3f(xOffset,yStart,0); - sprintf(buf,"a to draw temporal AABBs"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - - glRasterPos3f(xOffset,yStart,0); - sprintf(buf,"h to toggle help text"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - bool useBulletLCP = !(getDebugMode() & IDebugDraw::DBG_DisableBulletLCP); - - bool useCCD = (getDebugMode() & IDebugDraw::DBG_EnableCCD); - - glRasterPos3f(xOffset,yStart,0); - sprintf(buf,"m Bullet GJK = %i",!isSatEnabled); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - glRasterPos3f(xOffset,yStart,0); - sprintf(buf,"n Bullet LCP = %i",useBulletLCP); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - glRasterPos3f(xOffset,yStart,0); - sprintf(buf,"1 CCD mode (adhoc) = %i",useCCD); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - glRasterPos3f(xOffset,yStart,0); - sprintf(buf,"+- shooting speed = %10.2f",bulletSpeed); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - } - -} - -void clientMoveAndDisplay() -{ - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - - - physicsEnvironmentPtr->proceedDeltaTime(0.f,deltaTime); - -#ifdef USE_QUICKPROF - Profiler::beginBlock("render"); -#endif //USE_QUICKPROF - - renderme(); - -#ifdef USE_QUICKPROF - Profiler::endBlock("render"); -#endif - glFlush(); - glutSwapBuffers(); - -} - - - -void clientDisplay(void) { - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - - physicsEnvironmentPtr->UpdateAabbs(deltaTime); - //draw contactpoints - physicsEnvironmentPtr->CallbackTriggers(); - - - renderme(); - - - glFlush(); - glutSwapBuffers(); -} - - - -///make this positive to show stack falling from a distance -///this shows the penalty tresholds in action, springy/spungy look - -void clientResetScene() -{ - - int i; - for (i=0;i0) - { - - if ((getDebugMode() & IDebugDraw::DBG_NoHelpText)) - { - if (physObjects[i]->GetRigidBody()->GetCollisionShape()->GetShapeType() == BOX_SHAPE_PROXYTYPE) - { - physObjects[i]->GetRigidBody()->SetCollisionShape(shapePtr[2]); - } else - { - physObjects[i]->GetRigidBody()->SetCollisionShape(shapePtr[1]); - } - - BroadphaseProxy* bpproxy = physObjects[i]->GetRigidBody()->m_broadphaseHandle; - physicsEnvironmentPtr->GetBroadphase()->CleanProxyFromPairs(bpproxy); - } - - //stack them - int colsize = 10; - int row = (i*CUBE_HALF_EXTENTS*2)/(colsize*2*CUBE_HALF_EXTENTS); - int row2 = row; - int col = (i)%(colsize)-colsize/2; - - - if (col>3) - { - col=11; - row2 |=1; - } - physObjects[i]->setPosition(col*2*CUBE_HALF_EXTENTS + (row2%2)*CUBE_HALF_EXTENTS, - row*2*CUBE_HALF_EXTENTS+CUBE_HALF_EXTENTS+EXTRA_HEIGHT,0); - physObjects[i]->setOrientation(0,0,0,1); - physObjects[i]->SetLinearVelocity(0,0,0,false); - physObjects[i]->SetAngularVelocity(0,0,0,false); - } - } -} - - - -void shootBox(const SimdVector3& destination) -{ - int i = numObjects-1; - - - - SimdVector3 linVel(destination[0]-eye[0],destination[1]-eye[1],destination[2]-eye[2]); - linVel.normalize(); - linVel*=bulletSpeed; - - physObjects[i]->setPosition(eye[0],eye[1],eye[2]); - physObjects[i]->setOrientation(0,0,0,1); - physObjects[i]->SetLinearVelocity(linVel[0],linVel[1],linVel[2],false); - physObjects[i]->SetAngularVelocity(0,0,0,false); -} - -void clientKeyboard(unsigned char key, int x, int y) -{ - - if (key == '.') - { - shootBox(SimdVector3(0,0,0)); - } - - if (key == '+') - { - bulletSpeed += 10.f; - } - if (key == '-') - { - bulletSpeed -= 10.f; - } - - defaultKeyboard(key, x, y); -} - -void clientSpecialKeyboard(int key, int x, int y) -{ - defaultSpecialKeyboard(key,x,y); -} - - - -int gPickingConstraintId = 0; -SimdVector3 gOldPickingPos; -float gOldPickingDist = 0.f; -RigidBody* pickedBody = 0;//for deactivation state - - -SimdVector3 GetRayTo(int x,int y) -{ - float top = 1.f; - float bottom = -1.f; - float nearPlane = 1.f; - float tanFov = (top-bottom)*0.5f / nearPlane; - float fov = 2.0 * atanf (tanFov); - - SimdVector3 rayFrom(eye[0],eye[1],eye[2]); - SimdVector3 rayForward = -rayFrom; - rayForward.normalize(); - float farPlane = 600.f; - rayForward*= farPlane; - - SimdVector3 rightOffset; - SimdVector3 vertical(0.f,1.f,0.f); - SimdVector3 hor; - hor = rayForward.cross(vertical); - hor.normalize(); - vertical = hor.cross(rayForward); - vertical.normalize(); - - float tanfov = tanf(0.5f*fov); - hor *= 2.f * farPlane * tanfov; - vertical *= 2.f * farPlane * tanfov; - SimdVector3 rayToCenter = rayFrom + rayForward; - SimdVector3 dHor = hor * 1.f/float(glutScreenWidth); - SimdVector3 dVert = vertical * 1.f/float(glutScreenHeight); - SimdVector3 rayTo = rayToCenter - 0.5f * hor + 0.5f * vertical; - rayTo += x * dHor; - rayTo -= y * dVert; - return rayTo; -} -void clientMouseFunc(int button, int state, int x, int y) -{ - //printf("button %i, state %i, x=%i,y=%i\n",button,state,x,y); - //button 0, state 0 means left mouse down - - SimdVector3 rayTo = GetRayTo(x,y); - - switch (button) - { - case 2: - { - if (state==0) - { - shootBox(rayTo); - } - break; - }; - case 1: - { - if (state==0) - { - //apply an impulse - if (physicsEnvironmentPtr) - { - float hit[3]; - float normal[3]; - PHY_IPhysicsController* hitObj = physicsEnvironmentPtr->rayTest(0,eye[0],eye[1],eye[2],rayTo.getX(),rayTo.getY(),rayTo.getZ(),hit[0],hit[1],hit[2],normal[0],normal[1],normal[2]); - if (hitObj) - { - CcdPhysicsController* physCtrl = static_cast(hitObj); - RigidBody* body = physCtrl->GetRigidBody(); - if (body) - { - body->SetActivationState(ACTIVE_TAG); - SimdVector3 impulse = rayTo; - impulse.normalize(); - float impulseStrength = 10.f; - impulse *= impulseStrength; - SimdVector3 relPos( - hit[0] - body->getCenterOfMassPosition().getX(), - hit[1] - body->getCenterOfMassPosition().getY(), - hit[2] - body->getCenterOfMassPosition().getZ()); - - body->applyImpulse(impulse,relPos); - } - - } - - } - - } else - { - - } - break; - } - case 0: - { - if (state==0) - { - //add a point to point constraint for picking - if (physicsEnvironmentPtr) - { - float hit[3]; - float normal[3]; - PHY_IPhysicsController* hitObj = physicsEnvironmentPtr->rayTest(0,eye[0],eye[1],eye[2],rayTo.getX(),rayTo.getY(),rayTo.getZ(),hit[0],hit[1],hit[2],normal[0],normal[1],normal[2]); - if (hitObj) - { - - CcdPhysicsController* physCtrl = static_cast(hitObj); - RigidBody* body = physCtrl->GetRigidBody(); - - if (body && !body->IsStatic()) - { - pickedBody = body; - pickedBody->SetActivationState(DISABLE_DEACTIVATION); - - SimdVector3 pickPos(hit[0],hit[1],hit[2]); - - SimdVector3 localPivot = body->getCenterOfMassTransform().inverse() * pickPos; - - gPickingConstraintId = physicsEnvironmentPtr->createConstraint(physCtrl,0,PHY_POINT2POINT_CONSTRAINT, - localPivot.getX(), - localPivot.getY(), - localPivot.getZ(), - 0,0,0); - //printf("created constraint %i",gPickingConstraintId); - - //save mouse position for dragging - gOldPickingPos = rayTo; - - - SimdVector3 eyePos(eye[0],eye[1],eye[2]); - - gOldPickingDist = (pickPos-eyePos).length(); - - Point2PointConstraint* p2p = static_cast(physicsEnvironmentPtr->getConstraintById(gPickingConstraintId)); - if (p2p) - { - //very weak constraint for picking - p2p->m_setting.m_tau = 0.1f; - } - } - } - } - } else - { - if (gPickingConstraintId && physicsEnvironmentPtr) - { - physicsEnvironmentPtr->removeConstraint(gPickingConstraintId); - //printf("removed constraint %i",gPickingConstraintId); - gPickingConstraintId = 0; - pickedBody->ForceActivationState(ACTIVE_TAG); - pickedBody->m_deactivationTime = 0.f; - pickedBody = 0; - - - } - } - - break; - - } - default: - { - } - } - -} - -void clientMotionFunc(int x,int y) -{ - - if (gPickingConstraintId && physicsEnvironmentPtr) - { - - //move the constraint pivot - - Point2PointConstraint* p2p = static_cast(physicsEnvironmentPtr->getConstraintById(gPickingConstraintId)); - if (p2p) - { - //keep it at the same picking distance - - SimdVector3 newRayTo = GetRayTo(x,y); - SimdVector3 eyePos(eye[0],eye[1],eye[2]); - SimdVector3 dir = newRayTo-eyePos; - dir.normalize(); - dir *= gOldPickingDist; - - SimdVector3 newPos = eyePos + dir; - p2p->SetPivotB(newPos); - } - - } -} diff --git a/Demos/CcdPhysicsDemo/CcdPhysicsDemo.h b/Demos/CcdPhysicsDemo/CcdPhysicsDemo.h new file mode 100644 index 000000000..e3cb05546 --- /dev/null +++ b/Demos/CcdPhysicsDemo/CcdPhysicsDemo.h @@ -0,0 +1,35 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef CCD_PHYSICS_DEMO_H +#define CCD_PHYSICS_DEMO_H + +#include "DemoApplication.h" + +///CcdPhysicsDemo shows basic stacking using Bullet physics, and allows toggle of Ccd (using key '1') +class CcdPhysicsDemo : public DemoApplication +{ + public: + + void initPhysics(); + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + virtual void clientResetScene(); + +}; + +#endif //CCD_PHYSICS_DEMO_H \ No newline at end of file diff --git a/Demos/ColladaDemo/BspConverter.cpp b/Demos/ColladaDemo/BspConverter.cpp deleted file mode 100644 index e8a472afe..000000000 --- a/Demos/ColladaDemo/BspConverter.cpp +++ /dev/null @@ -1,282 +0,0 @@ -/* -Bullet Continuous Collision Detection and Physics Library -Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ - -This software is provided 'as-is', without any express or implied warranty. -In no event will the authors be held liable for any damages arising from the use of this software. -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it freely, -subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. -2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. -3. This notice may not be removed or altered from any source distribution. -*/ - -#include "BspConverter.h" -#include "BspLoader.h" -#include "CcdPhysicsEnvironment.h" -#include "SimdVector3.h" - -void BspConverter::convertBsp(BspLoader& bspLoader,float scaling) -{ - { - SimdVector3 playerStart (0.f, 0.f, 100.f); - - if (bspLoader.findVectorByName(&playerStart[0],"info_player_start")) - { - printf("found playerstart\n"); - } - else - { - if (bspLoader.findVectorByName(&playerStart[0],"info_player_deathmatch")) - { - printf("found deatchmatch start\n"); - } - } - - playerStart[2] += 20.f; //start a bit higher - - playerStart *= scaling; - - - - //progressBegin("Loading bsp"); - - for (int i=0;i planeEquations; - - int brushid = bspLoader.m_dleafbrushes[leaf.firstLeafBrush+b]; - - BSPBrush& brush = bspLoader.m_dbrushes[brushid]; - if (brush.shaderNum!=-1) - { - if (bspLoader.m_dshaders[ brush.shaderNum ].contentFlags & BSPCONTENTS_SOLID) - { - brush.shaderNum = -1; - - for (int p=0;p vertices; - - getVerticesFromPlaneEquations(planeEquations,vertices); - printf("getVerticesFromPlaneEquations returned %i\n",vertices.size()); - - bool isEntity = false; - SimdVector3 entityTarget(0.f,0.f,0.f); - AddConvexVerticesCollider(vertices,isEntity,entityTarget); - - } - } - } - else - { - int i=0; - } - - } - } - -#define USE_ENTITIES -#ifdef USE_ENTITIES - - - { - int i; - for (i=0;i=0) && (modelnr < bspLoader.m_nummodels)) - { - const BSPModel& model = bspLoader.m_dmodels[modelnr]; - for (int n=0;n planeEquations; - bool isValidBrush = false; - - //convert brush - const BSPBrush& brush = bspLoader.m_dbrushes[model.firstBrush+n]; - { - for (int p=0;p vertices; - getVerticesFromPlaneEquations(planeEquations,vertices); - - bool isEntity=true; - AddConvexVerticesCollider(vertices,isEntity,targetLocation); - - } - } - - } - } - } - else - { - printf("unsupported trigger_push model, md3 ?\n"); - } - } - - } - } - } - } - -#endif //USE_ENTITIES - - - - //progressEnd(); - } - - } - - - - - - -void BspConverter::getVerticesFromPlaneEquations(const std::vector& planeEquations , std::vector& verticesOut ) -{ - float minimumDotProduct = 1e30f; - - const int numbrushes = planeEquations.size(); - // brute force: - for (int i=0;i 0.0001f ) && - ( n3n1.length2() > 0.0001f ) && - ( n1n2.length2() > 0.0001f ) ) - { - //point P out of 3 plane equations: - - // d1 ( N2 * N3 ) + d2 ( N3 * N1 ) + d3 ( N1 * N2 ) - //P = ------------------------------------------------------------------------- - // N1 . ( N2 * N3 ) - - - float quotient = (N1.dot(n2n3)); - if (SimdFabs(quotient) > 0.000001f) - { - quotient = -1.f / quotient; - n2n3 *= N1[3]; - n3n1 *= N2[3]; - n1n2 *= N3[3]; - SimdVector3 potentialVertex = n2n3; - potentialVertex += n3n1; - potentialVertex += n1n2; - potentialVertex *= quotient; - - //check if inside, and replace supportingVertexOut if needed - if (isInside(planeEquations,potentialVertex,0.1f)) - { - verticesOut.push_back(potentialVertex); - } - } - } - } - } - } -} - - - - -bool BspConverter::isInside(const std::vector& planeEquations, const SimdVector3& point, float margin) -{ - int numbrushes = planeEquations.size(); - for (int i=0;i0.f) - { - return false; - } - } - return true; - -} \ No newline at end of file diff --git a/Demos/ColladaDemo/BspLoader.cpp b/Demos/ColladaDemo/BspLoader.cpp deleted file mode 100644 index d4aa38de2..000000000 --- a/Demos/ColladaDemo/BspLoader.cpp +++ /dev/null @@ -1,713 +0,0 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ - - -#include "BspLoader.h" - -typedef struct -{ - char filename[1024]; - char *buffer,*script_p,*end_p; - int line; -} BSPScript; - -#define MAX_INCLUDES 8 -BSPScript scriptstack[MAX_INCLUDES]; -BSPScript *script; -int scriptline; - -char token[BSPMAXTOKEN]; -bool endofscript; -bool tokenready; // only true if UnGetToken was just called - -// -//LoadBSPFile -// - -int extrasize = 100; - -bool BspLoader::LoadBSPFile( void* memoryBuffer) { - - BSPHeader *header = (BSPHeader*) memoryBuffer; - - // load the file header - if (header) - { - // swap the header - SwapBlock( (int *)header, sizeof(*header) ); - - int length = (header->lumps[BSPLUMP_SHADERS].filelen) / sizeof(BSPShader); - m_dshaders.resize(length+extrasize); - m_numShaders = CopyLump( header, BSPLUMP_SHADERS, &m_dshaders[0], sizeof(BSPShader) ); - - length = (header->lumps[LUMP_MODELS].filelen) / sizeof(BSPModel); - m_dmodels.resize(length+extrasize); - m_nummodels = CopyLump( header, LUMP_MODELS, &m_dmodels[0], sizeof(BSPModel) ); - - length = (header->lumps[BSPLUMP_PLANES].filelen) / sizeof(BSPPlane); - m_dplanes.resize(length+extrasize); - m_numplanes = CopyLump( header, BSPLUMP_PLANES, &m_dplanes[0], sizeof(BSPPlane) ); - - length = (header->lumps[BSPLUMP_LEAFS].filelen) / sizeof(BSPLeaf); - m_dleafs.resize(length+extrasize); - m_numleafs = CopyLump( header, BSPLUMP_LEAFS, &m_dleafs[0], sizeof(BSPLeaf) ); - - length = (header->lumps[BSPLUMP_NODES].filelen) / sizeof(BSPNode); - m_dnodes.resize(length+extrasize); - m_numnodes = CopyLump( header, BSPLUMP_NODES, &m_dnodes[0], sizeof(BSPNode) ); - - length = (header->lumps[BSPLUMP_LEAFSURFACES].filelen) / sizeof(m_dleafsurfaces[0]); - m_dleafsurfaces.resize(length+extrasize); - m_numleafsurfaces = CopyLump( header, BSPLUMP_LEAFSURFACES, &m_dleafsurfaces[0], sizeof(m_dleafsurfaces[0]) ); - - length = (header->lumps[BSPLUMP_LEAFBRUSHES].filelen) / sizeof(m_dleafbrushes[0]) ; - m_dleafbrushes.resize(length+extrasize); - m_numleafbrushes = CopyLump( header, BSPLUMP_LEAFBRUSHES, &m_dleafbrushes[0], sizeof(m_dleafbrushes[0]) ); - - length = (header->lumps[LUMP_BRUSHES].filelen) / sizeof(BSPBrush); - m_dbrushes.resize(length+extrasize); - m_numbrushes = CopyLump( header, LUMP_BRUSHES, &m_dbrushes[0], sizeof(BSPBrush) ); - - - length = (header->lumps[LUMP_BRUSHSIDES].filelen) / sizeof(BSPBrushSide); - m_dbrushsides.resize(length+extrasize); - m_numbrushsides = CopyLump( header, LUMP_BRUSHSIDES, &m_dbrushsides[0], sizeof(BSPBrushSide) ); - - - length = (header->lumps[LUMP_SURFACES].filelen) / sizeof(BSPSurface); - m_drawSurfaces.resize(length+extrasize); - m_numDrawSurfaces = CopyLump( header, LUMP_SURFACES, &m_drawSurfaces[0], sizeof(BSPSurface) ); - - - length = (header->lumps[LUMP_DRAWINDEXES].filelen) / sizeof(m_drawIndexes[0]); - m_drawIndexes.resize(length+extrasize); - m_numDrawIndexes = CopyLump( header, LUMP_DRAWINDEXES, &m_drawIndexes[0], sizeof(m_drawIndexes[0]) ); - - length = (header->lumps[LUMP_VISIBILITY].filelen) / 1; - m_visBytes.resize(length+extrasize); - m_numVisBytes = CopyLump( header, LUMP_VISIBILITY, &m_visBytes[0], 1 ); - - length = (header->lumps[LUMP_LIGHTMAPS].filelen) / 1; - m_lightBytes.resize(length+extrasize); - m_numLightBytes = CopyLump( header, LUMP_LIGHTMAPS, &m_lightBytes[0], 1 ); - - length = (header->lumps[BSPLUMP_ENTITIES].filelen) / 1; - m_dentdata.resize(length+extrasize); - m_entdatasize = CopyLump( header, BSPLUMP_ENTITIES, &m_dentdata[0], 1); - - length = (header->lumps[LUMP_LIGHTGRID].filelen) / 1; - m_gridData.resize(length+extrasize); - m_numGridPoints = CopyLump( header, LUMP_LIGHTGRID, &m_gridData[0], 8 ); - - // swap everything - SwapBSPFile(); - - return true; - - } - return false; -} - - - -const char* BspLoader::ValueForKey( const BSPEntity* ent, const char* key ) const { - - const BSPKeyValuePair* ep; - - for (ep=ent->epairs ; ep ; ep=ep->next) { - if (!strcmp(ep->key, key) ) { - return ep->value; - } - } - return ""; -} - -float BspLoader::FloatForKey( const BSPEntity *ent, const char *key ) { - const char *k; - - k = ValueForKey( ent, key ); - return float(atof(k)); -} - -bool BspLoader::GetVectorForKey( const BSPEntity *ent, const char *key, BSPVector3 vec ) { - - const char *k; - k = ValueForKey (ent, key); - if (strcmp(k, "")) - { - sscanf (k, "%f %f %f", &vec[0], &vec[1], &vec[2]); - return true; - } - return false; -} - - - - -/* -============== -ParseFromMemory -============== -*/ -void BspLoader::ParseFromMemory (char *buffer, int size) -{ - script = scriptstack; - script++; - if (script == &scriptstack[MAX_INCLUDES]) - { - //printf("script file exceeded MAX_INCLUDES"); - } - strcpy (script->filename, "memory buffer" ); - - script->buffer = buffer; - script->line = 1; - script->script_p = script->buffer; - script->end_p = script->buffer + size; - - endofscript = false; - tokenready = false; -} - - -bool BspLoader::EndOfScript (bool crossline) -{ - if (!crossline) - //printf("Line %i is incomplete\n",scriptline); - - if (!strcmp (script->filename, "memory buffer")) - { - endofscript = true; - return false; - } - - //free (script->buffer); - if (script == scriptstack+1) - { - endofscript = true; - return false; - } - script--; - scriptline = script->line; - //printf ("returning to %s\n", script->filename); - return GetToken (crossline); -} - -/* - -============== -GetToken -============== -*/ -bool BspLoader::GetToken (bool crossline) -{ - char *token_p; - - if (tokenready) // is a token allready waiting? - { - tokenready = false; - return true; - } - - if (script->script_p >= script->end_p) - return EndOfScript (crossline); - -// -// skip space -// -skipspace: - while (*script->script_p <= 32) - { - if (script->script_p >= script->end_p) - return EndOfScript (crossline); - if (*script->script_p++ == '\n') - { - if (!crossline) - { - //printf("Line %i is incomplete\n",scriptline); - } - scriptline = script->line++; - } - } - - if (script->script_p >= script->end_p) - return EndOfScript (crossline); - - // ; # // comments - if (*script->script_p == ';' || *script->script_p == '#' - || ( script->script_p[0] == '/' && script->script_p[1] == '/') ) - { - if (!crossline) - { - //printf("Line %i is incomplete\n",scriptline); - } - while (*script->script_p++ != '\n') - if (script->script_p >= script->end_p) - return EndOfScript (crossline); - scriptline = script->line++; - goto skipspace; - } - - // /* */ comments - if (script->script_p[0] == '/' && script->script_p[1] == '*') - { - if (!crossline) - { - //printf("Line %i is incomplete\n",scriptline); - } - script->script_p+=2; - while (script->script_p[0] != '*' && script->script_p[1] != '/') - { - if ( *script->script_p == '\n' ) { - scriptline = script->line++; - } - script->script_p++; - if (script->script_p >= script->end_p) - return EndOfScript (crossline); - } - script->script_p += 2; - goto skipspace; - } - -// -// copy token -// - token_p = token; - - if (*script->script_p == '"') - { - // quoted token - script->script_p++; - while (*script->script_p != '"') - { - *token_p++ = *script->script_p++; - if (script->script_p == script->end_p) - break; - if (token_p == &token[BSPMAXTOKEN]) - { - //printf ("Token too large on line %i\n",scriptline); - } - } - script->script_p++; - } - else // regular token - while ( *script->script_p > 32 && *script->script_p != ';') - { - *token_p++ = *script->script_p++; - if (script->script_p == script->end_p) - break; - if (token_p == &token[BSPMAXTOKEN]) - { - //printf ("Token too large on line %i\n",scriptline); - } - } - - *token_p = 0; - - if (!strcmp (token, "$include")) - { - //GetToken (false); - //AddScriptToStack (token); - return false;//GetToken (crossline); - } - - return true; -} - -char *BspLoader::copystring(const char *s) -{ - char *b; - b = (char*) malloc( strlen(s)+1); - strcpy (b, s); - return b; -} - -void BspLoader::StripTrailing( char *e ) { - char *s; - - s = e + strlen(e)-1; - while (s >= e && *s <= 32) - { - *s = 0; - s--; - } -} -/* -================= -ParseEpair -================= -*/ -BSPKeyValuePair *BspLoader::ParseEpair( void ) { - BSPKeyValuePair *e; - - e = (struct BSPPair*) malloc( sizeof(BSPKeyValuePair)); - memset( e, 0, sizeof(BSPKeyValuePair) ); - - if ( strlen(token) >= BSPMAX_KEY-1 ) { - //printf ("ParseEpar: token too long"); - } - e->key = copystring( token ); - GetToken( false ); - if ( strlen(token) >= BSPMAX_VALUE-1 ) { - - //printf ("ParseEpar: token too long"); - } - e->value = copystring( token ); - - // strip trailing spaces that sometimes get accidentally - // added in the editor - StripTrailing( e->key ); - StripTrailing( e->value ); - - return e; -} - - -/* -================ -ParseEntity -================ -*/ -bool BspLoader::ParseEntity( void ) { - BSPKeyValuePair *e; - BSPEntity *mapent; - - if ( !GetToken (true) ) { - return false; - } - - if ( strcmp (token, "{") ) { - - //printf ("ParseEntity: { not found"); - } - - BSPEntity bla; - bla.brushes = 0; - bla.epairs = 0; - bla.firstDrawSurf = 0; - bla.origin[0] = 0.f; - bla.origin[1] = 0.f; - bla.origin[2] = 0.f; - bla.patches = 0; - - m_entities.push_back(bla); - mapent = &m_entities[m_entities.size()-1]; - m_num_entities++; - - do { - if ( !GetToken (true) ) { - //printf("ParseEntity: EOF without closing brace"); - } - if ( !strcmp (token, "}") ) { - break; - } - e = (struct BSPPair*)ParseEpair (); - e->next = mapent->epairs; - mapent->epairs = e; - } while (1); - - return true; -} - -/* -================ -ParseEntities - -Parses the dentdata string into entities -================ -*/ -void BspLoader::ParseEntities( void ) { - m_num_entities = 0; - m_entities.clear(); - - ParseFromMemory( &m_dentdata[0], m_entdatasize ); - - while ( ParseEntity () ) { - } -} - - - -int BspLoader::getMachineEndianness() -{ - long int i = 1; - const char *p = (const char *) &i; - if (p[0] == 1) // Lowest address contains the least significant byte - return BSP_LITTLE_ENDIAN; - else - return BSP_BIG_ENDIAN; -} - -short BspLoader::LittleShort (short l) -{ - if (machineEndianness() == BSP_BIG_ENDIAN) - { - unsigned char b1,b2; - - b1 = l&255; - b2 = (l>>8)&255; - - return (b1<<8) + b2; - } - //little endian - return l; -} - -short BspLoader::BigShort (short l) -{ - if (machineEndianness() == BSP_BIG_ENDIAN) - { - return l; - } - - unsigned char b1,b2; - - b1 = l&255; - b2 = (l>>8)&255; - - return (b1<<8) + b2; - - - -} - - -int BspLoader::LittleLong (int l) -{ - if (machineEndianness() == BSP_BIG_ENDIAN) - { - unsigned char b1,b2,b3,b4; - - b1 = l&255; - b2 = (l>>8)&255; - b3 = (l>>16)&255; - b4 = (l>>24)&255; - - return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4; - } - - //little endian - return l; - -} - -int BspLoader::BigLong (int l) -{ - if (machineEndianness() == BSP_BIG_ENDIAN) - { - return l; - } - - - unsigned char b1,b2,b3,b4; - - b1 = l&255; - b2 = (l>>8)&255; - b3 = (l>>16)&255; - b4 = (l>>24)&255; - - return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4; - -} - - -float BspLoader::LittleFloat (float l) -{ - if (machineEndianness() == BSP_BIG_ENDIAN) - { - union {unsigned char b[4]; float f;} in, out; - - in.f = l; - out.b[0] = in.b[3]; - out.b[1] = in.b[2]; - out.b[2] = in.b[1]; - out.b[3] = in.b[0]; - - return out.f; - } - - //little endian - return l; -} - -float BspLoader::BigFloat (float l) -{ - if (machineEndianness() == BSP_BIG_ENDIAN) - { - return l; - } - //little endian - union {unsigned char b[4]; float f;} in, out; - - in.f = l; - out.b[0] = in.b[3]; - out.b[1] = in.b[2]; - out.b[2] = in.b[1]; - out.b[3] = in.b[0]; - - return out.f; -} - - - - - - -// -// SwapBlock -// If all values are 32 bits, this can be used to swap everything -// - -void BspLoader::SwapBlock( int *block, int sizeOfBlock ) { - int i; - - sizeOfBlock >>= 2; - for ( i = 0 ; i < sizeOfBlock ; i++ ) { - block[i] = LittleLong( block[i] ); - } -} - -// -// CopyLump -// - -int BspLoader::CopyLump( BSPHeader *header, int lump, void *dest, int size ) { - int length, ofs; - - length = header->lumps[lump].filelen; - ofs = header->lumps[lump].fileofs; - - //if ( length % size ) { - // printf ("LoadBSPFile: odd lump size"); - //} - - memcpy( dest, (unsigned char *)header + ofs, length ); - - return length / size; -} - - - - -// -// SwapBSPFile -// - -void BspLoader::SwapBSPFile( void ) { - int i; - - // models - SwapBlock( (int *) &m_dmodels[0], m_nummodels * sizeof( m_dmodels[0] ) ); - - // shaders (don't swap the name) - for ( i = 0 ; i < m_numShaders ; i++ ) { - m_dshaders[i].contentFlags = LittleLong( m_dshaders[i].contentFlags ); - m_dshaders[i].surfaceFlags = LittleLong( m_dshaders[i].surfaceFlags ); - } - - // planes - SwapBlock( (int *)&m_dplanes[0], m_numplanes * sizeof( m_dplanes[0] ) ); - - // nodes - SwapBlock( (int *)&m_dnodes[0], m_numnodes * sizeof( m_dnodes[0] ) ); - - // leafs - SwapBlock( (int *)&m_dleafs[0], m_numleafs * sizeof( m_dleafs[0] ) ); - - // leaffaces - SwapBlock( (int *)&m_dleafsurfaces[0], m_numleafsurfaces * sizeof( m_dleafsurfaces[0] ) ); - - // leafbrushes - SwapBlock( (int *)&m_dleafbrushes[0], m_numleafbrushes * sizeof( m_dleafbrushes[0] ) ); - - // brushes - SwapBlock( (int *)&m_dbrushes[0], m_numbrushes * sizeof( m_dbrushes[0] ) ); - - // brushsides - SwapBlock( (int *)&m_dbrushsides[0], m_numbrushsides * sizeof( m_dbrushsides[0] ) ); - - // vis - ((int *)&m_visBytes)[0] = LittleLong( ((int *)&m_visBytes)[0] ); - ((int *)&m_visBytes)[1] = LittleLong( ((int *)&m_visBytes)[1] ); - - - // drawindexes - SwapBlock( (int *)&m_drawIndexes[0], m_numDrawIndexes * sizeof( m_drawIndexes[0] ) ); - - // drawsurfs - SwapBlock( (int *)&m_drawSurfaces[0], m_numDrawSurfaces * sizeof( m_drawSurfaces[0] ) ); - -} - - - - - -bool BspLoader::findVectorByName(float* outvec,const char* name) -{ - const char *cl; - BSPVector3 origin; - - bool found = false; - - ParseEntities(); - - for ( int i = 1; i < m_num_entities; i++ ) { - cl = ValueForKey (&m_entities[i], "classname"); - if ( !strcmp( cl, "info_player_start" ) ) { - GetVectorForKey( &m_entities[i], "origin", origin ); - found = true; - break; - } - if ( !strcmp( cl, "info_player_deathmatch" ) ) { - GetVectorForKey( &m_entities[i], "origin", origin ); - found = true; - break; - } - } - - if (found) - { - outvec[0] = origin[0]; - outvec[1] = origin[1]; - outvec[2] = origin[2]; - } - return found; -} - - - -const BSPEntity * BspLoader::getEntityByValue( const char* name, const char* value) -{ - const BSPEntity* entity = NULL; - - for ( int i = 1; i < m_num_entities; i++ ) { - - const BSPEntity& ent = m_entities[i]; - - const char* cl = ValueForKey (&m_entities[i], name); - if ( !strcmp( cl, value ) ) { - entity = &ent; - break; - } - } - return entity; -} \ No newline at end of file diff --git a/Demos/ColladaDemo/BspLoader.h b/Demos/ColladaDemo/BspLoader.h deleted file mode 100644 index c89a8a125..000000000 --- a/Demos/ColladaDemo/BspLoader.h +++ /dev/null @@ -1,304 +0,0 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ - - - -#ifndef BSP_LOADER_H -#define BSP_LOADER_H - -#define BSPMAXTOKEN 1024 -#define BSPMAX_KEY 32 -#define BSPMAX_VALUE 1024 -#define BSPCONTENTS_SOLID 1 -#define BSPCONTENTS_AREAPORTAL 0x8000 -#define BSPLUMP_ENTITIES 0 -#define BSPLUMP_SHADERS 1 -#define BSPLUMP_PLANES 2 -#define BSPLUMP_NODES 3 -#define BSPLUMP_LEAFS 4 -#define BSPLUMP_LEAFSURFACES 5 -#define BSPLUMP_LEAFBRUSHES 6 -#define LUMP_MODELS 7 -#define LUMP_BRUSHES 8 -#define LUMP_BRUSHSIDES 9 -#define LUMP_DRAWVERTS 10 -#define LUMP_DRAWINDEXES 11 -#define LUMP_SURFACES 13 -#define LUMP_LIGHTMAPS 14 -#define LUMP_LIGHTGRID 15 -#define LUMP_VISIBILITY 16 -#define HEADER_LUMPS 17 -#define MAX_QPATH 64 - -#include - - -typedef struct { - int fileofs, filelen; -} BSPLump; - -typedef float BSPVector3[3]; - -typedef struct { - int ident; - int version; - - BSPLump lumps[HEADER_LUMPS]; -} BSPHeader; - - -typedef struct { - float mins[3], maxs[3]; - int firstSurface, numSurfaces; - int firstBrush, numBrushes; -} BSPModel; - -typedef struct { - char shader[MAX_QPATH]; - int surfaceFlags; - int contentFlags; -} BSPShader; - -typedef struct { - float normal[3]; - float dist; -} BSPPlane; - -typedef struct { - int planeNum; - int children[2]; - int mins[3]; - int maxs[3]; -} BSPNode; - -typedef struct { - int cluster; - int area; - - int mins[3]; - int maxs[3]; - - int firstLeafSurface; - int numLeafSurfaces; - - int firstLeafBrush; - int numLeafBrushes; -} BSPLeaf; - -typedef struct { - int planeNum; - int shaderNum; -} BSPBrushSide; - -typedef struct { - int firstSide; - int numSides; - int shaderNum; -} BSPBrush; - - - - -typedef struct BSPPair { - struct BSPPair *next; - char *key; - char *value; -} BSPKeyValuePair; - -typedef struct { - BSPVector3 origin; - struct bspbrush_s *brushes; - struct parseMesh_s *patches; - int firstDrawSurf; - BSPKeyValuePair *epairs; -} BSPEntity; - -typedef enum { - MST_BAD, - MST_PLANAR, - MST_PATCH, - MST_TRIANGLE_SOUP, - MST_FLARE -} BSPMapSurface; - -typedef struct { - int shaderNum; - int fogNum; - int surfaceType; - - int firstVert; - int numVerts; - - int firstIndex; - int numIndexes; - - int lightmapNum; - int lightmapX, lightmapY; - int lightmapWidth, lightmapHeight; - - BSPVector3 lightmapOrigin; - BSPVector3 lightmapVecs[3]; - - int patchWidth; - int patchHeight; -} BSPSurface; - - - -///GPL code from IdSofware to parse a Quake 3 BSP file -///check that your platform define __BIG_ENDIAN__ correctly (in BspLoader.cpp) -class BspLoader -{ - int m_Endianness; - - public: - - BspLoader() - :m_num_entities(0) - { - m_Endianness = getMachineEndianness(); - if (m_Endianness == BSP_BIG_ENDIAN) - { - printf("Machine is BIG_ENDIAN\n"); - } else - { - printf("Machine is Little Endian\n"); - } - } - bool LoadBSPFile( void* memoryBuffer); - - const char* ValueForKey( const BSPEntity *ent, const char *key ) const; - - bool GetVectorForKey( const BSPEntity *ent, const char *key, BSPVector3 vec ); - - float FloatForKey( const BSPEntity *ent, const char *key ); - - void ParseEntities( void ); - - bool findVectorByName(float* outvec,const char* name); - - const BSPEntity * getEntityByValue( const char* name, const char* value); - - - protected: - - void ParseFromMemory (char *buffer, int size); - - - - bool EndOfScript (bool crossline); - - bool GetToken (bool crossline); - - char *copystring(const char *s); - - void StripTrailing( char *e ); - - BSPKeyValuePair * ParseEpair( void ); - - bool ParseEntity( void ); - - short LittleShort (short l); - int LittleLong (int l); - float LittleFloat (float l); - - int BigLong (int l); - short BigShort (short l); - float BigFloat (float l); - - void SwapBlock( int *block, int sizeOfBlock ); - - int CopyLump( BSPHeader *header, int lump, void *dest, int size ); - - void SwapBSPFile( void ); - - - - - public: //easier for conversion - int m_num_entities; - std::vector m_entities; - - int m_nummodels; - std::vector m_dmodels; - - int m_numShaders; - std::vector m_dshaders; - - int m_entdatasize; - std::vector m_dentdata; - - int m_numleafs; - std::vector m_dleafs; - - int m_numplanes; - std::vector m_dplanes; - - int m_numnodes; - std::vector m_dnodes; - - int m_numleafsurfaces; - std::vector m_dleafsurfaces; - - int m_numleafbrushes; - std::vector m_dleafbrushes; - - int m_numbrushes; - std::vector m_dbrushes; - - int m_numbrushsides; - std::vector m_dbrushsides; - - int m_numLightBytes; - std::vector m_lightBytes; - - int m_numGridPoints; - std::vector m_gridData; - - int m_numVisBytes; - std::vector m_visBytes; - - - int m_numDrawIndexes; - std::vector m_drawIndexes; - - int m_numDrawSurfaces; - std::vector m_drawSurfaces; - - enum - { - BSP_LITTLE_ENDIAN = 0, - BSP_BIG_ENDIAN = 1, - }; - - //returns machines big endian / little endian - // - int getMachineEndianness(); - - inline int machineEndianness() - { - return m_Endianness; - } - -}; - -#endif //BSP_LOADER_H diff --git a/Demos/ColladaDemo/ColladaDemo.cpp b/Demos/ColladaDemo/ColladaDemo.cpp index f461a44b2..d54c5189a 100644 --- a/Demos/ColladaDemo/ColladaDemo.cpp +++ b/Demos/ColladaDemo/ColladaDemo.cpp @@ -15,249 +15,44 @@ subject to the following restrictions: #include "CcdPhysicsEnvironment.h" #include "CcdPhysicsController.h" - -//#include "GL_LineSegmentShape.h" -#include "CollisionShapes/BoxShape.h" -#include "CollisionShapes/SphereShape.h" -#include "CollisionShapes/CylinderShape.h" -#include "CollisionShapes/ConeShape.h" -#include "CollisionShapes/StaticPlaneShape.h" -#include "CollisionShapes/ConvexHullShape.h" -#include "CollisionShapes/TriangleMesh.h" -#include "CollisionShapes/ConvexTriangleMeshShape.h" -#include "CollisionShapes/TriangleMeshShape.h" -#include "CollisionShapes/TriangleIndexVertexArray.h" -#include "CollisionShapes/CompoundShape.h" - - -extern SimdVector3 gCameraUp; -extern int gForwardAxis; - #include "CollisionShapes/Simplex1to4Shape.h" #include "CollisionShapes/EmptyShape.h" - #include "Dynamics/RigidBody.h" #include "CollisionDispatch/CollisionDispatcher.h" #include "BroadphaseCollision/SimpleBroadphase.h" #include "BroadphaseCollision/AxisSweep3.h" #include "ConstraintSolver/Point2PointConstraint.h" #include "ConstraintSolver/HingeConstraint.h" - #include "quickprof.h" #include "IDebugDraw.h" - #include "GLDebugDrawer.h" -//in future make it a bsp2dae -//#define QUAKE_BSP_IMPORTING 1 - -#ifdef QUAKE_BSP_IMPORTING -#include "BspLoader.h" -#include "BspConverter.h" -#endif //QUAKE_BSP_IMPORTING - - -//either FCollada or COLLADA_DOM //COLLADA_DOM and LibXML source code are included in Extras/ folder. //COLLADA_DOM should compile under all platforms, and is enabled by default. -//If you want to compile with FCollada (under windows), add the FCollada sourcecode -//in Extras/FCollada, and define USE_FOLLADE, and include the library. - -//#define USE_FCOLLADA 1 -#ifdef USE_FCOLLADA - -//Collada Physics test -//#define NO_LIBXML //need LIBXML, because FCDocument/FCDPhysicsRigidBody.h needs FUDaeWriter, through FCDPhysicsParameter.hpp -#include "FUtils/FUtils.h" -#include "FCDocument/FCDocument.h" -#include "FCDocument/FCDSceneNode.h" -#include "FUtils/FUFileManager.h" -#include "FUtils/FULogFile.h" -#include "FCDocument/FCDPhysicsSceneNode.h" -#include "FCDocument/FCDPhysicsModelInstance.h" -#include "FCDocument/FCDPhysicsRigidBodyInstance.h" -#include "FCDocument/FCDPhysicsRigidBody.h" -#include "FCDocument/FCDGeometryInstance.h" -#include "FCDocument/FCDGeometrySource.h" -#include "FCDocument/FCDGeometryMesh.h" -#include "FCDocument/FCDPhysicsParameter.h" -#include "FCDocument/FCDPhysicsShape.h" -#include "FCDocument/FCDGeometryPolygons.h" -#include "FUtils/FUDaeSyntax.h" - -#include "FCDocument/FCDGeometry.h" -#include "FCDocument/FCDPhysicsAnalyticalGeometry.h" - - -#else -//Use Collada-dom - #include "ColladaConverter.h" - -#endif - - - - - #include "PHY_Pro.h" #include "BMF_Api.h" #include //printf debugging float deltaTime = 1.f/60.f; -float bulletSpeed = 40.f; -#ifdef WIN32 -#if _MSC_VER >= 1310 -//only use SIMD Hull code under Win32 -#define USE_HULL 1 -#include "NarrowPhaseCollision/Hull.h" -#endif //_MSC_VER -#endif //WIN32 - - -#ifdef WIN32 //needed for glut.h -#include -#endif -//think different -#if defined(__APPLE__) && !defined (VMDMESA) -#include -#include -#include -#else -#include -#endif +#include "ColladaDemo.h" #include "GL_ShapeDrawer.h" - #include "GlutStuff.h" - -extern float eye[3]; -extern int glutScreenWidth; -extern int glutScreenHeight; - - - -int numObjects = 0; - -const int maxNumObjects = 450; - -SimdTransform startTransforms[maxNumObjects]; - -//quick test to export new position into a COLLADA .dae file -#ifndef USE_FCOLLADA - -#endif //USE_FCOLLADA - -DefaultMotionState ms[maxNumObjects]; -CcdPhysicsController* physObjects[maxNumObjects] = {0,0,0,0}; - -CcdPhysicsEnvironment* physicsEnvironmentPtr = 0; - - -#define CUBE_HALF_EXTENTS 1 -#define EXTRA_HEIGHT -20.f - - -CollisionShape* gShapePtr[maxNumObjects];//1 rigidbody has 1 shape (no re-use of shapes) - -//////////////////////////////////// - -///Very basic import -CcdPhysicsController* LocalCreatePhysicsObject(bool isDynamic, float mass, const SimdTransform& startTransform,CollisionShape* shape) -{ - - startTransforms[numObjects] = startTransform; - - PHY_ShapeProps shapeProps; - - shapeProps.m_do_anisotropic = false; - shapeProps.m_do_fh = false; - shapeProps.m_do_rot_fh = false; - shapeProps.m_friction_scaling[0] = 1.; - shapeProps.m_friction_scaling[1] = 1.; - shapeProps.m_friction_scaling[2] = 1.; - - shapeProps.m_inertia = 1.f; - shapeProps.m_lin_drag = 0.2f; - shapeProps.m_ang_drag = 0.1f; - shapeProps.m_mass = 10.0f; - - PHY_MaterialProps materialProps; - materialProps.m_friction = 10.5f; - materialProps.m_restitution = 0.0f; - - CcdConstructionInfo ccdObjectCi; - ccdObjectCi.m_friction = 0.5f; - - ccdObjectCi.m_linearDamping = shapeProps.m_lin_drag; - ccdObjectCi.m_angularDamping = shapeProps.m_ang_drag; - - SimdTransform tr; - tr.setIdentity(); - - int i = numObjects; - { - gShapePtr[i] = shape; - - shapeProps.m_shape = gShapePtr[i]; - shapeProps.m_shape->SetMargin(0.05f); - - SimdQuaternion orn = startTransform.getRotation(); - - - ms[i].setWorldOrientation(orn[0],orn[1],orn[2],orn[3]); - ms[i].setWorldPosition(startTransform.getOrigin().getX(),startTransform.getOrigin().getY(),startTransform.getOrigin().getZ()); - - ccdObjectCi.m_MotionState = &ms[i]; - ccdObjectCi.m_gravity = SimdVector3(0,-9.8,0); - ccdObjectCi.m_localInertiaTensor =SimdVector3(0,0,0); - if (!isDynamic) - { - shapeProps.m_mass = 0.f; - ccdObjectCi.m_mass = shapeProps.m_mass; - ccdObjectCi.m_collisionFlags = CollisionObject::isStatic; - } - else - { - shapeProps.m_mass = mass; - ccdObjectCi.m_mass = shapeProps.m_mass; - ccdObjectCi.m_collisionFlags = 0; - } - - - SimdVector3 localInertia(0.f,0.f,0.f); - - if (isDynamic) - { - gShapePtr[i]->CalculateLocalInertia(shapeProps.m_mass,localInertia); - } - - ccdObjectCi.m_localInertiaTensor = localInertia; - ccdObjectCi.m_collisionShape = gShapePtr[i]; - - - physObjects[i]= new CcdPhysicsController( ccdObjectCi); - - // Only do CCD if motion in one timestep (1.f/60.f) exceeds CUBE_HALF_EXTENTS - physObjects[i]->GetRigidBody()->m_ccdSquareMotionTreshold = 0.f; - - //Experimental: better estimation of CCD Time of Impact: - //physObjects[i]->GetRigidBody()->m_ccdSweptShereRadius = 0.5*CUBE_HALF_EXTENTS; - - physicsEnvironmentPtr->addCcdPhysicsController( physObjects[i]); - - } - - //return newly created PhysicsController - return physObjects[numObjects++]; -} - +///custom version of the converter, that creates physics objects/constraints class MyColladaConverter : public ColladaConverter { + DemoApplication* m_demoApp; + public: + MyColladaConverter(DemoApplication* demoApp) + :m_demoApp(demoApp) + { + } + ///those 2 virtuals are called for each constraint/physics object virtual int createUniversalD6Constraint( class PHY_IPhysicsController* ctrlRef,class PHY_IPhysicsController* ctrlOther, @@ -269,7 +64,7 @@ class MyColladaConverter : public ColladaConverter const SimdVector3& angularMaxLimits ) { - return physicsEnvironmentPtr->createUniversalD6Constraint( + return m_demoApp->GetPhysicsEnvironment()->createUniversalD6Constraint( ctrlRef,ctrlOther, localAttachmentFrameRef, localAttachmentOther, @@ -285,19 +80,19 @@ class MyColladaConverter : public ColladaConverter const SimdTransform& startTransform, CollisionShape* shape) { - CcdPhysicsController* ctrl = LocalCreatePhysicsObject(isDynamic, mass, startTransform,shape); + CcdPhysicsController* ctrl = m_demoApp->LocalCreatePhysicsObject(isDynamic, mass, startTransform,shape); return ctrl; } virtual void SetGravity(const SimdVector3& grav) { - physicsEnvironmentPtr->setGravity(grav.getX(),grav.getY(),grav.getZ()); + m_demoApp->GetPhysicsEnvironment()->setGravity(grav.getX(),grav.getY(),grav.getZ()); } virtual void SetCameraInfo(const SimdVector3& camUp,int forwardAxis) { - gCameraUp = camUp; - gForwardAxis = forwardAxis; + m_demoApp->setCameraUp(camUp); + m_demoApp->setCameraForwardAxis(forwardAxis); } }; @@ -305,629 +100,6 @@ class MyColladaConverter : public ColladaConverter MyColladaConverter* gColladaConverter = 0; -#ifdef QUAKE_BSP_IMPORTING - -///BspToBulletConverter extends the BspConverter to convert to Bullet datastructures -class BspToBulletConverter : public BspConverter -{ -public: - - virtual void AddConvexVerticesCollider(std::vector& vertices, bool isEntity, const SimdVector3& entityTargetLocation) - { - ///perhaps we can do something special with entities (isEntity) - ///like adding a collision Triggering (as example) - - if (vertices.size() > 0) - { - bool isDynamic = false; - float mass = 0.f; - SimdTransform startTransform; - //can use a shift - startTransform.setIdentity(); - startTransform.setOrigin(SimdVector3(0,0,-10.f)); - //this create an internal copy of the vertices - CollisionShape* shape = new ConvexHullShape(&vertices[0],vertices.size()); - - LocalCreatePhysicsObject(isDynamic, mass, startTransform,shape); - } - } -}; -#endif //QUAKE_BSP_IMPORTING - -#ifdef USE_FCOLLADA - - -bool ConvertColladaPhysicsToBulletPhysics(const FCDPhysicsSceneNode* inputNode) -{ - - assert(inputNode); - - /// FRSceneNodeList nodesToDelete; - // FRMeshPhysicsController::StartCooking(); - - FCDPhysicsModelInstanceList models = inputNode->GetInstances(); - - //Go through all of the physics models - for (FCDPhysicsModelInstanceList::iterator itM=models.begin(); itM != models.end(); itM++) - { - - FCDEntityInstanceList& instanceList = (*itM)->GetInstances(); - //create one node per physics model. This node is pretty much only a middle man, - //but better describes the structure we get from the input file - //FRSceneNode* modelNode = new FRSceneNode(); - //modelNode->SetParent(outputNode); - //outputNode->AddChild(modelNode); - //Go through all of the rigid bodies and rigid constraints in that model - - for (FCDEntityInstanceList::iterator itE=instanceList.begin(); itE!=instanceList.end(); itE++) - { - if ((*itE)->GetType() == FCDEntityInstance::PHYSICS_RIGID_CONSTRAINT) - { - //not yet, could add point to point / hinge support easily - } - else - if ((*itE)->GetType() == FCDEntityInstance::PHYSICS_RIGID_BODY) - { - - printf("PHYSICS_RIGID_BODY\n"); - - - //Create a controller per rigid-body - - physicsEnvironmentPtr->setGravity(inputNode->GetGravity().x,inputNode->GetGravity().y,inputNode->GetGravity().z); - //FRMeshPhysicsController* controller = new FRMeshPhysicsController(inputNode->GetGravity(), inputNode->GetTimestep()); - FCDPhysicsRigidBodyInstance* rbInstance = (FCDPhysicsRigidBodyInstance*)(*itE); - - FCDSceneNode* targetNode = rbInstance->GetTargetNode(); - - - if (!targetNode) - { - - - //DebugOut("FCTranslator: No target node defined in rigid body instance"); - - //SAFE_DELETE(controller); - - continue; - } - - - //Transfer all the transforms in n into cNode, and bake - //at the same time the scalings. It is necessary to re-translate the - //transforms as they will get deleted when we delete the old node. - //A better way to do this would be to steal the transforms from the old - //nodes, and make sure they're not deleted later, but this is impractical - //right now as we would also have to migrate all the animation curves. - - - SimdVector3 localScaling(1.f,1.f,1.f); - - - - - - SimdTransform accumulatedWorldTransform; - accumulatedWorldTransform.setIdentity(); - - uint32 numTransforms = targetNode->GetTransformCount(); - - for (uint32 i=0; iGetTransforms()[i]->GetType() == FCDTransform::SCALE) - { - - FCDTScale* scaleTrans = (FCDTScale*)targetNode->GetTransforms()[i]; - const FMVector3& scaling = scaleTrans->GetScale(); - localScaling[0] = scaling.x; - localScaling[1] = scaling.y; - localScaling[2] = scaling.z; - - } else - { - - FMMatrix44 mat = (targetNode->GetTransforms()[i])->ToMatrix(); - SimdVector3 pos(mat.GetTranslation().x,mat.GetTranslation().y,mat.GetTranslation().z); - - SimdMatrix3x3 rotMat( - mat.m[0][0],mat.m[0][1],mat.m[0][2], - mat.m[1][0],mat.m[1][1],mat.m[1][2], - mat.m[2][0],mat.m[2][1],mat.m[2][2]); - - rotMat = rotMat.transpose(); - SimdTransform trans(rotMat,pos); - - //TODO: check pre or post multiply - accumulatedWorldTransform = accumulatedWorldTransform * trans; - } - - } - - //Then affect all of its geometry instances. - //Collect all the entities inside the entity vector and inside the children nodes - /* - FREntityList childEntities = n->GetEntities(); - FRSceneNodeList childrenToParse = n->GetChildren(); - - while (!childrenToParse.empty()) - { - FRSceneNode* child = *childrenToParse.begin(); - const FREntityList& e = child->GetEntities(); - //add the entities of that child - childEntities.insert(childEntities.end(), e.begin(), e.end()); - //queue the grand-children nodes - childrenToParse.insert(childrenToParse.end(), child->GetChildren().begin(), child->GetChildren().end()); - childrenToParse.erase(childrenToParse.begin()); - - } - */ - //now check which ones are geometry mesh (right now an entity is only derived by mesh - //but do this to avoid problems in the future) - /* - for (FREntityList::iterator itT = childEntities.begin(); itT != childEntities.end(); itT++) - { - - if ((*itT)->GetType() == FREntity::MESH || (*itT)->GetType() == FREntity::MESH_CONTROLLER) - - { - - FRMesh* cMesh = (FRMesh*)*itT; - - //while we're here, bake the scaling transforms into the meshes - - BakeScalingIntoMesh(cMesh, scaleTransforms); - - controller->AddBindMesh((FRMesh*)*itT); - - } - - } - */ - - - ///////////////////////////////////////////////////////////////////// - //We're done with the targets. Now take care of the physics shapes. - FCDPhysicsRigidBody* rigidBody = rbInstance->FlattenRigidBody(); - FCDPhysicsMaterial* mat = rigidBody->GetPhysicsMaterial(); - FCDPhysicsShapeList shapes = rigidBody->GetPhysicsShapeList(); - - //need to deal with compound shapes and single shapes - //easiest is to always create a compound, and then add each shape - //and at the end, if compound consists of just 1 objects (without local transform) simplify it - CollisionShape* collisionShape = 0; - - - - FCDPhysicsParameter* dyn = (FCDPhysicsParameter*)rigidBody->FindParameterByReference(DAE_DYNAMIC_ELEMENT); - - bool isDynamic = true; - - if (dyn) - { - isDynamic = *dyn->GetValue(); - printf("isDynamic %i\n",isDynamic); - } - - for (uint32 i=0; iGetType();// - //controller->SetDensity(OldShape->GetDensity()); - - - if (OldShape->GetGeometryInstance()) - { - printf("mesh/convex geometry\n"); - - FCDGeometry* geoTemp = (FCDGeometry*)(OldShape->GetGeometryInstance()->GetEntity()); - - FCDGeometryMesh* colladaMesh = geoTemp->GetMesh(); - - - if (colladaMesh) - { - - if (1) - { - bool useConvexHull = false; - - //useConvexHull uses just the points. works, but there is no rendering at the moment - //for convex hull shapes - if (useConvexHull) - { - int count = colladaMesh->GetVertexSourceCount(); - for (int i=0;iGetVertexSource(i); - - if (geomSource->GetSourceType()==FUDaeGeometryInput::POSITION) - { - - int numPoints = geomSource->GetSourceData().size()/3; - SimdPoint3* points = new SimdPoint3[numPoints]; - for (int p=0;pGetSourceData()[p*3], - geomSource->GetSourceData()[p*3+1], - geomSource->GetSourceData()[p*3+2]); - } - - - collisionShape = new ConvexHullShape(points,numPoints); - - delete points; - - break; - } - } - - } - else - { - TriangleMesh* trimesh = new TriangleMesh(); - - int polyCount = colladaMesh->GetPolygonsCount(); - for (uint32 j=0; jGetPolygons(j); - poly->Triangulate(); - - int numfaces = poly->GetFaceCount(); - int numfacevertex = poly->GetFaceVertexCount(); - - std::vector dataIndices; - - - //for (FCDGeometryPolygonsInputList::iterator itI = poly->idxOwners.begin(); itI != idxOwners.end(); ++itI) - //{ - // UInt32List* indices = &(*itI)->indices; - // dataIndices.push_back(*indices); - //} - - - - - FCDGeometryPolygonsInput* inputs = poly->FindInput(FUDaeGeometryInput::POSITION); - - - int startIndex = 0; - for (int p=0;pGetFaceVertexCounts()[p]; - - switch (numfacevertices) - { - case 3: - { - - //float value = inputs->source->GetSourceData()[index]; - - int offset = poly->GetFaceVertexOffset(p); - int index; - index = inputs->indices[offset]; - - SimdVector3 vertex0( - inputs->GetSource()->GetSourceData()[index*3], - inputs->GetSource()->GetSourceData()[index*3+1], - inputs->GetSource()->GetSourceData()[index*3+2]); - - index = inputs->indices[offset+1]; - - SimdVector3 vertex1( - inputs->GetSource()->GetSourceData()[index*3], - inputs->GetSource()->GetSourceData()[index*3+1], - inputs->GetSource()->GetSourceData()[index*3+2]); - - index = inputs->indices[offset+2]; - - SimdVector3 vertex2( - inputs->GetSource()->GetSourceData()[index*3], - inputs->GetSource()->GetSourceData()[index*3+1], - inputs->GetSource()->GetSourceData()[index*3+2]); - - - trimesh->AddTriangle(vertex0,vertex1,vertex2); - break; - } - - case 4: - { - int offset = poly->GetFaceVertexOffset(p); - int index; - index = inputs->indices[offset]; - - SimdVector3 vertex0( - inputs->GetSource()->GetSourceData()[index*3], - inputs->GetSource()->GetSourceData()[index*3+1], - inputs->GetSource()->GetSourceData()[index*3+2]); - - index = inputs->indices[offset+1]; - - SimdVector3 vertex1( - inputs->GetSource()->GetSourceData()[index*3], - inputs->GetSource()->GetSourceData()[index*3+1], - inputs->GetSource()->GetSourceData()[index*3+2]); - - index = inputs->indices[offset+2]; - - SimdVector3 vertex2( - inputs->GetSource()->GetSourceData()[index*3], - inputs->GetSource()->GetSourceData()[index*3+1], - inputs->GetSource()->GetSourceData()[index*3+2]); - - index = inputs->indices[offset+3]; - - SimdVector3 vertex3( - inputs->GetSource()->GetSourceData()[index*3], - inputs->GetSource()->GetSourceData()[index*3+1], - inputs->GetSource()->GetSourceData()[index*3+2]); - - trimesh->AddTriangle(vertex0,vertex1,vertex2); - trimesh->AddTriangle(vertex0,vertex2,vertex3); - - break; - } - - default: - { - } - } - } - - if (colladaMesh->IsConvex() || isDynamic) - { - collisionShape = new ConvexTriangleMeshShape(trimesh); - } else - { - collisionShape = new TriangleMeshShape(trimesh); - } - - - } - - - } - - - } else - { - printf("static not yet?\n"); - - //should be static triangle mesh! - - //FRMesh* cMesh = ToFREntityGeometry(geoTemp); - //BakeScalingIntoMesh(cMesh, scaleTransforms); - - for (uint32 j=0; jGetPolygonsCount(); j++) - { - - /* - FRMeshPhysicsShape* NewShape = new FRMeshPhysicsShape(controller); - - if (!NewShape->CreateTriangleMesh(cMesh, j, true)) - - { - - SAFE_DELETE(NewShape); - - continue; - - } - if (mat) - { - NewShape->SetMaterial(mat->GetStaticFriction(), mat->GetDynamicFriction(), mat->GetRestitution()); - //FIXME - //NewShape->material->setFrictionCombineMode(); - //NewShape->material->setSpring(); - } - - controller->AddShape(NewShape); - - */ - } - } - } - - - - } - - else - - { - - //FRMeshPhysicsShape* NewShape = new FRMeshPhysicsShape(controller); - - FCDPhysicsAnalyticalGeometry* analGeom = OldShape->GetAnalyticalGeometry(); - - //increse the following value for nicer shapes with more vertices - - uint16 superEllipsoidSubdivisionLevel = 2; - - if (!analGeom) - - continue; - - switch (analGeom->GetGeomType()) - - { - - case FCDPhysicsAnalyticalGeometry::BOX: - - { - - FCDPASBox* box = (FCDPASBox*)analGeom; - printf("Box\n"); - collisionShape = new BoxShape(SimdVector3(box->halfExtents.x,box->halfExtents.y,box->halfExtents.z)); - - break; - - } - - case FCDPhysicsAnalyticalGeometry::PLANE: - - { - - FCDPASPlane* plane = (FCDPASPlane*)analGeom; - printf("Plane\n"); - break; - - } - - case FCDPhysicsAnalyticalGeometry::SPHERE: - - { - - FCDPASSphere* sphere = (FCDPASSphere*)analGeom; - collisionShape = new SphereShape(sphere->radius); - printf("Sphere\n"); - break; - - } - - case FCDPhysicsAnalyticalGeometry::CYLINDER: - - { - - //FIXME: only using the first radius of the cylinder - - FCDPASCylinder* cylinder = (FCDPASCylinder*)analGeom; - printf("Cylinder\n"); - //Blender exports Z cylinders - //collisionShape = new CylinderShapeZ(SimdVector3(cylinder->radius,cylinder->radius,cylinder->height)); - collisionShape = new CylinderShape(SimdVector3(cylinder->radius,cylinder->height,cylinder->radius)); - - break; - - } - - case FCDPhysicsAnalyticalGeometry::CAPSULE: - - { - - //FIXME: only using the first radius of the capsule - - FCDPASCapsule* capsule = (FCDPASCapsule*)analGeom; - printf("Capsule\n"); - - break; - - } - - case FCDPhysicsAnalyticalGeometry::TAPERED_CAPSULE: - - { - - //FIXME: only using the first radius of the capsule - - FCDPASTaperedCapsule* tcapsule = (FCDPASTaperedCapsule*)analGeom; - printf("TaperedCapsule\n"); - break; - - } - - case FCDPhysicsAnalyticalGeometry::TAPERED_CYLINDER: - - { - - //FIXME: only using the first radius of the cylinder - - FCDPASTaperedCylinder* tcylinder = (FCDPASTaperedCylinder*)analGeom; - printf("TaperedCylinder, creating a cone for now\n"); - if (!tcylinder->height) - { - printf("tapered_cylinder with height 0.0\n"); - tcylinder->height = 1.f; - } - //either use radius1 or radius2 for now - collisionShape = new ConeShape(tcylinder->radius,tcylinder->height); - - break; - - } - - default: - - { - - break; - - } - - } - - //controller->AddShape(NewShape); - } - - }//for all shapes - - - - FCDPhysicsParameter* mass = (FCDPhysicsParameter*)rigidBody->FindParameterByReference(DAE_MASS_ELEMENT); - - float mymass = 1.f; - - if (mass) - { - mymass = *mass->GetValue(); - printf("RB mass:%f\n",mymass); - } - - FCDPhysicsParameter* inertia = (FCDPhysicsParameter*)rigidBody->FindParameterByReference(DAE_INERTIA_ELEMENT); - - if (inertia) - { - inertia->GetValue();//this should be calculated from shape - } - - FCDPhysicsParameter* velocity = (FCDPhysicsParameter*)rigidBody->FindParameterByReference(DAE_VELOCITY_ELEMENT); - - if (velocity) - { - velocity->GetValue(); - } - - FCDPhysicsParameter* angularVelocity = (FCDPhysicsParameter*)rigidBody->FindParameterByReference(DAE_ANGULAR_VELOCITY_ELEMENT); - - if (angularVelocity) - { - angularVelocity->GetValue(); - } - - static int once = true; - - if (collisionShape) - { - once = false; - printf("create Physics Object\n"); - //void LocalCreatePhysicsObject(bool isDynamic, float mass, const SimdTransform& startTransform,CollisionShape* shape) - - collisionShape->setLocalScaling(localScaling); - ms[numObjects].m_localScaling = localScaling; - - LocalCreatePhysicsObject(isDynamic, mymass, accumulatedWorldTransform,collisionShape); - - - } - //controller->SetGlobalPose(n->CalculateWorldTransformation());//?? - - //SAFE_DELETE(rigidBody); - - } - - } - - } - - return true; -} - -#else -//Collada-dom - -#endif @@ -944,12 +116,8 @@ int main(int argc,char** argv) { /// Import Collada 1.4 Physics objects - - //char* filename = "analyticalGeomPhysicsTest.dae";//ColladaPhysics.dae"; - //char* filename = "colladaphysics_spherebox.dae"; - //char* filename = "friction.dae"; + /// also can pass filename in as argument char* filename = "jenga.dae"; - printf("argc=%i\n",argc); { for (int i=0;iinitPhysics(filename); + + + colladaDemo->clientResetScene(); + + colladaDemo->setCameraDistance(26.f); + + return glutmain(argc, argv,640,480,"Bullet COLLADA Physics Viewer http://bullet.sourceforge.net",colladaDemo); +} + +void ColladaDemo::initPhysics(const char* filename) +{ + m_cameraUp = SimdVector3(0,0,1); + m_forwardAxis = 1; ///Setup a Physics Simulation Environment CollisionDispatcher* dispatcher = new CollisionDispatcher(); @@ -971,73 +153,12 @@ int main(int argc,char** argv) SimdVector3 worldAabbMax(10000,10000,10000); OverlappingPairCache* broadphase = new AxisSweep3(worldAabbMin,worldAabbMax); //BroadphaseInterface* broadphase = new SimpleBroadphase(); - physicsEnvironmentPtr = new CcdPhysicsEnvironment(dispatcher,broadphase); - physicsEnvironmentPtr->setDeactivationTime(2.f); - physicsEnvironmentPtr->setGravity(0,0,-10); - physicsEnvironmentPtr->setDebugDrawer(&debugDrawer); + m_physicsEnvironmentPtr = new CcdPhysicsEnvironment(dispatcher,broadphase); + m_physicsEnvironmentPtr->setDeactivationTime(2.f); + m_physicsEnvironmentPtr->setGravity(0,0,-10); + m_physicsEnvironmentPtr->setDebugDrawer(&debugDrawer); - - -#ifdef QUAKE_BSP_IMPORTING - - void* memoryBuffer = 0; - char* bspfilename = "bsptest.bsp"; - FILE* file = fopen(bspfilename,"r"); - if (!file) - { - //try again other path, - //sight... visual studio leaves the current working directory in the projectfiles folder - //instead of executable folder. who wants this default behaviour?!? - bspfilename = "../../bsptest.bsp"; - file = fopen(bspfilename,"r"); - } - if (file) - { - BspLoader bspLoader; - int size=0; - if (fseek(file, 0, SEEK_END) || (size = ftell(file)) == EOF || fseek(file, 0, SEEK_SET)) { /* File operations denied? ok, just close and return failure */ - printf("Error: cannot get filesize from %s\n", bspfilename); - } else - { - //how to detect file size? - memoryBuffer = malloc(size+1); - fread(memoryBuffer,1,size,file); - bspLoader.LoadBSPFile( memoryBuffer); - - BspToBulletConverter bsp2bullet; - float bspScaling = 0.1f; - bsp2bullet.convertBsp(bspLoader,bspScaling); - - } - fclose(file); - } - -#endif - - - - -#ifdef USE_FCOLLADA - - FCDocument* document = new FCDocument(); - FUStatus status = document->LoadFromFile(filename); - bool success = status.IsSuccessful(); - printf ("Collada import %i\n",success); - - if (success) - { - const FCDPhysicsSceneNode* physicsSceneRoot = document->GetPhysicsSceneRoot(); - if (ConvertColladaPhysicsToBulletPhysics( physicsSceneRoot )) - { - printf("ConvertColladaPhysicsToBulletPhysics successfull\n"); - } else - { - printf("ConvertColladaPhysicsToBulletPhysics failed\n"); - } - } -#else - - MyColladaConverter* converter = new MyColladaConverter; + MyColladaConverter* converter = new MyColladaConverter(this); bool result = converter->load(filename); @@ -1052,279 +173,14 @@ int main(int argc,char** argv) { gColladaConverter = 0; } - -#endif - - clientResetScene(); - - setCameraDistance(26.f); - - return glutmain(argc, argv,640,480,"Bullet COLLADA Physics Viewer http://bullet.sourceforge.net"); } -//to be implemented by the demo -void renderme() -{ - debugDrawer.SetDebugMode(getDebugMode()); - - - float m[16]; - int i; - - - if (getDebugMode() & IDebugDraw::DBG_DisableBulletLCP) - { - //don't use Bullet, use quickstep - physicsEnvironmentPtr->setSolverType(0); - } else - { - //Bullet LCP solver - physicsEnvironmentPtr->setSolverType(1); - } - - if (getDebugMode() & IDebugDraw::DBG_EnableCCD) - { - physicsEnvironmentPtr->setCcdMode(3); - } else - { - physicsEnvironmentPtr->setCcdMode(0); - } - - - bool isSatEnabled = (getDebugMode() & IDebugDraw::DBG_EnableSatComparison); - - physicsEnvironmentPtr->EnableSatCollisionDetection(isSatEnabled); - - - - for (i=0;iGetRigidBody()->GetActivationState() == 1) //active - { - if (i & 1) - { - wireColor += SimdVector3 (1.f,0.f,0.f); - } else - { - wireColor += SimdVector3 (.5f,0.f,0.f); - } - } - if (physObjects[i]->GetRigidBody()->GetActivationState() == 2) //ISLAND_SLEEPING - { - if (i & 1) - { - wireColor += SimdVector3 (0.f,1.f, 0.f); - } else - { - wireColor += SimdVector3 (0.f,0.5f,0.f); - } - } - - char extraDebug[125]; - - sprintf(extraDebug,"islandId=%i, Body=%i, ShapeType=%s",physObjects[i]->GetRigidBody()->m_islandTag1,physObjects[i]->GetRigidBody()->m_debugBodyId,physObjects[i]->GetRigidBody()->GetCollisionShape()->GetName()); - physObjects[i]->GetRigidBody()->GetCollisionShape()->SetExtraDebugInfo(extraDebug); - GL_ShapeDrawer::DrawOpenGL(m,physObjects[i]->GetRigidBody()->GetCollisionShape(),wireColor,getDebugMode()); - - ///this block is just experimental code to show some internal issues with replacing shapes on the fly. - if (getDebugMode()!=0 && (i>0)) - { - if (physObjects[i]->GetRigidBody()->GetCollisionShape()->GetShapeType() == EMPTY_SHAPE_PROXYTYPE) - { - physObjects[i]->GetRigidBody()->SetCollisionShape(gShapePtr[1]); - - //remove the persistent collision pairs that were created based on the previous shape - - BroadphaseProxy* bpproxy = physObjects[i]->GetRigidBody()->m_broadphaseHandle; - - physicsEnvironmentPtr->GetBroadphase()->CleanProxyFromPairs(bpproxy); - - SimdVector3 newinertia; - SimdScalar newmass = 10.f; - physObjects[i]->GetRigidBody()->GetCollisionShape()->CalculateLocalInertia(newmass,newinertia); - physObjects[i]->GetRigidBody()->setMassProps(newmass,newinertia); - physObjects[i]->GetRigidBody()->updateInertiaTensor(); - - } - - } - - - } - - if (!(getDebugMode() & IDebugDraw::DBG_NoHelpText)) - { - - float xOffset = 10.f; - float yStart = 20.f; - - float yIncr = -2.f; - - SimdVector3 offset(xOffset,0,0); - SimdVector3 up = gCameraUp; - char buf[124]; - - glColor3f(0, 0, 0); - -#ifdef USE_QUICKPROF - - - if ( getDebugMode() & IDebugDraw::DBG_ProfileTimings) - { - static int counter = 0; - counter++; - std::map::iterator iter; - for (iter = Profiler::mProfileBlocks.begin(); iter != Profiler::mProfileBlocks.end(); ++iter) - { - char blockTime[128]; - sprintf(blockTime, "%s: %lf",&((*iter).first[0]),Profiler::getBlockTime((*iter).first, Profiler::BLOCK_CYCLE_SECONDS));//BLOCK_TOTAL_PERCENT)); - glRasterPos3f(xOffset,yStart,0); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),blockTime); - yStart += yIncr; - - } - } -#endif //USE_QUICKPROF - //profiling << Profiler::createStatsString(Profiler::BLOCK_TOTAL_PERCENT); - //<< std::endl; - - - SimdVector3 textPos = offset + up*yStart; - glRasterPos3f(textPos.getX(),textPos.getY(),textPos.getZ()); - sprintf(buf,"mouse to interact"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - - yStart += yIncr; - textPos = offset + up*yStart; - glRasterPos3f(textPos.getX(),textPos.getY(),textPos.getZ()); - sprintf(buf,"space to reset"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - textPos = offset + up*yStart; - glRasterPos3f(textPos.getX(),textPos.getY(),textPos.getZ()); - - sprintf(buf,"cursor keys and z,x to navigate"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - textPos = offset + up*yStart ; - glRasterPos3f(textPos.getX(),textPos.getY(),textPos.getZ()); - - sprintf(buf,"i to toggle simulation, s single step"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - textPos = offset + up*yStart ; - glRasterPos3f(textPos.getX(),textPos.getY(),textPos.getZ()); - - sprintf(buf,"q to quit"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - textPos = offset + up*yStart ; - glRasterPos3f(textPos.getX(),textPos.getY(),textPos.getZ()); - - sprintf(buf,"d to toggle deactivation"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - textPos = offset + up*yStart ; - glRasterPos3f(textPos.getX(),textPos.getY(),textPos.getZ()); - - sprintf(buf,"a to draw temporal AABBs"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - textPos = offset + up*yStart ; - glRasterPos3f(textPos.getX(),textPos.getY(),textPos.getZ()); - sprintf(buf,"e to export COLLADA 1.4 physics snapshot"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - textPos = offset + up*yStart ; - glRasterPos3f(textPos.getX(),textPos.getY(),textPos.getZ()); - sprintf(buf,"c to show contact points (wireframe more)"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - - textPos = offset + up*yStart ; - glRasterPos3f(textPos.getX(),textPos.getY(),textPos.getZ()); - - - sprintf(buf,"h to toggle help text"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - bool useBulletLCP = !(getDebugMode() & IDebugDraw::DBG_DisableBulletLCP); - - bool useCCD = (getDebugMode() & IDebugDraw::DBG_EnableCCD); - - textPos = offset + up*yStart ; - glRasterPos3f(textPos.getX(),textPos.getY(),textPos.getZ()); - - - sprintf(buf,"m Bullet GJK = %i",!isSatEnabled); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - textPos = offset + up*yStart ; - glRasterPos3f(textPos.getX(),textPos.getY(),textPos.getZ()); - - sprintf(buf,"n Bullet LCP = %i",useBulletLCP); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - textPos = offset + up*yStart ; - glRasterPos3f(textPos.getX(),textPos.getY(),textPos.getZ()); - - sprintf(buf,"1 CCD mode (adhoc) = %i",useCCD); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - textPos = offset + up*yStart ; - glRasterPos3f(textPos.getX(),textPos.getY(),textPos.getZ()); - - sprintf(buf,"+- shooting speed = %10.2f",bulletSpeed); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - } - -} - -void clientMoveAndDisplay() +void ColladaDemo::clientMoveAndDisplay() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - physicsEnvironmentPtr->proceedDeltaTime(0.f,deltaTime); + m_physicsEnvironmentPtr->proceedDeltaTime(0.f,deltaTime); renderme(); @@ -1335,12 +191,12 @@ void clientMoveAndDisplay() -void clientDisplay(void) { +void ColladaDemo::displayCallback(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - physicsEnvironmentPtr->UpdateAabbs(deltaTime); + m_physicsEnvironmentPtr->UpdateAabbs(deltaTime); renderme(); @@ -1351,282 +207,19 @@ void clientDisplay(void) { -///make this positive to show stack falling from a distance -///this shows the penalty tresholds in action, springy/spungy look -void clientResetScene() + + +void ColladaDemo::keyboardCallback(unsigned char key, int x, int y) { - for (int i=0;isetPosition(startTransforms[i].getOrigin().getX(),startTransforms[i].getOrigin().getY(),startTransforms[i].getOrigin().getZ()); - physObjects[i]->SetLinearVelocity(0,0,0,0); - physObjects[i]->SetAngularVelocity(0,0,0,0); - SimdQuaternion orn; - startTransforms[i].getBasis().getRotation(orn); - physObjects[i]->setOrientation(orn.x(),orn.y(),orn.z(),orn[3]); - - } - - //delete and reload, or keep transforms ready? -} - - - -void shootBox(const SimdVector3& destination) -{ - - bool isDynamic = true; - float mass = 1.f; - SimdTransform startTransform; - startTransform.setIdentity(); - startTransform.setOrigin(SimdVector3(eye[0],eye[1],eye[2])); - CollisionShape* boxShape = new BoxShape(SimdVector3(1.f,1.f,1.f)); - - LocalCreatePhysicsObject(isDynamic, mass, startTransform,boxShape); - - int i = numObjects-1; - - - - SimdVector3 linVel(destination[0]-eye[0],destination[1]-eye[1],destination[2]-eye[2]); - linVel.normalize(); - linVel*=bulletSpeed; - - physObjects[i]->setPosition(eye[0],eye[1],eye[2]); - physObjects[i]->setOrientation(0,0,0,1); - physObjects[i]->SetLinearVelocity(linVel[0],linVel[1],linVel[2],false); - physObjects[i]->SetAngularVelocity(0,0,0,false); -} - -void clientSpecialKeyboard(int key, int x, int y) -{ - defaultSpecialKeyboard(key,x,y); -} - -void clientKeyboard(unsigned char key, int x, int y) -{ - -#ifndef USE_FCOLLADA if (key =='e') { //save a COLLADA .dae physics snapshot if (gColladaConverter) gColladaConverter->saveAs(); - } -#endif - if (key == '.') + } else { - shootBox(SimdVector3(0,0,0)); - } - - if (key == '+') - { - bulletSpeed += 10.f; - } - if (key == '-') - { - bulletSpeed -= 10.f; - } - - defaultKeyboard(key, x, y); -} - -int gPickingConstraintId = 0; -SimdVector3 gOldPickingPos; -float gOldPickingDist = 0.f; -RigidBody* pickedBody = 0;//for deactivation state - - - -SimdVector3 GetRayTo(int x,int y) -{ - float top = 1.f; - float bottom = -1.f; - float nearPlane = 1.f; - float tanFov = (top-bottom)*0.5f / nearPlane; - float fov = 2.0 * atanf (tanFov); - - SimdVector3 rayFrom(eye[0],eye[1],eye[2]); - SimdVector3 rayForward = -rayFrom; - rayForward.normalize(); - float farPlane = 600.f; - rayForward*= farPlane; - - SimdVector3 rightOffset; - SimdVector3 vertical = gCameraUp; - - SimdVector3 hor; - hor = rayForward.cross(vertical); - hor.normalize(); - vertical = hor.cross(rayForward); - vertical.normalize(); - - float tanfov = tanf(0.5f*fov); - hor *= 2.f * farPlane * tanfov; - vertical *= 2.f * farPlane * tanfov; - SimdVector3 rayToCenter = rayFrom + rayForward; - SimdVector3 dHor = hor * 1.f/float(glutScreenWidth); - SimdVector3 dVert = vertical * 1.f/float(glutScreenHeight); - SimdVector3 rayTo = rayToCenter - 0.5f * hor + 0.5f * vertical; - rayTo += x * dHor; - rayTo -= y * dVert; - return rayTo; -} -void clientMouseFunc(int button, int state, int x, int y) -{ - //printf("button %i, state %i, x=%i,y=%i\n",button,state,x,y); - //button 0, state 0 means left mouse down - - SimdVector3 rayTo = GetRayTo(x,y); - - switch (button) - { - case 2: - { - if (state==0) - { - shootBox(rayTo); - } - break; - }; - case 1: - { - if (state==0) - { - //apply an impulse - if (physicsEnvironmentPtr) - { - float hit[3]; - float normal[3]; - PHY_IPhysicsController* hitObj = physicsEnvironmentPtr->rayTest(0,eye[0],eye[1],eye[2],rayTo.getX(),rayTo.getY(),rayTo.getZ(),hit[0],hit[1],hit[2],normal[0],normal[1],normal[2]); - if (hitObj) - { - CcdPhysicsController* physCtrl = static_cast(hitObj); - RigidBody* body = physCtrl->GetRigidBody(); - if (body) - { - body->SetActivationState(ACTIVE_TAG); - SimdVector3 impulse = rayTo; - impulse.normalize(); - float impulseStrength = 10.f; - impulse *= impulseStrength; - SimdVector3 relPos( - hit[0] - body->getCenterOfMassPosition().getX(), - hit[1] - body->getCenterOfMassPosition().getY(), - hit[2] - body->getCenterOfMassPosition().getZ()); - - body->applyImpulse(impulse,relPos); - } - - } - - } - - } else - { - - } - break; - } - case 0: - { - if (state==0) - { - //add a point to point constraint for picking - if (physicsEnvironmentPtr) - { - float hit[3]; - float normal[3]; - PHY_IPhysicsController* hitObj = physicsEnvironmentPtr->rayTest(0,eye[0],eye[1],eye[2],rayTo.getX(),rayTo.getY(),rayTo.getZ(),hit[0],hit[1],hit[2],normal[0],normal[1],normal[2]); - if (hitObj) - { - - CcdPhysicsController* physCtrl = static_cast(hitObj); - RigidBody* body = physCtrl->GetRigidBody(); - - if (body && !body->IsStatic()) - { - pickedBody = body; - pickedBody->SetActivationState(DISABLE_DEACTIVATION); - - SimdVector3 pickPos(hit[0],hit[1],hit[2]); - - SimdVector3 localPivot = body->getCenterOfMassTransform().inverse() * pickPos; - - gPickingConstraintId = physicsEnvironmentPtr->createConstraint(physCtrl,0,PHY_POINT2POINT_CONSTRAINT, - localPivot.getX(), - localPivot.getY(), - localPivot.getZ(), - 0,0,0); - //printf("created constraint %i",gPickingConstraintId); - - //save mouse position for dragging - gOldPickingPos = rayTo; - - - SimdVector3 eyePos(eye[0],eye[1],eye[2]); - - gOldPickingDist = (pickPos-eyePos).length(); - - Point2PointConstraint* p2p = static_cast(physicsEnvironmentPtr->getConstraintById(gPickingConstraintId)); - if (p2p) - { - //very weak constraint for picking - p2p->m_setting.m_tau = 0.1f; - } - } - } - } - } else - { - if (gPickingConstraintId && physicsEnvironmentPtr) - { - physicsEnvironmentPtr->removeConstraint(gPickingConstraintId); - //printf("removed constraint %i",gPickingConstraintId); - gPickingConstraintId = 0; - pickedBody->ForceActivationState(ACTIVE_TAG); - pickedBody->m_deactivationTime = 0.f; - pickedBody = 0; - - - } - } - - break; - - } - default: - { - } - } - -} - -void clientMotionFunc(int x,int y) -{ - - if (gPickingConstraintId && physicsEnvironmentPtr) - { - - //move the constraint pivot - - Point2PointConstraint* p2p = static_cast(physicsEnvironmentPtr->getConstraintById(gPickingConstraintId)); - if (p2p) - { - //keep it at the same picking distance - - SimdVector3 newRayTo = GetRayTo(x,y); - SimdVector3 eyePos(eye[0],eye[1],eye[2]); - SimdVector3 dir = newRayTo-eyePos; - dir.normalize(); - dir *= gOldPickingDist; - - SimdVector3 newPos = eyePos + dir; - p2p->SetPivotB(newPos); - } - + DemoApplication::keyboardCallback(key,x,y); } } - diff --git a/Demos/ColladaDemo/BspConverter.h b/Demos/ColladaDemo/ColladaDemo.h similarity index 51% rename from Demos/ColladaDemo/BspConverter.h rename to Demos/ColladaDemo/ColladaDemo.h index 01e9c9c5b..047aeb6b0 100644 --- a/Demos/ColladaDemo/BspConverter.h +++ b/Demos/ColladaDemo/ColladaDemo.h @@ -12,29 +12,29 @@ subject to the following restrictions: 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ +#ifndef COLLADA_PHYSICS_DEMO_H +#define COLLADA_PHYSICS_DEMO_H -#ifndef BSP_CONVERTER_H -#define BSP_CONVERTER_H +#include "DemoApplication.h" -class BspLoader; -#include -#include "SimdVector3.h" - -///BspConverter turns a loaded bsp level into convex parts (vertices) -class BspConverter +///ColladaDemo shows the loading and exporting of COLLADA physics xml files. +///It uses COLLADA DOM +class ColladaDemo : public DemoApplication { public: - void convertBsp(BspLoader& bspLoader,float scaling); + void initPhysics(const char* filename); - ///Utility function to create vertices from a Quake Brush. Brute force but it works. - ///Bit overkill to use QHull package - void getVerticesFromPlaneEquations(const std::vector& planeEquations , std::vector& verticesOut ); - bool isInside(const std::vector& planeEquations, const SimdVector3& point, float margin); + virtual void clientMoveAndDisplay(); - ///this callback is called for each brush that succesfully converted into vertices - virtual void AddConvexVerticesCollider(std::vector& vertices, bool isEntity, const SimdVector3& entityTargetLocation) = 0; + virtual void displayCallback(); + + virtual void clientResetScene() + { + } + + virtual void keyboardCallback(unsigned char key, int x, int y); }; -#endif //BSP_CONVERTER_H \ No newline at end of file +#endif //COLLADA_PHYSICS_DEMO_H \ No newline at end of file diff --git a/Demos/CollisionDemo/CollisionDemo.cpp b/Demos/CollisionDemo/CollisionDemo.cpp index 9c39dd2c4..d146d7661 100644 --- a/Demos/CollisionDemo/CollisionDemo.cpp +++ b/Demos/CollisionDemo/CollisionDemo.cpp @@ -30,19 +30,10 @@ subject to the following restrictions: #include "NarrowPhaseCollision/VoronoiSimplexSolver.h" #include "NarrowPhaseCollision/ConvexPenetrationDepthSolver.h" +#include "CollisionDemo.h" #include "GL_ShapeDrawer.h" -#ifdef WIN32 //needed for glut.h -#include -#endif -//think different -#if defined(__APPLE__) && !defined (VMDMESA) -#include -#include -#include -#else -#include -#endif #include "GlutStuff.h" +#include "IDebugDraw.h" float yaw=0.f,pitch=0.f,roll=0.f; @@ -64,7 +55,22 @@ void DrawRasterizerLine(float const* , float const*, int) int main(int argc,char** argv) { - setCameraDistance(20.f); + CollisionDemo* colDemo = new CollisionDemo(); + + colDemo->setCameraDistance(18.f); + + colDemo->initPhysics(); + + + + return glutmain(argc, argv,screenWidth,screenHeight,"Collision Demo",colDemo); +} + +void CollisionDemo::initPhysics() +{ + m_debugMode |= IDebugDraw::DBG_DrawWireframe; + m_azi = 250.f; + m_ele = 25.f; tr[0].setOrigin(SimdVector3(0.0013328250f,8.1363249f,7.0390840f)); tr[1].setOrigin(SimdVector3(0.00000000f,9.1262732f,2.0343180f)); @@ -90,25 +96,17 @@ int main(int argc,char** argv) SimdVector3 boxHalfExtentsA(1.0000004768371582f,1.0000004768371582f,1.0000001192092896f); SimdVector3 boxHalfExtentsB(3.2836332321166992f,3.2836332321166992f,3.2836320400238037f); - BoxShape boxA(boxHalfExtentsA); - BoxShape boxB(boxHalfExtentsB); - shapePtr[0] = &boxA; - shapePtr[1] = &boxB; - + BoxShape* boxA = new BoxShape(boxHalfExtentsA); + BoxShape* boxB = new BoxShape(boxHalfExtentsB); + shapePtr[0] = boxA; + shapePtr[1] = boxB; - SimdTransform tr; - tr.setIdentity(); - - - return glutmain(argc, argv,screenWidth,screenHeight,"Collision Demo"); } -//to be implemented by the demo - -void clientMoveAndDisplay() +void CollisionDemo::clientMoveAndDisplay() { - clientDisplay(); + displayCallback(); } @@ -117,7 +115,7 @@ SimplexSolverInterface& gGjkSimplexSolver = sGjkSimplexSolver; -void clientDisplay(void) { +void CollisionDemo::displayCallback(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDisable(GL_LIGHTING); @@ -182,37 +180,10 @@ void clientDisplay(void) { orn.setEuler(yaw,pitch,roll); tr[0].setRotation(orn); -// pitch += 0.005f; -// yaw += 0.01f; + pitch += 0.005f; + yaw += 0.01f; glFlush(); glutSwapBuffers(); } - - - - -void clientResetScene() -{ - -} - -void clientSpecialKeyboard(int key, int x, int y) -{ - defaultSpecialKeyboard(key,x,y); -} - -void clientKeyboard(unsigned char key, int x, int y) -{ - defaultKeyboard(key, x, y); -} - - -void clientMouseFunc(int button, int state, int x, int y) -{ - -} -void clientMotionFunc(int x,int y) -{ -} diff --git a/Demos/CollisionDemo/CollisionDemo.h b/Demos/CollisionDemo/CollisionDemo.h new file mode 100644 index 000000000..a69eaae17 --- /dev/null +++ b/Demos/CollisionDemo/CollisionDemo.h @@ -0,0 +1,36 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef COLLISION_DEMO_H +#define COLLISION_DEMO_H + +#include "DemoApplication.h" + +///CollisionDemo shows the low-level direct access to GJK +class CollisionDemo : public DemoApplication +{ + public: + + void initPhysics(); + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + virtual void clientResetScene() + { + } +}; + +#endif //COLLISION_DEMO_H \ No newline at end of file diff --git a/Demos/CollisionInterfaceDemo/CollisionInterfaceDemo.cpp b/Demos/CollisionInterfaceDemo/CollisionInterfaceDemo.cpp index 716ea1b48..a59a86cb3 100644 --- a/Demos/CollisionInterfaceDemo/CollisionInterfaceDemo.cpp +++ b/Demos/CollisionInterfaceDemo/CollisionInterfaceDemo.cpp @@ -24,29 +24,14 @@ subject to the following restrictions: #include "CollisionShapes/ConvexHullShape.h" #include "CollisionShapes/BoxShape.h" - - - #include "CollisionDispatch/CollisionWorld.h" #include "CollisionDispatch/CollisionObject.h" #include "CollisionDispatch/CollisionDispatcher.h" #include "BroadphaseCollision/SimpleBroadphase.h" #include "BroadphaseCollision/AxisSweep3.h" - - - +#include "IDebugDraw.h" #include "GL_ShapeDrawer.h" -#ifdef WIN32 //needed for glut.h -#include -#endif -//think different -#if defined(__APPLE__) && !defined (VMDMESA) -#include -#include -#include -#else -#include -#endif +#include "CollisionInterfaceDemo.h" #include "GlutStuff.h" @@ -66,8 +51,20 @@ int screenHeight = 480.f; int main(int argc,char** argv) { - clientResetScene(); + CollisionInterfaceDemo* collisionInterfaceDemo = new CollisionInterfaceDemo(); + collisionInterfaceDemo->initPhysics(); + + collisionInterfaceDemo->clientResetScene(); + + return glutmain(argc, argv,screenWidth,screenHeight,"Collision Interface Demo",collisionInterfaceDemo); +} + +void CollisionInterfaceDemo::initPhysics() +{ + + m_debugMode |= IDebugDraw::DBG_DrawWireframe; + SimdMatrix3x3 basisA; basisA.setIdentity(); @@ -80,38 +77,39 @@ int main(int argc,char** argv) SimdPoint3 points0[3]={SimdPoint3(1,0,0),SimdPoint3(0,1,0),SimdPoint3(0,0,1)}; SimdPoint3 points1[5]={SimdPoint3(1,0,0),SimdPoint3(0,1,0),SimdPoint3(0,0,1),SimdPoint3(0,0,-1),SimdPoint3(-1,-1,0)}; - BoxShape boxA(SimdVector3(1,1,1)); - BoxShape boxB(SimdVector3(0.5,0.5,0.5)); + BoxShape* boxA = new BoxShape(SimdVector3(1,1,1)); + BoxShape* boxB = new BoxShape(SimdVector3(0.5,0.5,0.5)); //ConvexHullShape hullA(points0,3); //hullA.setLocalScaling(SimdVector3(3,3,3)); //ConvexHullShape hullB(points1,4); //hullB.setLocalScaling(SimdVector3(4,4,4)); + objects[0].m_collisionShape = boxA;//&hullA; + objects[1].m_collisionShape = boxB;//&hullB; - objects[0].m_collisionShape = &boxA;//&hullA; - objects[1].m_collisionShape = &boxB;//&hullB; - - CollisionDispatcher dispatcher; - //SimpleBroadphase broadphase; + CollisionDispatcher* dispatcher = new CollisionDispatcher; SimdVector3 worldAabbMin(-1000,-1000,-1000); SimdVector3 worldAabbMax(1000,1000,1000); - AxisSweep3 broadphase(worldAabbMin,worldAabbMax); + AxisSweep3* broadphase = new AxisSweep3(worldAabbMin,worldAabbMax); + + //SimpleBroadphase is a brute force alternative, performing N^2 aabb overlap tests + //SimpleBroadphase* broadphase = new SimpleBroadphase; - collisionWorld = new CollisionWorld(&dispatcher,&broadphase); + collisionWorld = new CollisionWorld(dispatcher,broadphase); collisionWorld->AddCollisionObject(&objects[0]); collisionWorld->AddCollisionObject(&objects[1]); - return glutmain(argc, argv,screenWidth,screenHeight,"Collision Interface Demo"); } + //to be implemented by the demo -void clientMoveAndDisplay() +void CollisionInterfaceDemo::clientMoveAndDisplay() { - clientDisplay(); + displayCallback(); } @@ -120,7 +118,7 @@ SimplexSolverInterface& gGjkSimplexSolver = sGjkSimplexSolver; -void clientDisplay(void) { +void CollisionInterfaceDemo::displayCallback(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDisable(GL_LIGHTING); @@ -129,7 +127,7 @@ void clientDisplay(void) { collisionWorld->PerformDiscreteCollisionDetection(); int i; -/* + ///one way to draw all the contact points is iterating over contact manifolds / points: int numManifolds = collisionWorld->GetDispatcher()->GetNumManifolds(); @@ -155,9 +153,10 @@ void clientDisplay(void) { glVertex3d(ptB.x(),ptB.y(),ptB.z()); glEnd(); } - } -*/ + //you can un-comment out this line, and then all points are removed + //contactManifold->ClearManifold(); + } //GL_ShapeDrawer::DrawCoordSystem(); @@ -178,7 +177,7 @@ void clientDisplay(void) { orn.setEuler(yaw,pitch,roll); objects[1].m_worldTransform.setOrigin(objects[1].m_worldTransform.getOrigin()+SimdVector3(0,-0.01,0)); - //objects[0].m_worldTransform.setRotation(orn); + objects[0].m_worldTransform.setRotation(orn); pitch += 0.005f; yaw += 0.01f; @@ -187,28 +186,10 @@ void clientDisplay(void) { glutSwapBuffers(); } -void clientResetScene() +void CollisionInterfaceDemo::clientResetScene() { objects[0].m_worldTransform.setOrigin(SimdVector3(0.0f,3.f,0.f)); objects[1].m_worldTransform.setOrigin(SimdVector3(0.0f,9.f,0.f)); } -void clientSpecialKeyboard(int key, int x, int y) -{ - defaultSpecialKeyboard(key,x,y); -} -void clientKeyboard(unsigned char key, int x, int y) -{ - defaultKeyboard(key, x, y); -} - - - -void clientMouseFunc(int button, int state, int x, int y) -{ - -} -void clientMotionFunc(int x,int y) -{ -} diff --git a/Demos/CollisionInterfaceDemo/CollisionInterfaceDemo.h b/Demos/CollisionInterfaceDemo/CollisionInterfaceDemo.h new file mode 100644 index 000000000..35c2ec99a --- /dev/null +++ b/Demos/CollisionInterfaceDemo/CollisionInterfaceDemo.h @@ -0,0 +1,35 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef COLLISION_INTERFACE_DEMO_H +#define COLLISION_INTERFACE_DEMO_H + +#include "DemoApplication.h" + +///CollisionInterfaceDemo shows how to use the collision detection without dynamics (CollisionWorld/CollisionObject) +class CollisionInterfaceDemo : public DemoApplication +{ + public: + + void initPhysics(); + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + virtual void clientResetScene(); + +}; + +#endif //COLLISION_INTERFACE_DEMO_H \ No newline at end of file diff --git a/Demos/ConcaveDemo/ConcaveDemo.h b/Demos/ConcaveDemo/ConcaveDemo.h new file mode 100644 index 000000000..f162c7d69 --- /dev/null +++ b/Demos/ConcaveDemo/ConcaveDemo.h @@ -0,0 +1,36 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef CONCAVE_DEMO_H +#define CONCAVE_DEMO_H + +#include "DemoApplication.h" + +///ConcaveDemo shows usage of static concave triangle meshes +///It also shows per-triangle material (friction/restitution) through CustomMaterialCombinerCallback +class ConcaveDemo : public DemoApplication +{ + public: + + void initPhysics(); + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + virtual void clientResetScene(); + +}; + +#endif //CONCAVE_DEMO_H \ No newline at end of file diff --git a/Demos/ConcaveDemo/ConcavePhysicsDemo.cpp b/Demos/ConcaveDemo/ConcavePhysicsDemo.cpp index 429eb56fc..f19373368 100644 --- a/Demos/ConcaveDemo/ConcavePhysicsDemo.cpp +++ b/Demos/ConcaveDemo/ConcavePhysicsDemo.cpp @@ -16,76 +16,28 @@ subject to the following restrictions: #include "CcdPhysicsEnvironment.h" #include "CcdPhysicsController.h" #include "MyMotionState.h" -//#include "GL_LineSegmentShape.h" #include "CollisionShapes/BoxShape.h" #include "CollisionShapes/Simplex1to4Shape.h" #include "Dynamics/RigidBody.h" #include "BroadphaseCollision/AxisSweep3.h" #include "ConstraintSolver/SequentialImpulseConstraintSolver.h" -//#include "ConstraintSolver/OdeConstraintSolver.h" #include "CollisionDispatch/CollisionDispatcher.h" #include "BroadphaseCollision/SimpleBroadphase.h" #include "CollisionShapes/TriangleMeshShape.h" #include "CollisionShapes/TriangleIndexVertexArray.h" #include "CollisionShapes/BvhTriangleMeshShape.h" #include "CollisionShapes/TriangleMesh.h" - #include "IDebugDraw.h" #include "GLDebugDrawer.h" - #include "PHY_Pro.h" - - -#ifdef WIN32 //needed for glut.h -#include -#endif -//think different -#if defined(__APPLE__) && !defined (VMDMESA) -#include -#include -#include -#else -#include -#endif - +#include "ConcaveDemo.h" #include "GL_ShapeDrawer.h" - #include "GlutStuff.h" - -const int numObjects = 80; - -const int maxNumObjects = 100; -MyMotionState ms[maxNumObjects]; -CcdPhysicsController* physObjects[maxNumObjects] = {0,0,0,0}; -int shapeIndex[maxNumObjects]; -CcdPhysicsEnvironment* physicsEnvironmentPtr = 0; - -TriangleMesh meshData; -StridingMeshInterface* ptr; GLDebugDrawer debugDrawer; -//GL_LineSegmentShape shapeE(SimdPoint3(-50,0,0), -// SimdPoint3(50,0,0)); -CollisionShape* shapePtr[5] = -{ - new BoxShape (SimdVector3(100,10,100)), - new BoxShape (SimdVector3(2,2,2)), - new BU_Simplex1to4(SimdPoint3(-2,-2,-2),SimdPoint3(2,-2,-2),SimdPoint3(-2,2,-2),SimdPoint3(0,0,2)), - - - new BoxShape (SimdVector3(1,3,1)), -#ifdef DEBUG_MESH - new TriangleMeshShape(&meshData), -#else - NULL, -#endif - //(&meshData) - -}; - static const int NUM_VERTICES = 5; static const int NUM_TRIANGLES=4; @@ -155,82 +107,16 @@ int main(int argc,char** argv) { gContactAddedCallback = CustomMaterialCombinerCallback; - printf("BroadphaseProxy: %i\n",sizeof(BroadphaseProxy)); - printf("AxisSweep3::Handle : %i\n",sizeof(AxisSweep3::Handle)); + ConcaveDemo* concaveDemo = new ConcaveDemo(); + concaveDemo->initPhysics(); + concaveDemo->setCameraDistance(30.f); - printf("SimpleBroadphaseProxy : %i\n",sizeof(SimpleBroadphaseProxy)); + return glutmain(argc, argv,640,480,"Static Concave Mesh Demo",concaveDemo); +} - printf("RigidBody : %i\n",sizeof(RigidBody)); - - printf("CcdPhysicsController: %i\n",sizeof(CcdPhysicsController)); - - printf("ManifoldPoint: %i\n",sizeof(ManifoldPoint)); - - - - setCameraDistance(30.f); - -#define TRISIZE 10.f -#ifdef DEBUG_MESH - SimdVector3 vert0(-TRISIZE ,0,TRISIZE ); - SimdVector3 vert1(TRISIZE ,10,TRISIZE ); - SimdVector3 vert2(TRISIZE ,0,-TRISIZE ); - meshData.AddTriangle(vert0,vert1,vert2); - SimdVector3 vert3(-TRISIZE ,0,TRISIZE ); - SimdVector3 vert4(TRISIZE ,0,-TRISIZE ); - SimdVector3 vert5(-TRISIZE ,0,-TRISIZE ); - meshData.AddTriangle(vert3,vert4,vert5); -#else -#ifdef ODE_MESH - SimdVector3 Size = SimdVector3(15.f,15.f,12.5f); - - gVertices[0][0] = -Size[0]; - gVertices[0][1] = Size[2]; - gVertices[0][2] = -Size[1]; - - gVertices[1][0] = Size[0]; - gVertices[1][1] = Size[2]; - gVertices[1][2] = -Size[1]; - - gVertices[2][0] = Size[0]; - gVertices[2][1] = Size[2]; - gVertices[2][2] = Size[1]; - - gVertices[3][0] = -Size[0]; - gVertices[3][1] = Size[2]; - gVertices[3][2] = Size[1]; - - gVertices[4][0] = 0; - gVertices[4][1] = 0; - gVertices[4][2] = 0; - - gIndices[0] = 0; - gIndices[1] = 1; - gIndices[2] = 4; - - gIndices[3] = 1; - gIndices[4] = 2; - gIndices[5] = 4; - - gIndices[6] = 2; - gIndices[7] = 3; - gIndices[8] = 4; - - gIndices[9] = 3; - gIndices[10] = 0; - gIndices[11] = 4; - - int vertStride = sizeof(SimdVector3); - int indexStride = 3*sizeof(int); - - TriangleIndexVertexArray* indexVertexArrays = new TriangleIndexVertexArray(NUM_TRIANGLES, - gIndices, - indexStride, - NUM_VERTICES,(float*) &gVertices[0].x(),vertStride); - - //shapePtr[4] = new TriangleMeshShape(indexVertexArrays); - shapePtr[4] = new BvhTriangleMeshShape(indexVertexArrays); -#else +void ConcaveDemo::initPhysics() +{ + #define TRISIZE 10.f int vertStride = sizeof(SimdVector3); int indexStride = 3*sizeof(int); @@ -274,190 +160,49 @@ int main(int argc,char** argv) indexStride, totalVerts,(float*) &gVertices[0].x(),vertStride); - //shapePtr[4] = new TriangleMeshShape(indexVertexArrays); - shapePtr[4] = new BvhTriangleMeshShape(indexVertexArrays); -#endif + CollisionShape* trimeshShape = new BvhTriangleMeshShape(indexVertexArrays); + - -#endif//DEBUG_MESH - - - - ConstraintSolver* solver = new SequentialImpulseConstraintSolver; - //ConstraintSolver* solver = new OdeConstraintSolver; - + CollisionDispatcher* dispatcher = new CollisionDispatcher(); OverlappingPairCache* broadphase = new SimpleBroadphase(); - physicsEnvironmentPtr = new CcdPhysicsEnvironment(dispatcher,broadphase); + m_physicsEnvironmentPtr = new CcdPhysicsEnvironment(dispatcher,broadphase); + bool isDynamic = false; + float mass = 0.f; + SimdTransform startTransform; + startTransform.setIdentity(); + startTransform.setOrigin(SimdVector3(0,-2,0)); - physicsEnvironmentPtr->setGravity(-1,-10,1); - PHY_ShapeProps shapeProps; - - shapeProps.m_do_anisotropic = false; - shapeProps.m_do_fh = false; - shapeProps.m_do_rot_fh = false; - shapeProps.m_friction_scaling[0] = 1.; - shapeProps.m_friction_scaling[1] = 1.; - shapeProps.m_friction_scaling[2] = 1.; + CcdPhysicsController* staticTrimesh = LocalCreatePhysicsObject(isDynamic, mass, startTransform,trimeshShape); + //enable custom material callback + staticTrimesh->GetRigidBody()->m_collisionFlags |= CollisionObject::customMaterialCallback; - shapeProps.m_inertia = 1.f; - shapeProps.m_lin_drag = 0.95999998f; - shapeProps.m_ang_drag = 0.89999998f; - shapeProps.m_mass = 1.0f; - - PHY_MaterialProps materialProps; - materialProps.m_friction = 0.f;// 50.5f; - materialProps.m_restitution = 0.1f; - - CcdConstructionInfo ccdObjectCi; - ccdObjectCi.m_friction = 0.f;//50.5f; - - ccdObjectCi.m_linearDamping = shapeProps.m_lin_drag; - ccdObjectCi.m_angularDamping = shapeProps.m_ang_drag; - - SimdTransform tr; - tr.setIdentity(); - - - for (i=0;i0) - shapeIndex[i] = 1;//2 = tetrahedron - else - shapeIndex[i] = 4; + for (int i=0;i<10;i++) + { + CollisionShape* boxShape = new BoxShape(SimdVector3(1,1,1)); + startTransform.setOrigin(SimdVector3(2*i,1,1)); + CcdPhysicsController* boxRigidBody = LocalCreatePhysicsObject(true, 1, startTransform,boxShape); + } } - for (i=0;i0; - - if (!i) - { - ccdObjectCi.m_friction = 0.0f; - //SimdQuaternion orn(0,0,0.1*SIMD_HALF_PI); - //ms[i].setWorldOrientation(orn.x(),orn.y(),orn.z(),orn[3]); - //ms[i].setWorldPosition(0,-10,0); - } else - { - ccdObjectCi.m_friction = 0.5f; - ms[i].setWorldPosition(10,i*15-10,0); - } - -//either create a few stacks, to show several islands, or create 1 large stack, showing stability - //ms[i].setWorldPosition((i*5) % 30,i*15-10,0); - - - ccdObjectCi.m_MotionState = &ms[i]; - ccdObjectCi.m_gravity = SimdVector3(0,0,0); - ccdObjectCi.m_localInertiaTensor =SimdVector3(0,0,0); - if (!isDyna) - { - shapeProps.m_mass = 0.f; - ccdObjectCi.m_mass = shapeProps.m_mass; - ccdObjectCi.m_collisionFlags = CollisionObject::customMaterialCallback; - - } - else - { - shapeProps.m_mass = 1.f; - ccdObjectCi.m_mass = shapeProps.m_mass; - ccdObjectCi.m_collisionFlags =0; - } - - - SimdVector3 localInertia; - if (shapeProps.m_mass>0.f) - { - shapePtr[shapeIndex[i]]->CalculateLocalInertia(shapeProps.m_mass,localInertia); - } else - { - localInertia.setValue(0.f,0.f,0.f); + m_physicsEnvironmentPtr->setGravity(-1,-10,1); - - } - ccdObjectCi.m_localInertiaTensor = localInertia; - - ccdObjectCi.m_collisionShape = shapePtr[shapeIndex[i]]; - - physObjects[i]= new CcdPhysicsController( ccdObjectCi); - physicsEnvironmentPtr->addCcdPhysicsController( physObjects[i]); - -/* if (i==0) - { - physObjects[i]->SetAngularVelocity(0,0,-2,true); - physObjects[i]->GetRigidBody()->setDamping(0,0); - } -*/ - //for the line that represents the AABB extents - physicsEnvironmentPtr->setDebugDrawer(&debugDrawer); - - - } - return glutmain(argc, argv,640,480,"Static Concave Mesh Demo"); + m_physicsEnvironmentPtr->setDebugDrawer(&debugDrawer); } - - -void renderme() -{ - float m[16]; - int i; - - debugDrawer.SetDebugMode(getDebugMode()); - - for (i=0;iGetRigidBody()->GetActivationState() == 1) //active - { - wireColor = SimdVector3 (1.f,0.f,0.f); - } - if (physObjects[i]->GetRigidBody()->GetActivationState() == 2) //ISLAND_SLEEPING - { - wireColor = SimdVector3 (0.f,1.f,0.f); - } - - char extraDebug[125]; - //sprintf(extraDebug,"islId, Body=%i , %i",physObjects[i]->GetRigidBody()->m_islandTag1,physObjects[i]->GetRigidBody()->m_debugBodyId); - shapePtr[shapeIndex[i]]->SetExtraDebugInfo(extraDebug); - GL_ShapeDrawer::DrawOpenGL(m,shapePtr[shapeIndex[i]],wireColor,getDebugMode()); - } - -} -void clientMoveAndDisplay() +void ConcaveDemo::clientMoveAndDisplay() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); float deltaTime = 1.f/60.f; - physicsEnvironmentPtr->proceedDeltaTime(0.f,deltaTime); + m_physicsEnvironmentPtr->proceedDeltaTime(0.f,deltaTime); renderme(); @@ -466,10 +211,25 @@ void clientMoveAndDisplay() } +void ConcaveDemo::clientResetScene() +{ + int numObj = m_physicsEnvironmentPtr->GetNumControllers(); + + //skip ground + for (int i=1;iGetPhysicsController(i); + ctrl->setPosition(2*i,1,1); + ctrl->setOrientation(0,0,0,1); + ctrl->SetLinearVelocity(0,0,0,0); + ctrl->SetAngularVelocity(0,0,0,0); + } +} -void clientDisplay(void) { + +void ConcaveDemo::displayCallback(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -480,26 +240,3 @@ void clientDisplay(void) { } -void clientResetScene() -{ - -} - -void clientSpecialKeyboard(int key, int x, int y) -{ - defaultSpecialKeyboard(key,x,y); -} - -void clientKeyboard(unsigned char key, int x, int y) -{ - defaultKeyboard(key, x, y); -} - - -void clientMouseFunc(int button, int state, int x, int y) -{ - -} -void clientMotionFunc(int x,int y) -{ -} diff --git a/Demos/ConstraintDemo/ConstraintDemo.cpp b/Demos/ConstraintDemo/ConstraintDemo.cpp index d9d38acc3..9cc4aff74 100644 --- a/Demos/ConstraintDemo/ConstraintDemo.cpp +++ b/Demos/ConstraintDemo/ConstraintDemo.cpp @@ -16,14 +16,12 @@ subject to the following restrictions: #include "CcdPhysicsEnvironment.h" #include "CcdPhysicsController.h" #include "MyMotionState.h" -//#include "GL_LineSegmentShape.h" #include "CollisionShapes/BoxShape.h" #include "CollisionShapes/Simplex1to4Shape.h" #include "CollisionShapes/EmptyShape.h" #include "Dynamics/RigidBody.h" #include "ConstraintSolver/SequentialImpulseConstraintSolver.h" -//#include "ConstraintSolver/OdeConstraintSolver.h" #include "CollisionDispatch/CollisionDispatcher.h" #include "BroadphaseCollision/SimpleBroadphase.h" #include "IDebugDraw.h" @@ -34,50 +32,35 @@ subject to the following restrictions: #include "BMF_Api.h" #include //printf debugging -#ifdef WIN32 //needed for glut.h -#include -#endif -//think different -#if defined(__APPLE__) && !defined (VMDMESA) -#include -#include -#include -#else -#include -#endif +#include "ConstraintDemo.h" #include "GL_ShapeDrawer.h" #include "GlutStuff.h" const int numObjects = 3; -const int maxNumObjects = 400; -MyMotionState ms[maxNumObjects]; -CcdPhysicsController* physObjects[maxNumObjects] = {0,0,0,0}; -int shapeIndex[maxNumObjects]; -CcdPhysicsEnvironment* physicsEnvironmentPtr = 0; +#define CUBE_HALF_EXTENTS 1.f - -#define CUBE_HALF_EXTENTS 1 - -//GL_LineSegmentShape shapeE(SimdPoint3(-50,0,0), -// SimdPoint3(50,0,0)); -CollisionShape* shapePtr[4] = -{ - new BoxShape (SimdVector3(10,10,10)), - new BoxShape (SimdVector3(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS)), - //new EmptyShape(), - new BU_Simplex1to4(SimdPoint3(-1,-1,-1),SimdPoint3(1,-1,-1),SimdPoint3(-1,1,-1),SimdPoint3(0,0,1)), - //new BoxShape (SimdVector3(0.4,1,0.8)) - -}; - - - GLDebugDrawer debugDrawer; +GLDebugDrawer debugDrawer; int main(int argc,char** argv) { + ConstraintDemo* constraintDemo = new ConstraintDemo(); + + constraintDemo->initPhysics(); + + constraintDemo->setCameraDistance(46.f); + + return glutmain(argc, argv,640,480,"Constraint Demo. http://www.continuousphysics.com/Bullet/phpBB2/",constraintDemo); +} + + + + +void ConstraintDemo::initPhysics() +{ + ConstraintSolver* solver = new SequentialImpulseConstraintSolver; //ConstraintSolver* solver = new OdeConstraintSolver; @@ -87,111 +70,28 @@ int main(int argc,char** argv) OverlappingPairCache* broadphase = new SimpleBroadphase(); - physicsEnvironmentPtr = new CcdPhysicsEnvironment(dispatcher,broadphase); - physicsEnvironmentPtr->setDeactivationTime(0.f); + m_physicsEnvironmentPtr = new CcdPhysicsEnvironment(dispatcher,broadphase); + m_physicsEnvironmentPtr->setDeactivationTime(0.f); + m_physicsEnvironmentPtr->setGravity(0,-10,0); - physicsEnvironmentPtr->setGravity(0,-10,0); - PHY_ShapeProps shapeProps; + CollisionShape* shape = new BoxShape(SimdVector3(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS)); + SimdTransform trans; + trans.setIdentity(); + trans.setOrigin(SimdVector3(0,20,0)); + + bool isDynamic = false; + float mass = 1.f; + + CcdPhysicsController* ctrl0 = LocalCreatePhysicsObject( isDynamic,mass,trans,shape); + trans.setOrigin(SimdVector3(2*CUBE_HALF_EXTENTS,20,0)); + isDynamic = true; + CcdPhysicsController* ctrl1 = LocalCreatePhysicsObject( isDynamic,mass,trans,shape); - shapeProps.m_do_anisotropic = false; - shapeProps.m_do_fh = false; - shapeProps.m_do_rot_fh = false; - shapeProps.m_friction_scaling[0] = 1.; - shapeProps.m_friction_scaling[1] = 1.; - shapeProps.m_friction_scaling[2] = 1.; - - shapeProps.m_inertia = 1.f; - shapeProps.m_lin_drag = 0.2f; - shapeProps.m_ang_drag = 0.1f; - shapeProps.m_mass = 10.0f; - - PHY_MaterialProps materialProps; - materialProps.m_friction = 10.5f; - materialProps.m_restitution = 0.0f; - - CcdConstructionInfo ccdObjectCi; - ccdObjectCi.m_friction = 0.5f; - - ccdObjectCi.m_linearDamping = shapeProps.m_lin_drag; - ccdObjectCi.m_angularDamping = shapeProps.m_ang_drag; - - SimdTransform tr; - tr.setIdentity(); - - int i; - for (i=0;i0) - shapeIndex[i] = 1;//2 to test start with EmptyShape - else - shapeIndex[i] = 0; - } - for (i=0;iSetMargin(0.05f); - - - bool isDyna = i>1; - - if (0)//i==1) - { - SimdQuaternion orn(0,0,0.1*SIMD_HALF_PI); - ms[i].setWorldOrientation(orn.x(),orn.y(),orn.z(),orn[3]); - } - - - if (i>0) - { - ms[i].setWorldPosition(0,i*CUBE_HALF_EXTENTS*2 - CUBE_HALF_EXTENTS,0); - } else - { - ms[i].setWorldPosition(0,-10,0); - - } - - ccdObjectCi.m_MotionState = &ms[i]; - ccdObjectCi.m_gravity = SimdVector3(0,0,0); - ccdObjectCi.m_localInertiaTensor =SimdVector3(0,0,0); - if (!isDyna) - { - shapeProps.m_mass = 0.f; - ccdObjectCi.m_mass = shapeProps.m_mass; - } - else - { - shapeProps.m_mass = 1.f; - ccdObjectCi.m_mass = shapeProps.m_mass; - } - - - SimdVector3 localInertia; - if (shapePtr[shapeIndex[i]]->GetShapeType() == EMPTY_SHAPE_PROXYTYPE) - { - //take inertia from first shape - shapePtr[1]->CalculateLocalInertia(shapeProps.m_mass,localInertia); - } else - { - shapePtr[shapeIndex[i]]->CalculateLocalInertia(shapeProps.m_mass,localInertia); - } - ccdObjectCi.m_localInertiaTensor = localInertia; - - ccdObjectCi.m_collisionShape = shapePtr[shapeIndex[i]]; - - - physObjects[i]= new CcdPhysicsController( ccdObjectCi); - physicsEnvironmentPtr->addCcdPhysicsController( physObjects[i]); - - - - physicsEnvironmentPtr->setDebugDrawer(&debugDrawer); - - } clientResetScene(); + { - //physObjects[i]->SetAngularVelocity(0,0,-2,true); int constraintId; float pivotX=CUBE_HALF_EXTENTS, @@ -200,131 +100,28 @@ int main(int argc,char** argv) float axisX=0,axisY=0,axisZ=1; - constraintId =physicsEnvironmentPtr->createConstraint( - physObjects[1], - //0, - physObjects[2], - //PHY_POINT2POINT_CONSTRAINT, - PHY_GENERIC_6DOF_CONSTRAINT,//can leave any of the 6 degree of freedom 'free' or 'locked' + constraintId =m_physicsEnvironmentPtr->createConstraint( + ctrl0, + ctrl1, + PHY_POINT2POINT_CONSTRAINT, + //PHY_GENERIC_6DOF_CONSTRAINT,//can leave any of the 6 degree of freedom 'free' or 'locked' //PHY_LINEHINGE_CONSTRAINT, pivotX,pivotY,pivotZ, axisX,axisY,axisZ ); } - - setCameraDistance(46.f); - - return glutmain(argc, argv,640,480,"Constraint Demo. http://www.continuousphysics.com/Bullet/phpBB2/"); } -//to be implemented by the demo - -void renderme() -{ - debugDrawer.SetDebugMode(getDebugMode()); - - - float m[16]; - int i; - - for (i=0;iGetRigidBody()->GetActivationState() == 1) //active - { - wireColor = SimdVector3 (1.f,0.f,0.f); - } - if (physObjects[i]->GetRigidBody()->GetActivationState() == 2) //ISLAND_SLEEPING - { - wireColor = SimdVector3 (0.f,1.f,0.f); - } - - char extraDebug[125]; - sprintf(extraDebug,"islId, Body=%i , %i",physObjects[i]->GetRigidBody()->m_islandTag1,physObjects[i]->GetRigidBody()->m_debugBodyId); - physObjects[i]->GetRigidBody()->GetCollisionShape()->SetExtraDebugInfo(extraDebug); - GL_ShapeDrawer::DrawOpenGL(m,physObjects[i]->GetRigidBody()->GetCollisionShape(),wireColor,getDebugMode()); - - if (getDebugMode()!=0 && (i>0)) - { - if (physObjects[i]->GetRigidBody()->GetCollisionShape()->GetShapeType() == EMPTY_SHAPE_PROXYTYPE) - { - physObjects[i]->GetRigidBody()->SetCollisionShape(shapePtr[1]); - - //remove the persistent collision pairs that were created based on the previous shape - - BroadphaseProxy* bpproxy = physObjects[i]->GetRigidBody()->m_broadphaseHandle; - - physicsEnvironmentPtr->GetBroadphase()->CleanProxyFromPairs(bpproxy); - - SimdVector3 newinertia; - SimdScalar newmass = 10.f; - physObjects[i]->GetRigidBody()->GetCollisionShape()->CalculateLocalInertia(newmass,newinertia); - physObjects[i]->GetRigidBody()->setMassProps(newmass,newinertia); - physObjects[i]->GetRigidBody()->updateInertiaTensor(); - - } - - } - - - } - - glRasterPos3f(20,20,0); - char buf[124]; - sprintf(buf,"space to reset"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - glRasterPos3f(20,15,0); - sprintf(buf,"c to show contact points"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - - glRasterPos3f(20,10,0); - sprintf(buf,"cursor keys and z,x to navigate"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - - glRasterPos3f(20,5,0); - sprintf(buf,"i to toggle simulation, s single step"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - - - glRasterPos3f(20,0,0); - sprintf(buf,"q to quit"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - - glRasterPos3f(20,-5,0); - sprintf(buf,"d to toggle deactivation"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - -} -void clientMoveAndDisplay() +void ConstraintDemo::clientMoveAndDisplay() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); float deltaTime = 1.f/60.f; - physicsEnvironmentPtr->proceedDeltaTime(0.f,deltaTime); + m_physicsEnvironmentPtr->proceedDeltaTime(0.f,deltaTime); renderme(); @@ -336,67 +133,14 @@ void clientMoveAndDisplay() -void clientDisplay(void) { +void ConstraintDemo::displayCallback(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); renderme(); - - glFlush(); glutSwapBuffers(); } - -///make this positive to show stack falling from a distance -///this shows the penalty tresholds in action, springy/spungy look -#define EXTRA_HEIGHT 20.f - - -void clientResetScene() -{ - int i; - for (i=0;i0) - { - //stack them - int colsize = 10; - int row = (i*CUBE_HALF_EXTENTS*2)/(colsize*2*CUBE_HALF_EXTENTS); - int col = (i)%(colsize)-colsize/2; - - physObjects[i]->setPosition(col*2*CUBE_HALF_EXTENTS + (row%2)*CUBE_HALF_EXTENTS, - row*2*CUBE_HALF_EXTENTS+CUBE_HALF_EXTENTS+EXTRA_HEIGHT, - 0); - physObjects[i]->setOrientation(0,0,0,1); - physObjects[i]->SetLinearVelocity(0,0,0,false); - physObjects[i]->SetAngularVelocity(0,0,0,false); - } else - { - ms[i].setWorldPosition(0,-10,0); - - } - } -} - -void clientSpecialKeyboard(int key, int x, int y) -{ - defaultSpecialKeyboard(key,x,y); -} - - -void clientKeyboard(unsigned char key, int x, int y) -{ - defaultKeyboard(key, x, y); -} - - -void clientMouseFunc(int button, int state, int x, int y) -{ - -} -void clientMotionFunc(int x,int y) -{ -} diff --git a/Demos/ConstraintDemo/ConstraintDemo.h b/Demos/ConstraintDemo/ConstraintDemo.h new file mode 100644 index 000000000..66f2f9693 --- /dev/null +++ b/Demos/ConstraintDemo/ConstraintDemo.h @@ -0,0 +1,36 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef CONSTRAINT_DEMO_H +#define CONSTRAINT_DEMO_H + +#include "DemoApplication.h" + +///ConstraintDemo shows how to create a constraint, like Hinge or GenericD6constraint +class ConstraintDemo : public DemoApplication +{ + public: + + void initPhysics(); + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + virtual void clientResetScene() + { + } +}; + +#endif //CONSTRAINT_DEMO_H \ No newline at end of file diff --git a/Demos/ContinuousConvexCollision/ContinuousConvexCollision.h b/Demos/ContinuousConvexCollision/ContinuousConvexCollision.h new file mode 100644 index 000000000..dcc2ae7f7 --- /dev/null +++ b/Demos/ContinuousConvexCollision/ContinuousConvexCollision.h @@ -0,0 +1,36 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef CONTINUOUS_CONVEX_COLLISION_DEMO_H +#define CONTINUOUS_CONVEX_COLLISION_DEMO_H + +#include "DemoApplication.h" + +///ContinuousConvexCollisionDemo shows the working of the continuous collision detection, including linear and angular motion +class ContinuousConvexCollisionDemo : public DemoApplication +{ + public: + + void initPhysics(); + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + virtual void clientResetScene() + { + } +}; + +#endif //CONTINUOUS_CONVEX_COLLISION_DEMO_H \ No newline at end of file diff --git a/Demos/ContinuousConvexCollision/ContinuousConvexCollisionDemo.cpp b/Demos/ContinuousConvexCollision/ContinuousConvexCollisionDemo.cpp index 0c1808c2c..a433efbff 100644 --- a/Demos/ContinuousConvexCollision/ContinuousConvexCollisionDemo.cpp +++ b/Demos/ContinuousConvexCollision/ContinuousConvexCollisionDemo.cpp @@ -36,19 +36,11 @@ #include "CollisionShapes/Simplex1to4Shape.h" -#include "GL_ShapeDrawer.h" -#ifdef WIN32 //needed for glut.h -#include -#endif -//think different -#if defined(__APPLE__) && !defined (VMDMESA) -#include -#include -#include -#else -#include -#endif +#include "NarrowPhaseCollision/VoronoiSimplexSolver.h" +#include "NarrowPhaseCollision/ConvexPenetrationDepthSolver.h" +#include "GL_ShapeDrawer.h" +#include "ContinuousConvexCollision.h" #include "GlutStuff.h" @@ -65,21 +57,24 @@ PolyhedralConvexShape* shapePtr[maxNumObjects]; SimdTransform fromTrans[maxNumObjects]; SimdTransform toTrans[maxNumObjects]; -//SimdTransform tr[numObjects]; -void DrawRasterizerLine(float const* , float const*, int) -{ - -} int screenWidth = 640.f; int screenHeight = 480.f; int main(int argc,char** argv) { + ContinuousConvexCollisionDemo* ccdDemo = new ContinuousConvexCollisionDemo(); - setCameraDistance(40.f); + ccdDemo->setCameraDistance(40.f); + ccdDemo->initPhysics(); + + return glutmain(argc, argv,screenWidth,screenHeight,"Continuous Convex Collision Demo",ccdDemo); +} + +void ContinuousConvexCollisionDemo::initPhysics() +{ fromTrans[0].setOrigin(SimdVector3(0,10,20)); toTrans[0].setOrigin(SimdVector3(0,10,-20)); fromTrans[1].setOrigin(SimdVector3(-2,7,0)); @@ -101,17 +96,17 @@ int main(int argc,char** argv) toTrans[1].setBasis(identBasis); SimdVector3 boxHalfExtentsA(10,1,1); SimdVector3 boxHalfExtentsB(1.1f,1.1f,1.1f); - BoxShape boxA(boxHalfExtentsA); -// BU_Simplex1to4 boxA(SimdPoint3(-2,0,-2),SimdPoint3(2,0,-2),SimdPoint3(0,0,2),SimdPoint3(0,2,0)); -// BU_Simplex1to4 boxA(SimdPoint3(-12,0,0),SimdPoint3(12,0,0)); + BoxShape* boxA = new BoxShape(boxHalfExtentsA); +// BU_Simplex1to4* boxA = new BU_Simplex1to4(SimdPoint3(-2,0,-2),SimdPoint3(2,0,-2),SimdPoint3(0,0,2),SimdPoint3(0,2,0)); +// BU_Simplex1to4* boxA = new BU_Simplex1to4(SimdPoint3(-12,0,0),SimdPoint3(12,0,0)); - BoxShape boxB(boxHalfExtentsB); + BoxShape* boxB = new BoxShape(boxHalfExtentsB); // BU_Simplex1to4 boxB(SimdPoint3(0,10,0),SimdPoint3(0,-10,0)); - shapePtr[0] = &boxA; - shapePtr[1] = &boxB; + shapePtr[0] = boxA; + shapePtr[1] = boxB; shapePtr[0]->SetMargin(0.01f); shapePtr[1]->SetMargin(0.01f); @@ -121,18 +116,15 @@ int main(int argc,char** argv) SimdTransformUtil::CalculateVelocity(fromTrans[i],toTrans[i],1.f,linVels[i],angVels[i]); } - return glutmain(argc, argv,screenWidth,screenHeight,"Continuous Convex Collision Demo"); } //to be implemented by the demo -void clientMoveAndDisplay() +void ContinuousConvexCollisionDemo::clientMoveAndDisplay() { - clientDisplay(); + displayCallback(); } -#include "NarrowPhaseCollision/VoronoiSimplexSolver.h" -#include "NarrowPhaseCollision/ConvexPenetrationDepthSolver.h" static VoronoiSimplexSolver sVoronoiSimplexSolver; @@ -145,7 +137,7 @@ int minlines = 0; int maxlines = 512; -void clientDisplay(void) { +void ContinuousConvexCollisionDemo::displayCallback(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDisable(GL_LIGHTING); @@ -206,12 +198,10 @@ void clientDisplay(void) { fromTrans[1].setRotation(orn); toTrans[1].setRotation(orn); - extern bool stepping; - extern bool singleStep; - if (stepping || singleStep) + if (m_stepping || m_singleStep) { - singleStep = false; + m_singleStep = false; pitch += 0.005f; // yaw += 0.01f; } @@ -299,26 +289,4 @@ void clientDisplay(void) { glutSwapBuffers(); } -void clientResetScene() -{ -} -void clientSpecialKeyboard(int key, int x, int y) -{ - defaultSpecialKeyboard(key,x,y); -} - - -void clientKeyboard(unsigned char key, int x, int y) -{ - defaultKeyboard(key, x, y); -} - - -void clientMouseFunc(int button, int state, int x, int y) -{ - -} -void clientMotionFunc(int x,int y) -{ -} diff --git a/Demos/ConvexDecompositionDemo/ConvexDecompositionDemo.cpp b/Demos/ConvexDecompositionDemo/ConvexDecompositionDemo.cpp index 4e625ace9..850598331 100644 --- a/Demos/ConvexDecompositionDemo/ConvexDecompositionDemo.cpp +++ b/Demos/ConvexDecompositionDemo/ConvexDecompositionDemo.cpp @@ -49,86 +49,23 @@ subject to the following restrictions: #include //printf debugging float deltaTime = 1.f/60.f; -float bulletSpeed = 40.f; -bool createConstraint = false;//true; -#ifdef WIN32 -#if _MSC_VER >= 1310 -//only use SIMD Hull code under Win32 -#define USE_HULL 1 -#include "NarrowPhaseCollision/Hull.h" -#endif //_MSC_VER -#endif //WIN32 - -#ifdef WIN32 //needed for glut.h -#include -#endif -//think different -#if defined(__APPLE__) && !defined (VMDMESA) -#include -#include -#include -#else -#include -#endif +#include "ConvexDecompositionDemo.h" #include "GL_ShapeDrawer.h" #include "GlutStuff.h" - -extern float eye[3]; -extern int glutScreenWidth; -extern int glutScreenHeight; - - -#ifdef _DEBUG -int numObjects = 4;//22; -#else -int numObjects = 120; -#endif - const int maxNumObjects = 450; -DefaultMotionState ms[maxNumObjects]; -CcdPhysicsController* physObjects[maxNumObjects] = {0,0,0,0}; int shapeIndex[maxNumObjects]; -SimdVector3 centroids[maxNumObjects]; - -CcdPhysicsEnvironment* physicsEnvironmentPtr = 0; - +SimdVector3 centroid; #define CUBE_HALF_EXTENTS 4 -#define EXTRA_HEIGHT -20.f -//GL_LineSegmentShape shapeE(SimdPoint3(-50,0,0), -// SimdPoint3(50,0,0)); -static const int numShapes = 4; - CollisionShape* shapePtr[maxNumObjects]; -CollisionShape* prebuildShapePtr[numShapes] = -{ - ///Please don't make the box sizes larger then 1000: the collision detection will be inaccurate. - ///See http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=346 - - new BoxShape (SimdVector3(450,10,450)), - new BoxShape (SimdVector3(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS)), - new SphereShape (CUBE_HALF_EXTENTS- 0.05f), - - //new ConeShape(CUBE_HALF_EXTENTS,2.f*CUBE_HALF_EXTENTS), - //new BU_Simplex1to4(SimdPoint3(-1,-1,-1),SimdPoint3(1,-1,-1),SimdPoint3(-1,1,-1),SimdPoint3(0,0,1)), - - //new EmptyShape(), - - new BoxShape (SimdVector3(0.4,1,0.8)) - -}; - - - - //////////////////////////////////// @@ -140,31 +77,60 @@ GLDebugDrawer debugDrawer; int main(int argc,char** argv) { + int i; - for (i=0;i0) - { - shapePtr[i] = prebuildShapePtr[1]; - shapeIndex[i] = 1;//sphere - } - else - { - shapeIndex[i] = 0; - shapePtr[i] = prebuildShapePtr[0]; - } - } - ConvexDecomposition::WavefrontObj wo; char* filename = "file.obj"; + + + ConvexDecompositionDemo* convexDecompDemo = new ConvexDecompositionDemo(); + + convexDecompDemo->initPhysics(filename); + + + + convexDecompDemo->clientResetScene(); + + convexDecompDemo->setCameraDistance(26.f); + + return glutmain(argc, argv,640,480,"Bullet Physics Demo. http://www.continuousphysics.com/Bullet/phpBB2/",convexDecompDemo); +} + +void ConvexDecompositionDemo::initPhysics(const char* filename) +{ + ConvexDecomposition::WavefrontObj wo; + tcount = wo.loadObj(filename); + CollisionDispatcher* dispatcher = new CollisionDispatcher(); + + + SimdVector3 worldAabbMin(-10000,-10000,-10000); + SimdVector3 worldAabbMax(10000,10000,10000); + + OverlappingPairCache* broadphase = new AxisSweep3(worldAabbMin,worldAabbMax); + //OverlappingPairCache* broadphase = new SimpleBroadphase(); + + m_physicsEnvironmentPtr = new CcdPhysicsEnvironment(dispatcher,broadphase); + m_physicsEnvironmentPtr->setDeactivationTime(2.f); + + m_physicsEnvironmentPtr->setGravity(0,-10,0); + + SimdTransform startTransform; + startTransform.setIdentity(); + startTransform.setOrigin(SimdVector3(0,-4,0)); + + LocalCreatePhysicsObject(false,0,startTransform,new BoxShape(SimdVector3(30,2,30))); + class MyConvexDecomposition : public ConvexDecomposition::ConvexDecompInterface { + + ConvexDecompositionDemo* m_convexDemo; public: - MyConvexDecomposition (FILE* outputFile) - :mBaseCount(0), + MyConvexDecomposition (FILE* outputFile,ConvexDecompositionDemo* demo) + :m_convexDemo(demo), + mBaseCount(0), mHullCount(0), mOutputFile(outputFile) @@ -194,7 +160,7 @@ int main(int argc,char** argv) } //calc centroid, to shift vertices around center of mass - centroids[numObjects] = SimdVector3(0,0,0); + centroid.setValue(0,0,0); if ( 1 ) { const unsigned int *src = result.mHullIndices; @@ -209,14 +175,14 @@ int main(int argc,char** argv) vertex0 *= localScaling; vertex1 *= localScaling; vertex2 *= localScaling; - centroids[numObjects] += vertex0; - centroids[numObjects]+= vertex1; - centroids[numObjects]+= vertex2; + centroid += vertex0; + centroid += vertex1; + centroid += vertex2; } } - centroids[numObjects] *= 1.f/(float(result.mHullTcount) * 3); + centroid *= 1.f/(float(result.mHullTcount) * 3); if ( 1 ) { @@ -235,9 +201,9 @@ int main(int argc,char** argv) vertex1 *= localScaling; vertex2 *= localScaling; - vertex0 -= centroids[numObjects]; - vertex1 -= centroids[numObjects]; - vertex2 -= centroids[numObjects]; + vertex0 -= centroid; + vertex1 -= centroid; + vertex2 -= centroid; trimesh->AddTriangle(vertex0,vertex1,vertex2); @@ -249,9 +215,14 @@ int main(int argc,char** argv) } } - shapeIndex[numObjects] = numObjects; - shapePtr[numObjects++] = new ConvexTriangleMeshShape(trimesh); - + bool isDynamic = true; + float mass = 1.f; + CollisionShape* convexShape = new ConvexTriangleMeshShape(trimesh); + SimdTransform trans; + trans.setIdentity(); + trans.setOrigin(centroid); + m_convexDemo->LocalCreatePhysicsObject(isDynamic, mass, trans,convexShape); + mBaseCount+=result.mHullVcount; // advance the 'base index' counter. @@ -266,8 +237,6 @@ int main(int argc,char** argv) if (tcount) { - numObjects = 1; //always have the ground object first - TriangleMesh* trimesh = new TriangleMesh(); SimdVector3 localScaling(6.f,6.f,6.f); @@ -289,7 +258,16 @@ int main(int argc,char** argv) trimesh->AddTriangle(vertex0,vertex1,vertex2); } - shapePtr[numObjects++] = new ConvexTriangleMeshShape(trimesh); + CollisionShape* convexShape = new ConvexTriangleMeshShape(trimesh); + bool isDynamic = true; + float mass = 1.f; + + SimdTransform startTransform; + startTransform.setIdentity(); + startTransform.setOrigin(SimdVector3(20,2,0)); + + LocalCreatePhysicsObject(isDynamic, mass, startTransform,convexShape); + } @@ -322,7 +300,7 @@ int main(int argc,char** argv) desc.mMaxVertices = maxv; desc.mSkinWidth = skinWidth; - MyConvexDecomposition convexDecomposition(outputFile); + MyConvexDecomposition convexDecomposition(outputFile,this); desc.mCallback = &convexDecomposition; @@ -338,476 +316,18 @@ int main(int argc,char** argv) } - CollisionDispatcher* dispatcher = new CollisionDispatcher(); - - SimdVector3 worldAabbMin(-10000,-10000,-10000); - SimdVector3 worldAabbMax(10000,10000,10000); - - OverlappingPairCache* broadphase = new AxisSweep3(worldAabbMin,worldAabbMax); - //OverlappingPairCache* broadphase = new SimpleBroadphase(); - - physicsEnvironmentPtr = new CcdPhysicsEnvironment(dispatcher,broadphase); - physicsEnvironmentPtr->setDeactivationTime(2.f); - - physicsEnvironmentPtr->setGravity(0,-10,0); - PHY_ShapeProps shapeProps; - - shapeProps.m_do_anisotropic = false; - shapeProps.m_do_fh = false; - shapeProps.m_do_rot_fh = false; - shapeProps.m_friction_scaling[0] = 1.; - shapeProps.m_friction_scaling[1] = 1.; - shapeProps.m_friction_scaling[2] = 1.; - - shapeProps.m_inertia = 1.f; - shapeProps.m_lin_drag = 0.2f; - shapeProps.m_ang_drag = 0.1f; - shapeProps.m_mass = 10.0f; - - PHY_MaterialProps materialProps; - materialProps.m_friction = 10.5f; - materialProps.m_restitution = 0.0f; - - CcdConstructionInfo ccdObjectCi; - ccdObjectCi.m_friction = 0.5f; - - ccdObjectCi.m_linearDamping = shapeProps.m_lin_drag; - ccdObjectCi.m_angularDamping = shapeProps.m_ang_drag; - - SimdTransform tr; - tr.setIdentity(); - - - - for (i=0;iSetMargin(0.05f); - - - - bool isDyna = i>0; - //if (i==1) - // isDyna=false; - - if (0)//i==1) - { - SimdQuaternion orn(0,0,0.1*SIMD_HALF_PI); - ms[i].setWorldOrientation(orn.x(),orn.y(),orn.z(),orn[3]); - } - - - if (i>0) - { - - switch (i) - { - case 1: - { - ms[i].setWorldPosition(0,10,0); - //for testing, rotate the ground cube so the stack has to recover a bit - - break; - } - case 2: - { - ms[i].setWorldPosition(0,8,2); - break; - } - default: - ms[i].setWorldPosition(0,i*CUBE_HALF_EXTENTS*2 - CUBE_HALF_EXTENTS,0); - } - - float quatIma0,quatIma1,quatIma2,quatReal; - SimdQuaternion quat; - SimdVector3 axis(0,0,1); - SimdScalar angle=0.5f; - - quat.setRotation(axis,angle); - - ms[i].setWorldOrientation(quat.getX(),quat.getY(),quat.getZ(),quat[3]); - - - - } else - { - ms[i].setWorldPosition(0,-10+EXTRA_HEIGHT,0); - - } - - ccdObjectCi.m_MotionState = &ms[i]; - ccdObjectCi.m_gravity = SimdVector3(0,0,0); - ccdObjectCi.m_localInertiaTensor =SimdVector3(0,0,0); - if (!isDyna) - { - shapeProps.m_mass = 0.f; - ccdObjectCi.m_mass = shapeProps.m_mass; - ccdObjectCi.m_collisionFlags = CollisionObject::isStatic; - } - else - { - shapeProps.m_mass = 1.f; - ccdObjectCi.m_mass = shapeProps.m_mass; - ccdObjectCi.m_collisionFlags = 0; - } - - - SimdVector3 localInertia; - if (shapePtr[shapeIndex[i]]->GetShapeType() == EMPTY_SHAPE_PROXYTYPE) - { - //take inertia from first shape - shapePtr[1]->CalculateLocalInertia(shapeProps.m_mass,localInertia); - } else - { - shapePtr[shapeIndex[i]]->CalculateLocalInertia(shapeProps.m_mass,localInertia); - } - ccdObjectCi.m_localInertiaTensor = localInertia; - - ccdObjectCi.m_collisionShape = shapePtr[shapeIndex[i]]; - - - physObjects[i]= new CcdPhysicsController( ccdObjectCi); - - // Only do CCD if motion in one timestep (1.f/60.f) exceeds CUBE_HALF_EXTENTS - physObjects[i]->GetRigidBody()->m_ccdSquareMotionTreshold = CUBE_HALF_EXTENTS; - - //Experimental: better estimation of CCD Time of Impact: - //physObjects[i]->GetRigidBody()->m_ccdSweptShereRadius = 0.5*CUBE_HALF_EXTENTS; - - physicsEnvironmentPtr->addCcdPhysicsController( physObjects[i]); - - if (i==1) - { - //physObjects[i]->SetAngularVelocity(0,0,-2,true); - } - - physicsEnvironmentPtr->setDebugDrawer(&debugDrawer); - - } - - - //create a constraint - if (createConstraint) - { - //physObjects[i]->SetAngularVelocity(0,0,-2,true); - int constraintId; - - float pivotX=CUBE_HALF_EXTENTS, - pivotY=-CUBE_HALF_EXTENTS, - pivotZ=CUBE_HALF_EXTENTS; - - float axisX=1,axisY=0,axisZ=0; - - - - HingeConstraint* hinge = 0; - - SimdVector3 pivotInA(CUBE_HALF_EXTENTS,-CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS); - SimdVector3 pivotInB(-CUBE_HALF_EXTENTS,-CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS); - SimdVector3 axisInA(0,1,0); - SimdVector3 axisInB(0,-1,0); - - RigidBody* rb0 = physObjects[1]->GetRigidBody(); - RigidBody* rb1 = physObjects[2]->GetRigidBody(); - - hinge = new HingeConstraint( - *rb0, - *rb1,pivotInA,pivotInB,axisInA,axisInB); - - physicsEnvironmentPtr->m_constraints.push_back(hinge); - - hinge->SetUserConstraintId(100); - hinge->SetUserConstraintType(PHY_LINEHINGE_CONSTRAINT); - - } - - - - - clientResetScene(); - - setCameraDistance(26.f); - - return glutmain(argc, argv,640,480,"Bullet Physics Demo. http://www.continuousphysics.com/Bullet/phpBB2/"); -} - -//to be implemented by the demo -void renderme() -{ - debugDrawer.SetDebugMode(getDebugMode()); - - //render the hinge axis - if (createConstraint) - { - SimdVector3 color(1,0,0); - SimdVector3 dirLocal(0,1,0); - SimdVector3 pivotInA(CUBE_HALF_EXTENTS,-CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS); - SimdVector3 pivotInB(-CUBE_HALF_EXTENTS,-CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS); - SimdVector3 from = physObjects[1]->GetRigidBody()->getCenterOfMassTransform()(pivotInA); - SimdVector3 fromB = physObjects[2]->GetRigidBody()->getCenterOfMassTransform()(pivotInB); - SimdVector3 dirWorldA = physObjects[1]->GetRigidBody()->getCenterOfMassTransform().getBasis() * dirLocal ; - SimdVector3 dirWorldB = physObjects[2]->GetRigidBody()->getCenterOfMassTransform().getBasis() * dirLocal ; - debugDrawer.DrawLine(from,from+dirWorldA,color); - debugDrawer.DrawLine(fromB,fromB+dirWorldB,color); - } - - float m[16]; - int i; - - - if (getDebugMode() & IDebugDraw::DBG_DisableBulletLCP) - { - //don't use Bullet, use quickstep - physicsEnvironmentPtr->setSolverType(0); - } else - { - //Bullet LCP solver - physicsEnvironmentPtr->setSolverType(1); - } - - if (getDebugMode() & IDebugDraw::DBG_EnableCCD) - { - physicsEnvironmentPtr->setCcdMode(3); - } else - { - physicsEnvironmentPtr->setCcdMode(0); - } - - - bool isSatEnabled = (getDebugMode() & IDebugDraw::DBG_EnableSatComparison); - - physicsEnvironmentPtr->EnableSatCollisionDetection(isSatEnabled); - - -#ifdef USE_HULL - //some testing code for SAT - if (isSatEnabled) - { - for (int s=0;sIsPolyhedral()) - { - PolyhedralConvexShape* polyhedron = static_cast(shape); - if (!polyhedron->m_optionalHull) - { - //first convert vertices in 'Point3' format - int numPoints = polyhedron->GetNumVertices(); - Point3* points = new Point3[numPoints+1]; - //first 4 points should not be co-planar, so add central point to satisfy MakeHull - points[0] = Point3(0.f,0.f,0.f); - - SimdVector3 vertex; - for (int p=0;pGetVertex(p,vertex); - points[p+1] = Point3(vertex.getX(),vertex.getY(),vertex.getZ()); - } - - Hull* hull = Hull::MakeHull(numPoints+1,points); - polyhedron->m_optionalHull = hull; - } - - } - } - - } -#endif //USE_HULL - - - for (i=0;iGetRigidBody()->GetActivationState() == 1) //active - { - if (i & 1) - { - wireColor += SimdVector3 (1.f,0.f,0.f); - } else - { - wireColor += SimdVector3 (.5f,0.f,0.f); - } - } - if (physObjects[i]->GetRigidBody()->GetActivationState() == 2) //ISLAND_SLEEPING - { - if (i & 1) - { - wireColor += SimdVector3 (0.f,1.f, 0.f); - } else - { - wireColor += SimdVector3 (0.f,0.5f,0.f); - } - } - - char extraDebug[125]; - sprintf(extraDebug,"islId, Body=%i , %i",physObjects[i]->GetRigidBody()->m_islandTag1,physObjects[i]->GetRigidBody()->m_debugBodyId); - physObjects[i]->GetRigidBody()->GetCollisionShape()->SetExtraDebugInfo(extraDebug); - GL_ShapeDrawer::DrawOpenGL(m,physObjects[i]->GetRigidBody()->GetCollisionShape(),wireColor,getDebugMode()); - - ///this block is just experimental code to show some internal issues with replacing shapes on the fly. - if (getDebugMode()!=0 && (i>0)) - { - if (physObjects[i]->GetRigidBody()->GetCollisionShape()->GetShapeType() == EMPTY_SHAPE_PROXYTYPE) - { - physObjects[i]->GetRigidBody()->SetCollisionShape(shapePtr[1]); - - //remove the persistent collision pairs that were created based on the previous shape - - BroadphaseProxy* bpproxy = physObjects[i]->GetRigidBody()->m_broadphaseHandle; - - physicsEnvironmentPtr->GetBroadphase()->CleanProxyFromPairs(bpproxy); - - SimdVector3 newinertia; - SimdScalar newmass = 10.f; - physObjects[i]->GetRigidBody()->GetCollisionShape()->CalculateLocalInertia(newmass,newinertia); - physObjects[i]->GetRigidBody()->setMassProps(newmass,newinertia); - physObjects[i]->GetRigidBody()->updateInertiaTensor(); - - } - - } - - - } - - if (!(getDebugMode() & IDebugDraw::DBG_NoHelpText)) - { - - float xOffset = 10.f; - float yStart = 20.f; - - float yIncr = -2.f; - - char buf[124]; - - glColor3f(0, 0, 0); - -#ifdef USE_QUICKPROF - - - if ( getDebugMode() & IDebugDraw::DBG_ProfileTimings) - { - static int counter = 0; - counter++; - std::map::iterator iter; - for (iter = Profiler::mProfileBlocks.begin(); iter != Profiler::mProfileBlocks.end(); ++iter) - { - char blockTime[128]; - sprintf(blockTime, "%s: %lf",&((*iter).first[0]),Profiler::getBlockTime((*iter).first, Profiler::BLOCK_CYCLE_SECONDS));//BLOCK_TOTAL_PERCENT)); - glRasterPos3f(xOffset,yStart,0); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),blockTime); - yStart += yIncr; - - } - } -#endif //USE_QUICKPROF - //profiling << Profiler::createStatsString(Profiler::BLOCK_TOTAL_PERCENT); - //<< std::endl; - - - - glRasterPos3f(xOffset,yStart,0); - sprintf(buf,"mouse to interact"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - glRasterPos3f(xOffset,yStart,0); - sprintf(buf,"space to reset"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - glRasterPos3f(xOffset,yStart,0); - sprintf(buf,"cursor keys and z,x to navigate"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - glRasterPos3f(xOffset,yStart,0); - sprintf(buf,"i to toggle simulation, s single step"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - glRasterPos3f(xOffset,yStart,0); - sprintf(buf,"q to quit"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - glRasterPos3f(xOffset,yStart,0); - sprintf(buf,"d to toggle deactivation"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - glRasterPos3f(xOffset,yStart,0); - sprintf(buf,"a to draw temporal AABBs"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - - glRasterPos3f(xOffset,yStart,0); - sprintf(buf,"h to toggle help text"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - bool useBulletLCP = !(getDebugMode() & IDebugDraw::DBG_DisableBulletLCP); - - bool useCCD = (getDebugMode() & IDebugDraw::DBG_EnableCCD); - - glRasterPos3f(xOffset,yStart,0); - sprintf(buf,"m Bullet GJK = %i",!isSatEnabled); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - glRasterPos3f(xOffset,yStart,0); - sprintf(buf,"n Bullet LCP = %i",useBulletLCP); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - glRasterPos3f(xOffset,yStart,0); - sprintf(buf,"1 CCD mode (adhoc) = %i",useCCD); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - glRasterPos3f(xOffset,yStart,0); - sprintf(buf,"+- shooting speed = %10.2f",bulletSpeed); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - } + m_physicsEnvironmentPtr->setDebugDrawer(&debugDrawer); } -void clientMoveAndDisplay() +void ConvexDecompositionDemo::clientMoveAndDisplay() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - physicsEnvironmentPtr->proceedDeltaTime(0.f,deltaTime); + m_physicsEnvironmentPtr->proceedDeltaTime(0.f,deltaTime); renderme(); @@ -818,12 +338,12 @@ void clientMoveAndDisplay() -void clientDisplay(void) { +void ConvexDecompositionDemo::displayCallback(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - physicsEnvironmentPtr->UpdateAabbs(deltaTime); + m_physicsEnvironmentPtr->UpdateAabbs(deltaTime); renderme(); @@ -832,308 +352,3 @@ void clientDisplay(void) { glutSwapBuffers(); } - - -///make this positive to show stack falling from a distance -///this shows the penalty tresholds in action, springy/spungy look - -void clientResetScene() -{ - - int i; - for (i=0;i0) - { - - if ((getDebugMode() & IDebugDraw::DBG_NoHelpText)) - { - if (physObjects[i]->GetRigidBody()->GetCollisionShape()->GetShapeType() == BOX_SHAPE_PROXYTYPE) - { - physObjects[i]->GetRigidBody()->SetCollisionShape(shapePtr[2]); - } else - { - physObjects[i]->GetRigidBody()->SetCollisionShape(shapePtr[1]); - } - - BroadphaseProxy* bpproxy = physObjects[i]->GetRigidBody()->m_broadphaseHandle; - physicsEnvironmentPtr->GetBroadphase()->CleanProxyFromPairs(bpproxy); - } - - int p = i; - if (tcount) - { - if (p>2) - p=2; - } - - //stack them - int colsize = 10; - if (tcount) - colsize = 2; - int row = (p*CUBE_HALF_EXTENTS*2)/(colsize*2*CUBE_HALF_EXTENTS); - int row2 = row; - int col = (p)%(colsize)-colsize/2; - - - if (col>3) - { - col=11; - row2 |=1; - } - - SimdVector3 position(col*2*CUBE_HALF_EXTENTS + (row2%2)*CUBE_HALF_EXTENTS, - row*2*CUBE_HALF_EXTENTS+CUBE_HALF_EXTENTS+EXTRA_HEIGHT,0); - - if (tcount) - { - if (p==2) - { - position += centroids[i]; - } - } - physObjects[i]->setPosition(position[0],position[1],position[2]); - physObjects[i]->setOrientation(0,0,0,1); - physObjects[i]->SetLinearVelocity(0,0,0,false); - physObjects[i]->SetAngularVelocity(0,0,0,false); - } - } -} - - - -void shootBox(const SimdVector3& destination) -{ - int i = numObjects-1; - - - - SimdVector3 linVel(destination[0]-eye[0],destination[1]-eye[1],destination[2]-eye[2]); - linVel.normalize(); - linVel*=bulletSpeed; - - physObjects[i]->setPosition(eye[0],eye[1],eye[2]); - physObjects[i]->setOrientation(0,0,0,1); - physObjects[i]->SetLinearVelocity(linVel[0],linVel[1],linVel[2],false); - physObjects[i]->SetAngularVelocity(0,0,0,false); -} - -void clientSpecialKeyboard(int key, int x, int y) -{ - defaultSpecialKeyboard(key,x,y); -} - -void clientKeyboard(unsigned char key, int x, int y) -{ - - if (key == '.') - { - shootBox(SimdVector3(0,0,0)); - } - - if (key == '+') - { - bulletSpeed += 10.f; - } - if (key == '-') - { - bulletSpeed -= 10.f; - } - - defaultKeyboard(key, x, y); -} - -int gPickingConstraintId = 0; -SimdVector3 gOldPickingPos; -float gOldPickingDist = 0.f; -RigidBody* pickedBody = 0;//for deactivation state - - -SimdVector3 GetRayTo(int x,int y) -{ - float top = 1.f; - float bottom = -1.f; - float nearPlane = 1.f; - float tanFov = (top-bottom)*0.5f / nearPlane; - float fov = 2.0 * atanf (tanFov); - - SimdVector3 rayFrom(eye[0],eye[1],eye[2]); - SimdVector3 rayForward = -rayFrom; - rayForward.normalize(); - float farPlane = 600.f; - rayForward*= farPlane; - - SimdVector3 rightOffset; - SimdVector3 vertical(0.f,1.f,0.f); - SimdVector3 hor; - hor = rayForward.cross(vertical); - hor.normalize(); - vertical = hor.cross(rayForward); - vertical.normalize(); - - float tanfov = tanf(0.5f*fov); - hor *= 2.f * farPlane * tanfov; - vertical *= 2.f * farPlane * tanfov; - SimdVector3 rayToCenter = rayFrom + rayForward; - SimdVector3 dHor = hor * 1.f/float(glutScreenWidth); - SimdVector3 dVert = vertical * 1.f/float(glutScreenHeight); - SimdVector3 rayTo = rayToCenter - 0.5f * hor + 0.5f * vertical; - rayTo += x * dHor; - rayTo -= y * dVert; - return rayTo; -} -void clientMouseFunc(int button, int state, int x, int y) -{ - //printf("button %i, state %i, x=%i,y=%i\n",button,state,x,y); - //button 0, state 0 means left mouse down - - SimdVector3 rayTo = GetRayTo(x,y); - - switch (button) - { - case 2: - { - if (state==0) - { - shootBox(rayTo); - } - break; - }; - case 1: - { - if (state==0) - { - //apply an impulse - if (physicsEnvironmentPtr) - { - float hit[3]; - float normal[3]; - PHY_IPhysicsController* hitObj = physicsEnvironmentPtr->rayTest(0,eye[0],eye[1],eye[2],rayTo.getX(),rayTo.getY(),rayTo.getZ(),hit[0],hit[1],hit[2],normal[0],normal[1],normal[2]); - if (hitObj) - { - CcdPhysicsController* physCtrl = static_cast(hitObj); - RigidBody* body = physCtrl->GetRigidBody(); - if (body) - { - body->SetActivationState(ACTIVE_TAG); - SimdVector3 impulse = rayTo; - impulse.normalize(); - float impulseStrength = 10.f; - impulse *= impulseStrength; - SimdVector3 relPos( - hit[0] - body->getCenterOfMassPosition().getX(), - hit[1] - body->getCenterOfMassPosition().getY(), - hit[2] - body->getCenterOfMassPosition().getZ()); - - body->applyImpulse(impulse,relPos); - } - - } - - } - - } else - { - - } - break; - } - case 0: - { - if (state==0) - { - //add a point to point constraint for picking - if (physicsEnvironmentPtr) - { - float hit[3]; - float normal[3]; - PHY_IPhysicsController* hitObj = physicsEnvironmentPtr->rayTest(0,eye[0],eye[1],eye[2],rayTo.getX(),rayTo.getY(),rayTo.getZ(),hit[0],hit[1],hit[2],normal[0],normal[1],normal[2]); - if (hitObj) - { - - CcdPhysicsController* physCtrl = static_cast(hitObj); - RigidBody* body = physCtrl->GetRigidBody(); - - if (body) - { - pickedBody = body; - pickedBody->SetActivationState(DISABLE_DEACTIVATION); - - SimdVector3 pickPos(hit[0],hit[1],hit[2]); - - SimdVector3 localPivot = body->getCenterOfMassTransform().inverse() * pickPos; - - gPickingConstraintId = physicsEnvironmentPtr->createConstraint(physCtrl,0,PHY_POINT2POINT_CONSTRAINT, - localPivot.getX(), - localPivot.getY(), - localPivot.getZ(), - 0,0,0); - //printf("created constraint %i",gPickingConstraintId); - - //save mouse position for dragging - gOldPickingPos = rayTo; - - - SimdVector3 eyePos(eye[0],eye[1],eye[2]); - - gOldPickingDist = (pickPos-eyePos).length(); - - Point2PointConstraint* p2p = static_cast(physicsEnvironmentPtr->getConstraintById(gPickingConstraintId)); - if (p2p) - { - //very weak constraint for picking - p2p->m_setting.m_tau = 0.1f; - } - } - } - } - } else - { - if (gPickingConstraintId && physicsEnvironmentPtr) - { - physicsEnvironmentPtr->removeConstraint(gPickingConstraintId); - //printf("removed constraint %i",gPickingConstraintId); - gPickingConstraintId = 0; - pickedBody->ForceActivationState(ACTIVE_TAG); - pickedBody->m_deactivationTime = 0.f; - pickedBody = 0; - - - } - } - - break; - - } - default: - { - } - } - -} - -void clientMotionFunc(int x,int y) -{ - - if (gPickingConstraintId && physicsEnvironmentPtr) - { - - //move the constraint pivot - - Point2PointConstraint* p2p = static_cast(physicsEnvironmentPtr->getConstraintById(gPickingConstraintId)); - if (p2p) - { - //keep it at the same picking distance - - SimdVector3 newRayTo = GetRayTo(x,y); - SimdVector3 eyePos(eye[0],eye[1],eye[2]); - SimdVector3 dir = newRayTo-eyePos; - dir.normalize(); - dir *= gOldPickingDist; - - SimdVector3 newPos = eyePos + dir; - p2p->SetPivotB(newPos); - } - - } -} diff --git a/Demos/ConvexDecompositionDemo/ConvexDecompositionDemo.h b/Demos/ConvexDecompositionDemo/ConvexDecompositionDemo.h new file mode 100644 index 000000000..34bf095f4 --- /dev/null +++ b/Demos/ConvexDecompositionDemo/ConvexDecompositionDemo.h @@ -0,0 +1,38 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef CONVEX_DECOMPOSITION_DEMO_H +#define CONVEX_DECOMPOSITION_DEMO_H + +#include "DemoApplication.h" + +///ConvexDecompositionDemo shows automatic convex decomposition of a concave mesh +class ConvexDecompositionDemo : public DemoApplication +{ + public: + + void initPhysics(const char* filename); + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + virtual void clientResetScene() + { + //not yet + } + +}; + +#endif //CONVEX_DECOMPOSITION_DEMO_H \ No newline at end of file diff --git a/Demos/GjkConvexCastDemo/LinearConvexCastDemo.cpp b/Demos/GjkConvexCastDemo/LinearConvexCastDemo.cpp index 49e060ee0..674e6b638 100644 --- a/Demos/GjkConvexCastDemo/LinearConvexCastDemo.cpp +++ b/Demos/GjkConvexCastDemo/LinearConvexCastDemo.cpp @@ -35,21 +35,10 @@ #endif //USE_ALGEBRAIC_CCD #include "CollisionShapes/SphereShape.h" - #include "CollisionShapes/Simplex1to4Shape.h" #include "GL_ShapeDrawer.h" -#ifdef WIN32 //needed for glut.h -#include -#endif -//think different -#if defined(__APPLE__) && !defined (VMDMESA) -#include -#include -#include -#else -#include -#endif +#include "LinearConvexCastDemo.h" #include "GlutStuff.h" @@ -71,6 +60,16 @@ void DrawRasterizerLine(float const* , float const*, int) int main(int argc,char** argv) { + LinearConvexCastDemo* linearCastDemo = new LinearConvexCastDemo(); + + linearCastDemo->initPhysics(); + + + return glutmain(argc, argv,screenWidth,screenHeight,"Linear Convex Cast Demo",linearCastDemo); +} + +void LinearConvexCastDemo::initPhysics() +{ setCameraDistance(30.f); tr[0].setOrigin(SimdVector3(0,0,0)); tr[1].setOrigin(SimdVector3(0,10,0)); @@ -93,7 +92,7 @@ int main(int argc,char** argv) SimdVector3 boxHalfExtentsA(0.2,4,4); SimdVector3 boxHalfExtentsB(6,6,6); - BoxShape boxA(boxHalfExtentsA); + BoxShape* boxA = new BoxShape(boxHalfExtentsA); /* BU_Simplex1to4 boxB; boxB.AddVertex(SimdPoint3(-5,0,-5)); boxB.AddVertex(SimdPoint3(5,0,-5)); @@ -101,30 +100,23 @@ int main(int argc,char** argv) boxB.AddVertex(SimdPoint3(0,5,0)); */ - BoxShape boxB(boxHalfExtentsB); - shapePtr[0] = &boxA; - shapePtr[1] = &boxB; + BoxShape* boxB = new BoxShape(boxHalfExtentsB); + shapePtr[0] = boxA; + shapePtr[1] = boxB; shapePtr[0]->SetMargin(0.01f); shapePtr[1]->SetMargin(0.01f); -// boxA.SetMargin(1.f); -// boxB.SetMargin(1.f); - - SimdTransform tr; tr.setIdentity(); - - - return glutmain(argc, argv,screenWidth,screenHeight,"Linear Convex Cast Demo"); } //to be implemented by the demo -void clientMoveAndDisplay() +void LinearConvexCastDemo::clientMoveAndDisplay() { - clientDisplay(); + displayCallback(); } #include "NarrowPhaseCollision/VoronoiSimplexSolver.h" @@ -136,7 +128,9 @@ SimplexSolverInterface& gGjkSimplexSolver = sVoronoiSimplexSolver; bool drawLine= false; -void clientDisplay(void) { +void LinearConvexCastDemo::displayCallback(void) +{ + updateCamera(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDisable(GL_LIGHTING); @@ -159,12 +153,10 @@ void clientDisplay(void) { orn.setEuler(yaw,pitch,roll); tr[shapeIndex].setRotation(orn); - extern bool stepping; - extern bool singleStep; - if (stepping || singleStep) + if (m_stepping || m_singleStep) { - singleStep = false; + m_singleStep = false; pitch += 0.005f; yaw += 0.01f; } @@ -239,25 +231,3 @@ void clientDisplay(void) { glFlush(); glutSwapBuffers(); } -void clientResetScene() -{ -} - -void clientSpecialKeyboard(int key, int x, int y) -{ - defaultSpecialKeyboard(key,x,y); -} - -void clientKeyboard(unsigned char key, int x, int y) -{ - defaultKeyboard(key, x, y); -} - - -void clientMouseFunc(int button, int state, int x, int y) -{ - -} -void clientMotionFunc(int x,int y) -{ -} diff --git a/Demos/GjkConvexCastDemo/LinearConvexCastDemo.h b/Demos/GjkConvexCastDemo/LinearConvexCastDemo.h new file mode 100644 index 000000000..3f5093d4f --- /dev/null +++ b/Demos/GjkConvexCastDemo/LinearConvexCastDemo.h @@ -0,0 +1,36 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef LINEAR_CONVEX_CAST_DEMO_H +#define LINEAR_CONVEX_CAST_DEMO_H + +#include "DemoApplication.h" + +///LinearConvexCastDemo shows the working of the object sweep / pure-linear continuous collision detection query +class LinearConvexCastDemo : public DemoApplication +{ + public: + + void initPhysics(); + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + virtual void clientResetScene() + { + } +}; + +#endif //LINEAR_CONVEX_CAST_DEMO_H \ No newline at end of file diff --git a/Demos/OpenGL/DemoApplication.cpp b/Demos/OpenGL/DemoApplication.cpp new file mode 100644 index 000000000..71ea9dec1 --- /dev/null +++ b/Demos/OpenGL/DemoApplication.cpp @@ -0,0 +1,894 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "DemoApplication.h" +#include "IDebugDraw.h" + +#include "CcdPhysicsEnvironment.h" +#include "CcdPhysicsController.h" +#include "ConstraintSolver/Point2PointConstraint.h"//picking +#include "PHY_Pro.h" +#include "CollisionShapes/CollisionShape.h" +#include "CollisionShapes/BoxShape.h" +#include "GL_ShapeDrawer.h" + +#include "BMF_Api.h" + +int numObjects = 0; +const int maxNumObjects = 450; +DefaultMotionState ms[maxNumObjects]; +CcdPhysicsController* physObjects[maxNumObjects]; +SimdTransform startTransforms[maxNumObjects]; +CollisionShape* gShapePtr[maxNumObjects];//1 rigidbody has 1 shape (no re-use of shapes) + + +DemoApplication::DemoApplication() + //see IDebugDraw.h for modes +: +m_physicsEnvironmentPtr(0), +m_debugMode(0), + m_cameraDistance(15.0), + + m_ele(0.f), + m_azi(0.f), + m_cameraPosition(0.f,0.f,0.f), + m_cameraTargetPosition(0.f,0.f,0.f), + m_scaleBottom(0.5f), + m_scaleFactor(2.f), + m_cameraUp(0,1,0), + m_forwardAxis(2), + m_glutScreenWidth(0), + m_glutScreenHeight(0), + m_ShootBoxInitialSpeed(40.f), + m_stepping(true), + m_singleStep(false), + m_idle(false) +{ +} + + +DemoApplication::~DemoApplication() +{ + +} + + +void DemoApplication::myinit(void) +{ + + GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 }; + GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; + GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 }; + /* light_position is NOT default value */ + GLfloat light_position0[] = { 1.0, 1.0, 1.0, 0.0 }; + GLfloat light_position1[] = { -1.0, -1.0, -1.0, 0.0 }; + + glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); + glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); + glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); + glLightfv(GL_LIGHT0, GL_POSITION, light_position0); + + glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient); + glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse); + glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular); + glLightfv(GL_LIGHT1, GL_POSITION, light_position1); + + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_LIGHT1); + + + glShadeModel(GL_SMOOTH); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); + + glClearColor(0.8,0.8,0.8,0); + + // glEnable(GL_CULL_FACE); + // glCullFace(GL_BACK); +} + + +void DemoApplication::setCameraDistance(float dist) +{ + m_cameraDistance = dist; +} + +float DemoApplication::getCameraDistance() +{ + return m_cameraDistance; +} + + + +void DemoApplication::toggleIdle() { + if (m_idle) { + m_idle = false; + } + else { + m_idle = true; + } +} + + + + +void DemoApplication::updateCamera() { + + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + float rele = m_ele * 0.01745329251994329547;// rads per deg + float razi = m_azi * 0.01745329251994329547;// rads per deg + + + SimdQuaternion rot(m_cameraUp,razi); + + + SimdVector3 eyePos(0,0,0); + eyePos[m_forwardAxis] = -m_cameraDistance; + + SimdVector3 forward(eyePos[0],eyePos[1],eyePos[2]); + if (forward.length2() < SIMD_EPSILON) + { + forward.setValue(1.f,0.f,0.f); + } + SimdVector3 right = m_cameraUp.cross(forward); + SimdQuaternion roll(right,-rele); + + eyePos = SimdMatrix3x3(rot) * SimdMatrix3x3(roll) * eyePos; + + m_cameraPosition[0] = eyePos.getX(); + m_cameraPosition[1] = eyePos.getY(); + m_cameraPosition[2] = eyePos.getZ(); + + glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 10000.0); + gluLookAt(m_cameraPosition[0], m_cameraPosition[1], m_cameraPosition[2], + m_cameraTargetPosition[0], m_cameraTargetPosition[1], m_cameraTargetPosition[2], + m_cameraUp.getX(),m_cameraUp.getY(),m_cameraUp.getZ()); + glMatrixMode(GL_MODELVIEW); +} + + + +const float STEPSIZE = 5; + +void DemoApplication::stepLeft() +{ + m_azi -= STEPSIZE; if (m_azi < 0) m_azi += 360; updateCamera(); +} +void DemoApplication::stepRight() +{ + m_azi += STEPSIZE; if (m_azi >= 360) m_azi -= 360; updateCamera(); +} +void DemoApplication::stepFront() +{ + m_ele += STEPSIZE; if (m_azi >= 360) m_azi -= 360; updateCamera(); +} +void DemoApplication::stepBack() +{ + m_ele -= STEPSIZE; if (m_azi < 0) m_azi += 360; updateCamera(); +} +void DemoApplication::zoomIn() +{ + m_cameraDistance -= 1; updateCamera(); +} +void DemoApplication::zoomOut() +{ + m_cameraDistance += 1; updateCamera(); +} + + + + + + + + + + +void DemoApplication::reshape(int w, int h) +{ + m_glutScreenWidth = w; + m_glutScreenHeight = h; + + glViewport(0, 0, w, h); + updateCamera(); +} + + + + +void DemoApplication::keyboardCallback(unsigned char key, int x, int y) +{ + m_lastKey = 0; + + switch (key) + { + case 'q' : exit(0); break; + + case 'l' : stepLeft(); break; + case 'r' : stepRight(); break; + case 'f' : stepFront(); break; + case 'b' : stepBack(); break; + case 'z' : zoomIn(); break; + case 'x' : zoomOut(); break; + case 'i' : toggleIdle(); break; + case 'h': + if (m_debugMode & IDebugDraw::DBG_NoHelpText) + m_debugMode = m_debugMode & (~IDebugDraw::DBG_NoHelpText); + else + m_debugMode |= IDebugDraw::DBG_NoHelpText; + break; + + case 'w': + if (m_debugMode & IDebugDraw::DBG_DrawWireframe) + m_debugMode = m_debugMode & (~IDebugDraw::DBG_DrawWireframe); + else + m_debugMode |= IDebugDraw::DBG_DrawWireframe; + break; + + case 'p': + if (m_debugMode & IDebugDraw::DBG_ProfileTimings) + m_debugMode = m_debugMode & (~IDebugDraw::DBG_ProfileTimings); + else + m_debugMode |= IDebugDraw::DBG_ProfileTimings; + break; + + case 'm': + if (m_debugMode & IDebugDraw::DBG_EnableSatComparison) + m_debugMode = m_debugMode & (~IDebugDraw::DBG_EnableSatComparison); + else + m_debugMode |= IDebugDraw::DBG_EnableSatComparison; + break; + + case 'n': + if (m_debugMode & IDebugDraw::DBG_DisableBulletLCP) + m_debugMode = m_debugMode & (~IDebugDraw::DBG_DisableBulletLCP); + else + m_debugMode |= IDebugDraw::DBG_DisableBulletLCP; + break; + + case 't' : + if (m_debugMode & IDebugDraw::DBG_DrawText) + m_debugMode = m_debugMode & (~IDebugDraw::DBG_DrawText); + else + m_debugMode |= IDebugDraw::DBG_DrawText; + break; + case 'y': + if (m_debugMode & IDebugDraw::DBG_DrawFeaturesText) + m_debugMode = m_debugMode & (~IDebugDraw::DBG_DrawFeaturesText); + else + m_debugMode |= IDebugDraw::DBG_DrawFeaturesText; + break; + case 'a': + if (m_debugMode & IDebugDraw::DBG_DrawAabb) + m_debugMode = m_debugMode & (~IDebugDraw::DBG_DrawAabb); + else + m_debugMode |= IDebugDraw::DBG_DrawAabb; + break; + case 'c' : + if (m_debugMode & IDebugDraw::DBG_DrawContactPoints) + m_debugMode = m_debugMode & (~IDebugDraw::DBG_DrawContactPoints); + else + m_debugMode |= IDebugDraw::DBG_DrawContactPoints; + break; + + case 'd' : + if (m_debugMode & IDebugDraw::DBG_NoDeactivation) + m_debugMode = m_debugMode & (~IDebugDraw::DBG_NoDeactivation); + else + m_debugMode |= IDebugDraw::DBG_NoDeactivation; + break; + + + + case 'o' : + { + m_stepping = !m_stepping; + break; + } + case 's' : clientMoveAndDisplay(); break; +// case ' ' : newRandom(); break; + case ' ': + clientResetScene(); + break; + case '1': + { + if (m_debugMode & IDebugDraw::DBG_EnableCCD) + m_debugMode = m_debugMode & (~IDebugDraw::DBG_EnableCCD); + else + m_debugMode |= IDebugDraw::DBG_EnableCCD; + break; + } + + case '.': + { + shootBox(getCameraTargetPosition()); + break; + } + + case '+': + { + m_ShootBoxInitialSpeed += 10.f; + break; + } + case '-': + { + m_ShootBoxInitialSpeed -= 10.f; + break; + } + + default: +// std::cout << "unused key : " << key << std::endl; + break; + } + + glutPostRedisplay(); + +} + +void DemoApplication::specialKeyboard(int key, int x, int y) +{ + switch (key) + { + case GLUT_KEY_LEFT : stepLeft(); break; + case GLUT_KEY_RIGHT : stepRight(); break; + case GLUT_KEY_UP : stepFront(); break; + case GLUT_KEY_DOWN : stepBack(); break; + case GLUT_KEY_PAGE_UP : zoomIn(); break; + case GLUT_KEY_PAGE_DOWN : zoomOut(); break; + case GLUT_KEY_HOME : toggleIdle(); break; + default: +// std::cout << "unused (special) key : " << key << std::endl; + break; + } + + glutPostRedisplay(); + +} + + + +void DemoApplication::moveAndDisplay() +{ + if (!m_idle) + clientMoveAndDisplay(); +} + + + + +void DemoApplication::displayCallback() +{ +} + + + + +void DemoApplication::shootBox(const SimdVector3& destination) +{ + if (m_physicsEnvironmentPtr) + { + bool isDynamic = true; + float mass = 1.f; + SimdTransform startTransform; + startTransform.setIdentity(); + SimdVector3 camPos = getCameraPosition(); + startTransform.setOrigin(camPos); + CollisionShape* boxShape = new BoxShape(SimdVector3(1.f,1.f,1.f)); + + CcdPhysicsController* newBox = LocalCreatePhysicsObject(isDynamic, mass, startTransform,boxShape); + + SimdVector3 linVel(destination[0]-camPos[0],destination[1]-camPos[1],destination[2]-camPos[2]); + linVel.normalize(); + linVel*=m_ShootBoxInitialSpeed; + + newBox->setPosition(camPos[0],camPos[1],camPos[2]); + newBox->setOrientation(0,0,0,1); + newBox->SetLinearVelocity(linVel[0],linVel[1],linVel[2],false); + newBox->SetAngularVelocity(0,0,0,false); + } +} + + +int gPickingConstraintId = 0; +SimdVector3 gOldPickingPos; +float gOldPickingDist = 0.f; +RigidBody* pickedBody = 0;//for deactivation state + + +SimdVector3 DemoApplication::GetRayTo(int x,int y) +{ + + float top = 1.f; + float bottom = -1.f; + float nearPlane = 1.f; + float tanFov = (top-bottom)*0.5f / nearPlane; + float fov = 2.0 * atanf (tanFov); + + SimdVector3 rayFrom = getCameraPosition(); + SimdVector3 rayForward = (getCameraTargetPosition()-getCameraPosition()); + rayForward.normalize(); + float farPlane = 600.f; + rayForward*= farPlane; + + SimdVector3 rightOffset; + SimdVector3 vertical = m_cameraUp; + + SimdVector3 hor; + hor = rayForward.cross(vertical); + hor.normalize(); + vertical = hor.cross(rayForward); + vertical.normalize(); + + float tanfov = tanf(0.5f*fov); + hor *= 2.f * farPlane * tanfov; + vertical *= 2.f * farPlane * tanfov; + SimdVector3 rayToCenter = rayFrom + rayForward; + SimdVector3 dHor = hor * 1.f/float(m_glutScreenWidth); + SimdVector3 dVert = vertical * 1.f/float(m_glutScreenHeight); + SimdVector3 rayTo = rayToCenter - 0.5f * hor + 0.5f * vertical; + rayTo += x * dHor; + rayTo -= y * dVert; + return rayTo; +} + + +void DemoApplication::mouseFunc(int button, int state, int x, int y) +{ + //printf("button %i, state %i, x=%i,y=%i\n",button,state,x,y); + //button 0, state 0 means left mouse down + + SimdVector3 rayTo = GetRayTo(x,y); + + switch (button) + { + case 2: + { + if (state==0) + { + shootBox(rayTo); + } + break; + }; + case 1: + { + if (state==0) + { + //apply an impulse + if (m_physicsEnvironmentPtr) + { + float hit[3]; + float normal[3]; + PHY_IPhysicsController* hitObj = m_physicsEnvironmentPtr->rayTest(0,m_cameraPosition[0],m_cameraPosition[1],m_cameraPosition[2],rayTo.getX(),rayTo.getY(),rayTo.getZ(),hit[0],hit[1],hit[2],normal[0],normal[1],normal[2]); + if (hitObj) + { + CcdPhysicsController* physCtrl = static_cast(hitObj); + RigidBody* body = physCtrl->GetRigidBody(); + if (body) + { + body->SetActivationState(ACTIVE_TAG); + SimdVector3 impulse = rayTo; + impulse.normalize(); + float impulseStrength = 10.f; + impulse *= impulseStrength; + SimdVector3 relPos( + hit[0] - body->getCenterOfMassPosition().getX(), + hit[1] - body->getCenterOfMassPosition().getY(), + hit[2] - body->getCenterOfMassPosition().getZ()); + + body->applyImpulse(impulse,relPos); + } + + } + + } + + } else + { + + } + break; + } + case 0: + { + if (state==0) + { + //add a point to point constraint for picking + if (m_physicsEnvironmentPtr) + { + float hit[3]; + float normal[3]; + PHY_IPhysicsController* hitObj = m_physicsEnvironmentPtr->rayTest(0,m_cameraPosition[0],m_cameraPosition[1],m_cameraPosition[2],rayTo.getX(),rayTo.getY(),rayTo.getZ(),hit[0],hit[1],hit[2],normal[0],normal[1],normal[2]); + if (hitObj) + { + + CcdPhysicsController* physCtrl = static_cast(hitObj); + RigidBody* body = physCtrl->GetRigidBody(); + + if (body && !body->IsStatic()) + { + pickedBody = body; + pickedBody->SetActivationState(DISABLE_DEACTIVATION); + + SimdVector3 pickPos(hit[0],hit[1],hit[2]); + + SimdVector3 localPivot = body->getCenterOfMassTransform().inverse() * pickPos; + + gPickingConstraintId = m_physicsEnvironmentPtr->createConstraint(physCtrl,0,PHY_POINT2POINT_CONSTRAINT, + localPivot.getX(), + localPivot.getY(), + localPivot.getZ(), + 0,0,0); + //printf("created constraint %i",gPickingConstraintId); + + //save mouse position for dragging + gOldPickingPos = rayTo; + + + SimdVector3 eyePos(m_cameraPosition[0],m_cameraPosition[1],m_cameraPosition[2]); + + gOldPickingDist = (pickPos-eyePos).length(); + + Point2PointConstraint* p2p = static_cast(m_physicsEnvironmentPtr->getConstraintById(gPickingConstraintId)); + if (p2p) + { + //very weak constraint for picking + p2p->m_setting.m_tau = 0.1f; + } + } + } + } + } else + { + if (gPickingConstraintId && m_physicsEnvironmentPtr) + { + m_physicsEnvironmentPtr->removeConstraint(gPickingConstraintId); + //printf("removed constraint %i",gPickingConstraintId); + gPickingConstraintId = 0; + pickedBody->ForceActivationState(ACTIVE_TAG); + pickedBody->m_deactivationTime = 0.f; + pickedBody = 0; + + + } + } + + break; + + } + default: + { + } + } + +} + +void DemoApplication::mouseMotionFunc(int x,int y) +{ + + if (gPickingConstraintId && m_physicsEnvironmentPtr) + { + + //move the constraint pivot + + Point2PointConstraint* p2p = static_cast(m_physicsEnvironmentPtr->getConstraintById(gPickingConstraintId)); + if (p2p) + { + //keep it at the same picking distance + + SimdVector3 newRayTo = GetRayTo(x,y); + SimdVector3 eyePos(m_cameraPosition[0],m_cameraPosition[1],m_cameraPosition[2]); + SimdVector3 dir = newRayTo-eyePos; + dir.normalize(); + dir *= gOldPickingDist; + + SimdVector3 newPos = eyePos + dir; + p2p->SetPivotB(newPos); + } + + } +} + + +///Very basic import +CcdPhysicsController* DemoApplication::LocalCreatePhysicsObject(bool isDynamic, float mass, const SimdTransform& startTransform,CollisionShape* shape) +{ + + startTransforms[numObjects] = startTransform; + + PHY_ShapeProps shapeProps; + + shapeProps.m_do_anisotropic = false; + shapeProps.m_do_fh = false; + shapeProps.m_do_rot_fh = false; + shapeProps.m_friction_scaling[0] = 1.; + shapeProps.m_friction_scaling[1] = 1.; + shapeProps.m_friction_scaling[2] = 1.; + + shapeProps.m_inertia = 1.f; + shapeProps.m_lin_drag = 0.2f; + shapeProps.m_ang_drag = 0.1f; + shapeProps.m_mass = 10.0f; + + PHY_MaterialProps materialProps; + materialProps.m_friction = 10.5f; + materialProps.m_restitution = 0.0f; + + CcdConstructionInfo ccdObjectCi; + ccdObjectCi.m_friction = 0.5f; + + ccdObjectCi.m_linearDamping = shapeProps.m_lin_drag; + ccdObjectCi.m_angularDamping = shapeProps.m_ang_drag; + + SimdTransform tr; + tr.setIdentity(); + + int i = numObjects; + { + gShapePtr[i] = shape; + + shapeProps.m_shape = gShapePtr[i]; + shapeProps.m_shape->SetMargin(0.05f); + + SimdQuaternion orn = startTransform.getRotation(); + + + ms[i].setWorldOrientation(orn[0],orn[1],orn[2],orn[3]); + ms[i].setWorldPosition(startTransform.getOrigin().getX(),startTransform.getOrigin().getY(),startTransform.getOrigin().getZ()); + + ccdObjectCi.m_MotionState = &ms[i]; + ccdObjectCi.m_gravity = SimdVector3(0,-9.8,0); + ccdObjectCi.m_localInertiaTensor =SimdVector3(0,0,0); + if (!isDynamic) + { + shapeProps.m_mass = 0.f; + ccdObjectCi.m_mass = shapeProps.m_mass; + ccdObjectCi.m_collisionFlags = CollisionObject::isStatic; + ccdObjectCi.m_collisionFilterGroup = CcdConstructionInfo::StaticFilter; + ccdObjectCi.m_collisionFilterMask = CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::StaticFilter; + } + else + { + shapeProps.m_mass = mass; + ccdObjectCi.m_mass = shapeProps.m_mass; + ccdObjectCi.m_collisionFlags = 0; + } + + + SimdVector3 localInertia(0.f,0.f,0.f); + + if (isDynamic) + { + gShapePtr[i]->CalculateLocalInertia(shapeProps.m_mass,localInertia); + } + + ccdObjectCi.m_localInertiaTensor = localInertia; + ccdObjectCi.m_collisionShape = gShapePtr[i]; + + + physObjects[i]= new CcdPhysicsController( ccdObjectCi); + + // Only do CCD if motion in one timestep (1.f/60.f) exceeds CUBE_HALF_EXTENTS + physObjects[i]->GetRigidBody()->m_ccdSquareMotionTreshold = 0.f; + + //Experimental: better estimation of CCD Time of Impact: + //physObjects[i]->GetRigidBody()->m_ccdSweptShereRadius = 0.5*CUBE_HALF_EXTENTS; + + m_physicsEnvironmentPtr->addCcdPhysicsController( physObjects[i]); + + } + + //return newly created PhysicsController + return physObjects[numObjects++]; +} + +void DemoApplication::renderme() +{ + updateCamera(); + + float m[16]; + + if (m_physicsEnvironmentPtr) + { + + if (getDebugMode() & IDebugDraw::DBG_DisableBulletLCP) + { + //don't use Bullet, use quickstep + m_physicsEnvironmentPtr->setSolverType(0); + } else + { + //Bullet LCP solver + m_physicsEnvironmentPtr->setSolverType(1); + } + + if (getDebugMode() & IDebugDraw::DBG_EnableCCD) + { + m_physicsEnvironmentPtr->setCcdMode(3); + } else + { + m_physicsEnvironmentPtr->setCcdMode(0); + } + + + bool isSatEnabled = (getDebugMode() & IDebugDraw::DBG_EnableSatComparison); + + m_physicsEnvironmentPtr->EnableSatCollisionDetection(isSatEnabled); + + + + int numPhysicsObjects = m_physicsEnvironmentPtr->GetNumControllers(); + + int i; + + for (i=0;iGetPhysicsController(i); + RigidBody* body = ctrl->GetRigidBody(); + + body->m_worldTransform.getOpenGLMatrix( m ); + + SimdVector3 wireColor(1.f,1.0f,0.5f); //wants deactivation + if (i & 1) + { + wireColor = SimdVector3(0.f,0.0f,1.f); + } + ///color differently for active, sleeping, wantsdeactivation states + if (ctrl->GetRigidBody()->GetActivationState() == 1) //active + { + if (i & 1) + { + wireColor += SimdVector3 (1.f,0.f,0.f); + } else + { + wireColor += SimdVector3 (.5f,0.f,0.f); + } + } + if (ctrl->GetRigidBody()->GetActivationState() == 2) //ISLAND_SLEEPING + { + if (i & 1) + { + wireColor += SimdVector3 (0.f,1.f, 0.f); + } else + { + wireColor += SimdVector3 (0.f,0.5f,0.f); + } + } + + char extraDebug[125]; + sprintf(extraDebug,"islId, Body=%i , %i",ctrl->GetRigidBody()->m_islandTag1,ctrl->GetRigidBody()->m_debugBodyId); + ctrl->GetRigidBody()->GetCollisionShape()->SetExtraDebugInfo(extraDebug); + + float vec[16]; + SimdTransform ident; + ident.setIdentity(); + ident.getOpenGLMatrix(vec); + + + GL_ShapeDrawer::DrawOpenGL(m,ctrl->GetRigidBody()->GetCollisionShape(),wireColor,getDebugMode()); + + + + + } + + if (!(getDebugMode() & IDebugDraw::DBG_NoHelpText)) + { + + float xOffset = 10.f; + float yStart = 20.f; + + float yIncr = -2.f; + + char buf[124]; + + glColor3f(0, 0, 0); + + #ifdef USE_QUICKPROF + + + if ( getDebugMode() & IDebugDraw::DBG_ProfileTimings) + { + static int counter = 0; + counter++; + std::map::iterator iter; + for (iter = Profiler::mProfileBlocks.begin(); iter != Profiler::mProfileBlocks.end(); ++iter) + { + char blockTime[128]; + sprintf(blockTime, "%s: %lf",&((*iter).first[0]),Profiler::getBlockTime((*iter).first, Profiler::BLOCK_CYCLE_SECONDS));//BLOCK_TOTAL_PERCENT)); + glRasterPos3f(xOffset,yStart,0); + BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),blockTime); + yStart += yIncr; + + } + } + #endif //USE_QUICKPROF + //profiling << Profiler::createStatsString(Profiler::BLOCK_TOTAL_PERCENT); + //<< std::endl; + + + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"mouse to interact"); + BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); + yStart += yIncr; + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"space to reset"); + BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); + yStart += yIncr; + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"cursor keys and z,x to navigate"); + BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); + yStart += yIncr; + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"i to toggle simulation, s single step"); + BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); + yStart += yIncr; + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"q to quit"); + BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); + yStart += yIncr; + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"d to toggle deactivation"); + BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); + yStart += yIncr; + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"a to draw temporal AABBs"); + BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); + yStart += yIncr; + + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"h to toggle help text"); + BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); + yStart += yIncr; + + bool useBulletLCP = !(getDebugMode() & IDebugDraw::DBG_DisableBulletLCP); + + bool useCCD = (getDebugMode() & IDebugDraw::DBG_EnableCCD); + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"m Bullet GJK = %i",!isSatEnabled); + BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); + yStart += yIncr; + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"n Bullet LCP = %i",useBulletLCP); + BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); + yStart += yIncr; + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"1 CCD mode (adhoc) = %i",useCCD); + BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); + yStart += yIncr; + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"+- shooting speed = %10.2f",m_ShootBoxInitialSpeed); + BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); + yStart += yIncr; + + } + + } + +} \ No newline at end of file diff --git a/Demos/OpenGL/DemoApplication.h b/Demos/OpenGL/DemoApplication.h new file mode 100644 index 000000000..f49d2a1ec --- /dev/null +++ b/Demos/OpenGL/DemoApplication.h @@ -0,0 +1,170 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef DEMO_APPLICATION_H +#define DEMO_APPLICATION_H + + +#ifdef WIN32//for glut.h +#include +#endif + +//think different +#if defined(__APPLE__) && !defined (VMDMESA) +#include +#include +#include +#else +#include +#endif + +#include +#include +#include + + +#include "SimdVector3.h" +#include "SimdMatrix3x3.h" +#include "SimdTransform.h" + +class CcdPhysicsEnvironment; +class CcdPhysicsController; +class CollisionShape; + + +class DemoApplication +{ + + protected: + + + ///this is the most important class + CcdPhysicsEnvironment* m_physicsEnvironmentPtr; + + + float m_cameraDistance; + int m_debugMode; + + float m_ele; + float m_azi; + SimdVector3 m_cameraPosition; + SimdVector3 m_cameraTargetPosition;//look at + + float m_scaleBottom; + float m_scaleFactor; + SimdVector3 m_cameraUp; + int m_forwardAxis; + + int m_glutScreenWidth; + int m_glutScreenHeight; + + float m_ShootBoxInitialSpeed; + + bool m_stepping; + bool m_singleStep; + bool m_idle; + int m_lastKey; + + public: + + DemoApplication(); + + virtual ~DemoApplication(); + + + int getDebugMode() + { + return m_debugMode ; + } + + void setDebugMode(int mode) + { + m_debugMode = mode; + } + + CcdPhysicsEnvironment* GetPhysicsEnvironment() + { + return m_physicsEnvironmentPtr; + } + + void setCameraUp(const SimdVector3& camUp) + { + m_cameraUp = camUp; + } + void setCameraForwardAxis(int axis) + { + m_forwardAxis = axis; + } + + void myinit(); + + void toggleIdle(); + + virtual void updateCamera(); + + SimdVector3 getCameraPosition() + { + return m_cameraPosition; + } + SimdVector3 getCameraTargetPosition() + { + return m_cameraTargetPosition; + } + + + ///glut callbacks + + float getCameraDistance(); + void setCameraDistance(float dist); + void moveAndDisplay(); + + virtual void clientMoveAndDisplay() = 0; + + virtual void clientResetScene() =0 ; + + ///Demo functions + void shootBox(const SimdVector3& destination); + + SimdVector3 GetRayTo(int x,int y); + + CcdPhysicsController* LocalCreatePhysicsObject(bool isDynamic, float mass, const SimdTransform& startTransform,CollisionShape* shape); + + ///callback methods by glut + + virtual void keyboardCallback(unsigned char key, int x, int y); + + virtual void specialKeyboard(int key, int x, int y); + + virtual void reshape(int w, int h); + + virtual void mouseFunc(int button, int state, int x, int y); + + virtual void mouseMotionFunc(int x,int y); + + virtual void displayCallback(); + + virtual void renderme(); + + + void stepLeft(); + void stepRight(); + void stepFront(); + void stepBack(); + void zoomIn(); + void zoomOut(); + +}; + +#endif //DEMO_APPLICATION_H \ No newline at end of file diff --git a/Demos/OpenGL/GL_ShapeDrawer.cpp b/Demos/OpenGL/GL_ShapeDrawer.cpp index b81e286e1..86d6cdf13 100644 --- a/Demos/OpenGL/GL_ShapeDrawer.cpp +++ b/Demos/OpenGL/GL_ShapeDrawer.cpp @@ -153,7 +153,7 @@ void GL_ShapeDrawer::DrawOpenGL(float* m, const CollisionShape* shape, const Sim { const BU_Simplex1to4* tetra = static_cast(shape); //todo: - useWireframeFallback = false; +// useWireframeFallback = false; break; } case CONVEX_HULL_SHAPE_PROXYTYPE: @@ -307,10 +307,10 @@ void GL_ShapeDrawer::DrawOpenGL(float* m, const CollisionShape* shape, const Sim TriangleMeshShape* concaveMesh = (TriangleMeshShape*) shape; //SimdVector3 aabbMax(1e30f,1e30f,1e30f); //SimdVector3 aabbMax(100,100,100);//1e30f,1e30f,1e30f); - - extern float eye[3]; - SimdVector3 aabbMax(eye[0]+100,eye[1]+100,eye[2]+100);//1e30f,1e30f,1e30f); - SimdVector3 aabbMin(eye[0]-100,eye[1]-100,eye[2]-100);//1e30f,1e30f,1e30f); + + //todo pass camera, for some culling + SimdVector3 aabbMax(1e30f,1e30f,1e30f); + SimdVector3 aabbMin(-1e30f,-1e30f,-1e30f); GlDrawcallback drawCallback; @@ -323,9 +323,9 @@ void GL_ShapeDrawer::DrawOpenGL(float* m, const CollisionShape* shape, const Sim { ConvexTriangleMeshShape* convexMesh = (ConvexTriangleMeshShape*) shape; - extern float eye[3]; - SimdVector3 aabbMax(eye[0]+100,eye[1]+100,eye[2]+100); - SimdVector3 aabbMin(eye[0]-100,eye[1]-100,eye[2]-100); + //todo: pass camera for some culling + SimdVector3 aabbMax(1e30f,1e30f,1e30f); + SimdVector3 aabbMin(-1e30f,-1e30f,-1e30f); TriangleGlDrawcallback drawCallback; convexMesh->GetStridingMesh()->InternalProcessAllTriangles(&drawCallback,aabbMin,aabbMax); diff --git a/Demos/OpenGL/GlutStuff.cpp b/Demos/OpenGL/GlutStuff.cpp index d3cfe834b..f19d54f3b 100644 --- a/Demos/OpenGL/GlutStuff.cpp +++ b/Demos/OpenGL/GlutStuff.cpp @@ -13,361 +13,57 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ -#ifdef WIN32//for glut.h -#include -#endif - - -//think different -#if defined(__APPLE__) && !defined (VMDMESA) -#include -#include -#include -#else -#include -#endif - -#include -#include -#include -#include "IDebugDraw.h" -//see IDebugDraw.h for modes -static int sDebugMode = 0; - -int getDebugMode() -{ - return sDebugMode ; -} - -void setDebugMode(int mode) -{ - sDebugMode = mode; -} +#include "DemoApplication.h" +//glut is C code, this global gDemoApplication links glut to the C++ demo +static DemoApplication* gDemoApplication = 0; #include "GlutStuff.h" -void myinit(void) { - - GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 }; - GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; - GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 }; - /* light_position is NOT default value */ - GLfloat light_position0[] = { 1.0, 1.0, 1.0, 0.0 }; - GLfloat light_position1[] = { -1.0, -1.0, -1.0, 0.0 }; - - glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); - glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); - glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); - glLightfv(GL_LIGHT0, GL_POSITION, light_position0); - - glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient); - glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse); - glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular); - glLightfv(GL_LIGHT1, GL_POSITION, light_position1); - - glEnable(GL_LIGHTING); - glEnable(GL_LIGHT0); - glEnable(GL_LIGHT1); - - - glShadeModel(GL_SMOOTH); - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LESS); - - glClearColor(0.8,0.8,0.8,0); - - // glEnable(GL_CULL_FACE); - // glCullFace(GL_BACK); -} - - -static float DISTANCE = 15; -void setCameraDistance(float dist) +static void glutKeyboardCallback(unsigned char key, int x, int y) { - DISTANCE = dist; + gDemoApplication->keyboardCallback(key,x,y); } -static float ele = 0, azi = 0; -float eye[3] = {0, 0, DISTANCE}; -static float center[3] = {0, 0, 0}; -static const double SCALE_BOTTOM = 0.5; -static const double SCALE_FACTOR = 2; - -bool stepping= true; -bool singleStep = false; - - -static bool idle = false; - -void toggleIdle() { - - - if (idle) { - glutIdleFunc(clientMoveAndDisplay); - idle = false; - } - else { - glutIdleFunc(0); - idle = true; - } +static void glutSpecialKeyboardCallback(int key, int x, int y) +{ + gDemoApplication->specialKeyboard(key,x,y); } -#include "SimdMatrix3x3.h" +static void glutReshapeCallback(int w, int h) +{ + gDemoApplication->reshape(w,h); +} -SimdVector3 gCameraUp(0,1,0); -int gForwardAxis = 2; +static void glutMoveAndDisplayCallback() +{ + gDemoApplication->moveAndDisplay(); +} -void setCamera() { +static void glutMouseFuncCallback(int button, int state, int x, int y) +{ + gDemoApplication->mouseFunc(button,state,x,y); +} - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - float rele = ele * 0.01745329251994329547;// rads per deg - float razi = azi * 0.01745329251994329547;// rads per deg - - - SimdQuaternion rot(gCameraUp,razi); - - - SimdVector3 eyePos(0,0,0); - eyePos[gForwardAxis] = -DISTANCE; - - SimdVector3 forward(eyePos[0],eyePos[1],eyePos[2]); - if (forward.length2() < SIMD_EPSILON) - { - forward.setValue(1.f,0.f,0.f); - } - SimdVector3 right = gCameraUp.cross(forward); - SimdQuaternion roll(right,-rele); - - eyePos = SimdMatrix3x3(rot) * SimdMatrix3x3(roll) * eyePos; - - eye[0] = eyePos.getX(); - eye[1] = eyePos.getY(); - eye[2] = eyePos.getZ(); - - glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 10000.0); - gluLookAt(eye[0], eye[1], eye[2], - center[0], center[1], center[2], - gCameraUp.getX(),gCameraUp.getY(),gCameraUp.getZ()); - glMatrixMode(GL_MODELVIEW); -} - - - -const float STEPSIZE = 5; - -void stepLeft() { azi -= STEPSIZE; if (azi < 0) azi += 360; setCamera(); } -void stepRight() { azi += STEPSIZE; if (azi >= 360) azi -= 360; setCamera(); } -void stepFront() { ele += STEPSIZE; if (azi >= 360) azi -= 360; setCamera(); } -void stepBack() { ele -= STEPSIZE; if (azi < 0) azi += 360; setCamera(); } -void zoomIn() { DISTANCE -= 1; setCamera(); } -void zoomOut() { DISTANCE += 1; setCamera(); } - - -int glutScreenWidth = 0; -int glutScreenHeight = 0; - -void myReshape(int w, int h) { - glutScreenWidth = w; - glutScreenHeight = h; - - glViewport(0, 0, w, h); - setCamera(); -} - -int lastKey = 0; - -void defaultKeyboard(unsigned char key, int x, int y) -{ - lastKey = 0; - - switch (key) - { - case 'q' : exit(0); break; - - case 'l' : stepLeft(); break; - case 'r' : stepRight(); break; - case 'f' : stepFront(); break; - case 'b' : stepBack(); break; - case 'z' : zoomIn(); break; - case 'x' : zoomOut(); break; - case 'i' : toggleIdle(); break; - case 'h': - if (sDebugMode & IDebugDraw::DBG_NoHelpText) - sDebugMode = sDebugMode & (~IDebugDraw::DBG_NoHelpText); - else - sDebugMode |= IDebugDraw::DBG_NoHelpText; - break; - - case 'w': - if (sDebugMode & IDebugDraw::DBG_DrawWireframe) - sDebugMode = sDebugMode & (~IDebugDraw::DBG_DrawWireframe); - else - sDebugMode |= IDebugDraw::DBG_DrawWireframe; - break; - - case 'p': - if (sDebugMode & IDebugDraw::DBG_ProfileTimings) - sDebugMode = sDebugMode & (~IDebugDraw::DBG_ProfileTimings); - else - sDebugMode |= IDebugDraw::DBG_ProfileTimings; - break; - - case 'm': - if (sDebugMode & IDebugDraw::DBG_EnableSatComparison) - sDebugMode = sDebugMode & (~IDebugDraw::DBG_EnableSatComparison); - else - sDebugMode |= IDebugDraw::DBG_EnableSatComparison; - break; - - case 'n': - if (sDebugMode & IDebugDraw::DBG_DisableBulletLCP) - sDebugMode = sDebugMode & (~IDebugDraw::DBG_DisableBulletLCP); - else - sDebugMode |= IDebugDraw::DBG_DisableBulletLCP; - break; - - case 't' : - if (sDebugMode & IDebugDraw::DBG_DrawText) - sDebugMode = sDebugMode & (~IDebugDraw::DBG_DrawText); - else - sDebugMode |= IDebugDraw::DBG_DrawText; - break; - case 'y': - if (sDebugMode & IDebugDraw::DBG_DrawFeaturesText) - sDebugMode = sDebugMode & (~IDebugDraw::DBG_DrawFeaturesText); - else - sDebugMode |= IDebugDraw::DBG_DrawFeaturesText; - break; - case 'a': - if (sDebugMode & IDebugDraw::DBG_DrawAabb) - sDebugMode = sDebugMode & (~IDebugDraw::DBG_DrawAabb); - else - sDebugMode |= IDebugDraw::DBG_DrawAabb; - break; - case 'c' : - if (sDebugMode & IDebugDraw::DBG_DrawContactPoints) - sDebugMode = sDebugMode & (~IDebugDraw::DBG_DrawContactPoints); - else - sDebugMode |= IDebugDraw::DBG_DrawContactPoints; - break; - - case 'd' : - if (sDebugMode & IDebugDraw::DBG_NoDeactivation) - sDebugMode = sDebugMode & (~IDebugDraw::DBG_NoDeactivation); - else - sDebugMode |= IDebugDraw::DBG_NoDeactivation; - break; - - - - case 'o' : - { - stepping = !stepping; - break; - } - case 's' : clientMoveAndDisplay(); break; -// case ' ' : newRandom(); break; - case ' ': - clientResetScene(); - break; - case '1': - { - if (sDebugMode & IDebugDraw::DBG_EnableCCD) - sDebugMode = sDebugMode & (~IDebugDraw::DBG_EnableCCD); - else - sDebugMode |= IDebugDraw::DBG_EnableCCD; - break; - } - default: -// std::cout << "unused key : " << key << std::endl; - break; - } - - glutPostRedisplay(); - -} - - - -void defaultSpecialKeyboard(int key, int x, int y) -{ - switch (key) - { - case GLUT_KEY_LEFT : stepLeft(); break; - case GLUT_KEY_RIGHT : stepRight(); break; - case GLUT_KEY_UP : stepFront(); break; - case GLUT_KEY_DOWN : stepBack(); break; - case GLUT_KEY_PAGE_UP : zoomIn(); break; - case GLUT_KEY_PAGE_DOWN : zoomOut(); break; - case GLUT_KEY_HOME : toggleIdle(); break; - default: -// std::cout << "unused (special) key : " << key << std::endl; - break; - } - - glutPostRedisplay(); - -} - - -void goodbye( void) -{ - printf("goodbye \n"); - exit(0); -} - - -void menu(int choice) -{ - static int fullScreen = 0; - static int px, py, sx, sy; - - switch(choice) { - case 1: - if (fullScreen == 1) { - glutPositionWindow(px,py); - glutReshapeWindow(sx,sy); - glutChangeToMenuEntry(1,"Full Screen",1); - fullScreen = 0; - } else { - px=glutGet((GLenum)GLUT_WINDOW_X); - py=glutGet((GLenum)GLUT_WINDOW_Y); - sx=glutGet((GLenum)GLUT_WINDOW_WIDTH); - sy=glutGet((GLenum)GLUT_WINDOW_HEIGHT); - glutFullScreen(); - glutChangeToMenuEntry(1,"Close Full Screen",1); - fullScreen = 1; - } - break; - case 2: - toggleIdle(); - break; - case 3: - goodbye(); - break; - default: - break; - } -} - -void createMenu() -{ - glutCreateMenu(menu); - glutAddMenuEntry("Full Screen", 1); - glutAddMenuEntry("Toggle Idle (Start/Stop)", 2); - glutAddMenuEntry("Quit", 3); - glutAttachMenu(GLUT_RIGHT_BUTTON); -} - - - -int glutmain(int argc, char **argv,int width,int height,const char* title) { +static void glutMotionFuncCallback(int x,int y) +{ + gDemoApplication->mouseMotionFunc(x,y); +} + + +static void glutDisplayCallback(void) +{ + gDemoApplication->displayCallback(); +} + + + +int glutmain(int argc, char **argv,int width,int height,const char* title,DemoApplication* demoApp) { + gDemoApplication = demoApp; glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); @@ -375,17 +71,18 @@ int glutmain(int argc, char **argv,int width,int height,const char* title) { glutInitWindowSize(width, height); glutCreateWindow(title); - myinit(); - glutKeyboardFunc(clientKeyboard); - glutSpecialFunc(clientSpecialKeyboard); - glutReshapeFunc(myReshape); - //createMenu(); - glutIdleFunc(clientMoveAndDisplay); - glutMouseFunc(clientMouseFunc); - glutMotionFunc(clientMotionFunc); - glutDisplayFunc( clientDisplay ); + gDemoApplication->myinit(); - clientMoveAndDisplay(); + glutKeyboardFunc(glutKeyboardCallback); + glutSpecialFunc(glutSpecialKeyboardCallback); + glutReshapeFunc(glutReshapeCallback); + //createMenu(); + glutIdleFunc(glutMoveAndDisplayCallback); + glutMouseFunc(glutMouseFuncCallback); + glutMotionFunc(glutMotionFuncCallback); + glutDisplayFunc( glutDisplayCallback ); + + glutMoveAndDisplayCallback(); glutMainLoop(); return 0; diff --git a/Demos/OpenGL/GlutStuff.h b/Demos/OpenGL/GlutStuff.h index d18d3dd0e..03f5fc488 100644 --- a/Demos/OpenGL/GlutStuff.h +++ b/Demos/OpenGL/GlutStuff.h @@ -15,24 +15,8 @@ subject to the following restrictions: #ifndef GLUT_STUFF_H #define GLUT_STUFF_H -//to be implemented by the demo -void clientDisplay(); -void clientMoveAndDisplay(); -void clientResetScene(); +class DemoApplication; +int glutmain(int argc, char **argv,int width,int height,const char* title,DemoApplication* demoApp); -int glutmain(int argc, char **argv,int width,int height,const char* title); - -void setCameraDistance(float dist); -int getDebugMode(); -void setDebugMode(int mode); - -void defaultKeyboard(unsigned char key, int x, int y); -void clientKeyboard(unsigned char key, int x, int y); - -void defaultSpecialKeyboard(int key, int x, int y); -void clientSpecialKeyboard(int key, int x, int y); - -void clientMouseFunc(int button, int state, int x, int y); -void clientMotionFunc(int x,int y); #endif //GLUT_STUFF_H diff --git a/Demos/Raytracer/Raytracer.cpp b/Demos/Raytracer/Raytracer.cpp index 4179c637e..47a81a344 100644 --- a/Demos/Raytracer/Raytracer.cpp +++ b/Demos/Raytracer/Raytracer.cpp @@ -20,17 +20,8 @@ Very basic raytracer, rendering into a texture. #include "SimdQuaternion.h" #include "SimdTransform.h" #include "GL_ShapeDrawer.h" -#ifdef WIN32 //needed for glut.h -#include -#endif -//think different -#if defined(__APPLE__) && !defined (VMDMESA) -#include -#include -#include -#else -#include -#endif> + +#include "Raytracer.h" #include "GlutStuff.h" #include "NarrowPhaseCollision/VoronoiSimplexSolver.h" @@ -85,6 +76,17 @@ MinkowskiSumShape myMink(&myCylinder,&myBox); /// /// int main(int argc,char** argv) +{ + Raytracer* raytraceDemo = new Raytracer(); + + raytraceDemo->initPhysics(); + + raytraceDemo->setCameraDistance(6.f); + + return glutmain(argc, argv,screenWidth,screenHeight,"Minkowski-Sum Raytracer Demo",raytraceDemo); +} + +void Raytracer::initPhysics() { raytracePicture = new RenderTexture(screenWidth,screenHeight); @@ -110,38 +112,36 @@ int main(int argc,char** argv) }; SimdScalar radi[NUM_SPHERES] = { 0.35f,0.35f,0.45f,0.40f,0.40f }; - MultiSphereShape multiSphereShape(inertiaHalfExtents,positions,radi,NUM_SPHERES); - - ConvexHullShape convexHullShape(positions,3); + MultiSphereShape* multiSphereShape = new MultiSphereShape(inertiaHalfExtents,positions,radi,NUM_SPHERES); + ConvexHullShape* convexHullShape = new ConvexHullShape(positions,3); //choose shape shapePtr[0] = &myCone; shapePtr[1] =&simplex; - shapePtr[2] =&convexHullShape; - shapePtr[3] =&myMink;//myBox; + shapePtr[2] =convexHullShape; + shapePtr[3] =&myMink;//myBox;//multiSphereShape simplex.SetMargin(0.3f); - setCameraDistance(6.f); - return glutmain(argc, argv,screenWidth,screenHeight,"Minkowski-Sum Raytracer Demo"); } //to be implemented by the demo -void clientMoveAndDisplay() +void Raytracer::clientMoveAndDisplay() { - - clientDisplay(); + displayCallback(); } int once = 1; -extern float eye[3]; -void clientDisplay(void) + +void Raytracer::displayCallback() { + updateCamera(); + for (int i=0;i -#endif -//think different -#if defined(__APPLE__) && !defined (VMDMESA) -#include -#include -#include -#else -#include -#endif -#include "GlutStuff.h" - - #include "NarrowPhaseCollision/VoronoiSimplexSolver.h" +#include "SimplexDemo.h" +#include "GlutStuff.h" VoronoiSimplexSolver simplexSolver; @@ -61,34 +49,26 @@ PolyhedralConvexShape* shapePtr[maxNumObjects]; int main(int argc,char** argv) { - simplex.SetSimplexSolver(&simplexSolver); + SimplexDemo* demo = new SimplexDemo(); - simplex.AddVertex(SimdPoint3(-2,0,-2)); - simplex.AddVertex(SimdPoint3(2,0,-2)); - simplex.AddVertex(SimdPoint3(0,0,2)); - simplex.AddVertex(SimdPoint3(0,2,0)); - - shapePtr[0] = &simplex; - - SimdTransform tr; - tr.setIdentity(); - - return glutmain(argc, argv,screenWidth,screenHeight,"SimplexDemo"); + demo->initPhysics(); + + return glutmain(argc, argv,screenWidth,screenHeight,"SimplexDemo",demo); } //to be implemented by the demo -void clientMoveAndDisplay() +void SimplexDemo::clientMoveAndDisplay() { - clientDisplay(); + displayCallback(); } -void clientDisplay(void) { - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +void SimplexDemo::displayCallback() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDisable(GL_LIGHTING); GL_ShapeDrawer::DrawCoordSystem(); @@ -121,26 +101,18 @@ void clientDisplay(void) { glutSwapBuffers(); } -void clientResetScene() +void SimplexDemo::initPhysics() { -} + simplex.SetSimplexSolver(&simplexSolver); -void clientSpecialKeyboard(int key, int x, int y) -{ - defaultSpecialKeyboard(key,x,y); -} + simplex.AddVertex(SimdPoint3(-2,0,-2)); + simplex.AddVertex(SimdPoint3(2,0,-2)); + simplex.AddVertex(SimdPoint3(0,0,2)); + simplex.AddVertex(SimdPoint3(0,2,0)); -void clientKeyboard(unsigned char key, int x, int y) -{ - defaultKeyboard(key, x, y); -} + shapePtr[0] = &simplex; - -void clientMouseFunc(int button, int state, int x, int y) -{ - -} -void clientMotionFunc(int x,int y) -{ -} + SimdTransform tr; + tr.setIdentity(); +} \ No newline at end of file diff --git a/Demos/SimplexDemo/SimplexDemo.h b/Demos/SimplexDemo/SimplexDemo.h new file mode 100644 index 000000000..26ee00683 --- /dev/null +++ b/Demos/SimplexDemo/SimplexDemo.h @@ -0,0 +1,36 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef SIMPLEX_DEMO_H +#define SIMPLEX_DEMO_H + +#include "DemoApplication.h" + +///SimplexDemo shows the working of the sub-distance algorithm, used inside GJK +class SimplexDemo : public DemoApplication +{ + public: + + void initPhysics(); + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + virtual void clientResetScene() + { + } +}; + +#endif //SIMPLEX_DEMO_H \ No newline at end of file diff --git a/Demos/VehicleDemo/VehicleDemo.cpp b/Demos/VehicleDemo/VehicleDemo.cpp index c5cf0146c..4c18178e4 100644 --- a/Demos/VehicleDemo/VehicleDemo.cpp +++ b/Demos/VehicleDemo/VehicleDemo.cpp @@ -16,12 +16,9 @@ subject to the following restrictions: //Ignore this USE_PARALLEL_DISPATCHER define, it is for future optimizations //#define USE_PARALLEL_DISPATCHER 1 - /// September 2006: VehicleDemo is work in progress, this file is mostly just a placeholder /// This VehicleDemo file is very early in development, please check it later - - #include "CcdPhysicsEnvironment.h" #include "ParallelPhysicsEnvironment.h" @@ -59,65 +56,21 @@ subject to the following restrictions: #include "GLDebugDrawer.h" - - - #include "PHY_Pro.h" #include "BMF_Api.h" #include //printf debugging float deltaTime = 1.f/60.f; -float bulletSpeed = 40.f; -#ifdef WIN32 -#if _MSC_VER >= 1310 -//only use SIMD Hull code under Win32 -#define USE_HULL 1 -#include "NarrowPhaseCollision/Hull.h" -#endif //_MSC_VER -#endif //WIN32 - - -#ifdef WIN32 //needed for glut.h -#include -#endif - -//think different -#if defined(__APPLE__) && !defined (VMDMESA) -#include -#include -#include -#else -#include -#endif #include "GL_ShapeDrawer.h" #include "GlutStuff.h" - - -extern float eye[3]; -extern int glutScreenWidth; -extern int glutScreenHeight; +#include "VehicleDemo.h" const int maxProxies = 32766; const int maxOverlap = 65535; -bool createConstraint = true;//false; -bool useCompound = false;//true;//false; - - -#ifdef _DEBUG -const int numObjects = 2; -#else -const int numObjects = 2; -#endif -const int maxNumObjects = 32760; -DefaultMotionState ms[maxNumObjects]; -CcdPhysicsController* physObjects[maxNumObjects] = {0,0,0,0}; -int shapeIndex[maxNumObjects]; - - DefaultMotionState wheelMotionState[4]; @@ -126,74 +79,53 @@ DefaultMotionState wheelMotionState[4]; ///implementing explicit hinged-wheel constraints with cylinder collision, rather then raycasts PHY_IVehicle* gVehicleConstraint=0; float gEngineForce = 0.f; -float maxEngineForce = 1.f; +float maxEngineForce = 1000.f; float gVehicleSteering = 0.f; -float steeringIncrement = 0.1f; +float steeringIncrement = 0.1f; float steeringClamp = 0.3f; float wheelRadius = 0.5f; float wheelWidth = 0.2f; -float wheelFriction = 100.f; -float suspensionStiffness = 10.f; -float suspensionDamping = 1.3f; -float suspensionCompression = 2.4f; -float rollInfluence = 0.1f; +float wheelFriction = 100.f; +float suspensionStiffness = 10.f; +float suspensionDamping = 1.3f; +float suspensionCompression = 2.4f; +float rollInfluence = 0.1f; SimdVector3 wheelDirectionCS0(0,-1,0); SimdVector3 wheelAxleCS(1,0,0); SimdScalar suspensionRestLength(0.6); - - -#ifdef USE_PARALLEL_DISPATCHER -ParallelPhysicsEnvironment* physicsEnvironmentPtr = 0; -#else -CcdPhysicsEnvironment* physicsEnvironmentPtr = 0; -#endif - #define CUBE_HALF_EXTENTS 1 -#define EXTRA_HEIGHT -20.f -//GL_LineSegmentShape shapeE(SimdPoint3(-50,0,0), -// SimdPoint3(50,0,0)); -static const int numShapes = 4; - -CollisionShape* shapePtr[numShapes] = -{ - ///Please don't make the box sizes larger then 1000: the collision detection will be inaccurate. - ///See http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=346 - -//#define USE_GROUND_PLANE 1 -#ifdef USE_GROUND_PLANE - new StaticPlaneShape(SimdVector3(0,1,0),10), -#else - new BoxShape (SimdVector3(50,10,50)), -#endif - - new BoxShape (SimdVector3(CUBE_HALF_EXTENTS,0.5f*CUBE_HALF_EXTENTS,2.f*CUBE_HALF_EXTENTS)), - new SphereShape (CUBE_HALF_EXTENTS- 0.05f), - - //new ConeShape(CUBE_HALF_EXTENTS,2.f*CUBE_HALF_EXTENTS), - //new BU_Simplex1to4(SimdPoint3(-1,-1,-1),SimdPoint3(1,-1,-1),SimdPoint3(-1,1,-1),SimdPoint3(0,0,1)), - - //new EmptyShape(), - - new BoxShape (SimdVector3(0.4,1,0.8)) - -}; - //////////////////////////////////// - - - GLDebugDrawer debugDrawer; int main(int argc,char** argv) { + VehicleDemo* vehicleDemo = new VehicleDemo; + + vehicleDemo->setupPhysics(); + + return glutmain(argc, argv,640,480,"Bullet Vehicle Demo. http://www.continuousphysics.com/Bullet/phpBB2/", vehicleDemo); +} + +VehicleDemo::VehicleDemo() +: +m_carChassis(0), +m_cameraHeight(4.f), +m_minCameraDistance(3.f), +m_maxCameraDistance(10.f) +{ + m_cameraPosition = SimdVector3(30,30,30); +} + +void VehicleDemo::setupPhysics() +{ CollisionDispatcher* dispatcher = new CollisionDispatcher(); ParallelIslandDispatcher* dispatcher2 = new ParallelIslandDispatcher(); @@ -205,15 +137,19 @@ int main(int argc,char** argv) //OverlappingPairCache* broadphase = new SimpleBroadphase(maxProxies,maxOverlap); #ifdef USE_PARALLEL_DISPATCHER - physicsEnvironmentPtr = new ParallelPhysicsEnvironment(dispatcher2,broadphase); + m_physicsEnvironmentPtr = new ParallelPhysicsEnvironment(dispatcher2,broadphase); #else - physicsEnvironmentPtr = new CcdPhysicsEnvironment(dispatcher,broadphase); + m_physicsEnvironmentPtr = new CcdPhysicsEnvironment(dispatcher,broadphase); #endif - physicsEnvironmentPtr->setDeactivationTime(2.f); + m_physicsEnvironmentPtr->setDeactivationTime(2.f); - physicsEnvironmentPtr->setGravity(0,-10,0);//0,0);//-10,0); + m_physicsEnvironmentPtr->setDebugDrawer(&debugDrawer); + + m_physicsEnvironmentPtr->setGravity(0,-10,0);//0,0);//-10,0); int i; + CollisionShape* groundShape = new BoxShape(SimdVector3(50,3,50)); + #define USE_TRIMESH_GROUND 1 #ifdef USE_TRIMESH_GROUND @@ -263,208 +199,41 @@ const float TRIANGLE_SIZE=20.f; indexStride, totalVerts,(float*) &gVertices[0].x(),vertStride); - //shapePtr[4] = new TriangleMeshShape(indexVertexArrays); - shapePtr[0] = new BvhTriangleMeshShape(indexVertexArrays); - + groundShape = new BvhTriangleMeshShape(indexVertexArrays); #endif // - - - - PHY_ShapeProps shapeProps; - - shapeProps.m_do_anisotropic = false; - shapeProps.m_do_fh = false; - shapeProps.m_do_rot_fh = false; - shapeProps.m_friction_scaling[0] = 1.; - shapeProps.m_friction_scaling[1] = 1.; - shapeProps.m_friction_scaling[2] = 1.; - - shapeProps.m_inertia = 1.f; - shapeProps.m_lin_drag = 0.2f; - shapeProps.m_ang_drag = 0.1f; - shapeProps.m_mass = 800.0f; - - PHY_MaterialProps materialProps; - materialProps.m_friction = 10.5f; - materialProps.m_restitution = 0.0f; - - SimdTransform tr; tr.setIdentity(); + tr.setOrigin(SimdVector3(0,-20.f,0)); + + //create ground object + LocalCreatePhysicsObject(false,0,tr,groundShape); + + CollisionShape* chassisShape = new BoxShape(SimdVector3(1.f,0.5f,2.f)); + tr.setOrigin(SimdVector3(0,0.f,0)); + + m_carChassis = LocalCreatePhysicsObject(true,800,tr,chassisShape); - for (i=0;i0) - { - shapeIndex[i] = 1;//sphere - } - else - shapeIndex[i] = 0; - } - - if (useCompound) - { - CompoundShape* compoundShape = new CompoundShape(); - CollisionShape* oldShape = shapePtr[1]; - shapePtr[1] = compoundShape; - - SimdTransform ident; - ident.setIdentity(); - ident.setOrigin(SimdVector3(0,0,0)); - compoundShape->AddChildShape(ident,oldShape);// - ident.setOrigin(SimdVector3(0,1,-1)); - compoundShape->AddChildShape(ident,new SphereShape(0.9));// - } - - for (i=0;iSetMargin(0.05f); - - - - bool isDyna = i>0; - //if (i==1) - // isDyna=false; - - if (0)//i==1) - { - SimdQuaternion orn(0,0,0.1*SIMD_HALF_PI); - ms[i].setWorldOrientation(orn.x(),orn.y(),orn.z(),orn[3]); - } - - - if (i>0) - { - - switch (i) - { - case 1: - { - ms[i].setWorldPosition(0,10,0); - //for testing, rotate the ground cube so the stack has to recover a bit - - break; - } - case 2: - { - ms[i].setWorldPosition(0,8,2); - break; - } - default: - ms[i].setWorldPosition(0,i*CUBE_HALF_EXTENTS*2 - CUBE_HALF_EXTENTS,0); - } - - float quatIma0,quatIma1,quatIma2,quatReal; - SimdQuaternion quat; - SimdVector3 axis(0,0,1); - SimdScalar angle=0.5f; - - quat.setRotation(axis,angle); - - ms[i].setWorldOrientation(quat.getX(),quat.getY(),quat.getZ(),quat[3]); - - - - } else - { - ms[i].setWorldPosition(0,-10+EXTRA_HEIGHT,0); - - } - - ccdObjectCi.m_MotionState = &ms[i]; - ccdObjectCi.m_gravity = SimdVector3(0,0,0); - ccdObjectCi.m_localInertiaTensor =SimdVector3(0,0,0); - if (!isDyna) - { - shapeProps.m_mass = 0.f; - ccdObjectCi.m_mass = shapeProps.m_mass; - ccdObjectCi.m_collisionFlags = CollisionObject::isStatic; - - ccdObjectCi.m_collisionFilterGroup = CcdConstructionInfo::StaticFilter; - ccdObjectCi.m_collisionFilterMask = CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::StaticFilter; - } - else - { - shapeProps.m_mass = 1.f; - ccdObjectCi.m_mass = shapeProps.m_mass; - ccdObjectCi.m_collisionFlags = 0; - - } - - - SimdVector3 localInertia(0.f,0.f,0.f); - if (shapeIndex[i]) - { - if (shapePtr[shapeIndex[i]]->GetShapeType() == EMPTY_SHAPE_PROXYTYPE) - { - //take inertia from first shape - shapePtr[1]->CalculateLocalInertia(shapeProps.m_mass,localInertia); - } else - { - shapePtr[shapeIndex[i]]->CalculateLocalInertia(shapeProps.m_mass,localInertia); - } - - } - ccdObjectCi.m_localInertiaTensor = localInertia; - - ccdObjectCi.m_collisionShape = shapePtr[shapeIndex[i]]; - - - physObjects[i]= new CcdPhysicsController( ccdObjectCi); - - // Only do CCD if motion in one timestep (1.f/60.f) exceeds CUBE_HALF_EXTENTS - physObjects[i]->GetRigidBody()->m_ccdSquareMotionTreshold = CUBE_HALF_EXTENTS; - - //Experimental: better estimation of CCD Time of Impact: - physObjects[i]->GetRigidBody()->m_ccdSweptShereRadius = 0.2*CUBE_HALF_EXTENTS; - - physicsEnvironmentPtr->addCcdPhysicsController( physObjects[i]); - - if (i==1) - { - //physObjects[i]->SetAngularVelocity(0,0,-2,true); - } - - physicsEnvironmentPtr->setDebugDrawer(&debugDrawer); - - } - - clientResetScene(); - physicsEnvironmentPtr->SyncMotionStates(0.f); - if (createConstraint) + m_physicsEnvironmentPtr->SyncMotionStates(0.f); + + /// create vehicle { - //physObjects[i]->SetAngularVelocity(0,0,-2,true); int constraintId; - float pivotX=CUBE_HALF_EXTENTS, - pivotY=CUBE_HALF_EXTENTS, - pivotZ=CUBE_HALF_EXTENTS; - float axisX=0,axisY=1,axisZ=0; - - - constraintId =physicsEnvironmentPtr->createConstraint( - physObjects[1],0, + constraintId =m_physicsEnvironmentPtr->createConstraint( + m_carChassis,0, PHY_VEHICLE_CONSTRAINT, 0,0,0, 0,0,0); ///never deactivate the vehicle - physObjects[1]->GetRigidBody()->SetActivationState(DISABLE_DEACTIVATION); + m_carChassis->GetRigidBody()->SetActivationState(DISABLE_DEACTIVATION); - gVehicleConstraint = physicsEnvironmentPtr->getVehicleConstraint(constraintId); + gVehicleConstraint = m_physicsEnvironmentPtr->getVehicleConstraint(constraintId); SimdVector3 connectionPointCS0(CUBE_HALF_EXTENTS-(0.3*wheelWidth),0,2*CUBE_HALF_EXTENTS-wheelRadius); RaycastVehicle::VehicleTuning tuning; @@ -518,21 +287,19 @@ const float TRIANGLE_SIZE=20.f; gVehicleConstraint->SetWheelFriction(wheelFriction,3); - - - } setCameraDistance(26.f); - return glutmain(argc, argv,640,480,"Bullet Vehicle Demo. http://www.continuousphysics.com/Bullet/phpBB2/"); } //to be implemented by the demo -void renderme() +void VehicleDemo::renderme() { + updateCamera(); + debugDrawer.SetDebugMode(getDebugMode()); float m[16]; int i; @@ -545,270 +312,13 @@ void renderme() //draw wheels (cylinders) wheelMotionState[i].m_worldTransform.getOpenGLMatrix(m); GL_ShapeDrawer::DrawOpenGL(m,&wheelShape,wheelColor,getDebugMode()); - // debugDrawer.DrawLine(from,from+dirWorldA,color); - // debugDrawer.DrawLine(fromB,fromB+dirWorldB,color); } - - - - if (getDebugMode() & IDebugDraw::DBG_DisableBulletLCP) - { - //don't use Bullet, use quickstep - physicsEnvironmentPtr->setSolverType(0); - } else - { - //Bullet LCP solver - physicsEnvironmentPtr->setSolverType(1); - } - - if (getDebugMode() & IDebugDraw::DBG_EnableCCD) - { - physicsEnvironmentPtr->setCcdMode(3); - } else - { - physicsEnvironmentPtr->setCcdMode(0); - } - - - bool isSatEnabled = (getDebugMode() & IDebugDraw::DBG_EnableSatComparison); - - physicsEnvironmentPtr->EnableSatCollisionDetection(isSatEnabled); - - -#ifdef USE_HULL - //some testing code for SAT - if (isSatEnabled) - { - for (int s=0;sIsPolyhedral()) - { - PolyhedralConvexShape* polyhedron = static_cast(shape); - if (!polyhedron->m_optionalHull) - { - //first convert vertices in 'Point3' format - int numPoints = polyhedron->GetNumVertices(); - Point3* points = new Point3[numPoints+1]; - //first 4 points should not be co-planar, so add central point to satisfy MakeHull - points[0] = Point3(0.f,0.f,0.f); - - SimdVector3 vertex; - for (int p=0;pGetVertex(p,vertex); - points[p+1] = Point3(vertex.getX(),vertex.getY(),vertex.getZ()); - } - - Hull* hull = Hull::MakeHull(numPoints+1,points); - polyhedron->m_optionalHull = hull; - } - - } - } - - } -#endif //USE_HULL - - - for (i=0;iGetRigidBody()->GetActivationState() == 1) //active - { - if (i & 1) - { - wireColor += SimdVector3 (1.f,0.f,0.f); - } else - { - wireColor += SimdVector3 (.5f,0.f,0.f); - } - } - if (physObjects[i]->GetRigidBody()->GetActivationState() == 2) //ISLAND_SLEEPING - { - if (i & 1) - { - wireColor += SimdVector3 (0.f,1.f, 0.f); - } else - { - wireColor += SimdVector3 (0.f,0.5f,0.f); - } - } - - char extraDebug[125]; - sprintf(extraDebug,"islId, Body=%i , %i",physObjects[i]->GetRigidBody()->m_islandTag1,physObjects[i]->GetRigidBody()->m_debugBodyId); - physObjects[i]->GetRigidBody()->GetCollisionShape()->SetExtraDebugInfo(extraDebug); - - float vec[16]; - SimdTransform ident; - ident.setIdentity(); - ident.getOpenGLMatrix(vec); - //glPushMatrix(); - - //glLoadMatrixf(vec); - - GL_ShapeDrawer::DrawOpenGL(m,physObjects[i]->GetRigidBody()->GetCollisionShape(),wireColor,getDebugMode()); - - //glPopMatrix(); - - ///this block is just experimental code to show some internal issues with replacing shapes on the fly. - if (getDebugMode()!=0 && (i>0)) - { - if (physObjects[i]->GetRigidBody()->GetCollisionShape()->GetShapeType() == EMPTY_SHAPE_PROXYTYPE) - { - physObjects[i]->GetRigidBody()->SetCollisionShape(shapePtr[1]); - - //remove the persistent collision pairs that were created based on the previous shape - - BroadphaseProxy* bpproxy = physObjects[i]->GetRigidBody()->m_broadphaseHandle; - - physicsEnvironmentPtr->GetBroadphase()->CleanProxyFromPairs(bpproxy); - - SimdVector3 newinertia; - SimdScalar newmass = 10.f; - physObjects[i]->GetRigidBody()->GetCollisionShape()->CalculateLocalInertia(newmass,newinertia); - physObjects[i]->GetRigidBody()->setMassProps(newmass,newinertia); - physObjects[i]->GetRigidBody()->updateInertiaTensor(); - - } - - } - - - } - - if (!(getDebugMode() & IDebugDraw::DBG_NoHelpText)) - { - - float xOffset = 10.f; - float yStart = 20.f; - - float yIncr = -2.f; - - char buf[124]; - - glColor3f(0, 0, 0); - -#ifdef USE_QUICKPROF - - - if ( getDebugMode() & IDebugDraw::DBG_ProfileTimings) - { - static int counter = 0; - counter++; - std::map::iterator iter; - for (iter = Profiler::mProfileBlocks.begin(); iter != Profiler::mProfileBlocks.end(); ++iter) - { - char blockTime[128]; - sprintf(blockTime, "%s: %lf",&((*iter).first[0]),Profiler::getBlockTime((*iter).first, Profiler::BLOCK_CYCLE_SECONDS));//BLOCK_TOTAL_PERCENT)); - glRasterPos3f(xOffset,yStart,0); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),blockTime); - yStart += yIncr; - - } - } -#endif //USE_QUICKPROF - //profiling << Profiler::createStatsString(Profiler::BLOCK_TOTAL_PERCENT); - //<< std::endl; - - - - glRasterPos3f(xOffset,yStart,0); - sprintf(buf,"mouse to interact"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - glRasterPos3f(xOffset,yStart,0); - sprintf(buf,"space to reset"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - glRasterPos3f(xOffset,yStart,0); - sprintf(buf,"cursor keys and z,x to navigate"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - glRasterPos3f(xOffset,yStart,0); - sprintf(buf,"i to toggle simulation, s single step"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - glRasterPos3f(xOffset,yStart,0); - sprintf(buf,"q to quit"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - glRasterPos3f(xOffset,yStart,0); - sprintf(buf,"d to toggle deactivation"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - glRasterPos3f(xOffset,yStart,0); - sprintf(buf,"a to draw temporal AABBs"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - - glRasterPos3f(xOffset,yStart,0); - sprintf(buf,"h to toggle help text"); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - bool useBulletLCP = !(getDebugMode() & IDebugDraw::DBG_DisableBulletLCP); - - bool useCCD = (getDebugMode() & IDebugDraw::DBG_EnableCCD); - - glRasterPos3f(xOffset,yStart,0); - sprintf(buf,"m Bullet GJK = %i",!isSatEnabled); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - glRasterPos3f(xOffset,yStart,0); - sprintf(buf,"n Bullet LCP = %i",useBulletLCP); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - glRasterPos3f(xOffset,yStart,0); - sprintf(buf,"1 CCD mode (adhoc) = %i",useCCD); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - glRasterPos3f(xOffset,yStart,0); - sprintf(buf,"+- shooting speed = %10.2f",bulletSpeed); - BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); - yStart += yIncr; - - } + DemoApplication::renderme(); } -void clientMoveAndDisplay() +void VehicleDemo::clientMoveAndDisplay() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -826,7 +336,7 @@ void clientMoveAndDisplay() } - physicsEnvironmentPtr->proceedDeltaTime(0.f,deltaTime); + m_physicsEnvironmentPtr->proceedDeltaTime(0.f,deltaTime); @@ -848,14 +358,15 @@ void clientMoveAndDisplay() -void clientDisplay(void) { +void VehicleDemo::displayCallback(void) +{ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - physicsEnvironmentPtr->UpdateAabbs(deltaTime); + m_physicsEnvironmentPtr->UpdateAabbs(deltaTime); //draw contactpoints - physicsEnvironmentPtr->CallbackTriggers(); + m_physicsEnvironmentPtr->CallbackTriggers(); renderme(); @@ -867,75 +378,17 @@ void clientDisplay(void) { -///make this positive to show stack falling from a distance -///this shows the penalty tresholds in action, springy/spungy look - -void clientResetScene() +void VehicleDemo::clientResetScene() { - gEngineForce = 0.f; gVehicleSteering = 0.f; - - int i; - for (i=0;i0) - { - - if ((getDebugMode() & IDebugDraw::DBG_NoHelpText)) - { - if (physObjects[i]->GetRigidBody()->GetCollisionShape()->GetShapeType() == BOX_SHAPE_PROXYTYPE) - { - physObjects[i]->GetRigidBody()->SetCollisionShape(shapePtr[2]); - } else - { - physObjects[i]->GetRigidBody()->SetCollisionShape(shapePtr[1]); - } - - BroadphaseProxy* bpproxy = physObjects[i]->GetRigidBody()->m_broadphaseHandle; - physicsEnvironmentPtr->GetBroadphase()->CleanProxyFromPairs(bpproxy); - } - - //stack them - int colsize = 10; - int row = (i*CUBE_HALF_EXTENTS*2)/(colsize*2*CUBE_HALF_EXTENTS); - int row2 = row; - int col = (i)%(colsize)-colsize/2; - - - if (col>3) - { - col=11; - row2 |=1; - } - physObjects[i]->setPosition(col*2*CUBE_HALF_EXTENTS + (row2%2)*CUBE_HALF_EXTENTS, - row*2*CUBE_HALF_EXTENTS+CUBE_HALF_EXTENTS+EXTRA_HEIGHT,0); - physObjects[i]->setOrientation(0,0,0,1); - physObjects[i]->SetLinearVelocity(0,0,0,false); - physObjects[i]->SetAngularVelocity(0,0,0,false); - } - } + m_carChassis->setPosition(0,0,0); + m_carChassis->setOrientation(0,0,0,1); } -void shootBox(const SimdVector3& destination) -{ - int i = numObjects-1; - - - - SimdVector3 linVel(destination[0]-eye[0],destination[1]-eye[1],destination[2]-eye[2]); - linVel.normalize(); - linVel*=bulletSpeed; - - physObjects[i]->setPosition(eye[0],eye[1],eye[2]); - physObjects[i]->setOrientation(0,0,0,1); - physObjects[i]->SetLinearVelocity(linVel[0],linVel[1],linVel[2],false); - physObjects[i]->SetAngularVelocity(0,0,0,false); -} - -void clientSpecialKeyboard(int key, int x, int y) +void VehicleDemo::specialKeyboard(int key, int x, int y) { printf("key = %i x=%i y=%i\n",key,x,y); @@ -968,7 +421,7 @@ void clientSpecialKeyboard(int key, int x, int y) break; } default: - defaultSpecialKeyboard(key,x,y); + DemoApplication::specialKeyboard(key,x,y); break; } @@ -976,218 +429,42 @@ void clientSpecialKeyboard(int key, int x, int y) } -void clientKeyboard(unsigned char key, int x, int y) + + +void VehicleDemo::updateCamera() { + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); - if (key == '.') + //look at the vehicle + m_cameraTargetPosition = m_carChassis->GetRigidBody()->m_worldTransform.getOrigin(); + + //interpolate the camera height + m_cameraPosition[1] = (15.0*m_cameraPosition[1] + m_cameraTargetPosition[1] + m_cameraHeight)/16.0; + + SimdVector3 camToObject = m_cameraTargetPosition - m_cameraPosition; + + //keep distance between min and max distance + float cameraDistance = camToObject.length(); + float correctionFactor = 0.f; + if (cameraDistance < m_minCameraDistance) { - shootBox(SimdVector3(0,0,0)); + correctionFactor = 0.15*(m_minCameraDistance-cameraDistance)/cameraDistance; } - - if (key == '+') + if (cameraDistance > m_maxCameraDistance) { - bulletSpeed += 10.f; - } - if (key == '-') - { - bulletSpeed -= 10.f; + correctionFactor = 0.15*(m_maxCameraDistance-cameraDistance)/cameraDistance; } + m_cameraPosition -= correctionFactor*camToObject; + + //update OpenGL camera settings + glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 10000.0); - defaultKeyboard(key, x, y); -} - -int gPickingConstraintId = 0; -SimdVector3 gOldPickingPos; -float gOldPickingDist = 0.f; -RigidBody* pickedBody = 0;//for deactivation state - - -SimdVector3 GetRayTo(int x,int y) -{ - float top = 1.f; - float bottom = -1.f; - float nearPlane = 1.f; - float tanFov = (top-bottom)*0.5f / nearPlane; - float fov = 2.0 * atanf (tanFov); - - SimdVector3 rayFrom(eye[0],eye[1],eye[2]); - SimdVector3 rayForward = -rayFrom; - rayForward.normalize(); - float farPlane = 600.f; - rayForward*= farPlane; - - SimdVector3 rightOffset; - SimdVector3 vertical(0.f,1.f,0.f); - SimdVector3 hor; - hor = rayForward.cross(vertical); - hor.normalize(); - vertical = hor.cross(rayForward); - vertical.normalize(); - - float tanfov = tanf(0.5f*fov); - hor *= 2.f * farPlane * tanfov; - vertical *= 2.f * farPlane * tanfov; - SimdVector3 rayToCenter = rayFrom + rayForward; - SimdVector3 dHor = hor * 1.f/float(glutScreenWidth); - SimdVector3 dVert = vertical * 1.f/float(glutScreenHeight); - SimdVector3 rayTo = rayToCenter - 0.5f * hor + 0.5f * vertical; - rayTo += x * dHor; - rayTo -= y * dVert; - return rayTo; -} -void clientMouseFunc(int button, int state, int x, int y) -{ - //printf("button %i, state %i, x=%i,y=%i\n",button,state,x,y); - //button 0, state 0 means left mouse down - - SimdVector3 rayTo = GetRayTo(x,y); - - switch (button) - { - case 2: - { - if (state==0) - { - shootBox(rayTo); - } - break; - }; - case 1: - { - if (state==0) - { - //apply an impulse - if (physicsEnvironmentPtr) - { - float hit[3]; - float normal[3]; - PHY_IPhysicsController* hitObj = physicsEnvironmentPtr->rayTest(0,eye[0],eye[1],eye[2],rayTo.getX(),rayTo.getY(),rayTo.getZ(),hit[0],hit[1],hit[2],normal[0],normal[1],normal[2]); - if (hitObj) - { - CcdPhysicsController* physCtrl = static_cast(hitObj); - RigidBody* body = physCtrl->GetRigidBody(); - if (body) - { - body->SetActivationState(ACTIVE_TAG); - SimdVector3 impulse = rayTo; - impulse.normalize(); - float impulseStrength = 10.f; - impulse *= impulseStrength; - SimdVector3 relPos( - hit[0] - body->getCenterOfMassPosition().getX(), - hit[1] - body->getCenterOfMassPosition().getY(), - hit[2] - body->getCenterOfMassPosition().getZ()); - - body->applyImpulse(impulse,relPos); - } - - } - - } - - } else - { - - } - break; - } - case 0: - { - if (state==0) - { - //add a point to point constraint for picking - if (physicsEnvironmentPtr) - { - float hit[3]; - float normal[3]; - PHY_IPhysicsController* hitObj = physicsEnvironmentPtr->rayTest(0,eye[0],eye[1],eye[2],rayTo.getX(),rayTo.getY(),rayTo.getZ(),hit[0],hit[1],hit[2],normal[0],normal[1],normal[2]); - if (hitObj) - { - - CcdPhysicsController* physCtrl = static_cast(hitObj); - RigidBody* body = physCtrl->GetRigidBody(); - - if (body && !body->IsStatic()) - { - pickedBody = body; - pickedBody->SetActivationState(DISABLE_DEACTIVATION); - - SimdVector3 pickPos(hit[0],hit[1],hit[2]); - - SimdVector3 localPivot = body->getCenterOfMassTransform().inverse() * pickPos; - - gPickingConstraintId = physicsEnvironmentPtr->createConstraint(physCtrl,0,PHY_POINT2POINT_CONSTRAINT, - localPivot.getX(), - localPivot.getY(), - localPivot.getZ(), - 0,0,0); - //printf("created constraint %i",gPickingConstraintId); - - //save mouse position for dragging - gOldPickingPos = rayTo; - - - SimdVector3 eyePos(eye[0],eye[1],eye[2]); - - gOldPickingDist = (pickPos-eyePos).length(); - - Point2PointConstraint* p2p = static_cast(physicsEnvironmentPtr->getConstraintById(gPickingConstraintId)); - if (p2p) - { - //very weak constraint for picking - p2p->m_setting.m_tau = 0.1f; - } - } - } - } - } else - { - if (gPickingConstraintId && physicsEnvironmentPtr) - { - physicsEnvironmentPtr->removeConstraint(gPickingConstraintId); - //printf("removed constraint %i",gPickingConstraintId); - gPickingConstraintId = 0; - pickedBody->ForceActivationState(ACTIVE_TAG); - pickedBody->m_deactivationTime = 0.f; - pickedBody = 0; - - - } - } - - break; - - } - default: - { - } - } + gluLookAt(m_cameraPosition[0],m_cameraPosition[1],m_cameraPosition[2], + m_cameraTargetPosition[0],m_cameraTargetPosition[1], m_cameraTargetPosition[2], + m_cameraUp.getX(),m_cameraUp.getY(),m_cameraUp.getZ()); + glMatrixMode(GL_MODELVIEW); } -void clientMotionFunc(int x,int y) -{ - - if (gPickingConstraintId && physicsEnvironmentPtr) - { - - //move the constraint pivot - - Point2PointConstraint* p2p = static_cast(physicsEnvironmentPtr->getConstraintById(gPickingConstraintId)); - if (p2p) - { - //keep it at the same picking distance - - SimdVector3 newRayTo = GetRayTo(x,y); - SimdVector3 eyePos(eye[0],eye[1],eye[2]); - SimdVector3 dir = newRayTo-eyePos; - dir.normalize(); - dir *= gOldPickingDist; - - SimdVector3 newPos = eyePos + dir; - p2p->SetPivotB(newPos); - } - - } -} diff --git a/Demos/VehicleDemo/VehicleDemo.h b/Demos/VehicleDemo/VehicleDemo.h new file mode 100644 index 000000000..0a51ffa86 --- /dev/null +++ b/Demos/VehicleDemo/VehicleDemo.h @@ -0,0 +1,51 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef VEHICLE_DEMO_H +#define VEHICLE_DEMO_H + +#include "DemoApplication.h" + +///VehicleDemo shows how to setup and use the built-in raycast vehicle +class VehicleDemo : public DemoApplication +{ + public: + + CcdPhysicsController* m_carChassis; + + float m_cameraHeight; + + float m_minCameraDistance; + float m_maxCameraDistance; + + + VehicleDemo(); + + virtual void clientMoveAndDisplay(); + + virtual void clientResetScene(); + + virtual void displayCallback(); + + ///a very basic camera following the vehicle + virtual void updateCamera(); + + virtual void specialKeyboard(int key, int x, int y); + + void renderme(); + + void setupPhysics(); +}; + +#endif //VEHICLE_DEMO_H \ No newline at end of file