163 lines
4.1 KiB
C++
163 lines
4.1 KiB
C++
|
|
||
|
#ifndef B3_CONTACT_SPHERE_SPHERE_H
|
||
|
#define B3_CONTACT_SPHERE_SPHERE_H
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
void computeContactSphereConvex(int pairIndex,
|
||
|
int bodyIndexA, int bodyIndexB,
|
||
|
int collidableIndexA, int collidableIndexB,
|
||
|
const b3RigidBodyData* rigidBodies,
|
||
|
const b3Collidable* collidables,
|
||
|
const b3ConvexPolyhedronData* convexShapes,
|
||
|
const b3Vector3* convexVertices,
|
||
|
const int* convexIndices,
|
||
|
const b3GpuFace* faces,
|
||
|
b3Contact4* globalContactsOut,
|
||
|
int& nGlobalContactsOut,
|
||
|
int maxContactCapacity)
|
||
|
{
|
||
|
|
||
|
float radius = collidables[collidableIndexA].m_radius;
|
||
|
float4 spherePos1 = rigidBodies[bodyIndexA].m_pos;
|
||
|
b3Quaternion sphereOrn = rigidBodies[bodyIndexA].m_quat;
|
||
|
|
||
|
|
||
|
|
||
|
float4 pos = rigidBodies[bodyIndexB].m_pos;
|
||
|
|
||
|
|
||
|
b3Quaternion quat = rigidBodies[bodyIndexB].m_quat;
|
||
|
|
||
|
b3Transform tr;
|
||
|
tr.setIdentity();
|
||
|
tr.setOrigin(pos);
|
||
|
tr.setRotation(quat);
|
||
|
b3Transform trInv = tr.inverse();
|
||
|
|
||
|
float4 spherePos = trInv(spherePos1);
|
||
|
|
||
|
int collidableIndex = rigidBodies[bodyIndexB].m_collidableIdx;
|
||
|
int shapeIndex = collidables[collidableIndex].m_shapeIndex;
|
||
|
int numFaces = convexShapes[shapeIndex].m_numFaces;
|
||
|
float4 closestPnt = b3MakeVector3(0, 0, 0, 0);
|
||
|
float4 hitNormalWorld = b3MakeVector3(0, 0, 0, 0);
|
||
|
float minDist = -1000000.f; // TODO: What is the largest/smallest float?
|
||
|
bool bCollide = true;
|
||
|
int region = -1;
|
||
|
float4 localHitNormal;
|
||
|
for ( int f = 0; f < numFaces; f++ )
|
||
|
{
|
||
|
b3GpuFace face = faces[convexShapes[shapeIndex].m_faceOffset+f];
|
||
|
float4 planeEqn;
|
||
|
float4 localPlaneNormal = b3MakeVector3(face.m_plane.x,face.m_plane.y,face.m_plane.z,0.f);
|
||
|
float4 n1 = localPlaneNormal;//quatRotate(quat,localPlaneNormal);
|
||
|
planeEqn = n1;
|
||
|
planeEqn[3] = face.m_plane.w;
|
||
|
|
||
|
float4 pntReturn;
|
||
|
float dist = signedDistanceFromPointToPlane(spherePos, planeEqn, &pntReturn);
|
||
|
|
||
|
if ( dist > radius)
|
||
|
{
|
||
|
bCollide = false;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if ( dist > 0 )
|
||
|
{
|
||
|
//might hit an edge or vertex
|
||
|
b3Vector3 out;
|
||
|
|
||
|
bool isInPoly = IsPointInPolygon(spherePos,
|
||
|
&face,
|
||
|
&convexVertices[convexShapes[shapeIndex].m_vertexOffset],
|
||
|
convexIndices,
|
||
|
&out);
|
||
|
if (isInPoly)
|
||
|
{
|
||
|
if (dist>minDist)
|
||
|
{
|
||
|
minDist = dist;
|
||
|
closestPnt = pntReturn;
|
||
|
localHitNormal = planeEqn;
|
||
|
region=1;
|
||
|
}
|
||
|
} else
|
||
|
{
|
||
|
b3Vector3 tmp = spherePos-out;
|
||
|
b3Scalar l2 = tmp.length2();
|
||
|
if (l2<radius*radius)
|
||
|
{
|
||
|
dist = b3Sqrt(l2);
|
||
|
if (dist>minDist)
|
||
|
{
|
||
|
minDist = dist;
|
||
|
closestPnt = out;
|
||
|
localHitNormal = tmp/dist;
|
||
|
region=2;
|
||
|
}
|
||
|
|
||
|
} else
|
||
|
{
|
||
|
bCollide = false;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ( dist > minDist )
|
||
|
{
|
||
|
minDist = dist;
|
||
|
closestPnt = pntReturn;
|
||
|
localHitNormal = planeEqn;
|
||
|
region=3;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
static int numChecks = 0;
|
||
|
numChecks++;
|
||
|
|
||
|
if (bCollide && minDist > -10000)
|
||
|
{
|
||
|
|
||
|
float4 normalOnSurfaceB1 = tr.getBasis()*localHitNormal;//-hitNormalWorld;
|
||
|
float4 pOnB1 = tr(closestPnt);
|
||
|
//printf("dist ,%f,",minDist);
|
||
|
float actualDepth = minDist-radius;
|
||
|
if (actualDepth<0)
|
||
|
{
|
||
|
//printf("actualDepth = ,%f,", actualDepth);
|
||
|
//printf("normalOnSurfaceB1 = ,%f,%f,%f,", normalOnSurfaceB1.x,normalOnSurfaceB1.y,normalOnSurfaceB1.z);
|
||
|
//printf("region=,%d,\n", region);
|
||
|
pOnB1[3] = actualDepth;
|
||
|
|
||
|
int dstIdx;
|
||
|
// dstIdx = nGlobalContactsOut++;//AppendInc( nGlobalContactsOut, dstIdx );
|
||
|
|
||
|
if (nGlobalContactsOut < maxContactCapacity)
|
||
|
{
|
||
|
dstIdx=nGlobalContactsOut;
|
||
|
nGlobalContactsOut++;
|
||
|
|
||
|
b3Contact4* c = &globalContactsOut[dstIdx];
|
||
|
c->m_worldNormalOnB = normalOnSurfaceB1;
|
||
|
c->setFrictionCoeff(0.7);
|
||
|
c->setRestituitionCoeff(0.f);
|
||
|
|
||
|
c->m_batchIdx = pairIndex;
|
||
|
c->m_bodyAPtrAndSignBit = rigidBodies[bodyIndexA].m_invMass==0?-bodyIndexA:bodyIndexA;
|
||
|
c->m_bodyBPtrAndSignBit = rigidBodies[bodyIndexB].m_invMass==0?-bodyIndexB:bodyIndexB;
|
||
|
c->m_worldPosB[0] = pOnB1;
|
||
|
int numPoints = 1;
|
||
|
c->m_worldNormalOnB.w = (b3Scalar)numPoints;
|
||
|
}//if (dstIdx < numPairs)
|
||
|
}
|
||
|
}//if (hasCollision)
|
||
|
|
||
|
}
|
||
|
#endif //B3_CONTACT_SPHERE_SPHERE_H
|