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}