### Install MARTINI Package Source: https://github.com/mapbox/martini/blob/main/README.md Provides the command to install the MARTINI JavaScript library using npm. ```bash npm install @mapbox/martini ``` -------------------------------- ### Performance Benchmarking Mesh Generation (JavaScript) Source: https://context7.com/mapbox/martini/llms.txt Demonstrates generating multiple meshes at different error levels for performance testing and level-of-detail systems. It simulates realistic terrain data and measures the time taken for initialization, tile creation, and mesh generation at various error thresholds. Requires the Martini library. ```javascript import Martini from '@mapbox/martini'; // Create sample terrain data const gridSize = 513; // 512x512 terrain const terrain = new Float32Array(gridSize * gridSize); for (let y = 0; y < gridSize; y++) { for (let x = 0; x < gridSize; x++) { // Simulate realistic terrain with noise terrain[y * gridSize + x] = Math.sin(x * 0.02) * 200 + Math.cos(y * 0.03) * 150 + Math.random() * 50; } } // Benchmark initialization console.time('init tileset'); const martini = new Martini(gridSize); console.timeEnd('init tileset'); // Benchmark tile creation console.time('create tile'); const tile = martini.createTile(terrain); console.timeEnd('create tile'); // Benchmark mesh generation at various error levels const errorLevels = [0, 1, 5, 10, 20, 50, 100, 200, 500]; for (const maxError of errorLevels) { console.time(`mesh error=${maxError}`); const mesh = tile.getMesh(maxError); console.timeEnd(`mesh error=${maxError}`); console.log(` -> ${mesh.triangles.length / 3} triangles, ${mesh.vertices.length / 2} vertices`); } ``` -------------------------------- ### Initialize Martini Mesh Generator Source: https://context7.com/mapbox/martini/llms.txt Creates a new Martini mesh generator instance for a specific grid size. The grid size must be 2^k+1 (e.g., 257, 513, 1025) to work with the RTIN algorithm's binary tree structure. This instance can be reused to create multiple tiles. Invalid grid sizes will throw an error. ```javascript import Martini from '@mapbox/martini'; // Initialize mesh generator for 257x257 grid (256x256 terrain + 1) const martini = new Martini(257); // For larger, more detailed terrain (512x512 terrain) const martiniLarge = new Martini(513); // For smaller terrain (128x128 terrain) const martiniSmall = new Martini(129); // Invalid grid size will throw an error try { const invalid = new Martini(256); // Error: Expected grid size to be 2^n+1 } catch (e) { console.error(e.message); // "Expected grid size to be 2^n+1, got 256." } ``` -------------------------------- ### Create Tile from Terrain Data Source: https://context7.com/mapbox/martini/llms.txt Creates a Tile instance from terrain height data. The terrain parameter must be an array-like structure (Array, Float32Array, etc.) with exactly gridSize × gridSize elements, where each element represents the elevation at that grid point. Incorrect terrain sizes will throw an error. ```javascript import Martini from '@mapbox/martini'; // Create terrain data (257x257 = 66049 height values) const gridSize = 257; const terrain = new Float32Array(gridSize * gridSize); // Fill with sample elevation data (sinusoidal hills) for (let y = 0; y < gridSize; y++) { for (let x = 0; x < gridSize; x++) { const index = y * gridSize + x; terrain[index] = Math.sin(x * 0.05) * Math.cos(y * 0.05) * 100 + 500; } } // Initialize martini and create tile const martini = new Martini(gridSize); const tile = martini.createTile(terrain); // Tile is now ready for mesh generation console.log('Tile created successfully'); // Wrong terrain size will throw an error try { const wrongTerrain = new Float32Array(100); martini.createTile(wrongTerrain); } catch (e) { console.error(e.message); // "Expected terrain data of length 66049 (257 x 257), got 100." } ``` -------------------------------- ### Convert Mapbox Terrain RGB to Height Data and Generate Mesh (JavaScript) Source: https://context7.com/mapbox/martini/llms.txt Demonstrates converting Mapbox Terrain-RGB encoded PNG images into height data compatible with MARTINI. It includes a helper function to decode the Mapbox encoding and then generates a mesh from the decoded terrain. Dependencies include 'fs', 'pngjs', and '@mapbox/martini'. ```javascript import fs from 'fs'; import {PNG} from 'pngjs'; import Martini from '@mapbox/martini'; // Helper function to decode Mapbox Terrain-RGB format function mapboxTerrainToGrid(png) { const gridSize = png.width + 1; const terrain = new Float32Array(gridSize * gridSize); const tileSize = png.width; // Decode terrain values from RGB for (let y = 0; y < tileSize; y++) { for (let x = 0; x < tileSize; x++) { const k = (y * tileSize + x) * 4; const r = png.data[k + 0]; const g = png.data[k + 1]; const b = png.data[k + 2]; terrain[y * gridSize + x] = (r * 256 * 256 + g * 256.0 + b) / 10.0 - 10000.0; } } // Backfill right and bottom borders (required for 2^k+1 grid) for (let x = 0; x < gridSize - 1; x++) { terrain[gridSize * (gridSize - 1) + x] = terrain[gridSize * (gridSize - 2) + x]; } for (let y = 0; y < gridSize; y++) { terrain[gridSize * y + gridSize - 1] = terrain[gridSize * y + gridSize - 2]; } return terrain; } // Load and process terrain tile const png = PNG.sync.read(fs.readFileSync('./terrain-tile.png')); const terrain = mapboxTerrainToGrid(png); // Generate mesh const martini = new Martini(png.width + 1); const tile = martini.createTile(terrain); const mesh = tile.getMesh(30); console.log(`Vertices: ${mesh.vertices.length / 2}`); console.log(`Triangles: ${mesh.triangles.length / 3}`); ``` -------------------------------- ### Generate Terrain Mesh with MARTINI (JavaScript) Source: https://github.com/mapbox/martini/blob/main/README.md Demonstrates how to use the MARTINI JavaScript library to generate a terrain mesh. It initializes the generator, creates a tile from terrain data, and then retrieves a mesh with a specified error tolerance. ```javascript import Martini from '@mapbox/martini'; // set up mesh generator for a certain 2^k+1 grid size const martini = new Martini(257); // generate RTIN hierarchy from terrain data (an array of size^2 length) const tile = martini.createTile(terrain); // get a mesh (vertices and triangles indices) for a 10m error const mesh = tile.getMesh(10); ``` -------------------------------- ### Generate Terrain Mesh with getMesh Source: https://context7.com/mapbox/martini/llms.txt Generates a triangular mesh from a tile with a specified maximum error threshold. Lower error values produce more detailed meshes with more triangles, while higher values produce simpler meshes. The method returns an object containing vertices and triangles, suitable for WebGL rendering. ```javascript import Martini from '@mapbox/martini'; // Create sample terrain const gridSize = 257; const terrain = new Float32Array(gridSize * gridSize); for (let i = 0; i < terrain.length; i++) { terrain[i] = Math.random() * 1000; // Random elevation 0-1000m } const martini = new Martini(gridSize); const tile = martini.createTile(terrain); // Generate mesh with 10 meter max error (high detail) const highDetailMesh = tile.getMesh(10); console.log(`High detail: ${highDetailMesh.vertices.length / 2} vertices, ${highDetailMesh.triangles.length / 3} triangles`); // Generate mesh with 100 meter max error (low detail) const lowDetailMesh = tile.getMesh(100); console.log(`Low detail: ${lowDetailMesh.vertices.length / 2} vertices, ${lowDetailMesh.triangles.length / 3} triangles`); // Generate mesh with 0 error (maximum detail) const maxDetailMesh = tile.getMesh(0); console.log(`Max detail: ${maxDetailMesh.vertices.length / 2} vertices, ${maxDetailMesh.triangles.length / 3} triangles`); // Access mesh data for WebGL rendering const mesh = tile.getMesh(50); // mesh.vertices: Uint16Array of [x0, y0, x1, y1, x2, y2, ...] coordinates // mesh.triangles: Uint32Array of [a0, b0, c0, a1, b1, c1, ...] vertex indices // Convert to 3D vertices for WebGL const positions = new Float32Array(mesh.vertices.length / 2 * 3); for (let i = 0; i < mesh.vertices.length / 2; i++) { const x = mesh.vertices[i * 2]; const y = mesh.vertices[i * 2 + 1]; positions[i * 3] = x; positions[i * 3 + 1] = y; positions[i * 3 + 2] = terrain[y * gridSize + x]; // Height from terrain } console.log(`3D positions ready for WebGL: ${positions.length / 3} vertices`); ``` -------------------------------- ### Update Tile Mesh After Terrain Modification (JavaScript) Source: https://context7.com/mapbox/martini/llms.txt Recalculates the error map for a tile after its terrain data has been modified. This ensures that subsequent calls to getMesh reflect the updated terrain. It requires the Martini library. ```javascript import Martini from '@mapbox/martini'; const gridSize = 257; const terrain = new Float32Array(gridSize * gridSize); // Initial flat terrain terrain.fill(100); const martini = new Martini(gridSize); const tile = martini.createTile(terrain); // Get initial mesh (will be very simple since terrain is flat) const flatMesh = tile.getMesh(10); console.log(`Flat terrain: ${flatMesh.triangles.length / 3} triangles`); // Modify terrain - add a mountain in the center const centerX = Math.floor(gridSize / 2); const centerY = Math.floor(gridSize / 2); for (let y = 0; y < gridSize; y++) { for (let x = 0; x < gridSize; x++) { const dx = x - centerX; const dy = y - centerY; const dist = Math.sqrt(dx * dx + dy * dy); if (dist < 50) { terrain[y * gridSize + x] = 100 + (50 - dist) * 20; // Mountain peak } } } // Update tile to recalculate errors tile.update(); // Get new mesh reflecting the mountain const mountainMesh = tile.getMesh(10); console.log(`With mountain: ${mountainMesh.triangles.length / 3} triangles`); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.