Complete disaster-recovery snapshot: engine/game source, game data assets, VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive. Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false, no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
274 lines
6.1 KiB
C++
274 lines
6.1 KiB
C++
#pragma once
|
|
|
|
#include "Stuff.hpp"
|
|
#include "LinearMatrix.hpp"
|
|
#include "Sphere.hpp"
|
|
|
|
namespace Stuff {class OBB;}
|
|
|
|
#if !defined(Spew)
|
|
void Spew(
|
|
const char* group,
|
|
const Stuff::OBB &box
|
|
);
|
|
#endif
|
|
|
|
namespace Stuff {
|
|
|
|
class Line3D;
|
|
|
|
class OBB
|
|
{
|
|
public:
|
|
void TestInstance() const;
|
|
|
|
static OBB Identity;
|
|
|
|
LinearMatrix4D localToParent;
|
|
Vector3D axisExtents;
|
|
Scalar sphereRadius;
|
|
|
|
#if !defined(Spew)
|
|
friend void ::Spew(
|
|
const char* group,
|
|
const OBB &box
|
|
);
|
|
#endif
|
|
|
|
Scalar GetVolume() const
|
|
{Check_Object(this); return 8.0f*axisExtents.x*axisExtents.y*axisExtents.z;}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Construction
|
|
//
|
|
public:
|
|
OBB()
|
|
{}
|
|
OBB(const OBB& obb):
|
|
localToParent(obb.localToParent),
|
|
axisExtents(obb.axisExtents),
|
|
sphereRadius(obb.sphereRadius)
|
|
{}
|
|
OBB(
|
|
const LinearMatrix4D &origin,
|
|
const Vector3D &extents
|
|
):
|
|
localToParent(origin),
|
|
axisExtents(extents),
|
|
sphereRadius(extents.GetLength())
|
|
{}
|
|
OBB(
|
|
const LinearMatrix4D &origin,
|
|
const Vector3D &extents,
|
|
Scalar radius
|
|
):
|
|
localToParent(origin),
|
|
axisExtents(extents),
|
|
sphereRadius(radius)
|
|
{}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Assignment
|
|
//
|
|
public:
|
|
OBB& operator=(const OBB& obb)
|
|
{
|
|
Check_Pointer(this); Check_Object(&obb);
|
|
localToParent = obb.localToParent;
|
|
axisExtents = obb.axisExtents;
|
|
sphereRadius = obb.sphereRadius;
|
|
return *this;
|
|
}
|
|
OBB& operator=(const ExtentBox& box);
|
|
|
|
OBB& BuildSphere(const Sphere& sphere)
|
|
{
|
|
Check_Pointer(this); Check_Object(&sphere);
|
|
sphereRadius = sphere.radius;
|
|
localToParent.BuildTranslation(sphere.center);
|
|
return *this;
|
|
}
|
|
int ComputeBounds(ReadOnlyArrayOf<Point3D> &points);
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Transforms
|
|
//
|
|
public:
|
|
OBB& Multiply(
|
|
const OBB& obb,
|
|
const LinearMatrix4D &matrix
|
|
);
|
|
inline OBB& MultiplySphereOnly(
|
|
const OBB& obb,
|
|
const LinearMatrix4D &matrix
|
|
)
|
|
{
|
|
Check_Pointer(this);
|
|
Check_Object(&obb);
|
|
Check_Object(&matrix);
|
|
|
|
#if USE_ASSEMBLER_CODE
|
|
|
|
Scalar *f = localToParent.entries;
|
|
|
|
_asm {
|
|
mov edx, matrix
|
|
push esi
|
|
mov esi, obb.localToParent
|
|
|
|
mov eax, f
|
|
|
|
fld dword ptr [edx+4] // m[1][0]
|
|
fmul dword ptr [esi+01ch] // obb.localToParent(3,1)
|
|
|
|
fld dword ptr [edx+8] // m[2][0]
|
|
fmul dword ptr [esi+02Ch] // obb.localToParent(3,2)
|
|
|
|
fxch st(1)
|
|
fadd dword ptr [edx+0Ch] // m[3][0]
|
|
|
|
fld dword ptr [edx] // m[0][0]
|
|
fmul dword ptr [esi+0Ch] // obb.localToParent(3,0)
|
|
|
|
fxch st(2)
|
|
faddp st(1),st
|
|
|
|
fld dword ptr [edx+14h] // m[1][1]
|
|
fmul dword ptr [esi+01ch] // obb.localToParent(3,1)
|
|
|
|
fxch st(2)
|
|
faddp st(1),st
|
|
|
|
fld dword ptr [edx+18h] // m[2][1]
|
|
fmul dword ptr [esi+02ch] // obb.localToParent(3,2)
|
|
|
|
fxch st(1)
|
|
fstp dword ptr [eax+0ch] // localToParent(3,0)
|
|
|
|
fadd dword ptr [edx+1Ch] // m[3][1]
|
|
|
|
fld dword ptr [edx+10h] // m[0][1]
|
|
fmul dword ptr [esi+0ch] // obb.localToParent(3,0)
|
|
|
|
fxch st(2)
|
|
faddp st(1),st
|
|
|
|
fld dword ptr [edx+24h] // m[1][2]
|
|
fmul dword ptr [esi+01ch] // obb.localToParent(3,1)
|
|
|
|
fxch st(2)
|
|
faddp st(1),st
|
|
|
|
fld dword ptr [edx+28h] // m[2][2]
|
|
fmul dword ptr [esi+02ch] // obb.localToParent(3,2)
|
|
|
|
fxch st(1)
|
|
fstp dword ptr [eax+01ch] // localToParent(3,1)
|
|
|
|
fadd dword ptr [edx+2Ch] // m[3][2]
|
|
|
|
fld dword ptr [edx+20h] // m[0][2]
|
|
fmul dword ptr [esi+0ch] // obb.localToParent(3,0)
|
|
|
|
fxch st(2)
|
|
faddp st(1),st
|
|
|
|
pop esi
|
|
|
|
faddp st(1),st
|
|
|
|
fstp dword ptr [eax+02ch] // localToParent(3,2)
|
|
}
|
|
#else
|
|
localToParent(3,0) =
|
|
obb.localToParent(3,0)*matrix(0,0)
|
|
+ obb.localToParent(3,1)*matrix(1,0)
|
|
+ obb.localToParent(3,2)*matrix(2,0)
|
|
+ matrix(3,0);
|
|
localToParent(3,1) =
|
|
obb.localToParent(3,0)*matrix(0,1)
|
|
+ obb.localToParent(3,1)*matrix(1,1)
|
|
+ obb.localToParent(3,2)*matrix(2,1)
|
|
+ matrix(3,1);
|
|
localToParent(3,2) =
|
|
obb.localToParent(3,0)*matrix(0,2)
|
|
+ obb.localToParent(3,1)*matrix(1,2)
|
|
+ obb.localToParent(3,2)*matrix(2,2)
|
|
+ matrix(3,2);
|
|
#endif
|
|
|
|
sphereRadius = obb.sphereRadius;
|
|
return *this;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Intersection functions
|
|
//
|
|
public:
|
|
enum SeparatingAxis {
|
|
NoSeparation = 0,
|
|
A0,
|
|
A1,
|
|
A2,
|
|
B0,
|
|
B1,
|
|
B2,
|
|
A0xB0,
|
|
A0xB1,
|
|
A0xB2,
|
|
A1xB0,
|
|
A1xB1,
|
|
A1xB2,
|
|
A2xB0,
|
|
A2xB1,
|
|
A2xB2
|
|
};
|
|
|
|
SeparatingAxis FindSeparatingAxis(const OBB& box) const;
|
|
//
|
|
// Intersection functions
|
|
//
|
|
bool Contains(const Point3D &point) const;
|
|
bool Intersects(const Plane &plane) const;
|
|
|
|
void Union(
|
|
const OBB &first,
|
|
const OBB &second
|
|
);
|
|
|
|
SeparatingAxis CalculateSeparationVector(
|
|
Vector3D *vector,
|
|
const OBB &obb
|
|
);
|
|
void CalculateSecondarySeparationVector(
|
|
Vector3D *vector,
|
|
const OBB &obb,
|
|
const UnitVector3D &primary
|
|
);
|
|
};
|
|
|
|
inline Sphere& Sphere::operator =(const OBB &obb)
|
|
{
|
|
Check_Pointer(this); Check_Object(&obb);
|
|
center = obb.localToParent;
|
|
radius = obb.sphereRadius;
|
|
return *this;
|
|
}
|
|
|
|
}
|
|
|
|
namespace MemoryStreamIO {
|
|
|
|
inline Stuff::MemoryStream& Read(
|
|
Stuff::MemoryStream* stream,
|
|
Stuff::OBB *output
|
|
)
|
|
{return stream->ReadBytes(output, sizeof(*output));}
|
|
inline Stuff::MemoryStream& Write(
|
|
Stuff::MemoryStream* stream,
|
|
const Stuff::OBB *input
|
|
)
|
|
{return stream->WriteBytes(input, sizeof(*input));}
|
|
|
|
}
|