404 lines
8.1 KiB
C++
404 lines
8.1 KiB
C++
#pragma once
|
|
#include "head.h"
|
|
#define pi 3.14159265358979323846
|
|
#define deg(a) a*(180/pi)
|
|
#define CHECK_VALID( _v ) 0
|
|
|
|
class Vector
|
|
{
|
|
public:
|
|
float x, y, z;
|
|
Vector(void);
|
|
Vector(float X, float Y, float Z);
|
|
void Init(float ix = 0.0f, float iy = 0.0f, float iz = 0.0f);
|
|
bool IsValid() const;
|
|
float operator[](int i) const;
|
|
float& operator[](int i);
|
|
inline void Zero();
|
|
bool operator==(const Vector& v) const;
|
|
bool operator!=(const Vector& v) const;
|
|
__forceinline Vector& operator+=(const Vector& v);
|
|
__forceinline Vector& operator-=(const Vector& v);
|
|
__forceinline Vector& operator*=(const Vector& v);
|
|
__forceinline Vector& operator*=(float s);
|
|
__forceinline Vector& operator/=(const Vector& v);
|
|
Vector Angle(Vector* up);
|
|
__forceinline Vector& operator/=(float s);
|
|
__forceinline Vector& operator+=(float fl);
|
|
__forceinline Vector& operator-=(float fl);
|
|
inline float Length() const;
|
|
inline Vector Cross(Vector a) { return Vector(y * a.z - z * a.y, z * a.x - x * a.z, x * a.y - y * a.x); }
|
|
|
|
__forceinline float LengthSqr(void) const
|
|
{
|
|
CHECK_VALID(*this);
|
|
return (this->x * this->x + this->y * this->y + this->z * this->z);
|
|
}
|
|
|
|
bool IsZero(float tolerance = 0.01f) const
|
|
{
|
|
return (x > -tolerance && x < tolerance&&
|
|
y > -tolerance && y < tolerance&&
|
|
z > -tolerance && z < tolerance);
|
|
}
|
|
|
|
float NormalizeInPlace();
|
|
Vector Normalize();
|
|
__forceinline float DistToSqr(const Vector& vOther) const;
|
|
__forceinline float Dist(const Vector& vOther) const;
|
|
float Dot(const Vector& vOther) const;
|
|
float Dot(const float* fOther) const;
|
|
float Length2D(void) const;
|
|
float Length2DSqr(void) const;
|
|
Vector& operator=(const Vector& vOther);
|
|
Vector operator-(const Vector& v) const;
|
|
Vector operator+(const Vector& v) const;
|
|
Vector operator*(const Vector& v) const;
|
|
Vector operator/(const Vector& v) const;
|
|
Vector operator*(float fl) const;
|
|
Vector operator/(float fl) const;
|
|
// Base address...
|
|
float* Base();
|
|
float const* Base() const;
|
|
};
|
|
|
|
//===============================================
|
|
inline void Vector::Init(float ix, float iy, float iz)
|
|
{
|
|
x = ix;
|
|
y = iy;
|
|
z = iz;
|
|
CHECK_VALID(*this);
|
|
}
|
|
|
|
inline bool Vector::IsValid() const
|
|
{
|
|
return x == 0.f && y == 0.f && z == 0.f;
|
|
}
|
|
|
|
//===============================================
|
|
inline Vector::Vector(float X, float Y, float Z)
|
|
{
|
|
x = X;
|
|
y = Y;
|
|
z = Z;
|
|
CHECK_VALID(*this);
|
|
}
|
|
|
|
//===============================================
|
|
inline Vector::Vector(void)
|
|
{ }
|
|
|
|
//===============================================
|
|
inline void Vector::Zero()
|
|
{
|
|
x = y = z = 0.0f;
|
|
}
|
|
|
|
//===============================================
|
|
inline void VectorClear(Vector& a)
|
|
{
|
|
a.x = a.y = a.z = 0.0f;
|
|
}
|
|
|
|
//===============================================
|
|
inline Vector& Vector::operator=(const Vector& vOther)
|
|
{
|
|
CHECK_VALID(vOther);
|
|
x = vOther.x;
|
|
y = vOther.y;
|
|
z = vOther.z;
|
|
return *this;
|
|
}
|
|
|
|
//===============================================
|
|
inline float& Vector::operator[](int i)
|
|
{
|
|
return ((float*)this)[i];
|
|
}
|
|
|
|
//===============================================
|
|
inline float Vector::operator[](int i) const
|
|
{
|
|
return ((float*)this)[i];
|
|
}
|
|
|
|
//===============================================
|
|
inline bool Vector::operator==(const Vector& src) const
|
|
{
|
|
CHECK_VALID(src);
|
|
CHECK_VALID(*this);
|
|
return (src.x == x) && (src.y == y) && (src.z == z);
|
|
}
|
|
|
|
//===============================================
|
|
inline bool Vector::operator!=(const Vector& src) const
|
|
{
|
|
CHECK_VALID(src);
|
|
CHECK_VALID(*this);
|
|
return (src.x != x) || (src.y != y) || (src.z != z);
|
|
}
|
|
|
|
//===============================================
|
|
__forceinline void VectorCopy(const Vector& src, Vector& dst)
|
|
{
|
|
CHECK_VALID(src);
|
|
dst.x = src.x;
|
|
dst.y = src.y;
|
|
dst.z = src.z;
|
|
}
|
|
|
|
//===============================================
|
|
__forceinline Vector& Vector::operator+=(const Vector& v)
|
|
{
|
|
CHECK_VALID(*this);
|
|
CHECK_VALID(v);
|
|
x += v.x;
|
|
y += v.y;
|
|
z += v.z;
|
|
return *this;
|
|
}
|
|
|
|
//===============================================
|
|
__forceinline Vector& Vector::operator-=(const Vector& v)
|
|
{
|
|
CHECK_VALID(*this);
|
|
CHECK_VALID(v);
|
|
x -= v.x;
|
|
y -= v.y;
|
|
z -= v.z;
|
|
return *this;
|
|
}
|
|
|
|
//===============================================
|
|
__forceinline Vector& Vector::operator*=(float fl)
|
|
{
|
|
x *= fl;
|
|
y *= fl;
|
|
z *= fl;
|
|
CHECK_VALID(*this);
|
|
return *this;
|
|
}
|
|
|
|
//===============================================
|
|
__forceinline Vector& Vector::operator*=(const Vector& v)
|
|
{
|
|
CHECK_VALID(v);
|
|
x *= v.x;
|
|
y *= v.y;
|
|
z *= v.z;
|
|
CHECK_VALID(*this);
|
|
return *this;
|
|
}
|
|
|
|
//===============================================
|
|
__forceinline Vector& Vector::operator+=(float fl)
|
|
{
|
|
x += fl;
|
|
y += fl;
|
|
z += fl;
|
|
CHECK_VALID(*this);
|
|
return *this;
|
|
}
|
|
|
|
//===============================================
|
|
__forceinline Vector& Vector::operator-=(float fl)
|
|
{
|
|
x -= fl;
|
|
y -= fl;
|
|
z -= fl;
|
|
CHECK_VALID(*this);
|
|
return *this;
|
|
}
|
|
|
|
//===============================================
|
|
__forceinline Vector& Vector::operator/=(float fl)
|
|
{
|
|
float oofl = 1.0f / fl;
|
|
x *= oofl;
|
|
y *= oofl;
|
|
z *= oofl;
|
|
CHECK_VALID(*this);
|
|
return *this;
|
|
}
|
|
|
|
//===============================================
|
|
__forceinline Vector& Vector::operator/=(const Vector& v)
|
|
{
|
|
CHECK_VALID(v);
|
|
x /= v.x;
|
|
y /= v.y;
|
|
z /= v.z;
|
|
CHECK_VALID(*this);
|
|
return *this;
|
|
}
|
|
//===============================================
|
|
inline float Vector::Length2DSqr(void) const
|
|
{
|
|
return (x * x + y * y);
|
|
}
|
|
|
|
//===============================================
|
|
inline Vector CrossProduct(const Vector& a, const Vector& b)
|
|
{
|
|
return Vector(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x);
|
|
}
|
|
|
|
//===============================================
|
|
float Vector::DistToSqr(const Vector& vOther) const
|
|
{
|
|
Vector delta;
|
|
|
|
delta.x = x - vOther.x;
|
|
delta.y = y - vOther.y;
|
|
delta.z = z - vOther.z;
|
|
|
|
return delta.LengthSqr();
|
|
}
|
|
|
|
float Vector::Dist(const Vector& vOther) const
|
|
{
|
|
Vector delta;
|
|
|
|
delta.x = x - vOther.x;
|
|
delta.y = y - vOther.y;
|
|
delta.z = z - vOther.z;
|
|
|
|
return delta.Length();
|
|
}
|
|
|
|
inline Vector Vector::Normalize()
|
|
{
|
|
Vector vector;
|
|
float length = this->Length();
|
|
|
|
if (length != 0)
|
|
{
|
|
vector.x = x / length;
|
|
vector.y = y / length;
|
|
vector.z = z / length;
|
|
}
|
|
else
|
|
vector.x = vector.y = 0.0f;
|
|
vector.z = 1.0f;
|
|
|
|
return vector;
|
|
}
|
|
|
|
//===============================================
|
|
inline float Vector::NormalizeInPlace()
|
|
{
|
|
Vector& v = *this;
|
|
|
|
float iradius = 1.f / (this->Length() + 1.192092896e-07F); //FLT_EPSILON
|
|
|
|
v.x *= iradius;
|
|
v.y *= iradius;
|
|
v.z *= iradius;
|
|
}
|
|
|
|
//===============================================
|
|
inline float VectorNormalize(Vector& v)
|
|
{
|
|
float l = v.Length();
|
|
if (l != 0.0f)
|
|
{
|
|
v /= l;
|
|
}
|
|
else
|
|
{
|
|
v.x = v.y = 0.0f;
|
|
v.z = 1.0f;
|
|
}
|
|
return l;
|
|
}
|
|
|
|
//===============================================
|
|
FORCEINLINE float VectorNormalize(float* v)
|
|
{
|
|
return VectorNormalize(*(reinterpret_cast<Vector*>(v)));
|
|
}
|
|
|
|
//===============================================
|
|
inline Vector Vector::operator+(const Vector& v) const
|
|
{
|
|
Vector res;
|
|
res.x = x + v.x;
|
|
res.y = y + v.y;
|
|
res.z = z + v.z;
|
|
return res;
|
|
}
|
|
|
|
//===============================================
|
|
inline Vector Vector::operator-(const Vector& v) const
|
|
{
|
|
Vector res;
|
|
res.x = x - v.x;
|
|
res.y = y - v.y;
|
|
res.z = z - v.z;
|
|
return res;
|
|
}
|
|
|
|
//===============================================
|
|
inline Vector Vector::operator*(float fl) const
|
|
{
|
|
Vector res;
|
|
res.x = x * fl;
|
|
res.y = y * fl;
|
|
res.z = z * fl;
|
|
return res;
|
|
}
|
|
|
|
//===============================================
|
|
inline Vector Vector::operator*(const Vector& v) const
|
|
{
|
|
Vector res;
|
|
res.x = x * v.x;
|
|
res.y = y * v.y;
|
|
res.z = z * v.z;
|
|
return res;
|
|
}
|
|
|
|
//===============================================
|
|
inline Vector Vector::operator/(float fl) const
|
|
{
|
|
Vector res;
|
|
res.x = x / fl;
|
|
res.y = y / fl;
|
|
res.z = z / fl;
|
|
return res;
|
|
}
|
|
|
|
//===============================================
|
|
inline Vector Vector::operator/(const Vector& v) const
|
|
{
|
|
Vector res;
|
|
res.x = x / v.x;
|
|
res.y = y / v.y;
|
|
res.z = z / v.z;
|
|
return res;
|
|
}
|
|
|
|
inline float Vector::Dot(const Vector& vOther) const
|
|
{
|
|
const Vector& a = *this;
|
|
|
|
return (a.x * vOther.x + a.y * vOther.y + a.z * vOther.z);
|
|
}
|
|
|
|
inline float Vector::Dot(const float* fOther) const
|
|
{
|
|
const Vector& a = *this;
|
|
|
|
return (a.x * fOther[0] + a.y * fOther[1] + a.z * fOther[2]);
|
|
}
|
|
|
|
inline float* Vector::Base()
|
|
{
|
|
return (float*)this;
|
|
}
|
|
|
|
inline float const* Vector::Base() const
|
|
{
|
|
return (float const*)this;
|
|
} |