Physics Body
// Physics body.
class RVAPI Body
{
public:
// Body type.
enum class Type
{
// Fixed object. Does not react to collisions.
STATIC,
// Movable object. Does not react to collisions.
KINEMATIC,
// Movable object. Reacts to collisions.
DYNAMIC,
// Does not participate in the physics simulation.
NONE
};
struct Contact
{
// Contact state of intersected objects.
enum class State
{
// Contact is new.
NEW,
// Contact is acitve.
ACTIVE,
// Contact is ending.
ENDING
};
// Contact state.
State state;
// Normal of contact on other body.
S3f norm;
// Point of contact on this body.
S3f selfPt;
// Point of contact on other body.
S3f otherPt;
// Other reference.
void *ref;
// Contact ID.
uint id;
};
// Get world space position.
M4f GetPos() const;
// Get angular velocity.
S3f GetAngVel() const;
// Get linear velocity.
S3f GetLinVel() const;
// Get host entity from contact.
EntKey GetHost(const Contact &contact) const;
// Get first contact. Initializes [index] iterator. Returns 0 if no contact.
const Contact *GetFirstContact(int &index) const;
// Get next contact. Updates [index] iterator. Returns 0 if no contact.
const Contact *GetNextContact(int &index) const;
// Add cone joint between bodies. [angle] is maximum movement angle.
uint AddConeJoint(Body &other, float angle);
// Add revolute (hinge) joint between this body and [other] body. [posA] is world space joint position on this body.
// [posB] is world space joint position on other body. [lowerAngle] is low angle limit, or zero for no limit.
// [upperAngle] is high angle limit, or zero for no limit. [speed] is motor speed, or zero for no motor. [maxTorque]
// is maximum motor torque, or zero if no motor. Returns joint ID
uint AddRevoluteJoint(Body &other, const M4f &posA, const M4f &posB, float lowerAngle, float upperAngle, float speed, float maxTorque);
// Add sphere joint between this body and other body. [posA] is world space joint position on this body.
// [posB] is world space joint position on other body. Returns joint ID.
uint AddSphereJoint(Body &other, const S3f &posA, const S3f &posB);
// Add weld (fixed) joint between this body and [other] body. Returns joint ID.
uint AddWeldJoint(Body &other);
// Add spring joint between this body and [other] body. [posA] is world space joint position on this body.
// [posB] is world space joint position on other body. [length] is pring length. [freq] is spring frequency.
// [damp] is spring damping. Set [collideConnected] to true if connected body should collide with self.
// Returns joint ID.
uint AddSpringJoint(Body &other, const S3f &posA, const S3f &posB, float length, float freq, float damp, bool collideConnected = true);
// Remove joint with [id].
void RemoveJoint(uint id);
// Apply force. [force] is force vector in world space. Set [wake] true if force should wake body.
void ApplyForce(const S3f &force, bool wake = true);
// Apply force at body point. [force] is orce vector in world space.
// [pos] is force position in world space. Set [wake] true if force should wake body.
void ApplyForce(const S3f &force, const S3f &pos, bool wake = true);
// Apply torque. [torque] is torque vector in world space. Set [wake] true if force should wake body.
void ApplyTorque(const S3f &torque, bool wake = true);
// Apply angular impulse. [imp] is impulse vector in world space. Set [wake] true if force should wake body.
void ApplyAngImp(const S3f &imp, bool wake = true);
// Apply linear impulse. [imp] is impulse vector in world space. Set [wake] true if force should wake body.
void ApplyLinImp(const S3f &imp, bool wake = true);
// Apply linear impulse at point. [imp] is mpulse vector in world space. [pos] is impulse position in world space.
// Set [wake] true if force should wake body.
void ApplyLinImp(const S3f &imp, const S3f &pos, bool wake = true);
// Set angular damping. [damp] is damping vector.
void SetAngDamp(const S3f &damp);
// Set linear damping. [damp] is damping vector.
void SetLinDamp(const S3f &damp);
// Set angular velocity. [vel] is velocity vector.
void SetAngVel(const S3f &vel);
// Set linear velocity. [vel] is velocity vector.
void SetLinVel(const S3f &vel);
// Wake/Sleep body. Set [awake] to true to wake body, false to sleep body.
void SetAwake(bool awake);
// Set gravity effect. [scale] is gravity scale. Default is 1.
void SetGravityScale(const S3f &scale);
// Set world space position. [pos] is position matrix.
void SetPos(const M4f &pos);
// Add collision shape. [shape] is collision shape.
void AddCollShape(const CollShape &shape);
// Set physics properties. [mass] is mass value. Default is 1. [center] is center of mass. Default is (0, 0, 0).
// [inertiaX] is x inertia tensor. Normally use (1, 0, 0). [inertiaY] is y inertia tensor. Normally use (0, 1, 0).
// [inertiaZ] is z inertia tensor. Normally use (0, 0, 1).
void SetProps(float mass, const S3f ¢er = S3f(0, 0, 0), const S3f &inertiaX = S3f(1, 0, 0),
const S3f &inertiaY = S3f(0, 1, 0), const S3f &inertiaZ = S3f(0, 0, 1));
// Internal.
void *operator () () const { return (void *)wobj; }
// Initialize physics body. [host] is host entity. [type] is body type. [pos] is initial body position. [collMask]
// is collision bit mask. Only bodies with same bits collide. 0=collide all. [rotMask] flags restrict rotation.
// 1=X 2=Y 4=Z. Set [wantContacts] to true if collision contacts are wanted.
Body(EntKey host, Type type, const M4f &pos, uint collMask = 0, uint rotMask = 0, bool wantContacts = false);
// Destructor.
~Body();
private:
byte wobj[320];
};