transvoxel/
mesh_builder.rs

1/*!
2Structs and traits used to customize mesh generation
3*/
4
5use std::fmt::Debug;
6use std::ops::Add;
7use std::ops::Mul;
8
9use crate::traits::Coordinate;
10use crate::traits::VoxelData;
11
12/// A world space position
13#[derive(Debug)]
14pub struct Position<C: Coordinate> {
15    /// X
16    pub x: C,
17    /// Y
18    pub y: C,
19    /// Z
20    pub z: C,
21}
22
23impl<C: Coordinate> Position<C> {
24    /// Interpolate between this `self` position and `other`, by the given `factor` (0 giving self, 1 giving other)
25    pub fn interp_toward(&self, other: &Position<C>, factor: C) -> Position<C> {
26        Position {
27            x: self.x + factor * (other.x - self.x),
28            y: self.y + factor * (other.y - self.y),
29            z: self.z + factor * (other.z - self.z),
30        }
31    }
32}
33
34impl<C> Mul<C> for &Position<C>
35where
36    C: Coordinate,
37{
38    type Output = Position<C>;
39
40    fn mul(self, rhs: C) -> Self::Output {
41        Position {
42            x: self.x * rhs,
43            y: self.y * rhs,
44            z: self.z * rhs,
45        }
46    }
47}
48
49impl<C> Add<&[C; 3]> for &Position<C>
50where
51    C: Coordinate,
52{
53    type Output = Position<C>;
54
55    fn add(self, rhs: &[C; 3]) -> Self::Output {
56        Position {
57            x: self.x + rhs[0],
58            y: self.y + rhs[1],
59            z: self.z + rhs[2],
60        }
61    }
62}
63
64/// A grid point on the voxel grid. A pair of these will be passed to the mesh generator,
65/// when creating vertices
66#[derive(Debug)]
67pub struct GridPoint<V: VoxelData, C: Coordinate> {
68    /// World location of the grid point
69    pub position: Position<C>,
70    /// Density gradient (estimated) at the grid point
71    pub gradient: (V::Density, V::Density, V::Density),
72    /// Data at the grid point that was obtained from the field
73    pub voxel_data: V,
74}
75
76/// An index in the vertex buffer
77#[derive(Default, Clone, Copy)]
78pub struct VertexIndex(pub usize);
79
80/// Trait you need to implement to build a mesh
81pub trait MeshBuilder<V: VoxelData, C: Coordinate> {
82    /// Called by the extraction algorithm when a new vertex it to be created between 2 grid points.
83    ///
84    /// Must return the index in the vertex buffer of the created vertex, as this will potentially get reused later.
85    /// `interp_toward_b` indicates where the vertex is to be placed within the AB segment: near 0 means near A, near 1 means near B.
86    fn add_vertex_between(
87        &mut self,
88        point_a: GridPoint<V, C>,
89        point_b: GridPoint<V, C>,
90        interp_toward_b: V::Density,
91    ) -> VertexIndex;
92
93    /// Called by the extraction algorithm when a triangle is to be created, using 3 pre-created vertices.
94    fn add_triangle(
95        &mut self,
96        vertex_1_index: VertexIndex,
97        vertex_2_index: VertexIndex,
98        vertex_3_index: VertexIndex,
99    );
100}