Bullet Collision Detection & Physics Library
btGImpactShape.cpp
Go to the documentation of this file.
1/*
2This source file is part of GIMPACT Library.
3
4For the latest info, see http://gimpact.sourceforge.net/
5
6Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371.
7email: projectileman@yahoo.com
8
9
10This software is provided 'as-is', without any express or implied warranty.
11In no event will the authors be held liable for any damages arising from the use of this software.
12Permission is granted to anyone to use this software for any purpose,
13including commercial applications, and to alter it and redistribute it freely,
14subject to the following restrictions:
15
161. 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.
172. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
183. 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
27{
28 // moved from .h to .cpp because of conditional compilation
29 // (The setting of BT_THREADSAFE may differ between various cpp files, so it is best to
30 // avoid using it in h files)
34#if BT_THREADSAFE
35 // If threadsafe is requested, this object uses a different lock/unlock
36 // model with the btStridingMeshInterface -- lock once when the object is constructed
37 // and unlock once in the destructor.
38 // The other way of locking and unlocking for each collision check in the narrowphase
39 // is not threadsafe. Note these are not thread-locks, they are calls to the meshInterface's
40 // getLockedReadOnlyVertexIndexBase virtual function, which by default just returns a couple of
41 // pointers. In theory a client could override the lock function to do all sorts of
42 // things like reading data from GPU memory, or decompressing data on the fly, but such things
43 // do not seem all that likely or useful, given the performance cost.
45#endif
46}
47
49{
50 // moved from .h to .cpp because of conditional compilation
51#if BT_THREADSAFE
53#endif
54}
55
57{
58 // moved from .h to .cpp because of conditional compilation
59#if ! BT_THREADSAFE
60 // called in the narrowphase -- not threadsafe!
61 void * dummy = (void*) ( m_box_set.getPrimitiveManager() );
62 TrimeshPrimitiveManager * dummymanager = static_cast<TrimeshPrimitiveManager *>( dummy );
63 dummymanager->lock();
64#endif
65}
66
68{
69 // moved from .h to .cpp because of conditional compilation
70#if ! BT_THREADSAFE
71 // called in the narrowphase -- not threadsafe!
72 void * dummy = (void*) ( m_box_set.getPrimitiveManager() );
73 TrimeshPrimitiveManager * dummymanager = static_cast<TrimeshPrimitiveManager *>( dummy );
74 dummymanager->unlock();
75#endif
76}
77
78
79#define CALC_EXACT_INERTIA 1
80
81
83{
85#ifdef CALC_EXACT_INERTIA
86 inertia.setValue(0.f,0.f,0.f);
87
88 int i = this->getNumChildShapes();
89 btScalar shapemass = mass/btScalar(i);
90
91 while(i--)
92 {
93 btVector3 temp_inertia;
94 m_childShapes[i]->calculateLocalInertia(shapemass,temp_inertia);
96 {
97 inertia = gim_inertia_add_transformed( inertia,temp_inertia,m_childTransforms[i]);
98 }
99 else
100 {
101 inertia = gim_inertia_add_transformed( inertia,temp_inertia,btTransform::getIdentity());
102 }
103
104 }
105
106#else
107
108 // Calc box inertia
109
113 const btScalar x2 = lx*lx;
114 const btScalar y2 = ly*ly;
115 const btScalar z2 = lz*lz;
116 const btScalar scaledmass = mass * btScalar(0.08333333);
117
118 inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2));
119
120#endif
122}
123
124
125
127{
129
130
131#ifdef CALC_EXACT_INERTIA
132 inertia.setValue(0.f,0.f,0.f);
133
134 int i = this->getVertexCount();
135 btScalar pointmass = mass/btScalar(i);
136
137 while(i--)
138 {
139 btVector3 pointintertia;
140 this->getVertex(i,pointintertia);
141 pointintertia = gim_get_point_inertia(pointintertia,pointmass);
142 inertia+=pointintertia;
143 }
144
145#else
146
147 // Calc box inertia
148
152 const btScalar x2 = lx*lx;
153 const btScalar y2 = ly*ly;
154 const btScalar z2 = lz*lz;
155 const btScalar scaledmass = mass * btScalar(0.08333333);
156
157 inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2));
158
159#endif
160
162}
163
165{
166
167#ifdef CALC_EXACT_INERTIA
168 inertia.setValue(0.f,0.f,0.f);
169
170 int i = this->getMeshPartCount();
171 btScalar partmass = mass/btScalar(i);
172
173 while(i--)
174 {
175 btVector3 partinertia;
176 getMeshPart(i)->calculateLocalInertia(partmass,partinertia);
177 inertia+=partinertia;
178 }
179
180#else
181
182 // Calc box inertia
183
187 const btScalar x2 = lx*lx;
188 const btScalar y2 = ly*ly;
189 const btScalar z2 = lz*lz;
190 const btScalar scaledmass = mass * btScalar(0.08333333);
191
192 inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2));
193
194#endif
195}
196
197void btGImpactMeshShape::rayTest(const btVector3& rayFrom, const btVector3& rayTo, btCollisionWorld::RayResultCallback& resultCallback) const
198{
199}
200
202{
204
206 btVector3 rayDir(rayTo - rayFrom);
207 rayDir.normalize();
208 m_box_set.rayQuery(rayDir, rayFrom, collided);
209
210 if(collided.size()==0)
211 {
213 return;
214 }
215
216 int part = (int)getPart();
217 btPrimitiveTriangle triangle;
218 int i = collided.size();
219 while(i--)
220 {
221 getPrimitiveTriangle(collided[i],triangle);
222 callback->processTriangle(triangle.m_vertices,part,collided[i]);
223 }
225}
226
228{
230 btAABB box;
231 box.m_min = aabbMin;
232 box.m_max = aabbMax;
233
235 m_box_set.boxQuery(box,collided);
236
237 if(collided.size()==0)
238 {
240 return;
241 }
242
243 int part = (int)getPart();
244 btPrimitiveTriangle triangle;
245 int i = collided.size();
246 while(i--)
247 {
248 this->getPrimitiveTriangle(collided[i],triangle);
249 callback->processTriangle(triangle.m_vertices,part,collided[i]);
250 }
252
253}
254
255void btGImpactMeshShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
256{
257 int i = m_mesh_parts.size();
258 while(i--)
259 {
260 m_mesh_parts[i]->processAllTriangles(callback,aabbMin,aabbMax);
261 }
262}
263
265{
266 int i = m_mesh_parts.size();
267 while(i--)
268 {
269 m_mesh_parts[i]->processAllTrianglesRay(callback, rayFrom, rayTo);
270 }
271}
272
273
275const char* btGImpactMeshShape::serialize(void* dataBuffer, btSerializer* serializer) const
276{
277 btGImpactMeshShapeData* trimeshData = (btGImpactMeshShapeData*) dataBuffer;
278
279 btCollisionShape::serialize(&trimeshData->m_collisionShapeData,serializer);
280
281 m_meshInterface->serialize(&trimeshData->m_meshInterface, serializer);
282
283 trimeshData->m_collisionMargin = float(m_collisionMargin);
284
286
287 trimeshData->m_gimpactSubType = int(getGImpactShapeType());
288
289 return "btGImpactMeshShapeData";
290}
291
btVector3 gim_get_point_inertia(const btVector3 &point, btScalar mass)
btVector3 gim_inertia_add_transformed(const btVector3 &source_inertia, const btVector3 &added_inertia, const btTransform &transform)
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:292
Axis aligned box.
btVector3 m_min
btVector3 m_max
The btAlignedObjectArray template class uses a subset of the stl::vector interface for its methods It...
int size() const
return the number of elements in the array
virtual const char * serialize(void *dataBuffer, btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
btScalar m_collisionMargin
virtual void calculateLocalInertia(btScalar mass, btVector3 &inertia) const
Calculates the exact inertia tensor for this shape.
btAlignedObjectArray< btTransform > m_childTransforms
btAlignedObjectArray< btCollisionShape * > m_childShapes
virtual bool childrenHasTransform() const
if true, then its children must get transforms.
virtual int getNumChildShapes() const
Gets the number of children.
virtual void processAllTriangles(btTriangleCallback *callback, const btVector3 &aabbMin, const btVector3 &aabbMax) const
Function for retrieve triangles.
virtual void calculateLocalInertia(btScalar mass, btVector3 &inertia) const
virtual void processAllTrianglesRay(btTriangleCallback *callback, const btVector3 &rayFrom, const btVector3 &rayTo) const
Function for retrieve triangles.
void getVertex(int vertex_index, btVector3 &vertex) const
TrimeshPrimitiveManager m_primitive_manager
virtual void lockChildShapes() const
call when reading child shapes
virtual void unlockChildShapes() const
int getMeshPartCount() const
virtual void rayTest(const btVector3 &rayFrom, const btVector3 &rayTo, btCollisionWorld::RayResultCallback &resultCallback) const
virtual method for ray collision
virtual void calculateLocalInertia(btScalar mass, btVector3 &inertia) const
btGImpactMeshShapePart * getMeshPart(int index)
btStridingMeshInterface * m_meshInterface
virtual void processAllTriangles(btTriangleCallback *callback, const btVector3 &aabbMin, const btVector3 &aabbMax) const
Function for retrieve triangles.
virtual void processAllTrianglesRay(btTriangleCallback *callback, const btVector3 &rayFrom, const btVector3 &rayTo) const
Function for retrieve triangles.
virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType() const
Subshape member functions.
btAlignedObjectArray< btGImpactMeshShapePart * > m_mesh_parts
virtual const char * serialize(void *dataBuffer, btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
bool rayQuery(const btVector3 &ray_dir, const btVector3 &ray_origin, btAlignedObjectArray< int > &collided_results) const
returns the indices of the primitives in the m_primitive_manager
btPrimitiveManagerBase * getPrimitiveManager() const
bool boxQuery(const btAABB &box, btAlignedObjectArray< int > &collided_results) const
returns the indices of the primitives in the m_primitive_manager
void setPrimitiveManager(btPrimitiveManagerBase *primitive_manager)
void getPrimitiveTriangle(int index, btPrimitiveTriangle &triangle) const
if this trimesh
virtual void lockChildShapes() const
call when reading child shapes
btGImpactBoxSet m_box_set
virtual void unlockChildShapes() const
The btStridingMeshInterface is the interface class for high performance generic access to triangle me...
virtual const char * serialize(void *dataBuffer, btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
static const btTransform & getIdentity()
Return an identity transform.
Definition: btTransform.h:203
The btTriangleCallback provides a callback for each overlapping triangle when calling processAllTrian...
virtual void processTriangle(btVector3 *triangle, int partId, int triangleIndex)=0
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:84
void serializeFloat(struct btVector3FloatData &dataOut) const
Definition: btVector3.h:1323
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
Definition: btVector3.h:652
btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
Definition: btVector3.h:309
RayResultCallback is used to report new raycast results.
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
btCollisionShapeData m_collisionShapeData
btStridingMeshInterfaceData m_meshInterface
btVector3FloatData m_localScaling