mod common;
use embree3::{BufferUsage, Error};
#[test]
fn builder_map_refill_round_trips() {
let device = common::device();
let mut tri = common::unit_triangle(&device);
let moved = [[5.0, 0.0, 0.0], [6.0, 0.0, 0.0], [5.0, 1.0, 0.0]];
tri.map_buffer_mut::<[f32; 3]>(BufferUsage::VERTEX, 0)
.unwrap()
.copy_from_slice(&moved);
let view = tri.map_buffer::<[f32; 3]>(BufferUsage::VERTEX, 0).unwrap();
assert_eq!(
view.as_ref(),
&moved,
"map_buffer must read back exactly what map_buffer_mut wrote"
);
}
#[test]
fn committed_read_map_sees_build_phase_writes() {
let device = common::device();
let mut tri = common::unit_triangle(&device);
let moved = [[2.0, 0.0, 0.0], [3.0, 0.0, 0.0], [2.0, 1.0, 0.0]];
tri.map_buffer_mut::<[f32; 3]>(BufferUsage::VERTEX, 0)
.unwrap()
.copy_from_slice(&moved);
let geom = tri.commit();
let view = geom.map_buffer::<[f32; 3]>(BufferUsage::VERTEX, 0).unwrap();
assert_eq!(
view.as_ref(),
&moved,
"the committed geometry must expose the same buffer the builder filled"
);
}
#[test]
fn dynamic_edit_through_scene_moves_geometry() {
let device = common::device();
let mut scene = device.create_scene().unwrap();
let tri = common::unit_triangle(&device).commit();
let id = scene.attach_geometry(&tri);
scene.commit();
assert!(
common::cast_center_ray(&scene).hit.is_valid(),
"the triangle should be hit at its original position"
);
let written = scene
.with_geometry_buffer_mut::<[f32; 3], _>(id, BufferUsage::VERTEX, 0, |verts| {
for v in verts.iter_mut() {
v[0] += 10.0;
}
verts.len()
})
.unwrap();
assert_eq!(written, 3, "the closure should see all 3 mapped vertices");
scene.update_geometry_buffer(id, BufferUsage::VERTEX, 0);
scene.commit_geometry(id);
scene.commit();
assert!(
!common::cast_center_ray(&scene).hit.is_valid(),
"after moving the triangle off-axis the ray must miss, proving the mapped write reached \
embree's live buffer"
);
scene
.with_geometry_buffer_mut::<[f32; 3], _>(id, BufferUsage::VERTEX, 0, |verts| {
for v in verts.iter_mut() {
v[0] -= 10.0;
}
})
.unwrap();
scene.update_geometry_buffer(id, BufferUsage::VERTEX, 0);
scene.commit_geometry(id);
scene.commit();
assert!(
common::cast_center_ray(&scene).hit.is_valid(),
"restoring the vertices should make the triangle hittable again"
);
}
#[test]
fn map_rejects_invalid_requests() {
let device = common::device();
let geom = common::unit_triangle(&device).commit();
assert_eq!(
geom.map_buffer::<[f32; 3]>(BufferUsage::VERTEX, 5).err(),
Some(Error::INVALID_ARGUMENT),
"an unbound slot must not map"
);
assert_eq!(
geom.map_buffer::<[f32; 4]>(BufferUsage::VERTEX, 0).err(),
Some(Error::INVALID_ARGUMENT),
"an element type that does not tile the allocation must be rejected"
);
let mut scene = device.create_scene().unwrap();
let r = scene.with_geometry_buffer_mut::<[f32; 3], _>(999, BufferUsage::VERTEX, 0, |_verts| {
unreachable!("closure must not run for an unattached id")
});
assert_eq!(
r.err(),
Some(Error::INVALID_ARGUMENT),
"mapping an unattached geometry id must fail"
);
}