nuclear@0: #ifndef _N3DMATH_H_ nuclear@0: #define _N3DMATH_H_ nuclear@0: nuclear@0: // - n3dmath.h - nuclear@0: // Nuc3D 2 Header File nuclear@0: // written by: John Tsiombikas (10 Sep 2002) nuclear@0: // Last Modification: 14 April 2002 nuclear@0: // --------------------------- nuclear@0: // Mathematical stuff nuclear@0: nuclear@0: #include nuclear@0: #include nuclear@0: nuclear@0: #ifdef NUC3D_VER_DIRECT3D nuclear@0: #include "d3d8.h" // Direct3D type definitions (D3DMATRIX) nuclear@0: #endif //NUC3D_VER_DIRECT3D nuclear@0: nuclear@0: // forward declarations nuclear@0: class Matrix4x4; nuclear@0: class Matrix3x3; nuclear@0: class Vector3; nuclear@0: class Vector2; nuclear@0: class Vector4; nuclear@0: class Quaternion; nuclear@0: nuclear@0: // mathematical constants nuclear@0: const float Pi = 3.1415926535897932f; nuclear@0: const float TwoPi = 6.2831853071795865f;// Pi * 2.0f; nuclear@0: const float HalfPi = 1.5707963267948965f; //Pi * 0.5f; nuclear@0: const float QuarterPi = 0.7853981633974483f; //Pi * 0.25f; nuclear@0: const float ThreeQuartersPi = 2.3561944901923450f; //QuarterPi * 3.0f; nuclear@0: nuclear@0: const float XSmallNumber = 1.e-8f; nuclear@0: const float SmallNumber = 1.e-4f; nuclear@0: nuclear@0: // basis vectors nuclear@0: #define VECTOR3_I (Vector3(1.0f, 0.0f, 0.0f)) nuclear@0: #define VECTOR3_J (Vector3(0.0f, 1.0f, 0.0f)) nuclear@0: #define VECTOR3_K (Vector3(0.0f, 0.0f, 1.0f)) nuclear@0: nuclear@0: #define VECTOR2_I (Vector2(1.0f, 0.0f)) nuclear@0: #define VECTOR2_J (Vector2(0.0f, 1.0f)) nuclear@0: nuclear@0: // angle conversion nuclear@0: #define DEGTORAD(a) (Pi * (a) / 180) nuclear@0: #define RADTODEG(a) ((a) * 180 / Pi) nuclear@0: nuclear@0: nuclear@0: nuclear@0: // ------------- Vector3 class ------------- nuclear@0: nuclear@0: #ifdef NUC3D_VER_DIRECT3D // if we are using Direct3D version nuclear@0: nuclear@0: class Vector3 : public D3DVECTOR { nuclear@0: public: nuclear@0: nuclear@0: #else // not D3D nuclear@0: nuclear@0: class Vector3 { nuclear@0: public: nuclear@0: float x, y, z; nuclear@0: nuclear@0: #endif //NUC3D_VER_DIRECT3D nuclear@0: nuclear@0: Vector3(); nuclear@0: Vector3(float x, float y, float z); nuclear@0: nuclear@0: inline float DotProduct(const Vector3 &vec) const; nuclear@0: inline Vector3 CrossProduct(const Vector3 &vec) const; nuclear@0: nuclear@0: inline Vector3 operator +(const Vector3 &vec) const; nuclear@0: inline Vector3 operator -(const Vector3 &vec) const; nuclear@0: inline Vector3 operator *(float scalar) const; nuclear@0: inline Vector3 operator /(float scalar) const; nuclear@0: inline void operator +=(const Vector3 &vec); nuclear@0: inline void operator -=(const Vector3 &vec); nuclear@0: inline void operator *=(float scalar); nuclear@0: inline void operator /=(float scalar); nuclear@0: inline Vector3 operator -() const; // unary minus for inversion nuclear@0: nuclear@0: inline bool operator >(const Vector3 &vec) const; nuclear@0: inline bool operator <(const Vector3 &vec) const; nuclear@0: inline bool operator >(float len) const; nuclear@0: inline bool operator <(float len) const; nuclear@0: inline bool operator ==(const Vector3 &vec) const; nuclear@0: inline bool operator ==(float len) const; nuclear@0: nuclear@0: inline operator Vector2() const; nuclear@0: inline operator Vector4() const; nuclear@0: nuclear@0: inline float Length() const; nuclear@0: inline float LengthSq() const; nuclear@0: nuclear@0: inline void Normalize(); nuclear@0: inline Vector3 Normalized() const; nuclear@0: nuclear@0: inline Vector3 Reflection(const Vector3 &normal) const; nuclear@0: Vector3 Refraction(const Vector3 &normal, float FromIOR, float ToIOR) const; nuclear@0: nuclear@0: void Transform(const Matrix4x4 &mat); // transform a vector using a transformation matrix nuclear@0: void Transform(const Quaternion &quat); // transform by a quaternion nuclear@0: nuclear@0: // Direct transformations on the vector nuclear@0: void Translate(float x, float y, float z); nuclear@0: void Rotate(float x, float y, float z); nuclear@0: void Rotate(const Vector3 &axis, float angle); nuclear@0: void Scale(float x, float y, float z); nuclear@0: nuclear@0: float &operator [](int index); nuclear@0: nuclear@0: friend std::ostream &operator <<(std::ostream &out, const Vector3 &vec); nuclear@0: }; nuclear@0: nuclear@0: inline float DotProduct(const Vector3 &vec1, const Vector3 &vec2); nuclear@0: inline Vector3 CrossProduct(const Vector3 &vec1, const Vector3 &vec2); nuclear@0: nuclear@0: ////////////////////// 4-dimensional vectors //////////////////////////// nuclear@0: class Vector4 { nuclear@0: public: nuclear@0: float x, y, z, w; nuclear@0: nuclear@0: Vector4(); nuclear@0: Vector4(const Vector4 &vec); nuclear@0: Vector4(const Vector3 &vec); // create from a 3 dimensional vector setting w=1 nuclear@0: Vector4(float x, float y, float z, float w); nuclear@0: nuclear@0: float DotProduct(const Vector4 &vec) const; nuclear@0: Vector4 CrossProduct(const Vector4 &vec1, const Vector4 &vec2) const; nuclear@0: nuclear@0: Vector4 operator +(const Vector4 &vec) const; nuclear@0: Vector4 operator -(const Vector4 &vec) const; nuclear@0: Vector4 operator *(float scalar) const; nuclear@0: Vector4 operator /(float scalar) const; nuclear@0: void operator +=(const Vector4 &vec); nuclear@0: void operator -=(const Vector4 &vec); nuclear@0: void operator *=(float scalar); nuclear@0: void operator /=(float scalar); nuclear@0: Vector4 operator -() const; // unary minus for inversion nuclear@0: nuclear@0: bool operator >(const Vector4 &vec) const; nuclear@0: bool operator <(const Vector4 &vec) const; nuclear@0: bool operator >(float len) const; nuclear@0: bool operator <(float len) const; nuclear@0: bool operator ==(const Vector4 &vec) const; nuclear@0: bool operator ==(float len) const; nuclear@0: nuclear@0: operator Vector3() const; nuclear@0: nuclear@0: float Length() const; nuclear@0: float LengthSq() const; nuclear@0: nuclear@0: void Normalize(); nuclear@0: Vector4 Normalized() const; nuclear@0: nuclear@0: void Transform(const Matrix4x4 &mat); // transform a vector using a transformation matrix nuclear@0: nuclear@0: // Direct transformations on the vector nuclear@0: void Translate(float x, float y, float z, float w); nuclear@0: void Rotate(float x, float y, float z); nuclear@0: void Rotate(const Vector3 &axis, float angle); nuclear@0: void Scale(float x, float y, float z, float w); nuclear@0: nuclear@0: float &operator [](int index); nuclear@0: nuclear@0: friend std::ostream &operator <<(std::ostream &out, const Vector3 &vec); nuclear@0: }; nuclear@0: nuclear@0: float DotProduct(const Vector4 &vec1, const Vector4 &vec2); nuclear@0: Vector4 CrossProduct(const Vector4 &vec1, const Vector4 &vec2, const Vector4 &vec3); nuclear@0: nuclear@0: /////////////////////////// nuclear@0: nuclear@0: class Vector2 { nuclear@0: public: nuclear@0: float x, y; nuclear@0: nuclear@0: Vector2(); nuclear@0: Vector2(const Vector2 &vec); nuclear@0: Vector2(float x, float y); nuclear@0: nuclear@0: float DotProduct(const Vector2 &vec) const; nuclear@0: //Vector2 CrossProduct(const Vector2 &vec) const; nuclear@0: nuclear@0: Vector2 operator +(const Vector2 &vec) const; nuclear@0: Vector2 operator -(const Vector2 &vec) const; nuclear@0: Vector2 operator *(float scalar) const; nuclear@0: Vector2 operator /(float scalar) const; nuclear@0: void operator +=(const Vector2 &vec); nuclear@0: void operator -=(const Vector2 &vec); nuclear@0: void operator *=(float scalar); nuclear@0: void operator /=(float scalar); nuclear@0: Vector2 operator -() const; // unary minus for inversion nuclear@0: nuclear@0: bool operator >(const Vector2 &vec) const; nuclear@0: bool operator <(const Vector2 &vec) const; nuclear@0: bool operator >(float len) const; nuclear@0: bool operator <(float len) const; nuclear@0: bool operator ==(const Vector2 &vec) const; nuclear@0: bool operator ==(float len) const; nuclear@0: nuclear@0: operator Vector3() const; nuclear@0: nuclear@0: float Length() const; nuclear@0: float LengthSq() const; nuclear@0: nuclear@0: void Normalize(); nuclear@0: Vector2 Normalized() const; nuclear@0: nuclear@0: Vector2 Reflection(const Vector2 &normal) const; nuclear@0: Vector2 Refraction(const Vector2 &normal, float FromIOR, float ToIOR) const; nuclear@0: nuclear@0: void Transform(const Matrix3x3 &mat); // transform a vector using a transformation matrix nuclear@0: nuclear@0: // Direct transformations on the vector nuclear@0: void Translate(float x, float y); nuclear@0: void Rotate(float angle); nuclear@0: void Scale(float x, float y); nuclear@0: nuclear@0: float &operator [](int index); nuclear@0: nuclear@0: friend std::ostream &operator <<(std::ostream &out, const Vector2 &vec); nuclear@0: }; nuclear@0: nuclear@0: float DotProduct(const Vector3 &vec1, const Vector3 &vec2); nuclear@0: nuclear@0: nuclear@0: struct Vector2i { nuclear@0: int x, y; nuclear@0: nuclear@0: Vector2i(int x=0, int y=0) {this->x = x; this->y = y;} nuclear@0: }; nuclear@0: nuclear@0: nuclear@0: ////////////////// Quaternion /////////////////////// nuclear@0: nuclear@0: class Quaternion { nuclear@0: public: nuclear@0: float s; nuclear@0: Vector3 v; nuclear@0: nuclear@0: Quaternion(); nuclear@0: Quaternion(float s, const Vector3 &v); nuclear@0: Quaternion(float s, float x, float y, float z); nuclear@0: nuclear@0: Quaternion operator +(const Quaternion &quat) const; nuclear@0: Quaternion operator -(const Quaternion &quat) const; nuclear@0: Quaternion operator -() const; nuclear@0: Quaternion operator *(const Quaternion &quat) const; nuclear@0: nuclear@0: void operator +=(const Quaternion &quat); nuclear@0: void operator -=(const Quaternion &quat); nuclear@0: void operator *=(const Quaternion &quat); nuclear@0: nuclear@0: void ResetIdentity(); nuclear@0: nuclear@0: Quaternion Conjugate() const; nuclear@0: nuclear@0: float Length() const; nuclear@0: float LengthSq() const; nuclear@0: nuclear@0: void Normalize(); nuclear@0: Quaternion Normalized() const; nuclear@0: nuclear@0: Quaternion Inverse() const; nuclear@0: nuclear@0: void SetRotation(const Vector3 &axis, float angle); nuclear@0: void Rotate(const Vector3 &axis, float angle); nuclear@0: nuclear@0: Matrix3x3 GetRotationMatrix() const; nuclear@0: }; nuclear@0: nuclear@0: nuclear@0: nuclear@0: ////////////////////////// Matrices ////////////////////////////// nuclear@0: nuclear@0: #ifdef NUC3D_VER_DIRECT3D // if we are using Direct3D version nuclear@0: nuclear@0: class Matrix4x4 : public D3DMATRIX { nuclear@0: public: nuclear@0: nuclear@0: #else // Software or OpenGL version nuclear@0: nuclear@0: class Matrix4x4 { nuclear@0: public: nuclear@0: float m[4][4]; nuclear@0: nuclear@0: #endif //NUC3D_VER_DIRECT3D nuclear@0: nuclear@0: Matrix4x4(); nuclear@0: Matrix4x4(const Matrix4x4 &mat); nuclear@0: Matrix4x4(const Matrix3x3 &mat); nuclear@0: Matrix4x4( float m00, float m01, float m02, float m03, nuclear@0: float m10, float m11, float m12, float m13, nuclear@0: float m20, float m21, float m22, float m23, nuclear@0: float m30, float m31, float m32, float m33 ); nuclear@0: nuclear@0: // basic operations on matrices nuclear@0: Matrix4x4 operator +(const Matrix4x4 &mat) const; nuclear@0: Matrix4x4 operator -(const Matrix4x4 &mat) const; nuclear@0: Matrix4x4 operator *(const Matrix4x4 &mat) const; nuclear@0: Matrix4x4 operator *(float scalar) const; nuclear@0: void operator +=(const Matrix4x4 &mat); nuclear@0: void operator -=(const Matrix4x4 &mat); nuclear@0: void operator *=(const Matrix4x4 &mat); nuclear@0: void operator *=(float scalar); nuclear@0: nuclear@0: void ResetIdentity(); nuclear@0: nuclear@0: // concatenate various transformation matrices with our current matrix nuclear@0: void Translate(float x, float y, float z); nuclear@0: void Rotate(float x, float y, float z); nuclear@0: void Rotate(const Vector3 &axis, float rads); nuclear@0: void Scale(float x, float y, float z); nuclear@0: nuclear@0: // set the matrix to a specific transformation matrix nuclear@0: void SetTranslation(float x, float y, float z); nuclear@0: void SetRotation(float x, float y, float z); nuclear@0: void SetRotation(const Vector3 &axis, float angle); nuclear@0: void SetScaling(float x, float y, float z); nuclear@0: nuclear@0: // row and column accessors nuclear@0: void SetColumnVector(const Vector4 &vec, int columnindex); nuclear@0: void SetRowVector(const Vector4 &vec, int rowindex); nuclear@0: Vector4 GetColumnVector(int columnindex) const; nuclear@0: Vector4 GetRowVector(int rowindex) const; nuclear@0: nuclear@0: // other operations on matrices nuclear@0: void Transpose(); nuclear@0: Matrix4x4 Transposed() const; nuclear@0: nuclear@0: float Determinant() const; nuclear@0: Matrix4x4 Adjoint() const; nuclear@0: Matrix4x4 Inverse() const; nuclear@0: }; nuclear@0: nuclear@0: nuclear@0: ////////////////// Matrix3x3 ////////////////// nuclear@0: class Matrix3x3 { nuclear@0: public: nuclear@0: float m[3][3]; nuclear@0: nuclear@0: Matrix3x3(); nuclear@0: Matrix3x3(const Matrix3x3 &mat); nuclear@0: Matrix3x3( float m00, float m01, float m02, nuclear@0: float m10, float m11, float m12, nuclear@0: float m20, float m21, float m22 ); nuclear@0: nuclear@0: // basic operations on matrices nuclear@0: Matrix3x3 operator +(const Matrix3x3 &mat) const; nuclear@0: Matrix3x3 operator -(const Matrix3x3 &mat) const; nuclear@0: Matrix3x3 operator *(const Matrix3x3 &mat) const; nuclear@0: Matrix3x3 operator *(float scalar) const; nuclear@0: void operator +=(const Matrix3x3 &mat); nuclear@0: void operator -=(const Matrix3x3 &mat); nuclear@0: void operator *=(const Matrix3x3 &mat); nuclear@0: void operator *=(float scalar); nuclear@0: nuclear@0: void ResetIdentity(); nuclear@0: nuclear@0: // concatenate various transformation matrices with our current matrix nuclear@0: void Translate(float x, float y); nuclear@0: void Rotate(float angle); nuclear@0: void Scale(float x, float y); nuclear@0: nuclear@0: // set the matrix to a specific transformation matrix nuclear@0: void SetTranslation(float x, float y); nuclear@0: void SetRotation(float angle); nuclear@0: void SetScaling(float x, float y); nuclear@0: nuclear@0: // row and column accessors nuclear@0: void SetColumnVector(const Vector3 &vec, int columnindex); nuclear@0: void SetRowVector(const Vector3 &vec, int rowindex); nuclear@0: Vector3 GetColumnVector(int columnindex) const; nuclear@0: Vector3 GetRowVector(int rowindex) const; nuclear@0: nuclear@0: // other operations on matrices nuclear@0: void Transpose(); nuclear@0: Matrix3x3 Transposed() const; nuclear@0: nuclear@0: void OrthoNormalize(); nuclear@0: Matrix3x3 OrthoNormalized(); nuclear@0: nuclear@0: //float Determinant() const; // NYI nuclear@0: //Matrix3x3 Adjoint() const; nuclear@0: //Matrix3x3 Inverse() const; nuclear@0: }; nuclear@0: nuclear@0: ///////////////// ray ///////////////// nuclear@0: nuclear@0: class Ray { nuclear@0: public: nuclear@0: Vector3 Origin; nuclear@0: Vector3 Direction; nuclear@0: float Energy; nuclear@0: float CurrentIOR; nuclear@0: nuclear@0: Ray(); nuclear@0: Ray(const Vector3 &origin, const Vector3 &direction); nuclear@0: }; nuclear@0: nuclear@0: // a coordinate system basis nuclear@0: class Base { nuclear@0: public: nuclear@0: Vector3 i, j, k; nuclear@0: nuclear@0: Base(); nuclear@0: Base(const Vector3 &i, const Vector3 &j, const Vector3 &k); nuclear@0: Base(const Vector3 &dir, bool LeftHanded=true); nuclear@0: nuclear@0: void Rotate(float x, float y, float z); nuclear@0: void Rotate(const Vector3 &axis, float angle); nuclear@0: void Rotate(const Matrix4x4 &mat); nuclear@0: void Rotate(const Quaternion &quat); nuclear@0: nuclear@0: Matrix3x3 CreateRotationMatrix() const; nuclear@0: }; nuclear@0: nuclear@0: nuclear@0: nuclear@0: float frand(float range); nuclear@0: nuclear@0: nuclear@0: #include "n3dmath.inl" nuclear@0: nuclear@0: #endif // _N3DMATH_H_