00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "DemoApplication.h"
00017 #include "LinearMath/btAlignedObjectArray.h"
00018
00019 class btBroadphaseInterface;
00020 class btCollisionShape;
00021 class btOverlappingPairCache;
00022 class btCollisionDispatcher;
00023 class btConstraintSolver;
00024 struct btCollisionAlgorithmCreateFunc;
00025 class btDefaultCollisionConfiguration;
00026 class btTriangleIndexVertexArray;
00027
00030 class MultiMaterialDemo : public DemoApplication
00031 {
00032
00033
00034 btAlignedObjectArray<btCollisionShape*> m_collisionShapes;
00035
00036 btTriangleIndexVertexArray* m_indexVertexArrays;
00037
00038 btBroadphaseInterface* m_broadphase;
00039
00040 btCollisionDispatcher* m_dispatcher;
00041
00042 btConstraintSolver* m_solver;
00043
00044 btDefaultCollisionConfiguration* m_collisionConfiguration;
00045
00046 bool m_animatedMesh;
00047
00048 public:
00049
00050 MultiMaterialDemo() : m_animatedMesh(true)
00051 {
00052
00053 }
00054 void initPhysics();
00055
00056 void exitPhysics();
00057
00058 virtual ~MultiMaterialDemo()
00059 {
00060 exitPhysics();
00061 }
00062
00063 virtual void clientMoveAndDisplay();
00064
00065 virtual void displayCallback();
00066
00067
00068 void setVertexPositions(float waveheight, float offset);
00069
00070 virtual void keyboardCallback(unsigned char key, int x, int y);
00071
00072 static DemoApplication* Create()
00073 {
00074 MultiMaterialDemo* demo = new MultiMaterialDemo();
00075 demo->myinit();
00076 demo->initPhysics();
00077 return demo;
00078 };
00079 };
00080
00081 #include "btBulletDynamicsCommon.h"
00082 #include "LinearMath/btIDebugDraw.h"
00083 #include "GLDebugDrawer.h"
00084 #include "GL_ShapeDrawer.h"
00085 #include "GlutStuff.h"
00086
00087 #include "BulletCollision/CollisionShapes/btTriangleShape.h"
00088 #include "BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.h"
00089 #include "BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h"
00090 #include "BulletCollision/CollisionShapes/btMaterial.h"
00091
00092
00093 class CustomMaterial : public btMaterial
00094 {
00095 public:
00096 int foo1;
00097 int foo2;
00098 CustomMaterial(){}
00099 CustomMaterial(int a, int b) {foo1 = a; foo2 = b;}
00100 };
00101
00102
00103 static btVector3* gVertices = 0;
00104
00105 static int* gIndices = 0;
00106
00107 static CustomMaterial* gMaterials = 0;
00108
00109 static int* gFaceMaterialIndices = 0;
00110
00111 static btBvhTriangleMeshShape* trimeshShape =0;
00112 static btRigidBody* staticBody = 0;
00113 static float waveheight = 0.5;
00114
00115 const float TRIANGLE_SIZE=1.f;
00116
00117
00119 inline btScalar calculateCombinedFriction(float friction0,float friction1)
00120 {
00121 btScalar friction = friction0 * friction1;
00122
00123 const btScalar MAX_FRICTION = 10.f;
00124 if (friction < -MAX_FRICTION)
00125 friction = -MAX_FRICTION;
00126 if (friction > MAX_FRICTION)
00127 friction = MAX_FRICTION;
00128 return friction;
00129
00130 }
00131
00132 inline btScalar calculateCombinedRestitution(float restitution0,float restitution1)
00133 {
00134 return restitution0 * restitution1;
00135 }
00136
00137
00138
00139 static bool CustomMaterialCombinerCallback(btManifoldPoint& cp, const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1)
00140 {
00141
00142
00143 if (colObj0->getCollisionShape()->getShapeType() == TRIANGLE_SHAPE_PROXYTYPE)
00144 {
00145 const btCollisionShape* parent0 = colObj0->getRootCollisionShape();
00146 if(parent0 != 0 && parent0->getShapeType() == MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE)
00147 {
00148 btMultimaterialTriangleMeshShape* shape = (btMultimaterialTriangleMeshShape*)parent0;
00149 const btMaterial * props = shape->getMaterialProperties(partId0, index0);
00150 cp.m_combinedFriction = calculateCombinedFriction(props->m_friction, colObj1->getFriction());
00151 cp.m_combinedRestitution = props->m_restitution * colObj1->getRestitution();
00152 }
00153 }
00154 else if (colObj1->getCollisionShape()->getShapeType() == TRIANGLE_SHAPE_PROXYTYPE)
00155 {
00156 const btCollisionShape* parent1 = colObj1->getRootCollisionShape();
00157 if(parent1 != 0 && parent1->getShapeType() == MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE)
00158 {
00159 btMultimaterialTriangleMeshShape* shape = (btMultimaterialTriangleMeshShape*)parent1;
00160 const btMaterial * props = shape->getMaterialProperties(partId1, index1);
00161 cp.m_combinedFriction = calculateCombinedFriction(props->m_friction, colObj0->getFriction());
00162 cp.m_combinedRestitution = props->m_restitution * colObj0->getRestitution();
00163 }
00164 }
00165
00166
00167 return true;
00168 }
00169
00170 extern ContactAddedCallback gContactAddedCallback;
00171
00172 const int NUM_VERTS_X = 20;
00173 const int NUM_VERTS_Y = 50;
00174 const int totalVerts = NUM_VERTS_X*NUM_VERTS_Y;
00175
00176 void MultiMaterialDemo::setVertexPositions(float waveheight, float offset)
00177 {
00178 int i;
00179 int j;
00180
00181 for ( i=0;i<NUM_VERTS_X;i++)
00182 {
00183 for (j=0;j<NUM_VERTS_Y;j++)
00184 {
00185 gVertices[i+j*NUM_VERTS_X].setValue((i-NUM_VERTS_X*0.5f)*TRIANGLE_SIZE,
00186
00187 waveheight*sinf((float)i+offset)*cosf((float)j+offset),
00188 (j-NUM_VERTS_Y*0.5f)*TRIANGLE_SIZE);
00189 }
00190 }
00191 }
00192
00193 void MultiMaterialDemo::keyboardCallback(unsigned char key, int x, int y)
00194 {
00195 if (key == 'g')
00196 {
00197 m_animatedMesh = !m_animatedMesh;
00198 if (m_animatedMesh)
00199 {
00200 staticBody->setCollisionFlags( staticBody->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
00201 staticBody->setActivationState(DISABLE_DEACTIVATION);
00202 } else
00203 {
00204 staticBody->setCollisionFlags( staticBody->getCollisionFlags() & ~btCollisionObject::CF_KINEMATIC_OBJECT);
00205 staticBody->forceActivationState(ACTIVE_TAG);
00206 }
00207 }
00208
00209 DemoApplication::keyboardCallback(key,x,y);
00210
00211 }
00212
00213 void MultiMaterialDemo::initPhysics()
00214 {
00215 #define TRISIZE 50.f
00216
00217 gContactAddedCallback = CustomMaterialCombinerCallback;
00218
00219
00220 const int totalTriangles = 2*(NUM_VERTS_X-1)*(NUM_VERTS_Y-1);
00221
00222 const int totalMaterials = 2;
00223
00224 int vertStride = sizeof(btVector3);
00225 int indexStride = 3*sizeof(int);
00226 int materialStride = sizeof(CustomMaterial);
00227 int triangleMaterialStride = sizeof(int);
00228
00229 gVertices = new btVector3[totalVerts];
00230 gIndices = new int[totalTriangles*3];
00231 gMaterials = new CustomMaterial[totalMaterials];
00232 gFaceMaterialIndices = new int[totalTriangles];
00233
00234
00235 gMaterials[0].m_friction = 0;
00236 gMaterials[0].m_restitution = 0.9;
00237 gMaterials[0].foo1 = 5;
00238 gMaterials[0].foo2 = 7;
00239 gMaterials[1].m_friction = 0.9;
00240 gMaterials[1].m_restitution = 0.1;
00241 gMaterials[1].foo1 = 53;
00242 gMaterials[1].foo2 = 15;
00243
00244 int i;
00245
00246 setVertexPositions(waveheight,0.f);
00247 int index=0;
00248
00249 for ( i=0;i<NUM_VERTS_X-1;i++)
00250 {
00251 for (int j=0;j<NUM_VERTS_Y-1;j++)
00252 {
00253 gIndices[index++] = j*NUM_VERTS_X+i;
00254 gIndices[index++] = j*NUM_VERTS_X+i+1;
00255 gIndices[index++] = (j+1)*NUM_VERTS_X+i+1;
00256
00257 gIndices[index++] = j*NUM_VERTS_X+i;
00258 gIndices[index++] = (j+1)*NUM_VERTS_X+i+1;
00259 gIndices[index++] = (j+1)*NUM_VERTS_X+i;
00260 }
00261 }
00262
00263
00264 for(int a = 0; a < totalTriangles; a++)
00265 {
00266
00267
00268 if(a > totalTriangles*0.5f)
00269 gFaceMaterialIndices[a] = 0;
00270 else
00271 gFaceMaterialIndices[a] = 1;
00272 }
00273
00274
00275 m_indexVertexArrays = new btTriangleIndexVertexMaterialArray(
00276 totalTriangles, gIndices, indexStride,
00277 totalVerts,(btScalar*) &gVertices[0].x(),vertStride,
00278 totalMaterials, (unsigned char *)gMaterials, sizeof(CustomMaterial),
00279 gFaceMaterialIndices, sizeof(int));
00280
00281 bool useQuantizedAabbCompression = true;
00282
00283 trimeshShape = new btMultimaterialTriangleMeshShape((btTriangleIndexVertexMaterialArray*)m_indexVertexArrays,useQuantizedAabbCompression);
00284 m_collisionShapes.push_back(trimeshShape);
00285
00286 btCollisionShape* groundShape = trimeshShape;
00287
00288 m_collisionConfiguration = new btDefaultCollisionConfiguration();
00289
00290 m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
00291
00292 btVector3 worldMin(-1000,-1000,-1000);
00293 btVector3 worldMax(1000,1000,1000);
00294 m_broadphase = new btAxisSweep3(worldMin,worldMax);
00295 m_solver = new btSequentialImpulseConstraintSolver();
00296 m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration);
00297
00298 float mass = 0.f;
00299 btTransform startTransform;
00300 startTransform.setIdentity();
00301 startTransform.setOrigin(btVector3(0,-2,0));
00302
00303 btCollisionShape* colShape = new btBoxShape(btVector3(0.5f,0.5f,0.5f));
00304 m_collisionShapes.push_back(colShape);
00305
00306 {
00307 for (int i=0;i<1;i++)
00308 {
00309 startTransform.setOrigin(btVector3(10,10,-20));
00310 btRigidBody* body = localCreateRigidBody(1, startTransform,colShape);
00311 body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
00312 body->setFriction(0.9f);
00313 body->setGravity(btVector3(0,-20.f,0));
00314 body->applyCentralImpulse(btVector3(-7.7f,0,0));
00315 }
00316 }
00317
00318 startTransform.setIdentity();
00319 staticBody = localCreateRigidBody(mass, startTransform,groundShape);
00320
00321 staticBody->setCollisionFlags(staticBody->getCollisionFlags() | btCollisionObject::CF_STATIC_OBJECT);
00322
00323
00324 staticBody->setCollisionFlags(staticBody->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
00325 }
00326
00327 void MultiMaterialDemo::clientMoveAndDisplay()
00328 {
00329 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00330
00331 float dt = getDeltaTimeMicroseconds() * 0.000001f;
00332
00333 if (m_animatedMesh)
00334 {
00335 static float offset=0.f;
00336 offset+=0.01f;
00337
00338
00339
00340 int i;
00341 int j;
00342 btVector3 aabbMin(1e30,1e30,1e30);
00343 btVector3 aabbMax(-1e30,-1e30,-1e30);
00344
00345 for ( i=NUM_VERTS_X/2-3;i<NUM_VERTS_X/2+2;i++)
00346 {
00347 for (j=NUM_VERTS_X/2-3;j<NUM_VERTS_Y/2+2;j++)
00348 {
00349
00350 aabbMax.setMax(gVertices[i+j*NUM_VERTS_X]);
00351 aabbMin.setMin(gVertices[i+j*NUM_VERTS_X]);
00352
00353 gVertices[i+j*NUM_VERTS_X].setValue((i-NUM_VERTS_X*0.5f)*TRIANGLE_SIZE,
00354 0.f,
00355 (j-NUM_VERTS_Y*0.5f)*TRIANGLE_SIZE);
00356
00357 aabbMin.setMin(gVertices[i+j*NUM_VERTS_X]);
00358 aabbMax.setMax(gVertices[i+j*NUM_VERTS_X]);
00359
00360 }
00361 }
00362
00363 trimeshShape->partialRefitTree(aabbMin,aabbMax);
00364
00365
00366 m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(staticBody->getBroadphaseHandle(),getDynamicsWorld()->getDispatcher());
00367 }
00368
00369 m_dynamicsWorld->stepSimulation(dt);
00370
00371
00372 m_dynamicsWorld->debugDrawWorld();
00373
00374 renderme();
00375
00376 glFlush();
00377 glutSwapBuffers();
00378
00379 }
00380
00381
00382
00383
00384 void MultiMaterialDemo::displayCallback(void) {
00385
00386 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00387
00388 renderme();
00389
00390 glFlush();
00391 glutSwapBuffers();
00392 }
00393
00394
00395
00396 void MultiMaterialDemo::exitPhysics()
00397 {
00398
00399
00400
00401
00402
00403
00404 int i;
00405 for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--)
00406 {
00407 btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
00408 btRigidBody* body = btRigidBody::upcast(obj);
00409 if (body && body->getMotionState())
00410 {
00411 delete body->getMotionState();
00412 }
00413 m_dynamicsWorld->removeCollisionObject( obj );
00414 delete obj;
00415 }
00416
00417
00418 for (int j=0;j<m_collisionShapes.size();j++)
00419 {
00420 btCollisionShape* shape = m_collisionShapes[j];
00421 delete shape;
00422 }
00423
00424
00425 delete m_dynamicsWorld;
00426
00427 if (m_indexVertexArrays)
00428 delete m_indexVertexArrays;
00429
00430
00431 delete m_solver;
00432
00433
00434 delete m_broadphase;
00435
00436
00437 delete m_dispatcher;
00438
00439 delete m_collisionConfiguration;
00440
00441
00442 }
00443
00444
00445
00446 GLDebugDrawer gDebugDrawer;
00447
00448 int main(int argc,char** argv)
00449 {
00450
00451 MultiMaterialDemo* multiMaterialDemo = new MultiMaterialDemo();
00452 multiMaterialDemo->initPhysics();
00453 multiMaterialDemo->setCameraDistance(30.f);
00454
00455 multiMaterialDemo->getDynamicsWorld()->setDebugDrawer(&gDebugDrawer);
00456
00457 return glutmain(argc, argv,640,480,"Multimaterial Mesh Demo",multiMaterialDemo);
00458 }
00459