// D6 joint with a spring maintaining its position PxJoint* createDampedD6(PxPhysics* gPhysics, PxRigidActor* a0, const PxTransform& t0, PxRigidActor* a1, const PxTransform& t1) { PxD6Joint* j = PxD6JointCreate(*gPhysics, a0, t0, a1, t1); j->setMotion(PxD6Axis::eSWING1, PxD6Motion::eLOCKED); j->setMotion(PxD6Axis::eSWING2, PxD6Motion::eFREE); j->setMotion(PxD6Axis::eTWIST, PxD6Motion::eLOCKED); j->setDrive(PxD6Drive::eSLERP, PxD6JointDrive(0, 1000, FLT_MAX, true)); return j; }
physx::PxRigidDynamic* CPhysicManager::createDynamicSphere(const Vector3 &position, const float &radius, float mass, bool kinematic, bool trigger, int group, const Logic::Component::IPhysic *component) { assert(m_scene); PxTransform pose(Vector3ToPxVec3(position)); PxSphereGeometry geom(radius); PxMaterial *material = m_defaultMaterial; float density = mass / ((4/3) * Common::Util::Math::PI * radius * radius * radius); PxRigidDynamic *actor = nullptr; if(kinematic) { actor = PxCreateKinematic(*m_physics,pose,geom,*material,density); } else { actor = PxCreateDynamic(*m_physics,pose,geom,*material,density); } if(trigger) { PxShape *shape; actor->getShapes(&shape,1,0); shape->setFlag(PxShapeFlag::eSIMULATION_SHAPE, false); shape->setFlag(PxShapeFlag::eTRIGGER_SHAPE, true); } actor->userData = (void*)component; PxSetGroup(*actor,group); setupFiltering(actor,FilterGroup::eSPACE_FILTER,FilterGroup::eSPACE_FILTER); PxD6Joint* joint = PxD6JointCreate(*m_physics, actor, PxTransform::createIdentity(), nullptr, actor->getGlobalPose()); joint->setMotion(PxD6Axis::eX,PxD6Motion::eFREE); joint->setMotion(PxD6Axis::eY,PxD6Motion::eLOCKED); joint->setMotion(PxD6Axis::eZ,PxD6Motion::eFREE); joint->setMotion(PxD6Axis::eSWING1,PxD6Motion::eFREE); joint->setMotion(PxD6Axis::eSWING2,PxD6Motion::eLOCKED); joint->setMotion(PxD6Axis::eTWIST,PxD6Motion::eLOCKED); //TODO release //m_scene->addActor(*actor); return actor; }
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 InitPhysX() { cout<<"mass "<<Ma<<"\n"; cout<<"friction "<<friction<<"\n"; cout<<"dt "<<TempsFriction<<"\n"; cout<<"PhysX Version"<<PX_PHYSICS_VERSION<<"\n"; //Creating foundation for PhysX gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gDefaultAllocatorCallback, gDefaultErrorCallback); //Creating instance of PhysX SDK gPhysicsSDK = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale() ); if(gPhysicsSDK == NULL) { cerr<<"Error creating PhysX3 device, Exiting..."<<endl; exit(1); } //Creating scene PxSceneDesc sceneDesc(gPhysicsSDK->getTolerancesScale()); //Descriptor class for scenes //sceneDesc.gravity = PxVec3(0.0f, -9.8f, 0.0f); //Setting gravity sceneDesc.gravity = PxVec3(0.0f, 0.0f, 0.0f); //Setting gravity sceneDesc.cpuDispatcher = PxDefaultCpuDispatcherCreate(1); //Creates default CPU dispatcher for the scene /*//testing GPU dispatcher PxProfileZoneManager* profileZoneManager = &PxProfileZoneManager::createProfileZoneManager(gFoundation); PxCudaContextManagerDesc cudaContextManagerDesc; PxCudaContextManager* cudaContextManager = PxCreateCudaContextManager(*gFoundation,cudaContextManagerDesc,profileZoneManager); sceneDesc.gpuDispatcher = cudaContextManager->getGpuDispatcher(); *///testing GPU dispatcher sceneDesc.filterShader = customFilterShader; //Creates custom user collision filter shader for the scene sceneDesc.simulationEventCallback = &gSimulationEventCallback; //Resgistering for receiving simulation events sceneDesc.flags |= PxSceneFlag::eENABLE_CCD; //Set flag to enable CCD (Continuous Collision Detection) gScene = gPhysicsSDK->createScene(sceneDesc); //Creates a scene //This will enable basic visualization of PhysX objects like- actors collision shapes and their axes. //The function PxScene::getRenderBuffer() is used to render any active visualization for scene. gScene->setVisualizationParameter(PxVisualizationParameter::eSCALE, 1.0); //Global visualization scale which gets multiplied with the individual scales gScene->setVisualizationParameter(PxVisualizationParameter::eCOLLISION_SHAPES, 1.0f); //Enable visualization of actor's shape gScene->setVisualizationParameter(PxVisualizationParameter::eACTOR_AXES, 1.0f); //Enable visualization of actor's axis //Creating PhysX material (staticFriction, dynamicFriction, restitution) PxMaterial* material = gPhysicsSDK->createMaterial(0.5f,0.5f,0.5f); //---------Creating actors-----------] /* //1-Creating static plane that will act as ground PxTransform planePos = PxTransform(PxVec3(0.0f),PxQuat(PxHalfPi, PxVec3(0.0f, 0.0f, 1.0f))); //Position and orientation(transform) for plane actor PxRigidStatic* plane = gPhysicsSDK->createRigidStatic(planePos); //Creating rigid static actor plane->createShape(PxPlaneGeometry(), *material); //Defining geometry for plane actor gScene->addActor(*plane); //Adding plane actor to PhysX scene { //Creating a dynamic sphere (It will fall on to trigger shape which will invoke 'onTrigger()' function) PxTransform spherePos(PxVec3(-10.0f, 10.0f, 0.0f)); PxSphereGeometry sphereGeometry(2); PxRigidDynamic* sphere = PxCreateDynamic(*gPhysicsSDK, spherePos, sphereGeometry, *material, 1.0f); gScene->addActor(*sphere); //Creating a trigger shape(trigger shape can't collide against any abject, //thus it is made static otherwise it will fall under the effect of gravity) PxTransform boxPos(PxVec3(-10.0f, 2.10f, 0.0f)); PxShape* boxShape = gPhysicsSDK->createShape(PxBoxGeometry(PxVec3(3.0f,2.0f,3.0f)),*material); boxShape->setFlag(PxShapeFlag::eSIMULATION_SHAPE, false); //flagged to disable shape collision boxShape->setFlag(PxShapeFlag::eTRIGGER_SHAPE, true); //flagged as trigger shape PxRigidStatic* gBox = PxCreateStatic(*gPhysicsSDK, boxPos, *boxShape); gScene->addActor(*gBox); } */ { int numberofblocks=1000; //PxVec3 offset = PxVec3(0,0,-1); PxReal radius=1; PxReal height=1; PxVec3 offset0 = PxVec3(-height,0,0); PxVec3 offset1 = PxVec3(height,0,0); PxVec3 initpos = PxVec3(0.0f, 0.0f, 0.0f); PxTransform boxPos1(initpos,PxQuat(PxHalfPi, PxVec3(0.0f, 1.0f, 0.0f))); //Position and orientation(transform) for box actor PxRigidDynamic *gBoxOri = NULL; //Instance of box actor PxCapsuleGeometry sphereGeometry(4*radius,0.5*height); //Defining geometry for box actor gBoxOri = PxCreateDynamic(*gPhysicsSDK, boxPos1, sphereGeometry, *material, 1.0f); //Creating rigid static actor gBoxOri->setMass(Ma); gScene->addActor(*gBoxOri); //Adding box actor to PhysX scene arrayofBodies.push_back(gBoxOri); for (PxU32 i=1; i<numberofblocks; i++) { if (i<numberofblocks-1){ cout<<numberofblocks<<i<<"\n"; PxTransform boxPos1(initpos+PxVec3(0.0f, 0.0f, 2*i*height/*2.0f*/),PxQuat(PxHalfPi, PxVec3(0.0f, 1.0f, 0.0f))); //Position and orientation(transform) for box actor PxRigidDynamic *gBox = NULL; //Instance of box actor PxCapsuleGeometry sphereGeometry(radius,height); //Defining geometry for box actor gBox = PxCreateDynamic(*gPhysicsSDK, boxPos1, sphereGeometry, *material, 1.0f); //Creating rigid static actor gBox->setMass(Ma); gScene->addActor(*gBox); //Adding box actor to PhysX scene // adding some joint to the mix //PxSphericalJoint* joint = PxSphericalJointCreate(*gPhysicsSDK, gBoxOri, PxTransform(-offset), gBox, PxTransform(offset)); //PxSphericalJoint* joint = PxSphericalJointCreate(*gPhysicsSDK, gBoxOri, PxTransform(offset0), gBox, PxTransform(offset1)); //uncomment to use spherical joints PxD6Joint* joint = PxD6JointCreate(*gPhysicsSDK, gBoxOri, PxTransform(offset0), gBox, PxTransform(offset1)); //add some limits to the joint joint->setSwingLimit(PxJointLimitCone(1.57f,1.57f,0.1f)); joint->setConstraintFlag(PxConstraintFlag::eVISUALIZATION, true); joint->setMotion(PxD6Axis::eTWIST, PxD6Motion::eLOCKED); joint->setMotion(PxD6Axis::eSWING1, PxD6Motion::eLIMITED); joint->setMotion(PxD6Axis::eSWING2, PxD6Motion::eLIMITED); //joint->setMotion(PxD6Axis::eSWING1, PxD6Motion::eFREE); //free to rotate around y axis //add the body to the array before renaming the original box... arrayofBodies.push_back(gBox); gBoxOri=gBox; } if (i>=numberofblocks-1){ cout<<i<<"\n"; PxTransform boxPos1(initpos+PxVec3(0.0f, 0.0f, 2*i*height/*2.0f*/),PxQuat(PxHalfPi, PxVec3(0.0f, 1.0f, 0.0f))); //Position and orientation(transform) for box actor PxRigidDynamic *gBox = NULL; //Instance of box actor PxCapsuleGeometry sphereGeometry(4*radius,0.5*height); //Defining geometry for box actor gBox = PxCreateDynamic(*gPhysicsSDK, boxPos1, sphereGeometry, *material, 1.0f); //Creating rigid static actor gBox->setMass(Ma); gScene->addActor(*gBox); //Adding box actor to PhysX scene // adding some joint to the mix //PxSphericalJoint* joint = PxSphericalJointCreate(*gPhysicsSDK, gBoxOri, PxTransform(-offset), gBox, PxTransform(offset)); //PxSphericalJoint* joint = PxSphericalJointCreate(*gPhysicsSDK, gBoxOri, PxTransform(offset0), gBox, PxTransform(offset1)); //uncomment to use spherical joints PxD6Joint* joint = PxD6JointCreate(*gPhysicsSDK, gBoxOri, PxTransform(offset0), gBox, PxTransform(offset1)); //add some limits to the joint joint->setSwingLimit(PxJointLimitCone(1.57f,1.57f,0.1f)); joint->setConstraintFlag(PxConstraintFlag::eVISUALIZATION, true); joint->setMotion(PxD6Axis::eTWIST, PxD6Motion::eLOCKED); joint->setMotion(PxD6Axis::eSWING1, PxD6Motion::eLIMITED); joint->setMotion(PxD6Axis::eSWING2, PxD6Motion::eLIMITED); //joint->setMotion(PxD6Axis::eSWING1, PxD6Motion::eFREE); //free to rotate around y axis //add the body to the array before renaming the original box... arrayofBodies.push_back(gBox); gBoxOri=gBox; } //cout<< i <<"\n"; } //Creating a rigid dynamic box resting on static plane /* PxTransform boxPos(PxVec3(10.0f, 2.0f, 0.0f)); PxBoxGeometry boxGeometry(PxVec3(30.0f,2.0f,30.0f)); PxRigidDynamic* box2 = PxCreateDynamic(*gPhysicsSDK, boxPos, boxGeometry, *material, 1.0f); gScene->addActor(*box2); */ } }
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; }