makepad_platform/
geometry.rs

1use {
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        // we have a finger print, now we need to find a geometry that has this fingerprint
105        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