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