1 #define BLAAT
2 #include "RealTimeBullet3CollisionSdk.h"
3 #include "Bullet3Common/b3AlignedObjectArray.h"
4 #include "Bullet3Collision/NarrowPhaseCollision/shared/b3Collidable.h"
5 #include "Bullet3Collision/NarrowPhaseCollision/shared/b3ConvexPolyhedronData.h"
6 #include "Bullet3Collision/BroadPhaseCollision/shared/b3Aabb.h"
7 
8 //convert the opaque pointer to int
9 struct RTB3_ColliderOpaque2Int
10 {
11 	union {
12 		plCollisionObjectHandle m_ptrValue;
13 		int m_intValue;
14 	};
15 };
16 struct RTB3_ShapeOpaque2Int
17 {
18 	union {
19 		plCollisionShapeHandle m_ptrValue;
20 		int m_intValue;
21 	};
22 };
23 
24 enum RTB3ShapeTypes
25 {
26 	RTB3_SHAPE_SPHERE = 0,
27 	RTB3_SHAPE_PLANE,
28 	RTB3_SHAPE_CAPSULE,
29 	MAX_NUM_SINGLE_SHAPE_TYPES,
30 	RTB3_SHAPE_COMPOUND_INTERNAL,
31 
32 };
33 
34 //we start at 1, so that the 0 index is 'invalid' just like a nullptr
35 #define START_COLLIDABLE_INDEX 1
36 #define START_SHAPE_INDEX 1
37 
38 struct RTB3CollisionWorld
39 {
40 	b3AlignedObjectArray<void*> m_collidableUserPointers;
41 	b3AlignedObjectArray<int> m_collidableUserIndices;
42 	b3AlignedObjectArray<b3Float4> m_collidablePositions;
43 	b3AlignedObjectArray<b3Quaternion> m_collidableOrientations;
44 	b3AlignedObjectArray<b3Transform> m_collidableTransforms;
45 
46 	b3AlignedObjectArray<b3Collidable> m_collidables;
47 
48 	b3AlignedObjectArray<b3GpuChildShape> m_childShapes;
49 	b3AlignedObjectArray<b3Aabb> m_localSpaceAabbs;
50 	b3AlignedObjectArray<b3Aabb> m_worldSpaceAabbs;
51 	b3AlignedObjectArray<b3GpuFace> m_planeFaces;
52 	b3AlignedObjectArray<b3CompoundOverlappingPair> m_compoundOverlappingPairs;
53 
54 	union {
55 		int m_nextFreeShapeIndex;
56 		void* m_nextFreeShapePtr;
57 	};
58 	int m_nextFreeCollidableIndex;
59 	int m_nextFreePlaneFaceIndex;
60 
RTB3CollisionWorldRTB3CollisionWorld61 	RTB3CollisionWorld()
62 		: m_nextFreeShapeIndex(START_SHAPE_INDEX),
63 		  m_nextFreeCollidableIndex(START_COLLIDABLE_INDEX),
64 		  m_nextFreePlaneFaceIndex(0)  //this value is never exposed to the user, so we can start from 0
65 	{
66 	}
67 };
68 
69 struct RealTimeBullet3CollisionSdkInternalData
70 {
71 	b3AlignedObjectArray<RTB3CollisionWorld*> m_collisionWorlds;
72 };
73 
RealTimeBullet3CollisionSdk()74 RealTimeBullet3CollisionSdk::RealTimeBullet3CollisionSdk()
75 {
76 	//	int szCol = sizeof(b3Collidable);
77 	//	int szShap = sizeof(b3GpuChildShape);
78 	//	int szComPair = sizeof(b3CompoundOverlappingPair);
79 	m_internalData = new RealTimeBullet3CollisionSdkInternalData;
80 }
81 
~RealTimeBullet3CollisionSdk()82 RealTimeBullet3CollisionSdk::~RealTimeBullet3CollisionSdk()
83 {
84 	delete m_internalData;
85 	m_internalData = 0;
86 }
87 
createCollisionWorld(int maxNumObjsCapacity,int maxNumShapesCapacity,int maxNumPairsCapacity)88 plCollisionWorldHandle RealTimeBullet3CollisionSdk::createCollisionWorld(int maxNumObjsCapacity, int maxNumShapesCapacity, int maxNumPairsCapacity)
89 {
90 	RTB3CollisionWorld* world = new RTB3CollisionWorld();
91 	world->m_collidables.resize(maxNumObjsCapacity + START_COLLIDABLE_INDEX);
92 	world->m_collidablePositions.resize(maxNumObjsCapacity + START_COLLIDABLE_INDEX);
93 	world->m_collidableOrientations.resize(maxNumObjsCapacity + START_COLLIDABLE_INDEX);
94 	world->m_collidableTransforms.resize(maxNumObjsCapacity + START_COLLIDABLE_INDEX);
95 	world->m_collidableUserPointers.resize(maxNumObjsCapacity + START_COLLIDABLE_INDEX);
96 	world->m_collidableUserIndices.resize(maxNumObjsCapacity + START_COLLIDABLE_INDEX);
97 	world->m_childShapes.resize(maxNumShapesCapacity + START_SHAPE_INDEX);
98 	world->m_planeFaces.resize(maxNumShapesCapacity);
99 
100 	world->m_compoundOverlappingPairs.resize(maxNumPairsCapacity);
101 
102 	m_internalData->m_collisionWorlds.push_back(world);
103 	return (plCollisionWorldHandle)world;
104 }
105 
deleteCollisionWorld(plCollisionWorldHandle worldHandle)106 void RealTimeBullet3CollisionSdk::deleteCollisionWorld(plCollisionWorldHandle worldHandle)
107 {
108 	RTB3CollisionWorld* world = (RTB3CollisionWorld*)worldHandle;
109 	int loc = m_internalData->m_collisionWorlds.findLinearSearch(world);
110 	b3Assert(loc >= 0 && loc < m_internalData->m_collisionWorlds.size());
111 	if (loc >= 0 && loc < m_internalData->m_collisionWorlds.size())
112 	{
113 		m_internalData->m_collisionWorlds.remove(world);
114 		delete world;
115 	}
116 }
117 
createSphereShape(plCollisionWorldHandle worldHandle,plReal radius)118 plCollisionShapeHandle RealTimeBullet3CollisionSdk::createSphereShape(plCollisionWorldHandle worldHandle, plReal radius)
119 {
120 	RTB3CollisionWorld* world = (RTB3CollisionWorld*)worldHandle;
121 	b3Assert(world->m_nextFreeShapeIndex < world->m_childShapes.size());
122 	if (world->m_nextFreeShapeIndex < world->m_childShapes.size())
123 	{
124 		b3GpuChildShape& shape = world->m_childShapes[world->m_nextFreeShapeIndex];
125 		shape.m_childPosition.setZero();
126 		shape.m_childOrientation.setValue(0, 0, 0, 1);
127 		shape.m_radius = radius;
128 		shape.m_shapeType = RTB3_SHAPE_SPHERE;
129 		world->m_nextFreeShapeIndex++;
130 		return (plCollisionShapeHandle)world->m_nextFreeShapePtr;
131 	}
132 	return 0;
133 }
134 
createPlaneShape(plCollisionWorldHandle worldHandle,plReal planeNormalX,plReal planeNormalY,plReal planeNormalZ,plReal planeConstant)135 plCollisionShapeHandle RealTimeBullet3CollisionSdk::createPlaneShape(plCollisionWorldHandle worldHandle,
136 																	 plReal planeNormalX,
137 																	 plReal planeNormalY,
138 																	 plReal planeNormalZ,
139 																	 plReal planeConstant)
140 {
141 	RTB3CollisionWorld* world = (RTB3CollisionWorld*)worldHandle;
142 	b3Assert(world->m_nextFreeShapeIndex < world->m_childShapes.size() && world->m_nextFreePlaneFaceIndex < world->m_planeFaces.size());
143 
144 	if (world->m_nextFreeShapeIndex < world->m_childShapes.size() && world->m_nextFreePlaneFaceIndex < world->m_planeFaces.size())
145 	{
146 		b3GpuChildShape& shape = world->m_childShapes[world->m_nextFreeShapeIndex];
147 		shape.m_childPosition.setZero();
148 		shape.m_childOrientation.setValue(0, 0, 0, 1);
149 		world->m_planeFaces[world->m_nextFreePlaneFaceIndex].m_plane = b3MakeVector4(planeNormalX, planeNormalY, planeNormalZ, planeConstant);
150 		shape.m_shapeIndex = world->m_nextFreePlaneFaceIndex++;
151 		shape.m_shapeType = RTB3_SHAPE_PLANE;
152 		world->m_nextFreeShapeIndex++;
153 		return (plCollisionShapeHandle)world->m_nextFreeShapePtr;
154 	}
155 	return 0;
156 }
157 
createCapsuleShape(plCollisionWorldHandle worldHandle,plReal radius,plReal height,int capsuleAxis)158 plCollisionShapeHandle RealTimeBullet3CollisionSdk::createCapsuleShape(plCollisionWorldHandle worldHandle,
159 																	   plReal radius,
160 																	   plReal height,
161 																	   int capsuleAxis)
162 {
163 	RTB3CollisionWorld* world = (RTB3CollisionWorld*)worldHandle;
164 	b3Assert(world->m_nextFreeShapeIndex < world->m_childShapes.size() && world->m_nextFreePlaneFaceIndex < world->m_planeFaces.size());
165 
166 	if (world->m_nextFreeShapeIndex < world->m_childShapes.size() && world->m_nextFreePlaneFaceIndex < world->m_planeFaces.size())
167 	{
168 		b3GpuChildShape& shape = world->m_childShapes[world->m_nextFreeShapeIndex];
169 		shape.m_childPosition.setZero();
170 		shape.m_childOrientation.setValue(0, 0, 0, 1);
171 		shape.m_radius = radius;
172 		shape.m_height = height;
173 		shape.m_shapeIndex = capsuleAxis;
174 		shape.m_shapeType = RTB3_SHAPE_CAPSULE;
175 		world->m_nextFreeShapeIndex++;
176 		return (plCollisionShapeHandle)world->m_nextFreeShapePtr;
177 	}
178 	return 0;
179 }
180 
createCompoundShape(plCollisionWorldHandle worldHandle)181 plCollisionShapeHandle RealTimeBullet3CollisionSdk::createCompoundShape(plCollisionWorldHandle worldHandle)
182 {
183 	RTB3CollisionWorld* world = (RTB3CollisionWorld*)worldHandle;
184 	b3Assert(world->m_nextFreeShapeIndex < world->m_childShapes.size() && world->m_nextFreePlaneFaceIndex < world->m_planeFaces.size());
185 
186 	if (world->m_nextFreeShapeIndex < world->m_childShapes.size() && world->m_nextFreePlaneFaceIndex < world->m_planeFaces.size())
187 	{
188 		b3GpuChildShape& shape = world->m_childShapes[world->m_nextFreeShapeIndex];
189 		shape.m_childPosition.setZero();
190 		shape.m_childOrientation.setValue(0, 0, 0, 1);
191 		shape.m_numChildShapes = 0;
192 		shape.m_shapeType = RTB3_SHAPE_COMPOUND_INTERNAL;
193 		world->m_nextFreeShapeIndex++;
194 		return (plCollisionShapeHandle)world->m_nextFreeShapePtr;
195 	}
196 	return 0;
197 }
198 
addChildShape(plCollisionWorldHandle worldHandle,plCollisionShapeHandle compoundShape,plCollisionShapeHandle childShape,plVector3 childPos,plQuaternion childOrn)199 void RealTimeBullet3CollisionSdk::addChildShape(plCollisionWorldHandle worldHandle, plCollisionShapeHandle compoundShape, plCollisionShapeHandle childShape, plVector3 childPos, plQuaternion childOrn)
200 {
201 }
deleteShape(plCollisionWorldHandle worldHandle,plCollisionShapeHandle shape)202 void RealTimeBullet3CollisionSdk::deleteShape(plCollisionWorldHandle worldHandle, plCollisionShapeHandle shape)
203 {
204 	///todo
205 	//deleting shapes would involve a garbage collection phase, and mess up all user indices
206 	//this would be solved by one more in-direction, at some performance penalty for certain operations
207 	//for now, we don't delete and eventually run out-of-shapes
208 }
209 
addCollisionObject(plCollisionWorldHandle world,plCollisionObjectHandle object)210 void RealTimeBullet3CollisionSdk::addCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object)
211 {
212 	///createCollisionObject already adds it to the world
213 }
214 
removeCollisionObject(plCollisionWorldHandle world,plCollisionObjectHandle object)215 void RealTimeBullet3CollisionSdk::removeCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object)
216 {
217 	///todo, see deleteShape
218 }
219 
createCollisionObject(plCollisionWorldHandle worldHandle,void * userPointer,int userIndex,plCollisionShapeHandle shapeHandle,plVector3 startPosition,plQuaternion startOrientation)220 plCollisionObjectHandle RealTimeBullet3CollisionSdk::createCollisionObject(plCollisionWorldHandle worldHandle, void* userPointer,
221 																		   int userIndex, plCollisionShapeHandle shapeHandle,
222 																		   plVector3 startPosition, plQuaternion startOrientation)
223 {
224 	RTB3CollisionWorld* world = (RTB3CollisionWorld*)worldHandle;
225 	b3Assert(world->m_nextFreeCollidableIndex < world->m_collidables.size());
226 	if (world->m_nextFreeCollidableIndex < world->m_collidables.size())
227 	{
228 		b3Collidable& collidable = world->m_collidables[world->m_nextFreeCollidableIndex];
229 		world->m_collidablePositions[world->m_nextFreeCollidableIndex].setValue(startPosition[0], startPosition[1], startPosition[2]);
230 		world->m_collidableOrientations[world->m_nextFreeCollidableIndex].setValue(startOrientation[0], startOrientation[1], startOrientation[2], startOrientation[3]);
231 		world->m_collidableTransforms[world->m_nextFreeCollidableIndex].setOrigin(world->m_collidablePositions[world->m_nextFreeCollidableIndex]);
232 		world->m_collidableTransforms[world->m_nextFreeCollidableIndex].setRotation(world->m_collidableOrientations[world->m_nextFreeCollidableIndex]);
233 		world->m_collidableUserPointers[world->m_nextFreeCollidableIndex] = userPointer;
234 		world->m_collidableUserIndices[world->m_nextFreeCollidableIndex] = userIndex;
235 		RTB3_ShapeOpaque2Int caster;
236 		caster.m_ptrValue = shapeHandle;
237 		int shapeIndex = caster.m_intValue;
238 		collidable.m_shapeIndex = shapeIndex;
239 		b3GpuChildShape& shape = world->m_childShapes[shapeIndex];
240 		collidable.m_shapeType = shape.m_shapeType;
241 		collidable.m_numChildShapes = 1;
242 
243 		switch (collidable.m_shapeType)
244 		{
245 			case RTB3_SHAPE_SPHERE:
246 			{
247 				break;
248 			}
249 			case RTB3_SHAPE_PLANE:
250 			{
251 				break;
252 			}
253 			case RTB3_SHAPE_COMPOUND_INTERNAL:
254 			{
255 				break;
256 			}
257 			default:
258 			{
259 				b3Assert(0);
260 			}
261 		}
262 
263 		/*case SHAPE_COMPOUND_OF_CONVEX_HULLS:
264 		case SHAPE_COMPOUND_OF_SPHERES:
265 		case SHAPE_COMPOUND_OF_CAPSULES:
266 			{
267 				collidable.m_numChildShapes = shape.m_numChildShapes;
268 				collidable.m_shapeIndex = shape.m_shapeIndex;
269 				break;
270 		*/
271 		world->m_nextFreeCollidableIndex++;
272 		return (plCollisionObjectHandle)world->m_nextFreeShapePtr;
273 	}
274 	return 0;
275 }
276 
deleteCollisionObject(plCollisionObjectHandle body)277 void RealTimeBullet3CollisionSdk::deleteCollisionObject(plCollisionObjectHandle body)
278 {
279 	///todo, see deleteShape
280 }
281 
setCollisionObjectTransform(plCollisionWorldHandle world,plCollisionObjectHandle body,plVector3 position,plQuaternion orientation)282 void RealTimeBullet3CollisionSdk::setCollisionObjectTransform(plCollisionWorldHandle world, plCollisionObjectHandle body,
283 															  plVector3 position, plQuaternion orientation)
284 {
285 }
286 
287 struct plContactCache
288 {
289 	lwContactPoint* pointsOut;
290 	int pointCapacity;
291 	int numAddedPoints;
292 };
293 
294 typedef void (*plDetectCollisionFunc)(RTB3CollisionWorld* world, int colA, int shapeIndexA, int colB, int shapeIndexB,
295 									  plContactCache* contactCache);
296 
detectCollisionDummy(RTB3CollisionWorld * world,int colA,int shapeIndexA,int colB,int shapeIndexB,plContactCache * contactCache)297 void detectCollisionDummy(RTB3CollisionWorld* world, int colA, int shapeIndexA, int colB, int shapeIndexB,
298 						  plContactCache* contactCache)
299 {
300 	(void)world;
301 	(void)colA, (void)colB;
302 	(void)contactCache;
303 }
304 
plVecCopy(float * dst,const b3Vector3 & src)305 void plVecCopy(float* dst, const b3Vector3& src)
306 {
307 	dst[0] = src.x;
308 	dst[1] = src.y;
309 	dst[2] = src.z;
310 }
plVecCopy(double * dst,const b3Vector3 & src)311 void plVecCopy(double* dst, const b3Vector3& src)
312 {
313 	dst[0] = src.x;
314 	dst[1] = src.y;
315 	dst[2] = src.z;
316 }
317 
ComputeClosestPointsPlaneSphere(const b3Vector3 & planeNormalWorld,b3Scalar planeConstant,const b3Vector3 & spherePosWorld,b3Scalar sphereRadius,plContactCache * contactCache)318 void ComputeClosestPointsPlaneSphere(const b3Vector3& planeNormalWorld, b3Scalar planeConstant, const b3Vector3& spherePosWorld, b3Scalar sphereRadius, plContactCache* contactCache)
319 {
320 	if (contactCache->numAddedPoints < contactCache->pointCapacity)
321 	{
322 		lwContactPoint& pointOut = contactCache->pointsOut[contactCache->numAddedPoints];
323 		b3Scalar t = -(spherePosWorld.dot(-planeNormalWorld) + planeConstant);
324 		b3Vector3 intersectionPoint = spherePosWorld + t * -planeNormalWorld;
325 		b3Scalar distance = t - sphereRadius;
326 		if (distance <= 0)
327 		{
328 			pointOut.m_distance = distance;
329 			plVecCopy(pointOut.m_ptOnBWorld, intersectionPoint);
330 			plVecCopy(pointOut.m_ptOnAWorld, spherePosWorld + sphereRadius * -planeNormalWorld);
331 			plVecCopy(pointOut.m_normalOnB, planeNormalWorld);
332 			contactCache->numAddedPoints++;
333 		}
334 	}
335 }
336 
ComputeClosestPointsSphereSphere(b3Scalar sphereARadius,const b3Vector3 & sphereAPosWorld,b3Scalar sphereBRadius,const b3Vector3 & sphereBPosWorld,plContactCache * contactCache)337 void ComputeClosestPointsSphereSphere(b3Scalar sphereARadius, const b3Vector3& sphereAPosWorld, b3Scalar sphereBRadius, const b3Vector3& sphereBPosWorld, plContactCache* contactCache)
338 {
339 	if (contactCache->numAddedPoints < contactCache->pointCapacity)
340 	{
341 		lwContactPoint& pointOut = contactCache->pointsOut[contactCache->numAddedPoints];
342 		b3Vector3 diff = sphereAPosWorld - sphereBPosWorld;
343 
344 		b3Scalar len = diff.length();
345 		pointOut.m_distance = len - (sphereARadius + sphereBRadius);
346 		if (pointOut.m_distance <= 0)
347 		{
348 			b3Vector3 normOnB = b3MakeVector3(1, 0, 0);
349 			if (len > B3_EPSILON)
350 			{
351 				normOnB = diff / len;
352 			}
353 
354 			plVecCopy(pointOut.m_normalOnB, normOnB);
355 			b3Vector3 ptAWorld = sphereAPosWorld - sphereARadius * normOnB;
356 			plVecCopy(pointOut.m_ptOnAWorld, ptAWorld);
357 			plVecCopy(pointOut.m_ptOnBWorld, ptAWorld - normOnB * pointOut.m_distance);
358 
359 			contactCache->numAddedPoints++;
360 		}
361 	}
362 }
363 
detectCollisionSphereSphere(RTB3CollisionWorld * world,int colA,int shapeIndexA,int colB,int shapeIndexB,plContactCache * contactCache)364 B3_FORCE_INLINE void detectCollisionSphereSphere(RTB3CollisionWorld* world, int colA, int shapeIndexA, int colB, int shapeIndexB,
365 												 plContactCache* contactCache)
366 {
367 	const b3Scalar radiusA = world->m_childShapes[shapeIndexA].m_radius;
368 	const b3Scalar radiusB = world->m_childShapes[shapeIndexB].m_radius;
369 
370 	const b3Transform& trA = world->m_collidableTransforms[colA];
371 	const b3Vector3& sphereALocalPos = world->m_childShapes[shapeIndexA].m_childPosition;
372 	b3Vector3 spherePosAWorld = trA(sphereALocalPos);
373 	//b3Vector3 spherePosAWorld = b3QuatRotate( world->m_collidableOrientations[colA], sphereALocalPos ) + (world->m_collidablePositions[colA]);
374 
375 	const b3Transform& trB = world->m_collidableTransforms[colB];
376 	const b3Vector3& sphereBLocalPos = world->m_childShapes[shapeIndexB].m_childPosition;
377 	b3Vector3 spherePosBWorld = trB(sphereBLocalPos);
378 	//b3Vector3 spherePosBWorld = b3QuatRotate( world->m_collidableOrientations[colB], sphereBLocalPos ) + (world->m_collidablePositions[colB]);
379 
380 	ComputeClosestPointsSphereSphere(radiusA, spherePosAWorld, radiusB, spherePosBWorld, contactCache);
381 }
382 
detectCollisionSpherePlane(RTB3CollisionWorld * world,int colA,int shapeIndexA,int colB,int shapeIndexB,plContactCache * contactCache)383 void detectCollisionSpherePlane(RTB3CollisionWorld* world, int colA, int shapeIndexA, int colB, int shapeIndexB,
384 								plContactCache* contactCache)
385 {
386 	const b3Transform& trA = world->m_collidableTransforms[colA];
387 	const b3Vector3& sphereALocalPos = world->m_childShapes[shapeIndexA].m_childPosition;
388 	b3Vector3 spherePosAWorld = trA(sphereALocalPos);
389 
390 	int planeFaceIndex = world->m_childShapes[shapeIndexB].m_shapeIndex;
391 	b3Vector3 planeNormal = world->m_planeFaces[planeFaceIndex].m_plane;
392 	b3Scalar planeConstant = planeNormal[3];
393 	planeNormal[3] = 0.f;
394 
395 	ComputeClosestPointsPlaneSphere(planeNormal, planeConstant, spherePosAWorld, world->m_childShapes[shapeIndexA].m_radius, contactCache);
396 }
397 
detectCollisionPlaneSphere(RTB3CollisionWorld * world,int colA,int shapeIndexA,int colB,int shapeIndexB,plContactCache * contactCache)398 void detectCollisionPlaneSphere(RTB3CollisionWorld* world, int colA, int shapeIndexA, int colB, int shapeIndexB,
399 								plContactCache* contactCache)
400 {
401 	(void)world;
402 	(void)colA, (void)shapeIndexA, (void)colB, (void)shapeIndexB;
403 	(void)contactCache;
404 }
405 
406 #ifdef RTB3_SHAPE_CAPSULE
407 plDetectCollisionFunc funcTbl_detectCollision[MAX_NUM_SINGLE_SHAPE_TYPES, ][MAX_NUM_SINGLE_SHAPE_TYPES, ] = {
408 	{detectCollisionSphereSphere, detectCollisionSpherePlane, detectCollisionSphereCapsule},
409 	{detectCollisionPlaneSphere, detectCollisionDummy, detectCollisionPlaneCapsule},
410 	{detectCollisionCapsuleSphere, detectCollisionCapsulePlane, detectCollisionCapsuleCapsule},
411 };
412 #else
413 plDetectCollisionFunc funcTbl_detectCollision[MAX_NUM_SINGLE_SHAPE_TYPES][MAX_NUM_SINGLE_SHAPE_TYPES] = {
414 	{detectCollisionSphereSphere, detectCollisionSpherePlane},
415 	{detectCollisionPlaneSphere, detectCollisionDummy},
416 };
417 
418 #endif
419 
collide(plCollisionWorldHandle worldHandle,plCollisionObjectHandle colAHandle,plCollisionObjectHandle colBHandle,lwContactPoint * pointsOutOrg,int pointCapacity)420 int RealTimeBullet3CollisionSdk::collide(plCollisionWorldHandle worldHandle, plCollisionObjectHandle colAHandle, plCollisionObjectHandle colBHandle,
421 										 lwContactPoint* pointsOutOrg, int pointCapacity)
422 {
423 	RTB3CollisionWorld* world = (RTB3CollisionWorld*)worldHandle;
424 	RTB3_ColliderOpaque2Int caster;
425 	caster.m_ptrValue = colAHandle;
426 	int colAIndex = caster.m_intValue;
427 	caster.m_ptrValue = colBHandle;
428 	int colBIndex = caster.m_intValue;
429 	const b3Collidable& colA = world->m_collidables[colAIndex];
430 	const b3Collidable& colB = world->m_collidables[colBIndex];
431 
432 	plContactCache contactCache;
433 	contactCache.pointCapacity = pointCapacity;
434 	contactCache.pointsOut = pointsOutOrg;
435 	contactCache.numAddedPoints = 0;
436 
437 	for (int i = 0; i < colA.m_numChildShapes; i++)
438 	{
439 		for (int j = 0; j < colB.m_numChildShapes; j++)
440 		{
441 			if (contactCache.numAddedPoints < pointCapacity)
442 			{
443 				//funcTbl_detectCollision[world->m_childShapes[colA.m_shapeIndex+i].m_shapeType]
444 				//					   [world->m_childShapes[colB.m_shapeIndex+j].m_shapeType](world,colAIndex,colA.m_shapeIndex+i,colBIndex,colB.m_shapeIndex+j,&contactCache);
445 			}
446 		}
447 		return contactCache.numAddedPoints;
448 	}
449 
450 	return 0;
451 }
452 
collideWorld(plCollisionWorldHandle worldHandle,plNearCallback filter,void * userData)453 void RealTimeBullet3CollisionSdk::collideWorld(plCollisionWorldHandle worldHandle,
454 											   plNearCallback filter, void* userData)
455 {
456 	RTB3CollisionWorld* world = (RTB3CollisionWorld*)worldHandle;
457 	if (filter)
458 	{
459 		RTB3_ColliderOpaque2Int caster;
460 		plCollisionObjectHandle colA;
461 		plCollisionObjectHandle colB;
462 		for (int i = START_COLLIDABLE_INDEX; i < world->m_nextFreeCollidableIndex; i++)
463 		{
464 			for (int j = i + 1; j < world->m_nextFreeCollidableIndex; j++)
465 			{
466 				caster.m_intValue = i;
467 				colA = caster.m_ptrValue;
468 				caster.m_intValue = j;
469 				colB = caster.m_ptrValue;
470 				filter((plCollisionSdkHandle)this, worldHandle, userData, colA, colB);
471 			}
472 		}
473 	}
474 }
475 
createRealTimeBullet3CollisionSdkHandle()476 plCollisionSdkHandle RealTimeBullet3CollisionSdk::createRealTimeBullet3CollisionSdkHandle()
477 {
478 	return (plCollisionSdkHandle) new RealTimeBullet3CollisionSdk();
479 }