makepad_platform/
geometry.rs

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