mirror of
https://github.com/enduro2d/enduro2d.git
synced 2026-02-04 15:06:57 +07:00
remove quat and little clean up math
This commit is contained in:
@@ -23,8 +23,8 @@ namespace e2d
|
||||
renderer& translation(const v3f& translation) noexcept;
|
||||
[[nodiscard]] const v3f& translation() const noexcept;
|
||||
|
||||
renderer& rotation(const q4f& rotation) noexcept;
|
||||
[[nodiscard]] const q4f& rotation() const noexcept;
|
||||
renderer& rotation(const v3f& rotation) noexcept;
|
||||
[[nodiscard]] const v3f& rotation() const noexcept;
|
||||
|
||||
renderer& scale(const v3f& scale) noexcept;
|
||||
[[nodiscard]] const v3f& scale() const noexcept;
|
||||
@@ -81,12 +81,12 @@ namespace e2d
|
||||
return transform_.translation;
|
||||
}
|
||||
|
||||
inline renderer& renderer::rotation(const q4f& rotation) noexcept {
|
||||
inline renderer& renderer::rotation(const v3f& rotation) noexcept {
|
||||
transform_.rotation = rotation;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline const q4f& renderer::rotation() const noexcept {
|
||||
inline const v3f& renderer::rotation() const noexcept {
|
||||
return transform_.rotation;
|
||||
}
|
||||
|
||||
|
||||
@@ -50,8 +50,8 @@ namespace e2d
|
||||
void translation(const v2f& translation) noexcept;
|
||||
const v2f& translation() const noexcept;
|
||||
|
||||
void rotation(const radf& rotation) noexcept;
|
||||
const radf& rotation() const noexcept;
|
||||
void rotation(f32 rotation) noexcept;
|
||||
f32 rotation() const noexcept;
|
||||
|
||||
void scale(const v2f& scale) noexcept;
|
||||
const v2f& scale() const noexcept;
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include "mat2.hpp"
|
||||
#include "mat3.hpp"
|
||||
#include "mat4.hpp"
|
||||
#include "quat.hpp"
|
||||
#include "rect.hpp"
|
||||
#include "trig.hpp"
|
||||
#include "trs2.hpp"
|
||||
|
||||
@@ -28,9 +28,6 @@ namespace e2d
|
||||
template < typename T >
|
||||
class mat4;
|
||||
|
||||
template < typename T >
|
||||
class quat;
|
||||
|
||||
template < typename T >
|
||||
class rect;
|
||||
|
||||
@@ -94,13 +91,6 @@ namespace e2d
|
||||
using m4hi = mat4<i16>;
|
||||
using m4hu = mat4<u16>;
|
||||
|
||||
using q4d = quat<f64>;
|
||||
using q4f = quat<f32>;
|
||||
using q4i = quat<i32>;
|
||||
using q4u = quat<u32>;
|
||||
using q4hi = quat<i16>;
|
||||
using q4hu = quat<u16>;
|
||||
|
||||
using b2d = rect<f64>;
|
||||
using b2f = rect<f32>;
|
||||
using b2i = rect<i32>;
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
#include "trig.hpp"
|
||||
#include "unit.hpp"
|
||||
#include "vec2.hpp"
|
||||
#include "vec3.hpp"
|
||||
#include "vec4.hpp"
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
@@ -276,20 +274,6 @@ namespace e2d::math
|
||||
0, y};
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
mat2<T> make_scale_matrix2(const vec4<T>& xy) noexcept {
|
||||
return make_scale_matrix2(
|
||||
xy.x,
|
||||
xy.y);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
mat2<T> make_scale_matrix2(const vec3<T>& xy) noexcept {
|
||||
return make_scale_matrix2(
|
||||
xy.x,
|
||||
xy.y);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
mat2<T> make_scale_matrix2(const vec2<T>& xy) noexcept {
|
||||
return make_scale_matrix2(
|
||||
|
||||
@@ -7,12 +7,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "_math.hpp"
|
||||
#include "quat.hpp"
|
||||
#include "trig.hpp"
|
||||
#include "unit.hpp"
|
||||
#include "vec2.hpp"
|
||||
#include "vec3.hpp"
|
||||
#include "vec4.hpp"
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
@@ -304,14 +302,6 @@ namespace e2d::math
|
||||
0, 0, z};
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
mat3<T> make_scale_matrix3(const vec4<T>& xyz) noexcept {
|
||||
return make_scale_matrix3(
|
||||
xyz.x,
|
||||
xyz.y,
|
||||
xyz.z);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
mat3<T> make_scale_matrix3(const vec3<T>& xyz) noexcept {
|
||||
return make_scale_matrix3(
|
||||
@@ -329,7 +319,7 @@ namespace e2d::math
|
||||
}
|
||||
|
||||
//
|
||||
// make_rotation_matrix
|
||||
// make_rotation_matrix (axis)
|
||||
//
|
||||
|
||||
template < typename T, typename AngleTag >
|
||||
@@ -361,18 +351,6 @@ namespace e2d::math
|
||||
xzm + ysn, yzm - xsn, pz * ics + cs};
|
||||
}
|
||||
|
||||
template < typename T, typename AngleTag >
|
||||
mat3<T> make_rotation_matrix3(
|
||||
const unit<T, AngleTag>& angle,
|
||||
const vec4<T>& axis_xyz) noexcept
|
||||
{
|
||||
return make_rotation_matrix3(
|
||||
angle,
|
||||
axis_xyz.x,
|
||||
axis_xyz.y,
|
||||
axis_xyz.z);
|
||||
}
|
||||
|
||||
template < typename T, typename AngleTag >
|
||||
mat3<T> make_rotation_matrix3(
|
||||
const unit<T, AngleTag>& angle,
|
||||
@@ -385,42 +363,40 @@ namespace e2d::math
|
||||
axis_xyz.z);
|
||||
}
|
||||
|
||||
//
|
||||
// make_rotation_matrix (euler)
|
||||
//
|
||||
|
||||
template < typename T, typename AngleTag >
|
||||
mat3<T> make_rotation_matrix3(
|
||||
const unit<T, AngleTag>& angle,
|
||||
const vec2<T>& axis_xy,
|
||||
T axis_z) noexcept
|
||||
const unit<T, AngleTag>& roll,
|
||||
const unit<T, AngleTag>& pitch,
|
||||
const unit<T, AngleTag>& yaw) noexcept
|
||||
{
|
||||
return make_rotation_matrix3(
|
||||
angle,
|
||||
axis_xy.x,
|
||||
axis_xy.y,
|
||||
axis_z);
|
||||
const T csr = math::cos(roll);
|
||||
const T snr = math::sin(roll);
|
||||
|
||||
const T csp = math::cos(pitch);
|
||||
const T snp = math::sin(pitch);
|
||||
|
||||
const T csy = math::cos(yaw);
|
||||
const T sny = math::sin(yaw);
|
||||
|
||||
const T snr_snp = snr * snp;
|
||||
const T csr_snp = csr * snp;
|
||||
|
||||
return {
|
||||
csp * csy, csp * sny, -snp,
|
||||
snr_snp * csy - csr * sny, snr_snp * sny + csr * csy, snr * csp,
|
||||
csr_snp * csy + snr * sny, csr_snp * sny - snr * csy, csr * csp};
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
mat3<T> make_rotation_matrix3(const quat<T>& q) noexcept {
|
||||
const T x = q.x;
|
||||
const T y = q.y;
|
||||
const T z = q.z;
|
||||
const T w = q.w;
|
||||
|
||||
const T xx = x * x;
|
||||
const T xy = x * y;
|
||||
const T xz = x * z;
|
||||
const T xw = x * w;
|
||||
|
||||
const T yy = y * y;
|
||||
const T yz = y * z;
|
||||
const T yw = y * w;
|
||||
|
||||
const T zz = z * z;
|
||||
const T zw = z * w;
|
||||
|
||||
return {
|
||||
T(1) - T(2) * (yy + zz), T(2) * (xy + zw), T(2) * (xz - yw),
|
||||
T(2) * (xy - zw), T(1) - T(2) * (xx + zz), T(2) * (yz + xw),
|
||||
T(2) * (xz + yw), T(2) * (yz - xw), T(1) - T(2) * (xx + yy)};
|
||||
mat3<T> make_rotation_matrix3(const vec3<T>& rpy) noexcept {
|
||||
return make_rotation_matrix3(
|
||||
make_rad(rpy.x),
|
||||
make_rad(rpy.y),
|
||||
make_rad(rpy.z));
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "_math.hpp"
|
||||
#include "quat.hpp"
|
||||
#include "trig.hpp"
|
||||
#include "trs2.hpp"
|
||||
#include "trs3.hpp"
|
||||
@@ -335,14 +334,6 @@ namespace e2d::math
|
||||
0, 0, 0, 1};
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
mat4<T> make_scale_matrix4(const vec4<T>& xyz) noexcept {
|
||||
return make_scale_matrix4(
|
||||
xyz.x,
|
||||
xyz.y,
|
||||
xyz.z);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
mat4<T> make_scale_matrix4(const vec3<T>& xyz) noexcept {
|
||||
return make_scale_matrix4(
|
||||
@@ -372,14 +363,6 @@ namespace e2d::math
|
||||
x, y, z, 1};
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
mat4<T> make_translation_matrix4(const vec4<T>& xyz) noexcept {
|
||||
return make_translation_matrix4(
|
||||
xyz.x,
|
||||
xyz.y,
|
||||
xyz.z);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
mat4<T> make_translation_matrix4(const vec3<T>& xyz) noexcept {
|
||||
return make_translation_matrix4(
|
||||
@@ -397,7 +380,7 @@ namespace e2d::math
|
||||
}
|
||||
|
||||
//
|
||||
// make_rotation_matrix
|
||||
// make_rotation_matrix (axis)
|
||||
//
|
||||
|
||||
template < typename T, typename AngleTag >
|
||||
@@ -430,18 +413,6 @@ namespace e2d::math
|
||||
T(0), T(0), T(0), T(1)};
|
||||
}
|
||||
|
||||
template < typename T, typename AngleTag >
|
||||
mat4<T> make_rotation_matrix4(
|
||||
const unit<T, AngleTag>& angle,
|
||||
const vec4<T>& axis_xyz) noexcept
|
||||
{
|
||||
return make_rotation_matrix4(
|
||||
angle,
|
||||
axis_xyz.x,
|
||||
axis_xyz.y,
|
||||
axis_xyz.z);
|
||||
}
|
||||
|
||||
template < typename T, typename AngleTag >
|
||||
mat4<T> make_rotation_matrix4(
|
||||
const unit<T, AngleTag>& angle,
|
||||
@@ -454,43 +425,41 @@ namespace e2d::math
|
||||
axis_xyz.z);
|
||||
}
|
||||
|
||||
//
|
||||
// make_rotation_matrix (euler)
|
||||
//
|
||||
|
||||
template < typename T, typename AngleTag >
|
||||
mat4<T> make_rotation_matrix4(
|
||||
const unit<T, AngleTag>& angle,
|
||||
const vec2<T>& axis_xy,
|
||||
T axis_z) noexcept
|
||||
const unit<T, AngleTag>& roll,
|
||||
const unit<T, AngleTag>& pitch,
|
||||
const unit<T, AngleTag>& yaw) noexcept
|
||||
{
|
||||
return make_rotation_matrix4(
|
||||
angle,
|
||||
axis_xy.x,
|
||||
axis_xy.y,
|
||||
axis_z);
|
||||
const T csr = math::cos(roll);
|
||||
const T snr = math::sin(roll);
|
||||
|
||||
const T csp = math::cos(pitch);
|
||||
const T snp = math::sin(pitch);
|
||||
|
||||
const T csy = math::cos(yaw);
|
||||
const T sny = math::sin(yaw);
|
||||
|
||||
const T snr_snp = snr * snp;
|
||||
const T csr_snp = csr * snp;
|
||||
|
||||
return {
|
||||
csp * csy, csp * sny, -snp, T(0),
|
||||
snr_snp * csy - csr * sny, snr_snp * sny + csr * csy, snr * csp, T(0),
|
||||
csr_snp * csy + snr * sny, csr_snp * sny - snr * csy, csr * csp, T(0),
|
||||
T(0), T(0), T(0), T(1)};
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
mat4<T> make_rotation_matrix4(const quat<T>& q) noexcept {
|
||||
const T x = q.x;
|
||||
const T y = q.y;
|
||||
const T z = q.z;
|
||||
const T w = q.w;
|
||||
|
||||
const T xx = x * x;
|
||||
const T xy = x * y;
|
||||
const T xz = x * z;
|
||||
const T xw = x * w;
|
||||
|
||||
const T yy = y * y;
|
||||
const T yz = y * z;
|
||||
const T yw = y * w;
|
||||
|
||||
const T zz = z * z;
|
||||
const T zw = z * w;
|
||||
|
||||
return {
|
||||
T(1) - T(2) * (yy + zz), T(2) * (xy + zw), T(2) * (xz - yw), T(0),
|
||||
T(2) * (xy - zw), T(1) - T(2) * (xx + zz), T(2) * (yz + xw), T(0),
|
||||
T(2) * (xz + yw), T(2) * (yz - xw), T(1) - T(2) * (xx + yy), T(0),
|
||||
T(0), T(0), T(0), T(1)};
|
||||
mat4<T> make_rotation_matrix4(const vec3<T>& rpy) noexcept {
|
||||
return make_rotation_matrix4(
|
||||
make_rad(rpy.x),
|
||||
make_rad(rpy.y),
|
||||
make_rad(rpy.z));
|
||||
}
|
||||
|
||||
//
|
||||
@@ -500,7 +469,7 @@ namespace e2d::math
|
||||
template < typename T >
|
||||
mat4<T> make_trs_matrix4(const trs2<T>& trs) noexcept {
|
||||
return make_scale_matrix4(trs.scale)
|
||||
* make_rotation_matrix4(trs.rotation, v4f::unit_z())
|
||||
* make_rotation_matrix4(make_rad(trs.rotation), vec3<T>::unit_z())
|
||||
* make_translation_matrix4(trs.translation);
|
||||
}
|
||||
|
||||
@@ -518,8 +487,8 @@ namespace e2d::math
|
||||
template < typename T >
|
||||
std::enable_if_t<std::is_floating_point_v<T>, mat4<T>>
|
||||
make_look_at_lh_matrix4(const vec3<T>& eye, const vec3<T>& at, const vec3<T>& up) noexcept {
|
||||
const vec3<T> az = normalized(at - eye);
|
||||
const vec3<T> ax = normalized(math::cross(up, az));
|
||||
const vec3<T> az = math::normalized(at - eye);
|
||||
const vec3<T> ax = math::normalized(math::cross(up, az));
|
||||
const vec3<T> ay = math::cross(az, ax);
|
||||
const T dx = math::dot(ax, eye);
|
||||
const T dy = math::dot(ay, eye);
|
||||
@@ -538,8 +507,8 @@ namespace e2d::math
|
||||
template < typename T >
|
||||
std::enable_if_t<std::is_floating_point_v<T>, mat4<T>>
|
||||
make_look_at_rh_matrix4(const vec3<T>& eye, const vec3<T>& at, const vec3<T>& up) noexcept {
|
||||
const vec3<T> az = normalized(eye - at);
|
||||
const vec3<T> ax = normalized(math::cross(up, az));
|
||||
const vec3<T> az = math::normalized(eye - at);
|
||||
const vec3<T> ax = math::normalized(math::cross(up, az));
|
||||
const vec3<T> ay = math::cross(az, ax);
|
||||
const T dx = math::dot(ax, eye);
|
||||
const T dy = math::dot(ay, eye);
|
||||
|
||||
@@ -1,472 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018-2019, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "_math.hpp"
|
||||
#include "trig.hpp"
|
||||
#include "unit.hpp"
|
||||
#include "vec3.hpp"
|
||||
#include "vec4.hpp"
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
template < typename T >
|
||||
class quat final {
|
||||
static_assert(
|
||||
std::is_arithmetic_v<T>,
|
||||
"type of 'quat' must be arithmetic");
|
||||
public:
|
||||
using self_type = quat;
|
||||
using value_type = T;
|
||||
public:
|
||||
T x = 0;
|
||||
T y = 0;
|
||||
T z = 0;
|
||||
T w = 1;
|
||||
public:
|
||||
static constexpr quat zero() noexcept;
|
||||
static constexpr quat identity() noexcept;
|
||||
public:
|
||||
constexpr quat() noexcept = default;
|
||||
constexpr quat(const quat& other) noexcept = default;
|
||||
constexpr quat& operator=(const quat& other) noexcept = default;
|
||||
|
||||
constexpr quat(T x, T y, T z, T w) noexcept;
|
||||
constexpr explicit quat(const vec4<T>& other) noexcept;
|
||||
|
||||
template < typename To >
|
||||
quat<To> cast_to() const noexcept;
|
||||
|
||||
T* data() noexcept;
|
||||
const T* data() const noexcept;
|
||||
|
||||
T& operator[](std::size_t index) noexcept;
|
||||
T operator[](std::size_t index) const noexcept;
|
||||
|
||||
quat& operator+=(T v) noexcept;
|
||||
quat& operator*=(T v) noexcept;
|
||||
|
||||
quat& operator+=(const quat& other) noexcept;
|
||||
quat& operator*=(const quat& other) noexcept;
|
||||
};
|
||||
}
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
template < typename T >
|
||||
constexpr quat<T> quat<T>::zero() noexcept {
|
||||
return {0, 0, 0, 0};
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
constexpr quat<T> quat<T>::identity() noexcept {
|
||||
return {0, 0, 0, 1};
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
constexpr quat<T>::quat(T nx, T ny, T nz, T nw) noexcept
|
||||
: x(nx)
|
||||
, y(ny)
|
||||
, z(nz)
|
||||
, w(nw) {}
|
||||
|
||||
template < typename T >
|
||||
constexpr quat<T>::quat(const vec4<T>& other) noexcept
|
||||
: x(other.x)
|
||||
, y(other.y)
|
||||
, z(other.z)
|
||||
, w(other.w) {}
|
||||
|
||||
template < typename T >
|
||||
template < typename To >
|
||||
quat<To> quat<T>::cast_to() const noexcept {
|
||||
return {
|
||||
math::numeric_cast<To>(x),
|
||||
math::numeric_cast<To>(y),
|
||||
math::numeric_cast<To>(z),
|
||||
math::numeric_cast<To>(w)};
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
T* quat<T>::data() noexcept {
|
||||
return &x;
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
const T* quat<T>::data() const noexcept {
|
||||
return &x;
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
T& quat<T>::operator[](std::size_t index) noexcept {
|
||||
E2D_ASSERT(index < 4);
|
||||
return data()[index];
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
T quat<T>::operator[](std::size_t index) const noexcept {
|
||||
E2D_ASSERT(index < 4);
|
||||
return data()[index];
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
quat<T>& quat<T>::operator+=(T v) noexcept {
|
||||
return *this = *this + v;
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
quat<T>& quat<T>::operator*=(T v) noexcept {
|
||||
return *this = *this * v;
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
quat<T>& quat<T>::operator+=(const quat& other) noexcept {
|
||||
return *this = *this + other;
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
quat<T>& quat<T>::operator*=(const quat& other) noexcept {
|
||||
return *this = *this * other;
|
||||
}
|
||||
}
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
//
|
||||
// make_quat
|
||||
//
|
||||
|
||||
template < typename T >
|
||||
constexpr quat<T> make_quat(T x, T y, T z, T w) noexcept {
|
||||
return quat<T>(x, y, z, w);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
constexpr quat<T> make_quat(const vec4<T>& other) noexcept {
|
||||
return quat<T>(other);
|
||||
}
|
||||
|
||||
//
|
||||
// quat (==,!=) quat
|
||||
//
|
||||
|
||||
template < typename T >
|
||||
bool operator==(const quat<T>& l, const quat<T>& r) noexcept {
|
||||
return
|
||||
math::approximately(l.x, r.x) &&
|
||||
math::approximately(l.y, r.y) &&
|
||||
math::approximately(l.z, r.z) &&
|
||||
math::approximately(l.w, r.w);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
bool operator!=(const quat<T>& l, const quat<T>& r) noexcept {
|
||||
return !(l == r);
|
||||
}
|
||||
|
||||
//
|
||||
// quat (<,>,<=,>=) quat
|
||||
//
|
||||
|
||||
template < typename T >
|
||||
bool operator<(const quat<T>& l, const quat<T>& r) noexcept {
|
||||
return
|
||||
(l.x < r.x) ||
|
||||
(l.x == r.x && l.y < r.y) ||
|
||||
(l.x == r.x && l.y == r.y && l.z < r.z) ||
|
||||
(l.x == r.x && l.y == r.y && l.z == r.z && l.w < r.w);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
bool operator>(const quat<T>& l, const quat<T>& r) noexcept {
|
||||
return r < l;
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
bool operator<=(const quat<T>& l, const quat<T>& r) noexcept {
|
||||
return !(r < l);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
bool operator>=(const quat<T>& l, const quat<T>& r) noexcept {
|
||||
return !(l < r);
|
||||
}
|
||||
|
||||
//
|
||||
// quat (+,*) value
|
||||
//
|
||||
|
||||
template < typename T >
|
||||
quat<T> operator+(const quat<T>& l, T v) noexcept {
|
||||
return {
|
||||
l.x + v,
|
||||
l.y + v,
|
||||
l.z + v,
|
||||
l.w + v};
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
quat<T> operator*(const quat<T>& l, T v) noexcept {
|
||||
return {
|
||||
l.x * v,
|
||||
l.y * v,
|
||||
l.z * v,
|
||||
l.w * v};
|
||||
}
|
||||
|
||||
//
|
||||
// value (+,*) quat
|
||||
//
|
||||
|
||||
template < typename T >
|
||||
quat<T> operator+(T v, const quat<T>& r) noexcept {
|
||||
return {
|
||||
v + r.x,
|
||||
v + r.y,
|
||||
v + r.z,
|
||||
v + r.w};
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
quat<T> operator*(T v, const quat<T>& r) noexcept {
|
||||
return {
|
||||
v * r.x,
|
||||
v * r.y,
|
||||
v * r.z,
|
||||
v * r.w};
|
||||
}
|
||||
|
||||
//
|
||||
// quat (+,*) quat
|
||||
//
|
||||
|
||||
template < typename T >
|
||||
quat<T> operator+(const quat<T>& l, const quat<T>& r) noexcept {
|
||||
return {
|
||||
l.x + r.x,
|
||||
l.y + r.y,
|
||||
l.z + r.z,
|
||||
l.w + r.w};
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
quat<T> operator*(const quat<T>& l, const quat<T>& r) noexcept {
|
||||
return {
|
||||
(l.w * r.x) + (l.x * r.w) + (l.y * r.z) - (l.z * r.y),
|
||||
(l.w * r.y) + (l.y * r.w) + (l.z * r.x) - (l.x * r.z),
|
||||
(l.w * r.z) + (l.z * r.w) + (l.x * r.y) - (l.y * r.x),
|
||||
(l.w * r.w) - (l.x * r.x) - (l.y * r.y) - (l.z * r.z)};
|
||||
}
|
||||
|
||||
//
|
||||
// vec3 (*) quat
|
||||
//
|
||||
|
||||
template < typename T >
|
||||
vec3<T> operator*(const vec3<T>& l, const quat<T>& r) noexcept {
|
||||
const vec3<T> qvec{r.x, r.y, r.z};
|
||||
auto uv = math::cross(qvec, l);
|
||||
auto uuv = math::cross(qvec, uv);
|
||||
uv *= r.w * T(2);
|
||||
uuv *= T(2);
|
||||
return l + uv + uuv;
|
||||
}
|
||||
}
|
||||
|
||||
namespace e2d::math
|
||||
{
|
||||
//
|
||||
// make_quat_from_axis_angle
|
||||
//
|
||||
|
||||
template < typename T, typename AngleTag >
|
||||
std::enable_if_t<std::is_floating_point_v<T>, quat<T>>
|
||||
make_quat_from_axis_angle(
|
||||
const unit<T, AngleTag>& angle,
|
||||
const vec3<T>& axis_xyz) noexcept
|
||||
{
|
||||
const unit<T, AngleTag> ha = T(0.5) * angle;
|
||||
const T sa = math::sin(ha);
|
||||
const T ca = math::cos(ha);
|
||||
return {
|
||||
sa * axis_xyz.x,
|
||||
sa * axis_xyz.y,
|
||||
sa * axis_xyz.z,
|
||||
ca};
|
||||
}
|
||||
|
||||
//
|
||||
// make_quat_from_euler_angles
|
||||
//
|
||||
|
||||
template < typename T
|
||||
, typename AngleTagR
|
||||
, typename AngleTagP
|
||||
, typename AngleTagY >
|
||||
std::enable_if_t<std::is_floating_point_v<T>, quat<T>>
|
||||
make_quat_from_euler_angles(
|
||||
const unit<T, AngleTagR>& roll,
|
||||
const unit<T, AngleTagP>& pitch,
|
||||
const unit<T, AngleTagY>& yaw) noexcept
|
||||
{
|
||||
const unit<T, AngleTagR> hr = T(0.5) * roll;
|
||||
const T sr = math::sin(hr);
|
||||
const T cr = math::cos(hr);
|
||||
|
||||
const unit<T, AngleTagP> hp = T(0.5) * pitch;
|
||||
const T sp = math::sin(hp);
|
||||
const T cp = math::cos(hp);
|
||||
|
||||
const unit<T, AngleTagY> hy = T(0.5) * yaw;
|
||||
const T sy = math::sin(hy);
|
||||
const T cy = math::cos(hy);
|
||||
|
||||
const T cpcy = cp * cy;
|
||||
const T spcy = sp * cy;
|
||||
const T cpsy = cp * sy;
|
||||
const T spsy = sp * sy;
|
||||
|
||||
return {
|
||||
sr * cpcy - cr * spsy,
|
||||
cr * spcy + sr * cpsy,
|
||||
cr * cpsy - sr * spcy,
|
||||
cr * cpcy + sr * spsy};
|
||||
}
|
||||
|
||||
//
|
||||
// approximately
|
||||
//
|
||||
|
||||
template < typename T >
|
||||
bool approximately(
|
||||
const quat<T>& l,
|
||||
const quat<T>& r,
|
||||
T precision = math::default_precision<T>()) noexcept
|
||||
{
|
||||
return
|
||||
math::approximately(l.x, r.x, precision) &&
|
||||
math::approximately(l.y, r.y, precision) &&
|
||||
math::approximately(l.z, r.z, precision) &&
|
||||
math::approximately(l.w, r.w, precision);
|
||||
}
|
||||
|
||||
//
|
||||
// dot
|
||||
//
|
||||
|
||||
template < typename T >
|
||||
T dot(const quat<T>& l, const quat<T>& r) noexcept {
|
||||
return
|
||||
l.x * r.x +
|
||||
l.y * r.y +
|
||||
l.z * r.z +
|
||||
l.w * r.w;
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
T abs_dot(const quat<T>& l, const quat<T>& r) noexcept {
|
||||
return
|
||||
math::abs(l.x * r.x) +
|
||||
math::abs(l.y * r.y) +
|
||||
math::abs(l.z * r.z) +
|
||||
math::abs(l.w * r.w);
|
||||
}
|
||||
|
||||
//
|
||||
// length
|
||||
//
|
||||
|
||||
template < typename T >
|
||||
T length_squared(const quat<T>& v) noexcept {
|
||||
return dot(v, v);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
std::enable_if_t<std::is_floating_point_v<T>, T>
|
||||
length(const quat<T>& v) noexcept {
|
||||
return math::sqrt(length_squared(v));
|
||||
}
|
||||
|
||||
//
|
||||
// normalized
|
||||
//
|
||||
|
||||
template < typename T >
|
||||
std::enable_if_t<std::is_floating_point_v<T>, quat<T>>
|
||||
normalized(
|
||||
const quat<T>& v,
|
||||
T precision = math::default_precision<T>()) noexcept
|
||||
{
|
||||
const T l = length(v);
|
||||
if ( !math::is_near_zero(l, precision) ) {
|
||||
const T inv_l = T(1) / l;
|
||||
return v * inv_l;
|
||||
}
|
||||
return quat<T>::identity();
|
||||
}
|
||||
|
||||
//
|
||||
// lerp
|
||||
//
|
||||
|
||||
template < typename T >
|
||||
quat<T> lerp(const quat<T>& l, const quat<T>& r, T v) noexcept {
|
||||
return {
|
||||
math::lerp(l.x, r.x, v),
|
||||
math::lerp(l.y, r.y, v),
|
||||
math::lerp(l.z, r.z, v),
|
||||
math::lerp(l.w, r.w, v)};
|
||||
}
|
||||
|
||||
//
|
||||
// inversed
|
||||
//
|
||||
|
||||
template < typename T >
|
||||
std::enable_if_t<std::is_floating_point_v<T>, quat<T>>
|
||||
inversed(
|
||||
const quat<T>& q,
|
||||
T precision = math::default_precision<T>()) noexcept
|
||||
{
|
||||
const T l = length(q);
|
||||
if ( !math::is_near_zero(l, precision) ) {
|
||||
const T inv_l = T(1) / l;
|
||||
return {
|
||||
-q.x * inv_l,
|
||||
-q.y * inv_l,
|
||||
-q.z * inv_l,
|
||||
q.w * inv_l};
|
||||
}
|
||||
return quat<T>::identity();
|
||||
}
|
||||
|
||||
//
|
||||
// conjugated
|
||||
//
|
||||
|
||||
template < typename T >
|
||||
quat<T> conjugated(const quat<T>& q) noexcept {
|
||||
return {
|
||||
-q.x,
|
||||
-q.y,
|
||||
-q.z,
|
||||
q.w};
|
||||
}
|
||||
|
||||
//
|
||||
// contains_nan
|
||||
//
|
||||
|
||||
template < typename T >
|
||||
bool contains_nan(const quat<T>& v) noexcept {
|
||||
return
|
||||
!math::is_finite(v.x) ||
|
||||
!math::is_finite(v.y) ||
|
||||
!math::is_finite(v.z) ||
|
||||
!math::is_finite(v.w);
|
||||
}
|
||||
}
|
||||
@@ -66,6 +66,53 @@ namespace e2d::math
|
||||
}
|
||||
}
|
||||
|
||||
namespace e2d::math
|
||||
{
|
||||
//
|
||||
// deg_to_rad
|
||||
//
|
||||
|
||||
template < typename T >
|
||||
std::enable_if_t<std::is_floating_point_v<T>, T>
|
||||
deg_to_rad() noexcept {
|
||||
return math::pi<T>().value / T(180);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
std::enable_if_t<std::is_integral_v<T>, T>
|
||||
deg_to_rad(T deg) noexcept {
|
||||
return math::numeric_cast<T>(deg * deg_to_rad<f64>());
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
std::enable_if_t<std::is_floating_point_v<T>, T>
|
||||
deg_to_rad(T deg) noexcept {
|
||||
return deg * deg_to_rad<T>();
|
||||
}
|
||||
|
||||
//
|
||||
// rad_to_deg
|
||||
//
|
||||
|
||||
template < typename T >
|
||||
std::enable_if_t<std::is_floating_point_v<T>, T>
|
||||
rad_to_deg() noexcept {
|
||||
return T(180) / math::pi<T>().value;
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
std::enable_if_t<std::is_integral_v<T>, T>
|
||||
rad_to_deg(T rad) noexcept {
|
||||
return math::numeric_cast<T>(rad * rad_to_deg<f64>());
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
std::enable_if_t<std::is_floating_point_v<T>, T>
|
||||
rad_to_deg(T rad) noexcept {
|
||||
return rad * rad_to_deg<T>();
|
||||
}
|
||||
}
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
template < typename T >
|
||||
@@ -81,17 +128,8 @@ namespace e2d
|
||||
template <>
|
||||
struct unit_converter<rad_tag, deg_tag> {
|
||||
template < typename T >
|
||||
std::enable_if_t<std::is_integral_v<T>, deg<T>>
|
||||
operator()(const rad<T>& u) const noexcept {
|
||||
const f64 rad_to_deg = 180.0 / math::pi<f64>().value;
|
||||
return make_deg(u.value * rad_to_deg).template cast_to<T>();
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
std::enable_if_t<std::is_floating_point_v<T>, deg<T>>
|
||||
operator()(const rad<T>& u) const noexcept {
|
||||
const T rad_to_deg = T(180) / math::pi<T>().value;
|
||||
return make_deg(u.value * rad_to_deg);
|
||||
deg<T> operator()(const rad<T>& u) const noexcept {
|
||||
return make_deg(math::rad_to_deg(u.value));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -99,17 +137,8 @@ namespace e2d
|
||||
struct unit_converter<deg_tag, rad_tag> {
|
||||
public:
|
||||
template < typename T >
|
||||
std::enable_if_t<std::is_integral_v<T>, rad<T>>
|
||||
operator()(const deg<T>& u) const noexcept {
|
||||
const f64 deg_to_rad = math::pi<f64>().value / 180.0;
|
||||
return make_rad(u.value * deg_to_rad).template cast_to<T>();
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
std::enable_if_t<std::is_floating_point_v<T>, rad<T>>
|
||||
operator()(const deg<T>& u) const noexcept {
|
||||
const T deg_to_rad = math::pi<T>().value / T(180);
|
||||
return make_rad(u.value * deg_to_rad);
|
||||
rad<T> operator()(const deg<T>& u) const noexcept {
|
||||
return make_rad(math::deg_to_rad(u.value));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "_math.hpp"
|
||||
#include "trig.hpp"
|
||||
#include "unit.hpp"
|
||||
#include "vec2.hpp"
|
||||
|
||||
namespace e2d
|
||||
@@ -23,7 +21,7 @@ namespace e2d
|
||||
using value_type = T;
|
||||
public:
|
||||
vec2<T> translation = vec2<T>::zero();
|
||||
rad<T> rotation = rad<T>::zero();
|
||||
T rotation = T(0);
|
||||
vec2<T> scale = vec2<T>::unit();
|
||||
public:
|
||||
static constexpr trs2 zero() noexcept;
|
||||
@@ -33,10 +31,9 @@ namespace e2d
|
||||
constexpr trs2(const trs2& other) noexcept = default;
|
||||
constexpr trs2& operator=(const trs2& other) noexcept = default;
|
||||
|
||||
template < typename AngleTag >
|
||||
constexpr trs2(
|
||||
const vec2<T>& t,
|
||||
const unit<T, AngleTag>& r,
|
||||
const T& r,
|
||||
const vec2<T>& s) noexcept;
|
||||
|
||||
template < typename To >
|
||||
@@ -50,7 +47,7 @@ namespace e2d
|
||||
constexpr trs2<T> trs2<T>::zero() noexcept {
|
||||
return {
|
||||
vec2<T>::zero(),
|
||||
rad<T>::zero(),
|
||||
T(0),
|
||||
vec2<T>::zero()};
|
||||
}
|
||||
|
||||
@@ -58,15 +55,14 @@ namespace e2d
|
||||
constexpr trs2<T> trs2<T>::identity() noexcept {
|
||||
return {
|
||||
vec2<T>::zero(),
|
||||
rad<T>::zero(),
|
||||
T(0),
|
||||
vec2<T>::unit()};
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
template < typename AngleTag >
|
||||
constexpr trs2<T>::trs2(
|
||||
const vec2<T>& t,
|
||||
const unit<T, AngleTag>& r,
|
||||
const T& r,
|
||||
const vec2<T>& s) noexcept
|
||||
: translation(t)
|
||||
, rotation(r)
|
||||
@@ -77,7 +73,7 @@ namespace e2d
|
||||
trs2<To> trs2<T>::cast_to() const noexcept {
|
||||
return {
|
||||
translation.template cast_to<To>(),
|
||||
rotation.template cast_to<To>(),
|
||||
math::numeric_cast<To>(rotation),
|
||||
scale.template cast_to<To>()};
|
||||
}
|
||||
}
|
||||
@@ -88,13 +84,13 @@ namespace e2d
|
||||
// make_trs2
|
||||
//
|
||||
|
||||
template < typename T, typename AngleTag >
|
||||
template < typename T >
|
||||
constexpr trs2<T> make_trs2(
|
||||
const vec2<T>& t,
|
||||
const unit<T, AngleTag>& r,
|
||||
const T& r,
|
||||
const vec2<T>& s) noexcept
|
||||
{
|
||||
return trs2<T>(t, r, s);
|
||||
return { t, r, s };
|
||||
}
|
||||
|
||||
//
|
||||
@@ -118,17 +114,17 @@ namespace e2d::math
|
||||
{
|
||||
template < typename T >
|
||||
trs2<T> make_translation_trs2(const vec2<T>& t) noexcept {
|
||||
return trs2<T>(t, rad<T>::zero(), vec2<T>::unit());
|
||||
return { t, T(0), vec2<T>::unit() };
|
||||
}
|
||||
|
||||
template < typename T, typename AngleTag >
|
||||
trs2<T> make_rotation_trs2(const unit<T, AngleTag>& r) noexcept {
|
||||
return trs2<T>(vec2<T>::zero(), r, vec2<T>::unit());
|
||||
template < typename T >
|
||||
trs2<T> make_rotation_trs2(const T& r) noexcept {
|
||||
return { vec2<T>::zero(), r, vec2<T>::unit() };
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
trs2<T> make_scale_trs2(const vec2<T>& s) noexcept {
|
||||
return trs2<T>(vec2<T>::zero(), rad<T>::zero(), s);
|
||||
return { vec2<T>::zero(), T(0), s };
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "_math.hpp"
|
||||
#include "quat.hpp"
|
||||
#include "vec3.hpp"
|
||||
|
||||
namespace e2d
|
||||
@@ -22,7 +21,7 @@ namespace e2d
|
||||
using value_type = T;
|
||||
public:
|
||||
vec3<T> translation = vec3<T>::zero();
|
||||
quat<T> rotation = quat<T>::identity();
|
||||
vec3<T> rotation = vec3<T>::zero();
|
||||
vec3<T> scale = vec3<T>::unit();
|
||||
public:
|
||||
static constexpr trs3 zero() noexcept;
|
||||
@@ -34,7 +33,7 @@ namespace e2d
|
||||
|
||||
constexpr trs3(
|
||||
const vec3<T>& t,
|
||||
const quat<T>& r,
|
||||
const vec3<T>& r,
|
||||
const vec3<T>& s) noexcept;
|
||||
|
||||
template < typename To >
|
||||
@@ -48,7 +47,7 @@ namespace e2d
|
||||
constexpr trs3<T> trs3<T>::zero() noexcept {
|
||||
return {
|
||||
vec3<T>::zero(),
|
||||
quat<T>::zero(),
|
||||
vec3<T>::zero(),
|
||||
vec3<T>::zero()};
|
||||
}
|
||||
|
||||
@@ -56,14 +55,14 @@ namespace e2d
|
||||
constexpr trs3<T> trs3<T>::identity() noexcept {
|
||||
return {
|
||||
vec3<T>::zero(),
|
||||
quat<T>::identity(),
|
||||
vec3<T>::zero(),
|
||||
vec3<T>::unit()};
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
constexpr trs3<T>::trs3(
|
||||
const vec3<T>& t,
|
||||
const quat<T>& r,
|
||||
const vec3<T>& r,
|
||||
const vec3<T>& s) noexcept
|
||||
: translation(t)
|
||||
, rotation(r)
|
||||
@@ -88,10 +87,10 @@ namespace e2d
|
||||
template < typename T >
|
||||
constexpr trs3<T> make_trs3(
|
||||
const vec3<T>& t,
|
||||
const quat<T>& r,
|
||||
const vec3<T>& r,
|
||||
const vec3<T>& s) noexcept
|
||||
{
|
||||
return trs3<T>(t, r, s);
|
||||
return { t, r, s };
|
||||
}
|
||||
|
||||
//
|
||||
@@ -115,17 +114,17 @@ namespace e2d::math
|
||||
{
|
||||
template < typename T >
|
||||
trs3<T> make_translation_trs3(const vec3<T>& t) noexcept {
|
||||
return trs3<T>(t, quat<T>::identity(), vec3<T>::unit());
|
||||
return { t, vec3<T>::zero(), vec3<T>::unit() };
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
trs3<T> make_rotation_trs3(const quat<T>& r) noexcept {
|
||||
return trs3<T>(vec3<T>::zero(), r, vec3<T>::unit());
|
||||
trs3<T> make_rotation_trs3(const vec3<T>& r) noexcept {
|
||||
return { vec3<T>::zero(), r, vec3<T>::unit() };
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
trs3<T> make_scale_trs3(const vec3<T>& s) noexcept {
|
||||
return trs3<T>(vec3<T>::zero(), quat<T>::identity(), s);
|
||||
return { vec3<T>::zero(), vec3<T>::zero(), s };
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
|
||||
@@ -34,8 +34,6 @@ namespace e2d::json_utils
|
||||
bool try_parse_value(const rapidjson::Value& root, m3f& v) noexcept;
|
||||
bool try_parse_value(const rapidjson::Value& root, m4f& v) noexcept;
|
||||
|
||||
bool try_parse_value(const rapidjson::Value& root, q4f& v) noexcept;
|
||||
|
||||
bool try_parse_value(const rapidjson::Value& root, b2i& b) noexcept;
|
||||
bool try_parse_value(const rapidjson::Value& root, b3i& b) noexcept;
|
||||
|
||||
|
||||
@@ -138,49 +138,6 @@ namespace e2d::strings
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// quat
|
||||
//
|
||||
|
||||
template < typename T >
|
||||
class format_arg<quat<T>, std::enable_if_t<std::is_integral_v<T>>> {
|
||||
quat<T> value_;
|
||||
u8 width_;
|
||||
public:
|
||||
template < typename U >
|
||||
explicit format_arg(U&& value, u8 width = 0) noexcept
|
||||
: value_(std::forward<U>(value)), width_(width) {}
|
||||
|
||||
std::ptrdiff_t write(char* dst, size_t size) const {
|
||||
return math::numeric_cast<std::ptrdiff_t>(
|
||||
format(dst, size, "(%0,%1,%2,%3)",
|
||||
make_format_arg(value_.x, width_),
|
||||
make_format_arg(value_.y, width_),
|
||||
make_format_arg(value_.z, width_),
|
||||
make_format_arg(value_.w, width_)));
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
class format_arg<quat<T>, std::enable_if_t<std::is_floating_point_v<T>>> {
|
||||
quat<T> value_;
|
||||
u8 width_;
|
||||
u8 precision_;
|
||||
public:
|
||||
template < typename U >
|
||||
explicit format_arg(U&& value, u8 width = 0, u8 precision = 6) noexcept
|
||||
: value_(std::forward<U>(value)), width_(width), precision_(precision) {}
|
||||
|
||||
std::ptrdiff_t write(char* dst, size_t size) const {
|
||||
return math::numeric_cast<std::ptrdiff_t>(
|
||||
format(dst, size, "(%0,%1,%2,%3)",
|
||||
make_format_arg(value_.x, width_, precision_),
|
||||
make_format_arg(value_.y, width_, precision_),
|
||||
make_format_arg(value_.z, width_, precision_),
|
||||
make_format_arg(value_.w, width_, precision_)));
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// rect
|
||||
//
|
||||
|
||||
@@ -12,8 +12,8 @@ local renderer = {
|
||||
---@type v3f
|
||||
translation = v3f.zero(),
|
||||
|
||||
---@type q4f
|
||||
rotation = q4f.identity(),
|
||||
---@type v3f
|
||||
rotation = v3f.zero(),
|
||||
|
||||
---@type v3f
|
||||
scale = v3f.unit()
|
||||
|
||||
@@ -16,8 +16,6 @@ function m2f.zero() end
|
||||
function m2f.identity() end
|
||||
|
||||
---@overload fun(x: number, y: number): m2f
|
||||
---@overload fun(xy: v4f): m2f
|
||||
---@overload fun(xy: v3f): m2f
|
||||
---@overload fun(xy: v2f): m2f
|
||||
---@return m2f
|
||||
function m2f.make_scale(...) end
|
||||
|
||||
@@ -23,10 +23,9 @@ function m3f.identity() end
|
||||
function m3f.make_scale(...) end
|
||||
|
||||
---@overload fun(a: number, x: number, y: number, z: number): m3f
|
||||
---@overload fun(a: number, xyz: v4f): m3f
|
||||
---@overload fun(a: number, xyz: v3f): m3f
|
||||
---@overload fun(a: number, xy: v2f, z: number): m3f
|
||||
---@overload fun(q: q4f): m3f
|
||||
---@overload fun(r: number, p: number, y: number): m3f
|
||||
---@overload fun(rpy: v3f): m3f
|
||||
---@return m3f
|
||||
function m3f.make_rotation(...) end
|
||||
|
||||
|
||||
@@ -16,24 +16,21 @@ function m4f.zero() end
|
||||
function m4f.identity() end
|
||||
|
||||
---@overload fun(x: number, y: number, z: number): m4f
|
||||
---@overload fun(xyz: v4f): m4f
|
||||
---@overload fun(xyz: v3f): m4f
|
||||
---@overload fun(xy: v2f, z: number): m4f
|
||||
---@return m4f
|
||||
function m4f.make_scale(...) end
|
||||
|
||||
---@overload fun(x: number, y: number, z: number): m4f
|
||||
---@overload fun(xyz: v4f): m4f
|
||||
---@overload fun(xyz: v3f): m4f
|
||||
---@overload fun(xy: v2f, z: number): m4f
|
||||
---@return m4f
|
||||
function m4f.make_translation(...) end
|
||||
|
||||
---@overload fun(a: number, x: number, y: number, z: number): m4f
|
||||
---@overload fun(a: number, xyz: v4f): m4f
|
||||
---@overload fun(a: number, xyz: v3f): m4f
|
||||
---@overload fun(a: number, xy: v2f, z: number): m4f
|
||||
---@overload fun(q: q4f): m4f
|
||||
---@overload fun(r: number, p: number, y: number): m3f
|
||||
---@overload fun(rpy: v3f): m3f
|
||||
---@return m4f
|
||||
function m4f.make_rotation(...) end
|
||||
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
---@class q4f
|
||||
local q4f = {
|
||||
---@type number
|
||||
x = 0,
|
||||
|
||||
---@type number
|
||||
y = 0,
|
||||
|
||||
---@type number
|
||||
z = 0,
|
||||
|
||||
---@type number
|
||||
w = 0
|
||||
}
|
||||
|
||||
---@overload fun(): q4f
|
||||
---@overload fun(q: q4f): q4f
|
||||
---@overload fun(x: number, y: number, z: number, w: number): q4f
|
||||
---@overload fun(v: v4f): q4f
|
||||
---@return q4f
|
||||
function q4f.new(...) end
|
||||
|
||||
---@return q4f
|
||||
function q4f.zero() end
|
||||
|
||||
---@return q4f
|
||||
function q4f.identity() end
|
||||
|
||||
---@param angle number
|
||||
---@param axis v3f
|
||||
---@return q4f
|
||||
function q4f.make_from_axis_angle(angle, axis) end
|
||||
|
||||
---@param roll number
|
||||
---@param pitch number
|
||||
---@param yaw number
|
||||
---@return q4f
|
||||
function q4f.make_from_euler_angles(roll, pitch, yaw) end
|
||||
|
||||
---@param l q4f
|
||||
---@param r q4f
|
||||
---@return boolean
|
||||
function q4f.approximately(l, r) end
|
||||
|
||||
---@param l q4f
|
||||
---@param r q4f
|
||||
---@return number
|
||||
function q4f.dot(l, r) end
|
||||
|
||||
---@param l q4f
|
||||
---@param r q4f
|
||||
---@return number
|
||||
function q4f.abs_dot(l, r) end
|
||||
|
||||
---@param q q4f
|
||||
---@return number
|
||||
function q4f.length_squared(q) end
|
||||
|
||||
---@param q q4f
|
||||
---@return number
|
||||
function q4f.length(q) end
|
||||
|
||||
---@param q q4f
|
||||
---@return q4f
|
||||
function q4f.normalized(q) end
|
||||
|
||||
---@param l q4f
|
||||
---@param r q4f
|
||||
---@param v number
|
||||
---@return q4f
|
||||
function q4f.lerp(l, r, v) end
|
||||
|
||||
---@param q q4f
|
||||
---@return q4f
|
||||
function q4f.inversed(q) end
|
||||
|
||||
---@param q q4f
|
||||
---@return q4f
|
||||
function q4f.conjugated(q) end
|
||||
|
||||
---@param q q4f
|
||||
---@return q4f
|
||||
function q4f.contains_nan(q) end
|
||||
|
||||
---@type q4f
|
||||
_G.q4f = _G.q4f or q4f
|
||||
@@ -3,8 +3,8 @@ local t3f = {
|
||||
---@type v3f
|
||||
translation = v3f.zero(),
|
||||
|
||||
---@type q4f
|
||||
rotation = q4f.identity(),
|
||||
---@type v3f
|
||||
rotation = v3f.zero(),
|
||||
|
||||
---@type v3f
|
||||
scale = v3f.unit()
|
||||
@@ -24,7 +24,7 @@ function t3f.identity() end
|
||||
---@return t3f
|
||||
function t3f.make_translation(t) end
|
||||
|
||||
---@param r q4f
|
||||
---@param r v3f
|
||||
---@return t3f
|
||||
function t3f.make_rotation(r) end
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ end
|
||||
---@param go gobject
|
||||
local function update_gnome_rotation(meta, go)
|
||||
local time = the_engine.time
|
||||
go.renderer.rotation = q4f.make_from_euler_angles(0, time, 0)
|
||||
go.renderer.rotation = v3f.new(0, time, 0)
|
||||
end
|
||||
|
||||
-- -----------------------------------------------------------------------------
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace
|
||||
};
|
||||
|
||||
struct renderer_rotator {
|
||||
v3f axis;
|
||||
v3f delta;
|
||||
};
|
||||
|
||||
class game_system final : public systems::update_system {
|
||||
@@ -68,16 +68,13 @@ namespace
|
||||
[&event](const ecs::const_entity&, const node_rotator&, actor& act){
|
||||
const node_iptr node = act.node();
|
||||
if ( node ) {
|
||||
node->rotation(make_rad(event.time));
|
||||
node->rotation(event.time);
|
||||
}
|
||||
});
|
||||
|
||||
owner.for_joined_components<renderer_rotator, renderer>(
|
||||
[&event](const ecs::const_entity&, const renderer_rotator& rot, renderer& r){
|
||||
const q4f q = math::make_quat_from_axis_angle(
|
||||
make_rad(event.time),
|
||||
rot.axis);
|
||||
r.rotation(q);
|
||||
r.rotation(r.rotation() + rot.delta * event.dt);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -114,7 +111,7 @@ namespace
|
||||
the<world>().instantiate(
|
||||
prefab,
|
||||
scene_i.component<actor>()->node(),
|
||||
make_trs2(v2f{0,50.f}, radf::zero(), v2f{20.f}));
|
||||
make_trs2(v2f{0,50.f}, 0.f, v2f{20.f}));
|
||||
}
|
||||
|
||||
{
|
||||
@@ -147,7 +144,7 @@ namespace
|
||||
for ( std::size_t j = 0; j < 5; ++j ) {
|
||||
t2f trans{
|
||||
{-80.f + j * 40.f, -200.f + i * 40.f},
|
||||
radf::zero(),
|
||||
0.f,
|
||||
{2.f,2.f}};
|
||||
gobject inst = the<world>().instantiate(
|
||||
prefab_a,
|
||||
@@ -159,7 +156,7 @@ namespace
|
||||
.component<node_rotator>()
|
||||
.component<actor>(node::create(make_trs2(
|
||||
v2f{20.f,0.f},
|
||||
radf::zero(),
|
||||
0.f,
|
||||
v2f{0.3f,0.3f})));
|
||||
|
||||
the<world>().instantiate(
|
||||
|
||||
@@ -59,8 +59,8 @@ namespace e2d::bindings::high
|
||||
[](gcomponent<renderer>& c, const v3f& v) { c->translation(v); }),
|
||||
|
||||
"rotation", sol::property(
|
||||
[](const gcomponent<renderer>& c) -> q4f { return c->rotation(); },
|
||||
[](gcomponent<renderer>& c, const q4f& v) { c->rotation(v); }),
|
||||
[](const gcomponent<renderer>& c) -> v3f { return c->rotation(); },
|
||||
[](gcomponent<renderer>& c, const v3f& v) { c->rotation(v); }),
|
||||
|
||||
"scale", sol::property(
|
||||
[](const gcomponent<renderer>& c) -> v3f { return c->scale(); },
|
||||
|
||||
@@ -26,8 +26,8 @@ namespace e2d::bindings::high
|
||||
[](node& n, const v2f& v) { n.translation(v); }),
|
||||
|
||||
"rotation", sol::property(
|
||||
[](const node& n) -> f32 { return n.rotation().value; },
|
||||
[](node& n, f32 v) { n.rotation(make_rad(v)); }),
|
||||
[](const node& n) -> f32 { return n.rotation(); },
|
||||
[](node& n, f32 v) { n.rotation(v); }),
|
||||
|
||||
"scale", sol::property(
|
||||
[](const node& n) -> v2f { return n.scale(); },
|
||||
|
||||
@@ -18,8 +18,6 @@ namespace e2d::bindings::math
|
||||
void bind_mat3(sol::state& l);
|
||||
void bind_mat4(sol::state& l);
|
||||
|
||||
void bind_quat(sol::state& l);
|
||||
|
||||
void bind_rect(sol::state& l);
|
||||
void bind_aabb(sol::state& l);
|
||||
|
||||
@@ -38,8 +36,6 @@ namespace e2d::bindings
|
||||
math::bind_mat3(l);
|
||||
math::bind_mat4(l);
|
||||
|
||||
math::bind_quat(l);
|
||||
|
||||
math::bind_rect(l);
|
||||
math::bind_aabb(l);
|
||||
|
||||
|
||||
@@ -42,8 +42,6 @@ namespace
|
||||
|
||||
"make_scale", sol::overload(
|
||||
sol::resolve<mat2<T>(T,T)>(&math::make_scale_matrix2),
|
||||
sol::resolve<mat2<T>(const vec4<T>&)>(&math::make_scale_matrix2),
|
||||
sol::resolve<mat2<T>(const vec3<T>&)>(&math::make_scale_matrix2),
|
||||
sol::resolve<mat2<T>(const vec2<T>&)>(&math::make_scale_matrix2)),
|
||||
|
||||
"make_rotation", [](T angle) -> mat2<T> {
|
||||
|
||||
@@ -42,16 +42,14 @@ namespace
|
||||
|
||||
"make_scale", sol::overload(
|
||||
sol::resolve<mat3<T>(T,T,T)>(&math::make_scale_matrix3),
|
||||
sol::resolve<mat3<T>(const vec4<T>&)>(&math::make_scale_matrix3),
|
||||
sol::resolve<mat3<T>(const vec3<T>&)>(&math::make_scale_matrix3),
|
||||
sol::resolve<mat3<T>(const vec2<T>&, T)>(&math::make_scale_matrix3)),
|
||||
|
||||
"make_rotation", sol::overload(
|
||||
[](T angle, T x, T y, T z) -> mat3<T> { return math::make_rotation_matrix3(make_rad(angle), x, y, z); },
|
||||
[](T angle, const vec4<T>& xyz) -> mat3<T> { return math::make_rotation_matrix3(make_rad(angle), xyz); },
|
||||
[](T angle, const vec3<T>& xyz) -> mat3<T> { return math::make_rotation_matrix3(make_rad(angle), xyz); },
|
||||
[](T angle, const vec2<T>& xy, T z) -> mat3<T> { return math::make_rotation_matrix3(make_rad(angle), xy, z); },
|
||||
[](const quat<T>& q) -> mat3<T> { return math::make_rotation_matrix3(q); }),
|
||||
[](T r, T p, T y) -> mat3<T> { return math::make_rotation_matrix3(make_rad(r), make_rad(p), make_rad(y)); },
|
||||
[](const vec3<T>& rpy) -> mat3<T> { return math::make_rotation_matrix3(rpy); }),
|
||||
|
||||
"approximately", [](const mat3<T>& l, const mat3<T>& r) -> bool {
|
||||
return math::approximately(l,r);
|
||||
|
||||
@@ -42,22 +42,19 @@ namespace
|
||||
|
||||
"make_scale", sol::overload(
|
||||
sol::resolve<mat4<T>(T,T,T)>(&math::make_scale_matrix4),
|
||||
sol::resolve<mat4<T>(const vec4<T>&)>(&math::make_scale_matrix4),
|
||||
sol::resolve<mat4<T>(const vec3<T>&)>(&math::make_scale_matrix4),
|
||||
sol::resolve<mat4<T>(const vec2<T>&, T)>(&math::make_scale_matrix4)),
|
||||
|
||||
"make_translation", sol::overload(
|
||||
sol::resolve<mat4<T>(T,T,T)>(&math::make_translation_matrix4),
|
||||
sol::resolve<mat4<T>(const vec4<T>&)>(&math::make_translation_matrix4),
|
||||
sol::resolve<mat4<T>(const vec3<T>&)>(&math::make_translation_matrix4),
|
||||
sol::resolve<mat4<T>(const vec2<T>&, T)>(&math::make_translation_matrix4)),
|
||||
|
||||
"make_rotation", sol::overload(
|
||||
[](T angle, T x, T y, T z) -> mat4<T> { return math::make_rotation_matrix4(make_rad(angle), x, y, z); },
|
||||
[](T angle, const vec4<T>& xyz) -> mat4<T> { return math::make_rotation_matrix4(make_rad(angle), xyz); },
|
||||
[](T angle, const vec3<T>& xyz) -> mat4<T> { return math::make_rotation_matrix4(make_rad(angle), xyz); },
|
||||
[](T angle, const vec2<T>& xy, T z) -> mat4<T> { return math::make_rotation_matrix4(make_rad(angle), xy, z); },
|
||||
[](const quat<T>& q) -> mat4<T> { return math::make_rotation_matrix4(q); }),
|
||||
[](T r, T p, T y) -> mat4<T> { return math::make_rotation_matrix4(make_rad(r), make_rad(p), make_rad(y)); },
|
||||
[](const vec3<T>& rpy) -> mat4<T> { return math::make_rotation_matrix4(rpy); }),
|
||||
|
||||
"make_trs", sol::overload(
|
||||
sol::resolve<mat4<T>(const trs2<T>&)>(&math::make_trs_matrix4),
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018-2019, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#include "_math_binds.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
using namespace e2d;
|
||||
|
||||
template < typename T >
|
||||
void bind_quat_t(const str& name, sol::state& l) {
|
||||
l.new_usertype<quat<T>>(name,
|
||||
sol::constructors<
|
||||
quat<T>(),
|
||||
quat<T>(quat<T>),
|
||||
quat<T>(T,T,T,T),
|
||||
quat<T>(vec4<T>)>(),
|
||||
|
||||
"zero", &quat<T>::zero,
|
||||
"identity", &quat<T>::identity,
|
||||
|
||||
"x", &quat<T>::x,
|
||||
"y", &quat<T>::y,
|
||||
"z", &quat<T>::z,
|
||||
"w", &quat<T>::w,
|
||||
|
||||
sol::meta_function::to_string, [](const quat<T>& v){
|
||||
return strings::rformat("%0", v);
|
||||
},
|
||||
|
||||
sol::meta_function::equal_to, sol::resolve<bool(const quat<T>&, const quat<T>&)>(::operator==),
|
||||
sol::meta_function::less_than, sol::resolve<bool(const quat<T>&, const quat<T>&)>(::operator<),
|
||||
sol::meta_function::less_than_or_equal_to, sol::resolve<bool(const quat<T>&, const quat<T>&)>(::operator<=),
|
||||
|
||||
sol::meta_function::addition, sol::overload(
|
||||
sol::resolve<quat<T>(T, const quat<T>&)>(::operator+),
|
||||
sol::resolve<quat<T>(const quat<T>&, T)>(::operator+),
|
||||
sol::resolve<quat<T>(const quat<T>&, const quat<T>&)>(::operator+)),
|
||||
|
||||
sol::meta_function::multiplication, sol::overload(
|
||||
sol::resolve<quat<T>(T, const quat<T>&)>(::operator*),
|
||||
sol::resolve<quat<T>(const quat<T>&, T)>(::operator*),
|
||||
sol::resolve<quat<T>(const quat<T>&, const quat<T>&)>(::operator*)),
|
||||
|
||||
"make_from_axis_angle", [](T angle, const vec3<T>& xyz) -> quat<T> {
|
||||
return math::make_quat_from_axis_angle(make_rad(angle), xyz);
|
||||
},
|
||||
|
||||
"make_from_euler_angles", [](T roll, T pitch, T yaw) -> quat<T> {
|
||||
return math::make_quat_from_euler_angles(make_rad(roll), make_rad(pitch), make_rad(yaw));
|
||||
},
|
||||
|
||||
"approximately", [](const quat<T>& l, const quat<T>& r){ return math::approximately(l,r); },
|
||||
|
||||
"dot", sol::resolve<T(const quat<T>&, const quat<T>&)>(&math::dot),
|
||||
"abs_dot", sol::resolve<T(const quat<T>&, const quat<T>&)>(&math::abs_dot),
|
||||
|
||||
"length_squared", sol::resolve<T(const quat<T>&)>(&math::length_squared),
|
||||
"length", sol::resolve<T(const quat<T>&)>(&math::length),
|
||||
|
||||
"normalized", [](const quat<T>& v){ return math::normalized(v); },
|
||||
|
||||
"lerp", sol::resolve<quat<T>(const quat<T>&, const quat<T>&, T)>(&math::lerp),
|
||||
|
||||
"inversed", [](const quat<T>& v){ return math::inversed(v); },
|
||||
"conjugated", [](const quat<T>& v){ return math::conjugated(v); },
|
||||
|
||||
"contains_nan", sol::resolve<bool(const quat<T>&)>(&math::contains_nan));
|
||||
}
|
||||
}
|
||||
|
||||
namespace e2d::bindings::math
|
||||
{
|
||||
void bind_quat(sol::state& l) {
|
||||
bind_quat_t<f32>("q4f", l);
|
||||
}
|
||||
}
|
||||
@@ -19,9 +19,7 @@ namespace
|
||||
"identity", &trs2<T>::identity,
|
||||
|
||||
"translation", &trs2<T>::translation,
|
||||
"rotation", sol::property(
|
||||
[](const trs2<T>& t){ return t.rotation.value; },
|
||||
[](trs2<T>& t, T v){ t.rotation.value = v; }),
|
||||
"rotation", &trs2<T>::rotation,
|
||||
"scale", &trs2<T>::scale,
|
||||
|
||||
sol::meta_function::to_string, [](const trs2<T>& v){
|
||||
@@ -34,8 +32,8 @@ namespace
|
||||
return math::make_translation_trs2(t);
|
||||
},
|
||||
|
||||
"make_rotation", [](T angle) -> trs2<T> {
|
||||
return math::make_rotation_trs2(make_rad(angle));
|
||||
"make_rotation", [](T r) -> trs2<T> {
|
||||
return math::make_rotation_trs2(r);
|
||||
},
|
||||
|
||||
"make_scale", [](const vec2<T>& s) -> trs2<T> {
|
||||
|
||||
@@ -32,8 +32,8 @@ namespace
|
||||
return math::make_translation_trs3(t);
|
||||
},
|
||||
|
||||
"make_rotation", [](const quat<T>& q) -> trs3<T> {
|
||||
return math::make_rotation_trs3(q);
|
||||
"make_rotation", [](const vec3<T>& r) -> trs3<T> {
|
||||
return math::make_rotation_trs3(r);
|
||||
},
|
||||
|
||||
"make_scale", [](const vec3<T>& s) -> trs3<T> {
|
||||
|
||||
@@ -55,8 +55,7 @@ namespace
|
||||
sol::resolve<vec3<T>(T, const vec3<T>&)>(::operator*),
|
||||
sol::resolve<vec3<T>(const vec3<T>&, T)>(::operator*),
|
||||
sol::resolve<vec3<T>(const vec3<T>&, const vec3<T>&)>(::operator*),
|
||||
sol::resolve<vec3<T>(const vec3<T>&, const mat3<T>&)>(::operator*),
|
||||
sol::resolve<vec3<T>(const vec3<T>&, const quat<T>&)>(::operator*)),
|
||||
sol::resolve<vec3<T>(const vec3<T>&, const mat3<T>&)>(::operator*)),
|
||||
|
||||
sol::meta_function::division, sol::overload(
|
||||
sol::resolve<vec3<T>(T, const vec3<T>&)>(::operator/),
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace e2d
|
||||
}
|
||||
|
||||
if ( ctx.root.HasMember("rotation") ) {
|
||||
radf rotation = component.node()->rotation();
|
||||
f32 rotation = component.node()->rotation();
|
||||
if ( !json_utils::try_parse_value(ctx.root["rotation"], rotation) ) {
|
||||
the<debug>().error("ACTOR: Incorrect formatting of 'rotation' property");
|
||||
return false;
|
||||
|
||||
@@ -91,12 +91,12 @@ namespace e2d
|
||||
return transform_.translation;
|
||||
}
|
||||
|
||||
void node::rotation(const radf& rotation) noexcept {
|
||||
void node::rotation(f32 rotation) noexcept {
|
||||
transform_.rotation = rotation;
|
||||
mark_dirty_local_matrix_();
|
||||
}
|
||||
|
||||
const radf& node::rotation() const noexcept {
|
||||
f32 node::rotation() const noexcept {
|
||||
return transform_.rotation;
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace
|
||||
.add_system<label_system>())
|
||||
.feature<struct render_feature>(ecs::feature()
|
||||
.add_system<render_system>())
|
||||
.feature<struct sript_feature>(ecs::feature()
|
||||
.feature<struct script_feature>(ecs::feature()
|
||||
.add_system<script_system>())
|
||||
.feature<struct spine_feature>(ecs::feature()
|
||||
.add_system<spine_system>());
|
||||
|
||||
@@ -114,38 +114,6 @@ namespace
|
||||
"items" : { "type" : "number" }
|
||||
}]
|
||||
},
|
||||
"q4" : {
|
||||
"anyOf" : [{
|
||||
"type" : "number"
|
||||
}, {
|
||||
"type" : "object",
|
||||
"required" : [ "angle", "axis" ],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"angle" : { "type" : "number" },
|
||||
"axis" : { "$ref": "#/common_definitions/v3" }
|
||||
}
|
||||
}, {
|
||||
"type" : "object",
|
||||
"required" : [ "roll", "pitch", "yaw" ],
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"roll" : { "type" : "number" },
|
||||
"pitch" : { "type" : "number" },
|
||||
"yaw" : { "type" : "number" }
|
||||
}
|
||||
}, {
|
||||
"type" : "array",
|
||||
"minItems" : 3,
|
||||
"maxItems" : 3,
|
||||
"items" : { "type" : "number" }
|
||||
}, {
|
||||
"type" : "array",
|
||||
"minItems" : 4,
|
||||
"maxItems" : 4,
|
||||
"items" : { "type" : "number" }
|
||||
}]
|
||||
},
|
||||
"b2" : {
|
||||
"anyOf" : [{
|
||||
"type" : "array",
|
||||
@@ -206,7 +174,7 @@ namespace
|
||||
"additionalProperties" : false,
|
||||
"properties" : {
|
||||
"translation" : { "$ref": "#/common_definitions/v3" },
|
||||
"rotation" : { "$ref": "#/common_definitions/q4" },
|
||||
"rotation" : { "$ref": "#/common_definitions/v3" },
|
||||
"scale" : { "$ref": "#/common_definitions/v3" }
|
||||
}
|
||||
},
|
||||
@@ -367,80 +335,6 @@ namespace
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
// quat
|
||||
//
|
||||
|
||||
template < typename V, typename FV >
|
||||
bool parse_q4(const rapidjson::Value& root, V& v, FV&& f) noexcept {
|
||||
if ( root.IsNumber() ) {
|
||||
typename V::value_type tv;
|
||||
if ( f(root, tv) ) {
|
||||
v = math::make_quat_from_axis_angle(
|
||||
make_deg(tv),
|
||||
vec3<typename V::value_type>::unit_z());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( root.IsObject() ) {
|
||||
if ( root.HasMember("angle") && root.HasMember("axis") ) {
|
||||
typename V::value_type tangle;
|
||||
vec3<typename V::value_type> vaxis;
|
||||
if ( f(root["angle"], tangle) && parse_vN<3>(root["axis"], vaxis, f) ) {
|
||||
v = math::make_quat_from_axis_angle(
|
||||
make_deg(tangle),
|
||||
vaxis);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( root.HasMember("roll") && root.HasMember("pitch") && root.HasMember("yaw") ) {
|
||||
typename V::value_type troll, tpitch, tyaw;
|
||||
if ( f(root["roll"], troll) && f(root["pitch"], tpitch) && f(root["yaw"], tyaw) ) {
|
||||
v = math::make_quat_from_euler_angles(
|
||||
make_deg(troll),
|
||||
make_deg(tpitch),
|
||||
make_deg(tyaw));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( root.IsArray() ) {
|
||||
if ( root.Size() == 3 ) {
|
||||
vec3<typename V::value_type> veuler;
|
||||
if ( parse_vN<3>(root, veuler, f) ) {
|
||||
v = math::make_quat_from_euler_angles(
|
||||
make_deg(veuler.x),
|
||||
make_deg(veuler.y),
|
||||
make_deg(veuler.z));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( root.Size() == 4 ) {
|
||||
vec4<typename V::value_type> vq;
|
||||
if ( parse_vN<4>(root, vq, f) ) {
|
||||
v = V(vq);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool parse_q4f(const rapidjson::Value& root, q4f& v) noexcept {
|
||||
return parse_q4(root, v, [](const rapidjson::Value& jv, f32& o){
|
||||
if ( !jv.IsNumber() ) {
|
||||
return false;
|
||||
}
|
||||
o = jv.GetFloat();
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
// rect
|
||||
//
|
||||
@@ -787,15 +681,6 @@ namespace e2d::json_utils
|
||||
return true;
|
||||
}
|
||||
|
||||
bool try_parse_value(const rapidjson::Value& root, q4f& v) noexcept {
|
||||
q4f tv;
|
||||
if ( !parse_q4f(root, tv) ) {
|
||||
return false;
|
||||
}
|
||||
v = tv;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool try_parse_value(const rapidjson::Value& root, b2i& b) noexcept {
|
||||
b2i tb;
|
||||
if ( !parse_b2i(root, tb) ) {
|
||||
|
||||
@@ -52,15 +52,6 @@ TEST_CASE("luasol") {
|
||||
REQUIRE(r2 == v4f(6));
|
||||
}
|
||||
|
||||
SECTION("quat") {
|
||||
v3f r0 = l.with_state([](sol::state& lua){
|
||||
return lua.script(R"lua(
|
||||
return v3f.new(1,2,3) * q4f.make_from_axis_angle(10, v3f.new(1,2,3))
|
||||
)lua");
|
||||
});
|
||||
REQUIRE(r0 == v3f(1,2,3) * math::make_quat_from_axis_angle(radf(10.f), v3f(1,2,3)));
|
||||
}
|
||||
|
||||
SECTION("mat2/mat2/mat3") {
|
||||
std::pair<m2f, bool> r0 = l.with_state([](sol::state& lua){
|
||||
return lua.script(R"lua(
|
||||
|
||||
@@ -657,14 +657,14 @@ TEST_CASE("node") {
|
||||
|
||||
REQUIRE(p->transform() == t2f::identity());
|
||||
REQUIRE(p->translation() == v2f::zero());
|
||||
REQUIRE(p->rotation() == radf::zero());
|
||||
REQUIRE(math::approximately(p->rotation(), 0.f));
|
||||
REQUIRE(p->scale() == v2f::unit());
|
||||
|
||||
p->translation(v2f(1,2));
|
||||
REQUIRE(p->translation() == v2f(1,2));
|
||||
|
||||
p->rotation(radf(1.f));
|
||||
REQUIRE(p->rotation() == radf(1.f));
|
||||
p->rotation(1.f);
|
||||
REQUIRE(math::approximately(p->rotation(), 1.f));
|
||||
|
||||
p->scale(v2f(1,2));
|
||||
REQUIRE(p->scale() == v2f(1,2));
|
||||
|
||||
@@ -30,7 +30,7 @@ TEST_CASE("mat3") {
|
||||
REQUIRE(math::make_scale_matrix3(v2i(1,1),1) == math::make_scale_matrix3(v3i::unit()));
|
||||
|
||||
REQUIRE(math::make_rotation_matrix3(make_rad(1.f),1.f,1.f,1.f) == math::make_rotation_matrix3(make_rad(1.f), v3f::unit()));
|
||||
REQUIRE(math::make_rotation_matrix3(make_rad(1.f),v2f(1.f,1.f),1.f) == math::make_rotation_matrix3(make_rad(1.f), v3f::unit()));
|
||||
REQUIRE(math::make_rotation_matrix3(make_rad(1.f),v3f(1.f,1.f,1.f)) == math::make_rotation_matrix3(make_rad(1.f), v3f::unit()));
|
||||
}
|
||||
{
|
||||
REQUIRE(m3f(m3f::identity()) == m3f::identity());
|
||||
|
||||
@@ -33,7 +33,7 @@ TEST_CASE("mat4") {
|
||||
REQUIRE(math::make_translation_matrix4(v2i(1,1),1) == math::make_translation_matrix4(v3i::unit()));
|
||||
|
||||
REQUIRE(math::make_rotation_matrix4(make_rad(1.f),1.f,1.f,1.f) == math::make_rotation_matrix4(make_rad(1.f), v3f::unit()));
|
||||
REQUIRE(math::make_rotation_matrix4(make_rad(1.f),v2f(1.f,1.f),1.f) == math::make_rotation_matrix4(make_rad(1.f), v3f::unit()));
|
||||
REQUIRE(math::make_rotation_matrix4(make_rad(1.f),v3f(1.f,1.f,1.f)) == math::make_rotation_matrix4(make_rad(1.f), v3f::unit()));
|
||||
|
||||
REQUIRE(math::make_orthogonal_lh_matrix4(640.f, 480.f, 0.f, 1.f) == math::make_orthogonal_lh_matrix4(v2f(640,480), 0.f, 1.f));
|
||||
REQUIRE(math::make_orthogonal_lh_matrix4(640.0, 480.0, 0.0, 1.0) == math::make_orthogonal_lh_matrix4(v2d(640,480), 0.0, 1.0));
|
||||
@@ -137,10 +137,8 @@ TEST_CASE("mat4") {
|
||||
REQUIRE(math::make_trs_matrix4(math::make_translation_trs3(v3f(1.f,2.f,3.f)))
|
||||
== math::make_translation_matrix4(1.f,2.f,3.f));
|
||||
|
||||
REQUIRE(math::make_trs_matrix4(math::make_rotation_trs2(make_rad(3.f)))
|
||||
== math::make_rotation_matrix4(make_rad(3.f), v4f::unit_z()));
|
||||
REQUIRE(math::make_trs_matrix4(math::make_rotation_trs3(q4f(1,2,3,4)))
|
||||
== math::make_rotation_matrix4(q4f(1,2,3,4)));
|
||||
REQUIRE(math::make_trs_matrix4(math::make_rotation_trs2(3.f))
|
||||
== math::make_rotation_matrix4(make_rad(3.f), v3f::unit_z()));
|
||||
|
||||
REQUIRE(math::make_trs_matrix4(math::make_scale_trs2(v2f(1.f,2.f)))
|
||||
== math::make_scale_matrix4(1.f,2.f));
|
||||
@@ -152,7 +150,7 @@ TEST_CASE("mat4") {
|
||||
math::make_translation_matrix4(30.f, 40.f, 50.f);
|
||||
REQUIRE(m0 == math::make_trs_matrix4(make_trs3(
|
||||
v3f(30.f, 40.f, 50.f),
|
||||
math::make_quat_from_axis_angle(make_rad(1.f), v3f::unit_z()),
|
||||
v3f::unit_z(),
|
||||
v3f(2.f,4.f,5.f))));
|
||||
}
|
||||
{
|
||||
|
||||
@@ -1,185 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018-2019, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#include "_math.hpp"
|
||||
using namespace e2d;
|
||||
|
||||
#include <random>
|
||||
|
||||
TEST_CASE("quat") {
|
||||
{
|
||||
REQUIRE(q4f() == q4f{0,0,0,1});
|
||||
REQUIRE(q4f::zero() == q4f{0,0,0,0});
|
||||
REQUIRE(q4f::identity() == q4f{0,0,0,1});
|
||||
REQUIRE(q4i(1,2,3,4).x == 1);
|
||||
REQUIRE(q4i(1,2,3,4).y == 2);
|
||||
REQUIRE(q4i(1,2,3,4).z == 3);
|
||||
REQUIRE(q4i(1,2,3,4).w == 4);
|
||||
REQUIRE(q4i(v4i{1,2,3,4}) == q4i(1,2,3,4));
|
||||
}
|
||||
{
|
||||
auto q = q4i(1,2,3,4);
|
||||
REQUIRE(q[0] == 1);
|
||||
REQUIRE(q[1] == 2);
|
||||
REQUIRE(q[2] == 3);
|
||||
REQUIRE(q[3] == 4);
|
||||
REQUIRE(q.data()[0] == 1);
|
||||
REQUIRE(q.data()[1] == 2);
|
||||
REQUIRE(q.data()[2] == 3);
|
||||
REQUIRE(q.data()[3] == 4);
|
||||
|
||||
const auto qq = q;
|
||||
REQUIRE(qq[0] == 1);
|
||||
REQUIRE(qq[1] == 2);
|
||||
REQUIRE(qq[2] == 3);
|
||||
REQUIRE(qq[3] == 4);
|
||||
REQUIRE(qq.data()[0] == 1);
|
||||
REQUIRE(qq.data()[1] == 2);
|
||||
REQUIRE(qq.data()[2] == 3);
|
||||
REQUIRE(qq.data()[3] == 4);
|
||||
}
|
||||
{
|
||||
auto q = q4i(1,2,3,4);
|
||||
q += 2;
|
||||
REQUIRE(q == q4i{3,4,5,6});
|
||||
q *= 2;
|
||||
REQUIRE(q == q4i{6,8,10,12});
|
||||
q += q4i{1,2,3,4};
|
||||
REQUIRE(q == q4i{7,10,13,16});
|
||||
}
|
||||
{
|
||||
auto q = q4i(1,2,3,4);
|
||||
auto qu = q.cast_to<u32>();
|
||||
REQUIRE(qu == q4u{1,2,3,4});
|
||||
}
|
||||
{
|
||||
REQUIRE(make_quat(1,2,3,4) == q4i(1,2,3,4));
|
||||
REQUIRE(make_quat(v4i(1,2,3,4)) == q4i(1,2,3,4));
|
||||
}
|
||||
{
|
||||
REQUIRE(q4i(1,2,3,4) == q4i(1,2,3,4));
|
||||
REQUIRE_FALSE(q4i(1,2,3,4) != q4i(1,2,3,4));
|
||||
|
||||
REQUIRE_FALSE(q4i(1,2,3,4) == q4i(0,2,3,4));
|
||||
REQUIRE_FALSE(q4i(1,2,3,4) == q4i(1,3,3,4));
|
||||
REQUIRE_FALSE(q4i(1,2,3,4) == q4i(1,2,2,4));
|
||||
REQUIRE_FALSE(q4i(1,2,3,4) == q4i(1,2,3,5));
|
||||
|
||||
REQUIRE(q4i(1,2,3,4) != q4i(0,2,3,4));
|
||||
REQUIRE(q4i(1,2,3,4) != q4i(1,3,3,4));
|
||||
REQUIRE(q4i(1,2,3,4) != q4i(1,2,2,4));
|
||||
REQUIRE(q4i(1,2,3,4) != q4i(1,2,3,5));
|
||||
}
|
||||
{
|
||||
auto q1 = math::make_quat_from_axis_angle(make_rad(11.f), v3f::unit_z());
|
||||
auto q2 = math::make_quat_from_axis_angle(make_rad(12.f), v3f::unit_z());
|
||||
auto q3 = math::make_quat_from_axis_angle(make_rad(23.f), v3f::unit_z());
|
||||
REQUIRE(q1 * q2 == q3);
|
||||
}
|
||||
{
|
||||
{
|
||||
auto q1 = math::make_quat_from_euler_angles(make_rad(2.f), make_rad(0.f), make_rad(0.f));
|
||||
auto q2 = math::make_quat_from_euler_angles(make_rad(4.f), make_rad(0.f), make_rad(0.f));
|
||||
auto q3 = math::make_quat_from_euler_angles(make_rad(6.f), make_rad(0.f), make_rad(0.f));
|
||||
REQUIRE(q1 * q2 == q3);
|
||||
}
|
||||
{
|
||||
auto q1 = math::make_quat_from_euler_angles(make_rad(0.f), make_rad(3.f), make_rad(0.f));
|
||||
auto q2 = math::make_quat_from_euler_angles(make_rad(0.f), make_rad(4.f), make_rad(0.f));
|
||||
auto q3 = math::make_quat_from_euler_angles(make_rad(0.f), make_rad(7.f), make_rad(0.f));
|
||||
REQUIRE(q1 * q2 == q3);
|
||||
}
|
||||
{
|
||||
auto q1 = math::make_quat_from_euler_angles(make_rad(0.f), make_rad(0.f), make_rad(1.f));
|
||||
auto q2 = math::make_quat_from_euler_angles(make_rad(0.f), make_rad(0.f), make_rad(5.f));
|
||||
auto q3 = math::make_quat_from_euler_angles(make_rad(0.f), make_rad(0.f), make_rad(6.f));
|
||||
REQUIRE(q1 * q2 == q3);
|
||||
}
|
||||
}
|
||||
{
|
||||
{
|
||||
auto q = math::make_quat_from_euler_angles(make_rad(0.f), make_rad(0.f), make_deg(90.f));
|
||||
auto qq = math::make_quat_from_euler_angles(make_rad(0.f), make_rad(0.f), make_deg(-90.f));
|
||||
REQUIRE(v3f(1,1,0) * q == v3f(-1,1,0));
|
||||
REQUIRE(v3f(1,1,0) * qq == v3f(1,-1,0));
|
||||
}
|
||||
{
|
||||
auto q = math::make_quat_from_euler_angles(make_rad(0.f), make_deg(90.f), make_deg(0.f));
|
||||
auto qq = math::make_quat_from_euler_angles(make_rad(0.f), make_deg(-90.f), make_deg(0.f));
|
||||
REQUIRE(v3f(1,1,0) * q == v3f(0,1,-1));
|
||||
REQUIRE(v3f(1,1,0) * qq == v3f(0,1,1));
|
||||
}
|
||||
{
|
||||
auto q = math::make_quat_from_euler_angles(make_deg(90.f), make_deg(0.f), make_deg(0.f));
|
||||
auto qq = math::make_quat_from_euler_angles(make_deg(-90.f), make_deg(0.f), make_deg(0.f));
|
||||
REQUIRE(v3f(1,1,0) * q == v3f(1,0,1));
|
||||
REQUIRE(v3f(1,1,0) * qq == v3f(1,0,-1));
|
||||
}
|
||||
}
|
||||
{
|
||||
const auto q1 = math::make_quat_from_euler_angles(make_rad(2.f), make_rad(0.f), make_rad(0.f));
|
||||
const auto q2 = math::make_quat_from_euler_angles(make_rad(4.f), make_rad(0.f), make_rad(0.f));
|
||||
REQUIRE(math::lerp(q1, q2, 0.0f) == q1);
|
||||
REQUIRE(math::lerp(q1, q2, 1.0f) == q2);
|
||||
}
|
||||
{
|
||||
std::random_device rd;
|
||||
std::mt19937 gen(rd());
|
||||
std::uniform_real_distribution<f32> dis(-1000.f, 1000.f);
|
||||
for ( std::size_t i = 0; i < 1000; ++i ) {
|
||||
const auto q = math::make_quat_from_euler_angles(
|
||||
make_rad(dis(gen)),
|
||||
make_rad(dis(gen)),
|
||||
make_rad(dis(gen)));
|
||||
const auto v = v3f(dis(gen), dis(gen), dis(gen));
|
||||
const auto v1 = v * q;
|
||||
const auto v2 = v * math::make_rotation_matrix3(q);
|
||||
const auto v3 = v4f(v, 1.f) * math::make_rotation_matrix4(q);
|
||||
REQUIRE(math::approximately(v1, v2, 0.001f));
|
||||
REQUIRE(math::approximately(v2, v3f(v3), 0.001f));
|
||||
}
|
||||
}
|
||||
{
|
||||
std::random_device rd;
|
||||
std::mt19937 gen(rd());
|
||||
std::uniform_real_distribution<f32> dis(-1000.f, 1000.f);
|
||||
for ( std::size_t i = 0; i < 1000; ++i ) {
|
||||
const auto angle = make_rad(dis(gen));
|
||||
const auto axis = math::normalized(make_vec3(dis(gen), dis(gen), dis(gen)));
|
||||
const auto q = math::make_quat_from_axis_angle(angle, axis);
|
||||
|
||||
const auto v = v3f(dis(gen), dis(gen), dis(gen));
|
||||
const auto v1 = v * q;
|
||||
const auto v2 = v * math::make_rotation_matrix3(q);
|
||||
const auto v3 = v4f(v, 1.f) * math::make_rotation_matrix4(q);
|
||||
|
||||
REQUIRE(math::approximately(v1, v2, 0.001f));
|
||||
REQUIRE(math::approximately(v2, v3f(v3), 0.001f));
|
||||
}
|
||||
}
|
||||
{
|
||||
std::random_device rd;
|
||||
std::mt19937 gen(rd());
|
||||
std::uniform_real_distribution<f32> dis(-1000.f, 1000.f);
|
||||
for ( std::size_t i = 0; i < 1000; ++i ) {
|
||||
const auto angle = make_rad(dis(gen));
|
||||
const auto axis = math::normalized(make_vec3(dis(gen), dis(gen), dis(gen)));
|
||||
|
||||
const auto q = math::make_quat_from_axis_angle(angle, axis);
|
||||
const auto m1 = math::make_rotation_matrix3(angle, axis);
|
||||
const auto m2 = math::make_rotation_matrix4(q);
|
||||
|
||||
const auto v = make_vec3(dis(gen), dis(gen), dis(gen));
|
||||
|
||||
const auto v1 = v * q;
|
||||
const auto v2 = v * m1;
|
||||
const auto v3 = v4f(v, 1.f) * m2;
|
||||
|
||||
REQUIRE(math::approximately(v1, v2, 0.001f));
|
||||
REQUIRE(math::approximately(v2, v3f(v3), 0.001f));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,11 +10,11 @@ using namespace e2d;
|
||||
TEST_CASE("trs2") {
|
||||
{
|
||||
REQUIRE(t2i::zero().translation == v2i(0));
|
||||
REQUIRE(t2i::zero().rotation == make_rad(0));
|
||||
REQUIRE(t2i::zero().rotation == 0);
|
||||
REQUIRE(t2i::zero().scale == v2i(0));
|
||||
|
||||
REQUIRE(t2i::identity().translation == v2i(0));
|
||||
REQUIRE(t2i::identity().rotation == make_rad(0));
|
||||
REQUIRE(t2i::identity().rotation == 0);
|
||||
REQUIRE(t2i::identity().scale == v2i(1));
|
||||
}
|
||||
{
|
||||
@@ -28,7 +28,7 @@ TEST_CASE("trs2") {
|
||||
i32, decltype(std::declval<t2i>().translation.x)
|
||||
>::value, "static unit test error");
|
||||
static_assert(std::is_same<
|
||||
i32, decltype(std::declval<t2i>().rotation.value)
|
||||
i32, decltype(std::declval<t2i>().rotation)
|
||||
>::value, "static unit test error");
|
||||
static_assert(std::is_same<
|
||||
i32, decltype(std::declval<t2i>().scale.x)
|
||||
@@ -44,7 +44,7 @@ TEST_CASE("trs2") {
|
||||
f32, decltype(std::declval<t2f>().translation.x)
|
||||
>::value, "static unit test error");
|
||||
static_assert(std::is_same<
|
||||
f32, decltype(std::declval<t2f>().rotation.value)
|
||||
f32, decltype(std::declval<t2f>().rotation)
|
||||
>::value, "static unit test error");
|
||||
static_assert(std::is_same<
|
||||
f32, decltype(std::declval<t2f>().scale.x)
|
||||
@@ -52,19 +52,19 @@ TEST_CASE("trs2") {
|
||||
}
|
||||
{
|
||||
auto t0 = t2f();
|
||||
auto t1 = t2f(v2f(1.f,2.f), make_rad(3.f), v2f(4.f,5.f));
|
||||
auto t2 = t2f(v2f(1.f,2.f), math::to_deg(make_rad(3.f)), v2f(4.f,5.f));
|
||||
auto t1 = t2f(v2f(1.f,2.f), 3.f, v2f(4.f,5.f));
|
||||
auto t2 = t1;
|
||||
|
||||
REQUIRE(t0.translation == v2f(0.f));
|
||||
REQUIRE(t0.rotation == make_rad(0.f));
|
||||
REQUIRE(math::approximately(t0.rotation, 0.f));
|
||||
REQUIRE(t0.scale == v2f(1.f));
|
||||
|
||||
REQUIRE(t1.translation == v2f(1.f,2.f));
|
||||
REQUIRE(t1.rotation == make_rad(3.f));
|
||||
REQUIRE(math::approximately(t1.rotation, 3.f));
|
||||
REQUIRE(t1.scale == v2f(4.f,5.f));
|
||||
|
||||
REQUIRE(t2.translation == v2f(1.f,2.f));
|
||||
REQUIRE(math::approximately(t2.rotation, make_rad(3.f)));
|
||||
REQUIRE(math::approximately(t2.rotation, 3.f));
|
||||
REQUIRE(t2.scale == v2f(4.f,5.f));
|
||||
|
||||
REQUIRE(t0 == t2f::identity());
|
||||
@@ -75,28 +75,28 @@ TEST_CASE("trs2") {
|
||||
REQUIRE(t0 != t1);
|
||||
}
|
||||
{
|
||||
auto t1 = make_trs2(v2f(1.f,2.f), make_rad(3.f), v2f(4.f,5.f));
|
||||
auto t1 = make_trs2(v2f(1.f,2.f), 3.f, v2f(4.f,5.f));
|
||||
auto t2 = t1.cast_to<i32>();
|
||||
REQUIRE(t2.translation == v2i(1,2));
|
||||
REQUIRE(t2.rotation == make_rad(3));
|
||||
REQUIRE(t2.rotation == 3);
|
||||
REQUIRE(t2.scale == v2i(4,5));
|
||||
}
|
||||
{
|
||||
auto t1 = math::make_translation_trs2(v2f(3.f,4.f));
|
||||
REQUIRE(t1.translation == v2f(3.f,4.f));
|
||||
REQUIRE(t1.rotation == make_rad(0.f));
|
||||
REQUIRE(math::approximately(t1.rotation, 0.f));
|
||||
REQUIRE(t1.scale == v2f::unit());
|
||||
}
|
||||
{
|
||||
auto t1 = math::make_rotation_trs2(make_deg(3.f));
|
||||
auto t1 = math::make_rotation_trs2(3.f);
|
||||
REQUIRE(t1.translation == v2f::zero());
|
||||
REQUIRE(t1.rotation == math::to_rad(make_deg(3.f)));
|
||||
REQUIRE(math::approximately(t1.rotation, 3.f));
|
||||
REQUIRE(t1.scale == v2f::unit());
|
||||
}
|
||||
{
|
||||
auto t1 = math::make_scale_trs2(v2f(3.f,4.f));
|
||||
REQUIRE(t1.translation == v2f::zero());
|
||||
REQUIRE(t1.rotation == make_rad(0.f));
|
||||
REQUIRE(math::approximately(t1.rotation, 0.f));
|
||||
REQUIRE(t1.scale == make_vec2(3.f,4.f));
|
||||
}
|
||||
{
|
||||
|
||||
@@ -10,11 +10,11 @@ using namespace e2d;
|
||||
TEST_CASE("trs3") {
|
||||
{
|
||||
REQUIRE(t3i::zero().translation == v3i(0));
|
||||
REQUIRE(t3i::zero().rotation == q4i::zero());
|
||||
REQUIRE(t3i::zero().rotation == v3i::zero());
|
||||
REQUIRE(t3i::zero().scale == v3i(0));
|
||||
|
||||
REQUIRE(t3i::identity().translation == v3i(0));
|
||||
REQUIRE(t3i::identity().rotation == q4i::identity());
|
||||
REQUIRE(t3i::identity().rotation == v3i(0));
|
||||
REQUIRE(t3i::identity().scale == v3i(1));
|
||||
}
|
||||
{
|
||||
@@ -54,15 +54,15 @@ TEST_CASE("trs3") {
|
||||
auto t0 = t3f();
|
||||
auto t1 = t3f(
|
||||
v3f(1.f,2.f,3.f),
|
||||
make_quat(2.f,3.f,4.f,5.f),
|
||||
v3f(2.f,3.f,4.f),
|
||||
v3f(4.f,5.f,6.f));
|
||||
|
||||
REQUIRE(t0.translation == v3f(0.f));
|
||||
REQUIRE(t0.rotation == q4f::identity());
|
||||
REQUIRE(t0.rotation == v3f(0.f));
|
||||
REQUIRE(t0.scale == v3f(1.f));
|
||||
|
||||
REQUIRE(t1.translation == v3f(1.f,2.f,3.f));
|
||||
REQUIRE(t1.rotation == make_quat(2.f,3.f,4.f,5.f));
|
||||
REQUIRE(t1.rotation == v3f(2.f,3.f,4.f));
|
||||
REQUIRE(t1.scale == v3f(4.f,5.f,6.f));
|
||||
|
||||
REQUIRE(t0 == t3f::identity());
|
||||
@@ -73,29 +73,29 @@ TEST_CASE("trs3") {
|
||||
{
|
||||
auto t1 = make_trs3(
|
||||
v3f(1.f,2.f,3.f),
|
||||
make_quat(2.f,3.f,4.f,5.f),
|
||||
v3f(2.f,3.f,4.f),
|
||||
v3f(4.f,5.f,6.f));
|
||||
auto t2 = t1.cast_to<i32>();
|
||||
REQUIRE(t2.translation == v3i(1,2,3));
|
||||
REQUIRE(t2.rotation == make_quat(2,3,4,5));
|
||||
REQUIRE(t2.rotation == v3i(2,3,4));
|
||||
REQUIRE(t2.scale == v3i(4,5,6));
|
||||
}
|
||||
{
|
||||
auto t1 = math::make_translation_trs3(v3f(3.f,4.f,5.f));
|
||||
REQUIRE(t1.translation == v3f(3.f,4.f,5.f));
|
||||
REQUIRE(t1.rotation == q4f::identity());
|
||||
REQUIRE(t1.rotation == v3f::zero());
|
||||
REQUIRE(t1.scale == v3f::unit());
|
||||
}
|
||||
{
|
||||
auto t1 = math::make_rotation_trs3(make_quat(2,3,4,5));
|
||||
auto t1 = math::make_rotation_trs3(make_vec3(2,3,4));
|
||||
REQUIRE(t1.translation == v3i::zero());
|
||||
REQUIRE(t1.rotation == make_quat(2,3,4,5));
|
||||
REQUIRE(t1.rotation == make_vec3(2,3,4));
|
||||
REQUIRE(t1.scale == v3i::unit());
|
||||
}
|
||||
{
|
||||
auto t1 = math::make_scale_trs3(v3f(3.f,4.f,5.f));
|
||||
REQUIRE(t1.translation == v3f::zero());
|
||||
REQUIRE(t1.rotation == q4f::identity());
|
||||
REQUIRE(t1.rotation == v3f::zero());
|
||||
REQUIRE(t1.scale == make_vec3(3.f,4.f,5.f));
|
||||
}
|
||||
{
|
||||
|
||||
@@ -36,18 +36,6 @@ namespace
|
||||
"m33_" : [1,2,3,3,4,5,5,6,7],
|
||||
"m44_" : [1,2,3,4,3,4,5,6,5,6,7,8,7,8,9,0],
|
||||
|
||||
"q0" : 42,
|
||||
"q1" : { "angle" : -42, "axis" : [1,2,3] },
|
||||
"q2" : { "roll" : 1, "pitch" : 2, "yaw" : 3 },
|
||||
"q3" : [1,2,3],
|
||||
"q4" : [1,2,3,4],
|
||||
"q5_" : "hello",
|
||||
"q6_" : { "angle" : -42 },
|
||||
"q7_" : { "axis" : [1,2,3] },
|
||||
"q8_" : { "angle" : -42, "axis" : "hello" },
|
||||
"q9_" : { "roll" : 1, "pitch" : 2 },
|
||||
"q10_" : { "roll" : 1, "pitch" : 2, "yaw" : {} },
|
||||
|
||||
"b2_0" : { "x" : 1, "w" : 2 },
|
||||
"b2_1" : { "x" : 1, "y" : 2, "w" : 3, "h" : 4 },
|
||||
"b2_2" : { "x" : 1, "y" : -2, "w" : 3, "h" : 4 },
|
||||
@@ -70,7 +58,7 @@ namespace
|
||||
|
||||
"t3" : {
|
||||
"translation" : [1,2,3],
|
||||
"rotation" : [4,5,6,7],
|
||||
"rotation" : [4,5,6],
|
||||
"scale" : [8,9,10]
|
||||
},
|
||||
|
||||
@@ -204,11 +192,11 @@ TEST_CASE("json_utils") {
|
||||
{
|
||||
t2f t2;
|
||||
REQUIRE(json_utils::try_parse_value(doc["t2"], t2));
|
||||
REQUIRE(t2 == make_trs2(v2f(1,2), radf(3), v2f(4,5)));
|
||||
REQUIRE(t2 == make_trs2(v2f(1,2), 3.f, v2f(4,5)));
|
||||
|
||||
t3f t3;
|
||||
REQUIRE(json_utils::try_parse_value(doc["t3"], t3));
|
||||
REQUIRE(t3 == make_trs3(v3f(1,2,3), q4f(4,5,6,7), v3f(8,9,10)));
|
||||
REQUIRE(t3 == make_trs3(v3f(1,2,3), v3f(4,5,6), v3f(8,9,10)));
|
||||
}
|
||||
{
|
||||
color c0, c1, c2;
|
||||
@@ -298,25 +286,6 @@ TEST_CASE("json_utils") {
|
||||
REQUIRE_FALSE(json_utils::try_parse_value(doc["m33_"], m1));
|
||||
REQUIRE(m0 == m1);
|
||||
}
|
||||
{
|
||||
q4f q0, q1, q2, q3, q4, qe;
|
||||
REQUIRE(json_utils::try_parse_value(doc["q0"], q0));
|
||||
REQUIRE(json_utils::try_parse_value(doc["q1"], q1));
|
||||
REQUIRE(json_utils::try_parse_value(doc["q2"], q2));
|
||||
REQUIRE(json_utils::try_parse_value(doc["q3"], q3));
|
||||
REQUIRE(json_utils::try_parse_value(doc["q4"], q4));
|
||||
REQUIRE_FALSE(json_utils::try_parse_value(doc["q5_"], qe));
|
||||
REQUIRE_FALSE(json_utils::try_parse_value(doc["q6_"], qe));
|
||||
REQUIRE_FALSE(json_utils::try_parse_value(doc["q7_"], qe));
|
||||
REQUIRE_FALSE(json_utils::try_parse_value(doc["q8_"], qe));
|
||||
REQUIRE_FALSE(json_utils::try_parse_value(doc["q9_"], qe));
|
||||
REQUIRE_FALSE(json_utils::try_parse_value(doc["q10_"], qe));
|
||||
REQUIRE(q0 == math::make_quat_from_axis_angle(make_deg(42.f), v3f::unit_z()));
|
||||
REQUIRE(q1 == math::make_quat_from_axis_angle(make_deg(-42.f), v3f(1.f,2.f,3.f)));
|
||||
REQUIRE(q2 == math::make_quat_from_euler_angles(make_deg(1.f), make_deg(2.f), make_deg(3.f)));
|
||||
REQUIRE(q3 == math::make_quat_from_euler_angles(make_deg(1.f), make_deg(2.f), make_deg(3.f)));
|
||||
REQUIRE(q4 == q4f(1.f,2.f,3.f,4.f));
|
||||
}
|
||||
{
|
||||
v2f v0;
|
||||
REQUIRE(json_utils::try_parse_value(doc["v0"], v0));
|
||||
|
||||
@@ -157,15 +157,11 @@ TEST_CASE("strfmts") {
|
||||
}
|
||||
{
|
||||
REQUIRE(strings::rformat("%0", make_rect(1,2,3,4)) == "(1,2,3,4)");
|
||||
REQUIRE(strings::rformat("%0", make_quat(1,2,3,4)) == "(1,2,3,4)");
|
||||
REQUIRE(strings::rformat("%0", make_aabb(1,2,3,4,5,6)) == "(1,2,3,4,5,6)");
|
||||
|
||||
REQUIRE(strings::rformat(
|
||||
"%0",
|
||||
strings::make_format_arg(make_rect(1.f,2.f,3.f,4.f), u8(5), u8(2))) == "( 1.00, 2.00, 3.00, 4.00)");
|
||||
REQUIRE(strings::rformat(
|
||||
"%0",
|
||||
strings::make_format_arg(make_quat(1.f,2.f,3.f,4.f), u8(5), u8(2))) == "( 1.00, 2.00, 3.00, 4.00)");
|
||||
REQUIRE(strings::rformat(
|
||||
"%0",
|
||||
strings::make_format_arg(make_aabb(1.f,2.f,3.f,4.f,5.f,6.f), u8(5), u8(2))) == "( 1.00, 2.00, 3.00, 4.00, 5.00, 6.00)");
|
||||
|
||||
Reference in New Issue
Block a user