Просмотр исходного кода

Rigidbody interface and PhysX implementation

BearishSun 10 лет назад
Родитель
Сommit
e13e228290

+ 71 - 1
BansheeCore/Include/BsRigidbody.h

@@ -7,16 +7,86 @@
 
 namespace BansheeEngine
 {
+	enum class ForceMode
+	{
+		Force, 
+		Impulse,
+		Velocity,
+		Acceleration
+	};
+
+	enum class PointForceMode
+	{
+		Force,
+		Impulse,
+	};
+
 	class BS_CORE_EXPORT Rigidbody
 	{
 	public:
 		virtual ~Rigidbody();
 
-		// TODO
+		virtual void move(const Vector3& position) = 0;
+		virtual void rotate(const Quaternion& rotation) = 0;
+
+		virtual Vector3 getPosition() const = 0;
+		virtual Quaternion getRotation() const = 0;
+		virtual void setTransform(const Vector3& pos, const Quaternion& rot) = 0;
+
+		virtual void setMass(float mass) = 0;
+		virtual float getMass() const = 0;
+
+		virtual void setIsKinematic(bool kinematic) = 0;
+		virtual bool getIsKinematic() const = 0;
+
+		virtual bool isSleeping() const = 0;
+		virtual void sleep() = 0;
+		virtual void wakeUp() = 0;
+
+		virtual void setSleepThreshold(float threshold) = 0;
+		virtual float getSleepThreshold() const = 0;
+
+		virtual void setUseGravity(bool gravity) = 0;
+		virtual bool getUseGravity() const = 0;
+
+		virtual void setVelocity(const Vector3& velocity) = 0;
+		virtual Vector3 getVelocity() const = 0;
+
+		virtual void setAngularVelocity(const Vector3& velocity) = 0;
+		virtual Vector3 getAngularVelocity() const = 0;
+
+		virtual void setDrag(float drag) = 0;
+		virtual float getDrag() const = 0;
+
+		virtual void setAngularDrag(float drag) = 0;
+		virtual float getAngularDrag() const = 0;
+
+		virtual void setInertiaTensor(const Vector3& tensor) = 0;
+		virtual Vector3 getInertiaTensor() const = 0;
+
+		virtual void setMaxAngularVelocity(float maxVelocity) = 0;
+		virtual float getMaxAngularVelocity() const = 0;
+
+		virtual void setCenterOfMass(const Vector3& position, const Quaternion& rotation) = 0;
+		virtual Vector3 getCenterOfMassPosition() const = 0;
+		virtual Quaternion getCenterOfMassRotatation() const = 0;
+
+		virtual void setPositionSolverCount(UINT32 count) = 0;
+		virtual UINT32 getPositionSolverCount() const = 0;
+
+		virtual void setVelocitySolverCount(UINT32 count) = 0;
+		virtual UINT32 getVelocitySolverCount() const = 0;
 
 		virtual void setIsActive(bool value);
 		virtual bool getIsActive() const { return mIsActive; }
 
+		virtual void addForce(const Vector3& force, ForceMode mode = ForceMode::Force) = 0;
+		virtual void addTorque(const Vector3& torque, ForceMode mode = ForceMode::Force) = 0;
+		virtual void addForceAtPoint(const Vector3& force, const Vector3& position, 
+			PointForceMode mode = PointForceMode::Force) = 0;
+
+		virtual Vector3 getVelocityAtPoint(const Vector3& point) const = 0;
+
 		static SPtr<Rigidbody> create(const Vector3& position, const Quaternion& rotation);
 
 		Event<void(const CollisionData&)> onCollisionBegin;

+ 61 - 1
BansheePhysX/Include/BsPhysXRigidbody.h

@@ -4,6 +4,8 @@
 
 #include "BsPhysXPrerequisites.h"
 #include "BsRigidbody.h"
+#include "BsVector3.h"
+#include "BsQuaternion.h"
 #include "PxPhysics.h"
 
 namespace BansheeEngine
@@ -14,7 +16,65 @@ namespace BansheeEngine
 		PhysXRigidbody(physx::PxPhysics* physx, physx::PxScene* scene, const Vector3& position, const Quaternion& rotation);
 		~PhysXRigidbody();
 
-		// TODO
+		void move(const Vector3& position) override;
+		void rotate(const Quaternion& rotation) override;
+
+		Vector3 getPosition() const override;
+		Quaternion getRotation() const override;
+		void setTransform(const Vector3& pos, const Quaternion& rot) override;
+
+		void setMass(float mass) override;
+		float getMass() const override;
+
+		void setIsKinematic(bool kinematic) override;
+		bool getIsKinematic() const override;
+
+		bool isSleeping() const override;
+		void sleep() override;
+		void wakeUp() override;
+
+		void setSleepThreshold(float threshold) override;
+		float getSleepThreshold() const override;
+
+		void setUseGravity(bool gravity) override;
+		bool getUseGravity() const override;
+
+		void setVelocity(const Vector3& velocity) override;
+		Vector3 getVelocity() const override;
+
+		void setAngularVelocity(const Vector3& velocity) override;
+		Vector3 getAngularVelocity() const override;
+
+		void setDrag(float drag) override;
+		float getDrag() const override;
+
+		void setAngularDrag(float drag) override;
+		float getAngularDrag() const override;
+
+		void setInertiaTensor(const Vector3& tensor) override;
+		Vector3 getInertiaTensor() const override;
+
+		void setMaxAngularVelocity(float maxVelocity) override;
+		float getMaxAngularVelocity() const override;
+
+		void setCenterOfMass(const Vector3& position, const Quaternion& rotation) override;
+		Vector3 getCenterOfMassPosition() const override;
+		Quaternion getCenterOfMassRotatation() const override;
+
+		void setPositionSolverCount(UINT32 count) override;
+		UINT32 getPositionSolverCount() const override;
+
+		void setVelocitySolverCount(UINT32 count) override;
+		UINT32 getVelocitySolverCount() const override;
+
+		void setIsActive(bool value) override;
+
+		void addForce(const Vector3& force, ForceMode mode = ForceMode::Force) override;
+		void addTorque(const Vector3& torque, ForceMode mode = ForceMode::Force) override;
+		void addForceAtPoint(const Vector3& force, const Vector3& position,
+			PointForceMode mode = PointForceMode::Force) override;
+
+		Vector3 getVelocityAtPoint(const Vector3& point) const override;
 
 	private:
 		physx::PxRigidDynamic* mInternal;

+ 269 - 0
BansheePhysX/Source/BsPhysXRigidbody.cpp

@@ -6,6 +6,36 @@ using namespace physx;
 
 namespace BansheeEngine
 {
+	PxForceMode::Enum toPxForceMode(ForceMode mode)
+	{
+		switch(mode)
+		{
+		case ForceMode::Force:
+			return PxForceMode::eFORCE;
+		case ForceMode::Impulse:
+			return PxForceMode::eIMPULSE;
+		case ForceMode::Velocity:
+			return PxForceMode::eVELOCITY_CHANGE;
+		case ForceMode::Acceleration:
+			return PxForceMode::eACCELERATION;
+		}
+
+		return PxForceMode::eFORCE;
+	}
+
+	PxForceMode::Enum toPxForceMode(PointForceMode mode)
+	{
+		switch (mode)
+		{
+		case PointForceMode::Force:
+			return PxForceMode::eFORCE;
+		case PointForceMode::Impulse:
+			return PxForceMode::eIMPULSE;
+		}
+
+		return PxForceMode::eFORCE;
+	}
+
 	PhysXRigidbody::PhysXRigidbody(PxPhysics* physx, PxScene* scene, const Vector3& position, const Quaternion& rotation)
 	{
 		PxTransform tfrm = toPxTransform(position, rotation);
@@ -19,4 +49,243 @@ namespace BansheeEngine
 		// TODO - Remove from scene? Or is that part of release()?
 		mInternal->release();
 	}
+
+	void PhysXRigidbody::move(const Vector3& position)
+	{
+		PxTransform target;
+		mInternal->getKinematicTarget(target);
+
+		target.p = toPxVector(position);
+
+		mInternal->setKinematicTarget(target);
+	}
+
+	void PhysXRigidbody::rotate(const Quaternion& rotation)
+	{
+		PxTransform target;
+		mInternal->getKinematicTarget(target);
+
+		target.q = toPxQuaternion(rotation);
+
+		mInternal->setKinematicTarget(target);
+	}
+
+	Vector3 PhysXRigidbody::getPosition() const
+	{
+		return fromPxVector(mInternal->getGlobalPose().p);
+	}
+
+	Quaternion PhysXRigidbody::getRotation() const
+	{
+		return fromPxQuaternion(mInternal->getGlobalPose().q);
+	}
+
+	void PhysXRigidbody::setTransform(const Vector3& pos, const Quaternion& rot)
+	{
+		mInternal->setGlobalPose(toPxTransform(pos, rot));
+	}
+
+	void PhysXRigidbody::setMass(float mass)
+	{
+		mInternal->setMass(mass);
+	}
+
+	float PhysXRigidbody::getMass() const
+	{
+		return mInternal->getMass();
+	}
+
+	void PhysXRigidbody::setIsKinematic(bool kinematic)
+	{
+		mInternal->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, kinematic);
+	}
+
+	bool PhysXRigidbody::getIsKinematic() const
+	{
+		return ((UINT32)mInternal->getRigidBodyFlags() & PxRigidBodyFlag::eKINEMATIC) != 0;
+	}
+
+	bool PhysXRigidbody::isSleeping() const
+	{
+		return mInternal->isSleeping();
+	}
+
+	void PhysXRigidbody::sleep()
+	{
+		mInternal->putToSleep();
+	}
+
+	void PhysXRigidbody::wakeUp()
+	{
+		mInternal->wakeUp();
+	}
+
+	void PhysXRigidbody::setSleepThreshold(float threshold)
+	{
+		mInternal->setSleepThreshold(threshold);
+	}
+
+	float PhysXRigidbody::getSleepThreshold() const
+	{
+		return mInternal->getSleepThreshold();
+	}
+
+	void PhysXRigidbody::setUseGravity(bool gravity)
+	{
+		mInternal->setActorFlag(PxActorFlag::eDISABLE_GRAVITY, !gravity);
+	}
+
+	bool PhysXRigidbody::getUseGravity() const
+	{
+		return ((UINT32)mInternal->getActorFlags() & PxActorFlag::eDISABLE_GRAVITY) == 0;
+	}
+
+	void PhysXRigidbody::setVelocity(const Vector3& velocity)
+	{
+		mInternal->setLinearVelocity(toPxVector(velocity));
+	}
+
+	Vector3 PhysXRigidbody::getVelocity() const
+	{
+		return fromPxVector(mInternal->getLinearVelocity());
+	}
+
+	void PhysXRigidbody::setAngularVelocity(const Vector3& velocity)
+	{
+		mInternal->setAngularVelocity(toPxVector(velocity));
+	}
+
+	Vector3 PhysXRigidbody::getAngularVelocity() const
+	{
+		return fromPxVector(mInternal->getAngularVelocity());
+	}
+
+	void PhysXRigidbody::setDrag(float drag)
+	{
+		mInternal->setLinearDamping(drag);
+	}
+
+	float PhysXRigidbody::getDrag() const
+	{
+		return mInternal->getLinearDamping();
+	}
+
+	void PhysXRigidbody::setAngularDrag(float drag)
+	{
+		mInternal->setAngularDamping(drag);
+	}
+
+	float PhysXRigidbody::getAngularDrag() const
+	{
+		return mInternal->getAngularDamping();
+	}
+
+	void PhysXRigidbody::setInertiaTensor(const Vector3& tensor)
+	{
+		mInternal->setMassSpaceInertiaTensor(toPxVector(tensor));
+	}
+
+	Vector3 PhysXRigidbody::getInertiaTensor() const
+	{
+		return fromPxVector(mInternal->getMassSpaceInertiaTensor());
+	}
+
+	void PhysXRigidbody::setMaxAngularVelocity(float maxVelocity)
+	{
+		mInternal->setMaxAngularVelocity(maxVelocity);
+	}
+
+	float PhysXRigidbody::getMaxAngularVelocity() const
+	{
+		return mInternal->getMaxAngularVelocity();
+	}
+
+	void PhysXRigidbody::setCenterOfMass(const Vector3& position, const Quaternion& rotation)
+	{
+		mInternal->setCMassLocalPose(toPxTransform(position, rotation));
+	}
+
+	Vector3 PhysXRigidbody::getCenterOfMassPosition() const
+	{
+		PxTransform cMassTfrm = mInternal->getCMassLocalPose();
+		return fromPxVector(cMassTfrm.p);
+	}
+
+	Quaternion PhysXRigidbody::getCenterOfMassRotatation() const
+	{
+		PxTransform cMassTfrm = mInternal->getCMassLocalPose();
+		return fromPxQuaternion(cMassTfrm.q);
+	}
+
+	void PhysXRigidbody::setPositionSolverCount(UINT32 count)
+	{
+		mInternal->setSolverIterationCounts(std::max(1U, count), getVelocitySolverCount());
+	}
+
+	UINT32 PhysXRigidbody::getPositionSolverCount() const
+	{
+		UINT32 posCount = 1;
+		UINT32 velCount = 1;
+
+		mInternal->getSolverIterationCounts(posCount, velCount);
+		return posCount;
+	}
+
+	void PhysXRigidbody::setVelocitySolverCount(UINT32 count)
+	{
+		mInternal->setSolverIterationCounts(getPositionSolverCount(), std::max(1U, count));
+	}
+
+	UINT32 PhysXRigidbody::getVelocitySolverCount() const
+	{
+		UINT32 posCount = 1;
+		UINT32 velCount = 1;
+
+		mInternal->getSolverIterationCounts(posCount, velCount);
+		return velCount;
+	}
+
+	void PhysXRigidbody::setIsActive(bool value)
+	{
+		// TODO
+	}
+
+	void PhysXRigidbody::addForce(const Vector3& force, ForceMode mode)
+	{
+		mInternal->addForce(toPxVector(force), toPxForceMode(mode));
+	}
+
+	void PhysXRigidbody::addTorque(const Vector3& force, ForceMode mode)
+	{
+		mInternal->addTorque(toPxVector(force), toPxForceMode(mode));
+	}
+
+	void PhysXRigidbody::addForceAtPoint(const Vector3& force, const Vector3& position, PointForceMode mode)
+	{
+		const PxVec3& pxForce = toPxVector(force);
+		const PxVec3& pxPos = toPxVector(position);
+
+		const PxTransform globalPose = mInternal->getGlobalPose();
+		PxVec3 centerOfMass = globalPose.transform(mInternal->getCMassLocalPose().p);
+
+		PxForceMode::Enum pxMode = toPxForceMode(mode);
+
+		PxVec3 torque = (pxPos - centerOfMass).cross(pxForce);
+		mInternal->addForce(pxForce, pxMode);
+		mInternal->addTorque(torque, pxMode);
+	}
+
+	Vector3 PhysXRigidbody::getVelocityAtPoint(const Vector3& point) const
+	{
+		const PxVec3& pxPoint = toPxVector(point);
+
+		const PxTransform globalPose = mInternal->getGlobalPose();
+		const PxVec3 centerOfMass = globalPose.transform(mInternal->getCMassLocalPose().p);
+		const PxVec3 rpoint = pxPoint - centerOfMass;
+
+		PxVec3 velocity = mInternal->getLinearVelocity();
+		velocity += mInternal->getAngularVelocity().cross(rpoint);
+
+		return fromPxVector(velocity);
+	}
 }