|
|
@@ -7,25 +7,41 @@
|
|
|
|
|
|
namespace BansheeEngine
|
|
|
{
|
|
|
+ /** Type of force or torque that can be applied to a rigidbody. */
|
|
|
enum class ForceMode
|
|
|
{
|
|
|
- Force,
|
|
|
- Impulse,
|
|
|
- Velocity,
|
|
|
- Acceleration
|
|
|
+ Force, /**< Value applied is a force. */
|
|
|
+ Impulse, /**< Value applied is an impulse (i.e. a direct change in its linear or angular momentum). */
|
|
|
+ Velocity, /**< Value applied is velocity. */
|
|
|
+ Acceleration /**< Value applied is accelearation. */
|
|
|
};
|
|
|
|
|
|
+ /** Type of force that can be applied to a rigidbody at an arbitrary point. */
|
|
|
enum class PointForceMode
|
|
|
{
|
|
|
- Force,
|
|
|
- Impulse,
|
|
|
+ Force, /**< Value applied is a force. */
|
|
|
+ Impulse, /**< Value applied is an impulse (i.e. a direct change in its linear or angular momentum). */
|
|
|
};
|
|
|
|
|
|
+ /** @addtogroup Physics
|
|
|
+ * @{
|
|
|
+ */
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Rigidbody is a dynamic physics object that can be moved using forces (or directly). It will interact with other
|
|
|
+ * static and dynamic physics objects in the scene accordingly (i.e. it will push other non-kinematic rigidbodies,
|
|
|
+ * and collide with static objects).
|
|
|
+ *
|
|
|
+ * The shape and mass of a rigidbody is governed by its colliders. You must attach at least one collider for the
|
|
|
+ * rigidbody to be valid.
|
|
|
+ */
|
|
|
class BS_CORE_EXPORT Rigidbody
|
|
|
{
|
|
|
public:
|
|
|
+ /** Flags that control options of a Rigidbody object. */
|
|
|
enum class Flag
|
|
|
{
|
|
|
+ /** No options. */
|
|
|
None = 0x00,
|
|
|
/** Automatically calculate center of mass transform and inertia tensors from child shapes (colliders) */
|
|
|
AutoTensors = 0x01,
|
|
|
@@ -33,85 +49,255 @@ namespace BansheeEngine
|
|
|
AutoMass = 0x02,
|
|
|
};
|
|
|
|
|
|
+ /**
|
|
|
+ * Constructs a new rigidbody.
|
|
|
+ *
|
|
|
+ * @param[in] linkedSO Scene object that owns this rigidbody. All physics updates applied to this object
|
|
|
+ * will be transfered to this scene object (i.e. the movement/rotation resulting from
|
|
|
+ * those updates).
|
|
|
+ */
|
|
|
Rigidbody(const HSceneObject& linkedSO);
|
|
|
virtual ~Rigidbody();
|
|
|
|
|
|
+ /**
|
|
|
+ * Moves the rigidbody to a specific position. This method will ensure physically correct movement, i.e. the body
|
|
|
+ * will collide with other objects along the way.
|
|
|
+ */
|
|
|
virtual void move(const Vector3& position) = 0;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Rotates the rigidbody. This method will ensure physically correct rotation, i.e. the body will collide with other
|
|
|
+ * objects along the way.
|
|
|
+ */
|
|
|
virtual void rotate(const Quaternion& rotation) = 0;
|
|
|
|
|
|
+ /** Returns the current position of the rigidbody. */
|
|
|
virtual Vector3 getPosition() const = 0;
|
|
|
+
|
|
|
+ /** Returns the current rotation of the rigidbody. */
|
|
|
virtual Quaternion getRotation() const = 0;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Moves and rotates the rigidbody to a specific position. Unlike move() and rotate() this will not transform the
|
|
|
+ * body in a physically correct manner, but will instead "teleport" it immediately to the specified position and
|
|
|
+ * rotation.
|
|
|
+ */
|
|
|
virtual void setTransform(const Vector3& pos, const Quaternion& rot) = 0;
|
|
|
|
|
|
+ /**
|
|
|
+ * Sets the mass of the object and all of its collider shapes. Only relevant if Flag::AutoMass or Flag::AutoTensors
|
|
|
+ * is turned off. Value of zero means the object is immovable (but can be rotated).
|
|
|
+ */
|
|
|
virtual void setMass(float mass) = 0;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Returns the mass of the object. This may be mass manually set by setMass(), or the mass of all child colliders,
|
|
|
+ * depending if the mass is calculated automatically or not.
|
|
|
+ */
|
|
|
virtual float getMass() const = 0;
|
|
|
|
|
|
+ /**
|
|
|
+ * Sets if the body is kinematic. Kinematic body will not move in response to external forces (e.g. gravity, or
|
|
|
+ * another object pushing it), essentially behaving like collider. Unlike a collider though, you can still move
|
|
|
+ * the object and have other dynamic objects respond correctly (i.e. it will push other objects).
|
|
|
+ */
|
|
|
virtual void setIsKinematic(bool kinematic) = 0;
|
|
|
+
|
|
|
+ /** Checks if the body is kinematic. */
|
|
|
virtual bool getIsKinematic() const = 0;
|
|
|
|
|
|
+ /**
|
|
|
+ * Checks if the body is sleeping. Objects that aren't moved/rotated for a while are put to sleep to reduce load
|
|
|
+ * on the physics system.
|
|
|
+ */
|
|
|
virtual bool isSleeping() const = 0;
|
|
|
+
|
|
|
+ /** Forces the object to sleep. Useful if you know the object will not move in any significant way for a while. */
|
|
|
virtual void sleep() = 0;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Wakes an object up. Useful if you modified properties of this object, and potentially surrounding objects which
|
|
|
+ * might result in the object being moved by physics (although the physics system will automatically wake the
|
|
|
+ * object up for majority of such cases).
|
|
|
+ */
|
|
|
virtual void wakeUp() = 0;
|
|
|
|
|
|
+ /** Sets a treshold of force and torque under which the object will be considered to be put to sleep. */
|
|
|
virtual void setSleepThreshold(float threshold) = 0;
|
|
|
+
|
|
|
+ /** Gets a treshold of force and torque under which the object will be considered to be put to sleep. */
|
|
|
virtual float getSleepThreshold() const = 0;
|
|
|
|
|
|
+ /** Sets whether or not the rigidbody will have the global gravity force applied to it. */
|
|
|
virtual void setUseGravity(bool gravity) = 0;
|
|
|
+
|
|
|
+ /** Gets whether or not the rigidbody will have the global gravity force applied to it. */
|
|
|
virtual bool getUseGravity() const = 0;
|
|
|
|
|
|
+ /** Sets the linear velocity of the body. */
|
|
|
virtual void setVelocity(const Vector3& velocity) = 0;
|
|
|
+
|
|
|
+ /** Returns the current linear velocity of the body. */
|
|
|
virtual Vector3 getVelocity() const = 0;
|
|
|
|
|
|
+ /** Sets the angular velocity of the body. */
|
|
|
virtual void setAngularVelocity(const Vector3& velocity) = 0;
|
|
|
+
|
|
|
+ /** Returns the current angular velocity of the body. */
|
|
|
virtual Vector3 getAngularVelocity() const = 0;
|
|
|
|
|
|
+ /** Sets the linear drag of the body. Higher drag values means the object resists linear movement more. */
|
|
|
virtual void setDrag(float drag) = 0;
|
|
|
+
|
|
|
+ /** Gets the linear drag of the body. Higher drag values means the object resists linear movement more. */
|
|
|
virtual float getDrag() const = 0;
|
|
|
|
|
|
+ /** Sets the angular drag of the body. Higher drag values means the object resists angular movement more. */
|
|
|
virtual void setAngularDrag(float drag) = 0;
|
|
|
+
|
|
|
+ /** Gets the angular drag of the body. Higher drag values means the object resists angular movement more. */
|
|
|
virtual float getAngularDrag() const = 0;
|
|
|
|
|
|
+ /**
|
|
|
+ * Sets the inertia tensor in local mass space. Inertia tensor determines how difficult is to rotate the object.
|
|
|
+ * Values of zero in the inertia tensor mean the object will be unable to rotate around a specific axis.
|
|
|
+ */
|
|
|
virtual void setInertiaTensor(const Vector3& tensor) = 0;
|
|
|
+
|
|
|
+ /** Gets the inertia tensor in local mass space. */
|
|
|
virtual Vector3 getInertiaTensor() const = 0;
|
|
|
|
|
|
+ /** Returns the maximum angular velocity of the rigidbody. Velocity will be clamped to this value. */
|
|
|
virtual void setMaxAngularVelocity(float maxVelocity) = 0;
|
|
|
+
|
|
|
+ /** Gets the maximum angular velocity of the rigidbody. */
|
|
|
virtual float getMaxAngularVelocity() const = 0;
|
|
|
|
|
|
+ /**
|
|
|
+ * Sets the rigidbody's center of mass transform.
|
|
|
+ *
|
|
|
+ * @param[in] position Position of the center of mass.
|
|
|
+ * @param[in] rotation Rotation that determines orientation of the inertia tensor.
|
|
|
+ */
|
|
|
virtual void setCenterOfMass(const Vector3& position, const Quaternion& rotation) = 0;
|
|
|
+
|
|
|
+ /** Returns the position of the center of mass. */
|
|
|
virtual Vector3 getCenterOfMassPosition() const = 0;
|
|
|
+
|
|
|
+ /** Returns the rotation of the inertia tensor. */
|
|
|
virtual Quaternion getCenterOfMassRotation() const = 0;
|
|
|
|
|
|
+ /**
|
|
|
+ * Sets the number of iterations to use when solving for position. Higher values can improve precision and
|
|
|
+ * numerical stability of the simulation.
|
|
|
+ */
|
|
|
virtual void setPositionSolverCount(UINT32 count) = 0;
|
|
|
+
|
|
|
+ /** Gets the number of iterations to use when solving for position. */
|
|
|
virtual UINT32 getPositionSolverCount() const = 0;
|
|
|
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Sets the number of iterations to use when solving for velocity. Higher values can improve precision and
|
|
|
+ * numerical stability of the simulation.
|
|
|
+ */
|
|
|
virtual void setVelocitySolverCount(UINT32 count) = 0;
|
|
|
+
|
|
|
+ /** Gets the number of iterations to use when solving for velocity. */
|
|
|
virtual UINT32 getVelocitySolverCount() const = 0;
|
|
|
|
|
|
+ /** Sets flags that control the behaviour of the rigidbody. */
|
|
|
virtual void setFlags(Flag flags) { mFlags = flags; }
|
|
|
+
|
|
|
+ /** Gets flags that control the behaviour of the rigidbody. */
|
|
|
virtual Flag getFlags() const { return mFlags; }
|
|
|
|
|
|
+ /**
|
|
|
+ * Applies a force to the center of the mass of the rigidbody. This will produce linear momentum.
|
|
|
+ *
|
|
|
+ * @param[in] force Force to apply.
|
|
|
+ * @param[in] mode Determines what is the type of @p force.
|
|
|
+ */
|
|
|
virtual void addForce(const Vector3& force, ForceMode mode = ForceMode::Force) = 0;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Applies a torque to the rigidbody. This will produce angular momentum.
|
|
|
+ *
|
|
|
+ * @param[in] torque Torque to apply.
|
|
|
+ * @param[in] mode Determines what is the type of @p torque.
|
|
|
+ */
|
|
|
virtual void addTorque(const Vector3& torque, ForceMode mode = ForceMode::Force) = 0;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Applies a force to a specific point on the rigidbody. This will in most cases produce both linear and angular
|
|
|
+ * momentum.
|
|
|
+ *
|
|
|
+ * @param[in] force Force to apply.
|
|
|
+ * @param[in] position World position to apply the force at.
|
|
|
+ * @param[in] mode Determines what is the type of @p force.
|
|
|
+ */
|
|
|
virtual void addForceAtPoint(const Vector3& force, const Vector3& position,
|
|
|
PointForceMode mode = PointForceMode::Force) = 0;
|
|
|
|
|
|
+ /**
|
|
|
+ * Returns the total (linear + angular) velocity at a specific point.
|
|
|
+ *
|
|
|
+ * @param[in] point Point in world space.
|
|
|
+ * @return Total velocity of the point.
|
|
|
+ */
|
|
|
virtual Vector3 getVelocityAtPoint(const Vector3& point) const = 0;
|
|
|
|
|
|
+ /** Registers a new collider as a child of this rigidbody. */
|
|
|
virtual void addCollider(FCollider* collider) = 0;
|
|
|
+
|
|
|
+ /** Removes a collider from the child list of this rigidbody. */
|
|
|
virtual void removeCollider(FCollider* collider) = 0;
|
|
|
+
|
|
|
+ /** Removes all colliders from the child list of this rigidbody. */
|
|
|
virtual void removeColliders() = 0;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Recalculates rigidbody's mass, inertia tensors and center of mass depending on the currently set child colliders.
|
|
|
+ * This should be called whenever relevant child collider properties change (like mass or shape).
|
|
|
+ *
|
|
|
+ * If automatic tensor calculation is turned off then this will do nothing. If automatic mass calculation is turned
|
|
|
+ * off then this will use the mass set directly on the body using setMass().
|
|
|
+ */
|
|
|
virtual void updateMassDistribution() { }
|
|
|
|
|
|
+ /**
|
|
|
+ * Creates a new rigidbody.
|
|
|
+ *
|
|
|
+ * @param[in] linkedSO Scene object that owns this rigidbody. All physics updates applied to this object
|
|
|
+ * will be transfered to this scene object (i.e. the movement/rotation resulting from
|
|
|
+ * those updates).
|
|
|
+ */
|
|
|
static SPtr<Rigidbody> create(const HSceneObject& linkedSO);
|
|
|
|
|
|
+ /** Triggered when one of the colliders owned by the rigidbody starts colliding with another object. */
|
|
|
Event<void(const CollisionData&)> onCollisionBegin;
|
|
|
+
|
|
|
+ /** Triggered when a previously colliding collider stays in collision. Triggered once per frame. */
|
|
|
Event<void(const CollisionData&)> onCollisionStay;
|
|
|
+
|
|
|
+ /** Triggered when one of the colliders owned by the rigidbody stops colliding with another object. */
|
|
|
Event<void(const CollisionData&)> onCollisionEnd;
|
|
|
|
|
|
/** @cond INTERNAL */
|
|
|
|
|
|
+ /**
|
|
|
+ * Sets the priority of the physics update. Bodies with a higher priority will be updated before the bodies with
|
|
|
+ * lower priority. This allows you to control the order of updated in case rigidbodies are in some way dependant.
|
|
|
+ */
|
|
|
void _setPriority(UINT32 priority);
|
|
|
+
|
|
|
+ /** Sets a unique ID of the rigidbody, so it can be recognized by the physics system. */
|
|
|
void _setPhysicsId(UINT32 id) { mPhysicsId = id; }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Applies new transform values retrieved from the most recent physics update (i.e. values resulting from physics
|
|
|
+ * simulation).
|
|
|
+ */
|
|
|
void _setTransform(const Vector3& position, const Quaternion& rotation);
|
|
|
|
|
|
/**
|
|
|
@@ -137,4 +323,6 @@ namespace BansheeEngine
|
|
|
UINT32 mPhysicsId = 0;
|
|
|
HSceneObject mLinkedSO;
|
|
|
};
|
|
|
+
|
|
|
+ /** @} */
|
|
|
}
|