/////////////////////////////////////////////////////////////////////////////// // // ## ###### // ###### ### Based on: // ## ############### // ########## # # # Shark 3D Engine (www.shark3d.com) // ######## // ######### # # # Copyright (c) 1996-2001 Spinor GmbH. // ## ########## // ## // /////////////////////////////////////////////////////////////////////////////// // // G A M E.O.N.E - LOW LEVEL LIB V1.0 // Copyright (C) 2001 LEVEL ONE ENTERTAINMENT, // Licensed under the terms of LGPL. //:--------------------------------------------------------------------------- //:Description // // LOW LEVEL 3D VEC2 UTIL HEADERFILE // //:--------------------------------------------------------------------------- #ifndef _LL3D_VEC2_H #define _LL3D_VEC2_H #include "ll3d_math.h" namespace ll3d { template struct CVec2; template struct CMat2x2; typedef CVec2 CVec2f; typedef const CVec2f CVec2f_c; typedef CVec2f &CVec2f_r; typedef const CVec2f &CVec2f_cr; typedef CVec2 CVec2d; typedef const CVec2d CVec2d_c; typedef CVec2d &CVec2d_r; typedef const CVec2d &CVec2d_cr; typedef CMat2x2 CMat2x2f; typedef const CMat2x2f CMat2x2f_c; typedef CMat2x2f &CMat2x2f_r; typedef const CMat2x2f &CMat2x2f_cr; typedef CMat2x2 CMat2x2d; typedef const CMat2x2d CMat2x2d_c; typedef CMat2x2d &CMat2x2d_r; typedef const CMat2x2d &CMat2x2d_cr; /* * 2D Vector */ template struct CVec2 { T m_u, m_v; CVec2(); // Set each component to the same value. // Also allows to use 0 as null vector CVec2(T s); CVec2(T u, T v); CVec2(const CVec2 &v); CVec2 &operator=(const CVec2 &v); CVec2 &operator+() const; CVec2 &operator-() const; CVec2 &operator+=(const CVec2 &v); CVec2 &operator-=(const CVec2 &v); CVec2 &operator*=(T s); CVec2 &operator/=(T s); T GetSqLen() const; T GetLen() const; CVec2 GetNormalized() const; CVec2 GetNormalized(T Len) const; CVec2 GetDual() const;// Contract with the Levicita tensor. bool IsFinite() const;// Are both components finite? CVec2 GetAbsComp() const;// Return for each component the absolute value. T GetMinComp() const;// Return the smallest component. T GetMaxComp() const;// Return the largest component. T GetSumAbsComp() const;// Return the sum of the absolute value of all components. T GetMaxAbsComp() const;// Return the maximum of the absolute value of all components. CVec2 &SetCompToMin(const CVec2 &v); CVec2 &SetCompToMax(const CVec2 &v); CVec2 operator+(const CVec2 &v) const; CVec2 operator-(const CVec2 &v) const; CVec2 operator*(T s) const; CVec2 operator/(T s) const; T operator*(const CVec2 &v) const; T operator^(const CVec2 &v) const;// Area spanned by two vectors. // Linear interpolation between two vectors. // Returns (*this) + (v - (*this)) * Frac. CVec2 InterpLinear(const CVec2 &v, T Frac) const; CVec2 operator*(const CMat2x2 &m) const; bool operator==(const CVec2 &v) const; bool operator!=(const CVec2 &v) const; int CompareComp(const CVec2 &v) const; }; /* * 2D Matrix */ template struct CMat2x2 { T m_uu, m_uv; T m_vu, m_vv; CMat2x2(); // Multiple of unitary matrix. // Also allows to use 0 as null matrix and 1 as unity matrix. CMat2x2(T s); CMat2x2(T uu, T uv, T vu, T vv); CMat2x2(const CMat2x2 &m); CMat2x2 &operator=(const CMat2x2 &m); CMat2x2 operator+() const; CMat2x2 operator-() const; CMat2x2 &operator+=(const CMat2x2 &m); CMat2x2 &operator-=(const CMat2x2 &m); CMat2x2 &operator*=(const CMat2x2 &m); CMat2x2 &operator*=(T s); CMat2x2 &operator/=(T s); CMat2x2 GetTransposed() const; CMat2x2 GetInv() const; T GetSqLen() const; T GetLen() const; T GetDet() const; T GetTrace() const; bool IsFinite() const;// Are all components finite? CVec2 GetRowU() const { return CVec2(m_uu, m_uv); }// Return m_uu, m_uv as vector. CVec2 GetRowV() const { return CVec2(m_vu, m_vv); }// Return m_vu, m_vv as vector. CVec2 GetColU() const { return CVec2(m_uu, m_vu); }// Return m_uu, m_vu as vector. CVec2 GetColV() const { return CVec2(m_uv, m_vv); }// Return m_uv, m_vv as vector. CMat2x2 GetCompAbs() const;// Return componentwis absolute value. CMat2x2 GetScaledRows(const CVec2 &v) const; CMat2x2 GetScaledCols(const CVec2 &v) const; static CMat2x2 ByTensorProd( const CVec2 &v1, const CVec2 &v2); static CMat2x2 ByDual(T Scal); static CMat2x2 ByDiag(const CVec2 &v); // Diagonal matrix static CMat2x2 ByRows( const CVec2 &u, const CVec2 &v); static CMat2x2 ByCols( const CVec2 &u, const CVec2 &v); static CMat2x2 ByAngleUnit(T Angle); static CMat2x2 ByAngleLen(T Angle, T Len); CMat2x2 operator+(const CMat2x2 &m) const; CMat2x2 operator-(const CMat2x2 &m) const; CMat2x2 operator*(T s) const; CMat2x2 operator/(T s) const; CMat2x2 operator*(const CMat2x2 &m) const; CVec2 operator*(const CVec2 &v) const; bool operator==(const CMat2x2 &m) const; bool operator!=(const CMat2x2 &m) const; }; /* * Implementation */ template inline CVec2::CVec2() { } template inline CVec2::CVec2(T s) { m_u = m_v = s; } template inline CVec2::CVec2(T u, T v) { m_u = u; m_v = v; } template inline CVec2::CVec2(const CVec2 &v) { m_u = v.m_u; m_v = v.m_v; } template inline CVec2 &CVec2::operator=(const CVec2 &v) { m_u = v.m_u, m_v = v.m_v; return *this; } template inline CVec2 &CVec2::operator+() const { return *this; } template inline CVec2 &CVec2::operator-() const { return CVec2(- m_u, - m_v); } template inline CVec2 &CVec2::operator+=(const CVec2 &v) { return *this = *this + v; } template inline CVec2 &CVec2::operator-=(const CVec2 &v) { return *this = *this - v; } template inline CVec2 &CVec2::operator*=(T s) { return *this = *this * s; } template inline CVec2 &CVec2::operator/=(T s) { return *this = *this / s; } template inline T CVec2::GetSqLen() const { return m_u * m_u + m_v * m_v; } template inline T CVec2::GetLen() const { return Sqrt(m_u * m_u + m_v * m_v); } template CVec2 CVec2::GetNormalized() const { T f = 1 / Sqrt(m_u * m_u + m_v * m_v); return CVec2(f * m_u, f * m_v); } template CVec2 CVec2::GetNormalized(T Len) const { T f = Len / Sqrt(m_u * m_u + m_v * m_v); return CVec2(f * m_u, f * m_v); } template inline CVec2 CVec2::GetDual() const { return CVec2(- m_v, m_u); } template bool CVec2::IsFinite() const { return IsFinite(m_u) && IsFinite(m_v); } template CVec2 CVec2::GetAbsComp() const { return CVec2(Abs(m_u), Abs(m_v)); } template T CVec2::GetMinComp() const { return Min(m_u, m_v); } template T CVec2::GetMaxComp() const { return Max(m_u, m_v); } template T CVec2::GetSumAbsComp() const { return Abs(m_u) + Abs(m_v); } template T CVec2::GetMaxAbsComp() const { return Max(Abs(m_u), Abs(m_v)); } template CVec2 &CVec2::SetCompToMin(const CVec2 &v) { if(v.m_u < m_u) m_u = v.m_u; if(v.m_v < m_v) m_v = v.m_v; return *this; } template CVec2 &CVec2::SetCompToMax(const CVec2 &v) { if(v.m_u > m_u) m_u = v.m_u; if(v.m_v > m_v) m_v = v.m_v; return *this; } template inline CVec2 CVec2::operator+(const CVec2 &v) const { return CVec2(m_u + v.m_u, m_v + v.m_v); } template inline CVec2 CVec2::operator-(const CVec2 &v) const { return CVec2(m_u - v.m_u, m_v - v.m_v); } template inline CVec2 CVec2::operator*(T s) const { return CVec2(m_u * s, m_v * s); } template inline CVec2 CVec2::operator/(T s) const { return CVec2(m_u / s, m_v / s); } template inline T CVec2::operator*(const CVec2 &v) const { return m_u * v.m_u + m_v * v.m_v; } template inline T CVec2::operator^(const CVec2 &v) const { return m_u * v.m_v - m_v * v.m_u; } template CVec2 CVec2::InterpLinear(const CVec2 &v, T Frac) const { return *this + (v - *this) * Frac; } template CVec2 CVec2::operator*(const CMat2x2 &m) const { return CVec2( m_u * m.m_uu + m_v * m.m_vu, m_u * m.m_uv + m_v * m.m_vv); } template inline bool CVec2::operator==(const CVec2 &v) const { return m_u == v.m_u && m_v == v.m_v; } template inline bool CVec2::operator!=(const CVec2 &v) const { return m_u != v.m_u || m_v != v.m_v; } template int CVec2::CompareComp(const CVec2 &v) const { if(m_u < v.m_u) return -1; else if(m_u > v.m_u) return 1; else if(m_v < v.m_v) return -1; else if(m_v > v.m_v) return 1; else return 0; } /* * Implementation CMat2x2 */ template inline CMat2x2::CMat2x2() { } template inline CMat2x2::CMat2x2(T s) { m_uu = s; m_uv = 0; m_vu = 0; m_vv = s; } template inline CMat2x2::CMat2x2(T uu, T uv, T vu, T vv) { m_uu = uu; m_uv = uv; m_vu = vu; m_vv = vv; } template inline CMat2x2::CMat2x2(const CMat2x2 &m) { m_uu = m.m_uu; m_uv = m.m_uv; m_vu = m.m_vu; m_vv = m.m_vv; } template inline CMat2x2 &CMat2x2::operator=(const CMat2x2 &m) { m_uu = m.m_uu; m_uv = m.m_uv; m_vu = m.m_vu; m_vv = m.m_vv; return *this; } template inline CMat2x2 CMat2x2::operator+() const { return *this; } template inline CMat2x2 CMat2x2::operator-() const { return CMat2x2(- m_uu, - m_uv, - m_vu, - m_vv); } template inline CMat2x2 &CMat2x2::operator+=(const CMat2x2 &m) { return *this = *this + m; } template inline CMat2x2 &CMat2x2::operator-=(const CMat2x2 &m) { return *this = *this - m; } template inline CMat2x2 &CMat2x2::operator*=(const CMat2x2 &m) { return *this = *this * m; } template inline CMat2x2 &CMat2x2::operator*=(T s) { return *this = *this * s; } template inline CMat2x2 &CMat2x2::operator/=(T s) { return *this = *this / s; } template inline CMat2x2 CMat2x2::GetTransposed() const { return CMat2x2(m_uu, m_vu, m_uv, m_vv); } template CMat2x2 CMat2x2::GetInv() const { T f = 1.0f / (m_uu * m_vv - m_uv * m_vu); return CMat2x2(f * m_vv, - f * m_vu, - f * m_uv, f * m_uu); } template T CMat2x2::GetSqLen() const { return (m_uu * m_uu + m_uv * m_uv) + (m_vu * m_vu + m_vv * m_vv); } template T CMat2x2::GetLen() const { return Sqrt(GetSqLen()); } template T CMat2x2::GetDet() const { return m_uu * m_vv - m_uv * m_vu; } template inline T CMat2x2::GetTrace() const { return m_uu + m_vv; } template bool CMat2x2::IsFinite() const { return IsFinite(m_uu) && IsFinite(m_uv) && IsFinite(m_vu) && IsFinite(m_vv); }; template CMat2x2 CMat2x2::GetCompAbs() const { return CMat2x2( Abs(m_uu), Abs(m_uv), Abs(m_vu), Abs(m_vv)); } template CMat2x2 CMat2x2::GetScaledRows(const CVec2 &v) const { return CMat2x2( v.m_u * m_uu, v.m_u * m_uv, v.m_v * m_vu, v.m_v * m_vv); } template CMat2x2 CMat2x2::GetScaledCols(const CVec2 &v) const { return CMat2x2( v.m_u * m_uu, v.m_v * m_uv, v.m_u * m_vu, v.m_v * m_vv); } template CMat2x2 CMat2x2::ByTensorProd( const CVec2 &v1, const CVec2 &v2) { return CMat2x2( v1.m_u * v2.m_u, v1.m_u * v2.m_v, v1.m_v * v2.m_u, v1.m_v * v2.m_v); } template inline CMat2x2 ByDual(T Scal) { return CMat2x2(0, Scal, - Scal, 0); } template inline CMat2x2 CMat2x2::ByDiag(const CVec2 &v) { return CMat2x2(v.m_u, 0.0f, 0.0f, v.m_v); } template inline CMat2x2 CMat2x2::ByRows( const CVec2 &u, const CVec2 &v) { return CMat2x2(u.m_u, u.m_v, v.m_u, v.m_v); } template inline CMat2x2 CMat2x2::ByCols( const CVec2 &u, const CVec2 &v) { return CMat2x2(u.m_u, v.m_u, u.m_v, v.m_v); } template CMat2x2 CMat2x2::ByAngleUnit(T Angle) { T ls = Sin(Angle); T lc = Cos(Angle); return CMat2x2(lc, -ls, ls, lc); } template CMat2x2 CMat2x2::ByAngleLen(T Angle, T Len) { T ls = Len * Sin(Angle); T lc = Len * Cos(Angle); return CMat2x2(lc, -ls, ls, lc); } template inline CMat2x2 CMat2x2::operator+(const CMat2x2 &m) const { return CMat2x2( m_uu + m.m_uu, m_uv + m.m_uv, m_vu + m.m_vu, m_vv + m.m_vv); } template inline CMat2x2 CMat2x2::operator-(const CMat2x2 &m) const { return CMat2x2( m_uu - m.m_uu, m_uv - m.m_uv, m_vu - m.m_vu, m_vv - m.m_vv); } template inline CMat2x2 CMat2x2::operator*(T s) const { return CMat2x2( m_uu * s, m_uv * s, m_vu * s, m_vv * s); } template inline CMat2x2 CMat2x2::operator/(T s) const { return CMat2x2( m_uu / s, m_uv / s, m_vu / s, m_vv / s); } template CMat2x2 CMat2x2::operator*(const CMat2x2 &m) const { return CMat2x2( m_uu * m.m_uu + m_uv * m.m_vu, m_uu * m.m_uv + m_uv * m.m_vv, m_vu * m.m_uu + m_vv * m.m_vu, m_vu * m.m_uv + m_vv * m.m_vv); } template CVec2 CMat2x2::operator*(const CVec2 &v) const { return CVec2( m_uu * v.m_u + m_uv * v.m_v, m_vu * v.m_u + m_vv * v.m_v); } }//namespace ll2d #endif //_LL3D_VEC2_H