8#ifdef TTK_ENABLE_EMBREE
10int ttk::CinemaImagingEmbree::deallocateScene(RTCDevice &device,
11 RTCScene &scene)
const {
15 rtcReleaseScene(scene);
16 rtcReleaseDevice(device);
23int ttk::CinemaImagingEmbree::initializeDevice(RTCDevice &device)
const {
27 device = rtcNewDevice(
"hugepages=1,threads=1");
30 this->printErr(
"Unable to create device");
31 this->printErr(std::to_string(rtcGetDeviceError(
nullptr)));
36 = [](
void *
ttkNotUsed(userPtr),
enum RTCError error,
const char *str) {
37 printf(
"error %d: %s\n", error, str);
40 rtcSetDeviceErrorFunction(device, errorFunction,
nullptr);
47int ttk::CinemaImagingEmbree::renderImage(
49 unsigned int *primitiveIds,
50 float *barycentricCoordinates,
52 const RTCScene &scene,
53 const double resolution[2],
54 const double camPos[3],
55 const double camDirRaw[3],
56 const double camUp[3],
57 const double &camFactor,
58 const bool &orthographicProjection)
const {
61 const int resX = resolution[0];
62 const int resY = resolution[1];
65 + std::string(orthographicProjection ?
"O" :
"P") +
"|"
66 + std::to_string(resX) +
"x" + std::to_string(resY) +
")",
69 struct RTCIntersectContext context;
70 rtcInitIntersectContext(&context);
72 const auto normalize = [](
double out[3],
const double in[3]) {
73 const double temp = sqrt(in[0] * in[0] + in[1] * in[1] + in[2] * in[2]);
74 out[0] = in[0] / temp;
75 out[1] = in[1] / temp;
76 out[2] = in[2] / temp;
79 double camDir[3]{0, 0, 0};
83 double camRight[3]{camDir[1] * camUp[2] - camDir[2] * camUp[1],
84 camDir[2] * camUp[0] - camDir[0] * camUp[2],
85 camDir[0] * camUp[1] - camDir[1] * camUp[0]};
89 double camUpTrue[3]{camDir[1] * (-camRight[2]) - camDir[2] * (-camRight[1]),
90 camDir[2] * (-camRight[0]) - camDir[0] * (-camRight[2]),
91 camDir[0] * (-camRight[1]) - camDir[1] * (-camRight[0])};
94 struct RTCRayHit rayhit;
95 rayhit.ray.dir_x = -1;
96 rayhit.ray.dir_y = -1;
97 rayhit.ray.dir_z = -1;
99 size_t pixelIndex = 0;
101 const float nan = std::numeric_limits<float>::quiet_NaN();
103 if(orthographicProjection) {
106 const double aspect = resolution[0] / resolution[1];
107 const double camSize[2] = {aspect * camFactor, camFactor};
110 const double pixelWidthWorld = camSize[0] / resolution[0];
111 const double pixelHeightWorld = camSize[1] / resolution[1];
116 const double camWidthWorldHalf = 0.5 * camSize[0] - 0.5 * pixelWidthWorld;
117 const double camHeightWorldHalf = 0.5 * camSize[1] - 0.5 * pixelHeightWorld;
121 const double camPosCorner[3] = {camPos[0] - camRight[0] * camWidthWorldHalf
122 - camUpTrue[0] * camHeightWorldHalf,
123 camPos[1] - camRight[1] * camWidthWorldHalf
124 - camUpTrue[1] * camHeightWorldHalf,
125 camPos[2] - camRight[2] * camWidthWorldHalf
126 - camUpTrue[2] * camHeightWorldHalf};
128 for(
int y = 0; y < resY; y++) {
129 const double v = ((double)y) * pixelHeightWorld;
131 for(
int x = 0; x < resX; x++) {
132 const double u = ((double)x) * pixelWidthWorld;
135 rayhit.ray.org_x = camPosCorner[0] + u * camRight[0] + v * camUpTrue[0];
136 rayhit.ray.org_y = camPosCorner[1] + u * camRight[1] + v * camUpTrue[1];
137 rayhit.ray.org_z = camPosCorner[2] + u * camRight[2] + v * camUpTrue[2];
140 rayhit.ray.dir_x = camDir[0];
141 rayhit.ray.dir_y = camDir[1];
142 rayhit.ray.dir_z = camDir[2];
145 rayhit.ray.tnear = 0.01;
146 rayhit.ray.tfar = INFINITY;
148 rayhit.ray.flags = 0;
149 rayhit.hit.geomID = RTC_INVALID_GEOMETRY_ID;
150 rayhit.hit.instID[0] = RTC_INVALID_GEOMETRY_ID;
151 rtcIntersect1(scene, &context, &rayhit);
154 const bool hitPrimitive = rayhit.hit.geomID != RTC_INVALID_GEOMETRY_ID;
156 depthBuffer[pixelIndex] = std::max(0.0f, rayhit.ray.tfar);
157 primitiveIds[pixelIndex] = rayhit.hit.primID;
158 barycentricCoordinates[bcIndex++] = rayhit.hit.u;
159 barycentricCoordinates[bcIndex++] = rayhit.hit.v;
161 depthBuffer[pixelIndex] = nan;
163 barycentricCoordinates[bcIndex++] = nan;
164 barycentricCoordinates[bcIndex++] = nan;
172 = (camFactor / 180.0 * 3.141592653589793) / resolution[0];
174 for(
int y = 0; y < resY; y++) {
175 const double v = (y - resY * 0.5) * factor;
177 for(
int x = 0; x < resX; x++) {
178 const double u = (x - resX * 0.5) * factor;
181 rayhit.ray.org_x = camPos[0];
182 rayhit.ray.org_y = camPos[1];
183 rayhit.ray.org_z = camPos[2];
186 rayhit.ray.dir_x = camDir[0] + u * camRight[0] + v * camUpTrue[0];
187 rayhit.ray.dir_y = camDir[1] + u * camRight[1] + v * camUpTrue[1];
188 rayhit.ray.dir_z = camDir[2] + u * camRight[2] + v * camUpTrue[2];
191 rayhit.ray.tnear = 0.01;
192 rayhit.ray.tfar = INFINITY;
194 rayhit.ray.flags = 0;
195 rayhit.hit.geomID = RTC_INVALID_GEOMETRY_ID;
196 rayhit.hit.instID[0] = RTC_INVALID_GEOMETRY_ID;
197 rtcIntersect1(scene, &context, &rayhit);
200 const bool hitPrimitive = rayhit.hit.geomID != RTC_INVALID_GEOMETRY_ID;
202 depthBuffer[pixelIndex] = std::max(0.0f, rayhit.ray.tfar);
203 primitiveIds[pixelIndex] = rayhit.hit.primID;
204 barycentricCoordinates[bcIndex++] = rayhit.hit.u;
205 barycentricCoordinates[bcIndex++] = rayhit.hit.v;
207 depthBuffer[pixelIndex] = nan;
209 barycentricCoordinates[bcIndex++] = nan;
210 barycentricCoordinates[bcIndex++] = nan;
218 + std::string(orthographicProjection ?
"O" :
"P") +
"|"
219 + std::to_string(resX) +
"x" + std::to_string(resY) +
")",
220 1, timer.getElapsedTime(), this->threadNumber_);
#define ttkNotUsed(x)
Mark function/method parameters that are not used in the function body at all.
~CinemaImagingEmbree() override
static const unsigned int INVALID_ID
void setDebugMsgPrefix(const std::string &prefix)
coefficient_t normalize(const coefficient_t n, const coefficient_t modulus)
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/|__ _|"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)