[dali_2.3.21] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-physics / third-party / bullet3 / 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 void btGhostObject::addOverlappingObjectInternal(btBroadphaseProxy* otherProxy, btBroadphaseProxy* thisProxy)
33 {
34         btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject;
35         btAssert(otherObject);
36         ///if this linearSearch becomes too slow (too many overlapping objects) we should add a more appropriate data structure
37         int index = m_overlappingObjects.findLinearSearch(otherObject);
38         if (index == m_overlappingObjects.size())
39         {
40                 //not found
41                 m_overlappingObjects.push_back(otherObject);
42         }
43 }
44
45 void btGhostObject::removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy, btDispatcher* dispatcher, btBroadphaseProxy* thisProxy)
46 {
47         btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject;
48         btAssert(otherObject);
49         int index = m_overlappingObjects.findLinearSearch(otherObject);
50         if (index < m_overlappingObjects.size())
51         {
52                 m_overlappingObjects[index] = m_overlappingObjects[m_overlappingObjects.size() - 1];
53                 m_overlappingObjects.pop_back();
54         }
55 }
56
57 btPairCachingGhostObject::btPairCachingGhostObject()
58 {
59         m_hashPairCache = new (btAlignedAlloc(sizeof(btHashedOverlappingPairCache), 16)) btHashedOverlappingPairCache();
60 }
61
62 btPairCachingGhostObject::~btPairCachingGhostObject()
63 {
64         m_hashPairCache->~btHashedOverlappingPairCache();
65         btAlignedFree(m_hashPairCache);
66 }
67
68 void btPairCachingGhostObject::addOverlappingObjectInternal(btBroadphaseProxy* otherProxy, btBroadphaseProxy* thisProxy)
69 {
70         btBroadphaseProxy* actualThisProxy = thisProxy ? thisProxy : getBroadphaseHandle();
71         btAssert(actualThisProxy);
72
73         btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject;
74         btAssert(otherObject);
75         int index = m_overlappingObjects.findLinearSearch(otherObject);
76         if (index == m_overlappingObjects.size())
77         {
78                 m_overlappingObjects.push_back(otherObject);
79                 m_hashPairCache->addOverlappingPair(actualThisProxy, otherProxy);
80         }
81 }
82
83 void btPairCachingGhostObject::removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy, btDispatcher* dispatcher, btBroadphaseProxy* thisProxy1)
84 {
85         btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject;
86         btBroadphaseProxy* actualThisProxy = thisProxy1 ? thisProxy1 : getBroadphaseHandle();
87         btAssert(actualThisProxy);
88
89         btAssert(otherObject);
90         int index = m_overlappingObjects.findLinearSearch(otherObject);
91         if (index < m_overlappingObjects.size())
92         {
93                 m_overlappingObjects[index] = m_overlappingObjects[m_overlappingObjects.size() - 1];
94                 m_overlappingObjects.pop_back();
95                 m_hashPairCache->removeOverlappingPair(actualThisProxy, otherProxy, dispatcher);
96         }
97 }
98
99 void btGhostObject::convexSweepTest(const btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, btCollisionWorld::ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration) const
100 {
101         btTransform convexFromTrans, convexToTrans;
102         convexFromTrans = convexFromWorld;
103         convexToTrans = convexToWorld;
104         btVector3 castShapeAabbMin, castShapeAabbMax;
105         /* Compute AABB that encompasses angular movement */
106         {
107                 btVector3 linVel, angVel;
108                 btTransformUtil::calculateVelocity(convexFromTrans, convexToTrans, 1.0, linVel, angVel);
109                 btTransform R;
110                 R.setIdentity();
111                 R.setRotation(convexFromTrans.getRotation());
112                 castShape->calculateTemporalAabb(R, linVel, angVel, 1.0, castShapeAabbMin, castShapeAabbMax);
113         }
114
115         /// go over all objects, and if the ray intersects their aabb + cast shape aabb,
116         // do a ray-shape query using convexCaster (CCD)
117         int i;
118         for (i = 0; i < m_overlappingObjects.size(); i++)
119         {
120                 btCollisionObject* collisionObject = m_overlappingObjects[i];
121                 //only perform raycast if filterMask matches
122                 if (resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
123                 {
124                         //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
125                         btVector3 collisionObjectAabbMin, collisionObjectAabbMax;
126                         collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(), collisionObjectAabbMin, collisionObjectAabbMax);
127                         AabbExpand(collisionObjectAabbMin, collisionObjectAabbMax, castShapeAabbMin, castShapeAabbMax);
128                         btScalar hitLambda = btScalar(1.);  //could use resultCallback.m_closestHitFraction, but needs testing
129                         btVector3 hitNormal;
130                         if (btRayAabb(convexFromWorld.getOrigin(), convexToWorld.getOrigin(), collisionObjectAabbMin, collisionObjectAabbMax, hitLambda, hitNormal))
131                         {
132                                 btCollisionWorld::objectQuerySingle(castShape, convexFromTrans, convexToTrans,
133                                                                                                         collisionObject,
134                                                                                                         collisionObject->getCollisionShape(),
135                                                                                                         collisionObject->getWorldTransform(),
136                                                                                                         resultCallback,
137                                                                                                         allowedCcdPenetration);
138                         }
139                 }
140         }
141 }
142
143 void btGhostObject::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const
144 {
145         btTransform rayFromTrans;
146         rayFromTrans.setIdentity();
147         rayFromTrans.setOrigin(rayFromWorld);
148         btTransform rayToTrans;
149         rayToTrans.setIdentity();
150         rayToTrans.setOrigin(rayToWorld);
151
152         int i;
153         for (i = 0; i < m_overlappingObjects.size(); i++)
154         {
155                 btCollisionObject* collisionObject = m_overlappingObjects[i];
156                 //only perform raycast if filterMask matches
157                 if (resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
158                 {
159                         btCollisionWorld::rayTestSingle(rayFromTrans, rayToTrans,
160                                                                                         collisionObject,
161                                                                                         collisionObject->getCollisionShape(),
162                                                                                         collisionObject->getWorldTransform(),
163                                                                                         resultCallback);
164                 }
165         }
166 }