1 /*
2 This source file is part of GIMPACT Library.
3
4 For the latest info, see http://gimpact.sourceforge.net/
5
6 Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371.
7 email: projectileman@yahoo.com
8
9
10 This software is provided 'as-is', without any express or implied warranty.
11 In no event will the authors be held liable for any damages arising from the use of this software.
12 Permission is granted to anyone to use this software for any purpose,
13 including commercial applications, and to alter it and redistribute it freely,
14 subject to the following restrictions:
15
16 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.
17 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
18 3. This notice may not be removed or altered from any source distribution.
19 */
20
21
22 #include "btGImpactShape.h"
23 #include "btGImpactMassUtil.h"
24
25
26 #define CALC_EXACT_INERTIA 1
27
28
calculateLocalInertia(btScalar mass,btVector3 & inertia) const29 void btGImpactCompoundShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
30 {
31 lockChildShapes();
32 #ifdef CALC_EXACT_INERTIA
33 inertia.setValue(0.f,0.f,0.f);
34
35 int i = this->getNumChildShapes();
36 btScalar shapemass = mass/btScalar(i);
37
38 while(i--)
39 {
40 btVector3 temp_inertia;
41 m_childShapes[i]->calculateLocalInertia(shapemass,temp_inertia);
42 if(childrenHasTransform())
43 {
44 inertia = gim_inertia_add_transformed( inertia,temp_inertia,m_childTransforms[i]);
45 }
46 else
47 {
48 inertia = gim_inertia_add_transformed( inertia,temp_inertia,btTransform::getIdentity());
49 }
50
51 }
52
53 #else
54
55 // Calc box inertia
56
57 btScalar lx= m_localAABB.m_max[0] - m_localAABB.m_min[0];
58 btScalar ly= m_localAABB.m_max[1] - m_localAABB.m_min[1];
59 btScalar lz= m_localAABB.m_max[2] - m_localAABB.m_min[2];
60 const btScalar x2 = lx*lx;
61 const btScalar y2 = ly*ly;
62 const btScalar z2 = lz*lz;
63 const btScalar scaledmass = mass * btScalar(0.08333333);
64
65 inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2));
66
67 #endif
68 unlockChildShapes();
69 }
70
71
72
calculateLocalInertia(btScalar mass,btVector3 & inertia) const73 void btGImpactMeshShapePart::calculateLocalInertia(btScalar mass,btVector3& inertia) const
74 {
75 lockChildShapes();
76
77
78 #ifdef CALC_EXACT_INERTIA
79 inertia.setValue(0.f,0.f,0.f);
80
81 int i = this->getVertexCount();
82 btScalar pointmass = mass/btScalar(i);
83
84 while(i--)
85 {
86 btVector3 pointintertia;
87 this->getVertex(i,pointintertia);
88 pointintertia = gim_get_point_inertia(pointintertia,pointmass);
89 inertia+=pointintertia;
90 }
91
92 #else
93
94 // Calc box inertia
95
96 btScalar lx= m_localAABB.m_max[0] - m_localAABB.m_min[0];
97 btScalar ly= m_localAABB.m_max[1] - m_localAABB.m_min[1];
98 btScalar lz= m_localAABB.m_max[2] - m_localAABB.m_min[2];
99 const btScalar x2 = lx*lx;
100 const btScalar y2 = ly*ly;
101 const btScalar z2 = lz*lz;
102 const btScalar scaledmass = mass * btScalar(0.08333333);
103
104 inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2));
105
106 #endif
107
108 unlockChildShapes();
109 }
110
calculateLocalInertia(btScalar mass,btVector3 & inertia) const111 void btGImpactMeshShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
112 {
113
114 #ifdef CALC_EXACT_INERTIA
115 inertia.setValue(0.f,0.f,0.f);
116
117 int i = this->getMeshPartCount();
118 btScalar partmass = mass/btScalar(i);
119
120 while(i--)
121 {
122 btVector3 partinertia;
123 getMeshPart(i)->calculateLocalInertia(partmass,partinertia);
124 inertia+=partinertia;
125 }
126
127 #else
128
129 // Calc box inertia
130
131 btScalar lx= m_localAABB.m_max[0] - m_localAABB.m_min[0];
132 btScalar ly= m_localAABB.m_max[1] - m_localAABB.m_min[1];
133 btScalar lz= m_localAABB.m_max[2] - m_localAABB.m_min[2];
134 const btScalar x2 = lx*lx;
135 const btScalar y2 = ly*ly;
136 const btScalar z2 = lz*lz;
137 const btScalar scaledmass = mass * btScalar(0.08333333);
138
139 inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2));
140
141 #endif
142 }
143
rayTest(const btVector3 & rayFrom,const btVector3 & rayTo,btCollisionWorld::RayResultCallback & resultCallback) const144 void btGImpactMeshShape::rayTest(const btVector3& rayFrom, const btVector3& rayTo, btCollisionWorld::RayResultCallback& resultCallback) const
145 {
146 }
147
processAllTrianglesRay(btTriangleCallback * callback,const btVector3 & rayFrom,const btVector3 & rayTo) const148 void btGImpactMeshShapePart::processAllTrianglesRay(btTriangleCallback* callback,const btVector3& rayFrom, const btVector3& rayTo) const
149 {
150 lockChildShapes();
151
152 btAlignedObjectArray<int> collided;
153 btVector3 rayDir(rayTo - rayFrom);
154 rayDir.normalize();
155 m_box_set.rayQuery(rayDir, rayFrom, collided);
156
157 if(collided.size()==0)
158 {
159 unlockChildShapes();
160 return;
161 }
162
163 int part = (int)getPart();
164 btPrimitiveTriangle triangle;
165 int i = collided.size();
166 while(i--)
167 {
168 getPrimitiveTriangle(collided[i],triangle);
169 callback->processTriangle(triangle.m_vertices,part,collided[i]);
170 }
171 unlockChildShapes();
172 }
173
processAllTriangles(btTriangleCallback * callback,const btVector3 & aabbMin,const btVector3 & aabbMax) const174 void btGImpactMeshShapePart::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
175 {
176 lockChildShapes();
177 btAABB box;
178 box.m_min = aabbMin;
179 box.m_max = aabbMax;
180
181 btAlignedObjectArray<int> collided;
182 m_box_set.boxQuery(box,collided);
183
184 if(collided.size()==0)
185 {
186 unlockChildShapes();
187 return;
188 }
189
190 int part = (int)getPart();
191 btPrimitiveTriangle triangle;
192 int i = collided.size();
193 while(i--)
194 {
195 this->getPrimitiveTriangle(collided[i],triangle);
196 callback->processTriangle(triangle.m_vertices,part,collided[i]);
197 }
198 unlockChildShapes();
199
200 }
201
processAllTriangles(btTriangleCallback * callback,const btVector3 & aabbMin,const btVector3 & aabbMax) const202 void btGImpactMeshShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
203 {
204 int i = m_mesh_parts.size();
205 while(i--)
206 {
207 m_mesh_parts[i]->processAllTriangles(callback,aabbMin,aabbMax);
208 }
209 }
210
processAllTrianglesRay(btTriangleCallback * callback,const btVector3 & rayFrom,const btVector3 & rayTo) const211 void btGImpactMeshShape::processAllTrianglesRay(btTriangleCallback* callback,const btVector3& rayFrom, const btVector3& rayTo) const
212 {
213 int i = m_mesh_parts.size();
214 while(i--)
215 {
216 m_mesh_parts[i]->processAllTrianglesRay(callback, rayFrom, rayTo);
217 }
218 }
219
220
221 ///fills the dataBuffer and returns the struct name (and 0 on failure)
serialize(void * dataBuffer,btSerializer * serializer) const222 const char* btGImpactMeshShape::serialize(void* dataBuffer, btSerializer* serializer) const
223 {
224 btGImpactMeshShapeData* trimeshData = (btGImpactMeshShapeData*) dataBuffer;
225
226 btCollisionShape::serialize(&trimeshData->m_collisionShapeData,serializer);
227
228 m_meshInterface->serialize(&trimeshData->m_meshInterface, serializer);
229
230 trimeshData->m_collisionMargin = float(m_collisionMargin);
231
232 localScaling.serializeFloat(trimeshData->m_localScaling);
233
234 trimeshData->m_gimpactSubType = int(getGImpactShapeType());
235
236 return "btGImpactMeshShapeData";
237 }
238
239