-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathCameraRenderInfo.cpp
More file actions
170 lines (148 loc) · 7.48 KB
/
Copy pathCameraRenderInfo.cpp
File metadata and controls
170 lines (148 loc) · 7.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/*
* Copyright (C) 2025: Arizona Board of Regents on Behalf of the University of Arizona
*/
#ifdef WIN32
#define _USE_MATH_DEFINES
#endif
#include <cmath>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/quaternion.hpp>
#include <glm/gtc/type_ptr.hpp>
#include "CameraRenderInfo.h"
#include <iostream>
using namespace asdp::render;
void CameraRenderInfo::ComputePlanarCameraMeshInfo(size_t nx, size_t ny, float depth)
{
// Lock the mutex to protect the mesh data.
std::lock_guard<std::mutex> lock(m_meshMutex);
// Pre-divide so we can use multiplications instead of divisions in the loop, which is faster.
double fnxInv = 1 / static_cast<GLfloat>(nx);
double fnyInv = 1 / static_cast<GLfloat>(ny);
// Compute the scaled X, Y coordinates for the four corners of the quad that place them
// for a correctly-sized quad given the camera info to get them to scaled space.
// The Z coordinate is along the negative Z axis at the specified depth.
double xHalfSpan = tan(glm::radians(m_fovDegrees[0]) * 0.5) * depth;
double yHalfSpan = tan(glm::radians(m_fovDegrees[1]) * 0.5) * depth;
// Rotate the points in the helicopter view space by the specified orientation change
// to point them in the direction that the camera is looking.
glm::mat4 rotationX = glm::rotate(glm::mat4(1.0f),
glm::radians(static_cast<GLfloat>(m_orientationDegrees[0])),
glm::vec3(1.0f, 0.0f, 0.0f));
glm::mat4 rotationY = glm::rotate(rotationX,
glm::radians(static_cast<GLfloat>(m_orientationDegrees[1])),
glm::vec3(0.0f, 1.0f, 0.0f));
glm::mat4 rotation = glm::rotate(rotationY,
glm::radians(static_cast<GLfloat>(m_orientationDegrees[2])),
glm::vec3(0.0f, 0.0f, 1.0f));
// Create the vertices including the texture coordinates. Each entry will have
// 6 floats: X, Y, Z, U, V, vignette. We add entries that span the entire range, with one
// more vertex in each dimension than there are quads. We start from the lower-
// left, move right, then move up at the end of each line.
std::vector<VertexInfo> vertices;
for (size_t j = 0; j <= ny; j++) {
for (size_t i = 0; i <= nx; i++) {
// Compute the U and V normalized texture coordinates for the vertex in the range 0 to 1.
// The normalized texture coordinates in the range 0 to 1 handle mapping the texture so that
// the corners of the last pixels are at the edges of the quad. Flip the V coordinate so that
// the image can be drawn in right-handed coordinates.
GLfloat u = i * fnxInv;
GLfloat v = 1.0f - j * fnyInv;
// Compute the normalized X, Y, coordinates in the range -1 to 1.
double xn = -1.0f + 2.0f * i * fnxInv;
double yn = -1.0f + 2.0f * j * fnyInv;
// Compute the scaled X, Y coordinates for the four corners of the quad that place them
// for a correctly-sized quad given the camera info to get them to scaled space.
// The Z coordinate is along the negative Z axis at the specified depth.
double xs = xn * xHalfSpan;
double ys = yn * yHalfSpan;
double zs = -depth;
// Perform distortion correction on the X, Y coordinates to get to canonical view
// space, which has a camera looking down -Z. This provides us the location in the
// canonical view space. If we don't have a distortion model, we just use the X, Y, Z
// coordinates as is.
std::array<double, 3> distPoint = std::array<double, 3>{xs, ys, zs};
if (m_distortion != nullptr) {
distPoint = m_distortion->MapPoint(distPoint);
}
double& xc = distPoint[0];
double& yc = distPoint[1];
double& zc = distPoint[2];
// Rotate the X, Y, Z coordinates to match the camera center of projection
// and viewing direction of this camera in the coordinate system of the camera cluster.
// This will be the local helicopter coordinate system that maps +X helicopter from +X,
// +Y helicopter from -Z, and +Z helicopter from +Y.
double xh = xc;
double yh = -zc;
double zh = yc;
// Rotate the points in the helicopter view space by the specified orientation change
// to point them in the direction that the camera is looking.
glm::vec4 point(xh, yh, zh, 1.0f);
glm::vec3 transformedPoint = glm::vec3(rotation * point);
// Add the vertex description, computing quantities as needed
VertexInfo vertex;
vertex.offset = transformedPoint;
vertex.texCoord = glm::vec2(u, v);
vertex.normalizedOffset = glm::normalize(transformedPoint);
vertex.depth = glm::length(transformedPoint);
vertex.vignetteGain = 1.0;
if (m_vignette != nullptr) {
// Compute the vignette gain at the point (xn, yn)
vertex.vignetteGain = m_vignette->EvaluateAtPoint({ xn, yn });
}
vertices.push_back(vertex);
}
}
m_mesh.nx = nx;
m_mesh.ny = ny;
m_mesh.vertexInfo = vertices;
}
glm::vec3 CameraRenderInfo::WorldSpaceFromUV(float u, float v, float depth) const
{
double xHalfSpan = tan(glm::radians(m_fovDegrees[0]) * 0.5) * depth;
double yHalfSpan = tan(glm::radians(m_fovDegrees[1]) * 0.5) * depth;
// Rotate the point in the helicopter view space by the specified orientation change
// to point in the direction that the camera is looking.
glm::mat4 rotationX = glm::rotate(glm::mat4(1.0f),
glm::radians(static_cast<GLfloat>(m_orientationDegrees[0])),
glm::vec3(1.0f, 0.0f, 0.0f));
glm::mat4 rotationY = glm::rotate(rotationX,
glm::radians(static_cast<GLfloat>(m_orientationDegrees[1])),
glm::vec3(0.0f, 1.0f, 0.0f));
glm::mat4 rotation = glm::rotate(rotationY,
glm::radians(static_cast<GLfloat>(m_orientationDegrees[2])),
glm::vec3(0.0f, 0.0f, 1.0f));
// Compute the normalized X, Y, coordinates in the range -1 to 1.
// Flip the Y coordinate to match what is done in the mesh generation.
double xn = -1.0f + 2.0f * u;
double yn = -(-1.0f + 2.0f * v);
// Compute the scaled X, Y coordinates for the four corners of the quad that place them
// for a correctly-sized quad given the camera info to get them to scaled space.
// The Z coordinate is along the negative Z axis at the specified depth.
double xs = xn * xHalfSpan;
double ys = yn * yHalfSpan;
double zs = -depth;
// Perform distortion correction on the X, Y coordinates to get to canonical view
// space, which has a camera looking down -Z. This provides us the location in the
// canonical view space. If we don't have a distortion model, we just use the X, Y, Z
// coordinates as is.
std::array<double, 3> distPoint = std::array<double, 3>{ xs, ys, zs };
if (m_distortion != nullptr) {
distPoint = m_distortion->MapPoint(distPoint);
}
double& xc = distPoint[0];
double& yc = distPoint[1];
double& zc = distPoint[2];
// Rotate the X, Y, Z coordinates to match the camera center of projection
// and viewing direction of this camera in the coordinate system of the camera cluster.
// This will be the local helicopter coordinate system that maps +X helicopter from +X,
// +Y helicopter from -Z, and +Z helicopter from +Y.
double xh = xc;
double yh = -zc;
double zh = yc;
// Rotate the points in the helicopter view space by the specified orientation change
// to point them in the direction that the camera is looking.
glm::vec3 point(xh, yh, zh);
return glm::vec3(rotation * glm::vec4(point, 1.0f));
}