Geometry API
The geometry system provides 3D shapes for robot visual and collision components through the IGeometry
interface and concrete implementations.
IGeometry Interface
The base interface that all geometry types implement:
interface IGeometry {
meshes: BABYLON.AbstractMesh[] | undefined;
transform: BABYLON.TransformNode | undefined;
create(scene: BABYLON.Scene, mat: Material | undefined): void;
dispose(): void;
setLoadCompleteCallback?(callback: () => void): void;
}
Properties
meshes
: Array of Babylon.js mesh objectstransform
: Transform node for positioning and hierarchy
Methods
create()
: Creates the geometry in the scene with optional materialdispose()
: Cleans up geometry resourcessetLoadCompleteCallback()
: Optional callback for async loading completion
Primitive Geometries
Box Geometry
Creates rectangular box shapes.
import { Box } from '@ranchhandrobotics/babylon_ros';
const box = new Box(width, height, depth);
Constructor Parameters:
- width
: number - X-axis dimension (meters)
- height
: number - Y-axis dimension (meters)
- depth
: number - Z-axis dimension (meters)
Example:
// Create a 2x1x0.5 meter box
const chassisBox = new Box(2.0, 1.0, 0.5);
chassisBox.create(scene, material);
Sphere Geometry
Creates spherical shapes.
import { Sphere } from '@ranchhandrobotics/babylon_ros';
const sphere = new Sphere(radius);
Constructor Parameters:
- radius
: number - Sphere radius (meters)
Example:
// Create a 10cm radius sphere
const ballJoint = new Sphere(0.1);
ballJoint.create(scene, material);
Cylinder Geometry
Creates cylindrical shapes.
import { Cylinder } from '@ranchhandrobotics/babylon_ros';
const cylinder = new Cylinder(length, radius);
Constructor Parameters:
- length
: number - Cylinder height/length (meters)
- radius
: number - Cylinder radius (meters)
Special Behavior: - Automatically rotated 90° around X-axis to align with ROS conventions - ROS cylinders are along Z-axis, Babylon.js cylinders are along Y-axis
Example:
// Create a 50cm long, 5cm radius cylinder
const robotArm = new Cylinder(0.5, 0.05);
robotArm.create(scene, material);
Mesh Geometry
Loads complex 3D models from files.
import { Mesh } from '@ranchhandrobotics/babylon_ros';
const mesh = new Mesh(uri, scale);
Constructor Parameters:
- uri
: string - Path to 3D model file
- scale
: BABYLON.Vector3 - Scaling factors for X, Y, Z axes
Supported Formats: - COLLADA (.dae): Full feature support including materials, animations - STL (.stl): Basic mesh geometry (automatically handles coordinate conversion) - OBJ (.obj): Basic mesh geometry - glTF (.gltf, .glb): Modern format with full PBR material support
Properties
Property | Type | Description |
---|---|---|
uri |
string |
File path or URL to the mesh |
scale |
BABYLON.Vector3 |
Scaling applied to loaded mesh |
meshes |
BABYLON.AbstractMesh[] \| undefined |
Loaded mesh objects |
transform |
BABYLON.TransformNode \| undefined |
Transform node |
material |
Material \| undefined |
Override material |
skeletons |
BABYLON.Skeleton[] \| undefined |
Animation skeletons |
Methods
setLoadCompleteCallback(callback: () => void): void
Sets a callback function to be called when mesh loading completes.
Example:
const robotMesh = new Mesh("robot_body.dae", new BABYLON.Vector3(1, 1, 1));
robotMesh.setLoadCompleteCallback(() => {
console.log("Robot mesh loaded successfully");
// Perform post-load operations
});
robotMesh.create(scene, material);
Usage Examples
Creating Primitive Shapes
// Robot chassis - large box
const chassis = new Box(2.0, 1.0, 0.3);
const chassisMaterial = new Material();
chassisMaterial.color = new BABYLON.Color4(0.5, 0.5, 0.5, 1);
chassis.create(scene, chassisMaterial);
// Wheel - cylinder
const wheel = new Cylinder(0.1, 0.3); // 10cm wide, 30cm diameter
const rubberMaterial = new Material();
rubberMaterial.color = new BABYLON.Color4(0.1, 0.1, 0.1, 1);
wheel.create(scene, rubberMaterial);
// Sensor housing - sphere
const lidarDome = new Sphere(0.08); // 8cm radius
const blackMaterial = new Material();
blackMaterial.color = new BABYLON.Color4(0, 0, 0, 1);
lidarDome.create(scene, blackMaterial);
Loading Complex Meshes
// High-detail robot arm from COLLADA file
const armMesh = new Mesh(
"models/robot_arm_detailed.dae",
new BABYLON.Vector3(1, 1, 1) // No scaling
);
// Handle async loading
let meshLoadComplete = false;
armMesh.setLoadCompleteCallback(() => {
meshLoadComplete = true;
console.log("Arm mesh loaded");
});
armMesh.create(scene, material);
// Scaled STL mesh (STL files often need scaling)
const gearMesh = new Mesh(
"parts/gear.stl",
new BABYLON.Vector3(0.001, 0.001, 0.001) // Scale from mm to m
);
gearMesh.create(scene, metalMaterial);
Geometry in Visual Components
const visual = new Visual();
visual.name = "robot_body";
// Use different geometry based on requirements
if (detailedMode) {
// High-detail mesh for close viewing
visual.geometry = new Mesh("detailed_body.dae", new BABYLON.Vector3(1, 1, 1));
} else {
// Simple box for performance
visual.geometry = new Box(1.5, 0.8, 0.4);
}
visual.create(scene, materialMap);
Coordinate System Conversions
ROS to Babylon.js Coordinate Systems
The geometry classes handle coordinate system differences:
ROS Conventions: - X-forward, Y-left, Z-up - Cylinders along Z-axis - STL files in millimeters
Babylon.js Conventions:
- X-right, Y-up, Z-forward
- Cylinders along Y-axis
- Meters for all units
Automatic Conversions
// Cylinder: Automatically rotated 90° around X-axis
const cylinder = new Cylinder(0.5, 0.05);
// Result: 50cm cylinder pointing along Z-axis (ROS convention)
// STL Mesh: Automatically handles coordinate conversion
const stlMesh = new Mesh("part.stl", new BABYLON.Vector3(0.001, 0.001, 0.001));
// Result: Proper orientation and scaling from mm to meters
Performance Considerations
Primitive Geometries
- Fast Creation: Generated procedurally, very fast
- Low Memory: Minimal memory footprint
- Good for Collision: Perfect for simple collision shapes
Mesh Geometries
- Loading Time: Files must be loaded from disk/network
- Memory Usage: Can be large for detailed models
- Rendering Cost: Complex meshes impact rendering performance
Optimization Strategies
// Use appropriate level of detail
const simpleCollision = new Box(2, 1, 0.5); // Simple collision
const detailedVisual = new Mesh("detailed.dae", scale); // Detailed visual
// Scale optimization
const lowPolyMesh = new Mesh("low_poly.dae", scale); // For distant objects
const highPolyMesh = new Mesh("high_poly.dae", scale); // For close viewing
// Async loading management
const loader = new Mesh("large_model.dae", scale);
loader.setLoadCompleteCallback(() => {
// Enable rendering after loading
robotScene.readyToRender = true;
});
Material Integration
Geometry with Materials
// Primitive with solid color
const box = new Box(1, 1, 1);
const redMaterial = new Material();
redMaterial.color = new BABYLON.Color4(1, 0, 0, 1);
box.create(scene, redMaterial);
// Mesh with texture (material can be embedded in file)
const texturedMesh = new Mesh("textured_model.dae", scale);
texturedMesh.create(scene, undefined); // Uses embedded materials
// Mesh with override material
const meshWithOverride = new Mesh("model.dae", scale);
meshWithOverride.create(scene, customMaterial); // Overrides embedded materials
Error Handling
File Loading Errors
const mesh = new Mesh("missing_file.dae", scale);
mesh.setLoadCompleteCallback(() => {
if (mesh.meshes && mesh.meshes.length > 0) {
console.log("Mesh loaded successfully");
} else {
console.error("Failed to load mesh");
}
});
Disposal and Cleanup
// Always dispose geometries to prevent memory leaks
geometry.dispose();
// For meshes, this cleans up:
// - Loaded mesh data
// - Transform nodes
// - Associated materials (if not shared)
// - Animation data
Integration with Robot Components
Geometries are typically used within Visual components:
// Part of robot loading process
const link = new Link();
const visual = new Visual();
// Choose appropriate geometry
visual.geometry = new Box(1, 0.5, 0.3); // Simple box
// OR
visual.geometry = new Mesh("complex_part.dae", scale); // Complex mesh
link.visuals.push(visual);
This creates a complete chain: Robot → Link → Visual → Geometry → Babylon.js Mesh