### Install meshoptimizer target Source: https://github.com/zeux/meshoptimizer/blob/master/CMakeLists.txt Installs the meshoptimizer target, including runtime, library, archive, and include files, based on the MESHOPT_INSTALL flag. This configures the installation paths according to standard CMake directories. ```cmake install(TARGETS meshoptimizer EXPORT meshoptimizerTargets COMPONENT meshoptimizer RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) ``` -------------------------------- ### Install meshoptimizer header file Source: https://github.com/zeux/meshoptimizer/blob/master/CMakeLists.txt Installs the main meshoptimizer header file (meshoptimizer.h) to the include directory. ```cmake install(FILES src/meshoptimizer.h COMPONENT meshoptimizer DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) ``` -------------------------------- ### meshopt_Stream Example Source: https://github.com/zeux/meshoptimizer/blob/master/_autodocs/types.md Example demonstrating how to initialize meshopt_Stream structures for interleaved vertex attributes like positions, normals, and UVs. ```c meshopt_Stream streams[] = { {&positions[0].x, sizeof(float) * 3, sizeof(Vertex)}, {&normals[0].x, sizeof(float) * 3, sizeof(Vertex)}, {&texcoords[0].u, sizeof(float) * 2, sizeof(Vertex)}, }; ``` -------------------------------- ### Install CMake package configuration files Source: https://github.com/zeux/meshoptimizer/blob/master/CMakeLists.txt Installs the generated meshoptimizerConfig.cmake and meshoptimizerConfigVersion.cmake files. These files are essential for CMake's package management system to locate and use the installed meshoptimizer library. ```cmake install(FILES ${CMAKE_CURRENT_BINARY_DIR}/meshoptimizerConfig.cmake ${CMAKE_CURRENT_BINARY_DIR}/meshoptimizerConfigVersion.cmake COMPONENT meshoptimizer DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/meshoptimizer) ``` -------------------------------- ### Three.js and meshoptimizer Setup Source: https://github.com/zeux/meshoptimizer/blob/master/demo/index.html Initializes the Three.js scene, camera, renderer, and lighting. Sets up the GLTFLoader with the meshoptDecoder for efficient model loading. ```javascript import * as THREE from 'three'; import { GLTFLoader } from 'three-examples/loaders/GLTFLoader.js'; import { MeshoptDecoder } from '../js/meshopt_decoder.mjs'; var container; var camera, scene, renderer, mixer, timer; var windowHalfX = window.innerWidth / 2; var windowHalfY = window.innerHeight / 2; init(); animate(); function init() { container = document.createElement('div'); document.body.appendChild(container); camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.01, 100); camera.position.y = 1.0; camera.position.z = 3.0; scene = new THREE.Scene(); scene.background = new THREE.Color(0x300a24); var ambientLight = new THREE.AmbientLight(0xcccccc, 1); scene.add(ambientLight); var pointLight = new THREE.PointLight(0xffffff, 4); pointLight.position.set(3, 3, 0); pointLight.decay = 0.5; camera.add(pointLight); scene.add(camera); var onProgress = function (xhr) { }; var onError = function (e) { console.log(e); }; var loader = new GLTFLoader(); loader.setMeshoptDecoder(MeshoptDecoder); loader.load( 'pirate.glb', function (gltf) { var bbox = new THREE.Box3().setFromObject(gltf.scene); var scale = 2 / (bbox.max.y - bbox.min.y); gltf.scene.scale.set(scale, scale, scale); gltf.scene.position.set(0, 0, 0); scene.add(gltf.scene); mixer = new THREE.AnimationMixer(gltf.scene); if (gltf.animations.length) { mixer.clipAction(gltf.animations[gltf.animations.length - 1]).play(); } }, onProgress, onError ); renderer = new THREE.WebGLRenderer(); renderer.setPixelRatio(window.devicePixelRatio); renderer.setSize(window.innerWidth, window.innerHeight); container.appendChild(renderer.domElement); window.addEventListener('resize', onWindowResize, false); timer = new THREE.Timer(); timer.connect(document); } function onWindowResize() { windowHalfX = window.innerWidth / 2; windowHalfY = window.innerHeight / 2; camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); } function animate(timestamp) { timer.update(timestamp); if (mixer) { mixer.update(timer.getDelta()); } requestAnimationFrame(animate); render(); } function render() { renderer.render(scene, camera); } ``` -------------------------------- ### Install gltfpack target Source: https://github.com/zeux/meshoptimizer/blob/master/CMakeLists.txt Installs the gltfpack target if MESHOPT_BUILD_GLTFPACK is enabled. This places the executable in the runtime destination directory. ```cmake if(MESHOPT_BUILD_GLTFPACK) install(TARGETS gltfpack RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) endif() ``` -------------------------------- ### Install meshoptimizer CMake export files Source: https://github.com/zeux/meshoptimizer/blob/master/CMakeLists.txt Installs the CMake export files for the meshoptimizer targets, enabling package configuration for other CMake projects. ```cmake install(EXPORT meshoptimizerTargets COMPONENT meshoptimizer DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/meshoptimizer NAMESPACE meshoptimizer::) ``` -------------------------------- ### Install PDB files on MSVC Source: https://github.com/zeux/meshoptimizer/blob/master/CMakeLists.txt Conditionally installs Program Database (PDB) files for debug symbols on MSVC builds. This applies to the meshoptimizer and gltfpack targets if they are not static libraries. ```cmake if(MSVC) set(PDB_TARGETS meshoptimizer) if(MESHOPT_BUILD_GLTFPACK) list(APPEND PDB_TARGETS gltfpack) endif() foreach(TARGET ${PDB_TARGETS}) get_target_property(TARGET_TYPE ${TARGET} TYPE) if(NOT ${TARGET_TYPE} STREQUAL "STATIC_LIBRARY") install(FILES $ COMPONENT meshoptimizer DESTINATION ${CMAKE_INSTALL_BINDIR} OPTIONAL) endif() endforeach(TARGET) endif() ``` -------------------------------- ### Await MeshoptEncoder.ready Source: https://github.com/zeux/meshoptimizer/blob/master/_autodocs/javascript-api.md Always await MeshoptEncoder.ready before using encoder functions to ensure the WebAssembly module is loaded. This example shows awaiting readiness before encoding a vertex buffer. ```javascript await MeshoptEncoder.ready; const encoded = MeshoptEncoder.encodeVertexBuffer(...); ``` -------------------------------- ### meshopt_Bounds Culling Usage Source: https://github.com/zeux/meshoptimizer/blob/master/_autodocs/types.md Provides example code for performing backface culling using the normal cone and frustum culling using the bounding sphere. Demonstrates usage with and without a cone apex for perspective culling. ```c // Orthographic backface culling: if (dot(view_direction, cone_axis) >= cone_cutoff) reject_cluster(); // Perspective backface culling (with apex): if (dot(normalize(cone_apex - camera_pos), cone_axis) >= cone_cutoff) reject_cluster(); // Without apex (uses sphere center): if (dot(center - camera_pos, cone_axis) >= cone_cutoff * length(center - camera_pos) + radius) reject_cluster(); ``` -------------------------------- ### MeshoptDecoder Asynchronous Decoding Setup Source: https://github.com/zeux/meshoptimizer/blob/master/js/README.md Configures the number of Web Workers to use for asynchronous decoding. This function should be called once at startup. ```typescript useWorkers: (count: number) => void; ``` -------------------------------- ### C/C++ API Reference Source: https://github.com/zeux/meshoptimizer/blob/master/_autodocs/MANIFEST.txt Detailed documentation for the C/C++ API, including vertex remapping, cache optimization, overdraw optimization, vertex fetch optimization, shadow index buffers, and geometry generation. This section covers over 80 exported functions with parameter tables, return value documentation, and code examples. ```APIDOC ## C/C++ API Overview This section details the C/C++ API for mesh optimization. ### Core Optimization Functions - Vertex remapping and deduplication - Cache optimization (adaptive, FIFO, strip) - Overdraw optimization - Vertex fetch optimization - Shadow index buffers and filtering - **Total Exported Functions:** 15+ ### Advanced Features - Geometry generation (adjacency, tessellation, provoking) - Index/vertex compression and encoding - Vertex filters (Oct, Quat, Exp, Color) - Stripification/unstripification - **Total Exported Functions:** 22+ ### Simplification - Mesh simplification (topology-preserving) - Simplification with attributes - Destructive simplification with updates - Sloppy and pruning simplification - Point cloud simplification - **Total Exported Functions:** 7 ### Meshlets - Meshlet building (quality, scan, flex, spatial) - Meshlet optimization - Cluster bounds (sphere, cone) - Cluster partitioning - **Total Exported Functions:** 12+ ### Analysis - Vertex cache analysis (ACMR, ATVR) - Vertex fetch analysis (overfetch) - Overdraw analysis - Coverage analysis - Spatial operations (sorting, clustering) - **Total Exported Functions:** 7 ### Quantization - Half-precision float quantization - Float mantissa reduction - Fixed-point quantization (unorm, snorm) - Position quantization - Memory management - **Total Exported Functions:** 6+ **Note:** All 80+ exported functions are documented with parameter tables, return values, and code examples. ``` -------------------------------- ### Write meshoptimizerConfig.cmake Source: https://github.com/zeux/meshoptimizer/blob/master/CMakeLists.txt Writes the meshoptimizerConfig.cmake file, which is used by CMake to find and configure the installed meshoptimizer package. It includes the generated Targets.cmake file. ```cmake file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/meshoptimizerConfig.cmake "include(\"${CMAKE_CURRENT_LIST_DIR}/meshoptimizerTargets.cmake\")\n") ``` -------------------------------- ### Initialize Scene and Renderer Source: https://github.com/zeux/meshoptimizer/blob/master/demo/simplify.html Sets up the main container, camera, and timer for the 3D scene. Handles window resizing to update renderer sizes. ```javascript function init() { container = document.createElement('div'); document.body.appendChild(container); gridContainer = document.getElementById('grid-container'); // Create a single camera shared by all views camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.y = 1.0; camera.position.z = 3.0; timer = new THREE.Timer(); timer.connect(document); window.addEventListener('resize', updateRendererSizes, false); } ``` -------------------------------- ### Build gltfpack with Texture Compression Support Source: https://github.com/zeux/meshoptimizer/blob/master/gltf/README.md Clone the necessary repositories for basis_universal and libwebp, then use CMake to configure the build with the specified paths. Finally, build the gltfpack target. ```bash git clone -b gltfpack https://github.com/zeux/basis_universal git clone https://github.com/webmproject/libwebp cmake . -DMESHOPT_BUILD_GLTFPACK=ON -DMESHOPT_GLTFPACK_BASISU_PATH=basis_universal -DMESHOPT_GLTFPACK_LIBWEBP_PATH=libwebp -DCMAKE_BUILD_TYPE=Release cmake --build . --target gltfpack --config Release ``` -------------------------------- ### Initialize Scene and Renderer Source: https://github.com/zeux/meshoptimizer/blob/master/demo/simplify.html Sets up the Three.js scene, renderer, lighting, and controls. This is boilerplate code for a Three.js application. ```javascript var statsLabel = document.createElement('div'); statsLabel.className = 'stats-label'; rendererContainer.appendChild(statsLabel); // Initialize stats for this view viewStats.push({ triangles: 0, vertices: 0, error: 0, ratio: 0, label: statsLabel, }); // Create renderer var renderer = new THREE.WebGLRenderer(); renderer.setPixelRatio(window.devicePixelRatio); rendererContainer.appendChild(renderer.domElement); renderers.push(renderer); // Create scene var scene = new THREE.Scene(); scene.background = new THREE.Color(0x300a24); scenes.push(scene); // Add lighting var ambientLight = new THREE.AmbientLight(0xcccccc, 1); scene.add(ambientLight); var pointLightR = new THREE.PointLight(0xffffff, 4); pointLightR.position.set(3, 3, 0); pointLightR.decay = 0.5; scene.add(pointLightR); var pointLightL = new THREE.PointLight(0xffffff, 1); pointLightL.position.set(-3, 5, 0); pointLightL.decay = 0.5; scene.add(pointLightL); // Create controls var control = new OrbitControls(camera, renderer.domElement); control.addEventListener('change', updateAutoLod); controls.push(control); // Set null placeholders models.push(null); mixers.push(null); // Adjust renderer size updateRendererSizes(); // Update label clickability for all views updateLabelsClickability(); ``` -------------------------------- ### Get Mesh Error Scaling Factor Source: https://github.com/zeux/meshoptimizer/blob/master/_autodocs/api-reference-simplification.md Calculates the scale factor used to convert between relative and absolute error for mesh simplification. Multiply the result error by this value to get object-space error. ```c float meshopt_simplifyScale( const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride ); ``` ```c++ float scale = meshopt_simplifyScale(&vertices[0].x, vertex_count, sizeof(Vertex)); float absolute_error = relative_error * scale; ``` -------------------------------- ### Importing Libraries for meshoptimizer Demo Source: https://github.com/zeux/meshoptimizer/blob/master/demo/simplify.html Imports necessary libraries for 3D rendering (Three.js), model loading (GLTFLoader, OBJLoader), controls (OrbitControls), geometry utilities, meshopt decoders and simplifiers, and a GUI library (lil-gui). ```javascript import * as THREE from 'three'; import { GLTFLoader } from 'three-examples/loaders/GLTFLoader.js'; import { OBJLoader } from 'three-examples/loaders/OBJLoader.js'; import { OrbitControls } from 'three-examples/controls/OrbitControls.js'; import { mergeGeometries, mergeVertices } from 'three-examples/utils/BufferGeometryUtils.js'; import { MeshoptDecoder } from '../js/meshopt_decoder.mjs'; import { MeshoptSimplifier } from '../js/meshopt_simplifier.js'; import { GUI } from 'lil-gui'; ``` -------------------------------- ### Get Bounding Box Radius Source: https://github.com/zeux/meshoptimizer/blob/master/demo/simplify.html Calculates the radius of the bounding box for a given 3D object. ```javascript function getRadius(obj) { var box = new THREE.Box3().setFromObject(obj); return box.max.sub(box.min).length() / 2; } ``` -------------------------------- ### Get Compile-Time Version Source: https://github.com/zeux/meshoptimizer/blob/master/_autodocs/api-reference-quantization.md Retrieves the compile-time version constant for meshoptimizer. The format is version major*1000 + minor*10 + patch. ```c #define MESHOPTIMIZER_VERSION 1010 /* version major*1000 + minor*10 + patch */ ``` -------------------------------- ### Basic Optimization Pipeline in C++ Source: https://github.com/zeux/meshoptimizer/blob/master/_autodocs/overview.md This snippet demonstrates a common pipeline for optimizing a mesh using the meshoptimizer library. It includes steps for vertex remapping, vertex cache optimization, overdraw optimization, vertex fetch optimization, quantization to half-precision, and compression. ```cpp // 1. Remove duplicate vertices std::vector remap(vertex_count); size_t unique = meshopt_generateVertexRemap(&remap[0], NULL, 0, &vertices[0], vertex_count, sizeof(Vertex)); std::vector unique_vertices(unique); meshopt_remapVertexBuffer(&unique_vertices[0], &vertices[0], vertex_count, sizeof(Vertex), &remap[0]); std::vector unique_indices(index_count); meshopt_remapIndexBuffer(&unique_indices[0], &indices[0], index_count, &remap[0]); // 2. Optimize vertex cache std::vector cache_opt(index_count); meshopt_optimizeVertexCache(&cache_opt[0], &unique_indices[0], index_count, unique); // 3. Optimize for overdraw std::vector overdraw_opt(index_count); meshopt_optimizeOverdraw(&overdraw_opt[0], &cache_opt[0], index_count, &unique_vertices[0].x, unique, sizeof(Vertex), 1.05f); // 4. Optimize vertex fetch std::vector fetch_opt(unique); unique = meshopt_optimizeVertexFetch(&fetch_opt[0], &overdraw_opt[0], index_count, &unique_vertices[0], unique, sizeof(Vertex)); // 5. Quantize (position to half-precision) for (auto& v : fetch_opt) { v.x = meshopt_dequantizeHalf(meshopt_quantizeHalf(v.x)); v.y = meshopt_dequantizeHalf(meshopt_quantizeHalf(v.y)); v.z = meshopt_dequantizeHalf(meshopt_quantizeHalf(v.z)); } // 6. Compress size_t vbuf_bound = meshopt_encodeVertexBufferBound(unique, sizeof(Vertex)); std::vector vbuf(vbuf_bound); size_t vbuf_size = meshopt_encodeVertexBuffer(&vbuf[0], vbuf_bound, &fetch_opt[0], unique, sizeof(Vertex)); size_t ibuf_bound = meshopt_encodeIndexBufferBound(index_count, unique); std::vector ibuf(ibuf_bound); size_t ibuf_size = meshopt_encodeIndexBuffer(&ibuf[0], ibuf_bound, &overdraw_opt[0], index_count); ``` -------------------------------- ### Build Meshlets using meshopt_buildMeshletsScan Source: https://github.com/zeux/meshoptimizer/blob/master/_autodocs/api-reference-meshlets.md Builds meshlets using a greedy approach, which is faster but results in lower quality clustering compared to meshopt_buildMeshlets. Suitable for scenarios where load-time performance is critical. ```c size_t meshopt_buildMeshletsScan( struct meshopt_Meshlet* meshlets, unsigned int* meshlet_vertices, unsigned char* meshlet_triangles, const unsigned int* indices, size_t index_count, size_t vertex_count, size_t max_vertices, size_t max_triangles ); ``` -------------------------------- ### Clone meshoptimizer Repository Source: https://github.com/zeux/meshoptimizer/blob/master/README.md Use this command to download the latest release of the meshoptimizer library from GitHub. ```bash git clone -b v1.1 https://github.com/zeux/meshoptimizer.git ``` -------------------------------- ### Compute Bounding Sphere Source: https://github.com/zeux/meshoptimizer/blob/master/_autodocs/api-reference-meshlets.md Computes the bounding sphere for a set of points or existing spheres. Use this to get an encompassing sphere for a collection of data points. ```c struct meshopt_Bounds meshopt_computeSphereBounds( const float* positions, size_t count, size_t positions_stride, const float* radii, size_t radii_stride ); ``` -------------------------------- ### Decode Vertex Buffer Example Source: https://github.com/zeux/meshoptimizer/blob/master/_autodocs/javascript-api.md Decode vertex data that was previously encoded by MeshoptEncoder.encodeVertexBuffer. Ensure the target buffer is correctly sized based on vertex count and size. ```javascript const decoded = new Uint8Array(vertexCount * vertexSize); MeshoptDecoder.decodeVertexBuffer(decoded, vertexCount, vertexSize, encoded); ``` -------------------------------- ### Build Meshlet Data with meshopt_buildMeshlets Source: https://github.com/zeux/meshoptimizer/blob/master/README.md Generates meshlet data from vertex and index buffers. Adjust `max_vertices` and `max_triangles` based on GPU hardware recommendations (e.g., 64/126 for NVIDIA). `cone_weight` balances culling efficiency; use 0 if cone culling is not needed. ```c++ const size_t max_vertices = 64; const size_t max_triangles = 126; // note: in v0.25 or prior, max_triangles needs to be divisible by 4 const float cone_weight = 0.0f; size_t max_meshlets = meshopt_buildMeshletsBound(indices.size(), max_vertices, max_triangles); std::vector meshlets(max_meshlets); std::vector meshlet_vertices(indices.size()); std::vector meshlet_triangles(indices.size()); // note: in v0.25 or prior, use indices.size() + max_meshlets * 3 size_t meshlet_count = meshopt_buildMeshlets(meshlets.data(), meshlet_vertices.data(), meshlet_triangles.data(), indices.data(), indices.size(), &vertices[0].x, vertices.size(), sizeof(Vertex), max_vertices, max_triangles, cone_weight); ``` -------------------------------- ### Cone Culling Rejection Condition Source: https://github.com/zeux/meshoptimizer/blob/master/README.md Example condition for rejecting a meshlet based on cone culling. This checks if the camera is outside the cone defined by the meshlet's bounding cone. ```c++ if (dot(normalize(cone_apex - camera_position), cone_axis) >= cone_cutoff) reject(); ``` -------------------------------- ### Handle UV Mirroring with Vertex Splitting Source: https://github.com/zeux/meshoptimizer/blob/master/README.md Efficiently splits vertices along mirror edges to ensure correct tangent spaces when UV mirroring is present. This process involves iterating through triangle corners, finding matching tangents, and creating new vertices with appropriate tangent data if necessary. ```c++ // seed each vertex with one of its corner tangents; the loop below fixes any mismatches for (size_t i = 0; i < indices.size(); ++i) vertices[indices[i]].tangent = tangents[i]; std::vector splits(vertices.size(), ~0u); for (size_t i = 0; i < indices.size(); ++i) { // walk the chain of split copies looking for a vertex whose tangent matches unsigned int v = indices[i]; while (v != ~0u && vertices[v].tangent != tangents[i]) v = splits[v]; // no match in chain: append a new split copy with the target tangent and chain it if (v == ~0u) { v = unsigned(vertices.size()); vertices.push_back(vertices[indices[i]]); vertices[v].tangent = tangents[i]; splits.push_back(splits[indices[i]]); splits[indices[i]] = v; } indices[i] = v; } ``` -------------------------------- ### Get Mesh Error Scaling Factor Source: https://github.com/zeux/meshoptimizer/blob/master/_autodocs/javascript-api.md Calculates the error scaling factor for a mesh based on vertex positions. This is useful for normalizing error metrics across different meshes. ```typescript getScale( vertex_positions: Float32Array, vertex_positions_stride: number ): number ``` -------------------------------- ### Load and Simplify glTF/GLB Models Source: https://github.com/zeux/meshoptimizer/blob/master/demo/simplify.html Loads glTF or GLB files using GLTFLoader and applies meshoptDecoder for optimization. Includes animation handling and calls a simplification function. ```javascript if (ext == 'gltf' || ext == 'glb') { var loader = new GLTFLoader(); loader.setMeshoptDecoder(MeshoptDecoder); loader.load( path, function (gltf) { models[viewIndex] = gltf.scene; center(models[viewIndex]); scenes[viewIndex].add(models[viewIndex]); mixers[viewIndex] = new THREE.AnimationMixer(models[viewIndex]); if (gltf.animations.length) { mixers[viewIndex].clipAction(gltf.animations[gltf.animations.length - 1]).play(); } // Apply simplification simplify(); }, onProgress, onError ); } ``` -------------------------------- ### Build Meshlets using meshopt_buildMeshlets Source: https://github.com/zeux/meshoptimizer/blob/master/_autodocs/api-reference-meshlets.md Clusters mesh into meshlets for mesh shading, optimizing for vertex reuse and cone culling. Use this for general mesh shading applications. ```c++ size_t max_meshlets = meshopt_buildMeshletsBound(index_count, 64, 126); std::vector meshlets(max_meshlets); std::vector meshlet_verts(index_count); std::vector meshlet_tris(index_count); size_t meshlet_count = meshopt_buildMeshlets(meshlets.data(), meshlet_verts.data(), meshlet_tris.data(), indices.data(), index_count, &vertices[0].x, vertex_count, sizeof(Vertex), 64, 126, 0.25f); meshlets.resize(meshlet_count); const auto& last = meshlets.back(); meshlet_verts.resize(last.vertex_offset + last.vertex_count); meshlet_tris.resize(last.triangle_offset + last.triangle_count * 3); ``` -------------------------------- ### Creating a New View Source: https://github.com/zeux/meshoptimizer/blob/master/demo/simplify.html Creates a new renderer container and label for a given index and name. This function appends the container to the grid and sets up the initial label with the file name. ```javascript function createView(index, name) { // Create renderer container var rendererContainer = document.createElement('div'); rendererContainer.className = 'renderer-container'; gridContainer.appendChild(rendererContainer); // Add label with file name var label = document.createElement('div'); label.className = 'renderer-label'; label.textContent = name; label.onclick ``` -------------------------------- ### Protecting UV Seams During Simplification Source: https://github.com/zeux/meshoptimizer/blob/master/README.md Generate a position remapping table and compare vertices to identify and protect UV seams using `meshopt_SimplifyVertex_Protect`. This allows fine-grained control over discontinuity preservation. ```c++ std::vector remap(vertices.size()); meshopt_generatePositionRemap(&remap[0], &vertices[0].px, vertices.size(), sizeof(Vertex)); std::vector locks(vertices.size()); for (size_t i = 0; i < vertices.size(); ++i) { unsigned int r = remap[i]; if (r != i && (vertices[r].tx != vertices[i].tx || vertices[r].ty != vertices[i].ty)) locks[i] |= meshopt_SimplifyVertex_Protect; // protect UV seams } ``` -------------------------------- ### Loading Multiple Files Source: https://github.com/zeux/meshoptimizer/blob/master/demo/simplify.html Handles the process of loading multiple files, clearing existing views, and setting up the grid layout based on the number of files. Each file is loaded into its own view. ```javascript function loadFiles(files) { // Clear existing views clearViews(); if (files.length > 0) { // Set grid columns based on the number of files, up to the max setting const columns = Math.min(files.length, settings.gridColumns); document.documentElement.style.setProperty('--grid-columns', columns); // Load each file into a separate view for (var i = 0; i < files.length; i++) { var file = files[i]; var uri = URL.createObjectURL(file); var ext = file.name.split('.').pop().toLowerCase(); createView(i, file.name); loadIntoView(i, uri, ext); } } } ``` -------------------------------- ### Build Meshlets with Flexible Triangle Limits Source: https://github.com/zeux/meshoptimizer/blob/master/README.md Builds meshlets using `meshopt_buildMeshletsFlex`, allowing for flexible triangle counts per meshlet. This function prioritizes spatial locality and can result in partially filled meshlets. ```c++ meshopt_buildMeshletsFlex(meshlets, meshlet_vertices, meshlet_triangles, m.vertex_count, m.triangle_count, vertex_positions, vertex_count, sizeof(Vertex), max_radius, min_triangles, max_triangles, split_factor); ``` -------------------------------- ### meshopt_buildMeshletsSpatial Source: https://github.com/zeux/meshoptimizer/blob/master/_autodocs/api-reference-meshlets.md Builds meshlets optimized for raytracing using Surface Area Heuristic (SAH). It uses recursive SAH-based spatial partitioning and allows a trade-off between fill rate and SAH efficiency. ```APIDOC ## meshopt_buildMeshletsSpatial ### Description Builds meshlets optimized for raytracing using Surface Area Heuristic (SAH). It uses recursive SAH-based spatial partitioning and allows a trade-off between fill rate and SAH efficiency. ### Signature ```c size_t meshopt_buildMeshletsSpatial( struct meshopt_Meshlet* meshlets, unsigned int* meshlet_vertices, unsigned char* meshlet_triangles, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t max_vertices, size_t min_triangles, size_t max_triangles, float fill_weight ); ``` ### Parameters #### Input - **indices** (const unsigned int*) - Required - Input indices. - **index_count** (size_t) - Required - Number of indices. - **vertex_positions** (const float*) - Required - Positions. - **vertex_count** (size_t) - Required - Vertex count. - **vertex_positions_stride** (size_t) - Required - Stride. - **max_vertices** (size_t) - Required - Max vertices per meshlet. - **min_triangles** (size_t) - Required - Min triangles per meshlet (recommend ≤max/4). - **max_triangles** (size_t) - Required - Max triangles per meshlet. - **fill_weight** (float) - Required - Fill vs SAH trade-off (0.5 typical). #### Output - **meshlets** (meshopt_Meshlet*) - Required - Output meshlet array. - **meshlet_vertices** (unsigned int*) - Required - Output vertex indices. - **meshlet_triangles** (unsigned char*) - Required - Output triangle data. ### Return Number of meshlets. ``` -------------------------------- ### Simplify Point Clouds with Color Support Source: https://github.com/zeux/meshoptimizer/blob/master/js/README.md Simplify point clouds, optionally preserving per-point colors. Use `color_weight` to balance color preservation with positional accuracy. The input colors should be in the [0..1] range for a weight of 1.0. ```typescript simplifyPoints: (vertex_positions: Float32Array, vertex_positions_stride: number, target_vertex_count: number, vertex_colors?: Float32Array, vertex_colors_stride?: number, color_weight?: number) => Uint32Array; ``` -------------------------------- ### JavaScript/WebAssembly API Reference Source: https://github.com/zeux/meshoptimizer/blob/master/_autodocs/MANIFEST.txt Documentation for the JavaScript API, providing bindings to WebAssembly functions for mesh optimization. Covers modules for encoding, decoding, simplification, cluster generation, and tangent generation. ```APIDOC ## JavaScript/WebAssembly API This section details the JavaScript API, which provides bindings to WebAssembly functions for mesh optimization. ### Modules - **MeshoptEncoder:** Handles reordering, compression, and filters. - **MeshoptDecoder:** Provides decompression and asynchronous capabilities. - **MeshoptSimplifier:** Offers mesh reduction functionalities. - **MeshoptClusterizer:** Enables meshlet generation. - **MeshoptTangents:** Used for tangent generation. **Total Documented Functions:** 40+ **Features:** - Complete type definitions (TypeScript) - Async/worker support documented ``` -------------------------------- ### Build Meshlets Optimized for Raytracing Source: https://github.com/zeux/meshoptimizer/blob/master/_autodocs/api-reference-meshlets.md Employ meshopt_buildMeshletsSpatial for meshlet generation optimized for raytracing using Surface Area Heuristic. This function produces more efficient clusters for ray intersection compared to rasterization-focused methods. ```c size_t meshopt_buildMeshletsSpatial( struct meshopt_Meshlet* meshlets, unsigned int* meshlet_vertices, unsigned char* meshlet_triangles, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t max_vertices, size_t min_triangles, size_t max_triangles, float fill_weight ); ``` -------------------------------- ### C: meshopt_simplifyWithUpdate - In-place Simplification with Updates Source: https://github.com/zeux/meshoptimizer/blob/master/_autodocs/api-reference-simplification.md Simplifies a mesh by updating vertex positions and attributes in-place for better quality. Requires calling meshopt_optimizeVertexFetch afterward and including texture coordinates in attributes to avoid distortion. ```c size_t meshopt_simplifyWithUpdate( unsigned int* indices, size_t index_count, float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, float* vertex_attributes, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, const unsigned char* vertex_lock, size_t target_index_count, float target_error, unsigned int options, float* result_error ); ``` -------------------------------- ### MeshoptEncoder.ready Source: https://github.com/zeux/meshoptimizer/blob/master/_autodocs/javascript-api.md Provides a promise that resolves when the WebAssembly module is loaded. This must be awaited before using any encoder functions. ```APIDOC ## MeshoptEncoder.ready ### Description Resolves when the WebAssembly module is loaded. Always await before using encoder functions. ### Type `Promise` ### Usage Example ```javascript await MeshoptEncoder.ready; const encoded = MeshoptEncoder.encodeVertexBuffer(...); ``` ``` -------------------------------- ### Load Model into View Source: https://github.com/zeux/meshoptimizer/blob/master/demo/simplify.html Removes existing model from the specified view, then loads a new model from the given path and extension. Handles progress and errors during loading. ```javascript function loadIntoView(viewIndex, path, ext) { if (models[viewIndex]) { scenes[viewIndex].remove(models[viewIndex]); models[viewIndex] = undefined; mixers[viewIndex] = undefined; } var onProgress = function (xhr) {}; var onError = function (e) { console.log(e); }; function center(model) { var bbox = new THREE.Box3().setFromObject(model); var scale = 2 / Math.max(bbox.max.x - bbox.min.x, bbox.max.y - bbox.min.y, bbox.max.z - bbox.min.z); var offset = new THREE.Vector3().addVectors( ``` -------------------------------- ### meshopt_buildMeshletsScan Source: https://github.com/zeux/meshoptimizer/blob/master/_autodocs/api-reference-meshlets.md Builds meshlets using a faster, greedy approach. This method is suitable when load-time performance is critical, though it may result in lower quality clustering compared to `meshopt_buildMeshlets`. ```APIDOC ## meshopt_buildMeshletsScan ### Description Builds meshlets using a greedy approach (faster, lower quality than buildMeshlets). Greedily packs consecutive cache-optimized triangles into meshlets. ### Signature ```c size_t meshopt_buildMeshletsScan( struct meshopt_Meshlet* meshlets, unsigned int* meshlet_vertices, unsigned char* meshlet_triangles, const unsigned int* indices, size_t index_count, size_t vertex_count, size_t max_vertices, size_t max_triangles ); ``` ### Parameters #### Input - **indices** (const unsigned int*) - Required - Input indices (should be vertex-cache optimized). - **index_count** (size_t) - Required - Number of indices. - **vertex_count** (size_t) - Required - Number of vertices. - **max_vertices** (size_t) - Required - Max vertices per meshlet. - **max_triangles** (size_t) - Required - Max triangles per meshlet. #### Output - **meshlets** (meshopt_Meshlet*) - Required - Output meshlet array. - **meshlet_vertices** (unsigned int*) - Required - Output vertex indices. - **meshlet_triangles** (unsigned char*) - Required - Output triangle data. ### Return Number of meshlets. ### Description Faster load-time alternative to meshopt_buildMeshlets but produces lower-quality clustering. ``` -------------------------------- ### Basic Operations API Source: https://github.com/zeux/meshoptimizer/blob/master/_autodocs/README.md Provides functions for vertex remapping, cache optimization, fetch optimization, shadow buffers, and index filtering. ```APIDOC ## Basic Operations API Reference This section details functions for core mesh optimization tasks. ### Functions - `meshopt_generateVertexRemap` - `meshopt_optimizeVertexCache` - `meshopt_optimizeVertexFetch` - `meshopt_generateShadowIndexBuffer` - `meshopt_filterIndexBuffer` ``` -------------------------------- ### Optimize Vertex Cache for FIFO - meshopt_optimizeVertexCacheFifo Source: https://github.com/zeux/meshoptimizer/blob/master/_autodocs/api-reference-core.md Optimizes index buffer for fixed-size FIFO vertex caches, offering faster execution but lower quality results than the adaptive algorithm. Suitable for rapid iteration. ```c++ std::vector optimized_indices(index_count); meshopt_optimizeVertexCacheFifo(&optimized_indices[0], &indices[0], index_count, vertex_count, cache_size); ``` -------------------------------- ### meshopt_generateTessellationIndexBuffer Source: https://github.com/zeux/meshoptimizer/blob/master/_autodocs/api-reference-advanced.md Generates an index buffer for PN-AEN tessellation with crack-free displacement. Each triangle is transformed into a 12-vertex patch, including original vertices, edge dominants, and corner dominants, for use with 12-point patch list topologies. ```APIDOC ## meshopt_generateTessellationIndexBuffer ### Description Generates index buffer for PN-AEN tessellation with crack-free displacement. Each triangle becomes a 12-vertex patch: vertices 0,1,2 (original), 3,4/5,6/7,8 (edge dominants), 9,10,11 (corner dominants). Use with 12-point patch list topology. ### Signature ```c void meshopt_generateTessellationIndexBuffer( unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride ); ``` ### Parameters #### Input - **indices** (const unsigned int*) - Required - Input index buffer. - **index_count** (size_t) - Required - Number of indices. - **vertex_positions** (const float*) - Required - Vertex positions. - **vertex_count** (size_t) - Required - Number of vertices. - **vertex_positions_stride** (size_t) - Required - Byte stride. #### Output - **destination** (unsigned int*) - Required - Output index buffer (index_count*4 elements). ### Return None (void). ``` -------------------------------- ### meshopt_Meshlet Usage Pattern Source: https://github.com/zeux/meshoptimizer/blob/master/_autodocs/types.md Illustrates how to iterate through meshlets and access their corresponding vertex and triangle data from global buffers. Useful for rendering or processing mesh data. ```c++ for (size_t i = 0; i < meshlet_count; ++i) { const meshopt_Meshlet& m = meshlets[i]; unsigned int* vertices = &meshlet_vertices[m.vertex_offset]; unsigned char* triangles = &meshlet_triangles[m.triangle_offset]; } ``` -------------------------------- ### meshopt_optimizeVertexCacheStrip Source: https://github.com/zeux/meshoptimizer/blob/master/_autodocs/api-reference-core.md Optimizes vertex cache for strip-like access patterns, aiming for better index compression. While it offers smaller triangle strips and better compression ratios, it results in inferior GPU cache efficiency compared to meshopt_optimizeVertexCache. ```APIDOC ## meshopt_optimizeVertexCacheStrip ### Description Optimizes vertex cache for strip-like access patterns, aiming for better index compression. While it offers smaller triangle strips and better compression ratios, it results in inferior GPU cache efficiency compared to meshopt_optimizeVertexCache. ### Signature ```c void meshopt_optimizeVertexCacheStrip( unsigned int* destination, const unsigned int* indices, size_t index_count, size_t vertex_count ); ``` ### Parameters #### Input/Output Parameters - **destination** (unsigned int*) - Required - Output index buffer - **indices** (const unsigned int*) - Required - Input index buffer - **index_count** (size_t) - Required - Number of indices - **vertex_count** (size_t) - Required - Number of vertices ### Example ```c++ std::vector optimized_indices(index_count); meshopt_optimizeVertexCacheStrip(&optimized_indices[0], &indices[0], index_count, vertex_count); ``` ``` -------------------------------- ### Conditional compilation for Basis Universal Source: https://github.com/zeux/meshoptimizer/blob/master/CMakeLists.txt Conditionally defines WITH_LIBWEBP_BASIS if MESHOPT_GLTFPACK_BASISU_PATH is set, otherwise links the 'imagedec' library. This handles Basis Universal integration for PNG/JPEG support. ```cmake if(NOT MESHOPT_GLTFPACK_BASISU_PATH STREQUAL "") target_compile_definitions(gltfpack PRIVATE WITH_LIBWEBP_BASIS) else() target_link_libraries(gltfpack imagedec) endif() ``` -------------------------------- ### Accessing Meshlet Data Buffers Source: https://github.com/zeux/meshoptimizer/blob/master/js/README.md Demonstrates how to access the raw packed buffers for meshlets, vertices, and triangles after generation. The meshlet count is also provided. ```javascript const buffers = MeshoptClusterizer.buildMeshlets(indices, positions, stride, /* args */); console.log(buffers.meshlets); console.log(buffers.vertices); console.log(buffers.triangles); console.log(buffers.meshletCount); ``` -------------------------------- ### Build Meshlets with Flexible Size Constraints Source: https://github.com/zeux/meshoptimizer/blob/master/_autodocs/api-reference-meshlets.md Use meshopt_buildMeshletsFlex to generate meshlets when you need to specify both minimum and maximum triangle counts. This function prioritizes spatial locality for hierarchical LOD. ```c size_t meshopt_buildMeshletsFlex( struct meshopt_Meshlet* meshlets, unsigned int* meshlet_vertices, unsigned char* meshlet_triangles, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t max_vertices, size_t min_triangles, size_t max_triangles, float cone_weight, float split_factor ); ``` -------------------------------- ### Generate Tessellation Index Buffer Source: https://github.com/zeux/meshoptimizer/blob/master/_autodocs/api-reference-advanced.md Generates an index buffer for PN-AEN tessellation with crack-free displacement. Each triangle becomes a 12-vertex patch. ```c void meshopt_generateTessellationIndexBuffer( unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride ); ``` -------------------------------- ### meshopt_unstripifyBound Source: https://github.com/zeux/meshoptimizer/blob/master/_autodocs/api-reference-advanced.md Computes the worst-case buffer size required for the `meshopt_unstripify` operation. ```APIDOC ## meshopt_unstripifyBound ### Description Compute worst-case buffer size for unstripification. ### Signature ```c size_t meshopt_unstripifyBound(size_t index_count); ``` ### Parameters #### Input - **index_count** (size_t) - Required - Number of input indices ### Return Maximum number of indices needed for output triangle list. ``` -------------------------------- ### MeshoptClusterizer.buildMeshletsSpatial Source: https://github.com/zeux/meshoptimizer/blob/master/_autodocs/javascript-api.md Builds meshlets optimized for raytracing by considering spatial distribution. It aims to create compact and efficient meshlet structures. ```APIDOC ## MeshoptClusterizer.buildMeshletsSpatial ### Description Build meshlets optimized for raytracing. This function clusters mesh data into meshlets with a focus on spatial coherence, making them suitable for raytracing acceleration structures. ### Method Signature ```typescript buildMeshletsSpatial( indices: Uint32Array, vertex_positions: Float32Array, vertex_positions_stride: number, max_vertices: number, min_triangles: number, max_triangles: number, fill_weight?: number ): MeshletBuffers ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **indices** (Uint32Array) - Input triangle indices. - **vertex_positions** (Float32Array) - Vertex positions (float). - **vertex_positions_stride** (number) - Byte stride for vertex positions. - **max_vertices** (number) - Maximum number of vertices allowed per meshlet. - **min_triangles** (number) - Minimum number of triangles required per meshlet. - **max_triangles** (number) - Maximum number of triangles allowed per meshlet. - **fill_weight** (number, optional) - Weight controlling how densely meshlets are filled. ### Response #### Success Response (200) - **buffers** (MeshletBuffers) - An object containing meshlet data, including meshlets, vertices, and triangles arrays. #### Response Example ```json { "meshlets": Meshlet[], "vertices": MeshletVertex[], "triangles": MeshletTriangle[] } ``` ``` -------------------------------- ### Simplify Point Cloud Source: https://github.com/zeux/meshoptimizer/blob/master/demo/simplify.html Simplifies a point cloud based on a target ratio and optional color weighting. Assumes position and color attributes are present. ```javascript function simplifyPoints(geo) { var positions = new Float32Array(geo.attributes.position.array); var colors = undefined; var target = Math.floor(geo.attributes.position.count * settings.ratio); if (settings.useAttributes && geo.attributes.color) { colors = new Float32Array(geo.attributes.color.array); } var pos_stride = geo.attributes.position instanceof THREE.InterleavedBufferAttribute ? geo.attributes.position.data.stride : 3; var col_stride = geo.attributes.color instanceof THREE.InterleavedBufferAttribute ? geo.attributes.color.data.stride : geo.attributes.color.itemSize; // note: we are converting source color array without normalization; if the color data is quantized, we need to divide by 255 to normalize it var colorScale = geo.attributes.color && geo.attributes.color.normalized ? 255 : 1; console.time('simplify'); var res = MeshoptSimplifier.simplifyPoints(positions, pos_stride, target, colors, col_stride, settings.colorWeight / colorScale); console.timeEnd('simplify'); console.log('simplified to', res.length); geo.index = new THREE.BufferAttribute(res, 1); } ``` -------------------------------- ### Basic glTF Conversion Source: https://github.com/zeux/meshoptimizer/blob/master/gltf/README.md Convert an input glTF file to an optimized GLB file. This is the most common usage for reducing file size and improving loading speed. ```bash gltfpack -i scene.gltf -o scene.glb ``` -------------------------------- ### Remap Index and Vertex Buffers Source: https://github.com/zeux/meshoptimizer/blob/master/README.md Generates new index and vertex buffers using a previously created remap table. This is done after generating the remap table. ```c++ meshopt_remapIndexBuffer(indices, NULL, index_count, &remap[0]); meshopt_remapVertexBuffer(vertices, &unindexed_vertices[0], unindexed_vertex_count, sizeof(Vertex), &remap[0]); ``` -------------------------------- ### C: meshopt_simplifySloppy - Fast Topology-Agnostic Simplification Source: https://github.com/zeux/meshoptimizer/blob/master/_autodocs/api-reference-simplification.md Performs fast mesh simplification without preserving topology, which can merge spatially close but topologically disjoint features. Useful for rapid iteration when seam preservation is not critical. ```c size_t meshopt_simplifySloppy( unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, const unsigned char* vertex_lock, size_t target_index_count, float target_error, float* result_error ); ``` -------------------------------- ### Loading Compressed glTF with Three.js Source: https://github.com/zeux/meshoptimizer/blob/master/gltf/README.md Load compressed glTF files in Three.js by setting the meshopt decoder. Requires Three.js r122+ and the meshopt_decoder module. ```javascript import { MeshoptDecoder } from './meshopt_decoder.mjs'; ... var loader = new GLTFLoader(); loader.setMeshoptDecoder(MeshoptDecoder); loader.load('pirate.glb', function (gltf) { scene.add(gltf.scene); }); ``` -------------------------------- ### Generate Vertex Fetch Remap Table (C++) Source: https://github.com/zeux/meshoptimizer/blob/master/_autodocs/api-reference-core.md Generates a remap table for vertex fetch optimization, useful for multi-stream vertex buffers. Does not reorder vertex data itself. ```c++ std::vector remap(vertex_count); size_t unique = meshopt_optimizeVertexFetchRemap(&remap[0], &indices[0], index_count, vertex_count); // Apply remap to each vertex stream separately ``` -------------------------------- ### File Loading and Update Controls Source: https://github.com/zeux/meshoptimizer/blob/master/demo/simplify.html Manage file loading operations, including loading new files, updating modules, debugging checkerboard patterns, and enabling auto-update functionality. ```javascript var guiLoad = gui.addFolder('Load'); guiLoad.add(settings, 'loadFile'); guiLoad.add(settings, 'updateModule'); guiLoad.add(settings, 'debugCheckerboard'); guiLoad.add(settings, 'autoUpdate').onChange(autoReload); guiLoad.add(settings, 'autoUpdateStatus').listen(); ```