- BORLAND/: Borland C++ 4.52 (chosen over 4.5 by byte-match: CODE/RP/CW32.LIB
is identical to 4.52's install lib). BCC32/TLINK32/TLIB/MAKE run natively on
Win11; CODE/BT/OPT.MAK is the shipped BTL4OPT.EXE's exact flag recipe
(extender = Borland PowerPack DPMI32, not Phar Lap TNT).
- restoration/source410/: the literal 1995-form reconstruction of the missing
BT game source (never mixed into CODE/). Round 1-3 state:
* 6 of 10 surviving original TUs COMPILE CLEAN under the period toolchain
(BTMSSN, BTCNSL, BTSCNRL, BTTEAM, BTL4MODE, BTL4ARND) - first builds
since 1996.
* BT_L4/BTL4APP.CPP pilot reconstruction: 12/12 functions, Fail() lands on
its binary-recorded line 400 exactly.
* BT/BTCNSL.HPP: console wire IDs recovered from the binary's ctors
(Killed=9, Damaged=10, ScoreUpdate=13, DeathWithoutHonor=15 [T1];
TeamScore=12 flagged [T4]).
* MUNGA/: 8 engine-header backfills back-dated from the BT412 WinTesla tree
(VDATA numbering decomp-verified; AUDREND's OpenAL-era virtual removed -
the period compiler is the drift detector).
* Tooling: backdate.py (WinTesla->1995 header transform), compile410.sh
(per-TU verification sweep under authentic OPT.MAK flags).
* README: corrected roadmap - MECH.HPP is the capstone grown with the mech
TU reconstructions; BTREG.CPP green = the header-family milestone.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
313 lines
8.0 KiB
C++
313 lines
8.0 KiB
C++
#if !defined(ROTATION_HPP)
|
|
# define ROTATION_HPP
|
|
|
|
# if !defined(ANGLE_HPP)
|
|
# include <angle.hpp>
|
|
# endif
|
|
|
|
class Quaternion;
|
|
class Origin;
|
|
class YawPitchRoll;
|
|
class UnitVector;
|
|
class LinearMatrix;
|
|
class Vector3D;
|
|
|
|
//##########################################################################
|
|
//############################ Hinge #################################
|
|
//##########################################################################
|
|
|
|
class Hinge
|
|
{
|
|
public:
|
|
int axisNumber;
|
|
Radian rotationAmount;
|
|
|
|
//
|
|
// Constructors
|
|
//
|
|
Hinge() {}
|
|
Hinge(int axis, const Radian &angle) : axisNumber(axis), rotationAmount(angle) {}
|
|
#if defined(USE_SIGNATURE)
|
|
friend int Is_Signature_Bad(const volatile Hinge *);
|
|
#endif
|
|
//
|
|
// Assignment operators
|
|
//
|
|
Hinge& operator=(const Hinge &hinge)
|
|
{
|
|
Check_Pointer(this);
|
|
Check(&hinge);
|
|
axisNumber = hinge.axisNumber;
|
|
rotationAmount = hinge.rotationAmount;
|
|
return *this;
|
|
}
|
|
|
|
//
|
|
// "Close-enough" comparators
|
|
//
|
|
friend Logical Small_Enough(const Hinge &a, Scalar e = SMALL)
|
|
{
|
|
Check(&a);
|
|
return Small_Enough(a, e);
|
|
}
|
|
Logical operator!() const { return Small_Enough(*this,SMALL); }
|
|
|
|
friend Logical Close_Enough(const Hinge &a1, const Hinge &a2, Scalar e = SMALL);
|
|
Logical operator==(const Hinge& a) const { return Close_Enough(*this, a, SMALL); }
|
|
Logical operator!=(const Hinge& a) const { return !Close_Enough(*this, a, SMALL); }
|
|
|
|
//
|
|
// Template support
|
|
//
|
|
Hinge& Lerp(const Hinge& v1, const Hinge& v2, Scalar t);
|
|
|
|
//
|
|
// Support functions
|
|
//
|
|
friend ostream& operator<<(ostream& stream, const Hinge& angles);
|
|
Logical TestInstance() const;
|
|
};
|
|
|
|
//##########################################################################
|
|
//######################### EulerAngles #############################
|
|
//##########################################################################
|
|
|
|
class EulerAngles
|
|
{
|
|
public:
|
|
Radian pitch, yaw, roll;
|
|
|
|
static const EulerAngles Identity;
|
|
|
|
#if defined(USE_SIGNATURE)
|
|
friend int Is_Signature_Bad(const volatile EulerAngles *);
|
|
#endif
|
|
|
|
//
|
|
// Constructors
|
|
//
|
|
EulerAngles() {}
|
|
EulerAngles(const Radian &pitch, const Radian &yaw, const Radian &roll)
|
|
{
|
|
this->pitch = pitch;
|
|
this->yaw = yaw;
|
|
this->roll = roll;
|
|
}
|
|
|
|
//
|
|
// Assignment operators
|
|
//
|
|
EulerAngles& operator=(const EulerAngles &angles);
|
|
EulerAngles& operator=(const YawPitchRoll &angles);
|
|
EulerAngles& operator=(const Hinge &hinge);
|
|
EulerAngles& operator=(const Quaternion &quaternion);
|
|
EulerAngles& operator=(const LinearMatrix &matrix);
|
|
EulerAngles& operator=(const Origin &p);
|
|
|
|
//
|
|
// "Close-enough" comparators
|
|
//
|
|
friend Logical Small_Enough(const EulerAngles &a, Scalar e = SMALL);
|
|
Logical operator!() const { return Small_Enough(*this); }
|
|
|
|
friend Logical Close_Enough(const EulerAngles &a1, const EulerAngles &a2, Scalar e = SMALL);
|
|
Logical operator==(const EulerAngles& a) const { return Close_Enough(*this, a, SMALL); }
|
|
Logical operator!=(const EulerAngles& a) const { return !Close_Enough(*this, a, SMALL); }
|
|
|
|
//
|
|
// Axis index operators
|
|
//
|
|
const Radian& operator[](size_t index) const
|
|
{
|
|
Check_Pointer(this);
|
|
Warn(index>Z_Axis);
|
|
return (&pitch)[index];
|
|
}
|
|
Radian& operator[](size_t index)
|
|
{
|
|
Check_Pointer(this);
|
|
Warn(index>Z_Axis);
|
|
return (&pitch)[index];
|
|
}
|
|
|
|
//
|
|
// Multiplication operators
|
|
//
|
|
EulerAngles& Multiply(const EulerAngles &q1, const EulerAngles &q2);
|
|
EulerAngles& Multiply(const EulerAngles &q, Scalar scale);
|
|
EulerAngles& MultiplyScaled(const EulerAngles &q1, const EulerAngles &q2, Scalar t);
|
|
|
|
//
|
|
// Template support
|
|
//
|
|
EulerAngles& Lerp(const EulerAngles& v1, const EulerAngles& v2, Scalar t);
|
|
|
|
//
|
|
// Support functions
|
|
//
|
|
EulerAngles& Normalize();
|
|
friend ostream& operator<<(ostream& stream, const EulerAngles& angles);
|
|
|
|
//
|
|
// Test functions
|
|
//
|
|
Logical TestInstance() const;
|
|
static Logical TestClass();
|
|
};
|
|
|
|
//##########################################################################
|
|
//######################### YawPitchRoll ############################
|
|
//##########################################################################
|
|
|
|
class YawPitchRoll
|
|
{
|
|
public:
|
|
Radian yaw, pitch, roll;
|
|
|
|
static const YawPitchRoll Identity;
|
|
|
|
#if defined(USE_SIGNATURE)
|
|
friend int Is_Signature_Bad(const volatile YawPitchRoll *);
|
|
#endif
|
|
|
|
//
|
|
// Constructors
|
|
//
|
|
YawPitchRoll() {}
|
|
YawPitchRoll(const Radian &yaw, const Radian &pitch, const Radian &roll)
|
|
{
|
|
this->pitch = pitch;
|
|
this->yaw = yaw;
|
|
this->roll = roll;
|
|
}
|
|
|
|
//
|
|
// Assignment operators
|
|
//
|
|
YawPitchRoll& operator=(const Hinge &hinge);
|
|
YawPitchRoll& operator=(const YawPitchRoll &angles);
|
|
YawPitchRoll& operator=(const EulerAngles &angles);
|
|
YawPitchRoll& operator=(const Quaternion &quaternion);
|
|
YawPitchRoll& operator=(const LinearMatrix &matrix);
|
|
YawPitchRoll& operator=(const Origin &p);
|
|
|
|
//
|
|
// "Close-enough" comparators
|
|
//
|
|
friend Logical Small_Enough(const YawPitchRoll &a, Scalar e = SMALL);
|
|
Logical operator!() const { return Small_Enough(*this); }
|
|
|
|
friend Logical Close_Enough(const YawPitchRoll &a1, const YawPitchRoll &a2, Scalar e = SMALL);
|
|
Logical operator==(const YawPitchRoll& a) const { return Close_Enough(*this, a); }
|
|
Logical operator!=(const YawPitchRoll& a) const { return !Close_Enough(*this, a); }
|
|
|
|
//
|
|
// Support functions
|
|
//
|
|
YawPitchRoll& Normalize();
|
|
friend ostream& operator<<(ostream& stream, const YawPitchRoll& angles);
|
|
|
|
//
|
|
// Test functions
|
|
//
|
|
Logical TestInstance() const;
|
|
};
|
|
|
|
//##########################################################################
|
|
//######################### Quaternion ###############################
|
|
//##########################################################################
|
|
|
|
class Quaternion
|
|
{
|
|
public:
|
|
static const Quaternion Identity;
|
|
|
|
#if defined(USE_SIGNATURE)
|
|
friend int Is_Signature_Bad(const volatile Quaternion *);
|
|
#endif
|
|
|
|
Scalar x, y, z, w;
|
|
|
|
//
|
|
// Constructors
|
|
//
|
|
Quaternion() {}
|
|
Quaternion(Scalar x, Scalar y, Scalar z, Scalar w);
|
|
|
|
//
|
|
// Assignment operators
|
|
//
|
|
Quaternion& operator=(const Quaternion &q);
|
|
Quaternion& operator=(const Hinge &hinge);
|
|
Quaternion& operator=(const EulerAngles &angles);
|
|
Quaternion& operator=(const YawPitchRoll &angles);
|
|
Quaternion& operator=(const LinearMatrix &matrix);
|
|
Quaternion& operator=(const Origin &p);
|
|
|
|
//
|
|
// "Close-enough" comparators
|
|
//
|
|
friend Logical Small_Enough(const Quaternion &q, Scalar e = SMALL)
|
|
{
|
|
Check(&q);
|
|
return Close_Enough(q.w, 1.0f, e);
|
|
}
|
|
Logical operator!() const { return Small_Enough(*this, SMALL); }
|
|
|
|
//
|
|
// Axis index operators
|
|
//
|
|
const Scalar& operator[](size_t index) const
|
|
{
|
|
Check_Pointer(this);
|
|
Warn(index>W_Axis);
|
|
return (&x)[index];
|
|
}
|
|
Scalar& operator[](size_t index)
|
|
{
|
|
Check_Pointer(this);
|
|
Warn(index>W_Axis);
|
|
return (&x)[index];
|
|
}
|
|
|
|
Scalar GetAngle();
|
|
void GetAxis(UnitVector *axis);
|
|
|
|
//
|
|
// Multiplication operators
|
|
//
|
|
Quaternion& Multiply(const Quaternion &q1, const Quaternion &q2);
|
|
Quaternion& Multiply(const Quaternion &q, Scalar scale);
|
|
Quaternion& MultiplyScaled(const Quaternion &q1, const Quaternion &q2, Scalar t);
|
|
Quaternion& Add(const Quaternion &source, const Vector3D &delta);
|
|
Quaternion& AddScaled(const Quaternion &source, const Vector3D &delta, Scalar t);
|
|
|
|
//
|
|
// Transform functions
|
|
//
|
|
Quaternion& Multiply(const Quaternion &q, const LinearMatrix &m);
|
|
Quaternion& operator*=(const LinearMatrix &m);
|
|
|
|
//
|
|
// Template support
|
|
//
|
|
Quaternion& Lerp(const Quaternion& v1, const Quaternion& v2, Scalar t);
|
|
|
|
//
|
|
// Miscellaneous functions
|
|
//
|
|
Quaternion& Normalize();
|
|
Quaternion& Subtract(const Quaternion &end, const Quaternion &start);
|
|
Quaternion& Subtract(const UnitVector &end, const UnitVector &start);
|
|
Quaternion& Subtract(const Vector3D &end, const Vector3D &start);
|
|
|
|
//
|
|
// Support functions
|
|
//
|
|
friend ostream& operator<<(ostream& stream, const Quaternion& quaternion);
|
|
Logical TestInstance() const;
|
|
static Logical TestClass();
|
|
};
|
|
|
|
#endif
|