Bullet Collision Detection & Physics Library
btGImpactShape.cpp
Go to the documentation of this file.
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 
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)
31  m_primitive_manager.m_meshInterface = meshInterface;
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 {
128  lockChildShapes();
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 
197 void btGImpactMeshShape::rayTest(const btVector3& rayFrom, const btVector3& rayTo, btCollisionWorld::RayResultCallback& resultCallback) const
198 {
199 }
200 
202 {
203  lockChildShapes();
204 
205  btAlignedObjectArray<int> collided;
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 
227 void btGImpactMeshShapePart::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
228 {
229  lockChildShapes();
230  btAABB box;
231  box.m_min = aabbMin;
232  box.m_max = aabbMax;
233 
234  btAlignedObjectArray<int> collided;
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 
255 void 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 
264 void btGImpactMeshShape::processAllTrianglesRay(btTriangleCallback* callback,const btVector3& rayFrom, const btVector3& rayTo) const
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 
275 const 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 
virtual bool childrenHasTransform() const
if true, then its children must get transforms.
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
Definition: btVector3.h:652
virtual void rayTest(const btVector3 &rayFrom, const btVector3 &rayTo, btCollisionWorld::RayResultCallback &resultCallback) const
virtual method for ray collision
virtual void unlockChildShapes() const
btVector3 m_max
void getVertex(int vertex_index, btVector3 &vertex) const
virtual void calculateLocalInertia(btScalar mass, btVector3 &inertia) const
virtual void processTriangle(btVector3 *triangle, int partId, int triangleIndex)=0
btScalar m_collisionMargin
RayResultCallback is used to report new raycast results.
virtual void calculateLocalInertia(btScalar mass, btVector3 &inertia) const
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
btVector3 m_min
virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType() const
Subshape member functions.
btGImpactBoxSet m_box_set
btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
Definition: btVector3.h:309
int size() const
return the number of elements in the array
The btTriangleCallback provides a callback for each overlapping triangle when calling processAllTrian...
virtual void processAllTrianglesRay(btTriangleCallback *callback, const btVector3 &rayFrom, const btVector3 &rayTo) const
Function for retrieve triangles.
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.
btVector3 gim_inertia_add_transformed(const btVector3 &source_inertia, const btVector3 &added_inertia, const btTransform &transform)
virtual void processAllTriangles(btTriangleCallback *callback, const btVector3 &aabbMin, const btVector3 &aabbMax) const
Function for retrieve triangles.
btStridingMeshInterfaceData m_meshInterface
TrimeshPrimitiveManager m_primitive_manager
virtual const char * serialize(void *dataBuffer, btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
void setPrimitiveManager(btPrimitiveManagerBase *primitive_manager)
Axis aligned box.
void serializeFloat(struct btVector3FloatData &dataOut) const
Definition: btVector3.h:1324
btCollisionShapeData m_collisionShapeData
btPrimitiveManagerBase * getPrimitiveManager() const
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:83
The btStridingMeshInterface is the interface class for high performance generic access to triangle me...
static const btTransform & getIdentity()
Return an identity transform.
Definition: btTransform.h:203
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 ...
btVector3 gim_get_point_inertia(const btVector3 &point, btScalar mass)
virtual void lockChildShapes() const
call when reading child shapes
virtual void calculateLocalInertia(btScalar mass, btVector3 &inertia) const
Calculates the exact inertia tensor for this shape.
bool boxQuery(const btAABB &box, btAlignedObjectArray< int > &collided_results) const
returns the indices of the primitives in the m_primitive_manager
void getPrimitiveTriangle(int index, btPrimitiveTriangle &triangle) const
if this trimesh
btVector3FloatData m_localScaling
virtual void processAllTrianglesRay(btTriangleCallback *callback, const btVector3 &rayFrom, const btVector3 &rayTo) const
Function for retrieve triangles.
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:292
virtual const char * serialize(void *dataBuffer, btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
int getVertexCount() const