diff --git a/etk/math/Matrix4.cpp b/etk/math/Matrix4.cpp index a630946..a26d695 100644 --- a/etk/math/Matrix4.cpp +++ b/etk/math/Matrix4.cpp @@ -12,19 +12,13 @@ #include -void etk::Matrix4::Rotate(etk::Vector3D vect, float angleRad) +void etk::Matrix4::Rotate(const vec3& vect, float angleRad) { etk::Matrix4 tmpMat = etk::matRotate(vect, angleRad); *this *= tmpMat; } -void etk::Matrix4::Rotate(etk::Vector3D& vect, float angleRad) -{ - etk::Matrix4 tmpMat = etk::matRotate(vect, angleRad); - *this *= tmpMat; -} - -void etk::Matrix4::Translate(etk::Vector3D& vect) +void etk::Matrix4::Translate(const vec3& vect) { etk::Matrix4 tmpMat = etk::matTranslate(vect); *this *= tmpMat; @@ -82,19 +76,19 @@ etk::Matrix4 etk::matOrtho(float left, float right, float bottom, float top, flo return tmp; } -etk::Matrix4 etk::matTranslate(etk::Vector3D vect) +etk::Matrix4 etk::matTranslate(vec3 vect) { etk::Matrix4 tmp; // set translation : - tmp.m_mat[3] = vect.x; - tmp.m_mat[7] = vect.y; - tmp.m_mat[11] = vect.z; + tmp.m_mat[3] = vect.x(); + tmp.m_mat[7] = vect.y(); + tmp.m_mat[11] = vect.z(); //TK_INFO("Translate :"); //etk::matrix::Display(tmp); return tmp; } -etk::Matrix4 etk::matScale(etk::Vector3D vect) +etk::Matrix4 etk::matScale(vec3 vect) { etk::Matrix4 tmp; tmp.Scale(vect); @@ -109,59 +103,59 @@ etk::Matrix4 etk::matScale(etk::Vector3D vect) return tmp; } -etk::Matrix4 etk::matRotate(etk::Vector3D vect, float angleRad) +etk::Matrix4 etk::matRotate(vec3 vect, float angleRad) { etk::Matrix4 tmp; float cosVal = cos(angleRad); float sinVal = sin(angleRad); float invVal = 1.0-cosVal; // set rotation : - tmp.m_mat[0] = vect.x * vect.x * invVal + cosVal; - tmp.m_mat[1] = vect.x * vect.y * invVal - vect.z * sinVal; - tmp.m_mat[2] = vect.x * vect.z * invVal + vect.y * sinVal; + tmp.m_mat[0] = vect.x() * vect.x() * invVal + cosVal; + tmp.m_mat[1] = vect.x() * vect.y() * invVal - vect.z() * sinVal; + tmp.m_mat[2] = vect.x() * vect.z() * invVal + vect.y() * sinVal; - tmp.m_mat[4] = vect.y * vect.x * invVal + vect.z * sinVal; - tmp.m_mat[5] = vect.y * vect.y * invVal + cosVal; - tmp.m_mat[6] = vect.y * vect.z * invVal - vect.x * sinVal; + tmp.m_mat[4] = vect.y() * vect.x() * invVal + vect.z() * sinVal; + tmp.m_mat[5] = vect.y() * vect.y() * invVal + cosVal; + tmp.m_mat[6] = vect.y() * vect.z() * invVal - vect.x() * sinVal; - tmp.m_mat[8] = vect.z * vect.x * invVal - vect.y * sinVal; - tmp.m_mat[9] = vect.z * vect.y * invVal + vect.x * sinVal; - tmp.m_mat[10] = vect.z * vect.z * invVal + cosVal; + tmp.m_mat[8] = vect.z() * vect.x() * invVal - vect.y() * sinVal; + tmp.m_mat[9] = vect.z() * vect.y() * invVal + vect.x() * sinVal; + tmp.m_mat[10] = vect.z() * vect.z() * invVal + cosVal; return tmp; } -etk::Matrix4 etk::matRotate2(etk::Vector3D vect) +etk::Matrix4 etk::matRotate2(vec3 vect) { - return matLookAt(vect, etk::Vector3D(0,0,0), etk::Vector3D(0,1,0)); + return matLookAt(vect, vec3(0,0,0), vec3(0,1,0)); } -etk::Matrix4 etk::matLookAt(etk::Vector3D eye, - etk::Vector3D center, - etk::Vector3D up) +etk::Matrix4 etk::matLookAt(vec3 eye, + vec3 center, + vec3 up) { etk::Matrix4 tmp; - etk::Vector3D forward = center - eye; - forward.Normalize(); - etk::Vector3D side = forward.CrossProduct(up); - side.Normalize(); + vec3 forward = center - eye; + forward.normalize(); + vec3 side = forward.cross(up); + side.normalize(); - etk::Vector3D plane_up = side.CrossProduct(forward); - plane_up.Normalize(); + vec3 plane_up = side.cross(forward); + plane_up.normalize(); - tmp.m_mat[0] = side.x; - tmp.m_mat[1] = plane_up.x; - tmp.m_mat[2] = -forward.x; + tmp.m_mat[0] = side.x(); + tmp.m_mat[1] = plane_up.x(); + tmp.m_mat[2] = -forward.x(); tmp.m_mat[3] = 0.0f; - tmp.m_mat[4] = side.y; - tmp.m_mat[5] = plane_up.y; - tmp.m_mat[6] = -forward.y; + tmp.m_mat[4] = side.y(); + tmp.m_mat[5] = plane_up.y(); + tmp.m_mat[6] = -forward.y(); tmp.m_mat[7] = 0.0f; - tmp.m_mat[8] = side.z; - tmp.m_mat[9] = plane_up.z; - tmp.m_mat[10] = -forward.z; + tmp.m_mat[8] = side.z(); + tmp.m_mat[9] = plane_up.z(); + tmp.m_mat[10] = -forward.z(); tmp.m_mat[11] = 0.0f; tmp.m_mat[12] = 0.0f; diff --git a/etk/math/Matrix4.h b/etk/math/Matrix4.h index 0ea8418..ac54f14 100644 --- a/etk/math/Matrix4.h +++ b/etk/math/Matrix4.h @@ -179,9 +179,9 @@ namespace etk } vec3 operator*(const vec3& point) const { - return vec3( m_mat[0]*point.x + m_mat[1]*point.y + m_mat[2]*point.z + m_mat[3], - m_mat[4]*point.x + m_mat[5]*point.y + m_mat[6]*point.z + m_mat[7], - m_mat[8]*point.x + m_mat[9]*point.y + m_mat[10]*point.z + m_mat[11] ); + return vec3( m_mat[0]*point.x() + m_mat[1]*point.y() + m_mat[2]*point.z() + m_mat[3], + m_mat[4]*point.x() + m_mat[5]*point.y() + m_mat[6]*point.z() + m_mat[7], + m_mat[8]*point.x() + m_mat[9]*point.y() + m_mat[10]*point.z() + m_mat[11] ); } /***************************************************** * other basic function : @@ -214,7 +214,7 @@ namespace etk } void Scale(const vec3& p) { - Scale(p.x, p.y, p.z); + Scale(p.x(), p.y(), p.z()); } void Scale(float sx, float sy, float sz) { @@ -222,59 +222,17 @@ namespace etk m_mat[4] *= sx; m_mat[5] *= sy; m_mat[6] *= sz; m_mat[8] *= sx; m_mat[9] *= sy; m_mat[10] *= sz; } - #if 0 - /** - * @brief Sets a rotation matrix around the X axis. - * @param[in] angleRad Angle to rotate in radian. - */ - void RotateX(float angleRad) - { - float Cos = cosf(angleRad); - float Sin = sinf(angleRad); - Identity(); - m_mat[5] = m_mat[10] = Cos; - m_mat[9] = -Sin; - m_mat[6] = Sin; - } - /** - * @brief Sets a rotation matrix around the Y axis. - * @param[in] angleRad Angle to rotate in radian. - */ - void RotateY(float angleRad) - { - float Cos = cosf(angleRad); - float Sin = sinf(angleRad); - Identity(); - m_mat[0] = m_mat[10] = Cos; - m_mat[8] = Sin; - m_mat[2] = -Sin; - } - /** - * @brief Sets a rotation matrix around the Z axis. - * @param[in] angleRad Angle to rotate in radian. - */ - void RotateZ(float angleRad) - { - float Cos = cosf(angle); - float Sin = sinf(angle); - Identity(); - m_mat[0] = m_mat[9] = Cos; - m_mat[4] = -Sin; - m_mat[1] = Sin; - } -#endif /** * @brief Makes a rotation matrix about an arbitrary axis. * @param[in] vect vector to apply the angle. * @param[in] angleRad angle to apply. */ - void Rotate(etk::Vector3D& vect, float angleRad=0.0); - void Rotate(etk::Vector3D vect, float angleRad=0.0); + void Rotate(const vec3& vect, float angleRad=0.0); /** * @brief Makes a translation of the matrix * @param[in] vect Translation to apply. */ - void Translate(etk::Vector3D& vect); + void Translate(const vec3& vect); /** * @brief Computes a cofactor. Used for matrix inversion. * @param[in] row Id of raw. @@ -297,13 +255,13 @@ namespace etk Matrix4 matFrustum(float xmin, float xmax, float ymin, float ymax, float zNear, float zFar); Matrix4 matPerspective(float foxy, float aspect, float zNear, float zFar); Matrix4 matOrtho(float left, float right, float bottom, float top, float nearVal, float farVal); - Matrix4 matTranslate(etk::Vector3D vect); - Matrix4 matScale(etk::Vector3D vect); - Matrix4 matRotate(etk::Vector3D vect, float angleRad=0.0); - Matrix4 matRotate2(etk::Vector3D vect); - Matrix4 matLookAt(etk::Vector3D eye, - etk::Vector3D center, - etk::Vector3D up); + Matrix4 matTranslate(vec3 vect); + Matrix4 matScale(vec3 vect); + Matrix4 matRotate(vec3 vect, float angleRad=0.0); + Matrix4 matRotate2(vec3 vect); + Matrix4 matLookAt(vec3 eye, + vec3 center, + vec3 up); /** * @brief Debug operator To display the curent element in a Human redeable information */ diff --git a/etk/math/Vector2D.cpp b/etk/math/Vector2D.cpp index 160267b..a4d03e6 100644 --- a/etk/math/Vector2D.cpp +++ b/etk/math/Vector2D.cpp @@ -11,9 +11,9 @@ etk::CCout& etk::operator <<(etk::CCout &os, const etk::Vector2D obj) { os << "("; - os << obj.x; + os << obj.x(); os << ","; - os << obj.y; + os << obj.y(); os << ")"; return os; } @@ -21,9 +21,29 @@ etk::CCout& etk::operator <<(etk::CCout &os, const etk::Vector2D obj) etk::CCout& etk::operator <<(etk::CCout &os, const etk::Vector2D obj) { os << "("; - os << obj.x; + os << obj.x(); os << ","; - os << obj.y; + os << obj.y(); + os << ")"; + return os; +} + +etk::CCout& etk::operator <<(etk::CCout &os, const etk::Vector2D obj) +{ + os << "("; + os << obj.x(); + os << ","; + os << obj.y(); + os << ")"; + return os; +} + +etk::CCout& etk::operator <<(etk::CCout &os, const etk::Vector2D obj) +{ + os << "("; + os << obj.x(); + os << ","; + os << obj.y(); os << ")"; return os; } diff --git a/etk/math/Vector2D.h b/etk/math/Vector2D.h index 1748850..20ea3ea 100644 --- a/etk/math/Vector2D.h +++ b/etk/math/Vector2D.h @@ -11,6 +11,7 @@ #include #include +#include #include namespace etk @@ -18,164 +19,126 @@ namespace etk template class Vector2D { public: - T x; - T y; + T m_floats[2]; public: /***************************************************** * Constructor *****************************************************/ - Vector2D(T _x=0, T _y=0) : x(_x), y(_y) { }; - Vector2D(const Vector2D& obj) : x((T)obj.x), y((T)obj.y) { }; - Vector2D(const Vector2D& obj) : x((T)obj.x), y((T)obj.y) { }; - Vector2D(const Vector2D& obj) : x((T)obj.x), y((T)obj.y) { }; + Vector2D(void) { }; // do nothing ==> better for optimisation + Vector2D(T _x, T _y) { m_floats[0] = _x; m_floats[1] = _y; }; + Vector2D(const Vector2D& obj) { m_floats[0] = (T)obj.x(); m_floats[1] = (T)obj.y(); }; + Vector2D(const Vector2D& obj) { m_floats[0] = (T)obj.x(); m_floats[1] = (T)obj.y(); }; + Vector2D(const Vector2D& obj) { m_floats[0] = (T)obj.x(); m_floats[1] = (T)obj.y(); }; ~Vector2D(void) { }; /***************************************************** * = assigment *****************************************************/ const Vector2D& operator= (const Vector2D& obj ) { - x = obj.x; - y = obj.y; + m_floats[0] = obj.m_floats[0]; + m_floats[1] = obj.m_floats[1]; return *this; } const Vector2D& operator= (const T val ) { - x = val; - y = val; + m_floats[0] = val; + m_floats[1] = val; return *this; } /***************************************************** * == operator *****************************************************/ bool operator== (const Vector2D& obj) const { - if ((T)obj.x == x && (T)obj.y == y) { - return true; - } - return false; + return ( (T)obj.m_floats[0] == m_floats[0] + && (T)obj.m_floats[1] == m_floats[1]); } /***************************************************** * != operator *****************************************************/ bool operator!= (const Vector2D& obj) const { - if ((T)obj.x == x && (T)obj.y == y) { - return false; - } - return true; + return ( (T)obj.m_floats[0] != m_floats[0] + || (T)obj.m_floats[1] != m_floats[1]); } /***************************************************** * += operator *****************************************************/ const Vector2D& operator+= (const Vector2D& obj) { - x += obj.x; - y += obj.y; + m_floats[0] += obj.m_floats[0]; + m_floats[1] += obj.m_floats[1]; return *this; } const Vector2D& operator+= (const T val) { - x += val; - y += val; + m_floats[0] += val; + m_floats[1] += val; return *this; } /***************************************************** * + operator *****************************************************/ Vector2D operator+ (const Vector2D& obj) { - Vector2D tmpp(x,y); - tmpp.x += obj.x; - tmpp.y += obj.y; + Vector2D tmpp(m_floats[0],m_floats[1]); + tmpp.m_floats[0] += obj.m_floats[0]; + tmpp.m_floats[1] += obj.m_floats[1]; return tmpp; } Vector2D operator+ (const T val) { - Vector2D tmpp(x,y); - tmpp.x += val; - tmpp.y += val; + Vector2D tmpp(m_floats[0],m_floats[1]); + tmpp.m_floats[0] += val; + tmpp.m_floats[1] += val; return tmpp; } /***************************************************** * -= operator *****************************************************/ const Vector2D& operator-= (const Vector2D& obj) { - x -= obj.x; - y -= obj.y; + m_floats[0] -= obj.m_floats[0]; + m_floats[1] -= obj.m_floats[1]; return *this; } const Vector2D& operator-= (const T val) { - x -= val; - y -= val; + m_floats[0] -= val; + m_floats[1] -= val; return *this; } /***************************************************** * - operator *****************************************************/ Vector2D operator- (const Vector2D& obj) { - Vector2D tmpp(x,y); - tmpp.x -= obj.x; - tmpp.y -= obj.y; + Vector2D tmpp(m_floats[0],m_floats[1]); + tmpp.m_floats[0] -= obj.m_floats[0]; + tmpp.m_floats[1] -= obj.m_floats[1]; return tmpp; } Vector2D operator- (const T val) { - Vector2D tmpp(x,y); - tmpp.x -= val; - tmpp.y -= val; - return tmpp; - } - /***************************************************** - * /= operator - *****************************************************/ - const Vector2D& operator/= (const Vector2D& obj) { - if (obj.x!=0) { - x /= obj.x; - } - if (obj.y!=0) { - y /= obj.y; - } - return *this; - } - const Vector2D& operator/= (const T val) { - if (val != 0) { - x /= val; - y /= val; - } - return *this; - } - /***************************************************** - * / operator - *****************************************************/ - Vector2D operator/ (const Vector2D& obj) { - Vector2D tmpp(x,y); - tmpp.x /= (T)obj.x; - tmpp.y /= (T)obj.y; - return tmpp; - } - Vector2D operator/ (const T val) { - Vector2D tmpp(x,y); - tmpp.x /= val; - tmpp.y /= val; + Vector2D tmpp(m_floats[0],m_floats[1]); + tmpp.m_floats[0] -= val; + tmpp.m_floats[1] -= val; return tmpp; } /***************************************************** * *= operator *****************************************************/ const Vector2D& operator*= (const Vector2D& obj) { - x *= obj.x; - y *= obj.y; + m_floats[0] *= obj.m_floats[0]; + m_floats[1] *= obj.m_floats[1]; return *this; } const Vector2D& operator*= (const T val) { - x *= val; - y *= val; + m_floats[0] *= val; + m_floats[1] *= val; return *this; } /***************************************************** * * operator *****************************************************/ Vector2D operator* (const Vector2D& obj) { - Vector2D tmpp(x,y); - tmpp.x *= obj.x; - tmpp.y *= obj.y; + Vector2D tmpp(m_floats[0],m_floats[1]); + tmpp.m_floats[0] *= obj.m_floats[0]; + tmpp.m_floats[1] *= obj.m_floats[1]; return tmpp; } Vector2D operator* (const T val) { - Vector2D tmpp(x,y); - tmpp.x *= val; - tmpp.y *= val; + Vector2D tmpp(m_floats[0],m_floats[1]); + tmpp.m_floats[0] *= val; + tmpp.m_floats[1] *= val; return tmpp; } /***************************************************** @@ -183,8 +146,8 @@ namespace etk *****************************************************/ Vector2D& operator++() // prefix { - ++x; - ++y; + ++m_floats[0]; + ++m_floats[1]; return *this; } Vector2D operator++(int unused) // postfix @@ -198,8 +161,8 @@ namespace etk *****************************************************/ Vector2D& operator--() // prefix { - --x; - --y; + --m_floats[0]; + --m_floats[1]; return *this; } @@ -211,97 +174,175 @@ namespace etk } /** - * @brief Set the vector at (0,0) + * @brief Return the dot product + * @param v The other vector in the dot product */ - void Zero(void) + btScalar dot(const Vector2D& v) const { - x=0; - y=0; - }; - /** - * @brief Set the vector at (1,1) - */ - void One(void) - { - x=0; - y=0; - }; + return m_floats[0] * v.m_floats[0] + + m_floats[1] * v.m_floats[1]; + } /** - * @brief normalize the curent vector + * @brief Return the length of the vector squared */ - void Normalize(void) + btScalar length2(void) const { - float length=GetLength(); - if( length==1 - || length==0) { - return; - } - float scalefactor = 1.0f/length; - x *= scalefactor; - y *= scalefactor; - }; + return dot(*this); + } /** - * @brief Get the normalized vector - * @return a new vector normalized + * @brief Return the length of the vector */ - Vector2D GetNormalized(void) const + btScalar length(void) const { - Vector2D tmp(*this); - tmp.Normalize(); - return tmp; - }; + return btSqrt(length2()); + } /** - * @brief Get the size of the vector - * @return the float value + * @brief Return the distance squared between the ends of this and another vector + * This is symantically treating the vector like a point */ - float GetLength(void) const + btScalar distance2(const btVector3& v) const { - return (float)sqrt((x*x)+(y*y)); - }; + return (v - *this).length2(); + } /** - * @brief Get the square size of the vector - * @return flat value + * @brief Return the distance between the ends of this and another vector + * This is symantically treating the vector like a point */ - float GetSquaredLength(void) const + btScalar distance(const btVector3& v) const { - return (float)(x*x)+(y*y); - }; + return (v - *this).length(); + } /** - * @brief Linar intermolation of the curent Vector - * @param[in] input - * @param[in] factor - * @return the interpolate vector + * @brief Normalize this vector + * x^2 + y^2 + z^2 = 1 */ - Vector2D LinearInterpolate(const Vector2D & input, float factor) const + Vector3D& normalize(void) { - return (*this)*(1.0f-factor) + input*factor; - }; + return *this /= length(); + } /** - * @brief Quadratic intermolation of the curent Vector - * @param[in] v1 - * @param[in] v2 - * @param[in] factor - * @return the interpolate vector + * @brief Return a normalized version of this vector */ - Vector2D QuadraticInterpolate(const Vector2D & v2, const Vector2D & v3, float factor) const + Vector2D normalized(void) const { - return (*this)*(1.0f-factor)*(1.0f-factor) + 2*v2*factor*(1.0f-factor) + v3*factor*factor; - }; + return *this / length(); + } + + /** + * @brief Return a vector will the absolute values of each element + */ + Vector2D absolute(void) const + { + return Vector2D( abs(m_floats[0]), + abs(m_floats[1])); + } + + /** + * @brief Return the axis with the smallest value + * Note return values are 0,1,2 for x, y, or z + */ + int32_t minAxis(void) const + { + return m_floats[0] < m_floats[1] ? 0 : 1; + } + + /** + * @brief Return the axis with the largest value + * Note return values are 0,1,2 for x, y, or z + */ + int32_t maxAxis(void) const + { + return m_floats[0] < m_floats[1] ? 1 : 0; + } + + int32_t furthestAxis(void) const + { + return absolute().minAxis(); + } + + int32_t closestAxis(void) const + { + return absolute().maxAxis(); + } + + /** + * @brief Return the x value + */ + const T& getX() const { return m_floats[0]; } + /** + * @brief Return the y value + */ + const T& getY() const { return m_floats[1]; } + /** + * @brief Set the x value + */ + void setX(T _x) { m_floats[0] = _x;}; + /** + * @brief Set the y value + */ + void setY(T _y) { m_floats[1] = _y;}; + /** + * @brief Return the x value + */ + const T& x() const { return m_floats[0]; } + /** + * @brief Return the y value + */ + const T& y() const { return m_floats[1]; } + + operator T *() { return &m_floats[0]; } + operator const T *() const { return &m_floats[0]; } + + /** + * @brief Set each element to the max of the current values and the values of another btVector3 + * @param other The other btVector3 to compare with + */ + void setMax(const Vector2D& other) + { + btSetMax(m_floats[0], other.m_floats[0]); + btSetMax(m_floats[1], other.m_floats[1]); + } + + /** + * @brief Set each element to the min of the current values and the values of another btVector3 + * @param other The other btVector3 to compare with + */ + void setMin(const Vector2D& other) + { + btSetMin(m_floats[0], other.m_floats[0]); + btSetMin(m_floats[1], other.m_floats[1]); + } + + void setValue(const T& _x, const T& _y) + { + m_floats[0]=_x; + m_floats[1]=_y; + } + + void setZero(void) + { + setValue(0,0); + } + + bool isZero(void) const + { + return m_floats[0] == 0 && m_floats[1] == 0; + } + }; /** * @brief Debug operator To display the curent element in a Human redeable information */ etk::CCout& operator <<(etk::CCout &os, const etk::Vector2D obj); - /** - * @brief Debug operator To display the curent element in a Human redeable information - */ etk::CCout& operator <<(etk::CCout &os, const etk::Vector2D obj); + etk::CCout& operator <<(etk::CCout &os, const etk::Vector2D obj); + etk::CCout& operator <<(etk::CCout &os, const etk::Vector2D obj); }; diff --git a/etk/math/Vector3D.cpp b/etk/math/Vector3D.cpp index bd1e29d..40e5b94 100644 --- a/etk/math/Vector3D.cpp +++ b/etk/math/Vector3D.cpp @@ -11,23 +11,47 @@ etk::CCout& etk::operator <<(etk::CCout &os, const etk::Vector3D obj) { os << "("; - os << obj.x; + os << obj.x(); os << ","; - os << obj.y; + os << obj.y(); os << ","; - os << obj.z; + os << obj.z(); os << ")"; return os; } -etk::CCout& etk::operator <<(etk::CCout &os, const etk::Vector3D obj) +etk::CCout& etk::operator <<(etk::CCout &os, const btVector3 obj) { os << "("; - os << obj.x; + os << obj.x(); os << ","; - os << obj.y; + os << obj.y(); os << ","; - os << obj.z; + os << obj.z(); + os << ")"; + return os; +} + +etk::CCout& etk::operator <<(etk::CCout &os, const etk::Vector3D obj) +{ + os << "("; + os << obj.x(); + os << ","; + os << obj.y(); + os << ","; + os << obj.z(); + os << ")"; + return os; +} + +etk::CCout& etk::operator <<(etk::CCout &os, const etk::Vector3D obj) +{ + os << "("; + os << obj.x(); + os << ","; + os << obj.y(); + os << ","; + os << obj.z(); os << ")"; return os; } diff --git a/etk/math/Vector3D.h b/etk/math/Vector3D.h index e24b865..433b993 100644 --- a/etk/math/Vector3D.h +++ b/etk/math/Vector3D.h @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include namespace etk @@ -20,415 +22,395 @@ namespace etk template class Vector3D { public: - T x; - T y; - T z; + T m_floats[4]; public: - /***************************************************** - * Constructor - *****************************************************/ - Vector3D(T _x=0, T _y=0, T _z=0) : x(_x), y(_y), z(_z) { }; - Vector3D(const Vector3D& obj) : x((T)obj.x), y((T)obj.y), z((T)obj.z) { }; - Vector3D(const Vector3D& obj) : x((T)obj.x), y((T)obj.y), z((T)obj.z) { }; - Vector3D(const Vector3D& obj) : x((T)obj.x), y((T)obj.y), z((T)obj.z) { }; - ~Vector3D(void) { }; - /***************************************************** - * = assigment - *****************************************************/ - const Vector3D& operator= (const Vector3D& obj ) { - x = (T)obj.x; - y = (T)obj.y; - z = (T)obj.z; - return *this; - } - /***************************************************** - * == operator - *****************************************************/ - bool operator== (const Vector3D& obj) const { - if ((T)obj.x == x && (T)obj.y == y && (T)obj.z == z) { - return true; - } - return false; - } - /***************************************************** - * != operator - *****************************************************/ - bool operator!= (const Vector3D& obj) const { - if ((T)obj.x == x && (T)obj.y == y && (T)obj.z == z) { - return false; - } - return true; - } - /***************************************************** - * += operator - *****************************************************/ - const Vector3D& operator+= (const Vector3D& obj) { - x += (T)obj.x; - y += (T)obj.y; - z += (T)obj.z; - return *this; - } - const Vector3D& operator+= (const T val) { - x += val; - y += val; - z += val; - return *this; - } - /***************************************************** - * + operator - *****************************************************/ - Vector3D operator+ (const Vector3D& obj) { - Vector3D tmpp(x,y,z); - tmpp.x += (T)obj.x; - tmpp.y += (T)obj.y; - tmpp.z += (T)obj.z; - return tmpp; - } - Vector3D operator+ (const T val) { - Vector3D tmpp(x,y,z); - tmpp.x += val; - tmpp.y += val; - tmpp.z += val; - return tmpp; - } - /***************************************************** - * -= operator - *****************************************************/ - const Vector3D& operator-= (const Vector3D& obj) { - x -= (T)obj.x; - y -= (T)obj.y; - z -= (T)obj.z; - return *this; - } - const Vector3D& operator-= (const T val) { - x -= val; - y -= val; - z -= val; - return *this; - } - /***************************************************** - * - operator - *****************************************************/ - Vector3D operator- (const Vector3D& obj) { - Vector3D tmpp(x,y,z); - tmpp.x -= (T)obj.x; - tmpp.y -= (T)obj.y; - tmpp.z -= (T)obj.z; - return tmpp; - } - Vector3D operator- (const T val) { - Vector3D tmpp(x,y,z); - tmpp.x -= val; - tmpp.y -= val; - tmpp.z -= val; - return tmpp; - } - /***************************************************** - * /= operator - *****************************************************/ - const Vector3D& operator/= (const Vector3D& obj) { - if (obj.x != 0) { - x /= (T)obj.x; - } - if (obj.y != 0) { - y /= (T)obj.y; - } - if (obj.z != 0) { - z /= (T)obj.z; - } - return *this; - } - const Vector3D& operator/= (const T val) { - if (val==0) { - return *this; - } - x /= val; - y /= val; - z /= val; - return *this; - } - /***************************************************** - * / operator - *****************************************************/ - Vector3D operator/ (const Vector3D& obj) { - Vector3D tmpp(x,y,z); - if (obj.x != 0) { - tmpp.x /= (T)obj.x; - } - if (obj.y != 0) { - tmpp.y /= (T)obj.y; - } - if (obj.z != 0) { - tmpp.z /= (T)obj.z; - } - return tmpp; - } - Vector3D operator/ (const T val) { - Vector3D tmpp(x,y,z); - if (val==0) { - return tmpp; - } - tmpp.x /= val; - tmpp.y /= val; - tmpp.z /= val; - return tmpp; - } - /***************************************************** - * *= operator - *****************************************************/ - const Vector3D& operator*= (const Vector3D& obj) { - x *= (T)obj.x; - y *= (T)obj.y; - z *= (T)obj.z; - return *this; - } - const Vector3D& operator*= (const T val) { - x *= val; - y *= val; - z *= val; - return *this; - } - /***************************************************** - * * operator - *****************************************************/ - Vector3D operator* (const Vector3D& obj) { - Vector3D tmpp(x,y,z); - tmpp.x *= (T)obj.x; - tmpp.y *= (T)obj.y; - tmpp.z *= (T)obj.z; - return tmpp; - } - Vector3D operator* (const T val) { - Vector3D tmpp(x,y,z); - tmpp.x *= val; - tmpp.y *= val; - tmpp.z *= val; - return tmpp; - } - /***************************************************** - * ++ operator - *****************************************************/ - Vector3D& operator++() // prefix - { - ++x; - ++y; - ++z; - return *this; - } - Vector3D operator++(int unused) // postfix - { - Vector3D result = *this; - ++(*this); - return result; - } - /***************************************************** - * -- operator - *****************************************************/ - Vector3D& operator--() // prefix - { - --x; - --y; - --z; - return *this; - } - Vector3D operator--(int unused) // postfix - { - Vector3D result = *this; - --(*this); - return result; - } - - void Zero(void) - { - x=0; - y=0; - z=0; - }; - void One(void) - { - x=1; - y=1; - z=1; - }; - - //vector algebra - Vector3D CrossProduct(const Vector3D& obj) const - { - return Vector3D( y*obj.z - z*obj.y, - z*obj.x - x*obj.z, - x*obj.y - y*obj.x); - }; - - float DotProduct(const Vector3D& obj) const - { - return x*obj.x - + y*obj.y - + z*obj.z; - }; - - void Normalize(void) - { - float length=GetLength(); - if(length==1 || length==0) { - return; - } - float scalefactor = 1.0f/length; - x *= scalefactor; - y *= scalefactor; - z *= scalefactor; - }; - - Vector3D GetNormalized(void) const - { - Vector3D tmpp(*this); - tmpp.Normalize(); - return tmpp; - }; - - float GetLength(void) const - { - return sqrtf((x*x)+(y*y)+(z*z)); - }; - - float GetSquaredLength(void) const - { - return (x*x)+(y*y)+(z*z); - }; /** - * @brief Set the absolute value of the vector + * @brief No initialization constructor (faster ...) */ - void Abs(void) + Vector3D(void) { - if (x<0) { - x = -x; - } - if (y<0) { - y = -y; - } - if (z<0) { - z = -z; - } - }; - - - //rotations - void RotateX(float angle) - { - (*this)=GetRotatedX(angle); - }; - - Vector3D GetRotatedX(float angle) const - { - if(angle==0.0) { - return (*this); - } - float sinAngle=sinf(angle); - float cosAngle=cosf(angle); - return Vector3D( x, - y*cosAngle - z*sinAngle, - y*sinAngle + z*cosAngle); - }; - - void RotateY(float angle) + } + /** + * @brief Constructor from scalars + * @param x X value + * @param y Y value + * @param z Z value + */ + Vector3D(const T& _x, const T& _y, const T& _z) { - (*this)=GetRotatedY(angle); - }; - - Vector3D GetRotatedY(float angle) const - { - if(angle==0.0) { - return (*this); - } - float sinAngle=sinf(angle); - float cosAngle=cosf(angle); - return Vector3D( x*cosAngle + z*sinAngle, - y, - -x*sinAngle + z*cosAngle); - }; - - void RotateZ(float angle) - { - (*this)=GetRotatedZ(angle); - }; - - Vector3D GetRotatedZ(float angle) const - { - if(angle==0.0) { - return (*this); - } - float sinAngle=sinf(angle); - float cosAngle=cosf(angle); - return Vector3D( x*cosAngle - y*sinAngle, - x*sinAngle + y*cosAngle, - z); - }; - - void RotateAxis(const Vector3D & axis, float angle) - { - (*this)=GetRotatedAxis(axis, angle); - TK_DEBUG("Rotate : " << *this); - }; - - Vector3D GetRotatedAxis(const Vector3D & axis, float angle) const - { - if(angle==0.0) { - return (*this); - } - Vector3D u=axis.GetNormalized(); - Vector3D rotMatrixRow0, rotMatrixRow1, rotMatrixRow2; - float sinAngle=sinf(angle); - float cosAngle=cosf(angle); - float MinusCosAngle=1.0f-cosAngle; - rotMatrixRow0.x=(u.x)*(u.x) + cosAngle*(1-(u.x)*(u.x)); - rotMatrixRow0.y=(u.x)*(u.y)*(MinusCosAngle) - sinAngle*u.z; - rotMatrixRow0.z=(u.x)*(u.z)*(MinusCosAngle) + sinAngle*u.y; - rotMatrixRow1.x=(u.x)*(u.y)*(MinusCosAngle) + sinAngle*u.z; - rotMatrixRow1.y=(u.y)*(u.y) + cosAngle*(1-(u.y)*(u.y)); - rotMatrixRow1.z=(u.y)*(u.z)*(MinusCosAngle) - sinAngle*u.x; - rotMatrixRow2.x=(u.x)*(u.z)*(MinusCosAngle) - sinAngle*u.y; - rotMatrixRow2.y=(u.y)*(u.z)*(MinusCosAngle) + sinAngle*u.x; - rotMatrixRow2.z=(u.z)*(u.z) + cosAngle*(1-(u.z)*(u.z)); - return Vector3D( this->DotProduct(rotMatrixRow0), - this->DotProduct(rotMatrixRow1), - this->DotProduct(rotMatrixRow2)); - }; + m_floats[0] = _x; + m_floats[1] = _y; + m_floats[2] = _z; + m_floats[3] = 0; + } /** - * @brief Linar intermolation of the curent Vector - * @param[in] input - * @param[in] factor - * @return the interpolate vector + * @brief Add a vector to this one + * @param The vector to add to this one */ - Vector3D LinearInterpolate(const Vector3D& input, float factor) const + Vector3D& operator+=(const Vector3D& v) { - return (*this)*(1.0f-factor) + input*factor; - }; + m_floats[0] += v.m_floats[0]; + m_floats[1] += v.m_floats[1]; + m_floats[2] += v.m_floats[2]; + return *this; + } + /** - * @brief Quadratic intermolation of the curent Vector - * @param[in] v1 - * @param[in] v2 - * @param[in] factor - * @return the interpolate vector + * @brief Subtract a vector from this one + * @param The vector to subtract */ - Vector3D QuadraticInterpolate(const Vector3D& v2, const Vector3D& v3, float factor) const + Vector3D& operator-=(const Vector3D& v) { - return (*this)*(1.0f-factor)*(1.0f-factor) + 2*v2*factor*(1.0f-factor) + v3*factor*factor; - }; + m_floats[0] -= v.m_floats[0]; + m_floats[1] -= v.m_floats[1]; + m_floats[2] -= v.m_floats[2]; + return *this; + } + + /** + * @brief Scale the vector + * @param s Scale factor + */ + Vector3D& operator*=(const T& s) + { + m_floats[0] *= s; + m_floats[1] *= s; + m_floats[2] *= s; + return *this; + } + + /** + * @brief Inversely scale the vector + * @param s Scale factor to divide by + */ + Vector3D& operator/=(const Vector3D& s) + { + if (0!=s) { + return *this *= btScalar(1.0) / s; + } + return 0; + } + + /** + * @brief Return the dot product + * @param v The other vector in the dot product + */ + btScalar dot(const Vector3D& v) const + { + return m_floats[0] * v.m_floats[0] + + m_floats[1] * v.m_floats[1] + + m_floats[2] * v.m_floats[2]; + } + + /** + * @brief Return the length of the vector squared + */ + btScalar length2() const + { + return dot(*this); + } + + /** + * @brief Return the length of the vector + */ + btScalar length() const + { + return btSqrt(length2()); + } + + /** + * @brief Return the distance squared between the ends of this and another vector + * This is symantically treating the vector like a point + */ + btScalar distance2(const btVector3& v) const + { + return (v - *this).length2(); + } + + /** + * @brief Return the distance between the ends of this and another vector + * This is symantically treating the vector like a point + */ + btScalar distance(const btVector3& v) const + { + return (v - *this).length(); + } + + Vector3D& safeNormalize() + { + Vector3D absVec = this->absolute(); + int maxIndex = absVec.maxAxis(); + if (absVec[maxIndex]>0) + { + *this /= absVec[maxIndex]; + return *this /= length(); + } + setValue(1,0,0); + return *this; + } + + /** + * @brief Normalize this vector + * x^2 + y^2 + z^2 = 1 + */ + Vector3D& normalize() + { + return *this /= length(); + } + + /** + * @brief Return a normalized version of this vector + */ + Vector3D normalized() const + { + return *this / length(); + } + + /** + * @brief Return a rotated version of this vector + * @param wAxis The axis to rotate about + * @param angle The angle to rotate by + */ + Vector3D rotate( const Vector3D& wAxis, const btScalar angle ) const + { + Vector3D o = wAxis * wAxis.dot( *this ); + Vector3D _x = *this - o; + Vector3D _y; + _y = wAxis.cross( *this ); + return ( o + _x * cosf(angle) + _y * sinf(angle) ); + } + + /** + * @brief Return the angle between this and another vector + * @param v The other vector + */ + btScalar angle(const Vector3D& v) const + { + btScalar s = sqrtf(length2() * v.length2()); + if (0!=s) { + return acosf(dot(v) / s); + } + return 0; + } + + /** + * @brief Return a vector will the absolute values of each element + */ + Vector3D absolute(void) const + { + return Vector3D( abs(m_floats[0]), + abs(m_floats[1]), + abs(m_floats[2])); + } + + /** + * @brief Return the cross product between this and another vector + * @param v The other vector + */ + Vector3D cross(const Vector3D& v) const + { + return Vector3D(m_floats[1] * v.m_floats[2] - m_floats[2] * v.m_floats[1], + m_floats[2] * v.m_floats[0] - m_floats[0] * v.m_floats[2], + m_floats[0] * v.m_floats[1] - m_floats[1] * v.m_floats[0]); + } + + T triple(const Vector3D& v1, const Vector3D& v2) const + { + return m_floats[0] * (v1.m_floats[1] * v2.m_floats[2] - v1.m_floats[2] * v2.m_floats[1]) + + m_floats[1] * (v1.m_floats[2] * v2.m_floats[0] - v1.m_floats[0] * v2.m_floats[2]) + + m_floats[2] * (v1.m_floats[0] * v2.m_floats[1] - v1.m_floats[1] * v2.m_floats[0]); + } + + /** + * @brief Return the axis with the smallest value + * Note return values are 0,1,2 for x, y, or z + */ + int32_t minAxis(void) const + { + return m_floats[0] < m_floats[1] ? (m_floats[0] & v0, const Vector3D& v1, T rt) + { + btScalar s = 1 - rt; + m_floats[0] = s * v0.m_floats[0] + rt * v1.m_floats[0]; + m_floats[1] = s * v0.m_floats[1] + rt * v1.m_floats[1]; + m_floats[2] = s * v0.m_floats[2] + rt * v1.m_floats[2]; + //don't do the unused w component + // m_co[3] = s * v0[3] + rt * v1[3]; + } + + /** + * @brief Return the linear interpolation between this and another vector + * @param v The other vector + * @param t The ration of this to v (t = 0 => return this, t=1 => return other) + */ + Vector3D lerp(const Vector3D& v, const btScalar& t) const + { + return Vector3D(m_floats[0] + (v.m_floats[0] - m_floats[0]) * t, + m_floats[1] + (v.m_floats[1] - m_floats[1]) * t, + m_floats[2] + (v.m_floats[2] - m_floats[2]) * t); + } + + /** + * @brief Elementwise multiply this vector by the other + * @param v The other vector + */ + Vector3D& operator*=(const Vector3D& v) + { + m_floats[0] *= v.m_floats[0]; + m_floats[1] *= v.m_floats[1]; + m_floats[2] *= v.m_floats[2]; + return *this; + } + + /** + * @brief Return the x value + */ + const T& getX() const { return m_floats[0]; } + /** + * @brief Return the y value + */ + const T& getY() const { return m_floats[1]; } + /** + * @brief Return the z value + */ + const T& getZ() const { return m_floats[2]; } + /** + * @brief Set the x value + */ + void setX(T _x) { m_floats[0] = _x;}; + /** + * @brief Set the y value + */ + void setY(T _y) { m_floats[1] = _y;}; + /** + * @brief Set the z value + */ + void setZ(T _z) { m_floats[2] = _z;}; + /** + * @brief Set the w value + */ + void setW(T _w) { m_floats[3] = _w;}; + /** + * @brief Return the x value + */ + const T& x() const { return m_floats[0]; } + /** + * @brief Return the y value + */ + const T& y() const { return m_floats[1]; } + /** + * @brief Return the z value + */ + const T& z() const { return m_floats[2]; } + /** + * @brief Return the w value + */ + const T& w() const { return m_floats[3]; } + + operator T *() { return &m_floats[0]; } + operator const T *() const { return &m_floats[0]; } + + bool operator==(const Vector3D& other) const + { + return ( (m_floats[3]==other.m_floats[3]) + && (m_floats[2]==other.m_floats[2]) + && (m_floats[1]==other.m_floats[1]) + && (m_floats[0]==other.m_floats[0])); + } + + bool operator!=(const Vector3D& other) const + { + return ( (m_floats[3]!=other.m_floats[3]) + || (m_floats[2]!=other.m_floats[2]) + || (m_floats[1]!=other.m_floats[1]) + || (m_floats[0]!=other.m_floats[0])); + } + + /** + * @brief Set each element to the max of the current values and the values of another btVector3 + * @param other The other btVector3 to compare with + */ + void setMax(const Vector3D& other) + { + btSetMax(m_floats[0], other.m_floats[0]); + btSetMax(m_floats[1], other.m_floats[1]); + btSetMax(m_floats[2], other.m_floats[2]); + btSetMax(m_floats[3], other.m_floats[3]); + } + + /** + * @brief Set each element to the min of the current values and the values of another btVector3 + * @param other The other btVector3 to compare with + */ + void setMin(const Vector3D& other) + { + btSetMin(m_floats[0], other.m_floats[0]); + btSetMin(m_floats[1], other.m_floats[1]); + btSetMin(m_floats[2], other.m_floats[2]); + btSetMin(m_floats[3], other.m_floats[3]); + } + + void setValue(const T& _x, const T& _y, const T& _z) + { + m_floats[0]=_x; + m_floats[1]=_y; + m_floats[2]=_z; + m_floats[3] = 0; + } + + void getSkewSymmetricMatrix(Vector3D* v0,Vector3D* v1,Vector3D* v2) const + { + v0->setValue(0. ,-z() ,y()); + v1->setValue(z() ,0. ,-x()); + v2->setValue(-y() ,x() ,0.); + } + + void setZero(void) + { + setValue(0,0,0); + } + + bool isZero(void) const + { + return m_floats[0] == 0 && m_floats[1] == 0 && m_floats[2] == 0; + } }; /** * @brief Debug operator To display the curent element in a Human redeable information */ etk::CCout& operator <<(etk::CCout &os, const etk::Vector3D obj); - /** - * @brief Debug operator To display the curent element in a Human redeable information - */ - etk::CCout& operator <<(etk::CCout &os, const etk::Vector3D obj); + etk::CCout& operator <<(etk::CCout &os, const btVector3 obj); + etk::CCout& operator <<(etk::CCout &os, const etk::Vector3D obj); + etk::CCout& operator <<(etk::CCout &os, const etk::Vector3D obj); }; // To siplify the writing of the code ==> this permit to have the same name with the glsl language... -typedef etk::Vector3D vec3; +typedef btVector3 vec3; +typedef etk::Vector3D ovec3; // specific for OpenGL ... ==> never change this ... typedef etk::Vector3D ivec3; // not compatible with glsl ... but it is better to have a same writing typedef etk::Vector3D uivec3; @@ -437,3 +419,4 @@ typedef etk::Vector3D bvec3; #endif +