knightonline/server/N3BASE/My_3DStruct.h

357 lines
7.7 KiB
C++

#pragma once
#include <math.h>
#include <cfloat>
/* Here follow the extremely few remaining D3D8 components we require */
// NOTE: We're using this over M_PI because of the precision
#define D3DX_PI ((float) 3.141592654f)
#define D3DXToRadian( degree ) ((degree) * (D3DX_PI / 180.0f))
/* D3D8 structs */
typedef struct _D3DVECTOR {
float x;
float y;
float z;
} D3DVECTOR;
typedef struct _D3DMATRIX {
union {
struct {
float _11, _12, _13, _14;
float _21, _22, _23, _24;
float _31, _32, _33, _34;
float _41, _42, _43, _44;
};
float m[4][4];
};
} D3DMATRIX;
struct __Matrix44;
struct __Vector3 : public D3DVECTOR // 3D Vertex
{
public:
INLINE __Vector3() {}
INLINE __Vector3(float fx, float fy, float fz) { Set(fx, fy, fz); }
INLINE void Zero() { Set(0.0f, 0.0f, 0.0f); }
INLINE void Set(float fx, float fy, float fz) { x = fx; y = fy; z = fz; }
void Normalize();
float Magnitude() const;
float Dot(const D3DVECTOR& vec) const;
void Cross(const D3DVECTOR& v1, const D3DVECTOR& v2);
void Absolute();
const __Vector3& operator = (const __Vector3& vec);
const __Vector3 operator * (const D3DMATRIX& mtx) const;
void operator *= (float fDelta);
void operator *= (const D3DMATRIX& mtx);
__Vector3 operator + (const D3DVECTOR& vec) const;
__Vector3 operator - (const D3DVECTOR& vec) const;
__Vector3 operator * (const D3DVECTOR& vec) const;
__Vector3 operator / (const D3DVECTOR& vec) const;
void operator += (const D3DVECTOR& vec);
void operator -= (const D3DVECTOR& vec);
void operator *= (const D3DVECTOR& vec);
void operator /= (const D3DVECTOR& vec);
__Vector3 operator + (float fDelta) const;
__Vector3 operator - (float fDelta) const;
__Vector3 operator * (float fDelta) const;
__Vector3 operator / (float fDelta) const;
};
struct __Matrix44 : public D3DMATRIX // 4x4 Matrix
{
public:
__Matrix44() {}
void Zero();
void Identity();
void RotationY(float fDelta);
};
INLINE void __Vector3::Normalize()
{
float fn = sqrtf(x*x + y*y + z*z);
if(fn == 0) return;
x /= fn; y /= fn; z /= fn;
}
INLINE float __Vector3::Magnitude() const
{
return sqrtf(x*x + y*y + z*z);
}
INLINE float __Vector3::Dot(const D3DVECTOR& vec) const
{
return x*vec.x + y*vec.y + z*vec.z;
}
INLINE void __Vector3::Cross(const D3DVECTOR& v1, const D3DVECTOR& v2)
{
x = v1.y * v2.z - v1.z * v2.y;
y = v1.z * v2.x - v1.x * v2.z;
z = v1.x * v2.y - v1.y * v2.x;
}
INLINE void __Vector3::Absolute()
{
if(x < 0) x *= -1.0f;
if(y < 0) y *= -1.0f;
if(z < 0) z *= -1.0f;
}
INLINE const __Vector3& __Vector3::operator = (const __Vector3& vec)
{
x = vec.x; y = vec.y; z = vec.z;
return *this;
}
INLINE const __Vector3 __Vector3::operator * (const D3DMATRIX& mtx) const
{
static __Vector3 vTmp;
vTmp.x = x*mtx._11 + y*mtx._21 + z*mtx._31 + mtx._41;
vTmp.y = x*mtx._12 + y*mtx._22 + z*mtx._32 + mtx._42;
vTmp.z = x*mtx._13 + y*mtx._23 + z*mtx._33 + mtx._43;
return vTmp;
}
INLINE void __Vector3::operator *= (float fDelta)
{
x *= fDelta;
y *= fDelta;
z *= fDelta;
}
INLINE void __Vector3::operator *= (const D3DMATRIX& mtx)
{
static __Vector3 vTmp;
vTmp.Set(x,y,z);
x = vTmp.x*mtx._11 + vTmp.y*mtx._21 + vTmp.z*mtx._31 + mtx._41;
y = vTmp.x*mtx._12 + vTmp.y*mtx._22 + vTmp.z*mtx._32 + mtx._42;
z = vTmp.x*mtx._13 + vTmp.y*mtx._23 + vTmp.z*mtx._33 + mtx._43;
}
INLINE __Vector3 __Vector3::operator + (const D3DVECTOR& vec) const
{
static __Vector3 vTmp;
vTmp.x = x + vec.x;
vTmp.y = y + vec.y;
vTmp.z = z + vec.z;
return vTmp;
}
INLINE __Vector3 __Vector3::operator - (const D3DVECTOR& vec) const
{
static __Vector3 vTmp;
vTmp.x = x - vec.x;
vTmp.y = y - vec.y;
vTmp.z = z - vec.z;
return vTmp;
}
INLINE __Vector3 __Vector3::operator * (const D3DVECTOR& vec) const
{
static __Vector3 vTmp;
vTmp.x = x * vec.x;
vTmp.y = y * vec.y;
vTmp.z = z * vec.z;
return vTmp;
}
INLINE __Vector3 __Vector3::operator / (const D3DVECTOR& vec) const
{
static __Vector3 vTmp;
vTmp.x = x / vec.x;
vTmp.y = y / vec.y;
vTmp.z = z / vec.z;
return vTmp;
}
INLINE void __Vector3::operator += (const D3DVECTOR& vec)
{
x += vec.x;
y += vec.y;
z += vec.z;
}
INLINE void __Vector3::operator -= (const D3DVECTOR& vec)
{
x -= vec.x;
y -= vec.y;
z -= vec.z;
}
INLINE void __Vector3::operator *= (const D3DVECTOR& vec)
{
x *= vec.x;
y *= vec.y;
z *= vec.z;
}
INLINE void __Vector3::operator /= (const D3DVECTOR& vec)
{
x /= vec.x;
y /= vec.y;
z /= vec.z;
}
INLINE __Vector3 __Vector3::operator + (float fDelta) const
{
static __Vector3 vTmp;
vTmp.x = x + fDelta;
vTmp.y = y + fDelta;
vTmp.z = z + fDelta;
return vTmp;
}
INLINE __Vector3 __Vector3::operator - (float fDelta) const
{
static __Vector3 vTmp;
vTmp.x = x - fDelta;
vTmp.y = y - fDelta;
vTmp.z = z - fDelta;
return vTmp;
}
INLINE __Vector3 __Vector3::operator * (float fDelta) const
{
static __Vector3 vTmp;
vTmp.x = x * fDelta;
vTmp.y = y * fDelta;
vTmp.z = z * fDelta;
return vTmp;
}
INLINE __Vector3 __Vector3::operator / (float fDelta) const
{
static __Vector3 vTmp;
vTmp.x = x / fDelta;
vTmp.y = y / fDelta;
vTmp.z = z / fDelta;
return vTmp;
}
INLINE void __Matrix44::Identity()
{
_12 = _13 = _14 = _21 = _23 = _24 = _31 = _32 = _34 = _41 = _42 = _43 = 0;
_11 = _22 = _33 = _44 = 1.0f;
}
INLINE void __Matrix44::RotationY(float fDelta)
{
this->Identity();
_11 = cosf(fDelta); _13 = -sinf(fDelta); _31 = -_13; _33 = _11;
}
INLINE bool _IntersectTriangle(const __Vector3& vOrig, const __Vector3& vDir,
const __Vector3& v0, const __Vector3& v1, const __Vector3& v2,
float& fT, float& fU, float& fV, __Vector3* pVCol = nullptr)
{
// Find vectors for two edges sharing vert0
static __Vector3 vEdge1, vEdge2;
vEdge1 = v1 - v0;
vEdge2 = v2 - v0;
// Begin calculating determinant - also used to calculate U parameter
__Vector3 pVec; float fDet;
pVec.Cross(vEdge1, vEdge2);
fDet = pVec.Dot(vDir);
if (fDet > -0.0001f )
return false;
pVec.Cross(vDir, vEdge2);
// If determinant is near zero, ray lies in plane of triangle
fDet = vEdge1.Dot(pVec);
if( fDet < 0.0001f )
return false;
// Calculate distance from vert0 to ray origin
__Vector3 tVec = vOrig - v0;
// Calculate U parameter and test bounds
fU = tVec.Dot(pVec);
if( fU < 0.0f || fU > fDet )
return false;
// Prepare to test V parameter
__Vector3 qVec;
qVec.Cross(tVec, vEdge1);
// Calculate V parameter and test bounds
fV = vDir.Dot(qVec);
if( fV < 0.0f || fU + fV > fDet )
return false;
// Calculate t, scale parameters, ray intersects triangle
fT = vEdge2.Dot(qVec);
float fInvDet = 1.0f / fDet;
fT *= fInvDet;
fU *= fInvDet;
fV *= fInvDet;
if(pVCol) (*pVCol) = vOrig + (vDir * fT);
return (fT >= 0.0f);
}
INLINE bool _IntersectTriangle(const __Vector3& vOrig, const __Vector3& vDir, const __Vector3& v0, const __Vector3& v1, const __Vector3& v2)
{
// Find vectors for two edges sharing vert0
// Begin calculating determinant - also used to calculate U parameter
static float fDet, fT, fU, fV;
static __Vector3 vEdge1, vEdge2, tVec, pVec, qVec;
vEdge1 = v1 - v0;
vEdge2 = v2 - v0;
pVec.Cross(vEdge1, vEdge2);
fDet = pVec.Dot(vDir);
if (fDet > -0.0001f )
return false;
pVec.Cross(vDir, vEdge2);
// If determinant is near zero, ray lies in plane of triangle
fDet = vEdge1.Dot(pVec);
if( fDet < 0.0001f )
return false;
// Calculate distance from vert0 to ray origin
tVec = vOrig - v0;
// Calculate U parameter and test bounds
fU = tVec.Dot(pVec);
if( fU < 0.0f || fU > fDet )
return false;
// Prepare to test V parameter
qVec.Cross(tVec, vEdge1);
// Calculate V parameter and test bounds
fV = vDir.Dot(qVec);
if( fV < 0.0f || fU + fV > fDet )
return false;
// Calculate t, scale parameters, ray intersects triangle
fT = vEdge2.Dot(qVec) / fDet;
return (fT >= 0.0f);
}