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