172 lines
5.0 KiB
C++
172 lines
5.0 KiB
C++
#ifndef B3_CLIP_FACES_H
|
|
#define B3_CLIP_FACES_H
|
|
|
|
#include "Bullet3Common/shared/b3Int4.h"
|
|
#include "Bullet3Collision/NarrowPhaseCollision/shared/b3RigidBodyData.h"
|
|
#include "Bullet3Collision/NarrowPhaseCollision/shared/b3Collidable.h"
|
|
#include "Bullet3Collision/BroadPhaseCollision/shared/b3Aabb.h"
|
|
#include "Bullet3Collision/NarrowPhaseCollision/shared/b3BvhSubtreeInfoData.h"
|
|
#include "Bullet3Collision/NarrowPhaseCollision/shared/b3QuantizedBvhNodeData.h"
|
|
#include "Bullet3Collision/NarrowPhaseCollision/shared/b3ConvexPolyhedronData.h"
|
|
|
|
inline b3Float4 b3Lerp3(b3Float4ConstArg a, b3Float4ConstArg b, float t)
|
|
{
|
|
return b3MakeFloat4(a.x + (b.x - a.x) * t,
|
|
a.y + (b.y - a.y) * t,
|
|
a.z + (b.z - a.z) * t,
|
|
0.f);
|
|
}
|
|
|
|
// Clips a face to the back of a plane, return the number of vertices out, stored in ppVtxOut
|
|
int clipFaceGlobal(__global const b3Float4* pVtxIn, int numVertsIn, b3Float4ConstArg planeNormalWS, float planeEqWS, __global b3Float4* ppVtxOut)
|
|
{
|
|
int ve;
|
|
float ds, de;
|
|
int numVertsOut = 0;
|
|
//double-check next test
|
|
// if (numVertsIn < 2)
|
|
// return 0;
|
|
|
|
b3Float4 firstVertex = pVtxIn[numVertsIn - 1];
|
|
b3Float4 endVertex = pVtxIn[0];
|
|
|
|
ds = b3Dot(planeNormalWS, firstVertex) + planeEqWS;
|
|
|
|
for (ve = 0; ve < numVertsIn; ve++)
|
|
{
|
|
endVertex = pVtxIn[ve];
|
|
de = b3Dot(planeNormalWS, endVertex) + planeEqWS;
|
|
if (ds < 0)
|
|
{
|
|
if (de < 0)
|
|
{
|
|
// Start < 0, end < 0, so output endVertex
|
|
ppVtxOut[numVertsOut++] = endVertex;
|
|
}
|
|
else
|
|
{
|
|
// Start < 0, end >= 0, so output intersection
|
|
ppVtxOut[numVertsOut++] = b3Lerp3(firstVertex, endVertex, (ds * 1.f / (ds - de)));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (de < 0)
|
|
{
|
|
// Start >= 0, end < 0 so output intersection and end
|
|
ppVtxOut[numVertsOut++] = b3Lerp3(firstVertex, endVertex, (ds * 1.f / (ds - de)));
|
|
ppVtxOut[numVertsOut++] = endVertex;
|
|
}
|
|
}
|
|
firstVertex = endVertex;
|
|
ds = de;
|
|
}
|
|
return numVertsOut;
|
|
}
|
|
|
|
__kernel void clipFacesAndFindContactsKernel(__global const b3Float4* separatingNormals,
|
|
__global const int* hasSeparatingAxis,
|
|
__global b3Int4* clippingFacesOut,
|
|
__global b3Float4* worldVertsA1,
|
|
__global b3Float4* worldNormalsA1,
|
|
__global b3Float4* worldVertsB1,
|
|
__global b3Float4* worldVertsB2,
|
|
int vertexFaceCapacity,
|
|
int pairIndex)
|
|
{
|
|
// int i = get_global_id(0);
|
|
//int pairIndex = i;
|
|
int i = pairIndex;
|
|
|
|
float minDist = -1e30f;
|
|
float maxDist = 0.02f;
|
|
|
|
// if (i<numPairs)
|
|
{
|
|
if (hasSeparatingAxis[i])
|
|
{
|
|
// int bodyIndexA = pairs[i].x;
|
|
// int bodyIndexB = pairs[i].y;
|
|
|
|
int numLocalContactsOut = 0;
|
|
|
|
int capacityWorldVertsB2 = vertexFaceCapacity;
|
|
|
|
__global b3Float4* pVtxIn = &worldVertsB1[pairIndex * capacityWorldVertsB2];
|
|
__global b3Float4* pVtxOut = &worldVertsB2[pairIndex * capacityWorldVertsB2];
|
|
|
|
{
|
|
__global b3Int4* clippingFaces = clippingFacesOut;
|
|
|
|
int closestFaceA = clippingFaces[pairIndex].x;
|
|
// int closestFaceB = clippingFaces[pairIndex].y;
|
|
int numVertsInA = clippingFaces[pairIndex].z;
|
|
int numVertsInB = clippingFaces[pairIndex].w;
|
|
|
|
int numVertsOut = 0;
|
|
|
|
if (closestFaceA >= 0)
|
|
{
|
|
// clip polygon to back of planes of all faces of hull A that are adjacent to witness face
|
|
|
|
for (int e0 = 0; e0 < numVertsInA; e0++)
|
|
{
|
|
const b3Float4 aw = worldVertsA1[pairIndex * capacityWorldVertsB2 + e0];
|
|
const b3Float4 bw = worldVertsA1[pairIndex * capacityWorldVertsB2 + ((e0 + 1) % numVertsInA)];
|
|
const b3Float4 WorldEdge0 = aw - bw;
|
|
b3Float4 worldPlaneAnormal1 = worldNormalsA1[pairIndex];
|
|
b3Float4 planeNormalWS1 = -b3Cross(WorldEdge0, worldPlaneAnormal1);
|
|
b3Float4 worldA1 = aw;
|
|
float planeEqWS1 = -b3Dot(worldA1, planeNormalWS1);
|
|
b3Float4 planeNormalWS = planeNormalWS1;
|
|
float planeEqWS = planeEqWS1;
|
|
numVertsOut = clipFaceGlobal(pVtxIn, numVertsInB, planeNormalWS, planeEqWS, pVtxOut);
|
|
__global b3Float4* tmp = pVtxOut;
|
|
pVtxOut = pVtxIn;
|
|
pVtxIn = tmp;
|
|
numVertsInB = numVertsOut;
|
|
numVertsOut = 0;
|
|
}
|
|
|
|
b3Float4 planeNormalWS = worldNormalsA1[pairIndex];
|
|
float planeEqWS = -b3Dot(planeNormalWS, worldVertsA1[pairIndex * capacityWorldVertsB2]);
|
|
|
|
for (int i = 0; i < numVertsInB; i++)
|
|
{
|
|
float depth = b3Dot(planeNormalWS, pVtxIn[i]) + planeEqWS;
|
|
if (depth <= minDist)
|
|
{
|
|
depth = minDist;
|
|
}
|
|
/*
|
|
static float maxDepth = 0.f;
|
|
if (depth < maxDepth)
|
|
{
|
|
maxDepth = depth;
|
|
if (maxDepth < -10)
|
|
{
|
|
printf("error at framecount %d?\n",myframecount);
|
|
}
|
|
printf("maxDepth = %f\n", maxDepth);
|
|
|
|
}
|
|
*/
|
|
if (depth <= maxDist)
|
|
{
|
|
b3Float4 pointInWorld = pVtxIn[i];
|
|
pVtxOut[numLocalContactsOut++] = b3MakeFloat4(pointInWorld.x, pointInWorld.y, pointInWorld.z, depth);
|
|
}
|
|
}
|
|
}
|
|
clippingFaces[pairIndex].w = numLocalContactsOut;
|
|
}
|
|
|
|
for (int i = 0; i < numLocalContactsOut; i++)
|
|
pVtxIn[i] = pVtxOut[i];
|
|
|
|
} // if (hasSeparatingAxis[i])
|
|
} // if (i<numPairs)
|
|
}
|
|
|
|
#endif //B3_CLIP_FACES_H
|