This commit is contained in:
Hartmut Seichter 2024-07-13 00:29:47 +02:00
parent 2919c47e99
commit 114f17a499
13 changed files with 327 additions and 519 deletions

View file

@ -1,5 +1,5 @@
# first build dependencies # first build dependencies
# add_subdirectory(deps) add_subdirectory(deps)
# build internal core # build internal core
add_subdirectory(core) add_subdirectory(core)

View file

@ -8,7 +8,6 @@ set(hdrs
include/pw/core/globals.hpp include/pw/core/globals.hpp
include/pw/core/material.hpp include/pw/core/material.hpp
include/pw/core/math.hpp include/pw/core/math.hpp
include/pw/core/matrixbase.hpp
include/pw/core/matrix.hpp include/pw/core/matrix.hpp
include/pw/core/quaternion.hpp include/pw/core/quaternion.hpp
include/pw/core/image.hpp include/pw/core/image.hpp

View file

@ -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,
@ -24,39 +24,31 @@
#define PW_CORE_COLOR_HPP #define PW_CORE_COLOR_HPP
#include <pw/core/vector.hpp> #include <pw/core/vector.hpp>
#include <limits>
#include <cstdint>
namespace pw { namespace pw {
struct color { struct color {
vector4 rgba {0, 0, 0, 1}; vector4f rgba{vector4f::all(1)};
color() = default; static constexpr auto from_rgb8888(uint8_t r8, uint8_t g8, uint8_t b8,
uint8_t a8) -> color {
color(uint8_t r8,uint8_t g8,uint8_t b8,uint8_t a8) return {static_cast<float>(r8) / std::numeric_limits<uint8_t>::max(),
: color(static_cast<real_t>(r8 / std::numeric_limits<uint8_t>::max()), static_cast<float>(g8) / std::numeric_limits<uint8_t>::max(),
static_cast<real_t>(g8 / std::numeric_limits<uint8_t>::max()), static_cast<float>(b8) / std::numeric_limits<uint8_t>::max(),
static_cast<real_t>(b8 / std::numeric_limits<uint8_t>::max()), static_cast<float>(a8) / std::numeric_limits<uint8_t>::max()};
static_cast<real_t>(a8 / std::numeric_limits<uint8_t>::max()))
{
} }
color(real_t r,real_t g,real_t b,real_t a) static constexpr auto from_rgb8888(uint32_t v) -> color {
: rgba({r,g,b,a}) return from_rgb8888((v & 0xff000000) >> 24, (v & 0x00ff0000) >> 16,
{ (v & 0x0000ff00) >> 8, (v & 0x000000ff));
} }
color(const vector4& v) : rgba(v) { } uint32_t to_rgb8888() const { return 0; }
operator vector4() const { return rgba; }
uint32_t to_rgb8888() const {
return 0;
}
}; };
} } // namespace pw
#endif #endif

View file

@ -26,9 +26,11 @@
#include <pw/core/globals.hpp> #include <pw/core/globals.hpp>
#include <pw/core/math.hpp> #include <pw/core/math.hpp>
#include <pw/core/vector.hpp> #include <pw/core/vector.hpp>
#include <utility> #include <utility>
namespace pw { namespace pw {
template <typename Scalar, unsigned int Rows, unsigned int Cols> template <typename Scalar, unsigned int Rows, unsigned int Cols>
struct matrix final { struct matrix final {
@ -69,8 +71,7 @@ struct matrix final {
}(std::make_index_sequence<diag_size>{}); }(std::make_index_sequence<diag_size>{});
} }
constexpr auto constexpr auto column(const unsigned int& c) const noexcept -> column_type {
column(std::unsigned_integral auto c) const noexcept -> column_type {
return [this, &c]<std::size_t... Rs>(std::index_sequence<Rs...>) { return [this, &c]<std::size_t... Rs>(std::index_sequence<Rs...>) {
return column_type{(*this)[Rs][c]...}; return column_type{(*this)[Rs][c]...};
}(std::make_index_sequence<Cols>{}); }(std::make_index_sequence<Cols>{});

View file

@ -1,198 +0,0 @@
/*
* Copyright (c) 1999-2021 Hartmut Seichter
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* 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 SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
#ifndef PW_CORE_MATRIXBASE_HPP
#define PW_CORE_MATRIXBASE_HPP
#include <algorithm>
#include <iterator>
#include <numeric>
#include <type_traits>
#include <cmath>
namespace pw {
template <typename T, typename Derived>
struct matrixbase_ {
using value_type = T;
using derived_type = Derived;
using iterator = value_type*;
using const_iterator = const value_type*;
constexpr Derived& derived() noexcept { return static_cast<Derived&>(*this); }
constexpr const Derived& derived() const noexcept { return static_cast<const Derived&>(*this); }
constexpr std::size_t size() const noexcept {
return std::extent<decltype(Derived::data)>::value;
}
constexpr Derived& fill(const T& v) noexcept {
std::fill(std::begin(derived().data), std::end(derived().data), T(v));
return derived();
}
constexpr Derived& zero() {
return derived().fill(0);
}
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;
});
}
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());
}
constexpr Derived normalized() const noexcept {
return *this / this->norm() ;
}
constexpr void normalize() {
*this /= this->norm();
}
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];
}
constexpr const T& operator [] (std::size_t i) const {
return derived().data[i];
}
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) noexcept
{
return a + (b - a) * t;
}
//
// M (op) scalar
//
constexpr Derived operator*(const T& b) const {
Derived r(derived());
for (auto& e : r)
e *= b;
return r;
}
constexpr Derived operator/(const T& b) const {
Derived r(derived());
for (auto& e : r)
e /= b;
return r;
}
constexpr Derived operator+(const T& b) const {
Derived r(derived());
for (auto& e : r)
e += b;
return r;
}
constexpr Derived operator-(const T& b) const {
Derived r(derived());
for (auto& e : r)
e -= b;
return r;
}
//
// M (op)== N
//
constexpr void operator*=(const std::convertible_to<T> auto& b) {
for (auto& e : derived())
e *= b;
}
constexpr void operator/=(const std::convertible_to<T> auto& b) {
for (auto& e : derived())
e /= b;
}
constexpr void operator+=(const std::convertible_to<T> auto& b) {
for (auto& e : derived())
e += b;
}
constexpr void operator-=(const std::convertible_to<T> auto& b) {
for (auto& e : derived())
e -= b;
}
//
// M (op) N
//
/// @brief in-place addition with matrix of same size
/// @param rhs righthand-side matrix
constexpr void operator+=(const Derived& b) noexcept {
std::transform(b.cbegin(), b.cend(), (*this).cbegin(), (*this).begin(),
std::plus<>{});
}
/// @brief in-place subtraction with matrix of same size
/// @param rhs righthand-side matrix
constexpr void operator-=(const Derived& b) noexcept {
std::transform(b.cbegin(), b.cend(), (*this).cbegin(), (*this).begin(),
std::minus<>{});
}
/// @brief addition with matrix of same size
/// @param rhs righthand-side matrix
constexpr Derived operator+(const std::convertible_to<Derived> auto& rhs) const noexcept {
Derived d{derived()};
std::transform(std::begin(rhs), std::end(rhs), (d).begin(), std::plus<>{});
return d;
}
/// @brief subtraction with matrix of same size
/// @param rhs righthand-side matrix
constexpr Derived operator-(const Derived& rhs) const noexcept {
Derived d(derived());
d -= rhs;
return d;
}
};
}
#endif

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999-2021 Hartmut Seichter * Copyright (c) 1999-2024 Hartmut Seichter
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -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,
@ -23,61 +23,143 @@
#ifndef PW_CORE_QUATERNION_HPP #ifndef PW_CORE_QUATERNION_HPP
#define PW_CORE_QUATERNION_HPP #define PW_CORE_QUATERNION_HPP
#include <pw/core/vector.hpp> #include <pw/core/matrix.hpp>
#include <pw/core/axisangle.hpp> #include <pw/core/axisangle.hpp>
#include <pw/core/vector.hpp>
#include <concepts>
namespace pw { namespace pw {
/** /**
* simplified quaternion class * simplified quaternion class
*/ */
template <typename T> template <std::floating_point Scalar> struct quaternion final {
struct quaternion_ : vector4_<T> {
typedef vector4_<T> base_type; using value_type = vector<Scalar, 4>;
using typename base_type::value_type; value_type q_{value_type::basis(3)}; // preset to identity
using base_type::base_type;
using base_type::x;
using base_type::y;
using base_type::z;
using base_type::w;
using base_type::lerp;
using base_type::xyz;
// using base_type::operator*;
// using base_type::operator/;
auto&& x(this auto&& self) {
return std::forward<decltype(self)>(self).q_.x();
}
auto&& y(this auto&& self) {
return std::forward<decltype(self)>(self).q_.y();
}
auto&& z(this auto&& self) {
return std::forward<decltype(self)>(self).q_.z();
}
auto&& w(this auto&& self) {
return std::forward<decltype(self)>(self).q_.w();
}
quaternion_(const base_type& other) : base_type(other) {} constexpr auto
operator*(const quaternion& rhs) const noexcept -> quaternion {
return {rhs.w() * x() + rhs.x() * w() + rhs.y() * z() - rhs.z() * y(),
rhs.w() * y() - rhs.x() * z() + rhs.y() * w() + rhs.z() * x(),
rhs.w() * z() + rhs.x() * y() - rhs.y() * x() + rhs.z() * w(),
rhs.w() * w() - rhs.x() * x() - rhs.y() * y() - rhs.z() * z()};
}
inline const quaternion_ operator * (const quaternion_& rhs) const { constexpr auto conjugate() const noexcept -> quaternion {
return {-x(), -y(), -z(), w()};
}
constexpr auto norm() const noexcept -> Scalar { return q_.norm(); }
constexpr auto operator*(const Scalar& rhs) const noexcept -> quaternion {
return {.q_ = q_ * rhs};
}
constexpr auto operator/(const Scalar& rhs) const noexcept -> quaternion {
return operator*(Scalar{1} / rhs);
}
constexpr auto normalized() const noexcept -> quaternion {
return {.q_ = q_.normalized()};
}
constexpr auto inverse() const noexcept -> quaternion {
return conjugate() / this->norm();
}
constexpr auto to_matrix() const noexcept -> matrix<Scalar, 3, 3> {
const Scalar xx = x() * x();
const Scalar xy = x() * y();
const Scalar xz = x() * z();
const Scalar xw = x() * w();
const Scalar yy = y() * y();
const Scalar yz = y() * z();
const Scalar yw = y() * w();
const Scalar zz = z() * z();
const Scalar zw = z() * w();
return {
vector{1 - 2 * (yy + zz), 2 * (xy - zw), 2 * (xz + yw)},
vector{2 * (xy + zw), 1 - 2 * (xx + zz), 2 * (yz - xw)},
vector{2 * (xz - yw), 2 * (yz + xw), 1 - 2 * (xx + yy)},
};
}
static constexpr auto identity() noexcept -> quaternion { return {}; }
static constexpr auto pi_around_x() noexcept -> quaternion {
return {Scalar{1}, Scalar{0}, Scalar{0}, Scalar{0}};
}
static constexpr auto pi_around_y() noexcept -> quaternion {
return {Scalar{0}, Scalar{1}, Scalar{0}, Scalar{0}};
}
static constexpr auto pi_around_z() noexcept -> quaternion {
return {Scalar{0}, Scalar{0}, Scalar{1}, Scalar{0}};
}
static constexpr auto lerp(const quaternion& a, const quaternion& b,
const Scalar& t) -> quaternion {
return {value_type::lerp(a.q_, b.q_, t).normalized()};
}
};
// deduction guide for quaternion
template <class T, class... U, class CT = std::common_type_t<T, U...>>
quaternion(T, U...) -> quaternion<CT>;
#if 0
constexpr quaternion_ operator*(const quaternion_& rhs) const {
return quaternion_( return quaternion_(
rhs.w() * x() + rhs.x() * w() + rhs.y() * z() - rhs.z() * y(), rhs.w() * x() + rhs.x() * w() + rhs.y() * z() - rhs.z() * y(),
rhs.w() * y() - rhs.x() * z() + rhs.y() * w() + rhs.z() * x(), rhs.w() * y() - rhs.x() * z() + rhs.y() * w() + rhs.z() * x(),
rhs.w() * z() + rhs.x() * y() - rhs.y() * x() + rhs.z() * w(), rhs.w() * z() + rhs.x() * y() - rhs.y() * x() + rhs.z() * w(),
rhs.w()*w() - rhs.x()*x() - rhs.y()*y() - rhs.z()*z() rhs.w() * w() - rhs.x() * x() - rhs.y() * y() - rhs.z() * z());
);
} }
inline auto operator/(const T& rhs) const { inline auto operator/(const T& rhs) const {
return quaternion_( { x() / rhs, y() / rhs, z() / rhs, w() / rhs, } ); return quaternion_({
x() / rhs,
y() / rhs,
z() / rhs,
w() / rhs,
});
} }
//! conjugate //! conjugate
inline auto conjugate() const { return quaternion_( { -x(),-y(),-z(),w() } ); } inline auto conjugate() const {
return quaternion_({-x(), -y(), -z(), w()});
}
//! compute inverse //! compute inverse
inline auto inverse() const { inline auto inverse() const { return conjugate() / this->norm(); }
return conjugate() / this->norm();
}
inline static auto identity() { inline static auto identity() { return quaternion_({0, 0, 0, 1}); }
return quaternion_({0,0,0,1});
}
const matrix4x4_<T> to_matrix() const { const matrix4x4_<T> to_matrix() const {
matrix4x4_<T> m; m.set_identity(); matrix4x4_<T> m;
m.set_identity();
T xx = x() * x(); T xx = x() * x();
T xy = x() * y(); T xy = x() * y();
@ -110,27 +192,26 @@ struct quaternion_ : vector4_<T> {
using std::sqrt; using std::sqrt;
auto wtemp = sqrt(T(1) + m(0, 0) + m(1, 1) + m(2, 2)) / T(2); auto wtemp = sqrt(T(1) + m(0, 0) + m(1, 1) + m(2, 2)) / T(2);
auto w4 = T(4.0) * wtemp; auto w4 = T(4.0) * wtemp;
return quaternion_({ return quaternion_({(m(2, 1) - m(1, 2)) / w4, (m(0, 2) - m(2, 0)) / w4,
(m(2,1) - m(1,2)) / w4, (m(1, 0) - m(0, 1)) / w4, wtemp});
(m(0,2) - m(2,0)) / w4,
(m(1,0) - m(0,1)) / w4,
wtemp});
} }
static auto normalized_lerp(const quaternion_ &a,const quaternion_ &b,const T &t) { static auto normalized_lerp(const quaternion_& a, const quaternion_& b,
const T& t) {
return quaternion_(lerp(a, b, t).normalized()); return quaternion_(lerp(a, b, t).normalized());
} }
static auto slerp(const quaternion_& qa,const quaternion_& qb,const T& t) static auto slerp(const quaternion_& qa, const quaternion_& qb,
{ const T& t) {
using std::abs; using std::abs;
using std::sqrt;
using std::acos; using std::acos;
using std::sqrt;
// quaternion to return // quaternion to return
quaternion_ qm; quaternion_ qm;
// Calculate angle between them. // Calculate angle between them.
T cosHalfTheta = qa.w() * qb.w() + qa.x() * qb.x() + qa.y() * qb.y() + qa.z() * qb.z(); T cosHalfTheta = qa.w() * qb.w() + qa.x() * qb.x() + qa.y() * qb.y() +
qa.z() * qb.z();
// if qa=qb or qa=-qb then theta = 0 and we can return qa // if qa=qb or qa=-qb then theta = 0 and we can return qa
if (abs(cosHalfTheta) >= T(1)) { if (abs(cosHalfTheta) >= T(1)) {
return qa; return qa;
@ -159,36 +240,24 @@ struct quaternion_ : vector4_<T> {
return qm; return qm;
} }
static auto from_axisangle(const axisangle_<T>& aa) { static auto from_axisangle(const axisangle_<T>& aa) {
using std::sin;
using std::cos; using std::cos;
using std::sin;
const T sinHalfAngle(sin(aa.angle * T(0.5))); const T sinHalfAngle(sin(aa.angle * T(0.5)));
return quaternion_<T>( { aa.axis.x() * sinHalfAngle, // x return quaternion_<T>({
aa.axis.x() * sinHalfAngle, // x
aa.axis.y() * sinHalfAngle, // y aa.axis.y() * sinHalfAngle, // y
aa.axis.z() * sinHalfAngle, // z aa.axis.z() * sinHalfAngle, // z
cos(aa.angle * T(0.5)) // w cos(aa.angle * T(0.5)) // w
} });
);
} }
}; };
// #endif
//
//
using quaternion = quaternion_<real_t>;
using quaternionf = quaternion_<float>;
using quaterniond = quaternion_<double>;
}
} // namespace pw
#if 0 #if 0
/** /**
@ -412,9 +481,6 @@ const quaternion_<T> quaternion_<T>::slerp(const quaternion_<T>& qa,const quater
return qm; return qm;
} }
#endif #endif
#endif #endif

View file

@ -28,18 +28,15 @@
namespace pw { namespace pw {
class resource { struct resource final {
public:
using change_t = std::atomic_int_fast64_t; using change_t = std::atomic_int_fast64_t;
resource() = default; constexpr int64_t changecount() const noexcept { return changecount_; }
void touch() { ++changecount_; };
int64_t changecount() const { return _changecount; }
void dirty() { ++_changecount; };
protected: protected:
change_t changecount_{};
change_t _changecount;
}; };
} }

View file

@ -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,
@ -23,12 +23,15 @@
#ifndef PW_CORE_SERIALIZE_HPP #ifndef PW_CORE_SERIALIZE_HPP
#define PW_CORE_SERIALIZE_HPP #define PW_CORE_SERIALIZE_HPP
#include "vector.hpp" #include <pw/core/axisangle.hpp>
#include <pw/core/matrix.hpp> #include <pw/core/matrix.hpp>
#include <pw/core/quaternion.hpp>
#include <pw/core/vector.hpp>
#include <pw/core/color.hpp>
#include <string>
#include <sstream> #include <sstream>
#include <string>
namespace pw { namespace pw {
@ -37,7 +40,8 @@ struct serialize {
template <typename T, auto N> template <typename T, auto N>
constexpr static std::string to_string(const vector<T, N>& v) { constexpr static std::string to_string(const vector<T, N>& v) {
std::stringstream ss; std::stringstream ss;
for(const auto& e : v) ss << e << ' '; for (const auto& e : v)
ss << e << ' ';
return ss.str(); return ss.str();
} }
@ -52,9 +56,20 @@ struct serialize {
return ss.str(); return ss.str();
} }
template <typename T>
}; constexpr static std::string to_string(const quaternion<T>& v) {
std::stringstream ss;
ss << to_string(v.q_);
return ss.str();
} }
constexpr static std::string to_string(const color& v) {
std::stringstream ss;
ss << to_string(v.rgba);
return ss.str();
}
};
} // namespace pw
#endif #endif

View file

@ -1,15 +1,13 @@
macro(make_test arg1) macro(make_test arg1)
add_executable(${arg1} add_executable(${arg1} ${arg1}.cpp)
${arg1}.cpp target_link_libraries(${arg1} pwcore)
)
target_link_libraries(${arg1}
pwcore)
endmacro() endmacro()
# make_test(pwcore_test_matrix)
make_test(pwcore_test_vector) make_test(pwcore_test_vector)
make_test(pwcore_test_matrix)
make_test(pwcore_test_axisangle) make_test(pwcore_test_axisangle)
# make_test(pwcore_test_quaternion) make_test(pwcore_test_quaternion)
make_test(pwcore_test_color)
# make_test(pwcore_test_transform_tools) # make_test(pwcore_test_transform_tools)
# make_test(pwcore_test_mesh) # make_test(pwcore_test_mesh)

View file

@ -0,0 +1,20 @@
#include <cstdio>
#include <pw/core/color.hpp>
#include <pw/core/debug.hpp>
#include <pw/core/serialize.hpp>
auto main() -> int {
pw::debug::d() << "pixwerx.color.test\n";
auto col = pw::color::from_rgb8888(255,0,0,255);
pw::debug::d() << "col -> \n" << pw::serialize::to_string(col);
auto col_hx = pw::color::from_rgb8888(0xFF'EE'BB'AA);
pw::debug::d() << "col_hx(0xFFAABBAA) -> \n" << pw::serialize::to_string(col_hx);
return 0;
}

View file

@ -1,130 +1,41 @@
#include <pw/core/matrix.hpp>
#include <pw/core/vector.hpp>
#include <pw/core/serialize.hpp>
#include <pw/core/debug.hpp> #include <pw/core/debug.hpp>
#include <pw/core/matrix.hpp>
#include <pw/core/serialize.hpp>
#include <pw/core/vector.hpp>
#include <iostream> auto main() -> int {
#include <sstream>
pw::debug::d() << "pixwerx.matrix.test\n";
int main(int argc,char **argv) { auto m22 = pw::matrix<float, 2, 2>{};
pw::debug::d() << "matrix<2,2>{} -> \n" << pw::serialize::to_string(m22);
using namespace pw; m22[0][0] = 1;
m22[0][1] = 2;
matrix2x2f m22; m22.zero(); m22[1][0] = 3;
m22[1][1] = 4;
m22(0,0) = 1; m22(0,1) = 2;
m22(1,0) = 3; m22(1,1) = 4;
vector2f v2;
v2[0] = 1; v2[1] = 3;
vector2f v3( { 1.f,2.f } );
pw::debug::d() << "matrix<2,2>{1,2,3,4} -> \n"
<< pw::serialize::to_string(m22);
auto m22_inv = m22.inverse(); auto m22_inv = m22.inverse();
auto m22_id = m22_inv * m22;
auto v2_t = m22_id * v2; pw::debug::d() << "matrix<2,2>{1,2,3,4}.inverse() -> \n"
auto v3_t = m22_id * v3; << pw::serialize::to_string(m22_inv);
auto v2_f = m22 * v2; auto m22_inv_inv = m22_inv.inverse();
auto v2_b = m22_inv * v2_f; pw::debug::d() << "matrix<2,2>{1,2,3,4}.inverse().inverse() -> \n"
<< pw::serialize::to_string(m22_inv_inv);
vector2_<float> r_m22 = m22.row(0).transposed(); auto row_1 = m22_inv[1];
vector2_<float> c_m22 = m22.column(1); pw::debug::d() << "matrix<2,2>{1,2,3,4}.inverse()[1] -> \n"
<< pw::serialize::to_string(row_1);
auto r_m22_h = r_m22.homogenous(); auto m22_tp = m22.transposed();
pw::debug::d() << "matrix<2,2>{1,2,3,4}.transposed() -> \n"
<< pw::serialize::to_string(m22_tp);
debug::d() << "offset(0,1) col-major " << m22.offset(0,1); auto m22_tp_col1 = m22_tp.column(1);
debug::d() << "det " << m22.determinant(); pw::debug::d() << "matrix<2,2>{1,2,3,4}.transposed().column(1) -> \n"
<< pw::serialize::to_string(m22_tp_col1);
std::cout << "m22 " << pw::serialize::matrix(m22) << std::endl;
std::cout << "m22-1 " << pw::serialize::matrix(m22_inv) << std::endl;
std::cout << "m22-i " << pw::serialize::matrix(m22_id) << std::endl;
std::cout << "v22_t " << pw::serialize::matrix(v2_t) << std::endl;
std::cout << "v3_t " << pw::serialize::matrix(v3_t) << std::endl;
std::cout << "v2_f " << pw::serialize::matrix(v2_f) << std::endl;
std::cout << "v2_b " << pw::serialize::matrix(v2_b) << std::endl;
std::cout << "v2_b.norm " << v2_b.norm() << std::endl;
// v2_b.normalize();
std::cout << "v2_b.normalized " << pw::serialize::matrix(v2_b.normalized()) << std::endl;
// std::cout << "v2_b~v3_t " << rad_to_deg(vector2f::angle_between(v2,v3)) << std::endl;
// vector2f v2 = m22.slice<2,1>(0,0);
// m22.set_slice<2,1>(v2,0,0);
// v2 *= 2;
// v2 += 1;
// m22 *= 3;
// m22.determinant();
// debug::d() << sizeof(v2);
// auto m22_i = m22.inverse();
#if 0
pw::matrix4x4d m;
m.set_identity();
std::cout << "m = " << pw::serialize::matrix(m) << std::endl;
std::cout << "row_stride() : " << m.row_stride() << std::endl;
std::cout << "col_stride() : " << m.col_stride() << std::endl;
std::cout << "rows() : " << m.rows() << std::endl;
std::cout << "cols() : " << m.cols() << std::endl;
std::cout << "data() : " << m.data() << std::endl;
std::cout << "data()[0] : " << m.data()[0] << std::endl;
std::cout << "at(0,0) : " << m.at(0,0) << std::endl;
std::cout << "determinant(): " << m.determinant() << std::endl;
pw::matrix4x4d mi = m.get_inverse();
std::cout << "mi.at(0,0) : " << mi.at(0,0) << std::endl;
pw::matrix4x4d mscale = m * 4.2;
std::cout << "mscale = " << pw::serialize::matrix(mscale) << std::endl;
pw::matrix4x4d a;
for (int r = 0; r < m.rows(); r++) {
for (int c = 0; c < m.cols(); c++) {
a.at(r,c) = r * m.cols() + c;
}
}
std::cout << "a = " << pw::serialize::matrix(a) << std::endl;
pw::matrix4x4d r = a * mscale;
std::cout << "a * mscale = " << pw::serialize::matrix(r) << std::endl;
return 0;
#endif
} }

View file

@ -1,29 +1,36 @@
#include <pw/core/debug.hpp>
#include <pw/core/quaternion.hpp> #include <pw/core/quaternion.hpp>
#include <pw/core/serialize.hpp> #include <pw/core/serialize.hpp>
#include <iostream> auto main() -> int {
int main(int argc,char **argv) { pw::debug::d() << "pixwerx.quaternion.test\n";
pw::quaternion_<float> qf; auto q0 = pw::quaternion<float>{};
auto q1 = pw::quaternion{1.f, 2.f, 3.f, 4.f};
std::cout << "qf = " << pw::serialize::matrix(qf) << std::endl; pw::debug::d() << "q0 = quaternion{} -> \n" << pw::serialize::to_string(q0);
std::cout << "qf.matrix() = " << pw::serialize::matrix(qf.to_matrix()) << std::endl; pw::debug::d() << "q1 = quaternion{1,2,3,4} -> \n"
<< pw::serialize::to_string(q1);
std::cout << "qf.squared_norm() = " << qf.squared_norm() << std::endl; auto q0_x_q1 = q0 * q1;
// std::cout << "qf.dot(qf) = " << qf.dot(qf) << std::endl; pw::debug::d() << "q0 * q1 -> \n" << pw::serialize::to_string(q0_x_q1);
std::cout << "qf.conjugate() = " << pw::serialize::matrix(qf.conjugate()) << std::endl;
pw::quaternionf qc = qf.conjugate(); auto q1_conj = q1.conjugate();
std::cout << "qf.conjugate() (qc) = " << pw::serialize::matrix(qc.to_matrix()) << std::endl; pw::debug::d() << "q1.conjugate() -> \n"
<< pw::serialize::to_string(q1_conj);
pw::quaternionf qi = qf.inverse(); auto q1_conj_nml = q1_conj.normalized();
std::cout << "qf.inverse() (qi) = " << pw::serialize::matrix(qi.to_matrix()) << std::endl; pw::debug::d() << "q1.conjugate().normalized() -> \n"
<< pw::serialize::to_string(q1_conj_nml);
pw::quaternionf qmid = pw::quaternionf::normalized_lerp(qi,qf,0.5f);
// std::cout << "qmid.dot() (half between qf and qi) = " << pw::rad_to_deg(quaternionf::angle_between()) << std::endl;
auto q1_conj_inv = q1_conj.inverse();
pw::debug::d() << "q1.conjugate().inverse() -> \n"
<< pw::serialize::to_string(q1_conj_inv);
auto lerp_q0_q1_half = decltype(q0)::lerp(q0, q1, 0.5f);
pw::debug::d() << "quaternion::lerp(q0,q1,0.5) -> \n"
<< pw::serialize::to_string(lerp_q0_q1_half);
return 0; return 0;

View file

@ -38,4 +38,4 @@ target_include_directories(
include include
) )
target_link_libraries(pwvisual pwscene glad) target_link_libraries(pwvisual pwcore pwscene glad)