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; }
static bool CustomMaterialCombinerCallback(btManifoldPoint& cp, const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1) { float friction0 = colObj0->getFriction(); float friction1 = colObj1->getFriction(); float restitution0 = colObj0->getRestitution(); float restitution1 = colObj1->getRestitution(); if (colObj0->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) { friction0 = 1.0;//partId0,index0 restitution0 = 0.f; } if (colObj1->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) { if (index1&1) { friction1 = 1.0f;//partId1,index1 } else { friction1 = 0.f; } restitution1 = 0.f; } cp.m_combinedFriction = calculateCombinedFriction(friction0,friction1); cp.m_combinedRestitution = calculateCombinedRestitution(restitution0,restitution1); //this return value is currently ignored, but to be on the safe side: return false if you don't calculate friction return true; }
void SpuContactResult::setContactInfo(btPersistentManifold* spuManifold, ppu_address_t manifoldAddress,const btTransform& worldTrans0,const btTransform& worldTrans1, btScalar restitution0,btScalar restitution1, btScalar friction0,btScalar friction1, bool isSwapped) { //spu_printf("SpuContactResult::setContactInfo ManifoldAddress: %lu\n", manifoldAddress); m_rootWorldTransform0 = worldTrans0; m_rootWorldTransform1 = worldTrans1; m_manifoldAddress = manifoldAddress; m_spuManifold = spuManifold; m_combinedFriction = calculateCombinedFriction(friction0,friction1); m_combinedRestitution = calculateCombinedRestitution(restitution0,restitution1); m_isSwapped = isSwapped; }
static bool CustomMaterialCombinerCallback(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1) { if (enable) { btAdjustInternalEdgeContacts(cp,colObj1Wrap,colObj0Wrap, partId1,index1); //btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1, BT_TRIANGLE_CONVEX_BACKFACE_MODE); //btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1, BT_TRIANGLE_CONVEX_DOUBLE_SIDED+BT_TRIANGLE_CONCAVE_DOUBLE_SIDED); } float friction0 = colObj0Wrap->getCollisionObject()->getFriction(); float friction1 = colObj1Wrap->getCollisionObject()->getFriction(); float restitution0 = colObj0Wrap->getCollisionObject()->getRestitution(); float restitution1 = colObj1Wrap->getCollisionObject()->getRestitution(); if (colObj0Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) { friction0 = 1.0;//partId0,index0 restitution0 = 0.f; } if (colObj1Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) { if (index1&1) { friction1 = 1.0f;//partId1,index1 } else { friction1 = 0.f; } restitution1 = 0.f; } cp.m_combinedFriction = calculateCombinedFriction(friction0,friction1); cp.m_combinedRestitution = calculateCombinedRestitution(restitution0,restitution1); //this return value is currently ignored, but to be on the safe side: return false if you don't calculate friction return true; }
void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth) { assert(m_manifoldPtr); //order in manifold needs to match if (depth > m_manifoldPtr->getContactBreakingThreshold()) return; bool isSwapped = m_manifoldPtr->getBody0() != m_body0; btVector3 pointA = pointInWorld + normalOnBInWorld * depth; btVector3 localA; btVector3 localB; if (isSwapped) { localA = m_rootTransB.invXform(pointA ); localB = m_rootTransA.invXform(pointInWorld); } else { localA = m_rootTransA.invXform(pointA ); localB = m_rootTransB.invXform(pointInWorld); } btManifoldPoint newPt(localA,localB,normalOnBInWorld,depth); newPt.m_positionWorldOnA = pointA; newPt.m_positionWorldOnB = pointInWorld; int insertIndex = m_manifoldPtr->getCacheEntry(newPt); newPt.m_combinedFriction = calculateCombinedFriction(m_body0,m_body1); newPt.m_combinedRestitution = calculateCombinedRestitution(m_body0,m_body1); //BP mod, store contact triangles. newPt.m_partId0 = m_partId0; newPt.m_partId1 = m_partId1; newPt.m_index0 = m_index0; newPt.m_index1 = m_index1; ///todo, check this for any side effects if (insertIndex >= 0) { //const btManifoldPoint& oldPoint = m_manifoldPtr->getContactPoint(insertIndex); m_manifoldPtr->replaceContactPoint(newPt,insertIndex); } else { m_manifoldPtr->AddManifoldPoint(newPt); } //User can override friction and/or restitution if (gContactAddedCallback && //and if either of the two bodies requires custom material ((m_body0->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) || (m_body1->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK))) { //experimental feature info, for per-triangle material etc. btCollisionObject* obj0 = isSwapped? m_body1 : m_body0; btCollisionObject* obj1 = isSwapped? m_body0 : m_body1; (*gContactAddedCallback)(newPt,obj0,m_partId0,m_index0,obj1,m_partId1,m_index1); } }
void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld, const btVector3& pointInWorld, btScalar depth) { btAssert(m_manifoldPtr); //order in manifold needs to match if (depth > m_manifoldPtr->getContactBreakingThreshold()) // if (depth > m_manifoldPtr->getContactProcessingThreshold()) return; bool isSwapped = m_manifoldPtr->getBody0() != m_body0Wrap->getCollisionObject(); btVector3 pointA = pointInWorld + normalOnBInWorld * depth; btVector3 localA; btVector3 localB; if (isSwapped) { localA = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointA ); localB = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld); } else { localA = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointA ); localB = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld); } btManifoldPoint newPt(localA, localB, normalOnBInWorld, depth); newPt.m_positionWorldOnA = pointA; newPt.m_positionWorldOnB = pointInWorld; int insertIndex = m_manifoldPtr->getCacheEntry(newPt); newPt.m_combinedFriction = calculateCombinedFriction(m_body0Wrap->getCollisionObject(), m_body1Wrap->getCollisionObject()); newPt.m_combinedRestitution = calculateCombinedRestitution(m_body0Wrap->getCollisionObject(), m_body1Wrap->getCollisionObject()); newPt.m_combinedRollingFriction = calculateCombinedRollingFriction(m_body0Wrap->getCollisionObject(), m_body1Wrap->getCollisionObject()); btPlaneSpace1(newPt.m_normalWorldOnB, newPt.m_lateralFrictionDir1, newPt.m_lateralFrictionDir2); //BP mod, store contact triangles. if (isSwapped) { newPt.m_partId0 = m_partId1; newPt.m_partId1 = m_partId0; newPt.m_index0 = m_index1; newPt.m_index1 = m_index0; } else { newPt.m_partId0 = m_partId0; newPt.m_partId1 = m_partId1; newPt.m_index0 = m_index0; newPt.m_index1 = m_index1; } //printf("depth=%f\n", depth); ///@todo, check this for any side effects if (insertIndex >= 0) { //const btManifoldPoint& oldPoint = m_manifoldPtr->getContactPoint(insertIndex); m_manifoldPtr->replaceContactPoint(newPt, insertIndex); } else { insertIndex = m_manifoldPtr->addManifoldPoint(newPt); } //User can override friction and/or restitution // DrChat: Removed for multithreading version /* if (gContactAddedCallback && //and if either of the two bodies requires custom material ((m_body0Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) || (m_body1Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK))) { //experimental feature info, for per-triangle material etc. const btCollisionObjectWrapper* obj0Wrap = isSwapped? m_body1Wrap : m_body0Wrap; const btCollisionObjectWrapper* obj1Wrap = isSwapped? m_body0Wrap : m_body1Wrap; (*gContactAddedCallback)(m_manifoldPtr->getContactPoint(insertIndex), obj0Wrap, newPt.m_partId0, newPt.m_index0, obj1Wrap, newPt.m_partId1, newPt.m_index1); } */ }