Blender  V3.3
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 #include "btGImpactShape.h"
22 #include "btGImpactMassUtil.h"
23 
25 {
26  // moved from .h to .cpp because of conditional compilation
27  // (The setting of BT_THREADSAFE may differ between various cpp files, so it is best to
28  // avoid using it in h files)
29  m_primitive_manager.m_meshInterface = meshInterface;
32 #if BT_THREADSAFE
33  // If threadsafe is requested, this object uses a different lock/unlock
34  // model with the btStridingMeshInterface -- lock once when the object is constructed
35  // and unlock once in the destructor.
36  // The other way of locking and unlocking for each collision check in the narrowphase
37  // is not threadsafe. Note these are not thread-locks, they are calls to the meshInterface's
38  // getLockedReadOnlyVertexIndexBase virtual function, which by default just returns a couple of
39  // pointers. In theory a client could override the lock function to do all sorts of
40  // things like reading data from GPU memory, or decompressing data on the fly, but such things
41  // do not seem all that likely or useful, given the performance cost.
43 #endif
44 }
45 
47 {
48  // moved from .h to .cpp because of conditional compilation
49 #if BT_THREADSAFE
51 #endif
52 }
53 
55 {
56  // moved from .h to .cpp because of conditional compilation
57 #if !BT_THREADSAFE
58  // called in the narrowphase -- not threadsafe!
59  void* dummy = (void*)(m_box_set.getPrimitiveManager());
60  TrimeshPrimitiveManager* dummymanager = static_cast<TrimeshPrimitiveManager*>(dummy);
61  dummymanager->lock();
62 #endif
63 }
64 
66 {
67  // moved from .h to .cpp because of conditional compilation
68 #if !BT_THREADSAFE
69  // called in the narrowphase -- not threadsafe!
70  void* dummy = (void*)(m_box_set.getPrimitiveManager());
71  TrimeshPrimitiveManager* dummymanager = static_cast<TrimeshPrimitiveManager*>(dummy);
72  dummymanager->unlock();
73 #endif
74 }
75 
76 #define CALC_EXACT_INERTIA 1
77 
79 {
81 #ifdef CALC_EXACT_INERTIA
82  inertia.setValue(0.f, 0.f, 0.f);
83 
84  int i = this->getNumChildShapes();
85  btScalar shapemass = mass / btScalar(i);
86 
87  while (i--)
88  {
89  btVector3 temp_inertia;
90  m_childShapes[i]->calculateLocalInertia(shapemass, temp_inertia);
92  {
93  inertia = gim_inertia_add_transformed(inertia, temp_inertia, m_childTransforms[i]);
94  }
95  else
96  {
97  inertia = gim_inertia_add_transformed(inertia, temp_inertia, btTransform::getIdentity());
98  }
99  }
100 
101 #else
102 
103  // Calc box inertia
104 
105  btScalar lx = m_localAABB.m_max[0] - m_localAABB.m_min[0];
106  btScalar ly = m_localAABB.m_max[1] - m_localAABB.m_min[1];
107  btScalar lz = m_localAABB.m_max[2] - m_localAABB.m_min[2];
108  const btScalar x2 = lx * lx;
109  const btScalar y2 = ly * ly;
110  const btScalar z2 = lz * lz;
111  const btScalar scaledmass = mass * btScalar(0.08333333);
112 
113  inertia = scaledmass * (btVector3(y2 + z2, x2 + z2, x2 + y2));
114 
115 #endif
117 }
118 
120 {
121  lockChildShapes();
122 
123 #ifdef CALC_EXACT_INERTIA
124  inertia.setValue(0.f, 0.f, 0.f);
125 
126  int i = this->getVertexCount();
127  btScalar pointmass = mass / btScalar(i);
128 
129  while (i--)
130  {
131  btVector3 pointintertia;
132  this->getVertex(i, pointintertia);
133  pointintertia = gim_get_point_inertia(pointintertia, pointmass);
134  inertia += pointintertia;
135  }
136 
137 #else
138 
139  // Calc box inertia
140 
141  btScalar lx = m_localAABB.m_max[0] - m_localAABB.m_min[0];
142  btScalar ly = m_localAABB.m_max[1] - m_localAABB.m_min[1];
143  btScalar lz = m_localAABB.m_max[2] - m_localAABB.m_min[2];
144  const btScalar x2 = lx * lx;
145  const btScalar y2 = ly * ly;
146  const btScalar z2 = lz * lz;
147  const btScalar scaledmass = mass * btScalar(0.08333333);
148 
149  inertia = scaledmass * (btVector3(y2 + z2, x2 + z2, x2 + y2));
150 
151 #endif
152 
154 }
155 
157 {
158 #ifdef CALC_EXACT_INERTIA
159  inertia.setValue(0.f, 0.f, 0.f);
160 
161  int i = this->getMeshPartCount();
162  btScalar partmass = mass / btScalar(i);
163 
164  while (i--)
165  {
166  btVector3 partinertia;
167  getMeshPart(i)->calculateLocalInertia(partmass, partinertia);
168  inertia += partinertia;
169  }
170 
171 #else
172 
173  // Calc box inertia
174 
175  btScalar lx = m_localAABB.m_max[0] - m_localAABB.m_min[0];
176  btScalar ly = m_localAABB.m_max[1] - m_localAABB.m_min[1];
177  btScalar lz = m_localAABB.m_max[2] - m_localAABB.m_min[2];
178  const btScalar x2 = lx * lx;
179  const btScalar y2 = ly * ly;
180  const btScalar z2 = lz * lz;
181  const btScalar scaledmass = mass * btScalar(0.08333333);
182 
183  inertia = scaledmass * (btVector3(y2 + z2, x2 + z2, x2 + y2));
184 
185 #endif
186 }
187 
188 void btGImpactMeshShape::rayTest(const btVector3& rayFrom, const btVector3& rayTo, btCollisionWorld::RayResultCallback& resultCallback) const
189 {
190 }
191 
193 {
194  lockChildShapes();
195 
196  btAlignedObjectArray<int> collided;
197  btVector3 rayDir(rayTo - rayFrom);
198  rayDir.normalize();
199  m_box_set.rayQuery(rayDir, rayFrom, collided);
200 
201  if (collided.size() == 0)
202  {
204  return;
205  }
206 
207  int part = (int)getPart();
208  btPrimitiveTriangle triangle;
209  int i = collided.size();
210  while (i--)
211  {
212  getPrimitiveTriangle(collided[i], triangle);
213  callback->processTriangle(triangle.m_vertices, part, collided[i]);
214  }
216 }
217 
219 {
220  lockChildShapes();
221  btAABB box;
222  box.m_min = aabbMin;
223  box.m_max = aabbMax;
224 
225  btAlignedObjectArray<int> collided;
226  m_box_set.boxQuery(box, collided);
227 
228  if (collided.size() == 0)
229  {
231  return;
232  }
233 
234  int part = (int)getPart();
235  btPrimitiveTriangle triangle;
236  int i = collided.size();
237  while (i--)
238  {
239  this->getPrimitiveTriangle(collided[i], triangle);
240  callback->processTriangle(triangle.m_vertices, part, collided[i]);
241  }
243 }
244 
246 {
247  int i = m_mesh_parts.size();
248  while (i--)
249  {
250  m_mesh_parts[i]->processAllTriangles(callback, aabbMin, aabbMax);
251  }
252 }
253 
255 {
256  int i = m_mesh_parts.size();
257  while (i--)
258  {
259  m_mesh_parts[i]->processAllTrianglesRay(callback, rayFrom, rayTo);
260  }
261 }
262 
264 const char* btGImpactMeshShape::serialize(void* dataBuffer, btSerializer* serializer) const
265 {
266  btGImpactMeshShapeData* trimeshData = (btGImpactMeshShapeData*)dataBuffer;
267 
268  btCollisionShape::serialize(&trimeshData->m_collisionShapeData, serializer);
269 
270  m_meshInterface->serialize(&trimeshData->m_meshInterface, serializer);
271 
272  trimeshData->m_collisionMargin = float(m_collisionMargin);
273 
274  localScaling.serializeFloat(trimeshData->m_localScaling);
275 
276  trimeshData->m_gimpactSubType = int(getGImpactShapeType());
277 
278  return "btGImpactMeshShapeData";
279 }
typedef float(TangentPoint)[2]
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble x2
btAABB
Axis aligned box.
btScalar m_collisionMargin
SIMD_FORCE_INLINE btVector3 gim_inertia_add_transformed(const btVector3 &source_inertia, const btVector3 &added_inertia, const btTransform &transform)
SIMD_FORCE_INLINE btVector3 gim_get_point_inertia(const btVector3 &point, btScalar mass)
static const btMatrix3x3 & getIdentity()
Definition: btMatrix3x3.h:350
virtual bool serialize(void *o_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian) const
Data buffer MUST be 16 byte aligned.
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:314
btStridingMeshInterface
btVector3
btVector3 can be used to represent 3D points and vectors. It has an un-used w component to suit 16-by...
Definition: btVector3.h:82
SIMD_FORCE_INLINE int size() const
return the number of elements in the array
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.
SIMD_FORCE_INLINE int getPart() const
virtual void calculateLocalInertia(btScalar mass, btVector3 &inertia) const
SIMD_FORCE_INLINE int getVertexCount() const
SIMD_FORCE_INLINE void getVertex(int vertex_index, btVector3 &vertex) const
virtual void processAllTrianglesRay(btTriangleCallback *callback, const btVector3 &rayFrom, const btVector3 &rayTo) const
Function for retrieve triangles.
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
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.
btGImpactMeshShapePart * getMeshPart(int index)
virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType() const
Base method for determinig which kind of GIMPACT shape we get.
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
SIMD_FORCE_INLINE btPrimitiveManagerBase * getPrimitiveManager() const
bool boxQuery(const btAABB &box, btAlignedObjectArray< int > &collided_results) const
returns the indices of the primitives in the m_primitive_manager
SIMD_FORCE_INLINE void setPrimitiveManager(btPrimitiveManagerBase *primitive_manager)
SIMD_FORCE_INLINE 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
DEGForeachIDComponentCallback callback
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