/* Vector.cpp Written by Matthew Fisher The Vec3 struct represents a 3-dimensional (x, y, z) real ordered triplet. It is used constantly everywhere. The Vec4 struct represents a 4-dimensional (x, y, z, w) real ordered triplet. It is used mostly for matrix multiplication. Most of the Vec3 and Vec4 functions and overloaded operators are self-explanitory and are not commented. */ #ifndef __SPACEVECTOR_CPP #define __SPACEVECTOR_CPP #include "Vector.h" Vec3::Vec3() { } Vec3::Vec3(float _x, float _y, float _z) { x = _x; y = _y; z = _z; } Vec3::Vec3(const Vec3 &V) { x = V.x; y = V.y; z = V.z; } Vec3::Vec3(const RGBColor &c) { x = c.r / 255.0f; y = c.g / 255.0f; z = c.b / 255.0f; } __forceinline Vec3& Vec3::operator = (const Vec3 &V) { x = V.x; y = V.y; z = V.z; return *this; } __forceinline void Vec3::StdRandomVector() { x = float(rand()) / RAND_MAX * 2.0f - 1.0f; y = float(rand()) / RAND_MAX * 2.0f - 1.0f; z = float(rand()) / RAND_MAX * 2.0f - 1.0f; } __forceinline void Vec3::StdRandomNormal() { StdRandomVector(); Normalize(); } __forceinline float Vec3::Length() { return sqrtf(x*x+y*y+z*z); } __forceinline float Vec3::LengthSq() { return x*x+y*y+z*z; } __forceinline void Vec3::Normalize() { float Len = Length(); //MyAssert(Len != 0.0f); x /= Len; y /= Len; z /= Len; } __forceinline Vec3::operator D3DXVECTOR3() const { D3DXVECTOR3 V(x, y, z); return V; } __forceinline void Vec3Cross(Vec3 &Target, const Vec3 &Left, const Vec3 &Right) { Vec3 Temp; Temp.x = Left.y * Right.z - Left.z * Right.y; Temp.y = Left.z * Right.x - Left.x * Right.z; Temp.z = Left.x * Right.y - Left.y * Right.x; Target = Temp; } __forceinline void Vec3TriNormal(Vec3 &Target, const Vec3 &V1, const Vec3 &V2, const Vec3 &V3) { Vec3 Diff1 = V2 - V1; Vec3 Diff2 = V3 - V1; Vec3Cross(Target, Diff1, Diff2); Target.Normalize(); } __forceinline float Vec3Dot(const Vec3 &Left, const Vec3 &Right) { return (Left.x * Right.x + Left.y * Right.y + Left.z * Right.z); } __forceinline void Vec3Lerp(Vec3 &Target, const Vec3 &Left, const Vec3 &Right, float s) { Target = Left + s * (Right - Left); } __forceinline void Vec3Maximize(Vec3 &Target, const Vec3 &Left, const Vec3 &Right) { Vec3 Target2 = Right; if(Left.x > Right.x) Target2.x = Left.x; if(Left.y > Right.y) Target2.y = Left.y; if(Left.z > Right.z) Target2.z = Left.z; Target = Target2; } __forceinline void Vec3Minimize(Vec3 &Target, const Vec3 &Left, const Vec3 &Right) { Vec3 Target2 = Right; if(Left.x < Right.x) Target2.x = Left.x; if(Left.y < Right.y) Target2.y = Left.y; if(Left.z < Right.z) Target2.z = Left.z; Target = Target2; } __forceinline Vec3 operator * (const Vec3 &Left, float Right) { Vec3 Return; Return.x = Left.x * Right; Return.y = Left.y * Right; Return.z = Left.z * Right; return Return; } __forceinline Vec3 operator * (float Right, const Vec3 &Left) { Vec3 Return; Return.x = Left.x * Right; Return.y = Left.y * Right; Return.z = Left.z * Right; return Return; } __forceinline Vec3 operator / (const Vec3 &Left, float Right) { Vec3 Return; Return.x = Left.x / Right; Return.y = Left.y / Right; Return.z = Left.z / Right; return Return; } __forceinline Vec3 operator + (const Vec3 &Left, const Vec3 &Right) { Vec3 Return; Return.x = Left.x + Right.x; Return.y = Left.y + Right.y; Return.z = Left.z + Right.z; return Return; } __forceinline Vec3 operator - (const Vec3 &Left, const Vec3 &Right) { Vec3 Return; Return.x = Left.x - Right.x; Return.y = Left.y - Right.y; Return.z = Left.z - Right.z; return Return; } __forceinline Vec3& Vec3::operator *= (float Right) { x *= Right; y *= Right; z *= Right; return *this; } __forceinline Vec3& Vec3::operator /= (float Right) { x /= Right; y /= Right; z /= Right; return *this; } __forceinline Vec3& Vec3::operator += (const Vec3 &Right) { x += Right.x; y += Right.y; z += Right.z; return *this; } __forceinline Vec3& Vec3::operator -= (const Vec3 &Right) { x -= Right.x; y -= Right.y; z -= Right.z; return *this; } Vec3 Vec3::ComponentSquare() { //return Vec3(x*x, y*y, z*z); return Vec3(fabsf(x), fabsf(y), fabsf(z)); } __forceinline Vec3 operator - (const Vec3 &V) { Vec3 Result; Result.x = -V.x; Result.y = -V.y; Result.z = -V.z; return Result; } Vec4::Vec4() { } Vec4::Vec4(float _x, float _y, float _z, float _w) { x = _x; y = _y; z = _z; w = _w; } Vec4::Vec4(const Vec4 &V) { x = V.x; y = V.y; z = V.z; w = V.w; } Vec4& Vec4::operator = (const Vec4 &V) { x = V.x; y = V.y; z = V.z; w = V.w; return *this; } float Vec4::Length() { return sqrtf(x*x+y*y+z*z+w*w); } float Vec4::LengthSq() { return x*x+y*y+z*z+w*w; } void Vec4::Normalize() { float Len = Length(); x /= Len; y /= Len; z /= Len; w /= Len; } float Vec4Dot(const Vec4 &Left, const Vec4 &Right) { return (Left.x * Right.x + Left.y * Right.y + Left.z * Right.z + Left.w * Right.w); } void Vec4Lerp(Vec4 &Target, const Vec4 &Left, const Vec4 &Right, float s) { Target = Left + s * (Right - Left); } void Vec4Maximize(Vec4 &Target, const Vec4 &Left, const Vec4 &Right) { Target = Right; if(Left.x > Right.x) Target.x = Left.x; if(Left.y > Right.y) Target.y = Left.y; if(Left.z > Right.z) Target.z = Left.z; if(Left.w > Right.w) Target.w = Left.w; } void Vec4Minimize(Vec4 &Target, const Vec4 &Left, const Vec4 &Right) { Target = Right; if(Left.x < Right.x) Target.x = Left.x; if(Left.y < Right.y) Target.y = Left.y; if(Left.z < Right.z) Target.z = Left.z; if(Left.w < Right.w) Target.w = Left.w; } Vec4 operator * (const Vec4 &Left, float Right) { Vec4 Return; Return.x = Left.x * Right; Return.y = Left.y * Right; Return.z = Left.z * Right; Return.w = Left.w * Right; return Return; } Vec4 operator * (float Right, const Vec4 &Left) { Vec4 Return; Return.x = Left.x * Right; Return.y = Left.y * Right; Return.z = Left.z * Right; Return.w = Left.w * Right; return Return; } Vec4 operator / (const Vec4 &Left, float Right) { Vec4 Return; Return.x = Left.x / Right; Return.y = Left.y / Right; Return.z = Left.z / Right; Return.w = Left.w / Right; return Return; } Vec4 operator + (const Vec4 &Left, const Vec4 &Right) { Vec4 Return; Return.x = Left.x + Right.x; Return.y = Left.y + Right.y; Return.z = Left.z + Right.z; Return.w = Left.w + Right.w; return Return; } Vec4 operator - (const Vec4 &Left, const Vec4 &Right) { Vec4 Return; Return.x = Left.x - Right.x; Return.y = Left.y - Right.y; Return.z = Left.z - Right.z; Return.w = Left.w - Right.w; return Return; } Vec4& Vec4::operator *= (float Right) { x *= Right; y *= Right; z *= Right; w *= Right; return *this; } Vec4& Vec4::operator /= (float Right) { x /= Right; y /= Right; z /= Right; w /= Right; return *this; } Vec4& Vec4::operator += (const Vec4 &Right) { x += Right.x; y += Right.y; z += Right.z; w += Right.w; return *this; } Vec4& Vec4::operator -= (const Vec4 &Right) { x -= Right.x; y -= Right.y; z -= Right.z; w -= Right.w; return *this; } __forceinline Vec4 operator - (const Vec4 &V) { Vec4 Result; Result.x = -V.x; Result.y = -V.y; Result.z = -V.z; Result.w = -V.w; return Result; } istream& operator >> (istream &is, Vec3 &v) { is >> v.x >> v.y >> v.z; return is; } ostream& operator << (ostream &os, const Vec3 &v) { os << v.x << ' ' << v.y << ' ' << v.z; return os; } ostream& operator << (ostream &os, const Vec4 &v) { os << v.x << ' ' << v.y << ' ' << v.z << ' ' << v.w; return os; } float AngleBetween(const Vec3 &Left, const Vec3 &Right) { //the cosine of the angle between two vectors is the dot product of the two vectors after normalization Vec3 V1 = Left, V2 = Right; V1.Normalize(); V2.Normalize(); float Dot = Vec3Dot(V1, V2); if(fabsf(Dot) >= 1.0f) Dot = 0.999f; return acosf(Dot); } #endif