1use crate::prelude::*;
2use maths_rs::prelude::*;
3
4#[derive(Clone)]
6#[repr(C)]
7pub struct Vertex3D {
8 pub position: Vec3f,
9 pub texcoord: Vec2f,
10 pub normal: Vec3f,
11 pub tangent: Vec3f,
12 pub bitangent: Vec3f,
13}
14
15#[derive(Clone)]
17#[repr(C)]
18pub struct Vertex2D {
19 pub position: Vec2f,
20 pub texcoord: Vec2f,
21}
22
23const INV_PHI : f32 = 0.618034;
25
26fn basis_from_axis(axis: Vec3f) -> (Vec3f, Vec3f, Vec3f) {
28 let mut right = cross(axis, Vec3f::unit_y());
30 if mag(right) < 0.1 {
31 right = cross(axis, Vec3f::unit_z());
32 }
33 if mag(right) < 0.1 {
34 right = cross(axis, Vec3f::unit_x());
35 }
36 right = normalize(right);
37
38 let up = normalize(cross(axis, right));
40 right = normalize(cross(axis, up));
41
42 let at = cross(right, up);
44
45 (right, up, at)
46}
47
48pub fn subdivide_quad(q0: &Vertex3D, q1: &Vertex3D, q2: &Vertex3D, q3: &Vertex3D, order: u32, max_order: u32) -> Vec<Vertex3D> {
50 if order == max_order {
51 vec![q0.clone(), q1.clone(), q2.clone(), q3.clone()]
52 }
53 else {
54 let lerp_half = |a: &Vertex3D, b: &Vertex3D| -> Vertex3D {
63 Vertex3D {
64 position: a.position + (b.position - a.position) * 0.5,
65 texcoord: a.texcoord + (b.texcoord - a.texcoord) * 0.5,
66 tangent: a.tangent,
67 normal: a.normal,
68 bitangent: a.bitangent
69 }
70 };
71
72 let s0 = lerp_half(q0, q1);
73 let s1 = lerp_half(q1, q2);
74 let s2 = lerp_half(q2, q3);
75 let s3 = lerp_half(q3, q0);
76 let s4 = lerp_half(&s3, &s1);
77
78 let mut sub = subdivide_quad(q0, &s0, &s4, &s3, order + 1, max_order);
79 sub.extend(subdivide_quad(&s0, q1, &s1, &s4, order + 1, max_order));
80 sub.extend(subdivide_quad(&s4, &s1, q2, &s2, order + 1, max_order));
81 sub.extend(subdivide_quad(&s3, &s4, &s2, q3, order + 1, max_order));
82 sub
83 }
84}
85
86pub fn subdivide_triangle(t0: &Vertex3D, t1: &Vertex3D, t2: &Vertex3D, order: u32, max_order: u32) -> Vec<Vertex3D> {
88 if order == max_order {
89 vec![t0.clone(), t1.clone(), t2.clone()]
90 }
91 else {
92 let lerp_half = |a: &Vertex3D, b: &Vertex3D| -> Vertex3D {
100 Vertex3D {
101 position: a.position + (b.position - a.position) * 0.5,
102 texcoord: a.texcoord + (b.texcoord - a.texcoord) * 0.5,
103 tangent: a.tangent,
104 normal: a.normal,
105 bitangent: a.bitangent
106 }
107 };
108
109 let s0 = lerp_half(t0, t1);
110 let s1 = lerp_half(t0, t2);
111 let s2 = lerp_half(t2, t1);
112
113 let mut sub = subdivide_triangle(t0, &s0, &s1, order + 1, max_order);
114 sub.extend(subdivide_triangle(&s0, t1, &s2, order + 1, max_order));
115 sub.extend(subdivide_triangle(&s1, &s0, &s2, order + 1, max_order));
116 sub.extend(subdivide_triangle(&s1, &s2, t2, order + 1, max_order));
117 sub
118 }
119}
120
121fn create_mesh_3d<D: gfx::Device>(dev: &mut D, vertices: Vec<Vertex3D>, indices: Vec<usize>) -> pmfx::Mesh<D> {
123 let max_index = vertices.len();
124 let index_buffer = if max_index > 65535 {
125 let mut indices32 : Vec<u32> = Vec::new();
126 for i in &indices {
127 indices32.push(*i as u32);
128 }
129
130 dev.create_buffer(&gfx::BufferInfo {
131 usage: gfx::BufferUsage::INDEX,
132 cpu_access: gfx::CpuAccessFlags::NONE,
133 num_elements: indices32.len(),
134 format: gfx::Format::R32u,
135 stride: 4,
136 initial_state: gfx::ResourceState::IndexBuffer
137 },
138 Some(indices32.as_slice())
139 ).unwrap()
140 }
141 else {
142 let mut indices16 : Vec<u16> = Vec::new();
143 for i in &indices {
144 indices16.push(*i as u16);
145 }
146
147 dev.create_buffer(&gfx::BufferInfo {
148 usage: gfx::BufferUsage::INDEX,
149 cpu_access: gfx::CpuAccessFlags::NONE,
150 num_elements: indices16.len(),
151 format: gfx::Format::R16u,
152 stride: 2,
153 initial_state: gfx::ResourceState::IndexBuffer
154 },
155 Some(indices16.as_slice())
156 ).unwrap()
157 };
158
159 let (aabb_min, aabb_max) =
160 indices.iter().fold((Vec3f::max_value(), -Vec3f::max_value()), |acc, i| min_max(vertices[*i].position, acc));
161
162 pmfx::Mesh {
163 vb: dev.create_buffer(&gfx::BufferInfo {
164 usage: gfx::BufferUsage::VERTEX,
165 cpu_access: gfx::CpuAccessFlags::NONE,
166 num_elements: vertices.len(),
167 format: gfx::Format::Unknown,
168 stride: std::mem::size_of::<Vertex3D>(),
169 initial_state: gfx::ResourceState::VertexConstantBuffer
170 },
171 Some(vertices.as_slice())
172 ).unwrap(),
173 ib: index_buffer,
174 num_indices: indices.len() as u32,
175 aabb_min,
176 aabb_max
177 }
178}
179
180fn create_faceted_mesh_3d<D: gfx::Device>(dev: &mut D, vertices: Vec<Vertex3D>) -> pmfx::Mesh<D> {
182 let mut indices = Vec::new();
183 for i in 0..vertices.len() {
184 indices.push(i);
185 }
186 create_mesh_3d(dev, vertices, indices)
187}
188
189fn create_sphere_vertices(segments: usize, hemi_start: usize, hemi_end: usize, cap: bool) -> (Vec<Vertex3D>, Vec<usize>) {
190 let vertex_segments = segments + 1;
191
192 let angle_step = f32::two_pi() / segments as f32;
193 let height_step = 2.0 / (segments - 1) as f32;
194
195 let mut vertices = Vec::new();
196 let mut indices = Vec::new();
197 let mut angle = 0.0;
198 let mut y = -1.0;
199
200 for _ in 0..vertex_segments {
201 angle = -f32::pi();
202 for i in 0..vertex_segments {
203 let x = cos(angle);
204 let z = -sin(angle);
205
206 let u = 0.5 + atan2(z, x) / f32::two_pi();
207
208 let radius = 1.0 - abs(y);
209 let xz = vec3f(x, 0.0, z) * radius;
210 let p = vec3f(xz.x, y, xz.z);
211
212 angle += angle_step;
214
215 let x = cos(angle);
216 let z = -sin(angle);
217 let xz = vec3f(x, 0.0, z) * radius;
218
219 let p_next = vec3f(xz.x, y, xz.z);
220 let p_next = normalize(p_next);
221
222 let p = normalize(p);
223
224 let mut t = p_next - p;
225
226 if mag2(t) < 0.001 {
228 t = Vec3f::unit_x();
229 }
230
231 let bt = cross(p, t);
232
233 let v = 0.5 + asin(p.y) / f32::pi();
234
235 let u = if i == segments { 0.0 } else { u };
237 let u = if i == 0 { 1.0 } else { u };
238
239 vertices.push(Vertex3D{
240 position: p,
241 normal: p,
242 tangent: t,
243 bitangent: bt,
244 texcoord: vec2f(1.0 - u, 1.0 - v) * 3.0
245 });
246 }
247
248 y += height_step;
249 }
250
251 let hemi_start = if hemi_start > 0 {
256 hemi_start - 1
257 }
258 else {
259 hemi_start
260 };
261
262 let hemi_start = min(hemi_start, segments);
263 let hemi_end = max(min(hemi_end, segments-1), 1);
264
265 for r in hemi_start..hemi_end {
266 for i in 0..segments {
267 let i_next = i + 1;
268 let v_index = r * vertex_segments;
269 let v_next_index = (r + 1) * vertex_segments + i;
270 let v_next_next_index = (r + 1) * vertex_segments + i_next;
271
272 indices.extend(vec![
273 v_index + i,
274 v_next_index,
275 v_index + i_next,
276 v_next_index,
277 v_next_next_index,
278 v_index + i_next,
279 ]);
280 }
281 }
282
283 if cap {
284 let n = Vec3f::unit_y();
286 let t = Vec3f::unit_x();
287 let bt = Vec3f::unit_z();
288 let y = -1.0 + (hemi_end as f32 * height_step); let centre_cap = vertices.len();
291 vertices.push(Vertex3D{
292 position: Vec3f::unit_y() * y,
293 normal: n,
294 tangent: t,
295 bitangent: bt,
296 texcoord: Vec2f::point_five()
297 });
298
299 let loop_start = centre_cap + 1;
300
301 for _ in 0..vertex_segments {
302 let x = cos(angle);
303 let z = -sin(angle);
304 let radius = 1.0 - abs(y);
305 let xz = vec3f(x, 0.0, z) * radius;
306 let p = vec3f(xz.x, y, xz.z);
307 let p = normalize(p);
308
309 vertices.push(Vertex3D{
310 position: p,
311 normal: n,
312 tangent: t,
313 bitangent: bt,
314 texcoord: vec2f(p.x, p.z) * 0.5 + 0.5
315 });
316
317 angle += angle_step;
318 }
319
320 for i in 0..segments {
322 indices.extend(vec![
323 loop_start + i,
324 centre_cap,
325 loop_start + i + 1
326 ]);
327 }
328 }
329 (vertices, indices)
330}
331
332pub fn create_prism_vertices(segments: usize, smooth: bool, cap: bool) -> (Vec<Vertex3D>, Vec<usize>) {
334 let axis = Vec3f::unit_y();
335 let right = Vec3f::unit_x();
336 let up = cross(axis, right);
337 let right = cross(axis, up);
338
339 let mut vertices = Vec::new();
340 let mut points = Vec::new();
341 let mut bottom_points = Vec::new();
342 let mut top_points = Vec::new();
343 let mut tangents = Vec::new();
344 let mut indices = Vec::new();
345
346 let vertex_segments = segments + 1;
348
349 let mut angle = 0.0;
351 let angle_step = f32::two_pi() / segments as f32;
352 for i in 0..vertex_segments {
353 let mut x = cos(angle);
355 let mut y = -sin(angle);
356 let v1 = right * x + up * y;
357
358 angle += angle_step;
360 x = cos(angle);
361 y = -sin(angle);
362 let v2 = right * x + up * y;
363
364 points.push(v1);
365 tangents.push(v2 - v1);
366 bottom_points.push(points[i] - Vec3f::unit_y());
367 top_points.push(points[i] + Vec3f::unit_y());
368 }
369
370 for i in 0..vertex_segments {
376 let u = 0.5 + atan2(bottom_points[i].z, bottom_points[i].x) / f32::two_pi();
377 let u = if i == segments { 0.0 } else { u };
378 let bt = cross(tangents[i], points[i]);
379 vertices.push(Vertex3D{
380 position: bottom_points[i],
381 normal: points[i],
382 tangent: tangents[i],
383 bitangent: bt,
384 texcoord: Vec2f::new(u * 3.0, 0.0)
385 });
386 }
387
388 for i in 0..vertex_segments {
390 let u = 0.5 + atan2(top_points[i].z, top_points[i].x) / f32::two_pi();
391 let u = if i == segments { 0.0 } else { u };
392 let bt = cross(tangents[i], points[i]);
393 vertices.push(Vertex3D{
394 position: top_points[i],
395 normal: points[i],
396 tangent: tangents[i],
397 bitangent: bt,
398 texcoord: Vec2f::new(u * 3.0, 1.0)
399 });
400 }
401
402 for point in bottom_points.iter().take(segments) {
404 vertices.push(Vertex3D{
405 position: *point,
406 normal: -Vec3f::unit_y(),
407 tangent: Vec3f::unit_x(),
408 bitangent: Vec3f::unit_z(),
409 texcoord: Vec2f::new(point.x, point.z) * 0.5 + 0.5
410 });
411 }
412
413 for point in top_points.iter().take(segments) {
415 vertices.push(Vertex3D{
416 position: *point,
417 normal: Vec3f::unit_y(),
418 tangent: Vec3f::unit_x(),
419 bitangent: Vec3f::unit_z(),
420 texcoord: Vec2f::new(point.x, point.z) * 0.5 + 0.5
421 });
422 }
423
424 vertices.push(Vertex3D{
426 position: -Vec3f::unit_y(),
427 normal: -Vec3f::unit_y(),
428 tangent: Vec3f::unit_x(),
429 bitangent: Vec3f::unit_z(),
430 texcoord: Vec2f::point_five()
431 });
432 let centre_bottom = vertices.len()-1;
433
434 vertices.push(Vertex3D{
435 position: Vec3f::unit_y(),
436 normal: Vec3f::unit_y(),
437 tangent: Vec3f::unit_x(),
438 bitangent: Vec3f::unit_z(),
439 texcoord: Vec2f::point_five()
440 });
441 let centre_top = vertices.len()-1;
442
443 if smooth {
444
445 for i in 0..segments {
451 let bottom = i;
452 let top = i + vertex_segments;
453 let next = i + 1;
454 let top_next = i + 1 + vertex_segments;
455 indices.extend(vec![
456 bottom,
457 top,
458 next,
459 top,
460 top_next,
461 next
462 ]);
463 }
464
465 if cap {
466 for i in 0..segments {
468 let face_offset = vertex_segments * 2;
469 let face_current = face_offset + i;
470 let face_next = face_offset + (i + 1);
471 indices.extend(vec![
472 centre_bottom,
473 face_current,
474 face_next
475 ]);
476 }
477
478 for i in 0..segments {
480 let face_offset = vertex_segments * 3;
481 let face_current = face_offset + i;
482 let face_next = face_offset + (i + 1);
483 indices.extend(vec![
484 centre_top,
485 face_next,
486 face_current
487 ]);
488 }
489 }
490
491 (vertices, indices)
492 }
493 else {
494 let mut triangle_vertices = Vec::new();
496 for i in 0..segments {
497 let bottom = i;
498 let top = i + vertex_segments;
499 let next = i + 1;
500 let top_next = i + 1 + vertex_segments;
501
502 let face_index = triangle_vertices.len();
503 triangle_vertices.extend(vec![
504 vertices[bottom].clone(),
505 vertices[top].clone(),
506 vertices[next].clone(),
507 vertices[top].clone(),
508 vertices[top_next].clone(),
509 vertices[next].clone()
510 ]);
511
512 let v = face_index;
513 let n = get_triangle_normal(
514 triangle_vertices[v].position,
515 triangle_vertices[v+2].position,
516 triangle_vertices[v+1].position
517 );
518
519 for vertex in triangle_vertices.iter_mut().skip(face_index) {
521 vertex.normal = n;
522 }
523 }
524
525 if cap {
526 for i in 0..segments {
528 let face_offset = vertex_segments * 2;
529 let face_current = face_offset + i;
530 let face_next = face_offset + (i + 1);
531 triangle_vertices.extend(vec![
532 vertices[centre_bottom].clone(),
533 vertices[face_current].clone(),
534 vertices[face_next].clone(),
535 ]);
536 }
537
538 for i in 0..segments {
540 let face_offset = vertex_segments * 3;
541 let face_current = face_offset + i;
542 let face_next = face_offset + (i + 1);
543 triangle_vertices.extend(vec![
544 vertices[centre_top].clone(),
545 vertices[face_next].clone(),
546 vertices[face_current].clone(),
547 ]);
548 }
549 }
550
551 (vertices, Vec::new())
552 }
553}
554
555pub fn create_unit_quad_mesh<D: gfx::Device>(dev: &mut D) -> pmfx::Mesh<D> {
557 let vertices: Vec<Vertex2D> = vec![
559 Vertex2D {
560 position: vec2f(-1.0, -1.0),
561 texcoord: vec2f(0.0, 1.0),
562 },
563 Vertex2D {
564 position: vec2f(1.0, -1.0),
565 texcoord: vec2f(1.0, 1.0),
566 },
567 Vertex2D {
568 position: vec2f(1.0, 1.0),
569 texcoord: vec2f(1.0, 0.0),
570 },
571 Vertex2D {
572 position: vec2f(-1.0, 1.0),
573 texcoord: vec2f(0.0, 0.0),
574 }
575 ];
576
577 let indices: Vec<u16> = vec![
578 0, 2, 1, 2, 0, 3
579 ];
580
581 pmfx::Mesh {
582 vb: dev.create_buffer(&gfx::BufferInfo {
583 usage: gfx::BufferUsage::VERTEX,
584 cpu_access: gfx::CpuAccessFlags::NONE,
585 num_elements: 4,
586 format: gfx::Format::Unknown,
587 stride: std::mem::size_of::<Vertex2D>(),
588 initial_state: gfx::ResourceState::VertexConstantBuffer
589 },
590 Some(vertices.as_slice())
591 ).unwrap(),
592 ib: dev.create_buffer(&gfx::BufferInfo {
593 usage: gfx::BufferUsage::INDEX,
594 cpu_access: gfx::CpuAccessFlags::NONE,
595 num_elements: 6,
596 format: gfx::Format::R16u,
597 stride: std::mem::size_of::<u16>(),
598 initial_state: gfx::ResourceState::IndexBuffer
599 },
600 Some(indices.as_slice())
601 ).unwrap(),
602 num_indices: 6,
603 aabb_min: vec3f(-1.0, -1.0, 0.0),
604 aabb_max: vec3f( 1.0, 1.0, 0.0)
605 }
606}
607
608pub fn create_billboard_mesh<D: gfx::Device>(dev: &mut D) -> pmfx::Mesh<D> {
610 let vertices: Vec<Vertex3D> = vec![
612 Vertex3D {
614 position: vec3f(-1.0, -1.0, 0.0),
615 texcoord: vec2f(0.0, 1.0),
616 normal: vec3f(0.0, 0.0, 1.0),
617 tangent: vec3f(1.0, 0.0, 0.0),
618 bitangent: vec3f(0.0, 1.0, 0.0),
619 },
620 Vertex3D {
621 position: vec3f(1.0, -1.0, 0.0),
622 texcoord: vec2f(1.0, 1.0),
623 normal: vec3f(0.0, 0.0, 1.0),
624 tangent: vec3f(1.0, 0.0, 0.0),
625 bitangent: vec3f(0.0, 1.0, 0.0),
626 },
627 Vertex3D {
628 position: vec3f(1.0, 1.0, 0.0),
629 texcoord: vec2f(1.0, 0.0),
630 normal: vec3f(0.0, 0.0, 1.0),
631 tangent: vec3f(1.0, 0.0, 0.0),
632 bitangent: vec3f(0.0, 1.0, 0.0),
633 },
634 Vertex3D {
635 position: vec3f(-1.0, 1.0, 0.0),
636 texcoord: vec2f(0.0, 0.0),
637 normal: vec3f(0.0, 0.0, 1.0),
638 tangent: vec3f(1.0, 0.0, 0.0),
639 bitangent: vec3f(0.0, 1.0, 0.0),
640 }
641 ];
642
643 let indices: Vec<u16> = vec![
644 0, 2, 1, 2, 0, 3, ];
646
647 pmfx::Mesh {
648 vb: dev.create_buffer(&gfx::BufferInfo {
649 usage: gfx::BufferUsage::VERTEX,
650 cpu_access: gfx::CpuAccessFlags::NONE,
651 num_elements: 4,
652 format: gfx::Format::Unknown,
653 stride: std::mem::size_of::<Vertex3D>(),
654 initial_state: gfx::ResourceState::VertexConstantBuffer
655 },
656 Some(vertices.as_slice())
657 ).unwrap(),
658 ib: dev.create_buffer(&gfx::BufferInfo {
659 usage: gfx::BufferUsage::INDEX,
660 cpu_access: gfx::CpuAccessFlags::NONE,
661 num_elements: 6,
662 format: gfx::Format::R16u,
663 stride: std::mem::size_of::<u16>(),
664 initial_state: gfx::ResourceState::IndexBuffer
665 },
666 Some(indices.as_slice())
667 ).unwrap(),
668 num_indices: 6,
669 aabb_min: vec3f(-1.0, -1.0, 0.0),
670 aabb_max: vec3f( 1.0, 1.0, 0.0)
671 }
672}
673
674pub fn create_triangle_mesh<D: gfx::Device>(dev: &mut D) -> pmfx::Mesh<D> {
676 let vertices: Vec<Vertex3D> = vec![
678 Vertex3D {
680 position: vec3f(-1.0, -1.0, 0.0),
681 texcoord: vec2f(0.0, 1.0),
682 normal: vec3f(0.0, 0.0, 1.0),
683 tangent: vec3f(1.0, 0.0, 0.0),
684 bitangent: vec3f(0.0, 1.0, 0.0),
685 },
686 Vertex3D {
687 position: vec3f(1.0, -1.0, 0.0),
688 texcoord: vec2f(1.0, 1.0),
689 normal: vec3f(0.0, 0.0, 1.0),
690 tangent: vec3f(1.0, 0.0, 0.0),
691 bitangent: vec3f(0.0, 1.0, 0.0),
692 },
693 Vertex3D {
694 position: vec3f(0.0, 1.0, 0.0),
695 texcoord: vec2f(0.5, 0.0),
696 normal: vec3f(0.0, 0.0, 1.0),
697 tangent: vec3f(1.0, 0.0, 0.0),
698 bitangent: vec3f(0.0, 1.0, 0.0),
699 }
700 ];
701
702 let indices: Vec<u16> = vec![
703 0, 1, 2
704 ];
705
706 let aabb_min = vertices.iter().fold( Vec3f::max_value(), |acc, v| min(acc, v.position));
707 let aabb_max = vertices.iter().fold(-Vec3f::max_value(), |acc, v| max(acc, v.position));
708
709 pmfx::Mesh {
710 vb: dev.create_buffer(&gfx::BufferInfo {
711 usage: gfx::BufferUsage::VERTEX,
712 cpu_access: gfx::CpuAccessFlags::NONE,
713 num_elements: 3,
714 format: gfx::Format::Unknown,
715 stride: std::mem::size_of::<Vertex3D>(),
716 initial_state: gfx::ResourceState::VertexConstantBuffer
717 },
718 Some(vertices.as_slice())
719 ).unwrap(),
720 ib: dev.create_buffer(&gfx::BufferInfo {
721 usage: gfx::BufferUsage::INDEX,
722 cpu_access: gfx::CpuAccessFlags::NONE,
723 num_elements: 3,
724 format: gfx::Format::R16u,
725 stride: std::mem::size_of::<u16>(),
726 initial_state: gfx::ResourceState::IndexBuffer
727 },
728 Some(indices.as_slice())
729 ).unwrap(),
730 num_indices: 3,
731 aabb_min,
732 aabb_max
733 }
734}
735
736pub fn create_plane_mesh<D: gfx::Device>(dev: &mut D, subdivisions: u32) -> pmfx::Mesh<D> {
738 let start = vec3f(-1.0, 0.0, -1.0);
739 let increment = 2.0 / subdivisions as f32;
740
741 let mut pos = start;
742 let mut vertices = Vec::new();
743 let mut indices = Vec::new();
744
745 for _ in 0..subdivisions {
746 pos.x = start.x;
747 for _ in 0..subdivisions {
748 let quad_base_index = vertices.len();
750
751 vertices.extend(vec![
752 Vertex3D {
753 position: vec3f(pos.x, 0.0, pos.z),
754 texcoord: vec2f(0.0, 0.0),
755 normal: Vec3f::unit_y(),
756 tangent: vec3f(1.0, 0.0, 0.0),
757 bitangent: vec3f(0.0, 1.0, 0.0),
758 },
759 Vertex3D {
760 position: vec3f(pos.x + increment, 0.0, pos.z),
761 texcoord: vec2f(1.0, 0.0),
762 normal: Vec3f::unit_y(),
763 tangent: vec3f(1.0, 0.0, 0.0),
764 bitangent: vec3f(0.0, 1.0, 0.0),
765 },
766 Vertex3D {
767 position: vec3f(pos.x + increment, 0.0, pos.z + increment),
768 texcoord: vec2f(1.0, 1.0),
769 normal: Vec3f::unit_y(),
770 tangent: vec3f(1.0, 0.0, 0.0),
771 bitangent: vec3f(0.0, 1.0, 0.0),
772 },
773 Vertex3D {
774 position: vec3f(pos.x, 0.0, pos.z + increment),
775 texcoord: vec2f(0.0, 1.0),
776 normal: Vec3f::unit_y(),
777 tangent: vec3f(1.0, 0.0, 0.0),
778 bitangent: vec3f(0.0, 1.0, 0.0),
779 }
780 ]);
781
782 indices.extend(vec![
783 quad_base_index, quad_base_index + 1, quad_base_index + 2,
784 quad_base_index, quad_base_index + 2, quad_base_index + 3
785 ]);
786
787 pos.x += increment;
788 }
789 pos.z += increment;
790 }
791
792 create_mesh_3d(dev, vertices, indices)
793}
794
795pub fn create_tetrahedron_mesh<D: gfx::Device>(dev: &mut D) -> pmfx::Mesh<D> {
797 let pos = vec3f(0.0, -INV_PHI, 0.0);
798 let right = Vec3f::unit_x();
799 let up = Vec3f::unit_z();
800 let at = Vec3f::unit_y();
801 let angle_step = (f32::pi() * 2.0) / 3.0;
802 let tip = pos + at * sqrt(2.0); let mut base_positions = Vec::new();
806 let mut vertices = Vec::new();
807
808 let get_face_vertices = |p: Vec3f, np: Vec3f, tp: Vec3f| -> Vec<Vertex3D> {
810 let n = maths_rs::get_triangle_normal(p, np, tp);
811 let b = normalize(p - np);
812 let t = cross(n, b);
813 vec![
814 Vertex3D {
815 position: normalize(tp),
816 texcoord: vec2f(0.5, 0.0),
817 normal: n,
818 tangent: t,
819 bitangent: b,
820 },
821 Vertex3D {
822 position: normalize(np),
823 texcoord: vec2f(1.0, 1.0),
824 normal: n,
825 tangent: t,
826 bitangent: b,
827 },
828 Vertex3D {
829 position: normalize(p),
830 texcoord: vec2f(0.0, 1.0),
831 normal: n,
832 tangent: t,
833 bitangent: b,
834 }
835 ]
836 };
837
838 let mut a = 0.0;
840 for _ in 0..3 {
841 let x = f32::sin(a);
843 let y = f32::cos(a);
844 let p = pos + right * x + up * y;
845
846 a += angle_step;
848 let x2 = f32::sin(a);
849 let y2 = f32::cos(a);
850 let np = pos + right * x2 + up * y2;
851 let tp = tip;
852
853 base_positions.push(p);
854 vertices.extend(get_face_vertices(p , np, tp));
855 }
856
857 vertices.extend(get_face_vertices(base_positions[0], base_positions[2], base_positions[1]));
859
860 create_faceted_mesh_3d(dev, vertices)
862}
863
864pub fn cube_vertices() -> Vec<Vertex3D> {
865 vec![
866 Vertex3D {
868 position: vec3f(-1.0, -1.0, 1.0),
869 texcoord: vec2f(0.0, 1.0),
870 normal: vec3f(0.0, 0.0, 1.0),
871 tangent: vec3f(1.0, 0.0, 0.0),
872 bitangent: vec3f(0.0, 1.0, 0.0),
873 },
874 Vertex3D {
875 position: vec3f(1.0, -1.0, 1.0),
876 texcoord: vec2f(1.0, 1.0),
877 normal: vec3f(0.0, 0.0, 1.0),
878 tangent: vec3f(1.0, 0.0, 0.0),
879 bitangent: vec3f(0.0, 1.0, 0.0),
880 },
881 Vertex3D {
882 position: vec3f(1.0, 1.0, 1.0),
883 texcoord: vec2f(1.0, 0.0),
884 normal: vec3f(0.0, 0.0, 1.0),
885 tangent: vec3f(1.0, 0.0, 0.0),
886 bitangent: vec3f(0.0, 1.0, 0.0),
887 },
888 Vertex3D {
889 position: vec3f(-1.0, 1.0, 1.0),
890 texcoord: vec2f(0.0, 0.0),
891 normal: vec3f(0.0, 0.0, 1.0),
892 tangent: vec3f(1.0, 0.0, 0.0),
893 bitangent: vec3f(0.0, 1.0, 0.0),
894 },
895 Vertex3D {
897 position: vec3f(-1.0, -1.0, -1.0),
898 texcoord: vec2f(1.0, 1.0),
899 normal: vec3f(0.0, 0.0, -1.0),
900 tangent: vec3f(-1.0, 0.0, 0.0),
901 bitangent: vec3f(0.0, 1.0, 0.0),
902 },
903 Vertex3D {
904 position: vec3f(-1.0, 1.0, -1.0),
905 texcoord: vec2f(1.0, 0.0),
906 normal: vec3f(0.0, 0.0, -1.0),
907 tangent: vec3f(-1.0, 0.0, 0.0),
908 bitangent: vec3f(0.0, 1.0, 0.0),
909 },
910 Vertex3D {
911 position: vec3f(1.0, 1.0, -1.0),
912 texcoord: vec2f(0.0, 0.0),
913 normal: vec3f(0.0, 0.0, -1.0),
914 tangent: vec3f(-1.0, 0.0, 0.0),
915 bitangent: vec3f(0.0, 1.0, 0.0),
916 },
917 Vertex3D {
918 position: vec3f(1.0, -1.0, -1.0),
919 texcoord: vec2f(0.0, 1.0),
920 normal: vec3f(0.0, 0.0, -1.0),
921 tangent: vec3f(-1.0, 0.0, 0.0),
922 bitangent: vec3f(0.0, 1.0, 0.0),
923 },
924 Vertex3D {
926 position: vec3f(1.0, -1.0, -1.0),
927 texcoord: vec2f(0.0, 1.0),
928 normal: vec3f(1.0, 0.0, 0.0),
929 tangent: vec3f(0.0, 0.0, 1.0),
930 bitangent: vec3f(0.0, 1.0, 0.0),
931 },
932 Vertex3D {
933 position: vec3f(1.0, 1.0, -1.0),
934 texcoord: vec2f(0.0, 0.0),
935 normal: vec3f(1.0, 0.0, 0.0),
936 tangent: vec3f(0.0, 0.0, 1.0),
937 bitangent: vec3f(0.0, 1.0, 0.0),
938 },
939 Vertex3D {
940 position: vec3f(1.0, 1.0, 1.0),
941 texcoord: vec2f(1.0, 0.0),
942 normal: vec3f(1.0, 0.0, 0.0),
943 tangent: vec3f(0.0, 0.0, 1.0),
944 bitangent: vec3f(0.0, 1.0, 0.0),
945 },
946 Vertex3D {
947 position: vec3f(1.0, -1.0, 1.0),
948 texcoord: vec2f(1.0, 1.0),
949 normal: vec3f(1.0, 0.0, 0.0),
950 tangent: vec3f(0.0, 0.0, 1.0),
951 bitangent: vec3f(0.0, 1.0, 0.0),
952 },
953 Vertex3D {
955 position: vec3f(-1.0, -1.0, -1.0),
956 texcoord: vec2f(1.0, 1.0),
957 normal: vec3f(-1.0, 0.0, 0.0),
958 tangent: vec3f(0.0, 0.0, -1.0),
959 bitangent: vec3f(0.0, 1.0, 0.0),
960 },
961 Vertex3D {
962 position: vec3f(-1.0, -1.0, 1.0),
963 texcoord: vec2f(0.0, 1.0),
964 normal: vec3f(-1.0, 0.0, 0.0),
965 tangent: vec3f(0.0, 0.0, -1.0),
966 bitangent: vec3f(0.0, 1.0, 0.0),
967 },
968 Vertex3D {
969 position: vec3f(-1.0, 1.0, 1.0),
970 texcoord: vec2f(0.0, 0.0),
971 normal: vec3f(-1.0, 0.0, 0.0),
972 tangent: vec3f(0.0, 0.0, -1.0),
973 bitangent: vec3f(0.0, 1.0, 0.0),
974 },
975 Vertex3D {
976 position: vec3f(-1.0, 1.0, -1.0),
977 texcoord: vec2f(1.0, 0.0),
978 normal: vec3f(-1.0, 0.0, 0.0),
979 tangent: vec3f(0.0, 0.0, -1.0),
980 bitangent: vec3f(0.0, 1.0, 0.0),
981 },
982 Vertex3D {
984 position: vec3f(-1.0, 1.0, -1.0),
985 texcoord: vec2f(0.0, 1.0),
986 normal: vec3f(0.0, 1.0, 0.0),
987 tangent: vec3f(1.0, 0.0, 0.0),
988 bitangent: vec3f(0.0, 0.0, 1.0),
989 },
990 Vertex3D {
991 position: vec3f(-1.0, 1.0, 1.0),
992 texcoord: vec2f(0.0, 0.0),
993 normal: vec3f(0.0, 1.0, 0.0),
994 tangent: vec3f(1.0, 0.0, 0.0),
995 bitangent: vec3f(0.0, 0.0, 1.0),
996 },
997 Vertex3D {
998 position: vec3f(1.0, 1.0, 1.0),
999 texcoord: vec2f(1.0, 0.0),
1000 normal: vec3f(0.0, 1.0, 0.0),
1001 tangent: vec3f(1.0, 0.0, 0.0),
1002 bitangent: vec3f(0.0, 0.0, 1.0),
1003 },
1004 Vertex3D {
1005 position: vec3f(1.0, 1.0, -1.0),
1006 texcoord: vec2f(1.0, 1.0),
1007 normal: vec3f(0.0, 1.0, 0.0),
1008 tangent: vec3f(1.0, 0.0, 0.0),
1009 bitangent: vec3f(0.0, 0.0, 1.0),
1010 },
1011 Vertex3D {
1013 position: vec3f(-1.0, -1.0, -1.0),
1014 texcoord: vec2f(1.0, 0.0),
1015 normal: vec3f(0.0, -1.0, 0.0),
1016 tangent: vec3f(-1.0, 0.0, 0.0),
1017 bitangent: vec3f(0.0, 0.0, -1.0),
1018 },
1019 Vertex3D {
1020 position: vec3f(1.0, -1.0, -1.0),
1021 texcoord: vec2f(0.0, 0.0),
1022 normal: vec3f(0.0, -1.0, 0.0),
1023 tangent: vec3f(-1.0, 0.0, 0.0),
1024 bitangent: vec3f(0.0, 0.0, -1.0),
1025 },
1026 Vertex3D {
1027 position: vec3f(1.0, -1.0, 1.0),
1028 texcoord: vec2f(0.0, 1.0),
1029 normal: vec3f(0.0, -1.0, 0.0),
1030 tangent: vec3f(-1.0, 0.0, 0.0),
1031 bitangent: vec3f(0.0, 0.0, -1.0),
1032 },
1033 Vertex3D {
1034 position: vec3f(-1.0, -1.0, 1.0),
1035 texcoord: vec2f(1.0, 1.0),
1036 normal: vec3f(0.0, -1.0, 0.0),
1037 tangent: vec3f(-1.0, 0.0, 0.0),
1038 bitangent: vec3f(0.0, 0.0, -1.0),
1039 },
1040 ]
1041}
1042
1043pub fn create_cube_mesh<D: gfx::Device>(dev: &mut D) -> pmfx::Mesh<D> {
1045 let indices: Vec<usize> = vec![
1046 0, 2, 1, 2, 0, 3, 4, 6, 5, 6, 4, 7, 8, 10, 9, 10, 8, 11, 12, 14, 13, 14, 12, 15, 16, 18, 17, 18, 16, 19, 20, 22, 21, 22, 20, 23 ];
1053
1054 create_mesh_3d(dev, cube_vertices(), indices)
1055}
1056
1057pub fn create_octahedron_mesh<D: gfx::Device>(dev: &mut D) -> pmfx::Mesh<D> {
1059 let corner = [
1060 vec3f(-1.0, 0.0, -1.0),
1061 vec3f(-1.0, 0.0, 1.0),
1062 vec3f( 1.0, 0.0, 1.0),
1063 vec3f( 1.0, 0.0, -1.0)
1064 ];
1065
1066 let pc = sqrt(2.0);
1067 let top = vec3f(0.0, pc, 0.0);
1068 let bottom = vec3f(0.0, -pc, 0.0);
1069
1070 let yextent = [
1072 top,
1073 bottom
1074 ];
1075
1076 let mut vertices = Vec::new();
1077
1078 for i in 0..4 {
1079 let n = (i + 1) % 4;
1080
1081 for (j, yextent) in yextent.iter().enumerate() {
1083
1084 let mut t0 = corner[i];
1086 let t1 = corner[n];
1087 let mut t2 = *yextent;
1088
1089 let mut tc0 = vec2f(1.0, 1.0);
1091 let tc1 = vec2f(0.0, 1.0);
1092 let mut tc2 = vec2f(0.5, 0.0);
1093
1094 if j == 0 {
1096 std::mem::swap(&mut t0, &mut t2);
1097 std::mem::swap(&mut tc0, &mut tc2);
1098 }
1099
1100 let n = get_triangle_normal(t0, t2, t1);
1102 let b = normalize(t0 - t1);
1103 let t = cross(n, b);
1104
1105 let tri: Vec<Vertex3D> = vec![
1106 Vertex3D {
1107 position: t0,
1108 texcoord: tc0,
1109 normal: n,
1110 tangent: t,
1111 bitangent: b,
1112 },
1113 Vertex3D {
1114 position: t1,
1115 texcoord: tc1,
1116 normal: n,
1117 tangent: t,
1118 bitangent: b,
1119 },
1120 Vertex3D {
1121 position: t2,
1122 texcoord: tc2,
1123 normal: n,
1124 tangent: t,
1125 bitangent: b,
1126 }
1127 ];
1128 vertices.extend(tri);
1129 }
1130 }
1131
1132 create_faceted_mesh_3d(dev, vertices)
1133}
1134
1135fn dodecahedron_face_in_axis(axis: Vec3f, pos: Vec3f, start_angle: f32, recurse: bool) -> Vec<Vertex3D> {
1137 let (right, up, _) = basis_from_axis(axis);
1138 let angle_step = f32::pi() / 2.5;
1139
1140 let mut a = start_angle;
1141 let mut vertices = Vec::new();
1142
1143 let t2 = pos;
1145
1146 for _ in 0..5 {
1148 let x = f32::sin(a) * INV_PHI;
1149 let y = f32::cos(a) * INV_PHI;
1150 let t0 = pos + right * x + up * y;
1151 let uv0 = Vec2f::new(f32::sin(a), f32::cos(a));
1152
1153 a += angle_step;
1154 let x2 = f32::sin(a) * INV_PHI;
1155 let y2 = f32::cos(a) * INV_PHI;
1156 let t1 = pos + right * x2 + up * y2;
1157 let uv1 = Vec2f::new(f32::sin(a), f32::cos(a));
1158
1159 let n = get_triangle_normal(t0, t2, t1);
1160 let b = normalize(t0 - t1);
1161 let t = cross(n, b);
1162
1163 let tri = vec![
1164 Vertex3D {
1165 position: t0,
1166 texcoord: uv0 * 0.5 + 0.5,
1167 normal: n,
1168 tangent: t,
1169 bitangent: b,
1170 },
1171 Vertex3D {
1172 position: t1,
1173 texcoord: uv1 * 0.5 + 0.5,
1174 normal: n,
1175 tangent: t,
1176 bitangent: b,
1177 },
1178 Vertex3D {
1179 position: t2,
1180 texcoord: Vec2f::point_five(),
1181 normal: n,
1182 tangent: t,
1183 bitangent: b,
1184 }
1185 ];
1186 vertices.extend(tri);
1187
1188 if recurse {
1189 let half_gr = f32::phi() / 2.0;
1190 let internal_angle = 0.309017 * 1.5;
1191
1192 let ev = normalize(t1 - t0);
1193 let cp = normalize(cross(ev, axis));
1194 let mid = t0 + (t1 - t0) * 0.5;
1195
1196 let rx = f32::sin((f32::pi() * 2.0) + internal_angle) * INV_PHI;
1197 let ry = f32::cos((f32::pi() * 2.0) + internal_angle) * INV_PHI;
1198 let xp = mid + cp * rx + axis * ry;
1199 let xv = normalize(xp - mid);
1200
1201 let next_axis = normalize(cross(xv, ev));
1202 let face_vertices = dodecahedron_face_in_axis(next_axis, mid + xv * half_gr * INV_PHI, f32::pi() + start_angle, false);
1203 vertices.extend(face_vertices);
1204 }
1205 }
1206 vertices
1207}
1208
1209pub fn create_dodecahedron_mesh<D: gfx::Device>(dev: &mut D) -> pmfx::Mesh<D> {
1211 let h = f32::pi() * 0.8333333 * 0.5 * INV_PHI;
1212 let mut vertices = dodecahedron_face_in_axis(Vec3f::unit_y(), vec3f(0.0, -h, 0.0), 0.0, true);
1213 let bottom_vertices = dodecahedron_face_in_axis(-Vec3f::unit_y(), vec3f(0.0, h, 0.0), f32::pi(), true);
1214 vertices.extend(bottom_vertices);
1215 create_faceted_mesh_3d(dev, vertices)
1216}
1217
1218pub fn hemi_icosohedron(axis: Vec3f, pos: Vec3f, start_angle: f32, subdivisions: u32) -> Vec<Vertex3D> {
1220 let (right, up, at) = basis_from_axis(axis);
1221
1222 let tip = pos - at * INV_PHI;
1223 let dip = pos + at * 0.5 * 2.0;
1224
1225 let angle_step = f32::pi() / 2.5;
1226
1227 let mut a = start_angle;
1228 let mut vertices = Vec::new();
1229
1230 for _ in 0..5 {
1231 let x = f32::sin(a);
1232 let y = f32::cos(a);
1233 let p = pos + right * x + up * y;
1234
1235 a += angle_step;
1236 let x2 = f32::sin(a);
1237 let y2 = f32::cos(a);
1238 let np = pos + right * x2 + up * y2;
1239
1240 let n = get_triangle_normal(p, np, tip);
1241 let b = normalize(p - tip);
1242 let t = cross(n, b);
1243
1244 let tri = vec![
1245 Vertex3D {
1246 position: p,
1247 texcoord: Vec2f::new(0.0, 0.0),
1248 normal: n,
1249 tangent: t,
1250 bitangent: b,
1251 },
1252 Vertex3D {
1253 position: tip,
1254 texcoord: Vec2f::new(0.5, 1.0),
1255 normal: n,
1256 tangent: t,
1257 bitangent: b,
1258 },
1259 Vertex3D {
1260 position: np,
1261 texcoord: Vec2f::new(1.0, 0.0),
1262 normal: n,
1263 tangent: t,
1264 bitangent: b,
1265 }
1266 ];
1267 vertices.extend(subdivide_triangle(&tri[0], &tri[1], &tri[2], 0, subdivisions));
1268
1269 let side_dip = dip + cross(normalize(p-np), at);
1270
1271 let n = get_triangle_normal(p, side_dip, np);
1272 let b = normalize(p - np);
1273 let t = cross(n, b);
1274
1275 let tri = vec![
1276 Vertex3D {
1277 position: p,
1278 texcoord: Vec2f::new(0.0, 1.0),
1279 normal: n,
1280 tangent: t,
1281 bitangent: b,
1282 },
1283 Vertex3D {
1284 position: np,
1285 texcoord: Vec2f::new(1.0, 1.0),
1286 normal: n,
1287 tangent: t,
1288 bitangent: b,
1289 },
1290 Vertex3D {
1291 position: side_dip,
1292 texcoord: Vec2f::new(0.5, 0.0),
1293 normal: n,
1294 tangent: t,
1295 bitangent: b,
1296 }
1297 ];
1298 vertices.extend(subdivide_triangle(&tri[0], &tri[1], &tri[2], 0, subdivisions));
1299 }
1300 vertices
1301}
1302
1303pub fn create_icosahedron_mesh<D: gfx::Device>(dev: &mut D) -> pmfx::Mesh<D> {
1305 let mut vertices = hemi_icosohedron(Vec3f::unit_y(), Vec3f::unit_y() * 0.5, 0.0, 0);
1307 let bottom_vertices = hemi_icosohedron(-Vec3f::unit_y(), Vec3f::unit_y() * -0.5, f32::pi(), 0);
1308 vertices.extend(bottom_vertices);
1309 create_faceted_mesh_3d(dev, vertices)
1310}
1311
1312pub fn create_icosasphere_mesh<D: gfx::Device>(dev: &mut D, subdivisions: u32) -> pmfx::Mesh<D> {
1314 let mut vertices = hemi_icosohedron(Vec3f::unit_y(), Vec3f::unit_y() * 0.5, 0.0, subdivisions);
1316 let bottom_vertices = hemi_icosohedron(-Vec3f::unit_y(), Vec3f::unit_y() * -0.5, f32::pi(), subdivisions);
1317 vertices.extend(bottom_vertices);
1318
1319 for v in &mut vertices {
1321 v.position = normalize(v.position);
1322 }
1323
1324 for i in (0..vertices.len()).step_by(3) {
1326 let n = get_triangle_normal(vertices[i].position, vertices[i + 2].position, vertices[i + 1].position);
1327 let b = normalize(vertices[i].position - vertices[i + 2].position);
1328 let t = cross(n, b);
1329 for v in vertices.iter_mut().skip(i).take(3) {
1330 v.normal = n;
1331 v.bitangent = b;
1332 v.tangent = t;
1333 }
1334 }
1335
1336 create_faceted_mesh_3d(dev, vertices)
1337}
1338
1339pub fn create_sphere_mesh_truncated<D: gfx::Device>(dev: &mut D, segments: usize, hemi_segments: usize, cap: bool) -> pmfx::Mesh<D> {
1343 let (vertices, indices) = create_sphere_vertices(segments, 0, hemi_segments, cap);
1344 create_mesh_3d(dev, vertices, indices)
1345}
1346
1347pub fn create_sphere_mesh<D: gfx::Device>(dev: &mut D, segments: usize) -> pmfx::Mesh<D> {
1349 create_sphere_mesh_truncated(dev, segments, segments, false)
1350}
1351
1352pub fn create_prism_mesh<D: gfx::Device>(dev: &mut D, segments: usize, smooth: bool, cap: bool, height: f32, taper: f32) -> pmfx::Mesh<D> {
1355 let axis = Vec3f::unit_y();
1356 let right = Vec3f::unit_x();
1357 let up = cross(axis, right);
1358 let right = cross(axis, up);
1359
1360 let mut vertices = Vec::new();
1361 let mut points = Vec::new();
1362 let mut bottom_points = Vec::new();
1363 let mut top_points = Vec::new();
1364 let mut tangents = Vec::new();
1365 let mut indices = Vec::new();
1366
1367 let vertex_segments = segments + 1;
1369
1370 let mut angle = 0.0;
1372 let angle_step = f32::two_pi() / segments as f32;
1373 for i in 0..vertex_segments {
1374 let mut x = cos(angle);
1376 let mut y = -sin(angle);
1377 let v1 = right * x + up * y;
1378
1379 angle += angle_step;
1381 x = cos(angle);
1382 y = -sin(angle);
1383 let v2 = right * x + up * y;
1384
1385 points.push(v1);
1386 tangents.push(v2 - v1);
1387
1388 bottom_points.push(points[i] - Vec3f::unit_y() * height);
1389 top_points.push(points[i] * taper + Vec3f::unit_y() * height);
1390 }
1391
1392 for i in 0..vertex_segments {
1398 let u = 0.5 + atan2(bottom_points[i].z, bottom_points[i].x) / f32::two_pi();
1399 let u = if i == segments { 0.0 } else { u };
1400 let bt = cross(points[i], tangents[i]);
1401 vertices.push(Vertex3D{
1402 position: bottom_points[i],
1403 normal: points[i],
1404 tangent: tangents[i],
1405 bitangent: bt,
1406 texcoord: Vec2f::new((1.0 - u) * 3.0, 1.0)
1407 });
1408 }
1409
1410 for i in 0..vertex_segments {
1412 let u = 0.5 + atan2(top_points[i].z, top_points[i].x) / f32::two_pi();
1413 let u = if i == segments { 0.0 } else { u };
1414 let bt = cross(points[i], tangents[i]);
1415 vertices.push(Vertex3D{
1416 position: top_points[i],
1417 normal: points[i],
1418 tangent: tangents[i],
1419 bitangent: bt,
1420 texcoord: Vec2f::new((1.0 - u) * 3.0, 0.0)
1421 });
1422 }
1423
1424 for point in bottom_points.iter().take(vertex_segments) {
1426 vertices.push(Vertex3D{
1427 position: *point,
1428 normal: -Vec3f::unit_y(),
1429 tangent: Vec3f::unit_x(),
1430 bitangent: Vec3f::unit_z(),
1431 texcoord: Vec2f::new(-point.x, -point.z) * 0.5 + 0.5
1432 });
1433 }
1434
1435 for point in top_points.iter().take(vertex_segments) {
1437 vertices.push(Vertex3D{
1438 position: *point,
1439 normal: Vec3f::unit_y(),
1440 tangent: Vec3f::unit_x(),
1441 bitangent: Vec3f::unit_z(),
1442 texcoord: Vec2f::new(point.x, -point.z) * 0.5 + 0.5
1443 });
1444 }
1445
1446 vertices.push(Vertex3D{
1448 position: -Vec3f::unit_y() * height,
1449 normal: -Vec3f::unit_y(),
1450 tangent: Vec3f::unit_x(),
1451 bitangent: Vec3f::unit_z(),
1452 texcoord: Vec2f::point_five()
1453 });
1454 let centre_bottom = vertices.len()-1;
1455
1456 vertices.push(Vertex3D{
1457 position: Vec3f::unit_y() * height,
1458 normal: Vec3f::unit_y(),
1459 tangent: Vec3f::unit_x(),
1460 bitangent: Vec3f::unit_z(),
1461 texcoord: Vec2f::point_five()
1462 });
1463 let centre_top = vertices.len()-1;
1464
1465 if smooth {
1466
1467 for i in 0..segments {
1473 let bottom = i;
1474 let top = i + vertex_segments;
1475 let next = i + 1;
1476 let top_next = i + 1 + vertex_segments;
1477 indices.extend(vec![
1478 bottom,
1479 top,
1480 next,
1481 top,
1482 top_next,
1483 next
1484 ]);
1485 }
1486
1487 if cap {
1488 for i in 0..segments {
1490 let face_offset = vertex_segments * 2;
1491 let face_current = face_offset + i;
1492 let face_next = face_offset + (i + 1);
1493 indices.extend(vec![
1494 centre_bottom,
1495 face_current,
1496 face_next
1497 ]);
1498 }
1499
1500 for i in 0..segments {
1502 let face_offset = vertex_segments * 3;
1503 let face_current = face_offset + i;
1504 let face_next = face_offset + (i + 1);
1505 indices.extend(vec![
1506 centre_top,
1507 face_next,
1508 face_current
1509 ]);
1510 }
1511 }
1512
1513 create_mesh_3d(dev, vertices, indices)
1514 }
1515 else {
1516 let mut triangle_vertices = Vec::new();
1517 if taper != 1.0 {
1518 for i in 0..segments {
1520 let bottom = i;
1521 let top = i + vertex_segments;
1522 let next = i + 1;
1523 let top_next = i + 1 + vertex_segments;
1524
1525 let mut mid = vertices[bottom].clone();
1527 mid.position = (
1528 vertices[bottom].position +
1529 vertices[top].position +
1530 vertices[next].position +
1531 vertices[top_next].position
1532 ) * 0.25;
1533
1534 mid.texcoord = splat2f(0.5);
1535
1536 let face_index = triangle_vertices.len();
1537 triangle_vertices.extend(vec![
1538 vertices[bottom].clone(),
1539 vertices[top].clone(),
1540 mid.clone(),
1541
1542 vertices[top].clone(),
1543 vertices[top_next].clone(),
1544 mid.clone(),
1545
1546 vertices[bottom].clone(),
1547 mid.clone(),
1548 vertices[next].clone(),
1549
1550 vertices[next].clone(),
1551 mid,
1552 vertices[top_next].clone(),
1553 ]);
1554
1555 let v = face_index;
1556 let n = get_triangle_normal(
1557 triangle_vertices[v].position,
1558 triangle_vertices[v+2].position,
1559 triangle_vertices[v+1].position
1560 );
1561
1562 for vertex in triangle_vertices.iter_mut().skip(face_index) {
1564 vertex.normal = n;
1565 }
1566
1567 let top_u = 0.0;
1568 let top_next_u = 1.0;
1569
1570 triangle_vertices[face_index].texcoord.x = 0.0;
1571 triangle_vertices[face_index + 1].texcoord.x = top_u;
1572 triangle_vertices[face_index + 3].texcoord.x = top_u;
1573 triangle_vertices[face_index + 4].texcoord.x = top_next_u;
1574 triangle_vertices[face_index + 6].texcoord.x = 0.0;
1575 triangle_vertices[face_index + 8].texcoord.x = 1.0;
1576 triangle_vertices[face_index + 9].texcoord.x = 1.0;
1577 triangle_vertices[face_index + 11].texcoord.x = top_next_u;
1578 }
1579 }
1580 else {
1581 for i in 0..segments {
1583 let bottom = i;
1584 let top = i + vertex_segments;
1585 let next = i + 1;
1586 let top_next = i + 1 + vertex_segments;
1587
1588 let face_index = triangle_vertices.len();
1589 triangle_vertices.extend(vec![
1590 vertices[bottom].clone(),
1591 vertices[top].clone(),
1592 vertices[next].clone(),
1593 vertices[top].clone(),
1594 vertices[top_next].clone(),
1595 vertices[next].clone()
1596 ]);
1597
1598 let v = face_index;
1599 let n = get_triangle_normal(
1600 triangle_vertices[v].position,
1601 triangle_vertices[v+2].position,
1602 triangle_vertices[v+1].position
1603 );
1604
1605 for vertex in triangle_vertices.iter_mut().skip(face_index) {
1607 vertex.normal = n;
1608 }
1609 }
1610 }
1611
1612 if cap {
1613 for i in 0..segments {
1615 let face_offset = vertex_segments * 2;
1616 let face_current = face_offset + i;
1617 let face_next = face_offset + (i + 1);
1618 triangle_vertices.extend(vec![
1619 vertices[centre_bottom].clone(),
1620 vertices[face_current].clone(),
1621 vertices[face_next].clone(),
1622 ]);
1623 }
1624
1625 for i in 0..segments {
1627 let face_offset = vertex_segments * 3;
1628 let face_current = face_offset + i;
1629 let face_next = face_offset + (i + 1);
1630 triangle_vertices.extend(vec![
1631 vertices[centre_top].clone(),
1632 vertices[face_next].clone(),
1633 vertices[face_current].clone(),
1634 ]);
1635 }
1636 }
1637
1638 create_faceted_mesh_3d(dev, triangle_vertices)
1639 }
1640}
1641
1642pub fn create_cylinder_mesh<D: gfx::Device>(dev: &mut D, segments: usize) -> pmfx::Mesh<D> {
1644 create_prism_mesh(dev, segments, true, true, 1.0, 1.0)
1645}
1646
1647pub fn create_cube_subdivision_mesh<D: gfx::Device>(dev: &mut D, subdivisions: u32) -> pmfx::Mesh<D> {
1649 let vertices = cube_vertices();
1650
1651 let mut subdiv_vertices = Vec::new();
1652 for i in (0..vertices.len()).step_by(4) {
1653 let sub = subdivide_quad(&vertices[i], &vertices[i+1], &vertices[i+2], &vertices[i+3], 0, subdivisions);
1654 subdiv_vertices.extend(sub);
1655 }
1656
1657 for v in &mut subdiv_vertices {
1659 v.position = normalize(v.position);
1660 v.normal = v.position;
1661 }
1662
1663 let mut indices = Vec::new();
1671 for i in (0..subdiv_vertices.len()).step_by(4) {
1672 let quad = (i / 4) % 4;
1673 if subdivisions > 0 {
1674 if quad == 0 {
1675 indices.extend(vec![
1676 i, i + 3, i + 1,
1677 i + 1, i + 3, i + 2
1678 ]);
1679 }
1680 else if quad == 3 {
1681 indices.extend(vec![
1682 i, i + 3, i + 2,
1683 i, i + 2, i + 1
1684 ]);
1685 }
1686 else if quad == 2 {
1687 indices.extend(vec![
1688 i, i + 3, i + 1,
1689 i + 1, i + 3, i + 2
1690 ]);
1691 }
1692 else {
1693 indices.extend(vec![
1694 i, i + 2, i + 1,
1695 i, i + 3, i + 2
1696 ]);
1697 }
1698 }
1699 else {
1700 indices.extend(vec![
1701 i, i + 2, i + 1, i + 2, i, i + 3
1702 ]);
1703 }
1704 }
1705
1706 create_mesh_3d(dev, subdiv_vertices, indices)
1707}
1708
1709pub fn create_pyramid_mesh<D: gfx::Device>(dev: &mut D, segments: usize, smooth: bool, cap: bool) -> pmfx::Mesh<D> {
1711 let axis = Vec3f::unit_y();
1712 let right = Vec3f::unit_x();
1713 let up = cross(axis, right);
1714 let right = cross(axis, up);
1715 let tip = Vec3f::unit_y();
1716 let base = -Vec3f::unit_y();
1717
1718 let mut segment_vertices = Vec::new();
1719 let mut vertices = Vec::new();
1720
1721 let vertex_segments = segments + 1;
1723
1724 let mut angle = 0.0;
1726 let angle_step = f32::two_pi() / segments as f32;
1727 for i in 0..vertex_segments {
1728 let mut x = cos(angle);
1730 let mut y = -sin(angle);
1731 let v1 = right * x + up * y;
1732
1733 angle += angle_step;
1735 x = cos(angle);
1736 y = -sin(angle);
1737 let v2 = right * x + up * y;
1738
1739 let u = 0.5 + atan2(v1.z, v2.x) / f32::two_pi();
1741 let u = if i == segments { 0.0 } else { u };
1742
1743 let n = cross(normalize(v2 - v1), normalize(tip - v1));
1745 let t = v2 - v1;
1746 let bt = cross(n, t);
1747
1748 segment_vertices.push(
1749 Vertex3D {
1750 position: v1 - Vec3f::unit_y(),
1751 texcoord: vec2f((1.0 - u) * 3.0, 1.0),
1752 normal: n,
1753 tangent: t,
1754 bitangent: bt
1755 });
1756 }
1757
1758 if smooth {
1764 for i in 0..segments {
1765 let mid = segment_vertices[i].texcoord.x + (segment_vertices[i + 1].texcoord.x - segment_vertices[i].texcoord.x) * 0.5;
1766 vertices.extend(vec![
1767 segment_vertices[i].clone(),
1768 Vertex3D {
1769 position: tip,
1770 texcoord: vec2f(mid, 0.0),
1771 normal: segment_vertices[i].normal,
1772 tangent: segment_vertices[i].tangent,
1773 bitangent: segment_vertices[i].bitangent,
1774 },
1775 segment_vertices[i + 1].clone(),
1776 ])
1777 }
1778 }
1779 else {
1780 for i in 0..segments {
1781
1782 let t0 = segment_vertices[i].position;
1783 let t1 = tip;
1784 let t2 = segment_vertices[i + 1].position;
1785 let n = get_triangle_normal(t0, t2, t1);
1786
1787 vertices.extend(vec![
1788 Vertex3D {
1789 position: t0,
1790 texcoord: vec2f(0.0, 1.0),
1791 normal: n,
1792 tangent: segment_vertices[i].tangent,
1793 bitangent: segment_vertices[i].bitangent,
1794 },
1795 Vertex3D {
1796 position: t1,
1797 texcoord: vec2f(0.5, 0.0),
1798 normal: n,
1799 tangent: segment_vertices[i].tangent,
1800 bitangent: segment_vertices[i].bitangent,
1801 },
1802 Vertex3D {
1803 position: t2,
1804 texcoord: vec2f(1.0, 1.0),
1805 normal: n,
1806 tangent: segment_vertices[i].tangent,
1807 bitangent: segment_vertices[i].bitangent,
1808 }
1809 ])
1810 }
1811 }
1812
1813 if cap {
1815 for i in 0..segments {
1816 vertices.extend(vec![
1817 Vertex3D {
1818 position: segment_vertices[i].position,
1819 texcoord: segment_vertices[i].position.xz() * 0.5 + 0.5,
1820 normal: -Vec3f::unit_y(),
1821 tangent: Vec3f::unit_x(),
1822 bitangent: Vec3f::unit_z(),
1823 },
1824 Vertex3D {
1825 position: segment_vertices[i + 1].position,
1826 texcoord: segment_vertices[i + 1].position.xz() * 0.5 + 0.5,
1827 normal: -Vec3f::unit_y(),
1828 tangent: Vec3f::unit_x(),
1829 bitangent: Vec3f::unit_z(),
1830 },
1831 Vertex3D {
1832 position: base,
1833 texcoord: Vec2f::point_five(),
1834 normal: -Vec3f::unit_y(),
1835 tangent: Vec3f::unit_x(),
1836 bitangent: Vec3f::unit_z(),
1837 }
1838 ])
1839 }
1840 }
1841
1842 create_faceted_mesh_3d(dev, vertices)
1843}
1844
1845pub fn create_cone_mesh<D: gfx::Device>(dev: &mut D, segments: usize) -> pmfx::Mesh<D> {
1847 create_pyramid_mesh(dev, segments, true, true)
1848}
1849
1850pub fn create_capsule_mesh<D: gfx::Device>(dev: &mut D, segments: usize) -> pmfx::Mesh<D> {
1852 let mut vertices = Vec::new();
1853 let mut indices = Vec::new();
1854
1855 let offset = 0.5 + (1.0 / segments as f32);
1856
1857 let mut weld_positions = Vec::new();
1859 let weld_size = (1.0 / segments as f32) * 0.1;
1860
1861 let (mut v0, i0) = create_sphere_vertices(segments, 0, segments/2, false);
1863
1864 for v in &mut v0 {
1865 v.position += vec3f(0.0, -offset, 0.0);
1866 weld_positions.push(v.position);
1867 }
1868
1869 let (mut v1, mut i1) = create_sphere_vertices(segments, segments/2, segments, false);
1871 for v in &mut v1 {
1872 v.position += vec3f(0.0, offset, 0.0);
1873 weld_positions.push(v.position);
1874 }
1875
1876 let base = v0.len();
1878 for i in &mut i1 {
1879 *i += base;
1880 }
1881
1882 let (mut v2, mut i2) = create_prism_vertices(segments, true, false);
1884 for v in &mut v2 {
1885 v.position *= vec3f(1.0, 0.5, 1.0);
1886 v.texcoord.y = 1.0 - v.texcoord.y;
1887
1888 for w in &weld_positions {
1890 if dist2(v.position, *w) < weld_size {
1891 v.position = *w;
1892 break;
1893 }
1894 }
1895 }
1896
1897 let base = base + v1.len();
1899 for i in &mut i2 {
1900 *i += base;
1901 }
1902
1903 vertices.extend(v0);
1904 indices.extend(i0);
1905 vertices.extend(v1);
1906 indices.extend(i1);
1907 vertices.extend(v2);
1908 indices.extend(i2);
1909
1910 create_mesh_3d(dev, vertices, indices)
1911}
1912
1913pub fn create_tourus_mesh<D: gfx::Device>(dev: &mut D, segments: usize) -> pmfx::Mesh<D> {
1915 let mut segment_vertices = Vec::new();
1916 let mut vertices = Vec::new();
1917
1918 let vertex_segments = segments + 1;
1920 let radius = 0.5;
1921
1922 let mut hangle = -f32::pi();
1924 let angle_step = f32::two_pi() / segments as f32;
1925 for i in 0..vertex_segments + 1 {
1926 let x = cos(hangle);
1927 let y = -sin(hangle);
1928
1929 hangle += angle_step;
1930 let x2 = cos(hangle);
1931 let y2 = -sin(hangle);
1932
1933 let p = vec3f(x, 0.0, y);
1934 let np = vec3f(x2, 0.0, y2);
1935
1936 let at = normalize(np - p);
1937 let up = Vec3f::unit_y();
1938 let right = cross(up, at);
1939
1940 let mut vangle = -f32::pi();
1941 for j in 0..vertex_segments {
1942 let vx = cos(vangle) * radius;
1943 let vy = -sin(vangle) * radius;
1944 let vv = p + vx * up + vy * right;
1945
1946 let n = normalize(vx * up + vy * right);
1947 let t = right;
1948 let bt = up;
1949
1950 let u = 0.5 + atan2(y, x) / f32::two_pi();
1951 let u = if i == 0 { 1.0 } else { u };
1952
1953 let v = 0.5 + atan2(vy, vx) / f32::two_pi();
1954 let v = if j == 0 { 1.0 } else { v };
1955
1956 segment_vertices.extend(vec![
1957 Vertex3D {
1958 position: vv,
1959 normal: n,
1960 tangent: t,
1961 bitangent: bt,
1962 texcoord: vec2f(1.0 - u, 1.0 - v) * 3.0
1963 }
1964 ]);
1965
1966 vangle += angle_step;
1967 }
1968 }
1969
1970 for i in 0..segments {
1971 for j in 0..segments {
1972 let base = (i * vertex_segments) + j;
1973 let next_loop = base + 1;
1974 let next_base = ((i + 1) * vertex_segments) + j;
1975 let next_next_loop = next_base + 1;
1976 vertices.extend(vec![
1977 segment_vertices[base].clone(),
1978 segment_vertices[next_base].clone(),
1979 segment_vertices[next_loop].clone(),
1980 segment_vertices[next_base].clone(),
1981 segment_vertices[next_next_loop].clone(),
1982 segment_vertices[next_loop].clone(),
1983 ]);
1984 }
1985 }
1986
1987 create_faceted_mesh_3d(dev, vertices)
1988}
1989
1990pub fn create_helix_mesh<D: gfx::Device>(dev: &mut D, segments: usize, coils: usize) -> pmfx::Mesh<D> {
1992 let mut segment_vertices = Vec::new();
1993 let mut vertices = Vec::new();
1994
1995 let vertex_segments = segments + 1;
1997 let radius = 0.5;
1998
1999 let mut hangle = -f32::pi();
2001 let angle_step = f32::two_pi() / segments as f32;
2002 let height_step = 1.5 / segments as f32;
2003 let scale = 2.0 / coils as f32;
2004
2005 let mut h = -height_step * (segments * 2) as f32;
2006 for _ in 0..coils {
2007 let mut uv_hangle = -f32::pi();
2008 for i in 0..vertex_segments {
2009 let x = cos(hangle);
2010 let y = -sin(hangle);
2011
2012 let uvx = cos(uv_hangle);
2013 let uvy = -sin(uv_hangle);
2014 uv_hangle += angle_step;
2015
2016 hangle += angle_step;
2017 let x2 = cos(hangle);
2018 let y2 = -sin(hangle);
2019
2020 let p = vec3f(x, h, y);
2021 let np = vec3f(x2, h + angle_step, y2);
2022
2023 let at = normalize(np - p);
2024 let up = Vec3f::unit_y();
2025 let right = cross(up, at);
2026
2027 let mut vangle = -f32::pi();
2028 for j in 0..vertex_segments {
2029 let vx = cos(vangle) * radius;
2030 let vy = -sin(vangle) * radius;
2031 let vv = p + vx * up + vy * right;
2032
2033 let n = normalize(vx * up + vy * right);
2034 let t = right;
2035 let bt = up;
2036
2037 let u = 0.5 + atan2(uvy, uvx) / f32::two_pi();
2038 let u = if i == 0 { 1.0 } else { u };
2039
2040 let v = 0.5 + atan2(vy, vx) / f32::two_pi();
2041 let v = if j == 0 { 1.0 } else { v };
2042
2043 segment_vertices.extend(vec![
2044 Vertex3D {
2045 position: vv * scale,
2046 normal: n,
2047 tangent: t,
2048 bitangent: bt,
2049 texcoord: vec2f(u, 1.0 - v) * 3.0
2050 }
2051 ]);
2052
2053 vangle += angle_step;
2054 }
2055
2056 h += height_step;
2057
2058 if i == segments {
2060 hangle -= angle_step;
2061 h -= height_step;
2062 }
2063 }
2064 }
2065
2066 for k in 0..coils {
2067 for i in 0..segments {
2068 for j in 0..segments {
2069 let coil_base = vertex_segments * segments * k;
2070 let base = coil_base + (i * vertex_segments) + j;
2071 let next_loop = base + 1;
2072 let next_base = coil_base + ((i + 1) * vertex_segments) + j;
2073 let next_next_loop = next_base + 1;
2074 vertices.extend(vec![
2075 segment_vertices[base].clone(),
2076 segment_vertices[next_base].clone(),
2077 segment_vertices[next_loop].clone(),
2078 segment_vertices[next_base].clone(),
2079 segment_vertices[next_next_loop].clone(),
2080 segment_vertices[next_loop].clone(),
2081 ]);
2082 }
2083 }
2084 }
2085
2086 let mut mid_pos = Vec3f::zero();
2088 for vertex in segment_vertices.iter().take(segments) {
2089 mid_pos += vertex.position;
2090 }
2091 mid_pos /= segments as f32;
2092
2093 for j in 0..segments {
2094 let p0 = segment_vertices[j + 1].position;
2095 let p1 = segment_vertices[j].position;
2096 vertices.extend(vec![
2097 Vertex3D {
2098 position: p0,
2099 normal: -Vec3f::unit_z(),
2100 texcoord: normalize(mid_pos.xy() - p0.xy()) * 0.5 + 0.5,
2101 tangent: Vec3f::unit_x(),
2102 bitangent: Vec3f::unit_y()
2103 },
2104 Vertex3D {
2105 position: mid_pos,
2106 normal: -Vec3f::unit_z(),
2107 texcoord: vec2f(0.5, 0.5),
2108 tangent: Vec3f::unit_x(),
2109 bitangent: Vec3f::unit_y()
2110 },
2111 Vertex3D {
2112 position: p1,
2113 normal: -Vec3f::unit_z(),
2114 texcoord: normalize(mid_pos.xy() - p1.xy()) * 0.5 + 0.5,
2115 tangent: Vec3f::unit_x(),
2116 bitangent: Vec3f::unit_y()
2117 }
2118 ]);
2119 }
2120
2121 let offset = vertex_segments * segments * coils;
2123 let mut mid_pos = Vec3f::zero();
2124 for j in 0..segments {
2125 mid_pos += segment_vertices[offset + j].position;
2126 }
2127 mid_pos /= segments as f32;
2128
2129 for j in 0..segments {
2130 let p0 = segment_vertices[offset + j].position;
2131 let p1 = segment_vertices[offset + j + 1].position;
2132 vertices.extend(vec![
2133 Vertex3D {
2134 position: p0,
2135 normal: Vec3f::unit_z(),
2136 texcoord: normalize(mid_pos.xy() - p0.xy()) * 0.5 + 0.5,
2137 tangent: Vec3f::unit_x(),
2138 bitangent: Vec3f::unit_y()
2139 },
2140 Vertex3D {
2141 position: mid_pos,
2142 normal: Vec3f::unit_z(),
2143 texcoord: vec2f(0.5, 0.5),
2144 tangent: Vec3f::unit_x(),
2145 bitangent: Vec3f::unit_y()
2146 },
2147 Vertex3D {
2148 position: p1,
2149 normal: Vec3f::unit_z(),
2150 texcoord: normalize(mid_pos.xy() - p1.xy()) * 0.5 + 0.5,
2151 tangent: Vec3f::unit_x(),
2152 bitangent: Vec3f::unit_y()
2153 }
2154 ]);
2155 }
2156
2157 create_faceted_mesh_3d(dev, vertices)
2158}
2159
2160pub fn create_chamfer_cube_mesh<D: gfx::Device>(dev: &mut D, radius: f32, segments: usize) -> pmfx::Mesh<D> {
2162 let inset = 1.0 - radius;
2163 let edge_uv_scale = radius;
2164
2165 let mut vertices = cube_vertices();
2167
2168 let insets = [
2169 vec3f(inset, inset, 1.0),
2170 vec3f(1.0, inset, inset),
2171 vec3f(inset, 1.0, inset),
2172 ];
2173
2174 for (i, vertex) in vertices.iter_mut().enumerate() {
2175 let face = i / 8;
2176 vertex.position *= insets[face];
2177 }
2178
2179 let mut indices: Vec<usize> = vec![
2180 0, 2, 1, 2, 0, 3, 4, 6, 5, 6, 4, 7, 8, 10, 9, 10, 8, 11, 12, 14, 13, 14, 12, 15, 16, 18, 17, 18, 16, 19, 20, 22, 21, 22, 20, 23, ];
2187
2188 let join_edge = |edge_indices: [usize; 4], clamp_axis: usize, vertices: &mut Vec<Vertex3D>, indices: &mut Vec<usize>| {
2190 let bottom_start = vertices[edge_indices[0]].position;
2191 let top_start = vertices[edge_indices[1]].position;
2192 let top_end = vertices[edge_indices[2]].position;
2193 let bottom_end = vertices[edge_indices[3]].position;
2194 let fsegments = segments as f32;
2195 let base_index = vertices.len();
2196
2197 let pivot = bottom_start - vertices[edge_indices[0]].normal * radius;
2198 let top_pivot = top_start - vertices[edge_indices[0]].normal * radius;
2199
2200 for i in 0..segments+1 {
2201 let cur = (1.0 / fsegments) * i as f32;
2202 let v = cur * edge_uv_scale;
2203
2204 let lv0 = lerp(bottom_start, bottom_end, cur);
2206 let lv1 = lerp(top_start, top_end, cur);
2207
2208 let cur = if cur > 0.5 {
2210 1.0 - cur
2211 }
2212 else {
2213 cur
2214 };
2215
2216 let mut p0 = lerp(chebyshev_normalize(lv0), lv0, cur);
2218 let mut p1 = lerp(chebyshev_normalize(lv1), lv1, cur);
2219
2220 p0[clamp_axis] = bottom_start[clamp_axis];
2222 p1[clamp_axis] = top_start[clamp_axis];
2223
2224 let n = normalize(p0 - pivot);
2225 let t = normalize(top_pivot - pivot);
2226 let bt = cross(n, t);
2227
2228 vertices.extend(
2229 vec![
2230 Vertex3D {
2231 position: pivot + normalize(p0 - pivot) * radius,
2232 normal: n,
2233 tangent: t,
2234 bitangent: bt,
2235 texcoord: vec2f(0.0, v)
2236 },
2237 Vertex3D {
2238 position: top_pivot + normalize(p1 - top_pivot) * radius,
2239 normal: n,
2240 tangent: t,
2241 bitangent: bt,
2242 texcoord: vec2f(1.0, v)
2243 }
2244 ]
2245 );
2246 }
2247
2248 for i in 0..segments {
2249 let strip_base = base_index + i * 2;
2250 indices.extend(vec![
2251 strip_base, strip_base + 1, strip_base + 3,
2252 strip_base, strip_base + 3, strip_base + 2
2253 ]);
2254 }
2255 };
2256
2257 join_edge([1, 2, 10, 11], 1, &mut vertices, &mut indices); join_edge([8, 9, 6, 7], 1, &mut vertices, &mut indices); join_edge([4, 5, 12, 15], 1, &mut vertices, &mut indices); join_edge([13, 14, 0, 3], 1, &mut vertices, &mut indices); let ft_loop_start = vertices.len();
2265 join_edge([2, 3, 17, 18], 0, &mut vertices, &mut indices); let rt_loop_start = vertices.len();
2268 join_edge([9, 10, 19, 18], 2, &mut vertices, &mut indices); let bt_loop_start = vertices.len();
2271 join_edge([5, 6, 16, 19], 0, &mut vertices, &mut indices); let lt_loop_start = vertices.len();
2274 join_edge([14, 15, 16, 17], 2, &mut vertices, &mut indices); let fb_loop_start = vertices.len();
2278 join_edge([0, 1, 22, 23], 0, &mut vertices, &mut indices); let rb_loop_start = vertices.len();
2281 join_edge([11, 8, 22, 21], 2, &mut vertices, &mut indices); let bb_loop_start = vertices.len();
2284 join_edge([7, 4, 21, 20], 0, &mut vertices, &mut indices); let lb_loop_start = vertices.len();
2287 join_edge([12, 13, 20, 23], 2, &mut vertices, &mut indices); let join_corner = |start_loop_start: usize, end_loop_start: usize, vertices: &mut Vec<Vertex3D>, indices: &mut Vec<usize>| {
2290 let base_index = vertices.len();
2291 let fsegments = segments as f32;
2292 let centre = vertices[start_loop_start].position - vertices[start_loop_start].normal * radius;
2293
2294 for j in 0..segments+1 {
2295 let joffset = j * 2;
2296 let start = vertices[start_loop_start + joffset].position;
2297 let end = vertices[end_loop_start + 1 + joffset].position;
2298 let v = (1.0 / fsegments) * j as f32;
2299
2300 for i in 0..segments+1 {
2301 let u = (1.0 / fsegments) * i as f32;
2302 let next = (1.0 / fsegments) * (i+1) as f32;
2303
2304 let lv0 = lerp(start, end, u);
2305 let lv1 = lerp(start, end, next);
2306
2307 let p = centre + normalize(lv0 - centre) * radius;
2308 let nextp = centre + normalize(lv1 - centre) * radius;
2309
2310 let n = normalize(lv0 - centre);
2311 let mut t = normalize(p - nextp);
2312
2313 if j > segments - 1 {
2314 t = Vec3f::unit_x();
2315 }
2316 let bt = cross(n, t);
2317
2318 vertices.extend(vec![
2319 Vertex3D {
2320 position: p,
2321 normal: n,
2322 tangent: t,
2323 bitangent: bt,
2324 texcoord: vec2f(u, v) * edge_uv_scale
2325 },
2326 ]);
2327 }
2328 }
2329
2330 for j in 0..segments {
2331 let ycur = base_index + j * (segments+1);
2332 let ynext = base_index + (j+1) * (segments+1);
2333 for i in 0..segments {
2334 let xcur = ycur + i;
2335 let xnext = ynext + i;
2336 indices.extend(vec![
2337 xcur, xnext, xcur + 1,
2338 xnext, xnext+1, xcur + 1
2339 ]);
2340 }
2341 }
2342 };
2343
2344 join_corner(ft_loop_start, rt_loop_start, &mut vertices, &mut indices);
2345 join_corner(rt_loop_start, bt_loop_start, &mut vertices, &mut indices);
2346 join_corner(bt_loop_start, lt_loop_start, &mut vertices, &mut indices);
2347 join_corner(lt_loop_start, ft_loop_start, &mut vertices, &mut indices);
2348 join_corner(rb_loop_start, fb_loop_start, &mut vertices, &mut indices);
2349 join_corner(bb_loop_start, rb_loop_start, &mut vertices, &mut indices);
2350 join_corner(lb_loop_start, bb_loop_start, &mut vertices, &mut indices);
2351 join_corner(fb_loop_start, lb_loop_start, &mut vertices, &mut indices);
2352
2353 create_mesh_3d(dev, vertices, indices)
2354}
2355
2356#[allow(clippy::too_many_arguments)]
2360pub fn create_tube_prism_mesh<D: gfx::Device>(
2361 dev: &mut D, segments: usize, trunc_start: usize, trunc_end: usize, smooth: bool, cap: bool, height: f32, thickness: f32, taper: f32) -> pmfx::Mesh<D> {
2362 let axis = Vec3f::unit_y();
2363 let right = Vec3f::unit_x();
2364 let up = cross(axis, right);
2365 let right = cross(axis, up);
2366
2367 let vertex_segments = segments + 1;
2369
2370 let prism_vertices = |radius: f32, flip: f32| -> (Vec<Vertex3D>, Vec<Vertex3D>) {
2371 let mut vertices = Vec::new();
2372 let mut cap_vertices = Vec::new();
2373 let mut points = Vec::new();
2374 let mut bottom_points = Vec::new();
2375 let mut top_points = Vec::new();
2376 let mut tangents = Vec::new();
2377
2378 let mut angle = 0.0;
2380 let angle_step = f32::two_pi() / segments as f32;
2381 for i in 0..vertex_segments {
2382 let mut x = cos(angle);
2384 let mut y = -sin(angle);
2385 let v1 = right * x + up * y;
2386
2387 angle += angle_step;
2389 x = cos(angle);
2390 y = -sin(angle);
2391 let v2 = right * x + up * y;
2392
2393 points.push(v1 * radius);
2394 tangents.push(v2 - v1);
2395
2396 bottom_points.push(points[i] - Vec3f::unit_y() * height);
2397 top_points.push(points[i] * taper + Vec3f::unit_y() * height);
2398 }
2399
2400 for i in 0..vertex_segments {
2402 let u = 0.5 + atan2(bottom_points[i].z, bottom_points[i].x) / f32::two_pi();
2403 let u = if i == segments { 0.0 } else { u };
2404 let bt = cross(tangents[i], points[i]);
2405 vertices.push(Vertex3D{
2406 position: bottom_points[i],
2407 normal: points[i] * flip,
2408 tangent: tangents[i],
2409 bitangent: bt,
2410 texcoord: Vec2f::new(u * 3.0, 0.0)
2411 });
2412 }
2413
2414 for i in 0..vertex_segments {
2416 let u = 0.5 + atan2(top_points[i].z, top_points[i].x) / f32::two_pi();
2417 let u = if i == segments { 0.0 } else { u };
2418 let bt = cross(tangents[i], points[i]);
2419 vertices.push(Vertex3D{
2420 position: top_points[i],
2421 normal: points[i] * flip,
2422 tangent: tangents[i],
2423 bitangent: bt,
2424 texcoord: Vec2f::new(u * 3.0, 1.0)
2425 });
2426 }
2427
2428 for point in bottom_points.iter().take(vertex_segments) {
2430 cap_vertices.push(Vertex3D{
2431 position: point.xyz(),
2432 normal: -Vec3f::unit_y(),
2433 tangent: Vec3f::unit_x(),
2434 bitangent: Vec3f::unit_z(),
2435 texcoord: point.xz() * 0.5 + 0.5
2436 });
2437 }
2438
2439 for point in top_points.iter().take(vertex_segments) {
2441 cap_vertices.push(Vertex3D{
2442 position: point.xyz(),
2443 normal: Vec3f::unit_y(),
2444 tangent: Vec3f::unit_x(),
2445 bitangent: Vec3f::unit_z(),
2446 texcoord: point.xz() * 0.5 + 0.5
2447 });
2448 }
2449
2450 (vertices, cap_vertices)
2451 };
2452
2453 let end_cap = |loop_start: usize, v: &Vec<Vertex3D>, inner_offset: usize, flip: f32| -> Vec<Vertex3D> {
2454 let bottom = loop_start;
2456 let top = loop_start + vertex_segments;
2457 let inner_bottom = bottom + inner_offset;
2458 let inner_top = top + inner_offset;
2459
2460 let mut verts = vec![
2461 v[bottom].clone(),
2462 v[top].clone(),
2463 v[inner_bottom].clone(),
2464 v[inner_top].clone(),
2465 ];
2466
2467 let b = normalize(verts[1].position - verts[0].position);
2468 let t = normalize(verts[2].position - verts[0].position);
2469 let n = cross(b, t) * flip;
2470
2471 for v in &mut verts {
2472 v.normal = n;
2473 v.tangent = t;
2474 v.bitangent = b;
2475 }
2476
2477 verts[0].texcoord = Vec2f::zero();
2478 verts[1].texcoord = vec2f(0.0, 1.0);
2479 verts[2].texcoord = vec2f(1.0 - thickness, 0.0);
2480 verts[3].texcoord = vec2f(1.0 - thickness, 1.0);
2481
2482 verts
2483 };
2484
2485 let (outer_vertices, outer_cap_vertices) = prism_vertices(1.0, 1.0);
2486 let (inner_vertices, inner_cap_vertices) = prism_vertices(thickness, -1.0);
2487
2488 if smooth {
2489 let mut indices = Vec::new();
2490 let mut vertices = Vec::new();
2491
2492 vertices.extend(outer_vertices);
2493
2494 let outer_cap_offset = vertices.len();
2495 vertices.extend(outer_cap_vertices);
2496
2497 let inner_offset = vertices.len();
2498 vertices.extend(inner_vertices);
2499
2500 let inner_cap_offset = vertices.len();
2501 vertices.extend(inner_cap_vertices);
2502
2503 for i in trunc_start..trunc_end {
2505 let bottom = i;
2506 let top = i + vertex_segments;
2507 let next = i + 1;
2508 let top_next = i + 1 + vertex_segments;
2509
2510 indices.extend(vec![
2512 bottom,
2513 top,
2514 next,
2515 top,
2516 top_next,
2517 next
2518 ]);
2519
2520 indices.extend(vec![
2522 bottom + inner_offset,
2523 next + inner_offset,
2524 top + inner_offset,
2525 top + inner_offset,
2526 next + inner_offset,
2527 top_next + inner_offset,
2528 ]);
2529
2530 if cap {
2532 let inner_bottom = bottom + inner_cap_offset;
2533 let inner_top = top + inner_cap_offset;
2534 let inner_top_next = top_next + inner_cap_offset;
2535 let inner_bottom_next = next + inner_cap_offset;
2536
2537 let outer_bottom = bottom + outer_cap_offset;
2538 let outer_top = top + outer_cap_offset;
2539 let outer_top_next = top_next + outer_cap_offset;
2540 let outer_bottom_next = next + outer_cap_offset;
2541
2542 indices.extend(vec![
2543 outer_top,
2544 inner_top,
2545 inner_top_next,
2546 outer_top,
2547 inner_top_next,
2548 outer_top_next
2549 ]);
2550
2551 indices.extend(vec![
2552 inner_bottom,
2553 outer_bottom,
2554 outer_bottom_next,
2555 inner_bottom,
2556 outer_bottom_next,
2557 inner_bottom_next
2558 ]);
2559 }
2560 }
2561
2562 if trunc_start != 0 || trunc_end != segments {
2564 let start_verts = end_cap(trunc_start, &vertices, inner_offset, 1.0);
2565 let start_offset = vertices.len();
2566 vertices.extend(start_verts);
2567
2568 indices.extend(vec![
2569 start_offset,
2570 start_offset + 3,
2571 start_offset + 1,
2572 start_offset,
2573 start_offset + 2,
2574 start_offset + 3,
2575 ]);
2576
2577 let end_verts = end_cap(trunc_end, &vertices, inner_offset, -1.0);
2578 let end_offset = vertices.len();
2579 vertices.extend(end_verts);
2580
2581 indices.extend(vec![
2583 end_offset,
2584 end_offset + 1,
2585 end_offset + 3,
2586 end_offset,
2587 end_offset + 3,
2588 end_offset + 2,
2589 ]);
2590 }
2591
2592 create_mesh_3d(dev, vertices, indices)
2593 }
2594 else {
2595 let mut triangle_vertices = Vec::new();
2597 for i in trunc_start..trunc_end {
2598 let bottom = i;
2599 let top = i + vertex_segments;
2600 let next = i + 1;
2601 let top_next = i + 1 + vertex_segments;
2602
2603 let face_index = triangle_vertices.len();
2604 triangle_vertices.extend(vec![
2605 outer_vertices[bottom].clone(),
2606 outer_vertices[top].clone(),
2607 outer_vertices[next].clone(),
2608 outer_vertices[top].clone(),
2609 outer_vertices[top_next].clone(),
2610 outer_vertices[next].clone()
2611 ]);
2612
2613 let v = face_index;
2614 let n = get_triangle_normal(
2615 triangle_vertices[v].position,
2616 triangle_vertices[v+2].position,
2617 triangle_vertices[v+1].position
2618 );
2619
2620 for vertex in triangle_vertices.iter_mut().skip(face_index) {
2622 vertex.normal = n;
2623 }
2624 }
2625
2626 for i in trunc_start..trunc_end {
2627 let bottom = i;
2628 let top = i + vertex_segments;
2629 let next = i + 1;
2630 let top_next = i + 1 + vertex_segments;
2631
2632 let face_index = triangle_vertices.len();
2633 triangle_vertices.extend(vec![
2634 inner_vertices[bottom].clone(),
2635 inner_vertices[next].clone(),
2636 inner_vertices[top].clone(),
2637 inner_vertices[top].clone(),
2638 inner_vertices[next].clone(),
2639 inner_vertices[top_next].clone()
2640 ]);
2641
2642 let v = face_index;
2643 let n = get_triangle_normal(
2644 triangle_vertices[v].position,
2645 triangle_vertices[v+2].position,
2646 triangle_vertices[v+1].position,
2647 );
2648
2649 for vertex in triangle_vertices.iter_mut().skip(face_index) {
2651 vertex.normal = n;
2652 }
2653 }
2654
2655 if cap {
2657 for i in trunc_start..trunc_end {
2658 let bottom = i;
2659 let top = i + vertex_segments;
2660 let next = i + 1;
2661 let top_next = i + 1 + vertex_segments;
2662
2663 triangle_vertices.extend(vec![
2664 outer_cap_vertices[top].clone(),
2665 inner_cap_vertices[top].clone(),
2666 inner_cap_vertices[top_next].clone(),
2667 outer_cap_vertices[top].clone(),
2668 inner_cap_vertices[top_next].clone(),
2669 outer_cap_vertices[top_next].clone()
2670 ]);
2671
2672 triangle_vertices.extend(vec![
2673 inner_cap_vertices[bottom].clone(),
2674 outer_cap_vertices[bottom].clone(),
2675 outer_cap_vertices[next].clone(),
2676 inner_cap_vertices[bottom].clone(),
2677 outer_cap_vertices[next].clone(),
2678 inner_cap_vertices[next].clone()
2679 ]);
2680 }
2681 }
2682
2683 if trunc_start != 0 || trunc_end != segments {
2685 let mut vertices = outer_vertices.to_vec();
2686 let inner_offset = vertices.len();
2687 vertices.extend(inner_vertices);
2688
2689 let start_verts = end_cap(trunc_start, &vertices, inner_offset, 1.0);
2690 triangle_vertices.extend(vec![
2691 start_verts[0].clone(),
2692 start_verts[3].clone(),
2693 start_verts[1].clone(),
2694 start_verts[0].clone(),
2695 start_verts[2].clone(),
2696 start_verts[3].clone(),
2697 ]);
2698
2699 let end_verts = end_cap(trunc_end, &vertices, inner_offset, -1.0);
2700 triangle_vertices.extend(vec![
2701 end_verts[0].clone(),
2702 end_verts[1].clone(),
2703 end_verts[3].clone(),
2704 end_verts[0].clone(),
2705 end_verts[3].clone(),
2706 end_verts[2].clone(),
2707 ]);
2708 }
2709
2710 create_faceted_mesh_3d(dev, triangle_vertices)
2711 }
2712}
2713
2714fn cubic_interpolate(p1: Vec3f, p2: Vec3f, p3: Vec3f, p4: Vec3f, t: f32) -> Vec3f {
2715 p1 * (1.0 - t) * (1.0 - t) * (1.0 - t) +
2716 p2 * 3.0 * t * (1.0 - t) * (1.0 - t) +
2717 p3 * 3.0 * t * t * (1.0 - t) +
2718 p4 * t * t * t
2719}
2720
2721fn cubic_tangent(p1: Vec3f, p2: Vec3f, p3: Vec3f, p4: Vec3f, t: f32) -> Vec3f {
2722 p1 * (-1.0 + 2.0 * t - t * t) +
2723 p2 * (1.0 - 4.0 * t + 3.0 * t * t) +
2724 p3 * (2.0 * t - 3.0 * t * t) +
2725 p4 * (t * t)
2726}
2727
2728pub fn create_teapot_mesh<D: gfx::Device>(dev: &mut D, tessellation: usize) -> pmfx::Mesh<D> {
2730 struct TeapotPatch {
2732 mirror_z: bool,
2733 indices: [u32; 16]
2734 }
2735
2736 let patches = vec![
2737 TeapotPatch {
2739 mirror_z: true,
2740 indices: [
2741 102, 103, 104, 105, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
2742 ]
2743 },
2744
2745 TeapotPatch {
2747 mirror_z: true,
2748 indices: [
2749 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27
2750 ]
2751 },
2752 TeapotPatch {
2753 mirror_z: true,
2754 indices: [
2755 24, 25, 26, 27, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40
2756 ]
2757 },
2758
2759 TeapotPatch {
2761 mirror_z: true,
2762 indices: [
2763 96, 96, 96, 96, 97, 98, 99, 100, 101, 101, 101, 101, 0, 1, 2, 3
2764 ]
2765 },
2766 TeapotPatch {
2767 mirror_z: true,
2768 indices: [
2769 0, 1, 2, 3, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117
2770 ]
2771 },
2772
2773 TeapotPatch {
2775 mirror_z: false,
2776 indices: [
2777 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56
2778 ]
2779 },
2780 TeapotPatch {
2781 mirror_z: false,
2782 indices: [
2783 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 28, 65, 66, 67
2784 ]
2785 },
2786
2787 TeapotPatch {
2789 mirror_z: false,
2790 indices: [
2791 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83
2792 ]
2793 },
2794 TeapotPatch {
2795 mirror_z: false,
2796 indices: [
2797 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95
2798 ]
2799 },
2800
2801 TeapotPatch {
2803 mirror_z: true,
2804 indices: [
2805 118, 118, 118, 118, 124, 122, 119, 121, 123, 126, 125, 120, 40, 39, 38, 37
2806 ]
2807 }
2808 ];
2809
2810 let control_points = vec![
2811 vec3f(0.0, 0.345, -0.05),
2812 vec3f(-0.028, 0.345, -0.05),
2813 vec3f(-0.05, 0.345, -0.028),
2814 vec3f(-0.05, 0.345, -0.0),
2815 vec3f(0.0, 0.3028125, -0.334375),
2816 vec3f(-0.18725, 0.3028125, -0.334375),
2817 vec3f(-0.334375, 0.3028125, -0.18725),
2818 vec3f(-0.334375, 0.3028125, -0.0),
2819 vec3f(0.0, 0.3028125, -0.359375),
2820 vec3f(-0.20125, 0.3028125, -0.359375),
2821 vec3f(-0.359375, 0.3028125, -0.20125),
2822 vec3f(-0.359375, 0.3028125, -0.0),
2823 vec3f(0.0, 0.27, -0.375),
2824 vec3f(-0.21, 0.27, -0.375),
2825 vec3f(-0.375, 0.27, -0.21),
2826 vec3f(-0.375, 0.27, -0.0),
2827 vec3f(0.0, 0.13875, -0.4375),
2828 vec3f(-0.245, 0.13875, -0.4375),
2829 vec3f(-0.4375, 0.13875, -0.245),
2830 vec3f(-0.4375, 0.13875, -0.0),
2831 vec3f(0.0, 0.007499993, -0.5),
2832 vec3f(-0.28, 0.007499993, -0.5),
2833 vec3f(-0.5, 0.007499993, -0.28),
2834 vec3f(-0.5, 0.007499993, -0.0),
2835 vec3f(0.0, -0.105, -0.5),
2836 vec3f(-0.28, -0.105, -0.5),
2837 vec3f(-0.5, -0.105, -0.28),
2838 vec3f(-0.5, -0.105, -0.0),
2839 vec3f(0.0, -0.105, 0.5),
2840 vec3f(0.0, -0.2175, -0.5),
2841 vec3f(-0.28, -0.2175, -0.5),
2842 vec3f(-0.5, -0.2175, -0.28),
2843 vec3f(-0.5, -0.2175, -0.0),
2844 vec3f(0.0, -0.27375, -0.375),
2845 vec3f(-0.21, -0.27375, -0.375),
2846 vec3f(-0.375, -0.27375, -0.21),
2847 vec3f(-0.375, -0.27375, -0.0),
2848 vec3f(0.0, -0.2925, -0.375),
2849 vec3f(-0.21, -0.2925, -0.375),
2850 vec3f(-0.375, -0.2925, -0.21),
2851 vec3f(-0.375, -0.2925, -0.0),
2852 vec3f(0.0, 0.17625, 0.4),
2853 vec3f(-0.075, 0.17625, 0.4),
2854 vec3f(-0.075, 0.2325, 0.375),
2855 vec3f(0.0, 0.2325, 0.375),
2856 vec3f(0.0, 0.17625, 0.575),
2857 vec3f(-0.075, 0.17625, 0.575),
2858 vec3f(-0.075, 0.2325, 0.625),
2859 vec3f(0.0, 0.2325, 0.625),
2860 vec3f(0.0, 0.17625, 0.675),
2861 vec3f(-0.075, 0.17625, 0.675),
2862 vec3f(-0.075, 0.2325, 0.75),
2863 vec3f(0.0, 0.2325, 0.75),
2864 vec3f(0.0, 0.12, 0.675),
2865 vec3f(-0.075, 0.12, 0.675),
2866 vec3f(-0.075, 0.12, 0.75),
2867 vec3f(0.0, 0.12, 0.75),
2868 vec3f(0.0, 0.06375, 0.675),
2869 vec3f(-0.075, 0.06375, 0.675),
2870 vec3f(-0.075, 0.007499993, 0.75),
2871 vec3f(0.0, 0.007499993, 0.75),
2872 vec3f(0.0, -0.04875001, 0.625),
2873 vec3f(-0.075, -0.04875001, 0.625),
2874 vec3f(-0.075, -0.09562501, 0.6625),
2875 vec3f(0.0, -0.09562501, 0.6625),
2876 vec3f(-0.075, -0.105, 0.5),
2877 vec3f(-0.075, -0.18, 0.475),
2878 vec3f(0.0, -0.18, 0.475),
2879 vec3f(0.0, 0.02624997, -0.425),
2880 vec3f(-0.165, 0.02624997, -0.425),
2881 vec3f(-0.165, -0.18, -0.425),
2882 vec3f(0.0, -0.18, -0.425),
2883 vec3f(0.0, 0.02624997, -0.65),
2884 vec3f(-0.165, 0.02624997, -0.65),
2885 vec3f(-0.165, -0.12375, -0.775),
2886 vec3f(0.0, -0.12375, -0.775),
2887 vec3f(0.0, 0.195, -0.575),
2888 vec3f(-0.0625, 0.195, -0.575),
2889 vec3f(-0.0625, 0.17625, -0.6),
2890 vec3f(0.0, 0.17625, -0.6),
2891 vec3f(0.0, 0.27, -0.675),
2892 vec3f(-0.0625, 0.27, -0.675),
2893 vec3f(-0.0625, 0.27, -0.825),
2894 vec3f(0.0, 0.27, -0.825),
2895 vec3f(0.0, 0.28875, -0.7),
2896 vec3f(-0.0625, 0.28875, -0.7),
2897 vec3f(-0.0625, 0.2934375, -0.88125),
2898 vec3f(0.0, 0.2934375, -0.88125),
2899 vec3f(0.0, 0.28875, -0.725),
2900 vec3f(-0.0375, 0.28875, -0.725),
2901 vec3f(-0.0375, 0.298125, -0.8625),
2902 vec3f(0.0, 0.298125, -0.8625),
2903 vec3f(0.0, 0.27, -0.7),
2904 vec3f(-0.0375, 0.27, -0.7),
2905 vec3f(-0.0375, 0.27, -0.8),
2906 vec3f(0.0, 0.27, -0.8),
2907 vec3f(0.0, 0.4575, -0.0),
2908 vec3f(0.0, 0.4575, -0.2),
2909 vec3f(-0.1125, 0.4575, -0.2),
2910 vec3f(-0.2, 0.4575, -0.1125),
2911 vec3f(-0.2, 0.4575, -0.0),
2912 vec3f(0.0, 0.3825, -0.0),
2913 vec3f(0.0, 0.27, -0.35),
2914 vec3f(-0.196, 0.27, -0.35),
2915 vec3f(-0.35, 0.27, -0.196),
2916 vec3f(-0.35, 0.27, -0.0),
2917 vec3f(0.0, 0.3075, -0.1),
2918 vec3f(-0.056, 0.3075, -0.1),
2919 vec3f(-0.1, 0.3075, -0.056),
2920 vec3f(-0.1, 0.3075, -0.0),
2921 vec3f(0.0, 0.3075, -0.325),
2922 vec3f(-0.182, 0.3075, -0.325),
2923 vec3f(-0.325, 0.3075, -0.182),
2924 vec3f(-0.325, 0.3075, -0.0),
2925 vec3f(0.0, 0.27, -0.325),
2926 vec3f(-0.182, 0.27, -0.325),
2927 vec3f(-0.325, 0.27, -0.182),
2928 vec3f(-0.325, 0.27, -0.0),
2929 vec3f(0.0, -0.33, -0.0),
2930 vec3f(-0.1995, -0.33, -0.35625),
2931 vec3f(0.0, -0.31125, -0.375),
2932 vec3f(0.0, -0.33, -0.35625),
2933 vec3f(-0.35625, -0.33, -0.1995),
2934 vec3f(-0.375, -0.31125, -0.0),
2935 vec3f(-0.35625, -0.33, -0.0),
2936 vec3f(-0.21, -0.31125, -0.375),
2937 vec3f(-0.375, -0.31125, -0.21),
2938 ];
2939
2940 let create_patch_indices = |tessellation: usize, is_mirrored: bool, index_offset: usize| -> Vec<usize> {
2941 let stride = tessellation + 1;
2942 let mut indices = Vec::new();
2943 for i in 0..tessellation {
2944 for j in 0..tessellation {
2945 let mut arr = [
2946 i * stride + j,
2947 (i + 1) * stride + j,
2948 (i + 1) * stride + j + 1,
2949
2950 i * stride + j,
2951 (i + 1) * stride + j + 1,
2952 i * stride + j + 1,
2953 ];
2954
2955 if is_mirrored {
2956 arr.reverse();
2957 }
2958
2959 for ii in arr {
2960 indices.push(ii + index_offset)
2961 }
2962 }
2963 }
2964 indices
2965 };
2966
2967 let create_patch_vertices = |patch: Vec<Vec3f>, tessellation: usize, is_mirrored: bool| -> Vec<Vertex3D> {
2968 let mut vertices = Vec::new();
2969 for i in 0..tessellation+1 {
2970 let u = i as f32 / tessellation as f32;
2971 for j in 0..tessellation+1 {
2972 let v = j as f32 / tessellation as f32;
2973
2974 let p1 = cubic_interpolate(patch[0], patch[1], patch[2], patch[3], u);
2976 let p2 = cubic_interpolate(patch[4], patch[5], patch[6], patch[7], u);
2977 let p3 = cubic_interpolate(patch[8], patch[9], patch[10], patch[11], u);
2978 let p4 = cubic_interpolate(patch[12], patch[13], patch[14], patch[15], u);
2979
2980 let pos = cubic_interpolate(p1, p2, p3, p4, v);
2983
2984 let q1 = cubic_interpolate(patch[0], patch[4], patch[8], patch[12], v);
2987 let q2 = cubic_interpolate(patch[1], patch[5], patch[9], patch[13], v);
2988 let q3 = cubic_interpolate(patch[2], patch[6], patch[10], patch[14], v);
2989 let q4 = cubic_interpolate(patch[3], patch[7], patch[11], patch[15], v);
2990
2991 let mut tangent1 = cubic_tangent(p1, p2, p3, p4, v);
2992 let mut tangent2 = cubic_tangent(q1, q2, q3, q4, u);
2993 let mut normal = cross(tangent1, tangent2);
2994
2995 if is_mirrored {
2996 normal = -normal;
2997 }
2998
2999 if approx(normal, Vec3f::zero(), 0.001) {
3001 normal = Vec3f::unit_y();
3002 tangent1 = Vec3f::unit_x();
3003 tangent2 = Vec3f::unit_z();
3004 if pos.y < 0.0 {
3005 normal *= -1.0;
3006 tangent1 *= -1.0;
3007 }
3008 }
3009
3010 let uv = Vec2f {
3011 x: if is_mirrored { 1.0 - u } else { u },
3012 y: v
3013 };
3014
3015 vertices.push(Vertex3D {
3016 position: pos,
3017 texcoord: uv,
3018 normal: normalize(normal),
3019 tangent: tangent1,
3020 bitangent: tangent2
3021 });
3022 }
3023 }
3024 vertices
3025 };
3026
3027 let tessalate_patch = |patch: &TeapotPatch, tesselation: usize, scale: Vec3f, is_mirrored: bool, index_offset: usize| -> (Vec<Vertex3D>, Vec<usize>) {
3028
3029 let mut patch_verts = Vec::new();
3030 for i in 0..16 {
3031 patch_verts.push(control_points[patch.indices[i] as usize] * scale * 2.0);
3032 }
3033
3034 (create_patch_vertices(patch_verts, tesselation, is_mirrored), create_patch_indices(tesselation, is_mirrored, index_offset))
3035 };
3036
3037 let mut vertices = Vec::new();
3038 let mut indices = Vec::new();
3039 let mut lid_index_offset = 0;
3040 let mut spout_index_offset = 0;
3041
3042 for (ii, patch) in patches.iter().enumerate() {
3043 if ii == 4 {
3045 lid_index_offset = vertices.len();
3046 }
3047 else if ii == 8 {
3048 spout_index_offset = vertices.len();
3049 }
3050
3051 let (patch_vertices, patch_indices) = tessalate_patch(patch, tessellation, Vec3f::one(), false, vertices.len());
3052 vertices.extend(patch_vertices);
3053 indices.extend(patch_indices);
3054
3055 let (patch_vertices, patch_indices) = tessalate_patch(patch, tessellation, vec3f(-1.0, 1.0, 1.0), true, vertices.len());
3056 vertices.extend(patch_vertices);
3057 indices.extend(patch_indices);
3058
3059 if patch.mirror_z {
3060 let (patch_vertices, patch_indices) = tessalate_patch(patch, tessellation, vec3f(1.0, 1.0, -1.0), true, vertices.len());
3061 vertices.extend(patch_vertices);
3062 indices.extend(patch_indices);
3063
3064 let (patch_vertices, patch_indices) = tessalate_patch(patch, tessellation, vec3f(-1.0, 1.0, -1.0), false, vertices.len());
3065 vertices.extend(patch_vertices);
3066 indices.extend(patch_indices);
3067 }
3068 }
3069
3070 let stride = tessellation+1;
3072 for i in 0..tessellation {
3073 for q in 0..4 {
3075 let v = i + q * stride;
3076 let lid = lid_index_offset + tessellation + v * stride;
3077 let rim = v * stride;
3078 let lid_next = lid_index_offset + tessellation + (v+1) * stride;
3079 let rim_next = (v+1) * stride;
3080
3081 if q == 0 || q == 3 {
3083 indices.extend(vec![
3084 rim,
3085 lid,
3086 lid_next,
3087 rim,
3088 lid_next,
3089 rim_next
3090 ]);
3091 }
3092 else {
3093 indices.extend(vec![
3094 rim,
3095 lid_next,
3096 lid,
3097 rim,
3098 rim_next,
3099 lid_next
3100 ]);
3101 }
3102 }
3103 }
3104
3105 let (mut spout_verts, _) = tessalate_patch(&patches[8], tessellation, Vec3f::one(), false, vertices.len());
3107 let (spout_verts2, _) = tessalate_patch(&patches[8], tessellation, vec3f(-1.0, 1.0, 1.0), true, vertices.len());
3108 spout_verts.extend(spout_verts2);
3109
3110 let mut ii = 0;
3112 let mut loop_count = 0;
3113 let mut spout_centre = Vec3f::zero();
3114 for v in spout_verts {
3115 ii += 1;
3116 if (ii-1) % stride != tessellation {
3117 continue;
3118 }
3119 spout_centre += v.position;
3120 loop_count += 1;
3121 }
3122 spout_centre /= loop_count as f32;
3123
3124 let spount_centre_index = vertices.len();
3125 vertices.push(Vertex3D{
3126 position: spout_centre,
3127 texcoord: normalize(spout_centre.xz()) * 0.5 + 0.5,
3128 normal: Vec3f::unit_y(),
3129 tangent: Vec3f::unit_x(),
3130 bitangent: Vec3f::unit_z()
3131 });
3132
3133 for i in 0..tessellation {
3134 for q in 0..2 {
3135 let v = i + q * stride;
3136 let vi = spout_index_offset + tessellation + v * stride;
3137 let vn = spout_index_offset + tessellation + (v+1) * stride;
3138 if q == 1 {
3139 indices.extend(vec![
3140 vi,
3141 spount_centre_index,
3142 vn
3143 ])
3144 }
3145 else {
3146 indices.extend(vec![
3147 vi,
3148 vn,
3149 spount_centre_index
3150 ])
3151 }
3152 }
3153 }
3154
3155 create_mesh_3d(dev, vertices, indices)
3156}