diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..7917bc4 --- /dev/null +++ b/.clang-format @@ -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 diff --git a/.vscode/settings.json b/.vscode/settings.json index 36bf36d..7482615 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -16,7 +16,41 @@ "stdexcept": "cpp", "streambuf": "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 } \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 52ddf60..f1f52cb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,15 +1,15 @@ # # CMake build system for pixwerx # -cmake_minimum_required(VERSION 3.8) +cmake_minimum_required(VERSION 3.28) project(pixwerx) # -# pixwerx ist C++20 +# pixwerx ist C++23 # -set (CMAKE_CXX_STANDARD 20) +set (CMAKE_CXX_STANDARD 23) # internal cmake modules 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(share) +add_subdirectory(tests) diff --git a/README.md b/README.md index d9547ed..09ab938 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,27 @@ -# pixwerx +# pixwerx -pixwerx is an opinionated, academic approach to a 3D engine. It tries to mix -modern andproven methods to build a fast and portable engine beyond pure 3D. +pixwerx is an opinionated, academic approach to a 3D graphics engine. It mixes +modern and proven methods to build a fast and portable graphics system. ## Design Principles -Dogdooding: pixwerx is built on the principle of dogfooding. The engine is a -full-stack system that tries to implement all necessary functions. The engine +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 editor is just a UI build with the engine. -Reasonable dependencies: like many engines pixwerx tries to include as much 3rd- -party code as possible and implements some of the core systems itself. +Reasonable dependencies: like many engines pixwerx tries to include as much 3rd-party code as possible and implements some of the core systems itself. -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. +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. -Computer graphics 101: pixwerx does implement graphics components and systems in -a way that makes code portable and not over-parameterized. Usability is -achieved through layers on top of the core components. +Computer graphics 101: pixwerx does implement graphics components and systems in a way that makes code portable and not over-parameterized. Usability is +achieved through layers on top of the core components. ## 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. ## Authors © 1999-2020 Hartmut Seichter - - - - diff --git a/share/CMakeLists.txt b/share/CMakeLists.txt index 0ad654b..3cf5d0d 100644 --- a/share/CMakeLists.txt +++ b/share/CMakeLists.txt @@ -1,4 +1,4 @@ -find_package(mkdocs 1.0) +# find_package(mkdocs 1.0) # if(MKDOCS_FOUND) # configure_file(mkdocs.yml "${CMAKE_CURRENT_BINARY_DIR}/mkdocs.yml" COPYONLY) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 92925fa..3dd3765 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,15 +1,15 @@ # first build dependencies -add_subdirectory(deps) +# add_subdirectory(deps) # build internal core add_subdirectory(core) -add_subdirectory(scene) -add_subdirectory(system) -add_subdirectory(io) +# add_subdirectory(scene) +# add_subdirectory(system) +# add_subdirectory(io) #add_subdirectory(ui) -add_subdirectory(binding) -add_subdirectory(visual) -add_subdirectory(geometry) +# add_subdirectory(binding) +# add_subdirectory(visual) +# add_subdirectory(geometry) -add_subdirectory(runtime) +# add_subdirectory(runtime) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index f592f11..c11b65a 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -33,14 +33,14 @@ set(misc set(srcs # src/buffer.cpp src/core.cpp - src/image.cpp - src/debug.cpp - src/geometry.cpp - src/material.cpp - src/resource.cpp - src/serialize.cpp - src/time.cpp - src/image.cpp + # src/image.cpp + # src/debug.cpp + # src/geometry.cpp + # src/material.cpp + # src/resource.cpp + # src/serialize.cpp + # src/time.cpp + # src/image.cpp ) add_library(pwcore @@ -58,5 +58,5 @@ target_include_directories( target_link_libraries(pwcore) -add_subdirectory(tests) +# add_subdirectory(tests) diff --git a/src/core/include/pw/core/aabb.hpp b/src/core/include/pw/core/aabb.hpp index ada4cd1..4a36324 100644 --- a/src/core/include/pw/core/aabb.hpp +++ b/src/core/include/pw/core/aabb.hpp @@ -8,8 +8,8 @@ * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -29,24 +29,12 @@ namespace pw { struct aabb { - vector3 min; - 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; - } + vector3 min{}; + vector3 max{}; + constexpr vector3 dimension() const noexcept { return max - min; } }; -} +} // namespace pw #endif diff --git a/src/core/include/pw/core/axisangle.hpp b/src/core/include/pw/core/axisangle.hpp index 0ad6575..cda1b3b 100644 --- a/src/core/include/pw/core/axisangle.hpp +++ b/src/core/include/pw/core/axisangle.hpp @@ -31,23 +31,12 @@ template struct axisangle_ { using value_type = T; - using axis_type = vector3_; + using axis_type = vector3_; // todo - should default to UP - axis_type axis; - T angle; + axis_type axis{}; + T angle{}; - axisangle_() - : axis(vector3_::up()), - angle(0) - {} - - axisangle_(vector3_ axis,T angle) - : axis(std::move(axis)) - , angle(std::move(angle)) - { - } - - static const axisangle_ from_matrix(const matrix_<4,4,T>& m) + static axisangle_ from_matrix(const matrix_<4,4,T>& m) { using std::acos; using std::sqrt; diff --git a/src/core/include/pw/core/material.hpp b/src/core/include/pw/core/material.hpp index 7e1dd98..374be53 100644 --- a/src/core/include/pw/core/material.hpp +++ b/src/core/include/pw/core/material.hpp @@ -58,13 +58,10 @@ public: using texture_t = std::tuple; - - protected: + vector4 _color = {{}, {1.0, 0.0, 1.0, 1.0}}; - vector4 _color = vector4 { 1.0, 0.0, 1.0, 1.0 }; - - std::vector _textures; + std::vector _textures; }; diff --git a/src/core/include/pw/core/matrix.hpp b/src/core/include/pw/core/matrix.hpp index afacaea..09756ef 100644 --- a/src/core/include/pw/core/matrix.hpp +++ b/src/core/include/pw/core/matrix.hpp @@ -8,8 +8,8 @@ * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -27,253 +27,213 @@ #include #include +// #include #include -#include -namespace pw -{ +namespace pw { - template - struct matrix_ : matrixbase_> - { - T data[R * C]; +template +struct matrix_ : matrixbase_> { - using matrixbase_>::matrixbase_; + using base_type = matrixbase_>; + using typename base_type::value_type; + using typename base_type::derived_type; - static constexpr std::size_t rows{R}; - static constexpr std::size_t cols{C}; + static constexpr std::size_t rows{R}; + 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_; + using row_type = matrix_<1, C, T>; + using diag_type = matrix_; + using transpose_type = matrix_; - using col_type = matrix_; - using row_type = matrix_<1, C, T>; - using transpose_type = matrix_; - matrix_ &operator=(const matrix_ &other) - { - for (size_t i = 0; i < other.size(); i++) - (*this)[i] = other[i]; - return *this; - } + value_type data[R * C]{}; - matrix_(std::initializer_list args) - { - typename std::initializer_list::iterator it = args.begin(); - for (; it != args.end(); it++) - data[it - args.begin()] = *it; - } - template - matrix_ &set(Arguments... values) - { - static_assert(sizeof...(Arguments) == R * C, "Incorrect number of arguments"); - data = {values...}; - return *this; - } + template + static constexpr auto make(Arguments&&... values) -> matrix_ { + static_assert(sizeof...(Arguments) == coefficients, + "Incorrect number of arguments"); + return {.data = { T(values)... } }; + } - inline size_t offset(size_t r, size_t c) const - { - return (RowMajor) ? r * C + c : c * R + r; - } + constexpr size_t offset(size_t r, size_t c) const noexcept { + return (RowMajor) ? r * C + c : c * R + r; + } - inline T &operator()(std::size_t r, std::size_t c) - { - return data[offset(r, c)]; - } + constexpr T& operator()(std::size_t r, std::size_t c) noexcept { + return data[offset(r, c)]; + } - inline const T &operator()(std::size_t r, std::size_t c) const - { - return data[offset(r, c)]; - } + constexpr const T& operator()(std::size_t r, std::size_t c) const noexcept { + return data[offset(r, c)]; + } - inline const T *ptr() const { return &data[0]; } + constexpr const T* ptr() const noexcept { return &data[0]; } - //! set identity - inline matrix_ &set_identity() - { - for (std::size_t r = 0; r < rows; r++) - for (std::size_t c = 0; c < cols; c++) - (*this)(r, c) = (c == r) ? T(1) : T(0); - return *this; - } + //! set identity + constexpr matrix_& set_identity() { + for (std::size_t r = 0; r < rows; r++) + for (std::size_t c = 0; c < cols; c++) + (*this)(r, c) = (c == r) ? T(1) : T(0); + return *this; + } - inline matrix_ &set_uniform(const T& v) - { - std::fill(std::begin(data),std::end(data),v); - return *this; - } + constexpr matrix_& set_uniform(const T& v) { + std::fill(std::begin(data), std::end(data), v); + return *this; + } - template - auto slice(std::size_t r, std::size_t c) const - { - matrix_ s; - for (std::size_t ri = 0; ri < Rs; ri++) - for (std::size_t ci = 0; ci < Cs; ci++) - s(ri, ci) = (*this)(ri + r, ci + c); - return s; - } + template + auto slice(std::size_t r, std::size_t c) const { + matrix_ s; + for (std::size_t ri = 0; ri < Rs; ri++) + for (std::size_t ci = 0; ci < Cs; ci++) + s(ri, ci) = (*this)(ri + r, ci + c); + return s; + } - template - matrix_ &set_slice(const matrix_ &s, - std::size_t r, std::size_t c) - { - for (std::size_t ri = 0; ri < Rs; ri++) - for (std::size_t ci = 0; ci < Cs; ci++) - (*this)(ri + r, ci + c) = s(ri, ci); - return *this; - } + template + matrix_& set_slice(const matrix_& s, + std::size_t r, std::size_t c) { + for (std::size_t ri = 0; ri < Rs; ri++) + for (std::size_t ci = 0; ci < Cs; ci++) + (*this)(ri + r, ci + c) = s(ri, ci); + return *this; + } - template - auto minor(std::size_t r0, std::size_t c0) const - { - matrix_ m; - size_t r = 0; - for (size_t ri = 0; ri < R; ri++) - { - size_t c = 0; - if (ri == r0) - continue; - for (size_t ci = 0; ci < C; ci++) - { - if (ci == c0) - continue; - m(r, c) = (*this)(ri, ci); - c++; - } - r++; - } - return m; - } + template + auto minor(std::size_t r0, std::size_t c0) const { + matrix_ m; + size_t r = 0; + for (size_t ri = 0; ri < R; ri++) { + size_t c = 0; + if (ri == r0) + continue; + for (size_t ci = 0; ci < C; ci++) { + if (ci == c0) + continue; + m(r, c) = (*this)(ri, ci); + c++; + } + r++; + } + return m; + } - T determinant() const - { - T det(0); - for (size_t c = 0; c < C; c++) - det += ((c % 2 == 0) ? (*this)(0, c) : -(*this)(0, c)) * this->minor(0, c).determinant(); - return det; - } + constexpr T determinant() const { + T det(0); + for (size_t c = 0; c < C; c++) + det += ((c % 2 == 0) ? (*this)(0, c) : -(*this)(0, c)) * + this->minor(0, c).determinant(); + return det; + } - auto transposed() const - { - transpose_type res; - for (size_t r = rows; r-- > 0;) - for (size_t c = cols; c-- > 0;) - res(c, r) = (*this)(r, c); - return res; - } + auto transposed() const { + transpose_type res; + for (size_t r = rows; r-- > 0;) + for (size_t c = cols; c-- > 0;) + res(c, r) = (*this)(r, c); + return res; + } - auto inverse() const - { - T invDet = T(1) / this->determinant(); - matrix_ inv; - for (int j = 0; j < C; j++) - for (int i = 0; i < R; i++) - { - const T minorDet = this->minor(j, i).determinant(); - const T coFactor = ((i + j) % 2 == 1) ? -minorDet : minorDet; - inv(i, j) = invDet * coFactor; - } - return inv; - } + auto inverse() const { + T invDet = T(1) / this->determinant(); + matrix_ inv; + for (int j = 0; j < C; j++) + for (int i = 0; i < R; i++) { + const T minorDet = + this->minor(j, i).determinant(); + const T coFactor = ((i + j) % 2 == 1) ? -minorDet : minorDet; + inv(i, j) = invDet * coFactor; + } + return inv; + } - inline bool row_major() const - { - return RowMajor; - } + constexpr bool row_major() const { return RowMajor; } - inline bool square() const { return R == C; } + constexpr bool square() const { return R == C; } - inline const matrix_ operator+(const matrix_ &other) const - { - matrix_ res(*this); - for (size_t r = 0; r < R; r++) - for (size_t c = 0; c < C; c++) - res(r, c) += other(r, c); - return res; - } + constexpr const matrix_ operator+(const matrix_& other) const { + matrix_ res(*this); + for (size_t r = 0; r < R; r++) + for (size_t c = 0; c < C; c++) + res(r, c) += other(r, c); + return res; + } - inline const matrix_ operator-(const matrix_ &other) const - { - matrix_ res(*this); - for (size_t r = 0; r < R; r++) - for (size_t c = 0; c < C; c++) - res(r, c) -= other(r, c); - return res; - } + constexpr const matrix_ operator-(const matrix_& other) const { + matrix_ res(*this); + for (size_t r = 0; r < R; r++) + for (size_t c = 0; c < C; c++) + res(r, c) -= other(r, c); + return res; + } - auto row(size_t row_) const - { - row_type r; - for (size_t i = 0; i < cols; i++) - r[i] = (*this)(row_, i); - return r; - } + auto row(size_t row_) const { + row_type r; + for (size_t i = 0; i < cols; i++) + r[i] = (*this)(row_, i); + return r; + } - auto column(size_t col_) const - { - col_type c; - for (size_t i = 0; i < rows; i++) - c[i] = (*this)(i, col_); - return c; - } + auto column(size_t col_) const { + col_type c; + for (size_t i = 0; i < rows; i++) + c[i] = (*this)(i, col_); + return c; + } - static constexpr auto identity() - { - matrix_ res; - for (std::size_t r = 0; r < rows; r++) - for (std::size_t c = 0; c < cols; c++) - res(r, c) = (c == r) ? T(1) : T(0); - return res; - } - }; + static constexpr auto identity() { + matrix_ res; + for (std::size_t r = 0; r < rows; r++) + for (std::size_t c = 0; c < cols; c++) + res(r, c) = (c == r) ? T(1) : T(0); + return res; + } +}; - template <> - inline float matrix_<1, 1, float>::determinant() const - { - return (*this)(0, 0); - } - - template <> - inline double matrix_<1, 1, double>::determinant() const - { - return (*this)(0, 0); - } - - template - auto operator*(const matrix_ &A, - const matrix_ &B) - { - matrix_ 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 - using matrix2x2_ = matrix_<2, 2, T>; - template - using matrix3x3_ = matrix_<3, 3, T>; - template - using matrix4x4_ = matrix_<4, 4, T>; - - using matrix2x2f = matrix2x2_; - using matrix2x2d = matrix2x2_; - using matrix2x2 = matrix2x2_; - - using matrix3x3f = matrix3x3_; - using matrix3x3d = matrix3x3_; - using matrix3x3 = matrix3x3_; - - using matrix4x4f = matrix4x4_; - using matrix4x4d = matrix4x4_; - using matrix4x4 = matrix4x4_; +template <> constexpr float matrix_<1, 1, float>::determinant() const { + return (*this)(0, 0); } +template <> constexpr double matrix_<1, 1, double>::determinant() const { + return (*this)(0, 0); +} + +template +auto operator*(const matrix_& A, const matrix_& B) { + matrix_ 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 using matrix2x2_ = matrix_<2, 2, T>; +template using matrix3x3_ = matrix_<3, 3, T>; +template using matrix4x4_ = matrix_<4, 4, T>; + +using matrix2x2f = matrix2x2_; +using matrix2x2d = matrix2x2_; +using matrix2x2 = matrix2x2_; + +using matrix3x3f = matrix3x3_; +using matrix3x3d = matrix3x3_; +using matrix3x3 = matrix3x3_; + +using matrix4x4f = matrix4x4_; +using matrix4x4d = matrix4x4_; +using matrix4x4 = matrix4x4_; +} // namespace pw + #endif diff --git a/src/core/include/pw/core/matrix_transform.hpp b/src/core/include/pw/core/matrix_transform.hpp index 7131fe3..467b54a 100644 --- a/src/core/include/pw/core/matrix_transform.hpp +++ b/src/core/include/pw/core/matrix_transform.hpp @@ -30,8 +30,7 @@ namespace pw { template struct matrix_transform { - inline static - matrix_<4,4,T> scale_matrix(const vector3_& s) + constexpr static matrix_<4,4,T> scale_matrix(const vector3_& s) noexcept { 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); diff --git a/src/core/include/pw/core/matrixbase.hpp b/src/core/include/pw/core/matrixbase.hpp index e3f3a3d..abedbcd 100644 --- a/src/core/include/pw/core/matrixbase.hpp +++ b/src/core/include/pw/core/matrixbase.hpp @@ -24,93 +24,97 @@ #define PW_CORE_MATRIXBASE_HPP #include -#include #include #include #include -#include -#include #include -#include - namespace pw { template struct matrixbase_ { using value_type = T; + using derived_type = Derived; + using iterator = value_type*; + using const_iterator = const value_type*; - Derived& derived() { return static_cast(*this); } - const Derived& derived() const { return static_cast(*this); } + constexpr Derived& derived() noexcept { return static_cast(*this); } + constexpr const Derived& derived() const noexcept { return static_cast(*this); } - std::size_t size() const { + constexpr std::size_t size() const noexcept { return std::extent::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)); return derived(); } - Derived& zero() { + constexpr Derived& zero() { 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), [&](const T& a,const T& b){ return a + b * b; }); } - inline T norm() const { + static constexpr Derived + all(const std::convertible_to auto& v) noexcept { + Derived d; + d.fill(v); + return d; + } + + constexpr T norm() const noexcept { return std::sqrt(squared_norm()); } - inline constexpr Derived normalized() const { + constexpr Derived normalized() const noexcept { return *this / this->norm() ; } - inline void normalize() { + constexpr void normalize() { *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]; } - const T& operator [] (std::size_t i) const { + constexpr const T& operator [] (std::size_t i) const { 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)); } - 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; } - inline void operator *= (const T& b) { for (auto & e : *this) e *= b; } - inline void operator /= (const T& b) { for (auto & e : *this) e /= b; } - inline 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; } + constexpr void operator /= (const T& b) { for (auto & e : *this) e /= b; } + constexpr 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; } - inline 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; } - 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; } + constexpr 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; } + constexpr const Derived operator - (const T& b) const { Derived r(derived()); for (auto & e : r) e -= b; return r; } }; diff --git a/src/core/include/pw/core/vector.hpp b/src/core/include/pw/core/vector.hpp index 08a28d3..a1227a0 100644 --- a/src/core/include/pw/core/vector.hpp +++ b/src/core/include/pw/core/vector.hpp @@ -8,8 +8,8 @@ * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -31,138 +31,130 @@ namespace pw { * Basic vector types used in pixwerx. */ -template -struct vector2_ : matrix_<2,1,T> { +template 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::operator = ; + using base_type::operator=; 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]; } - inline T& x() { return (*this)[0]; } + constexpr const T& x() const { return (*this)[0]; } + constexpr T& x() { return (*this)[0]; } - inline const T& y() const { return (*this)[1]; } - inline T& y() { return (*this)[1]; } + constexpr const T& y() const { return (*this)[1]; } + constexpr T& y() { return (*this)[1]; } - inline 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() ) ); + constexpr auto homogenous(T w = 1) const { + return matrix_<3, 1, T>({x(), y(), w}); } - static constexpr auto zero() { return vector2_(0,0); } - -}; - -template -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_ &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 T angle_between(const vector2_& a, const vector2_& b) { + return std::acos(dot(a.normalized(), b.normalized())); } - - inline static constexpr vector3_ forward() { return vector3_ ( { T(0), T(0),-T(1) } ); } - inline static constexpr vector3_ backward() { return vector3_( { T(0), T(0), T(1) } ); } - inline static constexpr vector3_ right() { return vector3_ ( { T(1), T(0), T(0) } ); } - inline static constexpr vector3_ left() { return vector3_ ( {-T(1), T(0), T(0) } ); } - inline static constexpr vector3_ up() { return vector3_ ( { T(0), T(1), T(0) } ); } - inline static constexpr vector3_ down() { return vector3_ ( { T(0),-T(1), T(0) } ); } - - inline static vector3_ x_axis() { return vector3_ ( { T(1), T(0), T(0) } ); } - inline static vector3_ y_axis() { return vector3_ ( { T(0), T(1), T(0) } ); } - inline static vector3_ z_axis() { return vector3_ ( { T(0), T(0), T(1) } ); } - - static constexpr auto zero() { return vector3_(0,0,0); } + static constexpr auto zero() { return vector2_(0, 0); } }; -template -struct vector4_ : matrix_<4,1,T> { +template struct vector3_ : matrix_<3, 1, T> { - typedef matrix_<4,1,T> base_type; + typedef matrix_<3, 1, T> base_type; - using base_type::base_type; - using base_type::operator = ; + // using base_type::base_type; + // using base_type::operator=; - vector4_(T x_,T y_,T z_,T w_) : base_type( {x_,y_,z_,w_} ) {} - vector4_(const base_type& m) : base_type(m) {} - vector4_(const vector3_ &m, T w) : base_type({m(0),m(1),m(2),w}) {} + constexpr const T& x() const { return (*this)[0]; } + constexpr T& x() { return (*this)[0]; } + constexpr vector3_& set_x(T val) { + (*this)[0] = val; + return *this; + } - inline const T& x() const { return (*this)[0]; } - inline T& x() { return (*this)[0]; } + constexpr const T& y() const { return (*this)[1]; } + 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]; } - inline T& y() { return (*this)[1]; } + constexpr const T& z() const { return (*this)[2]; } + 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]; } - inline T& z() { return (*this)[2]; } + constexpr auto xy() const { return vector2_({x(), y()}); } + 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]; } - inline T& w() { return (*this)[3]; } + constexpr static vector3_ cross(const vector3_& lhs, const vector3_& rhs) { + 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_({ x(),y(),z() } ); } + constexpr static auto forward() { return vector3_::make(0, 0, -1); } + constexpr static auto backward() { return vector3_::make(0, 0, +1); } + constexpr static auto up() { return vector3_::make(0, +1, 0); } + constexpr static auto down() { return vector3_::make(0, -1, 0); } + constexpr static auto right() { return vector3_::make(+1, 0, 0); } + constexpr static auto left() { return vector3_::make(-1, 0, 0); } + constexpr static auto x_axis() { return vector3_::make(0, 0, +1); } + constexpr static auto y_axis() { return vector3_::make(0, 0, +1); } + constexpr static auto z_axis() { return vector3_::make(0, 0, +1); } - inline auto project() const { return vector3_({ x()/w(),y()/w(),z()/w() } ); } + static constexpr auto zero() { return vector3_(0, 0, 0); } +}; - static constexpr auto zero() { return vector2_(0,0,0,0); } +template 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_::make(x(), y(), z()); } + + constexpr auto project() const { + return vector3_::make(x() / w(), y() / w(), z() / w()); + } + + static constexpr auto zero() { return vector2_(0, 0, 0, 0); } }; // // // -using vector2f = vector2_; -using vector2d = vector2_; -using vector2i = vector2_; -using vector2 = vector2_; +using vector2f = vector2_; +using vector2d = vector2_; +using vector2i = vector2_; +using vector2 = vector2_; using vector2_array = std::vector; -using vector3f = vector3_; -using vector3d = vector3_; -using vector3 = vector3_; +using vector3f = vector3_; +using vector3d = vector3_; +using vector3 = vector3_; using vector3_array = std::vector; using vector4f = vector4_; using vector4d = vector4_; using vector4 = vector4_; -} +} // namespace pw #endif diff --git a/src/core/src/image.cpp b/src/core/src/image.cpp index 43b52a4..83ce110 100644 --- a/src/core/src/image.cpp +++ b/src/core/src/image.cpp @@ -3,6 +3,7 @@ #include #include +#include namespace pw { diff --git a/src/core/tests/CMakeLists.txt b/src/core/tests/CMakeLists.txt index 895d118..a358baf 100644 --- a/src/core/tests/CMakeLists.txt +++ b/src/core/tests/CMakeLists.txt @@ -7,9 +7,9 @@ macro(make_test arg1) endmacro() -make_test(pwcore_test_matrix) -make_test(pwcore_test_vector) -make_test(pwcore_test_axisangle) -make_test(pwcore_test_quaternion) -make_test(pwcore_test_transform_tools) -make_test(pwcore_test_mesh) +# make_test(pwcore_test_matrix) +# make_test(pwcore_test_vector) +# make_test(pwcore_test_axisangle) +# make_test(pwcore_test_quaternion) +# make_test(pwcore_test_transform_tools) +# make_test(pwcore_test_mesh) diff --git a/src/scene/src/scene.cpp b/src/scene/src/scene.cpp index b984613..0194622 100644 --- a/src/scene/src/scene.cpp +++ b/src/scene/src/scene.cpp @@ -28,8 +28,6 @@ scene::scene() // size_t scene::count_all_enties() const // { -// return _registry->storage(). - // size_t scene::count_alive_enties() const // { // return _registry->storage().alive(); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..a654f1f --- /dev/null +++ b/tests/CMakeLists.txt @@ -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 + ) diff --git a/tests/pw_test_core.cpp b/tests/pw_test_core.cpp new file mode 100644 index 0000000..3c736e7 --- /dev/null +++ b/tests/pw_test_core.cpp @@ -0,0 +1,66 @@ +#include + +#include +#include + + +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_::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_{}; + 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); + + + +}