-
Notifications
You must be signed in to change notification settings - Fork 293
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(3dtiles): add support for binary batch table
BREAKING CHANGE: `C3DTBatchTable` constructor signature has changed from C3DTBatchTable(buffer, binaryLength, batchLength, registeredExtensions) to C3DTBatchTable(buffer, jsonLength, binaryLength, batchLength, registeredExtensions)
- Loading branch information
Showing
9 changed files
with
221 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
import { Vector2, Vector3, Vector4 } from 'three'; | ||
|
||
/** | ||
* @enum {Object} componentTypeBytesSize - Size in byte of a component type. | ||
*/ | ||
const componentTypeBytesSize = { | ||
BYTE: 1, | ||
UNSIGNED_BYTE: 1, | ||
SHORT: 2, | ||
UNSIGNED_SHORT: 2, | ||
INT: 4, | ||
UNSIGNED_INT: 4, | ||
FLOAT: 4, | ||
DOUBLE: 8, | ||
}; | ||
|
||
/** | ||
* @enum {Object} componentTypeConstructor - TypedArray constructor for each 3D Tiles binary componentType | ||
*/ | ||
const componentTypeConstructor = { | ||
BYTE: Int8Array, | ||
UNSIGNED_BYTE: Uint8Array, | ||
SHORT: Int16Array, | ||
UNSIGNED_SHORT: Uint16Array, | ||
INT: Int32Array, | ||
UNSIGNED_INT: Uint32Array, | ||
FLOAT: Float32Array, | ||
DOUBLE: Float64Array, | ||
}; | ||
|
||
|
||
/** | ||
* @enum {Object} typeComponentsNumber - Number of components for a given type. | ||
*/ | ||
const typeComponentsNumber = { | ||
SCALAR: 1, | ||
VEC2: 2, | ||
VEC3: 3, | ||
VEC4: 4, | ||
}; | ||
|
||
/** | ||
* @enum {Object} typeConstructor - constructor for types (only for vectors since scalar will be converted to a single | ||
* value) | ||
*/ | ||
const typeConstructor = { | ||
// SCALAR: no constructor, just create a value (int, float, etc. depending on componentType) | ||
VEC2: Vector2, | ||
VEC3: Vector3, | ||
VEC4: Vector4, | ||
}; | ||
|
||
/** | ||
* Parses a 3D Tiles binary property. Used for batch table and feature table parsing. See the 3D Tiles spec for more | ||
* information on how these values are encoded: | ||
* [3D Tiles spec](https://github.com/CesiumGS/3d-tiles/blob/main/specification/TileFormats/BatchTable/README.md#binary-body)) | ||
* @param {ArrayBuffer} buffer The buffer to parse values from. | ||
* @param {Number} batchLength number of objects in the batch (= number of elements to parse). | ||
* @param {Number} byteOffset the offset in bytes into the buffer. | ||
* @param {String} componentType the type of component to parse (one of componentTypeBytesSize keys) | ||
* @param {String} type the type of element to parse (one of typeComponentsNumber keys) | ||
* @returns {Array} an array of values parsed from the buffer. An array of componentType if type is SCALAR. An array | ||
* of Threejs Vector2, Vector3 or Vector4 if type is VEC2, VEC3 or VEC4 respectively. | ||
*/ | ||
function binaryPropertyAccessor(buffer, batchLength, byteOffset, componentType, type) { | ||
if (!buffer) { | ||
throw new Error('Buffer is mandatory to parse binary property.'); | ||
} | ||
if (typeof batchLength === 'undefined' || batchLength === null) { | ||
throw new Error('batchLength is mandatory to parse binary property.'); | ||
} | ||
if (typeof byteOffset === 'undefined' || byteOffset === null) { | ||
throw new Error('byteOffset is mandatory to parse binary property.'); | ||
} | ||
if (!componentTypeBytesSize[componentType]) { | ||
throw new Error(`Uknown component type: ${componentType}. Cannot access binary property.`); | ||
} | ||
if (!typeComponentsNumber[type]) { | ||
throw new Error(`Uknown type: ${type}. Cannot access binary property.`); | ||
} | ||
|
||
const typeNb = typeComponentsNumber[type]; | ||
const elementsNb = batchLength * typeNb; // Number of elements to parse in the buffer | ||
|
||
const typedArray = new componentTypeConstructor[componentType](buffer, byteOffset, elementsNb); | ||
|
||
if (type === 'SCALAR') { | ||
return Array.from(typedArray); | ||
} else { | ||
// return an array of threejs vectors, depending on type (see typeConstructor) | ||
const array = []; | ||
// iteration step of 2, 3 or 4, depending on the type (VEC2, VEC3 or VEC4) | ||
for (let i = 0; i <= typedArray.length - typeNb; i += typeNb) { | ||
const vector = new typeConstructor[type](); | ||
// Create a vector from an array, starting at the offset i and takes the right number of elements depending | ||
// on its type (Vector2, Vector3, Vector 4) | ||
vector.fromArray(typedArray, i); | ||
array.push(vector); | ||
} | ||
return array; | ||
} | ||
} | ||
|
||
export default binaryPropertyAccessor; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import assert from 'assert'; | ||
import { Vector2 } from 'three'; | ||
import binaryPropertyAccessor from 'Core/3DTiles/utils/BinaryPropertyAccessor'; | ||
import { compareArrayWithEpsilon } from './utils'; | ||
|
||
describe('3D Tiles Binary Property Accessor', function () { | ||
it('Should parse float scalar binary array', function () { | ||
const refArray = [3.5, 2.1, -1.5]; | ||
const typedArray = new Float32Array(refArray); | ||
const buffer = typedArray.buffer; | ||
const batchLength = 3; | ||
const byteOffset = 0; | ||
const componentType = 'FLOAT'; | ||
const type = 'SCALAR'; | ||
|
||
var parsedArray = binaryPropertyAccessor(buffer, batchLength, byteOffset, componentType, type); | ||
|
||
assert.ok(compareArrayWithEpsilon(parsedArray, refArray, 0.001)); | ||
}); | ||
|
||
it('Should parse unsigned short int vector2 binary array', function () { | ||
const refArray = [14, 12, 3, 5, 108, 500]; | ||
const typedArray = new Uint16Array(refArray); | ||
const buffer = typedArray.buffer; | ||
const batchLength = 3; | ||
const byteOffset = 0; | ||
const componentType = 'UNSIGNED_SHORT'; | ||
const type = 'VEC2'; | ||
|
||
const parsedArray = binaryPropertyAccessor(buffer, batchLength, byteOffset, componentType, type); | ||
|
||
// Create expected array (array of THREE.Vector2s) | ||
const expectedArray = []; | ||
for (let i = 0; i <= refArray.length - 2; i += 2) { | ||
const vec2 = new Vector2(); | ||
expectedArray.push(vec2.fromArray(refArray, i)); | ||
} | ||
|
||
// Convert each vector2 to Array and compare them. | ||
for (let i = 0; i < parsedArray.length; i++) { | ||
assert.ok(compareArrayWithEpsilon(parsedArray[i].toArray(), expectedArray[i].toArray(), 0.001)); | ||
} | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
export function compareWithEpsilon(a, b, epsilon) { | ||
return a - epsilon < b && a + epsilon > b; | ||
} | ||
|
||
export function compareArrayWithEpsilon(arr1, arr2, epsilon) { | ||
if (arr1.length !== arr2.length) { | ||
return false; | ||
} | ||
for (let i = 0; i < arr1.length; i++) { | ||
if (!compareWithEpsilon(arr1[i], arr2[i], epsilon)) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} |