Skip to content

Commit

Permalink
Merge pull request zeux#622 from zeux/js-points
Browse files Browse the repository at this point in the history
js: Expose reorderPoints and simplifyPoints
  • Loading branch information
zeux authored Oct 15, 2023
2 parents 7a45349 + 50d0fd3 commit 92801eb
Show file tree
Hide file tree
Showing 10 changed files with 191 additions and 21 deletions.
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,11 @@ WASM_EXPORT_PREFIX=-Wl,--export
WASM_DECODER_SOURCES=src/vertexcodec.cpp src/indexcodec.cpp src/vertexfilter.cpp tools/wasmstubs.cpp
WASM_DECODER_EXPORTS=meshopt_decodeVertexBuffer meshopt_decodeIndexBuffer meshopt_decodeIndexSequence meshopt_decodeFilterOct meshopt_decodeFilterQuat meshopt_decodeFilterExp sbrk __wasm_call_ctors

WASM_ENCODER_SOURCES=src/vertexcodec.cpp src/indexcodec.cpp src/vertexfilter.cpp src/vcacheoptimizer.cpp src/vfetchoptimizer.cpp tools/wasmstubs.cpp
WASM_ENCODER_EXPORTS=meshopt_encodeVertexBuffer meshopt_encodeVertexBufferBound meshopt_encodeIndexBuffer meshopt_encodeIndexBufferBound meshopt_encodeIndexSequence meshopt_encodeIndexSequenceBound meshopt_encodeVertexVersion meshopt_encodeIndexVersion meshopt_encodeFilterOct meshopt_encodeFilterQuat meshopt_encodeFilterExp meshopt_optimizeVertexCache meshopt_optimizeVertexCacheStrip meshopt_optimizeVertexFetchRemap sbrk __wasm_call_ctors
WASM_ENCODER_SOURCES=src/vertexcodec.cpp src/indexcodec.cpp src/vertexfilter.cpp src/vcacheoptimizer.cpp src/vfetchoptimizer.cpp src/spatialorder.cpp tools/wasmstubs.cpp
WASM_ENCODER_EXPORTS=meshopt_encodeVertexBuffer meshopt_encodeVertexBufferBound meshopt_encodeIndexBuffer meshopt_encodeIndexBufferBound meshopt_encodeIndexSequence meshopt_encodeIndexSequenceBound meshopt_encodeVertexVersion meshopt_encodeIndexVersion meshopt_encodeFilterOct meshopt_encodeFilterQuat meshopt_encodeFilterExp meshopt_optimizeVertexCache meshopt_optimizeVertexCacheStrip meshopt_optimizeVertexFetchRemap meshopt_spatialSortRemap sbrk __wasm_call_ctors

WASM_SIMPLIFIER_SOURCES=src/simplifier.cpp src/vfetchoptimizer.cpp tools/wasmstubs.cpp
WASM_SIMPLIFIER_EXPORTS=meshopt_simplify meshopt_simplifyWithAttributes meshopt_simplifyScale meshopt_optimizeVertexFetchRemap sbrk __wasm_call_ctors
WASM_SIMPLIFIER_EXPORTS=meshopt_simplify meshopt_simplifyWithAttributes meshopt_simplifyScale meshopt_simplifyPoints meshopt_optimizeVertexFetchRemap sbrk __wasm_call_ctors

ifeq ($(config),iphone)
IPHONESDK=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk
Expand Down
8 changes: 8 additions & 0 deletions js/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ for (let i = 0; i < oldvertices.length; ++i)
newvertices[remap[i]] = oldvertices[i];
```

When the input is a point cloud and not a triangle mesh, it is recommended to reorder the points using a specialized function that performs spatial sorting that can result in significant improvements in compression ratio by the subsequent processing:

```ts
reorderPoints: (positions: Float32Array, positions_stride: number) => Uint32Array;
```

This function returns a remap array just like `reorderMesh`, so the vertices need to be reordered accordingly for every vertex stream - the `positions` input is not modified. Note that it assumes no index buffer is provided, as it is redundant for point clouds.

To quantize the attribute data (whether it represents a mesh component or something else like a rotation quaternion for a bone), typically some data-specific analysis should be performed to determine the optimal quantization strategy. For linear data such as positions or texture coordinates remapping the input range to 0..1 and quantizing the resulting integer using fixed-point encoding with a given number of bits stored in a 16-bit or 8-bit integer is recommended; however, this is not always best for compression ratio for data with complex cross-component dependencies.

To that end, three filter encoders are provided: octahedral (optimal for normal or tangent data), quaternion (optimal for unit-length quaternions) and exponential (optimal for compressing floating-point vectors). The last two are recommended for use for animation data, and exponential filter can additionally be used to quantize any floating-point vertex attribute for which integer quantization is not sufficiently precise.
Expand Down
29 changes: 25 additions & 4 deletions js/meshopt_encoder.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions js/meshopt_encoder.module.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export const MeshoptEncoder: {
ready: Promise<void>;

reorderMesh: (indices: Uint32Array, triangles: boolean, optsize: boolean) => [Uint32Array, number];
reorderPoints: (positions: Float32Array, positions_stride: number) => Uint32Array;

encodeVertexBuffer: (source: Uint8Array, count: number, size: number) => Uint8Array;
encodeIndexBuffer: (source: Uint8Array, count: number, size: number) => Uint8Array;
Expand Down
29 changes: 25 additions & 4 deletions js/meshopt_encoder.module.js

Large diffs are not rendered by default.

16 changes: 16 additions & 0 deletions js/meshopt_encoder.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,22 @@ var tests = {
assert.equal(res[1], 6); // unique
},

reorderPoints: function() {
var points = new Float32Array([
1, 1, 1,
11, 11, 11,
2, 2, 2,
12, 12, 12,
]);

var expected = new Uint32Array([
0, 2, 1, 3
]);

var remap = encoder.reorderPoints(points, 3);
assert.deepEqual(remap, expected);
},

roundtripVertexBuffer: function() {
var data = new Uint8Array(16 * 4);

Expand Down
47 changes: 42 additions & 5 deletions js/meshopt_simplifier.js

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions js/meshopt_simplifier.module.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ export const MeshoptSimplifier: {
simplifyWithAttributes: (indices: Uint32Array, vertex_positions: Float32Array, vertex_positions_stride: number, vertex_attributes: Float32Array, vertex_attributes_stride: number, attribute_weights: number[], target_index_count: number, target_error: number, flags?: Flags[]) => [Uint32Array, number];

getScale: (vertex_positions: Float32Array, vertex_positions_stride: number) => number;

simplifyPoints: (vertex_positions: Float32Array, vertex_positions_stride: number, target_vertex_count: number, vertex_colors?: Float32Array, vertex_colors_stride?: number, color_weight?: number) => Uint32Array;
};
47 changes: 42 additions & 5 deletions js/meshopt_simplifier.module.js

Large diffs are not rendered by default.

27 changes: 27 additions & 0 deletions js/meshopt_simplifier.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,33 @@ var tests = {

assert(simplifier.getScale(positions, 3) == 3.0);
},

simplifyPoints: function() {
var positions = new Float32Array([
0, 0, 0, 100, 0, 0, 100, 1, 1, 110, 0, 0,
]);
var colors = new Float32Array([
1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
]);

var expected = new Uint32Array([
0, 1
]);

var expectedC = new Uint32Array([
0, 2
]);

var res = simplifier.simplifyPoints(positions, 3, 2);
assert.deepEqual(res, expected);

// note: recommended value for color_weight is 1e-2 but here we push color weight to be very high to bias candidate selection for testing
var resC1 = simplifier.simplifyPoints(positions, 3, 2, colors, 3, 1e-1);
assert.deepEqual(resC1, expectedC);

var resC2 = simplifier.simplifyPoints(positions, 3, 2, colors, 3, 1e-2);
assert.deepEqual(resC2, expected);
}
};

Promise.all([simplifier.ready]).then(() => {
Expand Down

0 comments on commit 92801eb

Please sign in to comment.