diff --git a/Demos/MultiMaterialDemo/Jamfile b/Demos/MultiMaterialDemo/Jamfile new file mode 100644 index 000000000..b63378351 --- /dev/null +++ b/Demos/MultiMaterialDemo/Jamfile @@ -0,0 +1,3 @@ +SubDir TOP Demos MultiMaterialDemo ; + +BulletDemo MultiMaterialDemo : [ Wildcard *.h *.cpp ] ; diff --git a/Demos/MultiMaterialDemo/MultiMaterialDemo.cpp b/Demos/MultiMaterialDemo/MultiMaterialDemo.cpp new file mode 100644 index 000000000..eb65f0b5d --- /dev/null +++ b/Demos/MultiMaterialDemo/MultiMaterialDemo.cpp @@ -0,0 +1,382 @@ +/* +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 "btBulletDynamicsCommon.h" +#include "LinearMath/btIDebugDraw.h" +#include "GLDebugDrawer.h" +#include "MultiMaterialDemo.h" +#include "GL_ShapeDrawer.h" +#include "GlutStuff.h" + +#include "BulletCollision\CollisionShapes\btTriangleShape.h" +#include "BulletCollision\CollisionShapes\btTriangleIndexVertexMaterialArray.h" +#include "BulletCollision\CollisionShapes\btMultimaterialTriangleMeshShape.h" +#include "BulletCollision\CollisionShapes\btMaterial.h" + +// Create a custom material, just because we can +class CustomMaterial : public btMaterial +{ +public: + int foo1; + int foo2; + CustomMaterial(){} + CustomMaterial(int a, int b) {foo1 = a; foo2 = b;} +}; + +// Storage for the vertex data +static btVector3* gVertices = 0; +// Storage for the face data +static int* gIndices = 0; +// Storage for the material data +static CustomMaterial* gMaterials = 0; +// Storage for the face -> material index data +static int* gFaceMaterialIndices = 0; + +static btBvhTriangleMeshShape* trimeshShape =0; +static btRigidBody* staticBody = 0; +static float waveheight = 0.f; + +const float TRIANGLE_SIZE=1.f; + + +///User can override this material combiner by implementing gContactAddedCallback and setting body0->m_collisionFlags |= btCollisionObject::customMaterialCallback; +inline btScalar calculateCombinedFriction(float friction0,float friction1) +{ + btScalar friction = friction0 * friction1; + + const btScalar MAX_FRICTION = 10.f; + if (friction < -MAX_FRICTION) + friction = -MAX_FRICTION; + if (friction > MAX_FRICTION) + friction = MAX_FRICTION; + return friction; + +} + +inline btScalar calculateCombinedRestitution(float restitution0,float restitution1) +{ + return restitution0 * restitution1; +} + + + +static bool CustomMaterialCombinerCallback(btManifoldPoint& cp, const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1) +{ + + // Apply material properties + if (colObj0->getCollisionShape()->getShapeType() == TRIANGLE_SHAPE_PROXYTYPE) + { + const btCollisionShape* parent0 = colObj0->getRootCollisionShape(); + if(parent0 != 0 && parent0->getShapeType() == MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE) + { + btMultimaterialTriangleMeshShape* shape = (btMultimaterialTriangleMeshShape*)parent0; + const btMaterial * props = shape->getMaterialProperties(partId0, index0); + cp.m_combinedFriction = calculateCombinedFriction(props->m_friction, colObj1->getFriction()); + cp.m_combinedRestitution = props->m_restitution * colObj1->getRestitution(); + } + } + else if (colObj1->getCollisionShape()->getShapeType() == TRIANGLE_SHAPE_PROXYTYPE) + { + const btCollisionShape* parent1 = colObj1->getRootCollisionShape(); + if(parent1 != 0 && parent1->getShapeType() == MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE) + { + btMultimaterialTriangleMeshShape* shape = (btMultimaterialTriangleMeshShape*)parent1; + const btMaterial * props = shape->getMaterialProperties(partId1, index1); + cp.m_combinedFriction = calculateCombinedFriction(props->m_friction, colObj0->getFriction()); + cp.m_combinedRestitution = props->m_restitution * colObj0->getRestitution(); + } + } + + //this return value is currently ignored, but to be on the safe side: return false if you don't calculate friction + return true; +} + +extern ContactAddedCallback gContactAddedCallback; + +const int NUM_VERTS_X = 20; +const int NUM_VERTS_Y = 50; +const int totalVerts = NUM_VERTS_X*NUM_VERTS_Y; + +void MultiMaterialDemo::setVertexPositions(float waveheight, float offset) +{ + int i; + int j; + + for ( i=0;isetCollisionFlags( staticBody->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); + staticBody->setActivationState(DISABLE_DEACTIVATION); + } else + { + staticBody->setCollisionFlags( staticBody->getCollisionFlags() & ~btCollisionObject::CF_KINEMATIC_OBJECT); + staticBody->forceActivationState(ACTIVE_TAG); + } + } + + DemoApplication::keyboardCallback(key,x,y); + +} + +void MultiMaterialDemo::initPhysics() +{ +#define TRISIZE 50.f + + gContactAddedCallback = CustomMaterialCombinerCallback; + + // The number of triangles + const int totalTriangles = 2*(NUM_VERTS_X-1)*(NUM_VERTS_Y-1); + // The number of materials + const int totalMaterials = 2; + + int vertStride = sizeof(btVector3); + int indexStride = 3*sizeof(int); + int materialStride = sizeof(CustomMaterial); + int triangleMaterialStride = sizeof(int); + + gVertices = new btVector3[totalVerts]; + gIndices = new int[totalTriangles*3]; + gMaterials = new CustomMaterial[totalMaterials]; + gFaceMaterialIndices = new int[totalTriangles]; + + // Explicitly set up the materials. It's a small array so let's do it bit by bit. + gMaterials[0].m_friction = 0; + gMaterials[0].m_restitution = 0.9; + gMaterials[0].foo1 = 5; + gMaterials[0].foo2 = 7; + gMaterials[1].m_friction = 0.9; + gMaterials[1].m_restitution = 0.1; + gMaterials[1].foo1 = 53; + gMaterials[1].foo2 = 15; + + int i; + // Set up the vertex data + setVertexPositions(waveheight,0.f); + int index=0; + // Set up the face data + for ( i=0;imaterial index data + for(int a = 0; a < totalTriangles; a++) + { + // This will give the first half of the faces low friction and high restitution + // and the second half of the faces high friction and low restitution + if(a > totalTriangles*0.5f) + gFaceMaterialIndices[a] = 0; + else + gFaceMaterialIndices[a] = 1; + } + + // Create the array structure + m_indexVertexArrays = new btTriangleIndexVertexMaterialArray( + totalTriangles, gIndices, indexStride, + totalVerts,(btScalar*) &gVertices[0].x(),vertStride, + totalMaterials, (unsigned char *)gMaterials, sizeof(CustomMaterial), + gFaceMaterialIndices, sizeof(int)); + + bool useQuantizedAabbCompression = true; + // Create the multimaterial mesh shape + trimeshShape = new btMultimaterialTriangleMeshShape((btTriangleIndexVertexMaterialArray*)m_indexVertexArrays,useQuantizedAabbCompression); + m_collisionShapes.push_back(trimeshShape); + + btCollisionShape* groundShape = trimeshShape; + + m_collisionConfiguration = new btDefaultCollisionConfiguration(); + + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + + btVector3 worldMin(-1000,-1000,-1000); + btVector3 worldMax(1000,1000,1000); + m_broadphase = new btAxisSweep3(worldMin,worldMax); + m_solver = new btSequentialImpulseConstraintSolver(); + m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); + + float mass = 0.f; + btTransform startTransform; + startTransform.setIdentity(); + startTransform.setOrigin(btVector3(0,-2,0)); + + btCollisionShape* colShape = new btBoxShape(btVector3(0.5f,0.5f,0.5f)); + m_collisionShapes.push_back(colShape); + + { + for (int i=0;i<1;i++) + { + startTransform.setOrigin(btVector3(10,10,-20)); + btRigidBody* body = localCreateRigidBody(1, startTransform,colShape); + body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); + body->setFriction(0.9f); + body->setGravity(btVector3(0,-20.f,0)); + body->applyCentralImpulse(btVector3(-7.7f,0,0)); + } + } + + startTransform.setIdentity(); + staticBody = localCreateRigidBody(mass, startTransform,groundShape); + + staticBody->setCollisionFlags(staticBody->getCollisionFlags() | btCollisionObject::CF_STATIC_OBJECT); + + //enable custom material callback + staticBody->setCollisionFlags(staticBody->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); +} + +void MultiMaterialDemo::clientMoveAndDisplay() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + float dt = getDeltaTimeMicroseconds() * 0.000001f; + + if (m_animatedMesh) + { + static float offset=0.f; + offset+=0.01f; + + // setVertexPositions(waveheight,offset); + + int i; + int j; + btVector3 aabbMin(1e30,1e30,1e30); + btVector3 aabbMax(-1e30,-1e30,-1e30); + + for ( i=NUM_VERTS_X/2-3;ipartialRefitTree(aabbMin,aabbMax); + + //clear all contact points involving mesh proxy. Note: this is a slow/unoptimized operation. + m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(staticBody->getBroadphaseHandle(),getDynamicsWorld()->getDispatcher()); + } + + m_dynamicsWorld->stepSimulation(dt); + + //optional but useful: debug drawing + m_dynamicsWorld->debugDrawWorld(); + + renderme(); + + glFlush(); + glutSwapBuffers(); + +} + + + + +void MultiMaterialDemo::displayCallback(void) { + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + renderme(); + + glFlush(); + glutSwapBuffers(); +} + + + +void MultiMaterialDemo::exitPhysics() +{ + + + + //cleanup in the reverse order of creation/initialization + + //remove the rigidbodies from the dynamics world and delete them + int i; + for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + //delete collision shapes + for (int j=0;j m_collisionShapes; + + btTriangleIndexVertexArray* m_indexVertexArrays; + + btBroadphaseInterface* m_broadphase; + + btCollisionDispatcher* m_dispatcher; + + btConstraintSolver* m_solver; + + btDefaultCollisionConfiguration* m_collisionConfiguration; + + bool m_animatedMesh; + + public: + + MultiMaterialDemo() : m_animatedMesh(true) + { + + } + void initPhysics(); + + void exitPhysics(); + + virtual ~MultiMaterialDemo() + { + exitPhysics(); + } + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + //to show refit works + void setVertexPositions(float waveheight, float offset); + + virtual void keyboardCallback(unsigned char key, int x, int y); + + static DemoApplication* Create() + { + MultiMaterialDemo* demo = new MultiMaterialDemo(); + demo->myinit(); + demo->initPhysics(); + return demo; + }; +}; + +#endif //CONCAVE_DEMO_H + diff --git a/Demos/MultiMaterialDemo/main.cpp b/Demos/MultiMaterialDemo/main.cpp new file mode 100644 index 000000000..9b8d35bd9 --- /dev/null +++ b/Demos/MultiMaterialDemo/main.cpp @@ -0,0 +1,22 @@ + +#include "MultiMaterialDemo.h" +#include "GlutStuff.h" + +#include "GlutStuff.h" +#include "GLDebugDrawer.h" +#include "btBulletDynamicsCommon.h" + +GLDebugDrawer gDebugDrawer; + +int main(int argc,char** argv) +{ + + MultiMaterialDemo* multiMaterialDemo = new MultiMaterialDemo(); + multiMaterialDemo->initPhysics(); + multiMaterialDemo->setCameraDistance(30.f); + + multiMaterialDemo->getDynamicsWorld()->setDebugDrawer(&gDebugDrawer); + + return glutmain(argc, argv,640,480,"Multimaterial Mesh Demo",multiMaterialDemo); +} + diff --git a/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h b/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h index eabefdbdd..4e9b3f185 100644 --- a/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h +++ b/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h @@ -52,6 +52,8 @@ CONCAVE_SHAPES_START_HERE, TERRAIN_SHAPE_PROXYTYPE, ///Used for GIMPACT Trimesh integration GIMPACT_SHAPE_PROXYTYPE, +///Multimaterial mesh + MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE, EMPTY_SHAPE_PROXYTYPE, STATIC_PLANE_PROXYTYPE, diff --git a/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp b/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp index 4831efe72..d16412495 100644 --- a/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp +++ b/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp @@ -19,6 +19,7 @@ subject to the following restrictions: btCollisionObject::btCollisionObject() : m_broadphaseHandle(0), m_collisionShape(0), + m_rootCollisionShape(0), m_collisionFlags(btCollisionObject::CF_STATIC_OBJECT), m_islandTag1(-1), m_companionId(-1), diff --git a/src/BulletCollision/CollisionDispatch/btCollisionObject.h b/src/BulletCollision/CollisionDispatch/btCollisionObject.h index 57aee6173..96cbd1c3e 100644 --- a/src/BulletCollision/CollisionDispatch/btCollisionObject.h +++ b/src/BulletCollision/CollisionDispatch/btCollisionObject.h @@ -51,6 +51,11 @@ protected: btVector3 m_interpolationAngularVelocity; btBroadphaseProxy* m_broadphaseHandle; btCollisionShape* m_collisionShape; + + ///m_rootCollisionShape is temporarily used to store the original collision shape + ///The m_collisionShape might be temporarily replaced by a child collision shape during collision detection purposes + ///If it is NULL, the m_collisionShape is not temporarily replaced. + btCollisionShape* m_rootCollisionShape; int m_collisionFlags; @@ -141,6 +146,7 @@ public: void setCollisionShape(btCollisionShape* collisionShape) { m_collisionShape = collisionShape; + m_rootCollisionShape = collisionShape; } SIMD_FORCE_INLINE const btCollisionShape* getCollisionShape() const @@ -153,8 +159,22 @@ public: return m_collisionShape; } - + SIMD_FORCE_INLINE const btCollisionShape* getRootCollisionShape() const + { + return m_rootCollisionShape; + } + SIMD_FORCE_INLINE btCollisionShape* getRootCollisionShape() + { + return m_rootCollisionShape; + } + + ///Avoid using this internal API call + ///internalSetTemporaryCollisionShape is used to temporary replace the actual collision shape by a child collision shape. + void internalSetTemporaryCollisionShape(btCollisionShape* collisionShape) + { + m_collisionShape = collisionShape; + } int getActivationState() const { return m_activationState1;} diff --git a/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp b/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp index 222ae6384..179541e71 100644 --- a/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp +++ b/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp @@ -34,10 +34,9 @@ m_isSwapped(isSwapped) for (i=0;igetChildShape(i); - btCollisionShape* orgShape = colObj->getCollisionShape(); - colObj->setCollisionShape( childShape ); + colObj->internalSetTemporaryCollisionShape( childShape ); m_childCollisionAlgorithms[i] = ci.m_dispatcher1->findAlgorithm(colObj,otherObj); - colObj->setCollisionShape( orgShape ); + colObj->setCollisionShape( colObj->getRootCollisionShape()); } } diff --git a/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp b/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp index 06ea9563d..5ce093b53 100644 --- a/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp +++ b/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp @@ -116,14 +116,9 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, i { btTriangleShape tm(triangle[0],triangle[1],triangle[2]); tm.setMargin(m_collisionMarginTriangle); - btCollisionShape* tmpShape = ob->getCollisionShape(); - - //copy over user pointers to temporary shape - tm.setUserPointer(tmpShape->getUserPointer()); - ob->setCollisionShape( &tm ); + ob->internalSetTemporaryCollisionShape( &tm ); - btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(m_convexBody,m_triBody,m_manifoldPtr); ///this should use the btDispatcher, so the actual registered algorithm is used // btConvexConvexAlgorithm cvxcvxalgo(m_manifoldPtr,ci,m_convexBody,m_triBody); @@ -134,11 +129,9 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, i colAlgo->processCollision(m_convexBody,m_triBody,*m_dispatchInfoPtr,m_resultOut); colAlgo->~btCollisionAlgorithm(); ci.m_dispatcher1->freeCollisionAlgorithm(colAlgo); - ob->setCollisionShape( tmpShape ); - + ob->setCollisionShape( ob->getRootCollisionShape()); } - } diff --git a/src/BulletCollision/CollisionShapes/btMaterial.h b/src/BulletCollision/CollisionShapes/btMaterial.h new file mode 100644 index 000000000..751e58112 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btMaterial.h @@ -0,0 +1,34 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2008 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. +*/ + +/// This file was created by Alex Silverman + +#ifndef MATERIAL_H +#define MATERIAL_H + +// Material class to be used by btMultimaterialTriangleMeshShape to store triangle properties +class btMaterial +{ + // public members so that materials can change due to world events +public: + btScalar m_friction; + btScalar m_restitution; + int pad[2]; + + btMaterial(){} + btMaterial(btScalar fric, btScalar rest) { m_friction = fric; m_restitution = rest; } +}; + +#endif // MATERIAL_H \ No newline at end of file diff --git a/src/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.cpp b/src/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.cpp new file mode 100644 index 000000000..54501e6c3 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.cpp @@ -0,0 +1,45 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2008 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. +*/ + +/// This file was created by Alex Silverman + +#include "BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h" +#include "BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.h" +//#include "BulletCollision/CollisionShapes/btOptimizedBvh.h" + + +///Obtains the material for a specific triangle +const btMaterial * btMultimaterialTriangleMeshShape::getMaterialProperties(int partID, int triIndex) +{ + const unsigned char * materialBase = 0; + int numMaterials; + PHY_ScalarType materialType; + int materialStride; + const unsigned char * triangleMaterialBase = 0; + int numTriangles; + int triangleMaterialStride; + PHY_ScalarType triangleType; + + ((btTriangleIndexVertexMaterialArray*)m_meshInterface)->getLockedReadOnlyMaterialBase(&materialBase, numMaterials, materialType, materialStride, + &triangleMaterialBase, numTriangles, triangleMaterialStride, triangleType, partID); + + // return the pointer to the place with the friction for the triangle + // TODO: This depends on whether it's a moving mesh or not + // BUG IN GIMPACT + //return (btScalar*)(&materialBase[triangleMaterialBase[(triIndex-1) * triangleMaterialStride] * materialStride]); + int * matInd = (int *)(&(triangleMaterialBase[(triIndex * triangleMaterialStride)])); + btMaterial *matVal = (btMaterial *)(&(materialBase[*matInd * materialStride])); + return (matVal); +} diff --git a/src/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h b/src/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h new file mode 100644 index 000000000..dab7575ca --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h @@ -0,0 +1,125 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2008 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. +*/ + +/// This file was created by Alex Silverman + +#ifndef BVH_TRIANGLE_MATERIAL_MESH_SHAPE_H +#define BVH_TRIANGLE_MATERIAL_MESH_SHAPE_H + +#include "btBvhTriangleMeshShape.h" +#include "btMaterial.h" + +///BvhTriangleMaterialMeshShape extends BvhTriangleMeshShape. +///Its main contribution is the interface into a material array. +ATTRIBUTE_ALIGNED16(class) btMultimaterialTriangleMeshShape : public btBvhTriangleMeshShape +{ + btAlignedObjectArray m_materialList; + int ** m_triangleMaterials; + +public: + + BT_DECLARE_ALIGNED_ALLOCATOR(); + + btMultimaterialTriangleMeshShape(): btBvhTriangleMeshShape() {} + btMultimaterialTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression, bool buildBvh = true): + btBvhTriangleMeshShape(meshInterface, useQuantizedAabbCompression, buildBvh) + { + btVector3 m_triangle[3]; + const unsigned char *vertexbase; + int numverts; + PHY_ScalarType type; + int stride; + const unsigned char *indexbase; + int indexstride; + int numfaces; + PHY_ScalarType indicestype; + + //m_materialLookup = (int**)(btAlignedAlloc(sizeof(int*) * meshInterface->getNumSubParts(), 16)); + + for(int i = 0; i < meshInterface->getNumSubParts(); i++) + { + m_meshInterface->getLockedReadOnlyVertexIndexBase( + &vertexbase, + numverts, + type, + stride, + &indexbase, + indexstride, + numfaces, + indicestype, + i); + //m_materialLookup[i] = (int*)(btAlignedAlloc(sizeof(int) * numfaces, 16)); + } + } + + ///optionally pass in a larger bvh aabb, used for quantization. This allows for deformations within this aabb + btMultimaterialTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax, bool buildBvh = true): + btBvhTriangleMeshShape(meshInterface, useQuantizedAabbCompression, bvhAabbMin, bvhAabbMax, buildBvh) + { + btVector3 m_triangle[3]; + const unsigned char *vertexbase; + int numverts; + PHY_ScalarType type; + int stride; + const unsigned char *indexbase; + int indexstride; + int numfaces; + PHY_ScalarType indicestype; + + //m_materialLookup = (int**)(btAlignedAlloc(sizeof(int*) * meshInterface->getNumSubParts(), 16)); + + for(int i = 0; i < meshInterface->getNumSubParts(); i++) + { + m_meshInterface->getLockedReadOnlyVertexIndexBase( + &vertexbase, + numverts, + type, + stride, + &indexbase, + indexstride, + numfaces, + indicestype, + i); + //m_materialLookup[i] = (int*)(btAlignedAlloc(sizeof(int) * numfaces * 2, 16)); + } + } + + virtual ~btMultimaterialTriangleMeshShape() + { +/* + for(int i = 0; i < m_meshInterface->getNumSubParts(); i++) + { + btAlignedFree(m_materialValues[i]); + m_materialLookup[i] = NULL; + } + btAlignedFree(m_materialValues); + m_materialLookup = NULL; +*/ + } + virtual int getShapeType() const + { + return MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE; + } + + //debugging + virtual const char* getName()const {return "MULTIMATERIALTRIANGLEMESH";} + + ///Obtains the material for a specific triangle + const btMaterial * getMaterialProperties(int partID, int triIndex); + +} +; + +#endif //BVH_TRIANGLE_MATERIAL_MESH_SHAPE_H diff --git a/src/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp b/src/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp new file mode 100644 index 000000000..19f0bde12 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp @@ -0,0 +1,86 @@ +/* +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. +*/ + +///This file was created by Alex Silverman + +#include "btTriangleIndexVertexMaterialArray.h" + +btTriangleIndexVertexMaterialArray::btTriangleIndexVertexMaterialArray(int numTriangles,int* triangleIndexBase,int triangleIndexStride, + int numVertices,btScalar* vertexBase,int vertexStride, + int numMaterials, unsigned char* materialBase, int materialStride, + int* triangleMaterialsBase, int materialIndexStride) : +btTriangleIndexVertexArray(numTriangles, triangleIndexBase, triangleIndexStride, numVertices, vertexBase, vertexStride) +{ + btMaterialProperties mat; + + mat.m_numMaterials = numMaterials; + mat.m_materialBase = materialBase; + mat.m_materialStride = materialStride; +#ifdef BT_USE_DOUBLE_PRECISION + mat.m_materialType = PHY_DOUBLE; +#else + mat.m_materialType = PHY_FLOAT; +#endif + + mat.m_numTriangles = numTriangles; + mat.m_triangleMaterialsBase = (unsigned char *)triangleMaterialsBase; + mat.m_triangleMaterialStride = materialIndexStride; + mat.m_triangleType = PHY_INTEGER; + + addMaterialProperties(mat); +} + + +void btTriangleIndexVertexMaterialArray::getLockedMaterialBase(unsigned char **materialBase, int& numMaterials, PHY_ScalarType& materialType, int& materialStride, + unsigned char ** triangleMaterialBase, int& numTriangles, int& triangleMaterialStride, PHY_ScalarType& triangleType, int subpart) +{ + btAssert(subpart< getNumSubParts() ); + + btMaterialProperties& mats = m_materials[subpart]; + + numMaterials = mats.m_numMaterials; + (*materialBase) = (unsigned char *) mats.m_materialBase; +#ifdef BT_USE_DOUBLE_PRECISION + materialType = PHY_DOUBLE; +#else + materialType = PHY_FLOAT; +#endif + materialStride = mats.m_materialStride; + + numTriangles = mats.m_numTriangles; + (*triangleMaterialBase) = (unsigned char *)mats.m_triangleMaterialsBase; + triangleMaterialStride = mats.m_triangleMaterialStride; + triangleType = mats.m_triangleType; +} + +void btTriangleIndexVertexMaterialArray::getLockedReadOnlyMaterialBase(const unsigned char **materialBase, int& numMaterials, PHY_ScalarType& materialType, int& materialStride, + const unsigned char ** triangleMaterialBase, int& numTriangles, int& triangleMaterialStride, PHY_ScalarType& triangleType, int subpart) +{ + btMaterialProperties& mats = m_materials[subpart]; + + numMaterials = mats.m_numMaterials; + (*materialBase) = (const unsigned char *) mats.m_materialBase; +#ifdef BT_USE_DOUBLE_PRECISION + materialType = PHY_DOUBLE; +#else + materialType = PHY_FLOAT; +#endif + materialStride = mats.m_materialStride; + + numTriangles = mats.m_numTriangles; + (*triangleMaterialBase) = (const unsigned char *)mats.m_triangleMaterialsBase; + triangleMaterialStride = mats.m_triangleMaterialStride; + triangleType = mats.m_triangleType; +} diff --git a/src/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.h b/src/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.h new file mode 100644 index 000000000..c712071a2 --- /dev/null +++ b/src/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.h @@ -0,0 +1,84 @@ +/* +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. +*/ + +///This file was created by Alex Silverman + +#ifndef BT_MULTIMATERIAL_TRIANGLE_INDEX_VERTEX_ARRAY_H +#define BT_MULTIMATERIAL_TRIANGLE_INDEX_VERTEX_ARRAY_H + +#include "btTriangleIndexVertexArray.h" + + +ATTRIBUTE_ALIGNED16( struct) btMaterialProperties +{ + ///m_materialBase ==========> 2 btScalar values make up one material, friction then restitution + int m_numMaterials; + const unsigned char * m_materialBase; + int m_materialStride; + PHY_ScalarType m_materialType; + ///m_numTriangles <=========== This exists in the btIndexedMesh object for the same subpart, but since we're + /// padding the structure, it can be reproduced at no real cost + ///m_triangleMaterials =====> 1 integer value makes up one entry + /// eg: m_triangleMaterials[1] = 5; // This will set triangle 2 to use material 5 + int m_numTriangles; + const unsigned char * m_triangleMaterialsBase; + int m_triangleMaterialStride; + ///m_triangleType <========== Automatically set in addMaterialProperties + PHY_ScalarType m_triangleType; +}; + +typedef btAlignedObjectArray MaterialArray; + +///TriangleIndexVertexMaterialArray is built on TriangleIndexVertexArray +///The addition of a material array allows for the utilization of the partID and +///triangleIndex that are returned in the ContactAddedCallback. As with +///TriangleIndexVertexArray, no duplicate is made of the material data, so it +///is the users responsibility to maintain the array during the lifetime of the +///TriangleIndexVertexMaterialArray. +ATTRIBUTE_ALIGNED16(class) btTriangleIndexVertexMaterialArray : public btTriangleIndexVertexArray +{ +protected: + MaterialArray m_materials; + +public: + BT_DECLARE_ALIGNED_ALLOCATOR(); + + btTriangleIndexVertexMaterialArray() + { + } + + btTriangleIndexVertexMaterialArray(int numTriangles,int* triangleIndexBase,int triangleIndexStride, + int numVertices,btScalar* vertexBase,int vertexStride, + int numMaterials, unsigned char* materialBase, int materialStride, + int* triangleMaterialsBase, int materialIndexStride); + + virtual ~btTriangleIndexVertexMaterialArray() {} + + void addMaterialProperties(const btMaterialProperties& mat, PHY_ScalarType triangleType = PHY_INTEGER) + { + m_materials.push_back(mat); + m_materials[m_materials.size()-1].m_triangleType = triangleType; + } + + virtual void getLockedMaterialBase(unsigned char **materialBase, int& numMaterials, PHY_ScalarType& materialType, int& materialStride, + unsigned char ** triangleMaterialBase, int& numTriangles, int& triangleMaterialStride, PHY_ScalarType& triangleType ,int subpart = 0); + + virtual void getLockedReadOnlyMaterialBase(const unsigned char **materialBase, int& numMaterials, PHY_ScalarType& materialType, int& materialStride, + const unsigned char ** triangleMaterialBase, int& numTriangles, int& triangleMaterialStride, PHY_ScalarType& triangleType, int subpart = 0); + +} +; + +#endif //BT_MULTIMATERIAL_TRIANGLE_INDEX_VERTEX_ARRAY_H diff --git a/src/BulletCollision/CollisionShapes/btTriangleShape.h b/src/BulletCollision/CollisionShapes/btTriangleShape.h index 064c64fa6..ba7aa0c32 100644 --- a/src/BulletCollision/CollisionShapes/btTriangleShape.h +++ b/src/BulletCollision/CollisionShapes/btTriangleShape.h @@ -27,7 +27,6 @@ public: btVector3 m_vertices1[3]; - virtual int getNumVertices() const { return 3; @@ -84,14 +83,13 @@ public: - btTriangleShape(const btVector3& p0,const btVector3& p1,const btVector3& p2) - { - m_vertices1[0] = p0; - m_vertices1[1] = p1; - m_vertices1[2] = p2; - } + btTriangleShape(const btVector3& p0,const btVector3& p1,const btVector3& p2) + { + m_vertices1[0] = p0; + m_vertices1[1] = p1; + m_vertices1[2] = p2; + } - virtual void getPlane(btVector3& planeNormal,btPoint3& planeSupport,int i) const { diff --git a/src/BulletDynamics/Dynamics/btRigidBody.cpp b/src/BulletDynamics/Dynamics/btRigidBody.cpp index 54af82224..e2afb687a 100644 --- a/src/BulletDynamics/Dynamics/btRigidBody.cpp +++ b/src/BulletDynamics/Dynamics/btRigidBody.cpp @@ -77,7 +77,7 @@ void btRigidBody::setupRigidBody(const btRigidBody::btRigidBodyConstructionInfo& m_friction = constructionInfo.m_friction; m_restitution = constructionInfo.m_restitution; - m_collisionShape = constructionInfo.m_collisionShape; + setCollisionShape( constructionInfo.m_collisionShape ); m_debugBodyId = uniqueId++; setMassProps(constructionInfo.m_mass, constructionInfo.m_localInertia);