diff --git a/src/core/include/pw/core/transform_tools.hpp b/src/core/include/pw/core/transform_tools.hpp new file mode 100644 index 0000000..0941774 --- /dev/null +++ b/src/core/include/pw/core/transform_tools.hpp @@ -0,0 +1,144 @@ +/* + * Copyright (c) 1999-2019 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_TRANSFORM_TOOLS_HPP +#define PW_CORE_TRANSFORM_TOOLS_HPP + +#include + +namespace pw { + +template +struct transform_tools { + + inline static + matrix_<4,4,T> scale_matrix(const vector3_& s) + { + 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; + } + + inline static + matrix_<4,4,T> projection_from_frustum(T left,T right,T bottom,T top,T z_near,T z_far) + { + matrix_<4,4,T> frustum; frustum.zero(); + + frustum(0,0) = T(2) * z_near / (right - left); + frustum(1,1) = T(2) * z_near / (top - bottom); + + frustum(2,0) = (right+left)/(right-left); //A + frustum(2,1) = (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; + } + + inline static + matrix_<4,4,T> orthogonal_projection(T left, T right, + T bottom,T top, + T z_near, T z_far) + { + + matrix_<4,4,T> ortho; + + ortho.fill(0); + ortho(0,0) = 2 / (right-left); + ortho(1,1) = 2 / (top-bottom); + ortho(2,2) = -2 / (z_far-z_near); + + ortho(0,3) = -(right+left)/(right-left); + ortho(1,3) = -(top+bottom)/(top-bottom); + ortho(2,3) = -(z_far+z_near)/(z_far-z_near); + + ortho(3,3) = 1; + + return ortho; + } + + inline static + matrix_<4,4,T> perspective_projection(T fov_y, T aspect_ratio, T z_near, T z_far) + { + const T height = z_near * tan(fov_y/T(360) * pi()); // half height of near plane + const T width = height * aspect_ratio; // half width of near plane + + return projection_from_frustum(-width, width, -height, height, z_near, z_far ); + } + + inline static + matrix_<4,4,T> look_at( + const vector3_ &eye, + const vector3_ &target, + const vector3_ &up) + { + matrix_<4,4,T> view_matrix; view_matrix.set_identity(); + const vector3_ L = (target - eye).normalized(); // line of sight + + const vector3_ S = L.cross(up).normalized(); + const vector3_ Ud = S.cross(L).normalized(); + + // set base vectors + view_matrix.set_slice(S, 0,0); + view_matrix.set_slice(Ud, 0,1); + view_matrix.set_slice(L*T(-1), 0,2); + view_matrix.set_slice(eye, 0,3); + + return view_matrix; + + + // matrix<3,1,T> S = matrix31::Cross(L,up); + // S.normalize(); + // matrix<3,1,T> Ud = matrix31::Cross(S,L); + // Ud.normalize(); + + // lookat(0,0) = S.at(0); + // lookat(0,1) = S.at(1); + // lookat(0,2) = S.at(2); + // lookat(0,3) = T(0); + + // lookat(1,0) = Ud.at(0); + // lookat(1,1) = Ud.at(1); + // lookat(1,2) = Ud.at(2); + // lookat(1,3) = T(0); + + // lookat(2,0) = -L.at(0); + // lookat(2,1) = -L.at(1); + // lookat(2,2) = -L.at(2); + // lookat(3,2) = T(0); + + // lookat(3,0) = eye.at(0); + // lookat(3,1) = eye.at(1); + // lookat(3,2) = eye.at(2); + // lookat(3,3) = 1; + + // return lookat; + + } + +}; + +} + +#endif diff --git a/src/core/src/transform_tools.cpp b/src/core/src/transform_tools.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/core/tests/pwcore_test_mesh.cpp b/src/core/tests/pwcore_test_mesh.cpp new file mode 100644 index 0000000..a84e739 --- /dev/null +++ b/src/core/tests/pwcore_test_mesh.cpp @@ -0,0 +1,47 @@ +#include +#include +#include +#include +#include + +#include + +int main(int argc,char **argv) { + + pw::mesh amesh; + + pw::mesh::vertex3array_t vs = { {-1,-1,0},{1,-1,0},{0,1,0} }; + amesh.set_vertices(vs); + + for (auto v : amesh.vertices()) { + std::cout << pw::serialize::matrix(v.transposed()) << std::endl; + } + + auto scale = pw::transform_tools::scale_matrix({2,2,2}); + + amesh.apply(scale); + + std::cout << "after scale" << std::endl; + + for (auto v : amesh.vertices()) { + std::cout << pw::serialize::matrix(v.transposed()) << std::endl; + } + + pw::axisangle aa; + + aa.axis = pw::vector3({ 0, 0, 1 }); + aa.angle = pw::deg_to_rad(90.0f); + + auto rot_mat = aa.to_matrix(); + + amesh.apply(rot_mat); + + std::cout << "after rotate" << std::endl; + + for (auto v : amesh.vertices()) { + std::cout << pw::serialize::matrix(v.transposed()) << std::endl; + } + + + +} diff --git a/src/core/tests/pwcore_test_transform_tools.cpp b/src/core/tests/pwcore_test_transform_tools.cpp new file mode 100644 index 0000000..d1bfd6c --- /dev/null +++ b/src/core/tests/pwcore_test_transform_tools.cpp @@ -0,0 +1,18 @@ + +#include +#include +#include + +#include + +int main(int argc,char **argv) { + + auto perspective_mat = pw::transform_tools::perspective_projection(45.f,1.3f,10,100); + auto ortho_mat = pw::transform_tools::orthogonal_projection(-1,1,1,-1,10,100); + auto lookat_mat = pw::transform_tools::look_at(pw::vector3(0,0,5),pw::vector3(0,0,0),pw::vector3(0,1,0)); + + + 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; +}