/*
Vector.h
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_H
#define __SPACEVECTOR_H

struct Vec3 {
    //Initalization
    __forceinline Vec3();
    __forceinline Vec3(const Vec3 &V);
    __forceinline Vec3(float _x, float _y, float _z);
    __forceinline Vec3(const RGBColor &c);

    //Assignment
    __forceinline Vec3& operator = (const Vec3 &V);
    __forceinline void StdRandomVector();       //sets the current vector to be a point randomly chosen in the unit cube; (-1, 1) in all dimensions.
    __forceinline void StdRandomNormal();       //sets the current vector to be a point randomly chosen on the unit sphere.

    //Overloaded operators
    __forceinline Vec3& operator *= (float Right);
    __forceinline Vec3& operator /= (float Right);
    __forceinline Vec3& operator += (const Vec3 &Right);
    __forceinline Vec3& operator -= (const Vec3 &Right);

    //Normalization
    __forceinline void Normalize();         //normalizes the current vector
    __forceinline Vec3 ComponentSquare();

    //Accessors
    __forceinline float Length();
    __forceinline float LengthSq();         //returns the squared length of the vector

    __forceinline operator D3DXVECTOR3() const;

    float x, y, z;  //Local data
};

struct Vec4 {
    //Initalization
    __forceinline Vec4();
    __forceinline Vec4(const Vec4 &V);
    __forceinline Vec4(float _x, float _y, float _z, float _w);

    //Assignment
    __forceinline Vec4& operator = (const Vec4 &V);

    //Overloaded operators
    __forceinline Vec4& operator *= (float Right);
    __forceinline Vec4& operator /= (float Right);
    __forceinline Vec4& operator += (const Vec4 &Right);
    __forceinline Vec4& operator -= (const Vec4 &Right);

    //Normalization
    __forceinline void Normalize();

    //Accessors
    __forceinline float Length();
    __forceinline float LengthSq();

    float x, y, z, w;   //Local data
};

//Functions associated with Vec3
__forceinline void Vec3TriNormal(Vec3 &Target, const Vec3 &V1, const Vec3 &V2, const Vec3 &V3);
__forceinline void Vec3Cross(Vec3 &Target, const Vec3 &Left, const Vec3 &Right);
__forceinline float Vec3Dot(const Vec3 &Left, const Vec3 &Right);
__forceinline void Vec3Lerp(Vec3 &Target, const Vec3 &Left, const Vec3 &Right, float s);    //linear interpolation between Left and Right by s; if s = 0, Left is returned, if s = 1, Right is returned.
__forceinline void Vec3Maximize(Vec3 &Target, const Vec3 &Left, const Vec3 &Right);     //returns the largest components in Left and Right in Max.
__forceinline void Vec3Minimize(Vec3 &Target, const Vec3 &Left, const Vec3 &Right);     //returns the smallest components in Left and Right in Max.

//Vec3 overloaded operators
__forceinline Vec3 operator * (const Vec3 &Left, float Right);
__forceinline Vec3 operator * (float Left, const Vec3 &Right);
__forceinline Vec3 operator / (const Vec3 &Left, float Right);
__forceinline Vec3 operator + (const Vec3 &Left, const Vec3 &Right);
__forceinline Vec3 operator - (const Vec3 &Left, const Vec3 &Right);
__forceinline Vec3 operator - (const Vec3 &V);


__forceinline float Vec4Dot(const Vec4 &Left, const Vec4 &Right);
__forceinline void Vec4Lerp(Vec4 &Target, const Vec4 &Left, const Vec4 &Right, float s);
__forceinline void Vec4Maximize(Vec4 &Target, const Vec4 &Left, const Vec4 &Right);
__forceinline void Vec4Minimize(Vec4 &Target, const Vec4 &Left, const Vec4 &Right);

//Vec4 overloaded operators
__forceinline Vec4 operator * (const Vec4 &Left, float Right);
__forceinline Vec4 operator * (float Left, const Vec4 &Right);
__forceinline Vec4 operator / (const Vec4 &Left, float Right);
__forceinline Vec4 operator + (const Vec4 &Left, const Vec4 &Right);
__forceinline Vec4 operator - (const Vec4 &Left, const Vec4 &Right);
__forceinline Vec4 operator - (const Vec4 &V);

__forceinline istream& operator >> (istream &os, Vec3 &v);              //inputs the vector's x, y, and z components
__forceinline ostream& operator << (ostream &os, const Vec3 &v);        //outputs the vector's x, y, and z components
__forceinline ostream& operator << (ostream &os, const Vec4 &v);        //outputs the vector's x, y, z, and w components

__forceinline float AngleBetween(const Vec3 &Left, const Vec3 &Right);  //returns the angle between the two vectors

#include "Vector.cpp"

#endif

Top