rafx_framework/visibility/
visibility_resource.rs1use crate::render_features::RenderObjectHandle;
2use crate::visibility::view_frustum_arc::ViewFrustumArc;
3use crate::visibility::visibility_object_allocator::{
4 VisibilityObjectAllocator, VisibilityObjectId,
5};
6use crate::visibility::visibility_object_arc::{CullModel, VisibilityObjectArc};
7use crate::visibility::ObjectId;
8use crossbeam_channel::Sender;
9use rafx_visibility::geometry::Transform;
10use rafx_visibility::{AsyncCommand, ModelHandle, VisibilityObject, VisibilityWorld, ZoneHandle};
11
12pub struct VisibilityObjectInfo<'a> {
13 arc: VisibilityObjectArc,
14 obj: &'a VisibilityObject,
15}
16
17impl<'a> VisibilityObjectInfo<'a> {
18 pub fn object_id(&self) -> ObjectId {
19 self.arc.object_id()
20 }
21
22 pub fn render_objects(&self) -> &[RenderObjectHandle] {
23 self.arc.render_objects()
24 }
25
26 pub fn transform(&self) -> Transform {
27 self.obj.transform.unwrap_or_default()
28 }
29
30 pub fn previous_frame_transform(&self) -> Option<Transform> {
31 self.obj.previous_frame_transform
32 }
33
34 pub fn model_handle(&self) -> &Option<ModelHandle> {
35 &self.obj.cull_model
36 }
37}
38
39pub struct VisibilityResource {
40 allocator: VisibilityObjectAllocator,
41 commands: Sender<AsyncCommand>,
42 dynamic_zone: ZoneHandle,
43 static_zone: ZoneHandle,
44}
45
46impl VisibilityResource {
47 pub fn new() -> Self {
48 let mut visibility_world = VisibilityWorld::new();
49 let static_zone = visibility_world.inner.new_zone();
50 let dynamic_zone = visibility_world.inner.new_zone();
51 let commands = visibility_world.new_async_command_sender();
52 let allocator = VisibilityObjectAllocator::new(visibility_world);
53
54 VisibilityResource {
55 commands,
56 static_zone,
57 dynamic_zone,
58 allocator,
59 }
60 }
61
62 pub fn world(&self) -> &VisibilityWorld {
63 self.allocator.world()
64 }
65
66 pub fn update(&mut self) {
67 self.allocator.update();
68 }
69
70 pub fn register_view_frustum(&mut self) -> ViewFrustumArc {
71 self.allocator
72 .new_view_frustum(Some(self.static_zone), Some(self.dynamic_zone))
73 }
74
75 pub fn register_static_view_frustum(&mut self) -> ViewFrustumArc {
76 self.allocator
77 .new_view_frustum(Some(self.static_zone), None)
78 }
79
80 pub fn register_dynamic_view_frustum(&mut self) -> ViewFrustumArc {
81 self.allocator
82 .new_view_frustum(None, Some(self.dynamic_zone))
83 }
84
85 pub fn register_static_object(
89 &mut self,
90 object_id: ObjectId,
91 cull_model: CullModel,
92 render_objects: Vec<RenderObjectHandle>,
93 ) -> VisibilityObjectArc {
94 self.register_object(object_id, cull_model, render_objects, self.static_zone)
95 }
96
97 pub fn register_dynamic_object(
101 &mut self,
102 object_id: ObjectId,
103 cull_model: CullModel,
104 render_objects: Vec<RenderObjectHandle>,
105 ) -> VisibilityObjectArc {
106 self.register_object(object_id, cull_model, render_objects, self.dynamic_zone)
107 }
108
109 fn register_object(
110 &mut self,
111 object_id: ObjectId,
112 cull_model: CullModel,
113 render_objects: Vec<RenderObjectHandle>,
114 zone: ZoneHandle,
115 ) -> VisibilityObjectArc {
116 self.allocator
117 .new_object(object_id, cull_model, render_objects, Some(zone))
118 }
119
120 pub fn visibility_object_arc(
121 &self,
122 id: VisibilityObjectId,
123 ) -> Option<VisibilityObjectArc> {
124 self.allocator.object_ref(id)
125 }
126
127 pub fn visibility_object_info(
128 &self,
129 id: VisibilityObjectId,
130 ) -> Option<VisibilityObjectInfo> {
131 let arc = self.allocator.object_ref(id);
132 if let Some(arc) = arc {
133 let obj = self
134 .world()
135 .inner
136 .visibility_object(arc.visibility_object_handle());
137 if let Some(obj) = obj {
138 return Some(VisibilityObjectInfo { arc, obj });
139 }
140 }
141
142 None
143 }
144}
145
146impl Drop for VisibilityResource {
147 fn drop(&mut self) {
148 let _ = self
149 .commands
150 .send(AsyncCommand::DestroyZone(self.static_zone));
151 let _ = self
152 .commands
153 .send(AsyncCommand::DestroyZone(self.dynamic_zone));
154 }
155}