1use std::collections::HashMap;
2use std::marker::PhantomData;
3use std::arch::x86_64;
4use std::mem;
5
6use device::Device;
7use geometry::Geometry;
8use ray::{IntersectContext, Ray, RayHit};
9use ray_packet::{Ray4, RayHit4};
10use ray_stream::{RayN, RayHitN};
11use sys::*;
12
13pub struct Scene<'a> {
18 pub(crate) handle: RTCScene,
19 device: PhantomData<&'a Device>,
22 geometry: HashMap<u32, Geometry<'a>>,
23}
24
25impl<'a> Scene<'a> {
26 pub fn new(device: &'a Device) -> Scene {
27 unsafe {
31 x86_64::_MM_SET_FLUSH_ZERO_MODE(x86_64::_MM_FLUSH_ZERO_ON);
32 }
33 Scene {
34 handle: unsafe { rtcNewScene(device.handle) },
35 device: PhantomData,
36 geometry: HashMap::new(),
37 }
38 }
39 pub fn attach_geometry(&mut self, mesh: Geometry<'a>) -> u32 {
45 let id = unsafe { rtcAttachGeometry(self.handle, mesh.handle()) };
46 self.geometry.insert(id, mesh);
47 id
48 }
49 pub fn deattach_geometry(&mut self, id: u32) -> Option<Geometry<'a>> {
51 self.geometry.remove(&id)
52 }
53 pub fn get_geometry(&self, id: u32) -> Option<&Geometry<'a>> {
55 match self.geometry.get(&id) {
56 Some(g) => Some(g),
57 None => None,
58 }
59 }
60 pub fn get_geometry_mut(&mut self, id: u32) -> Option<&mut Geometry<'a>> {
62 match self.geometry.get_mut(&id) {
63 Some(g) => Some(g),
64 None => None,
65 }
66 }
67 pub fn iter(&self) -> std::collections::hash_map::Iter<u32, Geometry<'a>> {
69 self.geometry.iter()
70 }
71 pub fn iter_mut(&mut self) -> std::collections::hash_map::IterMut<u32, Geometry<'a>> {
73 self.geometry.iter_mut()
74 }
75 pub fn commit(&'a self) -> CommittedScene<'a> {
80 unsafe {
81 rtcCommitScene(self.handle);
82 }
83 CommittedScene { scene: &self }
84 }
85 pub unsafe fn handle(&self) -> RTCScene {
88 self.handle
89 }
90}
91
92impl<'a> Drop for Scene<'a> {
93 fn drop(&mut self) {
94 unsafe {
95 rtcReleaseScene(self.handle);
96 }
97 }
98}
99
100unsafe impl<'a> Sync for Scene<'a> {}
101
102pub struct CommittedScene<'a> {
105 pub (crate) scene: &'a Scene<'a>,
106}
107
108impl<'a> CommittedScene<'a> {
109 pub fn intersect(&self, ctx: &mut IntersectContext, ray: &mut RayHit) {
110 unsafe {
111 rtcIntersect1(
112 self.scene.handle,
113 ctx as *mut RTCIntersectContext,
114 ray as *mut RTCRayHit
115 );
116 }
117 }
118 pub fn occluded(&self, ctx: &mut IntersectContext, ray: &mut Ray) {
119 unsafe {
120 rtcOccluded1(
121 self.scene.handle,
122 ctx as *mut RTCIntersectContext,
123 ray as *mut RTCRay
124 );
125 }
126 }
127 pub fn intersect4(&self, ctx: &mut IntersectContext, ray: &mut RayHit4, valid: &[i32; 4]) {
128 unsafe {
129 rtcIntersect4(
130 valid.as_ptr(),
131 self.scene.handle,
132 ctx as *mut RTCIntersectContext,
133 ray as *mut RTCRayHit4
134 );
135 }
136 }
137 pub fn occluded4(&self, ctx: &mut IntersectContext, ray: &mut Ray4, valid: &[i32; 4]) {
138 unsafe {
139 rtcOccluded4(
140 valid.as_ptr(),
141 self.scene.handle,
142 ctx as *mut RTCIntersectContext,
143 ray as *mut RTCRay4
144 );
145 }
146 }
147 pub fn intersect_stream_aos(&self, ctx: &mut IntersectContext, rays: &mut Vec<RayHit>) {
148 let m = rays.len();
149 unsafe {
150 rtcIntersect1M(
151 self.scene.handle,
152 ctx as *mut RTCIntersectContext,
153 rays.as_mut_ptr(),
154 m as u32,
155 mem::size_of::<RayHit>()
156 );
157 }
158 }
159 pub fn occluded_stream_aos(&self, ctx: &mut IntersectContext, rays: &mut Vec<Ray>) {
160 let m = rays.len();
161 unsafe {
162 rtcOccluded1M(
163 self.scene.handle,
164 ctx as *mut RTCIntersectContext,
165 rays.as_mut_ptr(),
166 m as u32,
167 mem::size_of::<Ray>()
168 );
169 }
170 }
171 pub fn intersect_stream_soa(&self, ctx: &mut IntersectContext, rays: &mut RayHitN) {
172 let n = rays.len();
173 unsafe {
174 let mut rayhit = rays.as_rayhitnp();
175 rtcIntersectNp(
176 self.scene.handle,
177 ctx as *mut RTCIntersectContext,
178 &mut rayhit as *mut RTCRayHitNp,
179 n as u32
180 );
181 }
182 }
183 pub fn occluded_stream_soa(&self, ctx: &mut IntersectContext, rays: &mut RayN) {
184 let n = rays.len();
185 unsafe {
186 let mut r = rays.as_raynp();
187 rtcOccludedNp(
188 self.scene.handle,
189 ctx as *mut RTCIntersectContext,
190 &mut r as *mut RTCRayNp,
191 n as u32
192 );
193 }
194 }
195 pub fn bounds(&self) -> RTCBounds {
196 let mut bounds = RTCBounds {
197 lower_x: 0.0,
198 upper_x: 0.0,
199 lower_y: 0.0,
200 upper_y: 0.0,
201 lower_z: 0.0,
202 upper_z: 0.0,
203 align0: 0.0,
204 align1: 0.0,
205 };
206 unsafe {
207 rtcGetSceneBounds(self.handle(), &mut bounds as *mut RTCBounds);
208 }
209 bounds
210 }
211 pub unsafe fn handle(&self) -> RTCScene {
214 self.scene.handle
215 }
216}
217
218unsafe impl<'a> Sync for CommittedScene<'a> {}
219