[DEV] new 2x2 and 3x3 matrix, quaternion, transform

This commit is contained in:
Edouard DUPIN 2017-05-08 23:48:36 +00:00
parent f03e3ebe3d
commit ff59f92dd7
28 changed files with 2918 additions and 341 deletions

View File

@ -9,82 +9,77 @@
std::ostream& etk::operator <<(std::ostream& _os, const etk::Matrix2& _obj) {
_os << "{";
_os << _obj.m_mat[0] << ",";
_os << _obj.m_mat[4] << ",";
_os << _obj.m_mat[1] << ",";
_os << _obj.m_mat[3] << ",";
_os << _obj.m_mat[1] << ";";
_os << _obj.m_mat[2] << ",";
_os << _obj.m_mat[5] << "}";
_os << _obj.m_mat[3] << "}";
return _os;
}
void etk::Matrix2::identity() {
m_mat[0] = 1.0;
m_mat[1] = 0.0;
m_mat[2] = 0.0;
m_mat[3] = 1.0;
m_mat[4] = 0.0;
m_mat[5] = 0.0;
}
etk::Matrix2::Matrix2() {
// TODO: Remove this ...
identity();
}
etk::Matrix2::Matrix2(const etk::Matrix2& _obj) {
for(int32_t iii=0; iii<2*3 ; iii++) {
m_mat[iii] = _obj.m_mat[iii];
}
m_mat[0] = 0.0f;
m_mat[1] = 0.0f;
m_mat[2] = 0.0f;
m_mat[3] = 0.0f;
}
etk::Matrix2::Matrix2(float _sx,
float _shy,
float _shx,
float _sy,
float _tx,
float _ty) {
m_mat[0] = _sx;
m_mat[4] = _shy;
m_mat[1] = _shx;
m_mat[3] = _sy;
m_mat[2] = _tx;
m_mat[5] = _ty;
etk::Matrix2::Matrix2(float _value) {
m_mat[0] = _value;
m_mat[1] = _value;
m_mat[2] = _value;
m_mat[3] = _value;
}
etk::Matrix2::Matrix2(const float* _values) {
if (_values == nullptr) {
identity();
return;
}
m_mat[0] = _values[0];
m_mat[4] = _values[1];
m_mat[1] = _values[2];
m_mat[3] = _values[3];
m_mat[2] = _values[4];
m_mat[5] = _values[5];
etk::Matrix2::Matrix2(float _a1, float _a2,float _b1, float _b2) {
m_mat[0] = _a1;
m_mat[1] = _a2;
m_mat[2] = _b1;
m_mat[3] = _b2;
}
etk::Matrix2::Matrix2(const double* _values) {
if (_values == nullptr) {
identity();
return;
etk::Matrix2::Matrix2(const Matrix2& _obj) {
m_mat[0] = _obj.m_mat[0];
m_mat[1] = _obj.m_mat[1];
m_mat[2] = _obj.m_mat[2];
m_mat[3] = _obj.m_mat[3];
}
void etk::Matrix2::setValue(float _a1, float _a2,float _b1, float _b2) {
m_mat[0] = _a1;
m_mat[1] = _a2;
m_mat[2] = _b1;
m_mat[3] = _b2;
}
void etk::Matrix2::setZero() {
m_mat[0] = 0;
m_mat[1] = 0;
m_mat[2] = 0;
m_mat[3] = 0;
}
vec2 etk::Matrix2::getColumn(uint32_t _iii) const {
if (_iii == 0) {
return vec2(m_mat[0], m_mat[2]);
}
m_mat[0] = _values[0];
m_mat[4] = _values[1];
m_mat[1] = _values[2];
m_mat[3] = _values[3];
m_mat[2] = _values[4];
m_mat[5] = _values[5];
return vec2(m_mat[1], m_mat[3]);
}
vec2 etk::Matrix2::getRow(uint32_t _iii) const {
if (_iii == 0) {
return vec2(m_mat[0], m_mat[1]);
}
return vec2(m_mat[2], m_mat[3]);
}
const etk::Matrix2& etk::Matrix2::operator= (const etk::Matrix2& _obj ) {
for(int32_t iii=0; iii<2*3 ; ++iii) {
for(int32_t iii=0; iii<2*2 ; ++iii) {
m_mat[iii] = _obj.m_mat[iii];
}
return *this;
}
bool etk::Matrix2::operator== (const etk::Matrix2& _obj) const {
for(int32_t iii=0; iii<2*3 ; ++iii) {
for(int32_t iii=0; iii<2*2 ; ++iii) {
if(m_mat[iii] != _obj.m_mat[iii]) {
return false;
}
@ -93,7 +88,7 @@ bool etk::Matrix2::operator== (const etk::Matrix2& _obj) const {
}
bool etk::Matrix2::operator!= (const etk::Matrix2& _obj) const {
for(int32_t iii=0; iii<2*3 ; ++iii) {
for(int32_t iii=0; iii<2*2 ; ++iii) {
if(m_mat[iii] != _obj.m_mat[iii]) {
return true;
}
@ -102,7 +97,7 @@ bool etk::Matrix2::operator!= (const etk::Matrix2& _obj) const {
}
const etk::Matrix2& etk::Matrix2::operator+= (const etk::Matrix2& _obj) {
for(int32_t iii=0; iii<2*3 ; ++iii) {
for(int32_t iii=0; iii<2*2 ; ++iii) {
m_mat[iii] += _obj.m_mat[iii];
}
return *this;
@ -115,7 +110,7 @@ etk::Matrix2 etk::Matrix2::operator+ (const etk::Matrix2& _obj) const {
}
const etk::Matrix2& etk::Matrix2::operator-= (const etk::Matrix2& _obj) {
for(int32_t iii=0; iii<2*3 ; ++iii) {
for(int32_t iii=0; iii<2*2 ; ++iii) {
m_mat[iii] -= _obj.m_mat[iii];
}
return *this;
@ -123,126 +118,119 @@ const etk::Matrix2& etk::Matrix2::operator-= (const etk::Matrix2& _obj) {
etk::Matrix2 etk::Matrix2::operator- (const etk::Matrix2& _obj) const {
etk::Matrix2 tmpp(*this);
tmpp += _obj;
tmpp -= _obj;
return tmpp;
}
const etk::Matrix2& etk::Matrix2::operator *= (const etk::Matrix2& _obj) {
float t0 = m_mat[0] * _obj.m_mat[0] + m_mat[4] * _obj.m_mat[1];
float t2 = m_mat[1] * _obj.m_mat[0] + m_mat[3] * _obj.m_mat[1];
float t4 = m_mat[2] * _obj.m_mat[0] + m_mat[5] * _obj.m_mat[1] + _obj.m_mat[2];
m_mat[4] = m_mat[0] * _obj.m_mat[4] + m_mat[4] * _obj.m_mat[3];
m_mat[3] = m_mat[1] * _obj.m_mat[4] + m_mat[3] * _obj.m_mat[3];
m_mat[5] = m_mat[2] * _obj.m_mat[4] + m_mat[5] * _obj.m_mat[3] + _obj.m_mat[5];
float t0 = m_mat[0] * _obj.m_mat[0] + m_mat[1] * _obj.m_mat[2];
float t2 = m_mat[2] * _obj.m_mat[0] + m_mat[3] * _obj.m_mat[2];
m_mat[1] = m_mat[0] * _obj.m_mat[1] + m_mat[1] * _obj.m_mat[3];
m_mat[3] = m_mat[2] * _obj.m_mat[1] + m_mat[3] * _obj.m_mat[3];
m_mat[0] = t0;
m_mat[1] = t2;
m_mat[2] = t4;
m_mat[2] = t2;
return *this;
}
etk::Matrix2 etk::Matrix2::operator * (const etk::Matrix2& _obj) {
etk::Matrix2 etk::Matrix2::operator * (const etk::Matrix2& _obj) const {
etk::Matrix2 tmp(*this);
tmp *= _obj;
return tmp;
}
vec2 etk::Matrix2::operator * (const vec2& _point) const {
return vec2(_point.x()*m_mat[0] + _point.y()*m_mat[1] + m_mat[2],
_point.x()*m_mat[4] + _point.y()*m_mat[3] + m_mat[5]);
}
vec2 etk::Matrix2::applyScaleRotation(const vec2& _point) const {
return vec2(_point.x()*m_mat[0] + _point.y()*m_mat[1],
_point.x()*m_mat[4] + _point.y()*m_mat[3]);
_point.x()*m_mat[2] + _point.y()*m_mat[3]);
}
etk::Matrix2 etk::Matrix2::operator ~ () const {
etk::Matrix2 tmp(*this);
tmp.invert();
return tmp;
}
void etk::Matrix2::flipX() {
m_mat[0] = -m_mat[0];
m_mat[4] = -m_mat[4];
m_mat[2] = -m_mat[2];
}
void etk::Matrix2::flipY() {
m_mat[1] = -m_mat[1];
m_mat[3] = -m_mat[3];
m_mat[5] = -m_mat[5];
}
void etk::Matrix2::scale(const vec2& _vect) {
m_mat[0] *= _vect.x();
m_mat[1] *= _vect.x();
m_mat[2] *= _vect.x();
m_mat[4] *= _vect.y();
m_mat[3] *= _vect.y();
m_mat[5] *= _vect.y();
}
void etk::Matrix2::scale(float _value) {
const etk::Matrix2& etk::Matrix2::operator *= (float _value) {
m_mat[0] *= _value;
m_mat[1] *= _value;
m_mat[2] *= _value;
m_mat[4] *= _value;
m_mat[3] *= _value;
m_mat[5] *= _value;
return *this;
}
void etk::Matrix2::rotate(float _angleRad) {
float ca = cos(_angleRad);
float sa = sin(_angleRad);
float t0 = m_mat[0] * ca - m_mat[4] * sa;
float t2 = m_mat[1] * ca - m_mat[3] * sa;
float t4 = m_mat[2] * ca - m_mat[5] * sa;
m_mat[4] = m_mat[0] * sa + m_mat[4] * ca;
m_mat[3] = m_mat[1] * sa + m_mat[3] * ca;
m_mat[5] = m_mat[2] * sa + m_mat[5] * ca;
m_mat[0] = t0;
m_mat[1] = t2;
m_mat[2] = t4;
etk::Matrix2 etk::Matrix2::operator * (float _value) const {
etk::Matrix2 tmp(*this);
tmp *= _value;
return tmp;
}
void etk::Matrix2::translate(const vec2& _vect) {
m_mat[2] += _vect.x();
m_mat[5] += _vect.y();
etk::Matrix2 etk::Matrix2::getTranspose() const {
return Matrix2(m_mat[0], m_mat[2],
m_mat[1], m_mat[3]);
}
void etk::Matrix2::transpose() {
float tmp = m_mat[2];
m_mat[2] = m_mat[1];
m_mat[1] = tmp;
}
float etk::Matrix2::determinant() const {
return m_mat[0] * m_mat[3] - m_mat[4] * m_mat[1];
return m_mat[0] * m_mat[3] - m_mat[2] * m_mat[1];
}
void etk::Matrix2::invert() {
float det = 1.0f / determinant();
float t0 = m_mat[3] * det;
m_mat[3] = m_mat[0] * det;
m_mat[4] = -m_mat[4] * det;
m_mat[1] = -m_mat[1] * det;
float t4 = -m_mat[2] * t0 - m_mat[5] * m_mat[1];
m_mat[5] = -m_mat[2] * m_mat[4] - m_mat[5] * m_mat[3];
m_mat[0] = t0;
m_mat[2] = t4;
float etk::Matrix2::getTrace() const {
return m_mat[0] + m_mat[3];
}
void etk::Matrix2::setIdentity() {
m_mat[0] = 1.0f;
m_mat[1] = 0.0f;
m_mat[2] = 0.0f;
m_mat[3] = 1.0f;
}
etk::Matrix2 etk::Matrix2::identity() {
return etk::Matrix2(1.0f, 0.0f, 0.0f, 1.0f);
}
etk::Matrix2 etk::Matrix2::zero() {
return etk::Matrix2(0.0f, 0.0f, 0.0f, 0.0f);
}
etk::Matrix2 etk::Matrix2::getAbsolute() const {
return Matrix2(std::abs(m_mat[0]), std::abs(m_mat[1]),
std::abs(m_mat[2]), std::abs(m_mat[3]));
}
void etk::Matrix2::absolute() {
m_mat[0] = std::abs(m_mat[0]);
m_mat[1] = std::abs(m_mat[1]);
m_mat[2] = std::abs(m_mat[2]);
m_mat[3] = std::abs(m_mat[3]);
}
void etk::Matrix2::inverse() {
*this = getInverse();
}
etk::Matrix2 etk::Matrix2::getInverse() const {
float det = determinant();
//assert(std::abs(det) > MACHINE_EPSILON);
float invDet = 1.0f / det;
return etk::Matrix2(m_mat[3], -m_mat[1], -m_mat[2], m_mat[0]) * invDet;
}
etk::Matrix2 etk::mat2Rotate(float _angleRad) {
return Matrix2(cos(_angleRad), sin(_angleRad), -sin(_angleRad), cos(_angleRad), 0.0, 0.0);
};
return Matrix2(cos(_angleRad), sin(_angleRad), -sin(_angleRad), cos(_angleRad));
}
etk::Matrix2 etk::mat2Scale(const vec2& _scale) {
return Matrix2(_scale.x(), 0.0, 0.0, _scale.y(), 0.0, 0.0);
};
return Matrix2(_scale.x(), 0.0, 0.0, _scale.y());
}
etk::Matrix2 etk::mat2Scale(float _scale) {
return Matrix2(_scale, 0.0, 0.0, _scale, 0.0, 0.0);
};
etk::Matrix2 etk::mat2Translate(const vec2& _translate) {
return Matrix2(1.0, 0.0, 0.0, 1.0, _translate.x(), _translate.y());
};
return Matrix2(_scale, 0.0, 0.0, _scale);
}
etk::Matrix2 etk::mat2Skew(const vec2& _skew) {
return Matrix2(1.0, tan(_skew.y()), tan(_skew.x()), 1.0, 0.0, 0.0);
};
return Matrix2(1.0, tan(_skew.y()), tan(_skew.x()), 1.0);
}
etk::Matrix2 operator-(const etk::Matrix2& _matrix) {
return etk::Matrix2(-_matrix.m_mat[0], -_matrix.m_mat[1], -_matrix.m_mat[2], -_matrix.m_mat[3]);
}

View File

@ -3,62 +3,123 @@
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
#pragma once
#include <etk/math/Vector2D.hpp>
#include <etk/types.hpp>
#include <etk/math/Vector2D.hpp>
#include <cmath>
namespace etk {
/**
* @brief Transformation matrix for vector 2D.
* This class represents a 2x2 matrix.
*/
class Matrix2 {
public:
/**
* @brief Internal data
* sx shx tx
* sy shy ty
* sx shx
* sy shy
*/
float m_mat[2*3];
public:
float m_mat[2*2];
public :
/**
* @brief Constructor that load identity
* @brief Constructor that load zero matrix
*/
Matrix2();
/**
* @brief Configuration constructorwith single value.
* @param[in] _value single vamue
*/
Matrix2(float _value);
/**
* @brief Configuration constructor.
* @param[in] _a1 element 0x0
* @param[in] _a2 element 0x1
* @param[in] _b1 element 1x0
* @param[in] _b2 element 1x1
*/
Matrix2(float _a1, float _a2, float _b1, float _b2);
/**
* @brief Copy constructor.
* @param[in] _obj Matrix object to copy
*/
Matrix2(const Matrix2& _obj);
Matrix2(const Matrix2& _matrix);
/**
* @brief Configuration constructor.
* @param[in] _sx Scale threw X axis
* @param[in] _shy Rotate in radian threw Y axis
* @param[in] _shx Rotate in radian threw X axis
* @param[in] _sy Scale threw Y axis
* @param[in] _tx Translate threw X axis
* @param[in] _ty translate threw Y axis
* @brief Set Value on the matrix
* @param[in] _a1 element 0x0
* @param[in] _a2 element 0x1
* @param[in] _b1 element 1x0
* @param[in] _b2 element 1x1
*/
Matrix2(float _sx,
float _shy,
float _shx,
float _sy,
float _tx,
float _ty);
void setValue(float _a1, float _a2, float _b1, float _b2);
/**
* @brief Configuration constructor.
* @param[in] _values vector of values in float
* @brief Load Zero matrix
*/
Matrix2(const float* _values);
void setZero();
/**
* @brief Configuration constructor.
* @param[in] _values vector of values in double
* @brief get the colom id values
* @param[in] _iii Id of the colomn
* @return Vector 2D vith the values
*/
Matrix2(const double* _values);
vec2 getColumn(uint32_t _iii) const;
/**
* @brief get the row id values
* @param[in] _iii Id of the row
* @return Vector 2D vith the values
*/
vec2 getRow(uint32_t _iii) const;
/**
* @brief get a transpose matrix of this one.
* @return the transpose matrix
*/
Matrix2 getTranspose() const;
/**
* @brief Transpose the current matrix.
*/
void transpose();
/**
* @brief Computes the determinant of the matrix.
* @return The determinent Value.
*/
float determinant() const;
/**
* @brief Calculate the trace of the matrix
* @return value of addition of all element in the diagonal
*/
float getTrace() const;
/**
* @brief Inverts the matrix.
* @note The determinant must be != 0, otherwithe the matrix can't be inverted.
* @return The inverted matrix.
*/
Matrix2 getInverse() const;
/**
* @brief Inverts the current matrix.
* @note The determinant must be != 0, otherwithe the matrix can't be inverted.
*/
void inverse();
/**
* @brief get the mathix with the absolute value
* @return matix in absolute
*/
Matrix2 getAbsolute() const;
/**
* @brief absolutise the matrix
*/
void absolute();
/**
* @brief Load Identity matrix
*/
void identity();
void setIdentity();
/**
* @brief create a Identity matrix
* @return created new matrix
*/
static etk::Matrix2 identity();
/**
* @brief create a ZERO matrix
* @return created new matrix
*/
static Matrix2 zero();
/**
* @brief Operator= Asign the current object with an other object
* @param[in] _obj Reference on the external object
@ -78,7 +139,7 @@ namespace etk {
* @return true The Objects are NOT identical
* @return false The Objects are identical
*/
bool operator!= (const Matrix2& _obj) const;
bool operator!= (const Matrix2& _obj) const;
/**
* @brief Operator+= Addition an other matrix with this one
* @param[in] _obj Reference on the external object
@ -114,64 +175,27 @@ namespace etk {
* @param[in] _obj Reference on the external object
* @return New vector containing the value
*/
Matrix2 operator * (const Matrix2& _obj);
Matrix2 operator * (const Matrix2& _obj) const;
/**
* @brief Operator*= Multiplication a value
* @param[in] _value value to multiply all the matrix
* @return Local reference of the vector multiplicated
*/
const Matrix2& operator *= (float _value);
/**
* @brief Operator*= Multiplication a value
* @param[in] _value value to multiply all the matrix
* @return Local reference of the vector multiplicated
*/
Matrix2 operator * (float _value) const;
/**
* @brief Operator* apply matrix on a vector
* @param[in] _point Point value to apply the matrix
* @return New vector containing the value
*/
vec2 operator * (const vec2& _point) const;
/**
* @brief Apply matrix on a vector Scale Rotate, but NOT the translation
* @param[in] _point Point value to apply the matrix
* @return New vector containing the value
*/
vec2 applyScaleRotation(const vec2& _point) const;
/**
* @brief Inverse the current Matrix
* @return New vector containing the value
*/
Matrix2 operator ~ () const;
/**
* @brief Flip the mathix threw the X axis
*/
void flipX();
/**
* @brief Flip the mathix threw the Y axis
*/
void flipY();
/**
* @brief Scale the current Matrix.
* @param[in] _vect Vector to scale matrix.
*/
void scale(const vec2& _vect);
/**
* @brief Scale the current Matrix.
* @param[in] _value Single value to scale in X andf Y.
*/
void scale(float _value);
/**
* @brief Makes a rotation matrix.
* @param[in] _angleRad angle to apply.
*/
void rotate(float _angleRad);
/**
* @brief Makes a translation of the matrix
* @param[in] _vect Translation to apply.
*/
void translate(const vec2& _vect);
/**
* @brief Computes the determinant of the matrix.
* @return The determinent Value.
*/
float determinant() const;
/**
* @brief Inverts the matrix.
* @note The determinant must be != 0, otherwithe the matrix can't be inverted.
* @return The inverted matrix.
*/
void invert();
};
/**
* @brief Create a matrix 2D with a simple rotation
* @param[in] _angleRad Radian angle to set at the matrix
@ -190,12 +214,6 @@ namespace etk {
* @return New matrix of the transformation requested
*/
Matrix2 mat2Scale(float _scale);
/**
* @brief Create a matrix 2D with a simple translation
* @param[in] _translate 2 dimention translation
* @return New matrix of the transformation requested
*/
Matrix2 mat2Translate(const vec2& _translate);
/**
* @brief Create a matrix 2D with a simple skew
* @param[in] _skew 2 dimention skew
@ -205,6 +223,9 @@ namespace etk {
//! @not_in_doc
std::ostream& operator <<(std::ostream& _os, const etk::Matrix2& _obj);
}
etk::Matrix2 operator-(const etk::Matrix2& _matrix);
// simplify using of matrix ...
using mat2 = etk::Matrix2; //!< Use simplification in upper application to use matrix like openGL shader

298
etk/math/Matrix3.cpp Normal file
View File

@ -0,0 +1,298 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
#include <etk/math/Matrix3.hpp>
std::ostream& etk::operator <<(std::ostream& _os, const etk::Matrix3& _obj) {
_os << "{";
_os << _obj.m_mat[0] << ",";
_os << _obj.m_mat[1] << ",";
_os << _obj.m_mat[2] << ";";
_os << _obj.m_mat[3] << ",";
_os << _obj.m_mat[4] << ",";
_os << _obj.m_mat[5] << ";";
_os << _obj.m_mat[6] << ",";
_os << _obj.m_mat[7] << ",";
_os << _obj.m_mat[8] << "}";
return _os;
}
etk::Matrix3::Matrix3() {
m_mat[0] = 0.0f;
m_mat[1] = 0.0f;
m_mat[2] = 0.0f;
m_mat[3] = 0.0f;
m_mat[4] = 0.0f;
m_mat[5] = 0.0f;
m_mat[6] = 0.0f;
m_mat[7] = 0.0f;
m_mat[8] = 0.0f;
}
etk::Matrix3::Matrix3(float _value) {
m_mat[0] = _value;
m_mat[1] = _value;
m_mat[2] = _value;
m_mat[3] = _value;
m_mat[4] = _value;
m_mat[5] = _value;
m_mat[6] = _value;
m_mat[7] = _value;
m_mat[8] = _value;
}
etk::Matrix3::Matrix3(float _a1, float _a2, float _a3,
float _b1, float _b2, float _b3,
float _c1, float _c2, float _c3) {
m_mat[0] = _a1; m_mat[1] = _a2; m_mat[2] = _a3;
m_mat[3] = _b1; m_mat[4] = _b2; m_mat[5] = _b3;
m_mat[6] = _c1; m_mat[7] = _c2; m_mat[8] = _c3;
}
etk::Matrix3::Matrix3(const etk::Matrix3& _obj) {
m_mat[0] = _obj.m_mat[0];
m_mat[1] = _obj.m_mat[1];
m_mat[2] = _obj.m_mat[2];
m_mat[3] = _obj.m_mat[3];
m_mat[4] = _obj.m_mat[4];
m_mat[5] = _obj.m_mat[5];
m_mat[6] = _obj.m_mat[6];
m_mat[7] = _obj.m_mat[7];
m_mat[8] = _obj.m_mat[8];
}
void etk::Matrix3::setValue(float _a1, float _a2, float _a3,
float _b1, float _b2, float _b3,
float _c1, float _c2, float _c3) {
m_mat[0] = _a1; m_mat[1] = _a2; m_mat[2] = _a3;
m_mat[3] = _b1; m_mat[4] = _b2; m_mat[5] = _b3;
m_mat[6] = _c1; m_mat[7] = _c2; m_mat[8] = _c3;
}
void etk::Matrix3::setZero() {
m_mat[0] = 0.0f;
m_mat[1] = 0.0f;
m_mat[2] = 0.0f;
m_mat[3] = 0.0f;
m_mat[4] = 0.0f;
m_mat[5] = 0.0f;
m_mat[6] = 0.0f;
m_mat[7] = 0.0f;
m_mat[8] = 0.0f;
}
vec3 etk::Matrix3::getColumn(uint32_t _iii) const {
if (_iii == 0) {
return vec3(m_mat[0], m_mat[3], m_mat[6]);
} else if (_iii == 1) {
return vec3(m_mat[1], m_mat[4], m_mat[7]);
}
return vec3(m_mat[2], m_mat[5], m_mat[8]);
}
vec3 etk::Matrix3::getRow(uint32_t _iii) const {
if (_iii == 0) {
return vec3(m_mat[0], m_mat[1], m_mat[2]);
} else if (_iii == 1) {
return vec3(m_mat[3], m_mat[4], m_mat[5]);
}
return vec3(m_mat[6], m_mat[7], m_mat[8]);
}
etk::Matrix3 etk::Matrix3::getTranspose() const {
return etk::Matrix3(m_mat[0], m_mat[3], m_mat[6],
m_mat[1], m_mat[4], m_mat[7],
m_mat[2], m_mat[5], m_mat[8]);
}
void etk::Matrix3::transpose() {
float tmp = m_mat[1];
m_mat[1] = m_mat[3];
m_mat[3] = tmp;
tmp = m_mat[2];
m_mat[2] = m_mat[6];
m_mat[6] = tmp;
tmp = m_mat[5];
m_mat[5] = m_mat[7];
m_mat[7] = tmp;
}
float etk::Matrix3::determinant() const {
return m_mat[0]*(m_mat[4]*m_mat[8]-m_mat[7]*m_mat[5])
- m_mat[1]*(m_mat[3]*m_mat[8]-m_mat[6]*m_mat[5])
+ m_mat[2]*(m_mat[3]*m_mat[7]-m_mat[6]*m_mat[4]);
}
float etk::Matrix3::getTrace() const {
return (m_mat[0] + m_mat[4] + m_mat[8]);
}
void etk::Matrix3::setIdentity() {
m_mat[0] = 1.0; m_mat[1] = 0.0; m_mat[2] = 0.0;
m_mat[3] = 0.0; m_mat[4] = 1.0; m_mat[5] = 0.0;
m_mat[6] = 0.0; m_mat[7] = 0.0; m_mat[8] = 1.0;
}
etk::Matrix3 etk::Matrix3::identity() {
return etk::Matrix3(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0);
}
etk::Matrix3 etk::Matrix3::zero() {
return etk::Matrix3(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
}
void etk::Matrix3::absolute() {
m_mat[0] = std::abs(m_mat[0]);
m_mat[1] = std::abs(m_mat[1]);
m_mat[2] = std::abs(m_mat[2]);
m_mat[3] = std::abs(m_mat[3]);
m_mat[4] = std::abs(m_mat[4]);
m_mat[5] = std::abs(m_mat[5]);
m_mat[6] = std::abs(m_mat[6]);
m_mat[7] = std::abs(m_mat[7]);
m_mat[8] = std::abs(m_mat[8]);
}
etk::Matrix3 etk::Matrix3::getAbsolute() const {
return etk::Matrix3(std::abs(m_mat[0]), std::abs(m_mat[1]), std::abs(m_mat[2]),
std::abs(m_mat[3]), std::abs(m_mat[4]), std::abs(m_mat[5]),
std::abs(m_mat[6]), std::abs(m_mat[7]), std::abs(m_mat[8]));
}
const etk::Matrix3& etk::Matrix3::operator= (const etk::Matrix3& _obj ) {
for(int32_t iii=0; iii<3*3 ; ++iii) {
m_mat[iii] = _obj.m_mat[iii];
}
return *this;
}
bool etk::Matrix3::operator== (const etk::Matrix3& _obj) const {
for(int32_t iii=0; iii<3*3 ; ++iii) {
if(m_mat[iii] != _obj.m_mat[iii]) {
return false;
}
}
return true;
}
bool etk::Matrix3::operator!= (const etk::Matrix3& _obj) const {
for(int32_t iii=0; iii<3*3 ; ++iii) {
if(m_mat[iii] != _obj.m_mat[iii]) {
return true;
}
}
return false;
}
const etk::Matrix3& etk::Matrix3::operator+= (const etk::Matrix3& _obj) {
for(int32_t iii=0; iii<3*3 ; ++iii) {
m_mat[iii] += _obj.m_mat[iii];
}
return *this;
}
etk::Matrix3 etk::Matrix3::operator+ (const etk::Matrix3& _obj) const {
etk::Matrix3 tmpp(*this);
tmpp += _obj;
return tmpp;
}
const etk::Matrix3& etk::Matrix3::operator-= (const etk::Matrix3& _obj) {
for(int32_t iii=0; iii<3*3 ; ++iii) {
m_mat[iii] -= _obj.m_mat[iii];
}
return *this;
}
etk::Matrix3 etk::Matrix3::operator- (const etk::Matrix3& _obj) const {
etk::Matrix3 tmpp(*this);
tmpp -= _obj;
return tmpp;
}
const etk::Matrix3& etk::Matrix3::operator *= (const etk::Matrix3& _obj) {
float a1 = m_mat[0]*_obj.m_mat[0] + m_mat[1]*_obj.m_mat[3] + m_mat[2]*_obj.m_mat[6];
float b1 = m_mat[3]*_obj.m_mat[0] + m_mat[4]*_obj.m_mat[3] + m_mat[5]*_obj.m_mat[6];
float c1 = m_mat[6]*_obj.m_mat[0] + m_mat[7]*_obj.m_mat[3] + m_mat[8]*_obj.m_mat[6];
float a2 = m_mat[0]*_obj.m_mat[1] + m_mat[1]*_obj.m_mat[4] + m_mat[2]*_obj.m_mat[7];
float b2 = m_mat[3]*_obj.m_mat[1] + m_mat[4]*_obj.m_mat[4] + m_mat[5]*_obj.m_mat[7];
float c2 = m_mat[6]*_obj.m_mat[1] + m_mat[7]*_obj.m_mat[4] + m_mat[8]*_obj.m_mat[7];
m_mat[2] = m_mat[0]*_obj.m_mat[2] + m_mat[1]*_obj.m_mat[5] + m_mat[2]*_obj.m_mat[8];
m_mat[5] = m_mat[3]*_obj.m_mat[2] + m_mat[4]*_obj.m_mat[5] + m_mat[5]*_obj.m_mat[8];
m_mat[8] = m_mat[6]*_obj.m_mat[2] + m_mat[7]*_obj.m_mat[5] + m_mat[8]*_obj.m_mat[8];
m_mat[0] = a1;
m_mat[3] = b1;
m_mat[6] = c1;
m_mat[1] = a2;
m_mat[4] = b2;
m_mat[7] = c2;
return *this;
}
etk::Matrix3 etk::Matrix3::operator * (const etk::Matrix3& _obj) const {
etk::Matrix3 tmp(*this);
tmp *= _obj;
return tmp;
}
vec3 etk::Matrix3::operator * (const vec3& _point) const {
return vec3(_point.x()*m_mat[0] + _point.y()*m_mat[1] + _point.z()*m_mat[2],
_point.x()*m_mat[3] + _point.y()*m_mat[4] + _point.z()*m_mat[5],
_point.x()*m_mat[6] + _point.y()*m_mat[7] + _point.z()*m_mat[8]);
}
const etk::Matrix3& etk::Matrix3::operator *= (float _value) {
m_mat[0] *= _value;
m_mat[1] *= _value;
m_mat[2] *= _value;
m_mat[3] *= _value;
m_mat[4] *= _value;
m_mat[5] *= _value;
m_mat[6] *= _value;
m_mat[7] *= _value;
m_mat[8] *= _value;
return *this;
}
etk::Matrix3 etk::Matrix3::operator * (float _value) const {
etk::Matrix3 tmp(*this);
tmp *= _value;
return tmp;
}
void etk::Matrix3::inverse() {
*this = getInverse();
}
etk::Matrix3 etk::Matrix3::getInverse() const {
float det = determinant();
//assert(std::abs(det) > MACHINE_EPSILON);
float invDet = 1.0f / det;
return etk::Matrix3( (m_mat[4]*m_mat[8]-m_mat[7]*m_mat[5]),
-(m_mat[1]*m_mat[8]-m_mat[7]*m_mat[2]),
(m_mat[1]*m_mat[5]-m_mat[2]*m_mat[4]),
-(m_mat[3]*m_mat[8]-m_mat[6]*m_mat[5]),
(m_mat[0]*m_mat[8]-m_mat[6]*m_mat[2]),
-(m_mat[0]*m_mat[5]-m_mat[3]*m_mat[2]),
(m_mat[3]*m_mat[7]-m_mat[6]*m_mat[4]),
-(m_mat[0]*m_mat[7]-m_mat[6]*m_mat[1]),
(m_mat[0]*m_mat[4]-m_mat[1]*m_mat[3]))* invDet;
}
etk::Matrix3 etk::Matrix3::computeSkewSymmetricMatrixForCrossProduct(const vec3& vector) {
return etk::Matrix3( 0.0f , -vector.z(), vector.y(),
vector.z(), 0.0f , -vector.x(),
-vector.y(), vector.x(), 0.0f);
}
etk::Matrix3 operator-(const etk::Matrix3& _matrix) {
return etk::Matrix3(-_matrix.m_mat[0], -_matrix.m_mat[1], -_matrix.m_mat[2],
-_matrix.m_mat[3], -_matrix.m_mat[4], -_matrix.m_mat[5],
-_matrix.m_mat[6], -_matrix.m_mat[7], -_matrix.m_mat[8]);
}

222
etk/math/Matrix3.hpp Normal file
View File

@ -0,0 +1,222 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
#pragma once
#include <etk/types.hpp>
#include <etk/math/Vector3D.hpp>
#include <cmath>
namespace etk {
/**
* @brief This class represents a 3x3 matrix.
*/
class Matrix3 {
public:
float m_mat[3*3]; //!< matrix data
public :
/**
* @brief Constructor that load zero matrix
*/
Matrix3();
/**
* @brief Configuration constructorwith single value.
* @param[in] _value single vamue
*/
Matrix3(float value);
/**
* @brief Configuration constructor.
* @param[in] _a1 element 0x0
* @param[in] _a2 element 0x1
* @param[in] _a3 element 0x2
* @param[in] _b1 element 1x0
* @param[in] _b2 element 1x1
* @param[in] _b3 element 1x2
* @param[in] _c1 element 2x0
* @param[in] _c2 element 2x1
* @param[in] _c3 element 2x2
*/
Matrix3(float _a1, float _a2, float _a3,
float _b1, float _b2, float _b3,
float _c1, float _c2, float _c3);
/**
* @brief Copy constructor.
* @param[in] _obj Matrix object to copy
*/
Matrix3(const Matrix3& _obj);
/**
* @brief Set Value on the matrix
* @param[in] _a1 element 0x0
* @param[in] _a2 element 0x1
* @param[in] _a3 element 0x2
* @param[in] _b1 element 1x0
* @param[in] _b2 element 1x1
* @param[in] _b3 element 1x2
* @param[in] _c1 element 2x0
* @param[in] _c2 element 2x1
* @param[in] _c3 element 2x2
*/
void setValue(float _a1, float _a2, float _a3,
float _b1, float _b2, float _b3,
float _c1, float _c2, float _c3);
/**
* @brief Load Zero matrix
*/
void setZero();
/**
* @brief get the colom id values
* @param[in] _iii Id of the colomn
* @return Vector 3D vith the values
*/
vec3 getColumn(uint32_t _iii) const;
/**
* @brief get the row id values
* @param[in] _iii Id of the row
* @return Vector 3D vith the values
*/
vec3 getRow(uint32_t _iii) const;
/**
* @brief get a transpose matrix of this one.
* @return the transpose matrix
*/
Matrix3 getTranspose() const;
/**
* @brief Transpose the current matrix.
*/
void transpose();
/**
* @brief Computes the determinant of the matrix.
* @return The determinent Value.
*/
float determinant() const;
/**
* @brief Calculate the trace of the matrix
* @return value of addition of all element in the diagonal
*/
float getTrace() const;
/**
* @brief Inverts the matrix.
* @note The determinant must be != 0, otherwithe the matrix can't be inverted.
* @return The inverted matrix.
*/
Matrix3 getInverse() const;
/**
* @brief Inverts the current matrix.
* @note The determinant must be != 0, otherwithe the matrix can't be inverted.
*/
void inverse();
/**
* @brief get the matrix with the absolute value
* @return matix in absolute
*/
Matrix3 getAbsolute() const;
/**
* @brief absolutise the matrix
*/
void absolute();
/**
* @brief Load Identity matrix
*/
void setIdentity();
/**
* @brief create a Identity matrix
* @return created new matrix
*/
static Matrix3 identity();
/**
* @brief create a ZERO matrix
* @return created new matrix
*/
static Matrix3 zero();
/**
* @brief create a skew-symmetric matrix using a given vector that can be used to compute cross product with another vector using matrix multiplication
* @param[in] _vector Vector to comute
* @return Matrix to compute
*/
static Matrix3 computeSkewSymmetricMatrixForCrossProduct(const vec3& _vector);
/**
* @brief Operator= Asign the current object with an other object
* @param[in] _obj Reference on the external object
* @return Local reference of the vector asigned
*/
const Matrix3& operator= (const Matrix3& _obj );
/**
* @brief Equality compare operator with an other object.
* @param[in] _obj Reference on the comparing object
* @return true The Objects are identical
* @return false The Objects are NOT identical
*/
bool operator== (const Matrix3& _obj) const;
/**
* @brief In-Equality compare operator with an other object.
* @param[in] _obj Reference on the comparing object
* @return true The Objects are NOT identical
* @return false The Objects are identical
*/
bool operator!= (const Matrix3& _obj) const;
/**
* @brief Operator+= Addition an other matrix with this one
* @param[in] _obj Reference on the external object
* @return Local reference of the vector additionned
*/
const Matrix3& operator+= (const Matrix3& _obj);
/**
* @brief Operator+ Addition an other matrix with this one
* @param[in] _obj Reference on the external object
* @return New vector containing the value
*/
Matrix3 operator+ (const Matrix3& _obj) const;
/**
* @brief Operator-= Decrement an other matrix with this one
* @param[in] _obj Reference on the external object
* @return Local reference of the vector decremented
*/
const Matrix3& operator-= (const Matrix3& _obj);
/**
* @brief Operator- Decrement an other matrix with this one
* @param[in] _obj Reference on the external object
* @return New vector containing the value
*/
Matrix3 operator- (const Matrix3& _obj) const;
/**
* @brief Operator*= Multiplication an other matrix with this one
* @param[in] _obj Reference on the external object
* @return Local reference of the vector multiplicated
*/
const Matrix3& operator *= (const Matrix3& _obj);
/**
* @brief Operator* Multiplication an other matrix with this one
* @param[in] _obj Reference on the external object
* @return New vector containing the value
*/
Matrix3 operator * (const Matrix3& _obj) const;
/**
* @brief Operator*= Multiplication a value
* @param[in] _value value to multiply all the matrix
* @return Local reference of the vector multiplicated
*/
const Matrix3& operator *= (float _value);
/**
* @brief Operator*= Multiplication a value
* @param[in] _value value to multiply all the matrix
* @return Local reference of the vector multiplicated
*/
Matrix3 operator * (float _value) const;
/**
* @brief Operator* apply matrix on a vector
* @param[in] _point Point value to apply the matrix
* @return New vector containing the value
*/
vec3 operator * (const vec3& _point) const;
};
//! @not_in_doc
std::ostream& operator <<(std::ostream& _os, const etk::Matrix3& _obj);
}
etk::Matrix3 operator-(const etk::Matrix3& _matrix);
// simplify using of matrix ...
using mat3 = etk::Matrix3; //!< Use simplification in upper application to use matrix like openGL shader

View File

@ -346,7 +346,7 @@ float etk::Matrix4::determinant() const {
etk::Matrix4 etk::Matrix4::invert() {
float det = determinant();
if(fabsf(det) < (1.0e-7f)) {
if(std::abs(det) < (1.0e-7f)) {
// The matrix is not invertible! Singular case!
return *this;
}

View File

@ -32,7 +32,7 @@ namespace etk {
return _val*T(180.0)/M_PI;
}
/**
* @brief Transformation matrix for vector 3D.
* @brief This class represents a 4x4 matrix.
*/
class Matrix4 {
public:
@ -238,7 +238,8 @@ namespace etk {
*/
Matrix4 matRotate(vec3 _normal, float _angleRad=0.0);
//! @not_in_doc
Matrix4 matRotate2(vec3 _vect); /**
Matrix4 matRotate2(vec3 _vect);
/**
* @brief Create projection matrix with camera property (camera view in -z axis)
* @param[in] _eye Optical center of the camera
* @param[in] _target Point of where the camera is showing

153
etk/math/Quaternion.cpp Normal file
View File

@ -0,0 +1,153 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
#include <etk/math/Quaternion.hpp>
std::ostream& etk::operator <<(std::ostream &_os, const etk::Quaternion& _obj) {
_os << "(";
_os << _obj.x();
_os << ",";
_os << _obj.y();
_os << ",";
_os << _obj.z();
_os << ",";
_os << _obj.w();
_os << ")";
return _os;
}
etk::Quaternion::Quaternion(const etk::Matrix3& _matrix) {
float trace = _matrix.getTrace();
if (trace < 0.0f) {
if (_matrix.m_mat[4] > _matrix.m_mat[0]) {
if(_matrix.m_mat[8] > _matrix.m_mat[4]) {
float rrr = sqrt(_matrix.m_mat[8] - _matrix.m_mat[0] - _matrix.m_mat[4] + 1.0f);
float sss = 0.5f / rrr;
m_floats[0] = (_matrix.m_mat[6] + _matrix.m_mat[2]) * sss;
m_floats[1] = (_matrix.m_mat[5] + _matrix.m_mat[7]) * sss;
m_floats[2] = 0.5f * rrr;
m_floats[3] = (_matrix.m_mat[3] - _matrix.m_mat[1]) * sss;
} else {
float rrr = sqrt(_matrix.m_mat[4] - _matrix.m_mat[8] - _matrix.m_mat[0] + 1.0f);
float sss = 0.5f / rrr;
m_floats[0] = (_matrix.m_mat[1] + _matrix.m_mat[3]) * sss;
m_floats[1] = 0.5f * rrr;
m_floats[2] = (_matrix.m_mat[5] + _matrix.m_mat[7]) * sss;
m_floats[3] = (_matrix.m_mat[2] - _matrix.m_mat[6]) * sss;
}
} else if (_matrix.m_mat[8] > _matrix.m_mat[0]) {
float rrr = sqrt(_matrix.m_mat[8] - _matrix.m_mat[0] - _matrix.m_mat[4] + 1.0f);
float sss = 0.5f / rrr;
m_floats[0] = (_matrix.m_mat[6] + _matrix.m_mat[2]) * sss;
m_floats[1] = (_matrix.m_mat[5] + _matrix.m_mat[7]) * sss;
m_floats[2] = 0.5f * rrr;
m_floats[3] = (_matrix.m_mat[3] - _matrix.m_mat[1]) * sss;
} else {
float rrr = sqrt(_matrix.m_mat[0] - _matrix.m_mat[4] - _matrix.m_mat[8] + 1.0f);
float sss = 0.5f / rrr;
m_floats[0] = 0.5f * rrr;
m_floats[1] = (_matrix.m_mat[1] + _matrix.m_mat[3]) * sss;
m_floats[2] = (_matrix.m_mat[6] - _matrix.m_mat[2]) * sss;
m_floats[3] = (_matrix.m_mat[7] - _matrix.m_mat[5]) * sss;
}
} else {
float rrr = sqrt(trace + 1.0f);
float sss = 0.5f / rrr;
m_floats[0] = (_matrix.m_mat[7] - _matrix.m_mat[5]) * sss;
m_floats[1] = (_matrix.m_mat[2] - _matrix.m_mat[6]) * sss;
m_floats[2] = (_matrix.m_mat[3] - _matrix.m_mat[1]) * sss;
m_floats[3] = 0.5f * rrr;
}
}
void etk::Quaternion::getAngleAxis(float& _angle, vec3& _axis) const {
etk::Quaternion quaternion = getUnit();
_angle = acos(quaternion.w()) * 2.0f;
vec3 rotationAxis(quaternion.x(), quaternion.y(), quaternion.z());
rotationAxis = rotationAxis.normalized();
_axis.setValue(rotationAxis.x(), rotationAxis.y(), rotationAxis.z());
}
etk::Matrix3 etk::Quaternion::getMatrix() const {
float nQ = m_floats[0]*m_floats[0]
+ m_floats[1]*m_floats[1]
+ m_floats[2]*m_floats[2]
+ m_floats[3]*m_floats[3];
float sss = 0.0f;
if (nQ > 0.0f) {
sss = 2.0f / nQ;
}
float xs = m_floats[0]*sss;
float ys = m_floats[1]*sss;
float zs = m_floats[2]*sss;
float wxs = m_floats[3]*xs;
float wys = m_floats[3]*ys;
float wzs = m_floats[3]*zs;
float xxs = m_floats[0]*xs;
float xys = m_floats[0]*ys;
float xzs = m_floats[0]*zs;
float yys = m_floats[1]*ys;
float yzs = m_floats[1]*zs;
float zzs = m_floats[2]*zs;
return etk::Matrix3(1.0f - yys - zzs,
xys - wzs,
xzs + wys,
xys + wzs,
1.0f - xxs - zzs,
yzs - wxs,
xzs - wys,
yzs + wxs,
1.0f - xxs - yys);
}
etk::Quaternion etk::Quaternion::slerp(const Quaternion& _obj1,
const Quaternion& _obj2,
float _ttt) {
TK_ASSERT(_ttt >= 0.0f && _ttt <= 1.0f, "wrong intermolation");
float invert = 1.0f;
float cosineTheta = _obj1.dot(_obj2);
if (cosineTheta < 0.0f) {
cosineTheta = -cosineTheta;
invert = -1.0f;
}
if(1-cosineTheta < 0.00001f) {
return _obj1 * (1.0f-_ttt) + _obj2 * (_ttt * invert);
}
float theta = acos(cosineTheta);
float sineTheta = sin(theta);
float coeff1 = sin((1.0f-_ttt)*theta) / sineTheta;
float coeff2 = sin(_ttt*theta) / sineTheta * invert;
return _obj1 * coeff1 + _obj2 * coeff2;
}
void etk::Quaternion::setEulerAngles(const vec3& _angles) {
float angle = _angles.x() * 0.5f;
float sinX = std::sin(angle);
float cosX = std::cos(angle);
angle = _angles.y() * 0.5f;
float sinY = std::sin(angle);
float cosY = std::cos(angle);
angle = _angles.z() * 0.5f;
float sinZ = std::sin(angle);
float cosZ = std::cos(angle);
float cosYcosZ = cosY * cosZ;
float sinYcosZ = sinY * cosZ;
float cosYsinZ = cosY * sinZ;
float sinYsinZ = sinY * sinZ;
m_floats[0] = sinX * cosYcosZ - cosX * sinYsinZ;
m_floats[1] = cosX * sinYcosZ + sinX * cosYsinZ;
m_floats[2] = cosX * cosYsinZ - sinX * sinYcosZ;
m_floats[3] = cosX * cosYcosZ + sinX * sinYsinZ;
normalize();
}
etk::Quaternion etk::Quaternion::zero() {
return etk::Quaternion(0,0,0,0);
}
etk::Quaternion etk::Quaternion::identity() {
return etk::Quaternion(0,0,0,1);
}

547
etk/math/Quaternion.hpp Normal file
View File

@ -0,0 +1,547 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
#pragma once
#include <etk/types.hpp>
#include <cmath>
#include <etk/math/Matrix3.hpp>
#include <etk/math/Vector3D.hpp>
namespace etk {
/**
* @brief This class represents a quaternion.
*/
struct Quaternion {
public:
float m_floats[4]; //!< all internal values
public:
/**
* @brief No initialization constructor (faster ...)
*/
Quaternion() {
m_floats[0] = 0.0f;
m_floats[1] = 0.0f;
m_floats[2] = 0.0f;
m_floats[3] = 0.0f;
}
/**
* @brief Constructor from scalars.
* @param _xxx X value
* @param _yyy Y value
* @param _zzz Z value
* @param _www W value
*/
Quaternion(const float& _xxx, const float& _yyy, const float& _zzz, const float& _www) {
m_floats[0] = _xxx;
m_floats[1] = _yyy;
m_floats[2] = _zzz;
m_floats[3] = _www;
}
/**
* @brief Constructor with the component w and a vector 3D.
* @param _www W value
* @param _vec 3D vector value
*/
Quaternion(float _www, const vec3& _vec) {
m_floats[0] = _vec.x();
m_floats[1] = _vec.y();
m_floats[2] = _vec.z();
m_floats[3] = _www;
}
/**
* @brief Constructor with Euler angles (in radians) to a quaternion
* @param _eulerAngles list of all euleu angle
*/
Quaternion(const vec3& _eulerAngles) {
setEulerAngles(_eulerAngles);
}
/**
* @brief Create a unit quaternion from a rotation matrix
* @param _matrix generic matrix
*/
Quaternion(const etk::Matrix3& _matrix);
/**
* @brief Add a vector to this one.
* @param[in] _obj The vector to add to this one
* @return Local reference of the vector
*/
Quaternion& operator+=(const Quaternion& _obj) {
m_floats[0] += _obj.m_floats[0];
m_floats[1] += _obj.m_floats[1];
m_floats[2] += _obj.m_floats[2];
m_floats[3] += _obj.m_floats[3];
return *this;
}
/**
* @brief Add a vector to this one.
* @param[in] _obj The vector to add to this one
* @return New vector containing the value
*/
Quaternion operator+(const Quaternion& _obj) {
return Quaternion(m_floats[0] + _obj.m_floats[0],
m_floats[1] + _obj.m_floats[1],
m_floats[2] + _obj.m_floats[2],
m_floats[3] + _obj.m_floats[3]);
}
/**
* @brief Subtract a vector from this one
* @param _obj The vector to subtract
* @return Local reference of the vector
*/
Quaternion& operator-=(const Quaternion& _obj) {
m_floats[0] -= _obj.m_floats[0];
m_floats[1] -= _obj.m_floats[1];
m_floats[2] -= _obj.m_floats[2];
m_floats[3] -= _obj.m_floats[3];
return *this;
}
/**
* @brief Subtract a vector from this one
* @param _obj The vector to subtract
* @return New quaternion containing the value
*/
Quaternion operator-(const Quaternion& _obj) {
return Quaternion(m_floats[0] - _obj.m_floats[0],
m_floats[1] - _obj.m_floats[1],
m_floats[2] - _obj.m_floats[2],
m_floats[3] - _obj.m_floats[3]);
}
/**
* @brief Scale the quaternion
* @param[in] _val Scale factor
* @return Local reference of the quaternion
*/
Quaternion& operator*=(const float& _val) {
m_floats[0] *= _val;
m_floats[1] *= _val;
m_floats[2] *= _val;
m_floats[3] *= _val;
return *this;
}
/**
* @brief Scale the quaternion
* @param[in] _val Scale factor
* @return New quaternion containing the value
*/
Quaternion operator*(const float& _val) const {
return Quaternion(m_floats[0] * _val,
m_floats[1] * _val,
m_floats[2] * _val,
m_floats[3] * _val);
}
/**
* @brief Inversely scale the quaternion
* @param[in] _val Scale factor to divide by.
* @return Local reference of the quaternion
*/
Quaternion& operator/=(const float& _val) {
if (_val != 0) {
m_floats[0] /= _val;
m_floats[1] /= _val;
m_floats[2] /= _val;
m_floats[3] /= _val;
return *this;
}
return *this;
}
/**
* @brief Inversely scale the quaternion
* @param[in] _val Scale factor to divide by.
* @return New quaternion containing the value
*/
Quaternion operator/(const float& _val) const {
if (_val != 0) {
return Quaternion(m_floats[0] / _val,
m_floats[1] / _val,
m_floats[2] / _val,
m_floats[3] / _val);
}
return *this;
}
/**
* @brief Return the dot product
* @param _obj The other quaternion in the dot product
* @return Dot result value
*/
float dot(const Quaternion& _obj) const {
return m_floats[0] * _obj.m_floats[0]
+ m_floats[1] * _obj.m_floats[1]
+ m_floats[2] * _obj.m_floats[2]
+ m_floats[3] * _obj.m_floats[3];
}
/**
* @brief Return the squared length of the quaternion.
* @return Squared length value.
*/
float length2() const {
return dot(*this);
}
/**
* @brief Return the length of the quaternion
* @return Length value
*/
float length() const {
#if __CPP_VERSION__ >= 2011 && !defined(__TARGET_OS__MacOs) && !defined(__TARGET_OS__IOs)
return std::sqrt(length2());
#else
return sqrt(length2());
#endif
}
/**
* @brief Return the distance squared between the ends of this and another quaternion
* This is symantically treating the quaternion like a point
* @param[in] _obj The other quaternion to compare distance
* @return the square distance of the 2 points
*/
/*
float distance2(const Quaternion& _obj) const {
return (_obj - *this).length2();
}
*/
/**
* @brief Return the distance between the ends of this and another quaternion
* This is symantically treating the quaternion like a point
* @param[in] _obj The other quaternion to compare distance
* @return the distance of the 2 points
*/
/*
float distance(const Quaternion& _obj) const {
return (_obj - *this).length();
}
*/
/**
* @brief Normalize this quaternion x^2 + y^2 + z^2 + w^2 = 1
* @return Local reference of the quaternion normalized
*/
Quaternion& normalize() {
float invLength = 1.0f / length();
m_floats[0] *= invLength;
m_floats[1] *= invLength;
m_floats[2] *= invLength;
m_floats[3] *= invLength;
return *this;
}
/**
* @brief Return a normalized version of this quaternion
* @return New quaternion containing the value
*/
Quaternion normalized() const {
etk::Quaternion tmp = *this;
tmp.normalize();
return tmp;
}
/**
* @brief Return a quaternion will the absolute values of each element
* @return New quaternion with the absolute value
*/
Quaternion absolute() const {
return Quaternion( std::abs(m_floats[0]),
std::abs(m_floats[1]),
std::abs(m_floats[2]),
std::abs(m_floats[3]));
}
/**
* @brief Get X value
* @return the x value
*/
const float& getX() const {
return m_floats[0];
}
/**
* @brief Get Y value
* @return the y value
*/
const float& getY() const {
return m_floats[1];
}
/**
* @brief Get Z value
* @return the z value
*/
const float& getZ() const {
return m_floats[2];
}
/**
* @brief Get W value
* @return the w value
*/
const float& getW() const {
return m_floats[3];
}
/**
* @brief Set the x value
* @param[in] _x New value
*/
void setX(float _x) {
m_floats[0] = _x;
};
/**
* @brief Set the y value
* @param[in] _y New value
*/
void setY(float _y) {
m_floats[1] = _y;
};
/**
* @brief Set the z value
* @param[in] _z New value
*/
void setZ(float _z) {
m_floats[2] = _z;
};
/**
* @brief Set the w value
* @param[in] _w New value
*/
void setW(float _w) {
m_floats[3] = _w;
};
/**
* @brief Get X value
* @return the x value
*/
const float& x() const {
return m_floats[0];
}
/**
* @brief Get Y value
* @return the y value
*/
const float& y() const {
return m_floats[1];
}
/**
* @brief Get Z value
* @return the z value
*/
const float& z() const {
return m_floats[2];
}
/**
* @brief Get W value
* @return the w value
*/
const float& w() const {
return m_floats[3];
}
/**
* @brief Cast the quaternion in the type T* requested.
* @return Pointer on the data
*/
operator float *() {
return &m_floats[0];
}
/**
* @brief Cast the quaternion in the type const float* requested.
* @return Pointer on the const data
*/
operator const float *() const {
return &m_floats[0];
}
/**
* @brief Equality compare operator with an other object.
* @param[in] _obj Reference on the comparing object
* @return true The Objects are identical
* @return false The Objects are NOT identical
*/
bool operator==(const Quaternion& _obj) const {
return ( (m_floats[3] == _obj.m_floats[3])
&& (m_floats[2] == _obj.m_floats[2])
&& (m_floats[1] == _obj.m_floats[1])
&& (m_floats[0] == _obj.m_floats[0]));
}
/**
* @brief In-Equality compare operator with an other object.
* @param[in] _obj Reference on the comparing object
* @return true The Objects are NOT identical
* @return false The Objects are identical
*/
bool operator!=(const Quaternion& _obj) const {
return ( (m_floats[3] != _obj.m_floats[3])
|| (m_floats[2] != _obj.m_floats[2])
|| (m_floats[1] != _obj.m_floats[1])
|| (m_floats[0] != _obj.m_floats[0]));
}
/**
* @brief Multiply this quaternion by the other.
* @param _obj The other quaternion
* @return Local reference of the quaternion
*/
Quaternion& operator*=(const Quaternion& _obj) {
vec3 base = getVectorV();
vec3 crossValue = base.cross(_obj.getVectorV());
m_floats[0] = m_floats[3] * _obj.m_floats[0] + _obj.m_floats[3] * m_floats[0] + crossValue.x();
m_floats[1] = m_floats[3] * _obj.m_floats[1] + _obj.m_floats[3] * m_floats[1] + crossValue.y();
m_floats[2] = m_floats[3] * _obj.m_floats[2] + _obj.m_floats[3] * m_floats[2] + crossValue.z();
m_floats[3] = m_floats[3] * _obj.m_floats[3] - base.dot(_obj.getVectorV());
return *this;
}
/**
* @brief Multiply this quaternion by the other.
* @param _obj The other quaternion
* @return New quaternion containing the value
*/
Quaternion operator*(const Quaternion& _obj) const {
etk::Quaternion tmp = *this;
tmp *= _obj;
return tmp;
}
/**
* @brief Operator* with a vector. This methods rotates a point given the rotation of a quaternion
* @param[in] _point Point to move
* @return Point with the updated position
*/
vec3 operator*(const vec3& _point) const {
// TODO :Xheck this ==> if seams a little complicated ...
Quaternion p(0.0, _point);
return (((*this) * p) * getConjugate()).getVectorV();
}
/**
* @brief Set each element to the max of the current values and the values of another Vector
* @param _obj The other Vector to compare with
*/
void setMax(const Quaternion& _obj) {
std::max(m_floats[0], _obj.m_floats[0]);
std::max(m_floats[1], _obj.m_floats[1]);
std::max(m_floats[2], _obj.m_floats[2]);
std::max(m_floats[3], _obj.m_floats[3]);
}
/**
* @brief Set each element to the min of the current values and the values of another Vector
* @param _obj The other Vector to compare with
*/
void setMin(const Quaternion& _obj) {
std::min(m_floats[0], _obj.m_floats[0]);
std::min(m_floats[1], _obj.m_floats[1]);
std::min(m_floats[2], _obj.m_floats[2]);
std::min(m_floats[3], _obj.m_floats[3]);
}
/**
* @brief Set Value on the quaternion
* @param[in] _xxx X value.
* @param[in] _yyy Y value.
* @param[in] _zzz Z value.
* @param[in] _www W value.
*/
void setValue(const float& _xxx, const float& _yyy, const float& _zzz, const float& _www) {
m_floats[0]=_xxx;
m_floats[1]=_yyy;
m_floats[2]=_zzz;
m_floats[3]=_www;
}
/**
* @brief Set 0 value on all the quaternion
*/
void setZero() {
setValue(0,0,0,0);
}
/**
* @brief get a 0 value on all a quaternion
* @return a zero quaternion
*/
static Quaternion zero();
/**
* @brief Check if the quaternion is equal to (0,0,0,0)
* @return true The value is equal to (0,0,0,0)
* @return false The value is NOT equal to (0,0,0,0)
*/
bool isZero() const {
return m_floats[0] == 0
&& m_floats[1] == 0
&& m_floats[2] == 0
&& m_floats[3] == 0;
}
/**
* @brief Set identity value at the quaternion
*/
void setIdentity() {
setValue(0,0,0,1);
}
/**
* @brief get an identity quaternion
* @return an identity quaternion
*/
static Quaternion identity();
/**
* @brief get x, y, z in a vec3
*/
vec3 getVectorV() const {
return vec3(m_floats[0],
m_floats[1],
m_floats[2]);
}
/**
* @brief Inverse the quaternion
*/
void inverse() {
float invLengthSquare = 1.0f / length2();
m_floats[0] *= -invLengthSquare;
m_floats[1] *= -invLengthSquare;
m_floats[2] *= -invLengthSquare;
m_floats[3] *= invLengthSquare;
}
/**
* @brief Return the inverse of the quaternion
* @return inverted quaternion
*/
Quaternion getInverse() const {
etk::Quaternion tmp = *this;
tmp.inverse();
return tmp;
}
/**
* @brief Return the unit quaternion
* @return Quaternion unitarised
*/
Quaternion getUnit() const {
return normalized();
}
/**
* @brief Conjugate the quaternion
*/
void conjugate() {
m_floats[0] *= -1.0f;
m_floats[1] *= -1.0f;
m_floats[2] *= -1.0f;
}
/**
* @brief Return the conjugate of the quaternion
* @return Conjugate quaternion
*/
Quaternion getConjugate() const {
etk::Quaternion tmp = *this;
tmp.conjugate();
return tmp;
}
/**
* @brief Compute the rotation angle (in radians) and the rotation axis
* @param[out] _angle Angle of the quaternion
* @param[out] _axis Axis of the quaternion
*/
void getAngleAxis(float& _angle, vec3& _axis) const;
/**
* @brief Get the orientation matrix corresponding to this quaternion
* @return the 3x3 transformation matrix
*/
etk::Matrix3 getMatrix() const;
/**
* @brief Compute the spherical linear interpolation between two quaternions.
* @param[in] _obj1 First quaternion
* @param[in] _obj2 Second quaternion
* @param[in] _ttt linar coefficient interpolation to be such that [0..1]
*/
Quaternion slerp(const Quaternion& _obj1, const Quaternion& _obj2, float _ttt);
/**
* @brief Configure the quaternion with euler angles.
* @param[out] _angles Eular angle of the quaternion.
*/
void setEulerAngles(const vec3& _angles);
};
//! @not_in_doc
std::ostream& operator <<(std::ostream& _os, const etk::Quaternion& _obj);
}

0
etk/math/Transform.cpp Normal file
View File

145
etk/math/Transform.hpp Normal file
View File

@ -0,0 +1,145 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
#pragma once
#include <etk/types.hpp>
// Libraries
#include <etk/math/Matrix3x3.hpp>
#include <etk/math/Vector3D.hpp>
#include <etk/math/Quaternion.hpp>
namespace etk {
/**
* @brief This class represents a position and an orientation in 3D. It can also be seen as representing a translation and a rotation.
*/
class Transform {
public:
Transform():
m_position(vec3(0.0, 0.0, 0.0)),
m_orientation(Quaternion::identity()) {
}
Transform(const vec3& _position, const Matrix3x3& _orientation):
m_position(_position),
m_orientation(Quaternion(_orientation)) {
}
Transform(const vec3& _position, const Quaternion& _orientation):
m_position(_position),
m_orientation(_orientation) {
}
Transform(const Transform& _other):
m_position(_other.m_position),
m_orientation(_other.m_orientation) {
}
protected:
vec3 m_position; //! Position
public:
/// Return the origin of the transform
const vec3& getPosition() const {
return m_position;
}
/// Set the origin of the transform
void setPosition(const vec3& _position) {
m_position = _position;
}
protected:
Quaternion m_orientation; //!< Orientation
public:
/// Return the orientation quaternion
const Quaternion& getOrientation() const {
return m_orientation;
}
/// Set the rotation quaternion
void setOrientation(const Quaternion& _orientation) {
m_orientation = _orientation;
}
public:
/// Set the transform to the identity transform
void setToIdentity() {
m_position = vec3(0.0, 0.0, 0.0);
m_orientation = Quaternion::identity();
}
/// Set the transform from an OpenGL transform matrix
void setFromOpenGL(float* _matrix) {
Matrix3x3 matrix(_matrix[0], _matrix[4], _matrix[8],
_matrix[1], _matrix[5], _matrix[9],
_matrix[2], _matrix[6], _matrix[10]);
m_orientation = Quaternion(matrix);
m_position.setValue(_matrix[12], _matrix[13], _matrix[14]);
}
/// Get the OpenGL matrix of the transform
void getOpenGLMatrix(float* _matrix) const {
const Matrix3x3& matrix = m_orientation.getMatrix();
_matrix[0] = matrix[0][0];
_matrix[1] = matrix[1][0];
_matrix[2] = matrix[2][0];
_matrix[3] = 0.0;
_matrix[4] = matrix[0][1];
_matrix[5] = matrix[1][1];
_matrix[6] = matrix[2][1];
_matrix[7] = 0.0;
_matrix[8] = matrix[0][2];
_matrix[9] = matrix[1][2];
_matrix[10] = matrix[2][2];
_matrix[11] = 0.0;
_matrix[12] = m_position.x();
_matrix[13] = m_position.y();
_matrix[14] = m_position.z();
_matrix[15] = 1.0;
}
/// Return the inverse of the transform
Transform getInverse() const {
const Quaternion& invQuaternion = m_orientation.getInverse();
Matrix3x3 invMatrix = invQuaternion.getMatrix();
return Transform(invMatrix * (-m_position), invQuaternion);
}
/// Return an interpolated transform
Transform interpolateTransforms(const Transform& _old,
const Transform& _new,
float _interpolationFactor) {
vec3 interPosition = _old.m_position * (decimal(1.0) - _interpolationFactor) +
_new.m_position * _interpolationFactor;
Quaternion interOrientation = Quaternion::slerp(_old.m_orientation,
_naw.m_orientation,
_interpolationFactor);
return Transform(interPosition, interOrientation);
}
/// Return the identity transform
Transform identity() {
return Transform(vec3(0, 0, 0), Quaternion::identity());
}
/// Return the transformed vector
vec3 operator*(const vec3& _vector) const {
return (m_orientation.getMatrix() * _vector) + m_position;
}
/// Operator of multiplication of a transform with another one
Transform operator*(const Transform& _transform2) const {
return Transform(m_position + m_orientation.getMatrix() * _transform2.m_position,
m_orientation * _transform2.m_orientation);
}
/// Return true if the two transforms are equal
bool operator==(const Transform& _transform2) const {
return (m_position == _transform2.m_position) && (m_orientation == _transform2.m_orientation);
}
/// Return true if the two transforms are different
bool operator!=(const Transform& _transform2) const {
return !(*this == _transform2);
}
/// Assignment operator
Transform& operator=(const Transform& _transform) {
if (&_transform != this) {
m_position = _transform.m_position;
m_orientation = _transform.m_orientation;
}
return *this;
}
};
}

View File

@ -15,9 +15,9 @@ namespace etk {
/**
* @brief Vectorial 2-dimention vector (x/y)
*/
template <typename T> class Vector2D {
template <typename ETK_TYPE> class Vector2D {
public:
T m_floats[2]; //!< all internal values
ETK_TYPE m_floats[2]; //!< all internal values
public:
/* ****************************************************
* Constructor
@ -25,16 +25,18 @@ namespace etk {
Vector2D() {
#ifdef DEBUG
// in debug mode we set supid value to prevent forget of the inits ...
m_floats[0] = (T)34673363;
m_floats[1] = (T)34523535;
m_floats[0] = (ETK_TYPE)34673363;
m_floats[1] = (ETK_TYPE)34523535;
#endif
m_floats[0] = (ETK_TYPE)0;
m_floats[1] = (ETK_TYPE)0;
}
/**
* @brief Constructor from scalars
* @param[in] _xxx X value
* @param[in] _yyy Y value
*/
Vector2D(T _xxx, T _yyy) {
Vector2D(ETK_TYPE _xxx, ETK_TYPE _yyy) {
m_floats[0] = _xxx;
m_floats[1] = _yyy;
}
@ -43,24 +45,24 @@ namespace etk {
* @param[in] _obj The vector to add to this one
*/
Vector2D(const Vector2D<double>& _obj) {
m_floats[0] = (T)_obj.x();
m_floats[1] = (T)_obj.y();
m_floats[0] = (ETK_TYPE)_obj.x();
m_floats[1] = (ETK_TYPE)_obj.y();
}
/**
* @brief Constructor with external vector
* @param[in] _obj The vector to add to this one
*/
Vector2D(const Vector2D<float>& _obj) {
m_floats[0] = (T)_obj.x();
m_floats[1] = (T)_obj.y();
m_floats[0] = (ETK_TYPE)_obj.x();
m_floats[1] = (ETK_TYPE)_obj.y();
}
/**
* @brief Constructor with external vector
* @param[in] _obj The vector to add to this one
*/
Vector2D(const Vector2D<int32_t>& _obj) {
m_floats[0] = (T)_obj.x();
m_floats[1] = (T)_obj.y();
m_floats[0] = (ETK_TYPE)_obj.x();
m_floats[1] = (ETK_TYPE)_obj.y();
}
/**
* @brief Constructor with string data
@ -75,7 +77,7 @@ namespace etk {
* @param[in] _obj Reference on the external object
* @return Local reference of the vector asigned
*/
const Vector2D<T>& operator= (const Vector2D<T>& _obj ) {
const Vector2D<ETK_TYPE>& operator= (const Vector2D<ETK_TYPE>& _obj ) {
m_floats[0] = _obj.m_floats[0];
m_floats[1] = _obj.m_floats[1];
return *this;
@ -85,7 +87,7 @@ namespace etk {
* @param[in] _val Value to assign on the object
* @return Local reference of the vector asigned
*/
const Vector2D<T>& operator= (const T _val ) {
const Vector2D<ETK_TYPE>& operator= (const ETK_TYPE _val ) {
m_floats[0] = _val;
m_floats[1] = _val;
return *this;
@ -96,9 +98,9 @@ namespace etk {
* @return true The Objects are identical
* @return false The Objects are NOT identical
*/
bool operator== (const Vector2D<T>& _obj) const {
return ( (T)_obj.m_floats[0] == m_floats[0]
&& (T)_obj.m_floats[1] == m_floats[1]);
bool operator== (const Vector2D<ETK_TYPE>& _obj) const {
return ( (ETK_TYPE)_obj.m_floats[0] == m_floats[0]
&& (ETK_TYPE)_obj.m_floats[1] == m_floats[1]);
}
/**
* @brief In-Equality compare operator with an other object.
@ -106,16 +108,16 @@ namespace etk {
* @return true The Objects are NOT identical
* @return false The Objects are identical
*/
bool operator!= (const Vector2D<T>& _obj) const {
return ( (T)_obj.m_floats[0] != m_floats[0]
|| (T)_obj.m_floats[1] != m_floats[1]);
bool operator!= (const Vector2D<ETK_TYPE>& _obj) const {
return ( (ETK_TYPE)_obj.m_floats[0] != m_floats[0]
|| (ETK_TYPE)_obj.m_floats[1] != m_floats[1]);
}
/**
* @brief Operator+= Addition an other vertor with this one
* @param[in] _obj Reference on the external object
* @return Local reference of the vector additionned
*/
const Vector2D<T>& operator+= (const Vector2D<T>& _obj) {
const Vector2D<ETK_TYPE>& operator+= (const Vector2D<ETK_TYPE>& _obj) {
m_floats[0] += _obj.m_floats[0];
m_floats[1] += _obj.m_floats[1];
return *this;
@ -125,7 +127,7 @@ namespace etk {
* @param[in] _val Value to addition at x/y
* @return Local reference of the vector additionned
*/
const Vector2D<T>& operator+= (const T _val) {
const Vector2D<ETK_TYPE>& operator+= (const ETK_TYPE _val) {
m_floats[0] += _val;
m_floats[1] += _val;
return *this;
@ -135,8 +137,8 @@ namespace etk {
* @param[in] _obj Reference on the external object
* @return New vector containing the value
*/
Vector2D<T> operator+ (const Vector2D<T>& _obj) const {
Vector2D<T> tmpp(m_floats[0],m_floats[1]);
Vector2D<ETK_TYPE> operator+ (const Vector2D<ETK_TYPE>& _obj) const {
Vector2D<ETK_TYPE> 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;
@ -146,8 +148,8 @@ namespace etk {
* @param[in] _val Value to addition at x/y
* @return New vector containing the value
*/
Vector2D<T> operator+ (const T _val) const {
Vector2D<T> tmpp(m_floats[0],m_floats[1]);
Vector2D<ETK_TYPE> operator+ (const ETK_TYPE _val) const {
Vector2D<ETK_TYPE> tmpp(m_floats[0],m_floats[1]);
tmpp.m_floats[0] += _val;
tmpp.m_floats[1] += _val;
return tmpp;
@ -157,7 +159,7 @@ namespace etk {
* @param[in] _obj Reference on the external object
* @return Local reference of the vector decremented
*/
const Vector2D<T>& operator-= (const Vector2D<T>& _obj) {
const Vector2D<ETK_TYPE>& operator-= (const Vector2D<ETK_TYPE>& _obj) {
m_floats[0] -= _obj.m_floats[0];
m_floats[1] -= _obj.m_floats[1];
return *this;
@ -167,7 +169,7 @@ namespace etk {
* @param[in] _val Value to addition at x/y
* @return Local reference of the vector decremented
*/
const Vector2D<T>& operator-= (const T _val) {
const Vector2D<ETK_TYPE>& operator-= (const ETK_TYPE _val) {
m_floats[0] -= _val;
m_floats[1] -= _val;
return *this;
@ -177,8 +179,8 @@ namespace etk {
* @param[in] _obj Reference on the external object
* @return New vector containing the value
*/
Vector2D<T> operator- (const Vector2D<T>& _obj) const {
Vector2D<T> tmpp(m_floats[0],m_floats[1]);
Vector2D<ETK_TYPE> operator- (const Vector2D<ETK_TYPE>& _obj) const {
Vector2D<ETK_TYPE> 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;
@ -188,8 +190,8 @@ namespace etk {
* @param[in] _val Value to addition at x/y
* @return New vector containing the value
*/
Vector2D<T> operator- (const T _val) const {
Vector2D<T> tmpp(m_floats[0],m_floats[1]);
Vector2D<ETK_TYPE> operator- (const ETK_TYPE _val) const {
Vector2D<ETK_TYPE> tmpp(m_floats[0],m_floats[1]);
tmpp.m_floats[0] -= _val;
tmpp.m_floats[1] -= _val;
return tmpp;
@ -199,7 +201,7 @@ namespace etk {
* @param[in] _obj Reference on the external object
* @return Local reference of the vector multiplicated
*/
const Vector2D<T>& operator*= (const Vector2D<T>& _obj) {
const Vector2D<ETK_TYPE>& operator*= (const Vector2D<ETK_TYPE>& _obj) {
m_floats[0] *= _obj.m_floats[0];
m_floats[1] *= _obj.m_floats[1];
return *this;
@ -209,7 +211,7 @@ namespace etk {
* @param[in] _val Value to addition at x/y
* @return Local reference of the vector multiplicated
*/
const Vector2D<T>& operator*= (const T _val) {
const Vector2D<ETK_TYPE>& operator*= (const ETK_TYPE _val) {
m_floats[0] *= _val;
m_floats[1] *= _val;
return *this;
@ -219,8 +221,8 @@ namespace etk {
* @param[in] _obj Reference on the external object
* @return New vector containing the value
*/
Vector2D<T> operator* (const Vector2D<T>& _obj) const {
Vector2D<T> tmpp(m_floats[0],m_floats[1]);
Vector2D<ETK_TYPE> operator* (const Vector2D<ETK_TYPE>& _obj) const {
Vector2D<ETK_TYPE> 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;
@ -230,8 +232,8 @@ namespace etk {
* @param[in] _val Value to addition at x/y
* @return New vector containing the value
*/
Vector2D<T> operator* (const T _val) const {
Vector2D<T> tmpp(m_floats[0],m_floats[1]);
Vector2D<ETK_TYPE> operator* (const ETK_TYPE _val) const {
Vector2D<ETK_TYPE> tmpp(m_floats[0],m_floats[1]);
tmpp.m_floats[0] *= _val;
tmpp.m_floats[1] *= _val;
return tmpp;
@ -241,8 +243,8 @@ namespace etk {
* @param[in] _obj Reference on the external object
* @return Local reference of the vector divided
*/
Vector2D<T> operator/ (const Vector2D<T>& _obj) const{
Vector2D<T> tmpp(m_floats[0], m_floats[1]);
Vector2D<ETK_TYPE> operator/ (const Vector2D<ETK_TYPE>& _obj) const{
Vector2D<ETK_TYPE> 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;
@ -252,8 +254,8 @@ namespace etk {
* @param[in] _val Value to addition at x/y
* @return Local reference of the vector divided
*/
Vector2D<T> operator/ (const T _val) const {
Vector2D<T> tmpp(m_floats[0], m_floats[1]);
Vector2D<ETK_TYPE> operator/ (const ETK_TYPE _val) const {
Vector2D<ETK_TYPE> tmpp(m_floats[0], m_floats[1]);
tmpp.m_floats[0] /= _val;
tmpp.m_floats[1] /= _val;
return tmpp;
@ -263,7 +265,7 @@ namespace etk {
* @param[in] _obj Reference on the external object
* @return New vector containing the value
*/
const Vector2D<T>& operator/= (const Vector2D<T>& _obj) {
const Vector2D<ETK_TYPE>& operator/= (const Vector2D<ETK_TYPE>& _obj) {
m_floats[0] /= _obj.m_floats[0];
m_floats[1] /= _obj.m_floats[1];
return *this;
@ -273,7 +275,7 @@ namespace etk {
* @param[in] _val Value to addition at x/y
* @return New vector containing the value
*/
const Vector2D<T>& operator/= (const T _val) {
const Vector2D<ETK_TYPE>& operator/= (const ETK_TYPE _val) {
m_floats[0] /= _val;
m_floats[1] /= _val;
return *this;
@ -282,7 +284,7 @@ namespace etk {
* @brief Operator++ Pre-incrementation of this vector
* @return Local reference of the vector incremented
*/
Vector2D<T>& operator++() {
Vector2D<ETK_TYPE>& operator++() {
++m_floats[0];
++m_floats[1];
return *this;
@ -291,8 +293,8 @@ namespace etk {
* @brief Operator++ Post-incrementation of this vector
* @return New vector containing the last value
*/
Vector2D<T> operator++(int) {
Vector2D<T> result = *this;
Vector2D<ETK_TYPE> operator++(int) {
Vector2D<ETK_TYPE> result = *this;
++(*this);
return result;
}
@ -300,7 +302,7 @@ namespace etk {
* @brief Operator++ Pre-decrementation of this vector
* @return Local reference of the vector incremented
*/
Vector2D<T>& operator--() {
Vector2D<ETK_TYPE>& operator--() {
--m_floats[0];
--m_floats[1];
return *this;
@ -309,8 +311,8 @@ namespace etk {
* @brief Operator++ Post-decrementation of this vector
* @return New vector containing the last value
*/
Vector2D<T> operator--(int) {
Vector2D<T> result = *this;
Vector2D<ETK_TYPE> operator--(int) {
Vector2D<ETK_TYPE> result = *this;
--(*this);
return result;
}
@ -319,7 +321,7 @@ namespace etk {
* @param _obj The other vector in the cross product
* @return cross product value
*/
T cross(const Vector2D<T>& _obj) const {
ETK_TYPE cross(const Vector2D<ETK_TYPE>& _obj) const {
return m_floats[0] * _obj.m_floats[1]
- m_floats[1] * _obj.m_floats[0];
}
@ -328,7 +330,7 @@ namespace etk {
* @param _obj The other vector in the dot product
* @return Dot product value
*/
T dot(const Vector2D<T>& _obj) const {
ETK_TYPE dot(const Vector2D<ETK_TYPE>& _obj) const {
return m_floats[0] * _obj.m_floats[0]
+ m_floats[1] * _obj.m_floats[1];
}
@ -336,7 +338,7 @@ namespace etk {
* @brief Get the length of the vector squared
* @return Squared length value.
*/
T length2() const {
ETK_TYPE length2() const {
return dot(*this);
}
/**
@ -356,7 +358,7 @@ namespace etk {
* @param[in] _obj The other vector to compare distance
* @return the square distance of the 2 points
*/
T distance2(const Vector2D<T>& _obj) const {
ETK_TYPE distance2(const Vector2D<ETK_TYPE>& _obj) const {
return (_obj - *this).length2();
}
/**
@ -365,14 +367,14 @@ namespace etk {
* @param[in] _obj The other vector to compare distance
* @return the distance of the 2 points
*/
float distance(const Vector2D<T>& _obj) const {
float distance(const Vector2D<ETK_TYPE>& _obj) const {
return (_obj - *this).length();
}
/**
* @brief Normalize this vector x^2 + y^2 = 1
* @return Local reference of the vector normalized
*/
Vector2D<T>& normalize() {
Vector2D<ETK_TYPE>& normalize() {
*this /= length();
return *this;
}
@ -380,8 +382,8 @@ namespace etk {
* @brief Normalize this vector x^2 + y^2 = 1 (check if not deviding by 0, if it is the case ==> return (1,0))
* @return Local reference of the vector normalized
*/
Vector2D<T>& safeNormalize() {
T tmp = length();
Vector2D<ETK_TYPE>& safeNormalize() {
ETK_TYPE tmp = length();
if (tmp != 0) {
*this /= length();
return *this;
@ -393,16 +395,16 @@ namespace etk {
* @brief Return a normalized version of this vector
* @return New vector containing the value
*/
Vector2D<T> normalized() const {
Vector2D<ETK_TYPE> normalized() const {
return *this / length();
}
/**
* @brief Return a vector will the absolute values of each element
* @return New vector containing the value
*/
Vector2D<T> absolute() const {
return Vector2D<T>( abs(m_floats[0]),
abs(m_floats[1]));
Vector2D<ETK_TYPE> absolute() const {
return Vector2D<ETK_TYPE>( std::abs(m_floats[0]),
std::abs(m_floats[1]));
}
/**
* @brief Return the axis with the smallest value
@ -436,63 +438,63 @@ namespace etk {
* @brief Get X value
* @return the x value
*/
const T& getX() const {
const ETK_TYPE& getX() const {
return m_floats[0];
}
/**
* @brief Get Y value
* @return the y value
*/
const T& getY() const {
const ETK_TYPE& getY() const {
return m_floats[1];
}
/**
* @brief Set the x value
* @param[in] _xxx New value
*/
void setX(T _xxx) {
void setX(ETK_TYPE _xxx) {
m_floats[0] = _xxx;
};
/**
* @brief Set the y value
* @param[in] _yyy New value
*/
void setY(T _yyy) {
void setY(ETK_TYPE _yyy) {
m_floats[1] = _yyy;
};
/**
* @brief Get X value
* @return the x value
*/
const T& x() const {
const ETK_TYPE& x() const {
return m_floats[0];
}
/**
* @brief Get Y value
* @return the y value
*/
const T& y() const {
const ETK_TYPE& y() const {
return m_floats[1];
}
/**
* @brief Cast the vector in the type T* requested.
* @return Pointer on the data
*/
operator T *() {
operator ETK_TYPE *() {
return &m_floats[0];
}
/**
* @brief Cast the vector in the type const T* requested.
* @return Pointer on the const data
*/
operator const T *() const {
operator const ETK_TYPE *() const {
return &m_floats[0];
}
/**
* @brief Set each element to the max of the current values and the values of another vector
* @param _other The other vector to compare with
*/
void setMax(const Vector2D<T>& _other) {
void setMax(const Vector2D<ETK_TYPE>& _other) {
m_floats[0] = std::max(m_floats[0], _other.m_floats[0]);
m_floats[1] = std::max(m_floats[1], _other.m_floats[1]);
}
@ -500,7 +502,7 @@ namespace etk {
* @brief Set each element to the min of the current values and the values of another vector
* @param _other The other vector to compare with
*/
void setMin(const Vector2D<T>& _other) {
void setMin(const Vector2D<ETK_TYPE>& _other) {
m_floats[0] = std::min(m_floats[0], _other.m_floats[0]);
m_floats[1] = std::min(m_floats[1], _other.m_floats[1]);
}
@ -509,7 +511,7 @@ namespace etk {
* @param[in] _xxx X value.
* @param[in] _yyy Y value.
*/
void setValue(const T& _xxx, const T& _yyy) {
void setValue(const ETK_TYPE& _xxx, const ETK_TYPE& _yyy) {
m_floats[0] = _xxx;
m_floats[1] = _yyy;
}
@ -528,6 +530,17 @@ namespace etk {
return m_floats[0] == 0
&& m_floats[1] == 0;
}
/*
// -------------------- Friends -------------------- //
friend Vector2D<ETK_TYPE> operator+(const Vector2D<ETK_TYPE>& _vect1, const Vector2D<ETK_TYPE>& _vect2);
friend Vector2D<ETK_TYPE> operator-(const Vector2D<ETK_TYPE>& _vect1, const Vector2D<ETK_TYPE>& _vect2);
friend Vector2D<ETK_TYPE> operator-(const Vector2D<ETK_TYPE>& _vect);
friend Vector2D<ETK_TYPE> operator*(const Vector2D<ETK_TYPE>& _vect, ETK_TYPE _value);
friend Vector2D<ETK_TYPE> operator*(ETK_TYPE _value, const Vector2D<ETK_TYPE>& _vect);
friend Vector2D<ETK_TYPE> operator*(const Vector2D<ETK_TYPE>& _vect1, const Vector2D<ETK_TYPE>& _vect2);
friend Vector2D<ETK_TYPE> operator/(const Vector2D<ETK_TYPE>& _vect, ETK_TYPE _value);
friend Vector2D<ETK_TYPE> operator/(const Vector2D<ETK_TYPE>& _vect1, const Vector2D<ETK_TYPE>& _vect2);
*/
/**
* @brief String caster of the object.
* @return the Object cated in string (x.x,y.y)
@ -594,3 +607,45 @@ namespace etk {
std::ostream& operator <<(std::ostream& _os, const std::vector<bvec2 >& _obj);
}
template<class ETK_TYPE>
inline etk::Vector2D<ETK_TYPE> operator+(const etk::Vector2D<ETK_TYPE>& _vect1, const etk::Vector2D<ETK_TYPE>& _vect2) {
return etk::Vector2D<ETK_TYPE>(_vect1.x() + _vect2.x(), _vect1.y() + _vect2.y());
}
template<class ETK_TYPE>
inline etk::Vector2D<ETK_TYPE> operator-(const etk::Vector2D<ETK_TYPE>& _vect1, const etk::Vector2D<ETK_TYPE>& _vect2) {
return etk::Vector2D<ETK_TYPE>(_vect1.x() - _vect2.x(), _vect1.y() - _vect2.y());
}
template<class ETK_TYPE>
inline etk::Vector2D<ETK_TYPE> operator-(const etk::Vector2D<ETK_TYPE>& _vect) {
return etk::Vector2D<ETK_TYPE>(-_vect.x(), -_vect.y());
}
template<class ETK_TYPE>
inline etk::Vector2D<ETK_TYPE> operator*(const etk::Vector2D<ETK_TYPE>& _vect, ETK_TYPE _value) {
return etk::Vector2D<ETK_TYPE>(_value * _vect.x(), _value * _vect.y());
}
template<class ETK_TYPE>
inline etk::Vector2D<ETK_TYPE> operator*(const etk::Vector2D<ETK_TYPE>& _vect1, const etk::Vector2D<ETK_TYPE>& _vect2) {
return etk::Vector2D<ETK_TYPE>(_vect1.x() * _vect2.x(), _vect1.y() * _vect2.y());
}
template<class ETK_TYPE>
inline etk::Vector2D<ETK_TYPE> operator/(const etk::Vector2D<ETK_TYPE>& _vect, ETK_TYPE _value) {
//assert(_value > MACHINE_EPSILON);
return etk::Vector2D<ETK_TYPE>(_vect.x() / _value, _vect.y() / _value);
}
template<class ETK_TYPE>
inline etk::Vector2D<ETK_TYPE> operator/(const etk::Vector2D<ETK_TYPE>& _vect1, const etk::Vector2D<ETK_TYPE>& _vect2) {
//assert(_vect2.x() > MACHINE_EPSILON);
//assert(_vect2.y() > MACHINE_EPSILON);
return etk::Vector2D<ETK_TYPE>(_vect1.x() / _vect2.x(), _vect1.y() / _vect2.y());
}
template<class ETK_TYPE>
inline etk::Vector2D<ETK_TYPE> operator*(ETK_TYPE _value, const etk::Vector2D<ETK_TYPE>& _vect) {
return _vect * _value;
}

View File

@ -5,6 +5,7 @@
*/
#include <etk/types.hpp>
#include <etk/debug.hpp>
#pragma once
@ -77,7 +78,7 @@ namespace etk {
* @param[in] _obj The vector to add to this one
* @return New vector containing the value
*/
Vector3D<T> operator+(const Vector3D<T>& _obj) {
Vector3D<T> operator+(const Vector3D<T>& _obj) const {
return Vector3D<T>(m_floats[0] + _obj.m_floats[0],
m_floats[1] + _obj.m_floats[1],
m_floats[2] + _obj.m_floats[2]);
@ -98,7 +99,7 @@ namespace etk {
* @param[in] _obj The vector to subtract
* @return New vector containing the value
*/
Vector3D<T> operator-(const Vector3D<T>& _obj) {
Vector3D<T> operator-(const Vector3D<T>& _obj) const {
return Vector3D<T>(m_floats[0] - _obj.m_floats[0],
m_floats[1] - _obj.m_floats[1],
m_floats[2] - _obj.m_floats[2]);
@ -119,7 +120,7 @@ namespace etk {
* @param[in] _val Scale factor
* @return New vector containing the value
*/
Vector3D<T> operator*(const T& _val) {
Vector3D<T> operator*(const T& _val) const {
return Vector3D<T>(m_floats[0] * _val,
m_floats[1] * _val,
m_floats[2] * _val);
@ -200,10 +201,8 @@ namespace etk {
* @return Local reference of the vector normalized
*/
Vector3D<T>& safeNormalize() {
Vector3D<T> absVec = this->absolute();
int maxIndex = absVec.maxAxis();
if (absVec[maxIndex]>0) {
*this /= absVec[maxIndex];
float lenght = length();
if (lenght != 0.0f) {
return *this /= length();
}
setValue(1,0,0);
@ -214,6 +213,7 @@ namespace etk {
* @return Local reference of the vector normalized
*/
Vector3D<T>& normalize() {
TK_ASSERT(length() != 0.0f, "Normalisation error");
return *this /= length();
}
/**
@ -222,8 +222,7 @@ namespace etk {
*/
Vector3D<T> normalized() const {
Vector3D<T> out = *this;
out /= length();
return out;
return out.normalize();
}
/**
* @brief Return a rotated version of this vector
@ -255,9 +254,9 @@ namespace etk {
* @return New vector containing the value
*/
Vector3D<T> absolute() const {
return Vector3D<T>( abs(m_floats[0]),
abs(m_floats[1]),
abs(m_floats[2]));
return Vector3D<T>( std::abs(m_floats[0]),
std::abs(m_floats[1]),
std::abs(m_floats[2]));
}
/**
* @brief Return the cross product between this and another vector
@ -344,7 +343,7 @@ namespace etk {
* @return Local reference of the vector normalized
*/
Vector3D<T>& operator*=(const Vector3D<T>& _obj) {
m_floats[0] *= _obj.m_floats[0];
m_floats[0] *= _obj.m_floats[0];
m_floats[1] *= _obj.m_floats[1];
m_floats[2] *= _obj.m_floats[2];
return *this;
@ -354,7 +353,7 @@ namespace etk {
* @param _obj The other vector
* @return New vector containing the value
*/
Vector3D<T> operator*(const Vector3D<T>& _obj) {
Vector3D<T> operator*(const Vector3D<T>& _obj) const {
return Vector3D<T>(m_floats[0] * _obj.m_floats[0],
m_floats[1] * _obj.m_floats[1],
m_floats[2] * _obj.m_floats[2]);
@ -597,3 +596,47 @@ namespace etk {
}
template<class ETK_TYPE>
inline etk::Vector3D<ETK_TYPE> operator+(const etk::Vector3D<ETK_TYPE>& _vect1, const etk::Vector3D<ETK_TYPE>& _vect2) {
return etk::Vector3D<ETK_TYPE>(_vect1.x() + _vect2.x(), _vect1.y() + _vect2.y(), _vect1.z() + _vect2.z());
}
template<class ETK_TYPE>
inline etk::Vector3D<ETK_TYPE> operator-(const etk::Vector3D<ETK_TYPE>& _vect1, const etk::Vector3D<ETK_TYPE>& _vect2) {
return etk::Vector3D<ETK_TYPE>(_vect1.x() - _vect2.x(), _vect1.y() + _vect2.y(), _vect1.z() + _vect2.z());
}
template<class ETK_TYPE>
inline etk::Vector3D<ETK_TYPE> operator-(const etk::Vector3D<ETK_TYPE>& _vect) {
return etk::Vector3D<ETK_TYPE>(-_vect.x(), -_vect.y(), -_vect.z());
}
template<class ETK_TYPE>
inline etk::Vector3D<ETK_TYPE> operator*(const etk::Vector3D<ETK_TYPE>& _vect, ETK_TYPE _value) {
return etk::Vector3D<ETK_TYPE>(_value * _vect.x(), _value * _vect.y(), _value * _vect.z());
}
template<class ETK_TYPE>
inline etk::Vector3D<ETK_TYPE> operator*(const etk::Vector3D<ETK_TYPE>& _vect1, const etk::Vector3D<ETK_TYPE>& _vect2) {
return etk::Vector3D<ETK_TYPE>(_vect1.x() * _vect2.x(), _vect1.y() * _vect2.y(), _vect1.z() * _vect2.z());
}
template<class ETK_TYPE>
inline etk::Vector3D<ETK_TYPE> operator/(const etk::Vector3D<ETK_TYPE>& _vect, ETK_TYPE _value) {
//assert(_value > MACHINE_EPSILON);
return etk::Vector3D<ETK_TYPE>(_vect.x() / _value, _vect.y() / _value, _vect.z() / _value);
}
template<class ETK_TYPE>
inline etk::Vector3D<ETK_TYPE> operator/(const etk::Vector3D<ETK_TYPE>& _vect1, const etk::Vector3D<ETK_TYPE>& _vect2) {
//assert(_vect2.x() > MACHINE_EPSILON);
//assert(_vect2.y() > MACHINE_EPSILON);
//assert(_vect2.z() > MACHINE_EPSILON);
return etk::Vector3D<ETK_TYPE>(_vect1.x() / _vect2.x(), _vect1.y() / _vect2.y(), _vect1.z() / _vect2.z());
}
template<class ETK_TYPE>
inline etk::Vector3D<ETK_TYPE> operator*(ETK_TYPE _value, const etk::Vector3D<ETK_TYPE>& _vect) {
return _vect * _value;
}

View File

@ -219,10 +219,10 @@ namespace etk {
* @return New vector with the absolute value
*/
Vector4D<T> absolute() const {
return Vector4D<T>( abs(m_floats[0]),
abs(m_floats[1]),
abs(m_floats[2]),
abs(m_floats[3]));
return Vector4D<T>( std::abs(m_floats[0]),
std::abs(m_floats[1]),
std::abs(m_floats[2]),
std::abs(m_floats[3]));
}
/**
* @brief Multiply this vector by the other.

View File

@ -26,7 +26,19 @@ def get_maintainer():
def configure(target, my_module):
my_module.add_src_file([
'test/main.cpp'
'test/main.cpp',
'test/testColor.cpp',
'test/testHash.cpp',
'test/testMatrix3x3.cpp',
'test/testRegExp.cpp',
'test/testTransform.cpp',
'test/testVector3_f.cpp',
'test/testArchive.cpp',
'test/testFSNode.cpp',
'test/testMatrix2x2.cpp',
'test/testQuaternion.cpp',
'test/testStdShared.cpp',
'test/testVector2_f.cpp',
])
my_module.add_depend([
'etk',

View File

@ -36,10 +36,13 @@ def configure(target, my_module):
'etk/Color.cpp',
'etk/RegExp.cpp',
'etk/math/Matrix2.cpp',
'etk/math/Matrix3.cpp',
'etk/math/Matrix4.cpp',
'etk/math/Vector2D.cpp',
'etk/math/Vector3D.cpp',
'etk/math/Vector4D.cpp',
'etk/math/Quaternion.cpp',
'etk/math/Transform.cpp',
'etk/os/FSNode.cpp',
'etk/os/FSNodeRight.cpp',
'etk/archive/Archive.cpp',
@ -57,10 +60,13 @@ def configure(target, my_module):
'etk/Buffer.hpp',
'etk/Hash.hpp',
'etk/math/Matrix2.hpp',
'etk/math/Matrix3.hpp',
'etk/math/Matrix4.hpp',
'etk/math/Vector2D.hpp',
'etk/math/Vector3D.hpp',
'etk/math/Vector4D.hpp',
'etk/math/Quaternion.hpp',
'etk/math/Transform.hpp',
'etk/os/Fifo.hpp',
'etk/os/FSNode.hpp',
'etk/os/FSNodeRight.hpp',

View File

@ -8,22 +8,12 @@
#include <test-debug/debug.hpp>
#include <vector>
#include <string>
#include <etk/Hash.hpp>
#include <etk/os/FSNode.hpp>
#include <etk/archive/Archive.hpp>
#include <etk/etk.hpp>
#include <etk/Color.hpp>
#include <etk/stdTools.hpp>
#include <string>
#define NAME "Empty"
#include <etk/os/FSNode.hpp>
#include <gtest/gtest.h>
#include "testArchive.hpp"
#include "testColor.hpp"
#include "testFSNode.hpp"
#include "testHash.hpp"
#include "testRegExp.hpp"
#include "testStdShared.hpp"
int main(int argc, const char *argv[]) {
// init Google test :

View File

@ -7,8 +7,9 @@
*/
#include <gtest/gtest.h>
#undef NAME
#define NAME "Archive"
#include <etk/archive/Archive.hpp>
#include <test-debug/debug.hpp>
#ifdef ETK_BUILD_MINIZIP

View File

@ -7,7 +7,8 @@
*/
#include <gtest/gtest.h>
#undef NAME
#include <etk/Color.hpp>
#include <test-debug/debug.hpp>
#define NAME "Color"
TEST(TestEtkColor, RGBA8) {

View File

@ -7,7 +7,8 @@
*/
#include <gtest/gtest.h>
#undef NAME
#include <test-debug/debug.hpp>
#include <etk/os/FSNode.hpp>
#define NAME "FSNode"
TEST(TestEtkFSNode, checkType) {

View File

@ -8,7 +8,8 @@
#include <gtest/gtest.h>
#undef NAME
#include <etk/Hash.hpp>
#include <test-debug/debug.hpp>
#define NAME "Hash"
TEST(TestEtkHash, Creation) {

258
test/testMatrix2x2.cpp Normal file
View File

@ -0,0 +1,258 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license MPL v2.0 (see license file)
*/
#include <gtest/gtest.h>
#include <etk/math/Matrix2.hpp>
#include <test-debug/debug.hpp>
#define NAME "etk::Matrix2x2"
TEST(TestMatrix2x2, constructor) {
// Test contructor value
etk::Matrix2 test1(99.0);
EXPECT_FLOAT_EQ(test1.m_mat[0], 99.0);
EXPECT_FLOAT_EQ(test1.m_mat[1], 99.0);
EXPECT_FLOAT_EQ(test1.m_mat[2], 99.0);
EXPECT_FLOAT_EQ(test1.m_mat[3], 99.0);
etk::Matrix2 test2(11,22,33,44);
EXPECT_FLOAT_EQ(test2.m_mat[0], 11.0);
EXPECT_FLOAT_EQ(test2.m_mat[1], 22.0);
EXPECT_FLOAT_EQ(test2.m_mat[2], 33.0);
EXPECT_FLOAT_EQ(test2.m_mat[3], 44.0);
etk::Matrix2 test3(test2);
EXPECT_FLOAT_EQ(test3.m_mat[0], 11.0);
EXPECT_FLOAT_EQ(test3.m_mat[1], 22.0);
EXPECT_FLOAT_EQ(test3.m_mat[2], 33.0);
EXPECT_FLOAT_EQ(test3.m_mat[3], 44.0);
etk::Matrix2 test4 = test1;
EXPECT_FLOAT_EQ(test4.m_mat[0], 99.0);
EXPECT_FLOAT_EQ(test4.m_mat[1], 99.0);
EXPECT_FLOAT_EQ(test4.m_mat[2], 99.0);
EXPECT_FLOAT_EQ(test4.m_mat[3], 99.0);
test1 = test3;
EXPECT_FLOAT_EQ(test1.m_mat[0], 11.0);
EXPECT_FLOAT_EQ(test1.m_mat[1], 22.0);
EXPECT_FLOAT_EQ(test1.m_mat[2], 33.0);
EXPECT_FLOAT_EQ(test1.m_mat[3], 44.0);
}
TEST(TestMatrix2x2, equity) {
etk::Matrix2 test1(99,32,56,92);
etk::Matrix2 test2(11,22,33,44);
etk::Matrix2 test3(11,22,33,44);
EXPECT_EQ(test1 == test2, false);
EXPECT_EQ(test1 != test2, true);
EXPECT_EQ(test3 == test2, true);
EXPECT_EQ(test3 != test2, false);
}
TEST(TestMatrix2x2, set) {
etk::Matrix2 test;
test.setValue(22, 54, 45, 985);
EXPECT_FLOAT_EQ(test.m_mat[0], 22.0);
EXPECT_FLOAT_EQ(test.m_mat[1], 54.0);
EXPECT_FLOAT_EQ(test.m_mat[2], 45.0);
EXPECT_FLOAT_EQ(test.m_mat[3], 985.0);
test.setZero();
EXPECT_FLOAT_EQ(test.m_mat[0], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[1], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[2], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[3], 0.0);
test.setIdentity();
EXPECT_FLOAT_EQ(test.m_mat[0], 1.0);
EXPECT_FLOAT_EQ(test.m_mat[1], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[2], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[3], 1.0);
test = etk::Matrix2::zero();
EXPECT_FLOAT_EQ(test.m_mat[0], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[1], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[2], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[3], 0.0);
test = etk::Matrix2::identity();
EXPECT_FLOAT_EQ(test.m_mat[0], 1.0);
EXPECT_FLOAT_EQ(test.m_mat[1], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[2], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[3], 1.0);
}
TEST(TestMatrix2x2, getRowColomn) {
etk::Matrix2 test(11, 22, 33, 44);
EXPECT_FLOAT_EQ(test.getColumn(0).x(), 11.0);
EXPECT_FLOAT_EQ(test.getColumn(0).y(), 33.0);
EXPECT_FLOAT_EQ(test.getColumn(1).x(), 22.0);
EXPECT_FLOAT_EQ(test.getColumn(1).y(), 44.0);
EXPECT_FLOAT_EQ(test.getColumn(999).x(), 22.0);
EXPECT_FLOAT_EQ(test.getColumn(999).y(), 44.0);
EXPECT_FLOAT_EQ(test.getRow(0).x(), 11.0);
EXPECT_FLOAT_EQ(test.getRow(0).y(), 22.0);
EXPECT_FLOAT_EQ(test.getRow(1).x(), 33.0);
EXPECT_FLOAT_EQ(test.getRow(1).y(), 44.0);
EXPECT_FLOAT_EQ(test.getRow(999).x(), 33.0);
EXPECT_FLOAT_EQ(test.getRow(999).y(), 44.0);
}
TEST(TestMatrix2x2, transpose) {
etk::Matrix2 test(11, 22, 33, 44);
etk::Matrix2 test2 = test.getTranspose();
EXPECT_FLOAT_EQ(test2.m_mat[0], 11.0);
EXPECT_FLOAT_EQ(test2.m_mat[1], 33.0);
EXPECT_FLOAT_EQ(test2.m_mat[2], 22.0);
EXPECT_FLOAT_EQ(test2.m_mat[3], 44.0);
// check if original matrix is not transposed
EXPECT_FLOAT_EQ(test.m_mat[0], 11.0);
EXPECT_FLOAT_EQ(test.m_mat[1], 22.0);
EXPECT_FLOAT_EQ(test.m_mat[2], 33.0);
EXPECT_FLOAT_EQ(test.m_mat[3], 44.0);
test.transpose();
EXPECT_FLOAT_EQ(test.m_mat[0], 11.0);
EXPECT_FLOAT_EQ(test.m_mat[1], 33.0);
EXPECT_FLOAT_EQ(test.m_mat[2], 22.0);
EXPECT_FLOAT_EQ(test.m_mat[3], 44.0);
}
TEST(TestMatrix2x2, determinant) {
etk::Matrix2 test(11, 22, 33, 44);
EXPECT_FLOAT_EQ(test.determinant(), -242.0);
EXPECT_FLOAT_EQ(etk::Matrix2::identity().determinant(), 1.0);
}
TEST(TestMatrix2x2, trace) {
etk::Matrix2 test(11, 22, 33, 44);
EXPECT_FLOAT_EQ(test.getTrace(), 55.0);
}
TEST(TestMatrix2x2, inverse) {
etk::Matrix2 test(1, 2, 3, 4);
etk::Matrix2 test2 = test.getInverse();
// check if original matrix is not inversed
EXPECT_FLOAT_EQ(test.m_mat[0], 1.0);
EXPECT_FLOAT_EQ(test.m_mat[1], 2.0);
EXPECT_FLOAT_EQ(test.m_mat[2], 3.0);
EXPECT_FLOAT_EQ(test.m_mat[3], 4.0);
EXPECT_FLOAT_EQ(test2.m_mat[0], -2.0);
EXPECT_FLOAT_EQ(test2.m_mat[1], 1.0);
EXPECT_FLOAT_EQ(test2.m_mat[2], 1.5);
EXPECT_FLOAT_EQ(test2.m_mat[3], -0.5);
test.inverse();
EXPECT_FLOAT_EQ(test.m_mat[0], -2.0);
EXPECT_FLOAT_EQ(test.m_mat[1], 1.0);
EXPECT_FLOAT_EQ(test.m_mat[2], 1.5);
EXPECT_FLOAT_EQ(test.m_mat[3], -0.5);
}
TEST(TestMatrix2x2, absolute) {
etk::Matrix2 test(-1, -2, -3, -4);
etk::Matrix2 test2 = test.getAbsolute();
// check if original matrix is not inversed
EXPECT_FLOAT_EQ(test.m_mat[0], -1.0);
EXPECT_FLOAT_EQ(test.m_mat[1], -2.0);
EXPECT_FLOAT_EQ(test.m_mat[2], -3.0);
EXPECT_FLOAT_EQ(test.m_mat[3], -4.0);
EXPECT_FLOAT_EQ(test2.m_mat[0], 1.0);
EXPECT_FLOAT_EQ(test2.m_mat[1], 2.0);
EXPECT_FLOAT_EQ(test2.m_mat[2], 3.0);
EXPECT_FLOAT_EQ(test2.m_mat[3], 4.0);
test.absolute();
EXPECT_FLOAT_EQ(test.m_mat[0], 1.0);
EXPECT_FLOAT_EQ(test.m_mat[1], 2.0);
EXPECT_FLOAT_EQ(test.m_mat[2], 3.0);
EXPECT_FLOAT_EQ(test.m_mat[3], 4.0);
}
TEST(TestMatrix2x2, operatorAddition) {
etk::Matrix2 test1(-1, -2, -3, -4);
etk::Matrix2 test2(1, 2, 3, 4);
etk::Matrix2 test3 = test1 + test2;
// check no change
EXPECT_FLOAT_EQ(test1.m_mat[0], -1.0);
EXPECT_FLOAT_EQ(test1.m_mat[1], -2.0);
EXPECT_FLOAT_EQ(test1.m_mat[2], -3.0);
EXPECT_FLOAT_EQ(test1.m_mat[3], -4.0);
EXPECT_FLOAT_EQ(test2.m_mat[0], 1.0);
EXPECT_FLOAT_EQ(test2.m_mat[1], 2.0);
EXPECT_FLOAT_EQ(test2.m_mat[2], 3.0);
EXPECT_FLOAT_EQ(test2.m_mat[3], 4.0);
EXPECT_FLOAT_EQ(test3.m_mat[0], 0.0);
EXPECT_FLOAT_EQ(test3.m_mat[1], 0.0);
EXPECT_FLOAT_EQ(test3.m_mat[2], 0.0);
EXPECT_FLOAT_EQ(test3.m_mat[3], 0.0);
test1 += test2;
EXPECT_FLOAT_EQ(test1.m_mat[0], 0.0);
EXPECT_FLOAT_EQ(test1.m_mat[1], 0.0);
EXPECT_FLOAT_EQ(test1.m_mat[2], 0.0);
EXPECT_FLOAT_EQ(test1.m_mat[3], 0.0);
}
TEST(TestMatrix2x2, operatorSubstraction) {
etk::Matrix2 test1(-1, -2, -3, -4);
etk::Matrix2 test2(1, 2, 3, 4);
etk::Matrix2 test3 = test1 - test2;
// check no change
EXPECT_FLOAT_EQ(test1.m_mat[0], -1.0);
EXPECT_FLOAT_EQ(test1.m_mat[1], -2.0);
EXPECT_FLOAT_EQ(test1.m_mat[2], -3.0);
EXPECT_FLOAT_EQ(test1.m_mat[3], -4.0);
EXPECT_FLOAT_EQ(test2.m_mat[0], 1.0);
EXPECT_FLOAT_EQ(test2.m_mat[1], 2.0);
EXPECT_FLOAT_EQ(test2.m_mat[2], 3.0);
EXPECT_FLOAT_EQ(test2.m_mat[3], 4.0);
EXPECT_FLOAT_EQ(test3.m_mat[0], -2.0);
EXPECT_FLOAT_EQ(test3.m_mat[1], -4.0);
EXPECT_FLOAT_EQ(test3.m_mat[2], -6.0);
EXPECT_FLOAT_EQ(test3.m_mat[3], -8.0);
test1 -= test2;
EXPECT_FLOAT_EQ(test1.m_mat[0], -2.0);
EXPECT_FLOAT_EQ(test1.m_mat[1], -4.0);
EXPECT_FLOAT_EQ(test1.m_mat[2], -6.0);
EXPECT_FLOAT_EQ(test1.m_mat[3], -8.0);
}
TEST(TestMatrix2x2, operatorNegation) {
etk::Matrix2 test1(-1, -2, -3, -4);
etk::Matrix2 test2 = -test1;
EXPECT_FLOAT_EQ(test1.m_mat[0], -1.0);
EXPECT_FLOAT_EQ(test1.m_mat[1], -2.0);
EXPECT_FLOAT_EQ(test1.m_mat[2], -3.0);
EXPECT_FLOAT_EQ(test1.m_mat[3], -4.0);
EXPECT_FLOAT_EQ(test2.m_mat[0], 1.0);
EXPECT_FLOAT_EQ(test2.m_mat[1], 2.0);
EXPECT_FLOAT_EQ(test2.m_mat[2], 3.0);
EXPECT_FLOAT_EQ(test2.m_mat[3], 4.0);
}
TEST(TestMatrix2x2, operatorMultiplicationMatrix) {
etk::Matrix2 test1(1, 2, 3, 4);
etk::Matrix2 test2(5, 6, 7, 10);
etk::Matrix2 test3 = test1 * test2;
EXPECT_FLOAT_EQ(test1.m_mat[0], 1.0);
EXPECT_FLOAT_EQ(test1.m_mat[1], 2.0);
EXPECT_FLOAT_EQ(test1.m_mat[2], 3.0);
EXPECT_FLOAT_EQ(test1.m_mat[3], 4.0);
EXPECT_FLOAT_EQ(test2.m_mat[0], 5.0);
EXPECT_FLOAT_EQ(test2.m_mat[1], 6.0);
EXPECT_FLOAT_EQ(test2.m_mat[2], 7.0);
EXPECT_FLOAT_EQ(test2.m_mat[3], 10.0);
EXPECT_FLOAT_EQ(test3.m_mat[0], 19.0);
EXPECT_FLOAT_EQ(test3.m_mat[1], 26.0);
EXPECT_FLOAT_EQ(test3.m_mat[2], 43.0);
EXPECT_FLOAT_EQ(test3.m_mat[3], 58.0);
test1 *= test2;
EXPECT_FLOAT_EQ(test1.m_mat[0], 19.0);
EXPECT_FLOAT_EQ(test1.m_mat[1], 26.0);
EXPECT_FLOAT_EQ(test1.m_mat[2], 43.0);
EXPECT_FLOAT_EQ(test1.m_mat[3], 58.0);
}
TEST(TestMatrix2x2, operatorMultiplicationVector) {
etk::Matrix2 test1(1, 2, 3, 4);
vec2 result = test1 * vec2(1,2);
EXPECT_FLOAT_EQ(result.x(), 5.0);
EXPECT_FLOAT_EQ(result.y(), 11.0);
}

437
test/testMatrix3x3.cpp Normal file
View File

@ -0,0 +1,437 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license MPL v2.0 (see license file)
*/
#include <gtest/gtest.h>
#include <etk/math/Vector3D.hpp>
#include <etk/math/Matrix3.hpp>
#include <test-debug/debug.hpp>
#define NAME "etk::Matrix3"
TEST(TestMatrix3x3, constructor) {
// Test contructor value
etk::Matrix3 test1(99.0);
EXPECT_FLOAT_EQ(test1.m_mat[0], 99.0);
EXPECT_FLOAT_EQ(test1.m_mat[1], 99.0);
EXPECT_FLOAT_EQ(test1.m_mat[2], 99.0);
EXPECT_FLOAT_EQ(test1.m_mat[3], 99.0);
EXPECT_FLOAT_EQ(test1.m_mat[4], 99.0);
EXPECT_FLOAT_EQ(test1.m_mat[5], 99.0);
EXPECT_FLOAT_EQ(test1.m_mat[6], 99.0);
EXPECT_FLOAT_EQ(test1.m_mat[7], 99.0);
EXPECT_FLOAT_EQ(test1.m_mat[8], 99.0);
etk::Matrix3 test2(11,22,33,44,55,66,77,88,99);
EXPECT_FLOAT_EQ(test2.m_mat[0], 11.0);
EXPECT_FLOAT_EQ(test2.m_mat[1], 22.0);
EXPECT_FLOAT_EQ(test2.m_mat[2], 33.0);
EXPECT_FLOAT_EQ(test2.m_mat[3], 44.0);
EXPECT_FLOAT_EQ(test2.m_mat[4], 55.0);
EXPECT_FLOAT_EQ(test2.m_mat[5], 66.0);
EXPECT_FLOAT_EQ(test2.m_mat[6], 77.0);
EXPECT_FLOAT_EQ(test2.m_mat[7], 88.0);
EXPECT_FLOAT_EQ(test2.m_mat[8], 99.0);
etk::Matrix3 test3(test2);
EXPECT_FLOAT_EQ(test3.m_mat[0], 11.0);
EXPECT_FLOAT_EQ(test3.m_mat[1], 22.0);
EXPECT_FLOAT_EQ(test3.m_mat[2], 33.0);
EXPECT_FLOAT_EQ(test3.m_mat[3], 44.0);
EXPECT_FLOAT_EQ(test3.m_mat[4], 55.0);
EXPECT_FLOAT_EQ(test3.m_mat[5], 66.0);
EXPECT_FLOAT_EQ(test3.m_mat[6], 77.0);
EXPECT_FLOAT_EQ(test3.m_mat[7], 88.0);
EXPECT_FLOAT_EQ(test3.m_mat[8], 99.0);
etk::Matrix3 test4 = test1;
EXPECT_FLOAT_EQ(test4.m_mat[0], 99.0);
EXPECT_FLOAT_EQ(test4.m_mat[1], 99.0);
EXPECT_FLOAT_EQ(test4.m_mat[2], 99.0);
EXPECT_FLOAT_EQ(test4.m_mat[3], 99.0);
EXPECT_FLOAT_EQ(test4.m_mat[4], 99.0);
EXPECT_FLOAT_EQ(test4.m_mat[5], 99.0);
EXPECT_FLOAT_EQ(test4.m_mat[6], 99.0);
EXPECT_FLOAT_EQ(test4.m_mat[7], 99.0);
EXPECT_FLOAT_EQ(test4.m_mat[8], 99.0);
test1 = test3;
EXPECT_FLOAT_EQ(test1.m_mat[0], 11.0);
EXPECT_FLOAT_EQ(test1.m_mat[1], 22.0);
EXPECT_FLOAT_EQ(test1.m_mat[2], 33.0);
EXPECT_FLOAT_EQ(test1.m_mat[3], 44.0);
EXPECT_FLOAT_EQ(test1.m_mat[4], 55.0);
EXPECT_FLOAT_EQ(test1.m_mat[5], 66.0);
EXPECT_FLOAT_EQ(test1.m_mat[6], 77.0);
EXPECT_FLOAT_EQ(test1.m_mat[7], 88.0);
EXPECT_FLOAT_EQ(test1.m_mat[8], 99.0);
}
TEST(TestMatrix3x3, equity) {
etk::Matrix3 test1(99,32,56,92,56,32,45,12,54);
etk::Matrix3 test2(11,22,33,44,55,66,77,88,99);
etk::Matrix3 test3(11,22,33,44,55,66,77,88,99);
EXPECT_EQ(test1 == test2, false);
EXPECT_EQ(test1 != test2, true);
EXPECT_EQ(test3 == test2, true);
EXPECT_EQ(test3 != test2, false);
}
TEST(TestMatrix3x3, set) {
etk::Matrix3 test;
test.setValue(22, 54, 45, 985, 54, 87, 98, 6532, -8652);
EXPECT_FLOAT_EQ(test.m_mat[0], 22.0);
EXPECT_FLOAT_EQ(test.m_mat[1], 54.0);
EXPECT_FLOAT_EQ(test.m_mat[2], 45.0);
EXPECT_FLOAT_EQ(test.m_mat[3], 985.0);
EXPECT_FLOAT_EQ(test.m_mat[4], 54.0);
EXPECT_FLOAT_EQ(test.m_mat[5], 87.0);
EXPECT_FLOAT_EQ(test.m_mat[6], 98.0);
EXPECT_FLOAT_EQ(test.m_mat[7], 6532.0);
EXPECT_FLOAT_EQ(test.m_mat[8], -8652.0);
test.setZero();
EXPECT_FLOAT_EQ(test.m_mat[0], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[1], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[2], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[3], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[4], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[5], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[6], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[7], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[8], 0.0);
test.setIdentity();
EXPECT_FLOAT_EQ(test.m_mat[0], 1.0);
EXPECT_FLOAT_EQ(test.m_mat[1], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[2], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[3], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[4], 1.0);
EXPECT_FLOAT_EQ(test.m_mat[5], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[6], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[7], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[8], 1.0);
test = etk::Matrix3::zero();
EXPECT_FLOAT_EQ(test.m_mat[0], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[1], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[2], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[3], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[4], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[5], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[6], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[7], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[8], 0.0);
test = etk::Matrix3::identity();
EXPECT_FLOAT_EQ(test.m_mat[0], 1.0);
EXPECT_FLOAT_EQ(test.m_mat[1], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[2], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[3], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[4], 1.0);
EXPECT_FLOAT_EQ(test.m_mat[5], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[6], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[7], 0.0);
EXPECT_FLOAT_EQ(test.m_mat[8], 1.0);
}
TEST(TestMatrix3x3, getRowColomn) {
etk::Matrix3 test(11, 22, 33, 44, 55, 66, 77, 88, 99);
EXPECT_FLOAT_EQ(test.getColumn(0).x(), 11.0);
EXPECT_FLOAT_EQ(test.getColumn(0).y(), 44.0);
EXPECT_FLOAT_EQ(test.getColumn(0).z(), 77.0);
EXPECT_FLOAT_EQ(test.getColumn(1).x(), 22.0);
EXPECT_FLOAT_EQ(test.getColumn(1).y(), 55.0);
EXPECT_FLOAT_EQ(test.getColumn(1).z(), 88.0);
EXPECT_FLOAT_EQ(test.getColumn(2).x(), 33.0);
EXPECT_FLOAT_EQ(test.getColumn(2).y(), 66.0);
EXPECT_FLOAT_EQ(test.getColumn(2).z(), 99.0);
EXPECT_FLOAT_EQ(test.getColumn(999).x(), 33.0);
EXPECT_FLOAT_EQ(test.getColumn(999).y(), 66.0);
EXPECT_FLOAT_EQ(test.getColumn(999).z(), 99.0);
EXPECT_FLOAT_EQ(test.getRow(0).x(), 11.0);
EXPECT_FLOAT_EQ(test.getRow(0).y(), 22.0);
EXPECT_FLOAT_EQ(test.getRow(0).z(), 33.0);
EXPECT_FLOAT_EQ(test.getRow(1).x(), 44.0);
EXPECT_FLOAT_EQ(test.getRow(1).y(), 55.0);
EXPECT_FLOAT_EQ(test.getRow(1).z(), 66.0);
EXPECT_FLOAT_EQ(test.getRow(2).x(), 77.0);
EXPECT_FLOAT_EQ(test.getRow(2).y(), 88.0);
EXPECT_FLOAT_EQ(test.getRow(2).z(), 99.0);
EXPECT_FLOAT_EQ(test.getRow(999).x(), 77.0);
EXPECT_FLOAT_EQ(test.getRow(999).y(), 88.0);
EXPECT_FLOAT_EQ(test.getRow(999).z(), 99.0);
}
TEST(TestMatrix3x3, transpose) {
etk::Matrix3 test(11, 22, 33, 44, 55, 66, 77, 88, 99);
etk::Matrix3 test2 = test.getTranspose();
EXPECT_FLOAT_EQ(test2.m_mat[0], 11.0);
EXPECT_FLOAT_EQ(test2.m_mat[1], 44.0);
EXPECT_FLOAT_EQ(test2.m_mat[2], 77.0);
EXPECT_FLOAT_EQ(test2.m_mat[3], 22.0);
EXPECT_FLOAT_EQ(test2.m_mat[4], 55.0);
EXPECT_FLOAT_EQ(test2.m_mat[5], 88.0);
EXPECT_FLOAT_EQ(test2.m_mat[6], 33.0);
EXPECT_FLOAT_EQ(test2.m_mat[7], 66.0);
EXPECT_FLOAT_EQ(test2.m_mat[8], 99.0);
// check if original matrix is not transposed
EXPECT_FLOAT_EQ(test.m_mat[0], 11.0);
EXPECT_FLOAT_EQ(test.m_mat[1], 22.0);
EXPECT_FLOAT_EQ(test.m_mat[2], 33.0);
EXPECT_FLOAT_EQ(test.m_mat[3], 44.0);
EXPECT_FLOAT_EQ(test.m_mat[4], 55.0);
EXPECT_FLOAT_EQ(test.m_mat[5], 66.0);
EXPECT_FLOAT_EQ(test.m_mat[6], 77.0);
EXPECT_FLOAT_EQ(test.m_mat[7], 88.0);
EXPECT_FLOAT_EQ(test.m_mat[8], 99.0);
test.transpose();
EXPECT_FLOAT_EQ(test.m_mat[0], 11.0);
EXPECT_FLOAT_EQ(test.m_mat[1], 44.0);
EXPECT_FLOAT_EQ(test.m_mat[2], 77.0);
EXPECT_FLOAT_EQ(test.m_mat[3], 22.0);
EXPECT_FLOAT_EQ(test.m_mat[4], 55.0);
EXPECT_FLOAT_EQ(test.m_mat[5], 88.0);
EXPECT_FLOAT_EQ(test.m_mat[6], 33.0);
EXPECT_FLOAT_EQ(test.m_mat[7], 66.0);
EXPECT_FLOAT_EQ(test.m_mat[8], 99.0);
}
TEST(TestMatrix3x3, determinant) {
etk::Matrix3 test(11, -6, 6, 4, -5, 1, 8, -9, -6);
EXPECT_FLOAT_EQ(test.determinant(), 261.0);
EXPECT_FLOAT_EQ(etk::Matrix3::identity().determinant(), 1.0);
}
TEST(TestMatrix3x3, trace) {
etk::Matrix3 test(11, 22, 33, 44, 55, 66, 77, 88, 99);
EXPECT_FLOAT_EQ(test.getTrace(), 165.0);
}
TEST(TestMatrix3x3, inverse) {
etk::Matrix3 test(1, -4, 3, -6, 5, 6, 7, 8, 9);
etk::Matrix3 test2 = test.getInverse();
// check if original matrix is not inversed
EXPECT_FLOAT_EQ(test.m_mat[0], 1.0);
EXPECT_FLOAT_EQ(test.m_mat[1], -4.0);
EXPECT_FLOAT_EQ(test.m_mat[2], 3.0);
EXPECT_FLOAT_EQ(test.m_mat[3], -6.0);
EXPECT_FLOAT_EQ(test.m_mat[4], 5.0);
EXPECT_FLOAT_EQ(test.m_mat[5], 6.0);
EXPECT_FLOAT_EQ(test.m_mat[6], 7.0);
EXPECT_FLOAT_EQ(test.m_mat[7], 8.0);
EXPECT_FLOAT_EQ(test.m_mat[8], 9.0);
EXPECT_FLOAT_EQ(test2.m_mat[0], 0.0047169812);
EXPECT_FLOAT_EQ(test2.m_mat[1], -0.094339617);
EXPECT_FLOAT_EQ(test2.m_mat[2], 0.061320752);
EXPECT_FLOAT_EQ(test2.m_mat[3], -0.1509434);
EXPECT_FLOAT_EQ(test2.m_mat[4], 0.018867925);
EXPECT_FLOAT_EQ(test2.m_mat[5], 0.03773585);
EXPECT_FLOAT_EQ(test2.m_mat[6], 0.13050313);
EXPECT_FLOAT_EQ(test2.m_mat[7], 0.056603771);
EXPECT_FLOAT_EQ(test2.m_mat[8], 0.029874213);
test.inverse();
EXPECT_FLOAT_EQ(test.m_mat[0], 0.0047169812);
EXPECT_FLOAT_EQ(test.m_mat[1], -0.094339617);
EXPECT_FLOAT_EQ(test.m_mat[2], 0.061320752);
EXPECT_FLOAT_EQ(test.m_mat[3], -0.1509434);
EXPECT_FLOAT_EQ(test.m_mat[4], 0.018867925);
EXPECT_FLOAT_EQ(test.m_mat[5], 0.03773585);
EXPECT_FLOAT_EQ(test.m_mat[6], 0.13050313);
EXPECT_FLOAT_EQ(test.m_mat[7], 0.056603771);
EXPECT_FLOAT_EQ(test.m_mat[8], 0.029874213);
}
TEST(TestMatrix3x3, absolute) {
etk::Matrix3 test(-1, -2, -3, -4, -5, -6, -7, -8, -9);
etk::Matrix3 test2 = test.getAbsolute();
// check if original matrix is not inversed
EXPECT_FLOAT_EQ(test.m_mat[0], -1.0);
EXPECT_FLOAT_EQ(test.m_mat[1], -2.0);
EXPECT_FLOAT_EQ(test.m_mat[2], -3.0);
EXPECT_FLOAT_EQ(test.m_mat[3], -4.0);
EXPECT_FLOAT_EQ(test.m_mat[4], -5.0);
EXPECT_FLOAT_EQ(test.m_mat[5], -6.0);
EXPECT_FLOAT_EQ(test.m_mat[6], -7.0);
EXPECT_FLOAT_EQ(test.m_mat[7], -8.0);
EXPECT_FLOAT_EQ(test.m_mat[8], -9.0);
EXPECT_FLOAT_EQ(test2.m_mat[0], 1.0);
EXPECT_FLOAT_EQ(test2.m_mat[1], 2.0);
EXPECT_FLOAT_EQ(test2.m_mat[2], 3.0);
EXPECT_FLOAT_EQ(test2.m_mat[3], 4.0);
EXPECT_FLOAT_EQ(test2.m_mat[4], 5.0);
EXPECT_FLOAT_EQ(test2.m_mat[5], 6.0);
EXPECT_FLOAT_EQ(test2.m_mat[6], 7.0);
EXPECT_FLOAT_EQ(test2.m_mat[7], 8.0);
EXPECT_FLOAT_EQ(test2.m_mat[8], 9.0);
test.absolute();
EXPECT_FLOAT_EQ(test.m_mat[0], 1.0);
EXPECT_FLOAT_EQ(test.m_mat[1], 2.0);
EXPECT_FLOAT_EQ(test.m_mat[2], 3.0);
EXPECT_FLOAT_EQ(test.m_mat[3], 4.0);
EXPECT_FLOAT_EQ(test.m_mat[4], 5.0);
EXPECT_FLOAT_EQ(test.m_mat[5], 6.0);
EXPECT_FLOAT_EQ(test.m_mat[6], 7.0);
EXPECT_FLOAT_EQ(test.m_mat[7], 8.0);
EXPECT_FLOAT_EQ(test.m_mat[8], 9.0);
}
TEST(TestMatrix3x3, operatorAddition) {
etk::Matrix3 test1(-1, -2, -3, -4, -5, -6, -7, -8, -9);
etk::Matrix3 test2(1, 2, 3, 4, 5, 6, 7, 8, 9);
etk::Matrix3 test3 = test1 + test2;
// check no change
EXPECT_FLOAT_EQ(test1.m_mat[0], -1.0);
EXPECT_FLOAT_EQ(test1.m_mat[1], -2.0);
EXPECT_FLOAT_EQ(test1.m_mat[2], -3.0);
EXPECT_FLOAT_EQ(test1.m_mat[3], -4.0);
EXPECT_FLOAT_EQ(test1.m_mat[4], -5.0);
EXPECT_FLOAT_EQ(test1.m_mat[5], -6.0);
EXPECT_FLOAT_EQ(test1.m_mat[6], -7.0);
EXPECT_FLOAT_EQ(test1.m_mat[7], -8.0);
EXPECT_FLOAT_EQ(test1.m_mat[8], -9.0);
EXPECT_FLOAT_EQ(test2.m_mat[0], 1.0);
EXPECT_FLOAT_EQ(test2.m_mat[1], 2.0);
EXPECT_FLOAT_EQ(test2.m_mat[2], 3.0);
EXPECT_FLOAT_EQ(test2.m_mat[3], 4.0);
EXPECT_FLOAT_EQ(test2.m_mat[4], 5.0);
EXPECT_FLOAT_EQ(test2.m_mat[5], 6.0);
EXPECT_FLOAT_EQ(test2.m_mat[6], 7.0);
EXPECT_FLOAT_EQ(test2.m_mat[7], 8.0);
EXPECT_FLOAT_EQ(test2.m_mat[8], 9.0);
EXPECT_FLOAT_EQ(test3.m_mat[0], 0.0);
EXPECT_FLOAT_EQ(test3.m_mat[1], 0.0);
EXPECT_FLOAT_EQ(test3.m_mat[2], 0.0);
EXPECT_FLOAT_EQ(test3.m_mat[3], 0.0);
EXPECT_FLOAT_EQ(test3.m_mat[4], 0.0);
EXPECT_FLOAT_EQ(test3.m_mat[5], 0.0);
EXPECT_FLOAT_EQ(test3.m_mat[6], 0.0);
EXPECT_FLOAT_EQ(test3.m_mat[7], 0.0);
EXPECT_FLOAT_EQ(test3.m_mat[8], 0.0);
test1 += test2;
EXPECT_FLOAT_EQ(test1.m_mat[0], 0.0);
EXPECT_FLOAT_EQ(test1.m_mat[1], 0.0);
EXPECT_FLOAT_EQ(test1.m_mat[2], 0.0);
EXPECT_FLOAT_EQ(test1.m_mat[3], 0.0);
EXPECT_FLOAT_EQ(test1.m_mat[4], 0.0);
EXPECT_FLOAT_EQ(test1.m_mat[5], 0.0);
EXPECT_FLOAT_EQ(test1.m_mat[6], 0.0);
EXPECT_FLOAT_EQ(test1.m_mat[7], 0.0);
EXPECT_FLOAT_EQ(test1.m_mat[8], 0.0);
}
TEST(TestMatrix3x3, operatorSubstraction) {
etk::Matrix3 test1(-1, -2, -3, -4, -5, -6, -7, -8, -9);
etk::Matrix3 test2(1, 2, 3, 4, 5, 6, 7, 8, 9);
etk::Matrix3 test3 = test1 - test2;
// check no change
EXPECT_FLOAT_EQ(test1.m_mat[0], -1.0);
EXPECT_FLOAT_EQ(test1.m_mat[1], -2.0);
EXPECT_FLOAT_EQ(test1.m_mat[2], -3.0);
EXPECT_FLOAT_EQ(test1.m_mat[3], -4.0);
EXPECT_FLOAT_EQ(test1.m_mat[4], -5.0);
EXPECT_FLOAT_EQ(test1.m_mat[5], -6.0);
EXPECT_FLOAT_EQ(test1.m_mat[6], -7.0);
EXPECT_FLOAT_EQ(test1.m_mat[7], -8.0);
EXPECT_FLOAT_EQ(test1.m_mat[8], -9.0);
EXPECT_FLOAT_EQ(test2.m_mat[0], 1.0);
EXPECT_FLOAT_EQ(test2.m_mat[1], 2.0);
EXPECT_FLOAT_EQ(test2.m_mat[2], 3.0);
EXPECT_FLOAT_EQ(test2.m_mat[3], 4.0);
EXPECT_FLOAT_EQ(test2.m_mat[4], 5.0);
EXPECT_FLOAT_EQ(test2.m_mat[5], 6.0);
EXPECT_FLOAT_EQ(test2.m_mat[6], 7.0);
EXPECT_FLOAT_EQ(test2.m_mat[7], 8.0);
EXPECT_FLOAT_EQ(test2.m_mat[8], 9.0);
EXPECT_FLOAT_EQ(test3.m_mat[0], -2.0);
EXPECT_FLOAT_EQ(test3.m_mat[1], -4.0);
EXPECT_FLOAT_EQ(test3.m_mat[2], -6.0);
EXPECT_FLOAT_EQ(test3.m_mat[3], -8.0);
EXPECT_FLOAT_EQ(test3.m_mat[4], -10.0);
EXPECT_FLOAT_EQ(test3.m_mat[5], -12.0);
EXPECT_FLOAT_EQ(test3.m_mat[6], -14.0);
EXPECT_FLOAT_EQ(test3.m_mat[7], -16.0);
EXPECT_FLOAT_EQ(test3.m_mat[8], -18.0);
test1 -= test2;
EXPECT_FLOAT_EQ(test1.m_mat[0], -2.0);
EXPECT_FLOAT_EQ(test1.m_mat[1], -4.0);
EXPECT_FLOAT_EQ(test1.m_mat[2], -6.0);
EXPECT_FLOAT_EQ(test1.m_mat[3], -8.0);
EXPECT_FLOAT_EQ(test1.m_mat[4], -10.0);
EXPECT_FLOAT_EQ(test1.m_mat[5], -12.0);
EXPECT_FLOAT_EQ(test1.m_mat[6], -14.0);
EXPECT_FLOAT_EQ(test1.m_mat[7], -16.0);
EXPECT_FLOAT_EQ(test1.m_mat[8], -18.0);
}
TEST(TestMatrix3x3, operatorNegation) {
etk::Matrix3 test1(-1, -2, -3, -4, -5, -6, -7, -8, -9);
etk::Matrix3 test2 = -test1;
// check no change
EXPECT_FLOAT_EQ(test1.m_mat[0], -1.0);
EXPECT_FLOAT_EQ(test1.m_mat[1], -2.0);
EXPECT_FLOAT_EQ(test1.m_mat[2], -3.0);
EXPECT_FLOAT_EQ(test1.m_mat[3], -4.0);
EXPECT_FLOAT_EQ(test1.m_mat[4], -5.0);
EXPECT_FLOAT_EQ(test1.m_mat[5], -6.0);
EXPECT_FLOAT_EQ(test1.m_mat[6], -7.0);
EXPECT_FLOAT_EQ(test1.m_mat[7], -8.0);
EXPECT_FLOAT_EQ(test1.m_mat[8], -9.0);
EXPECT_FLOAT_EQ(test2.m_mat[0], 1.0);
EXPECT_FLOAT_EQ(test2.m_mat[1], 2.0);
EXPECT_FLOAT_EQ(test2.m_mat[2], 3.0);
EXPECT_FLOAT_EQ(test2.m_mat[3], 4.0);
EXPECT_FLOAT_EQ(test2.m_mat[4], 5.0);
EXPECT_FLOAT_EQ(test2.m_mat[5], 6.0);
EXPECT_FLOAT_EQ(test2.m_mat[6], 7.0);
EXPECT_FLOAT_EQ(test2.m_mat[7], 8.0);
EXPECT_FLOAT_EQ(test2.m_mat[8], 9.0);
}
TEST(TestMatrix3x3, operatorMultiplicationMatrix) {
etk::Matrix3 test1(-1, -2, -3, -4, -5, -6, -7, -8, -9);
etk::Matrix3 test2(1, 2, 3, 4, 5, 6, 7, 8, 9);
etk::Matrix3 test3 = test1 * test2;
EXPECT_FLOAT_EQ(test1.m_mat[0], -1.0);
EXPECT_FLOAT_EQ(test1.m_mat[1], -2.0);
EXPECT_FLOAT_EQ(test1.m_mat[2], -3.0);
EXPECT_FLOAT_EQ(test1.m_mat[3], -4.0);
EXPECT_FLOAT_EQ(test1.m_mat[4], -5.0);
EXPECT_FLOAT_EQ(test1.m_mat[5], -6.0);
EXPECT_FLOAT_EQ(test1.m_mat[6], -7.0);
EXPECT_FLOAT_EQ(test1.m_mat[7], -8.0);
EXPECT_FLOAT_EQ(test1.m_mat[8], -9.0);
EXPECT_FLOAT_EQ(test2.m_mat[0], 1.0);
EXPECT_FLOAT_EQ(test2.m_mat[1], 2.0);
EXPECT_FLOAT_EQ(test2.m_mat[2], 3.0);
EXPECT_FLOAT_EQ(test2.m_mat[3], 4.0);
EXPECT_FLOAT_EQ(test2.m_mat[4], 5.0);
EXPECT_FLOAT_EQ(test2.m_mat[5], 6.0);
EXPECT_FLOAT_EQ(test2.m_mat[6], 7.0);
EXPECT_FLOAT_EQ(test2.m_mat[7], 8.0);
EXPECT_FLOAT_EQ(test2.m_mat[8], 9.0);
EXPECT_FLOAT_EQ(test3.m_mat[0], -30);
EXPECT_FLOAT_EQ(test3.m_mat[1], -36);
EXPECT_FLOAT_EQ(test3.m_mat[2], -42);
EXPECT_FLOAT_EQ(test3.m_mat[3], -66);
EXPECT_FLOAT_EQ(test3.m_mat[4], -81);
EXPECT_FLOAT_EQ(test3.m_mat[5], -96);
EXPECT_FLOAT_EQ(test3.m_mat[6], -102);
EXPECT_FLOAT_EQ(test3.m_mat[7], -126);
EXPECT_FLOAT_EQ(test3.m_mat[8], -150);
test1 *= test2;
EXPECT_FLOAT_EQ(test1.m_mat[0], -30);
EXPECT_FLOAT_EQ(test1.m_mat[1], -36);
EXPECT_FLOAT_EQ(test1.m_mat[2], -42);
EXPECT_FLOAT_EQ(test1.m_mat[3], -66);
EXPECT_FLOAT_EQ(test1.m_mat[4], -81);
EXPECT_FLOAT_EQ(test1.m_mat[5], -96);
EXPECT_FLOAT_EQ(test1.m_mat[6], -102);
EXPECT_FLOAT_EQ(test1.m_mat[7], -126);
EXPECT_FLOAT_EQ(test1.m_mat[8], -150);
}
TEST(TestMatrix3x3, operatorMultiplicationVector) {
etk::Matrix3 test1(1, 2, 3, 4, 5, 6, 7, 8, 9);
vec3 result = test1 * vec3(1,2,3);
EXPECT_FLOAT_EQ(result.x(), 14.0);
EXPECT_FLOAT_EQ(result.y(), 32.0);
EXPECT_FLOAT_EQ(result.z(), 50.0);
}

161
test/testQuaternion.cpp Normal file
View File

@ -0,0 +1,161 @@
/**
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
#include <gtest/gtest.h>
#include <etk/math/Quaternion.hpp>
#include <test-debug/debug.hpp>
#define NAME "etk::Quaternion"
TEST(TestQuaternion, constructor) {
etk::Quaternion test0(1,2,3,4);
EXPECT_FLOAT_EQ(test0.x(), 1.0);
EXPECT_FLOAT_EQ(test0.y(), 2.0);
EXPECT_FLOAT_EQ(test0.z(), 3.0);
EXPECT_FLOAT_EQ(test0.w(), 4.0);
etk::Quaternion test1(4, etk::Vector3D<float>(1,2,3));
EXPECT_FLOAT_EQ(test1.x(), 1.0);
EXPECT_FLOAT_EQ(test1.y(), 2.0);
EXPECT_FLOAT_EQ(test1.z(), 3.0);
EXPECT_FLOAT_EQ(test1.w(), 4.0);
etk::Quaternion test2;
EXPECT_FLOAT_EQ(test2.x(), 0.0);
EXPECT_FLOAT_EQ(test2.y(), 0.0);
EXPECT_FLOAT_EQ(test2.z(), 0.0);
EXPECT_FLOAT_EQ(test2.w(), 0.0);
etk::Quaternion test3(test0);
EXPECT_FLOAT_EQ(test3.x(), 1.0);
EXPECT_FLOAT_EQ(test3.y(), 2.0);
EXPECT_FLOAT_EQ(test3.z(), 3.0);
EXPECT_FLOAT_EQ(test3.w(), 4.0);
etk::Quaternion test4 = test0;
EXPECT_FLOAT_EQ(test4.x(), 1.0);
EXPECT_FLOAT_EQ(test4.y(), 2.0);
EXPECT_FLOAT_EQ(test4.z(), 3.0);
EXPECT_FLOAT_EQ(test4.w(), 4.0);
test2 = test0;
EXPECT_FLOAT_EQ(test2.x(), 1.0);
EXPECT_FLOAT_EQ(test2.y(), 2.0);
EXPECT_FLOAT_EQ(test2.z(), 3.0);
EXPECT_FLOAT_EQ(test2.w(), 4.0);
}
TEST(TestQuaternion, constructorMatrix) {
etk::Quaternion test1(0.18257423, 0.3651484, 0.54772264, 0.73029673);
etk::Quaternion test2(test1.getMatrix());
EXPECT_FLOAT_EQ(test2.x(), 0.18257423);
EXPECT_FLOAT_EQ(test2.y(), 0.3651484);
EXPECT_FLOAT_EQ(test2.z(), 0.54772264);
EXPECT_FLOAT_EQ(test2.w(), 0.73029673);
}
TEST(TestQuaternion, constructorEuler) {
etk::Quaternion test0(etk::Vector3D<float>(M_PI*0.5f, 0, 0));
etk::Quaternion test01(std::sin(M_PI*0.25f), 0, 0, std::cos(M_PI*0.25f));
test01.normalize();
EXPECT_FLOAT_EQ(test0.x(), test01.x());
EXPECT_FLOAT_EQ(test0.y(), test01.y());
EXPECT_FLOAT_EQ(test0.z(), test01.z());
EXPECT_FLOAT_EQ(test0.w(), test01.w());
etk::Quaternion test1(etk::Vector3D<float>(0, M_PI*0.5f, 0));
etk::Quaternion test11(0, std::sin(M_PI*0.25f), 0, std::cos(M_PI*0.25f));
test11.normalize();
EXPECT_FLOAT_EQ(test1.x(), test11.x());
EXPECT_FLOAT_EQ(test1.y(), test11.y());
EXPECT_FLOAT_EQ(test1.z(), test11.z());
EXPECT_FLOAT_EQ(test1.w(), test11.w());
etk::Quaternion test2(etk::Vector3D<float>(0, 0, M_PI*0.5f));
etk::Quaternion test21(0, 0, std::sin(M_PI*0.25f), std::cos(M_PI*0.25f));
test21.normalize();
EXPECT_FLOAT_EQ(test2.x(), test21.x());
EXPECT_FLOAT_EQ(test2.y(), test21.y());
EXPECT_FLOAT_EQ(test2.z(), test21.z());
EXPECT_FLOAT_EQ(test2.w(), test21.w());
}
TEST(TestQuaternion, normalize) {
etk::Quaternion test1(5, 3, 8, 2);
etk::Quaternion test2 = test1.normalized();
// check if other quaternion does not change
EXPECT_FLOAT_EQ(test1.x(), 5.0);
EXPECT_FLOAT_EQ(test1.y(), 3.0);
EXPECT_FLOAT_EQ(test1.z(), 8.0);
EXPECT_FLOAT_EQ(test1.w(), 2.0);
EXPECT_FLOAT_EQ(test2.x(), 0.4950738);
EXPECT_FLOAT_EQ(test2.y(), 0.29704428);
EXPECT_FLOAT_EQ(test2.z(), 0.79211807);
EXPECT_FLOAT_EQ(test2.w(), 0.19802952);
test1.normalize();
EXPECT_FLOAT_EQ(test1.x(), 0.4950738);
EXPECT_FLOAT_EQ(test1.y(), 0.29704428);
EXPECT_FLOAT_EQ(test1.z(), 0.79211807);
EXPECT_FLOAT_EQ(test1.w(), 0.19802952);
}
TEST(TestQuaternion, length) {
etk::Quaternion test1(5, 3, 8, 2);
EXPECT_FLOAT_EQ(test1.length2(), 102.0);
EXPECT_FLOAT_EQ(test1.length(), 10.099504);
EXPECT_FLOAT_EQ(test1.normalized().length(), 1.0);
}
TEST(TestQuaternion, set) {
etk::Quaternion test1(5, 3, 8, 2);
test1.setValue(12, 15, 22, 13);
EXPECT_FLOAT_EQ(test1.x(), 12.0);
EXPECT_FLOAT_EQ(test1.y(), 15.0);
EXPECT_FLOAT_EQ(test1.z(), 22.0);
EXPECT_FLOAT_EQ(test1.w(), 13.0);
test1.setZero();
EXPECT_FLOAT_EQ(test1.x(), 0.0);
EXPECT_FLOAT_EQ(test1.y(), 0.0);
EXPECT_FLOAT_EQ(test1.z(), 0.0);
EXPECT_FLOAT_EQ(test1.w(), 0.0);
test1.setIdentity();
EXPECT_FLOAT_EQ(test1.x(), 0.0);
EXPECT_FLOAT_EQ(test1.y(), 0.0);
EXPECT_FLOAT_EQ(test1.z(), 0.0);
EXPECT_FLOAT_EQ(test1.w(), 1.0);
test1 = etk::Quaternion::zero();
EXPECT_FLOAT_EQ(test1.x(), 0.0);
EXPECT_FLOAT_EQ(test1.y(), 0.0);
EXPECT_FLOAT_EQ(test1.z(), 0.0);
EXPECT_FLOAT_EQ(test1.w(), 0.0);
test1 = etk::Quaternion::identity();
EXPECT_FLOAT_EQ(test1.x(), 0.0);
EXPECT_FLOAT_EQ(test1.y(), 0.0);
EXPECT_FLOAT_EQ(test1.z(), 0.0);
EXPECT_FLOAT_EQ(test1.w(), 1.0);
}
TEST(TestQuaternion, getVector) {
etk::Quaternion test1(5, 3, 8, 2);
etk::Vector3D<float> test2 = test1.getVectorV();
EXPECT_FLOAT_EQ(test2.x(), 5.0);
EXPECT_FLOAT_EQ(test2.y(), 3.0);
EXPECT_FLOAT_EQ(test2.z(), 8.0);
}
TEST(TestQuaternion, conjugate) {
etk::Quaternion test1(5, 3, 8, 2);
etk::Quaternion test2 = test1.getConjugate();
// check if other quaternion does not change
EXPECT_FLOAT_EQ(test1.x(), 5.0);
EXPECT_FLOAT_EQ(test1.y(), 3.0);
EXPECT_FLOAT_EQ(test1.z(), 8.0);
EXPECT_FLOAT_EQ(test1.w(), 2.0);
EXPECT_FLOAT_EQ(test2.x(), -5.0);
EXPECT_FLOAT_EQ(test2.y(), -3.0);
EXPECT_FLOAT_EQ(test2.z(), -8.0);
EXPECT_FLOAT_EQ(test2.w(), 2.0);
test1.conjugate();
EXPECT_FLOAT_EQ(test1.x(), -5.0);
EXPECT_FLOAT_EQ(test1.y(), -3.0);
EXPECT_FLOAT_EQ(test1.z(), -8.0);
EXPECT_FLOAT_EQ(test1.w(), 2.0);
}

View File

@ -8,8 +8,8 @@
#include <gtest/gtest.h>
#include <etk/RegExp.hpp>
#include <test-debug/debug.hpp>
#undef NAME
#define NAME "Hash"
std::pair<int32_t, int32_t> testRegExpSingle(const std::string& _expression, const std::string& _search) {

View File

@ -8,7 +8,7 @@
#include <gtest/gtest.h>
#include <ememory/memory.hpp>
#undef NAME
#include <test-debug/debug.hpp>
#define NAME "Shared_ptr"
class Example : public ememory::EnableSharedFromThis<Example> {

0
test/testTransform.cpp Normal file
View File

109
test/testVector2_f.cpp Normal file
View File

@ -0,0 +1,109 @@
/**
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
#include <gtest/gtest.h>
#include <etk/math/Vector2D.hpp>
#include <test-debug/debug.hpp>
#define NAME "etk:Vector2D<float>"
TEST(TestVector2D_f, constructor) {
// Test contructor value
etk::Vector2D<float> test0(0,0);
EXPECT_FLOAT_EQ(test0.x(), 0.0);
EXPECT_FLOAT_EQ(test0.y(), 0.0);
etk::Vector2D<float> vect1(4,5);
EXPECT_FLOAT_EQ(vect1.x(), 4.0);
EXPECT_FLOAT_EQ(vect1.y(), 5.0);
etk::Vector2D<float> vect2(vect1);
EXPECT_FLOAT_EQ(vect2.x(), 4.0);
EXPECT_FLOAT_EQ(vect2.y(), 5.0);
etk::Vector2D<float> vect3 = vect1;
EXPECT_FLOAT_EQ(vect3.x(), 4.0);
EXPECT_FLOAT_EQ(vect3.y(), 5.0);
test0 = vect2;
EXPECT_FLOAT_EQ(test0.x(), 4.0);
EXPECT_FLOAT_EQ(test0.y(), 5.0);
}
TEST(TestVector2D_f, constructorString) {
etk::Vector2D<float> vect1("(4,-8.5)");
EXPECT_FLOAT_EQ(vect1.x(), 4.0);
EXPECT_FLOAT_EQ(vect1.y(), -8.5);
etk::Vector2D<float> vect2("-6,5.5");
EXPECT_FLOAT_EQ(vect2.x(), -6.0);
EXPECT_FLOAT_EQ(vect2.y(), 5.5);
etk::Vector2D<float> vect3("256.38");
EXPECT_FLOAT_EQ(vect3.x(), 256.38);
EXPECT_FLOAT_EQ(vect3.y(), 256.38);
}
TEST(TestVector2D_f, equity) {
etk::Vector2D<float> test1(99,32);
etk::Vector2D<float> test2(11,22);
etk::Vector2D<float> test3(11,22);
EXPECT_EQ(test1 == test2, false);
EXPECT_EQ(test1 != test2, true);
EXPECT_EQ(test3 == test2, true);
EXPECT_EQ(test3 != test2, false);
}
TEST(TestVector2D_f, set) {
// Test contructor value
etk::Vector2D<float> test1(0,0);
EXPECT_FLOAT_EQ(test1.x(), 0.0);
EXPECT_FLOAT_EQ(test1.y(), 0.0);
test1.setValue(1,2);
EXPECT_FLOAT_EQ(test1.x(), 1.0);
EXPECT_FLOAT_EQ(test1.y(), 2.0);
}
TEST(TestVector2D_f, setSetZero) {
// Test contructor value
etk::Vector2D<float> test1(4,5);
EXPECT_FLOAT_EQ(test1.x(), 4.0);
EXPECT_FLOAT_EQ(test1.y(), 5.0);
test1.setZero();
EXPECT_FLOAT_EQ(test1.x(), 0.0);
EXPECT_FLOAT_EQ(test1.y(), 0.0);
}
TEST(TestVector2D_f, length) {
// Test contructor value
etk::Vector2D<float> test1(0,0);
EXPECT_FLOAT_EQ(test1.length(), 0.0);
EXPECT_FLOAT_EQ(test1.length2(), 0.0);
test1.setValue(2,0);
EXPECT_FLOAT_EQ(test1.length(), 2.0);
test1.setValue(0,3);
EXPECT_FLOAT_EQ(test1.length(), 3.0);
test1.setValue(3,4);
EXPECT_FLOAT_EQ(test1.length2(), 25.0);
}
TEST(TestVector2D_f, normalize) {
etk::Vector2D<float> test1(11,22);
etk::Vector2D<float> test2 = test1.normalized();
EXPECT_FLOAT_EQ(test1.x(), 11.0);
EXPECT_FLOAT_EQ(test1.y(), 22.0);
EXPECT_FLOAT_EQ(test2.x(), 0.44721359);
EXPECT_FLOAT_EQ(test2.y(), 0.89442718);
test1.normalize();
EXPECT_FLOAT_EQ(test1.x(), 0.44721359);
EXPECT_FLOAT_EQ(test1.y(), 0.89442718);
}
TEST(TestVector2D_f, dot) {
etk::Vector2D<float> test1(11,0);
etk::Vector2D<float> test2(0,88);
EXPECT_FLOAT_EQ(test1.dot(test1), 121.0);
EXPECT_FLOAT_EQ(test1.dot(test2), 0.0);
test1.setValue(2,3);
test2.setValue(9,7);
EXPECT_FLOAT_EQ(test1.dot(test2), 39.0);
}

127
test/testVector3_f.cpp Normal file
View File

@ -0,0 +1,127 @@
/**
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
#include <gtest/gtest.h>
#include <etk/math/Vector3D.hpp>
#include <test-debug/debug.hpp>
#define NAME "etk:Vector3D<float>"
TEST(TestVector3D_f, constructor) {
// Test contructor value
etk::Vector3D<float> test0(0,0,0);
EXPECT_FLOAT_EQ(test0.x(), 0.0);
EXPECT_FLOAT_EQ(test0.y(), 0.0);
EXPECT_FLOAT_EQ(test0.z(), 0.0);
etk::Vector3D<float> vect1(4,5,8);
EXPECT_FLOAT_EQ(vect1.x(), 4.0);
EXPECT_FLOAT_EQ(vect1.y(), 5.0);
EXPECT_FLOAT_EQ(vect1.z(), 8.0);
etk::Vector3D<float> vect2(vect1);
EXPECT_FLOAT_EQ(vect2.x(), 4.0);
EXPECT_FLOAT_EQ(vect2.y(), 5.0);
EXPECT_FLOAT_EQ(vect2.z(), 8.0);
etk::Vector3D<float> vect3 = vect1;
EXPECT_FLOAT_EQ(vect3.x(), 4.0);
EXPECT_FLOAT_EQ(vect3.y(), 5.0);
EXPECT_FLOAT_EQ(vect3.z(), 8.0);
test0 = vect2;
EXPECT_FLOAT_EQ(test0.x(), 4.0);
EXPECT_FLOAT_EQ(test0.y(), 5.0);
EXPECT_FLOAT_EQ(test0.z(), 8.0);
}
TEST(TestVector3D_f, equity) {
etk::Vector3D<float> test1(99,32,56);
etk::Vector3D<float> test2(11,22,33);
etk::Vector3D<float> test3(11,22,33);
EXPECT_EQ(test1 == test2, false);
EXPECT_EQ(test1 != test2, true);
EXPECT_EQ(test3 == test2, true);
EXPECT_EQ(test3 != test2, false);
}
TEST(TestVector3D_f, set) {
// Test contructor value
etk::Vector3D<float> test1(0,0,0);
EXPECT_FLOAT_EQ(test1.x(), 0.0);
EXPECT_FLOAT_EQ(test1.y(), 0.0);
EXPECT_FLOAT_EQ(test1.z(), 0.0);
test1.setValue(1,2,3);
EXPECT_FLOAT_EQ(test1.x(), 1.0);
EXPECT_FLOAT_EQ(test1.y(), 2.0);
EXPECT_FLOAT_EQ(test1.z(), 3.0);
}
TEST(TestVector3D_f, setSetZero) {
// Test contructor value
etk::Vector3D<float> test1(4,5,6);
EXPECT_FLOAT_EQ(test1.x(), 4.0);
EXPECT_FLOAT_EQ(test1.y(), 5.0);
EXPECT_FLOAT_EQ(test1.z(), 6.0);
test1.setZero();
EXPECT_FLOAT_EQ(test1.x(), 0.0);
EXPECT_FLOAT_EQ(test1.y(), 0.0);
EXPECT_FLOAT_EQ(test1.z(), 0.0);
}
TEST(TestVector3D_f, length) {
// Test contructor value
etk::Vector3D<float> test1(0,0,0);
EXPECT_FLOAT_EQ(test1.length(), 0.0);
EXPECT_FLOAT_EQ(test1.length2(), 0.0);
test1.setValue(2,0,0);
EXPECT_FLOAT_EQ(test1.length(), 2.0);
test1.setValue(0,3,0);
EXPECT_FLOAT_EQ(test1.length(), 3.0);
test1.setValue(0,0,4);
EXPECT_FLOAT_EQ(test1.length(), 4.0);
test1.setValue(3,4,5);
EXPECT_FLOAT_EQ(test1.length2(), 50.0);
}
TEST(TestVector3D_f, normalize) {
etk::Vector3D<float> test1(11,22,33);
etk::Vector3D<float> test2 = test1.normalized();
EXPECT_FLOAT_EQ(test1.x(), 11.0);
EXPECT_FLOAT_EQ(test1.y(), 22.0);
EXPECT_FLOAT_EQ(test1.z(), 33.0);
EXPECT_FLOAT_EQ(test2.x(), 0.26726124);
EXPECT_FLOAT_EQ(test2.y(), 0.53452247);
EXPECT_FLOAT_EQ(test2.z(), 0.80178374);
test1.normalize();
EXPECT_FLOAT_EQ(test1.x(), 0.26726124);
EXPECT_FLOAT_EQ(test1.y(), 0.53452247);
EXPECT_FLOAT_EQ(test1.z(), 0.80178374);
}
TEST(TestVector3D_f, dot) {
etk::Vector3D<float> test1(11,0,0);
etk::Vector3D<float> test2(0,88,66);
EXPECT_FLOAT_EQ(test1.dot(test1), 121.0);
EXPECT_FLOAT_EQ(test1.dot(test2), 0.0);
test1.setValue(2,3,5);
test2.setValue(9,7,6);
EXPECT_FLOAT_EQ(test1.dot(test2), 69.0); // ????
}
TEST(TestVector3D_f, cross) {
etk::Vector3D<float> test1(0,0,0);
etk::Vector3D<float> test2(-55,88,66);
EXPECT_EQ(test1.cross(test1), vec3(0,0,0));
EXPECT_EQ(test2.cross(test2), vec3(0,0,0));
test1.setValue(1,0,0);
test2.setValue(0,1,0);
EXPECT_EQ(test1.cross(test2), vec3(0,0,1));
test2.setValue(0,0,1);
EXPECT_EQ(test1.cross(test2), vec3(0,-1,0));
test1.setValue(0,1,0);
EXPECT_EQ(test1.cross(test2), vec3(1,0,0));
test1.setValue(8,9,-10);
test2.setValue(2,-3,5);
EXPECT_EQ(test1.cross(test2), vec3(15,-60,-42));
}