1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
//! [](https://crates.io/crates/embree3)
//! [](https://github.com/matthiascy/embree3/actions/workflows/main.yml)
//!
//! Safe Rust bindings to [Embree](https://embree.github.io/) 3.13.5, Intel's
//! high-performance ray-tracing kernels.
//!
//! This crate is a thin `unsafe` FFI wrapper whose one job is to turn Embree's
//! raw pointers and C callbacks into a memory-safe Rust API: callback closures
//! are heap-owned and reached through a lock-free per-geometry table; geometry
//! mutation is gated by the [`GeometryBuilder`] / [`Geometry`] typestate; and
//! [`Scene`] is a non-`Clone` unique owner of its handle (share a committed one
//! across threads with `Arc<Scene>`).
//!
//! # Overview
//!
//! - [`Device`] is the entry point. From it you create a [`Scene`], a geometry
//! builder ([`Device::create_geometry`]), or a standalone BVH
//! ([`Device::create_bvh`]).
//! - Configure a [`GeometryBuilder`] (buffers, callbacks), [`commit`] it to a
//! shareable read-only [`Geometry`], attach it to a [`Scene`], and commit the
//! scene.
//! - Query the scene with [`Scene::intersect`] / [`Scene::occluded`] (single
//! rays), their `4` / `8` / `16`-wide packet variants, the stream APIs, or
//! [`Scene::point_query`]; find scene-vs-scene candidate pairs with
//! [`Scene::collide`].
//!
//! [`commit`]: GeometryBuilder::commit
//!
//! # Quick start
//!
//! ```no_run
//! use embree3::{BufferUsage, Device, Format, GeometryKind, IntersectContext, Ray, RayHit};
//!
//! let device = Device::new().unwrap();
//! let mut scene = device.create_scene().unwrap();
//!
//! // One triangle.
//! let mut tri = device.create_geometry(GeometryKind::TRIANGLE).unwrap();
//! tri.set_new_buffer::<[f32; 3]>(BufferUsage::VERTEX, 0, Format::FLOAT3, 3 * 4, 3)
//! .unwrap()
//! .copy_from_slice(&[[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]);
//! tri.set_new_buffer::<[u32; 3]>(BufferUsage::INDEX, 0, Format::UINT3, 3 * 4, 1)
//! .unwrap()
//! .copy_from_slice(&[[0, 1, 2]]);
//! let tri = tri.commit();
//! scene.attach_geometry(&tri);
//! scene.commit();
//!
//! // Trace one ray at it.
//! let mut ctx = IntersectContext::coherent();
//! let mut rayhit = RayHit::from(Ray::segment(
//! [0.25, 0.25, -1.0],
//! [0.0, 0.0, 1.0],
//! 0.0,
//! f32::INFINITY,
//! ));
//! scene.intersect(&mut ctx, &mut rayhit);
//! assert!(rayhit.hit.is_valid());
//! ```
//!
//! # Documentation
//!
//! Rust doc can be found [here](https://docs.rs/embree3/).
//! Embree documentation can be found [here](https://embree.github.io/api.html).
//! See the [examples/](https://github.com/matthiascy/embree3/tree/master/examples)
//! for some example applications using the bindings.
//!
//! # Intentionally unwrapped embree functions
//!
//! A few embree C entry points are deliberately *not* exposed, because a safer
//! or more idiomatic Rust mechanism already covers them. Reach for the
//! alternative listed here:
//!
//! | embree C function | Use instead | Why |
//! |---|---|---|
//! | `rtcNewSharedBuffer` | [`GeometryBuilder::set_shared_buffer`] | App-owned, zero-copy data is bound through a real `&'buf [u8]` borrow, so the compiler enforces "the data outlives the geometry". The C buffer *object* exists to share a raw pointer across bindings, which a Rust reference already does, so it adds no capability. |
//! | `rtcSetGeometryPointQueryFunction` | [`Scene::point_query`] | Its callback receives no per-geometry pointer (only the scene query's `userPtr`), so it cannot host a capturing closure. Branch on `geomID` inside the [`Scene::point_query`] closure for per-geometry logic. |
//! | `rtcGetSceneDevice` | [`Scene::device`] | The scene already tracks (and hands back) its [`Device`]; the raw getter would only duplicate it. |
//! | `rtcSetDeviceProperty` | *(none)* | Embree exposes **no public writable device properties** (the only settable ones are hidden internal debug integers), so a wrapper would reject every public `DeviceProperty`. Use [`Device::get_property`] for the read-only queries. |
//! | `rtcRetainBVH` | *(none)* | [`Bvh`] is a non-`Clone` build target (the build result borrows it exclusively), so there is never a second handle to retain; `rtcReleaseBVH` runs once in `Drop`. |
//! | `rtcRetainScene` | `Arc<Scene>` | [`Scene`] is a non-`Clone` unique owner of its handle (so `&mut Scene` stays exclusive for mutation/commit); share a committed scene with `Arc<Scene>`. There is never a second handle to retain, and `rtcReleaseScene` runs once in `Drop`. |
//!
//! Two further functions, `rtcGetGeometryUserData` and `rtcRetainGeometry`, are
//! not exposed because the crate's geometry ownership model (an internal `Arc`
//! plus a lock-free callback table) supersedes them; no user action is needed.
//!
//! # Panics in callbacks
//!
//! User closures registered as embree callbacks (geometry
//! intersect/occluded/bounds/filter/displacement, the scene progress monitor,
//! point queries, the BVH builder, and [`Scene::collide`]) run behind embree's
//! non-unwinding `extern "C"` ABI. A panic that escapes such a callback
//! **aborts the process** -- Rust turns an unwind that reaches a non-`-unwind`
//! `extern "C"` boundary into an abort, so this is defined behavior, not UB.
//! The hot per-ray/per-primitive trampolines therefore call the closure
//! directly (no per-call `catch_unwind` landing pad). Handle recoverable errors
//! *inside* the closure (e.g. record them in captured state); do not rely on
//! catching a panic across a query.
extern crate core;
use ;
/// Automatically generated bindings to the Embree C API.
pub use *;
pub use *;
pub use *;
pub use *;
pub use *;
pub use *;
pub use *;
// Pull in some cleaned up enum and bitfield types directly,
// with prettier aliases
/// An axis-aligned bounding box, given by its `lower` and `upper` corners.
/// Returned by [`Scene::get_bounds`] and filled in by user-geometry bounds
/// callbacks.
pub type Bounds = RTCBounds;
/// Linear (motion-blur) bounds: the axis-aligned bounding box at the start
/// (`bounds0`) and end (`bounds1`) of the scene's time range. See
/// [`Scene::get_linear_bounds`](crate::Scene::get_linear_bounds).
pub type LinearBounds = RTCLinearBounds;
/// Defines the type of slots to assign data buffers to.
///
/// For most geometry types the [`BufferUsage::INDEX`] slot is used to assign
/// an index buffer, while the [`BufferUsage::VERTEX`] is used to assign the
/// corresponding vertex buffer.
///
/// The [`BufferUsage::VERTEX_ATTRIBUTE`] slot can get used to assign
/// arbitrary additional vertex data which can get interpolated using the
/// [`Geometry::interpolate`] and [`Geometry::interpolate_n`] API calls.
///
/// The [`BufferUsage::NORMAL`], [`BufferUsage::TANGENT`], and
/// [`BufferUsage::NORMAL_DERIVATIVE`] are special buffers required to assign
/// per vertex normals, tangents, and normal derivatives for some curve types.
///
/// The [`BufferUsage::GRID`] buffer is used to assign the grid primitive buffer
/// for grid geometries (see [`GeometryKind::GRID`]).
///
/// The [`BufferUsage::FACE`], [`BufferUsage::LEVEL`],
/// [`BufferUsage::EDGE_CREASE_INDEX`], [`BufferUsage::EDGE_CREASE_WEIGHT`],
/// [`BufferUsage::VERTEX_CREASE_INDEX`], [`BufferUsage::VERTEX_CREASE_WEIGHT`],
/// and [`BufferUsage::HOLE`] are special buffers required to create subdivision
/// meshes (see [`GeometryKind::SUBDIVISION`]).
///
/// [`BufferUsage::FLAGS`] can get used to add additional flag per primitive of
/// a geometry, and is currently only used for linear curves.
pub type BufferUsage = RTCBufferType;
/// Speed-vs-quality trade-off for a scene or BVH build (see
/// [`Scene::set_build_quality`] and [`BuildConfig`]).
pub type BuildQuality = RTCBuildQuality;
/// Flags controlling a standalone BVH build (e.g. dynamic / refittable). See
/// [`BuildConfig`].
pub type BuildFlags = RTCBuildFlags;
/// Per-segment flags for curve geometries (e.g. neighbor joins).
pub type CurveFlags = RTCCurveFlags;
/// A queryable, read-only device property (see [`Device::get_property`]).
pub type DeviceProperty = RTCDeviceProperty;
/// An Embree error code. Returned by fallible operations and reported through
/// the device error callback; see [`Device::get_error`].
pub type Error = RTCError;
/// The element format of a data buffer, e.g. [`Format::FLOAT3`] for vertex
/// positions or [`Format::UINT3`] for a triangle index.
pub type Format = RTCFormat;
/// Flags on an [`IntersectContext`] selecting the traversal mode (e.g. coherent
/// vs incoherent ray distributions).
pub type IntersectContextFlags = RTCIntersectContextFlags;
/// Scene-level flags (e.g. `DYNAMIC`, `ROBUST`, `COMPACT`); see
/// [`Scene::set_flags`].
pub type SceneFlags = RTCSceneFlags;
/// Subdivision mode for subdivision-surface geometries (how the limit surface
/// is evaluated near boundaries and creases).
pub type SubdivisionMode = RTCSubdivisionMode;
/// The type of a geometry, used to determine which geometry type to create.
pub type GeometryKind = RTCGeometryType;
/// Marker trait for types usable as callback user data: geometry callback user
/// data (bound via [`GeometryBuilder`]'s `_owned` / `_borrowed` callback
/// setters) or point-query user data ([`Scene::point_query`]).
///
/// The blanket impl covers every `Send + Sync + 'static` type. The bounds are
/// required because callbacks may read the data from embree worker threads
/// (`Send + Sync`) for as long as the geometry/scene lives (`'static`).
/// Validity mask value for rays or hits in the filter functions.
/// See [`ValidityN`].
/// Structure that represents a quaternion decomposition of an affine
/// transformation.
///
/// The affine transformation can be decomposed into three parts:
///
/// 1. A upper triangular scaling/skew/shift matrix
///
/// ```text
/// | scale_x skew_xy skew_xz shift_x |
/// | 0 scale_y skew_yz shift_y |
/// | 0 0 scale_z shift_z |
/// | 0 0 0 1 |
/// ```
///
/// 2. A translation matrix
/// ```text
/// | 1 0 0 translation_x |
/// | 0 1 0 translation_y |
/// | 0 0 1 translation_z |
/// | 0 0 0 1 |
/// ```
///
/// 3. A rotation matrix R, represented as a quaternion
/// ```text
/// quaternion_r + i * quaternion_i + j * quaternion_j + k * quaternion_k
/// ```
/// where i, j, k are the imaginary unit vectors. The passed quaternion will
/// be normalized internally.
///
/// The affine transformation matrix corresponding to a quaternion decomposition
/// is TRS and a point `p = (x, y, z, 1)^T` is transformed as follows:
///
/// ```text
/// p' = T * R * S * p
/// ```
pub type QuaternionDecomposition = RTCQuaternionDecomposition;
/// The invalid ID for Embree intersection results (e.g. `Hit::geomID`,
/// `Hit::primID`, etc.)
pub const INVALID_ID: u32 = u32MAX;
/// Object used to traverses the BVH and calls a user defined callback function
/// for each primitive of the scene that intersects the query domain.
///
/// See [`Scene::point_query`] for more information.
pub type PointQuery = RTCPointQuery;
/// A SoA packet of 4 point queries (see [`Scene::point_query4`]).
pub type PointQuery4 = RTCPointQuery4;
/// A SoA packet of 8 point queries (see [`Scene::point_query8`]).
pub type PointQuery8 = RTCPointQuery8;
/// A SoA packet of 16 point queries (see [`Scene::point_query16`]).
pub type PointQuery16 = RTCPointQuery16;
/// Primitives that can be used to build a BVH.
pub type BuildPrimitive = RTCBuildPrimitive;
/// A candidate colliding primitive pair reported by [`Scene::collide`]: the
/// `geomID`/`primID` of one primitive in each scene. It is a
/// potentially-intersecting pair from a leaf pair reached during broad-phase
/// traversal; embree does not test the bounds before reporting, so the pair's
/// bounds need not overlap and the callback must narrow-phase.
pub type Collision = RTCCollision;
/// Utility for making specifically aligned vector.
///
/// This is a growable, dynamically allocated, arbitrarily aligned container.
/// Please use [`AlignedArray`] if you only need a 16 bytes aligned, fix-sized
/// storage.
///
/// This is a wrapper around `Vec` that ensures the alignment of the vector.
/// The reason for this is that memory must be deallocated with the
/// same alignment as it was allocated with. This is not guaranteed if
/// we allocate a memory block with the alignment then cast it to a
/// `Vec` of `T` and then drop it, since the `Vec` will deallocate the
/// memory with the alignment of `T`.
/// 16 bytes aligned with known size at compile time.
;
/// Utility function to normalise a vector.