PxRigidDynamic* PxCloneDynamic(PxPhysics& physicsSDK, const PxTransform& transform, const PxRigidDynamic& from) { PxRigidDynamic* to = physicsSDK.createRigidDynamic(transform); if(!to) return NULL; copyStaticProperties(*to, from); to->setRigidDynamicFlags(from.getRigidDynamicFlags()); to->setMass(from.getMass()); to->setMassSpaceInertiaTensor(from.getMassSpaceInertiaTensor()); to->setCMassLocalPose(from.getCMassLocalPose()); to->setLinearVelocity(from.getLinearVelocity()); to->setAngularVelocity(from.getAngularVelocity()); to->setLinearDamping(from.getAngularDamping()); to->setAngularDamping(from.getAngularDamping()); to->setMaxAngularVelocity(from.getMaxAngularVelocity()); PxU32 posIters, velIters; from.getSolverIterationCounts(posIters, velIters); to->setSolverIterationCounts(posIters, velIters); to->setSleepThreshold(from.getSleepThreshold()); to->setContactReportThreshold(from.getContactReportThreshold()); return to; }
PxRigidDynamic* PxCreateKinematic(PxPhysics& sdk, const PxTransform& transform, PxShape& shape, PxReal density) { PX_CHECK_AND_RETURN_NULL(transform.isValid(), "PxCreateKinematic: transform is not valid."); bool isDynGeom = isDynamicGeometry(shape.getGeometryType()); if(isDynGeom && density <= 0.0f) return NULL; PxRigidDynamic* actor = sdk.createRigidDynamic(transform); if(actor) { actor->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, true); if(!isDynGeom) shape.setFlag(PxShapeFlag::eSIMULATION_SHAPE, false); actor->attachShape(shape); if(isDynGeom) PxRigidBodyExt::updateMassAndInertia(*actor, density); else { actor->setMass(1.f); actor->setMassSpaceInertiaTensor(PxVec3(1.f,1.f,1.f)); } } return actor; }
PxRigidDynamic* PxCreateKinematic(PxPhysics& sdk, const PxTransform& transform, const PxGeometry& geometry, PxMaterial& material, PxReal density, const PxTransform& shapeOffset) { PX_CHECK_AND_RETURN_NULL(transform.isValid(), "PxCreateKinematic: transform is not valid."); PX_CHECK_AND_RETURN_NULL(shapeOffset.isValid(), "PxCreateKinematic: shapeOffset is not valid."); bool isDynGeom = isDynamicGeometry(geometry); if(isDynGeom && density <= 0.0f) return NULL; PxShape* shape; PxRigidDynamic* actor = setShape(sdk.createRigidDynamic(transform), geometry, material, shapeOffset, shape); if(actor) { actor->setRigidDynamicFlag(PxRigidDynamicFlag::eKINEMATIC, true); if(isDynGeom) PxRigidBodyExt::updateMassAndInertia(*actor, density); else { shape->setFlag(PxShapeFlag::eSIMULATION_SHAPE, false); actor->setMass(1); actor->setMassSpaceInertiaTensor(PxVec3(1,1,1)); } } return actor; }
void PxScaleRigidActor(PxRigidActor& actor, PxReal scale, bool scaleMassProps) { PX_CHECK_AND_RETURN(scale > 0, "PxScaleRigidActor requires that the scale parameter is greater than zero"); Ps::InlineArray<PxShape*, 64> shapes; shapes.resize(actor.getNbShapes()); actor.getShapes(shapes.begin(), shapes.size()); for(PxU32 i=0;i<shapes.size();i++) { shapes[i]->setLocalPose(scalePosition(shapes[i]->getLocalPose(), scale)); PxGeometryHolder h = shapes[i]->getGeometry(); switch(h.getType()) { case PxGeometryType::eSPHERE: h.sphere().radius *= scale; break; case PxGeometryType::ePLANE: break; case PxGeometryType::eCAPSULE: h.capsule().halfHeight *= scale; h.capsule().radius *= scale; break; case PxGeometryType::eBOX: h.box().halfExtents *= scale; break; case PxGeometryType::eCONVEXMESH: h.convexMesh().scale.scale *= scale; break; case PxGeometryType::eTRIANGLEMESH: h.triangleMesh().scale.scale *= scale; break; case PxGeometryType::eHEIGHTFIELD: h.heightField().heightScale *= scale; h.heightField().rowScale *= scale; h.heightField().columnScale *= scale; break; case PxGeometryType::eINVALID: case PxGeometryType::eGEOMETRY_COUNT: default: PX_ASSERT(0); } shapes[i]->setGeometry(h.any()); } if(!scaleMassProps) return; PxRigidDynamic* dynamic = (&actor)->is<PxRigidDynamic>(); if(!dynamic) return; PxReal scale3 = scale*scale*scale; dynamic->setMass(dynamic->getMass()*scale3); dynamic->setMassSpaceInertiaTensor(dynamic->getMassSpaceInertiaTensor()*scale3*scale*scale); dynamic->setCMassLocalPose(scalePosition(dynamic->getCMassLocalPose(), scale)); }
void PhysXRigidManager::setInertiaTensor(std::string name, float * value) { if (rigidBodies.find(name) != rigidBodies.end()) { PxRigidDynamic * dyn = rigidBodies[name].info.actor->is<PxRigidDynamic>(); if (dyn) { dyn->setMassSpaceInertiaTensor(PxVec3(value[0], value[1], value[2])); } } }
PxRigidDynamic* Vehicle::createVehicleActor(const PxVehicleChassisData& chassisData, PxMaterial** wheelMaterials, PxConvexMesh** wheelConvexMeshes, const PxU32 numWheels, PxMaterial** chassisMaterials, PxConvexMesh** chassisConvexMeshes, const PxU32 numChassisMeshes, PxPhysics& physics, PxVec3 initPos) { //We need a rigid body actor for the vehicle. //Don't forget to add the actor to the scene after setting up the associated vehicle. PxRigidDynamic* vehActor = physics.createRigidDynamic(PxTransform(initPos)); vehActor->setRigidBodyFlag(PxRigidBodyFlag::eENABLE_CCD, true); //Wheel and chassis simulation filter data. PxFilterData wheelSimFilterData; wheelSimFilterData.word0 = COLLISION_FLAG_WHEEL; wheelSimFilterData.word1 = COLLISION_FLAG_WHEEL_AGAINST; PxFilterData chassisSimFilterData; chassisSimFilterData.word0 = COLLISION_FLAG_CHASSIS; chassisSimFilterData.word1 = COLLISION_FLAG_CHASSIS_AGAINST; //Wheel and chassis query filter data. //Optional: cars don't drive on other cars. PxFilterData wheelQryFilterData; wheelQryFilterData.word0 = FilterGroup::eWHEEL; setupNonDrivableSurface(wheelQryFilterData); PxFilterData chassisQryFilterData; chassisQryFilterData.word0 = FilterGroup::eVEHICLE; setupNonDrivableSurface(chassisQryFilterData); //Add all the wheel shapes to the actor. for (PxU32 i = 0; i < numWheels; i++) { PxConvexMeshGeometry geom(wheelConvexMeshes[i]); PxShape* wheelShape = vehActor->createShape(geom, *wheelMaterials[i]); wheelShape->setQueryFilterData(wheelQryFilterData); wheelShape->setSimulationFilterData(wheelSimFilterData); wheelShape->setLocalPose(PxTransform(PxIdentity)); } //Add the chassis shapes to the actor. for (PxU32 i = 0; i < numChassisMeshes; i++) { PxShape* chassisShape = vehActor->createShape (PxConvexMeshGeometry(chassisConvexMeshes[i]), *chassisMaterials[i]); chassisShape->setQueryFilterData(chassisQryFilterData); chassisShape->setSimulationFilterData(chassisSimFilterData); chassisShape->setLocalPose(PxTransform(PxIdentity)); } vehActor->setMass(chassisData.mMass); vehActor->setMassSpaceInertiaTensor(chassisData.mMOI); vehActor->setCMassLocalPose(PxTransform(chassisData.mCMOffset, PxQuat(PxIdentity))); return vehActor; }
PxRigidDynamic* SampleParticles::Raygun::createRayCapsule(bool enableCollision, PxFilterData filterData) { PxRigidDynamic* actor = mSample->getPhysics().createRigidDynamic(PxTransform::createIdentity()); mSample->runtimeAssert(actor, "PxPhysics::createRigidDynamic returned NULL\n"); PxShape* shape = actor->createShape(PxCapsuleGeometry(0.1f, 150.0f), mSample->getDefaultMaterial()); mSample->runtimeAssert(shape, "PxRigidDynamic::createShape returned NULL\n"); shape->setFlag(PxShapeFlag::eSCENE_QUERY_SHAPE, false); shape->setFlag(PxShapeFlag::eSIMULATION_SHAPE, enableCollision); shape->setSimulationFilterData(filterData); actor->setRigidDynamicFlag(PxRigidDynamicFlag::eKINEMATIC, true); actor->setMass(1.0f); actor->setMassSpaceInertiaTensor(PxVec3(1.0f)); mSample->getActiveScene().addActor(*actor); return actor; }
PxRigidDynamic* CloneDynamic(PxPhysics& physicsSDK, const PxTransform& transform, const PxRigidDynamic& from, NxMirrorScene::MirrorFilter &mirrorFilter) { PxRigidDynamic* to = physicsSDK.createRigidDynamic(transform); if(!to) return NULL; if ( !copyStaticProperties(*to, from, mirrorFilter) ) { to->release(); to = NULL; return NULL; } to->setRigidDynamicFlags(from.getRigidDynamicFlags()); to->setMass(from.getMass()); to->setMassSpaceInertiaTensor(from.getMassSpaceInertiaTensor()); to->setCMassLocalPose(from.getCMassLocalPose()); if ( !(to->getRigidDynamicFlags() & PxRigidDynamicFlag::eKINEMATIC) ) { to->setLinearVelocity(from.getLinearVelocity()); to->setAngularVelocity(from.getAngularVelocity()); } to->setLinearDamping(from.getAngularDamping()); to->setAngularDamping(from.getAngularDamping()); to->setMaxAngularVelocity(from.getMaxAngularVelocity()); PxU32 posIters, velIters; from.getSolverIterationCounts(posIters, velIters); to->setSolverIterationCounts(posIters, velIters); to->setSleepThreshold(from.getSleepThreshold()); to->setContactReportThreshold(from.getContactReportThreshold()); return to; }
bool CTank::CreateTankActor( CPhysX * pPhysX ) { if( !LoadData( "InitShader.lua" ) ) return false; // CParamTank* pParamTank = new CParamTank; // // if( !CLua::LoadParamTank( "", &pParamTank ) ) // { // // } if( GameObject * pBody = GetDetail( BODY ) ) { if ( pBody->CreateTriangleMesh( pPhysX ) ) { pBody->Update( 0.f ); PxTriangleMesh* triangleMesh = pBody->GetTriangleMesh(); D3DXVECTOR3 Position = pBody->GetPosition(); //D3DXComputeBoundingBox(Vertices, g_pMesh->GetNumVertices(), FVFVertexSize, &pMin, &pMax); //PxRigidDynamic* pRigDynAct = pPhysX->GetPhysics()->createRigidDynamic( PxTransform( physx::PxVec3( Position.x, Position.y, Position.z ) ) ); // PxRigidDynamic* pRigDynAct = PxCreateDynamic( *pPhysX->GetPhysics(), PxTransform( physx::PxVec3( Position.x, Position.y, Position.z ) ), PxBoxGeometry( 14.f, 4.6f, 6.f ), *pMaterial, 1.f ); // // if( pRigDynAct && pMaterial && triangleMesh ) // { // //pRigDynAct->createShape( PxTriangleMeshGeometry( triangleMesh ), *pMaterial ); // // pRigDynAct->setRigidDynamicFlag(PxRigidDynamicFlag::eKINEMATIC, false); // pRigDynAct->setActorFlag( PxActorFlag::eVISUALIZATION, true ); // pRigDynAct->setAngularDamping( 0.5f ); // //pRigDynAct->setMass( 10000.f ); // PxRigidBodyExt::updateMassAndInertia( *pRigDynAct, 10.f ); // // if( pMaterial ) // pPhysX->PushMaterial( pMaterial ); // // pPhysX->AddActorScene( pRigDynAct ); // m_pActor = pRigDynAct; // // return true; // } const int nWheels = 12; PxF32 chassisMass = 1500.f; const PxF32 wheelMass = 50.f; PxF32 fShift = -0.85f; PxVec3 wheelCentreOffsets[ nWheels ]; for( int i = 0; i < nWheels/2; ++i ) { wheelCentreOffsets[ i*2 ] = PxVec3( -1.2f, -0.5f, 2.1f + i * fShift ); wheelCentreOffsets[ i*2+1 ] = PxVec3( 1.2f, -0.5f, 2.1f + i * fShift ); } // размеры корпуса const PxVec3 chassisDims( 2.4f, 1.f, 6.f );// = computeChassisAABBDimensions(chassisConvexMesh); // Начало координат находится в центре шасси сетки // Установить центр масс будет ниже этой точки const PxVec3 chassisCMOffset = PxVec3( 0.f, -chassisDims.y * 0.5f - 0.65f, 0.f ); PxVehicleWheelsSimData* wheelsSimData = PxVehicleWheelsSimData::allocate( nWheels ); PxVehicleWheelsSimData& wheelsData = *wheelsSimData; PxVehicleDriveSimData4W driveData; PxVec3 chassisMOI( (chassisDims.y*chassisDims.y + chassisDims.z * chassisDims.z) * chassisMass / 12.f, (chassisDims.x*chassisDims.x + chassisDims.z * chassisDims.z) * chassisMass / 12.f, (chassisDims.x*chassisDims.x + chassisDims.y * chassisDims.y) * chassisMass / 12.f); // структура шасси PxVehicleChassisData chassisData; chassisData.mMass = chassisMass; // Масса транспортного средства жесткой актер тела chassisData.mMOI = chassisMOI; // Момент инерции автомобиля жесткая актер тела. chassisData.mCMOffset = chassisCMOffset; // Центр масс смещение автомобиля жесткая актер тела. // Немного настройки здесь.Автомобиль будет иметь более отзывчивым поворот, если мы сведем // у-компоненты шасси момента инерции. chassisMOI.y *= 0.8f; const PxF32 massRear = 0.5f * chassisMass * ( chassisDims.z - 3 * chassisCMOffset.z ) / chassisDims.z; const PxF32 massFront = massRear; //Extract the wheel radius and width from the wheel convex meshes PxF32 wheelWidths[ nWheels ] = {0.f}; PxF32 wheelRadii[ nWheels ] = {0.f}; for( PxU32 i = 0; i < nWheels; ++i ) { wheelWidths[ i ] = 0.5f; wheelRadii [ i ] = 0.32f; } // Теперь вычислим колеса массы и инерции компонентов вокруг оси оси PxF32 wheelMOIs[ nWheels ]; for( PxU32 i = 0; i < nWheels; ++i ) { wheelMOIs[ i ] = 0.5f * wheelMass * wheelRadii[ i ] * wheelRadii[ i ]; } // Давайте создадим структуру данных колеса теперь с радиусом, массы и МВД PxVehicleWheelData wheels[ nWheels ]; for(PxU32 i = 0; i < nWheels; ++i ) { wheels[ i ].mRadius = wheelRadii[ i ]; // Радиус блок, который включает в себя колеса металл плюс резиновые шины wheels[ i ].mMass = wheelMass; // Масса колеса плюс шины wheels[ i ].mMOI = wheelMOIs[ i ]; // Момент инерции колеса wheels[ i ].mWidth = wheelWidths[ i ]; // Максимальная ширина блок, который включает в себя колеса плюс шин //wheels[ i ].mMaxHandBrakeTorque = 0.f; // Отключение стояночного тормоза от передних колес и позволяют для задних колес //wheels[ i ].mMaxSteer = 0.f; // Включить рулевого управления для передних колес и отключить для передних колес //wheels[ i ].mDampingRate = 1.f; // Скорость затухания описывает скорость, с которой свободно вращающееся колесо теряет скорость вращения } //Let's set up the tire data structures now. //Put slicks on the front tires and wets on the rear tires. PxVehicleTireData tires[ nWheels ]; for(PxU32 i = 0; i < nWheels; ++i ) { tires[ i ].mType = 1; // тип сцепления шин с поверхностью } // Структура данных подвески PxVehicleSuspensionData susps[ nWheels ]; for( PxU32 i = 0; i < nWheels; i++ ) { susps[ i ].mMaxCompression = 0.03f; // Максимальное сжатие пружинной подвески susps[ i ].mMaxDroop = 0.03f; // Максимальное удлинение пружинной подвески susps[ i ].mSpringStrength = 20000.f; // пружинная сила подвески блока susps[ i ].mSpringDamperRate = 500.f; susps[ i ].mSprungMass = chassisMass / nWheels; // Масса транспортного средства, которая поддерживается пружинная подвеска, указанных в кг. } PxVec3 suspTravelDirections[ nWheels ]; PxVec3 wheelCentreCMOffsets[ nWheels ]; PxVec3 suspForceAppCMOffsets[ nWheels ]; PxVec3 tireForceAppCMOffsets[ nWheels ]; for( PxU32 i = 0 ; i < nWheels; ++i ) { wheelCentreCMOffsets [ i ] = wheelCentreOffsets[ i ] - chassisCMOffset; suspForceAppCMOffsets[ i ] = PxVec3( wheelCentreCMOffsets[ i ].x, -0.3f, wheelCentreCMOffsets[ i ].z ); tireForceAppCMOffsets[ i ] = PxVec3( wheelCentreCMOffsets[ i ].x, -0.3f, wheelCentreCMOffsets[ i ].z ); suspTravelDirections [ i ] = PxVec3( 0, -1, 0 ); // направление подвески } // Теперь добавьте колеса, шины и подвеска данных for( PxU32 i = 0; i < nWheels; ++i ) { wheelsData.setWheelData( i, wheels[ i ] ); // установить данные колеса wheelsData.setTireData( i, tires[ i ] ); // Установите шину данных колеса wheelsData.setSuspensionData( i, susps[ i ] ); // Установите подвеску данные колеса wheelsData.setSuspTravelDirection( i, suspTravelDirections[ i ] ); // Установить направление движения подвески колес wheelsData.setWheelCentreOffset( i, wheelCentreCMOffsets[ i ] ); // Установить смещение от центра жесткой тело массой в центре колеса wheelsData.setSuspForceAppPointOffset( i, suspForceAppCMOffsets[ i ] ); // Установить приложение точкой подвески силу подвески колес wheelsData.setTireForceAppPointOffset( i, tireForceAppCMOffsets[ i ] ); // Установить приложение точку шин силу шинах колес } //Diff PxVehicleDifferential4WData diff; diff.mType = PxVehicleDifferential4WData::eDIFF_TYPE_LS_4WD; driveData.setDiffData( diff ); //Engine PxVehicleEngineData engine; engine.mPeakTorque = 300.f; // максимальная скорость вращения двигателя engine.mMaxOmega = 400.f; // Максимальный крутящий момент доступен обратиться к двигателю engine.mDampingRateFullThrottle = 0.15f; // скорость затухания двигатель при полностью открытой дроссельной заслонке engine.mDampingRateZeroThrottleClutchEngaged = 8.f; // скорость затухания двигатель при нулевой газ при включении сцепления engine.mDampingRateZeroThrottleClutchDisengaged = 0.35f; // Краткие скорость затухания двигатель при нулевой газ при выключенном сцеплении (на нейтральной передаче) driveData.setEngineData( engine ); //Gears PxVehicleGearsData gears; gears.mSwitchTime = 0.5f; driveData.setGearsData( gears ); // Прочность сцепления PxVehicleClutchData clutch; clutch.mStrength = PxVehicleGearsData::eMAX_NUM_GEAR_RATIOS; driveData.setClutchData( clutch ); //Ackermann steer accuracy PxVehicleAckermannGeometryData ackermann; ackermann.mAccuracy = 0.1f; ackermann.mAxleSeparation = wheelCentreOffsets[ 0 ].z - wheelCentreOffsets[ nWheels - 1 ].z; // Расстояние между центром передней оси и центром задней оси ackermann.mFrontWidth = wheelCentreOffsets[ 0 ].x - wheelCentreOffsets[ 1 ].x; // Расстояние между центральной точке два передних колеса ackermann.mRearWidth = wheelCentreOffsets[ nWheels - 2 ].x - wheelCentreOffsets[ nWheels - 1 ].x; // Расстояние между центральной точке два задних колеса driveData.setAckermannGeometryData(ackermann); PxTriangleMesh * pTriangleMesh = 0; D3DXVECTOR3 vPosition; if( GameObject * pRoller = GetDetail( WHEEL_LEFT_1ST ) ) { if( pRoller->CreateTriangleMesh( pPhysX ) ) { pRoller->Update( 0.f ); pTriangleMesh = pRoller->GetTriangleMesh(); Position = pRoller->GetPosition(); } } // Нам нужно добавить колеса столкновения форм, их местный позы, материал для колес, и моделирование фильтра для колес PxTriangleMeshGeometry WheelGeom( pTriangleMesh ); PxGeometry* wheelGeometries[ nWheels ] = {0}; PxTransform wheelLocalPoses[ nWheels ]; for( PxU32 i = 0; i < nWheels; ++i ) { wheelGeometries[ i ] = &WheelGeom; wheelLocalPoses[ i ] = PxTransform::createIdentity(); } PxMaterial* pMaterial = pPhysX->GetPhysics()->createMaterial( 0.5f, 0.5f, 0.1f ); //коэффициенты трения скольжения и покоя(Dynamic friction,Static friction), коэффициент упругости const PxMaterial& wheelMaterial = *pMaterial; PxFilterData wheelCollFilterData; wheelCollFilterData.word0 = COLLISION_FLAG_WHEEL; wheelCollFilterData.word1 = COLLISION_FLAG_WHEEL_AGAINST; // Нам нужно добавить шасси столкновения форм, их местный позы, материала для шасси и моделирования фильтр для шасси. //PxBoxGeometry chassisConvexGeom( 1.5f, 0.3f, 4.f ); PxBoxGeometry chassisConvexGeom( chassisDims.x/2, chassisDims.y/2, chassisDims.z/2 ); const PxGeometry* chassisGeoms = &chassisConvexGeom; const PxTransform chassisLocalPoses = PxTransform::createIdentity(); const PxMaterial& chassisMaterial = *pMaterial; PxFilterData chassisCollFilterData; chassisCollFilterData.word0 = COLLISION_FLAG_CHASSIS; chassisCollFilterData.word1 = COLLISION_FLAG_CHASSIS_AGAINST; // Создание фильтра запроса данных для автомобилей, чтобы машины не пытайтесь ездить на себя. PxFilterData vehQryFilterData; SampleVehicleSetupVehicleShapeQueryFilterData( &vehQryFilterData ); PxRigidDynamic* vehActor = pPhysX->GetPhysics()->createRigidDynamic( PxTransform::createIdentity() ); //Add all the wheel shapes to the actor. for( PxU32 i = 0; i < nWheels; ++i ) { PxShape* wheelShape=vehActor->createShape( *wheelGeometries[ i ], wheelMaterial ); wheelShape->setQueryFilterData( vehQryFilterData ); wheelShape->setSimulationFilterData( wheelCollFilterData ); wheelShape->setLocalPose( wheelLocalPoses[ i ] ); wheelShape->setFlag( PxShapeFlag::eSIMULATION_SHAPE, true ); } //Add the chassis shapes to the actor PxShape* chassisShape = vehActor->createShape( *chassisGeoms, chassisMaterial ); chassisShape->setQueryFilterData( vehQryFilterData ); chassisShape->setSimulationFilterData( chassisCollFilterData ); chassisShape->setLocalPose( PxTransform( physx::PxVec3( 0, 0, 0 ) ) ); vehActor->setMass( chassisData.mMass ); vehActor->setMassSpaceInertiaTensor( chassisData.mMOI ); vehActor->setCMassLocalPose( PxTransform( chassisData.mCMOffset, PxQuat::createIdentity() ) ); vehActor->setGlobalPose( PxTransform( physx::PxVec3( 0, 8, 0 ), PxQuat::createIdentity() ) ); PxVehicleDriveTank* pTank = PxVehicleDriveTank::allocate( nWheels ); pTank->setup( pPhysX->GetPhysics(), vehActor, *wheelsSimData, driveData, nWheels ); pPhysX->AddActorScene( vehActor ); m_pActor = vehActor; pPhysX->AddTank( pTank ); //Free the sim data because we don't need that any more. wheelsSimData->free(); //pTank->setDriveModel( PxVehicleDriveTank::eDRIVE_MODEL_SPECIAL ); pTank->setToRestState(); pTank->mDriveDynData.setUseAutoGears( true ); return true; } } return false; }
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; }