50 unsigned int *primitiveIds,
51 float *barycentricCoordinates,
53 const float *vertexCoords,
55 const IT *connectivityList,
57 const double resolution[2],
58 const double camPos[3],
59 const double camDirRaw[3],
60 const double camUp[3],
61 const double &camHeight,
62 const bool &orthographicProjection,
63 const double &viewAngle)
const {
65 int const resX = resolution[0];
66 int const resY = resolution[1];
69 + std::string(orthographicProjection ?
"O" :
"P") +
"|"
70 + std::to_string(resX) +
"x" + std::to_string(resY) +
")",
74 const double aspect = resolution[0] / resolution[1];
75 const double camSize[2] = {aspect * camHeight, camHeight};
77 const auto normalize = [](
double out[3],
const double in[3]) {
78 double const temp = sqrt(in[0] * in[0] + in[1] * in[1] + in[2] * in[2]);
79 out[0] = in[0] / temp;
80 out[1] = in[1] / temp;
81 out[2] = in[2] / temp;
84 double camDir[3]{0, 0, 0};
88 double camRight[3]{camDir[1] * camUp[2] - camDir[2] * camUp[1],
89 camDir[2] * camUp[0] - camDir[0] * camUp[2],
90 camDir[0] * camUp[1] - camDir[1] * camUp[0]};
94 double camUpTrue[3]{camDir[1] * (-camRight[2]) - camDir[2] * (-camRight[1]),
95 camDir[2] * (-camRight[0]) - camDir[0] * (-camRight[2]),
96 camDir[0] * (-camRight[1]) - camDir[1] * (-camRight[0])};
100 double const pixelWidthWorld = camSize[0] / resolution[0];
101 double const pixelHeightWorld = camSize[1] / resolution[1];
106 double const camWidthWorldHalf = 0.5 * camSize[0] - 0.5 * pixelWidthWorld;
107 double const camHeightWorldHalf = 0.5 * camSize[1] - 0.5 * pixelHeightWorld;
111 double const camPosCorner[3] = {camPos[0] - camRight[0] * camWidthWorldHalf
112 - camUpTrue[0] * camHeightWorldHalf,
113 camPos[1] - camRight[1] * camWidthWorldHalf
114 - camUpTrue[1] * camHeightWorldHalf,
115 camPos[2] - camRight[2] * camWidthWorldHalf
116 - camUpTrue[2] * camHeightWorldHalf};
118 float const nan = std::numeric_limits<float>::quiet_NaN();
119 if(orthographicProjection) {
120#ifdef TTK_ENABLE_OPENMP
121#pragma omp parallel for num_threads(this->threadNumber_)
123 for(
int y = 0; y < resY; y++) {
124 double const v = ((double)y) * pixelHeightWorld;
126 size_t pixelIndex = y * resX;
127 size_t bcIndex = 2 * pixelIndex;
129 for(
int x = 0; x < resX; x++) {
130 double const u = ((double)x) * pixelWidthWorld;
132 depthBuffer[pixelIndex] = nan;
134 barycentricCoordinates[bcIndex] = nan;
135 barycentricCoordinates[bcIndex + 1] = nan;
139 = camPosCorner[0] + u * camRight[0] + v * camUpTrue[0];
141 = camPosCorner[1] + u * camRight[1] + v * camUpTrue[1];
143 = camPosCorner[2] + u * camRight[2] + v * camUpTrue[2];
145 float ray_origin[3] = {org_x, org_y, org_z};
148 float const dir_x = camDir[0];
149 float const dir_y = camDir[1];
150 float const dir_z = camDir[2];
152 float ray_dir[3] = {dir_x, dir_y, dir_z};
154 Ray ray(ray_dir, ray_origin);
159 ray, connectivityList, vertexCoords, &triIdx, &distance);
161 depthBuffer[pixelIndex] = distance;
162 primitiveIds[pixelIndex] = triIdx;
163 barycentricCoordinates[bcIndex] = ray.
u;
164 barycentricCoordinates[bcIndex + 1] = ray.
v;
172 = (viewAngle / 180.0 * 3.141592653589793) / resolution[0];
174#ifdef TTK_ENABLE_OPENMP
175#pragma omp parallel for num_threads(this->threadNumber_)
177 for(
int y = 0; y < resY; y++) {
178 double const v = (y - resY * 0.5) * factor;
179 size_t pixelIndex = y * resX;
180 size_t bcIndex = 2 * pixelIndex;
182 for(
int x = 0; x < resX; x++) {
183 double const u = (x - resX * 0.5) * factor;
185 depthBuffer[pixelIndex] = nan;
187 barycentricCoordinates[bcIndex] = nan;
188 barycentricCoordinates[bcIndex + 1] = nan;
191 float const org_x = camPos[0];
192 float const org_y = camPos[1];
193 float const org_z = camPos[2];
195 float ray_origin[3] = {org_x, org_y, org_z};
197 float const dir_x = camDir[0] + u * camRight[0] + v * camUpTrue[0];
198 float const dir_y = camDir[1] + u * camRight[1] + v * camUpTrue[1];
199 float const dir_z = camDir[2] + u * camRight[2] + v * camUpTrue[2];
201 float ray_dir[3] = {dir_x, dir_y, dir_z};
203 Ray ray(ray_dir, ray_origin);
208 ray, connectivityList, vertexCoords, &triIdx, &distance);
210 depthBuffer[pixelIndex] = distance;
211 primitiveIds[pixelIndex] = triIdx;
212 barycentricCoordinates[bcIndex] = ray.
u;
213 barycentricCoordinates[bcIndex + 1] = ray.
v;
221 + std::string(orthographicProjection ?
"O" :
"P") +
"|"
222 + std::to_string(resX) +
"x" + std::to_string(resY) +
")",
int renderImage(float *depthBuffer, unsigned int *primitiveIds, float *barycentricCoordinates, const size_t &nVertices, const float *vertexCoords, const size_t &nTriangles, const IT *connectivityList, const BoundingVolumeHierarchy< IT > &bvh, const double resolution[2], const double camPos[3], const double camDirRaw[3], const double camUp[3], const double &camHeight, const bool &orthographicProjection, const double &viewAngle) const