void AddRadialForceToPxRigidDynamic(PxRigidDynamic& PRigidDynamic, const FVector& Origin, float Radius, float Strength, uint8 Falloff) { #if WITH_PHYSX if (!(PRigidDynamic.getRigidDynamicFlags() & PxRigidDynamicFlag::eKINEMATIC)) { float Mass = PRigidDynamic.getMass(); PxTransform PCOMTransform = PRigidDynamic.getGlobalPose().transform(PRigidDynamic.getCMassLocalPose()); PxVec3 PCOMPos = PCOMTransform.p; // center of mass in world space PxVec3 POrigin = U2PVector(Origin); // origin of radial impulse, in world space PxVec3 PDelta = PCOMPos - POrigin; // vector from float Mag = PDelta.magnitude(); // Distance from COM to origin, in Unreal scale : @todo: do we still need conversion scale? // If COM is outside radius, do nothing. if (Mag > Radius) { return; } PDelta.normalize(); // If using linear falloff, scale with distance. float ForceMag = Strength; if (Falloff == RIF_Linear) { ForceMag *= (1.0f - (Mag / Radius)); } // Apply force PxVec3 PImpulse = PDelta * ForceMag; PRigidDynamic.addForce(PImpulse, PxForceMode::eFORCE); } #endif // WITH_PHYSX }
void AddRadialImpulseToPxRigidDynamic(PxRigidDynamic& PRigidDynamic, const FVector& Origin, float Radius, float Strength, uint8 Falloff, bool bVelChange) { #if WITH_PHYSX if (!(PRigidDynamic.getRigidDynamicFlags() & PxRigidDynamicFlag::eKINEMATIC)) { float Mass = PRigidDynamic.getMass(); PxTransform PCOMTransform = PRigidDynamic.getGlobalPose().transform(PRigidDynamic.getCMassLocalPose()); PxVec3 PCOMPos = PCOMTransform.p; // center of mass in world space PxVec3 POrigin = U2PVector(Origin); // origin of radial impulse, in world space PxVec3 PDelta = PCOMPos - POrigin; // vector from origin to COM float Mag = PDelta.magnitude(); // Distance from COM to origin, in Unreal scale : @todo: do we still need conversion scale? // If COM is outside radius, do nothing. if (Mag > Radius) { return; } PDelta.normalize(); // Scale by U2PScale here, because units are velocity * mass. float ImpulseMag = Strength; if (Falloff == RIF_Linear) { ImpulseMag *= (1.0f - (Mag / Radius)); } PxVec3 PImpulse = PDelta * ImpulseMag; PxForceMode::Enum Mode = bVelChange ? PxForceMode::eVELOCITY_CHANGE : PxForceMode::eIMPULSE; PRigidDynamic.addForce(PImpulse, Mode); } #endif // WITH_PHYSX }
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)); }