reworking the transform tools
This commit is contained in:
parent
114f17a499
commit
6b4eb83e64
7 changed files with 126 additions and 49 deletions
|
@ -23,9 +23,9 @@
|
|||
#ifndef PW_CORE_COLOR_HPP
|
||||
#define PW_CORE_COLOR_HPP
|
||||
|
||||
#include <pw/core/globals.hpp>
|
||||
#include <pw/core/vector.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace pw {
|
||||
|
||||
|
@ -46,7 +46,9 @@ struct color {
|
|||
(v & 0x0000ff00) >> 8, (v & 0x000000ff));
|
||||
}
|
||||
|
||||
uint32_t to_rgb8888() const { return 0; }
|
||||
uint32_t to_rgb8888() const {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace pw
|
||||
|
|
|
@ -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,
|
||||
|
@ -24,6 +24,8 @@
|
|||
#define PW_CORE_GLOBALS_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -34,11 +36,9 @@ using std::shared_ptr;
|
|||
using std::unique_ptr;
|
||||
using std::weak_ptr;
|
||||
|
||||
using std::make_unique;
|
||||
using std::make_shared;
|
||||
using std::make_unique;
|
||||
|
||||
using real_t = float;
|
||||
|
||||
}
|
||||
} // namespace pw
|
||||
|
||||
#endif
|
||||
|
|
|
@ -27,9 +27,6 @@
|
|||
#include <algorithm>
|
||||
#include <numbers>
|
||||
|
||||
//#include <pw/core/matrix.hpp>
|
||||
//#include <pw/core/quaternion.hpp>
|
||||
|
||||
namespace pw {
|
||||
|
||||
constexpr double __PW_PI = 3.1415926535897932384626433832795028841971693993751058209;
|
||||
|
|
|
@ -97,6 +97,15 @@ struct matrix final {
|
|||
}(std::make_index_sequence<Rows>{});
|
||||
}
|
||||
|
||||
static constexpr auto from_diagonal(const diag_type& d) noexcept -> matrix {
|
||||
static_assert(
|
||||
Rows == Cols,
|
||||
"creating from diagonal vector only defined for square matrices");
|
||||
return [&d]<std::size_t... Rs>(std::index_sequence<Rs...>) {
|
||||
return matrix{vector<Scalar, Cols>::basis(Rs) * d[Rs]...};
|
||||
}(std::make_index_sequence<Rows>{});
|
||||
}
|
||||
|
||||
constexpr auto minor(std::unsigned_integral auto r0,
|
||||
std::unsigned_integral auto c0) const noexcept {
|
||||
static_assert(Rows > 1 && Cols > 1, "cannot create minor matrix");
|
||||
|
|
|
@ -23,40 +23,88 @@
|
|||
#ifndef PW_CORE_MATRIX_TRANSFORM_HPP
|
||||
#define PW_CORE_MATRIX_TRANSFORM_HPP
|
||||
|
||||
#include <pw/core/math.hpp>
|
||||
#include <pw/core/matrix.hpp>
|
||||
#include <pw/core/vector.hpp>
|
||||
|
||||
namespace pw {
|
||||
|
||||
template <typename T> struct matrix_transform {
|
||||
template <typename Scalar> struct frustum final {
|
||||
Scalar left{-1}, right{1}, bottom{-1}, top{1}, z_near{-1}, z_far{1};
|
||||
|
||||
constexpr static matrix_<4, 4, T>
|
||||
scale_matrix(const vector3_<T>& 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);
|
||||
return scale;
|
||||
static constexpr auto make_perspective_symmetric(Scalar fov_h_deg,
|
||||
Scalar aspect_ratio,
|
||||
Scalar z_near,
|
||||
Scalar z_far) -> frustum {
|
||||
const auto tangent_half{std::tan(pw::deg_to_rad(fov_h_deg / 2))};
|
||||
const auto top{tangent_half * z_near};
|
||||
const auto right{top * aspect_ratio};
|
||||
|
||||
return {.left = -right,
|
||||
.right = right,
|
||||
.bottom = -top,
|
||||
.top = top,
|
||||
.z_near = z_near,
|
||||
.z_far = z_far};
|
||||
}
|
||||
|
||||
constexpr auto perspective_frustum_rh(const T& left, const T& right,
|
||||
const T& bottom, const T& top,
|
||||
const T& z_near, const T& z_far) {
|
||||
matrix<T, 4, 4> frustum::identity();
|
||||
|
||||
frustum[0][0] = T(2) * z_near / (right - left);
|
||||
frustum[1][1] = T(2) * z_near / (top - bottom);
|
||||
|
||||
frustum[0][2] = (right + left) / (right - left); // A
|
||||
frustum[1][2] = (top + bottom) / (top - bottom); // B
|
||||
frustum[2][2] = -(z_far + z_near) / (z_far - z_near); // C
|
||||
frustum[2][3] = -T(2) * z_far * z_near / (z_far - z_near); // D
|
||||
|
||||
frustum[3][2] = -T(1);
|
||||
|
||||
return frustum;
|
||||
static constexpr auto make_orthographic_symmetric(Scalar scale,
|
||||
Scalar aspect_ratio,
|
||||
Scalar z_near,
|
||||
Scalar z_far) -> frustum {
|
||||
return {.left = -scale,
|
||||
.right = scale,
|
||||
.bottom = -scale * aspect_ratio,
|
||||
.top = scale * aspect_ratio,
|
||||
.z_near = z_near,
|
||||
.z_far = z_far};
|
||||
}
|
||||
};
|
||||
|
||||
struct matrix_transform {
|
||||
|
||||
template <typename Scalar>
|
||||
constexpr static auto
|
||||
scale_matrix(vector<Scalar, 4>&& diag) noexcept -> matrix<Scalar, 4, 4> {
|
||||
return matrix<Scalar, 4, 4>::from_diagonal(
|
||||
std::forward<vector<Scalar, 4>>(diag));
|
||||
}
|
||||
|
||||
template <typename Scalar>
|
||||
constexpr static auto
|
||||
frustum_matrix(const frustum<Scalar>& f) -> matrix<Scalar, 4, 4> {
|
||||
|
||||
const auto Sx{Scalar{2} * f.z_near / (f.right - f.left)};
|
||||
const auto Sy{Scalar{2} * f.z_near / (f.top - f.bottom)};
|
||||
|
||||
const auto A{(f.right + f.left) / (f.right - f.left)};
|
||||
const auto B{(f.top + f.bottom) / (f.top - f.bottom)};
|
||||
const auto C{-(f.z_far + f.z_near) / (f.z_far - f.z_near)};
|
||||
const auto D{-Scalar{2} * f.z_far * f.z_near / (f.z_far - f.z_near)};
|
||||
|
||||
// clang-format off
|
||||
return {vector{Sx, 0, A, 0},
|
||||
vector{0, Sy, B, 0},
|
||||
vector{0, 0, C, D},
|
||||
vector{0, 0, -1, Scalar{1}}};
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
template <typename Scalar>
|
||||
constexpr static auto
|
||||
look_at_matrix(vector3<Scalar> position, vector3<Scalar> target,
|
||||
vector3<Scalar> up) -> matrix<Scalar, 4, 4> {
|
||||
|
||||
const auto lofs = (target - position).normalized(); // line of sight
|
||||
const auto side = lofs.cross(up).normalized(); // side vector
|
||||
const auto upvc = side.cross(lofs).normalized(); // upvector
|
||||
|
||||
return {side.unproject(0), upvc.unproject(0),
|
||||
lofs.unproject(0) * Scalar{-1}, position.unproject(1)};
|
||||
}
|
||||
};
|
||||
|
||||
#if 0
|
||||
|
||||
// /// creates a projection from a frustum planes with a reversed depth
|
||||
// mapped to [0..1] pub fn make_projection_rh_from_frustum_reversed(
|
||||
|
@ -156,7 +204,8 @@ template <typename T> struct matrix_transform {
|
|||
|
||||
return view_matrix;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace pw
|
||||
|
||||
|
|
|
@ -8,6 +8,6 @@ make_test(pwcore_test_matrix)
|
|||
make_test(pwcore_test_axisangle)
|
||||
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)
|
||||
|
|
|
@ -1,18 +1,38 @@
|
|||
|
||||
#include <pw/core/vector.hpp>
|
||||
#include <pw/core/serialize.hpp>
|
||||
#include <pw/core/debug.hpp>
|
||||
#include <pw/core/matrix_transform.hpp>
|
||||
#include <pw/core/serialize.hpp>
|
||||
#include <pw/core/vector.hpp>
|
||||
|
||||
#include <iostream>
|
||||
auto main() -> int {
|
||||
|
||||
int main(int argc,char **argv) {
|
||||
pw::debug::d() << "pixwerx.matrix_transform.test\n";
|
||||
|
||||
auto perspective_mat = pw::matrix_transform<float>::perspective_projection(45.f,1.3f,10,100);
|
||||
auto ortho_mat = pw::matrix_transform<float>::orthographic_frustum(-1,1,1,-1,10,100);
|
||||
auto lookat_mat = pw::matrix_transform<float>::look_at(pw::vector3(0,0,5),pw::vector3(0,0,0),pw::vector3(0,1,0));
|
||||
auto scale_123 =
|
||||
pw::matrix_transform::scale_matrix<float>({1.f, 2.f, 3.f, 1.f});
|
||||
pw::debug::d() << "matrix_transform::scale(1,2,3) -> \n"
|
||||
<< pw::serialize::to_string(scale_123);
|
||||
|
||||
auto fm_default =
|
||||
pw::matrix_transform::frustum_matrix(pw::frustum<float>{});
|
||||
pw::debug::d() << "matrix_transform::frustum::default -> \n"
|
||||
<< pw::serialize::to_string(fm_default);
|
||||
|
||||
std::cout << pw::serialize::matrix(perspective_mat) << std::endl;
|
||||
std::cout << pw::serialize::matrix(ortho_mat) << std::endl;
|
||||
std::cout << pw::serialize::matrix(lookat_mat) << std::endl;
|
||||
auto fm_45deg_1dot3 = pw::matrix_transform::frustum_matrix(
|
||||
pw::frustum<float>::make_perspective_symmetric(45.f, 1.3f, 0.1f,
|
||||
1000.f));
|
||||
pw::debug::d() << "matrix_transform::frustum::45deg -> \n"
|
||||
<< pw::serialize::to_string(fm_45deg_1dot3);
|
||||
|
||||
auto fm_ortho = pw::matrix_transform::frustum_matrix(
|
||||
pw::frustum<float>::make_orthographic_symmetric(0.5f, 1.3f, 0.1f,
|
||||
1000.f));
|
||||
pw::debug::d() << "matrix_transform::frustum::ortho -> \n"
|
||||
<< pw::serialize::to_string(fm_ortho);
|
||||
|
||||
auto lookat_mat = pw::matrix_transform::look_at_matrix(
|
||||
pw::vector{0.f, 0, 5}, pw::vector{0.f, 0, 0}, pw::vector{0.f, 1, 0});
|
||||
|
||||
pw::debug::d() << "matrix_transform::look_at -> \n"
|
||||
<< pw::serialize::to_string(lookat_mat);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue