void UPhysicsHandleComponent::OnUnregister() { if(GrabbedComponent) { ReleaseComponent(); } #if WITH_PHYSX if(HandleData) { check(KinActorData); // use correct scene PxScene* PScene = GetPhysXSceneFromIndex( SceneIndex ); if(PScene) { // destroy joint HandleData->release(); HandleData = NULL; // Destroy temporary actor. KinActorData->release(); KinActorData = NULL; } } #endif // WITH_PHYSX Super::OnUnregister(); }
void UShapeComponent::CreateShapeBodySetupIfNeeded() { if (ShapeBodySetup == nullptr || ShapeBodySetup->IsPendingKill()) { ShapeBodySetup = NewObject<UBodySetup>(this); if (GUObjectArray.IsDisregardForGC(this)) { ShapeBodySetup->AddToRoot(); } ShapeBodySetup->CollisionTraceFlag = CTF_UseSimpleAsComplex; AddShapeToGeomArray<ShapeElemType>(); ShapeBodySetup->bNeverNeedsCookedCollisionData = true; bUseArchetypeBodySetup = false; //We're making our own body setup, so don't use the archetype's. //Update bodyinstance and shapes BodyInstance.BodySetup = ShapeBodySetup; { if(BodyInstance.IsValidBodyInstance()) { #if WITH_PHYSX SCOPED_SCENE_READ_LOCK(GetPhysXSceneFromIndex(BodyInstance.GetSceneIndex())); TArray<PxShape *> PShapes; BodyInstance.GetAllShapes_AssumesLocked(PShapes); check(PShapes.Num() == 1); //Shape component should only have 1 shape SetShapeToNewGeom<ShapeElemType>(PShapes[0]); #endif } } } }
bool UGripMotionControllerComponent::DestroyPhysicsHandle(int32 SceneIndex, physx::PxD6Joint** HandleData, physx::PxRigidDynamic** KinActorData) { #if WITH_PHYSX if (HandleData && *HandleData) { check(*KinActorData); // use correct scene PxScene* PScene = GetPhysXSceneFromIndex(SceneIndex); if (PScene) { SCOPED_SCENE_WRITE_LOCK(PScene); // Destroy joint. (*HandleData)->release(); // Destroy temporary actor. (*KinActorData)->release(); } *KinActorData = NULL; *HandleData = NULL; } else return false; #endif // WITH_PHYSX return true; }
void UPhysicsHandleComponent::ReleaseComponent() { #if WITH_PHYSX if(GrabbedComponent) { if(HandleData) { check(KinActorData); // use correct scene PxScene* PScene = GetPhysXSceneFromIndex( SceneIndex ); if(PScene) { // Destroy joint. HandleData->release(); // Destroy temporary actor. KinActorData->release(); } KinActorData = NULL; HandleData = NULL; } bRotationConstrained = false; GrabbedComponent = NULL; GrabbedBoneName = NAME_None; } #endif // WITH_PHYSX }
void FPhysScene::FDeferredSceneData::FlushDeferredActors() { check(AddInstances.Num() == AddActors.Num()); if (AddInstances.Num() > 0) { PxScene* Scene = GetPhysXSceneFromIndex(SceneIndex); SCOPED_SCENE_WRITE_LOCK(Scene); Scene->addActors(AddActors.GetData(), AddActors.Num()); int32 Idx = -1; for (FBodyInstance* Instance : AddInstances) { ++Idx; Instance->CurrentSceneState = BodyInstanceSceneState::Added; if(Instance->GetPxRigidDynamic_AssumesLocked()) { // Extra setup necessary for dynamic objects. Instance->InitDynamicProperties_AssumesLocked(); } } AddInstances.Empty(); AddActors.Empty(); } check(RemoveInstances.Num() == RemoveActors.Num()); if (RemoveInstances.Num() > 0) { PxScene* Scene = GetPhysXSceneFromIndex(SceneIndex); SCOPED_SCENE_WRITE_LOCK(Scene); Scene->removeActors(RemoveActors.GetData(), RemoveActors.Num()); for (FBodyInstance* Instance : AddInstances) { Instance->CurrentSceneState = BodyInstanceSceneState::Removed; } RemoveInstances.Empty(); RemoveActors.Empty(); } }
bool UGripMotionControllerComponent::TeleportMoveGrippedActor(AActor * GrippedActorToMove) { if (!GrippedActorToMove || !GrippedActors.Num()) return false; FTransform WorldTransform; FTransform InverseTransform = this->GetComponentTransform().Inverse(); for (int i = GrippedActors.Num() - 1; i >= 0; --i) { if (GrippedActors[i].Actor == GrippedActorToMove) { // GetRelativeTransformReverse had some serious f*****g floating point errors associated with it that was f*****g everything up // Not sure whats wrong with the function but I might want to push a patch out eventually WorldTransform = GrippedActors[i].RelativeTransform.GetRelativeTransform(InverseTransform); // Need to use WITH teleport for this function so that the velocity isn't updated and without sweep so that they don't collide GrippedActors[i].Actor->SetActorTransform(WorldTransform, false, NULL, ETeleportType::TeleportPhysics); FBPActorPhysicsHandleInformation * Handle = GetPhysicsGrip(GrippedActors[i]); if (Handle && Handle->KinActorData) { { PxScene* PScene = GetPhysXSceneFromIndex(Handle->SceneIndex); if (PScene) { SCOPED_SCENE_WRITE_LOCK(PScene); Handle->KinActorData->setKinematicTarget(PxTransform(U2PVector(WorldTransform.GetLocation()), Handle->KinActorData->getGlobalPose().q)); Handle->KinActorData->setGlobalPose(PxTransform(U2PVector(WorldTransform.GetLocation()), Handle->KinActorData->getGlobalPose().q)); } } //Handle->KinActorData->setGlobalPose(PxTransform(U2PVector(WorldTransform.GetLocation()), Handle->KinActorData->getGlobalPose().q)); UPrimitiveComponent *root = Cast<UPrimitiveComponent>(GrippedActors[i].Actor->GetRootComponent()); if (root) { FBodyInstance * body = root->GetBodyInstance(); if (body) { body->SetBodyTransform(WorldTransform, ETeleportType::TeleportPhysics); } } } return true; } } return false; }
void FConstraintInstance::TermConstraint() { #if WITH_PHYSX if (!ConstraintData) { return; } // use correct scene if(PxScene* PScene = GetPhysXSceneFromIndex(SceneIndex)) { ConstraintData->release(); } ConstraintData = nullptr; #endif }
void UGripMotionControllerComponent::UpdatePhysicsHandleTransform(const FBPActorGripInformation &GrippedActor, const FTransform& NewTransform) { if (!GrippedActor.Actor && !GrippedActor.Component) return; FBPActorPhysicsHandleInformation * HandleInfo = GetPhysicsGrip(GrippedActor); if (!HandleInfo || !HandleInfo->KinActorData) return; #if WITH_PHYSX bool bChangedPosition = true; bool bChangedRotation = true; PxRigidDynamic* KinActor = HandleInfo->KinActorData; PxScene* PScene = GetPhysXSceneFromIndex(HandleInfo->SceneIndex); SCOPED_SCENE_WRITE_LOCK(PScene); // Check if the new location is worthy of change PxVec3 PNewLocation = U2PVector(NewTransform.GetTranslation()); PxVec3 PCurrentLocation = KinActor->getGlobalPose().p; if ((PNewLocation - PCurrentLocation).magnitudeSquared() <= 0.01f*0.01f) { PNewLocation = PCurrentLocation; bChangedPosition = false; } // Check if the new rotation is worthy of change PxQuat PNewOrientation = U2PQuat(NewTransform.GetRotation()); PxQuat PCurrentOrientation = KinActor->getGlobalPose().q; if ((FMath::Abs(PNewOrientation.dot(PCurrentOrientation)) > (1.f - SMALL_NUMBER))) { PNewOrientation = PCurrentOrientation; bChangedRotation = false; } // Don't call moveKinematic if it hasn't changed - that will stop bodies from going to sleep. if (bChangedPosition || bChangedRotation) { KinActor->setKinematicTarget(PxTransform(PNewLocation, PNewOrientation)); } #endif // WITH_PHYSX }
/** Finds the common scene and appropriate actors for the passed in body instances. Makes sure to do this without requiring a scene lock*/ PxScene* GetPScene_LockFree(const FBodyInstance* Body1, const FBodyInstance* Body2) { const int32 SceneIndex1 = Body1 ? Body1->GetSceneIndex() : -1; const int32 SceneIndex2 = Body2 ? Body2->GetSceneIndex() : -1; PxScene* PScene = nullptr; //now we check if the two actors are valid if(SceneIndex1 == -1 && SceneIndex2 == -1) { UE_LOG(LogPhysics, Log, TEXT("Attempting to create a joint between two null actors. No joint created.")); } else if(SceneIndex1 >= 0 && SceneIndex2 >= 0 && SceneIndex1 != SceneIndex2) { UE_LOG(LogPhysics, Log, TEXT("Attempting to create a joint between two actors in different scenes. No joint created.")); } else { PScene = GetPhysXSceneFromIndex(SceneIndex1 >= 0 ? SceneIndex1 : SceneIndex2); } return PScene; }
void UGripMotionControllerComponent::PostTeleportMoveGrippedActors() { if (!GrippedActors.Num()) return; FTransform WorldTransform; FTransform InverseTransform = this->GetComponentTransform().Inverse(); for (int i = GrippedActors.Num() - 1; i >= 0; --i) { // GetRelativeTransformReverse had some serious f*****g floating point errors associated with it that was f*****g everything up // Not sure whats wrong with the function but I might want to push a patch out eventually WorldTransform = GrippedActors[i].RelativeTransform.GetRelativeTransform(InverseTransform); if (GrippedActors[i].Actor) { // Need to use WITH teleport for this function so that the velocity isn't updated and without sweep so that they don't collide GrippedActors[i].Actor->SetActorTransform(WorldTransform, false, NULL, ETeleportType::TeleportPhysics); } else if (GrippedActors[i].Component) { // Need to use WITH teleport for this function so that the velocity isn't updated and without sweep so that they don't collide GrippedActors[i].Component->SetWorldTransform(WorldTransform, false, NULL, ETeleportType::TeleportPhysics); } FBPActorPhysicsHandleInformation * Handle = GetPhysicsGrip(GrippedActors[i]); if (Handle && Handle->KinActorData) { { PxScene* PScene = GetPhysXSceneFromIndex(Handle->SceneIndex); if (PScene) { SCOPED_SCENE_WRITE_LOCK(PScene); Handle->KinActorData->setKinematicTarget(PxTransform(U2PVector(WorldTransform.GetLocation()), Handle->KinActorData->getGlobalPose().q)); Handle->KinActorData->setGlobalPose(PxTransform(U2PVector(WorldTransform.GetLocation()), Handle->KinActorData->getGlobalPose().q)); } } //Handle->KinActorData->setGlobalPose(PxTransform(U2PVector(WorldTransform.GetLocation()), Handle->KinActorData->getGlobalPose().q)); if (GrippedActors[i].Actor) { UPrimitiveComponent *root = Cast<UPrimitiveComponent>(GrippedActors[i].Actor->GetRootComponent()); if (root) { FBodyInstance * body = root->GetBodyInstance(); if (body) { body->SetBodyTransform(WorldTransform, ETeleportType::TeleportPhysics); } } } else if (GrippedActors[i].Component) { FBodyInstance * body = GrippedActors[i].Component->GetBodyInstance(); if (body) { body->SetBodyTransform(WorldTransform, ETeleportType::TeleportPhysics); } } } /*else { if (bIsServer) { DestroyPhysicsHandle(GrippedActors[i]); GrippedActors.RemoveAt(i); // If it got garbage collected then just remove the pointer, won't happen with new uproperty use, but keeping it here anyway } }*/ } }
/** Utility for looking up the PxScene associated with this FPhysScene. */ PxScene* FPhysScene::GetPhysXScene(uint32 SceneType) { check(SceneType < NumPhysScenes); return GetPhysXSceneFromIndex(PhysXSceneIndex[SceneType]); }