Triangles.cpp

Go to the documentation of this file.
00001 /*
00002  * Triangles.cpp
00003  *
00004  * Copyright (C) 2009  Thomas A. Vaughan
00005  * All rights reserved.
00006  *
00007  * Quick demo to test loading of triangle meshes.
00008  */
00009 
00010 #include "physics-demo/physics-demo.h"
00011 
00012 #include <fstream>
00013 
00014 #include "DemoApplication.h"
00015 #include "GLDebugDrawer.h"              // bullet demo file
00016 
00017 #include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h"
00018 #include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h"
00019 
00020 #include "common/wave_ex.h"
00021 #include "geometry/geometry_3d.h"
00022 #include "threadsafe/smart_ptr.h"
00023 #include "trimesh/trimesh.h"
00024 #include "util/token_stream.h"
00025 
00026 
00027 
00028 static void
00029 dumpVector
00030 (
00031 IN const btVector3& v,
00032 IN const char * title
00033 )
00034 throw()
00035 {
00036         ASSERT(title, "null");
00037 
00038         DPRINTF("%s: (%f, %f, %f)", title, v.x(), v.y(), v.z());
00039 }
00040 
00041 
00042 
00043 ////////////////////////////////////////////////////////////////////////////////
00044 //
00045 //      Triangles class -- Demo class for triangle mesh functionality
00046 //
00047 ////////////////////////////////////////////////////////////////////////////////
00048 
00049 class Triangles : public DemoApplication {
00050 public:
00051         // DemoApplication class interface methods -----------------------------
00052         virtual void clientMoveAndDisplay();
00053         virtual void displayCallback();
00054         virtual void keyboardCallback(unsigned char key, int x, int y);
00055         virtual void initPhysics(void) {}
00056 
00057         // static factory methods ----------------------------------------------        
00058         static DemoApplication * create(IN const char * filename) {
00059                         ASSERT(filename, "null");
00060                         Triangles * tri = new Triangles();
00061                         ASSERT(tri, "out of memory");
00062                         tri->initialize(filename);
00063                         return tri;
00064                 }
00065 
00066 private:
00067         // private helper methods ----------------------------------------------
00068         void initialize(IN const char * filename);
00069 
00070         // private member data -------------------------------------------------
00071         btAlignedObjectArray<btCollisionShape*> m_collisionShapes;
00072         smart_ptr<btTriangleIndexVertexArray>   m_indexVertexArrays;
00073         smart_ptr<btBroadphaseInterface>        m_broadphase;
00074         smart_ptr<btCollisionDispatcher>        m_dispatcher;
00075         smart_ptr<btConstraintSolver>           m_solver;
00076         smart_ptr<btDefaultCollisionConfiguration> m_collisionConfiguration;
00077         smart_ptr<GLDebugDrawer>                m_debugDrawer;
00078         smart_ptr<trimesh::Trimesh>             m_trimesh;
00079 };
00080 
00081 void Triangles::keyboardCallback(unsigned char key, int x, int y)
00082 {
00083     DemoApplication::keyboardCallback(key,x,y);
00084 
00085 }
00086 
00087 void
00088 Triangles::initialize
00089 (
00090 IN const char * filename
00091 )
00092 {
00093         ASSERT(filename, "null");
00094 
00095         // get the data
00096         m_trimesh = trimesh::Trimesh::load(filename);
00097         ASSERT(m_trimesh, "failed to create triangle mesh object");
00098 
00099         // set up the world
00100         m_collisionConfiguration = new btDefaultCollisionConfiguration();
00101         m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
00102         btVector3 worldMin(-1000,-1000,-1000);
00103         btVector3 worldMax(1000,1000,1000);
00104         m_broadphase = new btAxisSweep3(worldMin,worldMax);
00105         m_solver = new btSequentialImpulseConstraintSolver();
00106         m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration);
00107 
00108         // Create the array structure
00109         int triangleStride = 3 * sizeof(int);
00110         int vertexStride = sizeof(point3d_t);
00111         m_indexVertexArrays = new btTriangleIndexVertexArray(
00112             m_trimesh->getTriangleCount(), (int *) m_trimesh->getTriangleArray(), triangleStride,
00113             m_trimesh->getVertexCount(), (btScalar *) m_trimesh->getVertexArray(), vertexStride);
00114         ASSERT(m_indexVertexArrays, "out of memory");
00115 
00116         // Create the triangle mesh shape
00117         btBvhTriangleMeshShape * mesh = new btBvhTriangleMeshShape(m_indexVertexArrays, true);
00118         ASSERT(mesh, "out of memory");
00119 
00120         m_collisionShapes.push_back(mesh);
00121 
00122         btCollisionShape * groundShape = mesh;
00123 
00124         // add to world
00125         btTransform T;
00126         T.setIdentity();
00127         btRigidBody * ground = this->localCreateRigidBody(0.0, T, groundShape);
00128         ASSERT(ground, "null");
00129 
00130         // debug
00131         float invmass = ground->getInvMass();
00132         DPRINTF("Inverse mass: %f", invmass);
00133         btVector3 v = ground->getCenterOfMassPosition();
00134         dumpVector(v, "center of mass");
00135         btVector3 min, max;
00136         ground->getAabb(min, max);
00137         DPRINTF("AABB: (%f, %f, %f) - (%f, %f, %f)",
00138             min.x(), min.y(), min.z(), max.x(), max.y(), max.z());
00139         DPRINTF("ground %s in world", ground->isInWorld() ? "is" : "is NOT");
00140 
00141         // set up debug drawing
00142         m_debugDrawer = new GLDebugDrawer;
00143         ASSERT(m_debugDrawer, "null");
00144         this->getDynamicsWorld()->setDebugDrawer(m_debugDrawer);
00145 }
00146 
00147 
00148 
00149 void Triangles::clientMoveAndDisplay()
00150 {
00151     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
00152 
00153     float dt = getDeltaTimeMicroseconds() * 0.000001f;
00154 
00155     m_dynamicsWorld->stepSimulation(dt);
00156 
00157     //optional but useful: debug drawing
00158     m_dynamicsWorld->debugDrawWorld();
00159 
00160     renderme();
00161 
00162     glFlush();
00163     glutSwapBuffers();
00164 }
00165 
00166 
00167 
00168 
00169 void Triangles::displayCallback(void) {
00170 
00171     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
00172 
00173     renderme();
00174 
00175     glFlush();
00176     glutSwapBuffers();
00177 }
00178 
00179 
00180 
00181 ////////////////////////////////////////////////////////////////////////////////
00182 //
00183 //      entry point
00184 //
00185 ////////////////////////////////////////////////////////////////////////////////
00186 
00187 int
00188 main
00189 (
00190 IN int argc,
00191 IN char ** argv
00192 )
00193 {
00194         ASSERT(2 == argc, "usage: physics-demo-Triangles <data-file>");
00195         const char * filename = argv[1];
00196 
00197         DemoApplication * demo = Triangles::create(filename);
00198         ASSERT(demo, "null");
00199 
00200         return glutmain(argc, argv, 640, 480, "Triangles Demo", demo);
00201 }
00202