Skip to main content

Overview

The OBJ/MTL loader enables you to load 3D models in the Wavefront OBJ format with optional MTL (Material Template Library) files. This is one of the most common 3D model formats and is widely supported by modeling software.

Usage

tb.loadObj({
  type: 'mtl',
  obj: 'https://example.com/model.obj',
  mtl: 'https://example.com/model.mtl',
  units: 'meters',
  scale: 1,
  rotation: { x: 90, y: 0, z: 0 },
  anchor: 'center'
}, function(model) {
  tb.add(model);
});

Parameters

type
string
default:"mtl"
Loader type. Use 'mtl' for OBJ files (this is the default if not specified).
obj
string
required
URL or path to the OBJ model file.
mtl
string
URL or path to the MTL material file. Optional but recommended for textured models.If not provided, the model will load with default materials.
units
string
default:"scene"
Units for the model scale. Options:
  • 'scene' - Scene units (default)
  • 'meters' - Meters
scale
number | array
default:"1"
Scale factor for the model. Can be:
  • A single number: 1 (uniform scale)
  • An array: [x, y, z] for per-axis scaling
Example: scale: [2, 2, 2] or scale: 2
rotation
number | object | array
default:"0"
Rotation for the model in degrees. Can be:
  • A single number: 90 (rotation around Y axis)
  • An object: { x: 90, y: 0, z: 0 }
  • An array: [90, 0, 0] (X, Y, Z rotation)
anchor
string
default:"bottom-left"
Anchor point for the model positioning. Options:
  • 'center' - Center of the model
  • 'bottom-left' - Bottom-left corner
  • 'bottom-right' - Bottom-right corner
  • 'top-left' - Top-left corner
  • 'top-right' - Top-right corner
  • 'bottom-center' - Bottom center
  • 'top-center' - Top center
  • 'left' - Left center
  • 'right' - Right center
adjustment
object
Manual adjustment to override the automatic center calculation.Example: { x: 0, y: 0, z: 0 }
raycasted
boolean
default:"true"
Whether the model should be included in raycasting for mouse interactions.
bbox
boolean
default:"true"
Whether to calculate and display a bounding box for the model.
tooltip
boolean
default:"true"
Whether to enable tooltips for the model.
clone
boolean
default:"true"
Whether to clone the model when adding multiple instances.
withCredentials
boolean
default:"false"
Whether to send cookies and authorization headers with cross-origin requests.Applies to both OBJ and MTL file requests.

Callback

The callback function receives the loaded model object with the following properties:
function(model) {
  // Model object with added methods
  model.setCoords([lng, lat]); // Position on map
  model.setRotation({ x: 0, y: 90, z: 0 }); // Rotate model
  model.setScale(2); // Scale model
  
  // Access the internal THREE.js model
  console.log(model.model); // THREE.Object3D
  
  // OBJ models don't typically have animations
  console.log(model.animations); // Usually empty array
}

Model Structure

OBJ/MTL models are loaded with the following structure:
  • The first child of the loaded OBJ becomes the root object
  • Materials from the MTL file are applied automatically
  • Multiple meshes and groups are preserved
  • Texture paths in MTL are resolved relative to the MTL file location
From /home/daytona/workspace/source/src/objects/loadObj.js:68-70:
case "mtl":
  obj = obj.children[0];
  break;

Material Loading

The MTL file is loaded first, then applied to the OBJ model:
// MTL is loaded and preloaded
materialLoader.load(options.mtl, loadObject, () => (null), error => {
  console.warn("No material file found " + error.stack);
});

// Then applied to OBJ
if (materials && options.type == "mtl") {
  materials.preload();
  loader.setMaterials(materials);
}
From /home/daytona/workspace/source/src/objects/loadObj.js:44-60 If the MTL file fails to load, the model will still load with default gray materials.

Examples

Basic OBJ with Materials

tb.loadObj({
  type: 'mtl',
  obj: 'https://example.com/building.obj',
  mtl: 'https://example.com/building.mtl',
  scale: 5,
  rotation: { x: 0, y: 45, z: 0 },
  anchor: 'center'
}, function(model) {
  model.setCoords([-122.4194, 37.7749]);
  tb.add(model);
});

OBJ without MTL (Default Materials)

tb.loadObj({
  type: 'mtl',
  obj: 'https://example.com/simple.obj',
  // No mtl specified - will use default gray material
  scale: 2,
  anchor: 'bottom-center'
}, function(model) {
  model.setCoords([-122.4194, 37.7749]);
  tb.add(model);
  
  // You can modify materials after loading
  model.model.traverse(function(child) {
    if (child.isMesh) {
      child.material.color.set(0xff0000); // Red
    }
  });
});

Multiple OBJ Instances

tb.loadObj({
  obj: 'https://example.com/tree.obj',
  mtl: 'https://example.com/tree.mtl',
  scale: 3,
  clone: true
}, function(model) {
  // Place trees at different locations
  const locations = [
    [-122.4194, 37.7749],
    [-122.4200, 37.7750],
    [-122.4190, 37.7745]
  ];
  
  locations.forEach(coords => {
    let tree = model.duplicate();
    tree.setCoords(coords);
    tree.setRotation({ x: 0, y: Math.random() * 360, z: 0 });
    tb.add(tree);
  });
});

Custom Anchor Point

tb.loadObj({
  obj: 'https://example.com/statue.obj',
  mtl: 'https://example.com/statue.mtl',
  scale: 10,
  anchor: 'bottom-center', // Model sits on the ground
  adjustment: { x: 0, y: 2, z: 0 } // Fine-tune vertical position
}, function(model) {
  model.setCoords([-122.4194, 37.7749]);
  tb.add(model);
});

Texture Paths

Texture references in MTL files should be relative paths or absolute URLs:
# Relative to MTL file location
map_Kd textures/diffuse.jpg

# Or absolute URL
map_Kd https://example.com/textures/diffuse.jpg
Ensure texture files are accessible from the same domain or CORS is properly configured.

Common Issues

MTL Not Loading

If materials don’t appear:
  1. Check the browser console for MTL loading errors
  2. Verify the MTL path is correct and accessible
  3. Ensure CORS headers are set if loading from a different domain
  4. Use withCredentials: true if authentication is required

Model Orientation

OBJ models may need rotation to align with Mapbox’s coordinate system:
// Common orientation fix
rotation: { x: 90, y: 0, z: 0 }

Model Scale

If the model is too large or small, adjust the scale:
scale: 0.1  // Make smaller
scale: 10   // Make larger

Build docs developers (and LLMs) love