Tizen 2.1 base
[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                                         MyContactResultCallback() :m_connected(false)\r
26                                         {\r
27                                         }\r
28                                         virtual   btScalar   addSingleResult(btManifoldPoint& cp,   const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1)\r
29                                         {\r
30                                                 if (cp.getDistance()<=0)\r
31                                                         m_connected = true;\r
32                                                 return 1.f;\r
33                                         }\r
34                            };\r
35 \r
36                                 MyContactResultCallback result;\r
37 \r
38                                 btCollisionObject obA;\r
39                                 obA.setWorldTransform(compound->getChildTransform(i));\r
40                                 obA.setCollisionShape(compound->getChildShape(i));\r
41                                 btCollisionObject obB;\r
42                                 obB.setWorldTransform(compound->getChildTransform(j));\r
43                                 obB.setCollisionShape(compound->getChildShape(j));\r
44                                 world->contactPairTest(&obA,&obB,result);\r
45                                 if (result.m_connected)\r
46                                 {\r
47                                         btConnection tmp;\r
48                                         tmp.m_childIndex0 = i;\r
49                                         tmp.m_childIndex1 = j;\r
50                                         tmp.m_childShape0 = compound->getChildShape(i);\r
51                                         tmp.m_childShape1 = compound->getChildShape(j);\r
52                                         tmp.m_strength = 1.f;//??\r
53                                         m_connections.push_back(tmp);\r
54                                 }\r
55                         }\r
56                 }\r
57         }\r
58         \r
59 \r
60 }\r
61 \r
62 btCompoundShape* btFractureBody::shiftTransformDistributeMass(btCompoundShape* boxCompound,btScalar mass,btTransform& shift)\r
63 {\r
64 \r
65         btVector3 principalInertia;\r
66 \r
67         btScalar* masses = new btScalar[boxCompound->getNumChildShapes()];\r
68         for (int j=0;j<boxCompound->getNumChildShapes();j++)\r
69         {\r
70                 //evenly distribute mass\r
71                 masses[j]=mass/boxCompound->getNumChildShapes();\r
72         }\r
73 \r
74         return shiftTransform(boxCompound,masses,shift,principalInertia);\r
75 \r
76 }\r
77 \r
78 \r
79 btCompoundShape* btFractureBody::shiftTransform(btCompoundShape* boxCompound,btScalar* masses,btTransform& shift, btVector3& principalInertia)\r
80 {\r
81         btTransform principal;\r
82 \r
83         boxCompound->calculatePrincipalAxisTransform(masses,principal,principalInertia);\r
84 \r
85 \r
86         ///create a new compound with world transform/center of mass properly aligned with the principal axis\r
87 \r
88         ///non-recursive compound shapes perform better\r
89         \r
90 #ifdef USE_RECURSIVE_COMPOUND\r
91 \r
92         btCompoundShape* newCompound = new btCompoundShape();\r
93         newCompound->addChildShape(principal.inverse(),boxCompound);\r
94         newBoxCompound = newCompound;\r
95         //m_collisionShapes.push_back(newCompound);\r
96 \r
97         //btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);\r
98         //btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,newCompound,principalInertia);\r
99 \r
100 #else\r
101 #ifdef CHANGE_COMPOUND_INPLACE\r
102         newBoxCompound = boxCompound;\r
103         for (int i=0;i<boxCompound->getNumChildShapes();i++)\r
104         {\r
105                 btTransform newChildTransform = principal.inverse()*boxCompound->getChildTransform(i);\r
106                 ///updateChildTransform is really slow, because it re-calculates the AABB each time. todo: add option to disable this update\r
107                 boxCompound->updateChildTransform(i,newChildTransform);\r
108         }\r
109         bool isDynamic = (mass != 0.f);\r
110         btVector3 localInertia(0,0,0);\r
111         if (isDynamic)\r
112                 boxCompound->calculateLocalInertia(mass,localInertia);\r
113         \r
114 #else\r
115         ///creation is faster using a new compound to store the shifted children\r
116         btCompoundShape* newBoxCompound = new btCompoundShape();\r
117         for (int i=0;i<boxCompound->getNumChildShapes();i++)\r
118         {\r
119                 btTransform newChildTransform = principal.inverse()*boxCompound->getChildTransform(i);\r
120                 ///updateChildTransform is really slow, because it re-calculates the AABB each time. todo: add option to disable this update\r
121                 newBoxCompound->addChildShape(newChildTransform,boxCompound->getChildShape(i));\r
122         }\r
123 \r
124 \r
125 \r
126 #endif\r
127 \r
128 #endif//USE_RECURSIVE_COMPOUND\r
129 \r
130         shift = principal;\r
131         return newBoxCompound;\r
132 }\r
133 \r
134 \r
135 \r
136 \r
137 \r
138 \r