btFractureBody.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. #include "btFractureBody.h"
  2. #include "BulletCollision/CollisionDispatch/btCollisionWorld.h"
  3. #include "BulletCollision/CollisionShapes/btCompoundShape.h"
  4. #include "BulletDynamics/Dynamics/btDynamicsWorld.h"
  5. void btFractureBody::recomputeConnectivity(btCollisionWorld* world)
  6. {
  7. m_connections.clear();
  8. //@todo use the AABB tree to avoid N^2 checks
  9. if (getCollisionShape()->isCompound())
  10. {
  11. btCompoundShape* compound = (btCompoundShape*)getCollisionShape();
  12. for (int i=0;i<compound->getNumChildShapes();i++)
  13. {
  14. for (int j=i+1;j<compound->getNumChildShapes();j++)
  15. {
  16. struct MyContactResultCallback : public btCollisionWorld::ContactResultCallback
  17. {
  18. bool m_connected;
  19. btScalar m_margin;
  20. MyContactResultCallback() :m_connected(false),m_margin(0.05)
  21. {
  22. }
  23. virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1)
  24. {
  25. if (cp.getDistance()<=m_margin)
  26. m_connected = true;
  27. return 1.f;
  28. }
  29. };
  30. MyContactResultCallback result;
  31. btCollisionObject obA;
  32. obA.setWorldTransform(compound->getChildTransform(i));
  33. obA.setCollisionShape(compound->getChildShape(i));
  34. btCollisionObject obB;
  35. obB.setWorldTransform(compound->getChildTransform(j));
  36. obB.setCollisionShape(compound->getChildShape(j));
  37. world->contactPairTest(&obA,&obB,result);
  38. if (result.m_connected)
  39. {
  40. btConnection tmp;
  41. tmp.m_childIndex0 = i;
  42. tmp.m_childIndex1 = j;
  43. tmp.m_childShape0 = compound->getChildShape(i);
  44. tmp.m_childShape1 = compound->getChildShape(j);
  45. tmp.m_strength = 1.f;//??
  46. m_connections.push_back(tmp);
  47. }
  48. }
  49. }
  50. }
  51. }
  52. btCompoundShape* btFractureBody::shiftTransformDistributeMass(btCompoundShape* boxCompound,btScalar mass,btTransform& shift)
  53. {
  54. btVector3 principalInertia;
  55. btScalar* masses = new btScalar[boxCompound->getNumChildShapes()];
  56. for (int j=0;j<boxCompound->getNumChildShapes();j++)
  57. {
  58. //evenly distribute mass
  59. masses[j]=mass/boxCompound->getNumChildShapes();
  60. }
  61. return shiftTransform(boxCompound,masses,shift,principalInertia);
  62. }
  63. btCompoundShape* btFractureBody::shiftTransform(btCompoundShape* boxCompound,btScalar* masses,btTransform& shift, btVector3& principalInertia)
  64. {
  65. btTransform principal;
  66. boxCompound->calculatePrincipalAxisTransform(masses,principal,principalInertia);
  67. ///create a new compound with world transform/center of mass properly aligned with the principal axis
  68. ///non-recursive compound shapes perform better
  69. #ifdef USE_RECURSIVE_COMPOUND
  70. btCompoundShape* newCompound = new btCompoundShape();
  71. newCompound->addChildShape(principal.inverse(),boxCompound);
  72. newBoxCompound = newCompound;
  73. //m_collisionShapes.push_back(newCompound);
  74. //btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
  75. //btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,newCompound,principalInertia);
  76. #else
  77. #ifdef CHANGE_COMPOUND_INPLACE
  78. newBoxCompound = boxCompound;
  79. for (int i=0;i<boxCompound->getNumChildShapes();i++)
  80. {
  81. btTransform newChildTransform = principal.inverse()*boxCompound->getChildTransform(i);
  82. ///updateChildTransform is really slow, because it re-calculates the AABB each time. todo: add option to disable this update
  83. boxCompound->updateChildTransform(i,newChildTransform);
  84. }
  85. bool isDynamic = (mass != 0.f);
  86. btVector3 localInertia(0,0,0);
  87. if (isDynamic)
  88. boxCompound->calculateLocalInertia(mass,localInertia);
  89. #else
  90. ///creation is faster using a new compound to store the shifted children
  91. btCompoundShape* newBoxCompound = new btCompoundShape();
  92. for (int i=0;i<boxCompound->getNumChildShapes();i++)
  93. {
  94. btTransform newChildTransform = principal.inverse()*boxCompound->getChildTransform(i);
  95. ///updateChildTransform is really slow, because it re-calculates the AABB each time. todo: add option to disable this update
  96. newBoxCompound->addChildShape(newChildTransform,boxCompound->getChildShape(i));
  97. }
  98. #endif
  99. #endif//USE_RECURSIVE_COMPOUND
  100. shift = principal;
  101. return newBoxCompound;
  102. }