Skip to content

Commit

Permalink
Merge pull request #160 from CesiumGS/handle-meshopt-in-buffer-structure
Browse files Browse the repository at this point in the history
Decode meshopt in buffer structure
  • Loading branch information
lilleyse authored Nov 30, 2024
2 parents 3c2b9a4 + 1eec439 commit a2900b0
Show file tree
Hide file tree
Showing 5 changed files with 625 additions and 25 deletions.
143 changes: 143 additions & 0 deletions specs/base/binary/BinaryBufferDataResolverSpec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import fs from "fs";
import path from "path";

import { BinaryBufferDataResolver } from "../../../src/base";
import { ResourceResolvers } from "../../../src/base";

import { SpecHelpers } from "../../SpecHelpers";

const SPECS_DATA_BASE_DIRECTORY = SpecHelpers.getSpecsDataBaseDirectory();

describe("BinaryBufferDataResolver", function () {
it("resolves the data from the buffer structure of a glTF", async function () {
const p = SPECS_DATA_BASE_DIRECTORY + "/Triangle/Triangle.gltf";
const directory = path.dirname(p);
const resourceResolver =
ResourceResolvers.createFileResourceResolver(directory);

const gltfBuffer = fs.readFileSync(p);
const gltf = JSON.parse(gltfBuffer.toString());
const binaryBufferData = await BinaryBufferDataResolver.resolve(
gltf,
undefined,
resourceResolver
);

// The indices are unsigned short (16 bit) integer values
const indicesBufferView = binaryBufferData.bufferViewsData[0];
const indicesArray = new Uint16Array(
indicesBufferView.buffer,
indicesBufferView.byteOffset,
indicesBufferView.byteLength / Uint16Array.BYTES_PER_ELEMENT
);
const actualIndices = [...indicesArray];
const expectedIndices = [0, 1, 2];

// The positions are float values
const positionsBufferView = binaryBufferData.bufferViewsData[1];
const positionsArray = new Float32Array(
positionsBufferView.buffer,
positionsBufferView.byteOffset,
positionsBufferView.byteLength / Float32Array.BYTES_PER_ELEMENT
);
const actualPositions = [...positionsArray];
// prettier-ignore
const expectedPositions = [
0.0, 0.0, 0.0,
1.0, 0.0, 0.0,
0.0, 1.0, 0.0
];

expect(actualIndices).toEqual(expectedIndices);
expect(actualPositions).toEqual(expectedPositions);
});

it("resolves the data from the buffer structure of a glTF with meshopt compression", async function () {
const p = SPECS_DATA_BASE_DIRECTORY + "/Triangle/TriangleMeshopt.gltf";
const directory = path.dirname(p);
const resourceResolver =
ResourceResolvers.createFileResourceResolver(directory);

const gltfBuffer = fs.readFileSync(p);
const gltf = JSON.parse(gltfBuffer.toString());
const binaryBufferData = await BinaryBufferDataResolver.resolve(
gltf,
undefined,
resourceResolver
);

// The indices are unsigned short (16 bit) integer values
const indicesBufferView = binaryBufferData.bufferViewsData[0];
const indicesArray = new Uint16Array(
indicesBufferView.buffer,
indicesBufferView.byteOffset,
indicesBufferView.byteLength / Uint16Array.BYTES_PER_ELEMENT
);
const actualIndices = [...indicesArray];
const expectedIndices = [0, 1, 2];

// The positions are ALSO unsigned 16-bit integer values (normalized)
const positionsBufferView = binaryBufferData.bufferViewsData[1];
const positionsArray = new Uint16Array(
positionsBufferView.buffer,
positionsBufferView.byteOffset,
positionsBufferView.byteLength / Uint16Array.BYTES_PER_ELEMENT
);
const actualPositions = [...positionsArray];
// prettier-ignore
const expectedPositions = [
32769, 32769, 0,
0, 32767, 32769,
0, 0, 32769,
32767, 0, 0
]

expect(actualIndices).toEqual(expectedIndices);
expect(actualPositions).toEqual(expectedPositions);
});

it("resolves the data from the buffer structure of a glTF without default byte offsets with meshopt compression", async function () {
const p =
SPECS_DATA_BASE_DIRECTORY + "/Triangle/TriangleMeshoptNoByteOffset.gltf";
const directory = path.dirname(p);
const resourceResolver =
ResourceResolvers.createFileResourceResolver(directory);

const gltfBuffer = fs.readFileSync(p);
const gltf = JSON.parse(gltfBuffer.toString());
const binaryBufferData = await BinaryBufferDataResolver.resolve(
gltf,
undefined,
resourceResolver
);

// The indices are unsigned short (16 bit) integer values
const indicesBufferView = binaryBufferData.bufferViewsData[0];
const indicesArray = new Uint16Array(
indicesBufferView.buffer,
indicesBufferView.byteOffset,
indicesBufferView.byteLength / Uint16Array.BYTES_PER_ELEMENT
);
const actualIndices = [...indicesArray];
const expectedIndices = [0, 1, 2];

// The positions are ALSO unsigned 16-bit integer values (normalized)
const positionsBufferView = binaryBufferData.bufferViewsData[1];
const positionsArray = new Uint16Array(
positionsBufferView.buffer,
positionsBufferView.byteOffset,
positionsBufferView.byteLength / Uint16Array.BYTES_PER_ELEMENT
);
const actualPositions = [...positionsArray];
// prettier-ignore
const expectedPositions = [
32769, 32769, 0,
0, 32767, 32769,
0, 0, 32769,
32767, 0, 0
]

expect(actualIndices).toEqual(expectedIndices);
expect(actualPositions).toEqual(expectedPositions);
});
});
Binary file added specs/data/Triangle/TriangleMeshopt.bin
Binary file not shown.
127 changes: 127 additions & 0 deletions specs/data/Triangle/TriangleMeshopt.gltf
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
{
"asset": {
"generator": "glTF-Transform v3.10.1",
"version": "2.0"
},
"accessors": [
{
"type": "SCALAR",
"componentType": 5123,
"count": 3,
"normalized": false,
"byteOffset": 0,
"bufferView": 0
},
{
"type": "VEC3",
"componentType": 5122,
"count": 3,
"max": [
32767,
32767,
0
],
"min": [
-32767,
-32767,
0
],
"normalized": true,
"byteOffset": 0,
"bufferView": 1
}
],
"bufferViews": [
{
"buffer": 1,
"byteOffset": 0,
"byteLength": 6,
"target": 34963,
"extensions": {
"EXT_meshopt_compression": {
"buffer": 0,
"byteOffset": 0,
"byteLength": 18,
"mode": "TRIANGLES",
"byteStride": 2,
"count": 3
}
}
},
{
"buffer": 1,
"byteOffset": 8,
"byteLength": 24,
"target": 34962,
"byteStride": 8,
"extensions": {
"EXT_meshopt_compression": {
"buffer": 0,
"byteOffset": 20,
"byteLength": 60,
"mode": "ATTRIBUTES",
"byteStride": 8,
"count": 3
}
}
}
],
"buffers": [
{
"uri": "TriangleMeshopt.bin",
"byteLength": 80
},
{
"byteLength": 32,
"extensions": {
"EXT_meshopt_compression": {
"fallback": true
}
}
}
],
"meshes": [
{
"primitives": [
{
"attributes": {
"POSITION": 1
},
"mode": 4,
"indices": 0
}
]
}
],
"nodes": [
{
"translation": [
0.5,
0.5,
0
],
"scale": [
0.5,
0.5,
0.5
],
"mesh": 0
}
],
"scenes": [
{
"nodes": [
0
]
}
],
"scene": 0,
"extensionsUsed": [
"KHR_mesh_quantization",
"EXT_meshopt_compression"
],
"extensionsRequired": [
"KHR_mesh_quantization",
"EXT_meshopt_compression"
]
}
123 changes: 123 additions & 0 deletions specs/data/Triangle/TriangleMeshoptNoByteOffset.gltf
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
{
"asset": {
"generator": "glTF-Transform v3.10.1",
"version": "2.0"
},
"accessors": [
{
"type": "SCALAR",
"componentType": 5123,
"count": 3,
"normalized": false,
"bufferView": 0
},
{
"type": "VEC3",
"componentType": 5122,
"count": 3,
"max": [
32767,
32767,
0
],
"min": [
-32767,
-32767,
0
],
"normalized": true,
"bufferView": 1
}
],
"bufferViews": [
{
"buffer": 1,
"byteLength": 6,
"target": 34963,
"extensions": {
"EXT_meshopt_compression": {
"buffer": 0,
"byteLength": 18,
"mode": "TRIANGLES",
"byteStride": 2,
"count": 3
}
}
},
{
"buffer": 1,
"byteOffset": 8,
"byteLength": 24,
"target": 34962,
"byteStride": 8,
"extensions": {
"EXT_meshopt_compression": {
"buffer": 0,
"byteOffset": 20,
"byteLength": 60,
"mode": "ATTRIBUTES",
"byteStride": 8,
"count": 3
}
}
}
],
"buffers": [
{
"uri": "TriangleMeshopt.bin",
"byteLength": 80
},
{
"byteLength": 32,
"extensions": {
"EXT_meshopt_compression": {
"fallback": true
}
}
}
],
"meshes": [
{
"primitives": [
{
"attributes": {
"POSITION": 1
},
"mode": 4,
"indices": 0
}
]
}
],
"nodes": [
{
"translation": [
0.5,
0.5,
0
],
"scale": [
0.5,
0.5,
0.5
],
"mesh": 0
}
],
"scenes": [
{
"nodes": [
0
]
}
],
"scene": 0,
"extensionsUsed": [
"KHR_mesh_quantization",
"EXT_meshopt_compression"
],
"extensionsRequired": [
"KHR_mesh_quantization",
"EXT_meshopt_compression"
]
}
Loading

0 comments on commit a2900b0

Please sign in to comment.