Merge remote branch 'origin/master'
This commit is contained in:
commit
878ea70ef7
13 changed files with 369 additions and 356 deletions
4
TODO.md
4
TODO.md
|
@ -1,6 +1,7 @@
|
||||||
# core
|
# core
|
||||||
|
|
||||||
* rewrite matrix and associated code
|
* rewrite matrix and associated code
|
||||||
|
* rename rect to rectangle
|
||||||
|
|
||||||
|
|
||||||
# scripting
|
# scripting
|
||||||
|
@ -8,5 +9,8 @@
|
||||||
* refactor script into something like a runtime - script
|
* refactor script into something like a runtime - script
|
||||||
|
|
||||||
|
|
||||||
|
# scene
|
||||||
|
|
||||||
|
* add_child and add_component should have guards - use std::lock_guard
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -19,24 +19,28 @@ set(hdrs
|
||||||
include/pw/core/image.hpp
|
include/pw/core/image.hpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
set(misc
|
||||||
|
${CMAKE_SOURCE_DIR}/README.md
|
||||||
|
${CMAKE_SOURCE_DIR}/LICENSE
|
||||||
|
${CMAKE_SOURCE_DIR}/TODO.md
|
||||||
|
)
|
||||||
|
|
||||||
set(srcs
|
set(srcs
|
||||||
# src/buffer.cpp
|
# src/buffer.cpp
|
||||||
src/image.cpp
|
src/image.cpp
|
||||||
src/debug.cpp
|
src/debug.cpp
|
||||||
src/mesh.cpp
|
# src/mesh.cpp
|
||||||
src/core.cpp
|
src/core.cpp
|
||||||
src/serialize.cpp
|
src/serialize.cpp
|
||||||
src/timer.cpp
|
src/timer.cpp
|
||||||
src/image.cpp
|
src/image.cpp
|
||||||
${CMAKE_SOURCE_DIR}/README.md
|
|
||||||
${CMAKE_SOURCE_DIR}/LICENSE
|
|
||||||
${CMAKE_SOURCE_DIR}/TODO.md
|
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(pwcore
|
add_library(pwcore
|
||||||
STATIC
|
STATIC
|
||||||
${hdrs}
|
${hdrs}
|
||||||
${srcs}
|
${srcs}
|
||||||
|
${misc}
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(
|
target_include_directories(
|
||||||
|
@ -47,8 +51,5 @@ target_include_directories(
|
||||||
|
|
||||||
target_link_libraries(pwcore)
|
target_link_libraries(pwcore)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#add_subdirectory(src)
|
|
||||||
add_subdirectory(tests)
|
add_subdirectory(tests)
|
||||||
|
|
||||||
|
|
|
@ -24,48 +24,39 @@
|
||||||
#define PW_CORE_MATRIX_HPP
|
#define PW_CORE_MATRIX_HPP
|
||||||
|
|
||||||
#include <pw/core/globals.hpp>
|
#include <pw/core/globals.hpp>
|
||||||
#include <pw/core/matrixbase.hpp>
|
|
||||||
#include <pw/core/math.hpp>
|
#include <pw/core/math.hpp>
|
||||||
|
#include <pw/core/matrixbase.hpp>
|
||||||
|
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
|
||||||
namespace pw {
|
namespace pw {
|
||||||
|
|
||||||
template <std::size_t R,std::size_t C,bool RowMajor = false>
|
|
||||||
struct matrixtraits_
|
template <std::size_t R,std::size_t C, typename T, bool RowMajor = false>
|
||||||
|
struct matrix_ : matrixbase_<T, matrix_<R, C, T>>
|
||||||
{
|
{
|
||||||
//! rows
|
|
||||||
inline std::size_t rows() const { return R; }
|
|
||||||
|
|
||||||
//! return number of columns
|
|
||||||
inline std::size_t cols() const { return C; }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T, std::size_t R,std::size_t C,bool RowMajor = false>
|
|
||||||
struct matrix_ : matrixbase_<T, matrix_<T, R, C>>,matrixtraits_<R,C,RowMajor>
|
|
||||||
{
|
|
||||||
|
|
||||||
T data[R*C];
|
T data[R*C];
|
||||||
|
|
||||||
// typedef matrixbase_<T, matrix_<T, R, C>> Base;
|
using matrixbase_<T, matrix_<R, C, T>>::matrixbase_;
|
||||||
using matrixbase_<T, matrix_<T, R, C>>::matrixbase_;
|
|
||||||
using matrixtraits_<R,C,RowMajor>::rows;
|
|
||||||
using matrixtraits_<R,C,RowMajor>::cols;
|
|
||||||
|
|
||||||
|
static const std::size_t rows = R;
|
||||||
|
static const std::size_t cols = C;
|
||||||
|
|
||||||
|
typedef matrix_<R,1,T> col_type;
|
||||||
|
typedef matrix_<1,C,T> row_type;
|
||||||
|
|
||||||
matrix_(const matrix_& other)
|
matrix_(const matrix_& other)
|
||||||
{
|
{
|
||||||
*this = other;
|
*this = other;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
explicit matrix_(std::initializer_list<T> args)
|
explicit matrix_(std::initializer_list<T> args)
|
||||||
{
|
{
|
||||||
typename std::initializer_list<T>::iterator it = args.begin();
|
typename std::initializer_list<T>::iterator it = args.begin();
|
||||||
for (;it != args.end();it++) data[it-args.begin()] = *it;
|
for (;it != args.end();it++) data[it-args.begin()] = *it;
|
||||||
}
|
}
|
||||||
|
|
||||||
matrix_& operator = (const matrix_<T,R,C,RowMajor>& other)
|
matrix_& operator = (const matrix_& other)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < other.size();i++) (*this)[i] = other[i];
|
for (size_t i = 0; i < other.size();i++) (*this)[i] = other[i];
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -100,16 +91,16 @@ struct matrix_ : matrixbase_<T, matrix_<T, R, C>>,matrixtraits_<R,C,RowMajor>
|
||||||
//! set identity
|
//! set identity
|
||||||
inline matrix_& set_identity()
|
inline matrix_& set_identity()
|
||||||
{
|
{
|
||||||
for (unsigned int r = 0;r < rows(); r++)
|
for (std::size_t r = 0;r < rows; r++)
|
||||||
for (unsigned int c = 0; c < cols(); c++)
|
for (std::size_t c = 0; c < cols; c++)
|
||||||
(*this)(r,c) = (c == r) ? T(1) : T(0);
|
(*this)(r,c) = (c == r) ? T(1) : T(0);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t Rs,std::size_t Cs,bool RowMajorSlice = RowMajor>
|
template<std::size_t Rs,std::size_t Cs,bool RowMajorSlice = RowMajor>
|
||||||
matrix_<T,Rs,Cs,RowMajorSlice> slice(std::size_t r,std::size_t c) const
|
auto slice(std::size_t r,std::size_t c) const
|
||||||
{
|
{
|
||||||
matrix_<T,Rs,Cs,RowMajorSlice> s;
|
matrix_<Rs,Cs,T,RowMajorSlice> s;
|
||||||
for (std::size_t ri = 0;ri < Rs;ri++)
|
for (std::size_t ri = 0;ri < Rs;ri++)
|
||||||
for (std::size_t ci = 0;ci < Cs;ci++)
|
for (std::size_t ci = 0;ci < Cs;ci++)
|
||||||
s(ri,ci) = (*this)(ri+r,ci+c);
|
s(ri,ci) = (*this)(ri+r,ci+c);
|
||||||
|
@ -117,7 +108,7 @@ struct matrix_ : matrixbase_<T, matrix_<T, R, C>>,matrixtraits_<R,C,RowMajor>
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t Rs,std::size_t Cs,bool RowMajorSlice = RowMajor>
|
template<std::size_t Rs,std::size_t Cs,bool RowMajorSlice = RowMajor>
|
||||||
matrix_& set_slice(const matrix_<T,Rs,Cs,RowMajorSlice>& s,std::size_t r,std::size_t c)
|
matrix_& set_slice(const matrix_<Rs,Cs,T,RowMajorSlice>& s,std::size_t r,std::size_t c)
|
||||||
{
|
{
|
||||||
for (std::size_t ri = 0;ri < Rs;ri++)
|
for (std::size_t ri = 0;ri < Rs;ri++)
|
||||||
for (std::size_t ci = 0;ci < Cs;ci++)
|
for (std::size_t ci = 0;ci < Cs;ci++)
|
||||||
|
@ -127,9 +118,9 @@ struct matrix_ : matrixbase_<T, matrix_<T, R, C>>,matrixtraits_<R,C,RowMajor>
|
||||||
|
|
||||||
|
|
||||||
template<std::size_t Rs,std::size_t Cs,bool RowMajorSlice = RowMajor>
|
template<std::size_t Rs,std::size_t Cs,bool RowMajorSlice = RowMajor>
|
||||||
matrix_<T,Rs,Cs,RowMajorSlice> minor(std::size_t r0,std::size_t c0) const
|
auto minor(std::size_t r0,std::size_t c0) const
|
||||||
{
|
{
|
||||||
matrix_<T,Rs,Cs,RowMajorSlice> m;
|
matrix_<Rs,Cs,T,RowMajorSlice> m;
|
||||||
size_t r = 0;
|
size_t r = 0;
|
||||||
for (size_t ri = 0; ri < R; ri++) {
|
for (size_t ri = 0; ri < R; ri++) {
|
||||||
size_t c = 0;
|
size_t c = 0;
|
||||||
|
@ -155,17 +146,17 @@ struct matrix_ : matrixbase_<T, matrix_<T, R, C>>,matrixtraits_<R,C,RowMajor>
|
||||||
return det;
|
return det;
|
||||||
}
|
}
|
||||||
|
|
||||||
matrix_<T,C,R,RowMajor> transposed() const {
|
auto transposed() const {
|
||||||
matrix_<T,C,R,RowMajor> res;
|
matrix_<C,R,T,RowMajor> res;
|
||||||
for (size_t r = this->rows();r-->0;)
|
for (size_t r = rows;r-->0;)
|
||||||
for (size_t c = this->cols();c-->0;)
|
for (size_t c = cols;c-->0;)
|
||||||
res(c,r) = (*this)(r,c);
|
res(c,r) = (*this)(r,c);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
matrix_<T,C,R,RowMajor> inverse() const {
|
auto inverse() const {
|
||||||
T invDet = T(1) / this->determinant();
|
T invDet = T(1) / this->determinant();
|
||||||
matrix_<T,C,R,RowMajor> inv;
|
matrix_<R,C,T,RowMajor> inv;
|
||||||
for (int j = 0; j < C; j++)
|
for (int j = 0; j < C; j++)
|
||||||
for (int i = 0; i < R; i++)
|
for (int i = 0; i < R; i++)
|
||||||
{
|
{
|
||||||
|
@ -199,16 +190,21 @@ struct matrix_ : matrixbase_<T, matrix_<T, R, C>>,matrixtraits_<R,C,RowMajor>
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
row_type row(size_t row_) const {
|
||||||
|
row_type r; for (size_t i = 0; i < cols; i++) r[i] = (*this)(row_,i); return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> inline
|
template <> inline
|
||||||
float matrix_<float,1,1>::determinant() const
|
float matrix_<1,1,float>::determinant() const
|
||||||
{
|
{
|
||||||
return (*this)(0,0);
|
return (*this)(0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <> inline
|
template <> inline
|
||||||
double matrix_<double,1,1>::determinant() const
|
double matrix_<1,1,double>::determinant() const
|
||||||
{
|
{
|
||||||
return (*this)(0,0);
|
return (*this)(0,0);
|
||||||
}
|
}
|
||||||
|
@ -216,11 +212,11 @@ double matrix_<double,1,1>::determinant() const
|
||||||
|
|
||||||
|
|
||||||
template <typename T, std::size_t R, std::size_t Ca,std::size_t Cb>
|
template <typename T, std::size_t R, std::size_t Ca,std::size_t Cb>
|
||||||
auto operator * (const matrix_<T, R, Ca>& A,
|
auto operator * (const matrix_<R, Ca, T>& A,
|
||||||
const matrix_<T, R, Cb>& B
|
const matrix_<R, Cb, T>& B
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
matrix_<T,R,Cb> result; result.zero(); // zero the output
|
matrix_<R,Cb,T> result; result.zero(); // zero the output
|
||||||
for (size_t r = 0; r < R; r++)
|
for (size_t r = 0; r < R; r++)
|
||||||
for (size_t c = 0; c < Cb; c++)
|
for (size_t c = 0; c < Cb; c++)
|
||||||
for (size_t iI = 0; iI < R; iI++)
|
for (size_t iI = 0; iI < R; iI++)
|
||||||
|
@ -234,49 +230,49 @@ auto operator * (const matrix_<T, R, Ca>& A,
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
template <typename T> using matrix2x2_ = matrix_<T, 2, 2>;
|
template <typename T> using matrix2x2_ = matrix_<2, 2, T>;
|
||||||
template <typename T> using matrix3x3_ = matrix_<T, 3, 3>;
|
//template <typename T> using matrix3x3_ = matrix_<T, 3, 3>;
|
||||||
template <typename T> using matrix4x4_ = matrix_<T, 4, 4>;
|
//template <typename T> using matrix4x4_ = matrix_<T, 4, 4>;
|
||||||
|
|
||||||
using matrix2x2f = matrix_<float, 2, 2>;
|
using matrix2x2f = matrix_<2, 2,float>;
|
||||||
using matrix2x2d = matrix_<double, 2, 2>;
|
using matrix2x2d = matrix_<2, 2,double>;
|
||||||
using matrix2x2 = matrix_<real_t, 2, 2>;
|
using matrix2x2 = matrix_<2, 2,real_t>;
|
||||||
|
|
||||||
using matrix3x3f = matrix_<float, 3, 3>;
|
//using matrix3x3f = matrix_<float, 3, 3>;
|
||||||
using matrix3x3d = matrix_<double, 3, 3>;
|
//using matrix3x3d = matrix_<double, 3, 3>;
|
||||||
using matrix3x3 = matrix_<real_t, 3, 3>;
|
//using matrix3x3 = matrix_<real_t, 3, 3>;
|
||||||
|
|
||||||
using matrix4x4f = matrix_<float, 4, 4>;
|
//using matrix4x4f = matrix_<float, 4, 4>;
|
||||||
using matrix4x4d = matrix_<double, 4, 4>;
|
//using matrix4x4d = matrix_<double, 4, 4>;
|
||||||
using matrix4x4 = matrix_<real_t, 4, 4>;
|
//using matrix4x4 = matrix_<real_t, 4, 4>;
|
||||||
|
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
||||||
template <typename T>
|
//template <typename T>
|
||||||
struct matrix_tools {
|
//struct matrix_tools {
|
||||||
|
|
||||||
inline static
|
// inline static
|
||||||
matrix4x4_<T> projection_from_frustum(T Left,T Right,T Bottom,T Top,T zNear,T zFar)
|
// matrix4x4_<T> projection_from_frustum(T Left,T Right,T Bottom,T Top,T zNear,T zFar)
|
||||||
{
|
// {
|
||||||
matrix4x4_<T> frustum;
|
// matrix4x4_<T> frustum;
|
||||||
|
|
||||||
frustum.fill(0);
|
// frustum.fill(0);
|
||||||
|
|
||||||
frustum(0,0) = T(2) * zNear/(Right-Left);
|
// frustum(0,0) = T(2) * zNear/(Right-Left);
|
||||||
frustum(1,1) = T(2) * zNear/(Top-Bottom);
|
// frustum(1,1) = T(2) * zNear/(Top-Bottom);
|
||||||
|
|
||||||
frustum(0,2) = (Right+Left)/(Right-Left); //A
|
// frustum(0,2) = (Right+Left)/(Right-Left); //A
|
||||||
frustum(1,2) = (Top+Bottom)/(Top-Bottom); //B
|
// frustum(1,2) = (Top+Bottom)/(Top-Bottom); //B
|
||||||
frustum(2,2) = - (zFar+zNear)/(zFar-zNear); //C
|
// frustum(2,2) = - (zFar+zNear)/(zFar-zNear); //C
|
||||||
frustum(3,2) = -(T(2) * zFar*zNear)/(zFar-zNear); //D
|
// frustum(3,2) = -(T(2) * zFar*zNear)/(zFar-zNear); //D
|
||||||
|
|
||||||
frustum(2,3) = -T(1);
|
// frustum(2,3) = -T(1);
|
||||||
|
|
||||||
return frustum;
|
// return frustum;
|
||||||
}
|
// }
|
||||||
};
|
//};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,6 +87,16 @@ struct matrixbase_ {
|
||||||
return derived().data[i];
|
return derived().data[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static T dot(const Derived &a,const Derived &b) {
|
||||||
|
Derived r; for (size_t i = 0;i < a.size();i++) r[i] = a[i] * b[i];
|
||||||
|
return std::accumulate(std::begin(r), std::end(r), T(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
static const Derived lerp(const Derived &a,const Derived &b,const T& t) {
|
||||||
|
return a + (b - a) * t;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// inline Derived& operator *= (const T& b) { for (auto & e : *this) e *= b; return derived(); }
|
// inline Derived& operator *= (const T& b) { for (auto & e : *this) e *= b; return derived(); }
|
||||||
// inline Derived& operator /= (const T& b) { for (auto & e : *this) e /= b; return derived(); }
|
// inline Derived& operator /= (const T& b) { for (auto & e : *this) e /= b; return derived(); }
|
||||||
// inline Derived& operator += (const T& b) { for (auto & e : *this) e += b; return derived(); }
|
// inline Derived& operator += (const T& b) { for (auto & e : *this) e += b; return derived(); }
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#define PW_CORE_QUATERNION_HPP
|
#define PW_CORE_QUATERNION_HPP
|
||||||
|
|
||||||
#include <pw/core/vector.hpp>
|
#include <pw/core/vector.hpp>
|
||||||
|
#include <pw/core/axisangle.hpp>
|
||||||
|
|
||||||
namespace pw {
|
namespace pw {
|
||||||
|
|
||||||
|
@ -33,79 +34,99 @@ namespace pw {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct quaternion_ : vector4_<T> {
|
struct quaternion_ : vector4_<T> {
|
||||||
|
|
||||||
typedef vector4_<T> Base;
|
typedef vector4_<T> Base;
|
||||||
|
|
||||||
using Base::Base;
|
using Base::Base;
|
||||||
using Base::x;
|
using Base::x;
|
||||||
using Base::y;
|
using Base::y;
|
||||||
using Base::z;
|
using Base::z;
|
||||||
using Base::w;
|
using Base::w;
|
||||||
// using Base::lerp;
|
using Base::lerp;
|
||||||
// using Base::operator*;
|
using Base::operator*;
|
||||||
using Base::operator/;
|
using Base::operator/;
|
||||||
|
|
||||||
inline const quaternion_ operator * (const quaternion_& rhs) const {
|
inline const quaternion_ operator * (const quaternion_& rhs) const {
|
||||||
return quaternion_(
|
return quaternion_(
|
||||||
rhs.w()*x() + rhs.x()*w() + rhs.y()*z() - rhs.z()*y(),
|
rhs.w()*x() + rhs.x()*w() + rhs.y()*z() - rhs.z()*y(),
|
||||||
rhs.w()*y() - rhs.x()*z() + rhs.y()*w() + rhs.z()*x(),
|
rhs.w()*y() - rhs.x()*z() + rhs.y()*w() + rhs.z()*x(),
|
||||||
rhs.w()*z() + rhs.x()*y() - rhs.y()*x() + rhs.z()*w(),
|
rhs.w()*z() + rhs.x()*y() - rhs.y()*x() + rhs.z()*w(),
|
||||||
rhs.w()*w() - rhs.x()*x() - rhs.y()*y() - rhs.z()*z()
|
rhs.w()*w() - rhs.x()*x() - rhs.y()*y() - rhs.z()*z()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! conjugate
|
inline const quaternion_ operator / (const T& rhs) const {
|
||||||
inline quaternion_ conjugate() const { return quaternion_( { -x(),-y(),-z(),w() } ); }
|
return quaternion_( { x() / rhs, y() / rhs, z() / rhs, w() / rhs, } );
|
||||||
|
}
|
||||||
|
|
||||||
//! compute inverse
|
//! conjugate
|
||||||
inline quaternion_ inverse() const {
|
inline quaternion_ conjugate() const { return quaternion_( { -x(),-y(),-z(),w() } ); }
|
||||||
return conjugate() / this->norm();
|
|
||||||
}
|
|
||||||
|
|
||||||
const matrix4x4_<T> to_matrix() const {
|
//! compute inverse
|
||||||
|
inline quaternion_ inverse() const {
|
||||||
|
return conjugate() / this->norm();
|
||||||
|
}
|
||||||
|
|
||||||
matrix4x4_<T> m; m.set_identity();
|
const matrix4x4_<T> to_matrix() const {
|
||||||
|
|
||||||
T xx = x() * x();
|
matrix4x4_<T> m; m.set_identity();
|
||||||
T xy = x() * y();
|
|
||||||
T xz = x() * z();
|
|
||||||
T xw = x() * w();
|
|
||||||
|
|
||||||
T yy = y() * y();
|
T xx = x() * x();
|
||||||
T yz = y() * z();
|
T xy = x() * y();
|
||||||
T yw = y() * w();
|
T xz = x() * z();
|
||||||
|
T xw = x() * w();
|
||||||
|
|
||||||
T zz = z() * z();
|
T yy = y() * y();
|
||||||
T zw = z() * w();
|
T yz = y() * z();
|
||||||
|
T yw = y() * w();
|
||||||
|
|
||||||
m(0,0) = 1 - 2 * ( yy + zz );
|
T zz = z() * z();
|
||||||
m(0,1) = 2 * ( xy - zw );
|
T zw = z() * w();
|
||||||
m(0,2) = 2 * ( xz + yw );
|
|
||||||
|
|
||||||
m(1,0) = 2 * ( xy + zw );
|
m(0,0) = 1 - 2 * ( yy + zz );
|
||||||
m(1,1) = 1 - 2 * ( xx + zz );
|
m(0,1) = 2 * ( xy - zw );
|
||||||
m(1,2) = 2 * ( yz - xw );
|
m(0,2) = 2 * ( xz + yw );
|
||||||
|
|
||||||
m(2,0) = 2 * ( xz - yw );
|
m(1,0) = 2 * ( xy + zw );
|
||||||
m(2,1) = 2 * ( yz + xw );
|
m(1,1) = 1 - 2 * ( xx + zz );
|
||||||
m(2,2) = 1 - 2 * ( xx + yy );
|
m(1,2) = 2 * ( yz - xw );
|
||||||
|
|
||||||
return m;
|
m(2,0) = 2 * ( xz - yw );
|
||||||
}
|
m(2,1) = 2 * ( yz + xw );
|
||||||
|
m(2,2) = 1 - 2 * ( xx + yy );
|
||||||
|
|
||||||
static quaternion_<T> from_matrix(const matrix_<T,4,4> &m) {
|
return m;
|
||||||
using std::sqrt;
|
}
|
||||||
const T wtemp = sqrt(T(1) + m(0,0) + m(1,1) + m(2,2)) / T(2);
|
|
||||||
const T w4 = T(4.0) * wtemp;
|
|
||||||
return quaternion_<T>(
|
|
||||||
(m(2,1) - m(1,2)) / w4,
|
|
||||||
(m(0,2) - m(2,0)) / w4,
|
|
||||||
(m(1,0) - m(0,1)) / w4,
|
|
||||||
wtemp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const quaternion_ normalized_lerp(const quaternion_ &a,const quaternion_ &b,const T &t) {
|
static quaternion_<T> from_matrix(const matrix_<T,4,4> &m) {
|
||||||
return quaternion_(lerp(a,b,t).normalized());
|
using std::sqrt;
|
||||||
}
|
const T wtemp = sqrt(T(1) + m(0,0) + m(1,1) + m(2,2)) / T(2);
|
||||||
|
const T w4 = T(4.0) * wtemp;
|
||||||
|
return quaternion_<T>(
|
||||||
|
(m(2,1) - m(1,2)) / w4,
|
||||||
|
(m(0,2) - m(2,0)) / w4,
|
||||||
|
(m(1,0) - m(0,1)) / w4,
|
||||||
|
wtemp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const quaternion_<T> normalized_lerp(const quaternion_<T> &a,const quaternion_<T> &b,const T &t) {
|
||||||
|
return quaternion_<T>(lerp(a,b,t).normalized());
|
||||||
|
}
|
||||||
|
|
||||||
|
static const quaternion_<T> from_axisangle(const axisangle_<T> &aa) {
|
||||||
|
|
||||||
|
using std::sin;
|
||||||
|
using std::cos;
|
||||||
|
|
||||||
|
const T sinHalfAngle( sin(aa.angle() * T(0.5) ));
|
||||||
|
|
||||||
|
return quaternion_<T>( { aa.axis().x() * sinHalfAngle, // x
|
||||||
|
aa.axis().y() * sinHalfAngle, // y
|
||||||
|
aa.axis().z() * sinHalfAngle, // z
|
||||||
|
cos(aa.angle() * T(0.5)) // w
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
//
|
//
|
||||||
|
@ -129,129 +150,129 @@ typedef quaternion_<double> quaterniond;
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class quaternion_ {
|
class quaternion_ {
|
||||||
|
|
||||||
static const T _sqrt90;
|
static const T _sqrt90;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef vector4_<T> coefficient_type;
|
typedef vector4_<T> coefficient_type;
|
||||||
typedef T value_type;
|
typedef T value_type;
|
||||||
|
|
||||||
quaternion_() { *this = identity(); }
|
quaternion_() { *this = identity(); }
|
||||||
|
|
||||||
quaternion_(const T& x,const T& y,const T& z,const T& w)
|
quaternion_(const T& x,const T& y,const T& z,const T& w)
|
||||||
: _q(coefficient_type(x,y,z,w)) {}
|
: _q(coefficient_type(x,y,z,w)) {}
|
||||||
|
|
||||||
quaternion_(const coefficient_type& vec) { *this = vec; }
|
quaternion_(const coefficient_type& vec) { *this = vec; }
|
||||||
|
|
||||||
inline quaternion_& operator = (const coefficient_type& vec) { _q = vec; return *this; }
|
inline quaternion_& operator = (const coefficient_type& vec) { _q = vec; return *this; }
|
||||||
|
|
||||||
inline void set(const T& x,const T& y,const T& z,const T& w) {
|
inline void set(const T& x,const T& y,const T& z,const T& w) {
|
||||||
_q.set(x,y,z,w);
|
_q.set(x,y,z,w);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void set_x(const T& v) { x() = v; }
|
inline void set_x(const T& v) { x() = v; }
|
||||||
inline void set_y(const T& v) { y() = v; }
|
inline void set_y(const T& v) { y() = v; }
|
||||||
inline void set_z(const T& v) { z() = v; }
|
inline void set_z(const T& v) { z() = v; }
|
||||||
inline void set_w(const T& v) { w() = v; }
|
inline void set_w(const T& v) { w() = v; }
|
||||||
|
|
||||||
inline const coefficient_type& as_vector() const { return _q; }
|
inline const coefficient_type& as_vector() const { return _q; }
|
||||||
|
|
||||||
inline T& x() { return _q.x(); }
|
inline T& x() { return _q.x(); }
|
||||||
inline T& y() { return _q.x(); }
|
inline T& y() { return _q.x(); }
|
||||||
inline T& z() { return _q.z(); }
|
inline T& z() { return _q.z(); }
|
||||||
inline T& w() { return _q.w(); }
|
inline T& w() { return _q.w(); }
|
||||||
|
|
||||||
inline const T& x() const { return _q.z(); }
|
inline const T& x() const { return _q.z(); }
|
||||||
inline const T& y() const { return _q.y(); }
|
inline const T& y() const { return _q.y(); }
|
||||||
inline const T& z() const { return _q.z(); }
|
inline const T& z() const { return _q.z(); }
|
||||||
inline const T& w() const { return _q.w(); }
|
inline const T& w() const { return _q.w(); }
|
||||||
|
|
||||||
|
|
||||||
//! multiplication
|
//! multiplication
|
||||||
inline const quaternion_ operator * (const quaternion_& rhs) const {
|
inline const quaternion_ operator * (const quaternion_& rhs) const {
|
||||||
return quaternion_(
|
return quaternion_(
|
||||||
rhs.w()*x() + rhs.x()*w() + rhs.y()*z() - rhs.z()*y(),
|
rhs.w()*x() + rhs.x()*w() + rhs.y()*z() - rhs.z()*y(),
|
||||||
rhs.w()*y() - rhs.x()*z() + rhs.y()*w() + rhs.z()*x(),
|
rhs.w()*y() - rhs.x()*z() + rhs.y()*w() + rhs.z()*x(),
|
||||||
rhs.w()*z() + rhs.x()*y() - rhs.y()*x() + rhs.z()*w(),
|
rhs.w()*z() + rhs.x()*y() - rhs.y()*x() + rhs.z()*w(),
|
||||||
rhs.w()*w() - rhs.x()*x() - rhs.y()*y() - rhs.z()*z()
|
rhs.w()*w() - rhs.x()*x() - rhs.y()*y() - rhs.z()*z()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! multiply with scalar
|
//! multiply with scalar
|
||||||
inline const quaternion_ operator * (const T& s) const {
|
inline const quaternion_ operator * (const T& s) const {
|
||||||
return quaternion_(x()*s,y()*s,z()*s,w()*s);
|
return quaternion_(x()*s,y()*s,z()*s,w()*s);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! addition
|
//! addition
|
||||||
inline const quaternion_ operator + (const quaternion_& rhs) const {
|
inline const quaternion_ operator + (const quaternion_& rhs) const {
|
||||||
return quaternion_(coefficient_type(this->_q + rhs._q));
|
return quaternion_(coefficient_type(this->_q + rhs._q));
|
||||||
}
|
}
|
||||||
|
|
||||||
//! addition
|
//! addition
|
||||||
inline const quaternion_ operator - (const quaternion_& rhs) const {
|
inline const quaternion_ operator - (const quaternion_& rhs) const {
|
||||||
return quaternion_(this->_q - rhs._q);
|
return quaternion_(this->_q - rhs._q);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! squared norm
|
//! squared norm
|
||||||
inline const T squared_norm() const { return _q.squared_norm(); }
|
inline const T squared_norm() const { return _q.squared_norm(); }
|
||||||
|
|
||||||
//! norm
|
//! norm
|
||||||
inline const T norm() const { return _q.norm(); }
|
inline const T norm() const { return _q.norm(); }
|
||||||
|
|
||||||
//! dot product
|
//! dot product
|
||||||
inline const T dot(const quaternion_& other) const { return dot(_q,other._q); }
|
inline const T dot(const quaternion_& other) const { return dot(_q,other._q); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//! compute normalized
|
//! compute normalized
|
||||||
inline quaternion_ normalized() const {
|
inline quaternion_ normalized() const {
|
||||||
return quaternion_(_q.normalized());
|
return quaternion_(_q.normalized());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void normalize() { *this = this->normalized(); }
|
inline void normalize() { *this = this->normalized(); }
|
||||||
|
|
||||||
//! conversion from a matrix
|
//! conversion from a matrix
|
||||||
inline static const quaternion_ from_matrix(const matrix_<T,4,4> &m);
|
inline static const quaternion_ from_matrix(const matrix_<T,4,4> &m);
|
||||||
|
|
||||||
//! conversion to a matrix
|
//! conversion to a matrix
|
||||||
const matrix_<T,4,4> to_matrix() const;
|
const matrix_<T,4,4> to_matrix() const;
|
||||||
|
|
||||||
//! return identiy quaternion
|
//! return identiy quaternion
|
||||||
static const quaternion_<T> identity();
|
static const quaternion_<T> identity();
|
||||||
|
|
||||||
static const quaternion_<T> rotate_180_degree_around_x(); ///< rotate 180 degree around X axis
|
static const quaternion_<T> rotate_180_degree_around_x(); ///< rotate 180 degree around X axis
|
||||||
static const quaternion_<T> rotate_180_degree_around_y(); ///< rotate 180 degree around Y axis
|
static const quaternion_<T> rotate_180_degree_around_y(); ///< rotate 180 degree around Y axis
|
||||||
static const quaternion_<T> rotate_180_degree_around_z(); ///< rotate 180 degree around Z axis
|
static const quaternion_<T> rotate_180_degree_around_z(); ///< rotate 180 degree around Z axis
|
||||||
|
|
||||||
static const quaternion_<T> rotate_90_degree_around_x(bool negative = false);
|
static const quaternion_<T> rotate_90_degree_around_x(bool negative = false);
|
||||||
static const quaternion_<T> rotate_90_degree_around_y(bool negative = false);
|
static const quaternion_<T> rotate_90_degree_around_y(bool negative = false);
|
||||||
static const quaternion_<T> rotate_90_degree_around_z(bool negative = false);
|
static const quaternion_<T> rotate_90_degree_around_z(bool negative = false);
|
||||||
|
|
||||||
template <typename AxisAngleType>
|
template <typename AxisAngleType>
|
||||||
static const quaternion_<T> from_axisangle(const AxisAngleType &aa) {
|
static const quaternion_<T> from_axisangle(const AxisAngleType &aa) {
|
||||||
|
|
||||||
using std::sin;
|
using std::sin;
|
||||||
using std::cos;
|
using std::cos;
|
||||||
|
|
||||||
const T sinHalfAngle(sin(aa.angle() * T(0.5) ));
|
const T sinHalfAngle(sin(aa.angle() * T(0.5) ));
|
||||||
|
|
||||||
return quaternion_<T>(aa.axis().x() * sinHalfAngle, // x
|
return quaternion_<T>(aa.axis().x() * sinHalfAngle, // x
|
||||||
aa.axis().y() * sinHalfAngle, // y
|
aa.axis().y() * sinHalfAngle, // y
|
||||||
aa.axis().z() * sinHalfAngle, // z
|
aa.axis().z() * sinHalfAngle, // z
|
||||||
cos(aa.angle() * 0.5) // w
|
cos(aa.angle() * 0.5) // w
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const quaternion_<T> lerp(const quaternion_& qa,const quaternion_& qb,const T& t);
|
static const quaternion_<T> lerp(const quaternion_& qa,const quaternion_& qb,const T& t);
|
||||||
static const quaternion_<T> normalized_lerp(const quaternion_& qa,const quaternion_& qb,const T& t);
|
static const quaternion_<T> normalized_lerp(const quaternion_& qa,const quaternion_& qb,const T& t);
|
||||||
static const quaternion_<T> slerp(const quaternion_& qa,const quaternion_& qb,const T& t);
|
static const quaternion_<T> slerp(const quaternion_& qa,const quaternion_& qb,const T& t);
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
coefficient_type _q;
|
coefficient_type _q;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -265,42 +286,42 @@ const T quaternion_<T>::_sqrt90 = std::sqrt(0.5);
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const quaternion_<T> quaternion_<T>::identity()
|
const quaternion_<T> quaternion_<T>::identity()
|
||||||
{
|
{
|
||||||
return quaternion_<T>(0,0,0,1);
|
return quaternion_<T>(0,0,0,1);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const quaternion_<T> quaternion_<T>::rotate_180_degree_around_x()
|
const quaternion_<T> quaternion_<T>::rotate_180_degree_around_x()
|
||||||
{
|
{
|
||||||
return quaternion_<T>(1,0,0,0);
|
return quaternion_<T>(1,0,0,0);
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const quaternion_<T> quaternion_<T>::rotate_180_degree_around_y()
|
const quaternion_<T> quaternion_<T>::rotate_180_degree_around_y()
|
||||||
{
|
{
|
||||||
return quaternion_<T>(0,1,0,0);
|
return quaternion_<T>(0,1,0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const quaternion_<T> quaternion_<T>::rotate_180_degree_around_z()
|
const quaternion_<T> quaternion_<T>::rotate_180_degree_around_z()
|
||||||
{
|
{
|
||||||
return quaternion_<T>(0,0,1,0);
|
return quaternion_<T>(0,0,1,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const quaternion_<T> quaternion_<T>::rotate_90_degree_around_x(bool negative/* = false*/)
|
const quaternion_<T> quaternion_<T>::rotate_90_degree_around_x(bool negative/* = false*/)
|
||||||
{
|
{
|
||||||
return quaternion_<T>((negative) ? - _sqrt90 : _sqrt90,0,0,_sqrt90);
|
return quaternion_<T>((negative) ? - _sqrt90 : _sqrt90,0,0,_sqrt90);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const quaternion_<T> quaternion_<T>::rotate_90_degree_around_y(bool negative/* = false*/)
|
const quaternion_<T> quaternion_<T>::rotate_90_degree_around_y(bool negative/* = false*/)
|
||||||
{
|
{
|
||||||
return quaternion_<T>(0, (negative) ? -_sqrt90 : _sqrt90,0,_sqrt90);
|
return quaternion_<T>(0, (negative) ? -_sqrt90 : _sqrt90,0,_sqrt90);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const quaternion_<T> quaternion_<T>::rotate_90_degree_around_z(bool negative/* = false*/)
|
const quaternion_<T> quaternion_<T>::rotate_90_degree_around_z(bool negative/* = false*/)
|
||||||
{
|
{
|
||||||
return quaternion_<T>(0,0,(negative) ? -_sqrt90 : _sqrt90, _sqrt90);
|
return quaternion_<T>(0,0,(negative) ? -_sqrt90 : _sqrt90, _sqrt90);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -308,40 +329,40 @@ const quaternion_<T> quaternion_<T>::rotate_90_degree_around_z(bool negative/* =
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const quaternion_<T> quaternion_<T>::slerp(const quaternion_<T>& qa,const quaternion_<T>& qb,const T& t)
|
const quaternion_<T> quaternion_<T>::slerp(const quaternion_<T>& qa,const quaternion_<T>& qb,const T& t)
|
||||||
{
|
{
|
||||||
using std::abs;
|
using std::abs;
|
||||||
using std::sqrt;
|
using std::sqrt;
|
||||||
using std::acos;
|
using std::acos;
|
||||||
|
|
||||||
// quaternion to return
|
// quaternion to return
|
||||||
quaternion_ qm;
|
quaternion_ qm;
|
||||||
// Calculate angle between them.
|
// Calculate angle between them.
|
||||||
double cosHalfTheta = qa.w() * qb.w() + qa.x() * qb.x() + qa.y() * qb.y() + qa.z() * qb.z();
|
double cosHalfTheta = qa.w() * qb.w() + qa.x() * qb.x() + qa.y() * qb.y() + qa.z() * qb.z();
|
||||||
// if qa=qb or qa=-qb then theta = 0 and we can return qa
|
// if qa=qb or qa=-qb then theta = 0 and we can return qa
|
||||||
if (abs(cosHalfTheta) >= T(1.)) {
|
if (abs(cosHalfTheta) >= T(1.)) {
|
||||||
return qa;
|
return qa;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate temporary values.
|
// Calculate temporary values.
|
||||||
double halfTheta = acos(cosHalfTheta);
|
double halfTheta = acos(cosHalfTheta);
|
||||||
double sinHalfTheta = sqrt(1.0 - cosHalfTheta * cosHalfTheta);
|
double sinHalfTheta = sqrt(1.0 - cosHalfTheta * cosHalfTheta);
|
||||||
// if theta = 180 degrees then result is not fully defined
|
// if theta = 180 degrees then result is not fully defined
|
||||||
// we could rotate around any axis normal to qa or qb
|
// we could rotate around any axis normal to qa or qb
|
||||||
if (::std::abs(sinHalfTheta) < 0.001){ // fabs is floating point absolute
|
if (::std::abs(sinHalfTheta) < 0.001){ // fabs is floating point absolute
|
||||||
qm.w() = (qa.w() * 0.5 + qb.w() * 0.5);
|
qm.w() = (qa.w() * 0.5 + qb.w() * 0.5);
|
||||||
qm.x() = (qa.x() * 0.5 + qb.x() * 0.5);
|
qm.x() = (qa.x() * 0.5 + qb.x() * 0.5);
|
||||||
qm.y() = (qa.y() * 0.5 + qb.y() * 0.5);
|
qm.y() = (qa.y() * 0.5 + qb.y() * 0.5);
|
||||||
qm.z() = (qa.z() * 0.5 + qb.z() * 0.5);
|
qm.z() = (qa.z() * 0.5 + qb.z() * 0.5);
|
||||||
return qm;
|
return qm;
|
||||||
}
|
}
|
||||||
double ratioA = sin((1 - t) * halfTheta) / sinHalfTheta;
|
double ratioA = sin((1 - t) * halfTheta) / sinHalfTheta;
|
||||||
double ratioB = sin(t * halfTheta) / sinHalfTheta;
|
double ratioB = sin(t * halfTheta) / sinHalfTheta;
|
||||||
//calculate Quaternion.
|
//calculate Quaternion.
|
||||||
qm.w() = (qa.w() * ratioA + qb.w() * ratioB);
|
qm.w() = (qa.w() * ratioA + qb.w() * ratioB);
|
||||||
qm.x() = (qa.x() * ratioA + qb.x() * ratioB);
|
qm.x() = (qa.x() * ratioA + qb.x() * ratioB);
|
||||||
qm.y() = (qa.y() * ratioA + qb.y() * ratioB);
|
qm.y() = (qa.y() * ratioA + qb.y() * ratioB);
|
||||||
qm.z() = (qa.z() * ratioA + qb.z() * ratioB);
|
qm.z() = (qa.z() * ratioA + qb.z() * ratioB);
|
||||||
|
|
||||||
return qm;
|
return qm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -33,12 +33,12 @@ namespace pw {
|
||||||
|
|
||||||
struct serialize {
|
struct serialize {
|
||||||
|
|
||||||
template <typename T,size_t R,size_t C>
|
template <size_t R,size_t C,typename T>
|
||||||
inline static std::string matrix(const matrix_<T,R,C>& m) {
|
inline static std::string matrix(const matrix_<R,C,T>& m) {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
|
|
||||||
for (int r = 0; r < m.rows();r++) {
|
for (int r = 0; r < m.rows;r++) {
|
||||||
for (int c = 0; c < m.cols();c++) {
|
for (int c = 0; c < m.cols;c++) {
|
||||||
ss << m(r,c) << " ";
|
ss << m(r,c) << " ";
|
||||||
}
|
}
|
||||||
ss << std::endl;
|
ss << std::endl;
|
||||||
|
|
|
@ -41,8 +41,6 @@ struct size_ {
|
||||||
template <typename To_>
|
template <typename To_>
|
||||||
size_<To_> cast() const { return size_<To_>(static_cast<To_>(width),static_cast<To_>(height)); }
|
size_<To_> cast() const { return size_<To_>(static_cast<To_>(width),static_cast<To_>(height)); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef size_<real_t> size;
|
typedef size_<real_t> size;
|
||||||
|
|
|
@ -27,46 +27,36 @@
|
||||||
|
|
||||||
namespace pw {
|
namespace pw {
|
||||||
|
|
||||||
template <typename T, std::size_t N>
|
template <std::size_t N,typename T>
|
||||||
struct vector_ : matrix_<T, N, 1,false>
|
struct vector_ : matrix_<N,1,T>
|
||||||
{
|
{
|
||||||
typedef matrix_<T, N, 1, false> Base;
|
static const size_t coefficients = N;
|
||||||
|
|
||||||
using typename Base::value_type;
|
using matrix_<N,1,T>::matrix_;
|
||||||
using Base::Base;
|
|
||||||
|
|
||||||
static T dot(const Base &a,const Base &b) {
|
|
||||||
vector_ r; for (size_t i = 0;i < N;i++) r[i] = a[i] * b[i];
|
|
||||||
return std::accumulate(std::begin(r), std::end(r), T(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
static T angle_between(const Base &a,const Base &b) {
|
|
||||||
return std::acos( dot( a.normalized(), b.normalized() ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
static const vector_ lerp(const vector_ &a,const vector_ &b,const T& t) {
|
|
||||||
return a + (b - a) * t;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// static T angle_between(const vector_ &a,const vector_ &b) {
|
||||||
|
// return std::acos( dot( a.normalized(), b.normalized() ) );
|
||||||
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct vector2_ : vector_<T,2> {
|
struct vector2_ : vector_<2,T> {
|
||||||
|
using vector_<2,T>::vector_;
|
||||||
using vector_<T,2>::vector_;
|
|
||||||
|
|
||||||
|
|
||||||
inline const T& x() const { return (*this)[0]; }
|
inline const T& x() const { return (*this)[0]; }
|
||||||
inline T& x() { return (*this)[0]; }
|
inline T& x() { return (*this)[0]; }
|
||||||
|
|
||||||
inline const T& y() const { return (*this)[1]; }
|
inline const T& y() const { return (*this)[1]; }
|
||||||
|
|
||||||
inline T& y() { return (*this)[1]; }
|
inline T& y() { return (*this)[1]; }
|
||||||
inline auto homogenous(T w = 1) const { return vector_<T,3>(x(),y(),w); }
|
|
||||||
|
inline auto homogenous(T w = 1) const { return vector_<3,T>( { x(),y(),w } ); }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(_D)
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct vector3_ : vector_<T,3> {
|
struct vector3_ : vector_<T,3> {
|
||||||
|
|
||||||
|
@ -117,27 +107,28 @@ struct vector4_ : vector_<T,4> {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
||||||
using vector2f = vector2_<float>;
|
using vector2f = vector2_<float>;
|
||||||
using vector2d = vector2_<double>;
|
using vector2d = vector2_<double>;
|
||||||
using vector2 = vector2_<real_t>;
|
//using vector2 = vector2_<real_t>;
|
||||||
|
|
||||||
using vector3f = vector3_<float>;
|
//using vector3f = vector3_<float>;
|
||||||
using vector3d = vector3_<double>;
|
//using vector3d = vector3_<double>;
|
||||||
using vector3 = vector3_<real_t>;
|
//using vector3 = vector3_<real_t>;
|
||||||
|
|
||||||
|
//using vector4f = vector4_<float>;
|
||||||
|
//using vector4d = vector4_<double>;
|
||||||
|
//using vector4 = vector4_<real_t>;
|
||||||
|
|
||||||
using vector4f = vector4_<float>;
|
|
||||||
using vector4d = vector4_<double>;
|
|
||||||
using vector4 = vector4_<real_t>;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(___OLDSTUFF)
|
#if defined(___OLDSTUFF)
|
||||||
|
|
||||||
template <unsigned int components,typename T>
|
template <unsigned int components,typename T>
|
||||||
|
@ -328,4 +319,6 @@ typedef vector4_<unsigned int> vector4ui;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -5,25 +5,25 @@ add_executable(pwcore_test_matrix
|
||||||
target_link_libraries(pwcore_test_matrix
|
target_link_libraries(pwcore_test_matrix
|
||||||
pwcore)
|
pwcore)
|
||||||
|
|
||||||
add_executable(pwcore_test_vector
|
#add_executable(pwcore_test_vector
|
||||||
pwcore_test_vector.cpp
|
# pwcore_test_vector.cpp
|
||||||
)
|
# )
|
||||||
|
|
||||||
target_link_libraries(pwcore_test_vector
|
#target_link_libraries(pwcore_test_vector
|
||||||
pwcore)
|
# pwcore)
|
||||||
|
|
||||||
|
|
||||||
add_executable(pwcore_test_quaternion
|
#add_executable(pwcore_test_quaternion
|
||||||
pwcore_test_quaternion.cpp
|
# pwcore_test_quaternion.cpp
|
||||||
)
|
# )
|
||||||
|
|
||||||
target_link_libraries(pwcore_test_quaternion
|
#target_link_libraries(pwcore_test_quaternion
|
||||||
pwcore)
|
# pwcore)
|
||||||
|
|
||||||
|
|
||||||
add_executable(pwcore_test_axisangle
|
#add_executable(pwcore_test_axisangle
|
||||||
pwcore_test_axisangle.cpp
|
# pwcore_test_axisangle.cpp
|
||||||
)
|
# )
|
||||||
|
|
||||||
target_link_libraries(pwcore_test_axisangle
|
#target_link_libraries(pwcore_test_axisangle
|
||||||
pwcore)
|
# pwcore)
|
||||||
|
|
|
@ -8,11 +8,10 @@ int main(int argc,char **argv) {
|
||||||
|
|
||||||
pw::axisangle_<float> aa = pw::axisangle_<float>();
|
pw::axisangle_<float> aa = pw::axisangle_<float>();
|
||||||
|
|
||||||
// pw::quaternionf qf = pw::quaternionf::from_axisangle(aa);
|
pw::quaternionf qf = pw::quaternionf::from_axisangle(aa);
|
||||||
|
|
||||||
// std::cout << "aa as quaternion as vector = " << pw::serialize::matrix(qf.as_vector()) << std::endl;
|
std::cout << "aa as quaternion as matrix = " << pw::serialize::matrix(qf.to_matrix()) << std::endl;
|
||||||
|
std::cout << "aa.matrix() = " << pw::serialize::matrix(qf.to_matrix()) << std::endl;
|
||||||
// std::cout << "aa.matrix() = " << pw::serialize::matrix(qf.to_matrix()) << std::endl;
|
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -2,27 +2,13 @@
|
||||||
|
|
||||||
#include <pw/core/matrix.hpp>
|
#include <pw/core/matrix.hpp>
|
||||||
#include <pw/core/vector.hpp>
|
#include <pw/core/vector.hpp>
|
||||||
|
#include <pw/core/serialize.hpp>
|
||||||
//#include <pw/core/serialize.hpp>
|
|
||||||
|
|
||||||
#include <pw/core/debug.hpp>
|
#include <pw/core/debug.hpp>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
template <typename T_,typename O_,size_t R,size_t C> inline static
|
|
||||||
std::basic_ostream<O_>& operator << (std::basic_ostream<O_>& os,
|
|
||||||
const pw::matrix_<T_,R,C>& m
|
|
||||||
)
|
|
||||||
{
|
|
||||||
for (size_t r = 0; r < R;r++){
|
|
||||||
for (size_t c = 0;c < C;c++) {
|
|
||||||
os << m(r,c) << " ";
|
|
||||||
}
|
|
||||||
os << std::endl;
|
|
||||||
}
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc,char **argv) {
|
int main(int argc,char **argv) {
|
||||||
|
|
||||||
|
@ -39,36 +25,39 @@ int main(int argc,char **argv) {
|
||||||
|
|
||||||
vector2f v3( { 1.f,2.f } );
|
vector2f v3( { 1.f,2.f } );
|
||||||
|
|
||||||
|
|
||||||
auto m22_inv = m22.inverse();
|
auto m22_inv = m22.inverse();
|
||||||
auto m22_id = m22_inv * m22;
|
auto m22_id = m22_inv * m22;
|
||||||
|
|
||||||
|
|
||||||
auto v2_t = m22_id * v2;
|
auto v2_t = m22_id * v2;
|
||||||
auto v3_t = m22_id * v3;
|
auto v3_t = m22_id * v3;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
auto v2_f = m22 * v2;
|
auto v2_f = m22 * v2;
|
||||||
auto v2_b = m22_inv * v2_f;
|
auto v2_b = m22_inv * v2_f;
|
||||||
|
|
||||||
|
|
||||||
|
vector2f r_m22 = m22.row(0);
|
||||||
|
|
||||||
debug::d() << "offset(0,1) col-major " << m22.offset(0,1);
|
debug::d() << "offset(0,1) col-major " << m22.offset(0,1);
|
||||||
debug::d() << "det " << m22.determinant();
|
debug::d() << "det " << m22.determinant();
|
||||||
|
|
||||||
std::cout << "m22 " << m22 << std::endl;
|
std::cout << "m22 " << pw::serialize::matrix(m22) << std::endl;
|
||||||
std::cout << "m22-1 " << m22_inv << std::endl;
|
std::cout << "m22-1 " << pw::serialize::matrix(m22_inv) << std::endl;
|
||||||
std::cout << "m22-i " << m22_id << std::endl;
|
std::cout << "m22-i " << pw::serialize::matrix(m22_id) << std::endl;
|
||||||
std::cout << "v22_t " << v2_t << std::endl;
|
std::cout << "v22_t " << pw::serialize::matrix(v2_t) << std::endl;
|
||||||
std::cout << "v3_t " << v3_t << std::endl;
|
std::cout << "v3_t " << pw::serialize::matrix(v3_t) << std::endl;
|
||||||
|
|
||||||
std::cout << "v2_f " << v2_f << std::endl;
|
|
||||||
std::cout << "v2_b " << v2_b << std::endl;
|
std::cout << "v2_f " << pw::serialize::matrix(v2_f) << std::endl;
|
||||||
|
std::cout << "v2_b " << pw::serialize::matrix(v2_b) << std::endl;
|
||||||
|
|
||||||
std::cout << "v2_b.norm " << v2_b.norm() << std::endl;
|
std::cout << "v2_b.norm " << v2_b.norm() << std::endl;
|
||||||
|
|
||||||
// v2_b.normalize();
|
// v2_b.normalize();
|
||||||
std::cout << "v2_b.normalized " << v2_b.normalized() << std::endl;
|
std::cout << "v2_b.normalized " << pw::serialize::matrix(v2_b.normalized()) << std::endl;
|
||||||
|
|
||||||
std::cout << "v2_b~v3_t " << rad_to_deg(vector2f::angle_between(v2,v3)) << std::endl;
|
// std::cout << "v2_b~v3_t " << rad_to_deg(vector2f::angle_between(v2,v3)) << std::endl;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -20,10 +20,8 @@ int main(int argc,char **argv) {
|
||||||
pw::quaternionf qi = qf.inverse();
|
pw::quaternionf qi = qf.inverse();
|
||||||
std::cout << "qf.inverse() (qi) = " << pw::serialize::matrix(qi) << std::endl;
|
std::cout << "qf.inverse() (qi) = " << pw::serialize::matrix(qi) << std::endl;
|
||||||
|
|
||||||
// pw::quaternionf qmid = pw::quaternionf::normalized_lerp(qi,qf,0.5f);
|
pw::quaternionf qmid = pw::quaternionf::normalized_lerp(qi,qf,0.5f);
|
||||||
|
// std::cout << "qmid.dot() (half between qf and qi) = " << pw::rad_to_deg(quaternionf::angle_between()) << std::endl;
|
||||||
// std::cout << "qmid.dot() (half between qf and qi) = " << pw::rad_to_deg(std::acos(qmid.dot(qf))) << std::endl;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,30 +6,34 @@
|
||||||
|
|
||||||
int main(int argc,char **argv) {
|
int main(int argc,char **argv) {
|
||||||
|
|
||||||
pw::vector4_<float> v4;
|
pw::vector2_<float> v2;
|
||||||
pw::vector3f v;
|
|
||||||
|
|
||||||
v4.fill(1.5);
|
v2.x = 0.1f;
|
||||||
|
|
||||||
std::cout << "v4 = " << pw::serialize::matrix(v4) << std::endl;
|
// pw::vector4_<float> v4;
|
||||||
|
// pw::vector3f v;
|
||||||
|
|
||||||
std::cout << "rows() : " << v4.rows() << std::endl;
|
// v4.fill(1.5);
|
||||||
std::cout << "cols() : " << v4.cols() << std::endl;
|
|
||||||
std::cout << "ptr() : " << v4.ptr() << std::endl;
|
|
||||||
std::cout << "ptr()[0] : " << v4.ptr()[0] << std::endl;
|
|
||||||
std::cout << "(0,0) : " << v4(0,0) << std::endl;
|
|
||||||
|
|
||||||
auto v3 = v4.xyz();
|
// std::cout << "v4 = " << pw::serialize::matrix(v4) << std::endl;
|
||||||
|
|
||||||
auto v3_p = v4.project();
|
// std::cout << "rows() : " << v4.rows() << std::endl;
|
||||||
|
// std::cout << "cols() : " << v4.cols() << std::endl;
|
||||||
|
// std::cout << "ptr() : " << v4.ptr() << std::endl;
|
||||||
|
// std::cout << "ptr()[0] : " << v4.ptr()[0] << std::endl;
|
||||||
|
// std::cout << "(0,0) : " << v4(0,0) << std::endl;
|
||||||
|
|
||||||
auto v3_h = v.homogenous();
|
// auto v3 = v4.xyz();
|
||||||
|
|
||||||
// auto v3_lerp = vector4f::lerp()
|
// auto v3_p = v4.project();
|
||||||
|
|
||||||
std::cout << "v3 = " << pw::serialize::matrix(v3) << std::endl;
|
// auto v3_h = v.homogenous();
|
||||||
|
|
||||||
std::cout << "v3.normalized() = " << pw::serialize::matrix(v3.normalized()) << std::endl;
|
//// auto v3_lerp = vector4f::lerp()
|
||||||
|
|
||||||
|
// std::cout << "v3 = " << pw::serialize::matrix(v3) << std::endl;
|
||||||
|
|
||||||
|
// std::cout << "v3.normalized() = " << pw::serialize::matrix(v3.normalized()) << std::endl;
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue