diff --git a/Engine/source/T3D/physics/bullet/btBody.cpp b/Engine/source/T3D/physics/bullet/btBody.cpp index e1a84cf9f..33d0240a4 100644 --- a/Engine/source/T3D/physics/bullet/btBody.cpp +++ b/Engine/source/T3D/physics/bullet/btBody.cpp @@ -356,7 +356,7 @@ void BtBody::applyImpulse( const Point3F &origin, const Point3F &force ) mActor->activate(); } -void BtBody::applyTorque(const Point3F &torque) +void BtBody::applyTorque( const Point3F &torque ) { AssertFatal(mActor, "BtBody::applyTorque - The actor is null!"); AssertFatal(isDynamic(), "BtBody::applyTorque - This call is only for dynamics!"); @@ -367,6 +367,24 @@ void BtBody::applyTorque(const Point3F &torque) mActor->activate(); } +void BtBody::applyForce( const Point3F &force ) +{ + AssertFatal(mActor, "BtBody::applyForce - The actor is null!"); + AssertFatal(isDynamic(), "BtBody::applyForce - This call is only for dynamics!"); + + if (mCenterOfMass) + { + Point3F relForce(force); + mCenterOfMass->mulV(relForce); + mActor->applyCentralForce(btCast(relForce)); + } + else + mActor->applyCentralForce(btCast(force)); + + if (!mActor->isActive()) + mActor->activate(); +} + Box3F BtBody::getWorldBounds() { btVector3 min, max; diff --git a/Engine/source/T3D/physics/bullet/btBody.h b/Engine/source/T3D/physics/bullet/btBody.h index c93ac5393..84b7dddc0 100644 --- a/Engine/source/T3D/physics/bullet/btBody.h +++ b/Engine/source/T3D/physics/bullet/btBody.h @@ -111,7 +111,8 @@ public: F32 staticFriction ); virtual void applyCorrection( const MatrixF &xfm ); virtual void applyImpulse( const Point3F &origin, const Point3F &force ); - virtual void applyTorque(const Point3F &torque); + virtual void applyTorque( const Point3F &torque ); + virtual void applyForce( const Point3F &force ); virtual void findContact(SceneObject **contactObject, VectorF *contactNormal, Vector *outOverlapObjects) const; virtual void moveKinematicTo(const MatrixF &xfm); diff --git a/Engine/source/T3D/physics/physicsBody.h b/Engine/source/T3D/physics/physicsBody.h index dd609cee7..28cf95d45 100644 --- a/Engine/source/T3D/physics/physicsBody.h +++ b/Engine/source/T3D/physics/physicsBody.h @@ -115,7 +115,10 @@ public: virtual void applyImpulse( const Point3F &origin, const Point3F &force ) = 0; /// - virtual void applyTorque(const Point3F &torque) = 0; + virtual void applyTorque( const Point3F &torque ) = 0; + + /// + virtual void applyForce( const Point3F &force ) = 0; virtual void findContact(SceneObject **contactObject, diff --git a/Engine/source/T3D/physics/physicsShape.cpp b/Engine/source/T3D/physics/physicsShape.cpp index c69d9458e..627b38a35 100644 --- a/Engine/source/T3D/physics/physicsShape.cpp +++ b/Engine/source/T3D/physics/physicsShape.cpp @@ -863,6 +863,12 @@ void PhysicsShape::applyTorque( const Point3F &torque ) mPhysicsRep->applyTorque( torque ); } +void PhysicsShape::applyForce( const Point3F &force ) +{ + if (mPhysicsRep && mPhysicsRep->isDynamic()) + mPhysicsRep->applyForce( force ); +} + void PhysicsShape::applyRadialImpulse( const Point3F &origin, F32 radius, F32 magnitude ) { if ( !mPhysicsRep || !mPhysicsRep->isDynamic() ) @@ -1193,4 +1199,12 @@ DefineEngineMethod( PhysicsShape, applyTorque, void, (Point3F torque), , "@note This value is ignored on physics shapes that are not dynamic. Wakes up the dynamic physics shape if it is sleeping.\n") { object->applyTorque( torque ); +} + +DefineEngineMethod(PhysicsShape, applyForce, void, (Point3F force), , + "@brief Add a force to a dynamic physics shape.\n\n" + "@param force to apply to the dynamic physics shape\n" + "@note This value is ignored on physics shapes that are not dynamic. Wakes up the dynamic physics shape if it is sleeping.\n") +{ + object->applyForce( force ); } \ No newline at end of file diff --git a/Engine/source/T3D/physics/physicsShape.h b/Engine/source/T3D/physics/physicsShape.h index 162a0368d..92092df64 100644 --- a/Engine/source/T3D/physics/physicsShape.h +++ b/Engine/source/T3D/physics/physicsShape.h @@ -247,6 +247,7 @@ public: void applyImpulse( const Point3F &pos, const VectorF &vec ); void applyRadialImpulse( const Point3F &origin, F32 radius, F32 magnitude ); void applyTorque( const Point3F &torque ); + void applyForce( const Point3F &force ); void setScale(const VectorF & scale); // GameBase diff --git a/Engine/source/T3D/physics/physx3/px3Body.cpp b/Engine/source/T3D/physics/physx3/px3Body.cpp index 708a01d0a..2d5fb46f7 100644 --- a/Engine/source/T3D/physics/physx3/px3Body.cpp +++ b/Engine/source/T3D/physics/physx3/px3Body.cpp @@ -427,6 +427,16 @@ void Px3Body::applyTorque( const Point3F &torque ) actor->addTorque( px3Cast(torque), physx::PxForceMode::eFORCE, true); } +void Px3Body::applyForce( const Point3F &force ) +{ + AssertFatal(mActor, "Px3Body::applyTorque - The actor is null!"); + + mWorld->releaseWriteLock(); + physx::PxRigidDynamic *actor = mActor->is(); + if (mIsEnabled && isDynamic()) + actor->addForce( px3Cast(force), physx::PxForceMode::eFORCE, true); +} + void Px3Body::findContact(SceneObject **contactObject, VectorF *contactNormal, Vector *outOverlapObjects) const diff --git a/Engine/source/T3D/physics/physx3/px3Body.h b/Engine/source/T3D/physics/physx3/px3Body.h index 56713e3fb..7873293bc 100644 --- a/Engine/source/T3D/physics/physx3/px3Body.h +++ b/Engine/source/T3D/physics/physx3/px3Body.h @@ -118,6 +118,7 @@ public: virtual void applyCorrection( const MatrixF &xfm ); virtual void applyImpulse( const Point3F &origin, const Point3F &force ); virtual void applyTorque( const Point3F &torque ); + virtual void applyForce( const Point3F &force ); virtual void findContact(SceneObject **contactObject, VectorF *contactNormal, Vector *outOverlapObjects) const; virtual void moveKinematicTo(const MatrixF &xfm);