2 #define SHAPE_CONVEX_HULL 3
4 #define SHAPE_CONCAVE_TRIMESH 5
5 #define SHAPE_COMPOUND_OF_CONVEX_HULLS 6
32 unsigned int m_collidableIdx;
34 float m_restituitionCoeff;
35 float m_frictionCoeff;
38 typedef struct Collidable
63 int m_uniqueEdgesOffset;
78 ///////////////////////////////////////
80 ///////////////////////////////////////
82 typedef float4 Quaternion;
85 Quaternion qtMul(Quaternion a, Quaternion b);
88 Quaternion qtNormalize(Quaternion in);
92 Quaternion qtInvert(Quaternion q);
96 float dot3F4(float4 a, float4 b)
98 float4 a1 = (float4)(a.xyz,0.f);
99 float4 b1 = (float4)(b.xyz,0.f);
105 Quaternion qtMul(Quaternion a, Quaternion b)
110 // ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);
111 ans.w = a.w*b.w - dot3F4(a, b);
116 Quaternion qtNormalize(Quaternion in)
118 return fast_normalize(in);
119 // in /= length( in );
123 float4 qtRotate(Quaternion q, float4 vec)
125 Quaternion qInv = qtInvert( q );
128 float4 out = qtMul(q,vcpy);
129 out = qtMul(out,qInv);
134 Quaternion qtInvert(Quaternion q)
136 return (Quaternion)(-q.xyz, q.w);
140 float4 qtInvRotate(const Quaternion q, float4 vec)
142 return qtRotate( qtInvert( q ), vec );
147 void trInverse(float4 translationIn, Quaternion orientationIn,
148 float4* translationOut, Quaternion* orientationOut)
150 *orientationOut = qtInvert(orientationIn);
151 *translationOut = qtRotate(*orientationOut, -translationIn);
158 bool rayConvex(float4 rayFromLocal, float4 rayToLocal, int numFaces, int faceOffset,
159 __global const b3GpuFace* faces, float* hitFraction, float4* hitNormal)
161 rayFromLocal.w = 0.f;
165 float exitFraction = hitFraction[0];
166 float enterFraction = -0.3f;
167 float4 curHitNormal = (float4)(0,0,0,0);
168 for (int i=0;i<numFaces && result;i++)
170 b3GpuFace face = faces[faceOffset+i];
171 float fromPlaneDist = dot(rayFromLocal,face.m_plane)+face.m_plane.w;
172 float toPlaneDist = dot(rayToLocal,face.m_plane)+face.m_plane.w;
173 if (fromPlaneDist<0.f)
175 if (toPlaneDist >= 0.f)
177 float fraction = fromPlaneDist / (fromPlaneDist-toPlaneDist);
178 if (exitFraction>fraction)
180 exitFraction = fraction;
187 float fraction = fromPlaneDist / (fromPlaneDist-toPlaneDist);
188 if (enterFraction <= fraction)
190 enterFraction = fraction;
191 curHitNormal = face.m_plane;
192 curHitNormal.w = 0.f;
199 if (exitFraction <= enterFraction)
203 if (enterFraction < 0.f)
210 hitFraction[0] = enterFraction;
211 hitNormal[0] = curHitNormal;
221 bool sphere_intersect(float4 spherePos, float radius, float4 rayFrom, float4 rayTo, float* hitFraction)
223 float4 rs = rayFrom - spherePos;
225 float4 rayDir = rayTo-rayFrom;
227 float A = dot(rayDir,rayDir);
228 float B = dot(rs, rayDir);
229 float C = dot(rs, rs) - (radius * radius);
231 float D = B * B - A*C;
235 float t = (-B - sqrt(D))/A;
237 if ( (t >= 0.0f) && (t < (*hitFraction)) )
246 float4 setInterpolate3(float4 from, float4 to, float t)
250 result = s * from + t * to;
255 __kernel void rayCastKernel(
257 const __global b3RayInfo* rays,
258 __global b3RayHit* hitResults,
260 __global Body* bodies,
261 __global Collidable* collidables,
262 __global const b3GpuFace* faces,
263 __global const ConvexPolyhedronCL* convexShapes )
266 int i = get_global_id(0);
270 hitResults[i].m_hitFraction = 1.f;
272 float4 rayFrom = rays[i].m_from;
273 float4 rayTo = rays[i].m_to;
274 float hitFraction = 1.f;
277 int hitBodyIndex= -1;
279 int cachedCollidableIndex = -1;
280 Collidable cachedCollidable;
282 for (int b=0;b<numBodies;b++)
284 if (hitResults[i].m_hitResult2==b)
286 Body body = bodies[b];
287 float4 pos = body.m_pos;
288 float4 orn = body.m_quat;
289 if (cachedCollidableIndex != body.m_collidableIdx)
291 cachedCollidableIndex = body.m_collidableIdx;
292 cachedCollidable = collidables[cachedCollidableIndex];
294 if (cachedCollidable.m_shapeType == SHAPE_CONVEX_HULL)
297 float4 invPos = (float4)(0,0,0,0);
298 float4 invOrn = (float4)(0,0,0,0);
299 float4 rayFromLocal = (float4)(0,0,0,0);
300 float4 rayToLocal = (float4)(0,0,0,0);
301 invOrn = qtInvert(orn);
302 invPos = qtRotate(invOrn, -pos);
303 rayFromLocal = qtRotate( invOrn, rayFrom ) + invPos;
304 rayToLocal = qtRotate( invOrn, rayTo) + invPos;
305 rayFromLocal.w = 0.f;
307 int numFaces = convexShapes[cachedCollidable.m_shapeIndex].m_numFaces;
308 int faceOffset = convexShapes[cachedCollidable.m_shapeIndex].m_faceOffset;
311 if (rayConvex(rayFromLocal, rayToLocal, numFaces, faceOffset,faces, &hitFraction, &hitNormal))
318 if (cachedCollidable.m_shapeType == SHAPE_SPHERE)
320 float radius = cachedCollidable.m_radius;
322 if (sphere_intersect(pos, radius, rayFrom, rayTo, &hitFraction))
325 hitNormal = (float4) (hitPoint-bodies[b].m_pos);
332 hitPoint = setInterpolate3(rayFrom, rayTo,hitFraction);
333 hitResults[i].m_hitFraction = hitFraction;
334 hitResults[i].m_hitPoint = hitPoint;
335 hitResults[i].m_hitNormal = normalize(hitNormal);
336 hitResults[i].m_hitResult0 = hitBodyIndex;
342 __kernel void findRayRigidPairIndexRanges(__global int2* rayRigidPairs,
343 __global int* out_firstRayRigidPairIndexPerRay,
344 __global int* out_numRayRigidPairsPerRay,
345 int numRayRigidPairs)
347 int rayRigidPairIndex = get_global_id(0);
348 if (rayRigidPairIndex >= numRayRigidPairs) return;
350 int rayIndex = rayRigidPairs[rayRigidPairIndex].x;
352 atomic_min(&out_firstRayRigidPairIndexPerRay[rayIndex], rayRigidPairIndex);
353 atomic_inc(&out_numRayRigidPairsPerRay[rayIndex]);
356 __kernel void rayCastPairsKernel(const __global b3RayInfo* rays,
357 __global b3RayHit* hitResults,
358 __global int* firstRayRigidPairIndexPerRay,
359 __global int* numRayRigidPairsPerRay,
361 __global Body* bodies,
362 __global Collidable* collidables,
363 __global const b3GpuFace* faces,
364 __global const ConvexPolyhedronCL* convexShapes,
366 __global int2* rayRigidPairs,
369 int i = get_global_id(0);
370 if (i >= numRays) return;
372 float4 rayFrom = rays[i].m_from;
373 float4 rayTo = rays[i].m_to;
375 hitResults[i].m_hitFraction = 1.f;
377 float hitFraction = 1.f;
380 int hitBodyIndex = -1;
383 for(int pair = 0; pair < numRayRigidPairsPerRay[i]; ++pair)
385 int rayRigidPairIndex = pair + firstRayRigidPairIndexPerRay[i];
386 int b = rayRigidPairs[rayRigidPairIndex].y;
388 if (hitResults[i].m_hitResult2 == b) continue;
390 Body body = bodies[b];
391 Collidable rigidCollidable = collidables[body.m_collidableIdx];
393 float4 pos = body.m_pos;
394 float4 orn = body.m_quat;
396 if (rigidCollidable.m_shapeType == SHAPE_CONVEX_HULL)
398 float4 invPos = (float4)(0,0,0,0);
399 float4 invOrn = (float4)(0,0,0,0);
400 float4 rayFromLocal = (float4)(0,0,0,0);
401 float4 rayToLocal = (float4)(0,0,0,0);
402 invOrn = qtInvert(orn);
403 invPos = qtRotate(invOrn, -pos);
404 rayFromLocal = qtRotate( invOrn, rayFrom ) + invPos;
405 rayToLocal = qtRotate( invOrn, rayTo) + invPos;
406 rayFromLocal.w = 0.f;
408 int numFaces = convexShapes[rigidCollidable.m_shapeIndex].m_numFaces;
409 int faceOffset = convexShapes[rigidCollidable.m_shapeIndex].m_faceOffset;
411 if (numFaces && rayConvex(rayFromLocal, rayToLocal, numFaces, faceOffset,faces, &hitFraction, &hitNormal))
414 hitPoint = setInterpolate3(rayFrom, rayTo, hitFraction);
418 if (rigidCollidable.m_shapeType == SHAPE_SPHERE)
420 float radius = rigidCollidable.m_radius;
422 if (sphere_intersect(pos, radius, rayFrom, rayTo, &hitFraction))
425 hitPoint = setInterpolate3(rayFrom, rayTo, hitFraction);
426 hitNormal = (float4) (hitPoint - bodies[b].m_pos);
431 if (hitBodyIndex >= 0)
433 hitResults[i].m_hitFraction = hitFraction;
434 hitResults[i].m_hitPoint = hitPoint;
435 hitResults[i].m_hitNormal = normalize(hitNormal);
436 hitResults[i].m_hitResult0 = hitBodyIndex;