|
|
|
@ -138,14 +138,10 @@ plPXPhysical::plPXPhysical()
|
|
|
|
|
, fSceneNode(nil) |
|
|
|
|
, fWorldKey(nil) |
|
|
|
|
, fSndGroup(nil) |
|
|
|
|
, fWorldHull(nil) |
|
|
|
|
, fSaveTriangles(nil) |
|
|
|
|
, fHullNumberPlanes(0) |
|
|
|
|
, fMass(0.f) |
|
|
|
|
, fWeWereHit(false) |
|
|
|
|
, fHitForce(0,0,0) |
|
|
|
|
, fHitPos(0,0,0) |
|
|
|
|
, fInsideConvexHull(false) |
|
|
|
|
{ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -190,11 +186,6 @@ plPXPhysical::~plPXPhysical()
|
|
|
|
|
plSimulationMgr::GetInstance()->ReleaseScene(fWorldKey); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (fWorldHull) |
|
|
|
|
delete [] fWorldHull; |
|
|
|
|
if (fSaveTriangles) |
|
|
|
|
delete [] fSaveTriangles; |
|
|
|
|
|
|
|
|
|
delete fProxyGen; |
|
|
|
|
|
|
|
|
|
// remove sdl modifier
|
|
|
|
@ -206,155 +197,6 @@ plPXPhysical::~plPXPhysical()
|
|
|
|
|
delete fSDLMod; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void MakeBoxFromHull(NxConvexMesh* convexMesh, NxBoxShapeDesc& box) |
|
|
|
|
{ |
|
|
|
|
NxConvexMeshDesc desc; |
|
|
|
|
convexMesh->saveToDesc(desc); |
|
|
|
|
|
|
|
|
|
float minX, minY, minZ, maxX, maxY, maxZ; |
|
|
|
|
minX = minY = minZ = FLT_MAX; |
|
|
|
|
maxX = maxY = maxZ = -FLT_MAX; |
|
|
|
|
|
|
|
|
|
for (int i = 0; i < desc.numVertices; i++) |
|
|
|
|
{ |
|
|
|
|
float* point = (float*)(((char*)desc.points) + desc.pointStrideBytes*i); |
|
|
|
|
float x = point[0]; |
|
|
|
|
float y = point[1]; |
|
|
|
|
float z = point[2]; |
|
|
|
|
|
|
|
|
|
minX = hsMinimum(minX, x); |
|
|
|
|
minY = hsMinimum(minY, y); |
|
|
|
|
minZ = hsMinimum(minZ, z); |
|
|
|
|
maxX = hsMaximum(maxX, x); |
|
|
|
|
maxY = hsMaximum(maxY, y); |
|
|
|
|
maxZ = hsMaximum(maxZ, z); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
float xWidth = maxX - minX; |
|
|
|
|
float yWidth = maxY - minY; |
|
|
|
|
float zWidth = maxZ - minZ; |
|
|
|
|
box.dimensions.x = xWidth / 2; |
|
|
|
|
box.dimensions.y = yWidth / 2; |
|
|
|
|
box.dimensions.z = zWidth / 2; |
|
|
|
|
|
|
|
|
|
//hsMatrix44 mat;
|
|
|
|
|
//box.localPose.getRowMajor44(&mat.fMap[0][0]);
|
|
|
|
|
hsPoint3 trans(minX + (xWidth / 2), minY + (yWidth / 2), minZ + (zWidth / 2)); |
|
|
|
|
//mat.SetTranslate(&trans);
|
|
|
|
|
//box.localPose.setRowMajor44(&mat.fMap[0][0]);
|
|
|
|
|
|
|
|
|
|
hsMatrix44 boxL2W; |
|
|
|
|
boxL2W.Reset(); |
|
|
|
|
boxL2W.SetTranslate(&trans); |
|
|
|
|
plPXConvert::Matrix(boxL2W, box.localPose); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void plPXPhysical::IMakeHull(NxConvexMesh* convexMesh, hsMatrix44 l2w) |
|
|
|
|
{ |
|
|
|
|
NxConvexMeshDesc desc; |
|
|
|
|
convexMesh->saveToDesc(desc); |
|
|
|
|
|
|
|
|
|
// make sure there are some triangles to work with
|
|
|
|
|
if (desc.numTriangles == 0) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
// get rid of any we may have already had
|
|
|
|
|
if (fSaveTriangles) |
|
|
|
|
delete [] fSaveTriangles; |
|
|
|
|
|
|
|
|
|
fHullNumberPlanes = desc.numTriangles; |
|
|
|
|
fSaveTriangles = new hsPoint3[fHullNumberPlanes*3]; |
|
|
|
|
|
|
|
|
|
for (int i = 0; i < desc.numTriangles; i++) |
|
|
|
|
{ |
|
|
|
|
uint32_t* triangle = (uint32_t*)(((char*)desc.triangles) + desc.triangleStrideBytes*i); |
|
|
|
|
float* vertex1 = (float*)(((char*)desc.points) + desc.pointStrideBytes*triangle[0]); |
|
|
|
|
float* vertex2 = (float*)(((char*)desc.points) + desc.pointStrideBytes*triangle[1]); |
|
|
|
|
float* vertex3 = (float*)(((char*)desc.points) + desc.pointStrideBytes*triangle[2]); |
|
|
|
|
hsPoint3 pt1(vertex1[0],vertex1[1],vertex1[2]); |
|
|
|
|
hsPoint3 pt2(vertex2[0],vertex2[1],vertex2[2]); |
|
|
|
|
hsPoint3 pt3(vertex3[0],vertex3[1],vertex3[2]); |
|
|
|
|
|
|
|
|
|
fSaveTriangles[(i*3)+0] = pt1; |
|
|
|
|
fSaveTriangles[(i*3)+1] = pt2; |
|
|
|
|
fSaveTriangles[(i*3)+2] = pt3; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void plPXPhysical::ISetHullToWorldWTriangles() |
|
|
|
|
{ |
|
|
|
|
// if we have a detector hull and the world hasn't been updated
|
|
|
|
|
if (fWorldHull == nil) |
|
|
|
|
{ |
|
|
|
|
fWorldHull = new hsPlane3[fHullNumberPlanes]; |
|
|
|
|
// use the local2world from the physics engine so that it matches the transform of the positions from the triggerees
|
|
|
|
|
hsMatrix44 l2w; |
|
|
|
|
plPXConvert::Matrix(fActor->getGlobalPose(), l2w); |
|
|
|
|
int i; |
|
|
|
|
for( i = 0; i < fHullNumberPlanes; i++ ) |
|
|
|
|
{ |
|
|
|
|
hsPoint3 pt1 = fSaveTriangles[i*3]; |
|
|
|
|
hsPoint3 pt2 = fSaveTriangles[(i*3)+1]; |
|
|
|
|
hsPoint3 pt3 = fSaveTriangles[(i*3)+2]; |
|
|
|
|
|
|
|
|
|
// local to world translation
|
|
|
|
|
pt1 = l2w * pt1; |
|
|
|
|
pt2 = l2w * pt2; |
|
|
|
|
pt3 = l2w * pt3; |
|
|
|
|
|
|
|
|
|
hsPlane3 plane(&pt1, &pt2, &pt3); |
|
|
|
|
fWorldHull[i] = plane; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool plPXPhysical::IsObjectInsideHull(const hsPoint3& pos) |
|
|
|
|
{ |
|
|
|
|
if (fSaveTriangles) |
|
|
|
|
{ |
|
|
|
|
ISetHullToWorldWTriangles(); |
|
|
|
|
int i; |
|
|
|
|
for( i = 0; i < fHullNumberPlanes; i++ ) |
|
|
|
|
{ |
|
|
|
|
if (!ITestPlane(pos, fWorldHull[i])) |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool plPXPhysical::Should_I_Trigger(bool enter, hsPoint3& pos) |
|
|
|
|
{ |
|
|
|
|
// see if we are inside the detector hull, if so, then don't trigger
|
|
|
|
|
bool trigger = false; |
|
|
|
|
bool inside = IsObjectInsideHull(pos); |
|
|
|
|
if ( !inside) |
|
|
|
|
{ |
|
|
|
|
trigger = true; |
|
|
|
|
fInsideConvexHull = enter; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
// catch those rare cases on slow machines that miss the collision before avatar penetrated the face
|
|
|
|
|
if (enter && !fInsideConvexHull) |
|
|
|
|
{ |
|
|
|
|
#ifdef PHYSX_SAVE_TRIGGERS_WORKAROUND |
|
|
|
|
trigger = true; |
|
|
|
|
fInsideConvexHull = enter; |
|
|
|
|
DetectorLogSpecial("**>Saved a missing enter collision: %s",GetObjectKey()->GetName().c_str()); |
|
|
|
|
#else |
|
|
|
|
DetectorLogSpecial("**>Could have saved a missing enter collision: %s",GetObjectKey()->GetName().c_str()); |
|
|
|
|
#endif PHYSX_SAVE_TRIGGERS_WORKAROUND |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return trigger; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool plPXPhysical::Init(PhysRecipe& recipe) |
|
|
|
|
{ |
|
|
|
|
bool startAsleep = false; |
|
|
|
@ -388,29 +230,6 @@ bool plPXPhysical::Init(PhysRecipe& recipe)
|
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case plSimDefs::kHullBounds: |
|
|
|
|
// FIXME PHYSX - Remove when hull detection is fixed
|
|
|
|
|
// If this is read time (ie, meshStream is nil), turn the convex hull
|
|
|
|
|
// into a box. That way the data won't have to change when convex hulls
|
|
|
|
|
// actually work right.
|
|
|
|
|
if (fGroup == plSimDefs::kGroupDetector && recipe.meshStream == nil) |
|
|
|
|
{ |
|
|
|
|
#ifdef USE_BOXES_FOR_DETECTOR_HULLS |
|
|
|
|
MakeBoxFromHull(recipe.convexMesh, boxDesc); |
|
|
|
|
plSimulationMgr::GetInstance()->GetSDK()->releaseConvexMesh(*recipe.convexMesh); |
|
|
|
|
boxDesc.group = fGroup; |
|
|
|
|
actorDesc.shapes.push_back(&boxDesc); |
|
|
|
|
#else |
|
|
|
|
#ifdef USE_PHYSX_CONVEXHULL_WORKAROUND |
|
|
|
|
// make a hull of planes for testing IsInside
|
|
|
|
|
IMakeHull(recipe.convexMesh,recipe.l2s); |
|
|
|
|
#endif // USE_PHYSX_CONVEXHULL_WORKAROUND
|
|
|
|
|
convexShapeDesc.meshData = recipe.convexMesh; |
|
|
|
|
convexShapeDesc.userData = recipe.meshStream; |
|
|
|
|
convexShapeDesc.group = fGroup; |
|
|
|
|
actorDesc.shapes.pushBack(&convexShapeDesc); |
|
|
|
|
#endif // USE_BOXES_FOR_DETECTOR_HULLS
|
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
convexShapeDesc.meshData = recipe.convexMesh; |
|
|
|
|
convexShapeDesc.userData = recipe.meshStream; |
|
|
|
@ -669,9 +488,6 @@ void plPXPhysical::IEnable(bool enable)
|
|
|
|
|
{ |
|
|
|
|
fActor->clearActorFlag(NX_AF_DISABLE_COLLISION); |
|
|
|
|
|
|
|
|
|
// PHYSX FIXME - after re-enabling a possible detector, we need to check to see if any avatar is already in the PhysX turdy hull detector region
|
|
|
|
|
plSimulationMgr::GetInstance()->UpdateAvatarInDetector(fWorldKey, this); |
|
|
|
|
|
|
|
|
|
if (fActor->isDynamic()) |
|
|
|
|
fActor->clearBodyFlag(NX_BF_FROZEN); |
|
|
|
|
else |
|
|
|
|