1use {
2 crate::{
3 makepad_derive_live::*,
4 makepad_platform::*,
5 },
6};
7
8live_design!{
9 GeometryQuad2D = {{GeometryQuad2D}} {
10 x1: 0.0;
11 y1: 0.0;
12 x2: 1.0;
13 y2: 1.0;
14 }
15}
16
17impl LiveHook for GeometryQuad2D {
18 fn after_apply(&mut self, cx: &mut Cx, _apply_from:ApplyFrom, _index:usize, _nodes:&[LiveNode]) {
19 let mut fp = GeometryFingerprint::new(LiveType::of::<Self>());
20 fp.push(self.x1);
21 fp.push(self.y1);
22 fp.push(self.x2);
23 fp.push(self.y2);
24 self.geometry_ref = Some(cx.get_geometry_ref(fp));
26 GeometryGen::from_quad_2d(
27 self.x1,
28 self.y1,
29 self.x2,
30 self.y2,
31 ).to_geometry(cx, &self.geometry_ref.as_ref().unwrap().0);
32 }
33}
34
35impl GeometryFields for GeometryQuad2D {
36 fn geometry_fields(&self, fields: &mut Vec<GeometryField>) {
37 fields.push(GeometryField {id: live_id!(geom_pos), ty: ShaderTy::Vec2});
38 }
39
40 fn get_geometry_id(&self) -> Option<GeometryId> {
41 if let Some(gr) = &self.geometry_ref{
43 Some(gr.0.geometry_id())
44 }
45 else{
46 None
47 }
48 }
49
50 fn live_type_check(&self) -> LiveType {
51 LiveType::of::<Self>()
52 }
53}
54
55#[derive(Live)]
56pub struct GeometryQuad2D {
57 #[rust] pub geometry_ref: Option<GeometryRef>,
58 #[live(0.0)] pub x1: f32,
59 #[live(0.0)] pub y1: f32,
60 #[live(1.0)] pub x2: f32,
61 #[live(1.0)] pub y2: f32,
62}
63
64#[derive(Clone, Debug, Default, PartialEq)]
65pub struct GeometryGen {
66 pub vertices: Vec<f32>, pub indices: Vec<u32>
68}
69
70#[derive(Clone, Copy)]
71pub enum GeometryAxis {
72 X = 0,
73 Y = 1,
74 Z = 2,
75}
76
77impl GeometryGen {
78
79 pub fn to_geometry(self, cx:&mut Cx, geometry:&Geometry){
80 geometry.update(cx, self.indices, self.vertices);
81 }
82
83 pub fn from_quad_2d(x1: f32, y1: f32, x2: f32, y2: f32) -> GeometryGen {
84 let mut g = Self::default();
85 g.add_quad_2d(x1, y1, x2, y2);
86 g
87 }
88
89 pub fn from_cube_3d(
90 width: f32,
91 height: f32,
92 depth: f32,
93 width_segments: usize,
94 height_segments: usize,
95 depth_segments: usize
96 ) -> GeometryGen {
97 let mut g = Self::default();
98 g.add_cube_3d(width, height, depth, width_segments, height_segments, depth_segments);
99 g
100 }
101
102 pub fn add_quad_2d(&mut self, x1: f32, y1: f32, x2: f32, y2: f32) {
104 let vertex_offset = self.vertices.len() as u32;
105 self.vertices.push(x1);
106 self.vertices.push(y1);
107 self.vertices.push(x2);
108 self.vertices.push(y1);
109 self.vertices.push(x2);
110 self.vertices.push(y2);
111 self.vertices.push(x1);
112 self.vertices.push(y2);
113 self.indices.push(vertex_offset + 0);
114 self.indices.push(vertex_offset + 1);
115 self.indices.push(vertex_offset + 2);
116 self.indices.push(vertex_offset + 2);
117 self.indices.push(vertex_offset + 3);
118 self.indices.push(vertex_offset + 0);
119 }
120
121 pub fn add_cube_3d(
123 &mut self,
124 width: f32,
125 height: f32,
126 depth: f32,
127 width_segments: usize,
128 height_segments: usize,
129 depth_segments: usize
130 ) {
131 self.add_plane_3d(GeometryAxis::Z, GeometryAxis::Y, GeometryAxis::X, -1.0, -1.0, depth, height, width, depth_segments, height_segments, 0.0);
132 self.add_plane_3d(GeometryAxis::Z, GeometryAxis::Y, GeometryAxis::X, 1.0, -1.0, depth, height, -width, depth_segments, height_segments, 1.0);
133 self.add_plane_3d(GeometryAxis::X, GeometryAxis::Z, GeometryAxis::Y, 1.0, 1.0, width, depth, height, width_segments, depth_segments, 2.0);
134 self.add_plane_3d(GeometryAxis::X, GeometryAxis::Z, GeometryAxis::Y, 1.0, -1.0, width, depth, -height, width_segments, depth_segments, 3.0);
135 self.add_plane_3d(GeometryAxis::X, GeometryAxis::Y, GeometryAxis::Z, 1.0, -1.0, width, height, depth, width_segments, height_segments, 4.0);
136 self.add_plane_3d(GeometryAxis::X, GeometryAxis::Y, GeometryAxis::Z, -1.0, -1.0, width, height, -depth, width_segments, height_segments, 5.0);
137 }
138
139
140 pub fn add_plane_3d(
142 &mut self,
143 u: GeometryAxis,
144 v: GeometryAxis,
145 w: GeometryAxis,
146 udir: f32,
147 vdir: f32,
148 width: f32,
149 height: f32,
150 depth: f32,
151 grid_x: usize,
152 grid_y: usize,
153 id: f32
154 ) {
155 let segment_width = width / (grid_x as f32);
156 let segment_height = height / (grid_y as f32);
157 let width_half = width / 2.0;
158 let height_half = height / 2.0;
159 let depth_half = depth / 2.0;
160 let grid_x1 = grid_x + 1;
161 let grid_y1 = grid_y + 1;
162
163 let vertex_offset = self.vertices.len() / 9;
164
165 for iy in 0..grid_y1 {
166 let y = (iy as f32) * segment_height - height_half;
167
168 for ix in 0..grid_x1 {
169
170 let x = (ix as f32) * segment_width - width_half;
171 let off = self.vertices.len();
172 self.vertices.push(0.0);
173 self.vertices.push(0.0);
174 self.vertices.push(0.0);
175
176 self.vertices[off + u as usize] = x * udir;
177 self.vertices[off + v as usize] = y * vdir;
178 self.vertices[off + w as usize] = depth_half;
179
180 self.vertices.push(id);
181 let off = self.vertices.len();
182 self.vertices.push(0.0);
183 self.vertices.push(0.0);
184 self.vertices.push(0.0);
185 self.vertices[off + w as usize] = if depth > 0.0 {1.0} else {-1.0};
186
187 self.vertices.push((ix as f32) / (grid_x as f32));
188 self.vertices.push(1.0 - (iy as f32) / (grid_y as f32));
189 }
190 }
191
192 for iy in 0..grid_y {
193 for ix in 0..grid_x {
194 let a = vertex_offset + ix + grid_x1 * iy;
195 let b = vertex_offset + ix + grid_x1 * (iy + 1);
196 let c = vertex_offset + (ix + 1) + grid_x1 * (iy + 1);
197 let d = vertex_offset + (ix + 1) + grid_x1 * iy;
198 self.indices.push(a as u32);
199 self.indices.push(b as u32);
200 self.indices.push(d as u32);
201 self.indices.push(b as u32);
202 self.indices.push(c as u32);
203 self.indices.push(d as u32);
204 }
205 }
206 }
207}