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
}
示例#5
0
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;
}
示例#7
0
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
			}
		}*/
	}
}
示例#11
0
/** Utility for looking up the PxScene associated with this FPhysScene. */
PxScene* FPhysScene::GetPhysXScene(uint32 SceneType)
{
	check(SceneType < NumPhysScenes);
	return GetPhysXSceneFromIndex(PhysXSceneIndex[SceneType]);
}