Files
wsg/docs/user/meshes/sources.md
T
Jérôme Bousquié d4c2d93fc5 eng doc
2026-09-25 20:06:10 +02:00

3.1 KiB
Raw Blame History

Geometry sources: procedural generators and file import

The wsg::mesh module is the single entry point for where the geometry comes from: procedural generators or file import.

Procedural primitives

Each primitive family is behind a feature — you only compile what you need.

Feature Function Description
prim-cube cube(size) Centered cube, 24 vertices, per-face normals
prim-plane plane(w, d, seg_x, seg_z) Horizontal XZ plane (normal +Y), subdivided
prim-sphere uv_sphere(r, sectors, stacks) Lat/long sphere, smooth normals
prim-sphere icosphere(r, subdivisions) Icosphere (subdivided icosahedron)
prim-cylinder cylinder(r, h, sectors) Cylinder (side + caps), analytic normals
prim-cone cone(r, h, sectors) Cone (apex + closed base)
prim-torus torus(major, minor, seg_maj, seg_min) Torus, smooth normals

Default features

# Your project's Cargo.toml
[dependencies]
wsg-lib = { path = "../lib" }
# Default: all primitives enabled (all-prims)
# Only compile the cube and the sphere:
wsg-lib = { path = "../lib", default-features = false, features = ["prim-cube", "prim-sphere"] }

Usage

use wsg_lib::prelude::*;

let cube = cube(2.0);
let sphere = uv_sphere(1.0, 32, 16);
let ico = icosphere(1.0, 2);

// All return a Geometry (positions + normals + UVs + indices)
assert_eq!(cube.positions.len(), 24);

File import

Feature Function Format
import-obj load_obj(path) / parse_obj(str) Wavefront OBJ
import-gltf load_gltf(path) glTF 2.0 / GLB (stub)

OBJ parser

Supports: v, vn, vt, f (3–4 vertices, fan triangulation). If the file has no normals, they are computed (area-weighted).

use wsg_lib::mesh::{load_obj, parse_obj};

// From a file
let geom = load_obj("model.obj")?;

// From a string
let geom = parse_obj("v 0 0 0\nv 1 0 0\nv 0 1 0\nf 1 2 3\n")?;

Errors

use wsg_lib::mesh::import::MeshImportError;

match load_obj("missing.obj") {
    Ok(geom) => { /* … */ }
    Err(MeshImportError::Io(e)) => eprintln!("file not accessible: {e}"),
    Err(MeshImportError::Parse(e)) => eprintln!("invalid syntax: {e}"),
    Err(MeshImportError::Unsupported(e)) => eprintln!("unsupported feature: {e}"),
}

From Geometry to the scene

The mesh module produces Geometry (CPU data). To render it, go through Scene::create_mesh, which uploads it to the GPU:

use wsg_lib::prelude::*;
use wsg_lib::mesh::cube;

// In AppHandler::setup:
let geom = cube(1.0);
app.scene.create_mesh("my_mesh", geom, Some("my_mat"))?;
app.scene.add_entity("my_entity", "my_mesh")?;

Example

cargo run -p wsg-lib --example import --features import-obj -- model.obj

Conventions

  • Y-up, centered on the origin (except plane: XZ plane at y=0)
  • Outward normals
  • UVs in [0,1]²
  • CCW winding (front face)