/** Interpolates kinematic actor transform - Assumes caller has obtained writer lock */ void FPhysSubstepTask::InterpolateKinematicActor(const FPhysTarget & PhysTarget, FBodyInstance * BodyInstance, float Alpha) { #if WITH_PHYSX PxRigidDynamic * PRigidDynamic = BodyInstance->GetPxRigidDynamic(); Alpha = FMath::Clamp(Alpha, 0.f, 1.f); /** Interpolate kinematic actors */ if (PhysTarget.bKinematicTarget) { //We should only be interpolating kinematic actors check(!IsRigidDynamicNonKinematic(PRigidDynamic)); const FKinematicTarget & KinematicTarget = PhysTarget.KinematicTarget; const FTransform & TargetTM = KinematicTarget.TargetTM; const FTransform & StartTM = KinematicTarget.OriginalTM; FTransform InterTM = FTransform::Identity; InterTM.SetLocation(FMath::Lerp(StartTM.GetLocation(), TargetTM.GetLocation(), Alpha)); InterTM.SetRotation(FMath::Lerp(StartTM.GetRotation(), TargetTM.GetRotation(), Alpha)); const PxTransform PNewPose = U2PTransform(InterTM); check(PNewPose.isValid()); PRigidDynamic->setKinematicTarget(PNewPose); } #endif }
/** Interpolates kinematic actor transform - Assumes caller has obtained writer lock */ void FPhysSubstepTask::InterpolateKinematicActor(const FPhysTarget& PhysTarget, FBodyInstance* BodyInstance, float InAlpha) { #if WITH_PHYSX PxRigidDynamic * PRigidDynamic = BodyInstance->GetPxRigidDynamic(); InAlpha = FMath::Clamp(InAlpha, 0.f, 1.f); /** Interpolate kinematic actors */ if (PhysTarget.bKinematicTarget) { //It's possible that the actor is no longer kinematic and is now simulating. In that case do nothing if (!IsRigidDynamicNonKinematic(PRigidDynamic)) { const FKinematicTarget& KinematicTarget = PhysTarget.KinematicTarget; const FTransform& TargetTM = KinematicTarget.TargetTM; const FTransform& StartTM = KinematicTarget.OriginalTM; FTransform InterTM = FTransform::Identity; InterTM.SetLocation(FMath::Lerp(StartTM.GetLocation(), TargetTM.GetLocation(), InAlpha)); InterTM.SetRotation(FMath::Lerp(StartTM.GetRotation(), TargetTM.GetRotation(), InAlpha)); const PxTransform PNewPose = U2PTransform(InterTM); check(PNewPose.isValid()); PRigidDynamic->setKinematicTarget(PNewPose); } } #endif }
void FPhysSubstepTask::AddTorque(FBodyInstance * Body, const FVector & Torque) { check(Body); PxRigidDynamic * PRigidDynamic = Body->GetPxRigidDynamic(); SCOPED_SCENE_READ_LOCK(PRigidDynamic->getScene()); //We should only apply torque on non kinematic actors if (IsRigidDynamicNonKinematic(PRigidDynamic)) { FTorqueTarget TorqueTarget; TorqueTarget.Torque = Torque; FPhysTarget & TargetState = PhysTargetBuffers[External].FindOrAdd(Body); TargetState.Torques.Add(TorqueTarget); } }
void FPhysSubstepTask::AddForce(FBodyInstance * Body, const FVector & Force) { check(Body); PxRigidDynamic * PRigidDynamic = Body->GetPxRigidDynamic(); SCOPED_SCENE_READ_LOCK(PRigidDynamic->getScene()); //We should only apply forces on non kinematic actors if (IsRigidDynamicNonKinematic(PRigidDynamic)) { FForceTarget ForceTarget; ForceTarget.bPosition = false; ForceTarget.Force = Force; FPhysTarget & TargetState = PhysTargetBuffers[External].FindOrAdd(Body); TargetState.Forces.Add(ForceTarget); } }
void FPhysSubstepTask::SetKinematicTarget(FBodyInstance * Body, const FTransform & TM) { check(Body); TM.DiagnosticCheckNaN_All(); PxRigidDynamic * PRigidDynamic = Body->GetPxRigidDynamic(); SCOPED_SCENE_READ_LOCK(PRigidDynamic->getScene()); //We only interpolate kinematic actors if (!IsRigidDynamicNonKinematic(PRigidDynamic)) { FKinematicTarget KinmaticTarget(Body, TM); FPhysTarget & TargetState = PhysTargetBuffers[External].FindOrAdd(Body); TargetState.bKinematicTarget = true; TargetState.KinematicTarget = KinmaticTarget; } }