void plPXPhysicalControllerCore::ISetKinematicLoc(const hsMatrix44& l2w) { hsPoint3 kPos; // Update our subworld position and rotation const plCoordinateInterface* subworldCI = GetSubworldCI(); if (subworldCI) { const hsMatrix44& w2s = subworldCI->GetWorldToLocal(); hsMatrix44 l2s = w2s * l2w; l2s.GetTranslate(&kPos); } else { l2w.GetTranslate(&kPos); } hsMatrix44 w2l; l2w.GetInverse(&w2l); if (fProxyGen) fProxyGen->SetTransform(l2w, w2l); // add z offset kPos.fZ += kPhysZOffset; // Update the physical position of kinematic if (fKinematicActor->readBodyFlag(NX_BF_KINEMATIC)) fKinematicActor->moveGlobalPosition(plPXConvert::Point(kPos)); else fKinematicActor->setGlobalPosition(plPXConvert::Point(kPos)); }
void plPXPhysicalControllerCore::ISetGlobalLoc(const hsMatrix44& l2w) { fLastGlobalLoc = l2w; // Update our subworld position and rotation const plCoordinateInterface* subworldCI = GetSubworldCI(); if (subworldCI) { const hsMatrix44& w2s = fPrevSubworldW2L; hsMatrix44 l2s = w2s * l2w; l2s.GetTranslate(&fLocalPosition); fLocalRotation.SetFromMatrix44(l2s); } else { l2w.GetTranslate(&fLocalPosition); fLocalRotation.SetFromMatrix44(l2w); } hsMatrix44 w2l; l2w.GetInverse(&w2l); if (fProxyGen) fProxyGen->SetTransform(l2w, w2l); // Update the physical position NxExtendedVec3 nxPos(fLocalPosition.fX, fLocalPosition.fY, fLocalPosition.fZ + kPhysZOffset); fController->setPosition(nxPos); IMatchKinematicToController(); }
void plPXPhysical::ISetTransformGlobal(const hsMatrix44& l2w) { hsAssert(fActor->isDynamic(), "Shouldn't move a static actor"); // If we wake up normal dynamic actors, they might explode. // However, kinematics won't update if they are asleep. Thankfully, kinematics don't // explode, move, or cause spontaneous nuclear warfare. if (fActor->readBodyFlag(NX_BF_KINEMATIC)) fActor->wakeUp(); NxMat34 mat; if (fWorldKey) { plSceneObject* so = plSceneObject::ConvertNoRef(fWorldKey->ObjectIsLoaded()); hsAssert(so, "Scene object not loaded while accessing subworld."); // physical to subworld (simulation space) hsMatrix44 p2s = so->GetCoordinateInterface()->GetWorldToLocal() * l2w; plPXConvert::Matrix(p2s, mat); if (fProxyGen) { hsMatrix44 w2l; p2s.GetInverse(&w2l); fProxyGen->SetTransform(p2s, w2l); } } // No need to localize else { plPXConvert::Matrix(l2w, mat); if (fProxyGen) { hsMatrix44 w2l; l2w.GetInverse(&w2l); fProxyGen->SetTransform(l2w, w2l); } } // This used to check for the kPhysAnim flag, however animated detectors // are also kinematic but not kPhysAnim, therefore, this would break on PhysX // SDKs (yes, I'm looking at you, 2.6.4) that actually obey the ***GlobalPose // rules set forth in the SDK documentation. if (fActor->readBodyFlag(NX_BF_KINEMATIC)) fActor->moveGlobalPose(mat); else fActor->setGlobalPose(mat); }
// GETTRANSFORM void plPXPhysical::GetTransform(hsMatrix44& l2w, hsMatrix44& w2l) { IGetTransformGlobal(l2w); l2w.GetInverse(&w2l); }