423 lines
13 KiB
C++
423 lines
13 KiB
C++
#pragma once
|
|
|
|
#include "gamelib/physics/afbody.h"
|
|
#include "gamelib/physics/clip.h"
|
|
#include "idlib/text/atomicstring.h"
|
|
|
|
#include <cstdint>
|
|
#include <cstddef>
|
|
|
|
class idDeclTable;
|
|
class idPhysics_AF;
|
|
class idRotation;
|
|
class idSerializer;
|
|
|
|
enum constraintType_t : int {
|
|
CONSTRAINT_INVALID = 0,
|
|
CONSTRAINT_FIXED = 1,
|
|
CONSTRAINT_BALLANDSOCKETJOINT = 2,
|
|
CONSTRAINT_UNIVERSALJOINT = 3,
|
|
CONSTRAINT_HINGE = 4,
|
|
CONSTRAINT_HINGESTEERING = 5,
|
|
CONSTRAINT_SLIDER = 6,
|
|
CONSTRAINT_CYLINDRICALJOINT = 7,
|
|
CONSTRAINT_PLANE = 9,
|
|
CONSTRAINT_SPRING = 10,
|
|
CONSTRAINT_CONTACT = 11,
|
|
CONSTRAINT_FRICTION = 12,
|
|
CONSTRAINT_CONELIMIT = 13,
|
|
CONSTRAINT_PYRAMIDLIMIT = 14,
|
|
CONSTRAINT_SUSPENSION = 15,
|
|
CONSTRAINT_WEEBLE = 16
|
|
};
|
|
|
|
class alignas(16) idAFConstraint {
|
|
public:
|
|
struct constraintFlags_s {
|
|
std::uint8_t reserved : 3;
|
|
std::uint8_t isZero : 1;
|
|
std::uint8_t isPrimary : 1;
|
|
std::uint8_t noCollision : 1;
|
|
std::uint8_t frameConstraint : 1;
|
|
std::uint8_t allowPrimary : 1;
|
|
};
|
|
|
|
idAFConstraint(const char* name = nullptr,
|
|
constraintType_t type = CONSTRAINT_INVALID,
|
|
idAFBody* body1 = nullptr, idAFBody* body2 = nullptr);
|
|
virtual ~idAFConstraint();
|
|
|
|
static void* operator new(std::size_t size);
|
|
static void operator delete(void* pointer) noexcept;
|
|
|
|
virtual void SetBody1(idAFBody*);
|
|
virtual void SetBody2(idAFBody*);
|
|
virtual void DebugDraw();
|
|
virtual void Translate(const idVec3&);
|
|
virtual void Rotate(const idRotation&);
|
|
virtual void GetCenter(idVec3&) const;
|
|
virtual void IssueCollisionQueries();
|
|
virtual void CancelCollisionQueries();
|
|
virtual void Serialize(idSerializer*);
|
|
virtual void Evaluate(const idPhysics_AF*, float);
|
|
virtual void ApplyFriction(float);
|
|
|
|
void InitSize(int size);
|
|
|
|
alignas(16) constraintType_t type;
|
|
idAtomicString name;
|
|
idAFBody* body1;
|
|
idAFBody* body2;
|
|
idPhysics_AF* physics;
|
|
idStaticSpatialVec lm;
|
|
idSpatialMat J1;
|
|
idSpatialMat J2;
|
|
idStaticSpatialVec c1;
|
|
idStaticSpatialVec c2;
|
|
idStaticSpatialVec lo;
|
|
idStaticSpatialVec hi;
|
|
idStaticSpatialVec e;
|
|
idAFConstraint* boxConstraint;
|
|
int boxIndex[6];
|
|
float boxScale[6];
|
|
idSpatialMat invI;
|
|
idSpatialMat J;
|
|
int firstIndex;
|
|
constraintFlags_s fl;
|
|
};
|
|
|
|
class alignas(16) idAFConstraint_Fixed : public idAFConstraint {
|
|
public:
|
|
idAFConstraint_Fixed(const char* name = nullptr,
|
|
idAFBody* body1 = nullptr, idAFBody* body2 = nullptr);
|
|
void SetBody1(idAFBody*) override;
|
|
void SetBody2(idAFBody*) override;
|
|
void Rotate(const idRotation&) override;
|
|
void GetCenter(idVec3&) const override;
|
|
void DebugDraw() override;
|
|
void Evaluate(const idPhysics_AF*, float) override;
|
|
void InitOffset();
|
|
|
|
idVec3 offset;
|
|
idMat3 relAxis;
|
|
bool shouldClamp;
|
|
};
|
|
|
|
class idAFConstraint_ConeLimit;
|
|
class idAFConstraint_PyramidLimit;
|
|
class idAFConstraint_BallAndSocketJointFriction;
|
|
|
|
class alignas(16) idAFConstraint_BallAndSocketJoint
|
|
: public idAFConstraint {
|
|
public:
|
|
idAFConstraint_BallAndSocketJoint(const char* name = nullptr,
|
|
idAFBody* body1 = nullptr, idAFBody* body2 = nullptr);
|
|
~idAFConstraint_BallAndSocketJoint() override;
|
|
void Translate(const idVec3&) override;
|
|
void Rotate(const idRotation&) override;
|
|
void GetCenter(idVec3&) const override;
|
|
void DebugDraw() override;
|
|
void Evaluate(const idPhysics_AF*, float) override;
|
|
void ApplyFriction(float) override;
|
|
void SetAnchor(const idVec3& worldPosition);
|
|
void SetWorldPosition(const idVec3& worldPosition);
|
|
float GetFriction() const;
|
|
void SetNoLimit();
|
|
void SetConeLimit(const idVec3& coneAxis, float coneAngle,
|
|
const idVec3& body1Axis);
|
|
void SetPyramidLimit(const idVec3& pyramidAxis,
|
|
const idVec3& baseAxis, float angle1, float angle2,
|
|
const idVec3& body1Axis);
|
|
|
|
idVec3 anchor1;
|
|
idVec3 anchor2;
|
|
float friction;
|
|
idAFConstraint_ConeLimit* coneLimit;
|
|
idAFConstraint_PyramidLimit* pyramidLimit;
|
|
idAFConstraint_BallAndSocketJointFriction* fc;
|
|
};
|
|
|
|
class alignas(16) idAFConstraint_BallAndSocketJointFriction
|
|
: public idAFConstraint {
|
|
public:
|
|
explicit idAFConstraint_BallAndSocketJointFriction(
|
|
idAFConstraint_BallAndSocketJoint* joint = nullptr);
|
|
bool Add(idPhysics_AF*, float invTimeStep);
|
|
idAFConstraint_BallAndSocketJoint* joint;
|
|
};
|
|
|
|
class idAFConstraint_UniversalJointFriction;
|
|
|
|
class alignas(16) idAFConstraint_UniversalJoint : public idAFConstraint {
|
|
public:
|
|
idAFConstraint_UniversalJoint(const char* name = nullptr,
|
|
idAFBody* body1 = nullptr, idAFBody* body2 = nullptr);
|
|
~idAFConstraint_UniversalJoint() override;
|
|
void Translate(const idVec3&) override;
|
|
void Rotate(const idRotation&) override;
|
|
void GetCenter(idVec3&) const override;
|
|
void DebugDraw() override;
|
|
void Evaluate(const idPhysics_AF*, float) override;
|
|
void ApplyFriction(float) override;
|
|
void SetAnchor(const idVec3& worldPosition);
|
|
void SetShafts(const idVec3& cardanShaft1,
|
|
const idVec3& cardanShaft2);
|
|
float GetFriction() const;
|
|
void SetNoLimit();
|
|
void SetConeLimit(const idVec3& coneAxis, float coneAngle,
|
|
const idVec3& body1Axis);
|
|
void SetPyramidLimit(const idVec3& pyramidAxis,
|
|
const idVec3& baseAxis, float angle1, float angle2,
|
|
const idVec3& body1Axis);
|
|
|
|
idVec3 anchor1;
|
|
idVec3 anchor2;
|
|
idVec3 shaft1;
|
|
idVec3 shaft2;
|
|
idVec3 axis1;
|
|
idVec3 axis2;
|
|
float friction;
|
|
idAFConstraint_ConeLimit* coneLimit;
|
|
idAFConstraint_PyramidLimit* pyramidLimit;
|
|
idAFConstraint_UniversalJointFriction* fc;
|
|
};
|
|
|
|
class alignas(16) idAFConstraint_UniversalJointFriction
|
|
: public idAFConstraint {
|
|
public:
|
|
explicit idAFConstraint_UniversalJointFriction(
|
|
idAFConstraint_UniversalJoint* joint = nullptr);
|
|
bool Add(idPhysics_AF*, float invTimeStep);
|
|
void Evaluate(const idPhysics_AF*, float) override;
|
|
idAFConstraint_UniversalJoint* joint;
|
|
};
|
|
|
|
class idAFConstraint_HingeFriction;
|
|
class idAFConstraint_HingeSteering;
|
|
|
|
class alignas(16) idAFConstraint_Hinge : public idAFConstraint {
|
|
public:
|
|
idAFConstraint_Hinge(const char* name = nullptr,
|
|
idAFBody* body1 = nullptr, idAFBody* body2 = nullptr);
|
|
~idAFConstraint_Hinge() override;
|
|
void Translate(const idVec3&) override;
|
|
void Rotate(const idRotation&) override;
|
|
void GetCenter(idVec3&) const override;
|
|
void DebugDraw() override;
|
|
void Evaluate(const idPhysics_AF*, float) override;
|
|
void ApplyFriction(float) override;
|
|
void SetAnchor(const idVec3& worldPosition);
|
|
void SetAxis(const idVec3& axis);
|
|
float GetFriction() const;
|
|
float GetAngle() const;
|
|
void SetNoLimit();
|
|
void SetLimit(float angle1, float angle2, float epsilon);
|
|
|
|
idVec3 anchor1;
|
|
idVec3 anchor2;
|
|
idVec3 axis1;
|
|
idVec3 axis2;
|
|
idMat3 initialAxis;
|
|
float friction;
|
|
idAFConstraint_ConeLimit* coneLimit;
|
|
idAFConstraint_HingeSteering* steering;
|
|
idAFConstraint_HingeFriction* fc;
|
|
};
|
|
|
|
class alignas(16) idAFConstraint_HingeFriction : public idAFConstraint {
|
|
public:
|
|
explicit idAFConstraint_HingeFriction(
|
|
idAFConstraint_Hinge* hinge = nullptr);
|
|
bool Add(idPhysics_AF*, float invTimeStep);
|
|
idAFConstraint_Hinge* hinge;
|
|
};
|
|
|
|
class idAFConstraint_HingeSteering : public idAFConstraint {
|
|
public:
|
|
explicit idAFConstraint_HingeSteering(
|
|
idAFConstraint_Hinge* hinge = nullptr);
|
|
bool Add(idPhysics_AF*, float invTimeStep);
|
|
idAFConstraint_Hinge* hinge;
|
|
float steerAngle;
|
|
float steerSpeed;
|
|
float epsilon;
|
|
};
|
|
|
|
class alignas(16) idAFConstraint_Slider : public idAFConstraint {
|
|
public:
|
|
idAFConstraint_Slider(const char* name = nullptr,
|
|
idAFBody* body1 = nullptr, idAFBody* body2 = nullptr);
|
|
void SetAxis(const idVec3&);
|
|
void GetCenter(idVec3&) const override;
|
|
void DebugDraw() override;
|
|
void Evaluate(const idPhysics_AF*, float) override;
|
|
idVec3 axis;
|
|
idVec3 offset;
|
|
idMat3 relAxis;
|
|
};
|
|
|
|
class idAFConstraint_Spring : public idAFConstraint {
|
|
public:
|
|
idAFConstraint_Spring(const char* name = nullptr,
|
|
idAFBody* body1 = nullptr, idAFBody* body2 = nullptr);
|
|
void Translate(const idVec3&) override;
|
|
void Rotate(const idRotation&) override;
|
|
void GetCenter(idVec3&) const override;
|
|
void DebugDraw() override;
|
|
void Evaluate(const idPhysics_AF*, float) override;
|
|
void SetAnchor(const idVec3& anchor1, const idVec3& anchor2);
|
|
void SetSpring(float stretch, float compress, float damping,
|
|
float restLength);
|
|
void SetLimit(float minLength, float maxLength);
|
|
idVec3 anchor1;
|
|
idVec3 anchor2;
|
|
float kstretch;
|
|
float kcompress;
|
|
float damping;
|
|
float restLength;
|
|
float minLength;
|
|
float maxLength;
|
|
};
|
|
|
|
class idAFConstraint_ContactFriction;
|
|
|
|
class alignas(16) idAFConstraint_Contact : public idAFConstraint {
|
|
public:
|
|
idAFConstraint_Contact();
|
|
~idAFConstraint_Contact() override;
|
|
void GetCenter(idVec3&) const override;
|
|
void DebugDraw() override;
|
|
void ApplyFriction(float) override;
|
|
void Setup(idAFBody* body1, idAFBody* body2,
|
|
const contactInfo_t&, float separation, float invTimeStep);
|
|
contactInfo_t contact;
|
|
float separation;
|
|
idAFConstraint_ContactFriction* fc;
|
|
};
|
|
|
|
class alignas(16) idAFConstraint_ContactFriction
|
|
: public idAFConstraint {
|
|
public:
|
|
explicit idAFConstraint_ContactFriction(
|
|
idAFConstraint_Contact* contact = nullptr);
|
|
bool Add(idPhysics_AF*, float invTimeStep);
|
|
idAFConstraint_Contact* cc;
|
|
};
|
|
|
|
class alignas(16) idAFConstraint_ConeLimit : public idAFConstraint {
|
|
public:
|
|
idAFConstraint_ConeLimit();
|
|
void Setup(idAFBody*, idAFBody*, const idVec3& coneAnchor,
|
|
const idVec3& coneAxis, float coneAngle,
|
|
const idVec3& body1Axis);
|
|
bool Add(idPhysics_AF*, float invTimeStep);
|
|
void Translate(const idVec3&) override;
|
|
void Rotate(const idRotation&) override;
|
|
void DebugDraw() override;
|
|
idVec3 coneAnchor;
|
|
idVec3 coneAxis;
|
|
idVec3 body1Axis;
|
|
float cosAngle;
|
|
float sinHalfAngle;
|
|
float cosHalfAngle;
|
|
float epsilon;
|
|
};
|
|
|
|
class alignas(16) idAFConstraint_PyramidLimit : public idAFConstraint {
|
|
public:
|
|
idAFConstraint_PyramidLimit();
|
|
void Setup(idAFBody*, idAFBody*, const idVec3& pyramidAnchor,
|
|
const idVec3& pyramidAxis, const idVec3& baseAxis,
|
|
float angle1, float angle2, const idVec3& body1Axis);
|
|
bool Add(idPhysics_AF*, float invTimeStep);
|
|
void Translate(const idVec3&) override;
|
|
void Rotate(const idRotation&) override;
|
|
void DebugDraw() override;
|
|
idVec3 pyramidAnchor;
|
|
idMat3 pyramidBasis;
|
|
idVec3 body1Axis;
|
|
float cosAngle[2];
|
|
float sinHalfAngle[2];
|
|
float cosHalfAngle[2];
|
|
float epsilon;
|
|
};
|
|
|
|
class alignas(16) idAFConstraint_Suspension : public idAFConstraint {
|
|
public:
|
|
idAFConstraint_Suspension();
|
|
void Setup(const char* name, idAFBody*, const idVec3& localOrigin,
|
|
idClip*, idClipModel*, int clipMask, float radius);
|
|
void SetSuspension(float up, float down, float compress,
|
|
float damping);
|
|
int GetContactEntity() const;
|
|
void Translate(const idVec3&) override;
|
|
void IssueCollisionQueries() override;
|
|
void CancelCollisionQueries() override;
|
|
void DebugDraw() override;
|
|
void Evaluate(const idPhysics_AF*, float) override;
|
|
void Serialize(idSerializer*) override;
|
|
|
|
idVec3 localOrigin;
|
|
float suspensionUp;
|
|
float suspensionDown;
|
|
float suspensionCompress;
|
|
float suspensionDamping;
|
|
const idDeclTable* friction_longitudinal;
|
|
const idDeclTable* friction_lateral;
|
|
float frictionLatMultiplier;
|
|
float frictionLongMultiplier;
|
|
idClip* clip;
|
|
idClipModel* wheelModel;
|
|
float wheelRadius;
|
|
int clipMask;
|
|
idVec3 cgLocation;
|
|
float steerAngle;
|
|
bool motorEnabled;
|
|
float motorForce;
|
|
float motorVelocity;
|
|
idClipQuery traceQuery;
|
|
float traceFraction;
|
|
idVec3 traceEndPos;
|
|
idVec3 traceNormal;
|
|
idVec3 tracePoint;
|
|
int traceSurfaceFlags;
|
|
int traceEntityNum;
|
|
float wheelVelocity;
|
|
float wheelAngle;
|
|
float lastWheelHeight;
|
|
float lastMotorVelocity;
|
|
float lastTorque;
|
|
float lastGrip;
|
|
bool lastOnGround;
|
|
bool limitLateralGrip;
|
|
float lateralSlip;
|
|
float longitudinalSlip;
|
|
float debugSpringForce;
|
|
idVec3 debugv1;
|
|
idVec3 debugv2;
|
|
idVec3 debugv3;
|
|
float debugf1;
|
|
float debugf2;
|
|
float debugf3;
|
|
float debugf4;
|
|
};
|
|
|
|
class idAFConstraint_Line : public idAFConstraint {};
|
|
class idAFConstraint_CylindricalJoint : public idAFConstraint {};
|
|
|
|
class alignas(16) idAFConstraint_Plane : public idAFConstraint {
|
|
public:
|
|
idVec3 anchor1;
|
|
idVec3 anchor2;
|
|
idVec3 planeNormal;
|
|
};
|
|
|
|
class alignas(16) idAFConstraint_Weeble : public idAFConstraint {
|
|
public:
|
|
idVec3 up;
|
|
bool enabled;
|
|
};
|
|
|
|
static_assert(sizeof(idAFConstraint::constraintFlags_s) == 1,
|
|
"Recovered AF constraint flags ABI changed");
|