91
91
ExtrusionBuilder {
92
92
base_builder : self . base_shape . mesh ( ) ,
93
93
half_depth : self . half_depth ,
94
+ segments : 1 ,
94
95
}
95
96
}
96
97
}
@@ -101,8 +102,9 @@ where
101
102
P : Primitive2d + Meshable ,
102
103
P :: Output : Extrudable ,
103
104
{
104
- base_builder : P :: Output ,
105
- half_depth : f32 ,
105
+ pub base_builder : P :: Output ,
106
+ pub half_depth : f32 ,
107
+ pub segments : usize ,
106
108
}
107
109
108
110
impl < P > ExtrusionBuilder < P >
@@ -115,8 +117,16 @@ where
115
117
Self {
116
118
base_builder : base_shape. mesh ( ) ,
117
119
half_depth : depth / 2. ,
120
+ segments : 1 ,
118
121
}
119
122
}
123
+
124
+ /// Sets the number of segments along the depth of the extrusion.
125
+ /// Must be greater than `0` for the geometry of the mantel to be generated.
126
+ pub fn segments ( mut self , segments : usize ) -> Self {
127
+ self . segments = segments;
128
+ self
129
+ }
120
130
}
121
131
122
132
impl ExtrusionBuilder < Circle > {
@@ -218,14 +228,19 @@ where
218
228
panic ! ( "The base mesh did not have vertex positions" ) ;
219
229
} ;
220
230
231
+ debug_assert ! ( self . segments > 0 ) ;
232
+
233
+ let layers = self . segments + 1 ;
234
+ let layer_depth_delta = self . half_depth * 2.0 / self . segments as f32 ;
235
+
221
236
let perimeter = self . base_builder . perimeter ( ) ;
222
237
let ( vert_count, index_count) =
223
238
perimeter
224
239
. iter ( )
225
240
. fold ( ( 0 , 0 ) , |( verts, indices) , perimeter| {
226
241
(
227
- verts + 2 * perimeter. vertices_per_layer ( ) ,
228
- indices + perimeter. indices_per_segment ( ) ,
242
+ verts + layers * perimeter. vertices_per_layer ( ) ,
243
+ indices + self . segments * perimeter. indices_per_segment ( ) ,
229
244
)
230
245
} ) ;
231
246
let mut positions = Vec :: with_capacity ( vert_count) ;
@@ -253,36 +268,37 @@ where
253
268
// Get the index of the next vertex added to the mantel.
254
269
let index = positions. len ( ) as u32 ;
255
270
256
- // Push the positions of the two indices and their equivalent points on the back face.
257
- // This works, since the front face has already been moved to the correct depth.
258
- positions. push ( a) ;
259
- positions. push ( b) ;
260
- positions. push ( [ a[ 0 ] , a[ 1 ] , -a[ 2 ] ] ) ;
261
- positions. push ( [ b[ 0 ] , b[ 1 ] , -b[ 2 ] ] ) ;
262
-
263
- // UVs for the mantel are between (0, 0.5) and (1, 1).
264
- uvs. extend_from_slice ( & [
265
- [ uv_x, 0.5 ] ,
266
- [ uv_x + uv_delta, 0.5 ] ,
267
- [ uv_x, 1. ] ,
268
- [ uv_x + uv_delta, 1. ] ,
269
- ] ) ;
271
+ // Push the positions of the two indices and their equivalent points on each layer.
272
+ for i in 0 ..layers {
273
+ let i = i as f32 ;
274
+ let z = a[ 2 ] - layer_depth_delta * i;
275
+ positions. push ( [ a[ 0 ] , a[ 1 ] , z] ) ;
276
+ positions. push ( [ b[ 0 ] , b[ 1 ] , z] ) ;
277
+
278
+ // UVs for the mantel are between (0, 0.5) and (1, 1).
279
+ let uv_y = 0.5 + 0.5 * i / self . segments as f32 ;
280
+ uvs. push ( [ uv_x, uv_y] ) ;
281
+ uvs. push ( [ uv_x + uv_delta, uv_y] ) ;
282
+ }
270
283
271
284
// The normal is calculated to be the normal of the line segment connecting a and b.
272
285
let n = Vec3 :: from_array ( [ b[ 1 ] - a[ 1 ] , a[ 0 ] - b[ 0 ] , 0. ] )
273
286
. normalize_or_zero ( )
274
287
. to_array ( ) ;
275
- normals. extend_from_slice ( & [ n; 4 ] ) ;
288
+ normals. extend_from_slice ( & vec ! [ n; 2 * layers ] ) ;
276
289
277
290
// Add the indices for the vertices created above to the mesh.
278
- indices. extend_from_slice ( & [
279
- index,
280
- index + 2 ,
281
- index + 1 ,
282
- index + 1 ,
283
- index + 2 ,
284
- index + 3 ,
285
- ] ) ;
291
+ for i in 0 ..self . segments as u32 {
292
+ let base_index = index + 2 * i;
293
+ indices. extend_from_slice ( & [
294
+ base_index,
295
+ base_index + 2 ,
296
+ base_index + 1 ,
297
+ base_index + 1 ,
298
+ base_index + 2 ,
299
+ base_index + 3 ,
300
+ ] ) ;
301
+ }
286
302
}
287
303
}
288
304
PerimeterSegment :: Smooth {
@@ -296,14 +312,22 @@ where
296
312
// we need to store the index of the first vertex that is part of this segment.
297
313
let base_index = positions. len ( ) as u32 ;
298
314
299
- // If there is a first vertex, we need to add it and its counterpart on the back face .
315
+ // If there is a first vertex, we need to add it and its counterparts on each layer .
300
316
// The normal is provided by `segment.first_normal`.
301
317
if let Some ( i) = segment_indices. first ( ) {
302
318
let p = cap_verts[ * i as usize ] ;
303
- positions. push ( p) ;
304
- positions. push ( [ p[ 0 ] , p[ 1 ] , -p[ 2 ] ] ) ;
305
- uvs. extend_from_slice ( & [ [ uv_start, 0.5 ] , [ uv_start, 1. ] ] ) ;
306
- normals. extend_from_slice ( & [ first_normal. extend ( 0. ) . to_array ( ) ; 2 ] ) ;
319
+ for i in 0 ..layers {
320
+ let i = i as f32 ;
321
+ let z = p[ 2 ] - layer_depth_delta * i;
322
+ positions. push ( [ p[ 0 ] , p[ 1 ] , z] ) ;
323
+
324
+ let uv_y = 0.5 + 0.5 * i / self . segments as f32 ;
325
+ uvs. push ( [ uv_start, uv_y] ) ;
326
+ }
327
+ normals. extend_from_slice ( & vec ! [
328
+ first_normal. extend( 0. ) . to_array( ) ;
329
+ layers
330
+ ] ) ;
307
331
}
308
332
309
333
// For all points inbetween the first and last vertices, we can automatically compute the normals.
@@ -315,11 +339,15 @@ where
315
339
let b = cap_verts[ segment_indices[ i] as usize ] ;
316
340
let c = cap_verts[ segment_indices[ i + 1 ] as usize ] ;
317
341
318
- // Add the current vertex and its counterpart on the backface
319
- positions. push ( b) ;
320
- positions. push ( [ b[ 0 ] , b[ 1 ] , -b[ 2 ] ] ) ;
342
+ // Add the current vertex and its counterparts on each layer.
343
+ for i in 0 ..layers {
344
+ let i = i as f32 ;
345
+ let z = b[ 2 ] - layer_depth_delta * i;
346
+ positions. push ( [ b[ 0 ] , b[ 1 ] , z] ) ;
321
347
322
- uvs. extend_from_slice ( & [ [ uv_x, 0.5 ] , [ uv_x, 1. ] ] ) ;
348
+ let uv_y = 0.5 + 0.5 * i / self . segments as f32 ;
349
+ uvs. push ( [ uv_x, uv_y] ) ;
350
+ }
323
351
324
352
// The normal for the current vertices can be calculated based on the two neighbouring vertices.
325
353
// The normal is interpolated between the normals of the two line segments connecting the current vertex with its neighbours.
@@ -333,32 +361,42 @@ where
333
361
. extend ( 0. )
334
362
. to_array ( )
335
363
} ;
336
- normals. extend_from_slice ( & [ n; 2 ] ) ;
364
+ normals. extend_from_slice ( & vec ! [ n; layers ] ) ;
337
365
}
338
366
339
- // If there is a last vertex, we need to add it and its counterpart on the back face .
367
+ // If there is a last vertex, we need to add it and its counterparts on each layer .
340
368
// The normal is provided by `segment.last_normal`.
341
369
if let Some ( i) = segment_indices. last ( ) {
342
370
let p = cap_verts[ * i as usize ] ;
343
- positions. push ( p) ;
344
- positions. push ( [ p[ 0 ] , p[ 1 ] , -p[ 2 ] ] ) ;
345
- uvs. extend_from_slice ( & [
346
- [ uv_start + uv_segment_delta, 0.5 ] ,
347
- [ uv_start + uv_segment_delta, 1. ] ,
371
+ for i in 0 ..layers {
372
+ let i = i as f32 ;
373
+ let z = p[ 2 ] - layer_depth_delta * i;
374
+ positions. push ( [ p[ 0 ] , p[ 1 ] , z] ) ;
375
+
376
+ let uv_y = 0.5 + 0.5 * i / self . segments as f32 ;
377
+ uvs. push ( [ uv_start + uv_segment_delta, uv_y] ) ;
378
+ }
379
+ normals. extend_from_slice ( & vec ! [
380
+ last_normal. extend( 0. ) . to_array( ) ;
381
+ layers
348
382
] ) ;
349
- normals. extend_from_slice ( & [ last_normal. extend ( 0. ) . to_array ( ) ; 2 ] ) ;
350
383
}
351
384
352
- for i in 0 ..( segment_indices. len ( ) as u32 - 1 ) {
353
- let index = base_index + 2 * i;
354
- indices. extend_from_slice ( & [
355
- index,
356
- index + 1 ,
357
- index + 2 ,
358
- index + 2 ,
359
- index + 1 ,
360
- index + 3 ,
361
- ] ) ;
385
+ let columns = segment_indices. len ( ) as u32 ;
386
+ let segments = self . segments as u32 ;
387
+ let layers = segments + 1 ;
388
+ for s in 0 ..segments {
389
+ for column in 0 ..( columns - 1 ) {
390
+ let index = base_index + s + column * layers;
391
+ indices. extend_from_slice ( & [
392
+ index,
393
+ index + 1 ,
394
+ index + layers,
395
+ index + layers,
396
+ index + 1 ,
397
+ index + layers + 1 ,
398
+ ] ) ;
399
+ }
362
400
}
363
401
}
364
402
}
0 commit comments