Bullet Collision Detection & Physics Library
SpuContactResult.cpp
Go to the documentation of this file.
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
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 "SpuContactResult.h"
17 
18 //#define DEBUG_SPU_COLLISION_DETECTION 1
19 
20 #ifdef DEBUG_SPU_COLLISION_DETECTION
21 #ifndef __SPU__
22 #include <stdio.h>
23 #define spu_printf printf
24 #endif
25 #endif //DEBUG_SPU_COLLISION_DETECTION
26 
28 {
30  m_spuManifold = NULL;
31  m_RequiresWriteBack = false;
32 }
33 
35 {
37 }
38 
41 {
42  btScalar friction = friction0*friction1;
43 
44  const btScalar MAX_FRICTION = btScalar(10.);
45 
46  if (friction < -MAX_FRICTION)
47  friction = -MAX_FRICTION;
48  if (friction > MAX_FRICTION)
49  friction = MAX_FRICTION;
50  return friction;
51 
52 }
53 
54 inline btScalar calculateCombinedRestitution(btScalar restitution0,btScalar restitution1)
55 {
56  return restitution0*restitution1;
57 }
58 
59 
60 
61  void SpuContactResult::setContactInfo(btPersistentManifold* spuManifold, ppu_address_t manifoldAddress,const btTransform& worldTrans0,const btTransform& worldTrans1, btScalar restitution0,btScalar restitution1, btScalar friction0,btScalar friction1, bool isSwapped)
62  {
63  //spu_printf("SpuContactResult::setContactInfo ManifoldAddress: %lu\n", manifoldAddress);
64  m_rootWorldTransform0 = worldTrans0;
65  m_rootWorldTransform1 = worldTrans1;
66  m_manifoldAddress = manifoldAddress;
67  m_spuManifold = spuManifold;
68 
69  m_combinedFriction = calculateCombinedFriction(friction0,friction1);
70  m_combinedRestitution = calculateCombinedRestitution(restitution0,restitution1);
71  m_isSwapped = isSwapped;
72  }
73 
74  void SpuContactResult::setShapeIdentifiersA(int partId0,int index0)
75  {
76 
77  }
78 
79  void SpuContactResult::setShapeIdentifiersB(int partId1,int index1)
80  {
81 
82  }
83 
84 
85 
87 bool ManifoldResultAddContactPoint(const btVector3& normalOnBInWorld,
88  const btVector3& pointInWorld,
89  float depth,
90  btPersistentManifold* manifoldPtr,
91  btTransform& transA,
92  btTransform& transB,
93  btScalar combinedFriction,
94  btScalar combinedRestitution,
95  bool isSwapped)
96 {
97 
98 // float contactTreshold = manifoldPtr->getContactBreakingThreshold();
99 
100  //spu_printf("SPU: add contactpoint, depth:%f, contactTreshold %f, manifoldPtr %llx\n",depth,contactTreshold,manifoldPtr);
101 
102 #ifdef DEBUG_SPU_COLLISION_DETECTION
103  spu_printf("SPU: contactTreshold %f\n",contactTreshold);
104 #endif //DEBUG_SPU_COLLISION_DETECTION
105  if (depth > manifoldPtr->getContactBreakingThreshold())
106  return false;
107 
108  //if (depth > manifoldPtr->getContactProcessingThreshold())
109  // return false;
110 
111 
112 
113  btVector3 pointA;
114  btVector3 localA;
115  btVector3 localB;
116  btVector3 normal;
117 
118 
119  if (isSwapped)
120  {
121  normal = normalOnBInWorld * -1;
122  pointA = pointInWorld + normal * depth;
123  localA = transA.invXform(pointA );
124  localB = transB.invXform(pointInWorld);
125  }
126  else
127  {
128  normal = normalOnBInWorld;
129  pointA = pointInWorld + normal * depth;
130  localA = transA.invXform(pointA );
131  localB = transB.invXform(pointInWorld);
132  }
133 
134  btManifoldPoint newPt(localA,localB,normal,depth);
135  newPt.m_positionWorldOnA = pointA;
136  newPt.m_positionWorldOnB = pointInWorld;
137 
138  newPt.m_combinedFriction = combinedFriction;
139  newPt.m_combinedRestitution = combinedRestitution;
140 
141 
142  int insertIndex = manifoldPtr->getCacheEntry(newPt);
143  if (insertIndex >= 0)
144  {
145  // we need to replace the current contact point, otherwise small errors will accumulate (spheres start rolling etc)
146  manifoldPtr->replaceContactPoint(newPt,insertIndex);
147  return true;
148 
149  } else
150  {
151 
152  /*
154  //User can override friction and/or restitution
155  if (gContactAddedCallback &&
156  //and if either of the two bodies requires custom material
157  ((m_body0->m_collisionFlags & btCollisionObject::customMaterialCallback) ||
158  (m_body1->m_collisionFlags & btCollisionObject::customMaterialCallback)))
159  {
160  //experimental feature info, for per-triangle material etc.
161  (*gContactAddedCallback)(newPt,m_body0,m_partId0,m_index0,m_body1,m_partId1,m_index1);
162  }
163  */
164 
165  manifoldPtr->addManifoldPoint(newPt);
166  return true;
167 
168  }
169  return false;
170 
171 }
172 
173 
175 {
178 #if defined (__SPU__) || defined (USE_LIBSPE2)
179  memcpy(g_manifoldDmaExport.getFront(),lsManifold,sizeof(btPersistentManifold));
180 
182  ppu_address_t mmAddr = (ppu_address_t)mmManifold;
184  // Should there be any kind of wait here? What if somebody tries to use this tag again? What if we call this function again really soon?
185  //no, the swapBuffers does the wait
186 #endif
187 }
188 
189 void SpuContactResult::addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)
190 {
191 #ifdef DEBUG_SPU_COLLISION_DETECTION
192  spu_printf("*** SpuContactResult::addContactPoint: depth = %f\n",depth);
193  spu_printf("*** normal = %f,%f,%f\n",normalOnBInWorld.getX(),normalOnBInWorld.getY(),normalOnBInWorld.getZ());
194  spu_printf("*** position = %f,%f,%f\n",pointInWorld.getX(),pointInWorld.getY(),pointInWorld.getZ());
195 #endif //DEBUG_SPU_COLLISION_DETECTION
196 
197 
198 #ifdef DEBUG_SPU_COLLISION_DETECTION
199  // int sman = sizeof(rage::phManifold);
200 // spu_printf("sizeof_manifold = %i\n",sman);
201 #endif //DEBUG_SPU_COLLISION_DETECTION
202 
203  btPersistentManifold* localManifold = m_spuManifold;
204 
205  btVector3 normalB(normalOnBInWorld.getX(),normalOnBInWorld.getY(),normalOnBInWorld.getZ());
206  btVector3 pointWrld(pointInWorld.getX(),pointInWorld.getY(),pointInWorld.getZ());
207 
208  //process the contact point
209  const bool retVal = ManifoldResultAddContactPoint(normalB,
210  pointWrld,
211  depth,
212  localManifold,
217  m_isSwapped);
219 }
220 
222 {
223 
225  {
227  m_RequiresWriteBack = true;
228  }
229 
230 
232  {
233 #ifdef DEBUG_SPU_COLLISION_DETECTION
234  spu_printf("SPU: Start SpuContactResult::flush (Put) DMA\n");
235  spu_printf("Num contacts:%d\n", m_spuManifold->getNumContacts());
236  spu_printf("Manifold address: %llu\n", m_manifoldAddress);
237 #endif //DEBUG_SPU_COLLISION_DETECTION
238  // spu_printf("writeDoubleBufferedManifold\n");
240 #ifdef DEBUG_SPU_COLLISION_DETECTION
241  spu_printf("SPU: Finished (Put) DMA\n");
242 #endif //DEBUG_SPU_COLLISION_DETECTION
243  }
244  m_spuManifold = NULL;
245  m_RequiresWriteBack = false;
246 }
247 
248 
void backBufferDmaPut(uint64_t ea, unsigned int numBytes, unsigned int tag)
btPersistentManifold is a contact point cache, it stays persistent as long as objects are overlapping...
int getCacheEntry(const btManifoldPoint &newPoint) const
DoubleBuffer< btPersistentManifold, 1 > g_manifoldDmaExport
void refreshContactPoints(const btTransform &trA, const btTransform &trB)
calculated new worldspace coordinates and depth, and reject points that exceed the collision margin ...
btScalar getContactBreakingThreshold() const
bool ManifoldResultAddContactPoint(const btVector3 &normalOnBInWorld, const btVector3 &pointInWorld, float depth, btPersistentManifold *manifoldPtr, btTransform &transA, btTransform &transB, btScalar combinedFriction, btScalar combinedRestitution, bool isSwapped)
return true if it requires a dma transfer back
btScalar m_combinedRestitution
btScalar calculateCombinedFriction(btScalar friction0, btScalar friction1)
User can override this material combiner by implementing gContactAddedCallback and setting body0->m_c...
#define spu_printf
uint32_t ppu_address_t
ManifoldContactPoint collects and maintains persistent contactpoints.
btScalar m_combinedRestitution
#define DMA_TAG(a)
Definition: SpuFakeDma.h:112
const btScalar & getZ() const
Return the z value.
Definition: btVector3.h:565
void writeDoubleBufferedManifold(btPersistentManifold *lsManifold, btPersistentManifold *mmManifold)
btPersistentManifold * m_spuManifold
btTransform m_rootWorldTransform0
btVector3 m_positionWorldOnB
btTransform m_rootWorldTransform1
const btScalar & getY() const
Return the y value.
Definition: btVector3.h:563
const btScalar & getX() const
Return the x value.
Definition: btVector3.h:561
btVector3 m_positionWorldOnA
m_positionWorldOnA is redundant information, see getPositionWorldOnA(), but for clarity ...
btVector3 invXform(const btVector3 &inVec) const
Definition: btTransform.h:223
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:83
virtual ~SpuContactResult()
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition: btTransform.h:34
virtual void addContactPoint(const btVector3 &normalOnBInWorld, const btVector3 &pointInWorld, btScalar depth)
btScalar m_combinedFriction
btScalar calculateCombinedRestitution(btScalar restitution0, btScalar restitution1)
btScalar m_combinedFriction
virtual void setShapeIdentifiersA(int partId0, int index0)
setShapeIdentifiersA/B provides experimental support for per-triangle material / custom material comb...
void setContactInfo(btPersistentManifold *spuManifold, ppu_address_t manifoldAddress, const btTransform &worldTrans0, const btTransform &worldTrans1, btScalar restitution0, btScalar restitution1, btScalar friction0, btScalar friction01, bool isSwapped)
void replaceContactPoint(const btManifoldPoint &newPoint, int insertIndex)
int addManifoldPoint(const btManifoldPoint &newPoint, bool isPredictive=false)
ppu_address_t m_manifoldAddress
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:266
virtual void setShapeIdentifiersB(int partId1, int index1)