Пример #1
0
MirrorActor::MirrorActor(size_t actorHash,
						 physx::PxRigidActor &actor,
						 MirrorScene &mirrorScene) : mMirrorScene(mirrorScene), mPrimaryActor(&actor), mActorHash(actorHash) 
{
	mReleasePosted = false;
	mMirrorActor = NULL;
	mShapeCount = 0;
	PxScene *scene = actor.getScene();
	PX_ASSERT(scene);
	if ( scene )
	{
		scene->lockWrite(__FILE__,__LINE__);
		mPrimaryGlobalPose = actor.getGlobalPose();
		PxPhysics *sdk = &scene->getPhysics();
		if ( actor.getType() == physx::PxActorType::eRIGID_STATIC )
		{
			mMirrorActor = CloneStatic(*sdk,actor.getGlobalPose(),actor, mirrorScene.getMirrorFilter());
		}
		else
		{
			physx::PxRigidDynamic *rd = static_cast< physx::PxRigidDynamic *>(&actor);
			mMirrorActor = CloneDynamic(*sdk,actor.getGlobalPose(),*rd, mirrorScene.getMirrorFilter());
			if ( mMirrorActor )
			{
				rd = static_cast< physx::PxRigidDynamic *>(mMirrorActor);
				rd->setRigidDynamicFlag(physx::PxRigidDynamicFlag::eKINEMATIC,true);
			}
		}
		scene->unlockWrite();
		if ( mMirrorActor )
		{
			MirrorCommand mc(MCT_CREATE_ACTOR,this);
			mMirrorScene.postCommand(mc);
		}
	}
}
bool UGripMotionControllerComponent::SetUpPhysicsHandle(const FBPActorGripInformation &NewGrip)
{
	UPrimitiveComponent *root = NewGrip.Component;
	if(!root)
		root = Cast<UPrimitiveComponent>(NewGrip.Actor->GetRootComponent());
	
	if (!root)
		return false;

	// Needs to be simulating in order to run physics
	root->SetSimulatePhysics(true);
	root->SetEnableGravity(false);

	FBPActorPhysicsHandleInformation * HandleInfo = CreatePhysicsGrip(NewGrip);

#if WITH_PHYSX
	// Get the PxRigidDynamic that we want to grab.
	FBodyInstance* BodyInstance = root->GetBodyInstance(NAME_None/*InBoneName*/);
	if (!BodyInstance)
	{
		return false;
	}

	ExecuteOnPxRigidDynamicReadWrite(BodyInstance, [&](PxRigidDynamic* Actor)
	{
		PxScene* Scene = Actor->getScene();
	
		// Get transform of actor we are grabbing

		FTransform WorldTransform;
		FTransform InverseTransform = this->GetComponentTransform().Inverse();
		WorldTransform = NewGrip.RelativeTransform.GetRelativeTransform(InverseTransform);

		PxVec3 KinLocation = U2PVector(WorldTransform.GetLocation() - (WorldTransform.GetLocation() - root->GetComponentLocation()));
		PxTransform GrabbedActorPose = Actor->getGlobalPose();
		PxTransform KinPose(KinLocation, GrabbedActorPose.q);

		// set target and current, so we don't need another "Tick" call to have it right
		//TargetTransform = CurrentTransform = P2UTransform(KinPose);

		// If we don't already have a handle - make one now.
		if (!HandleInfo->HandleData)
		{
			// Create kinematic actor we are going to create joint with. This will be moved around with calls to SetLocation/SetRotation.
			PxRigidDynamic* KinActor = Scene->getPhysics().createRigidDynamic(KinPose);
			KinActor->setRigidDynamicFlag(PxRigidDynamicFlag::eKINEMATIC, true);
			KinActor->setMass(0.0f); // 1.0f;
			KinActor->setMassSpaceInertiaTensor(PxVec3(0.0f, 0.0f, 0.0f));// PxVec3(1.0f, 1.0f, 1.0f));
			KinActor->setMaxDepenetrationVelocity(PX_MAX_F32);

			// No bodyinstance
			KinActor->userData = NULL;
			
			// Add to Scene
			Scene->addActor(*KinActor);

			// Save reference to the kinematic actor.
			HandleInfo->KinActorData = KinActor;

			// Create the joint
			PxVec3 LocalHandlePos = GrabbedActorPose.transformInv(KinLocation);
			PxD6Joint* NewJoint = PxD6JointCreate(Scene->getPhysics(), KinActor, PxTransform::createIdentity(), Actor, PxTransform(LocalHandlePos));
			
			if (!NewJoint)
			{
				HandleInfo->HandleData = 0;
			}
			else
			{
				// No constraint instance
				NewJoint->userData = NULL;
				HandleInfo->HandleData = NewJoint;

				// Remember the scene index that the handle joint/actor are in.
				FPhysScene* RBScene = FPhysxUserData::Get<FPhysScene>(Scene->userData);
				const uint32 SceneType = root->BodyInstance.UseAsyncScene(RBScene) ? PST_Async : PST_Sync;
				HandleInfo->SceneIndex = RBScene->PhysXSceneIndex[SceneType];
				
				// Setting up the joint
				NewJoint->setMotion(PxD6Axis::eX, PxD6Motion::eFREE);
				NewJoint->setMotion(PxD6Axis::eY, PxD6Motion::eFREE);
				NewJoint->setMotion(PxD6Axis::eZ, PxD6Motion::eFREE);
				NewJoint->setDrivePosition(PxTransform(PxVec3(0, 0, 0)));

				NewJoint->setMotion(PxD6Axis::eTWIST, PxD6Motion::eFREE);
				NewJoint->setMotion(PxD6Axis::eSWING1, PxD6Motion::eFREE);
				NewJoint->setMotion(PxD6Axis::eSWING2, PxD6Motion::eFREE);

				//UpdateDriveSettings();
				if (HandleInfo->HandleData != nullptr)
				{
					HandleInfo->HandleData->setDrive(PxD6Drive::eX, PxD6JointDrive(NewGrip.Stiffness, NewGrip.Damping, PX_MAX_F32, PxD6JointDriveFlag::eACCELERATION));
					HandleInfo->HandleData->setDrive(PxD6Drive::eY, PxD6JointDrive(NewGrip.Stiffness, NewGrip.Damping, PX_MAX_F32, PxD6JointDriveFlag::eACCELERATION));
					HandleInfo->HandleData->setDrive(PxD6Drive::eZ, PxD6JointDrive(NewGrip.Stiffness, NewGrip.Damping, PX_MAX_F32, PxD6JointDriveFlag::eACCELERATION));

					HandleInfo->HandleData->setDrive(PxD6Drive::eSLERP, PxD6JointDrive(NewGrip.Stiffness, NewGrip.Damping, PX_MAX_F32, PxD6JointDriveFlag::eACCELERATION));

						//HandleData->setDrive(PxD6Drive::eTWIST, PxD6JointDrive(Stiffness, Damping, PX_MAX_F32, PxD6JointDriveFlag::eACCELERATION));
						//HandleData->setDrive(PxD6Drive::eSWING, PxD6JointDrive(Stiffness, Damping, PX_MAX_F32, PxD6JointDriveFlag::eACCELERATION));
				}
			}
		}
	});
#else
	return false;
#endif // WITH_PHYSX

	return true;
}
void UPhysicsHandleComponent::GrabComponent(UPrimitiveComponent* InComponent, FName InBoneName, FVector Location, bool bConstrainRotation)
{
	// If we are already holding something - drop it first.
	if(GrabbedComponent != NULL)
	{
		ReleaseComponent();
	}

	if(!InComponent)
	{
		return;
	}

#if WITH_PHYSX
	// Get the PxRigidDynamic that we want to grab.
	FBodyInstance* BodyInstance = InComponent->GetBodyInstance(InBoneName);
	if (!BodyInstance)
	{
		return;
	}

	PxRigidDynamic* Actor = BodyInstance->GetPxRigidDynamic();
	if (!Actor)
		return;

	// Get the scene the PxRigidDynamic we want to grab is in.
	PxScene* Scene = Actor->getScene();
	check(Scene);

	// Get transform of actor we are grabbing
	PxVec3 KinLocation = U2PVector(Location);
	PxTransform GrabbedActorPose = Actor->getGlobalPose();
	PxTransform KinPose(KinLocation, GrabbedActorPose.q);

	// set target and current, so we don't need another "Tick" call to have it right
	TargetTransform = CurrentTransform = P2UTransform(KinPose);

	// If we don't already have a handle - make one now.
	if (!HandleData)
	{
		// Create kinematic actor we are going to create joint with. This will be moved around with calls to SetLocation/SetRotation.
		PxRigidDynamic* KinActor = Scene->getPhysics().createRigidDynamic(KinPose);
		KinActor->setRigidDynamicFlag(PxRigidDynamicFlag::eKINEMATIC, true);
		KinActor->setMass(1.0f);
		KinActor->setMassSpaceInertiaTensor(PxVec3(1.0f, 1.0f, 1.0f));

		// No bodyinstance
		KinActor->userData = NULL;

		// Add to Scene
		Scene->addActor(*KinActor);

		// Save reference to the kinematic actor.
		KinActorData = KinActor;
		
		// Create the joint
		PxVec3 LocalHandlePos = GrabbedActorPose.transformInv(KinLocation);
		PxD6Joint* NewJoint = PxD6JointCreate(Scene->getPhysics(), KinActor, PxTransform::createIdentity(), Actor, PxTransform(LocalHandlePos));

		if(!NewJoint)
		{
			HandleData = 0;
		}
		else
		{
			// No constraint instance
			NewJoint->userData = NULL;
			HandleData = NewJoint;

			// Remember the scene index that the handle joint/actor are in.
			FPhysScene* RBScene = FPhysxUserData::Get<FPhysScene>(Scene->userData);
			const uint32 SceneType = InComponent->BodyInstance.UseAsyncScene() ? PST_Async : PST_Sync;
			SceneIndex = RBScene->PhysXSceneIndex[SceneType];

			// Setting up the joint
			NewJoint->setMotion(PxD6Axis::eX, PxD6Motion::eFREE);
			NewJoint->setMotion(PxD6Axis::eY, PxD6Motion::eFREE);
			NewJoint->setMotion(PxD6Axis::eZ, PxD6Motion::eFREE);

			NewJoint->setDrive(PxD6Drive::eX, PxD6JointDrive(LinearStiffness, LinearDamping, PX_MAX_F32, PxD6JointDriveFlag::eACCELERATION));
			NewJoint->setDrive(PxD6Drive::eY, PxD6JointDrive(LinearStiffness, LinearDamping, PX_MAX_F32, PxD6JointDriveFlag::eACCELERATION));
			NewJoint->setDrive(PxD6Drive::eZ, PxD6JointDrive(LinearStiffness, LinearDamping, PX_MAX_F32, PxD6JointDriveFlag::eACCELERATION));
			NewJoint->setDrivePosition(PxTransform(PxVec3(0,0,0)));


			NewJoint->setMotion(PxD6Axis::eTWIST, PxD6Motion::eFREE);
			NewJoint->setMotion(PxD6Axis::eSWING1, PxD6Motion::eFREE);
			NewJoint->setMotion(PxD6Axis::eSWING2, PxD6Motion::eFREE);
			
			bRotationConstrained = bConstrainRotation;
			
			if (bRotationConstrained)
			{
				NewJoint->setDrive(PxD6Drive::eSLERP, PxD6JointDrive(AngularStiffness, AngularDamping, PX_MAX_F32, PxD6JointDriveFlag::eACCELERATION));

				//NewJoint->setDrive(PxD6Drive::eTWIST, PxD6JointDrive(AngularStiffness, AngularDamping, PX_MAX_F32, PxD6JointDriveFlag::eACCELERATION));
				//NewJoint->setDrive(PxD6Drive::eSWING, PxD6JointDrive(AngularStiffness, AngularDamping, PX_MAX_F32, PxD6JointDriveFlag::eACCELERATION));
				
				//PosJointDesc.setGlobalAxis(NxVec3(0,0,1));
			}

		}
	
	}
#endif // WITH_PHYSX


	GrabbedComponent = InComponent;
	GrabbedBoneName = InBoneName;
}