fixing axisangle and vector
This commit is contained in:
parent
3989c0f68e
commit
2919c47e99
7 changed files with 283 additions and 197 deletions
|
@ -58,5 +58,4 @@ target_include_directories(
|
|||
|
||||
target_link_libraries(pwcore)
|
||||
|
||||
# add_subdirectory(tests)
|
||||
|
||||
add_subdirectory(tests)
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
|
@ -24,83 +24,84 @@
|
|||
#define PW_CORE_AXISANGLE_HPP
|
||||
|
||||
#include <pw/core/vector.hpp>
|
||||
#include <pw/core/matrix.hpp>
|
||||
|
||||
namespace pw {
|
||||
|
||||
template <typename T>
|
||||
struct axisangle_ {
|
||||
template <typename T> struct axisangle {
|
||||
|
||||
using value_type = T;
|
||||
using axis_type = vector3_<T>; // todo - should default to UP
|
||||
using axis_type = vector3<T>;
|
||||
|
||||
axis_type axis{};
|
||||
axis_type axis = axis_type::basis(2);
|
||||
T angle{};
|
||||
|
||||
static axisangle_ from_matrix(const matrix_<4,4,T>& m)
|
||||
{
|
||||
using std::acos;
|
||||
using std::sqrt;
|
||||
constexpr static auto from_matrix(const matrix<T, 4, 4>& m) noexcept -> axisangle {
|
||||
using std::acos;
|
||||
using std::sqrt;
|
||||
|
||||
axisangle_ aa_res;
|
||||
aa_res.angle = acos((m(0,0) + m(1,1) + m(2,2) - 1) / T(2));
|
||||
const T m2112 = m(2,1) - m(1,2);
|
||||
const T m0220 = m(0,2) - m(2,0);
|
||||
const T m1001 = m(1,0) - m(0,1);
|
||||
// no singularity check here ...
|
||||
const T mrot_denom = sqrt( m2112 * m2112 + m0220 * m0220 + m1001 * m1001 );
|
||||
// axisangle aa_res;
|
||||
// aa_res.angle = acos((m[0][0]) + m[1][1] + m[2][2] - 1) / T{2});
|
||||
const T m2112 = m[2][1] - m[1][2];
|
||||
const T m0220 = m[0][2] - m[2][0];
|
||||
const T m1001 = m[1][0] - m[0][1];
|
||||
|
||||
aa_res.axis.x() = m2112 / mrot_denom;
|
||||
aa_res.axis.y() = m0220 / mrot_denom;
|
||||
aa_res.axis.z() = m1001 / mrot_denom;
|
||||
// no singularity check here ...
|
||||
const T mrot_denom =
|
||||
sqrt(m2112 * m2112 + m0220 * m0220 + m1001 * m1001);
|
||||
|
||||
return aa_res;
|
||||
}
|
||||
// aa_res.axis.x() = m2112 / mrot_denom;
|
||||
// aa_res.axis.y() = m0220 / mrot_denom;
|
||||
// aa_res.axis.z() = m1001 / mrot_denom;
|
||||
|
||||
matrix_<4,4,T> to_matrix() const
|
||||
{
|
||||
return {
|
||||
.axis = axis_type{
|
||||
m2112 / mrot_denom,
|
||||
m0220 / mrot_denom,
|
||||
m1001 / mrot_denom
|
||||
},
|
||||
.angle = acos( (m[0][0] + m[1][1] + m[2][2] - 1) / T{2} )
|
||||
};
|
||||
}
|
||||
|
||||
constexpr auto to_matrix() const noexcept -> matrix<T, 4, 4> {
|
||||
using std::cos;
|
||||
using std::sin;
|
||||
|
||||
// result
|
||||
matrix_<4,4,T> rot_mat; rot_mat.set_identity();
|
||||
axis_type axis_n = axis.normalized(); // always normalize
|
||||
auto rot_mat { matrix<T,4,4>::identity() };
|
||||
auto axis_n = axis.normalized(); // always normalize
|
||||
|
||||
const T cos_a = cos(angle);
|
||||
const T sin_a = sin(angle);
|
||||
const T cos_1_a = T(1) - cos_a;
|
||||
const T cos_a = cos(angle);
|
||||
const T sin_a = sin(angle);
|
||||
const T cos_1_a = T(1) - cos_a;
|
||||
|
||||
rot_mat(0,0) = cos_a + axis_n.x() * axis_n.x() * cos_1_a;
|
||||
rot_mat(1,1) = cos_a + axis_n.y() * axis_n.y() * cos_1_a;
|
||||
rot_mat(2,2) = cos_a + axis_n.z() * axis_n.z() * cos_1_a;
|
||||
rot_mat[0][0] = cos_a + axis_n.x() * axis_n.x() * cos_1_a;
|
||||
rot_mat[1][1] = cos_a + axis_n.y() * axis_n.y() * cos_1_a;
|
||||
rot_mat[2][2] = cos_a + axis_n.z() * axis_n.z() * cos_1_a;
|
||||
|
||||
T v1 = axis_n.x() * axis_n.y() * cos_1_a;
|
||||
T v2 = axis_n.z() * sin_a;
|
||||
rot_mat(1,0) = v1 + v2;
|
||||
rot_mat(0,1) = v1 - v2;
|
||||
T v1 = axis_n.x() * axis_n.y() * cos_1_a;
|
||||
T v2 = axis_n.z() * sin_a;
|
||||
rot_mat[1][0] = v1 + v2;
|
||||
rot_mat[0][1] = v1 - v2;
|
||||
|
||||
v1 = axis_n.x() * axis_n.z() * cos_1_a;
|
||||
v2 = axis_n.y() * sin_a;
|
||||
rot_mat(2,0) = v1 - v2;
|
||||
rot_mat(0,2) = v1 + v2;
|
||||
v1 = axis_n.x() * axis_n.z() * cos_1_a;
|
||||
v2 = axis_n.y() * sin_a;
|
||||
rot_mat[2][0] = v1 - v2;
|
||||
rot_mat[0][2] = v1 + v2;
|
||||
|
||||
v1 = axis_n.y() * axis_n.z() * cos_1_a;
|
||||
v2 = axis_n.x() * sin_a;
|
||||
rot_mat(2,1) = v1 + v2;
|
||||
rot_mat(1,2) = v1 - v2;
|
||||
v1 = axis_n.y() * axis_n.z() * cos_1_a;
|
||||
v2 = axis_n.x() * sin_a;
|
||||
rot_mat[2][1] = v1 + v2;
|
||||
rot_mat[1][2] = v1 - v2;
|
||||
|
||||
return rot_mat;
|
||||
}
|
||||
};
|
||||
|
||||
using axisanglef = axisangle<float>;
|
||||
using axisangled = axisangle<double>;
|
||||
|
||||
using axisangle = axisangle_<real_t> ;
|
||||
using axisanglef = axisangle_<float> ;
|
||||
using axisangled = axisangle_<double> ;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace pw
|
||||
|
||||
#endif
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#ifndef PW_CORE_SERIALIZE_HPP
|
||||
#define PW_CORE_SERIALIZE_HPP
|
||||
|
||||
#include "vector.hpp"
|
||||
#include <pw/core/matrix.hpp>
|
||||
|
||||
|
||||
|
@ -33,19 +34,25 @@ namespace pw {
|
|||
|
||||
struct serialize {
|
||||
|
||||
template <size_t R,size_t C,typename T>
|
||||
inline static std::string matrix(const matrix_<R,C,T>& m) {
|
||||
template <typename T,auto N>
|
||||
constexpr static std::string to_string(const vector<T, N>& v) {
|
||||
std::stringstream ss;
|
||||
for(const auto& e : v) ss << e << ' ';
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
template <typename T,auto R,auto C>
|
||||
constexpr static std::string to_string(const matrix<T,R,C>& m) {
|
||||
std::stringstream ss;
|
||||
|
||||
for (int r = 0; r < m.rows;r++) {
|
||||
for (int c = 0; c < m.cols;c++) {
|
||||
ss << m(r,c) << " ";
|
||||
}
|
||||
ss << std::endl;
|
||||
for (int r = 0; r < R;r++) {
|
||||
ss << to_string(m[r]) << '\n';
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -25,14 +25,32 @@
|
|||
|
||||
#include <pw/core/globals.hpp>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace pw {
|
||||
|
||||
template <typename Scalar, unsigned int size> struct vector final {
|
||||
template <typename T, auto N>
|
||||
concept Vector2 = (N == 2);
|
||||
|
||||
using value_type = Scalar;
|
||||
static constexpr unsigned int coefficients{size};
|
||||
template <typename T, auto N>
|
||||
concept Vector3 = (N == 3);
|
||||
|
||||
Scalar v_[size]{};
|
||||
template <typename T, auto N>
|
||||
concept Vector4 = (N == 4);
|
||||
|
||||
template <typename Scalar, unsigned int N> struct vector final {
|
||||
|
||||
using value_type = Scalar;
|
||||
using size_type = decltype(N);
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using reference = value_type&;
|
||||
using const_reference = const value_type&;
|
||||
using pointer = value_type*;
|
||||
using const_pointer = const value_type*;
|
||||
|
||||
static constexpr size_type coefficients{N};
|
||||
|
||||
Scalar v_[N]{};
|
||||
|
||||
auto&& data(this auto&& self) {
|
||||
return std::forward<decltype(self)>(self).v_;
|
||||
|
@ -45,20 +63,20 @@ template <typename Scalar, unsigned int size> struct vector final {
|
|||
static constexpr auto basis(const auto& d) noexcept {
|
||||
return [&d]<std::size_t... Ss>(std::index_sequence<Ss...>) {
|
||||
return vector{(d == Ss) ? Scalar(1) : Scalar(0)...};
|
||||
}(std::make_index_sequence<size>{});
|
||||
}(std::make_index_sequence<N>{});
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
static constexpr auto
|
||||
make(Args&&... values) noexcept -> vector<Scalar, sizeof...(Args)> {
|
||||
static_assert(sizeof...(Args) == size, "incorrect number of arguments");
|
||||
static_assert(sizeof...(Args) == N, "incorrect number of arguments");
|
||||
return {{Scalar(values)...}};
|
||||
}
|
||||
|
||||
static constexpr auto all(Scalar value) noexcept -> vector {
|
||||
return [&value]<std::size_t... Is>(std::index_sequence<Is...>) {
|
||||
return vector{value + Scalar(Is * 0)...};
|
||||
}(std::make_index_sequence<size>{});
|
||||
return vector{value + Scalar{Is * 0}...};
|
||||
}(std::make_index_sequence<N>{});
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
|
@ -69,22 +87,29 @@ template <typename Scalar, unsigned int size> struct vector final {
|
|||
|
||||
constexpr auto minor(std::unsigned_integral auto d0) const noexcept {
|
||||
return [this, &d0]<std::size_t... Ss>(std::index_sequence<Ss...>) {
|
||||
return vector<Scalar, size - 1>{
|
||||
return vector<Scalar, N - 1>{
|
||||
(*this).v_[(Ss < d0) ? Ss : Ss + 1]...};
|
||||
}(std::make_index_sequence<size - 1>{});
|
||||
}(std::make_index_sequence<N - 1>{});
|
||||
}
|
||||
|
||||
static constexpr auto sequence(Scalar factor = Scalar{1},
|
||||
Scalar offset = Scalar{0}) noexcept {
|
||||
return [&]<std::size_t... Ss>(std::index_sequence<Ss...>) {
|
||||
return vector<Scalar, size>{{Scalar{Ss} * factor + offset...}};
|
||||
}(std::make_index_sequence<size>{});
|
||||
return vector<Scalar, N>{{Scalar{Ss} * factor + offset...}};
|
||||
}(std::make_index_sequence<N>{});
|
||||
}
|
||||
|
||||
static constexpr auto lerp(const vector& A, const vector& B,const Scalar& factor) -> vector
|
||||
{
|
||||
return [&]<std::size_t... Ss>(std::index_sequence<Ss...>) {
|
||||
return vector<Scalar, N>{{A[Ss] + factor * (B[Ss] - A[Ss])...}};
|
||||
}(std::make_index_sequence<N>{});
|
||||
}
|
||||
|
||||
constexpr Scalar dot(const auto& other) const {
|
||||
return [this, &other]<std::size_t... Ss>(std::index_sequence<Ss...>) {
|
||||
return (... + (other[Ss] * (*this)[Ss]));
|
||||
}(std::make_index_sequence<size>{});
|
||||
}(std::make_index_sequence<N>{});
|
||||
}
|
||||
|
||||
constexpr auto squared_norm() const noexcept { return dot(*this); }
|
||||
|
@ -96,7 +121,7 @@ template <typename Scalar, unsigned int size> struct vector final {
|
|||
constexpr vector operator*(const Scalar& v) const noexcept {
|
||||
return [this, &v]<std::size_t... Ss>(std::index_sequence<Ss...>) {
|
||||
return vector{{(*this)[Ss] * v...}};
|
||||
}(std::make_index_sequence<size>{});
|
||||
}(std::make_index_sequence<N>{});
|
||||
}
|
||||
|
||||
constexpr vector operator/(const Scalar& v) const noexcept {
|
||||
|
@ -106,19 +131,19 @@ template <typename Scalar, unsigned int size> struct vector final {
|
|||
constexpr vector operator+(const vector& v) const noexcept {
|
||||
return [this, &v]<std::size_t... Ss>(std::index_sequence<Ss...>) {
|
||||
return vector{{(*this)[Ss] + v[Ss]...}};
|
||||
}(std::make_index_sequence<size>{});
|
||||
}(std::make_index_sequence<N>{});
|
||||
}
|
||||
|
||||
constexpr vector operator-(const vector& v) const noexcept {
|
||||
return [this, &v]<std::size_t... Ss>(std::index_sequence<Ss...>) {
|
||||
return vector{{(*this)[Ss] - v[Ss]...}};
|
||||
}(std::make_index_sequence<size>{});
|
||||
}(std::make_index_sequence<N>{});
|
||||
}
|
||||
|
||||
constexpr vector& operator*=(const Scalar& v) noexcept {
|
||||
[this, &v]<std::size_t... Ss>(std::index_sequence<Ss...>) {
|
||||
(((*this)[Ss] *= v), ...);
|
||||
}(std::make_index_sequence<size>{});
|
||||
}(std::make_index_sequence<N>{});
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -129,7 +154,7 @@ template <typename Scalar, unsigned int size> struct vector final {
|
|||
constexpr vector& operator+=(const Scalar& v) noexcept {
|
||||
[this, &v]<std::size_t... Ss>(std::index_sequence<Ss...>) {
|
||||
(((*this)[Ss] += v), ...);
|
||||
}(std::make_index_sequence<size>{});
|
||||
}(std::make_index_sequence<N>{});
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -137,78 +162,120 @@ template <typename Scalar, unsigned int size> struct vector final {
|
|||
return operator+=(-v);
|
||||
}
|
||||
|
||||
constexpr auto project() const noexcept -> vector<Scalar, size - 1> {
|
||||
constexpr auto project() const noexcept -> vector<Scalar, N - 1> {
|
||||
return [this]<std::size_t... Ss>(std::index_sequence<Ss...>) {
|
||||
return vector<Scalar, size - 1>{
|
||||
{(*this)[Ss] / (*this)[size - 1]...}};
|
||||
}(std::make_index_sequence<size - 1>{});
|
||||
return vector<Scalar, N - 1>{{(*this)[Ss] / (*this)[N - 1]...}};
|
||||
}(std::make_index_sequence<N - 1>{});
|
||||
}
|
||||
|
||||
constexpr auto
|
||||
unproject(auto&& w) const noexcept -> vector<Scalar, size + 1> {
|
||||
unproject(const Scalar& w) const noexcept -> vector<Scalar, N + 1> {
|
||||
return [this, &w]<std::size_t... Ss>(std::index_sequence<Ss...>) {
|
||||
return vector<Scalar, size + 1>{{(Ss < size) ? (*this)[Ss] : w...}};
|
||||
}(std::make_index_sequence<size + 1>{});
|
||||
return vector<Scalar, N + 1>{{(Ss < N) ? (*this)[Ss] : w...}};
|
||||
}(std::make_index_sequence<N + 1>{});
|
||||
}
|
||||
|
||||
template <typename ScalarCast>
|
||||
constexpr auto cast() const noexcept {
|
||||
return [this]<std::size_t... Ss>(std::index_sequence<Ss...>) {
|
||||
return vector{ ScalarCast{(*this)[Ss]}...};
|
||||
}(std::make_index_sequence<size>{});
|
||||
constexpr vector cross(const auto& rhs) const noexcept
|
||||
requires(Vector3<Scalar, N>)
|
||||
{
|
||||
return {(*this)[1] * rhs[2] - rhs[1] * (*this)[2],
|
||||
(*this)[2] * rhs[0] - rhs[2] * (*this)[0],
|
||||
(*this)[0] * rhs[1] - rhs[0] * (*this)[1]};
|
||||
}
|
||||
|
||||
constexpr vector normalized() const noexcept {
|
||||
return (*this) / norm();
|
||||
}
|
||||
|
||||
auto&& x(this auto&& self)
|
||||
requires(Vector2<Scalar, N> || Vector3<Scalar, N> || Vector4<Scalar, N>)
|
||||
{
|
||||
return std::forward<decltype(self)>(self).v_[0];
|
||||
}
|
||||
|
||||
auto&& y(this auto&& self)
|
||||
requires(Vector2<Scalar, N> || Vector3<Scalar, N> || Vector4<Scalar, N>)
|
||||
{
|
||||
return std::forward<decltype(self)>(self).v_[1];
|
||||
}
|
||||
|
||||
auto&& z(this auto&& self)
|
||||
requires(Vector3<Scalar, N> || Vector4<Scalar, N>)
|
||||
{
|
||||
return std::forward<decltype(self)>(self).v_[2];
|
||||
}
|
||||
|
||||
auto&& w(this auto&& self)
|
||||
requires(Vector4<Scalar, N>)
|
||||
{
|
||||
return std::forward<decltype(self)>(self).v_[3];
|
||||
}
|
||||
|
||||
static constexpr vector right() noexcept
|
||||
requires(Vector3<Scalar, N>)
|
||||
{
|
||||
return vector{1, 0, 0};
|
||||
};
|
||||
|
||||
static constexpr vector up() noexcept
|
||||
requires(Vector3<Scalar, N>)
|
||||
{
|
||||
return vector{0, 1, 0};
|
||||
};
|
||||
|
||||
static constexpr vector forward() noexcept
|
||||
requires(Vector3<Scalar, N>)
|
||||
{
|
||||
return vector{0, 0, -1};
|
||||
};
|
||||
|
||||
static constexpr vector x_axis() noexcept
|
||||
requires(Vector2<Scalar, N> || Vector3<Scalar, N> || Vector4<Scalar, N>)
|
||||
{
|
||||
return vector::basis(0);
|
||||
};
|
||||
|
||||
static constexpr vector y_axis() noexcept
|
||||
requires(Vector2<Scalar, N> || Vector3<Scalar, N> || Vector4<Scalar, N>)
|
||||
{
|
||||
return vector::basis(1);
|
||||
};
|
||||
|
||||
static constexpr vector z_axis() noexcept
|
||||
requires(Vector3<Scalar, N> || Vector4<Scalar, N>)
|
||||
{
|
||||
return vector::basis(2);
|
||||
};
|
||||
|
||||
static constexpr vector w_axis() noexcept
|
||||
requires(Vector4<Scalar, N>)
|
||||
{
|
||||
return vector::basis(3);
|
||||
};
|
||||
|
||||
//
|
||||
// Iterators
|
||||
//
|
||||
constexpr const_pointer begin() const {
|
||||
return &v_[0];
|
||||
}
|
||||
|
||||
constexpr const_pointer end() const {
|
||||
return &v_[N];
|
||||
}
|
||||
};
|
||||
|
||||
// deduction guide for vector
|
||||
template <class... U, class CT = std::common_type_t<U...>>
|
||||
vector(U...) -> vector<CT, sizeof...(U)>;
|
||||
template <class T, class... U, class CT = std::common_type_t<T, U...>>
|
||||
vector(T, U...) -> vector<CT, 1 + sizeof...(U)>;
|
||||
|
||||
template <typename Scalar> struct vector2 : vector<Scalar, 2> {
|
||||
//
|
||||
// Vector Aliases
|
||||
//
|
||||
|
||||
constexpr const Scalar& x() const { return (*this)[0]; }
|
||||
constexpr Scalar& x() { return (*this)[0]; }
|
||||
|
||||
constexpr const Scalar& y() const { return (*this)[1]; }
|
||||
constexpr Scalar& y() { return (*this)[1]; }
|
||||
};
|
||||
|
||||
template <typename Scalar> struct vector3 : vector<Scalar, 3> {
|
||||
|
||||
constexpr static vector3 cross(const vector3& lhs, const vector3& rhs) {
|
||||
return {lhs[1] * rhs[2] - rhs[1] * lhs[2],
|
||||
lhs[2] * rhs[0] - rhs[2] * lhs[0],
|
||||
lhs[0] * rhs[1] - rhs[0] * lhs[1]};
|
||||
}
|
||||
|
||||
constexpr static auto forward() { return {0, 0, -1}; }
|
||||
constexpr static auto backward() { return {0, 0, +1}; }
|
||||
constexpr static auto up() { return {0, +1, 0}; }
|
||||
constexpr static auto down() { return {0, -1, 0}; }
|
||||
constexpr static auto right() { return {+1, 0, 0}; }
|
||||
constexpr static auto left() { return {-1, 0, 0}; }
|
||||
constexpr static auto x_axis() { return {0, 0, +1}; }
|
||||
constexpr static auto y_axis() { return {0, 0, +1}; }
|
||||
constexpr static auto z_axis() { return {0, 0, +1}; }
|
||||
};
|
||||
|
||||
template <typename Scalar> struct vector4 : vector<Scalar, 4> {
|
||||
|
||||
using base_type = vector<Scalar, 4>;
|
||||
|
||||
constexpr const Scalar& x() const { return (*this)[0]; }
|
||||
constexpr Scalar& x() { return (*this)[0]; }
|
||||
|
||||
constexpr const Scalar& y() const { return (*this)[1]; }
|
||||
constexpr Scalar& y() { return (*this)[1]; }
|
||||
|
||||
constexpr const Scalar& z() const { return (*this)[2]; }
|
||||
constexpr Scalar& z() { return (*this)[2]; }
|
||||
|
||||
constexpr const Scalar& w() const { return (*this)[3]; }
|
||||
constexpr Scalar& w() { return (*this)[3]; }
|
||||
|
||||
constexpr auto xyz() const { return base_type::swizzle(0, 1, 2); }
|
||||
};
|
||||
template <typename Scalar> using vector2 = vector<Scalar, 2>;
|
||||
template <typename Scalar> using vector3 = vector<Scalar, 3>;
|
||||
template <typename Scalar> using vector4 = vector<Scalar, 4>;
|
||||
|
||||
using vector2f = vector2<float>;
|
||||
using vector2d = vector2<double>;
|
||||
|
@ -216,6 +283,11 @@ using vector2i = vector2<int>;
|
|||
|
||||
using vector3f = vector3<float>;
|
||||
using vector3d = vector3<double>;
|
||||
using vector3i = vector3<int>;
|
||||
|
||||
using vector4f = vector4<float>;
|
||||
using vector4d = vector4<double>;
|
||||
using vector4i = vector4<int>;
|
||||
|
||||
} // namespace pw
|
||||
|
||||
|
|
|
@ -7,9 +7,9 @@ macro(make_test arg1)
|
|||
endmacro()
|
||||
|
||||
|
||||
make_test(pwcore_test_matrix)
|
||||
# make_test(pwcore_test_matrix)
|
||||
make_test(pwcore_test_vector)
|
||||
# make_test(pwcore_test_axisangle)
|
||||
make_test(pwcore_test_axisangle)
|
||||
# make_test(pwcore_test_quaternion)
|
||||
# make_test(pwcore_test_transform_tools)
|
||||
# make_test(pwcore_test_mesh)
|
||||
|
|
|
@ -1,53 +1,46 @@
|
|||
#include <pw/core/axisangle.hpp>
|
||||
#include <pw/core/quaternion.hpp>
|
||||
#include <pw/core/serialize.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
int main(int argc,char **argv) {
|
||||
auto main() -> int {
|
||||
|
||||
pw::axisangle_<float> aa = pw::axisangle_<float>();
|
||||
|
||||
// pw::quaternionf qf = pw::quaternionf::from_axisangle(aa);
|
||||
// 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;
|
||||
auto aa = pw::axisangle<float>();
|
||||
|
||||
std::cout << "x-axis" << std::endl;
|
||||
|
||||
aa.axis = pw::vector3::x_axis();
|
||||
aa.axis = pw::vector3f::x_axis();
|
||||
aa.angle = pw::deg_to_rad(45.f);
|
||||
|
||||
std::cout << "aa.matrix() = " << std::endl << pw::serialize::matrix(aa.to_matrix()) << std::endl;
|
||||
|
||||
std::cout << "aa.matrix() = " << std::endl
|
||||
<< pw::serialize::to_string(aa.to_matrix()) << std::endl;
|
||||
std::cout << "y-axis" << std::endl;
|
||||
|
||||
aa.axis = pw::vector3::y_axis();
|
||||
aa.axis = pw::vector3f::y_axis();
|
||||
aa.angle = pw::deg_to_rad(45.f);
|
||||
|
||||
std::cout << "aa.matrix() = " << std::endl << pw::serialize::matrix(aa.to_matrix()) << std::endl;
|
||||
std::cout << "aa.matrix() = " << std::endl
|
||||
<< pw::serialize::to_string(aa.to_matrix()) << std::endl;
|
||||
|
||||
std::cout << "z-axis" << std::endl;
|
||||
|
||||
aa.axis = pw::vector3f::z_axis();
|
||||
aa.angle = pw::deg_to_rad(45.f);
|
||||
|
||||
std::cout << "z-axis" << std::endl;
|
||||
std::cout << "aa.matrix() = " << std::endl
|
||||
<< pw::serialize::to_string(aa.to_matrix()) << std::endl;
|
||||
|
||||
aa.axis = pw::vector3::z_axis();
|
||||
aa.angle = pw::deg_to_rad(45.f);
|
||||
std::cout << "from matrix" << std::endl;
|
||||
|
||||
std::cout << "aa.matrix() = " << std::endl << pw::serialize::matrix(aa.to_matrix()) << std::endl;
|
||||
|
||||
|
||||
std::cout << "from matrix" << std::endl;
|
||||
|
||||
pw::matrix4x4f mrot; mrot.zero();
|
||||
mrot(0,0) = 1;
|
||||
mrot(2,1) = 1;
|
||||
mrot(1,2) = -1;
|
||||
|
||||
pw::axisanglef aa_fm = pw::axisangle::from_matrix(mrot);
|
||||
|
||||
std::cout << pw::serialize::matrix(aa_fm.axis.transposed()) << " " << pw::rad_to_deg(aa_fm.angle) << "deg" << std::endl;
|
||||
auto mrot = pw::matrix<float, 4, 4>{};
|
||||
mrot[0][0] = 1;
|
||||
mrot[2][1] = 1;
|
||||
mrot[1][2] = -1;
|
||||
|
||||
auto aa_fm = pw::axisanglef::from_matrix(mrot);
|
||||
|
||||
std::cout << pw::serialize::to_string(aa_fm.axis) << " "
|
||||
<< pw::rad_to_deg(aa_fm.angle) << "deg" << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,51 +1,65 @@
|
|||
|
||||
#include <pw/core/vector.hpp>
|
||||
#include <pw/core/serialize.hpp>
|
||||
#include <pw/core/vector.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <print>
|
||||
|
||||
int main(int ,char **) {
|
||||
auto main() -> int {
|
||||
|
||||
pw::vector2_<float> v2_A = { 3.2, 1.2 };
|
||||
pw::vector2_<float> v2_B = { 3.2, 1.2 };
|
||||
auto v2_A = pw::vector{3.2, 1.2};
|
||||
auto v2_B = pw::vector{6.4, 2.4};
|
||||
|
||||
auto AB_lerp = pw::vector2f::lerp(v2_A,v2_B,0.5);
|
||||
auto AB_lerp = decltype(v2_A)::lerp(v2_A, v2_B, 0.5);
|
||||
|
||||
pw::vector4_<float> v4;
|
||||
pw::vector3f v = pw::vector3f::backward();
|
||||
std::print("lerp A:({}) B:({}) t:({}) -> {}\n",
|
||||
pw::serialize::to_string(v2_A), pw::serialize::to_string(v2_B),
|
||||
0.5, pw::serialize::to_string(AB_lerp));
|
||||
|
||||
v4.fill(1.5);
|
||||
auto v4_14 = pw::vector4<float>::all(1.4);
|
||||
auto v4_sq = pw::vector4<float>::sequence(1.4);
|
||||
auto v3_fw = pw::vector3f::forward();
|
||||
|
||||
std::cout << "v4 = " << pw::serialize::matrix(v4) << std::endl;
|
||||
std::print("all(1.4) -> {}\n", pw::serialize::to_string(v4_14));
|
||||
std::print("sequence(1.4) -> {}\n", pw::serialize::to_string(v4_sq));
|
||||
std::print("forward() -> {}\n", pw::serialize::to_string(v3_fw));
|
||||
|
||||
// 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_sw_1 = v4_sq.swizzle(0, 1); // xy
|
||||
auto v3_sw_2 = v4_sq.swizzle(1, 0); // yx
|
||||
auto v3_sw_3 = v4_sq.swizzle(0, 2); // xz
|
||||
|
||||
auto v3 = v4.xyz();
|
||||
std::print("swizzle(0,1) aka xy -> {}\n",
|
||||
pw::serialize::to_string(v3_sw_1));
|
||||
std::print("swizzle(1,0) aka yx -> {}\n",
|
||||
pw::serialize::to_string(v3_sw_2));
|
||||
std::print("swizzle(0,2) aka xz -> {}\n",
|
||||
pw::serialize::to_string(v3_sw_3));
|
||||
|
||||
auto v3_p = v4.project();
|
||||
auto v3_up_1 = v3_fw.unproject(1);
|
||||
auto v3_pj_1 = v3_up_1.project();
|
||||
|
||||
auto v3_h = v.homogenous();
|
||||
std::print("unproject(1) -> {}\n", pw::serialize::to_string(v3_up_1));
|
||||
std::print("project() -> {}\n", pw::serialize::to_string(v3_pj_1));
|
||||
|
||||
// auto v3_lerp = vector4f::
|
||||
auto v3_nlz = v3_up_1.normalized();
|
||||
std::print("normalized() -> {}\n", pw::serialize::to_string(v3_nlz));
|
||||
|
||||
std::cout << "v3 = " << pw::serialize::matrix(v3) << std::endl;
|
||||
|
||||
std::cout << "v3.normalized() = " << pw::serialize::matrix(v3.normalized()) << std::endl;
|
||||
|
||||
auto e1 = pw::vector3 { 2.0, 0.0, 0.0 };
|
||||
auto e2 = pw::vector3 { 0.0, 0.0, 2.0 };
|
||||
auto e1 = pw::vector{2.0, 0.0, 0.0};
|
||||
auto e2 = pw::vector{0.0, 0.0, 2.0};
|
||||
|
||||
auto e2_e1 = e1 - e2;
|
||||
|
||||
auto n_e1_e2 = pw::vector3::cross(e1,e2);
|
||||
std::print("{} - {} -> {}\n", pw::serialize::to_string(e1),
|
||||
pw::serialize::to_string(e2), pw::serialize::to_string(e2_e1));
|
||||
|
||||
std::cout << "e1xe2 " << pw::serialize::matrix(n_e1_e2) << std::endl;
|
||||
auto e1_cross_e2 = e1.cross(e2);
|
||||
std::print("{} x {} -> {}\n", pw::serialize::to_string(e1),
|
||||
pw::serialize::to_string(e2),
|
||||
pw::serialize::to_string(e1_cross_e2));
|
||||
|
||||
std::cout << "e1xe2 " << pw::serialize::matrix(e2_e1) << std::endl;
|
||||
auto e1_dot_e2 = e1.dot(e2);
|
||||
|
||||
std::print("{} * {} -> {}\n", pw::serialize::to_string(e1),
|
||||
pw::serialize::to_string(e2), e1_dot_e2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue