start to refactor for C++23
This commit is contained in:
parent
42c7221318
commit
cd19543627
19 changed files with 489 additions and 434 deletions
12
.clang-format
Normal file
12
.clang-format
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# We'll use defaults from the LLVM style, but with 4 columns indentation.
|
||||||
|
BasedOnStyle: LLVM
|
||||||
|
IndentWidth: 4
|
||||||
|
|
||||||
|
|
||||||
|
Language: Cpp
|
||||||
|
|
||||||
|
# Force pointers to the type for C++.
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
PointerAlignment: Left
|
||||||
|
AlignConsecutiveAssignments: true
|
||||||
|
LambdaBodyIndentation: OuterScope
|
36
.vscode/settings.json
vendored
36
.vscode/settings.json
vendored
|
@ -16,7 +16,41 @@
|
||||||
"stdexcept": "cpp",
|
"stdexcept": "cpp",
|
||||||
"streambuf": "cpp",
|
"streambuf": "cpp",
|
||||||
"type_traits": "cpp",
|
"type_traits": "cpp",
|
||||||
"tuple": "cpp"
|
"tuple": "cpp",
|
||||||
|
"cmath": "cpp",
|
||||||
|
"span": "cpp",
|
||||||
|
"*.tcc": "cpp",
|
||||||
|
"*.inc": "cpp",
|
||||||
|
"*.ipp": "cpp",
|
||||||
|
"bit": "cpp",
|
||||||
|
"bitset": "cpp",
|
||||||
|
"chrono": "cpp",
|
||||||
|
"format": "cpp",
|
||||||
|
"future": "cpp",
|
||||||
|
"optional": "cpp",
|
||||||
|
"ranges": "cpp",
|
||||||
|
"shared_mutex": "cpp",
|
||||||
|
"stop_token": "cpp",
|
||||||
|
"regex": "cpp",
|
||||||
|
"valarray": "cpp",
|
||||||
|
"*.def": "cpp",
|
||||||
|
"boundingsphere": "cpp",
|
||||||
|
"callback": "cpp",
|
||||||
|
"geometry": "cpp",
|
||||||
|
"node": "cpp",
|
||||||
|
"nodevisitor": "cpp",
|
||||||
|
"object": "cpp",
|
||||||
|
"plane": "cpp",
|
||||||
|
"program": "cpp",
|
||||||
|
"shape": "cpp",
|
||||||
|
"stateattribute": "cpp",
|
||||||
|
"observer_ptr": "cpp",
|
||||||
|
"thread": "cpp",
|
||||||
|
"concepts": "cpp",
|
||||||
|
"typeinfo": "cpp",
|
||||||
|
"drawable": "cpp",
|
||||||
|
"userdatacontainer": "cpp",
|
||||||
|
"*.txx": "cpp"
|
||||||
},
|
},
|
||||||
"mesonbuild.configureOnOpen": false
|
"mesonbuild.configureOnOpen": false
|
||||||
}
|
}
|
|
@ -1,15 +1,15 @@
|
||||||
#
|
#
|
||||||
# CMake build system for pixwerx
|
# CMake build system for pixwerx
|
||||||
#
|
#
|
||||||
cmake_minimum_required(VERSION 3.8)
|
cmake_minimum_required(VERSION 3.28)
|
||||||
|
|
||||||
|
|
||||||
project(pixwerx)
|
project(pixwerx)
|
||||||
|
|
||||||
#
|
#
|
||||||
# pixwerx ist C++20
|
# pixwerx ist C++23
|
||||||
#
|
#
|
||||||
set (CMAKE_CXX_STANDARD 20)
|
set (CMAKE_CXX_STANDARD 23)
|
||||||
|
|
||||||
# internal cmake modules
|
# internal cmake modules
|
||||||
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/etc/cmake ${CMAKE_MODULE_PATH})
|
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/etc/cmake ${CMAKE_MODULE_PATH})
|
||||||
|
@ -28,3 +28,4 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||||
#
|
#
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
add_subdirectory(share)
|
add_subdirectory(share)
|
||||||
|
add_subdirectory(tests)
|
||||||
|
|
27
README.md
27
README.md
|
@ -1,34 +1,27 @@
|
||||||
# pixwerx
|
# pixwerx
|
||||||
|
|
||||||
pixwerx is an opinionated, academic approach to a 3D engine. It tries to mix
|
pixwerx is an opinionated, academic approach to a 3D graphics engine. It mixes
|
||||||
modern andproven methods to build a fast and portable engine beyond pure 3D.
|
modern and proven methods to build a fast and portable graphics system.
|
||||||
|
|
||||||
## Design Principles
|
## Design Principles
|
||||||
|
|
||||||
Dogdooding: pixwerx is built on the principle of dogfooding. The engine is a
|
Dogfooding: pixwerx is built on the principle of dogfooding. The engine is a
|
||||||
full-stack system that tries to implement all necessary functions. The engine
|
full-stack system that tries to implement all necessary functions. The engine
|
||||||
editor is just a UI build with the engine.
|
editor is just a UI build with the engine.
|
||||||
|
|
||||||
Reasonable dependencies: like many engines pixwerx tries to include as much 3rd-
|
Reasonable dependencies: like many engines pixwerx tries to include as much 3rd-party code as possible and implements some of the core systems itself.
|
||||||
party code as possible and implements some of the core systems itself.
|
|
||||||
|
|
||||||
No premature optimization: pixwerx implements only very few systems with machine
|
No premature optimization: pixwerx implements only very few systems with machine code. It tries to utilize the power of the compiler as much as possible.
|
||||||
code. It tries to utilize the power of the compiler as much as possible.
|
|
||||||
|
|
||||||
Computer graphics 101: pixwerx does implement graphics components and systems in
|
Computer graphics 101: pixwerx does implement graphics components and systems in a way that makes code portable and not over-parameterized. Usability is
|
||||||
a way that makes code portable and not over-parameterized. Usability is
|
achieved through layers on top of the core components.
|
||||||
achieved through layers on top of the core components.
|
|
||||||
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
pixwerx is licenced under the terms of the MIT License. Please consult the
|
pixwerx is licenced under the terms of the MIT License. Please consult the
|
||||||
LICENSE file.
|
LICENSE file.
|
||||||
|
|
||||||
## Authors
|
## Authors
|
||||||
|
|
||||||
© 1999-2020 Hartmut Seichter
|
© 1999-2020 Hartmut Seichter
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
find_package(mkdocs 1.0)
|
# find_package(mkdocs 1.0)
|
||||||
|
|
||||||
# if(MKDOCS_FOUND)
|
# if(MKDOCS_FOUND)
|
||||||
# configure_file(mkdocs.yml "${CMAKE_CURRENT_BINARY_DIR}/mkdocs.yml" COPYONLY)
|
# configure_file(mkdocs.yml "${CMAKE_CURRENT_BINARY_DIR}/mkdocs.yml" COPYONLY)
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
# first build dependencies
|
# first build dependencies
|
||||||
add_subdirectory(deps)
|
# add_subdirectory(deps)
|
||||||
|
|
||||||
# build internal core
|
# build internal core
|
||||||
add_subdirectory(core)
|
add_subdirectory(core)
|
||||||
add_subdirectory(scene)
|
# add_subdirectory(scene)
|
||||||
add_subdirectory(system)
|
# add_subdirectory(system)
|
||||||
add_subdirectory(io)
|
# add_subdirectory(io)
|
||||||
|
|
||||||
#add_subdirectory(ui)
|
#add_subdirectory(ui)
|
||||||
add_subdirectory(binding)
|
# add_subdirectory(binding)
|
||||||
add_subdirectory(visual)
|
# add_subdirectory(visual)
|
||||||
add_subdirectory(geometry)
|
# add_subdirectory(geometry)
|
||||||
|
|
||||||
add_subdirectory(runtime)
|
# add_subdirectory(runtime)
|
||||||
|
|
|
@ -33,14 +33,14 @@ set(misc
|
||||||
set(srcs
|
set(srcs
|
||||||
# src/buffer.cpp
|
# src/buffer.cpp
|
||||||
src/core.cpp
|
src/core.cpp
|
||||||
src/image.cpp
|
# src/image.cpp
|
||||||
src/debug.cpp
|
# src/debug.cpp
|
||||||
src/geometry.cpp
|
# src/geometry.cpp
|
||||||
src/material.cpp
|
# src/material.cpp
|
||||||
src/resource.cpp
|
# src/resource.cpp
|
||||||
src/serialize.cpp
|
# src/serialize.cpp
|
||||||
src/time.cpp
|
# src/time.cpp
|
||||||
src/image.cpp
|
# src/image.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(pwcore
|
add_library(pwcore
|
||||||
|
@ -58,5 +58,5 @@ target_include_directories(
|
||||||
|
|
||||||
target_link_libraries(pwcore)
|
target_link_libraries(pwcore)
|
||||||
|
|
||||||
add_subdirectory(tests)
|
# add_subdirectory(tests)
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
@ -29,24 +29,12 @@ namespace pw {
|
||||||
|
|
||||||
struct aabb {
|
struct aabb {
|
||||||
|
|
||||||
vector3 min;
|
vector3 min{};
|
||||||
vector3 max;
|
vector3 max{};
|
||||||
|
|
||||||
aabb(const vector3 min_vec,const vector3 max_vec)
|
|
||||||
: min(min_vec)
|
|
||||||
, max(max_vec)
|
|
||||||
{}
|
|
||||||
|
|
||||||
aabb() {
|
|
||||||
min.zero(); max.zero();
|
|
||||||
}
|
|
||||||
|
|
||||||
vector3 dimension() const {
|
|
||||||
return max - min;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
constexpr vector3 dimension() const noexcept { return max - min; }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace pw
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -31,23 +31,12 @@ template <typename T>
|
||||||
struct axisangle_ {
|
struct axisangle_ {
|
||||||
|
|
||||||
using value_type = T;
|
using value_type = T;
|
||||||
using axis_type = vector3_<T>;
|
using axis_type = vector3_<T>; // todo - should default to UP
|
||||||
|
|
||||||
axis_type axis;
|
axis_type axis{};
|
||||||
T angle;
|
T angle{};
|
||||||
|
|
||||||
axisangle_()
|
static axisangle_ from_matrix(const matrix_<4,4,T>& m)
|
||||||
: axis(vector3_<T>::up()),
|
|
||||||
angle(0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
axisangle_(vector3_<T> axis,T angle)
|
|
||||||
: axis(std::move(axis))
|
|
||||||
, angle(std::move(angle))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static const axisangle_ from_matrix(const matrix_<4,4,T>& m)
|
|
||||||
{
|
{
|
||||||
using std::acos;
|
using std::acos;
|
||||||
using std::sqrt;
|
using std::sqrt;
|
||||||
|
|
|
@ -58,13 +58,10 @@ public:
|
||||||
|
|
||||||
using texture_t = std::tuple<texture_type,std::string,uint32_t>;
|
using texture_t = std::tuple<texture_type,std::string,uint32_t>;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
vector4 _color = {{}, {1.0, 0.0, 1.0, 1.0}};
|
||||||
|
|
||||||
vector4 _color = vector4 { 1.0, 0.0, 1.0, 1.0 };
|
std::vector<texture_t> _textures;
|
||||||
|
|
||||||
std::vector<texture_t> _textures;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
@ -27,253 +27,213 @@
|
||||||
#include <pw/core/math.hpp>
|
#include <pw/core/math.hpp>
|
||||||
#include <pw/core/matrixbase.hpp>
|
#include <pw/core/matrixbase.hpp>
|
||||||
|
|
||||||
|
// #include <array>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <array>
|
|
||||||
|
|
||||||
namespace pw
|
namespace pw {
|
||||||
{
|
|
||||||
|
|
||||||
template <std::size_t R, std::size_t C, typename T, bool RowMajor = false>
|
template <std::size_t R, std::size_t C, typename T, bool RowMajor = false>
|
||||||
struct matrix_ : matrixbase_<T, matrix_<R, C, T>>
|
struct matrix_ : matrixbase_<T, matrix_<R, C, T>> {
|
||||||
{
|
|
||||||
T data[R * C];
|
|
||||||
|
|
||||||
using matrixbase_<T, matrix_<R, C, T>>::matrixbase_;
|
using base_type = matrixbase_<T, matrix_<R, C, T>>;
|
||||||
|
using typename base_type::value_type;
|
||||||
|
using typename base_type::derived_type;
|
||||||
|
|
||||||
static constexpr std::size_t rows{R};
|
static constexpr std::size_t rows{R};
|
||||||
static constexpr std::size_t cols{C};
|
static constexpr std::size_t cols{C};
|
||||||
|
static constexpr std::size_t coefficients{R * C};
|
||||||
|
static constexpr std::size_t diagonal_size{std::min(R,C)};
|
||||||
|
|
||||||
static constexpr std::size_t coefficients{R * C};
|
using col_type = matrix_<R, 1, T>;
|
||||||
|
using row_type = matrix_<1, C, T>;
|
||||||
|
using diag_type = matrix_<diagonal_size, 1, T>;
|
||||||
|
using transpose_type = matrix_<C, R, T>;
|
||||||
|
|
||||||
using col_type = matrix_<R, 1, T>;
|
|
||||||
using row_type = matrix_<1, C, T>;
|
|
||||||
using transpose_type = matrix_<C, R, T>;
|
|
||||||
|
|
||||||
matrix_<R, C, T> &operator=(const matrix_<R, C, T> &other)
|
value_type data[R * C]{};
|
||||||
{
|
|
||||||
for (size_t i = 0; i < other.size(); i++)
|
|
||||||
(*this)[i] = other[i];
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
matrix_(std::initializer_list<T> args)
|
|
||||||
{
|
|
||||||
typename std::initializer_list<T>::iterator it = args.begin();
|
|
||||||
for (; it != args.end(); it++)
|
|
||||||
data[it - args.begin()] = *it;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename... Arguments>
|
template <typename... Arguments>
|
||||||
matrix_ &set(Arguments... values)
|
static constexpr auto make(Arguments&&... values) -> matrix_ {
|
||||||
{
|
static_assert(sizeof...(Arguments) == coefficients,
|
||||||
static_assert(sizeof...(Arguments) == R * C, "Incorrect number of arguments");
|
"Incorrect number of arguments");
|
||||||
data = {values...};
|
return {.data = { T(values)... } };
|
||||||
return *this;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
inline size_t offset(size_t r, size_t c) const
|
constexpr size_t offset(size_t r, size_t c) const noexcept {
|
||||||
{
|
return (RowMajor) ? r * C + c : c * R + r;
|
||||||
return (RowMajor) ? r * C + c : c * R + r;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
inline T &operator()(std::size_t r, std::size_t c)
|
constexpr T& operator()(std::size_t r, std::size_t c) noexcept {
|
||||||
{
|
return data[offset(r, c)];
|
||||||
return data[offset(r, c)];
|
}
|
||||||
}
|
|
||||||
|
|
||||||
inline const T &operator()(std::size_t r, std::size_t c) const
|
constexpr const T& operator()(std::size_t r, std::size_t c) const noexcept {
|
||||||
{
|
return data[offset(r, c)];
|
||||||
return data[offset(r, c)];
|
}
|
||||||
}
|
|
||||||
|
|
||||||
inline const T *ptr() const { return &data[0]; }
|
constexpr const T* ptr() const noexcept { return &data[0]; }
|
||||||
|
|
||||||
//! set identity
|
//! set identity
|
||||||
inline matrix_ &set_identity()
|
constexpr matrix_& set_identity() {
|
||||||
{
|
for (std::size_t r = 0; r < rows; r++)
|
||||||
for (std::size_t r = 0; r < rows; r++)
|
for (std::size_t c = 0; c < cols; c++)
|
||||||
for (std::size_t c = 0; c < cols; c++)
|
(*this)(r, c) = (c == r) ? T(1) : T(0);
|
||||||
(*this)(r, c) = (c == r) ? T(1) : T(0);
|
return *this;
|
||||||
return *this;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
inline matrix_ &set_uniform(const T& v)
|
constexpr matrix_& set_uniform(const T& v) {
|
||||||
{
|
std::fill(std::begin(data), std::end(data), v);
|
||||||
std::fill(std::begin(data),std::end(data),v);
|
return *this;
|
||||||
return *this;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
template <std::size_t Rs, std::size_t Cs, bool RowMajorSlice = RowMajor>
|
template <std::size_t Rs, std::size_t Cs, bool RowMajorSlice = RowMajor>
|
||||||
auto slice(std::size_t r, std::size_t c) const
|
auto slice(std::size_t r, std::size_t c) const {
|
||||||
{
|
matrix_<Rs, Cs, T, RowMajorSlice> s;
|
||||||
matrix_<Rs, Cs, T, RowMajorSlice> s;
|
for (std::size_t ri = 0; ri < Rs; ri++)
|
||||||
for (std::size_t ri = 0; ri < Rs; ri++)
|
for (std::size_t ci = 0; ci < Cs; ci++)
|
||||||
for (std::size_t ci = 0; ci < Cs; ci++)
|
s(ri, ci) = (*this)(ri + r, ci + c);
|
||||||
s(ri, ci) = (*this)(ri + r, ci + c);
|
return s;
|
||||||
return s;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
template <std::size_t Rs, std::size_t Cs, bool RowMajorSlice = RowMajor>
|
template <std::size_t Rs, std::size_t Cs, bool RowMajorSlice = RowMajor>
|
||||||
matrix_ &set_slice(const matrix_<Rs, Cs, T, RowMajorSlice> &s,
|
matrix_& set_slice(const matrix_<Rs, Cs, T, RowMajorSlice>& s,
|
||||||
std::size_t r, std::size_t c)
|
std::size_t r, std::size_t c) {
|
||||||
{
|
for (std::size_t ri = 0; ri < Rs; ri++)
|
||||||
for (std::size_t ri = 0; ri < Rs; ri++)
|
for (std::size_t ci = 0; ci < Cs; ci++)
|
||||||
for (std::size_t ci = 0; ci < Cs; ci++)
|
(*this)(ri + r, ci + c) = s(ri, ci);
|
||||||
(*this)(ri + r, ci + c) = s(ri, ci);
|
return *this;
|
||||||
return *this;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
template <std::size_t Rs, std::size_t Cs, bool RowMajorSlice = RowMajor>
|
template <std::size_t Rs, std::size_t Cs, bool RowMajorSlice = RowMajor>
|
||||||
auto minor(std::size_t r0, std::size_t c0) const
|
auto minor(std::size_t r0, std::size_t c0) const {
|
||||||
{
|
matrix_<Rs, Cs, T, RowMajorSlice> m;
|
||||||
matrix_<Rs, Cs, T, RowMajorSlice> m;
|
size_t r = 0;
|
||||||
size_t r = 0;
|
for (size_t ri = 0; ri < R; ri++) {
|
||||||
for (size_t ri = 0; ri < R; ri++)
|
size_t c = 0;
|
||||||
{
|
if (ri == r0)
|
||||||
size_t c = 0;
|
continue;
|
||||||
if (ri == r0)
|
for (size_t ci = 0; ci < C; ci++) {
|
||||||
continue;
|
if (ci == c0)
|
||||||
for (size_t ci = 0; ci < C; ci++)
|
continue;
|
||||||
{
|
m(r, c) = (*this)(ri, ci);
|
||||||
if (ci == c0)
|
c++;
|
||||||
continue;
|
}
|
||||||
m(r, c) = (*this)(ri, ci);
|
r++;
|
||||||
c++;
|
}
|
||||||
}
|
return m;
|
||||||
r++;
|
}
|
||||||
}
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
T determinant() const
|
constexpr T determinant() const {
|
||||||
{
|
T det(0);
|
||||||
T det(0);
|
for (size_t c = 0; c < C; c++)
|
||||||
for (size_t c = 0; c < C; c++)
|
det += ((c % 2 == 0) ? (*this)(0, c) : -(*this)(0, c)) *
|
||||||
det += ((c % 2 == 0) ? (*this)(0, c) : -(*this)(0, c)) * this->minor<R - 1, C - 1, RowMajor>(0, c).determinant();
|
this->minor<R - 1, C - 1, RowMajor>(0, c).determinant();
|
||||||
return det;
|
return det;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto transposed() const
|
auto transposed() const {
|
||||||
{
|
transpose_type res;
|
||||||
transpose_type res;
|
for (size_t r = rows; r-- > 0;)
|
||||||
for (size_t r = rows; r-- > 0;)
|
for (size_t c = cols; c-- > 0;)
|
||||||
for (size_t c = cols; c-- > 0;)
|
res(c, r) = (*this)(r, c);
|
||||||
res(c, r) = (*this)(r, c);
|
return res;
|
||||||
return res;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
auto inverse() const
|
auto inverse() const {
|
||||||
{
|
T invDet = T(1) / this->determinant();
|
||||||
T invDet = T(1) / this->determinant();
|
matrix_<R, C, T, RowMajor> inv;
|
||||||
matrix_<R, C, T, RowMajor> inv;
|
for (int j = 0; j < C; j++)
|
||||||
for (int j = 0; j < C; j++)
|
for (int i = 0; i < R; i++) {
|
||||||
for (int i = 0; i < R; i++)
|
const T minorDet =
|
||||||
{
|
this->minor<R - 1, C - 1, RowMajor>(j, i).determinant();
|
||||||
const T minorDet = this->minor<R - 1, C - 1, RowMajor>(j, i).determinant();
|
const T coFactor = ((i + j) % 2 == 1) ? -minorDet : minorDet;
|
||||||
const T coFactor = ((i + j) % 2 == 1) ? -minorDet : minorDet;
|
inv(i, j) = invDet * coFactor;
|
||||||
inv(i, j) = invDet * coFactor;
|
}
|
||||||
}
|
return inv;
|
||||||
return inv;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
inline bool row_major() const
|
constexpr bool row_major() const { return RowMajor; }
|
||||||
{
|
|
||||||
return RowMajor;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool square() const { return R == C; }
|
constexpr bool square() const { return R == C; }
|
||||||
|
|
||||||
inline const matrix_ operator+(const matrix_ &other) const
|
constexpr const matrix_ operator+(const matrix_& other) const {
|
||||||
{
|
matrix_ res(*this);
|
||||||
matrix_ res(*this);
|
for (size_t r = 0; r < R; r++)
|
||||||
for (size_t r = 0; r < R; r++)
|
for (size_t c = 0; c < C; c++)
|
||||||
for (size_t c = 0; c < C; c++)
|
res(r, c) += other(r, c);
|
||||||
res(r, c) += other(r, c);
|
return res;
|
||||||
return res;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
inline const matrix_ operator-(const matrix_ &other) const
|
constexpr const matrix_ operator-(const matrix_& other) const {
|
||||||
{
|
matrix_ res(*this);
|
||||||
matrix_ res(*this);
|
for (size_t r = 0; r < R; r++)
|
||||||
for (size_t r = 0; r < R; r++)
|
for (size_t c = 0; c < C; c++)
|
||||||
for (size_t c = 0; c < C; c++)
|
res(r, c) -= other(r, c);
|
||||||
res(r, c) -= other(r, c);
|
return res;
|
||||||
return res;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
auto row(size_t row_) const
|
auto row(size_t row_) const {
|
||||||
{
|
row_type r;
|
||||||
row_type r;
|
for (size_t i = 0; i < cols; i++)
|
||||||
for (size_t i = 0; i < cols; i++)
|
r[i] = (*this)(row_, i);
|
||||||
r[i] = (*this)(row_, i);
|
return r;
|
||||||
return r;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
auto column(size_t col_) const
|
auto column(size_t col_) const {
|
||||||
{
|
col_type c;
|
||||||
col_type c;
|
for (size_t i = 0; i < rows; i++)
|
||||||
for (size_t i = 0; i < rows; i++)
|
c[i] = (*this)(i, col_);
|
||||||
c[i] = (*this)(i, col_);
|
return c;
|
||||||
return c;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static constexpr auto identity()
|
static constexpr auto identity() {
|
||||||
{
|
matrix_ res;
|
||||||
matrix_ res;
|
for (std::size_t r = 0; r < rows; r++)
|
||||||
for (std::size_t r = 0; r < rows; r++)
|
for (std::size_t c = 0; c < cols; c++)
|
||||||
for (std::size_t c = 0; c < cols; c++)
|
res(r, c) = (c == r) ? T(1) : T(0);
|
||||||
res(r, c) = (c == r) ? T(1) : T(0);
|
return res;
|
||||||
return res;
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
template <> constexpr float matrix_<1, 1, float>::determinant() const {
|
||||||
inline float matrix_<1, 1, float>::determinant() const
|
return (*this)(0, 0);
|
||||||
{
|
|
||||||
return (*this)(0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
inline double matrix_<1, 1, double>::determinant() const
|
|
||||||
{
|
|
||||||
return (*this)(0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, std::size_t R, std::size_t Ca, std::size_t Cb>
|
|
||||||
auto operator*(const matrix_<R, Ca, T> &A,
|
|
||||||
const matrix_<R, Cb, T> &B)
|
|
||||||
{
|
|
||||||
matrix_<R, Cb, T> result;
|
|
||||||
result.zero(); // zero the output
|
|
||||||
for (size_t r = 0; r < R; r++)
|
|
||||||
for (size_t c = 0; c < Cb; c++)
|
|
||||||
for (size_t iI = 0; iI < R; iI++)
|
|
||||||
result(r, c) += A(r, iI) * B(iI, c); // inner product
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// common matrix types
|
|
||||||
//
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
using matrix2x2_ = matrix_<2, 2, T>;
|
|
||||||
template <typename T>
|
|
||||||
using matrix3x3_ = matrix_<3, 3, T>;
|
|
||||||
template <typename T>
|
|
||||||
using matrix4x4_ = matrix_<4, 4, T>;
|
|
||||||
|
|
||||||
using matrix2x2f = matrix2x2_<float>;
|
|
||||||
using matrix2x2d = matrix2x2_<double>;
|
|
||||||
using matrix2x2 = matrix2x2_<real_t>;
|
|
||||||
|
|
||||||
using matrix3x3f = matrix3x3_<float>;
|
|
||||||
using matrix3x3d = matrix3x3_<double>;
|
|
||||||
using matrix3x3 = matrix3x3_<real_t>;
|
|
||||||
|
|
||||||
using matrix4x4f = matrix4x4_<float>;
|
|
||||||
using matrix4x4d = matrix4x4_<double>;
|
|
||||||
using matrix4x4 = matrix4x4_<real_t>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <> constexpr double matrix_<1, 1, double>::determinant() const {
|
||||||
|
return (*this)(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::size_t R, std::size_t Ca, std::size_t Cb>
|
||||||
|
auto operator*(const matrix_<R, Ca, T>& A, const matrix_<R, Cb, T>& B) {
|
||||||
|
matrix_<R, Cb, T> result;
|
||||||
|
result.zero(); // zero the output
|
||||||
|
for (size_t r = 0; r < R; r++)
|
||||||
|
for (size_t c = 0; c < Cb; c++)
|
||||||
|
for (size_t iI = 0; iI < R; iI++)
|
||||||
|
result(r, c) += A(r, iI) * B(iI, c); // inner product
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// common matrix types
|
||||||
|
//
|
||||||
|
|
||||||
|
template <typename T> using matrix2x2_ = matrix_<2, 2, T>;
|
||||||
|
template <typename T> using matrix3x3_ = matrix_<3, 3, T>;
|
||||||
|
template <typename T> using matrix4x4_ = matrix_<4, 4, T>;
|
||||||
|
|
||||||
|
using matrix2x2f = matrix2x2_<float>;
|
||||||
|
using matrix2x2d = matrix2x2_<double>;
|
||||||
|
using matrix2x2 = matrix2x2_<real_t>;
|
||||||
|
|
||||||
|
using matrix3x3f = matrix3x3_<float>;
|
||||||
|
using matrix3x3d = matrix3x3_<double>;
|
||||||
|
using matrix3x3 = matrix3x3_<real_t>;
|
||||||
|
|
||||||
|
using matrix4x4f = matrix4x4_<float>;
|
||||||
|
using matrix4x4d = matrix4x4_<double>;
|
||||||
|
using matrix4x4 = matrix4x4_<real_t>;
|
||||||
|
} // namespace pw
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -30,8 +30,7 @@ namespace pw {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct matrix_transform {
|
struct matrix_transform {
|
||||||
|
|
||||||
inline static
|
constexpr static matrix_<4,4,T> scale_matrix(const vector3_<T>& s) noexcept
|
||||||
matrix_<4,4,T> scale_matrix(const vector3_<T>& s)
|
|
||||||
{
|
{
|
||||||
matrix_<4,4,T> scale; scale.zero();
|
matrix_<4,4,T> scale; scale.zero();
|
||||||
scale(0,0) = s[0]; scale(1,1) = s[1]; scale(2,2) = s[2]; scale(3,3) = T(1);
|
scale(0,0) = s[0]; scale(1,1) = s[1]; scale(2,2) = s[2]; scale(3,3) = T(1);
|
||||||
|
|
|
@ -24,93 +24,97 @@
|
||||||
#define PW_CORE_MATRIXBASE_HPP
|
#define PW_CORE_MATRIXBASE_HPP
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
|
||||||
#include <initializer_list>
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
namespace pw {
|
namespace pw {
|
||||||
|
|
||||||
template <typename T, typename Derived>
|
template <typename T, typename Derived>
|
||||||
struct matrixbase_ {
|
struct matrixbase_ {
|
||||||
|
|
||||||
using value_type = T;
|
using value_type = T;
|
||||||
|
using derived_type = Derived;
|
||||||
|
using iterator = value_type*;
|
||||||
|
using const_iterator = const value_type*;
|
||||||
|
|
||||||
Derived& derived() { return static_cast<Derived&>(*this); }
|
constexpr Derived& derived() noexcept { return static_cast<Derived&>(*this); }
|
||||||
const Derived& derived() const { return static_cast<const Derived&>(*this); }
|
constexpr const Derived& derived() const noexcept { return static_cast<const Derived&>(*this); }
|
||||||
|
|
||||||
std::size_t size() const {
|
constexpr std::size_t size() const noexcept {
|
||||||
return std::extent<decltype(Derived::data)>::value;
|
return std::extent<decltype(Derived::data)>::value;
|
||||||
}
|
}
|
||||||
|
|
||||||
Derived& fill(const T& v) {
|
constexpr Derived& fill(const T& v) noexcept {
|
||||||
std::fill(std::begin(derived().data), std::end(derived().data), T(v));
|
std::fill(std::begin(derived().data), std::end(derived().data), T(v));
|
||||||
return derived();
|
return derived();
|
||||||
}
|
}
|
||||||
|
|
||||||
Derived& zero() {
|
constexpr Derived& zero() {
|
||||||
return derived().fill(0);
|
return derived().fill(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline T squared_norm() const {
|
constexpr T squared_norm() const noexcept {
|
||||||
return std::accumulate(std::begin(derived().data),std::end(derived().data), T(0),
|
return std::accumulate(std::begin(derived().data),std::end(derived().data), T(0),
|
||||||
[&](const T& a,const T& b){
|
[&](const T& a,const T& b){
|
||||||
return a + b * b;
|
return a + b * b;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
inline T norm() const {
|
static constexpr Derived
|
||||||
|
all(const std::convertible_to<T> auto& v) noexcept {
|
||||||
|
Derived d;
|
||||||
|
d.fill(v);
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr T norm() const noexcept {
|
||||||
return std::sqrt(squared_norm());
|
return std::sqrt(squared_norm());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline constexpr Derived normalized() const {
|
constexpr Derived normalized() const noexcept {
|
||||||
return *this / this->norm() ;
|
return *this / this->norm() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void normalize() {
|
constexpr void normalize() {
|
||||||
*this /= this->norm();
|
*this /= this->norm();
|
||||||
}
|
}
|
||||||
|
|
||||||
using iterator = T*;
|
|
||||||
using const_iterator = const T*;
|
|
||||||
iterator begin() { return &derived().data[0]; }
|
|
||||||
iterator end() { return &derived().data[0] + size(); }
|
|
||||||
const_iterator begin() const { return &derived().data[0]; }
|
|
||||||
const_iterator end() const { return &derived().data[0] + size(); }
|
|
||||||
|
|
||||||
T& operator [] (std::size_t i) {
|
constexpr iterator begin() { return &derived().data[0]; }
|
||||||
|
constexpr iterator end() { return &derived().data[0] + size(); }
|
||||||
|
constexpr const_iterator begin() const { return &derived().data[0]; }
|
||||||
|
constexpr const_iterator end() const { return &derived().data[0] + size(); }
|
||||||
|
|
||||||
|
constexpr T& operator [] (std::size_t i) {
|
||||||
return derived().data[i];
|
return derived().data[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
const T& operator [] (std::size_t i) const {
|
constexpr const T& operator [] (std::size_t i) const {
|
||||||
return derived().data[i];
|
return derived().data[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr T dot(const Derived &a,const Derived &b)
|
static constexpr T dot(const Derived &a,const Derived &b) noexcept
|
||||||
{
|
{
|
||||||
return std::inner_product(std::begin(a),std::end(a),std::begin(b),T(0));
|
return std::inner_product(std::begin(a),std::end(a),std::begin(b),T(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr Derived lerp(const Derived &a,const Derived &b,const T& t)
|
static constexpr Derived lerp(const Derived &a,const Derived &b,const T& t) noexcept
|
||||||
{
|
{
|
||||||
return a + (b - a) * t;
|
return a + (b - a) * t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void operator *= (const T& b) { for (auto & e : *this) e *= b; }
|
constexpr void operator *= (const T& b) { for (auto & e : *this) e *= b; }
|
||||||
inline void operator /= (const T& b) { for (auto & e : *this) e /= b; }
|
constexpr void operator /= (const T& b) { for (auto & e : *this) e /= b; }
|
||||||
inline void operator += (const T& b) { for (auto & e : *this) e += b; }
|
constexpr void operator += (const T& b) { for (auto & e : *this) e += b; }
|
||||||
inline void operator -= (const T& b) { for (auto & e : *this) e -= b; }
|
constexpr void operator -= (const T& b) { for (auto & e : *this) e -= b; }
|
||||||
|
|
||||||
inline const Derived operator * (const T& b) const { Derived r(derived()); for (auto & e : r) e *= b; return r; }
|
constexpr const Derived operator * (const T& b) const { Derived r(derived()); for (auto & e : r) e *= b; return r; }
|
||||||
inline const Derived operator / (const T& b) const { Derived r(derived()); for (auto & e : r) e /= b; return r; }
|
constexpr const Derived operator / (const T& b) const { Derived r(derived()); for (auto & e : r) e /= b; return r; }
|
||||||
inline const Derived operator + (const T& b) const { Derived r(derived()); for (auto & e : r) e += b; return r; }
|
constexpr const Derived operator + (const T& b) const { Derived r(derived()); for (auto & e : r) e += b; return r; }
|
||||||
inline const Derived operator - (const T& b) const { Derived r(derived()); for (auto & e : r) e -= b; return r; }
|
constexpr const Derived operator - (const T& b) const { Derived r(derived()); for (auto & e : r) e -= b; return r; }
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
@ -31,138 +31,130 @@ namespace pw {
|
||||||
* Basic vector types used in pixwerx.
|
* Basic vector types used in pixwerx.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> struct vector2_ : matrix_<2, 1, T> {
|
||||||
struct vector2_ : matrix_<2,1,T> {
|
|
||||||
|
|
||||||
typedef matrix_<2,1,T> base_type;
|
using base_type = matrix_<2, 1, T>;
|
||||||
|
|
||||||
using base_type::base_type;
|
using base_type::base_type;
|
||||||
using base_type::operator = ;
|
using base_type::operator=;
|
||||||
|
|
||||||
vector2_(const base_type& m) : base_type(m) {}
|
vector2_(const base_type& m) : base_type(m) {}
|
||||||
vector2_(T x_,T y_) : base_type({x_,y_}) {}
|
vector2_(T x_, T y_) : base_type({x_, y_}) {}
|
||||||
|
|
||||||
inline const T& x() const { return (*this)[0]; }
|
constexpr const T& x() const { return (*this)[0]; }
|
||||||
inline T& x() { return (*this)[0]; }
|
constexpr T& x() { return (*this)[0]; }
|
||||||
|
|
||||||
inline const T& y() const { return (*this)[1]; }
|
constexpr const T& y() const { return (*this)[1]; }
|
||||||
inline T& y() { return (*this)[1]; }
|
constexpr T& y() { return (*this)[1]; }
|
||||||
|
|
||||||
inline auto homogenous(T w = 1) const { return matrix_<3,1,T>( { x(),y(),w } ); }
|
constexpr auto homogenous(T w = 1) const {
|
||||||
|
return matrix_<3, 1, T>({x(), y(), w});
|
||||||
static T angle_between(const vector2_ &a,const vector2_ &b) {
|
|
||||||
return std::acos( dot( a.normalized(), b.normalized() ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr auto zero() { return vector2_<T>(0,0); }
|
static T angle_between(const vector2_& a, const vector2_& b) {
|
||||||
|
return std::acos(dot(a.normalized(), b.normalized()));
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct vector3_ : matrix_<3,1,T> {
|
|
||||||
|
|
||||||
typedef matrix_<3,1,T> base_type;
|
|
||||||
|
|
||||||
using base_type::base_type;
|
|
||||||
using base_type::operator = ;
|
|
||||||
|
|
||||||
vector3_() : base_type() {}
|
|
||||||
vector3_(const base_type& m) : base_type(m) {}
|
|
||||||
vector3_(T x_,T y_,T z_) : base_type({x_,y_,z_}) {}
|
|
||||||
vector3_(const vector2_<T> &m, T w) : base_type({m(0),m(1),w}) {}
|
|
||||||
|
|
||||||
inline const T& x() const { return (*this)[0]; }
|
|
||||||
inline T& x() { return (*this)[0]; }
|
|
||||||
inline vector3_& set_x(T val) { (*this)[0] = val; return *this;}
|
|
||||||
|
|
||||||
inline const T& y() const { return (*this)[1]; }
|
|
||||||
inline T& y() { return (*this)[1]; }
|
|
||||||
inline vector3_& set_y(T val) { (*this)[1] = val; return *this;}
|
|
||||||
|
|
||||||
inline const T& z() const { return (*this)[2]; }
|
|
||||||
inline T& z() { return (*this)[2]; }
|
|
||||||
inline vector3_& set_z(T val) { (*this)[2] = val; return *this;}
|
|
||||||
|
|
||||||
inline auto xy() const { return vector2_( { x(),y() } ); }
|
|
||||||
inline auto homogenous(T w = 1) const { return matrix_<4,1,T>( { x(),y(),z(),w } ); }
|
|
||||||
|
|
||||||
inline static constexpr vector3_ cross(const vector3_& lhs,
|
|
||||||
const vector3_& rhs)
|
|
||||||
{
|
|
||||||
return vector3_( {
|
|
||||||
lhs[1] * rhs[2] - rhs[1] * lhs[2],
|
|
||||||
lhs[2] * rhs[0] - rhs[2] * lhs[0],
|
|
||||||
lhs[0] * rhs[1] - rhs[0] * lhs[1]
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static constexpr auto zero() { return vector2_<T>(0, 0); }
|
||||||
inline static constexpr vector3_<T> forward() { return vector3_<T> ( { T(0), T(0),-T(1) } ); }
|
|
||||||
inline static constexpr vector3_<T> backward() { return vector3_<T>( { T(0), T(0), T(1) } ); }
|
|
||||||
inline static constexpr vector3_<T> right() { return vector3_<T> ( { T(1), T(0), T(0) } ); }
|
|
||||||
inline static constexpr vector3_<T> left() { return vector3_<T> ( {-T(1), T(0), T(0) } ); }
|
|
||||||
inline static constexpr vector3_<T> up() { return vector3_<T> ( { T(0), T(1), T(0) } ); }
|
|
||||||
inline static constexpr vector3_<T> down() { return vector3_<T> ( { T(0),-T(1), T(0) } ); }
|
|
||||||
|
|
||||||
inline static vector3_<T> x_axis() { return vector3_<T> ( { T(1), T(0), T(0) } ); }
|
|
||||||
inline static vector3_<T> y_axis() { return vector3_<T> ( { T(0), T(1), T(0) } ); }
|
|
||||||
inline static vector3_<T> z_axis() { return vector3_<T> ( { T(0), T(0), T(1) } ); }
|
|
||||||
|
|
||||||
static constexpr auto zero() { return vector3_(0,0,0); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> struct vector3_ : matrix_<3, 1, T> {
|
||||||
struct vector4_ : matrix_<4,1,T> {
|
|
||||||
|
|
||||||
typedef matrix_<4,1,T> base_type;
|
typedef matrix_<3, 1, T> base_type;
|
||||||
|
|
||||||
using base_type::base_type;
|
// using base_type::base_type;
|
||||||
using base_type::operator = ;
|
// using base_type::operator=;
|
||||||
|
|
||||||
vector4_(T x_,T y_,T z_,T w_) : base_type( {x_,y_,z_,w_} ) {}
|
constexpr const T& x() const { return (*this)[0]; }
|
||||||
vector4_(const base_type& m) : base_type(m) {}
|
constexpr T& x() { return (*this)[0]; }
|
||||||
vector4_(const vector3_<T> &m, T w) : base_type({m(0),m(1),m(2),w}) {}
|
constexpr vector3_& set_x(T val) {
|
||||||
|
(*this)[0] = val;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
inline const T& x() const { return (*this)[0]; }
|
constexpr const T& y() const { return (*this)[1]; }
|
||||||
inline T& x() { return (*this)[0]; }
|
constexpr T& y() { return (*this)[1]; }
|
||||||
|
constexpr vector3_& set_y(T val) {
|
||||||
|
(*this)[1] = val;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
inline const T& y() const { return (*this)[1]; }
|
constexpr const T& z() const { return (*this)[2]; }
|
||||||
inline T& y() { return (*this)[1]; }
|
constexpr T& z() { return (*this)[2]; }
|
||||||
|
constexpr vector3_& set_z(T val) {
|
||||||
|
(*this)[2] = val;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
inline const T& z() const { return (*this)[2]; }
|
constexpr auto xy() const { return vector2_({x(), y()}); }
|
||||||
inline T& z() { return (*this)[2]; }
|
constexpr auto homogenous(T w = 1) const {
|
||||||
|
return matrix_<4, 1, T>::make(x(), y(), z(), w);
|
||||||
|
}
|
||||||
|
|
||||||
inline const T& w() const { return (*this)[3]; }
|
constexpr static vector3_ cross(const vector3_& lhs, const vector3_& rhs) {
|
||||||
inline T& w() { return (*this)[3]; }
|
return vector3_::make(lhs[1] * rhs[2] - rhs[1] * lhs[2],
|
||||||
|
lhs[2] * rhs[0] - rhs[2] * lhs[0],
|
||||||
|
lhs[0] * rhs[1] - rhs[0] * lhs[1]);
|
||||||
|
}
|
||||||
|
|
||||||
inline auto xyz() const { return vector3_<T>({ x(),y(),z() } ); }
|
constexpr static auto forward() { return vector3_<T>::make(0, 0, -1); }
|
||||||
|
constexpr static auto backward() { return vector3_<T>::make(0, 0, +1); }
|
||||||
|
constexpr static auto up() { return vector3_<T>::make(0, +1, 0); }
|
||||||
|
constexpr static auto down() { return vector3_<T>::make(0, -1, 0); }
|
||||||
|
constexpr static auto right() { return vector3_<T>::make(+1, 0, 0); }
|
||||||
|
constexpr static auto left() { return vector3_<T>::make(-1, 0, 0); }
|
||||||
|
constexpr static auto x_axis() { return vector3_<T>::make(0, 0, +1); }
|
||||||
|
constexpr static auto y_axis() { return vector3_<T>::make(0, 0, +1); }
|
||||||
|
constexpr static auto z_axis() { return vector3_<T>::make(0, 0, +1); }
|
||||||
|
|
||||||
inline auto project() const { return vector3_<T>({ x()/w(),y()/w(),z()/w() } ); }
|
static constexpr auto zero() { return vector3_(0, 0, 0); }
|
||||||
|
};
|
||||||
|
|
||||||
static constexpr auto zero() { return vector2_<T>(0,0,0,0); }
|
template <typename T> struct vector4_ : matrix_<4, 1, T> {
|
||||||
|
|
||||||
|
using base_type = matrix_<4, 1, T>;
|
||||||
|
// using base_type::operator=;
|
||||||
|
|
||||||
|
constexpr const T& x() const { return (*this)[0]; }
|
||||||
|
constexpr T& x() { return (*this)[0]; }
|
||||||
|
|
||||||
|
constexpr const T& y() const { return (*this)[1]; }
|
||||||
|
constexpr T& y() { return (*this)[1]; }
|
||||||
|
|
||||||
|
constexpr const T& z() const { return (*this)[2]; }
|
||||||
|
constexpr T& z() { return (*this)[2]; }
|
||||||
|
|
||||||
|
constexpr const T& w() const { return (*this)[3]; }
|
||||||
|
constexpr T& w() { return (*this)[3]; }
|
||||||
|
|
||||||
|
constexpr auto xyz() const { return vector3_<T>::make(x(), y(), z()); }
|
||||||
|
|
||||||
|
constexpr auto project() const {
|
||||||
|
return vector3_<T>::make(x() / w(), y() / w(), z() / w());
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr auto zero() { return vector2_<T>(0, 0, 0, 0); }
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
||||||
using vector2f = vector2_<float>;
|
using vector2f = vector2_<float>;
|
||||||
using vector2d = vector2_<double>;
|
using vector2d = vector2_<double>;
|
||||||
using vector2i = vector2_<int>;
|
using vector2i = vector2_<int>;
|
||||||
using vector2 = vector2_<real_t>;
|
using vector2 = vector2_<real_t>;
|
||||||
using vector2_array = std::vector<vector2>;
|
using vector2_array = std::vector<vector2>;
|
||||||
|
|
||||||
using vector3f = vector3_<float>;
|
using vector3f = vector3_<float>;
|
||||||
using vector3d = vector3_<double>;
|
using vector3d = vector3_<double>;
|
||||||
using vector3 = vector3_<real_t>;
|
using vector3 = vector3_<real_t>;
|
||||||
using vector3_array = std::vector<vector3>;
|
using vector3_array = std::vector<vector3>;
|
||||||
|
|
||||||
using vector4f = vector4_<float>;
|
using vector4f = vector4_<float>;
|
||||||
using vector4d = vector4_<double>;
|
using vector4d = vector4_<double>;
|
||||||
using vector4 = vector4_<real_t>;
|
using vector4 = vector4_<real_t>;
|
||||||
|
|
||||||
}
|
} // namespace pw
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <random>
|
#include <random>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace pw {
|
namespace pw {
|
||||||
|
|
||||||
|
|
|
@ -7,9 +7,9 @@ macro(make_test arg1)
|
||||||
endmacro()
|
endmacro()
|
||||||
|
|
||||||
|
|
||||||
make_test(pwcore_test_matrix)
|
# make_test(pwcore_test_matrix)
|
||||||
make_test(pwcore_test_vector)
|
# make_test(pwcore_test_vector)
|
||||||
make_test(pwcore_test_axisangle)
|
# make_test(pwcore_test_axisangle)
|
||||||
make_test(pwcore_test_quaternion)
|
# make_test(pwcore_test_quaternion)
|
||||||
make_test(pwcore_test_transform_tools)
|
# make_test(pwcore_test_transform_tools)
|
||||||
make_test(pwcore_test_mesh)
|
# make_test(pwcore_test_mesh)
|
||||||
|
|
|
@ -28,8 +28,6 @@ scene::scene()
|
||||||
|
|
||||||
// size_t scene::count_all_enties() const
|
// size_t scene::count_all_enties() const
|
||||||
// {
|
// {
|
||||||
// return _registry->storage().
|
|
||||||
|
|
||||||
// size_t scene::count_alive_enties() const
|
// size_t scene::count_alive_enties() const
|
||||||
// {
|
// {
|
||||||
// return _registry->storage().alive();
|
// return _registry->storage().alive();
|
||||||
|
|
21
tests/CMakeLists.txt
Normal file
21
tests/CMakeLists.txt
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
include(FetchContent)
|
||||||
|
|
||||||
|
FetchContent_Declare(snitch
|
||||||
|
GIT_REPOSITORY https://github.com/snitch-org/snitch.git
|
||||||
|
GIT_TAG v1.2.5) # update version number as needed
|
||||||
|
|
||||||
|
FetchContent_MakeAvailable(snitch)
|
||||||
|
|
||||||
|
set(pixwerx_test_files
|
||||||
|
pw_test_core.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
add_executable(pixwerx_tests ${pixwerx_test_files})
|
||||||
|
|
||||||
|
target_link_libraries(pixwerx_tests PRIVATE
|
||||||
|
snitch::snitch
|
||||||
|
pwcore
|
||||||
|
)
|
66
tests/pw_test_core.cpp
Normal file
66
tests/pw_test_core.cpp
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
#include <snitch/snitch.hpp>
|
||||||
|
|
||||||
|
#include <pw/core/matrix.hpp>
|
||||||
|
#include <pw/core/vector.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
TEST_CASE("core", "[matrix]") {
|
||||||
|
|
||||||
|
auto m44 = pw::matrix_<2, 2, float>{};
|
||||||
|
|
||||||
|
REQUIRE(m44(0, 0) == 0);
|
||||||
|
REQUIRE(m44(0, 1) == 0);
|
||||||
|
REQUIRE(m44(1, 0) == 0);
|
||||||
|
REQUIRE(m44(1, 1) == 0);
|
||||||
|
|
||||||
|
m44 = pw::matrix2x2_<float>::all(42.42f);
|
||||||
|
|
||||||
|
REQUIRE(m44(0, 0) == 42.42f);
|
||||||
|
REQUIRE(m44(0, 1) == 42.42f);
|
||||||
|
REQUIRE(m44(1, 0) == 42.42f);
|
||||||
|
REQUIRE(m44(1, 1) == 42.42f);
|
||||||
|
|
||||||
|
m44 *= 2;
|
||||||
|
REQUIRE(m44(0, 0) == 84.84f);
|
||||||
|
REQUIRE(m44(0, 1) == 84.84f);
|
||||||
|
REQUIRE(m44(1, 0) == 84.84f);
|
||||||
|
REQUIRE(m44(1, 1) == 84.84f);
|
||||||
|
|
||||||
|
m44.set_identity();
|
||||||
|
REQUIRE(m44(0, 0) == 1.0f);
|
||||||
|
REQUIRE(m44(0, 1) == 0.0f);
|
||||||
|
REQUIRE(m44(1, 0) == 0.0f);
|
||||||
|
REQUIRE(m44(1, 1) == 1.0f);
|
||||||
|
|
||||||
|
auto m44_2 = pw::matrix2x2::make(0, 1, 2, 3);
|
||||||
|
|
||||||
|
REQUIRE(m44_2(0, 0) == 0.0f);
|
||||||
|
REQUIRE(m44_2(1, 0) == 1.0f);
|
||||||
|
REQUIRE(m44_2(0, 1) == 2.0f);
|
||||||
|
REQUIRE(m44_2(1, 1) == 3.0f);
|
||||||
|
|
||||||
|
|
||||||
|
pw::matrix2x2 m44_3 = {{},{1, 2, 3, 4}};
|
||||||
|
|
||||||
|
REQUIRE(m44_3(0, 0) == 1.0f);
|
||||||
|
REQUIRE(m44_3(1, 0) == 2.0f);
|
||||||
|
REQUIRE(m44_3(0, 1) == 3.0f);
|
||||||
|
REQUIRE(m44_3(1, 1) == 4.0f);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("core", "[vector]") {
|
||||||
|
|
||||||
|
auto vec4_1 = pw::vector4_<float>{};
|
||||||
|
auto vec4_2 = pw::vector4::make(1, 2, 3, 4);
|
||||||
|
|
||||||
|
auto vec4_3 = vec4_1 + vec4_2;
|
||||||
|
|
||||||
|
REQUIRE(vec4_3[0] == 1.0f);
|
||||||
|
REQUIRE(vec4_3[1] == 2.0f);
|
||||||
|
REQUIRE(vec4_3[2] == 3.0f);
|
||||||
|
REQUIRE(vec4_3[3] == 4.0f);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue