2
Bullet Continuous Collision Detection and Physics Library
3
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
5
This software is provided 'as-is', without any express or implied warranty.
6
In no event will the authors be held liable for any damages arising from the use of this software.
7
Permission is granted to anyone to use this software for any purpose,
8
including commercial applications, and to alter it and redistribute it freely,
9
subject to the following restrictions:
11
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.
12
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13
3. This notice may not be removed or altered from any source distribution.
16
#include "CollisionWorld.h"
17
#include "CollisionDispatcher.h"
18
#include "CollisionDispatch/CollisionObject.h"
19
#include "CollisionShapes/CollisionShape.h"
20
#include "CollisionShapes/SphereShape.h" //for raycasting
21
#include "CollisionShapes/TriangleMeshShape.h" //for raycasting
22
#include "NarrowPhaseCollision/RaycastCallback.h"
24
#include "NarrowPhaseCollision/SubSimplexConvexCast.h"
25
#include "BroadphaseCollision/BroadphaseInterface.h"
26
#include "AabbUtil2.h"
30
CollisionWorld::~CollisionWorld()
32
//clean up remaining objects
33
std::vector<CollisionObject*>::iterator i;
36
for (i=m_collisionObjects.begin();
37
!(i==m_collisionObjects.end()); i++)
40
CollisionObject* collisionObject= (*i);
42
BroadphaseProxy* bp = collisionObject->m_broadphaseHandle;
46
// only clear the cached algorithms
48
GetBroadphase()->CleanProxyFromPairs(bp);
49
GetBroadphase()->DestroyProxy(bp);
55
void CollisionWorld::UpdateActivationState()
57
m_dispatcher->InitUnionFind(m_collisionObjects.size());
59
// put the index into m_controllers into m_tag
61
std::vector<CollisionObject*>::iterator i;
64
for (i=m_collisionObjects.begin();
65
!(i==m_collisionObjects.end()); i++)
68
CollisionObject* collisionObject= (*i);
69
collisionObject->m_islandTag1 = index;
70
collisionObject->m_hitFraction = 1.f;
77
m_dispatcher->FindUnions();
85
void CollisionWorld::StoreIslandActivationState()
87
// put the islandId ('find' value) into m_tag
89
UnionFind& unionFind = m_dispatcher->GetUnionFind();
91
std::vector<CollisionObject*>::iterator i;
94
for (i=m_collisionObjects.begin();
95
!(i==m_collisionObjects.end()); i++)
97
CollisionObject* collisionObject= (*i);
99
if (collisionObject->mergesSimulationIslands())
101
collisionObject->m_islandTag1 = unionFind.find(index);
104
collisionObject->m_islandTag1 = -1;
115
void CollisionWorld::AddCollisionObject(CollisionObject* collisionObject)
117
m_collisionObjects.push_back(collisionObject);
120
SimdTransform trans = collisionObject->m_worldTransform;
124
collisionObject->m_collisionShape->GetAabb(trans,minAabb,maxAabb);
126
int type = collisionObject->m_collisionShape->GetShapeType();
127
collisionObject->m_broadphaseHandle = GetBroadphase()->CreateProxy(
139
void CollisionWorld::PerformDiscreteCollisionDetection()
141
DispatcherInfo dispatchInfo;
142
dispatchInfo.m_timeStep = 0.f;
143
dispatchInfo.m_stepCount = 0;
145
//update aabb (of all moved objects)
147
SimdVector3 aabbMin,aabbMax;
148
for (size_t i=0;i<m_collisionObjects.size();i++)
150
m_collisionObjects[i]->m_collisionShape->GetAabb(m_collisionObjects[i]->m_worldTransform,aabbMin,aabbMax);
151
m_broadphase->SetAabb(m_collisionObjects[i]->m_broadphaseHandle,aabbMin,aabbMax);
154
m_broadphase->DispatchAllCollisionPairs(*GetDispatcher(),dispatchInfo);
158
void CollisionWorld::RemoveCollisionObject(CollisionObject* collisionObject)
162
//bool removeFromBroadphase = false;
166
BroadphaseProxy* bp = collisionObject->m_broadphaseHandle;
170
// only clear the cached algorithms
172
GetBroadphase()->CleanProxyFromPairs(bp);
173
GetBroadphase()->DestroyProxy(bp);
174
collisionObject->m_broadphaseHandle = 0;
179
std::vector<CollisionObject*>::iterator i = std::find(m_collisionObjects.begin(), m_collisionObjects.end(), collisionObject);
181
if (!(i == m_collisionObjects.end()))
183
std::swap(*i, m_collisionObjects.back());
184
m_collisionObjects.pop_back();
190
void CollisionWorld::RayTest(const SimdVector3& rayFromWorld, const SimdVector3& rayToWorld, RayResultCallback& resultCallback)
194
SimdTransform rayFromTrans,rayToTrans;
195
rayFromTrans.setIdentity();
196
rayFromTrans.setOrigin(rayFromWorld);
197
rayToTrans.setIdentity();
199
rayToTrans.setOrigin(rayToWorld);
201
//do culling based on aabb (rayFrom/rayTo)
202
SimdVector3 rayAabbMin = rayFromWorld;
203
SimdVector3 rayAabbMax = rayFromWorld;
204
rayAabbMin.setMin(rayToWorld);
205
rayAabbMax.setMax(rayToWorld);
207
SphereShape pointShape(0.0f);
209
/// brute force go over all objects. Once there is a broadphase, use that, or
210
/// add a raycast against aabb first.
212
std::vector<CollisionObject*>::iterator iter;
214
for (iter=m_collisionObjects.begin();
215
!(iter==m_collisionObjects.end()); iter++)
218
CollisionObject* collisionObject= (*iter);
220
//RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
221
SimdVector3 collisionObjectAabbMin,collisionObjectAabbMax;
222
collisionObject->m_collisionShape->GetAabb(collisionObject->m_worldTransform,collisionObjectAabbMin,collisionObjectAabbMax);
226
if (TestAabbAgainstAabb2(rayAabbMin,rayAabbMax,collisionObjectAabbMin,collisionObjectAabbMax))
228
if (collisionObject->m_collisionShape->IsConvex())
230
ConvexCast::CastResult castResult;
231
castResult.m_fraction = 1.f;//??
233
ConvexShape* convexShape = (ConvexShape*) collisionObject->m_collisionShape;
234
VoronoiSimplexSolver simplexSolver;
235
SubsimplexConvexCast convexCaster(&pointShape,convexShape,&simplexSolver);
236
//GjkConvexCast convexCaster(&pointShape,convexShape,&simplexSolver);
237
//ContinuousConvexCollision convexCaster(&pointShape,convexShape,&simplexSolver,0);
239
if (convexCaster.calcTimeOfImpact(rayFromTrans,rayToTrans,collisionObject->m_worldTransform,collisionObject->m_worldTransform,castResult))
242
if (castResult.m_normal.length2() > 0.0001f)
244
castResult.m_normal.normalize();
245
if (castResult.m_fraction < resultCallback.m_closestHitFraction)
249
CollisionWorld::LocalRayResult localRayResult
254
castResult.m_fraction
257
resultCallback.AddSingleResult(localRayResult);
266
if (collisionObject->m_collisionShape->IsConcave())
269
TriangleMeshShape* triangleMesh = (TriangleMeshShape*)collisionObject->m_collisionShape;
271
SimdTransform worldTocollisionObject = collisionObject->m_worldTransform.inverse();
273
SimdVector3 rayFromLocal = worldTocollisionObject * rayFromTrans.getOrigin();
274
SimdVector3 rayToLocal = worldTocollisionObject * rayToTrans.getOrigin();
276
//ConvexCast::CastResult
278
struct BridgeTriangleRaycastCallback : public TriangleRaycastCallback
280
RayResultCallback* m_resultCallback;
281
CollisionObject* m_collisionObject;
282
TriangleMeshShape* m_triangleMesh;
284
BridgeTriangleRaycastCallback( const SimdVector3& from,const SimdVector3& to,
285
RayResultCallback* resultCallback, CollisionObject* collisionObject,TriangleMeshShape* triangleMesh):
286
TriangleRaycastCallback(from,to),
287
m_resultCallback(resultCallback),
288
m_collisionObject(collisionObject),
289
m_triangleMesh(triangleMesh)
294
virtual float ReportHit(const SimdVector3& hitNormalLocal, float hitFraction, int partId, int triangleIndex )
296
CollisionWorld::LocalShapeInfo shapeInfo;
297
shapeInfo.m_shapePart = partId;
298
shapeInfo.m_triangleIndex = triangleIndex;
300
CollisionWorld::LocalRayResult rayResult
306
return m_resultCallback->AddSingleResult(rayResult);
314
BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,triangleMesh);
315
rcb.m_hitFraction = resultCallback.m_closestHitFraction;
317
SimdVector3 rayAabbMinLocal = rayFromLocal;
318
rayAabbMinLocal.setMin(rayToLocal);
319
SimdVector3 rayAabbMaxLocal = rayFromLocal;
320
rayAabbMaxLocal.setMax(rayToLocal);
322
triangleMesh->ProcessAllTriangles(&rcb,rayAabbMinLocal,rayAabbMaxLocal);