Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/physics/src/bullet/BulletMultiThreaded/SpuGatheringCollisionDispatcher.cpp @ 1967

Last change on this file since 1967 was 1966, checked in by rgrieder, 16 years ago

Let's go for multithreaded physics!

  • Property svn:eol-style set to native
File size: 7.4 KB
Line 
1/*
2Bullet Continuous Collision Detection and Physics Library
3Copyright (c) 2003-2007 Erwin Coumans  http://bulletphysics.com
4
5This software is provided 'as-is', without any express or implied warranty.
6In no event will the authors be held liable for any damages arising from the use of this software.
7Permission is granted to anyone to use this software for any purpose,
8including commercial applications, and to alter it and redistribute it freely,
9subject to the following restrictions:
10
111. 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.
122. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
133. This notice may not be removed or altered from any source distribution.
14*/
15
16#include "SpuGatheringCollisionDispatcher.h"
17#include "SpuCollisionTaskProcess.h"
18
19
20#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
21#include "BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h"
22#include "SpuContactManifoldCollisionAlgorithm.h"
23#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
24#include "BulletCollision/CollisionShapes/btCollisionShape.h"
25
26
27
28
29SpuGatheringCollisionDispatcher::SpuGatheringCollisionDispatcher(class  btThreadSupportInterface*       threadInterface, unsigned int   maxNumOutstandingTasks,btCollisionConfiguration* collisionConfiguration)
30:btCollisionDispatcher(collisionConfiguration),
31m_spuCollisionTaskProcess(0),
32m_threadInterface(threadInterface),
33m_maxNumOutstandingTasks(maxNumOutstandingTasks)
34{
35       
36}
37
38
39bool    SpuGatheringCollisionDispatcher::supportsDispatchPairOnSpu(int proxyType0,int proxyType1)
40{
41        bool supported0 = (
42                (proxyType0 == BOX_SHAPE_PROXYTYPE) ||
43                (proxyType0 == TRIANGLE_SHAPE_PROXYTYPE) ||
44                (proxyType0 == SPHERE_SHAPE_PROXYTYPE) ||
45                (proxyType0 == CAPSULE_SHAPE_PROXYTYPE) ||
46                (proxyType0 == CYLINDER_SHAPE_PROXYTYPE) ||
47//              (proxyType0 == CONE_SHAPE_PROXYTYPE) ||
48                (proxyType0 == TRIANGLE_MESH_SHAPE_PROXYTYPE) ||
49                (proxyType0 == CONVEX_HULL_SHAPE_PROXYTYPE)||
50                (proxyType0 == COMPOUND_SHAPE_PROXYTYPE)
51                );
52
53        bool supported1 = (
54                (proxyType1 == BOX_SHAPE_PROXYTYPE) ||
55                (proxyType1 == TRIANGLE_SHAPE_PROXYTYPE) ||
56                (proxyType1 == SPHERE_SHAPE_PROXYTYPE) ||
57                (proxyType1 == CAPSULE_SHAPE_PROXYTYPE) ||
58                (proxyType1 == CYLINDER_SHAPE_PROXYTYPE) ||
59//              (proxyType1 == CONE_SHAPE_PROXYTYPE) ||
60                (proxyType1 == TRIANGLE_MESH_SHAPE_PROXYTYPE) ||
61                (proxyType1 == CONVEX_HULL_SHAPE_PROXYTYPE) ||
62                (proxyType1 == COMPOUND_SHAPE_PROXYTYPE)
63                );
64
65        return supported0 && supported1;
66}
67
68
69
70SpuGatheringCollisionDispatcher::~SpuGatheringCollisionDispatcher()
71{
72        if (m_spuCollisionTaskProcess)
73                delete m_spuCollisionTaskProcess;
74       
75}
76
77#include "stdio.h"
78
79
80
81///interface for iterating all overlapping collision pairs, no matter how those pairs are stored (array, set, map etc)
82///this is useful for the collision dispatcher.
83class btSpuCollisionPairCallback : public btOverlapCallback
84{
85        const btDispatcherInfo& m_dispatchInfo;
86        SpuGatheringCollisionDispatcher*        m_dispatcher;
87
88public:
89
90        btSpuCollisionPairCallback(const btDispatcherInfo& dispatchInfo, SpuGatheringCollisionDispatcher*       dispatcher)
91        :m_dispatchInfo(dispatchInfo),
92        m_dispatcher(dispatcher)
93        {
94        }
95
96        virtual bool    processOverlap(btBroadphasePair& collisionPair)
97        {
98
99
100                //PPU version
101                //(*m_dispatcher->getNearCallback())(collisionPair,*m_dispatcher,m_dispatchInfo);
102
103                //only support discrete collision detection for now, we could fallback on PPU/unoptimized version for TOI/CCD
104                btAssert(m_dispatchInfo.m_dispatchFunc == btDispatcherInfo::DISPATCH_DISCRETE);
105
106                //by default, Bullet will use this near callback
107                {
108                        ///userInfo is used to determine if the SPU has to handle this case or not (skip PPU tasks)
109                        if (!collisionPair.m_userInfo)
110                        {
111                                collisionPair.m_userInfo = (void*) 1;
112                        }
113                        if (!collisionPair.m_algorithm)
114                        {
115                                btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject;
116                                btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject;
117
118                                btCollisionAlgorithmConstructionInfo ci;
119                                ci.m_dispatcher1 = m_dispatcher;
120                                ci.m_manifold = 0;
121
122                                if (m_dispatcher->needsCollision(colObj0,colObj1))
123                                {
124                                        int     proxyType0 = colObj0->getCollisionShape()->getShapeType();
125                                        int     proxyType1 = colObj1->getCollisionShape()->getShapeType();
126                                        if (m_dispatcher->supportsDispatchPairOnSpu(proxyType0,proxyType1))
127                                        {
128                                                int so = sizeof(SpuContactManifoldCollisionAlgorithm);
129                                                void* mem = m_dispatcher->allocateCollisionAlgorithm(so);
130                                                collisionPair.m_algorithm = new(mem) SpuContactManifoldCollisionAlgorithm(ci,colObj0,colObj1);
131                                                collisionPair.m_userInfo = (void*) 2;
132                                        } else
133                                        {
134                                                collisionPair.m_algorithm = m_dispatcher->findAlgorithm(colObj0,colObj1);
135                                                collisionPair.m_userInfo = (void*)3;
136                                        }
137                                } 
138                        }
139                }
140                return false;
141        }
142};
143
144void    SpuGatheringCollisionDispatcher::dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,const btDispatcherInfo& dispatchInfo, btDispatcher* dispatcher) 
145{
146
147        if (dispatchInfo.m_enableSPU)
148        {
149                if (!m_spuCollisionTaskProcess)
150                        m_spuCollisionTaskProcess = new SpuCollisionTaskProcess(m_threadInterface,m_maxNumOutstandingTasks);
151       
152                m_spuCollisionTaskProcess->initialize2(dispatchInfo.m_useEpa);
153       
154                ///modified version of btCollisionDispatcher::dispatchAllCollisionPairs:
155                {
156                        btSpuCollisionPairCallback      collisionCallback(dispatchInfo,this);
157
158                        pairCache->processAllOverlappingPairs(&collisionCallback,dispatcher);
159                }
160
161                //send one big batch
162                int numTotalPairs = pairCache->getNumOverlappingPairs();
163                btBroadphasePair* pairPtr = pairCache->getOverlappingPairArrayPtr();
164                int i;
165                for (i=0;i<numTotalPairs;)
166                {
167                        //Performance Hint: tweak this number during benchmarking
168                        static const int pairRange = SPU_BATCHSIZE_BROADPHASE_PAIRS;
169                        int endIndex = (i+pairRange) < numTotalPairs ? i+pairRange : numTotalPairs;
170                        m_spuCollisionTaskProcess->addWorkToTask(pairPtr,i,endIndex);
171                        i = endIndex;
172                }
173
174                //handle PPU fallback pairs
175                for (i=0;i<numTotalPairs;i++)
176                {
177                        btBroadphasePair& collisionPair = pairPtr[i];
178                        if (collisionPair.m_userInfo == (void*)3)
179                        {
180                                if (collisionPair.m_algorithm)
181                                {
182                                        btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject;
183                                        btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject;
184
185                                        if (dispatcher->needsCollision(colObj0,colObj1))
186                                        {
187                                                btManifoldResult contactPointResult(colObj0,colObj1);
188                                               
189                                                if (dispatchInfo.m_dispatchFunc ==              btDispatcherInfo::DISPATCH_DISCRETE)
190                                                {
191                                                        //discrete collision detection query
192                                                        collisionPair.m_algorithm->processCollision(colObj0,colObj1,dispatchInfo,&contactPointResult);
193                                                } else
194                                                {
195                                                        //continuous collision detection query, time of impact (toi)
196                                                        btScalar toi = collisionPair.m_algorithm->calculateTimeOfImpact(colObj0,colObj1,dispatchInfo,&contactPointResult);
197                                                        if (dispatchInfo.m_timeOfImpact > toi)
198                                                                dispatchInfo.m_timeOfImpact = toi;
199
200                                                }
201                                        }
202                                }
203                        }
204                }
205
206                //make sure all SPU work is done
207                m_spuCollisionTaskProcess->flush2();
208
209        } else
210        {
211                ///PPU fallback
212                ///!Need to make sure to clear all 'algorithms' when switching between SPU and PPU
213                btCollisionDispatcher::dispatchAllCollisionPairs(pairCache,dispatchInfo,dispatcher);
214        }
215}
Note: See TracBrowser for help on using the repository browser.