1// Copyright 2009-2021 Intel Corporation
2// SPDX-License-Identifier: Apache-2.0
3
4#define RTC_EXPORT_API
5
6#include "default.h"
7#include "device.h"
8#include "scene.h"
9#include "context.h"
10#include "../geometry/filter.h"
11#include "../../include/embree3/rtcore_ray.h"
12using namespace embree;
13
14RTC_NAMESPACE_BEGIN;
15
16 /* mutex to make API thread safe */
17 static MutexSys g_mutex;
18
19 RTC_API RTCDevice rtcNewDevice(const char* config)
20 {
21 RTC_CATCH_BEGIN;
22 RTC_TRACE(rtcNewDevice);
23 Lock<MutexSys> lock(g_mutex);
24 Device* device = new Device(config);
25 return (RTCDevice) device->refInc();
26 RTC_CATCH_END(nullptr);
27 return (RTCDevice) nullptr;
28 }
29
30 RTC_API void rtcRetainDevice(RTCDevice hdevice)
31 {
32 Device* device = (Device*) hdevice;
33 RTC_CATCH_BEGIN;
34 RTC_TRACE(rtcRetainDevice);
35 RTC_VERIFY_HANDLE(hdevice);
36 Lock<MutexSys> lock(g_mutex);
37 device->refInc();
38 RTC_CATCH_END(nullptr);
39 }
40
41 RTC_API void rtcReleaseDevice(RTCDevice hdevice)
42 {
43 Device* device = (Device*) hdevice;
44 RTC_CATCH_BEGIN;
45 RTC_TRACE(rtcReleaseDevice);
46 RTC_VERIFY_HANDLE(hdevice);
47 Lock<MutexSys> lock(g_mutex);
48 device->refDec();
49 RTC_CATCH_END(nullptr);
50 }
51
52 RTC_API ssize_t rtcGetDeviceProperty(RTCDevice hdevice, RTCDeviceProperty prop)
53 {
54 Device* device = (Device*) hdevice;
55 RTC_CATCH_BEGIN;
56 RTC_TRACE(rtcGetDeviceProperty);
57 RTC_VERIFY_HANDLE(hdevice);
58 Lock<MutexSys> lock(g_mutex);
59 return device->getProperty(prop);
60 RTC_CATCH_END(device);
61 return 0;
62 }
63
64 RTC_API void rtcSetDeviceProperty(RTCDevice hdevice, const RTCDeviceProperty prop, ssize_t val)
65 {
66 Device* device = (Device*) hdevice;
67 RTC_CATCH_BEGIN;
68 RTC_TRACE(rtcSetDeviceProperty);
69 const bool internal_prop = (size_t)prop >= 1000000 && (size_t)prop < 1000004;
70 if (!internal_prop) RTC_VERIFY_HANDLE(hdevice); // allow NULL device for special internal settings
71 Lock<MutexSys> lock(g_mutex);
72 device->setProperty(prop,val);
73 RTC_CATCH_END(device);
74 }
75
76 RTC_API RTCError rtcGetDeviceError(RTCDevice hdevice)
77 {
78 Device* device = (Device*) hdevice;
79 RTC_CATCH_BEGIN;
80 RTC_TRACE(rtcGetDeviceError);
81 if (device == nullptr) return Device::getThreadErrorCode();
82 else return device->getDeviceErrorCode();
83 RTC_CATCH_END(device);
84 return RTC_ERROR_UNKNOWN;
85 }
86
87 RTC_API void rtcSetDeviceErrorFunction(RTCDevice hdevice, RTCErrorFunction error, void* userPtr)
88 {
89 Device* device = (Device*) hdevice;
90 RTC_CATCH_BEGIN;
91 RTC_TRACE(rtcSetDeviceErrorFunction);
92 RTC_VERIFY_HANDLE(hdevice);
93 device->setErrorFunction(error, userPtr);
94 RTC_CATCH_END(device);
95 }
96
97 RTC_API void rtcSetDeviceMemoryMonitorFunction(RTCDevice hdevice, RTCMemoryMonitorFunction memoryMonitor, void* userPtr)
98 {
99 Device* device = (Device*) hdevice;
100 RTC_CATCH_BEGIN;
101 RTC_TRACE(rtcSetDeviceMemoryMonitorFunction);
102 device->setMemoryMonitorFunction(memoryMonitor, userPtr);
103 RTC_CATCH_END(device);
104 }
105
106 RTC_API RTCBuffer rtcNewBuffer(RTCDevice hdevice, size_t byteSize)
107 {
108 RTC_CATCH_BEGIN;
109 RTC_TRACE(rtcNewBuffer);
110 RTC_VERIFY_HANDLE(hdevice);
111 Buffer* buffer = new Buffer((Device*)hdevice, byteSize);
112 return (RTCBuffer)buffer->refInc();
113 RTC_CATCH_END((Device*)hdevice);
114 return nullptr;
115 }
116
117 RTC_API RTCBuffer rtcNewSharedBuffer(RTCDevice hdevice, void* ptr, size_t byteSize)
118 {
119 RTC_CATCH_BEGIN;
120 RTC_TRACE(rtcNewSharedBuffer);
121 RTC_VERIFY_HANDLE(hdevice);
122 Buffer* buffer = new Buffer((Device*)hdevice, byteSize, ptr);
123 return (RTCBuffer)buffer->refInc();
124 RTC_CATCH_END((Device*)hdevice);
125 return nullptr;
126 }
127
128 RTC_API void* rtcGetBufferData(RTCBuffer hbuffer)
129 {
130 Buffer* buffer = (Buffer*)hbuffer;
131 RTC_CATCH_BEGIN;
132 RTC_TRACE(rtcGetBufferData);
133 RTC_VERIFY_HANDLE(hbuffer);
134 return buffer->data();
135 RTC_CATCH_END2(buffer);
136 return nullptr;
137 }
138
139 RTC_API void rtcRetainBuffer(RTCBuffer hbuffer)
140 {
141 Buffer* buffer = (Buffer*)hbuffer;
142 RTC_CATCH_BEGIN;
143 RTC_TRACE(rtcRetainBuffer);
144 RTC_VERIFY_HANDLE(hbuffer);
145 buffer->refInc();
146 RTC_CATCH_END2(buffer);
147 }
148
149 RTC_API void rtcReleaseBuffer(RTCBuffer hbuffer)
150 {
151 Buffer* buffer = (Buffer*)hbuffer;
152 RTC_CATCH_BEGIN;
153 RTC_TRACE(rtcReleaseBuffer);
154 RTC_VERIFY_HANDLE(hbuffer);
155 buffer->refDec();
156 RTC_CATCH_END2(buffer);
157 }
158
159 RTC_API RTCScene rtcNewScene (RTCDevice hdevice)
160 {
161 RTC_CATCH_BEGIN;
162 RTC_TRACE(rtcNewScene);
163 RTC_VERIFY_HANDLE(hdevice);
164 Scene* scene = new Scene((Device*)hdevice);
165 return (RTCScene) scene->refInc();
166 RTC_CATCH_END((Device*)hdevice);
167 return nullptr;
168 }
169
170 RTC_API RTCDevice rtcGetSceneDevice(RTCScene hscene)
171 {
172 Scene* scene = (Scene*) hscene;
173 RTC_CATCH_BEGIN;
174 RTC_TRACE(rtcGetSceneDevice);
175 RTC_VERIFY_HANDLE(hscene);
176 return (RTCDevice)scene->device->refInc(); // user will own one additional device reference
177 RTC_CATCH_END2(scene);
178 return (RTCDevice)nullptr;
179 }
180
181 RTC_API void rtcSetSceneProgressMonitorFunction(RTCScene hscene, RTCProgressMonitorFunction progress, void* ptr)
182 {
183 Scene* scene = (Scene*) hscene;
184 RTC_CATCH_BEGIN;
185 RTC_TRACE(rtcSetSceneProgressMonitorFunction);
186 RTC_VERIFY_HANDLE(hscene);
187 Lock<MutexSys> lock(g_mutex);
188 scene->setProgressMonitorFunction(progress,ptr);
189 RTC_CATCH_END2(scene);
190 }
191
192 RTC_API void rtcSetSceneBuildQuality (RTCScene hscene, RTCBuildQuality quality)
193 {
194 Scene* scene = (Scene*) hscene;
195 RTC_CATCH_BEGIN;
196 RTC_TRACE(rtcSetSceneBuildQuality);
197 RTC_VERIFY_HANDLE(hscene);
198 if (quality != RTC_BUILD_QUALITY_LOW &&
199 quality != RTC_BUILD_QUALITY_MEDIUM &&
200 quality != RTC_BUILD_QUALITY_HIGH)
201 // -- GODOT start --
202 // throw std::runtime_error("invalid build quality");
203 abort();
204 // -- GODOT end --
205 scene->setBuildQuality(quality);
206 RTC_CATCH_END2(scene);
207 }
208
209 RTC_API void rtcSetSceneFlags (RTCScene hscene, RTCSceneFlags flags)
210 {
211 Scene* scene = (Scene*) hscene;
212 RTC_CATCH_BEGIN;
213 RTC_TRACE(rtcSetSceneFlags);
214 RTC_VERIFY_HANDLE(hscene);
215 scene->setSceneFlags(flags);
216 RTC_CATCH_END2(scene);
217 }
218
219 RTC_API RTCSceneFlags rtcGetSceneFlags(RTCScene hscene)
220 {
221 Scene* scene = (Scene*) hscene;
222 RTC_CATCH_BEGIN;
223 RTC_TRACE(rtcGetSceneFlags);
224 RTC_VERIFY_HANDLE(hscene);
225 return scene->getSceneFlags();
226 RTC_CATCH_END2(scene);
227 return RTC_SCENE_FLAG_NONE;
228 }
229
230 RTC_API void rtcCommitScene (RTCScene hscene)
231 {
232 Scene* scene = (Scene*) hscene;
233 RTC_CATCH_BEGIN;
234 RTC_TRACE(rtcCommitScene);
235 RTC_VERIFY_HANDLE(hscene);
236 scene->commit(false);
237 RTC_CATCH_END2(scene);
238 }
239
240 RTC_API void rtcJoinCommitScene (RTCScene hscene)
241 {
242 Scene* scene = (Scene*) hscene;
243 RTC_CATCH_BEGIN;
244 RTC_TRACE(rtcJoinCommitScene);
245 RTC_VERIFY_HANDLE(hscene);
246 scene->commit(true);
247 RTC_CATCH_END2(scene);
248 }
249
250 RTC_API void rtcGetSceneBounds(RTCScene hscene, RTCBounds* bounds_o)
251 {
252 Scene* scene = (Scene*) hscene;
253 RTC_CATCH_BEGIN;
254 RTC_TRACE(rtcGetSceneBounds);
255 RTC_VERIFY_HANDLE(hscene);
256 if (scene->isModified()) throw_RTCError(RTC_ERROR_INVALID_OPERATION,"scene not committed");
257 BBox3fa bounds = scene->bounds.bounds();
258 bounds_o->lower_x = bounds.lower.x;
259 bounds_o->lower_y = bounds.lower.y;
260 bounds_o->lower_z = bounds.lower.z;
261 bounds_o->align0 = 0;
262 bounds_o->upper_x = bounds.upper.x;
263 bounds_o->upper_y = bounds.upper.y;
264 bounds_o->upper_z = bounds.upper.z;
265 bounds_o->align1 = 0;
266 RTC_CATCH_END2(scene);
267 }
268
269 RTC_API void rtcGetSceneLinearBounds(RTCScene hscene, RTCLinearBounds* bounds_o)
270 {
271 Scene* scene = (Scene*) hscene;
272 RTC_CATCH_BEGIN;
273 RTC_TRACE(rtcGetSceneBounds);
274 RTC_VERIFY_HANDLE(hscene);
275 if (bounds_o == nullptr)
276 throw_RTCError(RTC_ERROR_INVALID_OPERATION,"invalid destination pointer");
277 if (scene->isModified())
278 throw_RTCError(RTC_ERROR_INVALID_OPERATION,"scene not committed");
279
280 bounds_o->bounds0.lower_x = scene->bounds.bounds0.lower.x;
281 bounds_o->bounds0.lower_y = scene->bounds.bounds0.lower.y;
282 bounds_o->bounds0.lower_z = scene->bounds.bounds0.lower.z;
283 bounds_o->bounds0.align0 = 0;
284 bounds_o->bounds0.upper_x = scene->bounds.bounds0.upper.x;
285 bounds_o->bounds0.upper_y = scene->bounds.bounds0.upper.y;
286 bounds_o->bounds0.upper_z = scene->bounds.bounds0.upper.z;
287 bounds_o->bounds0.align1 = 0;
288 bounds_o->bounds1.lower_x = scene->bounds.bounds1.lower.x;
289 bounds_o->bounds1.lower_y = scene->bounds.bounds1.lower.y;
290 bounds_o->bounds1.lower_z = scene->bounds.bounds1.lower.z;
291 bounds_o->bounds1.align0 = 0;
292 bounds_o->bounds1.upper_x = scene->bounds.bounds1.upper.x;
293 bounds_o->bounds1.upper_y = scene->bounds.bounds1.upper.y;
294 bounds_o->bounds1.upper_z = scene->bounds.bounds1.upper.z;
295 bounds_o->bounds1.align1 = 0;
296 RTC_CATCH_END2(scene);
297 }
298
299 RTC_API void rtcCollide (RTCScene hscene0, RTCScene hscene1, RTCCollideFunc callback, void* userPtr)
300 {
301 Scene* scene0 = (Scene*) hscene0;
302 Scene* scene1 = (Scene*) hscene1;
303 RTC_CATCH_BEGIN;
304 RTC_TRACE(rtcCollide);
305#if defined(DEBUG)
306 RTC_VERIFY_HANDLE(hscene0);
307 RTC_VERIFY_HANDLE(hscene1);
308 if (scene0->isModified()) throw_RTCError(RTC_ERROR_INVALID_OPERATION,"scene got not committed");
309 if (scene1->isModified()) throw_RTCError(RTC_ERROR_INVALID_OPERATION,"scene got not committed");
310 if (scene0->device != scene1->device) throw_RTCError(RTC_ERROR_INVALID_OPERATION,"scenes are from different devices");
311 auto nUserPrims0 = scene0->getNumPrimitives (Geometry::MTY_USER_GEOMETRY, false);
312 auto nUserPrims1 = scene1->getNumPrimitives (Geometry::MTY_USER_GEOMETRY, false);
313 if (scene0->numPrimitives() != nUserPrims0 && scene1->numPrimitives() != nUserPrims1) throw_RTCError(RTC_ERROR_INVALID_OPERATION,"scenes must only contain user geometries with a single timestep");
314#endif
315 scene0->intersectors.collide(scene0,scene1,callback,userPtr);
316 RTC_CATCH_END(scene0->device);
317 }
318
319 inline bool pointQuery(Scene* scene, RTCPointQuery* query, RTCPointQueryContext* userContext, RTCPointQueryFunction queryFunc, void* userPtr)
320 {
321 bool changed = false;
322 if (userContext->instStackSize > 0)
323 {
324 const AffineSpace3fa transform = AffineSpace3fa_load_unaligned((AffineSpace3fa*)userContext->world2inst[userContext->instStackSize-1]);
325
326 float similarityScale = 0.f;
327 const bool similtude = similarityTransform(transform, &similarityScale);
328 assert((similtude && similarityScale > 0) || (!similtude && similarityScale == 0.f));
329
330 PointQuery query_inst;
331 query_inst.p = xfmPoint(transform, Vec3fa(query->x, query->y, query->z));
332 query_inst.radius = query->radius * similarityScale;
333 query_inst.time = query->time;
334
335 PointQueryContext context_inst(scene, (PointQuery*)query,
336 similtude ? POINT_QUERY_TYPE_SPHERE : POINT_QUERY_TYPE_AABB,
337 queryFunc, userContext, similarityScale, userPtr);
338 changed = scene->intersectors.pointQuery((PointQuery*)&query_inst, &context_inst);
339 }
340 else
341 {
342 PointQueryContext context(scene, (PointQuery*)query,
343 POINT_QUERY_TYPE_SPHERE, queryFunc, userContext, 1.f, userPtr);
344 changed = scene->intersectors.pointQuery((PointQuery*)query, &context);
345 }
346 return changed;
347 }
348
349 RTC_API bool rtcPointQuery(RTCScene hscene, RTCPointQuery* query, RTCPointQueryContext* userContext, RTCPointQueryFunction queryFunc, void* userPtr)
350 {
351 Scene* scene = (Scene*) hscene;
352 RTC_CATCH_BEGIN;
353 RTC_TRACE(rtcPointQuery);
354#if defined(DEBUG)
355 RTC_VERIFY_HANDLE(hscene);
356 RTC_VERIFY_HANDLE(userContext);
357 if (scene->isModified()) throw_RTCError(RTC_ERROR_INVALID_OPERATION,"scene got not committed");
358 if (((size_t)query) & 0x0F) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "query not aligned to 16 bytes");
359 if (((size_t)userContext) & 0x0F) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "context not aligned to 16 bytes");
360#endif
361
362 return pointQuery(scene, query, userContext, queryFunc, userPtr);
363 RTC_CATCH_END2_FALSE(scene);
364 }
365
366 RTC_API bool rtcPointQuery4 (const int* valid, RTCScene hscene, RTCPointQuery4* query, struct RTCPointQueryContext* userContext, RTCPointQueryFunction queryFunc, void** userPtrN)
367 {
368 Scene* scene = (Scene*) hscene;
369 RTC_CATCH_BEGIN;
370 RTC_TRACE(rtcPointQuery4);
371
372#if defined(DEBUG)
373 RTC_VERIFY_HANDLE(hscene);
374 if (scene->isModified()) throw_RTCError(RTC_ERROR_INVALID_OPERATION,"scene got not committed");
375 if (((size_t)valid) & 0x0F) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "mask not aligned to 16 bytes");
376 if (((size_t)query) & 0x0F) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "query not aligned to 16 bytes");
377#endif
378 STAT(size_t cnt=0; for (size_t i=0; i<4; i++) cnt += ((int*)valid)[i] == -1;);
379 STAT3(point_query.travs,cnt,cnt,cnt);
380
381 bool changed = false;
382 PointQuery4* query4 = (PointQuery4*)query;
383 PointQuery query1;
384 for (size_t i=0; i<4; i++) {
385 if (!valid[i]) continue;
386 query4->get(i,query1);
387 changed |= pointQuery(scene, (RTCPointQuery*)&query1, userContext, queryFunc, userPtrN?userPtrN[i]:NULL);
388 query4->set(i,query1);
389 }
390 return changed;
391 RTC_CATCH_END2_FALSE(scene);
392 }
393
394 RTC_API bool rtcPointQuery8 (const int* valid, RTCScene hscene, RTCPointQuery8* query, struct RTCPointQueryContext* userContext, RTCPointQueryFunction queryFunc, void** userPtrN)
395 {
396 Scene* scene = (Scene*) hscene;
397 RTC_CATCH_BEGIN;
398 RTC_TRACE(rtcPointQuery8);
399
400#if defined(DEBUG)
401 RTC_VERIFY_HANDLE(hscene);
402 if (scene->isModified()) throw_RTCError(RTC_ERROR_INVALID_OPERATION,"scene got not committed");
403 if (((size_t)valid) & 0x0F) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "mask not aligned to 16 bytes");
404 if (((size_t)query) & 0x0F) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "query not aligned to 16 bytes");
405#endif
406 STAT(size_t cnt=0; for (size_t i=0; i<4; i++) cnt += ((int*)valid)[i] == -1;);
407 STAT3(point_query.travs,cnt,cnt,cnt);
408
409 bool changed = false;
410 PointQuery8* query8 = (PointQuery8*)query;
411 PointQuery query1;
412 for (size_t i=0; i<8; i++) {
413 if (!valid[i]) continue;
414 query8->get(i,query1);
415 changed |= pointQuery(scene, (RTCPointQuery*)&query1, userContext, queryFunc, userPtrN?userPtrN[i]:NULL);
416 query8->set(i,query1);
417 }
418 return changed;
419 RTC_CATCH_END2_FALSE(scene);
420 }
421
422 RTC_API bool rtcPointQuery16 (const int* valid, RTCScene hscene, RTCPointQuery16* query, struct RTCPointQueryContext* userContext, RTCPointQueryFunction queryFunc, void** userPtrN)
423 {
424 Scene* scene = (Scene*) hscene;
425 RTC_CATCH_BEGIN;
426 RTC_TRACE(rtcPointQuery16);
427
428#if defined(DEBUG)
429 RTC_VERIFY_HANDLE(hscene);
430 if (scene->isModified()) throw_RTCError(RTC_ERROR_INVALID_OPERATION,"scene got not committed");
431 if (((size_t)valid) & 0x0F) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "mask not aligned to 16 bytes");
432 if (((size_t)query) & 0x0F) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "query not aligned to 16 bytes");
433#endif
434 STAT(size_t cnt=0; for (size_t i=0; i<4; i++) cnt += ((int*)valid)[i] == -1;);
435 STAT3(point_query.travs,cnt,cnt,cnt);
436
437 bool changed = false;
438 PointQuery16* query16 = (PointQuery16*)query;
439 PointQuery query1;
440 for (size_t i=0; i<16; i++) {
441 if (!valid[i]) continue;
442 PointQuery query1; query16->get(i,query1);
443 changed |= pointQuery(scene, (RTCPointQuery*)&query1, userContext, queryFunc, userPtrN?userPtrN[i]:NULL);
444 query16->set(i,query1);
445 }
446 return changed;
447 RTC_CATCH_END2_FALSE(scene);
448 }
449
450 RTC_API void rtcIntersect1 (RTCScene hscene, RTCIntersectContext* user_context, RTCRayHit* rayhit)
451 {
452 Scene* scene = (Scene*) hscene;
453 RTC_CATCH_BEGIN;
454 RTC_TRACE(rtcIntersect1);
455#if defined(DEBUG)
456 RTC_VERIFY_HANDLE(hscene);
457 if (scene->isModified()) throw_RTCError(RTC_ERROR_INVALID_OPERATION,"scene not committed");
458 if (((size_t)rayhit) & 0x0F) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "ray not aligned to 16 bytes");
459#endif
460 STAT3(normal.travs,1,1,1);
461 IntersectContext context(scene,user_context);
462 scene->intersectors.intersect(*rayhit,&context);
463#if defined(DEBUG)
464 ((RayHit*)rayhit)->verifyHit();
465#endif
466 RTC_CATCH_END2(scene);
467 }
468
469 RTC_API void rtcIntersect4 (const int* valid, RTCScene hscene, RTCIntersectContext* user_context, RTCRayHit4* rayhit)
470 {
471 Scene* scene = (Scene*) hscene;
472 RTC_CATCH_BEGIN;
473 RTC_TRACE(rtcIntersect4);
474
475#if defined(DEBUG)
476 RTC_VERIFY_HANDLE(hscene);
477 if (scene->isModified()) throw_RTCError(RTC_ERROR_INVALID_OPERATION,"scene not committed");
478 if (((size_t)valid) & 0x0F) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "mask not aligned to 16 bytes");
479 if (((size_t)rayhit) & 0x0F) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "rayhit not aligned to 16 bytes");
480#endif
481 STAT(size_t cnt=0; for (size_t i=0; i<4; i++) cnt += ((int*)valid)[i] == -1;);
482 STAT3(normal.travs,cnt,cnt,cnt);
483
484 IntersectContext context(scene,user_context);
485#if !defined(EMBREE_RAY_PACKETS)
486 RayHit4* ray4 = (RayHit4*) rayhit;
487 for (size_t i=0; i<4; i++) {
488 if (!valid[i]) continue;
489 RayHit ray1; ray4->get(i,ray1);
490 scene->intersectors.intersect((RTCRayHit&)ray1,&context);
491 ray4->set(i,ray1);
492 }
493#else
494 scene->intersectors.intersect4(valid,*rayhit,&context);
495#endif
496
497 RTC_CATCH_END2(scene);
498 }
499
500 RTC_API void rtcIntersect8 (const int* valid, RTCScene hscene, RTCIntersectContext* user_context, RTCRayHit8* rayhit)
501 {
502 Scene* scene = (Scene*) hscene;
503 RTC_CATCH_BEGIN;
504 RTC_TRACE(rtcIntersect8);
505
506#if defined(DEBUG)
507 RTC_VERIFY_HANDLE(hscene);
508 if (scene->isModified()) throw_RTCError(RTC_ERROR_INVALID_OPERATION,"scene not committed");
509 if (((size_t)valid) & 0x1F) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "mask not aligned to 32 bytes");
510 if (((size_t)rayhit) & 0x1F) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "rayhit not aligned to 32 bytes");
511#endif
512 STAT(size_t cnt=0; for (size_t i=0; i<8; i++) cnt += ((int*)valid)[i] == -1;);
513 STAT3(normal.travs,cnt,cnt,cnt);
514
515 IntersectContext context(scene,user_context);
516#if !defined(EMBREE_RAY_PACKETS)
517 RayHit8* ray8 = (RayHit8*) rayhit;
518 for (size_t i=0; i<8; i++) {
519 if (!valid[i]) continue;
520 RayHit ray1; ray8->get(i,ray1);
521 scene->intersectors.intersect((RTCRayHit&)ray1,&context);
522 ray8->set(i,ray1);
523 }
524#else
525 if (likely(scene->intersectors.intersector8))
526 scene->intersectors.intersect8(valid,*rayhit,&context);
527 else
528 scene->device->rayStreamFilters.intersectSOA(scene,(char*)rayhit,8,1,sizeof(RTCRayHit8),&context);
529#endif
530 RTC_CATCH_END2(scene);
531 }
532
533 RTC_API void rtcIntersect16 (const int* valid, RTCScene hscene, RTCIntersectContext* user_context, RTCRayHit16* rayhit)
534 {
535 Scene* scene = (Scene*) hscene;
536 RTC_CATCH_BEGIN;
537 RTC_TRACE(rtcIntersect16);
538
539#if defined(DEBUG)
540 RTC_VERIFY_HANDLE(hscene);
541 if (scene->isModified()) throw_RTCError(RTC_ERROR_INVALID_OPERATION,"scene not committed");
542 if (((size_t)valid) & 0x3F) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "mask not aligned to 64 bytes");
543 if (((size_t)rayhit) & 0x3F) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "rayhit not aligned to 64 bytes");
544#endif
545 STAT(size_t cnt=0; for (size_t i=0; i<16; i++) cnt += ((int*)valid)[i] == -1;);
546 STAT3(normal.travs,cnt,cnt,cnt);
547
548 IntersectContext context(scene,user_context);
549#if !defined(EMBREE_RAY_PACKETS)
550 RayHit16* ray16 = (RayHit16*) rayhit;
551 for (size_t i=0; i<16; i++) {
552 if (!valid[i]) continue;
553 RayHit ray1; ray16->get(i,ray1);
554 scene->intersectors.intersect((RTCRayHit&)ray1,&context);
555 ray16->set(i,ray1);
556 }
557#else
558 if (likely(scene->intersectors.intersector16))
559 scene->intersectors.intersect16(valid,*rayhit,&context);
560 else
561 scene->device->rayStreamFilters.intersectSOA(scene,(char*)rayhit,16,1,sizeof(RTCRayHit16),&context);
562#endif
563 RTC_CATCH_END2(scene);
564 }
565
566 RTC_API void rtcIntersect1M (RTCScene hscene, RTCIntersectContext* user_context, RTCRayHit* rayhit, unsigned int M, size_t byteStride)
567 {
568 Scene* scene = (Scene*) hscene;
569 RTC_CATCH_BEGIN;
570 RTC_TRACE(rtcIntersect1M);
571
572#if defined (EMBREE_RAY_PACKETS)
573#if defined(DEBUG)
574 RTC_VERIFY_HANDLE(hscene);
575 if (scene->isModified()) throw_RTCError(RTC_ERROR_INVALID_OPERATION,"scene not committed");
576 if (((size_t)rayhit ) & 0x03) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "ray not aligned to 4 bytes");
577#endif
578 STAT3(normal.travs,M,M,M);
579 IntersectContext context(scene,user_context);
580
581 /* fast codepath for single rays */
582 if (likely(M == 1)) {
583 if (likely(rayhit->ray.tnear <= rayhit->ray.tfar))
584 scene->intersectors.intersect(*rayhit,&context);
585 }
586
587 /* codepath for streams */
588 else {
589 scene->device->rayStreamFilters.intersectAOS(scene,rayhit,M,byteStride,&context);
590 }
591#else
592 throw_RTCError(RTC_ERROR_INVALID_OPERATION,"rtcIntersect1M not supported");
593#endif
594 RTC_CATCH_END2(scene);
595 }
596
597 RTC_API void rtcIntersect1Mp (RTCScene hscene, RTCIntersectContext* user_context, RTCRayHit** rn, unsigned int M)
598 {
599 Scene* scene = (Scene*) hscene;
600 RTC_CATCH_BEGIN;
601 RTC_TRACE(rtcIntersect1Mp);
602
603#if defined (EMBREE_RAY_PACKETS)
604#if defined(DEBUG)
605 RTC_VERIFY_HANDLE(hscene);
606 if (scene->isModified()) throw_RTCError(RTC_ERROR_INVALID_OPERATION,"scene not committed");
607 if (((size_t)rn) & 0x03) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "ray not aligned to 4 bytes");
608#endif
609 STAT3(normal.travs,M,M,M);
610 IntersectContext context(scene,user_context);
611
612 /* fast codepath for single rays */
613 if (likely(M == 1)) {
614 if (likely(rn[0]->ray.tnear <= rn[0]->ray.tfar))
615 scene->intersectors.intersect(*rn[0],&context);
616 }
617
618 /* codepath for streams */
619 else {
620 scene->device->rayStreamFilters.intersectAOP(scene,rn,M,&context);
621 }
622#else
623 throw_RTCError(RTC_ERROR_INVALID_OPERATION,"rtcIntersect1Mp not supported");
624#endif
625 RTC_CATCH_END2(scene);
626 }
627
628 RTC_API void rtcIntersectNM (RTCScene hscene, RTCIntersectContext* user_context, struct RTCRayHitN* rayhit, unsigned int N, unsigned int M, size_t byteStride)
629 {
630 Scene* scene = (Scene*) hscene;
631 RTC_CATCH_BEGIN;
632 RTC_TRACE(rtcIntersectNM);
633
634#if defined (EMBREE_RAY_PACKETS)
635#if defined(DEBUG)
636 RTC_VERIFY_HANDLE(hscene);
637 if (scene->isModified()) throw_RTCError(RTC_ERROR_INVALID_OPERATION,"scene not committed");
638 if (((size_t)rayhit) & 0x03) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "ray not aligned to 4 bytes");
639#endif
640 STAT3(normal.travs,N*M,N*M,N*M);
641 IntersectContext context(scene,user_context);
642
643 /* code path for single ray streams */
644 if (likely(N == 1))
645 {
646 /* fast code path for streams of size 1 */
647 if (likely(M == 1)) {
648 if (likely(((RTCRayHit*)rayhit)->ray.tnear <= ((RTCRayHit*)rayhit)->ray.tfar))
649 scene->intersectors.intersect(*(RTCRayHit*)rayhit,&context);
650 }
651 /* normal codepath for single ray streams */
652 else {
653 scene->device->rayStreamFilters.intersectAOS(scene,(RTCRayHit*)rayhit,M,byteStride,&context);
654 }
655 }
656 /* code path for ray packet streams */
657 else {
658 scene->device->rayStreamFilters.intersectSOA(scene,(char*)rayhit,N,M,byteStride,&context);
659 }
660#else
661 throw_RTCError(RTC_ERROR_INVALID_OPERATION,"rtcIntersectNM not supported");
662#endif
663 RTC_CATCH_END2(scene);
664 }
665
666 RTC_API void rtcIntersectNp (RTCScene hscene, RTCIntersectContext* user_context, const RTCRayHitNp* rayhit, unsigned int N)
667 {
668 Scene* scene = (Scene*) hscene;
669 RTC_CATCH_BEGIN;
670 RTC_TRACE(rtcIntersectNp);
671
672#if defined (EMBREE_RAY_PACKETS)
673#if defined(DEBUG)
674 RTC_VERIFY_HANDLE(hscene);
675 if (scene->isModified()) throw_RTCError(RTC_ERROR_INVALID_OPERATION,"scene not committed");
676 if (((size_t)rayhit->ray.org_x ) & 0x03 ) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "rayhit->ray.org_x not aligned to 4 bytes");
677 if (((size_t)rayhit->ray.org_y ) & 0x03 ) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "rayhit->ray.org_y not aligned to 4 bytes");
678 if (((size_t)rayhit->ray.org_z ) & 0x03 ) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "rayhit->ray.org_z not aligned to 4 bytes");
679 if (((size_t)rayhit->ray.dir_x ) & 0x03 ) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "rayhit->ray.dir_x not aligned to 4 bytes");
680 if (((size_t)rayhit->ray.dir_y ) & 0x03 ) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "rayhit->ray.dir_y not aligned to 4 bytes");
681 if (((size_t)rayhit->ray.dir_z ) & 0x03 ) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "rayhit->ray.dir_z not aligned to 4 bytes");
682 if (((size_t)rayhit->ray.tnear ) & 0x03 ) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "rayhit->ray.dir_x not aligned to 4 bytes");
683 if (((size_t)rayhit->ray.tfar ) & 0x03 ) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "rayhit->ray.tnear not aligned to 4 bytes");
684 if (((size_t)rayhit->ray.time ) & 0x03 ) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "rayhit->ray.time not aligned to 4 bytes");
685 if (((size_t)rayhit->ray.mask ) & 0x03 ) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "rayhit->ray.mask not aligned to 4 bytes");
686 if (((size_t)rayhit->hit.Ng_x ) & 0x03 ) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "rayhit->hit.Ng_x not aligned to 4 bytes");
687 if (((size_t)rayhit->hit.Ng_y ) & 0x03 ) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "rayhit->hit.Ng_y not aligned to 4 bytes");
688 if (((size_t)rayhit->hit.Ng_z ) & 0x03 ) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "rayhit->hit.Ng_z not aligned to 4 bytes");
689 if (((size_t)rayhit->hit.u ) & 0x03 ) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "rayhit->hit.u not aligned to 4 bytes");
690 if (((size_t)rayhit->hit.v ) & 0x03 ) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "rayhit->hit.v not aligned to 4 bytes");
691 if (((size_t)rayhit->hit.geomID) & 0x03 ) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "rayhit->hit.geomID not aligned to 4 bytes");
692 if (((size_t)rayhit->hit.primID) & 0x03 ) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "rayhit->hit.primID not aligned to 4 bytes");
693 if (((size_t)rayhit->hit.instID) & 0x03 ) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "rayhit->hit.instID not aligned to 4 bytes");
694#endif
695 STAT3(normal.travs,N,N,N);
696 IntersectContext context(scene,user_context);
697 scene->device->rayStreamFilters.intersectSOP(scene,rayhit,N,&context);
698#else
699 throw_RTCError(RTC_ERROR_INVALID_OPERATION,"rtcIntersectNp not supported");
700#endif
701 RTC_CATCH_END2(scene);
702 }
703
704 RTC_API void rtcOccluded1 (RTCScene hscene, RTCIntersectContext* user_context, RTCRay* ray)
705 {
706 Scene* scene = (Scene*) hscene;
707 RTC_CATCH_BEGIN;
708 RTC_TRACE(rtcOccluded1);
709 STAT3(shadow.travs,1,1,1);
710#if defined(DEBUG)
711 RTC_VERIFY_HANDLE(hscene);
712 if (scene->isModified()) throw_RTCError(RTC_ERROR_INVALID_OPERATION,"scene not committed");
713 if (((size_t)ray) & 0x0F) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "ray not aligned to 16 bytes");
714#endif
715 IntersectContext context(scene,user_context);
716 scene->intersectors.occluded(*ray,&context);
717 RTC_CATCH_END2(scene);
718 }
719
720 RTC_API void rtcOccluded4 (const int* valid, RTCScene hscene, RTCIntersectContext* user_context, RTCRay4* ray)
721 {
722 Scene* scene = (Scene*) hscene;
723 RTC_CATCH_BEGIN;
724 RTC_TRACE(rtcOccluded4);
725
726#if defined(DEBUG)
727 RTC_VERIFY_HANDLE(hscene);
728 if (scene->isModified()) throw_RTCError(RTC_ERROR_INVALID_OPERATION,"scene not committed");
729 if (((size_t)valid) & 0x0F) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "mask not aligned to 16 bytes");
730 if (((size_t)ray) & 0x0F) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "ray not aligned to 16 bytes");
731#endif
732 STAT(size_t cnt=0; for (size_t i=0; i<4; i++) cnt += ((int*)valid)[i] == -1;);
733 STAT3(shadow.travs,cnt,cnt,cnt);
734
735 IntersectContext context(scene,user_context);
736#if !defined(EMBREE_RAY_PACKETS)
737 RayHit4* ray4 = (RayHit4*) ray;
738 for (size_t i=0; i<4; i++) {
739 if (!valid[i]) continue;
740 RayHit ray1; ray4->get(i,ray1);
741 scene->intersectors.occluded((RTCRay&)ray1,&context);
742 ray4->geomID[i] = ray1.geomID;
743 }
744#else
745 scene->intersectors.occluded4(valid,*ray,&context);
746#endif
747
748 RTC_CATCH_END2(scene);
749 }
750
751 RTC_API void rtcOccluded8 (const int* valid, RTCScene hscene, RTCIntersectContext* user_context, RTCRay8* ray)
752 {
753 Scene* scene = (Scene*) hscene;
754 RTC_CATCH_BEGIN;
755 RTC_TRACE(rtcOccluded8);
756
757#if defined(DEBUG)
758 RTC_VERIFY_HANDLE(hscene);
759 if (scene->isModified()) throw_RTCError(RTC_ERROR_INVALID_OPERATION,"scene not committed");
760 if (((size_t)valid) & 0x1F) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "mask not aligned to 32 bytes");
761 if (((size_t)ray) & 0x1F) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "ray not aligned to 32 bytes");
762#endif
763 STAT(size_t cnt=0; for (size_t i=0; i<8; i++) cnt += ((int*)valid)[i] == -1;);
764 STAT3(shadow.travs,cnt,cnt,cnt);
765
766 IntersectContext context(scene,user_context);
767#if !defined(EMBREE_RAY_PACKETS)
768 RayHit8* ray8 = (RayHit8*) ray;
769 for (size_t i=0; i<8; i++) {
770 if (!valid[i]) continue;
771 RayHit ray1; ray8->get(i,ray1);
772 scene->intersectors.occluded((RTCRay&)ray1,&context);
773 ray8->set(i,ray1);
774 }
775#else
776 if (likely(scene->intersectors.intersector8))
777 scene->intersectors.occluded8(valid,*ray,&context);
778 else
779 scene->device->rayStreamFilters.occludedSOA(scene,(char*)ray,8,1,sizeof(RTCRay8),&context);
780#endif
781
782 RTC_CATCH_END2(scene);
783 }
784
785 RTC_API void rtcOccluded16 (const int* valid, RTCScene hscene, RTCIntersectContext* user_context, RTCRay16* ray)
786 {
787 Scene* scene = (Scene*) hscene;
788 RTC_CATCH_BEGIN;
789 RTC_TRACE(rtcOccluded16);
790
791#if defined(DEBUG)
792 RTC_VERIFY_HANDLE(hscene);
793 if (scene->isModified()) throw_RTCError(RTC_ERROR_INVALID_OPERATION,"scene not committed");
794 if (((size_t)valid) & 0x3F) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "mask not aligned to 64 bytes");
795 if (((size_t)ray) & 0x3F) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "ray not aligned to 64 bytes");
796#endif
797 STAT(size_t cnt=0; for (size_t i=0; i<16; i++) cnt += ((int*)valid)[i] == -1;);
798 STAT3(shadow.travs,cnt,cnt,cnt);
799
800 IntersectContext context(scene,user_context);
801#if !defined(EMBREE_RAY_PACKETS)
802 RayHit16* ray16 = (RayHit16*) ray;
803 for (size_t i=0; i<16; i++) {
804 if (!valid[i]) continue;
805 RayHit ray1; ray16->get(i,ray1);
806 scene->intersectors.occluded((RTCRay&)ray1,&context);
807 ray16->set(i,ray1);
808 }
809#else
810 if (likely(scene->intersectors.intersector16))
811 scene->intersectors.occluded16(valid,*ray,&context);
812 else
813 scene->device->rayStreamFilters.occludedSOA(scene,(char*)ray,16,1,sizeof(RTCRay16),&context);
814#endif
815
816 RTC_CATCH_END2(scene);
817 }
818
819 RTC_API void rtcOccluded1M(RTCScene hscene, RTCIntersectContext* user_context, RTCRay* ray, unsigned int M, size_t byteStride)
820 {
821 Scene* scene = (Scene*) hscene;
822 RTC_CATCH_BEGIN;
823 RTC_TRACE(rtcOccluded1M);
824
825#if defined (EMBREE_RAY_PACKETS)
826#if defined(DEBUG)
827 RTC_VERIFY_HANDLE(hscene);
828 if (scene->isModified()) throw_RTCError(RTC_ERROR_INVALID_OPERATION,"scene not committed");
829 if (((size_t)ray) & 0x03) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "ray not aligned to 4 bytes");
830#endif
831 STAT3(shadow.travs,M,M,M);
832 IntersectContext context(scene,user_context);
833 /* fast codepath for streams of size 1 */
834 if (likely(M == 1)) {
835 if (likely(ray->tnear <= ray->tfar))
836 scene->intersectors.occluded (*ray,&context);
837 }
838 /* codepath for normal streams */
839 else {
840 scene->device->rayStreamFilters.occludedAOS(scene,ray,M,byteStride,&context);
841 }
842#else
843 throw_RTCError(RTC_ERROR_INVALID_OPERATION,"rtcOccluded1M not supported");
844#endif
845 RTC_CATCH_END2(scene);
846 }
847
848 RTC_API void rtcOccluded1Mp(RTCScene hscene, RTCIntersectContext* user_context, RTCRay** ray, unsigned int M)
849 {
850 Scene* scene = (Scene*) hscene;
851 RTC_CATCH_BEGIN;
852 RTC_TRACE(rtcOccluded1Mp);
853
854#if defined (EMBREE_RAY_PACKETS)
855#if defined(DEBUG)
856 RTC_VERIFY_HANDLE(hscene);
857 if (scene->isModified()) throw_RTCError(RTC_ERROR_INVALID_OPERATION,"scene not committed");
858 if (((size_t)ray) & 0x03) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "ray not aligned to 4 bytes");
859#endif
860 STAT3(shadow.travs,M,M,M);
861 IntersectContext context(scene,user_context);
862
863 /* fast codepath for streams of size 1 */
864 if (likely(M == 1)) {
865 if (likely(ray[0]->tnear <= ray[0]->tfar))
866 scene->intersectors.occluded (*ray[0],&context);
867 }
868 /* codepath for normal streams */
869 else {
870 scene->device->rayStreamFilters.occludedAOP(scene,ray,M,&context);
871 }
872#else
873 throw_RTCError(RTC_ERROR_INVALID_OPERATION,"rtcOccluded1Mp not supported");
874#endif
875 RTC_CATCH_END2(scene);
876 }
877
878 RTC_API void rtcOccludedNM(RTCScene hscene, RTCIntersectContext* user_context, RTCRayN* ray, unsigned int N, unsigned int M, size_t byteStride)
879 {
880 Scene* scene = (Scene*) hscene;
881 RTC_CATCH_BEGIN;
882 RTC_TRACE(rtcOccludedNM);
883
884#if defined (EMBREE_RAY_PACKETS)
885#if defined(DEBUG)
886 RTC_VERIFY_HANDLE(hscene);
887 if (byteStride < sizeof(RTCRayHit)) throw_RTCError(RTC_ERROR_INVALID_OPERATION,"byteStride too small");
888 if (scene->isModified()) throw_RTCError(RTC_ERROR_INVALID_OPERATION,"scene not committed");
889 if (((size_t)ray) & 0x03) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "ray not aligned to 4 bytes");
890#endif
891 STAT3(shadow.travs,N*M,N*N,N*N);
892 IntersectContext context(scene,user_context);
893
894 /* codepath for single rays */
895 if (likely(N == 1))
896 {
897 /* fast path for streams of size 1 */
898 if (likely(M == 1)) {
899 if (likely(((RTCRay*)ray)->tnear <= ((RTCRay*)ray)->tfar))
900 scene->intersectors.occluded (*(RTCRay*)ray,&context);
901 }
902 /* codepath for normal ray streams */
903 else {
904 scene->device->rayStreamFilters.occludedAOS(scene,(RTCRay*)ray,M,byteStride,&context);
905 }
906 }
907 /* code path for ray packet streams */
908 else {
909 scene->device->rayStreamFilters.occludedSOA(scene,(char*)ray,N,M,byteStride,&context);
910 }
911#else
912 throw_RTCError(RTC_ERROR_INVALID_OPERATION,"rtcOccludedNM not supported");
913#endif
914 RTC_CATCH_END2(scene);
915 }
916
917 RTC_API void rtcOccludedNp(RTCScene hscene, RTCIntersectContext* user_context, const RTCRayNp* ray, unsigned int N)
918 {
919 Scene* scene = (Scene*) hscene;
920 RTC_CATCH_BEGIN;
921 RTC_TRACE(rtcOccludedNp);
922
923#if defined (EMBREE_RAY_PACKETS)
924#if defined(DEBUG)
925 RTC_VERIFY_HANDLE(hscene);
926 if (scene->isModified()) throw_RTCError(RTC_ERROR_INVALID_OPERATION,"scene not committed");
927 if (((size_t)ray->org_x ) & 0x03 ) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "org_x not aligned to 4 bytes");
928 if (((size_t)ray->org_y ) & 0x03 ) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "org_y not aligned to 4 bytes");
929 if (((size_t)ray->org_z ) & 0x03 ) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "org_z not aligned to 4 bytes");
930 if (((size_t)ray->dir_x ) & 0x03 ) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "dir_x not aligned to 4 bytes");
931 if (((size_t)ray->dir_y ) & 0x03 ) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "dir_y not aligned to 4 bytes");
932 if (((size_t)ray->dir_z ) & 0x03 ) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "dir_z not aligned to 4 bytes");
933 if (((size_t)ray->tnear ) & 0x03 ) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "dir_x not aligned to 4 bytes");
934 if (((size_t)ray->tfar ) & 0x03 ) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "tnear not aligned to 4 bytes");
935 if (((size_t)ray->time ) & 0x03 ) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "time not aligned to 4 bytes");
936 if (((size_t)ray->mask ) & 0x03 ) throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "mask not aligned to 4 bytes");
937#endif
938 STAT3(shadow.travs,N,N,N);
939 IntersectContext context(scene,user_context);
940 scene->device->rayStreamFilters.occludedSOP(scene,ray,N,&context);
941#else
942 throw_RTCError(RTC_ERROR_INVALID_OPERATION,"rtcOccludedNp not supported");
943#endif
944 RTC_CATCH_END2(scene);
945 }
946
947 RTC_API void rtcRetainScene (RTCScene hscene)
948 {
949 Scene* scene = (Scene*) hscene;
950 RTC_CATCH_BEGIN;
951 RTC_TRACE(rtcRetainScene);
952 RTC_VERIFY_HANDLE(hscene);
953 scene->refInc();
954 RTC_CATCH_END2(scene);
955 }
956
957 RTC_API void rtcReleaseScene (RTCScene hscene)
958 {
959 Scene* scene = (Scene*) hscene;
960 RTC_CATCH_BEGIN;
961 RTC_TRACE(rtcReleaseScene);
962 RTC_VERIFY_HANDLE(hscene);
963 scene->refDec();
964 RTC_CATCH_END2(scene);
965 }
966
967 RTC_API void rtcSetGeometryInstancedScene(RTCGeometry hgeometry, RTCScene hscene)
968 {
969 Geometry* geometry = (Geometry*) hgeometry;
970 Ref<Scene> scene = (Scene*) hscene;
971 RTC_CATCH_BEGIN;
972 RTC_TRACE(rtcSetGeometryInstancedScene);
973 RTC_VERIFY_HANDLE(hgeometry);
974 RTC_VERIFY_HANDLE(hscene);
975 geometry->setInstancedScene(scene);
976 RTC_CATCH_END2(geometry);
977 }
978
979 AffineSpace3fa loadTransform(RTCFormat format, const float* xfm)
980 {
981 AffineSpace3fa space = one;
982 switch (format)
983 {
984 case RTC_FORMAT_FLOAT3X4_ROW_MAJOR:
985 space = AffineSpace3fa(Vec3fa(xfm[ 0], xfm[ 4], xfm[ 8]),
986 Vec3fa(xfm[ 1], xfm[ 5], xfm[ 9]),
987 Vec3fa(xfm[ 2], xfm[ 6], xfm[10]),
988 Vec3fa(xfm[ 3], xfm[ 7], xfm[11]));
989 break;
990
991 case RTC_FORMAT_FLOAT3X4_COLUMN_MAJOR:
992 space = AffineSpace3fa(Vec3fa(xfm[ 0], xfm[ 1], xfm[ 2]),
993 Vec3fa(xfm[ 3], xfm[ 4], xfm[ 5]),
994 Vec3fa(xfm[ 6], xfm[ 7], xfm[ 8]),
995 Vec3fa(xfm[ 9], xfm[10], xfm[11]));
996 break;
997
998 case RTC_FORMAT_FLOAT4X4_COLUMN_MAJOR:
999 space = AffineSpace3fa(Vec3fa(xfm[ 0], xfm[ 1], xfm[ 2]),
1000 Vec3fa(xfm[ 4], xfm[ 5], xfm[ 6]),
1001 Vec3fa(xfm[ 8], xfm[ 9], xfm[10]),
1002 Vec3fa(xfm[12], xfm[13], xfm[14]));
1003 break;
1004
1005 default:
1006 throw_RTCError(RTC_ERROR_INVALID_OPERATION, "invalid matrix format");
1007 break;
1008 }
1009 return space;
1010 }
1011
1012 void storeTransform(const AffineSpace3fa& space, RTCFormat format, float* xfm)
1013 {
1014 switch (format)
1015 {
1016 case RTC_FORMAT_FLOAT3X4_ROW_MAJOR:
1017 xfm[ 0] = space.l.vx.x; xfm[ 1] = space.l.vy.x; xfm[ 2] = space.l.vz.x; xfm[ 3] = space.p.x;
1018 xfm[ 4] = space.l.vx.y; xfm[ 5] = space.l.vy.y; xfm[ 6] = space.l.vz.y; xfm[ 7] = space.p.y;
1019 xfm[ 8] = space.l.vx.z; xfm[ 9] = space.l.vy.z; xfm[10] = space.l.vz.z; xfm[11] = space.p.z;
1020 break;
1021
1022 case RTC_FORMAT_FLOAT3X4_COLUMN_MAJOR:
1023 xfm[ 0] = space.l.vx.x; xfm[ 1] = space.l.vx.y; xfm[ 2] = space.l.vx.z;
1024 xfm[ 3] = space.l.vy.x; xfm[ 4] = space.l.vy.y; xfm[ 5] = space.l.vy.z;
1025 xfm[ 6] = space.l.vz.x; xfm[ 7] = space.l.vz.y; xfm[ 8] = space.l.vz.z;
1026 xfm[ 9] = space.p.x; xfm[10] = space.p.y; xfm[11] = space.p.z;
1027 break;
1028
1029 case RTC_FORMAT_FLOAT4X4_COLUMN_MAJOR:
1030 xfm[ 0] = space.l.vx.x; xfm[ 1] = space.l.vx.y; xfm[ 2] = space.l.vx.z; xfm[ 3] = 0.f;
1031 xfm[ 4] = space.l.vy.x; xfm[ 5] = space.l.vy.y; xfm[ 6] = space.l.vy.z; xfm[ 7] = 0.f;
1032 xfm[ 8] = space.l.vz.x; xfm[ 9] = space.l.vz.y; xfm[10] = space.l.vz.z; xfm[11] = 0.f;
1033 xfm[12] = space.p.x; xfm[13] = space.p.y; xfm[14] = space.p.z; xfm[15] = 1.f;
1034 break;
1035
1036 default:
1037 throw_RTCError(RTC_ERROR_INVALID_OPERATION, "invalid matrix format");
1038 break;
1039 }
1040 }
1041
1042 RTC_API void rtcSetGeometryTransform(RTCGeometry hgeometry, unsigned int timeStep, RTCFormat format, const void* xfm)
1043 {
1044 Geometry* geometry = (Geometry*) hgeometry;
1045 RTC_CATCH_BEGIN;
1046 RTC_TRACE(rtcSetGeometryTransform);
1047 RTC_VERIFY_HANDLE(hgeometry);
1048 RTC_VERIFY_HANDLE(xfm);
1049 const AffineSpace3fa transform = loadTransform(format, (const float*)xfm);
1050 geometry->setTransform(transform, timeStep);
1051 RTC_CATCH_END2(geometry);
1052 }
1053
1054 RTC_API void rtcSetGeometryTransformQuaternion(RTCGeometry hgeometry, unsigned int timeStep, const RTCQuaternionDecomposition* qd)
1055 {
1056 Geometry* geometry = (Geometry*) hgeometry;
1057 RTC_CATCH_BEGIN;
1058 RTC_TRACE(rtcSetGeometryTransformQuaternion);
1059 RTC_VERIFY_HANDLE(hgeometry);
1060 RTC_VERIFY_HANDLE(qd);
1061
1062 AffineSpace3fx transform;
1063 transform.l.vx.x = qd->scale_x;
1064 transform.l.vy.y = qd->scale_y;
1065 transform.l.vz.z = qd->scale_z;
1066 transform.l.vy.x = qd->skew_xy;
1067 transform.l.vz.x = qd->skew_xz;
1068 transform.l.vz.y = qd->skew_yz;
1069 transform.l.vx.y = qd->translation_x;
1070 transform.l.vx.z = qd->translation_y;
1071 transform.l.vy.z = qd->translation_z;
1072 transform.p.x = qd->shift_x;
1073 transform.p.y = qd->shift_y;
1074 transform.p.z = qd->shift_z;
1075
1076 // normalize quaternion
1077 Quaternion3f q(qd->quaternion_r, qd->quaternion_i, qd->quaternion_j, qd->quaternion_k);
1078 q = normalize(q);
1079 transform.l.vx.w = q.i;
1080 transform.l.vy.w = q.j;
1081 transform.l.vz.w = q.k;
1082 transform.p.w = q.r;
1083
1084 geometry->setQuaternionDecomposition(transform, timeStep);
1085 RTC_CATCH_END2(geometry);
1086 }
1087
1088 RTC_API void rtcGetGeometryTransform(RTCGeometry hgeometry, float time, RTCFormat format, void* xfm)
1089 {
1090 Geometry* geometry = (Geometry*) hgeometry;
1091 RTC_CATCH_BEGIN;
1092 RTC_TRACE(rtcGetGeometryTransform);
1093 const AffineSpace3fa transform = geometry->getTransform(time);
1094 storeTransform(transform, format, (float*)xfm);
1095 RTC_CATCH_END2(geometry);
1096 }
1097
1098 RTC_API void rtcFilterIntersection(const struct RTCIntersectFunctionNArguments* const args_i, const struct RTCFilterFunctionNArguments* filter_args)
1099 {
1100 IntersectFunctionNArguments* args = (IntersectFunctionNArguments*) args_i;
1101 isa::reportIntersection1(args, filter_args);
1102 }
1103
1104 RTC_API void rtcFilterOcclusion(const struct RTCOccludedFunctionNArguments* const args_i, const struct RTCFilterFunctionNArguments* filter_args)
1105 {
1106 OccludedFunctionNArguments* args = (OccludedFunctionNArguments*) args_i;
1107 isa::reportOcclusion1(args,filter_args);
1108 }
1109
1110 RTC_API RTCGeometry rtcNewGeometry (RTCDevice hdevice, RTCGeometryType type)
1111 {
1112 Device* device = (Device*) hdevice;
1113 RTC_CATCH_BEGIN;
1114 RTC_TRACE(rtcNewGeometry);
1115 RTC_VERIFY_HANDLE(hdevice);
1116
1117 switch (type)
1118 {
1119 case RTC_GEOMETRY_TYPE_TRIANGLE:
1120 {
1121#if defined(EMBREE_GEOMETRY_TRIANGLE)
1122 createTriangleMeshTy createTriangleMesh = nullptr;
1123 SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512(device->enabled_cpu_features,createTriangleMesh);
1124 Geometry* geom = createTriangleMesh(device);
1125 return (RTCGeometry) geom->refInc();
1126#else
1127 throw_RTCError(RTC_ERROR_UNKNOWN,"RTC_GEOMETRY_TYPE_TRIANGLE is not supported");
1128#endif
1129 }
1130
1131 case RTC_GEOMETRY_TYPE_QUAD:
1132 {
1133#if defined(EMBREE_GEOMETRY_QUAD)
1134 createQuadMeshTy createQuadMesh = nullptr;
1135 SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512(device->enabled_cpu_features,createQuadMesh);
1136 Geometry* geom = createQuadMesh(device);
1137 return (RTCGeometry) geom->refInc();
1138#else
1139 throw_RTCError(RTC_ERROR_UNKNOWN,"RTC_GEOMETRY_TYPE_QUAD is not supported");
1140#endif
1141 }
1142
1143 case RTC_GEOMETRY_TYPE_SPHERE_POINT:
1144 case RTC_GEOMETRY_TYPE_DISC_POINT:
1145 case RTC_GEOMETRY_TYPE_ORIENTED_DISC_POINT:
1146 {
1147#if defined(EMBREE_GEOMETRY_POINT)
1148 createPointsTy createPoints = nullptr;
1149 SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512(device->enabled_builder_cpu_features, createPoints);
1150
1151 Geometry *geom;
1152 switch(type) {
1153 case RTC_GEOMETRY_TYPE_SPHERE_POINT:
1154 geom = createPoints(device, Geometry::GTY_SPHERE_POINT);
1155 break;
1156 case RTC_GEOMETRY_TYPE_DISC_POINT:
1157 geom = createPoints(device, Geometry::GTY_DISC_POINT);
1158 break;
1159 case RTC_GEOMETRY_TYPE_ORIENTED_DISC_POINT:
1160 geom = createPoints(device, Geometry::GTY_ORIENTED_DISC_POINT);
1161 break;
1162 default:
1163 geom = nullptr;
1164 break;
1165 }
1166 return (RTCGeometry) geom->refInc();
1167#else
1168 throw_RTCError(RTC_ERROR_UNKNOWN,"RTC_GEOMETRY_TYPE_POINT is not supported");
1169#endif
1170 }
1171
1172 case RTC_GEOMETRY_TYPE_CONE_LINEAR_CURVE:
1173 case RTC_GEOMETRY_TYPE_ROUND_LINEAR_CURVE:
1174 case RTC_GEOMETRY_TYPE_FLAT_LINEAR_CURVE:
1175
1176 case RTC_GEOMETRY_TYPE_ROUND_BEZIER_CURVE:
1177 case RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE:
1178 case RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_BEZIER_CURVE:
1179
1180 case RTC_GEOMETRY_TYPE_ROUND_BSPLINE_CURVE:
1181 case RTC_GEOMETRY_TYPE_FLAT_BSPLINE_CURVE:
1182 case RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_BSPLINE_CURVE:
1183
1184 case RTC_GEOMETRY_TYPE_ROUND_HERMITE_CURVE:
1185 case RTC_GEOMETRY_TYPE_FLAT_HERMITE_CURVE:
1186 case RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_HERMITE_CURVE:
1187
1188 case RTC_GEOMETRY_TYPE_ROUND_CATMULL_ROM_CURVE:
1189 case RTC_GEOMETRY_TYPE_FLAT_CATMULL_ROM_CURVE:
1190 case RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_CATMULL_ROM_CURVE:
1191 {
1192#if defined(EMBREE_GEOMETRY_CURVE)
1193 createLineSegmentsTy createLineSegments = nullptr;
1194 SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512(device->enabled_cpu_features,createLineSegments);
1195 createCurvesTy createCurves = nullptr;
1196 SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512(device->enabled_cpu_features,createCurves);
1197
1198 Geometry* geom;
1199 switch (type) {
1200 case RTC_GEOMETRY_TYPE_CONE_LINEAR_CURVE : geom = createLineSegments (device,Geometry::GTY_CONE_LINEAR_CURVE); break;
1201 case RTC_GEOMETRY_TYPE_ROUND_LINEAR_CURVE : geom = createLineSegments (device,Geometry::GTY_ROUND_LINEAR_CURVE); break;
1202 case RTC_GEOMETRY_TYPE_FLAT_LINEAR_CURVE : geom = createLineSegments (device,Geometry::GTY_FLAT_LINEAR_CURVE); break;
1203 //case RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_LINEAR_CURVE : geom = createLineSegments (device,Geometry::GTY_ORIENTED_LINEAR_CURVE); break;
1204
1205 case RTC_GEOMETRY_TYPE_ROUND_BEZIER_CURVE : geom = createCurves(device,Geometry::GTY_ROUND_BEZIER_CURVE); break;
1206 case RTC_GEOMETRY_TYPE_FLAT_BEZIER_CURVE : geom = createCurves(device,Geometry::GTY_FLAT_BEZIER_CURVE); break;
1207 case RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_BEZIER_CURVE : geom = createCurves(device,Geometry::GTY_ORIENTED_BEZIER_CURVE); break;
1208
1209 case RTC_GEOMETRY_TYPE_ROUND_BSPLINE_CURVE : geom = createCurves(device,Geometry::GTY_ROUND_BSPLINE_CURVE); break;
1210 case RTC_GEOMETRY_TYPE_FLAT_BSPLINE_CURVE : geom = createCurves(device,Geometry::GTY_FLAT_BSPLINE_CURVE); break;
1211 case RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_BSPLINE_CURVE : geom = createCurves(device,Geometry::GTY_ORIENTED_BSPLINE_CURVE); break;
1212
1213 case RTC_GEOMETRY_TYPE_ROUND_HERMITE_CURVE : geom = createCurves(device,Geometry::GTY_ROUND_HERMITE_CURVE); break;
1214 case RTC_GEOMETRY_TYPE_FLAT_HERMITE_CURVE : geom = createCurves(device,Geometry::GTY_FLAT_HERMITE_CURVE); break;
1215 case RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_HERMITE_CURVE : geom = createCurves(device,Geometry::GTY_ORIENTED_HERMITE_CURVE); break;
1216
1217 case RTC_GEOMETRY_TYPE_ROUND_CATMULL_ROM_CURVE : geom = createCurves(device,Geometry::GTY_ROUND_CATMULL_ROM_CURVE); break;
1218 case RTC_GEOMETRY_TYPE_FLAT_CATMULL_ROM_CURVE : geom = createCurves(device,Geometry::GTY_FLAT_CATMULL_ROM_CURVE); break;
1219 case RTC_GEOMETRY_TYPE_NORMAL_ORIENTED_CATMULL_ROM_CURVE : geom = createCurves(device,Geometry::GTY_ORIENTED_CATMULL_ROM_CURVE); break;
1220 default: geom = nullptr; break;
1221 }
1222 return (RTCGeometry) geom->refInc();
1223#else
1224 throw_RTCError(RTC_ERROR_UNKNOWN,"RTC_GEOMETRY_TYPE_CURVE is not supported");
1225#endif
1226 }
1227
1228 case RTC_GEOMETRY_TYPE_SUBDIVISION:
1229 {
1230#if defined(EMBREE_GEOMETRY_SUBDIVISION)
1231 createSubdivMeshTy createSubdivMesh = nullptr;
1232 SELECT_SYMBOL_DEFAULT_AVX(device->enabled_cpu_features,createSubdivMesh);
1233 //SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512(device->enabled_cpu_features,createSubdivMesh); // FIXME: this does not work for some reason?
1234 Geometry* geom = createSubdivMesh(device);
1235 return (RTCGeometry) geom->refInc();
1236#else
1237 throw_RTCError(RTC_ERROR_UNKNOWN,"RTC_GEOMETRY_TYPE_SUBDIVISION is not supported");
1238#endif
1239 }
1240
1241 case RTC_GEOMETRY_TYPE_USER:
1242 {
1243#if defined(EMBREE_GEOMETRY_USER)
1244 createUserGeometryTy createUserGeometry = nullptr;
1245 SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512(device->enabled_cpu_features,createUserGeometry);
1246 Geometry* geom = createUserGeometry(device);
1247 return (RTCGeometry) geom->refInc();
1248#else
1249 throw_RTCError(RTC_ERROR_UNKNOWN,"RTC_GEOMETRY_TYPE_USER is not supported");
1250#endif
1251 }
1252
1253 case RTC_GEOMETRY_TYPE_INSTANCE:
1254 {
1255#if defined(EMBREE_GEOMETRY_INSTANCE)
1256 createInstanceTy createInstance = nullptr;
1257 SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512(device->enabled_cpu_features,createInstance);
1258 Geometry* geom = createInstance(device);
1259 return (RTCGeometry) geom->refInc();
1260#else
1261 throw_RTCError(RTC_ERROR_UNKNOWN,"RTC_GEOMETRY_TYPE_INSTANCE is not supported");
1262#endif
1263 }
1264
1265 case RTC_GEOMETRY_TYPE_GRID:
1266 {
1267#if defined(EMBREE_GEOMETRY_GRID)
1268 createGridMeshTy createGridMesh = nullptr;
1269 SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512(device->enabled_cpu_features,createGridMesh);
1270 Geometry* geom = createGridMesh(device);
1271 return (RTCGeometry) geom->refInc();
1272#else
1273 throw_RTCError(RTC_ERROR_UNKNOWN,"RTC_GEOMETRY_TYPE_GRID is not supported");
1274#endif
1275 }
1276
1277 default:
1278 throw_RTCError(RTC_ERROR_UNKNOWN,"invalid geometry type");
1279 }
1280
1281 RTC_CATCH_END(device);
1282 return nullptr;
1283 }
1284
1285 RTC_API void rtcSetGeometryUserPrimitiveCount(RTCGeometry hgeometry, unsigned int userPrimitiveCount)
1286 {
1287 Geometry* geometry = (Geometry*) hgeometry;
1288 RTC_CATCH_BEGIN;
1289 RTC_TRACE(rtcSetGeometryUserPrimitiveCount);
1290 RTC_VERIFY_HANDLE(hgeometry);
1291
1292 if (unlikely(geometry->getType() != Geometry::GTY_USER_GEOMETRY))
1293 throw_RTCError(RTC_ERROR_INVALID_OPERATION,"operation only allowed for user geometries");
1294
1295 geometry->setNumPrimitives(userPrimitiveCount);
1296 RTC_CATCH_END2(geometry);
1297 }
1298
1299 RTC_API void rtcSetGeometryTimeStepCount(RTCGeometry hgeometry, unsigned int timeStepCount)
1300 {
1301 Geometry* geometry = (Geometry*) hgeometry;
1302 RTC_CATCH_BEGIN;
1303 RTC_TRACE(rtcSetGeometryTimeStepCount);
1304 RTC_VERIFY_HANDLE(hgeometry);
1305
1306 if (timeStepCount > RTC_MAX_TIME_STEP_COUNT)
1307 throw_RTCError(RTC_ERROR_INVALID_ARGUMENT,"number of time steps is out of range");
1308
1309 geometry->setNumTimeSteps(timeStepCount);
1310 RTC_CATCH_END2(geometry);
1311 }
1312
1313 RTC_API void rtcSetGeometryTimeRange(RTCGeometry hgeometry, float startTime, float endTime)
1314 {
1315 Ref<Geometry> geometry = (Geometry*) hgeometry;
1316 RTC_CATCH_BEGIN;
1317 RTC_TRACE(rtcSetGeometryTimeRange);
1318 RTC_VERIFY_HANDLE(hgeometry);
1319
1320 if (startTime > endTime)
1321 throw_RTCError(RTC_ERROR_INVALID_ARGUMENT,"startTime has to be smaller or equal to the endTime");
1322
1323 geometry->setTimeRange(BBox1f(startTime,endTime));
1324 RTC_CATCH_END2(geometry);
1325 }
1326
1327 RTC_API void rtcSetGeometryVertexAttributeCount(RTCGeometry hgeometry, unsigned int N)
1328 {
1329 Geometry* geometry = (Geometry*) hgeometry;
1330 RTC_CATCH_BEGIN;
1331 RTC_TRACE(rtcSetGeometryVertexAttributeCount);
1332 RTC_VERIFY_HANDLE(hgeometry);
1333 geometry->setVertexAttributeCount(N);
1334 RTC_CATCH_END2(geometry);
1335 }
1336
1337 RTC_API void rtcSetGeometryTopologyCount(RTCGeometry hgeometry, unsigned int N)
1338 {
1339 Geometry* geometry = (Geometry*) hgeometry;
1340 RTC_CATCH_BEGIN;
1341 RTC_TRACE(rtcSetGeometryTopologyCount);
1342 RTC_VERIFY_HANDLE(hgeometry);
1343 geometry->setTopologyCount(N);
1344 RTC_CATCH_END2(geometry);
1345 }
1346
1347 RTC_API void rtcSetGeometryBuildQuality (RTCGeometry hgeometry, RTCBuildQuality quality)
1348 {
1349 Geometry* geometry = (Geometry*) hgeometry;
1350 RTC_CATCH_BEGIN;
1351 RTC_TRACE(rtcSetGeometryBuildQuality);
1352 RTC_VERIFY_HANDLE(hgeometry);
1353 if (quality != RTC_BUILD_QUALITY_LOW &&
1354 quality != RTC_BUILD_QUALITY_MEDIUM &&
1355 quality != RTC_BUILD_QUALITY_HIGH &&
1356 quality != RTC_BUILD_QUALITY_REFIT)
1357 // -- GODOT start --
1358 // throw std::runtime_error("invalid build quality");
1359 abort();
1360 // -- GODOT end --
1361 geometry->setBuildQuality(quality);
1362 RTC_CATCH_END2(geometry);
1363 }
1364
1365 RTC_API void rtcSetGeometryMaxRadiusScale(RTCGeometry hgeometry, float maxRadiusScale)
1366 {
1367 Geometry* geometry = (Geometry*) hgeometry;
1368 RTC_CATCH_BEGIN;
1369 RTC_TRACE(rtcSetGeometryMaxRadiusScale);
1370 RTC_VERIFY_HANDLE(hgeometry);
1371#if RTC_MIN_WIDTH
1372 if (maxRadiusScale < 1.0f) throw_RTCError(RTC_ERROR_INVALID_OPERATION,"maximal radius scale has to be larger or equal to 1");
1373 geometry->setMaxRadiusScale(maxRadiusScale);
1374#else
1375 throw_RTCError(RTC_ERROR_INVALID_OPERATION,"min-width feature is not enabled");
1376#endif
1377 RTC_CATCH_END2(geometry);
1378 }
1379
1380 RTC_API void rtcSetGeometryMask (RTCGeometry hgeometry, unsigned int mask)
1381 {
1382 Geometry* geometry = (Geometry*) hgeometry;
1383 RTC_CATCH_BEGIN;
1384 RTC_TRACE(rtcSetGeometryMask);
1385 RTC_VERIFY_HANDLE(hgeometry);
1386 geometry->setMask(mask);
1387 RTC_CATCH_END2(geometry);
1388 }
1389
1390 RTC_API void rtcSetGeometrySubdivisionMode (RTCGeometry hgeometry, unsigned topologyID, RTCSubdivisionMode mode)
1391 {
1392 Geometry* geometry = (Geometry*) hgeometry;
1393 RTC_CATCH_BEGIN;
1394 RTC_TRACE(rtcSetGeometrySubdivisionMode);
1395 RTC_VERIFY_HANDLE(hgeometry);
1396 geometry->setSubdivisionMode(topologyID,mode);
1397 RTC_CATCH_END2(geometry);
1398 }
1399
1400 RTC_API void rtcSetGeometryVertexAttributeTopology(RTCGeometry hgeometry, unsigned int vertexAttributeID, unsigned int topologyID)
1401 {
1402 Geometry* geometry = (Geometry*) hgeometry;
1403 RTC_CATCH_BEGIN;
1404 RTC_TRACE(rtcSetGeometryVertexAttributeTopology);
1405 RTC_VERIFY_HANDLE(hgeometry);
1406 geometry->setVertexAttributeTopology(vertexAttributeID, topologyID);
1407 RTC_CATCH_END2(geometry);
1408 }
1409
1410 RTC_API void rtcSetGeometryBuffer(RTCGeometry hgeometry, RTCBufferType type, unsigned int slot, RTCFormat format, RTCBuffer hbuffer, size_t byteOffset, size_t byteStride, size_t itemCount)
1411 {
1412 Geometry* geometry = (Geometry*) hgeometry;
1413 Ref<Buffer> buffer = (Buffer*)hbuffer;
1414 RTC_CATCH_BEGIN;
1415 RTC_TRACE(rtcSetGeometryBuffer);
1416 RTC_VERIFY_HANDLE(hgeometry);
1417 RTC_VERIFY_HANDLE(hbuffer);
1418
1419 if (geometry->device != buffer->device)
1420 throw_RTCError(RTC_ERROR_INVALID_ARGUMENT,"inputs are from different devices");
1421
1422 if (itemCount > 0xFFFFFFFFu)
1423 throw_RTCError(RTC_ERROR_INVALID_ARGUMENT,"buffer too large");
1424
1425 geometry->setBuffer(type, slot, format, buffer, byteOffset, byteStride, (unsigned int)itemCount);
1426 RTC_CATCH_END2(geometry);
1427 }
1428
1429 RTC_API void rtcSetSharedGeometryBuffer(RTCGeometry hgeometry, RTCBufferType type, unsigned int slot, RTCFormat format, const void* ptr, size_t byteOffset, size_t byteStride, size_t itemCount)
1430 {
1431 Geometry* geometry = (Geometry*) hgeometry;
1432 RTC_CATCH_BEGIN;
1433 RTC_TRACE(rtcSetSharedGeometryBuffer);
1434 RTC_VERIFY_HANDLE(hgeometry);
1435
1436 if (itemCount > 0xFFFFFFFFu)
1437 throw_RTCError(RTC_ERROR_INVALID_ARGUMENT,"buffer too large");
1438
1439 Ref<Buffer> buffer = new Buffer(geometry->device, itemCount*byteStride, (char*)ptr + byteOffset);
1440 geometry->setBuffer(type, slot, format, buffer, 0, byteStride, (unsigned int)itemCount);
1441 RTC_CATCH_END2(geometry);
1442 }
1443
1444 RTC_API void* rtcSetNewGeometryBuffer(RTCGeometry hgeometry, RTCBufferType type, unsigned int slot, RTCFormat format, size_t byteStride, size_t itemCount)
1445 {
1446 Geometry* geometry = (Geometry*) hgeometry;
1447 RTC_CATCH_BEGIN;
1448 RTC_TRACE(rtcSetNewGeometryBuffer);
1449 RTC_VERIFY_HANDLE(hgeometry);
1450
1451 if (itemCount > 0xFFFFFFFFu)
1452 throw_RTCError(RTC_ERROR_INVALID_ARGUMENT,"buffer too large");
1453
1454 /* vertex buffers need to get overallocated slightly as elements are accessed using SSE loads */
1455 size_t bytes = itemCount*byteStride;
1456 if (type == RTC_BUFFER_TYPE_VERTEX || type == RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE)
1457 bytes += (16 - (byteStride%16))%16;
1458
1459 Ref<Buffer> buffer = new Buffer(geometry->device, bytes);
1460 geometry->setBuffer(type, slot, format, buffer, 0, byteStride, (unsigned int)itemCount);
1461 return buffer->data();
1462 RTC_CATCH_END2(geometry);
1463 return nullptr;
1464 }
1465
1466 RTC_API void* rtcGetGeometryBufferData(RTCGeometry hgeometry, RTCBufferType type, unsigned int slot)
1467 {
1468 Geometry* geometry = (Geometry*) hgeometry;
1469 RTC_CATCH_BEGIN;
1470 RTC_TRACE(rtcGetGeometryBufferData);
1471 RTC_VERIFY_HANDLE(hgeometry);
1472 return geometry->getBuffer(type, slot);
1473 RTC_CATCH_END2(geometry);
1474 return nullptr;
1475 }
1476
1477 RTC_API void rtcEnableGeometry (RTCGeometry hgeometry)
1478 {
1479 Geometry* geometry = (Geometry*) hgeometry;
1480 RTC_CATCH_BEGIN;
1481 RTC_TRACE(rtcEnableGeometry);
1482 RTC_VERIFY_HANDLE(hgeometry);
1483 geometry->enable();
1484 RTC_CATCH_END2(geometry);
1485 }
1486
1487 RTC_API void rtcUpdateGeometryBuffer (RTCGeometry hgeometry, RTCBufferType type, unsigned int slot)
1488 {
1489 Geometry* geometry = (Geometry*) hgeometry;
1490 RTC_CATCH_BEGIN;
1491 RTC_TRACE(rtcUpdateGeometryBuffer);
1492 RTC_VERIFY_HANDLE(hgeometry);
1493 geometry->updateBuffer(type, slot);
1494 RTC_CATCH_END2(geometry);
1495 }
1496
1497 RTC_API void rtcDisableGeometry (RTCGeometry hgeometry)
1498 {
1499 Geometry* geometry = (Geometry*) hgeometry;
1500 RTC_CATCH_BEGIN;
1501 RTC_TRACE(rtcDisableGeometry);
1502 RTC_VERIFY_HANDLE(hgeometry);
1503 geometry->disable();
1504 RTC_CATCH_END2(geometry);
1505 }
1506
1507 RTC_API void rtcSetGeometryTessellationRate (RTCGeometry hgeometry, float tessellationRate)
1508 {
1509 Geometry* geometry = (Geometry*) hgeometry;
1510 RTC_CATCH_BEGIN;
1511 RTC_TRACE(rtcSetGeometryTessellationRate);
1512 RTC_VERIFY_HANDLE(hgeometry);
1513 geometry->setTessellationRate(tessellationRate);
1514 RTC_CATCH_END2(geometry);
1515 }
1516
1517 RTC_API void rtcSetGeometryUserData (RTCGeometry hgeometry, void* ptr)
1518 {
1519 Geometry* geometry = (Geometry*) hgeometry;
1520 RTC_CATCH_BEGIN;
1521 RTC_TRACE(rtcSetGeometryUserData);
1522 RTC_VERIFY_HANDLE(hgeometry);
1523 geometry->setUserData(ptr);
1524 RTC_CATCH_END2(geometry);
1525 }
1526
1527 RTC_API void* rtcGetGeometryUserData (RTCGeometry hgeometry)
1528 {
1529 Geometry* geometry = (Geometry*) hgeometry; // no ref counting here!
1530 RTC_CATCH_BEGIN;
1531 RTC_TRACE(rtcGetGeometryUserData);
1532 RTC_VERIFY_HANDLE(hgeometry);
1533 return geometry->getUserData();
1534 RTC_CATCH_END2(geometry);
1535 return nullptr;
1536 }
1537
1538 RTC_API void rtcSetGeometryBoundsFunction (RTCGeometry hgeometry, RTCBoundsFunction bounds, void* userPtr)
1539 {
1540 Geometry* geometry = (Geometry*) hgeometry;
1541 RTC_CATCH_BEGIN;
1542 RTC_TRACE(rtcSetGeometryBoundsFunction);
1543 RTC_VERIFY_HANDLE(hgeometry);
1544 geometry->setBoundsFunction(bounds,userPtr);
1545 RTC_CATCH_END2(geometry);
1546 }
1547
1548 RTC_API void rtcSetGeometryDisplacementFunction (RTCGeometry hgeometry, RTCDisplacementFunctionN displacement)
1549 {
1550 Geometry* geometry = (Geometry*) hgeometry;
1551 RTC_CATCH_BEGIN;
1552 RTC_TRACE(rtcSetGeometryDisplacementFunction);
1553 RTC_VERIFY_HANDLE(hgeometry);
1554 geometry->setDisplacementFunction(displacement);
1555 RTC_CATCH_END2(geometry);
1556 }
1557
1558 RTC_API void rtcSetGeometryIntersectFunction (RTCGeometry hgeometry, RTCIntersectFunctionN intersect)
1559 {
1560 Geometry* geometry = (Geometry*) hgeometry;
1561 RTC_CATCH_BEGIN;
1562 RTC_TRACE(rtcSetGeometryIntersectFunction);
1563 RTC_VERIFY_HANDLE(hgeometry);
1564 geometry->setIntersectFunctionN(intersect);
1565 RTC_CATCH_END2(geometry);
1566 }
1567
1568 RTC_API void rtcSetGeometryPointQueryFunction(RTCGeometry hgeometry, RTCPointQueryFunction pointQuery)
1569 {
1570 Geometry* geometry = (Geometry*) hgeometry;
1571 RTC_CATCH_BEGIN;
1572 RTC_TRACE(rtcSetGeometryPointQueryFunction);
1573 RTC_VERIFY_HANDLE(hgeometry);
1574 geometry->setPointQueryFunction(pointQuery);
1575 RTC_CATCH_END2(geometry);
1576 }
1577
1578 RTC_API unsigned int rtcGetGeometryFirstHalfEdge(RTCGeometry hgeometry, unsigned int faceID)
1579 {
1580 Geometry* geometry = (Geometry*) hgeometry;
1581 RTC_CATCH_BEGIN;
1582 RTC_TRACE(rtcGetGeometryFirstHalfEdge);
1583 return geometry->getFirstHalfEdge(faceID);
1584 RTC_CATCH_END2(geometry);
1585 return -1;
1586 }
1587
1588 RTC_API unsigned int rtcGetGeometryFace(RTCGeometry hgeometry, unsigned int edgeID)
1589 {
1590 Geometry* geometry = (Geometry*) hgeometry;
1591 RTC_CATCH_BEGIN;
1592 RTC_TRACE(rtcGetGeometryFace);
1593 return geometry->getFace(edgeID);
1594 RTC_CATCH_END2(geometry);
1595 return -1;
1596 }
1597
1598 RTC_API unsigned int rtcGetGeometryNextHalfEdge(RTCGeometry hgeometry, unsigned int edgeID)
1599 {
1600 Geometry* geometry = (Geometry*) hgeometry;
1601 RTC_CATCH_BEGIN;
1602 RTC_TRACE(rtcGetGeometryNextHalfEdge);
1603 return geometry->getNextHalfEdge(edgeID);
1604 RTC_CATCH_END2(geometry);
1605 return -1;
1606 }
1607
1608 RTC_API unsigned int rtcGetGeometryPreviousHalfEdge(RTCGeometry hgeometry, unsigned int edgeID)
1609 {
1610 Geometry* geometry = (Geometry*) hgeometry;
1611 RTC_CATCH_BEGIN;
1612 RTC_TRACE(rtcGetGeometryPreviousHalfEdge);
1613 return geometry->getPreviousHalfEdge(edgeID);
1614 RTC_CATCH_END2(geometry);
1615 return -1;
1616 }
1617
1618 RTC_API unsigned int rtcGetGeometryOppositeHalfEdge(RTCGeometry hgeometry, unsigned int topologyID, unsigned int edgeID)
1619 {
1620 Geometry* geometry = (Geometry*) hgeometry;
1621 RTC_CATCH_BEGIN;
1622 RTC_TRACE(rtcGetGeometryOppositeHalfEdge);
1623 return geometry->getOppositeHalfEdge(topologyID,edgeID);
1624 RTC_CATCH_END2(geometry);
1625 return -1;
1626 }
1627
1628 RTC_API void rtcSetGeometryOccludedFunction (RTCGeometry hgeometry, RTCOccludedFunctionN occluded)
1629 {
1630 Geometry* geometry = (Geometry*) hgeometry;
1631 RTC_CATCH_BEGIN;
1632 RTC_TRACE(rtcSetOccludedFunctionN);
1633 RTC_VERIFY_HANDLE(hgeometry);
1634 geometry->setOccludedFunctionN(occluded);
1635 RTC_CATCH_END2(geometry);
1636 }
1637
1638 RTC_API void rtcSetGeometryIntersectFilterFunction (RTCGeometry hgeometry, RTCFilterFunctionN filter)
1639 {
1640 Geometry* geometry = (Geometry*) hgeometry;
1641 RTC_CATCH_BEGIN;
1642 RTC_TRACE(rtcSetGeometryIntersectFilterFunction);
1643 RTC_VERIFY_HANDLE(hgeometry);
1644 geometry->setIntersectionFilterFunctionN(filter);
1645 RTC_CATCH_END2(geometry);
1646 }
1647
1648 RTC_API void rtcSetGeometryOccludedFilterFunction (RTCGeometry hgeometry, RTCFilterFunctionN filter)
1649 {
1650 Geometry* geometry = (Geometry*) hgeometry;
1651 RTC_CATCH_BEGIN;
1652 RTC_TRACE(rtcSetGeometryOccludedFilterFunction);
1653 RTC_VERIFY_HANDLE(hgeometry);
1654 geometry->setOcclusionFilterFunctionN(filter);
1655 RTC_CATCH_END2(geometry);
1656 }
1657
1658 RTC_API void rtcInterpolate(const RTCInterpolateArguments* const args)
1659 {
1660 Geometry* geometry = (Geometry*) args->geometry;
1661 RTC_CATCH_BEGIN;
1662 RTC_TRACE(rtcInterpolate);
1663#if defined(DEBUG)
1664 RTC_VERIFY_HANDLE(args->geometry);
1665#endif
1666 geometry->interpolate(args);
1667 RTC_CATCH_END2(geometry);
1668 }
1669
1670 RTC_API void rtcInterpolateN(const RTCInterpolateNArguments* const args)
1671 {
1672 Geometry* geometry = (Geometry*) args->geometry;
1673 RTC_CATCH_BEGIN;
1674 RTC_TRACE(rtcInterpolateN);
1675#if defined(DEBUG)
1676 RTC_VERIFY_HANDLE(args->geometry);
1677#endif
1678 geometry->interpolateN(args);
1679 RTC_CATCH_END2(geometry);
1680 }
1681
1682 RTC_API void rtcCommitGeometry (RTCGeometry hgeometry)
1683 {
1684 Geometry* geometry = (Geometry*) hgeometry;
1685 RTC_CATCH_BEGIN;
1686 RTC_TRACE(rtcCommitGeometry);
1687 RTC_VERIFY_HANDLE(hgeometry);
1688 return geometry->commit();
1689 RTC_CATCH_END2(geometry);
1690 }
1691
1692 RTC_API unsigned int rtcAttachGeometry (RTCScene hscene, RTCGeometry hgeometry)
1693 {
1694 Scene* scene = (Scene*) hscene;
1695 Geometry* geometry = (Geometry*) hgeometry;
1696 RTC_CATCH_BEGIN;
1697 RTC_TRACE(rtcAttachGeometry);
1698 RTC_VERIFY_HANDLE(hscene);
1699 RTC_VERIFY_HANDLE(hgeometry);
1700 if (scene->device != geometry->device)
1701 throw_RTCError(RTC_ERROR_INVALID_ARGUMENT,"inputs are from different devices");
1702 return scene->bind(RTC_INVALID_GEOMETRY_ID,geometry);
1703 RTC_CATCH_END2(scene);
1704 return -1;
1705 }
1706
1707 RTC_API void rtcAttachGeometryByID (RTCScene hscene, RTCGeometry hgeometry, unsigned int geomID)
1708 {
1709 Scene* scene = (Scene*) hscene;
1710 Geometry* geometry = (Geometry*) hgeometry;
1711 RTC_CATCH_BEGIN;
1712 RTC_TRACE(rtcAttachGeometryByID);
1713 RTC_VERIFY_HANDLE(hscene);
1714 RTC_VERIFY_HANDLE(hgeometry);
1715 RTC_VERIFY_GEOMID(geomID);
1716 if (scene->device != geometry->device)
1717 throw_RTCError(RTC_ERROR_INVALID_ARGUMENT,"inputs are from different devices");
1718 scene->bind(geomID,geometry);
1719 RTC_CATCH_END2(scene);
1720 }
1721
1722 RTC_API void rtcDetachGeometry (RTCScene hscene, unsigned int geomID)
1723 {
1724 Scene* scene = (Scene*) hscene;
1725 RTC_CATCH_BEGIN;
1726 RTC_TRACE(rtcDetachGeometry);
1727 RTC_VERIFY_HANDLE(hscene);
1728 RTC_VERIFY_GEOMID(geomID);
1729 scene->detachGeometry(geomID);
1730 RTC_CATCH_END2(scene);
1731 }
1732
1733 RTC_API void rtcRetainGeometry (RTCGeometry hgeometry)
1734 {
1735 Geometry* geometry = (Geometry*) hgeometry;
1736 RTC_CATCH_BEGIN;
1737 RTC_TRACE(rtcRetainGeometry);
1738 RTC_VERIFY_HANDLE(hgeometry);
1739 geometry->refInc();
1740 RTC_CATCH_END2(geometry);
1741 }
1742
1743 RTC_API void rtcReleaseGeometry (RTCGeometry hgeometry)
1744 {
1745 Geometry* geometry = (Geometry*) hgeometry;
1746 RTC_CATCH_BEGIN;
1747 RTC_TRACE(rtcReleaseGeometry);
1748 RTC_VERIFY_HANDLE(hgeometry);
1749 geometry->refDec();
1750 RTC_CATCH_END2(geometry);
1751 }
1752
1753 RTC_API RTCGeometry rtcGetGeometry (RTCScene hscene, unsigned int geomID)
1754 {
1755 Scene* scene = (Scene*) hscene;
1756 RTC_CATCH_BEGIN;
1757 RTC_TRACE(rtcGetGeometry);
1758#if defined(DEBUG)
1759 RTC_VERIFY_HANDLE(hscene);
1760 RTC_VERIFY_GEOMID(geomID);
1761#endif
1762 return (RTCGeometry) scene->get(geomID);
1763 RTC_CATCH_END2(scene);
1764 return nullptr;
1765 }
1766
1767 RTC_API RTCGeometry rtcGetGeometryThreadSafe (RTCScene hscene, unsigned int geomID)
1768 {
1769 Scene* scene = (Scene*) hscene;
1770 RTC_CATCH_BEGIN;
1771 RTC_TRACE(rtcGetGeometryThreadSafe);
1772#if defined(DEBUG)
1773 RTC_VERIFY_HANDLE(hscene);
1774 RTC_VERIFY_GEOMID(geomID);
1775#endif
1776 Ref<Geometry> geom = scene->get_locked(geomID);
1777 return (RTCGeometry) geom.ptr;
1778 RTC_CATCH_END2(scene);
1779 return nullptr;
1780 }
1781
1782RTC_NAMESPACE_END
1783