mirror of
https://github.com/BlackMATov/vmath.hpp.git
synced 2025-12-15 12:39:47 +07:00
vector rotate functions
This commit is contained in:
@@ -6,10 +6,13 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "vmath_fwd.hpp"
|
||||
|
||||
#include "vmath_fun.hpp"
|
||||
#include "vmath_ext.hpp"
|
||||
|
||||
#include "vmath_mat.hpp"
|
||||
#include "vmath_mat_fun.hpp"
|
||||
#include "vmath_mat_ext.hpp"
|
||||
|
||||
#include "vmath_vec.hpp"
|
||||
#include "vmath_vec_fun.hpp"
|
||||
#include "vmath_vec_ext.hpp"
|
||||
|
||||
@@ -9,6 +9,51 @@
|
||||
#include "vmath_fwd.hpp"
|
||||
|
||||
#include "vmath_fun.hpp"
|
||||
#include "vmath_vec_fun.hpp"
|
||||
#include "vmath_mat_fun.hpp"
|
||||
|
||||
//
|
||||
// Units
|
||||
//
|
||||
|
||||
namespace vmath_hpp
|
||||
{
|
||||
template < typename T > inline constexpr vec<T, 2> zero2{0, 0};
|
||||
template < typename T > inline constexpr vec<T, 3> zero3{0, 0, 0};
|
||||
template < typename T > inline constexpr vec<T, 4> zero4{0, 0, 0, 0};
|
||||
|
||||
template < typename T > inline constexpr vec<T, 2> unit2{1, 1};
|
||||
template < typename T > inline constexpr vec<T, 3> unit3{1, 1, 1};
|
||||
template < typename T > inline constexpr vec<T, 4> unit4{1, 1, 1, 1};
|
||||
|
||||
template < typename T > inline constexpr vec<T, 2> unit2_x{1, 0};
|
||||
template < typename T > inline constexpr vec<T, 2> unit2_y{0, 1};
|
||||
|
||||
template < typename T > inline constexpr vec<T, 3> unit3_x{1, 0, 0};
|
||||
template < typename T > inline constexpr vec<T, 3> unit3_y{0, 1, 0};
|
||||
template < typename T > inline constexpr vec<T, 3> unit3_z{0, 0, 1};
|
||||
|
||||
template < typename T > inline constexpr vec<T, 4> unit4_x{1, 0, 0, 0};
|
||||
template < typename T > inline constexpr vec<T, 4> unit4_y{0, 1, 0, 0};
|
||||
template < typename T > inline constexpr vec<T, 4> unit4_z{0, 0, 1, 0};
|
||||
template < typename T > inline constexpr vec<T, 4> unit4_w{0, 0, 0, 1};
|
||||
|
||||
template < typename T > inline constexpr mat<T, 2> zero2x2{0, 0, 0, 0};
|
||||
template < typename T > inline constexpr mat<T, 3> zero3x3{0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
template < typename T > inline constexpr mat<T, 4> zero4x4{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
template < typename T > inline constexpr mat<T, 2> unit2x2{1, 1, 1, 1};
|
||||
template < typename T > inline constexpr mat<T, 3> unit3x3{1, 1, 1, 1, 1, 1, 1, 1, 1};
|
||||
template < typename T > inline constexpr mat<T, 4> unit4x4{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
|
||||
|
||||
template < typename T > inline constexpr mat<T, 2> identity2x2{1, 0, 0, 1};
|
||||
template < typename T > inline constexpr mat<T, 3> identity3x3{1, 0, 0, 0, 1, 0, 0, 0, 1};
|
||||
template < typename T > inline constexpr mat<T, 4> identity4x4{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
|
||||
}
|
||||
|
||||
//
|
||||
// Hash
|
||||
//
|
||||
|
||||
namespace vmath_hpp::detail
|
||||
{
|
||||
@@ -18,12 +63,246 @@ namespace vmath_hpp::detail
|
||||
return (seed ^= std::hash<T>{}(x) + 0x9e3779b9 + (seed << 6) + ( seed >> 2));
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T, size_t Size >
|
||||
std::size_t hash(const vec<T, Size>& v) noexcept {
|
||||
return fold(hash_combiner{}, std::size_t{}, v);
|
||||
}
|
||||
|
||||
template < typename T, size_t Size >
|
||||
std::size_t hash(const mat<T, Size>& m) noexcept {
|
||||
return fold(hash_combiner{}, std::size_t{}, m);
|
||||
}
|
||||
}
|
||||
|
||||
namespace std
|
||||
{
|
||||
template < typename T, size_t Size >
|
||||
struct hash<vmath_hpp::vec<T, Size>> {
|
||||
size_t operator()(const vmath_hpp::vec<T, Size>& v) const noexcept {
|
||||
return vmath_hpp::detail::hash(v);
|
||||
}
|
||||
};
|
||||
|
||||
template < typename T, size_t Size >
|
||||
struct hash<vmath_hpp::mat<T, Size>> {
|
||||
size_t operator()(const vmath_hpp::mat<T, Size>& m) const noexcept {
|
||||
return vmath_hpp::detail::hash(m);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
//
|
||||
// Cast
|
||||
//
|
||||
|
||||
namespace vmath_hpp
|
||||
{
|
||||
template < typename To, typename From >
|
||||
constexpr To cast_to(From x) noexcept {
|
||||
return static_cast<To>(x);
|
||||
}
|
||||
|
||||
template < typename To, typename From, std::size_t Size >
|
||||
constexpr vec<To, Size> cast_to(const vec<From, Size>& v) {
|
||||
return detail::map([](From x){ return cast_to<To>(x); }, v);
|
||||
}
|
||||
|
||||
template < typename To, typename From, std::size_t Size >
|
||||
constexpr mat<To, Size> cast_to(const mat<From, Size>& m) {
|
||||
return detail::map([](const vec<From, Size>& v){ return cast_to<To>(v); }, m);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Access
|
||||
//
|
||||
|
||||
namespace vmath_hpp
|
||||
{
|
||||
// component
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
constexpr T component(const vec<T, Size>& v, std::size_t index) {
|
||||
return v[index];
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
constexpr vec<T, Size> component(vec<T, Size> v, std::size_t index, T x) {
|
||||
v[index] = x;
|
||||
return v;
|
||||
}
|
||||
|
||||
// row
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
constexpr vec<T, Size> row(const mat<T, Size>& m, std::size_t index) {
|
||||
return m.rows[index];
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
constexpr mat<T, Size> row(mat<T, Size> m, std::size_t index, const vec<T, Size>& v) {
|
||||
m.rows[index] = v;
|
||||
return m;
|
||||
}
|
||||
|
||||
// column
|
||||
|
||||
namespace impl
|
||||
{
|
||||
template < typename T, std::size_t Size, std::size_t... Is >
|
||||
constexpr vec<T, Size> column_impl(const mat<T, Size>& m, std::size_t index, std::index_sequence<Is...>) {
|
||||
return { m[Is][index]... };
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size, std::size_t... Is >
|
||||
constexpr mat<T, Size> column_impl(const mat<T, Size>& m, std::size_t index, const vec<T, Size>& v, std::index_sequence<Is...>) {
|
||||
return { component(m[Is], index, v[Is])... };
|
||||
}
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
constexpr vec<T, Size> column(const mat<T, Size>& m, std::size_t index) {
|
||||
return impl::column_impl(m, index, std::make_index_sequence<Size>{});
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
constexpr mat<T, Size> column(const mat<T, Size>& m, std::size_t index, const vec<T, Size>& v) {
|
||||
return impl::column_impl(m, index, v, std::make_index_sequence<Size>{});
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Matrix Transform
|
||||
//
|
||||
|
||||
namespace vmath_hpp
|
||||
{
|
||||
// translate
|
||||
|
||||
template < typename T >
|
||||
constexpr mat<T, 4> translate(T x, T y, T z) {
|
||||
return {
|
||||
{1, 0, 0, 0},
|
||||
{0, 1, 0, 0},
|
||||
{0, 0, 1, 0},
|
||||
{x, y, z, 1}};
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
constexpr mat<T, 4> translate(const vec<T, 3>& xyz) {
|
||||
return translate(xyz.x, xyz.y, xyz.z);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
constexpr mat<T, 4> translate(const mat<T, 4>& m, T x, T y, T z) {
|
||||
return m * translate(x, y, z);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
constexpr mat<T, 4> translate(const mat<T, 4>& m, const vec<T, 3>& xyz) {
|
||||
return m * translate(xyz);
|
||||
}
|
||||
|
||||
// rotate
|
||||
|
||||
template < typename T >
|
||||
mat<T, 4> rotate(T angle, T axis_x, T axis_y, T axis_z) {
|
||||
const T x = axis_x;
|
||||
const T y = axis_y;
|
||||
const T z = axis_z;
|
||||
const T px = x * x;
|
||||
const T py = y * y;
|
||||
const T pz = z * z;
|
||||
const T cs = cos(angle);
|
||||
const T sn = sin(angle);
|
||||
const T ics = T(1) - cs;
|
||||
const T xym = x * y * ics;
|
||||
const T xzm = x * z * ics;
|
||||
const T yzm = y * z * ics;
|
||||
const T xsn = x * sn;
|
||||
const T ysn = y * sn;
|
||||
const T zsn = z * sn;
|
||||
return {
|
||||
px * ics + cs, xym + zsn, xzm - ysn, 0,
|
||||
xym - zsn, py * ics + cs, yzm + xsn, 0,
|
||||
xzm + ysn, yzm - xsn, pz * ics + cs, 0,
|
||||
0, 0, 0, 1};
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
mat<T, 4> rotate(T angle, const vec<T, 3>& axis) {
|
||||
return rotate(angle, axis.x, axis.y, axis.z);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
mat<T, 4> rotate(const mat<T, 4>& m, T angle, T axis_x, T axis_y, T axis_z) {
|
||||
return m * rotate(angle, axis_x, axis_y, axis_z);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
mat<T, 4> rotate(const mat<T, 4>& m, T angle, const vec<T, 3>& axis) {
|
||||
return m * rotate(angle, axis);
|
||||
}
|
||||
|
||||
// scale
|
||||
|
||||
template < typename T >
|
||||
constexpr mat<T, 4> scale(T x, T y, T z) {
|
||||
return {
|
||||
{x, 0, 0, 0},
|
||||
{0, y, 0, 0},
|
||||
{0, 0, z, 0},
|
||||
{0, 0, 0, 1}};
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
constexpr mat<T, 4> scale(const vec<T, 3>& xyz) {
|
||||
return scale(xyz.x, xyz.y, xyz.z);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
constexpr mat<T, 4> scale(const mat<T, 4>& m, T x, T y, T z) {
|
||||
return m * scale(x, y, z);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
constexpr mat<T, 4> scale(const mat<T, 4>& m, const vec<T, 3>& xyz) {
|
||||
return m * scale(xyz);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Vector Transform
|
||||
//
|
||||
|
||||
namespace vmath_hpp
|
||||
{
|
||||
// angle
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
T angle(const vec<T, Size>& x, const vec<T, Size>& y) {
|
||||
return acos(dot(x, y) * invsqrt(length2(x) * length2(y)));
|
||||
}
|
||||
|
||||
// rotate
|
||||
|
||||
template < typename T >
|
||||
vec<T, 2> rotate(const vec<T, 2>& v, T angle) {
|
||||
const T cs = cos(angle);
|
||||
const T sn = sin(angle);
|
||||
return {
|
||||
v.x * cs - v.y * sn,
|
||||
v.x * sn + v.y * cs};
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
vec<T, 3> rotate(const vec<T, 3>& v, T angle, const vec<T, 3>& normal) {
|
||||
return v * mat<T, 3>(rotate(angle, normal));
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
vec<T, 4> rotate(const vec<T, 4>& v, T angle, const vec<T, 3>& normal) {
|
||||
return v * rotate(angle, normal);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,188 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "https://github.com/blackmatov/vmath.hpp"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2020, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "vmath_fwd.hpp"
|
||||
|
||||
#include "vmath_ext.hpp"
|
||||
#include "vmath_fun.hpp"
|
||||
|
||||
#include "vmath_vec.hpp"
|
||||
#include "vmath_vec_fun.hpp"
|
||||
#include "vmath_vec_ext.hpp"
|
||||
|
||||
#include "vmath_mat.hpp"
|
||||
#include "vmath_mat_fun.hpp"
|
||||
|
||||
namespace vmath_hpp
|
||||
{
|
||||
template < typename T > inline constexpr mat<T, 2> zero2x2{0, 0, 0, 0};
|
||||
template < typename T > inline constexpr mat<T, 3> zero3x3{0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
template < typename T > inline constexpr mat<T, 4> zero4x4{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
template < typename T > inline constexpr mat<T, 2> unit2x2{1, 1, 1, 1};
|
||||
template < typename T > inline constexpr mat<T, 3> unit3x3{1, 1, 1, 1, 1, 1, 1, 1, 1};
|
||||
template < typename T > inline constexpr mat<T, 4> unit4x4{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
|
||||
|
||||
template < typename T > inline constexpr mat<T, 2> identity2x2{1, 0, 0, 1};
|
||||
template < typename T > inline constexpr mat<T, 3> identity3x3{1, 0, 0, 0, 1, 0, 0, 0, 1};
|
||||
template < typename T > inline constexpr mat<T, 4> identity4x4{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
|
||||
}
|
||||
|
||||
namespace std
|
||||
{
|
||||
template < typename T, size_t Size >
|
||||
struct hash<vmath_hpp::mat<T, Size>> {
|
||||
size_t operator()(const vmath_hpp::mat<T, Size>& m) const noexcept {
|
||||
return vmath_hpp::detail::fold(vmath_hpp::detail::hash_combiner{}, size_t{}, m);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace vmath_hpp
|
||||
{
|
||||
// cast_to
|
||||
|
||||
template < typename To, typename From, std::size_t Size >
|
||||
constexpr mat<To, Size> cast_to(const mat<From, Size>& m) {
|
||||
return detail::map([](const vec<From, Size>& v){ return cast_to<To>(v); }, m);
|
||||
}
|
||||
|
||||
// row
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
constexpr vec<T, Size> row(const mat<T, Size>& m, std::size_t index) {
|
||||
return m.rows[index];
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
constexpr mat<T, Size> row(mat<T, Size> m, std::size_t index, const vec<T, Size>& v) {
|
||||
m.rows[index] = v;
|
||||
return m;
|
||||
}
|
||||
|
||||
// column
|
||||
|
||||
namespace impl
|
||||
{
|
||||
template < typename T, std::size_t Size, std::size_t... Is >
|
||||
constexpr vec<T, Size> column_impl(const mat<T, Size>& m, std::size_t index, std::index_sequence<Is...>) {
|
||||
return { m[Is][index]... };
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size, std::size_t... Is >
|
||||
constexpr mat<T, Size> column_impl(const mat<T, Size>& m, std::size_t index, const vec<T, Size>& v, std::index_sequence<Is...>) {
|
||||
return { component(m[Is], index, v[Is])... };
|
||||
}
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
constexpr vec<T, Size> column(const mat<T, Size>& m, std::size_t index) {
|
||||
return impl::column_impl(m, index, std::make_index_sequence<Size>{});
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
constexpr mat<T, Size> column(const mat<T, Size>& m, std::size_t index, const vec<T, Size>& v) {
|
||||
return impl::column_impl(m, index, v, std::make_index_sequence<Size>{});
|
||||
}
|
||||
}
|
||||
|
||||
namespace vmath_hpp
|
||||
{
|
||||
// translate
|
||||
|
||||
template < typename T >
|
||||
constexpr mat<T, 4> translate(T x, T y, T z) {
|
||||
return {
|
||||
{1, 0, 0, 0},
|
||||
{0, 1, 0, 0},
|
||||
{0, 0, 1, 0},
|
||||
{x, y, z, 1}};
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
constexpr mat<T, 4> translate(const vec<T, 3>& xyz) {
|
||||
return translate(xyz.x, xyz.y, xyz.z);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
constexpr mat<T, 4> translate(const mat<T, 4>& m, T x, T y, T z) {
|
||||
return m * translate(x, y, z);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
constexpr mat<T, 4> translate(const mat<T, 4>& m, const vec<T, 3>& xyz) {
|
||||
return m * translate(xyz);
|
||||
}
|
||||
|
||||
// rotate
|
||||
|
||||
template < typename T >
|
||||
mat<T, 4> rotate(T angle, T axis_x, T axis_y, T axis_z) {
|
||||
const T x = axis_x;
|
||||
const T y = axis_y;
|
||||
const T z = axis_z;
|
||||
const T px = x * x;
|
||||
const T py = y * y;
|
||||
const T pz = z * z;
|
||||
const T cs = cos(angle);
|
||||
const T sn = sin(angle);
|
||||
const T ics = T(1) - cs;
|
||||
const T xym = x * y * ics;
|
||||
const T xzm = x * z * ics;
|
||||
const T yzm = y * z * ics;
|
||||
const T xsn = x * sn;
|
||||
const T ysn = y * sn;
|
||||
const T zsn = z * sn;
|
||||
return {
|
||||
px * ics + cs, xym + zsn, xzm - ysn, 0,
|
||||
xym - zsn, py * ics + cs, yzm + xsn, 0,
|
||||
xzm + ysn, yzm - xsn, pz * ics + cs, 0,
|
||||
0, 0, 0, 1};
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
mat<T, 4> rotate(T angle, const vec<T, 3>& axis) {
|
||||
return rotate(angle, axis.x, axis.y, axis.z);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
mat<T, 4> rotate(const mat<T, 4>& m, T angle, T axis_x, T axis_y, T axis_z) {
|
||||
return m * rotate(angle, axis_x, axis_y, axis_z);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
mat<T, 4> rotate(const mat<T, 4>& m, T angle, const vec<T, 3>& axis) {
|
||||
return m * rotate(angle, axis);
|
||||
}
|
||||
|
||||
// scale
|
||||
|
||||
template < typename T >
|
||||
constexpr mat<T, 4> scale(T x, T y, T z) {
|
||||
return {
|
||||
{x, 0, 0, 0},
|
||||
{0, y, 0, 0},
|
||||
{0, 0, z, 0},
|
||||
{0, 0, 0, 1}};
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
constexpr mat<T, 4> scale(const vec<T, 3>& xyz) {
|
||||
return scale(xyz.x, xyz.y, xyz.z);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
constexpr mat<T, 4> scale(const mat<T, 4>& m, T x, T y, T z) {
|
||||
return m * scale(x, y, z);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
constexpr mat<T, 4> scale(const mat<T, 4>& m, const vec<T, 3>& xyz) {
|
||||
return m * scale(xyz);
|
||||
}
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "https://github.com/blackmatov/vmath.hpp"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2020, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "vmath_fwd.hpp"
|
||||
|
||||
#include "vmath_ext.hpp"
|
||||
#include "vmath_fun.hpp"
|
||||
|
||||
#include "vmath_vec.hpp"
|
||||
#include "vmath_vec_fun.hpp"
|
||||
|
||||
namespace vmath_hpp
|
||||
{
|
||||
template < typename T > inline constexpr vec<T, 2> zero2{0, 0};
|
||||
template < typename T > inline constexpr vec<T, 3> zero3{0, 0, 0};
|
||||
template < typename T > inline constexpr vec<T, 4> zero4{0, 0, 0, 0};
|
||||
|
||||
template < typename T > inline constexpr vec<T, 2> unit2{1, 1};
|
||||
template < typename T > inline constexpr vec<T, 3> unit3{1, 1, 1};
|
||||
template < typename T > inline constexpr vec<T, 4> unit4{1, 1, 1, 1};
|
||||
|
||||
template < typename T > inline constexpr vec<T, 2> unit2_x{1, 0};
|
||||
template < typename T > inline constexpr vec<T, 2> unit2_y{0, 1};
|
||||
|
||||
template < typename T > inline constexpr vec<T, 3> unit3_x{1, 0, 0};
|
||||
template < typename T > inline constexpr vec<T, 3> unit3_y{0, 1, 0};
|
||||
template < typename T > inline constexpr vec<T, 3> unit3_z{0, 0, 1};
|
||||
|
||||
template < typename T > inline constexpr vec<T, 4> unit4_x{1, 0, 0, 0};
|
||||
template < typename T > inline constexpr vec<T, 4> unit4_y{0, 1, 0, 0};
|
||||
template < typename T > inline constexpr vec<T, 4> unit4_z{0, 0, 1, 0};
|
||||
template < typename T > inline constexpr vec<T, 4> unit4_w{0, 0, 0, 1};
|
||||
}
|
||||
|
||||
namespace std
|
||||
{
|
||||
template < typename T, size_t Size >
|
||||
struct hash<vmath_hpp::vec<T, Size>> {
|
||||
size_t operator()(const vmath_hpp::vec<T, Size>& v) const noexcept {
|
||||
return vmath_hpp::detail::fold(vmath_hpp::detail::hash_combiner{}, size_t{}, v);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace vmath_hpp
|
||||
{
|
||||
// cast_to
|
||||
|
||||
template < typename To, typename From, std::size_t Size >
|
||||
constexpr vec<To, Size> cast_to(const vec<From, Size>& v) {
|
||||
return detail::map([](From x){ return cast_to<To>(x); }, v);
|
||||
}
|
||||
|
||||
// component
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
constexpr T component(const vec<T, Size>& v, std::size_t index) {
|
||||
return v[index];
|
||||
}
|
||||
|
||||
template < typename T, std::size_t Size >
|
||||
constexpr vec<T, Size> component(vec<T, Size> v, std::size_t index, T x) {
|
||||
v[index] = x;
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
namespace vmath_hpp
|
||||
{
|
||||
template < typename T, std::size_t Size >
|
||||
T angle(const vec<T, Size>& x, const vec<T, Size>& y) {
|
||||
return acos(dot(x, y) * invsqrt(length2(x) * length2(y)));
|
||||
}
|
||||
}
|
||||
@@ -18,9 +18,136 @@ namespace
|
||||
}
|
||||
|
||||
TEST_CASE("vmath/ext") {
|
||||
SECTION("units") {
|
||||
STATIC_REQUIRE(zero2<int> == int2(0,0));
|
||||
STATIC_REQUIRE(zero3<int> == int3(0,0,0));
|
||||
STATIC_REQUIRE(zero4<int> == int4(0,0,0,0));
|
||||
|
||||
STATIC_REQUIRE(unit2<int> == int2(1,1));
|
||||
STATIC_REQUIRE(unit2_x<int> == int2(1,0));
|
||||
STATIC_REQUIRE(unit2_y<int> == int2(0,1));
|
||||
|
||||
STATIC_REQUIRE(unit3<int> == int3(1,1,1));
|
||||
STATIC_REQUIRE(unit3_x<int> == int3(1,0,0));
|
||||
STATIC_REQUIRE(unit3_y<int> == int3(0,1,0));
|
||||
STATIC_REQUIRE(unit3_z<int> == int3(0,0,1));
|
||||
|
||||
STATIC_REQUIRE(unit4<int> == int4(1,1,1,1));
|
||||
STATIC_REQUIRE(unit4_x<int> == int4(1,0,0,0));
|
||||
STATIC_REQUIRE(unit4_y<int> == int4(0,1,0,0));
|
||||
STATIC_REQUIRE(unit4_z<int> == int4(0,0,1,0));
|
||||
STATIC_REQUIRE(unit4_w<int> == int4(0,0,0,1));
|
||||
|
||||
STATIC_REQUIRE(zero2x2<int> == int2x2(0,0,0,0));
|
||||
STATIC_REQUIRE(zero3x3<int> == int3x3(0,0,0,0,0,0,0,0,0));
|
||||
STATIC_REQUIRE(zero4x4<int> == int4x4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0));
|
||||
|
||||
STATIC_REQUIRE(unit2x2<int> == int2x2(1,1,1,1));
|
||||
STATIC_REQUIRE(unit3x3<int> == int3x3(1,1,1,1,1,1,1,1,1));
|
||||
STATIC_REQUIRE(unit4x4<int> == int4x4(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1));
|
||||
|
||||
STATIC_REQUIRE(identity2x2<int> == int2x2());
|
||||
STATIC_REQUIRE(identity3x3<int> == int3x3());
|
||||
STATIC_REQUIRE(identity4x4<int> == int4x4());
|
||||
}
|
||||
|
||||
SECTION("hash") {
|
||||
REQUIRE(std::hash<int2>{}({1,2}) == std::hash<int2>{}({1,2}));
|
||||
REQUIRE_FALSE(std::hash<int2>{}({1,2}) == std::hash<int2>{}({2,1}));
|
||||
|
||||
REQUIRE(std::hash<int3>{}({1,2,3}) == std::hash<int3>{}({1,2,3}));
|
||||
REQUIRE_FALSE(std::hash<int3>{}({1,2,3}) == std::hash<int3>{}({3,2,1}));
|
||||
|
||||
REQUIRE(std::hash<int4>{}({1,2,3,4}) == std::hash<int4>{}({1,2,3,4}));
|
||||
REQUIRE_FALSE(std::hash<int4>{}({1,2,3,4}) == std::hash<int4>{}({3,2,1,4}));
|
||||
|
||||
REQUIRE(std::hash<int2x2>{}({1,2,3,4}) == std::hash<int2x2>{}({1,2,3,4}));
|
||||
REQUIRE_FALSE(std::hash<int2x2>{}({1,2,3,4}) == std::hash<int2x2>{}({1,2,4,3}));
|
||||
}
|
||||
|
||||
SECTION("cast_to") {
|
||||
constexpr auto i = cast_to<int>(1.5f);
|
||||
STATIC_REQUIRE(i == 1);
|
||||
STATIC_REQUIRE(std::is_same_v<decltype(i), const int>);
|
||||
{
|
||||
constexpr auto i = cast_to<int>(1.5f);
|
||||
STATIC_REQUIRE(i == 1);
|
||||
STATIC_REQUIRE(std::is_same_v<decltype(i), const int>);
|
||||
}
|
||||
{
|
||||
constexpr auto v = cast_to<int>(float2{1.5f});
|
||||
STATIC_REQUIRE(v == int2(1));
|
||||
STATIC_REQUIRE(std::is_same_v<decltype(v)::value_type, int>);
|
||||
}
|
||||
{
|
||||
constexpr auto m = cast_to<int>(float2x2{1.5f});
|
||||
STATIC_REQUIRE(m == int2x2(1));
|
||||
STATIC_REQUIRE(std::is_same_v<decltype(m)::row_type, int2>);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("component") {
|
||||
STATIC_REQUIRE(component(int2{1,2}, 0) == 1);
|
||||
STATIC_REQUIRE(component(int2{1,2}, 1) == 2);
|
||||
|
||||
STATIC_REQUIRE(component(int2{0,0}, 0, 1) == int2{1,0});
|
||||
STATIC_REQUIRE(component(int2{0,0}, 1, 2) == int2{0,2});
|
||||
}
|
||||
|
||||
SECTION("row") {
|
||||
STATIC_REQUIRE(row(int2x2(1,2,3,4), 0) == int2(1,2));
|
||||
STATIC_REQUIRE(row(int2x2(1,2,3,4), 1) == int2(3,4));
|
||||
|
||||
STATIC_REQUIRE(row(int2x2(), 0, {1,2}) == int2x2(1,2,0,1));
|
||||
STATIC_REQUIRE(row(int2x2(), 1, {3,4}) == int2x2(1,0,3,4));
|
||||
}
|
||||
|
||||
SECTION("column") {
|
||||
STATIC_REQUIRE(column(int2x2(1,2,3,4), 0) == int2(1,3));
|
||||
STATIC_REQUIRE(column(int2x2(1,2,3,4), 1) == int2(2,4));
|
||||
|
||||
STATIC_REQUIRE(column(int2x2(), 0, {2,3}) == int2x2(2,0,3,1));
|
||||
STATIC_REQUIRE(column(int2x2(), 1, {3,4}) == int2x2(1,3,0,4));
|
||||
}
|
||||
|
||||
SECTION("matrix translate") {
|
||||
STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * translate(1.f,2.f,3.f) == approx4(3.f,5.f,7.f,1.f));
|
||||
STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * translate(float3{1.f,2.f,3.f}) == approx4(3.f,5.f,7.f,1.f));
|
||||
|
||||
STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * translate(translate(1.f,2.f,3.f), 1.f,2.f,3.f) == approx4(4.f,7.f,10.f,1.f));
|
||||
STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * translate(translate(1.f,2.f,3.f), float3{1.f,2.f,3.f}) == approx4(4.f,7.f,10.f,1.f));
|
||||
}
|
||||
|
||||
SECTION("matrix rotate") {
|
||||
constexpr float pi = radians(180.f);
|
||||
constexpr float pi_2 = radians(90.f);
|
||||
|
||||
REQUIRE(float4(2.f,3.f,4.f,1.f) * rotate(pi,0.f,0.f,1.f) == approx4(-2.f,-3.f,4.f,1.f));
|
||||
REQUIRE(float4(2.f,3.f,4.f,1.f) * rotate(pi,float3{0.f,0.f,1.f}) == approx4(-2.f,-3.f,4.f,1.f));
|
||||
|
||||
REQUIRE(float4(2.f,3.f,4.f,1.f) * rotate(rotate(pi_2,0.f,0.f,1.f),pi_2,0.f,0.f,1.f) == approx4(-2.f,-3.f,4.f,1.f));
|
||||
REQUIRE(float4(2.f,3.f,4.f,1.f) * rotate(rotate(pi_2,0.f,0.f,1.f),pi_2,float3{0.f,0.f,1.f}) == approx4(-2.f,-3.f,4.f,1.f));
|
||||
}
|
||||
|
||||
SECTION("matrix scale") {
|
||||
STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * scale(2.f,3.f,4.f) == approx4(4.f,9.f,16.f,1.f));
|
||||
STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * scale(float3{2.f,3.f,4.f}) == approx4(4.f,9.f,16.f,1.f));
|
||||
|
||||
STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * scale(scale(2.f,2.f,2.f), 2.f,3.f,4.f) == approx4(8.f,18.f,32.f,1.f));
|
||||
STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * scale(scale(2.f,2.f,2.f), float3{2.f,3.f,4.f}) == approx4(8.f,18.f,32.f,1.f));
|
||||
}
|
||||
|
||||
SECTION("vector angle") {
|
||||
REQUIRE(angle(float2(2.f,0.f), float2(0.f,1.f)) == Approx(radians(90.f)));
|
||||
REQUIRE(angle(float2(0.f,3.f), float2(1.f,0.f)) == Approx(radians(90.f)));
|
||||
REQUIRE(angle(float2(0.5f,0.f), float2(-1.f,0.f)) == Approx(radians(180.f)));
|
||||
REQUIRE(angle(float2(-0.2f,0.f), float2(1.f,0.f)) == Approx(radians(180.f)));
|
||||
REQUIRE(angle(float3(0.f,2.f,0.f), float3(0.f,0.f,1.f)) == Approx(radians(90.f)));
|
||||
REQUIRE(angle(float3(0.f,0.f,3.f), float3(0.f,1.f,0.f)) == Approx(radians(90.f)));
|
||||
}
|
||||
|
||||
SECTION("vector rotate") {
|
||||
REQUIRE(rotate(float2(2.f,0.f), radians(90.f)) == approx2(0.f,2.f));
|
||||
REQUIRE(rotate(float2(1.5f,0.f), radians(-90.f)) == approx2(0.f,-1.5f));
|
||||
|
||||
REQUIRE(rotate(float3(1.5f,0.f,0.f), radians(90.f), float3(0,0,1)) == approx3(0.f,1.5f,0.f));
|
||||
REQUIRE(rotate(float4(1.5f,0.f,0.f,1.f), radians(90.f), float3(0,0,1)) == approx4(0.f,1.5f,0.f,1.f));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "https://github.com/blackmatov/vmath.hpp"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2020, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#include <vmath.hpp/vmath_mat_ext.hpp>
|
||||
|
||||
#define CATCH_CONFIG_FAST_COMPILE
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
#include "vmath_tests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
using namespace vmath_hpp;
|
||||
using namespace vmath_tests;
|
||||
}
|
||||
|
||||
TEST_CASE("vmath/mat_ext") {
|
||||
SECTION("units") {
|
||||
STATIC_REQUIRE(zero2x2<int> == int2x2(0,0,0,0));
|
||||
STATIC_REQUIRE(zero3x3<int> == int3x3(0,0,0,0,0,0,0,0,0));
|
||||
STATIC_REQUIRE(zero4x4<int> == int4x4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0));
|
||||
|
||||
STATIC_REQUIRE(unit2x2<int> == int2x2(1,1,1,1));
|
||||
STATIC_REQUIRE(unit3x3<int> == int3x3(1,1,1,1,1,1,1,1,1));
|
||||
STATIC_REQUIRE(unit4x4<int> == int4x4(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1));
|
||||
|
||||
STATIC_REQUIRE(identity2x2<int> == int2x2());
|
||||
STATIC_REQUIRE(identity3x3<int> == int3x3());
|
||||
STATIC_REQUIRE(identity4x4<int> == int4x4());
|
||||
}
|
||||
|
||||
SECTION("hash") {
|
||||
REQUIRE(std::hash<int2x2>{}({1,2,3,4}) == std::hash<int2x2>{}({1,2,3,4}));
|
||||
REQUIRE_FALSE(std::hash<int2x2>{}({1,2,3,4}) == std::hash<int2x2>{}({1,2,4,3}));
|
||||
}
|
||||
|
||||
SECTION("cast_to") {
|
||||
constexpr auto m = cast_to<int>(float2x2{1.5f});
|
||||
STATIC_REQUIRE(m == int2x2(1));
|
||||
STATIC_REQUIRE(std::is_same_v<decltype(m)::row_type, int2>);
|
||||
}
|
||||
|
||||
SECTION("row") {
|
||||
STATIC_REQUIRE(row(int2x2(1,2,3,4), 0) == int2(1,2));
|
||||
STATIC_REQUIRE(row(int2x2(1,2,3,4), 1) == int2(3,4));
|
||||
|
||||
STATIC_REQUIRE(row(int2x2(), 0, {1,2}) == int2x2(1,2,0,1));
|
||||
STATIC_REQUIRE(row(int2x2(), 1, {3,4}) == int2x2(1,0,3,4));
|
||||
}
|
||||
|
||||
SECTION("column") {
|
||||
STATIC_REQUIRE(column(int2x2(1,2,3,4), 0) == int2(1,3));
|
||||
STATIC_REQUIRE(column(int2x2(1,2,3,4), 1) == int2(2,4));
|
||||
|
||||
STATIC_REQUIRE(column(int2x2(), 0, {2,3}) == int2x2(2,0,3,1));
|
||||
STATIC_REQUIRE(column(int2x2(), 1, {3,4}) == int2x2(1,3,0,4));
|
||||
}
|
||||
|
||||
SECTION("translate") {
|
||||
STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * translate(1.f,2.f,3.f) == approx4(3.f,5.f,7.f,1.f));
|
||||
STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * translate(float3{1.f,2.f,3.f}) == approx4(3.f,5.f,7.f,1.f));
|
||||
|
||||
STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * translate(translate(1.f,2.f,3.f), 1.f,2.f,3.f) == approx4(4.f,7.f,10.f,1.f));
|
||||
STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * translate(translate(1.f,2.f,3.f), float3{1.f,2.f,3.f}) == approx4(4.f,7.f,10.f,1.f));
|
||||
}
|
||||
|
||||
SECTION("rotate") {
|
||||
constexpr float pi = radians(180.f);
|
||||
constexpr float pi_2 = radians(90.f);
|
||||
|
||||
REQUIRE(float4(2.f,3.f,4.f,1.f) * rotate(pi,0.f,0.f,1.f) == approx4(-2.f,-3.f,4.f,1.f));
|
||||
REQUIRE(float4(2.f,3.f,4.f,1.f) * rotate(pi,float3{0.f,0.f,1.f}) == approx4(-2.f,-3.f,4.f,1.f));
|
||||
|
||||
REQUIRE(float4(2.f,3.f,4.f,1.f) * rotate(rotate(pi_2,0.f,0.f,1.f),pi_2,0.f,0.f,1.f) == approx4(-2.f,-3.f,4.f,1.f));
|
||||
REQUIRE(float4(2.f,3.f,4.f,1.f) * rotate(rotate(pi_2,0.f,0.f,1.f),pi_2,float3{0.f,0.f,1.f}) == approx4(-2.f,-3.f,4.f,1.f));
|
||||
}
|
||||
|
||||
SECTION("scale") {
|
||||
STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * scale(2.f,3.f,4.f) == approx4(4.f,9.f,16.f,1.f));
|
||||
STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * scale(float3{2.f,3.f,4.f}) == approx4(4.f,9.f,16.f,1.f));
|
||||
|
||||
STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * scale(scale(2.f,2.f,2.f), 2.f,3.f,4.f) == approx4(8.f,18.f,32.f,1.f));
|
||||
STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * scale(scale(2.f,2.f,2.f), float3{2.f,3.f,4.f}) == approx4(8.f,18.f,32.f,1.f));
|
||||
}
|
||||
}
|
||||
@@ -4,8 +4,7 @@
|
||||
* Copyright (C) 2020, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#include <vmath.hpp/vmath_mat_fun.hpp>
|
||||
#include <vmath.hpp/vmath_mat_ext.hpp>
|
||||
#include <vmath.hpp/vmath_ext.hpp>
|
||||
|
||||
#define CATCH_CONFIG_FAST_COMPILE
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "https://github.com/blackmatov/vmath.hpp"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2020, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#include <vmath.hpp/vmath_vec_ext.hpp>
|
||||
|
||||
#define CATCH_CONFIG_FAST_COMPILE
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
#include "vmath_tests.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
using namespace vmath_hpp;
|
||||
using namespace vmath_tests;
|
||||
}
|
||||
|
||||
TEST_CASE("vmath/vec_ext") {
|
||||
SECTION("units") {
|
||||
STATIC_REQUIRE(zero2<int> == int2(0,0));
|
||||
STATIC_REQUIRE(zero3<int> == int3(0,0,0));
|
||||
STATIC_REQUIRE(zero4<int> == int4(0,0,0,0));
|
||||
|
||||
STATIC_REQUIRE(unit2<int> == int2(1,1));
|
||||
STATIC_REQUIRE(unit2_x<int> == int2(1,0));
|
||||
STATIC_REQUIRE(unit2_y<int> == int2(0,1));
|
||||
|
||||
STATIC_REQUIRE(unit3<int> == int3(1,1,1));
|
||||
STATIC_REQUIRE(unit3_x<int> == int3(1,0,0));
|
||||
STATIC_REQUIRE(unit3_y<int> == int3(0,1,0));
|
||||
STATIC_REQUIRE(unit3_z<int> == int3(0,0,1));
|
||||
|
||||
STATIC_REQUIRE(unit4<int> == int4(1,1,1,1));
|
||||
STATIC_REQUIRE(unit4_x<int> == int4(1,0,0,0));
|
||||
STATIC_REQUIRE(unit4_y<int> == int4(0,1,0,0));
|
||||
STATIC_REQUIRE(unit4_z<int> == int4(0,0,1,0));
|
||||
STATIC_REQUIRE(unit4_w<int> == int4(0,0,0,1));
|
||||
}
|
||||
|
||||
SECTION("hash") {
|
||||
REQUIRE(std::hash<int2>{}({1,2}) == std::hash<int2>{}({1,2}));
|
||||
REQUIRE_FALSE(std::hash<int2>{}({1,2}) == std::hash<int2>{}({2,1}));
|
||||
|
||||
REQUIRE(std::hash<int3>{}({1,2,3}) == std::hash<int3>{}({1,2,3}));
|
||||
REQUIRE_FALSE(std::hash<int3>{}({1,2,3}) == std::hash<int3>{}({3,2,1}));
|
||||
|
||||
REQUIRE(std::hash<int4>{}({1,2,3,4}) == std::hash<int4>{}({1,2,3,4}));
|
||||
REQUIRE_FALSE(std::hash<int4>{}({1,2,3,4}) == std::hash<int4>{}({3,2,1,4}));
|
||||
}
|
||||
|
||||
SECTION("cast_to") {
|
||||
constexpr auto v = cast_to<int>(float2{1.5f});
|
||||
STATIC_REQUIRE(v == int2(1));
|
||||
STATIC_REQUIRE(std::is_same_v<decltype(v)::value_type, int>);
|
||||
}
|
||||
|
||||
SECTION("component") {
|
||||
STATIC_REQUIRE(component(int2{1,2}, 0) == 1);
|
||||
STATIC_REQUIRE(component(int2{1,2}, 1) == 2);
|
||||
|
||||
STATIC_REQUIRE(component(int2{0,0}, 0, 1) == int2{1,0});
|
||||
STATIC_REQUIRE(component(int2{0,0}, 1, 2) == int2{0,2});
|
||||
}
|
||||
|
||||
SECTION("angle") {
|
||||
REQUIRE(angle(float2(2.f,0.f), float2(0.f,1.f)) == Approx(radians(90.f)));
|
||||
REQUIRE(angle(float2(0.f,3.f), float2(1.f,0.f)) == Approx(radians(90.f)));
|
||||
REQUIRE(angle(float2(0.5f,0.f), float2(-1.f,0.f)) == Approx(radians(180.f)));
|
||||
REQUIRE(angle(float2(-0.2f,0.f), float2(1.f,0.f)) == Approx(radians(180.f)));
|
||||
REQUIRE(angle(float3(0.f,2.f,0.f), float3(0.f,0.f,1.f)) == Approx(radians(90.f)));
|
||||
REQUIRE(angle(float3(0.f,0.f,3.f), float3(0.f,1.f,0.f)) == Approx(radians(90.f)));
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (C) 2020, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#include <vmath.hpp/vmath_vec_fun.hpp>
|
||||
#include <vmath.hpp/vmath_ext.hpp>
|
||||
|
||||
#define CATCH_CONFIG_FAST_COMPILE
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
Reference in New Issue
Block a user