23#ifndef VCL_RENDER_VIEWER_MATRIX_H
24#define VCL_RENDER_VIEWER_MATRIX_H
26#include <vclib/space/core/matrix.h>
27#include <vclib/space/core/point.h>
31enum Handedness { LEFT_HAND, RIGHT_HAND };
35template<
typename Scalar>
36void projectionMatrixXYWH(
45 Handedness handedness = RIGHT_HAND)
49 Scalar diff = farPlane - nearPlane;
50 Scalar a = homogeneousNDC ? (farPlane + nearPlane) / diff : farPlane / diff;
52 homogeneousNDC ? (2.0 * farPlane * nearPlane) / diff : nearPlane * a;
54 std::fill(res, res + 16, 0);
58 res[8] = handedness == RIGHT_HAND ? x : -x;
59 res[9] = handedness == RIGHT_HAND ? y : -y;
60 res[10] = handedness == RIGHT_HAND ? -a : a;
61 res[11] = handedness == RIGHT_HAND ? -1.0 : 1.0;
81template<Po
int3Concept Po
intType>
85 const PointType& center,
87 Handedness handedness = RIGHT_HAND)
90 PointType zaxis = handedness == RIGHT_HAND ?
91 (eye - center).normalized() :
92 (center - eye).normalized();
94 PointType xaxis = up.cross(zaxis);
96 if (xaxis.dot(xaxis) == 0) {
97 xaxis = handedness == RIGHT_HAND ? PointType(1, 0, 0) :
101 xaxis = xaxis.normalized();
104 PointType yaxis = zaxis.cross(xaxis);
121 res[12] = -xaxis.dot(eye);
122 res[13] = -yaxis.dot(eye);
123 res[14] = -zaxis.dot(eye);
141template<MatrixConcept Matrix44, Po
int3Concept Po
intType>
142Matrix44 lookAtMatrix(
143 const PointType& eye,
144 const PointType& center,
146 Handedness handedness = RIGHT_HAND)
149 lookAtMatrix(res.data(), eye, center, up, handedness);
166template<Po
int3Concept Po
intType>
167void lookAtMatrixLeftHanded(
169 const PointType& eye,
170 const PointType& center,
173 lookAtMatrix(res, eye, center, up, LEFT_HAND);
188template<MatrixConcept Matrix44, Po
int3Concept Po
intType>
189Matrix44 lookAtMatrixLeftHanded(
190 const PointType& eye,
191 const PointType& center,
195 lookAtMatrix(res.data(), eye, center, up, LEFT_HAND);
199template<
typename Scalar>
200void projectionMatrix(
207 Handedness handedness = RIGHT_HAND)
209 Scalar h = 1.0 / std::tan(
vcl::toRad(fov) * 0.5);
210 Scalar w = h * 1.0 / aspect;
211 detail::projectionMatrixXYWH(
223template<MatrixConcept Matrix44,
typename Scalar>
224Matrix44 projectionMatrix(
230 Handedness handedness = RIGHT_HAND)
244template<
typename Scalar>
245void projectionMatrixLeftHanded(
253 Scalar h = 1.0 / std::tan(
vcl::toRad(fov) * 0.5);
254 Scalar w = h * 1.0 / aspect;
256 res, fov, aspect, nearPlane, farPlane, homogeneousNDC, LEFT_HAND);
259template<MatrixConcept Matrix44,
typename Scalar>
260Matrix44 projectionMatrixLeftHanded(
279template<
typename Scalar>
280void orthoProjectionMatrix(
289 Handedness handedness = RIGHT_HAND)
293 Scalar c = homogeneousNDC ? 2.0 / (farPlane - nearPlane) :
294 1.0 / (farPlane - nearPlane);
295 Scalar f = homogeneousNDC ?
296 (farPlane + nearPlane) / (nearPlane - farPlane) :
297 nearPlane / (nearPlane - farPlane);
299 std::fill(res, res + 16, 0);
300 res[0] = 2.0 / (right - left);
301 res[5] = 2.0 / (top - bottom);
302 res[10] = RIGHT_HAND ? -c : c;
303 res[12] = (right + left) / (left - right);
304 res[13] = (bottom + top) / (bottom - top);
309template<MatrixConcept Matrix44,
typename Scalar>
310Matrix44 orthoProjectionMatrix(
318 Handedness handedness = RIGHT_HAND)
321 orthoProjectionMatrix(
349template<MatrixConcept Matrix44, Po
int3Concept Po
intType>
351 const PointType& screenPos,
352 const Matrix44& modelViewProjection,
353 const Point4<typename Matrix44::Scalar>& viewport,
356 using Scalar = Matrix44::Scalar;
357 const Matrix44 inv = modelViewProjection.inverse();
359 (screenPos.x() - viewport[0]) / viewport[2] * 2.0 - 1.0,
360 (screenPos.y() - viewport[1]) / viewport[3] * 2.0 - 1.0,
361 homogeneousNDC ? 2.0 * screenPos.z() - 1.0 : screenPos.z(),
365 throw std::runtime_error(
"unproject: division by zero");
367 return p.template head<3>() / p.w();
Scalar toRad(const Scalar °)
Converts an angle in degrees to radians.
Definition base.h:83