Imported Upstream version 2.81
[platform/upstream/libbullet.git] / src / BulletCollision / CollisionDispatch / btGhostObject.cpp
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2008 Erwin Coumans  http://bulletphysics.com
4
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:
10
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.
14 */
15
16 #include "btGhostObject.h"
17 #include "btCollisionWorld.h"
18 #include "BulletCollision/CollisionShapes/btConvexShape.h"
19 #include "LinearMath/btAabbUtil2.h"
20
21 btGhostObject::btGhostObject()
22 {
23         m_internalType = CO_GHOST_OBJECT;
24 }
25
26 btGhostObject::~btGhostObject()
27 {
28         ///btGhostObject should have been removed from the world, so no overlapping objects
29         btAssert(!m_overlappingObjects.size());
30 }
31
32
33 void btGhostObject::addOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btBroadphaseProxy* thisProxy)
34 {
35         btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject;
36         btAssert(otherObject);
37         ///if this linearSearch becomes too slow (too many overlapping objects) we should add a more appropriate data structure
38         int index = m_overlappingObjects.findLinearSearch(otherObject);
39         if (index==m_overlappingObjects.size())
40         {
41                 //not found
42                 m_overlappingObjects.push_back(otherObject);
43         }
44 }
45
46 void btGhostObject::removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher,btBroadphaseProxy* thisProxy)
47 {
48         btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject;
49         btAssert(otherObject);
50         int index = m_overlappingObjects.findLinearSearch(otherObject);
51         if (index<m_overlappingObjects.size())
52         {
53                 m_overlappingObjects[index] = m_overlappingObjects[m_overlappingObjects.size()-1];
54                 m_overlappingObjects.pop_back();
55         }
56 }
57
58
59 btPairCachingGhostObject::btPairCachingGhostObject()
60 {
61         m_hashPairCache = new (btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16)) btHashedOverlappingPairCache();
62 }
63
64 btPairCachingGhostObject::~btPairCachingGhostObject()
65 {
66         m_hashPairCache->~btHashedOverlappingPairCache();
67         btAlignedFree( m_hashPairCache );
68 }
69
70 void btPairCachingGhostObject::addOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btBroadphaseProxy* thisProxy)
71 {
72         btBroadphaseProxy*actualThisProxy = thisProxy ? thisProxy : getBroadphaseHandle();
73         btAssert(actualThisProxy);
74
75         btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject;
76         btAssert(otherObject);
77         int index = m_overlappingObjects.findLinearSearch(otherObject);
78         if (index==m_overlappingObjects.size())
79         {
80                 m_overlappingObjects.push_back(otherObject);
81                 m_hashPairCache->addOverlappingPair(actualThisProxy,otherProxy);
82         }
83 }
84
85 void btPairCachingGhostObject::removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher,btBroadphaseProxy* thisProxy1)
86 {
87         btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject;
88         btBroadphaseProxy* actualThisProxy = thisProxy1 ? thisProxy1 : getBroadphaseHandle();
89         btAssert(actualThisProxy);
90
91         btAssert(otherObject);
92         int index = m_overlappingObjects.findLinearSearch(otherObject);
93         if (index<m_overlappingObjects.size())
94         {
95                 m_overlappingObjects[index] = m_overlappingObjects[m_overlappingObjects.size()-1];
96                 m_overlappingObjects.pop_back();
97                 m_hashPairCache->removeOverlappingPair(actualThisProxy,otherProxy,dispatcher);
98         }
99 }
100
101
102 void    btGhostObject::convexSweepTest(const btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, btCollisionWorld::ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration) const
103 {
104         btTransform     convexFromTrans,convexToTrans;
105         convexFromTrans = convexFromWorld;
106         convexToTrans = convexToWorld;
107         btVector3 castShapeAabbMin, castShapeAabbMax;
108         /* Compute AABB that encompasses angular movement */
109         {
110                 btVector3 linVel, angVel;
111                 btTransformUtil::calculateVelocity (convexFromTrans, convexToTrans, 1.0, linVel, angVel);
112                 btTransform R;
113                 R.setIdentity ();
114                 R.setRotation (convexFromTrans.getRotation());
115                 castShape->calculateTemporalAabb (R, linVel, angVel, 1.0, castShapeAabbMin, castShapeAabbMax);
116         }
117
118         /// go over all objects, and if the ray intersects their aabb + cast shape aabb,
119         // do a ray-shape query using convexCaster (CCD)
120         int i;
121         for (i=0;i<m_overlappingObjects.size();i++)
122         {
123                 btCollisionObject*      collisionObject= m_overlappingObjects[i];
124                 //only perform raycast if filterMask matches
125                 if(resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) {
126                         //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
127                         btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
128                         collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
129                         AabbExpand (collisionObjectAabbMin, collisionObjectAabbMax, castShapeAabbMin, castShapeAabbMax);
130                         btScalar hitLambda = btScalar(1.); //could use resultCallback.m_closestHitFraction, but needs testing
131                         btVector3 hitNormal;
132                         if (btRayAabb(convexFromWorld.getOrigin(),convexToWorld.getOrigin(),collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,hitNormal))
133                         {
134                                 btCollisionWorld::objectQuerySingle(castShape, convexFromTrans,convexToTrans,
135                                         collisionObject,
136                                                 collisionObject->getCollisionShape(),
137                                                 collisionObject->getWorldTransform(),
138                                                 resultCallback,
139                                                 allowedCcdPenetration);
140                         }
141                 }
142         }
143
144 }
145
146 void    btGhostObject::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const
147 {
148         btTransform rayFromTrans;
149         rayFromTrans.setIdentity();
150         rayFromTrans.setOrigin(rayFromWorld);
151         btTransform  rayToTrans;
152         rayToTrans.setIdentity();
153         rayToTrans.setOrigin(rayToWorld);
154
155
156         int i;
157         for (i=0;i<m_overlappingObjects.size();i++)
158         {
159                 btCollisionObject*      collisionObject= m_overlappingObjects[i];
160                 //only perform raycast if filterMask matches
161                 if(resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) 
162                 {
163                         btCollisionWorld::rayTestSingle(rayFromTrans,rayToTrans,
164                                                         collisionObject,
165                                                                 collisionObject->getCollisionShape(),
166                                                                 collisionObject->getWorldTransform(),
167                                                                 resultCallback);
168                 }
169         }
170 }
171