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