void plPhysicalControllerCore::IUpdate(int numSubSteps, float alpha) { if (fEnabled) { // Update local position and acheived velocity fLastLocalPosition = fLocalPosition; GetPositionSim(fLocalPosition); hsVector3 displacement = (hsVector3)(fLocalPosition - fLastLocalPosition); fAchievedLinearVelocity = displacement / fSimLength; displacement /= (float)numSubSteps; fLastLocalPosition = fLocalPosition - displacement; hsPoint3 interpLocalPos = fLastLocalPosition + (displacement * alpha); // Update global location fLocalRotation.MakeMatrix(&fLastGlobalLoc); fLastGlobalLoc.SetTranslate(&interpLocalPos); const plCoordinateInterface* subworldCI = GetSubworldCI(); if (subworldCI) { const hsMatrix44& subL2W = subworldCI->GetLocalToWorld(); fLastGlobalLoc = subL2W * fLastGlobalLoc; fPrevSubworldW2L = subworldCI->GetWorldToLocal(); } fMovementStrategy->Update(fSimLength); ISendCorrectionMessages(true); } else { fAchievedLinearVelocity.Set(0.0f, 0.0f, 0.0f); // Update global location if in a subworld const plCoordinateInterface* subworldCI = GetSubworldCI(); if (subworldCI) { hsMatrix44 l2s = fPrevSubworldW2L * fLastGlobalLoc; const hsMatrix44& subL2W = subworldCI->GetLocalToWorld(); fLastGlobalLoc = subL2W * l2s; fPrevSubworldW2L = subworldCI->GetWorldToLocal(); ISendCorrectionMessages(); } } if (fEnableChanged) IHandleEnableChanged(); }
void plPhysicalControllerCore::IApply(float delSecs) { fSimLength = delSecs; // Match controller to owner if transform has changed since the last frame plSceneObject* so = plSceneObject::ConvertNoRef(fOwner->ObjectIsLoaded()); const hsMatrix44& l2w = so->GetCoordinateInterface()->GetLocalToWorld(); if (!CompareMatrices(fLastGlobalLoc, l2w, 0.0001f)) SetGlobalLoc(l2w); if (fEnabled) { // Convert velocity from avatar to world space if (!fLinearVelocity.IsEmpty()) { fLinearVelocity = l2w * fLinearVelocity; const plCoordinateInterface* subworldCI = GetSubworldCI(); if (subworldCI) fLinearVelocity = subworldCI->GetWorldToLocal() * fLinearVelocity; } fMovementStrategy->Apply(delSecs); } }
void plPXPhysicalControllerCore::SetState(const hsPoint3& pos, float zRot) { plSceneObject* so = plSceneObject::ConvertNoRef(fOwner->ObjectIsLoaded()); if (so) { hsQuat worldRot; hsVector3 zAxis(0.f, 0.f, 1.f); worldRot.SetAngleAxis(zRot, zAxis); hsMatrix44 l2w, w2l; worldRot.MakeMatrix(&l2w); l2w.SetTranslate(&pos); // Localize new position and rotation to global coords if we're in a subworld const plCoordinateInterface* ci = GetSubworldCI(); if (ci) { const hsMatrix44& subworldL2W = ci->GetLocalToWorld(); l2w = subworldL2W * l2w; } l2w.GetInverse(&w2l); so->SetTransform(l2w, w2l); so->FlushTransform(); } }
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 plPXPhysicalControllerCore::SetSubworld(plKey world) { if (fWorldKey != world) { bool wasEnabled = fEnabled; #ifdef USE_PHYSX_CONVEXHULL_WORKAROUND // PHYSX FIXME - before leaving this world, sending leaving detector events if we are inside a convex hull detector hsPoint3 pos; IGetPositionSim(pos); plSimulationMgr::GetInstance()->UpdateDetectorsInScene(fWorldKey,GetOwner(),pos,false); #endif // USE_PHYSX_CONVEXHULL_WORKAROUND //need to inform detectors in the old world that we are leaving IInformDetectors(false); //done informing old world SimLog("Changing subworlds!"); IDeleteController(); SimLog("Deleted old controller"); fWorldKey = world; if (GetSubworldCI()) fPrevSubworldW2L = GetSubworldCI()->GetWorldToLocal(); // Update our subworld position and rotation const plCoordinateInterface* subworldCI = GetSubworldCI(); if (subworldCI) { const hsMatrix44& w2s = fPrevSubworldW2L; hsMatrix44 l2s = w2s * fLastGlobalLoc; l2s.GetTranslate(&fLocalPosition); fLocalRotation.SetFromMatrix44(l2s); } else { fLastGlobalLoc.GetTranslate(&fLocalPosition); fLocalRotation.SetFromMatrix44(fLastGlobalLoc); } hsMatrix44 w2l; fLastGlobalLoc.GetInverse(&w2l); if (fProxyGen) fProxyGen->SetTransform(fLastGlobalLoc, w2l); // Update the physical position SimLog("creating new controller"); hsPoint3 PositionPlusOffset=fLocalPosition; PositionPlusOffset.fZ +=kPhysZOffset; //placing new controller and kinematic in the appropriate location ICreateController(PositionPlusOffset); RebuildCache(); } }
void plPhysicalControllerCore::IUpdateNonPhysical(float alpha) { // Update global location if owner transform hasn't changed. plSceneObject* so = plSceneObject::ConvertNoRef(fOwner->ObjectIsLoaded()); const hsMatrix44& l2w = so->GetCoordinateInterface()->GetLocalToWorld(); if (CompareMatrices(fLastGlobalLoc, l2w, 0.0001f)) { if (fEnabled) { hsVector3 displacement = (hsVector3)(fLocalPosition - fLastLocalPosition); hsPoint3 interpLocalPos = fLastLocalPosition + (displacement * alpha); fLocalRotation.MakeMatrix(&fLastGlobalLoc); fLastGlobalLoc.SetTranslate(&interpLocalPos); const plCoordinateInterface* subworldCI = GetSubworldCI(); if (subworldCI) { const hsMatrix44& subL2W = subworldCI->GetLocalToWorld(); fLastGlobalLoc = subL2W * fLastGlobalLoc; fPrevSubworldW2L = subworldCI->GetWorldToLocal(); } ISendCorrectionMessages(); } else { // Update global location if in a subworld const plCoordinateInterface* subworldCI = GetSubworldCI(); if (subworldCI) { hsMatrix44 l2s = fPrevSubworldW2L * fLastGlobalLoc; const hsMatrix44& subL2W = subworldCI->GetLocalToWorld(); fLastGlobalLoc = subL2W * l2s; fPrevSubworldW2L = subworldCI->GetWorldToLocal(); ISendCorrectionMessages(); } } } }
void plPhysicalControllerCore::UpdateWorldRelativePos() { // Apply rotation and translation fLocalRotation.MakeMatrix(&fLastGlobalLoc); fLastGlobalLoc.SetTranslate(&fLocalPosition); // Localize to global coords if in a subworld const plCoordinateInterface* ci = GetSubworldCI(); if (ci) { const hsMatrix44& l2w = ci->GetLocalToWorld(); fLastGlobalLoc = l2w * fLastGlobalLoc; } }
void plPhysicalControllerCore::UpdateSubstepNonPhysical() { // When we're in non-phys or a behavior we can't go through the rest of the function // so we need to get out early, but we need to update the current position if we're // in a subworld. plSceneObject* so = plSceneObject::ConvertNoRef(fOwner->ObjectIsLoaded()); const plCoordinateInterface* ci = GetSubworldCI(); if (ci && so) { const hsMatrix44& soL2W = so->GetCoordinateInterface()->GetLocalToWorld(); const hsMatrix44& ciL2W = ci->GetLocalToWorld(); hsMatrix44 l2w =GetPrevSubworldW2L()* soL2W; l2w = ciL2W * l2w; hsMatrix44 w2l; l2w.GetInverse(&w2l); ((plCoordinateInterface*)so->GetCoordinateInterface())->SetTransform(l2w, w2l); ((plCoordinateInterface*)so->GetCoordinateInterface())->FlushTransform(); SetGlobalLoc(l2w); } }