rafx_framework/visibility/
visibility_object_arc.rs1use crate::render_features::RenderObjectHandle;
2use crate::visibility::visibility_object_allocator::VisibilityObjectId;
3use crate::visibility::ObjectId;
4use crossbeam_channel::Sender;
5use glam::{Quat, Vec3};
6use rafx_visibility::geometry::Transform;
7use rafx_visibility::{
8 AsyncCommand, ModelHandle, PolygonSoup, VisibilityObjectHandle, VisibleBounds, ZoneHandle,
9};
10use slotmap::Key;
11use std::sync::atomic::{AtomicU64, Ordering};
12use std::sync::{Arc, Weak};
13
14pub enum CullModel {
15 Mesh(PolygonSoup),
16 VisibleBounds(VisibleBounds),
17 Sphere(f32),
18 Quad(f32, f32),
19 None,
20}
21
22impl CullModel {
23 pub fn mesh(polygon_soup: PolygonSoup) -> CullModel {
24 CullModel::Mesh(polygon_soup)
25 }
26
27 pub fn visible_bounds(model: VisibleBounds) -> CullModel {
28 CullModel::VisibleBounds(model)
29 }
30
31 pub fn sphere(radius: f32) -> CullModel {
32 CullModel::Sphere(radius)
33 }
34
35 pub fn quad(
36 width: f32,
37 height: f32,
38 ) -> CullModel {
39 CullModel::Quad(width, height)
40 }
41
42 pub fn none() -> CullModel {
43 CullModel::None
44 }
45}
46
47pub struct VisibilityObjectArcInner {
48 object: VisibilityObjectRaii,
49 visibility_object_id: AtomicU64,
52 drop_tx: Sender<VisibilityObjectId>,
53}
54
55impl Drop for VisibilityObjectArcInner {
56 fn drop(&mut self) {
57 let _ = self
58 .drop_tx
59 .send(VisibilityObjectId::from(slotmap::KeyData::from_ffi(
60 self.visibility_object_id.load(Ordering::Relaxed),
61 )));
62 }
63}
64
65pub struct VisibilityObjectWeakArcInner {
66 inner: Weak<VisibilityObjectArcInner>,
67}
68
69impl VisibilityObjectWeakArcInner {
70 pub fn upgrade(&self) -> Option<VisibilityObjectArc> {
71 self.inner
72 .upgrade()
73 .map(|inner| VisibilityObjectArc { inner })
74 }
75}
76
77#[derive(Clone)]
78pub struct VisibilityObjectArc {
79 inner: Arc<VisibilityObjectArcInner>,
80}
81
82impl VisibilityObjectArc {
83 pub(crate) fn new(
84 object: VisibilityObjectRaii,
85 drop_tx: Sender<VisibilityObjectId>,
86 ) -> Self {
87 Self {
88 inner: Arc::new(VisibilityObjectArcInner {
89 object,
90 visibility_object_id: AtomicU64::default(),
91 drop_tx,
92 }),
93 }
94 }
95
96 pub fn downgrade(&self) -> VisibilityObjectWeakArcInner {
97 VisibilityObjectWeakArcInner {
98 inner: Arc::downgrade(&self.inner),
99 }
100 }
101
102 pub(super) fn set_visibility_object_id(
103 &self,
104 visibility_object_id: VisibilityObjectId,
105 ) {
106 self.inner
107 .visibility_object_id
108 .store(visibility_object_id.data().as_ffi(), Ordering::Relaxed);
109 }
110
111 #[allow(dead_code)]
112 pub(super) fn set_zone(
113 &self,
114 zone: Option<ZoneHandle>,
115 ) -> &Self {
116 self.inner.object.set_zone(zone);
117 self
118 }
119
120 pub fn object_id(&self) -> ObjectId {
121 self.inner.object.object_id()
122 }
123
124 pub fn visibility_object_handle(&self) -> VisibilityObjectHandle {
126 self.inner.object.handle
127 }
128
129 pub fn render_objects(&self) -> &[RenderObjectHandle] {
130 &self.inner.object.render_objects()
131 }
132
133 pub fn set_cull_model(
134 &self,
135 cull_model: Option<ModelHandle>,
136 ) -> &Self {
137 self.inner.object.set_cull_model(cull_model);
138 self
139 }
140
141 pub fn set_transform(
142 &self,
143 translation: Vec3,
144 rotation: Quat,
145 scale: Vec3,
146 ) -> &Self {
147 self.inner
148 .object
149 .set_transform(translation, rotation, scale);
150 self
151 }
152}
153
154pub struct VisibilityObjectRaii {
156 commands: Sender<AsyncCommand>,
157 handle: VisibilityObjectHandle,
158 object_id: ObjectId,
159 render_objects: Vec<RenderObjectHandle>, }
161
162impl Drop for VisibilityObjectRaii {
163 fn drop(&mut self) {
164 let _ = self.commands.send(AsyncCommand::DestroyObject(self.handle));
166 }
167}
168
169impl VisibilityObjectRaii {
170 pub fn new(
171 object_id: ObjectId,
172 render_objects: Vec<RenderObjectHandle>,
173 handle: VisibilityObjectHandle,
174 commands: Sender<AsyncCommand>,
175 ) -> Self {
176 Self {
177 commands,
178 handle,
179 object_id,
180 render_objects,
181 }
182 }
183
184 #[allow(dead_code)]
185 pub(super) fn set_zone(
186 &self,
187 zone: Option<ZoneHandle>,
188 ) -> &Self {
189 self.commands
190 .send(AsyncCommand::SetObjectZone(self.handle, zone))
191 .expect("Unable to send SetObjectZone command.");
192 self
193 }
194
195 pub fn object_id(&self) -> ObjectId {
196 self.object_id
197 }
198
199 pub fn render_objects(&self) -> &[RenderObjectHandle] {
200 &self.render_objects
201 }
202
203 pub fn set_cull_model(
204 &self,
205 cull_model: Option<ModelHandle>,
206 ) -> &Self {
207 self.commands
208 .send(AsyncCommand::SetObjectCullModel(self.handle, cull_model))
209 .expect("Unable to send SetObjectCullModel command.");
210 self
211 }
212
213 pub fn set_transform(
214 &self,
215 translation: Vec3,
216 rotation: Quat,
217 scale: Vec3,
218 ) -> &Self {
219 self.commands
220 .send(AsyncCommand::SetObjectTransform(
221 self.handle,
222 Transform {
223 translation,
224 rotation,
225 scale,
226 },
227 ))
228 .expect("Unable to send SetObjectPosition command.");
229 self
230 }
231}