2 This source file is part of GIMPACT Library.
4 For the latest info, see http://gimpact.sourceforge.net/
6 Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371.
7 email: projectileman@yahoo.com
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:
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.
21 #include "btGImpactShape.h"
22 #include "btGImpactMassUtil.h"
24 btGImpactMeshShapePart::btGImpactMeshShapePart(btStridingMeshInterface* meshInterface, int part)
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;
30 m_primitive_manager.m_part = part;
31 m_box_set.setPrimitiveManager(&m_primitive_manager);
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.
42 m_primitive_manager.lock();
46 btGImpactMeshShapePart::~btGImpactMeshShapePart()
48 // moved from .h to .cpp because of conditional compilation
50 m_primitive_manager.unlock();
54 void btGImpactMeshShapePart::lockChildShapes() const
56 // moved from .h to .cpp because of conditional compilation
58 // called in the narrowphase -- not threadsafe!
59 void* dummy = (void*)(m_box_set.getPrimitiveManager());
60 TrimeshPrimitiveManager* dummymanager = static_cast<TrimeshPrimitiveManager*>(dummy);
65 void btGImpactMeshShapePart::unlockChildShapes() const
67 // moved from .h to .cpp because of conditional compilation
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();
76 #define CALC_EXACT_INERTIA 1
78 void btGImpactCompoundShape::calculateLocalInertia(btScalar mass, btVector3& inertia) const
81 #ifdef CALC_EXACT_INERTIA
82 inertia.setValue(0.f, 0.f, 0.f);
84 int i = this->getNumChildShapes();
85 btScalar shapemass = mass / btScalar(i);
89 btVector3 temp_inertia;
90 m_childShapes[i]->calculateLocalInertia(shapemass, temp_inertia);
91 if (childrenHasTransform())
93 inertia = gim_inertia_add_transformed(inertia, temp_inertia, m_childTransforms[i]);
97 inertia = gim_inertia_add_transformed(inertia, temp_inertia, btTransform::getIdentity());
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);
113 inertia = scaledmass * (btVector3(y2 + z2, x2 + z2, x2 + y2));
119 void btGImpactMeshShapePart::calculateLocalInertia(btScalar mass, btVector3& inertia) const
123 #ifdef CALC_EXACT_INERTIA
124 inertia.setValue(0.f, 0.f, 0.f);
126 int i = this->getVertexCount();
127 btScalar pointmass = mass / btScalar(i);
131 btVector3 pointintertia;
132 this->getVertex(i, pointintertia);
133 pointintertia = gim_get_point_inertia(pointintertia, pointmass);
134 inertia += pointintertia;
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);
149 inertia = scaledmass * (btVector3(y2 + z2, x2 + z2, x2 + y2));
156 void btGImpactMeshShape::calculateLocalInertia(btScalar mass, btVector3& inertia) const
158 #ifdef CALC_EXACT_INERTIA
159 inertia.setValue(0.f, 0.f, 0.f);
161 int i = this->getMeshPartCount();
162 btScalar partmass = mass / btScalar(i);
166 btVector3 partinertia;
167 getMeshPart(i)->calculateLocalInertia(partmass, partinertia);
168 inertia += partinertia;
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);
183 inertia = scaledmass * (btVector3(y2 + z2, x2 + z2, x2 + y2));
188 void btGImpactMeshShape::rayTest(const btVector3& rayFrom, const btVector3& rayTo, btCollisionWorld::RayResultCallback& resultCallback) const
192 void btGImpactMeshShapePart::processAllTrianglesRay(btTriangleCallback* callback, const btVector3& rayFrom, const btVector3& rayTo) const
196 btAlignedObjectArray<int> collided;
197 btVector3 rayDir(rayTo - rayFrom);
199 m_box_set.rayQuery(rayDir, rayFrom, collided);
201 if (collided.size() == 0)
207 int part = (int)getPart();
208 btPrimitiveTriangle triangle;
209 int i = collided.size();
212 getPrimitiveTriangle(collided[i], triangle);
213 callback->processTriangle(triangle.m_vertices, part, collided[i]);
218 void btGImpactMeshShapePart::processAllTriangles(btTriangleCallback* callback, const btVector3& aabbMin, const btVector3& aabbMax) const
225 btAlignedObjectArray<int> collided;
226 m_box_set.boxQuery(box, collided);
228 if (collided.size() == 0)
234 int part = (int)getPart();
235 btPrimitiveTriangle triangle;
236 int i = collided.size();
239 this->getPrimitiveTriangle(collided[i], triangle);
240 callback->processTriangle(triangle.m_vertices, part, collided[i]);
245 void btGImpactMeshShape::processAllTriangles(btTriangleCallback* callback, const btVector3& aabbMin, const btVector3& aabbMax) const
247 int i = m_mesh_parts.size();
250 m_mesh_parts[i]->processAllTriangles(callback, aabbMin, aabbMax);
254 void btGImpactMeshShape::processAllTrianglesRay(btTriangleCallback* callback, const btVector3& rayFrom, const btVector3& rayTo) const
256 int i = m_mesh_parts.size();
259 m_mesh_parts[i]->processAllTrianglesRay(callback, rayFrom, rayTo);
263 ///fills the dataBuffer and returns the struct name (and 0 on failure)
264 const char* btGImpactMeshShape::serialize(void* dataBuffer, btSerializer* serializer) const
266 btGImpactMeshShapeData* trimeshData = (btGImpactMeshShapeData*)dataBuffer;
268 btCollisionShape::serialize(&trimeshData->m_collisionShapeData, serializer);
270 m_meshInterface->serialize(&trimeshData->m_meshInterface, serializer);
272 trimeshData->m_collisionMargin = float(m_collisionMargin);
274 localScaling.serializeFloat(trimeshData->m_localScaling);
276 trimeshData->m_gimpactSubType = int(getGImpactShapeType());
278 return "btGImpactMeshShapeData";