makepad_platform/
geometry.rs1use {
2 std::{
3 rc::Rc,
4 hash::{Hash, Hasher},
5 },
6 crate::{
7 id_pool::*,
8 makepad_error_log::*,
9 makepad_live_compiler::{
10 LiveType,
11 LiveId,
12 },
13 makepad_shader_compiler::ShaderTy,
14 os::CxOsGeometry,
15 cx::Cx,
16 }
17};
18
19
20#[derive(Debug)]
21pub struct Geometry(PoolId);
22
23#[derive(Clone, Copy, Debug, PartialEq)]
24pub struct GeometryId(usize, u64);
25
26impl Geometry{
27 pub fn geometry_id(&self)->GeometryId{GeometryId(self.0.id, self.0.generation)}
28}
29
30#[derive(Default)]
31pub struct CxGeometryPool(pub (crate) IdPool<CxGeometry>);
32
33impl CxGeometryPool{
34 pub fn alloc(&mut self)->Geometry{
35 Geometry(self.0.alloc())
36 }
37}
38
39impl std::ops::Index<GeometryId> for CxGeometryPool{
40 type Output = CxGeometry;
41 fn index(&self, index: GeometryId) -> &Self::Output{
42 let d = &self.0.pool[index.0];
43 if d.generation != index.1{
44 error!("Drawlist id generation wrong {} {} {}", index.0, d.generation, index.1)
45 }
46 &d.item
47 }
48}
49
50impl std::ops::IndexMut<GeometryId> for CxGeometryPool{
51 fn index_mut(&mut self, index: GeometryId) -> &mut Self::Output{
52 let d = &mut self.0.pool[index.0];
53 if d.generation != index.1{
54 error!("Drawlist id generation wrong {} {} {}", index.0, d.generation, index.1)
55 }
56 &mut d.item
57 }
58}
59
60#[derive(Clone, Debug)]
61pub struct GeometryRef(pub Rc<Geometry>);
62
63
64const MAX_GEOM_FINGERPRINT:usize = 16;
65#[derive(Clone, Debug)]
66pub struct GeometryFingerprint {
67 pub live_type: LiveType,
68 pub inputs_stored:usize,
69 pub inputs: [f32;MAX_GEOM_FINGERPRINT]
70}
71
72impl GeometryFingerprint{
73 pub fn new(live_type:LiveType)->Self{Self{live_type, inputs_stored:0, inputs:[0f32;MAX_GEOM_FINGERPRINT]}}
74 pub fn push(&mut self, f:f32){self.inputs[self.inputs_stored] = f;self.inputs_stored += 1;}
75}
76
77impl Hash for GeometryFingerprint {
78 fn hash<H: Hasher>(&self, state: &mut H) {
79 self.live_type.hash(state);
80 for i in 0..self.inputs_stored{
81 self.inputs[i].to_bits().hash(state);
82 }
83 }
84}
85
86impl PartialEq for GeometryFingerprint {
87 fn eq(&self, other: &Self) -> bool {
88 if self.inputs_stored != other.inputs_stored{
89 return false
90 }
91 for i in 0..self.inputs_stored{
92 if self.inputs[i] != other.inputs[i]{
93 return false
94 }
95 }
96 self.live_type == other.live_type
97 }
98}
99impl Eq for GeometryFingerprint {}
100
101impl Cx{
102
103 pub fn get_geometry_ref(&mut self, fingerprint:GeometryFingerprint)->GeometryRef{
104 if let Some(gr) = self.geometries_refs.get(&fingerprint){
106 if let Some(gr) = gr.upgrade(){
107 return GeometryRef(gr)
108 }
109 }
110 let geometry = Rc::new(Geometry::new(self));
111 let weak = Rc::downgrade(&geometry);
112 self.geometries_refs.insert(fingerprint, weak);
113 GeometryRef(geometry)
114 }
115
116
117}
118
119impl Geometry{
120 pub fn new(cx: &mut Cx) -> Self {
121 let geometry = cx.geometries.alloc();
122 cx.geometries[geometry.geometry_id()].indices.clear();
123 cx.geometries[geometry.geometry_id()].vertices.clear();
124 cx.geometries[geometry.geometry_id()].dirty = true;
125 geometry
126 }
127
128 pub fn update(&self, cx:&mut Cx, indices: Vec<u32>, vertices: Vec<f32>){
129 let cxgeom = &mut cx.geometries[self.geometry_id()];
130 cxgeom.indices = indices;
131 cxgeom.vertices = vertices;
132 cxgeom.dirty = true;
133 }
134}
135
136#[derive(Default)]
137pub struct CxGeometry{
138 pub indices: Vec<u32>,
139 pub vertices: Vec<f32>,
140 pub dirty: bool,
141 pub os: CxOsGeometry
142}
143
144
145#[derive(Debug)]
146pub struct GeometryField {
147 pub id: LiveId,
148 pub ty: ShaderTy
149}
150
151pub trait GeometryFields{
152 fn geometry_fields(&self, fields: &mut Vec<GeometryField>);
153 fn live_type_check(&self)->LiveType;
154 fn get_geometry_id(&self)->Option<GeometryId>;
155}
156
157