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