mod3d_base/example_objects/tetrahedron.rs
1//a Documentation
2/*!
3
4This provides a function to create [ExampleVertices] object that is a triangle of a specified size at z=0
5
6 */
7
8//a Imports
9use super::ExampleVertices;
10use crate::{
11 BufferElementType, Mesh, Primitive, PrimitiveType, Renderable, ShortIndex, VertexAttr,
12 VertexDesc,
13};
14
15/// Add new position, normal and indices views to an [ExampleVertices]
16/// for a tetrahedron with base at z=0 and tip at (0, 0, size)
17///
18/// The bottom plane is reflectionallty symmetric about the X axis
19///
20/// This has four vertices with a normal at each that is directed away
21/// from the centroid
22///
23/// The height is sqrt(2)/sqrt(3) * side length
24/// The centroid is 1/4 of the way up = 1/sqrt(24)
25/// sqrt(1-centroid^2) = sqrt(23/24)
26///
27/// Each equilateral triangle face has three sides of length size
28///
29/// The height of the triangles is size * sqrt(3)/2
30/// The centroid of these triangles is at 1/3 of the height
31///
32/// The X tip (Y=0, Z=0) is then at 2/3 * sqrt(3)/2 * size = size / sqrt(3)
33/// The other tips at Z=0 are then at
34/// X = -1/3 * sqrt(3)/2 * size = -size / (2*sqrt(3))
35/// Y = +- size/2
36pub fn new<R: Renderable>(eg: &mut ExampleVertices<R>, size: f32)
37where
38 <R as Renderable>::Descriptor: Unpin,
39{
40 let height = (2.0_f32 / 3.0).sqrt();
41 let centroid = height / 4.0;
42 let r3_2 = (3.0_f32).sqrt() * 0.5;
43 let s = 1.0 / (3.0_f32).sqrt();
44 let x = (23.0_f32 / 24.0).sqrt();
45 let vertex_data = [
46 size * 2.0 * s,
47 0.,
48 0.,
49 x,
50 0.,
51 -centroid,
52 -size * s,
53 size * 0.5,
54 0.,
55 -x * 0.5,
56 x * r3_2,
57 -centroid,
58 -size * s,
59 -size * 0.5,
60 0.,
61 -x * 0.5,
62 -x * r3_2,
63 -centroid,
64 0.,
65 0.,
66 size * height,
67 0.,
68 0.,
69 1.,
70 ];
71 let index_data = [0u8, 1, 2, 3, 0, 1];
72
73 let data_indices = eg.push_byte_buffer(Box::new(index_data));
74 let data_vertices = eg.push_byte_buffer(Box::new(vertex_data));
75
76 let indices = eg.push_index_accessor(data_indices, 6, BufferElementType::UInt8, 0);
77 let desc = eg.push_descriptor(data_vertices, 0, 0, 0); // Use all the buffer, and stride used to be 6*4
78 let normals = eg.push_data_accessor(
79 desc,
80 VertexDesc::vec(VertexAttr::Normal, BufferElementType::Float32, 3, 3 * 4),
81 );
82 let vertices = eg.push_data_accessor(
83 desc,
84 VertexDesc::vec(VertexAttr::Position, BufferElementType::Float32, 3, 0),
85 );
86
87 // Create set of data (indices, vertex data) to by subset into by the meshes and their primitives
88 eg.push_vertices(Some(indices), vertices, &[normals]);
89}
90
91/// Create a mesh for the tetrahedron given the vertices index and
92/// material index within a parent model3d::Object
93///
94/// The object should have had the vertices for the tetrahedron (created
95/// with new() above) added to it (using a parent [ExampleVertices])
96pub fn mesh(v_id: ShortIndex, m_id: ShortIndex) -> Mesh {
97 let mut mesh = Mesh::default();
98 mesh.add_primitive(Primitive::new(
99 PrimitiveType::TriangleStrip,
100 v_id,
101 0,
102 6,
103 m_id,
104 ));
105 mesh
106}