jaulib v1.3.8
Jau Support Library (C++, Java, ..)
Loading...
Searching...
No Matches
pmvmat4f.hpp
Go to the documentation of this file.
1/*
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright Gothel Software e.K.
4 *
5 * SPDX-License-Identifier: MIT
6 *
7 * This Source Code Form is subject to the terms of the MIT License
8 * If a copy of the MIT was not distributed with this file,
9 * you can obtain one at https://opensource.org/license/mit/.
10 */
11
12#ifndef JAU_MATH_UTIL_PMVMAT4f_HPP_
13#define JAU_MATH_UTIL_PMVMAT4f_HPP_
14
15#include <cmath>
16#include <cstdarg>
17#include <cstdint>
18#include <cassert>
19#include <string>
20#include <iostream>
21
22#include <jau/debug.hpp>
23#include <jau/functional.hpp>
24#include <jau/basic_types.hpp>
25#include <jau/math/mat4f.hpp>
30
31namespace jau::math::util {
32
33 /** \addtogroup Math
34 *
35 * @{
36 */
37
38
39/**
40 * PMVMatrix4 implements the basic computer graphics Matrix4 pack using
41 * projection (P), modelview (Mv) and texture (T) Matrix4 operations.
42 *
43 * PMVMatrix4 provides the {@link #getMvi() inverse modelview matrix (Mvi)} and
44 * {@link #getMvit() inverse transposed modelview matrix (Mvit)}.
45 * {@link Frustum} is also provided by {@link #getFrustum()}.
46 *
47 * To keep these derived values synchronized after mutable Mv operations like {@link #rotateMv(Quaternion)}
48 * users have to call {@link #update()} before using Mvi and Mvit.
49 *
50 * All matrices are provided in column-major order,
51 * as specified in the OpenGL fixed function pipeline, i.e. compatibility profile.
52 * See Matrix4.
53 *
54 * Maintaining the inverse projection provides conversion to and from view space.
55 *
56 * Passing the view or inverse-view matrix to map-functions
57 * allows conversion to and from world space.
58 *
59 * - view = V x M x Obj = Mv x Obj
60 * - world = V' x Mv x Obj = V' x V x M x Obj = M x Obj
61 * - clip = P x V x M x Obj = P x Mv x Obj
62 * etc ..
63 *
64 * PMVMatrix4 can supplement {@link com.jogamp.opengl.GL2ES2 GL2ES2} applications w/ the
65 * lack of the described matrix functionality.
66 *
67 * <a name="storageDetails"><h5>Matrix storage details</h5></a>
68 * The native data layout of the matrices are preserved, linear and can be utilized by `GLUniformData`
69 * directly to be pushed to the GPU eventually via SyncMatrix4 and SyncMatrices4,
70 * both SyncBuffer specializations for Matrix4.
71 *
72 * SyncBuffer's provided `sync_action_t` ensures that derived matrices, e.g. getMvi(), are updated before use.
73 *
74 * SyncBuffer's `sync_action_t` is called by `GLUniformData::getBuffer()`
75 * i.e. before the data is pushed to the GPU.
76 */
77
78template<typename Value_type,
79 std::enable_if_t<std::is_floating_point_v<Value_type>, bool> = true>
81 public:
84 typedef const value_type* const_pointer;
88 typedef const value_type* const_iterator;
89
96
97 private:
98 class PMVSync1 : public SyncMat4 {
99 private:
100 const Mat4& m_mat;
101 sync_action_t m_sync;
102
103 public:
104 PMVSync1(const Mat4& m, sync_action_t s) noexcept
105 : m_mat(m), m_sync( std::move(s) )
106 { }
107
108 PMVSync1(const Mat4& m) noexcept
109 : m_mat(m), m_sync( sync_action_t() )
110 { }
111
112 sync_action_t& action() noexcept override { return m_sync; }
113 const Mat4& matrix() const noexcept override { return m_mat; }
114 };
115
116 class PMVSyncN : public SyncMats4 {
117 private:
118 const Mat4& m_mat;
119 size_t m_count;
120 sync_action_t m_sync;
121
122 public:
123 PMVSyncN(const Mat4& m, size_t count, sync_action_t s) noexcept
124 : m_mat(m), m_count(count), m_sync( std::move(s) )
125 { }
126 PMVSyncN(const Mat4& m, size_t count) noexcept
127 : m_mat(m), m_count(count), m_sync( sync_action_t() )
128 { }
129
130 sync_action_t& action() noexcept override { return m_sync; }
131 const Mat4* matrices() const noexcept override { return &m_mat; }
132 size_t matrixCount() const noexcept override { return m_count; }
133 };
134
135 Mat4 m_matP;
136 Mat4 m_matMv;
137 Mat4 m_matMvi;
138 Mat4 m_matMvit;
139
140 Mat4 m_matPi;
141 Mat4 m_matTex;
142
143 MatrixStack<value_type> m_stackMv, m_stackP, m_stackTex;
144
145 uint32_t m_requestBits; // may contain the requested bits: INVERSE_MODELVIEW | INVERSE_PROJECTION | INVERSE_TRANSPOSED_MODELVIEW
146
147 PMVSync1 m_syncP = PMVSync1(m_matP);
148 PMVSync1 m_syncMv = PMVSync1(m_matMv);
149 PMVSync1 m_syncTex = PMVSync1(m_matTex);
150
151 PMVSync1 m_syncMvi = PMVSync1(m_matMvi, jau::bind_member(this, &PMVMatrix4::updateImpl0));
152 PMVSync1 m_syncMvit = PMVSync1(m_matMvit, jau::bind_member(this, &PMVMatrix4::updateImpl0));
153
154 PMVSyncN m_syncP_Mv = PMVSyncN(m_matP, 2);
155 PMVSyncN m_syncP_Mv_Mvi = PMVSyncN(m_matP, 3, jau::bind_member(this, &PMVMatrix4::updateImpl0));
156 PMVSyncN m_syncP_Mv_Mvi_Mvit = PMVSyncN(m_matP, 4, jau::bind_member(this, &PMVMatrix4::updateImpl0));
157
158 uint32_t m_modifiedBits = MODIFIED_ALL;
159 uint32_t m_dirtyBits = 0; // contains the dirty bits, i.e. hinting for update operation
160 Mat4 m_matPMv;
161 Mat4 m_matPMvi;
162 bool m_matPMviOK;
163 geom::Frustum m_frustum;
164
165 constexpr static uint32_t matToReq(uint32_t req) noexcept {
166 int mask = 0;
167 if( 0 != ( req & ( INVERSE_MODELVIEW | INVERSE_TRANSPOSED_MODELVIEW ) ) ) {
168 mask |= INVERSE_MODELVIEW;
169 }
170 if( 0 != ( req & INVERSE_TRANSPOSED_MODELVIEW ) ) {
172 }
173 if( 0 != ( req & INVERSE_PROJECTION ) ) {
174 mask |= INVERSE_PROJECTION;
175 }
176 return mask;
177 }
178
179 public:
180
181 /** Bit value stating a modified {@link #getP() projection matrix (P)}, since last {@link #update()} call. */
182 constexpr static const uint32_t MODIFIED_PROJECTION = 1 << 0;
183 /** Bit value stating a modified {@link #getMv() modelview matrix (Mv)}, since last {@link #update()} call. */
184 constexpr static const uint32_t MODIFIED_MODELVIEW = 1 << 1;
185 /** Bit value stating a modified {@link #getT() texture matrix (T)}, since last {@link #update()} call. */
186 constexpr static const uint32_t MODIFIED_TEXTURE = 1 << 2;
187 /** Bit value stating all is modified */
189 /** Bit value for {@link #getMvi() inverse modelview matrix (Mvi)}, updated via {@link #update()}. */
190 constexpr static const uint32_t INVERSE_MODELVIEW = 1 << 1;
191 /** Bit value for {@link #getMvit() inverse transposed modelview matrix (Mvit)}, updated via {@link #update()}. */
192 constexpr static const uint32_t INVERSE_TRANSPOSED_MODELVIEW = 1 << 2;
193 /** Bit value for {@link #getPi() inverse projection matrix (Pi)}, updated via {@link #update()}. */
194 constexpr static const uint32_t INVERSE_PROJECTION = 1 << 3;
195 /** Bit value for {@link #getFrustum() frustum} and updated by {@link #getFrustum()}. */
196 constexpr static const uint32_t FRUSTUM = 1 << 4;
197 /** Bit value for {@link #getPMv() pre-multiplied P x Mv}, updated by {@link #getPMv()}. */
198 constexpr static const uint32_t PREMUL_PMV = 1 << 5;
199 /** Bit value for {@link #getPMvi() pre-multiplied invert(P x Mv)}, updated by {@link #getPMvi()}. */
200 constexpr static const uint32_t PREMUL_PMVI = 1 << 6;
201 /** Manual bits not covered by {@link #update()} but {@link #getFrustum()}, {@link #FRUSTUM}, {@link #getPMv()}, {@link #PREMUL_PMV}, {@link #getPMvi()}, {@link #PREMUL_PMVI}, etc. */
202 constexpr static const uint32_t MANUAL_BITS = FRUSTUM | PREMUL_PMV | PREMUL_PMVI;
203
204 /**
205 * Creates an instance of PMVMatrix4.
206 *
207 * This constructor only sets up an instance w/o additional derived INVERSE_MODELVIEW, INVERSE_PROJECTION or INVERSE_TRANSPOSED_MODELVIEW matrices.
208 *
209 * @see #PMVMatrix4(int)
210 */
211 PMVMatrix4() noexcept
212 : PMVMatrix4(0) { }
213
214 /**
215 * Creates an instance of PMVMatrix4.
216 *
217 * Additional derived matrices can be requested via `derivedMatrices`, i.e.
218 * - INVERSE_MODELVIEW
219 * - INVERSE_PROJECTION
220 * - INVERSE_TRANSPOSED_MODELVIEW
221 *
222 * Implementation uses native Matrix4 elements using column-order fields.
223 * Derived matrices are updated at retrieval, e.g. getMvi(), or via synchronized access, e.g. getSyncMvi(), to the actual Mat4 instances.
224 *
225 * @param derivedMatrices additional matrices can be requested by passing bits {@link #INVERSE_MODELVIEW}, INVERSE_PROJECTION and {@link #INVERSE_TRANSPOSED_MODELVIEW}.
226 * @see #getReqBits()
227 * @see #isReqDirty()
228 * @see #getDirtyBits()
229 * @see #update()
230 */
231 PMVMatrix4(int derivedMatrices) noexcept
232 : m_requestBits( matToReq(derivedMatrices) )
233 {
234 m_matPMviOK = false;
235 reset();
236 }
237
238 /**
239 * Issues {@link Mat4#loadIdentity()} on all matrices and resets all internal states.
240 */
241 constexpr void reset() noexcept {
242 m_matP.loadIdentity();
243 m_matMv.loadIdentity();
244 m_matTex.loadIdentity();
245
246 m_modifiedBits = MODIFIED_ALL;
247 m_dirtyBits = m_requestBits | MANUAL_BITS;
248 }
249
250 //
251 // Regular Mat4 access as well as their SyncedBuffer counterpart SyncedMatrix and SyncedMatrices
252 //
253
254 /**
255 * Returns the {@link GLMatrixFunc#GL_TEXTURE_MATRIX texture matrix} (T).
256 * <p>
257 * Consider using {@link #setTextureDirty()} if modifying the returned {@link Mat4}.
258 * </p>
259 * <p>
260 * See <a href="#storageDetails"> matrix storage details</a>.
261 * </p>
262 */
263 constexpr Mat4& getT() noexcept { return m_matTex; }
264 constexpr const Mat4& getT() const noexcept { return m_matTex; }
265
266 /**
267 * Returns the {@link SyncMatrix} of {@link GLMatrixFunc#GL_TEXTURE_MATRIX texture matrix} (T).
268 * <p>
269 * See <a href="#storageDetails"> matrix storage details</a>.
270 * </p>
271 */
272 constexpr SyncMat4& getSyncT() noexcept { return m_syncTex; }
273 constexpr const SyncMats4& getSyncT() const noexcept { return m_syncTex; }
274
275 /**
276 * Returns the {@link GLMatrixFunc#GL_PROJECTION_MATRIX projection matrix} (P).
277 * <p>
278 * Consider using {@link #setProjectionDirty()} if modifying the returned {@link Mat4}.
279 * </p>
280 * <p>
281 * See <a href="#storageDetails"> matrix storage details</a>.
282 * </p>
283 */
284 constexpr Mat4& getP() noexcept { return m_matP; }
285 constexpr const Mat4& getP() const noexcept { return m_matP; }
286
287 /**
288 * Returns the {@link SyncMatrix} of {@link GLMatrixFunc#GL_PROJECTION_MATRIX projection matrix} (P).
289 * <p>
290 * See <a href="#storageDetails"> matrix storage details</a>.
291 * </p>
292 */
293 constexpr SyncMat4& getSyncP() noexcept { return m_syncP; }
294 constexpr const SyncMats4& getSyncP() const noexcept { return m_syncP; }
295
296 /**
297 * Returns the {@link GLMatrixFunc#GL_MODELVIEW_MATRIX modelview matrix} (Mv).
298 * <p>
299 * Consider using {@link #setModelviewDirty()} if modifying the returned {@link Mat4}.
300 * </p>
301 * <p>
302 * See <a href="#storageDetails"> matrix storage details</a>.
303 * </p>
304 */
305 constexpr Mat4& getMv() noexcept { return m_matMv; }
306 constexpr const Mat4& getMv() const noexcept { return m_matMv; }
307
308 /**
309 * Returns the {@link SyncMatrix} of {@link GLMatrixFunc#GL_MODELVIEW_MATRIX modelview matrix} (Mv).
310 * <p>
311 * See <a href="#storageDetails"> matrix storage details</a>.
312 * </p>
313 */
314 constexpr SyncMat4& getSyncMv() noexcept { return m_syncMv; }
315 constexpr const SyncMats4& getSyncMv() const noexcept { return m_syncMv; }
316
317 /**
318 * Returns {@link SyncMatrices4f} of 2 matrices within one FloatBuffer: {@link #getP() P} and {@link #getMv() Mv}.
319 * <p>
320 * See <a href="#storageDetails"> matrix storage details</a>.
321 * </p>
322 */
323 constexpr SyncMats4f& getSyncPMv() noexcept { return m_syncP_Mv; }
324 constexpr const SyncMats4f& getSyncPMv() const noexcept { return m_syncP_Mv; }
325
326 /**
327 * Returns the inverse {@link GLMatrixFunc#GL_MODELVIEW_MATRIX modelview matrix} (Pi) if requested.
328 * <p>
329 * See <a href="#storageDetails"> matrix storage details</a>.
330 * </p>
331 * @throws IllegalArgumentException if {@link #INVERSE_PROJECTION} has not been requested in ctor {@link #PMVMatrix4(int)}.
332 */
333 const Mat4& getPi() {
334 if( 0 == ( INVERSE_PROJECTION & m_requestBits ) ) {
335 throw jau::IllegalArgumentError("Not requested in ctor", E_FILE_LINE);
336 }
337 updateImpl(false);
338 return m_matPi;
339 }
340
341 /**
342 * Returns the inverse {@link GLMatrixFunc#GL_MODELVIEW_MATRIX modelview matrix} (Mvi) if requested.
343 * <p>
344 * See <a href="#storageDetails"> matrix storage details</a>.
345 * </p>
346 * @throws IllegalArgumentException if {@link #INVERSE_MODELVIEW} has not been requested in ctor {@link #PMVMatrix4(int)}.
347 */
348 const Mat4& getMvi() {
349 if( 0 == ( INVERSE_MODELVIEW & m_requestBits ) ) {
350 throw jau::IllegalArgumentError("Not requested in ctor", E_FILE_LINE);
351 }
352 updateImpl(false);
353 return m_matMvi;
354 }
355
356 /**
357 * Returns the {@link SyncMatrix} of inverse {@link GLMatrixFunc#GL_MODELVIEW_MATRIX modelview matrix} (Mvi) if requested.
358 * <p>
359 * See <a href="#storageDetails"> matrix storage details</a>.
360 * </p>
361 * @throws IllegalArgumentException if {@link #INVERSE_MODELVIEW} has not been requested in ctor {@link #PMVMatrix4(int)}.
362 */
364 if( 0 == ( INVERSE_MODELVIEW & m_requestBits ) ) {
365 throw jau::IllegalArgumentError("Not requested in ctor", E_FILE_LINE);
366 }
367 return m_syncMvi;
368 }
369
370 /**
371 * Returns the inverse transposed {@link GLMatrixFunc#GL_MODELVIEW_MATRIX modelview matrix} (Mvit) if requested.
372 * <p>
373 * See <a href="#storageDetails"> matrix storage details</a>.
374 * </p>
375 * @throws IllegalArgumentException if {@link #INVERSE_TRANSPOSED_MODELVIEW} has not been requested in ctor {@link #PMVMatrix4(int)}.
376 */
377 const Mat4& getMvit() {
378 if( 0 == ( INVERSE_TRANSPOSED_MODELVIEW & m_requestBits ) ) {
379 throw jau::IllegalArgumentError("Not requested in ctor", E_FILE_LINE);
380 }
381 updateImpl(false);
382 return m_matMvit;
383 }
384
385 /**
386 * Returns the {@link SyncMatrix} of inverse transposed {@link GLMatrixFunc#GL_MODELVIEW_MATRIX modelview matrix} (Mvit) if requested.
387 * <p>
388 * See <a href="#storageDetails"> matrix storage details</a>.
389 * </p>
390 * @throws IllegalArgumentException if {@link #INVERSE_TRANSPOSED_MODELVIEW} has not been requested in ctor {@link #PMVMatrix4(int)}.
391 */
393 if( 0 == ( INVERSE_TRANSPOSED_MODELVIEW & m_requestBits ) ) {
394 throw jau::IllegalArgumentError("Not requested in ctor", E_FILE_LINE);
395 }
396 return m_syncMvit;
397 }
398
399 /**
400 * Returns {@link SyncMatrices4f} of 3 matrices within one FloatBuffer: {@link #getP() P}, {@link #getMv() Mv} and {@link #getMvi() Mvi} if requested.
401 * <p>
402 * See <a href="#storageDetails"> matrix storage details</a>.
403 * </p>
404 * @throws IllegalArgumentException if {@link #INVERSE_MODELVIEW} has not been requested in ctor {@link #PMVMatrix4(int)}.
405 */
407 if( 0 == ( INVERSE_MODELVIEW & m_requestBits ) ) {
408 throw jau::IllegalArgumentError("Not requested in ctor", E_FILE_LINE);
409 }
410 return m_syncP_Mv_Mvi;
411 }
412
413 /**
414 * Returns {@link SyncMatrices4f} of 4 matrices within one FloatBuffer: {@link #getP() P}, {@link #getMv() Mv}, {@link #getMvi() Mvi} and {@link #getMvit() Mvit} if requested.
415 * <p>
416 * See <a href="#storageDetails"> matrix storage details</a>.
417 * </p>
418 * @throws IllegalArgumentException if {@link #INVERSE_TRANSPOSED_MODELVIEW} has not been requested in ctor {@link #PMVMatrix4(int)}.
419 */
421 if( 0 == ( INVERSE_TRANSPOSED_MODELVIEW & m_requestBits ) ) {
422 throw jau::IllegalArgumentError("Not requested in ctor", E_FILE_LINE);
423 }
424 return m_syncP_Mv_Mvi_Mvit;
425 }
426
427 //
428 // Basic Mat4, Vec3 and Vec4 operations similar to GLMatrixFunc
429 //
430
431 /**
432 * Returns multiplication result of {@link #getP() P} and {@link #getMv() Mv} matrix, i.e.
433 * <pre>
434 * result = P x Mv
435 * </pre>
436 * @param result 4x4 matrix storage for result
437 * @return given result matrix for chaining
438 */
439 constexpr Mat4& getMulPMv(Mat4& result) noexcept {
440 return result.mul(m_matP, m_matMv);
441 }
442
443 /**
444 * Returns multiplication result of {@link #getMv() Mv} and {@link #getP() P} matrix, i.e.
445 * <pre>
446 * result = Mv x P
447 * </pre>
448 * @param result 4x4 matrix storage for result
449 * @return given result matrix for chaining
450 */
451 constexpr Mat4& getMulMvP(Mat4& result) noexcept {
452 return result.mul(m_matMv, m_matP);
453 }
454
455 /**
456 * v_out = Mv x v_in
457 * @param v_in input vector, can be v_out for in-place transformation
458 * @param v_out output vector
459 * @returns v_out for chaining
460 */
461 constexpr Vec4& mulWithMv(const Vec4& v_in, Vec4& v_out) noexcept {
462 return m_matMv.mulVec4(v_in, v_out);
463 }
464
465 /**
466 * v_inout = Mv x v_inout
467 * @param v_inout input and output vector, i.e. in-place transformation
468 * @returns v_inout for chaining
469 */
470 constexpr Vec4& mulWithMv(Vec4& v_inout) noexcept {
471 return m_matMv.mulVec4(v_inout);
472 }
473
474 /**
475 * v_out = Mv x v_in
476 *
477 * Affine 3f-vector transformation by 4x4 matrix, see {@link Mat4#mulVec3(Vec3, Vec3)}.
478 *
479 * @param v_in input vector, can be v_out for in-place transformation
480 * @param v_out output vector
481 * @returns v_out for chaining
482 */
483 constexpr Vec3& mulWithMv(const Vec3& v_in, Vec3& v_out) noexcept {
484 return m_matMv.mulVec3(v_in, v_out);
485 }
486
487 //
488 // GLMatrixFunc alike functionality
489 //
490
491 /**
492 * Load the {@link #getMv() modelview matrix} with the provided values.
493 */
494 constexpr PMVMatrix4& loadMv(float values[]) noexcept {
495 m_matMv.load(values);
497 return *this;
498 }
499 /**
500 * Load the {@link #getMv() modelview matrix} with the values of the given {@link Mat4}.
501 */
502 constexpr PMVMatrix4& loadMv(const Mat4& m) noexcept {
503 m_matMv.load(m);
505 return *this;
506 }
507 /**
508 * Load the {@link #getMv() modelview matrix} with the values of the given {@link Quaternion}'s rotation Quaternion::toMatrix() representation.
509 */
510 constexpr PMVMatrix4& loadMv(const Quat4f& quat) noexcept {
511 quat.toMatrix(m_matMv);
513 return *this;
514 }
515
516 /**
517 * Load the {@link #getP() projection matrix} with the provided values.
518 */
519 constexpr PMVMatrix4& loadP(float values[]) noexcept {
520 m_matP.load(values);
522 return *this;
523 }
524 /**
525 * Load the {@link #getP() projection matrix} with the values of the given {@link Mat4}.
526 */
527 constexpr PMVMatrix4& loadP(const Mat4& m) {
528 m_matP.load(m);
530 return *this;
531 }
532 /**
533 * Load the {@link #getP() projection matrix} with the values of the given {@link Quaternion}'s rotation Quaternion::toMatrix() representation.
534 */
535 constexpr PMVMatrix4& loadP(const Quat4f& quat) noexcept {
536 quat.toMatrix(m_matP);
538 return *this;
539 }
540
541 /**
542 * Load the {@link #getT() texture matrix} with the provided values.
543 */
544 constexpr PMVMatrix4& loadT(float values[]) noexcept {
545 m_matTex.load(values);
547 return *this;
548 }
549 /**
550 * Load the {@link #getT() texture matrix} with the values of the given {@link Mat4}.
551 */
552 constexpr PMVMatrix4& loadT(Mat4& m) noexcept {
553 m_matTex.load(m);
555 return *this;
556 }
557 /**
558 * Load the {@link #getT() texture matrix} with the values of the given {@link Quaternion}'s rotation Quaternion::toMatrix() representation.
559 */
560 constexpr PMVMatrix4& loadT(const Quat4f& quat) noexcept {
561 quat.toMatrix(m_matTex);
563 return *this;
564 }
565
566 /**
567 * Load the {@link #getMv() modelview matrix} with the values of the given {@link Mat4}.
568 */
569 constexpr PMVMatrix4& loadMvIdentity() noexcept {
570 m_matMv.loadIdentity();
572 return *this;
573 }
574
575 /**
576 * Load the {@link #getP() projection matrix} with the values of the given {@link Mat4}.
577 */
578 constexpr PMVMatrix4& loadPIdentity() noexcept {
579 m_matP.loadIdentity();
581 return *this;
582 }
583
584 /**
585 * Load the {@link #getT() texture matrix} with the values of the given {@link Mat4}.
586 */
587 constexpr PMVMatrix4& loadTIdentity() noexcept {
588 m_matTex.loadIdentity();
590 return *this;
591 }
592
593 /**
594 * Multiply the {@link #getMv() modelview matrix}: [c] = [c] x [m]
595 * @param m the right hand Mat4
596 * @return *this instance of chaining
597 */
598 constexpr PMVMatrix4& mulMv(const Mat4& m) noexcept {
599 m_matMv.mul( m );
601 return *this;
602 }
603
604 /**
605 * Multiply the {@link #getP() projection matrix}: [c] = [c] x [m]
606 * @param m the right hand Mat4
607 * @return *this instance of chaining
608 */
609 constexpr PMVMatrix4& mulP(const Mat4& m) noexcept {
610 m_matP.mul( m );
612 return *this;
613 }
614
615 /**
616 * Multiply the {@link #getT() texture matrix}: [c] = [c] x [m]
617 * @param m the right hand Mat4
618 * @return *this instance of chaining
619 */
620 constexpr PMVMatrix4& mulT(const Mat4& m) noexcept {
621 m_matTex.mul( m );
623 return *this;
624 }
625
626 /**
627 * Translate the {@link #getMv() modelview matrix}.
628 * @param x
629 * @param y
630 * @param z
631 * @return *this instance of chaining
632 */
633 constexpr PMVMatrix4& translateMv(float x, float y, float z) noexcept {
634 Mat4 mat4Tmp1;
635 return mulMv( mat4Tmp1.setToTranslation(x, y, z) );
636 }
637 /**
638 * Translate the {@link #getMv() modelview matrix}.
639 * @param t translation vec3
640 * @return *this instance of chaining
641 */
642 constexpr PMVMatrix4& translateMv(const Vec3& t) noexcept {
643 Mat4 mat4Tmp1;
644 return mulMv( mat4Tmp1.setToTranslation(t) );
645 }
646
647 /**
648 * Translate the {@link #getP() projection matrix}.
649 * @param x
650 * @param y
651 * @param z
652 * @return *this instance of chaining
653 */
654 constexpr PMVMatrix4& translateP(float x, float y, float z) noexcept {
655 Mat4 mat4Tmp1;
656 return mulP( mat4Tmp1.setToTranslation(x, y, z) );
657 }
658 /**
659 * Translate the {@link #getP() projection matrix}.
660 * @param t translation vec3
661 * @return *this instance of chaining
662 */
663 constexpr PMVMatrix4& translateP(const Vec3& t) noexcept {
664 Mat4 mat4Tmp1;
665 return mulP( mat4Tmp1.setToTranslation(t) );
666 }
667
668 /**
669 * Scale the {@link #getMv() modelview matrix}.
670 * @param x
671 * @param y
672 * @param z
673 * @return *this instance of chaining
674 */
675 constexpr PMVMatrix4& scaleMv(float x, float y, float z) noexcept {
676 Mat4 mat4Tmp1;
677 return mulMv( mat4Tmp1.setToScale(x, y, z) );
678 }
679 /**
680 * Scale the {@link #getMv() modelview matrix}.
681 * @param s scale vec4f
682 * @return *this instance of chaining
683 */
684 constexpr PMVMatrix4& scaleMv(const Vec3& s) noexcept {
685 Mat4 mat4Tmp1;
686 return mulMv( mat4Tmp1.setToScale(s) );
687 }
688
689 /**
690 * Scale the {@link #getP() projection matrix}.
691 * @param x
692 * @param y
693 * @param z
694 * @return *this instance of chaining
695 */
696 constexpr PMVMatrix4& scaleP(float x, float y, float z) noexcept {
697 Mat4 mat4Tmp1;
698 return mulP( mat4Tmp1.setToScale(x, y, z) );
699 }
700 /**
701 * Scale the {@link #getP() projection matrix}.
702 * @param s scale vec4f
703 * @return *this instance of chaining
704 */
705 constexpr PMVMatrix4& scaleP(const Vec3& s) noexcept {
706 Mat4 mat4Tmp1;
707 return mulP( mat4Tmp1.setToScale(s) );
708 }
709
710 /**
711 * Rotate the {@link #getMv() modelview matrix} by the given axis and angle in radians.
712 * <p>
713 * Consider using {@link #rotateMv(Quaternion)}
714 * </p>
715 * @param ang_rad angle in radians
716 * @param axis rotation axis
717 * @return *this instance of chaining
718 * @see #rotateMv(Quaternion)
719 */
720 constexpr_cxx26 PMVMatrix4& rotateMv(const float ang_rad, const float x, const float y, const float z) noexcept {
721 Mat4 mat4Tmp1;
722 return mulMv( mat4Tmp1.setToRotationAxis(ang_rad, x, y, z) );
723 }
724 /**
725 * Rotate the {@link #getMv() modelview matrix} by the given axis and angle in radians.
726 * <p>
727 * Consider using {@link #rotateMv(Quaternion)}
728 * </p>
729 * @param ang_rad angle in radians
730 * @param axis rotation axis
731 * @return *this instance of chaining
732 * @see #rotateMv(Quaternion)
733 */
734 constexpr_cxx26 PMVMatrix4& rotateMv(const float ang_rad, const Vec3& axis) noexcept {
735 Mat4 mat4Tmp1;
736 return mulMv( mat4Tmp1.setToRotationAxis(ang_rad, axis) );
737 }
738 /**
739 * Rotate the {@link #getMv() modelview matrix} with the given {@link Quaternion}'s rotation {@link Mat4#setToRotation(Quaternion) matrix representation}.
740 * @param quat the {@link Quaternion}
741 * @return *this instance of chaining
742 */
743 constexpr PMVMatrix4& rotateMv(const Quat4f& quat) noexcept {
744 Mat4 mat4Tmp1;
745 return mulMv( quat.toMatrix(mat4Tmp1) );
746 }
747
748 /**
749 * Rotate the {@link #getP() projection matrix} by the given axis and angle in radians.
750 * <p>
751 * Consider using {@link #rotateP(Quaternion)}
752 * </p>
753 * @param ang_rad angle in radians
754 * @param axis rotation axis
755 * @return *this instance of chaining
756 * @see #rotateP(Quaternion)
757 */
758 constexpr_cxx26 PMVMatrix4& rotateP(const float ang_rad, const float x, const float y, const float z) noexcept {
759 Mat4 mat4Tmp1;
760 return mulP( mat4Tmp1.setToRotationAxis(ang_rad, x, y, z) );
761 }
762 /**
763 * Rotate the {@link #getP() projection matrix} by the given axis and angle in radians.
764 * <p>
765 * Consider using {@link #rotateP(Quaternion)}
766 * </p>
767 * @param ang_rad angle in radians
768 * @param axis rotation axis
769 * @return *this instance of chaining
770 * @see #rotateP(Quaternion)
771 */
772 constexpr_cxx26 PMVMatrix4& rotateP(const float ang_rad, const Vec3& axis) noexcept {
773 Mat4 mat4Tmp1;
774 return mulP( mat4Tmp1.setToRotationAxis(ang_rad, axis) );
775 }
776 /**
777 * Rotate the {@link #getP() projection matrix} with the given {@link Quaternion}'s rotation {@link Mat4#setToRotation(Quaternion) matrix representation}.
778 * @param quat the {@link Quaternion}
779 * @return *this instance of chaining
780 */
781 constexpr PMVMatrix4& rotateP(const Quat4f& quat) noexcept {
782 Mat4 mat4Tmp1;
783 return mulP( quat.toMatrix(mat4Tmp1) );
784 }
785
786 /** Pop the {@link #getMv() modelview matrix} from its stack. */
788 m_stackMv.pop(m_matMv);
790 return *this;
791 }
792 /** Pop the {@link #getP() projection matrix} from its stack. */
794 m_stackP.pop(m_matP);
796 return *this;
797 }
798 /** Pop the {@link #getT() texture matrix} from its stack. */
800 m_stackTex.pop(m_matTex);
802 return *this;
803 }
804 /** Push the {@link #getMv() modelview matrix} to its stack, while preserving its values. */
806 m_stackMv.push(m_matMv);
807 return *this;
808 }
809 /** Push the {@link #getP() projection matrix} to its stack, while preserving its values. */
811 m_stackP.push(m_matP);
812 return *this;
813 }
814 /** Push the {@link #getT() texture matrix} to its stack, while preserving its values. */
816 m_stackTex.push(m_matTex);
817 return *this;
818 }
819
820 /**
821 * {@link #mulP(Mat4) Multiply} the {@link #getP() projection matrix} with the orthogonal matrix.
822 * @param left
823 * @param right
824 * @param bottom
825 * @param top
826 * @param zNear
827 * @param zFar
828 * @see Mat4#setToOrtho(float, float, float, float, float, float)
829 */
830 constexpr void orthoP(const float left, const float right, const float bottom, const float top, const float zNear, const float zFar) noexcept {
831 Mat4 mat4Tmp1;
832 mulP( mat4Tmp1.setToOrtho(left, right, bottom, top, zNear, zFar) );
833 }
834
835 /**
836 * {@link #mulP(Mat4) Multiply} the {@link #getP() projection matrix} with the frustum matrix.
837 *
838 * @throws IllegalArgumentException if {@code zNear <= 0} or {@code zFar <= zNear}
839 * or {@code left == right}, or {@code bottom == top}.
840 * @see Mat4#setToFrustum(float, float, float, float, float, float)
841 */
842 void frustumP(const float left, const float right, const float bottom, const float top, const float zNear, const float zFar) {
843 Mat4 mat4Tmp1;
844 mulP( mat4Tmp1.setToFrustum(left, right, bottom, top, zNear, zFar) );
845 }
846
847 //
848 // Extra functionality
849 //
850
851 /**
852 * {@link #mulP(Mat4) Multiply} the {@link #getP() projection matrix} with the perspective/frustum matrix.
853 *
854 * @param fovy_rad fov angle in radians
855 * @param aspect aspect ratio width / height
856 * @param zNear
857 * @param zFar
858 * @throws IllegalArgumentException if {@code zNear <= 0} or {@code zFar <= zNear}
859 * @see Mat4#setToPerspective(float, float, float, float)
860 */
861 PMVMatrix4& perspectiveP(const float fovy_rad, const float aspect, const float zNear, const float zFar) {
862 Mat4 mat4Tmp1;
863 mulP( mat4Tmp1.setToPerspective(fovy_rad, aspect, zNear, zFar) );
864 return *this;
865 }
866
867 /**
868 * {@link #mulP(Mat4) Multiply} the {@link #getP() projection matrix}
869 * with the eye, object and orientation, i.e. {@link Mat4#setToLookAt(Vec3, Vec3, Vec3, Mat4)}.
870 */
871 constexpr PMVMatrix4& lookAtP(const Vec3& eye, const Vec3& center, const Vec3& up) noexcept {
872 Mat4 mat4Tmp2;
873 Mat4 mat4Tmp1;
874 mulP( mat4Tmp1.setToLookAt(eye, center, up, mat4Tmp2) );
875 return *this;
876 }
877
878 /**
879 * Map object coordinates to window coordinates.
880 *
881 * Traditional <code>gluProject</code> implementation.
882 *
883 * @param objPos 3 component object coordinate
884 * @param viewport Rect4i viewport
885 * @param winPos 3 component window coordinate, the result
886 * @return true if successful, otherwise false (z is 1)
887 */
888 bool mapObjToWin(const Vec3& objPos, const Recti& viewport, Vec3& winPos) const noexcept {
889 return Mat4::mapObjToWin(objPos, m_matMv, m_matP, viewport, winPos);
890 }
891
892 /**
893 * Map world coordinates to window coordinates.
894 *
895 * - world = M x Obj
896 * - win = P x V x World = P x V' x Mv
897 * - V' x V x M = M, with Mv = V x M
898 *
899 * @param objPos 3 component object coordinate
900 * @param matV the view matrix
901 * @param viewport Rect4i viewport
902 * @param winPos 3 component window coordinate, the result
903 * @return true if successful, otherwise false (z is 1)
904 */
905 bool mapWorldToWin(const Vec3& objPos, const Mat4& matV, const Recti& viewport, Vec3& winPos) const noexcept {
906 return Mat4::mapWorldToWin(objPos, matV, m_matP, viewport, winPos);
907 }
908
909 /**
910 * Map view coordinates ( Mv x object ) to window coordinates.
911 *
912 * @param view view position, 3 component vector
913 * @param mP projection matrix
914 * @param viewport Rect4i viewport
915 * @param winPos 3 component window coordinate, the result
916 * @return true if successful, otherwise false (z is 1)
917 */
918 bool mapViewToWin(const Vec3& view, const Recti& viewport, Vec3& winPos) const noexcept {
919 return Mat4::mapViewToWin(view, m_matP, viewport, winPos);
920 }
921
922 /**
923 * Map window coordinates to object coordinates.
924 * <p>
925 * Traditional <code>gluUnProject</code> implementation.
926 * </p>
927 *
928 * @param winx
929 * @param winy
930 * @param winz
931 * @param viewport Rect4i viewport
932 * @param objPos 3 component object coordinate, the result
933 * @return true if successful, otherwise false (failed to invert matrix, or becomes infinity due to zero z)
934 */
935 bool mapWinToObj(const float winx, const float winy, const float winz,
936 const Recti& viewport, Vec3& objPos) noexcept {
937 if( Mat4::mapWinToAny(winx, winy, winz, getPMvi(), viewport, objPos) ) {
938 return true;
939 } else {
940 return false;
941 }
942 }
943
944 /**
945 * Map window coordinates to object coordinates.
946 *
947 * The INVERSE_PROJECTION must have been request in the constructor.
948 *
949 * - Pv' = P' x V', using getPi()
950 * - V' x V x M = M, with Mv = V x M
951 *
952 * @param winx
953 * @param winy
954 * @param winz
955 * @param matVi the inverse view matrix
956 * @param viewport Rect4i viewport
957 * @param objPos 3 component object coordinate, the result
958 * @return true if successful, otherwise false (failed to invert matrix, or becomes infinity due to zero z)
959 */
960 bool mapWinToWorld(const float winx, const float winy, const float winz,
961 const Mat4& matVi, const Recti& viewport, Vec3& objPos) noexcept {
962 Mat4 invPv;
963 invPv.mul(getPi(), matVi);
964 if( Mat4::mapWinToAny(winx, winy, winz, invPv, viewport, objPos) ) {
965 return true;
966 } else {
967 return false;
968 }
969 }
970
971 /**
972 * Map window coordinates to view coordinates.
973 *
974 * @param winx
975 * @param winy
976 * @param winz
977 * @param viewport Rect4i viewport
978 * @param objPos 3 component object coordinate, the result
979 * @return true if successful, otherwise false (failed to invert matrix, or becomes infinity due to zero z)
980 */
981 bool mapWinToView(const float winx, const float winy, const float winz,
982 const Recti& viewport, Vec3& objPos) noexcept {
983 if( Mat4::mapWinToAny(winx, winy, winz, getPi(), viewport, objPos) ) {
984 return true;
985 } else {
986 return false;
987 }
988 }
989
990 /**
991 * Map window coordinates to object coordinates.
992 * <p>
993 * Traditional <code>gluUnProject4</code> implementation.
994 * </p>
995 *
996 * @param winx
997 * @param winy
998 * @param winz
999 * @param clipw
1000 * @param viewport Rect4i viewport
1001 * @param near
1002 * @param far
1003 * @param objPos 4 component object coordinate, the result
1004 * @return true if successful, otherwise false (failed to invert matrix, or becomes infinity due to zero z)
1005 */
1006 bool mapWinToObj4(const float winx, const float winy, const float winz, const float clipw,
1007 const Recti& viewport, const float near, const float far, Vec4& objPos) const noexcept {
1008 if( Mat4::mapWinToObj4(winx, winy, winz, clipw, getPMvi(), viewport, near, far, objPos) ) {
1009 return true;
1010 } else {
1011 return false;
1012 }
1013 }
1014
1015 /**
1016 * Map two window coordinates w/ shared X/Y and distinctive Z
1017 * to a {@link Ray} in object space.
1018 *
1019 * The resulting {@link Ray} maybe used for <i>picking</i>
1020 * using a {@link AABBox#getRayIntersection(Vec3, Ray, float, bool) bounding box}
1021 * of a shape also in object space.
1022 *
1023 * Notes for picking <i>winz0</i> and <i>winz1</i>:
1024 * - see jau::math::util::getZBufferEpsilon()
1025 * - see jau::math::util::getZBufferValue()
1026 * - see jau::math::util::getOrthoWinZ()
1027 * @param winx
1028 * @param winy
1029 * @param winz0
1030 * @param winz1
1031 * @param viewport
1032 * @param ray storage for the resulting {@link Ray}
1033 * @return true if successful, otherwise false (failed to invert matrix, or becomes z is infinity)
1034 */
1035 bool mapWinToObjRay(const float winx, const float winy, const float winz0, const float winz1,
1036 const Recti& viewport, Ray3f& ray) noexcept {
1037 return Mat4::mapWinToAnyRay(winx, winy, winz0, winz1, getPMvi(), viewport, ray);
1038 }
1039
1040 /**
1041 * Map two window coordinates w/ shared X/Y and distinctive Z
1042 * to a {@link Ray} in world space.
1043 *
1044 * The resulting {@link Ray} maybe used for <i>picking</i>
1045 * using a {@link AABBox#getRayIntersection(Vec3, Ray, float, bool) bounding box}
1046 * of a shape also in world space.
1047 *
1048 * The INVERSE_PROJECTION must have been request in the constructor.
1049 *
1050 * - Pv' = P' x V', using getPi()
1051 * - V' x V x M = M, with Mv = V x M
1052 *
1053 * Notes for picking <i>winz0</i> and <i>winz1</i>:
1054 * - see jau::math::util::getZBufferEpsilon()
1055 * - see jau::math::util::getZBufferValue()
1056 * - see jau::math::util::getOrthoWinZ()
1057 * @param winx
1058 * @param winy
1059 * @param winz0
1060 * @param winz1
1061 * @param matVi the inverse view matrix
1062 * @param viewport
1063 * @param ray storage for the resulting {@link Ray}
1064 * @return true if successful, otherwise false (failed to invert matrix, or becomes z is infinity)
1065 *
1066 * @see INVERSE_PROJECTION
1067 * @see setView()
1068 */
1069 bool mapWinToWorldRay(const float winx, const float winy, const float winz0, const float winz1,
1070 const Mat4& matVi, const Recti& viewport, Ray3f& ray) noexcept {
1071 Mat4 invPv;
1072 invPv.mul(getPi(), matVi);
1073 return Mat4::mapWinToAnyRay(winx, winy, winz0, winz1, invPv, viewport, ray);
1074 }
1075
1076 /**
1077 * Map two window coordinates w/ shared X/Y and distinctive Z
1078 * to a {@link Ray} in view space.
1079 *
1080 * The resulting {@link Ray} maybe used for <i>picking</i>
1081 * using a {@link AABBox#getRayIntersection(Vec3, Ray, float, bool) bounding box}
1082 * of a shape also in view space.
1083 *
1084 * Notes for picking <i>winz0</i> and <i>winz1</i>:
1085 * - see jau::math::util::getZBufferEpsilon()
1086 * - see jau::math::util::getZBufferValue()
1087 * - see jau::math::util::getOrthoWinZ()
1088 * @param winx
1089 * @param winy
1090 * @param winz0
1091 * @param winz1
1092 * @param viewport
1093 * @param ray storage for the resulting {@link Ray}
1094 * @return true if successful, otherwise false (failed to invert matrix, or becomes z is infinity)
1095 */
1096 bool mapWinToViewRay(const float winx, const float winy, const float winz0, const float winz1,
1097 const Recti& viewport, Ray3f& ray) noexcept {
1098 return Mat4::mapWinToAnyRay(winx, winy, winz0, winz1, getPi(), viewport, ray);
1099 }
1100
1101 std::string& toString(std::string& sb, const std::string& f) const noexcept {
1102 const bool pmvDirty = 0 != (PREMUL_PMV & m_dirtyBits);
1103
1104 const bool pmviDirty = 0 != (PREMUL_PMVI & m_dirtyBits);
1105
1106 const bool frustumDirty = 0 != (FRUSTUM & m_dirtyBits);
1107
1108 const bool mviDirty = 0 != (INVERSE_MODELVIEW & m_dirtyBits);
1109 const bool mviReq = 0 != (INVERSE_MODELVIEW & m_requestBits);
1110
1111 const bool mvitDirty = 0 != (INVERSE_TRANSPOSED_MODELVIEW & m_dirtyBits);
1112 const bool mvitReq = 0 != (INVERSE_TRANSPOSED_MODELVIEW & m_requestBits);
1113
1114 const bool piDirty = 0 != (INVERSE_PROJECTION & m_dirtyBits);
1115 const bool piReq = 0 != (INVERSE_PROJECTION & m_requestBits);
1116
1117 const bool modP = 0 != ( MODIFIED_PROJECTION & m_modifiedBits );
1118 const bool modMv = 0 != ( MODIFIED_MODELVIEW & m_modifiedBits );
1119 const bool modT = 0 != ( MODIFIED_TEXTURE & m_modifiedBits );
1120 int count = 3; // P, Mv, T
1121
1122 sb.append("PMVMatrix4[modified[P ").append(std::to_string(modP)).append(", Mv ").append(std::to_string(modMv)).append(", T ").append(std::to_string(modT));
1123 sb.append("], dirty[PMv ").append(std::to_string(pmvDirty))
1124 .append(", Pmvi ").append(std::to_string(pmviDirty))
1125 .append(", Frustum ").append(std::to_string(frustumDirty));
1126 sb.append("], dirty/req[Mvi ").append(std::to_string(mviDirty)).append("/").append(std::to_string(mviReq))
1127 .append(", Pi ").append(std::to_string(piDirty)).append("/").append(std::to_string(piReq))
1128 .append(", Mvit ").append(std::to_string(mvitDirty)).append("/").append(std::to_string(mvitReq)).append("]\n");
1129 sb.append(", Projection\n");
1130 m_matP.toString(sb, f);
1131 sb.append(", Modelview\n");
1132 m_matMv.toString(sb, f);
1133 sb.append(", Texture\n");
1134 m_matTex.toString(sb, f);
1135 {
1136 sb.append(", P * Mv\n");
1137 m_matPMv.toString(sb, f);
1138 ++count;
1139 }
1140 {
1141 sb.append(", P * Mv\n");
1142 m_matPMvi.toString(sb, f);
1143 ++count;
1144 }
1145 if( mviReq ) {
1146 sb.append(", Inverse Modelview\n");
1147 m_matMvi.toString(sb, f);
1148 ++count;
1149 }
1150 if( mvitReq ) {
1151 sb.append(", Inverse Transposed Modelview\n");
1152 m_matMvit.toString(sb, f);
1153 ++count;
1154 }
1155 int tmpCount = 1;
1156 if( true ) { // null != mat4Tmp2 ) {
1157 ++tmpCount;
1158 }
1159 sb.append(", matrices "+std::to_string(count)+" + "+std::to_string(tmpCount)+" temp = "+std::to_string(count+tmpCount)+"]");
1160 return sb;
1161 }
1162
1163 std::string toString() const noexcept {
1164 std::string sb;
1165 toString(sb, "%13.9f");
1166 return sb;
1167 }
1168
1169 /**
1170 * Returns the modified bits due to mutable operations..
1171 * <p>
1172 * A modified bit is set, if the corresponding matrix had been modified by a mutable operation
1173 * since last {@link #update()} or {@link #getModifiedBits(bool) getModifiedBits(true)} call.
1174 * </p>
1175 * @param clear if true, clears the modified bits, otherwise leaves them untouched.
1176 *
1177 * @see #MODIFIED_PROJECTION
1178 * @see #MODIFIED_MODELVIEW
1179 * @see #MODIFIED_TEXTURE
1180 * @see #getDirtyBits()
1181 * @see #isReqDirty()
1182 */
1183 constexpr uint32_t getModifiedBits(const bool clear) noexcept {
1184 const uint32_t r = m_modifiedBits;
1185 if(clear) {
1186 m_modifiedBits = 0;
1187 }
1188 return r;
1189 }
1190
1191 /**
1192 * Returns the dirty bits due to mutable operations,
1193 * i.e.
1194 * - {@link #INVERSE_MODELVIEW} (if requested)
1195 * - {@link #INVERSE_PROJECTION} (if requested)
1196 * - {@link #INVERSE_TRANSPOSED_MODELVIEW} (if requested)
1197 * - {@link #FRUSTUM} (always, cleared via {@link #getFrustum()}
1198 * <p>
1199 * A dirty bit is set, if the corresponding matrix had been modified by a mutable operation
1200 * since last {@link #update()} call and requested in the constructor {@link #PMVMatrix4(int)}.
1201 * </p>
1202 * <p>
1203 * {@link #update()} clears the dirty state for the matrices and {@link #getFrustum()} for {@link #FRUSTUM}.
1204 * </p>
1205 *
1206 * @see #isReqDirty()
1207 * @see #INVERSE_MODELVIEW
1208 * @see #INVERSE_PROJECTION
1209 * @see #INVERSE_TRANSPOSED_MODELVIEW
1210 * @see #FRUSTUM
1211 * @see #PMVMatrix4(int)
1212 * @see #getMvi()
1213 * @see #getMvit()
1214 * @see #getSyncPMvMvi()
1215 * @see #getSyncPMvMviMvit()
1216 * @see #getFrustum()
1217 */
1218 constexpr uint32_t getDirtyBits() noexcept {
1219 return m_dirtyBits;
1220 }
1221
1222 /**
1223 * Returns true if the one of the {@link #getReqBits() requested bits} are are set dirty due to mutable operations,
1224 * i.e. at least one of
1225 * - {@link #INVERSE_MODELVIEW}
1226 * - {@link #INVERSE_PROJECTION}
1227 * - {@link #INVERSE_TRANSPOSED_MODELVIEW}
1228 * <p>
1229 * A dirty bit is set, if the corresponding matrix had been modified by a mutable operation
1230 * since last {@link #update()} call and requested in the constructor {@link #PMVMatrix4(int)}.
1231 * </p>
1232 * <p>
1233 * {@link #update()} clears the dirty state for the matrices and {@link #getFrustum()} for {@link #FRUSTUM}.
1234 * </p>
1235 *
1236 * @see #INVERSE_MODELVIEW
1237 * @see #INVERSE_PROJECTION
1238 * @see #INVERSE_TRANSPOSED_MODELVIEW
1239 * @see #PMVMatrix4(int)
1240 * @see #getMvi()
1241 * @see #getMvit()
1242 * @see #getSyncPMvMvi()
1243 * @see #getSyncPMvMviMvit()
1244 */
1245 constexpr bool isReqDirty() noexcept {
1246 return 0 != ( m_requestBits & m_dirtyBits );
1247 }
1248
1249 /**
1250 * Sets the {@link #getMv() Modelview (Mv)} matrix dirty and modified,
1251 * i.e. adds INVERSE_MODELVIEW | INVERSE_TRANSPOSED_MODELVIEW | MANUAL_BITS to {@link #getDirtyBits() dirty bits}.
1252 * @see #isReqDirty()
1253 */
1254 constexpr void setModelviewDirty() noexcept {
1256 m_modifiedBits |= MODIFIED_MODELVIEW;
1257 }
1258
1259 /**
1260 * Sets the {@link #getP() Projection (P)} matrix dirty and modified,
1261 * i.e. adds INVERSE_PROJECTION | MANUAL_BITS to {@link #getDirtyBits() dirty bits}.
1262 */
1263 constexpr void setProjectionDirty() noexcept {
1264 m_dirtyBits |= INVERSE_PROJECTION | MANUAL_BITS ;
1265 m_modifiedBits |= MODIFIED_PROJECTION;
1266 }
1267
1268 /**
1269 * Sets the {@link #getT() Texture (T)} matrix modified.
1270 */
1271 constexpr void setTextureDirty() noexcept {
1272 m_modifiedBits |= MODIFIED_TEXTURE;
1273 }
1274
1275 /**
1276 * Returns the request bit mask, which uses bit values equal to the dirty mask
1277 * and may contain
1278 * - INVERSE_MODELVIEW
1279 * - INVERSE_PROJECTION
1280 * - INVERSE_TRANSPOSED_MODELVIEW
1281 * <p>
1282 * The request bit mask is set by in the constructor {@link #PMVMatrix4(int)}.
1283 * </p>
1284 *
1285 * @see #INVERSE_MODELVIEW
1286 * @see #INVERSE_PROJECTION
1287 * @see #INVERSE_TRANSPOSED_MODELVIEW
1288 * @see #PMVMatrix4(int)
1289 * @see #getMvi()
1290 * @see #getMvit()
1291 * @see #getSyncPMvMvi()
1292 * @see #getSyncPMvMviMvit()
1293 * @see #getFrustum()
1294 */
1295 constexpr uint32_t getReqBits() noexcept {
1296 return m_requestBits;
1297 }
1298
1299 /**
1300 * Returns the pre-multiplied projection x modelview, P x Mv.
1301 * <p>
1302 * This {@link Mat4} instance should be re-fetched via this method and not locally stored
1303 * to have it updated from a potential modification of underlying projection and/or modelview matrix.
1304 * {@link #update()} has no effect on this {@link Mat4}.
1305 * </p>
1306 * <p>
1307 * This pre-multipled P x Mv is considered dirty, if its corresponding
1308 * {@link #getP() P matrix} or {@link #getMv() Mv matrix} has been modified since its last update.
1309 * </p>
1310 * @see #update()
1311 */
1312 constexpr Mat4& getPMv() noexcept {
1313 if( 0 != ( m_dirtyBits & PREMUL_PMV ) ) {
1314 m_matPMv.mul(m_matP, m_matMv);
1315 m_dirtyBits &= ~PREMUL_PMV;
1316 }
1317 return m_matPMv;
1318 }
1319
1320 /**
1321 * Returns the pre-multiplied inverse projection x modelview,
1322 * if {@link Mat4#invert(Mat4)} succeeded, otherwise `null`.
1323 * <p>
1324 * This {@link Mat4} instance should be re-fetched via this method and not locally stored
1325 * to have it updated from a potential modification of underlying projection and/or modelview matrix.
1326 * {@link #update()} has no effect on this {@link Mat4}.
1327 * </p>
1328 * <p>
1329 * This pre-multipled invert(P x Mv) is considered dirty, if its corresponding
1330 * {@link #getP() P matrix} or {@link #getMv() Mv matrix} has been modified since its last update.
1331 * </p>
1332 * @see #update()
1333 */
1334 constexpr Mat4& getPMvi() noexcept {
1335 if( 0 != ( m_dirtyBits & PREMUL_PMVI ) ) {
1336 Mat4& mPMv = getPMv();
1337 m_matPMviOK = m_matPMvi.invert(mPMv);
1338 m_dirtyBits &= ~PREMUL_PMVI;
1339 }
1340 return m_matPMvi; // matPMviOK ? matPMvi : null; // FIXME
1341 }
1342
1343 /**
1344 * Returns the frustum, derived from projection x modelview.
1345 * <p>
1346 * This {@link Frustum} instance should be re-fetched via this method and not locally stored
1347 * to have it updated from a potential modification of underlying projection and/or modelview matrix.
1348 * {@link #update()} has no effect on this {@link Frustum}.
1349 * </p>
1350 * <p>
1351 * The {@link Frustum} is considered dirty, if its corresponding
1352 * {@link #getP() P matrix} or {@link #getMv() Mv matrix} has been modified since its last update.
1353 * </p>
1354 * @see #update()
1355 */
1357 if( 0 != ( m_dirtyBits & FRUSTUM ) ) {
1358 m_frustum.setFromMat(getPMv());
1359 m_dirtyBits &= ~FRUSTUM;
1360 }
1361 return m_frustum;
1362 }
1363
1364 /**
1365 * Update the derived {@link #getMvi() inverse modelview (Mvi)},
1366 * {@link #getMvit() inverse transposed modelview (Mvit)} matrices
1367 * <b>if</b> they {@link #isReqDirty() are dirty} <b>and</b>
1368 * requested via the constructor {@link #PMVMatrix4(int)}.<br/>
1369 * Hence updates the following dirty bits.
1370 * - {@link #INVERSE_MODELVIEW}
1371 * - {@link #INVERSE_PROJECTION}
1372 * - {@link #INVERSE_TRANSPOSED_MODELVIEW}
1373 * <p>
1374 * The {@link Frustum} is updated only via {@link #getFrustum()} separately.
1375 * </p>
1376 * <p>
1377 * The Mvi and Mvit matrices are considered dirty, if their corresponding
1378 * {@link #getMv() Mv matrix} has been modified since their last update.
1379 * </p>
1380 * <p>
1381 * Method is automatically called by {@link SyncMat4} and {@link SyncMatrices4f}
1382 * instances {@link SyncAction} as retrieved by e.g. {@link #getSyncMvit()}.
1383 * This ensures an automatic update cycle if used with {@link com.jogamp.opengl.GLUniformData}.
1384 * </p>
1385 * <p>
1386 * Method may be called manually in case mutable operations has been called
1387 * and caller operates on already fetched references, i.e. not calling
1388 * {@link #getMvi()}, {@link #getMvit()} anymore.
1389 * </p>
1390 * <p>
1391 * Method clears the modified bits like {@link #getModifiedBits(bool) getModifiedBits(true)},
1392 * which are set by any mutable operation. The modified bits have no impact
1393 * on this method, but the return value.
1394 * </p>
1395 *
1396 * @return true if any matrix has been modified since last update call or
1397 * if the derived matrices Mvi and Mvit were updated, otherwise false.
1398 * In other words, method returns true if any matrix used by the caller must be updated,
1399 * e.g. uniforms in a shader program.
1400 *
1401 * @see #getModifiedBits(bool)
1402 * @see #isReqDirty()
1403 * @see #INVERSE_MODELVIEW
1404 * @see #INVERSE_PROJECTION
1405 * @see #INVERSE_TRANSPOSED_MODELVIEW
1406 * @see #PMVMatrix4(int)
1407 * @see #getMvi()
1408 * @see #getMvit()
1409 * @see #getSyncPMvMvi()
1410 * @see #getSyncPMvMviMvit()
1411 */
1412 bool update() noexcept {
1413 return updateImpl(true);
1414 }
1415
1416 //
1417 // private
1418 //
1419
1420 private:
1421 void updateImpl0() noexcept { updateImpl(false); }
1422 bool updateImpl(bool clearModBits) noexcept {
1423 bool mod = 0 != m_modifiedBits;
1424 if( clearModBits ) {
1425 m_modifiedBits = 0;
1426 mod = false;
1427 }
1428 if( 0 != ( m_requestBits & ( ( m_dirtyBits & ( INVERSE_PROJECTION ) ) ) ) ) { // only if requested & dirty
1429 if( !m_matPi.invert(m_matP) ) {
1430 DBG_ERR_PRINT("Invalid source P matrix, can't compute inverse: %s", m_matP.toString().c_str(), E_FILE_LINE);
1431 // still continue with other derived matrices
1432 } else {
1433 mod = true;
1434 }
1435 m_dirtyBits &= ~INVERSE_PROJECTION;
1436 }
1437 if( 0 != ( m_requestBits & ( ( m_dirtyBits & ( INVERSE_MODELVIEW | INVERSE_TRANSPOSED_MODELVIEW ) ) ) ) ) { // only if requested & dirty
1438 if( !m_matMvi.invert(m_matMv) ) {
1439 DBG_ERR_PRINT("Invalid source Mv matrix, can't compute inverse: %s", m_matMv.toString().c_str(), E_FILE_LINE);
1441 return mod; // no successful update as we abort due to inversion failure, skip INVERSE_TRANSPOSED_MODELVIEW as well
1442 }
1443 m_dirtyBits &= ~INVERSE_MODELVIEW;
1444 mod = true;
1445 }
1446 if( 0 != ( m_requestBits & ( m_dirtyBits & INVERSE_TRANSPOSED_MODELVIEW ) ) ) { // only if requested & dirty
1447 m_matMvit.transpose(m_matMvi);
1448 m_dirtyBits &= ~INVERSE_TRANSPOSED_MODELVIEW;
1449 mod = true;
1450 }
1451 return mod;
1452 }
1453};
1454
1455template<typename Value_type,
1456 std::enable_if_t<std::is_floating_point_v<Value_type>, bool> = true>
1457inline std::ostream& operator<<(std::ostream& out, const PMVMatrix4<Value_type>& v) noexcept {
1458 return out << v.toString();
1459}
1460
1462
1463 /**@}*/
1464
1465 } // namespace jau::math::util
1466
1467 #endif // JAU_MATH_UTIL_PMVMAT4f_HPP_
#define E_FILE_LINE
Basic 4x4 value_type matrix implementation using fields for intensive use-cases (host operations).
Definition mat4f.hpp:101
constexpr Matrix4 & setToScale(const value_type x, const value_type y, const value_type z) noexcept
Set this matrix to scale.
Definition mat4f.hpp:954
static bool mapViewToWin(const Vec3 &view, const Matrix4 &mP, const Recti &viewport, Vec3 &winPos) noexcept
Definition mat4f.hpp:1515
constexpr_cxx26 Matrix4 & setToRotationAxis(const value_type ang_rad, value_type x, value_type y, value_type z) noexcept
Set this matrix to rotation from the given axis and angle in radians.
Definition mat4f.hpp:998
static bool mapWinToObj4(const value_type winx, const value_type winy, const value_type winz, const value_type clipw, const Matrix4 &mMv, const Matrix4 &mP, const Recti &viewport, const value_type near, const value_type far, Vec4 &objPos) noexcept
Map window coordinates to object coordinates.
Definition mat4f.hpp:1716
Matrix4 & setToPerspective(const value_type fovy_rad, const value_type aspect, const value_type zNear, const value_type zFar)
Set this matrix to perspective frustum projection.
Definition mat4f.hpp:1247
static bool mapObjToWin(const Vec3 &obj, const Matrix4 &mPMv, const Recti &viewport, Vec3 &winPos) noexcept
Definition mat4f.hpp:1462
Matrix4 & setToFrustum(const value_type left, const value_type right, const value_type bottom, const value_type top, const value_type zNear, const value_type zFar)
Set this matrix to frustum.
Definition mat4f.hpp:1198
static bool mapWinToAny(const value_type winx, const value_type winy, const value_type winz, const Matrix4 &invAny, const Recti &viewport, Vec3 &objPos) noexcept
Map window coordinates to object, world or view coordinates, depending on invAny argument.
Definition mat4f.hpp:1615
static bool mapWorldToWin(const Vec3 &world, const Matrix4 &mV, const Matrix4 &mP, const Recti &viewport, Vec3 &winPos) noexcept
Definition mat4f.hpp:1499
constexpr Matrix4 & setToOrtho(const value_type left, const value_type right, const value_type bottom, const value_type top, const value_type zNear, const value_type zFar) noexcept
Set this matrix to orthogonal projection.
Definition mat4f.hpp:1150
static bool mapWinToAnyRay(const value_type winx, const value_type winy, const value_type winz0, const value_type winz1, const Matrix4 &invAny, const Recti &viewport, Ray3 &ray) noexcept
Definition mat4f.hpp:1870
constexpr Matrix4 & mul(const Matrix4 &b) noexcept
Multiply matrix: [this] = [this] x [b].
Definition mat4f.hpp:713
constexpr Matrix4 & setToTranslation(const value_type x, const value_type y, const value_type z) noexcept
Set this matrix to translation.
Definition mat4f.hpp:912
constexpr Matrix4 & setToLookAt(const Vec3 &eye, const Vec3 &center, const Vec3 &up) noexcept
Set this matrix to the look-at matrix based on given parameters.
Definition mat4f.hpp:1294
Simple compound denoting a ray.
Definition vec3f.hpp:469
3D vector using three value_type components.
Definition vec3f.hpp:45
4D vector using four value_type components.
Definition vec4f.hpp:45
Providing frustum planes derived by different inputs (P*MV, ..) used to classify objects.
Definition frustum.hpp:78
PMVMatrix4 implements the basic computer graphics Matrix4 pack using projection (P),...
Definition pmvmat4f.hpp:80
constexpr PMVMatrix4 & loadPIdentity() noexcept
Load the projection matrix with the values of the given Mat4.
Definition pmvmat4f.hpp:578
bool mapWinToObj(const float winx, const float winy, const float winz, const Recti &viewport, Vec3 &objPos) noexcept
Map window coordinates to object coordinates.
Definition pmvmat4f.hpp:935
const Mat4 & getMvi()
Returns the inverse modelview matrix (Mvi) if requested.
Definition pmvmat4f.hpp:348
constexpr PMVMatrix4 & loadMvIdentity() noexcept
Load the modelview matrix with the values of the given Mat4.
Definition pmvmat4f.hpp:569
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:830
std::string toString() const noexcept
constexpr SyncMat4 & getSyncT() noexcept
Returns the SyncMatrix of texture matrix (T).
Definition pmvmat4f.hpp:272
constexpr PMVMatrix4 & mulT(const Mat4 &m) noexcept
Multiply the texture matrix: [c] = [c] x [m].
Definition pmvmat4f.hpp:620
jau::math::geom::Frustum getFrustum() noexcept
Returns the frustum, derived from projection x modelview.
static constexpr const uint32_t INVERSE_TRANSPOSED_MODELVIEW
Bit value for inverse transposed modelview matrix (Mvit), updated via update().
Definition pmvmat4f.hpp:192
const value_type * const_pointer
Definition pmvmat4f.hpp:84
constexpr PMVMatrix4 & translateP(float x, float y, float z) noexcept
Translate the projection matrix.
Definition pmvmat4f.hpp:654
constexpr bool isReqDirty() noexcept
Returns true if the one of the requested bits are are set dirty due to mutable operations,...
constexpr Mat4 & getPMv() noexcept
Returns the pre-multiplied projection x modelview, P x Mv.
constexpr PMVMatrix4 & mulP(const Mat4 &m) noexcept
Multiply the projection matrix: [c] = [c] x [m].
Definition pmvmat4f.hpp:609
SyncMats4f & getSyncPMvMviMvit()
Returns SyncMatrices4f of 4 matrices within one FloatBuffer: P, Mv, Mvi and Mvit if requested.
Definition pmvmat4f.hpp:420
PMVMatrix4(int derivedMatrices) noexcept
Creates an instance of PMVMatrix4.
Definition pmvmat4f.hpp:231
constexpr const SyncMats4f & getSyncPMv() const noexcept
Definition pmvmat4f.hpp:324
constexpr PMVMatrix4 & loadMv(float values[]) noexcept
Load the modelview matrix with the provided values.
Definition pmvmat4f.hpp:494
constexpr PMVMatrix4 & loadP(const Quat4f &quat) noexcept
Load the projection matrix with the values of the given Quaternion's rotation Quaternion::toMatrix() ...
Definition pmvmat4f.hpp:535
bool mapViewToWin(const Vec3 &view, const Recti &viewport, Vec3 &winPos) const noexcept
Map view coordinates ( Mv x object ) to window coordinates.
Definition pmvmat4f.hpp:918
const value_type & const_reference
Definition pmvmat4f.hpp:86
const Mat4 & getMvit()
Returns the inverse transposed modelview matrix (Mvit) if requested.
Definition pmvmat4f.hpp:377
constexpr PMVMatrix4 & scaleP(const Vec3 &s) noexcept
Scale the projection matrix.
Definition pmvmat4f.hpp:705
static constexpr const uint32_t INVERSE_PROJECTION
Bit value for inverse projection matrix (Pi), updated via update().
Definition pmvmat4f.hpp:194
constexpr_cxx20 PMVMatrix4 & popT() noexcept
Pop the texture matrix from its stack.
Definition pmvmat4f.hpp:799
constexpr const SyncMats4 & getSyncP() const noexcept
Definition pmvmat4f.hpp:294
SyncMats4f & getSyncPMvMvi()
Returns SyncMatrices4f of 3 matrices within one FloatBuffer: P, Mv and Mvi if requested.
Definition pmvmat4f.hpp:406
constexpr Mat4 & getP() noexcept
Returns the projection matrix (P).
Definition pmvmat4f.hpp:284
static constexpr const uint32_t INVERSE_MODELVIEW
Bit value for inverse modelview matrix (Mvi), updated via update().
Definition pmvmat4f.hpp:190
constexpr SyncMats4f & getSyncPMv() noexcept
Returns SyncMatrices4f of 2 matrices within one FloatBuffer: P and Mv.
Definition pmvmat4f.hpp:323
constexpr Mat4 & getMv() noexcept
Returns the modelview matrix (Mv).
Definition pmvmat4f.hpp:305
constexpr PMVMatrix4 & scaleMv(const Vec3 &s) noexcept
Scale the modelview matrix.
Definition pmvmat4f.hpp:684
constexpr_cxx26 PMVMatrix4 & rotateP(const float ang_rad, const Vec3 &axis) noexcept
Rotate the projection matrix by the given axis and angle in radians.
Definition pmvmat4f.hpp:772
bool mapWinToView(const float winx, const float winy, const float winz, const Recti &viewport, Vec3 &objPos) noexcept
Map window coordinates to view coordinates.
Definition pmvmat4f.hpp:981
constexpr Vec3 & mulWithMv(const Vec3 &v_in, Vec3 &v_out) noexcept
v_out = Mv x v_in
Definition pmvmat4f.hpp:483
constexpr const SyncMats4 & getSyncT() const noexcept
Definition pmvmat4f.hpp:273
constexpr const SyncMats4 & getSyncMv() const noexcept
Definition pmvmat4f.hpp:315
constexpr uint32_t getDirtyBits() noexcept
Returns the dirty bits due to mutable operations, i.e.
constexpr Mat4 & getPMvi() noexcept
Returns the pre-multiplied inverse projection x modelview, if Mat4#invert(Mat4) succeeded,...
constexpr PMVMatrix4 & loadT(float values[]) noexcept
Load the texture matrix with the provided values.
Definition pmvmat4f.hpp:544
Vector4F< value_type, std::is_floating_point_v< Value_type > > Vec4
Definition pmvmat4f.hpp:91
Matrix4< value_type, std::is_floating_point_v< Value_type > > Mat4
Definition pmvmat4f.hpp:93
constexpr uint32_t getModifiedBits(const bool clear) noexcept
Returns the modified bits due to mutable operations.
static constexpr const uint32_t FRUSTUM
Definition pmvmat4f.hpp:196
std::string & toString(std::string &sb, const std::string &f) const noexcept
constexpr_cxx26 PMVMatrix4 & rotateMv(const float ang_rad, const float x, const float y, const float z) noexcept
Rotate the modelview matrix by the given axis and angle in radians.
Definition pmvmat4f.hpp:720
SyncMatrix4< value_type, std::is_floating_point_v< Value_type > > SyncMat4
Definition pmvmat4f.hpp:94
constexpr PMVMatrix4 & mulMv(const Mat4 &m) noexcept
Multiply the modelview matrix: [c] = [c] x [m].
Definition pmvmat4f.hpp:598
constexpr PMVMatrix4 & loadMv(const Quat4f &quat) noexcept
Load the modelview matrix with the values of the given Quaternion's rotation Quaternion::toMatrix() r...
Definition pmvmat4f.hpp:510
constexpr_cxx20 PMVMatrix4 & popMv() noexcept
Pop the modelview matrix from its stack.
Definition pmvmat4f.hpp:787
bool mapWinToObjRay(const float winx, const float winy, const float winz0, const float winz1, const Recti &viewport, Ray3f &ray) noexcept
Map two window coordinates w/ shared X/Y and distinctive Z to a Ray in object space.
constexpr_cxx20 PMVMatrix4 & pushP() noexcept
Push the projection matrix to its stack, while preserving its values.
Definition pmvmat4f.hpp:810
constexpr PMVMatrix4 & loadTIdentity() noexcept
Load the texture matrix with the values of the given Mat4.
Definition pmvmat4f.hpp:587
constexpr SyncMat4 & getSyncP() noexcept
Returns the SyncMatrix of projection matrix (P).
Definition pmvmat4f.hpp:293
constexpr PMVMatrix4 & scaleP(float x, float y, float z) noexcept
Scale the projection matrix.
Definition pmvmat4f.hpp:696
Vector3F< value_type, std::is_floating_point_v< Value_type > > Vec3
Definition pmvmat4f.hpp:90
SyncMat4 & getSyncMvi()
Returns the SyncMatrix of inverse modelview matrix (Mvi) if requested.
Definition pmvmat4f.hpp:363
constexpr void setModelviewDirty() noexcept
Sets the Modelview (Mv) matrix dirty and modified, i.e.
bool update() noexcept
Update the derived inverse modelview (Mvi), inverse transposed modelview (Mvit) matrices if they are ...
constexpr_cxx20 PMVMatrix4 & pushMv() noexcept
Push the modelview matrix to its stack, while preserving its values.
Definition pmvmat4f.hpp:805
constexpr PMVMatrix4 & translateMv(float x, float y, float z) noexcept
Translate the modelview matrix.
Definition pmvmat4f.hpp:633
constexpr_cxx26 PMVMatrix4 & rotateP(const float ang_rad, const float x, const float y, const float z) noexcept
Rotate the projection matrix by the given axis and angle in radians.
Definition pmvmat4f.hpp:758
const Mat4 & getPi()
Returns the inverse modelview matrix (Pi) if requested.
Definition pmvmat4f.hpp:333
constexpr const Mat4 & getMv() const noexcept
Definition pmvmat4f.hpp:306
constexpr PMVMatrix4 & lookAtP(const Vec3 &eye, const Vec3 &center, const Vec3 &up) noexcept
Multiply the projection matrix with the eye, object and orientation, i.e.
Definition pmvmat4f.hpp:871
constexpr PMVMatrix4 & loadT(Mat4 &m) noexcept
Load the texture matrix with the values of the given Mat4.
Definition pmvmat4f.hpp:552
PMVMatrix4 & perspectiveP(const float fovy_rad, const float aspect, const float zNear, const float zFar)
Multiply the projection matrix with the perspective/frustum matrix.
Definition pmvmat4f.hpp:861
SyncMatrices4< value_type, std::is_floating_point_v< Value_type > > SyncMats4
Definition pmvmat4f.hpp:95
static constexpr const uint32_t MODIFIED_TEXTURE
Definition pmvmat4f.hpp:186
void frustumP(const float left, const float right, const float bottom, const float top, const float zNear, const float zFar)
Multiply the projection matrix with the frustum matrix.
Definition pmvmat4f.hpp:842
constexpr PMVMatrix4 & translateMv(const Vec3 &t) noexcept
Translate the modelview matrix.
Definition pmvmat4f.hpp:642
constexpr SyncMat4 & getSyncMv() noexcept
Returns the SyncMatrix of modelview matrix (Mv).
Definition pmvmat4f.hpp:314
constexpr const Mat4 & getT() const noexcept
Definition pmvmat4f.hpp:264
static constexpr const uint32_t MANUAL_BITS
Definition pmvmat4f.hpp:202
constexpr void setTextureDirty() noexcept
Sets the Texture (T) matrix modified.
constexpr PMVMatrix4 & rotateP(const Quat4f &quat) noexcept
Rotate the projection matrix with the given Quaternion's rotation matrix representation.
Definition pmvmat4f.hpp:781
constexpr_cxx20 PMVMatrix4 & popP() noexcept
Pop the projection matrix from its stack.
Definition pmvmat4f.hpp:793
bool mapWinToWorldRay(const float winx, const float winy, const float winz0, const float winz1, const Mat4 &matVi, const Recti &viewport, Ray3f &ray) noexcept
Map two window coordinates w/ shared X/Y and distinctive Z to a Ray in world space.
constexpr void setProjectionDirty() noexcept
Sets the Projection (P) matrix dirty and modified, i.e.
bool mapWinToWorld(const float winx, const float winy, const float winz, const Mat4 &matVi, const Recti &viewport, Vec3 &objPos) noexcept
Map window coordinates to object coordinates.
Definition pmvmat4f.hpp:960
PMVMatrix4() noexcept
Creates an instance of PMVMatrix4.
Definition pmvmat4f.hpp:211
constexpr PMVMatrix4 & rotateMv(const Quat4f &quat) noexcept
Rotate the modelview matrix with the given Quaternion's rotation matrix representation.
Definition pmvmat4f.hpp:743
static constexpr const uint32_t PREMUL_PMVI
Definition pmvmat4f.hpp:200
constexpr Mat4 & getMulPMv(Mat4 &result) noexcept
Returns multiplication result of P and Mv matrix, i.e.
Definition pmvmat4f.hpp:439
constexpr PMVMatrix4 & translateP(const Vec3 &t) noexcept
Translate the projection matrix.
Definition pmvmat4f.hpp:663
constexpr Mat4 & getT() noexcept
Returns the texture matrix (T).
Definition pmvmat4f.hpp:263
constexpr PMVMatrix4 & scaleMv(float x, float y, float z) noexcept
Scale the modelview matrix.
Definition pmvmat4f.hpp:675
constexpr Vec4 & mulWithMv(const Vec4 &v_in, Vec4 &v_out) noexcept
v_out = Mv x v_in
Definition pmvmat4f.hpp:461
constexpr PMVMatrix4 & loadMv(const Mat4 &m) noexcept
Load the modelview matrix with the values of the given Mat4.
Definition pmvmat4f.hpp:502
const value_type * const_iterator
Definition pmvmat4f.hpp:88
static constexpr const uint32_t PREMUL_PMV
Definition pmvmat4f.hpp:198
bool mapWinToViewRay(const float winx, const float winy, const float winz0, const float winz1, const Recti &viewport, Ray3f &ray) noexcept
Map two window coordinates w/ shared X/Y and distinctive Z to a Ray in view space.
constexpr Mat4 & getMulMvP(Mat4 &result) noexcept
Returns multiplication result of Mv and P matrix, i.e.
Definition pmvmat4f.hpp:451
constexpr PMVMatrix4 & loadP(const Mat4 &m)
Load the projection matrix with the values of the given Mat4.
Definition pmvmat4f.hpp:527
bool mapWorldToWin(const Vec3 &objPos, const Mat4 &matV, const Recti &viewport, Vec3 &winPos) const noexcept
Map world coordinates to window coordinates.
Definition pmvmat4f.hpp:905
static constexpr const uint32_t MODIFIED_PROJECTION
Definition pmvmat4f.hpp:182
static constexpr const uint32_t MODIFIED_MODELVIEW
Definition pmvmat4f.hpp:184
constexpr void reset() noexcept
Issues Mat4#loadIdentity() on all matrices and resets all internal states.
Definition pmvmat4f.hpp:241
constexpr const Mat4 & getP() const noexcept
Definition pmvmat4f.hpp:285
constexpr_cxx20 PMVMatrix4 & pushT() noexcept
Push the texture matrix to its stack, while preserving its values.
Definition pmvmat4f.hpp:815
constexpr PMVMatrix4 & loadP(float values[]) noexcept
Load the projection matrix with the provided values.
Definition pmvmat4f.hpp:519
constexpr Vec4 & mulWithMv(Vec4 &v_inout) noexcept
v_inout = Mv x v_inout
Definition pmvmat4f.hpp:470
SyncMat4 & getSyncMvit()
Returns the SyncMatrix of inverse transposed modelview matrix (Mvit) if requested.
Definition pmvmat4f.hpp:392
constexpr_cxx26 PMVMatrix4 & rotateMv(const float ang_rad, const Vec3 &axis) noexcept
Rotate the modelview matrix by the given axis and angle in radians.
Definition pmvmat4f.hpp:734
Ray3F< value_type, std::is_floating_point_v< Value_type > > Ray3
Definition pmvmat4f.hpp:92
bool mapWinToObj4(const float winx, const float winy, const float winz, const float clipw, const Recti &viewport, const float near, const float far, Vec4 &objPos) const noexcept
Map window coordinates to object coordinates.
static constexpr const uint32_t MODIFIED_ALL
Bit value stating all is modified.
Definition pmvmat4f.hpp:188
constexpr PMVMatrix4 & loadT(const Quat4f &quat) noexcept
Load the texture matrix with the values of the given Quaternion's rotation Quaternion::toMatrix() rep...
Definition pmvmat4f.hpp:560
constexpr uint32_t getReqBits() noexcept
Returns the request bit mask, which uses bit values equal to the dirty mask and may contain.
bool mapObjToWin(const Vec3 &objPos, const Recti &viewport, Vec3 &winPos) const noexcept
Map object coordinates to window coordinates.
Definition pmvmat4f.hpp:888
SyncBuffer interface with multiple underlying Matrix4.
Matrix4< value_type, std::is_floating_point_v< value_type > > Mat4
SyncBuffer interface with a single underlying Matrix4.
#define DBG_ERR_PRINT(...)
Use for environment-variable environment::DEBUG conditional error messages, prefix '[elapsed_time] Wa...
Definition debug.hpp:58
#define constexpr_cxx20
constexpr qualifier replacement for C++20 constexpr.
#define constexpr_cxx26
jau::function< R(A...)> bind_member(C1 *base, R(C0::*mfunc)(A...)) noexcept
Bind given class instance and non-void member function to an anonymous function using func_member_tar...
SyncMatrices4< float > SyncMats4f
Ray3F< float > Ray3f
Definition vec3f.hpp:499
jau::function< void()> sync_action_t
Specific data synchronization action implemented by the data provider to update the buffer with the u...
Quaternion< float > Quat4f
RectI< int > Recti
Definition recti.hpp:139
PMVMatrix4< float > PMVMat4f
std::ostream & operator<<(std::ostream &out, const PMVMatrix4< Value_type > &v) noexcept
uint8_t Value_type