void AddRadialForceToPxRigidBody_AssumesLocked(PxRigidBody& PRigidBody, const FVector& Origin, float Radius, float Strength, uint8 Falloff, bool bAccelChange)
{
#if WITH_PHYSX
	if (!(PRigidBody.getRigidBodyFlags() & PxRigidBodyFlag::eKINEMATIC))
	{
		float Mass = PRigidBody.getMass();
		PxTransform PCOMTransform = PRigidBody.getGlobalPose().transform(PRigidBody.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;
		PRigidBody.addForce(PImpulse, bAccelChange ? PxForceMode::eACCELERATION : PxForceMode::eFORCE);
	}
#endif // WITH_PHYSX
}
void AddRadialImpulseToPxRigidBody_AssumesLocked(PxRigidBody& PRigidBody, const FVector& Origin, float Radius, float Strength, uint8 Falloff, bool bVelChange)
{
#if WITH_PHYSX
	if (!(PRigidBody.getRigidBodyFlags() & PxRigidBodyFlag::eKINEMATIC))
	{
		float Mass = PRigidBody.getMass();
		PxTransform PCOMTransform = PRigidBody.getGlobalPose().transform(PRigidBody.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;
		PRigidBody.addForce(PImpulse, Mode);
	}
#endif // WITH_PHYSX
}
示例#3
0
void PhysActor_PhysX::AddForce(vec3f force, PhysForceMode::Enum mode)
{
	if (!impl->physActor)
	{
		LOG("Cannot add force to actor because physActor is null!");
		return;
	}

	PxRigidBody* actor = nullptr;

	PxVec3 pushDir;
	pushDir.x = force.x;
	pushDir.y = force.y;
	pushDir.z = force.z;

	PxForceMode::Enum physXMode;

	switch (mode)
	{
		case PhysForceMode::Acceleration:
			physXMode = PxForceMode::eACCELERATION;
			break;

		case PhysForceMode::Force:
			physXMode = PxForceMode::eFORCE;
			break;

		case PhysForceMode::VelocityChange:
			physXMode = PxForceMode::eVELOCITY_CHANGE;
			break;

		case PhysForceMode::Impulse:
		default:
			physXMode = PxForceMode::eIMPULSE;
			break;
	}

	if (impl->physActor->isRigidDynamic() || impl->physActor->isRigidBody())
	{
		actor = (PxRigidBody*)impl->physActor;
	}
	else
	{
		LOG("Cannot add force to actor because actor is not a Rigid Dynamic or Rigid Body actor.");
		return;
	}

	if (actor)
		actor->addForce(pushDir, physXMode);
}
示例#4
0
PX_INLINE void addForceAtPosInternal(PxRigidBody& body, const PxVec3& force, const PxVec3& pos, PxForceMode::Enum mode, bool wakeup)
{
	if(mode == PxForceMode::eACCELERATION || mode == PxForceMode::eVELOCITY_CHANGE)
	{
		Ps::getFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, 
			"PxRigidBodyExt::addForce methods do not support eACCELERATION or eVELOCITY_CHANGE modes");
		return;
	}

	const PxTransform globalPose = body.getGlobalPose();
	const PxVec3 centerOfMass = globalPose.transform(body.getCMassLocalPose().p);

	const PxVec3 torque = (pos - centerOfMass).cross(force);
	body.addForce(force, mode, wakeup);
	body.addTorque(torque, mode, wakeup);
}
/** Applies forces - Assumes caller has obtained writer lock */
void FPhysSubstepTask::ApplyForces_AssumesLocked(const FPhysTarget& PhysTarget, FBodyInstance* BodyInstance)
{
#if WITH_PHYSX
	/** Apply Forces */
	PxRigidBody* PRigidBody = BodyInstance->GetPxRigidBody_AssumesLocked();

	for (int32 i = 0; i < PhysTarget.Forces.Num(); ++i)
	{
		const FForceTarget& ForceTarget = PhysTarget.Forces[i];

		if (ForceTarget.bPosition)
		{
			PxRigidBodyExt::addForceAtPos(*PRigidBody, U2PVector(ForceTarget.Force), U2PVector(ForceTarget.Position), PxForceMode::eFORCE, true);
		}
		else
		{
			PRigidBody->addForce(U2PVector(ForceTarget.Force), ForceTarget.bAccelChange ? PxForceMode::eACCELERATION : PxForceMode::eFORCE, true);
		}
	}
#endif
}
示例#6
0
// Called every frame for vehicle
void Vehicle::update()
{
    resetIfNeeded();

    float handBrake = 0;
    float forwardSpeed = physicsVehicle->computeForwardSpeed();
    (input.handBrake) ? handBrake = 1.0f: handBrake = 0.0f;

    // Force gear change if speed is 0 (works, not sure why)
    if (forwardSpeed == 0)
    {
        if (input.forward > 0)
        {
            physicsVehicle->mDriveDynData.forceGearChange(PxVehicleGearsData::eFIRST);
        }
        else if (input.backward > 0)
        {
            physicsVehicle->mDriveDynData.forceGearChange(PxVehicleGearsData::eREVERSE);
        }
    }
    // If speed is close to 0 set new target gear
    else if (forwardSpeed < 5 && input.backward > 0)
    {
        physicsVehicle->mDriveDynData.setTargetGear(PxVehicleGearsData::eREVERSE);
    }
    else if (forwardSpeed > -5 && input.forward > 0)
    {
        physicsVehicle->mDriveDynData.setTargetGear(PxVehicleGearsData::eFIRST);
    }

    // Determine how to apply controller input depending on current gear
    if (physicsVehicle->mDriveDynData.getCurrentGear() == PxVehicleGearsData::eREVERSE)
    {
        vehicleInput.setAnalogAccel(input.backward);
        vehicleInput.setAnalogBrake(input.forward);
    }
    else
    {
        vehicleInput.setAnalogAccel(input.forward);
        vehicleInput.setAnalogBrake(input.backward);
        if(input.forward > 0)
            gasSignal(this);
    }
    if (input.forward == 0 && input.backward == 0)
        idleSignal(this);
    if (isSlipping && (forwardSpeed > 5 || forwardSpeed < -5))
        brakeSignal(this);

    // Steer and handbrake
    vehicleInput.setAnalogSteer(input.steer);
    vehicleInput.setAnalogHandbrake(handBrake);

    PxVehicleDrive4WSmoothAnalogRawInputsAndSetAnalogInputs(smoothingData, steerVsSpeedTable, vehicleInput, stepSizeS, isInAir, *physicsVehicle);

    if (input.shootPizza)
    {
        if (pizzaCount > 0)
        {
            shootPizzaSignal(this);
            pizzaCount--;
        }
        else
        {
            dryFireSignal(this);
        }
        input.shootPizza = false;
    }

    if (input.jump && (!isInAir || spaceMode))
    {
        PxRigidBody* rigid = (PxRigidBody*)actor;
        rigid->addForce(PxVec3(0, 375, 0), PxForceMode::eACCELERATION);
        input.jump = false;
    }
}