use cgmath::Vector3;
use std::iter::Iterator;
use std::marker::PhantomData;
use std::{f32, u32};
use soa_ray::{
SoAHit, SoAHitIter, SoAHitIterMut, SoAHitRef, SoARay, SoARayIter, SoARayIterMut, SoARayRef,
SoARayRefMut,
};
use sys;
use {aligned_vector, aligned_vector_init};
pub struct RayN {
org_x: Vec<f32>,
org_y: Vec<f32>,
org_z: Vec<f32>,
tnear: Vec<f32>,
dir_x: Vec<f32>,
dir_y: Vec<f32>,
dir_z: Vec<f32>,
time: Vec<f32>,
tfar: Vec<f32>,
mask: Vec<::std::os::raw::c_uint>,
id: Vec<::std::os::raw::c_uint>,
flags: Vec<::std::os::raw::c_uint>,
}
impl RayN {
pub fn new(n: usize) -> RayN {
RayN {
org_x: aligned_vector::<f32>(n, 16),
org_y: aligned_vector::<f32>(n, 16),
org_z: aligned_vector::<f32>(n, 16),
tnear: aligned_vector_init::<f32>(n, 16, 0.0),
dir_x: aligned_vector::<f32>(n, 16),
dir_y: aligned_vector::<f32>(n, 16),
dir_z: aligned_vector::<f32>(n, 16),
time: aligned_vector_init::<f32>(n, 16, 0.0),
tfar: aligned_vector_init::<f32>(n, 16, f32::INFINITY),
mask: aligned_vector_init::<u32>(n, 16, u32::MAX),
id: aligned_vector_init::<u32>(n, 16, 0),
flags: aligned_vector_init::<u32>(n, 16, 0),
}
}
pub fn iter(&self) -> SoARayIter<RayN> {
SoARayIter::new(self, self.len())
}
pub fn iter_mut(&mut self) -> SoARayIterMut<RayN> {
let n = self.len();
SoARayIterMut::new(self, n)
}
pub fn len(&self) -> usize {
self.org_x.len()
}
pub unsafe fn as_raynp(&mut self) -> sys::RTCRayNp {
sys::RTCRayNp {
org_x: self.org_x.as_mut_ptr(),
org_y: self.org_y.as_mut_ptr(),
org_z: self.org_z.as_mut_ptr(),
dir_x: self.dir_x.as_mut_ptr(),
dir_y: self.dir_y.as_mut_ptr(),
dir_z: self.dir_z.as_mut_ptr(),
tnear: self.tnear.as_mut_ptr(),
tfar: self.tfar.as_mut_ptr(),
time: self.time.as_mut_ptr(),
mask: self.mask.as_mut_ptr(),
id: self.id.as_mut_ptr(),
flags: self.flags.as_mut_ptr(),
}
}
}
impl SoARay for RayN {
fn org(&self, i: usize) -> Vector3<f32> {
Vector3::new(self.org_x[i], self.org_y[i], self.org_z[i])
}
fn set_org(&mut self, i: usize, o: Vector3<f32>) {
self.org_x[i] = o.x;
self.org_y[i] = o.y;
self.org_z[i] = o.z;
}
fn dir(&self, i: usize) -> Vector3<f32> {
Vector3::new(self.dir_x[i], self.dir_y[i], self.dir_z[i])
}
fn set_dir(&mut self, i: usize, d: Vector3<f32>) {
self.dir_x[i] = d.x;
self.dir_y[i] = d.y;
self.dir_z[i] = d.z;
}
fn tnear(&self, i: usize) -> f32 {
self.tnear[i]
}
fn set_tnear(&mut self, i: usize, near: f32) {
self.tnear[i] = near;
}
fn tfar(&self, i: usize) -> f32 {
self.tfar[i]
}
fn set_tfar(&mut self, i: usize, far: f32) {
self.tfar[i] = far;
}
fn time(&self, i: usize) -> f32 {
self.time[i]
}
fn set_time(&mut self, i: usize, time: f32) {
self.time[i] = time;
}
fn mask(&self, i: usize) -> u32 {
self.mask[i]
}
fn set_mask(&mut self, i: usize, mask: u32) {
self.mask[i] = mask;
}
fn id(&self, i: usize) -> u32 {
self.id[i]
}
fn set_id(&mut self, i: usize, id: u32) {
self.id[i] = id;
}
fn flags(&self, i: usize) -> u32 {
self.flags[i]
}
fn set_flags(&mut self, i: usize, flags: u32) {
self.flags[i] = flags;
}
}
pub struct HitN {
ng_x: Vec<f32>,
ng_y: Vec<f32>,
ng_z: Vec<f32>,
u: Vec<f32>,
v: Vec<f32>,
prim_id: Vec<::std::os::raw::c_uint>,
geom_id: Vec<::std::os::raw::c_uint>,
inst_id: Vec<::std::os::raw::c_uint>,
}
impl HitN {
pub fn new(n: usize) -> HitN {
HitN {
ng_x: aligned_vector::<f32>(n, 16),
ng_y: aligned_vector::<f32>(n, 16),
ng_z: aligned_vector::<f32>(n, 16),
u: aligned_vector::<f32>(n, 16),
v: aligned_vector::<f32>(n, 16),
prim_id: aligned_vector_init::<u32>(n, 16, u32::MAX),
geom_id: aligned_vector_init::<u32>(n, 16, u32::MAX),
inst_id: aligned_vector_init::<u32>(n, 16, u32::MAX),
}
}
pub fn any_hit(&self) -> bool {
self.hits().fold(false, |acc, g| acc || g)
}
pub fn hits<'a>(&'a self) -> impl Iterator<Item = bool> + 'a {
self.geom_id.iter().map(|g| *g != u32::MAX)
}
pub fn iter(&self) -> SoAHitIter<HitN> {
SoAHitIter::new(self, self.len())
}
pub fn iter_hits<'a>(&'a self) -> impl Iterator<Item = SoAHitRef<HitN>> + 'a {
SoAHitIter::new(self, self.len()).filter(|h| h.hit())
}
pub fn len(&self) -> usize {
self.ng_x.len()
}
pub unsafe fn as_hitnp(&mut self) -> sys::RTCHitNp {
sys::RTCHitNp {
Ng_x: self.ng_x.as_mut_ptr(),
Ng_y: self.ng_y.as_mut_ptr(),
Ng_z: self.ng_z.as_mut_ptr(),
u: self.u.as_mut_ptr(),
v: self.v.as_mut_ptr(),
primID: self.prim_id.as_mut_ptr(),
geomID: self.geom_id.as_mut_ptr(),
instID: [self.inst_id.as_mut_ptr(); 1usize],
}
}
}
impl SoAHit for HitN {
fn normal(&self, i: usize) -> Vector3<f32> {
Vector3::new(self.ng_x[i], self.ng_y[i], self.ng_z[i])
}
fn set_normal(&mut self, i: usize, n: Vector3<f32>) {
self.ng_x[i] = n.x;
self.ng_y[i] = n.y;
self.ng_z[i] = n.z;
}
fn uv(&self, i: usize) -> (f32, f32) {
(self.u[i], self.v[i])
}
fn set_u(&mut self, i: usize, u: f32) {
self.u[i] = u;
}
fn set_v(&mut self, i: usize, v: f32) {
self.v[i] = v;
}
fn prim_id(&self, i: usize) -> u32 {
self.prim_id[i]
}
fn set_prim_id(&mut self, i: usize, id: u32) {
self.prim_id[i] = id;
}
fn geom_id(&self, i: usize) -> u32 {
self.geom_id[i]
}
fn set_geom_id(&mut self, i: usize, id: u32) {
self.geom_id[i] = id;
}
fn inst_id(&self, i: usize) -> u32 {
self.inst_id[i]
}
fn set_inst_id(&mut self, i: usize, id: u32) {
self.inst_id[i] = id;
}
}
pub struct RayHitN {
pub ray: RayN,
pub hit: HitN,
}
impl RayHitN {
pub fn new(ray: RayN) -> RayHitN {
let n = ray.len();
RayHitN {
ray: ray,
hit: HitN::new(n),
}
}
pub fn iter(&self) -> std::iter::Zip<SoARayIter<RayN>, SoAHitIter<HitN>> {
self.ray.iter().zip(self.hit.iter())
}
pub fn len(&self) -> usize {
self.ray.len()
}
pub unsafe fn as_rayhitnp(&mut self) -> sys::RTCRayHitNp {
sys::RTCRayHitNp {
ray: self.ray.as_raynp(),
hit: self.hit.as_hitnp(),
}
}
}