How meshopt_spatialSortRemap Improves Point Cloud Compression: A Deep Dive

meshopt_spatialSortRemap reorders point cloud vertices using Morton codes so that nearby 3D points become neighbors in memory, enabling delta-based encoders to achieve 30-50% smaller compressed sizes.

The meshoptimizer library provides efficient algorithms for mesh compression, including specialized preprocessing functions that optimize data layout before encoding. meshopt_spatialSortRemap is a critical utility in src/spatialorder.cpp that reorders point cloud vertices spatially to maximize the efficiency of subsequent delta compression. By mapping 3D spatial proximity into linear memory order, the function ensures that meshopt_encodeVertexBuffer and similar codecs encounter small, highly predictable differences between successive vertices.

How Spatial Sorting Works

The implementation in src/spatialorder.cpp processes point clouds through three distinct stages to generate an optimal vertex reordering.

Stage 1: Morton Code Generation (Z-Order)

For each vertex, the algorithm computes a 48-bit Morton code that interleaves the bits of the scaled X, Y, and Z coordinates. This uses the part1By2 function combined with bit-shifts to spread the coordinate bits across the key. Because Morton codes preserve spatial locality—points that are close in 3D space tend to have similar code values—this creates a numerical representation of spatial proximity.

The relevant logic resides in the computeOrder function (lines 25-68), which converts floating-point positions into quantized integers before bit interleaving.

Stage 2: Radix Sort Implementation

Once Morton codes are generated, a 5-pass 10-bit radix sort (radixSort10) sorts the vertices while preserving their original indices. The sort extracts 10-bit key segments into a temporary array (keyk) before each pass, making the operation cache-friendly even for millions of points. This step orders the vertices by their spatial codes, ensuring that points near each other in 3D space appear consecutively in the sorted array.

You can find the radix sort implementation at lines 70-98 in src/spatialorder.cpp.

Stage 3: Remap Table Construction

After sorting, meshopt_spatialSortRemap builds the final remap table by inverting the order array using the operation destination[scratch[i]] = i. This creates an "old → new" mapping table that can be applied to the original vertex buffer to produce a spatially sorted point cloud without modifying the source data until explicitly applied.

The public API entry point at lines 18-52 handles the initialization and orchestrates these internal stages.

Why Spatial Locality Improves Compression

Reordering vertices spatially provides measurable benefits for compression codecs in src/vertexcodec.cpp:

  • Delta encoding efficiency – When meshopt_encodeVertexBuffer processes vertices, it stores differences between successive values rather than absolute coordinates. Spatially sorted vertices produce small, consistent deltas that share common prefixes, allowing entropy coders (Huffman or range coding) to achieve significantly higher compression ratios.

  • Quantization clustering – Spatial sorting clusters points with similar coordinate values, allowing quantizers to use fewer bits per component before the final compression stage. This pre-compression optimization reduces the information entropy of the input data.

  • Cache-friendly processing – The radix sort operates on short 10-bit keys, minimizing cache misses during the preprocessing stage. This keeps the sorting overhead low—typically adding only a few milliseconds for datasets containing millions of points.

Practical Usage Example

Apply the spatial sort remap before encoding to maximize compression efficiency:

#include "meshoptimizer.h"
#include <vector>

// Assume we have a point cloud: positions stored as 3 floats per vertex
std::vector<float> points = /* ... load your point cloud ... */;
size_t vertexCount = points.size() / 3;

// 1️⃣  Compute a remap that orders the points spatially
std::vector<unsigned int> remap(vertexCount);
meshopt_spatialSortRemap(remap.data(),
                         points.data(),
                         vertexCount,
                         /* stride = 3 floats = 12 bytes */ 12);

// 2️⃣  Apply the remap to obtain a sorted point buffer
std::vector<float> sortedPoints(vertexCount * 3);
for (size_t i = 0; i < vertexCount; ++i) {
    sortedPoints[i * 3 + 0] = points[remap[i] * 3 + 0];
    sortedPoints[i * 3 + 1] = points[remap[i] * 3 + 1];
    sortedPoints[i * 3 + 2] = points[remap[i] * 3 + 2];
}

// 3️⃣  Encode the sorted buffer – this now compresses much better
size_t bound = meshopt_encodeVertexBufferBound(vertexCount, 12);
std::vector<unsigned char> encoded(bound);
size_t encodedSize = meshopt_encodeVertexBuffer(
    encoded.data(), encoded.size(),
    sortedPoints.data(),
    vertexCount, 12);
encoded.resize(encodedSize);

Summary

  • meshopt_spatialSortRemap generates a vertex reordering that maps 3D spatial proximity to linear memory adjacency using 48-bit Morton codes and radix sorting.
  • The function is implemented in src/spatialorder.cpp and declared in src/meshoptimizer.h, processing data through computeOrder and radixSort10 before building the remap table.
  • Spatial sorting enables delta-based encoders in src/vertexcodec.cpp to achieve 30-50% smaller output sizes on typical LiDAR or photogrammetry datasets.
  • The reordering is non-destructive—the function outputs a remap table that you apply to your vertex buffer before calling meshopt_encodeVertexBuffer.

Frequently Asked Questions

What is the difference between meshopt_spatialSortRemap and meshopt_optimizeVertexCache?

meshopt_spatialSortRemap optimizes for compression by ordering vertices based on 3D spatial proximity using Morton codes, which benefits delta encoding. meshopt_optimizeVertexCache optimizes for GPU rendering performance by reordering triangles to maximize cache hits during rasterization. Use spatial sorting for point cloud compression, and vertex cache optimization for mesh rendering.

How much compression improvement can I expect from spatial sorting?

Typical LiDAR and photogrammetry point clouds see 30-50% reduction in encoded size when using meshopt_spatialSortRemap before meshopt_encodeVertexBuffer. The exact improvement depends on the spatial coherence of your input data—highly clustered point clouds benefit more than randomly distributed ones.

Does meshopt_spatialSortRemap modify the original vertex buffer?

No. The function populates a remap table that you must apply manually to your vertex buffer. This non-destructive approach allows you to reuse the original data or apply multiple optimization passes without copying large buffers until necessary.

What coordinate precision does the Morton code use?

The implementation uses 48-bit Morton codes with fixed-point quantization of the input float coordinates. The part1By2 function interleaves bits from the scaled X, Y, and Z components, providing sufficient precision to distinguish spatial relationships while maintaining efficient 64-bit integer operations during the radix sort.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →