tiramisu/asset
Asset Management System - loading and caching for textures, models, and audio.
Provides declarative asset loading with progress tracking, caching, and batch loading capabilities with LRU eviction.
Quick Example
import tiramisu/asset
// Load a texture
let load_effect = asset.load_texture("player.png")
|> promise.map(fn(result) {
case result {
Ok(texture) -> TextureLoaded(texture)
Error(err) -> LoadFailed(err)
}
})
|> effect.from_promise
// Use with cache
let cache = asset.new_cache()
let cache = asset.insert_texture(cache, "player.png", texture)
let texture = asset.get_texture(cache, "player.png")
Types
Asset cache/registry with LRU eviction
pub opaque type AssetCache
Asset loading error
pub type AssetError {
AssetLoadError(url: String, reason: String)
AssetNotFound(url: String)
InvalidAssetType(url: String)
}
Constructors
-
AssetLoadError(url: String, reason: String) -
AssetNotFound(url: String) -
InvalidAssetType(url: String)
Types of asset that can be loaded
pub type AssetType {
ModelAsset(url: String)
TextureAsset(url: String)
AudioAsset(url: String)
STLAsset(url: String)
OBJAsset(obj_url: String, mtl_url: option.Option(String))
FontAsset(url: String)
}
Constructors
-
ModelAsset(url: String)GLTF/GLB 3D model
-
TextureAsset(url: String)Texture image (PNG, JPG, etc.)
-
AudioAsset(url: String)Audio file (MP3, WAV, OGG)
-
STLAsset(url: String)STL 3D model
-
OBJAsset(obj_url: String, mtl_url: option.Option(String))OBJ 3D model with optional MTL material file
Supports loading Wavefront OBJ models with their associated MTL material files. The loader automatically:
- Loads diffuse color maps (map_Kd)
- Loads normal maps (map_bump) for surface detail
- Loads ambient occlusion maps (map_Ka) for realistic shadows
- Centers the model at origin
- Computes vertex normals if missing
MTL files can include texture paths with options (e.g., “map_bump -bm 1 texture.jpg”), which are properly parsed. Textures are assumed to be in the same directory as the MTL file.
-
FontAsset(url: String)Font for TextGeometry (typeface.json format)
Fonts must be in Three.js typeface.json format. You can convert TTF/OTF fonts using the facetype.js converter or download pre-converted fonts from the Three.js repository (examples/fonts/).
Result of batch loading
pub type BatchLoadResult {
BatchLoadResult(cache: AssetCache, errors: List(AssetError))
}
Constructors
-
BatchLoadResult(cache: AssetCache, errors: List(AssetError))
Opaque type for Three.js BufferGeometry.
Created by loading 3D models with asset.load_stl() or asset.load_model().
pub type BufferGeometry
Asset cache configuration
pub type CacheConfig {
CacheConfig(max_size: Int, current_time: Int)
}
Constructors
-
CacheConfig(max_size: Int, current_time: Int)
Opaque type for Three.js Font (for TextGeometry).
Created via asset.load_font() and used in text geometries.
Fonts must be in typeface.json format.
pub type Font
pub type GLTFData {
GLTFData(
scene: object3d.Object3D,
animations: List(object3d.AnimationClip),
)
}
Constructors
-
GLTFData( scene: object3d.Object3D, animations: List(object3d.AnimationClip), )
STL loading error
pub type LoadError {
LoadError(String)
InvalidUrl(String)
ParseError(String)
}
Constructors
-
LoadError(String) -
InvalidUrl(String) -
ParseError(String)
Progress information for batch loading
pub type LoadProgress {
LoadProgress(loaded: Int, total: Int, current_url: String)
}
Constructors
-
LoadProgress(loaded: Int, total: Int, current_url: String)
A loaded asset (opaque to enforce type safety)
pub opaque type LoadedAsset
Values
pub fn dispose_geometry(geometry: BufferGeometry) -> Nil
Dispose of a geometry and free GPU memory
pub fn dispose_object3d(object: object3d.Object3D) -> Nil
Dispose of an Object3D and all its resources (geometry, materials, textures, children)
pub fn dispose_texture(texture: Texture) -> Nil
Dispose of a texture and free GPU memory
pub fn get(
cache: AssetCache,
url: String,
) -> Result(LoadedAsset, AssetError)
Try to get any asset
pub fn get_audio(
cache: AssetCache,
url: String,
) -> Result(audio.AudioBuffer, AssetError)
Get an audio buffer from the cache
pub fn get_model(
cache: AssetCache,
url: String,
) -> Result(GLTFData, AssetError)
Get a GLTF model from the cache (updates LRU timestamp)
pub fn get_model_scene(
cache: AssetCache,
url: String,
) -> Result(object3d.Object3D, AssetError)
Get the scene object from a cached GLTF model
pub fn get_obj(
cache: AssetCache,
url: String,
) -> Result(object3d.Object3D, AssetError)
Get an OBJ model from the cache
Returns the loaded OBJ model as an Object3D. The model will have:
- Materials with textures applied (if MTL file was loaded)
- Vertex normals computed
- Center position at origin
Example
let assert Ok(bread_model) = asset.get_obj(cache, "models/bread.obj")
scene.Model3D(
id: "bread",
object: bread_model,
transform: transform.identity,
animation: option.None,
physics: option.None,
)
pub fn get_stl(
cache: AssetCache,
url: String,
) -> Result(BufferGeometry, AssetError)
Get an STL geometry from the cache
pub fn get_texture(
cache: AssetCache,
url: String,
) -> Result(Texture, AssetError)
Get a texture from the cache
pub fn insert_asset(
cache: AssetCache,
url: String,
asset: LoadedAsset,
) -> AssetCache
Insert a loaded asset into the cache manually If cache exceeds max_size, evicts least recently used asset
pub fn load_asset(
asset: AssetType,
) -> promise.Promise(Result(LoadedAsset, AssetError))
Load a single asset
pub fn load_audio(
url: String,
) -> promise.Promise(Result(audio.AudioBuffer, LoadError))
Load an audio file from a URL using Promises
Supports common audio formats including MP3, WAV, and OGG. Returns an AudioBuffer that can be used with the audio system.
Example
import tiramisu/asset
import gleam/javascript/promise
let load_effect = asset.load_audio("sounds/jump.mp3")
|> promise.map(fn(result) {
case result {
Ok(audio_buffer) -> AudioLoaded(audio_buffer)
Error(err) -> LoadFailed(err)
}
})
pub fn load_batch(
asset: List(AssetType),
on_progress: fn(LoadProgress) -> Nil,
) -> promise.Promise(BatchLoadResult)
Load multiple asset with progress tracking Returns a promise that resolves with the loaded asset and any errors
pub fn load_batch_simple(
asset: List(AssetType),
) -> promise.Promise(BatchLoadResult)
Load multiple asset without progress tracking
pub fn load_font(
url: String,
) -> promise.Promise(Result(Font, LoadError))
Load a font file (typeface.json format) for use with TextGeometry.
Three.js fonts must be in typeface.json format. You can:
- Download pre-converted fonts from Three.js repository (examples/fonts/)
- Convert TTF/OTF fonts using facetype.js converter
Example
import gleam/javascript/promise
import tiramisu/asset
let load_effect = asset.load_font("fonts/helvetiker_regular.typeface.json")
|> promise.map(fn(result) {
case result {
Ok(font) -> FontLoaded(font)
Error(err) -> LoadFailed(err)
}
})
Returns
A Promise that resolves to:
Ok(Font): Loaded font ready for TextGeometryError(LoadError): File not foundError(InvalidUrl): Invalid URL providedError(ParseError): Failed to parse font file
pub fn load_gltf(
url: String,
) -> promise.Promise(Result(GLTFData, LoadError))
Load a GLTF/GLB file from a URL using Promises
pub fn load_obj(
obj_url obj_url: String,
mtl_url mtl_url: String,
) -> promise.Promise(Result(object3d.Object3D, LoadError))
Load a Wavefront OBJ file with optional MTL materials
Loads a 3D model in OBJ format with full material and texture support. The loader handles:
- Diffuse/Color Maps (map_Kd): Base color textures
- Normal Maps (map_bump): Surface detail and lighting
- Ambient Occlusion Maps (map_Ka): Contact shadows and depth
- Vertex Normals: Computed automatically if missing
- Model Centering: Centers the model at origin
Textures are loaded from the same directory as the MTL file. The loader
properly parses MTL texture paths with options like map_bump -bm 1 normal.jpg.
Parameters
obj_url: Path to the OBJ filemtl_url: Path to the MTL file, or empty string""for no materials
Returns
A Promise that resolves to:
Ok(Object3D): Loaded model with materials and texturesError(LoadError): File not foundError(InvalidUrl): Invalid URL providedError(ParseError): Failed to parse OBJ/MTL file
pub fn load_stl(
url: String,
) -> promise.Promise(Result(BufferGeometry, LoadError))
Load an STL file from a URL using Promises
pub fn load_texture(
url: String,
) -> promise.Promise(Result(Texture, LoadError))
Load a texture from a URL using Promises
pub fn new_cache() -> AssetCache
Create a new empty asset cache with default max size (100 asset)
pub fn new_cache_with_size(max_size: Int) -> AssetCache
Create a new empty asset cache with custom max size