tiramisu/geometry
Geometry module - validated 3D shapes and primitives.
Provides validated constructors for geometric primitives used in 3D rendering.
All geometry functions return Result to catch invalid parameters at construction time.
Core Concepts
- Validation: Geometry constructors validate dimensions (positive sizes, valid segment counts)
- Primitives: Built-in shapes like boxes, spheres, planes, cylinders, toruses
- Custom Geometry: Support for loading external geometry via asset system
- Text Geometry: 3D text rendering with loaded fonts
Quick Example
import tiramisu/geometry
import tiramisu/scene
import tiramisu/material
// Create validated geometries
let assert Ok(cube) = geometry.box(width: 1.0, height: 1.0, depth: 1.0)
let assert Ok(ball) = geometry.sphere(radius: 0.5, width_segments: 32, height_segments: 16)
let assert Ok(ground) = geometry.plane(width: 100.0, height: 100.0)
// Use in scene
scene.Mesh(
id: "player",
geometry: cube,
material: my_material,
transform: transform.identity,
physics: option.None,
)
Available Primitives
- box: Rectangular cuboid (e.g., walls, buildings, crates)
- sphere: Perfect sphere (e.g., balls, planets, bubbles)
- plane: Flat 2D rectangle (e.g., ground, walls, billboards)
- circle: Flat circle (e.g., coins, targets, platforms)
- cylinder: Cylinder with configurable top/bottom radius (e.g., pillars, trees, pipes)
- cone: Cone shape (e.g., traffic cones, party hats)
- capsule: Cylinder with rounded caps (e.g., character colliders)
- torus: Donut shape (e.g., rings, hoops)
- tetrahedron: 4-sided polyhedron (e.g., low-poly crystals)
- icosahedron: 20-sided polyhedron (e.g., smooth low-poly spheres, dice)
- text: 3D extruded text with beveling (e.g., logos, titles, signs)
Validation
All geometry constructors validate their parameters:
// Valid
let assert Ok(cube) = geometry.box(width: 1.0, height: 1.0, depth: 1.0)
// Invalid - negative dimensions
let assert Error(geometry.NonPositiveWidth(-1.0)) =
geometry.box(width: -1.0, height: 1.0, depth: 1.0)
// Invalid - too few segments
let assert Error(geometry.LessThanThreeSegmentCountWidth(2)) =
geometry.sphere(radius: 1.0, width_segments: 2, height_segments: 16)
Types
3D geometry types supported by the engine.
Each variant represents a different primitive shape or custom geometry.
Use the validated constructor functions like box(), sphere(), etc.
pub opaque type Geometry
pub type GeometryError {
NonPositiveWidth(width: Float)
NonPositiveHeight(height: Float)
NonPositiveDepth(depth: Float)
NonPositiveRadius(radius: Float)
InvalidGeometryTube(tube: Float)
LessThanThreeSegmentCountWidth(count: Int)
LessThanTwoSegmentCountHeight(count: Int)
NegativeSegmentCount(count: Int)
EmptyText
NonPositiveSize(size: Float)
NegativeBevelThickness(thickness: Float)
NegativeBevelSize(size: Float)
}
Constructors
-
NonPositiveWidth(width: Float) -
NonPositiveHeight(height: Float) -
NonPositiveDepth(depth: Float) -
NonPositiveRadius(radius: Float) -
InvalidGeometryTube(tube: Float) -
LessThanThreeSegmentCountWidth(count: Int) -
LessThanTwoSegmentCountHeight(count: Int) -
NegativeSegmentCount(count: Int) -
EmptyText -
NonPositiveSize(size: Float) -
NegativeBevelThickness(thickness: Float) -
NegativeBevelSize(size: Float)
Values
pub fn box(
width width: Float,
height height: Float,
depth depth: Float,
) -> Result(Geometry, GeometryError)
Create a validated box geometry.
All dimensions must be positive (> 0).
Example
let assert Ok(cube) = scene.box(width: 1.0, height: 1.0, depth: 1.0)
let assert Ok(wall) = scene.box(width: 10.0, height: 3.0, depth: 0.1)
pub fn circle(
radius radius: Float,
segments segments: Int,
) -> Result(Geometry, GeometryError)
pub fn cone(
radius radius: Float,
height height: Float,
segments segments: Int,
) -> Result(Geometry, GeometryError)
pub fn custom_geometry(
geometry geometry: asset.BufferGeometry,
) -> Geometry
pub fn cylinder(
radius_top radius_top: Float,
radius_bottom radius_bottom: Float,
height height: Float,
radial_segments radial_segments: Int,
) -> Result(Geometry, GeometryError)
Create a validated cylinder geometry.
Both radii must be non-negative, height positive, radial segments >= 3. Set one radius to 0 to create a cone shape.
Example
let assert Ok(cylinder) = scene.cylinder(radius_top: 1.0, radius_bottom: 1.0, height: 2.0, radial_segments: 32)
let assert Ok(cone) = scene.cylinder(radius_top: 0.0, radius_bottom: 1.0, height: 2.0, radial_segments: 32)
pub fn icosahedron(
radius radius: Float,
detail detail: Int,
) -> Result(Geometry, GeometryError)
Create a validated icosahedron (20-sided polyhedron) geometry.
Detail level controls subdivision. Good for creating spheres with flat faces.
Example
let assert Ok(shape) = scene.icosahedron(radius: 1.0, detail: 2)
pub fn plane(
width width: Float,
height height: Float,
) -> Result(Geometry, GeometryError)
pub fn sphere(
radius radius: Float,
width_segments width_segments: Int,
height_segments height_segments: Int,
) -> Result(Geometry, GeometryError)
Create a validated sphere geometry.
Radius must be positive. Width segments >= 3, height segments >= 2. More segments = smoother sphere but more triangles.
Example
let assert Ok(ball) = scene.sphere(radius: 1.0, width_segments: 32, height_segments: 16)
let assert Ok(low_poly) = scene.sphere(radius: 1.0, width_segments: 8, height_segments: 6)
pub fn tetrahedron(
radius radius: Float,
detail detail: Int,
) -> Result(Geometry, GeometryError)
Create a validated tetrahedron (4-sided polyhedron) geometry.
Detail level controls subdivision (0 = no subdivision, higher = more triangles).
Example
let assert Ok(shape) = scene.tetrahedron(radius: 1.0, detail: 0)
pub fn text(
text text: String,
font font: asset.Font,
size size: Float,
depth depth: Float,
curve_segments curve_segments: Int,
bevel_enabled bevel_enabled: Bool,
bevel_thickness bevel_thickness: Float,
bevel_size bevel_size: Float,
bevel_offset bevel_offset: Float,
bevel_segments bevel_segments: Int,
) -> Result(Geometry, GeometryError)
Create validated 3D text geometry from a loaded font.
Renders text as 3D geometry with optional beveling (rounded edges).
Requires a font loaded via asset.load_font().
Example
import tiramisu/geometry
import tiramisu/asset
// After loading font...
let assert Ok(text) = geometry.text(
text: "Hello!",
font: my_font,
size: 1.0,
depth: 0.2,
curve_segments: 12,
bevel_enabled: True,
bevel_thickness: 0.05,
bevel_size: 0.02,
bevel_offset: 0.0,
bevel_segments: 5,
)
Parameters
text: String to render (must not be empty)font: Loaded font fromasset.load_font()size: Text size (must be positive)depth: Extrusion depth for 3D effect (0 for flat, >0 for 3D)curve_segments: Quality of curves (more = smoother but more triangles)bevel_enabled: Whether to add rounded edgesbevel_thickness: How deep bevels cut into textbevel_size: How far bevels extend outwardbevel_offset: Starting distance of bevel from outlinebevel_segments: Smoothness of bevel (more = rounder)
pub fn torus(
radius radius: Float,
tube tube: Float,
radial_segments radial_segments: Int,
tubular_segments tubular_segments: Int,
) -> Result(Geometry, GeometryError)
Create a validated torus (donut) geometry.
Example
let assert Ok(donut) = scene.torus(radius: 2.0, tube: 0.5, radial_segments: 16, tubular_segments: 100)