bool FPhysScene::GetKinematicTarget_AssumesLocked(const FBodyInstance* BodyInstance, FTransform& OutTM) const { #if WITH_PHYSX if (PxRigidDynamic * PRigidDynamic = BodyInstance->GetPxRigidDynamic_AssumesLocked()) { #if WITH_SUBSTEPPING uint32 BodySceneType = SceneType_AssumesLocked(BodyInstance); if (IsSubstepping(BodySceneType)) { FPhysSubstepTask * PhysSubStepper = PhysSubSteppers[BodySceneType]; return PhysSubStepper->GetKinematicTarget_AssumesLocked(BodyInstance, OutTM); } else #endif { PxTransform POutTM; bool validTM = PRigidDynamic->getKinematicTarget(POutTM); if (validTM) { OutTM = P2UTransform(POutTM); return true; } } } #endif return false; }
void FPhysScene::SetKinematicTarget(FBodyInstance * BodyInstance, const FTransform & TargetTransform) { TargetTransform.DiagnosticCheckNaN_All(); #if WITH_PHYSX if (PxRigidDynamic * PRigidDynamic = BodyInstance->GetPxRigidDynamic()) { #if WITH_SUBSTEPPING if (IsSubstepping()) { FPhysSubstepTask * PhysSubStepper = PhysSubSteppers[SceneType(BodyInstance)]; PhysSubStepper->SetKinematicTarget(BodyInstance, TargetTransform); } else #endif { const PxTransform PNewPose = U2PTransform(TargetTransform); check(PNewPose.isValid()); SCOPED_SCENE_WRITE_LOCK(PRigidDynamic->getScene()); PRigidDynamic->setKinematicTarget(PNewPose); } } #endif }
void FPhysScene::AddCustomPhysics_AssumesLocked(FBodyInstance* BodyInstance, FCalculateCustomPhysics& CalculateCustomPhysics) { #if WITH_PHYSX #if WITH_SUBSTEPPING uint32 BodySceneType = SceneType_AssumesLocked(BodyInstance); if (IsSubstepping(BodySceneType)) { FPhysSubstepTask * PhysSubStepper = PhysSubSteppers[SceneType_AssumesLocked(BodyInstance)]; PhysSubStepper->AddCustomPhysics_AssumesLocked(BodyInstance, CalculateCustomPhysics); } else #endif { // Since physics frame is set up before "pre-physics" tick group is called, can just fetch delta time from there CalculateCustomPhysics.ExecuteIfBound(this->DeltaSeconds, BodyInstance); } #endif }
void FPhysScene::AddTorque_AssumesLocked(FBodyInstance* BodyInstance, const FVector& Torque, bool bAllowSubstepping, bool bAccelChange) { #if WITH_PHYSX if (PxRigidBody * PRigidBody = BodyInstance->GetPxRigidBody_AssumesLocked()) { #if WITH_SUBSTEPPING uint32 BodySceneType = SceneType_AssumesLocked(BodyInstance); if (bAllowSubstepping && IsSubstepping(BodySceneType)) { FPhysSubstepTask * PhysSubStepper = PhysSubSteppers[BodySceneType]; PhysSubStepper->AddTorque_AssumesLocked(BodyInstance, Torque, bAccelChange); } else #endif { PRigidBody->addTorque(U2PVector(Torque), bAccelChange ? PxForceMode::eACCELERATION : PxForceMode::eFORCE, true); } } #endif }
void FPhysScene::AddRadialForceToBody_AssumesLocked(FBodyInstance* BodyInstance, const FVector& Origin, const float Radius, const float Strength, const uint8 Falloff, bool bAccelChange, bool bAllowSubstepping) { #if WITH_PHYSX if (PxRigidBody * PRigidBody = BodyInstance->GetPxRigidBody_AssumesLocked()) { #if WITH_SUBSTEPPING uint32 BodySceneType = SceneType_AssumesLocked(BodyInstance); if (bAllowSubstepping && IsSubstepping(BodySceneType)) { FPhysSubstepTask * PhysSubStepper = PhysSubSteppers[BodySceneType]; PhysSubStepper->AddRadialForceToBody_AssumesLocked(BodyInstance, Origin, Radius, Strength, Falloff, bAccelChange); } else #endif { AddRadialForceToPxRigidBody_AssumesLocked(*PRigidBody, Origin, Radius, Strength, Falloff, bAccelChange); } } #endif }
void FPhysScene::AddForceAtPosition_AssumesLocked(FBodyInstance* BodyInstance, const FVector& Force, const FVector& Position, bool bAllowSubstepping) { #if WITH_PHYSX if (PxRigidBody * PRigidBody = BodyInstance->GetPxRigidBody_AssumesLocked()) { #if WITH_SUBSTEPPING uint32 BodySceneType = SceneType_AssumesLocked(BodyInstance); if (bAllowSubstepping && IsSubstepping(BodySceneType)) { FPhysSubstepTask * PhysSubStepper = PhysSubSteppers[BodySceneType]; PhysSubStepper->AddForceAtPosition_AssumesLocked(BodyInstance, Force, Position); } else #endif { PxRigidBodyExt::addForceAtPos(*PRigidBody, U2PVector(Force), U2PVector(Position), PxForceMode::eFORCE, true); } } #endif }
void FPhysScene::AddTorque(FBodyInstance * BodyInstance, const FVector & Torque) { #if WITH_PHYSX if (PxRigidDynamic * PRigidDynamic = BodyInstance->GetPxRigidDynamic()) { #if WITH_SUBSTEPPING if (IsSubstepping()) { FPhysSubstepTask * PhysSubStepper = PhysSubSteppers[SceneType(BodyInstance)]; PhysSubStepper->AddTorque(BodyInstance, Torque); } else #endif { SCOPED_SCENE_WRITE_LOCK(PRigidDynamic->getScene()); PRigidDynamic->addTorque(U2PVector(Torque), PxForceMode::eFORCE, true); } } #endif }
void FPhysScene::AddForceAtPosition(FBodyInstance * BodyInstance, const FVector & Force, const FVector & Position) { #if WITH_PHYSX if (PxRigidDynamic * PRigidDynamic = BodyInstance->GetPxRigidDynamic()) { #if WITH_SUBSTEPPING if (IsSubstepping()) { FPhysSubstepTask * PhysSubStepper = PhysSubSteppers[SceneType(BodyInstance)]; PhysSubStepper->AddForceAtPosition(BodyInstance, Force, Position); } else #endif { SCOPED_SCENE_WRITE_LOCK(PRigidDynamic->getScene()); PxRigidBodyExt::addForceAtPos(*PRigidDynamic, U2PVector(Force), U2PVector(Position), PxForceMode::eFORCE, true); } } #endif }
void FPhysScene::AddTorque(FBodyInstance* BodyInstance, const FVector& Torque, bool bAllowSubstepping) { #if WITH_PHYSX if (PxRigidBody * PRigidBody = BodyInstance->GetPxRigidBody()) { #if WITH_SUBSTEPPING uint32 BodySceneType = SceneType(BodyInstance); if (bAllowSubstepping && IsSubstepping(BodySceneType)) { FPhysSubstepTask * PhysSubStepper = PhysSubSteppers[BodySceneType]; PhysSubStepper->AddTorque(BodyInstance, Torque); } else #endif { SCOPED_SCENE_WRITE_LOCK(PRigidBody->getScene()); PRigidBody->addTorque(U2PVector(Torque), PxForceMode::eFORCE, true); } } #endif }
void FPhysScene::AddForceAtPosition(FBodyInstance* BodyInstance, const FVector& Force, const FVector& Position, bool bAllowSubstepping) { #if WITH_PHYSX if (PxRigidBody * PRigidBody = BodyInstance->GetPxRigidBody()) { #if WITH_SUBSTEPPING uint32 BodySceneType = SceneType(BodyInstance); if (bAllowSubstepping && IsSubstepping(BodySceneType)) { FPhysSubstepTask * PhysSubStepper = PhysSubSteppers[BodySceneType]; PhysSubStepper->AddForceAtPosition(BodyInstance, Force, Position); } else #endif { SCOPED_SCENE_WRITE_LOCK(PRigidBody->getScene()); PxRigidBodyExt::addForceAtPos(*PRigidBody, U2PVector(Force), U2PVector(Position), PxForceMode::eFORCE, true); } } #endif }
void FPhysScene::SetKinematicTarget_AssumesLocked(FBodyInstance* BodyInstance, const FTransform& TargetTransform, bool bAllowSubstepping) { TargetTransform.DiagnosticCheckNaN_All(); #if WITH_PHYSX if (PxRigidDynamic * PRigidDynamic = BodyInstance->GetPxRigidDynamic_AssumesLocked()) { #if WITH_SUBSTEPPING uint32 BodySceneType = SceneType_AssumesLocked(BodyInstance); if (bAllowSubstepping && IsSubstepping(BodySceneType)) { FPhysSubstepTask * PhysSubStepper = PhysSubSteppers[BodySceneType]; PhysSubStepper->SetKinematicTarget_AssumesLocked(BodyInstance, TargetTransform); } else #endif { const PxTransform PNewPose = U2PTransform(TargetTransform); check(PNewPose.isValid()); PRigidDynamic->setKinematicTarget(PNewPose); } } #endif }
/** Exposes ticking of physics-engine scene outside Engine. */ void FPhysScene::TickPhysScene(uint32 SceneType, FGraphEventRef& InOutCompletionEvent) { SCOPE_CYCLE_COUNTER(STAT_TotalPhysicsTime); SCOPE_CYCLE_COUNTER(STAT_PhysicsKickOffDynamicsTime); check(SceneType < NumPhysScenes); if (bPhysXSceneExecuting[SceneType] != 0) { // Already executing this scene, must call WaitPhysScene before calling this function again. UE_LOG(LogPhysics, Log, TEXT("TickPhysScene: Already executing scene (%d) - aborting."), SceneType); return; } #if WITH_SUBSTEPPING if (IsSubstepping(SceneType)) //we don't bother sub-stepping cloth { //We're about to start stepping so swap buffers. Might want to find a better place for this? PhysSubSteppers[SceneType]->SwapBuffers(); } #endif /** * clamp down... if this happens we are simming physics slower than real-time, so be careful with it. * it can improve framerate dramatically (really, it is the same as scaling all velocities down and * enlarging all timesteps) but at the same time, it will screw with networking (client and server will * diverge a lot more.) */ float UseDelta = FMath::Min(UseSyncTime(SceneType) ? SyncDeltaSeconds : DeltaSeconds, MaxPhysicsDeltaTime); // Only simulate a positive time step. if (UseDelta <= 0.f) { if (UseDelta < 0.f) { // only do this if negative. Otherwise, whenever we pause, this will come up UE_LOG(LogPhysics, Warning, TEXT("TickPhysScene: Negative timestep (%f) - aborting."), UseDelta); } return; } #if WITH_PHYSX GatherPhysXStats(GetPhysXScene(SceneType), SceneType); #endif /** * Weight frame time according to PhysScene settings. */ AveragedFrameTime[SceneType] *= FrameTimeSmoothingFactor[SceneType]; AveragedFrameTime[SceneType] += (1.0f - FrameTimeSmoothingFactor[SceneType])*UseDelta; // Set execution flag bPhysXSceneExecuting[SceneType] = true; check(!InOutCompletionEvent.GetReference()); // these should be gone because nothing is outstanding InOutCompletionEvent = FGraphEvent::CreateGraphEvent(); bool bTaskOutstanding = false; #if WITH_PHYSX #if WITH_VEHICLE if (VehicleManager && SceneType == PST_Sync) { float TickTime = AveragedFrameTime[SceneType]; #if WITH_SUBSTEPPING if (IsSubstepping(SceneType)) { TickTime = UseSyncTime(SceneType) ? SyncDeltaSeconds : DeltaSeconds; } #endif VehicleManager->PreTick(TickTime); #if WITH_SUBSTEPPING if (IsSubstepping(SceneType) == false) #endif { VehicleManager->Update(AveragedFrameTime[SceneType]); } } #endif #if !WITH_APEX PxScene* PScene = GetPhysXScene(SceneType); if (PScene && (UseDelta > 0.f)) { PhysXCompletionTask* Task = new PhysXCompletionTask(InOutCompletionEvent, PScene->getTaskManager()); PScene->lockWrite(); PScene->simulate(AveragedFrameTime[SceneType], Task); PScene->unlockWrite(); Task->removeReference(); bTaskOutstanding = true; } #else // #if !WITH_APEX // The APEX scene calls the simulate function for the PhysX scene, so we only call ApexScene->simulate(). NxApexScene* ApexScene = GetApexScene(SceneType); if(ApexScene && UseDelta > 0.f) { #if WITH_SUBSTEPPING if (IsSubstepping(SceneType)) //we don't bother sub-stepping cloth { bTaskOutstanding = SubstepSimulation(SceneType, InOutCompletionEvent); }else #endif { PhysXCompletionTask* Task = new PhysXCompletionTask(InOutCompletionEvent, ApexScene->getTaskManager()); ApexScene->simulate(AveragedFrameTime[SceneType], true, Task); Task->removeReference(); bTaskOutstanding = true; } } #endif // #if !WITH_APEX #endif // WITH_PHYSX if (!bTaskOutstanding) { InOutCompletionEvent->DispatchSubsequents(); // nothing to do, so nothing to wait for } #if WITH_SUBSTEPPING bSubstepping = UPhysicsSettings::Get()->bSubstepping; bSubsteppingAsync = UPhysicsSettings::Get()->bSubsteppingAsync; #endif }