pub struct Mesh3DFile {
pub pos_attr: Pos3DATTR,
pub col_attr: ColATTR,
pub uvm_attr: UVMATTR,
pub nrm_attr: NrmATTR,
pub ind_attr: IndATTR,
pub cus_attrs: Vec<CustomATTR>,
}Expand description
CPU-side 3D mesh geometry — positions, normals, UVs, colours, and indices.
Mesh3DFile is the primary asset type for 3D geometry. It stores vertex
and index data in separate typed attribute arrays, ready for interleaving
and GPU upload via ship.
§Loading
| Method | Source |
|---|---|
from_obj_src | Wavefront OBJ string (triangles only) |
from_stl_src | STL bytes (ASCII or binary) |
from_disk | Auto-detected via file extension (debug caches, release loads cache) |
cube, cuboid, etc. | Procedural generation |
§Generated primitives
| Function | Description |
|---|---|
cube | Unit cube centred at origin |
cuboid | Box with per-axis extents |
sphere | UV sphere with configurable stacks/sectors |
cylinder | Cylinder with optional end caps |
cone | Cone with optional base cap |
torus | Torus with configurable ring counts |
plane | Flat XZ quad |
§Custom attributes
Use attach_custom_attr to add
per-vertex data beyond the built-in set (e.g. bone weights, AO values).
§Binary cache format
The .omesh cache uses a simple binary layout:
| Offset | Size | Field |
|---|---|---|
| 0 | 8 | Magic (OPTIC_MAGIC) |
| 8 | 2 | Version (OPTIC_CACHE_VERSION) |
| 10 | 1 | Flags (bit 0 = has normals, bit 1 = has UVs) |
| 11 | 4 | Position data size (bytes) |
| 15 | N | Position data (f32 × 3 per vertex) |
| … | 4 | Normal data size (0 if absent) |
| … | N | Normal data (optional) |
| … | 4 | UV data size (0 if absent) |
| … | N | UV data (optional) |
| … | 4 | Colour data size |
| … | N | Colour data (f32 × 4 per vertex) |
| … | 4 | Index data size |
| … | N | Index data (u32 per index) |
§Example
use optic_render::asset::Mesh3DFile;
// Load from OBJ
let obj = "\
v 0.0 0.0 0.0\n\
v 1.0 0.0 0.0\n\
v 0.0 1.0 0.0\n\
f 1 2 3";
let file = Mesh3DFile::from_obj_src(obj)?;
// Or generate procedurally
let cube = Mesh3DFile::cube(2.0);Fields§
§pos_attr: Pos3DATTR§col_attr: ColATTR§uvm_attr: UVMATTR§nrm_attr: NrmATTR§ind_attr: IndATTR§cus_attrs: Vec<CustomATTR>Implementations§
Source§impl Mesh3DFile
impl Mesh3DFile
Sourcepub fn from_obj_src(src: &str) -> OpticResult<Self>
pub fn from_obj_src(src: &str) -> OpticResult<Self>
Parses a Wavefront OBJ source string into a triangle mesh.
Supports v, vt, vn, and triangular f records. Non-triangle
faces produce an OpticError.
§Errors
Returns an error if the OBJ contains a face with more than 3 vertices (non-triangulated).
Sourcepub fn from_stl_src(data: &[u8]) -> OpticResult<Self>
pub fn from_stl_src(data: &[u8]) -> OpticResult<Self>
Parses an STL file (ASCII or binary) into a triangle mesh.
Vertices are deduplicated by position + normal. UVs are left empty and colours default to white.
§Errors
Returns an error if the data is truncated or not valid UTF-8 (for ASCII STL).
Sourcepub fn from_disk(path: &str) -> OpticResult<Self>
pub fn from_disk(path: &str) -> OpticResult<Self>
Loads a mesh from disk, detecting format by extension.
In debug builds: parses the source file and overwrites the cache.
In release builds: loads from the cached .omesh file directly for
faster startup.
Supported formats: .obj, .stl.
Sourcepub fn save_cached(&self, path: &str) -> OpticResult<()>
pub fn save_cached(&self, path: &str) -> OpticResult<()>
Saves the mesh to a binary cache file (.omesh format).
Sourcepub fn cube(side: f32) -> Self
pub fn cube(side: f32) -> Self
Generates a unit cube centred at the origin with all six faces. Generates a cube centred at the origin with equal side lengths.
This is a convenient shorthand for cuboid(side, side, side).
Each face is a quad (2 triangles, 4 vertices) with correct normals and
per-face UVs covering [0,1]².
§Conventions
- Y-up — the top face points toward +Y.
- UVs — each face covers the full
[0,1]²texture atlas. - Normals — per-face (flat, not smooth).
- Colour — all vertices white.
§Example
let cube = Mesh3DFile::cube(2.0);
let box_ = Mesh3DFile::cuboid(1.0, 2.0, 3.0);Sourcepub fn cuboid(w: f32, h: f32, d: f32) -> Self
pub fn cuboid(w: f32, h: f32, d: f32) -> Self
Generates a rectangular box centred at the origin.
Each face remains a quad with flat normals, full-cover UVs, and white
colour. Use cube for equal-sided boxes.
Sourcepub fn sphere(radius: f32, stacks: u32, sectors: u32) -> Self
pub fn sphere(radius: f32, stacks: u32, sectors: u32) -> Self
Generates a UV sphere centred at the origin.
The sphere is constructed with a latitude/longitude grid and normals that are exact for perfect shading. Positions and normals use the same unit direction vector, so the sphere works correctly with dynamic lighting.
§Conventions
- Y-up — the north pole is at
(0, radius, 0). - UVs —
uwraps around the equator,vgoes from pole to pole. - Normals — per-vertex smooth (interpolated across triangles).
§Resolution
stacks controls the number of latitude subdivisions, sectors controls
the number of longitude subdivisions. A sphere with stacks = 16 and
sectors = 32 is a good balance between quality and vertex count.
Sourcepub fn cylinder(radius: f32, height: f32, segments: u32, cap: bool) -> Self
pub fn cylinder(radius: f32, height: f32, segments: u32, cap: bool) -> Self
Generates a cylinder centred at the origin, oriented along Y.
The cylinder body consists of a single quad strip around the circumference
with segments subdivisions. Optionally closes the top and bottom caps
with triangular fans.
§Conventions
- Y-up — the top face at
+height / 2, bottom at-height / 2. - Normals — per-vertex on the cylinder body (exact radial normal); flat for caps (pointing straight up/down).
- UVs — wraps around the body; caps cover a radial fan.
§When to cap
Set cap = true for a solid cylinder (e.g. a column). Set cap = false
for an open tube (e.g. a pipe segment).
Sourcepub fn cone(radius: f32, height: f32, segments: u32, cap: bool) -> Self
pub fn cone(radius: f32, height: f32, segments: u32, cap: bool) -> Self
Generates a cone centred at the origin, oriented along Y, with the apex at +Y.
The cone body is a single strip of triangles from apex to base ring. Optionally closes the base with a triangular fan.
§Conventions
- Apex at
(0, +height / 2, 0), base at(0, -height / 2, 0). - Normals — per-vertex smooth normals that account for the cone’s slope (the normal leans outward from the apex).
- UVs — the body maps the apex to the top of the UV range.
§When to cap
Set cap = true for a solid cone. Set cap = false for a cone-shaped
surface (e.g. a speaker horn).
Sourcepub fn torus(
major_radius: f32,
minor_radius: f32,
major_segments: u32,
minor_segments: u32,
) -> Self
pub fn torus( major_radius: f32, minor_radius: f32, major_segments: u32, minor_segments: u32, ) -> Self
Generates a torus (donut shape) lying in the XZ plane.
The torus is a ring swept around the Y axis. major_radius controls the
overall size of the ring and minor_radius controls the thickness of the
tube.
§Conventions
- Y-up — the torus lies flat in the XZ plane.
- Normals — per-vertex smooth (exact radial normal from the tube centre).
- UVs —
uwraps around the major ring,vwraps around the minor ring. - Resolution —
major_segmentsaround the ring,minor_segmentsaround the tube. 32 × 16 gives a smooth result.
§Use cases
- Donuts, rings, tyres, rope coils, particle accelerator visualisations.
Sourcepub fn plane(width: f32, depth: f32) -> Self
pub fn plane(width: f32, depth: f32) -> Self
Generates a flat quad in the XZ plane (Y-up), centred at the origin.
The plane has a normal of (0, 1, 0) and covers width × depth units.
UVs span [0,1]² across the full surface.
§Use cases
- Ground planes, floors, table-tops, decals.
- Combine with a translucent shader for shadow receivers.
§Conventions
- Orientation — faces +Y (up).
- Windings — counter-clockwise when viewed from above.
Sourcepub fn attach_custom_attr(&mut self, attr: CustomATTR)
pub fn attach_custom_attr(&mut self, attr: CustomATTR)
Attaches a custom per-vertex attribute (e.g. bone weights, AO).
The custom attribute must have the same number of elements as the mesh’s vertex count.
Sourcepub fn has_no_attr(&self) -> bool
pub fn has_no_attr(&self) -> bool
Returns true if no built-in attributes are populated and no custom
attributes are attached.
Sourcepub fn starts_with_custom(&self) -> bool
pub fn starts_with_custom(&self) -> bool
Returns true if no built-in vertex attributes are populated.
This does not check custom attributes — use has_no_attr
for a complete emptiness check.
Sourcepub fn ship(&self) -> MeshHandle
pub fn ship(&self) -> MeshHandle
Interleaves vertex attributes and uploads to the GPU.
Returns a MeshHandle ready for instanced or direct drawing.
This is the final step of the asset-to-GPU pipeline for 3D meshes.
Auto Trait Implementations§
impl Freeze for Mesh3DFile
impl RefUnwindSafe for Mesh3DFile
impl Send for Mesh3DFile
impl Sync for Mesh3DFile
impl Unpin for Mesh3DFile
impl UnsafeUnpin for Mesh3DFile
impl UnwindSafe for Mesh3DFile
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more