1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
use crate::elements::view::{ColChar, Modifier};
use super::{Face, Transform3D, Vec3D, ViewElement3D};
/// The struct for a Mesh3D object, containing a position, rotation, collection of vertices and collection of [`Face`]s with indices to the vertex collection.
#[derive(Debug, Clone)]
pub struct Mesh3D {
pub transform: Transform3D,
/// A vector of the [`Mesh3D`]'s
pub vertices: Vec<Vec3D>,
/// A vector of [`Face`]s of indexes into [`Mesh3D::vertices`]
pub faces: Vec<Face>,
}
impl Mesh3D {
/// The gemini_engine equivalent of Blender's default cube. Has side lengths of 2
pub fn default_cube() -> Self {
Self::new_at_origin(
vec![
Vec3D::new(1.0, 1.0, -1.0),
Vec3D::new(1.0, 1.0, 1.0),
Vec3D::new(1.0, -1.0, -1.0),
Vec3D::new(1.0, -1.0, 1.0),
Vec3D::new(-1.0, 1.0, -1.0),
Vec3D::new(-1.0, 1.0, 1.0),
Vec3D::new(-1.0, -1.0, -1.0),
Vec3D::new(-1.0, -1.0, 1.0),
],
vec![
Face::new(vec![2, 3, 1, 0], ColChar::SOLID.with_mod(Modifier::BLUE)),
Face::new(vec![4, 5, 7, 6], ColChar::SOLID.with_mod(Modifier::BLUE)),
Face::new(vec![1, 3, 7, 5], ColChar::SOLID.with_mod(Modifier::None)),
Face::new(vec![4, 6, 2, 0], ColChar::SOLID.with_mod(Modifier::None)),
Face::new(vec![6, 7, 3, 2], ColChar::SOLID.with_mod(Modifier::RED)),
Face::new(vec![0, 1, 5, 4], ColChar::SOLID.with_mod(Modifier::RED)),
],
)
}
/// A gimbal to help you orient in gemini_engine's 3D space. The orientation is as follows (from the default [`Viewport`](super::Viewport))
/// - X (red) increases as you move to the right
/// - Y (green) increases as you move up
/// - Z (blue) increases as you move away from the viewport
///
/// Think of it like Blender's axes but with Y and Z swapped.
/// This Mesh does not render in `DisplayMode::SOLID` (see [`DisplayMode`](super::DisplayMode) documentation)
pub fn gimbal() -> Self {
Self::new_at_origin(
vec![
Vec3D::ZERO,
Vec3D::new(1.0, 0.0, 0.0),
Vec3D::new(0.0, 1.0, 0.0),
Vec3D::new(0.0, 0.0, 1.0),
],
vec![
Face::new(vec![0, 1], ColChar::SOLID.with_mod(Modifier::RED)),
Face::new(vec![0, 2], ColChar::SOLID.with_mod(Modifier::GREEN)),
Face::new(vec![0, 3], ColChar::SOLID.with_mod(Modifier::BLUE)),
],
)
}
/// Create a `Mesh3D` with a default `Transform3D`
pub const fn new(transform: Transform3D, vertices: Vec<Vec3D>, faces: Vec<Face>) -> Self {
Self {
transform,
vertices,
faces,
}
}
/// Create a `Mesh3D` with a default `Transform3D`
pub const fn new_at_origin(vertices: Vec<Vec3D>, faces: Vec<Face>) -> Mesh3D {
Mesh3D {
transform: Transform3D::DEFAULT,
vertices,
faces,
}
}
}
impl ViewElement3D for Mesh3D {
fn get_transform(&self) -> Transform3D {
self.transform
}
fn get_vertices(&self) -> &[Vec3D] {
&self.vertices
}
fn get_faces(&self) -> &[Face] {
&self.faces
}
}