jaulib v1.3.0
Jau Support Library (C++, Java, ..)
test_math_mat4f_10_project01.cpp
Go to the documentation of this file.
1/*
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2024 Gothel Software e.K.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24#include <thread>
25#include <cassert>
26#include <cinttypes>
27#include <cstring>
28
30
32
33using namespace jau;
34using namespace jau::math;
35using namespace jau::math::util;
36
37static const float EPSILON = std::numeric_limits<float>::epsilon();
38
39/**
40 * PMVMatrix w/ separate P + Mv vs Mat4f::mapObjToWin() w/ single PMv
41 *
42 * Both using same Mat4f::mapObjToWin(..).
43 */
44TEST_CASE( "Test 01 Project PMVMatrixToMatrix4f", "[project][mat4f][linear_algebra][math]" ) {
45 // Simple 10 x 10 view port
46 const Recti viewport(0,0,10,10);
47
48 Vec3f winA00, winA01, winA10, winA11;
49 Vec3f winB00, winB01, winB10, winB11;
50
51 PMVMat4f m;
52 Mat4f mat4PMv;
53 m.getMulPMv(mat4PMv);
54 // std::cout << mat4PMv.toString(null, "mat4PMv", "%10.5f"));
55
56 m.mapObjToWin(Vec3f(1, 0, 0), viewport, winA00); // separate P + Mv
57 std::cout << "A.0.0 - Project 1,0 -->" << winA00 << std::endl;
58 Mat4f::mapObjToWin(Vec3f(1, 0, 0), mat4PMv, viewport, winB00); // single PMv
59 std::cout << "B.0.0 - Project 1,0 -->" << winB00 << std::endl;
60
61 m.mapObjToWin(Vec3f(0, 0, 0), viewport, winA01);
62 std::cout << "A.0.1 - Project 0,0 -->" << winA01 << std::endl;
63 Mat4f::mapObjToWin(Vec3f(0, 0, 0), mat4PMv, viewport, winB01);
64 std::cout << "B.0.1 - Project 0,0 -->" << winB01 << std::endl;
65
66 m.orthoP(0, 10, 0, 10, 1, -1);
67 std::cout << "MATRIX - Ortho 0,0,10,10 - Locate the origin in the bottom left and scale" << std::endl;
68 std::cout << m << std::endl;
69 m.getMulPMv(mat4PMv);
70 std::cout << mat4PMv.toString("mat4PMv", "%10.5f") << std::endl;
71
72 m.mapObjToWin(Vec3f(1, 0, 0), viewport, winA10);
73 std::cout << "A.1.0 - Project 1,0 -->" << winA10 << std::endl;
74 Mat4f::mapObjToWin(Vec3f(1, 0, 0), mat4PMv, viewport, winB10);
75 std::cout << "B.1.0 - Project 1,0 -->" << winB10 << std::endl;
76
77 m.mapObjToWin(Vec3f(0, 0, 0), viewport, winA11);
78 std::cout << "A.1.1 - Project 0,0 -->" << winA11 << std::endl;
79 Mat4f::mapObjToWin(Vec3f(0, 0, 0), mat4PMv, viewport, winB11);
80 std::cout << "B.1.1 - Project 0,0 -->" << winB11 << std::endl;
81
82 REQUIRE_MSG("A/B 0.0 Project 1,0 failure", winB00 == winA00);
83 REQUIRE_MSG("A/B 0.1 Project 0,0 failure", winB01 == winA01);
84 REQUIRE_MSG("A/B 1.0 Project 1,0 failure", winB10 == winA10);
85 REQUIRE_MSG("A/B 1.1 Project 0,0 failure", winB11 == winA11);
86}
87
88/**
89 * PMVMatrix vs Mat4f::mapObjToWin(), both w/ separate P + Mv
90 *
91 * Both using same Mat4f::mapObjToWin().
92 */
93TEST_CASE( "Test 02 Project PMVMatrixToMatrix4f 2", "[project][mat4f][linear_algebra][math]" ) {
94 // Simple 10 x 10 view port
95 const Recti viewport(0,0,10,10);
96
97 Vec3f winA00, winA01, winA10, winA11;
98 Vec3f winB00, winB01, winB10, winB11;
99
100 PMVMat4f m;
101 Mat4f mat4Mv, mat4P;
102
103 float mat4Mv_f16[16];
104 float mat4P_f16[16];
105
106 m.getMv().get(mat4Mv_f16);
107 m.getP().get(mat4P_f16);
108
109 std::cout << m.getMv().toString("mat4Mv") << std::endl;
110 std::cout << m.getP().toString("mat4P") << std::endl;
111 mat4Mv.load( mat4Mv_f16 );
112 mat4P.load( mat4P_f16 );
113 REQUIRE( Mat4f(mat4Mv_f16) == mat4Mv);
114 REQUIRE( Mat4f(mat4P_f16) == mat4P);
115 REQUIRE( m.getMv() == mat4Mv);
116 REQUIRE( m.getP() == mat4P);
117
118 m.mapObjToWin(Vec3f(1, 0, 0), viewport, winA00);
119 std::cout << "A.0.0 - Project 1,0 -->" << winA00 << std::endl;
120 Mat4f::mapObjToWin(Vec3f(1, 0, 0), mat4Mv, mat4P, viewport, winB00);
121 std::cout << "B.0.0 - Project 1,0 -->" << winB00 << std::endl;
122
123 m.mapObjToWin(Vec3f(0, 0, 0), viewport, winA01);
124 std::cout << "A.0.1 - Project 0,0 -->" << winA01 << std::endl;
125 Mat4f::mapObjToWin(Vec3f(0, 0, 0), mat4Mv, mat4P, viewport, winB01);
126 std::cout << "B.0.1 - Project 0,0 -->" << winB01 << std::endl;
127
128 m.orthoP(0, 10, 0, 10, 1, -1);
129 std::cout << "MATRIX - Ortho 0,0,10,10 - Locate the origin in the bottom left and scale" << std::endl;
130 std::cout << m << std::endl;
131 m.getMv().get(mat4Mv_f16);
132 m.getP().get(mat4P_f16);
133 std::cout << m.getMv().toString("mat4Mv") << std::endl;
134 std::cout << m.getP().toString("mat4P") << std::endl;
135 mat4Mv.load( mat4Mv_f16 );
136 mat4P.load( mat4P_f16 );
137 REQUIRE( Mat4f(mat4Mv_f16) == mat4Mv);
138 REQUIRE( Mat4f(mat4P_f16) == mat4P);
139 REQUIRE( m.getMv() == mat4Mv);
140 REQUIRE( m.getP() == mat4P);
141
142 m.mapObjToWin(Vec3f(1, 0, 0), viewport, winA10);
143 std::cout << "A.1.0 - Project 1,0 -->" << winA10 << std::endl;
144 Mat4f::mapObjToWin(Vec3f(1, 0, 0), mat4Mv, mat4P, viewport, winB10);
145 std::cout << "B.1.0 - Project 1,0 -->" << winB10 << std::endl;
146
147 m.mapObjToWin(Vec3f(0, 0, 0), viewport, winA11);
148 std::cout << "A.1.1 - Project 0,0 -->" << winA11 << std::endl;
149 Mat4f::mapObjToWin(Vec3f(0, 0, 0), mat4Mv, mat4P, viewport, winB11);
150 std::cout << "B.1.1 - Project 0,0 -->" << winB11 << std::endl;
151
152 REQUIRE_MSG("A/B 0.0 Project 1,0 failure", winB00 == winA00);
153 REQUIRE_MSG("A/B 0.1 Project 0,0 failure", winB01 == winA01);
154 REQUIRE_MSG("A/B 1.0 Project 1,0 failure", winB10 == winA10);
155 REQUIRE_MSG("A/B 1.1 Project 0,0 failure", winB11 == winA11);
156}
157
158TEST_CASE( "Test 10 Project Matrix4f 1", "[project][mat4f][linear_algebra][math]" ) {
159 Vec3f winHas;
160 Vec2f winExp( 297, 360 );
161
162 Recti viewport(0, 0, 1280, 720);
163
164 Mat4f mat4Mv ({
165 0.40000000596046450000f, 0.00000000000000000000f, 0.00000000000000000000f, 0.00000000000000000000f,
166 0.00000000000000000000f, 0.40000000596046450000f, 0.00000000000000000000f, 0.00000000000000000000f,
167 0.00000000000000000000f, 0.00000000000000000000f, 1.00000000000000000000f, 0.00000000000000000000f,
168 -0.09278385341167450000f, -0.00471283448860049250f, -0.20000000298023224000f, 1.00000000000000000000f });
169
170 Mat4f mat4P ({
171 1.35799503326416020000f, 0.00000000000000000000f, 0.00000000000000000000f, 0.00000000000000000000f,
172 0.00000000000000000000f, 2.41421341896057130000f, 0.00000000000000000000f, 0.00000000000000000000f,
173 0.00000000000000000000f, 0.00000000000000000000f, -1.00002861022949220000f, -1.00000000000000000000f,
174 0.00000000000000000000f, 0.00000000000000000000f, -0.20000286400318146000f, 0.00000000000000000000f });
175
176 Vec3f objPos(0.02945519052445888500f, 0.01178207620978355400f, -0.00499999988824129100f);
177
178 std::cout << "pMv" << std::endl;
179 std::cout << mat4Mv.toString("", "%25.20f") << std::endl;
180 std::cout << "pP" << std::endl;
181 std::cout << mat4P.toString("", "%25.20f") << std::endl;
182
183 Mat4f::mapObjToWin(objPos, mat4Mv, mat4P, viewport, winHas);
184 std::cout << "B.0.0 - Project 1,0 -->" << winHas << std::endl;
185
186 REQUIRE_THAT( winExp.x, Catch::Matchers::WithinAbs(std::round(winHas.x), EPSILON) );
187 REQUIRE_THAT( winExp.y, Catch::Matchers::WithinAbs(std::round(winHas.y), EPSILON) );
188}
189
190TEST_CASE( "Test 11 Project Matrix4f 2", "[project][mat4f][linear_algebra][math]" ) {
191 Vec3f winHas;
192 Vec2f winExp( 136, 360 );
193
194 Recti viewport(0, 0, 1280, 720);
195
196 // m30 (row 3, column 0) differs from test01
197 Mat4f mat4Mv({
198 0.40000000596046450000f, 0.00000000000000000000f, 0.00000000000000000000f, 0.00000000000000000000f,
199 0.00000000000000000000f, 0.40000000596046450000f, 0.00000000000000000000f, 0.00000000000000000000f,
200 0.00000000000000000000f, 0.00000000000000000000f, 1.00000000000000000000f, 0.00000000000000000000f,
201 -0.13065303862094880000f, -0.00471283448860049250f, -0.20000000298023224000f, 1.00000000000000000000f });
202
203 Mat4f mat4P({
204 1.35799503326416020000f, 0.00000000000000000000f, 0.00000000000000000000f, 0.00000000000000000000f,
205 0.00000000000000000000f, 2.41421341896057130000f, 0.00000000000000000000f, 0.00000000000000000000f,
206 0.00000000000000000000f, 0.00000000000000000000f, -1.00002861022949220000f, -1.00000000000000000000f,
207 0.00000000000000000000f, 0.00000000000000000000f, -0.20000286400318146000f, 0.00000000000000000000f });
208
209 Vec3f objPos(0.02945519052445888500f, 0.01178207620978355400f, -0.00499999988824129100f);
210
211 std::cout << "pMv" << std::endl;
212 std::cout << mat4Mv.toString("", "%25.20ff") << std::endl;
213 std::cout << "pP" << std::endl;
214 std::cout << mat4P.toString("", "%25.20ff") << std::endl;
215
216 Mat4f::mapObjToWin(objPos, mat4Mv, mat4P, viewport, winHas);
217 std::cout << "B.0.0 - Project 1,0 -->" << winHas << std::endl;
218
219 REQUIRE_THAT( winExp.x, Catch::Matchers::WithinAbs(std::round(winHas.x), EPSILON) );
220 REQUIRE_THAT( winExp.y, Catch::Matchers::WithinAbs(std::round(winHas.y), EPSILON) );
221}
#define REQUIRE_MSG(MSG,...)
Definition: catch2_ext.hpp:58
Basic 4x4 value_type matrix implementation using fields for intensive use-cases (host operations).
Definition: mat4f.hpp:112
constexpr value_type get(const jau::nsize_t i) const noexcept
Returns the ith component of the given column-major order matrix, 0 <= i < 16, w/o boundary check.
Definition: mat4f.hpp:306
std::string toString(const std::string &rowPrefix, const std::string &f) const noexcept
Returns a formatted string representation of this matrix.
Definition: mat4f.hpp:1841
constexpr Matrix4 & load(const_iterator src) noexcept
Load the values of the given matrix src to this matrix w/o boundary check.
Definition: mat4f.hpp:264
Rectangle with x, y, width and height integer components.
Definition: recti.hpp:43
value_type x
Definition: vec2f.hpp:68
value_type y
Definition: vec2f.hpp:69
value_type x
Definition: vec3f.hpp:72
value_type y
Definition: vec3f.hpp:73
PMVMatrix4 implements the basic computer graphics Matrix4 pack using projection (P),...
Definition: pmvmat4f.hpp:84
constexpr void orthoP(const float left, const float right, const float bottom, const float top, const float zNear, const float zFar) noexcept
Multiply the projection matrix with the orthogonal matrix.
Definition: pmvmat4f.hpp:812
constexpr Mat4 & getP() noexcept
Returns the projection matrix (P).
Definition: pmvmat4f.hpp:281
constexpr Mat4 & getMv() noexcept
Returns the modelview matrix (Mv).
Definition: pmvmat4f.hpp:302
constexpr Mat4 & getMulPMv(Mat4 &result) noexcept
Returns multiplication result of P and Mv matrix, i.e.
Definition: pmvmat4f.hpp:421
bool mapObjToWin(const Vec3 &objPos, const Recti &viewport, Vec3 &winPos) noexcept
Map object coordinates to window coordinates.
Definition: pmvmat4f.hpp:871
Matrix4< float > Mat4f
Definition: mat4f.hpp:1881
Vector3F< float > Vec3f
Definition: vec3f.hpp:371
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
Definition: backtrace.hpp:32
TEST_CASE("Test 01 Project PMVMatrixToMatrix4f", "[project][mat4f][linear_algebra][math]")
PMVMatrix w/ separate P + Mv vs Mat4f::mapObjToWin() w/ single PMv.
static const float EPSILON