class Vector{public: float x,y,z;public: inline Vector(void) {} inline Vector(float Ix,float Iy,float Iz): x(Ix), y(Iy), z(Iz) {} inline float Normalise() { float fLength = Length(); if (fLength == 0.0f) return 0.0f; *this /= fLength; return fLength; } inline float LengthSquared(void)const { return (*this) * (*this); } inline float Length(void) const { return sqrt(LengthSquared()); } inline float operator[](int i) const { return (&x); } inline float& operator[](int i) { return (&x); } inline float operator*(const Vector &V) const { return (x * V.x) + (y * V.y) + (z * V.z); } inline Vector operator / ( const float &Scalar) const { return (*this) * (1.0f / Scalar); } inline Vector operator + ( const Vector &fromV) const { return Vector(x + fromV.x, y + fromV.y, z + fromV.z); } inline Vector operator - ( const Vector &fromV) const { return Vector(x - fromV.x, y - fromV.y, z - fromV.z); } inline Vector operator ^ (const Vector &V) { Vector Temp; Temp.Cross(*this, V); return Temp; } inline Vector operator * ( float k) const { return Vector(x * k, y * k, z * k); } inline Vector &operator /= (float k) { *this *= (1.0f / k); return *this; } inline Vector &operator *=(float k) { x *= k; y *= k; z *= k; return *this; } inline Vector &operator +=(const Vector &Other) { x += Other.x; y += Other.y; z += Other.z; return *this; } inline Vector &operator -=(const Vector &Other) { x -= Other.x; y -= Other.y; z -= Other.z; return *this; } friend Vector operator * (float k, const Vector& V) { return V * k; } inline Vector operator -() const { return Vector(-x, -y, -z); } inline Vector& Interpolate(const Vector &Vec1,const Vector &Vec2,float Fraction) { x = Vec1.x * Fraction; y = Vec1.y * Fraction; z = Vec1.z * Fraction; float OneMFrac = 1.0f - Fraction; x += Vec2.x * OneMFrac; y += Vec2.y * OneMFrac; z += Vec2.z * OneMFrac; return *this; } inline Vector& BoundMin(const Vector &V) { if (x > V.x) x = V.x; if (y > V.y) y = V.y; if (z > V.z) z = V.z; return *this; } inline Vector& BoundMax(const Vector &V) { if (x < V.x) x = V.x; if (y < V.y) y = V.y; if (z < V.z) z = V.z; return *this; } inline Vector& Scale(const Vector& Scalar) { x *= Scalar.x; y *= Scalar.y; z *= Scalar.z; return *this; } inline Vector& Cross(const Vector &In1,const Vector &In2) { float Tempx,Tempy; Tempx = (In1.y * In2.z) - (In1.z * In2.y); Tempy = (In1.z * In2.x) - (In1.x * In2.z); z = (In1.x * In2.y) - (In1.y * In2.x); x = Tempx; y = Tempy; return *this; } Vector& Zero() { x = y = z = 0.0f; return *this; }};extern Vector gWorldMin;extern Vector gWorldMax;struct Vector4{ float x, y, z, w; Vector4() { x = y = z = 0.0f; w = 1.0f; } Vector4(float _x, float _y, float _z, float _w=1.0f) { x = _x; y = _y; z = _z; w = _w; } Vector4(const Vector& V, float _w=1.0f) { x = V.x; y = V.y; z = V.z; w = _w; }};const float degen_tolerance = 0.000001f;bool CalculateInterval(Vector N, Vector PA, float* ea, Vector* DA, Vector PB, float* eb, Vector* DB, float& d, float& l2, Vector& D){ D = N; l2 = D * D; if(l2 <= degen_tolerance) { return true; } float pa = PA * D; float ra = fabs(DA[0] * D) * ea[0] + fabs(DA[1] * D) * ea[1] + fabs(DA[2] * D) * ea[2]; float pb = PB * D; float rb = fabs(DB[0] * D) * eb[0] + fabs(DB[1] * D) * eb[1] + fabs(DB[2] * D) * eb[2]; float mina = pa - ra; float maxa = pa + ra; float minb = pb - rb; float maxb = pb + rb; if (maxa < minb || maxb < mina) return false; float d0 = maxb - mina; float d1 = maxa - minb; d = (d0 < d1)? d0 : -d1; return true;}bool BoxBoxIntersect(Vector PA, Vector PB, float ea[3], float eb[3], Vector DA[3], Vector DB[3], Vector& MTD){ float l2[15]; float d[15]; Vector D[15]; if (!CalculateInterval(DA[0], PA, ea, DA, PB, eb, DB, d[0], l2[0], D[0])) return false; if (!CalculateInterval(DA[1], PA, ea, DA, PB, eb, DB, d[1], l2[1], D[1])) return false; if (!CalculateInterval(DA[2], PA, ea, DA, PB, eb, DB, d[2], l2[2], D[2])) return false; if (!CalculateInterval(DB[0], PA, ea, DA, PB, eb, DB, d[3], l2[3], D[3])) return false; if (!CalculateInterval(DB[1], PA, ea, DA, PB, eb, DB, d[4], l2[4], D[4])) return false; if (!CalculateInterval(DB[2], PA, ea, DA, PB, eb, DB, d[5], l2[4], D[5])) return false; if (!CalculateInterval(DA[0] ^ DB[0], PA, ea, DA, PB, eb, DB, d[6], l2[6], D[6])) return false; if (!CalculateInterval(DA[0] ^ DB[1], PA, ea, DA, PB, eb, DB, d[7], l2[7], D[7])) return false; if (!CalculateInterval(DA[0] ^ DB[2], PA, ea, DA, PB, eb, DB, d[8], l2[8], D[8])) return false; if (!CalculateInterval(DA[1] ^ DB[0], PA, ea, DA, PB, eb, DB, d[9], l2[9], D[9])) return false; if (!CalculateInterval(DA[1] ^ DB[1], PA, ea, DA, PB, eb, DB, d[10], l2[10], D[10])) return false; if (!CalculateInterval(DA[1] ^ DB[2], PA, ea, DA, PB, eb, DB, d[11], l2[11], D[11])) return false; if (!CalculateInterval(DA[2] ^ DB[0], PA, ea, DA, PB, eb, DB, d[12], l2[12], D[12])) return false; if (!CalculateInterval(DA[2] ^ DB[1], PA, ea, DA, PB, eb, DB, d[13], l2[13], D[13])) return false; if (!CalculateInterval(DA[2] ^ DB[2], PA, ea, DA, PB, eb, DB, d[14], l2[14], D[14])) return false; float minsep2 = -1; MTD = Vector(0, 0, 0); for(U32 i = 0; i < 15; i ++) { if(l2 <= degen_tolerance) continue; Vector Sep = D * (d / l2); float sep2 = (Sep * Sep); if(sep2 < minsep2 || minsep2 < 0.0f) { minsep2 = sep2; MTD = Sep; } } return true;}