Skip to main content

Mesh3DFile

Struct Mesh3DFile 

Source
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

MethodSource
from_obj_srcWavefront OBJ string (triangles only)
from_stl_srcSTL bytes (ASCII or binary)
from_diskAuto-detected via file extension (debug caches, release loads cache)
cube, cuboid, etc.Procedural generation

§Generated primitives

FunctionDescription
cubeUnit cube centred at origin
cuboidBox with per-axis extents
sphereUV sphere with configurable stacks/sectors
cylinderCylinder with optional end caps
coneCone with optional base cap
torusTorus with configurable ring counts
planeFlat 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:

OffsetSizeField
08Magic (OPTIC_MAGIC)
82Version (OPTIC_CACHE_VERSION)
101Flags (bit 0 = has normals, bit 1 = has UVs)
114Position data size (bytes)
15NPosition data (f32 × 3 per vertex)
4Normal data size (0 if absent)
NNormal data (optional)
4UV data size (0 if absent)
NUV data (optional)
4Colour data size
NColour data (f32 × 4 per vertex)
4Index data size
NIndex 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

Source

pub fn empty() -> Self

Creates an empty mesh with no vertices or indices.

Source

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).

Source

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).

Source

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.

Source

pub fn save_cached(&self, path: &str) -> OpticResult<()>

Saves the mesh to a binary cache file (.omesh format).

Source

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);
Source

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.

Source

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).
  • UVsu wraps around the equator, v goes 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.

Source

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).

Source

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).

Source

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).
  • UVsu wraps around the major ring, v wraps around the minor ring.
  • Resolutionmajor_segments around the ring, minor_segments around the tube. 32 × 16 gives a smooth result.
§Use cases
  • Donuts, rings, tyres, rope coils, particle accelerator visualisations.
Source

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.
Source

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.

Source

pub fn has_no_attr(&self) -> bool

Returns true if no built-in attributes are populated and no custom attributes are attached.

Source

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.

Source

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§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> Downcast<T> for T

Source§

fn downcast(&self) -> &T

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> Upcast<T> for T

Source§

fn upcast(&self) -> Option<&T>