use std::collections::HashMap;
use std::marker::PhantomData;
use std::arch::x86_64;
use std::mem;
use device::Device;
use geometry::Geometry;
use ray::{IntersectContext, Ray, RayHit};
use ray_packet::{Ray4, RayHit4};
use ray_stream::{RayN, RayHitN};
use sys::*;
pub struct Scene<'a> {
pub(crate) handle: RTCScene,
device: PhantomData<&'a Device>,
geometry: HashMap<u32, Geometry<'a>>,
}
impl<'a> Scene<'a> {
pub fn new(device: &'a Device) -> Scene {
unsafe {
x86_64::_MM_SET_FLUSH_ZERO_MODE(x86_64::_MM_FLUSH_ZERO_ON);
}
Scene {
handle: unsafe { rtcNewScene(device.handle) },
device: PhantomData,
geometry: HashMap::new(),
}
}
pub fn attach_geometry(&mut self, mesh: Geometry<'a>) -> u32 {
let id = unsafe { rtcAttachGeometry(self.handle, mesh.handle()) };
self.geometry.insert(id, mesh);
id
}
pub fn deattach_geometry(&mut self, id: u32) -> Option<Geometry<'a>> {
self.geometry.remove(&id)
}
pub fn get_geometry(&self, id: u32) -> Option<&Geometry<'a>> {
match self.geometry.get(&id) {
Some(g) => Some(g),
None => None,
}
}
pub fn get_geometry_mut(&mut self, id: u32) -> Option<&mut Geometry<'a>> {
match self.geometry.get_mut(&id) {
Some(g) => Some(g),
None => None,
}
}
pub fn iter(&self) -> std::collections::hash_map::Iter<u32, Geometry<'a>> {
self.geometry.iter()
}
pub fn iter_mut(&mut self) -> std::collections::hash_map::IterMut<u32, Geometry<'a>> {
self.geometry.iter_mut()
}
pub fn commit(&'a self) -> CommittedScene<'a> {
unsafe {
rtcCommitScene(self.handle);
}
CommittedScene { scene: &self }
}
}
impl<'a> Drop for Scene<'a> {
fn drop(&mut self) {
unsafe {
rtcReleaseScene(self.handle);
}
}
}
unsafe impl<'a> Sync for Scene<'a> {}
pub struct CommittedScene<'a> {
pub (crate) scene: &'a Scene<'a>,
}
impl<'a> CommittedScene<'a> {
pub fn intersect(&self, ctx: &mut IntersectContext, ray: &mut RayHit) {
unsafe {
rtcIntersect1(
self.scene.handle,
ctx as *mut RTCIntersectContext,
ray as *mut RTCRayHit
);
}
}
pub fn occluded(&self, ctx: &mut IntersectContext, ray: &mut Ray) {
unsafe {
rtcOccluded1(
self.scene.handle,
ctx as *mut RTCIntersectContext,
ray as *mut RTCRay
);
}
}
pub fn intersect4(&self, ctx: &mut IntersectContext, ray: &mut RayHit4, valid: &[i32; 4]) {
unsafe {
rtcIntersect4(
valid.as_ptr(),
self.scene.handle,
ctx as *mut RTCIntersectContext,
ray as *mut RTCRayHit4
);
}
}
pub fn occluded4(&self, ctx: &mut IntersectContext, ray: &mut Ray4, valid: &[i32; 4]) {
unsafe {
rtcOccluded4(
valid.as_ptr(),
self.scene.handle,
ctx as *mut RTCIntersectContext,
ray as *mut RTCRay4
);
}
}
pub fn intersect_stream_aos(&self, ctx: &mut IntersectContext, rays: &mut Vec<RayHit>) {
let m = rays.len();
unsafe {
rtcIntersect1M(
self.scene.handle,
ctx as *mut RTCIntersectContext,
rays.as_mut_ptr(),
m as u32,
mem::size_of::<RayHit>()
);
}
}
pub fn occluded_stream_aos(&self, ctx: &mut IntersectContext, rays: &mut Vec<Ray>) {
let m = rays.len();
unsafe {
rtcOccluded1M(
self.scene.handle,
ctx as *mut RTCIntersectContext,
rays.as_mut_ptr(),
m as u32,
mem::size_of::<Ray>()
);
}
}
pub fn intersect_stream_soa(&self, ctx: &mut IntersectContext, rays: &mut RayHitN) {
let n = rays.len();
unsafe {
let mut rayhit = RTCRayHitNp { ray: rays.ray.as_raynp(), hit: rays.hit.as_hitnp() };
rtcIntersectNp(
self.scene.handle,
ctx as *mut RTCIntersectContext,
&mut rayhit as *mut RTCRayHitNp,
n as u32
);
}
}
pub fn occluded_stream_soa(&self, ctx: &mut IntersectContext, rays: &mut RayN) {
let n = rays.len();
unsafe {
let mut r = rays.as_raynp();
rtcOccludedNp(
self.scene.handle,
ctx as *mut RTCIntersectContext,
&mut r as *mut RTCRayNp,
n as u32
);
}
}
}
unsafe impl<'a> Sync for CommittedScene<'a> {}