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

source code of qtquick3d/src/3rdparty/embree/kernels/common/rtcore.cpp