@loaders.gl/gltf 4.2.0-alpha.4 → 4.2.0-alpha.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dist.dev.js +1049 -517
- package/dist/dist.min.js +9 -0
- package/dist/glb-loader.d.ts +2 -2
- package/dist/glb-loader.d.ts.map +1 -1
- package/dist/glb-loader.js +22 -21
- package/dist/glb-writer.d.ts +2 -2
- package/dist/glb-writer.d.ts.map +1 -1
- package/dist/glb-writer.js +27 -24
- package/dist/gltf-loader.d.ts +3 -3
- package/dist/gltf-loader.d.ts.map +1 -1
- package/dist/gltf-loader.js +31 -36
- package/dist/gltf-writer.js +24 -26
- package/dist/index.cjs +95 -284
- package/dist/index.cjs.map +7 -0
- package/dist/index.d.ts +17 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/lib/api/gltf-extensions.d.ts +2 -2
- package/dist/lib/api/gltf-extensions.d.ts.map +1 -1
- package/dist/lib/api/gltf-extensions.js +45 -22
- package/dist/lib/api/gltf-scenegraph.d.ts +2 -2
- package/dist/lib/api/gltf-scenegraph.d.ts.map +1 -1
- package/dist/lib/api/gltf-scenegraph.js +561 -438
- package/dist/lib/api/normalize-gltf-v1.js +250 -181
- package/dist/lib/api/post-process-gltf.d.ts +3 -3
- package/dist/lib/api/post-process-gltf.d.ts.map +1 -1
- package/dist/lib/api/post-process-gltf.js +375 -339
- package/dist/lib/encoders/encode-glb.js +62 -48
- package/dist/lib/encoders/encode-gltf.js +24 -10
- package/dist/lib/extensions/EXT_mesh_features.d.ts +2 -2
- package/dist/lib/extensions/EXT_mesh_features.d.ts.map +1 -1
- package/dist/lib/extensions/EXT_mesh_features.js +55 -33
- package/dist/lib/extensions/EXT_meshopt_compression.d.ts +2 -2
- package/dist/lib/extensions/EXT_meshopt_compression.d.ts.map +1 -1
- package/dist/lib/extensions/EXT_meshopt_compression.js +27 -31
- package/dist/lib/extensions/EXT_structural_metadata.d.ts +2 -2
- package/dist/lib/extensions/EXT_structural_metadata.d.ts.map +1 -1
- package/dist/lib/extensions/EXT_structural_metadata.js +434 -230
- package/dist/lib/extensions/EXT_texture_webp.d.ts +2 -2
- package/dist/lib/extensions/EXT_texture_webp.d.ts.map +1 -1
- package/dist/lib/extensions/EXT_texture_webp.js +24 -17
- package/dist/lib/extensions/KHR_binary_gltf.d.ts +1 -1
- package/dist/lib/extensions/KHR_binary_gltf.d.ts.map +1 -1
- package/dist/lib/extensions/KHR_binary_gltf.js +29 -15
- package/dist/lib/extensions/KHR_draco_mesh_compression.d.ts +2 -2
- package/dist/lib/extensions/KHR_draco_mesh_compression.d.ts.map +1 -1
- package/dist/lib/extensions/KHR_draco_mesh_compression.js +110 -87
- package/dist/lib/extensions/KHR_texture_basisu.d.ts +2 -2
- package/dist/lib/extensions/KHR_texture_basisu.d.ts.map +1 -1
- package/dist/lib/extensions/KHR_texture_basisu.js +19 -12
- package/dist/lib/extensions/KHR_texture_transform.d.ts +2 -2
- package/dist/lib/extensions/KHR_texture_transform.d.ts.map +1 -1
- package/dist/lib/extensions/KHR_texture_transform.js +194 -154
- package/dist/lib/extensions/deprecated/EXT_feature_metadata.d.ts +2 -2
- package/dist/lib/extensions/deprecated/EXT_feature_metadata.d.ts.map +1 -1
- package/dist/lib/extensions/deprecated/EXT_feature_metadata.js +263 -143
- package/dist/lib/extensions/deprecated/KHR_lights_punctual.d.ts +1 -1
- package/dist/lib/extensions/deprecated/KHR_lights_punctual.d.ts.map +1 -1
- package/dist/lib/extensions/deprecated/KHR_lights_punctual.js +44 -32
- package/dist/lib/extensions/deprecated/KHR_materials_unlit.d.ts +1 -1
- package/dist/lib/extensions/deprecated/KHR_materials_unlit.d.ts.map +1 -1
- package/dist/lib/extensions/deprecated/KHR_materials_unlit.js +30 -24
- package/dist/lib/extensions/deprecated/KHR_techniques_webgl.d.ts +1 -1
- package/dist/lib/extensions/deprecated/KHR_techniques_webgl.d.ts.map +1 -1
- package/dist/lib/extensions/deprecated/KHR_techniques_webgl.js +65 -52
- package/dist/lib/extensions/utils/3d-tiles-utils.d.ts +2 -2
- package/dist/lib/extensions/utils/3d-tiles-utils.d.ts.map +1 -1
- package/dist/lib/extensions/utils/3d-tiles-utils.js +298 -181
- package/dist/lib/gltf-utils/get-typed-array.d.ts +1 -1
- package/dist/lib/gltf-utils/get-typed-array.d.ts.map +1 -1
- package/dist/lib/gltf-utils/get-typed-array.js +54 -42
- package/dist/lib/gltf-utils/gltf-attribute-utils.d.ts +1 -1
- package/dist/lib/gltf-utils/gltf-attribute-utils.d.ts.map +1 -1
- package/dist/lib/gltf-utils/gltf-attribute-utils.js +58 -52
- package/dist/lib/gltf-utils/gltf-constants.js +27 -27
- package/dist/lib/gltf-utils/gltf-utils.d.ts +1 -1
- package/dist/lib/gltf-utils/gltf-utils.d.ts.map +1 -1
- package/dist/lib/gltf-utils/gltf-utils.js +67 -60
- package/dist/lib/gltf-utils/resolve-url.js +12 -10
- package/dist/lib/parsers/parse-glb.d.ts +1 -1
- package/dist/lib/parsers/parse-glb.d.ts.map +1 -1
- package/dist/lib/parsers/parse-glb.js +132 -89
- package/dist/lib/parsers/parse-gltf.d.ts +3 -3
- package/dist/lib/parsers/parse-gltf.d.ts.map +1 -1
- package/dist/lib/parsers/parse-gltf.js +155 -126
- package/dist/lib/types/glb-types.js +0 -1
- package/dist/lib/types/gltf-ext-feature-metadata-schema.d.ts +1 -1
- package/dist/lib/types/gltf-ext-feature-metadata-schema.d.ts.map +1 -1
- package/dist/lib/types/gltf-ext-feature-metadata-schema.js +0 -1
- package/dist/lib/types/gltf-ext-mesh-features-schema.d.ts +1 -1
- package/dist/lib/types/gltf-ext-mesh-features-schema.d.ts.map +1 -1
- package/dist/lib/types/gltf-ext-mesh-features-schema.js +0 -1
- package/dist/lib/types/gltf-ext-structural-metadata-schema.d.ts +1 -1
- package/dist/lib/types/gltf-ext-structural-metadata-schema.d.ts.map +1 -1
- package/dist/lib/types/gltf-ext-structural-metadata-schema.js +0 -1
- package/dist/lib/types/gltf-json-schema.js +2 -1
- package/dist/lib/types/gltf-postprocessed-schema.js +2 -1
- package/dist/lib/types/gltf-types.d.ts +3 -3
- package/dist/lib/types/gltf-types.d.ts.map +1 -1
- package/dist/lib/types/gltf-types.js +1 -1
- package/dist/lib/utils/assert.js +6 -4
- package/dist/lib/utils/version.js +3 -1
- package/dist/meshopt/meshopt-decoder.js +86 -67
- package/dist/webp/webp.js +28 -19
- package/package.json +12 -8
- package/dist/glb-loader.js.map +0 -1
- package/dist/glb-writer.js.map +0 -1
- package/dist/gltf-loader.js.map +0 -1
- package/dist/gltf-writer.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/lib/api/gltf-extensions.js.map +0 -1
- package/dist/lib/api/gltf-scenegraph.js.map +0 -1
- package/dist/lib/api/normalize-gltf-v1.js.map +0 -1
- package/dist/lib/api/post-process-gltf.js.map +0 -1
- package/dist/lib/encoders/encode-glb.js.map +0 -1
- package/dist/lib/encoders/encode-gltf.js.map +0 -1
- package/dist/lib/extensions/EXT_mesh_features.js.map +0 -1
- package/dist/lib/extensions/EXT_meshopt_compression.js.map +0 -1
- package/dist/lib/extensions/EXT_structural_metadata.js.map +0 -1
- package/dist/lib/extensions/EXT_texture_webp.js.map +0 -1
- package/dist/lib/extensions/KHR_binary_gltf.js.map +0 -1
- package/dist/lib/extensions/KHR_draco_mesh_compression.js.map +0 -1
- package/dist/lib/extensions/KHR_texture_basisu.js.map +0 -1
- package/dist/lib/extensions/KHR_texture_transform.js.map +0 -1
- package/dist/lib/extensions/deprecated/EXT_feature_metadata.js.map +0 -1
- package/dist/lib/extensions/deprecated/KHR_lights_punctual.js.map +0 -1
- package/dist/lib/extensions/deprecated/KHR_materials_unlit.js.map +0 -1
- package/dist/lib/extensions/deprecated/KHR_techniques_webgl.js.map +0 -1
- package/dist/lib/extensions/utils/3d-tiles-utils.js.map +0 -1
- package/dist/lib/gltf-utils/get-typed-array.js.map +0 -1
- package/dist/lib/gltf-utils/gltf-attribute-utils.js.map +0 -1
- package/dist/lib/gltf-utils/gltf-constants.js.map +0 -1
- package/dist/lib/gltf-utils/gltf-utils.js.map +0 -1
- package/dist/lib/gltf-utils/resolve-url.js.map +0 -1
- package/dist/lib/parsers/parse-glb.js.map +0 -1
- package/dist/lib/parsers/parse-gltf.js.map +0 -1
- package/dist/lib/types/glb-types.js.map +0 -1
- package/dist/lib/types/gltf-ext-feature-metadata-schema.js.map +0 -1
- package/dist/lib/types/gltf-ext-mesh-features-schema.js.map +0 -1
- package/dist/lib/types/gltf-ext-structural-metadata-schema.js.map +0 -1
- package/dist/lib/types/gltf-json-schema.js.map +0 -1
- package/dist/lib/types/gltf-postprocessed-schema.js.map +0 -1
- package/dist/lib/types/gltf-types.js.map +0 -1
- package/dist/lib/utils/assert.js.map +0 -1
- package/dist/lib/utils/version.js.map +0 -1
- package/dist/meshopt/meshopt-decoder.js.map +0 -1
- package/dist/meshopt/meshopt-encoder.ts.disabled +0 -409
- package/dist/webp/webp.js.map +0 -1
|
@@ -1,214 +1,331 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* loaders.gl, MIT license
|
|
3
|
+
*
|
|
4
|
+
* Shared code for 3DTiles extensions:
|
|
5
|
+
* * EXT_feature_metadata
|
|
6
|
+
* * EXT_mesh_features
|
|
7
|
+
* * EXT_structural_metadata
|
|
8
|
+
*/
|
|
1
9
|
import { getComponentTypeFromArray } from "../../gltf-utils/gltf-utils.js";
|
|
2
10
|
import { getImageData } from '@loaders.gl/images';
|
|
3
11
|
function emod(n) {
|
|
4
|
-
|
|
12
|
+
return ((n % 1) + 1) % 1;
|
|
5
13
|
}
|
|
6
14
|
const ATTRIBUTE_TYPE_TO_COMPONENTS = {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
SCALAR: 1,
|
|
16
|
+
VEC2: 2,
|
|
17
|
+
VEC3: 3,
|
|
18
|
+
VEC4: 4,
|
|
19
|
+
MAT2: 4,
|
|
20
|
+
MAT3: 9,
|
|
21
|
+
MAT4: 16,
|
|
22
|
+
BOOLEAN: 1,
|
|
23
|
+
STRING: 1,
|
|
24
|
+
ENUM: 1
|
|
17
25
|
};
|
|
18
26
|
const ATTRIBUTE_COMPONENT_TYPE_TO_ARRAY = {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
INT8: Int8Array,
|
|
28
|
+
UINT8: Uint8Array,
|
|
29
|
+
INT16: Int16Array,
|
|
30
|
+
UINT16: Uint16Array,
|
|
31
|
+
INT32: Int32Array,
|
|
32
|
+
UINT32: Uint32Array,
|
|
33
|
+
INT64: BigInt64Array,
|
|
34
|
+
UINT64: BigUint64Array,
|
|
35
|
+
FLOAT32: Float32Array,
|
|
36
|
+
FLOAT64: Float64Array
|
|
29
37
|
};
|
|
30
38
|
const ATTRIBUTE_COMPONENT_TYPE_TO_BYTE_SIZE = {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
INT8: 1,
|
|
40
|
+
UINT8: 1,
|
|
41
|
+
INT16: 2,
|
|
42
|
+
UINT16: 2,
|
|
43
|
+
INT32: 4,
|
|
44
|
+
UINT32: 4,
|
|
45
|
+
INT64: 8,
|
|
46
|
+
UINT64: 8,
|
|
47
|
+
FLOAT32: 4,
|
|
48
|
+
FLOAT64: 8
|
|
41
49
|
};
|
|
42
50
|
export function getArrayElementByteSize(attributeType, componentType) {
|
|
43
|
-
|
|
51
|
+
return (ATTRIBUTE_COMPONENT_TYPE_TO_BYTE_SIZE[componentType] *
|
|
52
|
+
ATTRIBUTE_TYPE_TO_COMPONENTS[attributeType]);
|
|
44
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* Gets offset array from `arrayOffsets` or `stringOffsets`.
|
|
56
|
+
* @param scenegraph - Instance of the class for structured access to GLTF data.
|
|
57
|
+
* @param bufferViewIndex - Buffer view index
|
|
58
|
+
* @param offsetType - The type of values in `arrayOffsets` or `stringOffsets`.
|
|
59
|
+
* @param numberOfElements - The number of elements in each property array.
|
|
60
|
+
* @returns Array of values offsets. The number of offsets in the array is equal to `numberOfElements` plus one.
|
|
61
|
+
*/
|
|
45
62
|
export function getOffsetsForProperty(scenegraph, bufferViewIndex, offsetType, numberOfElements) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
63
|
+
if (offsetType !== 'UINT8' &&
|
|
64
|
+
offsetType !== 'UINT16' &&
|
|
65
|
+
offsetType !== 'UINT32' &&
|
|
66
|
+
offsetType !== 'UINT64') {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
const arrayOffsetsBytes = scenegraph.getTypedArrayForBufferView(bufferViewIndex);
|
|
70
|
+
const arrayOffsets = convertRawBufferToMetadataArray(arrayOffsetsBytes, 'SCALAR', // offsets consist of ONE component
|
|
71
|
+
offsetType, numberOfElements + 1 // The number of offsets is equal to the property table `count` plus one.
|
|
72
|
+
);
|
|
73
|
+
// We don't support BigInt offsets at the moment. It requires additional logic and potential issues in Safari
|
|
74
|
+
if (arrayOffsets instanceof BigInt64Array || arrayOffsets instanceof BigUint64Array) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
return arrayOffsets;
|
|
55
78
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
79
|
+
/**
|
|
80
|
+
* Converts raw bytes that are in the buffer to an array of the type defined by the schema.
|
|
81
|
+
* @param data - Raw bytes in the buffer.
|
|
82
|
+
* @param attributeType - SCALAR, VECN, MATN.
|
|
83
|
+
* @param componentType - Type of the component in elements, e.g. 'UINT8' or 'FLOAT32'.
|
|
84
|
+
* @param elementCount - Number of elements in the array. Default value is 1.
|
|
85
|
+
* @returns Data array
|
|
86
|
+
*/
|
|
87
|
+
export function convertRawBufferToMetadataArray(data, attributeType, componentType, elementCount = 1) {
|
|
88
|
+
const numberOfComponents = ATTRIBUTE_TYPE_TO_COMPONENTS[attributeType];
|
|
89
|
+
const ArrayType = ATTRIBUTE_COMPONENT_TYPE_TO_ARRAY[componentType];
|
|
90
|
+
const size = ATTRIBUTE_COMPONENT_TYPE_TO_BYTE_SIZE[componentType];
|
|
91
|
+
const length = elementCount * numberOfComponents;
|
|
92
|
+
const byteLength = length * size;
|
|
93
|
+
let buffer = data.buffer;
|
|
94
|
+
let offset = data.byteOffset;
|
|
95
|
+
if (offset % size !== 0) {
|
|
96
|
+
const bufferArray = new Uint8Array(buffer);
|
|
97
|
+
buffer = bufferArray.slice(offset, offset + byteLength).buffer;
|
|
98
|
+
offset = 0;
|
|
99
|
+
}
|
|
100
|
+
return new ArrayType(buffer, offset, length);
|
|
71
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* Processes data encoded in the texture associated with the primitive.
|
|
104
|
+
* @param scenegraph - Instance of the class for structured access to GLTF data.
|
|
105
|
+
* @param textureInfo - Reference to the texture where extension data are stored.
|
|
106
|
+
* @param primitive - Primitive object in the mesh.
|
|
107
|
+
* @returns Array of data taken. Null if data can't be taken from the texture.
|
|
108
|
+
*/
|
|
72
109
|
export function getPrimitiveTextureData(scenegraph, textureInfo, primitive) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
const imageIndex = (_json$textures = json.textures) === null || _json$textures === void 0 ? void 0 : (_json$textures$textur = _json$textures[textureIndex]) === null || _json$textures$textur === void 0 ? void 0 : _json$textures$textur.source;
|
|
80
|
-
if (typeof imageIndex !== 'undefined') {
|
|
81
|
-
var _json$images, _json$images$imageInd, _scenegraph$gltf$imag;
|
|
82
|
-
const mimeType = (_json$images = json.images) === null || _json$images === void 0 ? void 0 : (_json$images$imageInd = _json$images[imageIndex]) === null || _json$images$imageInd === void 0 ? void 0 : _json$images$imageInd.mimeType;
|
|
83
|
-
const parsedImage = (_scenegraph$gltf$imag = scenegraph.gltf.images) === null || _scenegraph$gltf$imag === void 0 ? void 0 : _scenegraph$gltf$imag[imageIndex];
|
|
84
|
-
if (parsedImage && typeof parsedImage.width !== 'undefined') {
|
|
85
|
-
const textureData = [];
|
|
86
|
-
for (let index = 0; index < textureCoordinates.length; index += 2) {
|
|
87
|
-
const value = getImageValueByCoordinates(parsedImage, mimeType, textureCoordinates, index, textureInfo.channels);
|
|
88
|
-
textureData.push(value);
|
|
110
|
+
/*
|
|
111
|
+
texture.index is an index for the "textures" array.
|
|
112
|
+
The texture object referenced by this index looks like this:
|
|
113
|
+
{
|
|
114
|
+
"sampler": 0,
|
|
115
|
+
"source": 0
|
|
89
116
|
}
|
|
90
|
-
|
|
117
|
+
"sampler" is an index for the "samplers" array
|
|
118
|
+
"source" is an index for the "images" array that contains data stored in rgba channels of the image.
|
|
119
|
+
|
|
120
|
+
texture.texCoord is a number-suffix (like 1) for an attribute like "TEXCOORD_1" in meshes.primitives
|
|
121
|
+
The value of "TEXCOORD_1" is an accessor that is used to get coordinates.
|
|
122
|
+
These coordinates are being used to get data from the image.
|
|
123
|
+
|
|
124
|
+
Default for texture.texCoord is 0
|
|
125
|
+
@see https://github.com/CesiumGS/glTF/blob/3d-tiles-next/specification/2.0/schema/textureInfo.schema.json
|
|
126
|
+
*/
|
|
127
|
+
const texCoordAccessorKey = `TEXCOORD_${textureInfo.texCoord || 0}`;
|
|
128
|
+
const texCoordAccessorIndex = primitive.attributes[texCoordAccessorKey];
|
|
129
|
+
const textureCoordinates = scenegraph.getTypedArrayForAccessor(texCoordAccessorIndex);
|
|
130
|
+
const json = scenegraph.gltf.json;
|
|
131
|
+
const textureIndex = textureInfo.index;
|
|
132
|
+
const imageIndex = json.textures?.[textureIndex]?.source;
|
|
133
|
+
if (typeof imageIndex !== 'undefined') {
|
|
134
|
+
const mimeType = json.images?.[imageIndex]?.mimeType;
|
|
135
|
+
const parsedImage = scenegraph.gltf.images?.[imageIndex];
|
|
136
|
+
// Checking for width is to prevent handling Un-processed images (e.g. [analyze] stage, where loadImages option is set to false)
|
|
137
|
+
if (parsedImage && typeof parsedImage.width !== 'undefined') {
|
|
138
|
+
const textureData = [];
|
|
139
|
+
for (let index = 0; index < textureCoordinates.length; index += 2) {
|
|
140
|
+
const value = getImageValueByCoordinates(parsedImage, mimeType, textureCoordinates, index, textureInfo.channels);
|
|
141
|
+
textureData.push(value);
|
|
142
|
+
}
|
|
143
|
+
return textureData;
|
|
144
|
+
}
|
|
91
145
|
}
|
|
92
|
-
|
|
93
|
-
return [];
|
|
146
|
+
return [];
|
|
94
147
|
}
|
|
148
|
+
/**
|
|
149
|
+
* Puts property data to attributes.
|
|
150
|
+
* It creates corresponding buffer, bufferView and accessor
|
|
151
|
+
* so the data can be accessed like regular data stored in buffers.
|
|
152
|
+
* @param scenegraph - Scenegraph object.
|
|
153
|
+
* @param attributeName - Name of the attribute.
|
|
154
|
+
* @param propertyData - Property data to store.
|
|
155
|
+
* @param featureTable - Array where unique data from the property data are being stored.
|
|
156
|
+
* @param primitive - Primitive object.
|
|
157
|
+
*/
|
|
95
158
|
export function primitivePropertyDataToAttributes(scenegraph, attributeName, propertyData, featureTable, primitive) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
const featureIndices = [];
|
|
100
|
-
for (const texelData of propertyData) {
|
|
101
|
-
let index = featureTable.findIndex(item => item === texelData);
|
|
102
|
-
if (index === -1) {
|
|
103
|
-
index = featureTable.push(texelData) - 1;
|
|
159
|
+
// No reason to create an empty buffer if there is no property data to store.
|
|
160
|
+
if (!propertyData?.length) {
|
|
161
|
+
return;
|
|
104
162
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
primitive.attributes[attributeName] = accessorIndex;
|
|
120
|
-
}
|
|
121
|
-
function getImageValueByCoordinates(parsedImage, mimeType, textureCoordinates, index) {
|
|
122
|
-
let channels = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : [0];
|
|
123
|
-
const CHANNELS_MAP = {
|
|
124
|
-
r: {
|
|
125
|
-
offset: 0,
|
|
126
|
-
shift: 0
|
|
127
|
-
},
|
|
128
|
-
g: {
|
|
129
|
-
offset: 1,
|
|
130
|
-
shift: 8
|
|
131
|
-
},
|
|
132
|
-
b: {
|
|
133
|
-
offset: 2,
|
|
134
|
-
shift: 16
|
|
135
|
-
},
|
|
136
|
-
a: {
|
|
137
|
-
offset: 3,
|
|
138
|
-
shift: 24
|
|
163
|
+
/*
|
|
164
|
+
featureTable will contain unique values, e.g.
|
|
165
|
+
propertyData = [24, 35, 28, 24]
|
|
166
|
+
featureTable = [24, 35, 28]
|
|
167
|
+
featureIndices will contain indices that refer featureTextureTable, e.g.
|
|
168
|
+
featureIndices = [0, 1, 2, 0]
|
|
169
|
+
*/
|
|
170
|
+
const featureIndices = [];
|
|
171
|
+
for (const texelData of propertyData) {
|
|
172
|
+
let index = featureTable.findIndex((item) => item === texelData);
|
|
173
|
+
if (index === -1) {
|
|
174
|
+
index = featureTable.push(texelData) - 1;
|
|
175
|
+
}
|
|
176
|
+
featureIndices.push(index);
|
|
139
177
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
178
|
+
const typedArray = new Uint32Array(featureIndices);
|
|
179
|
+
const bufferIndex = scenegraph.gltf.buffers.push({
|
|
180
|
+
arrayBuffer: typedArray.buffer,
|
|
181
|
+
byteOffset: typedArray.byteOffset,
|
|
182
|
+
byteLength: typedArray.byteLength
|
|
183
|
+
}) - 1;
|
|
184
|
+
const bufferViewIndex = scenegraph.addBufferView(typedArray, bufferIndex, 0);
|
|
185
|
+
const accessorIndex = scenegraph.addAccessor(bufferViewIndex, {
|
|
186
|
+
size: 1,
|
|
187
|
+
componentType: getComponentTypeFromArray(typedArray),
|
|
188
|
+
count: typedArray.length
|
|
189
|
+
});
|
|
190
|
+
primitive.attributes[attributeName] = accessorIndex;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Gets the value from the texture by coordinates provided.
|
|
194
|
+
* @param parsedImage - Image where the data are stored.
|
|
195
|
+
* @param mimeType - MIME type.
|
|
196
|
+
* @param textureCoordinates - uv coordinates to access data in the image.
|
|
197
|
+
* @param index - Index of uv coordinates in the array textureCoordinates.
|
|
198
|
+
* @param channels - Image channels where data are stored.
|
|
199
|
+
* Channels of an RGBA texture are numbered 0..3 respectively.
|
|
200
|
+
* For Ext_mesh_features and EXT_strucural_metadata the channels default is [0]
|
|
201
|
+
* @see https://github.com/CesiumGS/glTF/blob/3d-tiles-next/extensions/2.0/Vendor/EXT_mesh_features/schema/featureIdTexture.schema.json
|
|
202
|
+
* @see https://github.com/CesiumGS/glTF/blob/3d-tiles-next/extensions/2.0/Vendor/EXT_structural_metadata/schema/propertyTexture.property.schema.json
|
|
203
|
+
* @returns Value taken from the image.
|
|
204
|
+
*/
|
|
205
|
+
function getImageValueByCoordinates(parsedImage, mimeType, textureCoordinates, index, channels = [0]) {
|
|
206
|
+
const CHANNELS_MAP = {
|
|
207
|
+
r: { offset: 0, shift: 0 },
|
|
208
|
+
g: { offset: 1, shift: 8 },
|
|
209
|
+
b: { offset: 2, shift: 16 },
|
|
210
|
+
a: { offset: 3, shift: 24 }
|
|
211
|
+
};
|
|
212
|
+
const u = textureCoordinates[index];
|
|
213
|
+
const v = textureCoordinates[index + 1];
|
|
214
|
+
let components = 1;
|
|
215
|
+
if (mimeType && (mimeType.indexOf('image/jpeg') !== -1 || mimeType.indexOf('image/png') !== -1))
|
|
216
|
+
components = 4;
|
|
217
|
+
const offset = coordinatesToOffset(u, v, parsedImage, components);
|
|
218
|
+
let value = 0;
|
|
219
|
+
for (const c of channels) {
|
|
220
|
+
/*
|
|
221
|
+
According to the EXT_feature_metadata extension specification:
|
|
222
|
+
Channels are labeled by rgba and are swizzled with a string of 1-4 characters.
|
|
223
|
+
According to the EXT_mesh_features extension specification:
|
|
224
|
+
The channels array contains non-negative integer values corresponding to channels of the source texture that the feature ID consists of.
|
|
225
|
+
Channels of an RGBA texture are numbered 0–3 respectively.
|
|
226
|
+
Function getImageValueByCoordinates is used to process both extensions.
|
|
227
|
+
So, there should be possible to get the element of CHANNELS_MAP by either index (0, 1, 2, 3) or key (r, g, b, a).
|
|
228
|
+
*/
|
|
229
|
+
const map = typeof c === 'number' ? Object.values(CHANNELS_MAP)[c] : CHANNELS_MAP[c];
|
|
230
|
+
const imageOffset = offset + map.offset;
|
|
231
|
+
const imageData = getImageData(parsedImage);
|
|
232
|
+
if (imageData.data.length <= imageOffset) {
|
|
233
|
+
throw new Error(`${imageData.data.length} <= ${imageOffset}`);
|
|
234
|
+
}
|
|
235
|
+
const imageValue = imageData.data[imageOffset];
|
|
236
|
+
value |= imageValue << map.shift;
|
|
153
237
|
}
|
|
154
|
-
|
|
155
|
-
value |= imageValue << map.shift;
|
|
156
|
-
}
|
|
157
|
-
return value;
|
|
238
|
+
return value;
|
|
158
239
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
240
|
+
/**
|
|
241
|
+
* Retrieves the offset in the image where the data are stored.
|
|
242
|
+
* @param u - u-coordinate.
|
|
243
|
+
* @param v - v-coordinate.
|
|
244
|
+
* @param parsedImage - Image where the data are stored.
|
|
245
|
+
* @param componentsCount - Number of components the data consists of.
|
|
246
|
+
* @returns Offset in the image where the data are stored.
|
|
247
|
+
*/
|
|
248
|
+
function coordinatesToOffset(u, v, parsedImage, componentsCount = 1) {
|
|
249
|
+
const w = parsedImage.width;
|
|
250
|
+
const iX = emod(u) * (w - 1);
|
|
251
|
+
const indX = Math.round(iX);
|
|
252
|
+
const h = parsedImage.height;
|
|
253
|
+
const iY = emod(v) * (h - 1);
|
|
254
|
+
const indY = Math.round(iY);
|
|
255
|
+
const components = parsedImage.components ? parsedImage.components : componentsCount;
|
|
256
|
+
// components is a number of channels in the image
|
|
257
|
+
const offset = (indY * w + indX) * components;
|
|
258
|
+
return offset;
|
|
170
259
|
}
|
|
260
|
+
/**
|
|
261
|
+
* Parses variable-length array data.
|
|
262
|
+
* In this case every value of the property in the table will be an array
|
|
263
|
+
* of arbitrary length.
|
|
264
|
+
* @param valuesData - Values in a flat typed array.
|
|
265
|
+
* @param numberOfElements - Number of rows in the property table.
|
|
266
|
+
* @param arrayOffsets - Offsets of nested arrays in the flat values array.
|
|
267
|
+
* @param valuesDataBytesLength - Data byte length.
|
|
268
|
+
* @param valueSize - Value size in bytes.
|
|
269
|
+
* @returns Array of typed arrays.
|
|
270
|
+
*/
|
|
171
271
|
export function parseVariableLengthArrayNumeric(valuesData, numberOfElements, arrayOffsets, valuesDataBytesLength, valueSize) {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
272
|
+
const attributeValueArray = [];
|
|
273
|
+
for (let index = 0; index < numberOfElements; index++) {
|
|
274
|
+
const arrayOffset = arrayOffsets[index];
|
|
275
|
+
const arrayByteSize = arrayOffsets[index + 1] - arrayOffsets[index];
|
|
276
|
+
if (arrayByteSize + arrayOffset > valuesDataBytesLength) {
|
|
277
|
+
break;
|
|
278
|
+
}
|
|
279
|
+
const typedArrayOffset = arrayOffset / valueSize;
|
|
280
|
+
const elementCount = arrayByteSize / valueSize;
|
|
281
|
+
attributeValueArray.push(valuesData.slice(typedArrayOffset, typedArrayOffset + elementCount));
|
|
178
282
|
}
|
|
179
|
-
|
|
180
|
-
const elementCount = arrayByteSize / valueSize;
|
|
181
|
-
attributeValueArray.push(valuesData.slice(typedArrayOffset, typedArrayOffset + elementCount));
|
|
182
|
-
}
|
|
183
|
-
return attributeValueArray;
|
|
283
|
+
return attributeValueArray;
|
|
184
284
|
}
|
|
285
|
+
/**
|
|
286
|
+
* Parses fixed-length array data.
|
|
287
|
+
* In this case every value of the property in the table will be an array
|
|
288
|
+
* of constant length equal to `arrayCount`.
|
|
289
|
+
* @param valuesData - Values in a flat typed array.
|
|
290
|
+
* @param numberOfElements - Number of rows in the property table.
|
|
291
|
+
* @param arrayCount - Nested arrays length.
|
|
292
|
+
* @returns Array of typed arrays.
|
|
293
|
+
*/
|
|
185
294
|
export function parseFixedLengthArrayNumeric(valuesData, numberOfElements, arrayCount) {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
295
|
+
const attributeValueArray = [];
|
|
296
|
+
for (let index = 0; index < numberOfElements; index++) {
|
|
297
|
+
const elementOffset = index * arrayCount;
|
|
298
|
+
attributeValueArray.push(valuesData.slice(elementOffset, elementOffset + arrayCount));
|
|
299
|
+
}
|
|
300
|
+
return attributeValueArray;
|
|
192
301
|
}
|
|
302
|
+
/**
|
|
303
|
+
* Decodes properties of string type from binary source.
|
|
304
|
+
* @param numberOfElements - The number of elements in each property array that propertyTableProperty contains. It's a number of rows in the table.
|
|
305
|
+
* @param valuesDataBytes - Data taken from values property of the property table property.
|
|
306
|
+
* @param arrayOffsets - Offsets for variable-length arrays. It's null for fixed-length arrays or scalar types.
|
|
307
|
+
* @param stringOffsets - Index of the buffer view containing offsets for strings. It should be available for string type.
|
|
308
|
+
* @returns String property values
|
|
309
|
+
*/
|
|
193
310
|
export function getPropertyDataString(numberOfElements, valuesDataBytes, arrayOffsets, stringOffsets) {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
311
|
+
if (arrayOffsets) {
|
|
312
|
+
// TODO: implement it as soon as we have the corresponding tileset
|
|
313
|
+
throw new Error('Not implemented - arrayOffsets for strings is specified');
|
|
314
|
+
}
|
|
315
|
+
if (stringOffsets) {
|
|
316
|
+
const stringsArray = [];
|
|
317
|
+
const textDecoder = new TextDecoder('utf8');
|
|
318
|
+
let stringOffset = 0;
|
|
319
|
+
for (let index = 0; index < numberOfElements; index++) {
|
|
320
|
+
const stringByteSize = stringOffsets[index + 1] - stringOffsets[index];
|
|
321
|
+
if (stringByteSize + stringOffset <= valuesDataBytes.length) {
|
|
322
|
+
const stringData = valuesDataBytes.subarray(stringOffset, stringByteSize + stringOffset);
|
|
323
|
+
const stringAttribute = textDecoder.decode(stringData);
|
|
324
|
+
stringsArray.push(stringAttribute);
|
|
325
|
+
stringOffset += stringByteSize;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
return stringsArray;
|
|
209
329
|
}
|
|
210
|
-
return
|
|
211
|
-
}
|
|
212
|
-
return [];
|
|
330
|
+
return [];
|
|
213
331
|
}
|
|
214
|
-
//# sourceMappingURL=3d-tiles-utils.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { TypedArray } from '@loaders.gl/schema';
|
|
2
|
-
import type { GLTF, GLTFExternalBuffer, GLTFAccessor } from
|
|
2
|
+
import type { GLTF, GLTFExternalBuffer, GLTFAccessor } from "../types/gltf-types.js";
|
|
3
3
|
export declare function getTypedArrayForBufferView(json: any, buffers: any, bufferViewIndex: any): Uint8Array;
|
|
4
4
|
export declare function getTypedArrayForImageData(json: any, buffers: any, imageIndex: any): Uint8Array;
|
|
5
5
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-typed-array.d.ts","sourceRoot":"","sources":["../../../src/lib/gltf-utils/get-typed-array.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAC,IAAI,EAAE,kBAAkB,EAAE,YAAY,EAAC
|
|
1
|
+
{"version":3,"file":"get-typed-array.d.ts","sourceRoot":"","sources":["../../../src/lib/gltf-utils/get-typed-array.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAC,IAAI,EAAE,kBAAkB,EAAE,YAAY,EAAC,+BAA4B;AAKhF,wBAAgB,0BAA0B,CAAC,IAAI,KAAA,EAAE,OAAO,KAAA,EAAE,eAAe,KAAA,cAWxE;AAID,wBAAgB,yBAAyB,CAAC,IAAI,KAAA,EAAE,OAAO,KAAA,EAAE,UAAU,KAAA,cAIlE;AAED;;;;;;GAMG;AAEH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,kBAAkB,EAAE,EAC7B,QAAQ,EAAE,YAAY,GAAG,MAAM,GAC9B,UAAU,CAsCZ"}
|
|
@@ -1,51 +1,63 @@
|
|
|
1
|
+
// TODO - GLTFScenegraph should use these
|
|
1
2
|
import { assert } from "../utils/assert.js";
|
|
2
3
|
import { getAccessorArrayTypeAndLength } from "./gltf-utils.js";
|
|
4
|
+
// accepts buffer view index or buffer view object
|
|
5
|
+
// returns a `Uint8Array`
|
|
3
6
|
export function getTypedArrayForBufferView(json, buffers, bufferViewIndex) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
const bufferView = json.bufferViews[bufferViewIndex];
|
|
8
|
+
assert(bufferView);
|
|
9
|
+
// Get hold of the arrayBuffer
|
|
10
|
+
const bufferIndex = bufferView.buffer;
|
|
11
|
+
const binChunk = buffers[bufferIndex];
|
|
12
|
+
assert(binChunk);
|
|
13
|
+
const byteOffset = (bufferView.byteOffset || 0) + binChunk.byteOffset;
|
|
14
|
+
return new Uint8Array(binChunk.arrayBuffer, byteOffset, bufferView.byteLength);
|
|
11
15
|
}
|
|
16
|
+
// accepts accessor index or accessor object
|
|
17
|
+
// returns a `Uint8Array`
|
|
12
18
|
export function getTypedArrayForImageData(json, buffers, imageIndex) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
19
|
+
const image = json.images[imageIndex];
|
|
20
|
+
const bufferViewIndex = json.bufferViews[image.bufferView];
|
|
21
|
+
return getTypedArrayForBufferView(json, buffers, bufferViewIndex);
|
|
16
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* Gets data pointed by the accessor.
|
|
25
|
+
* @param json - json part of gltf content of a GLTF tile.
|
|
26
|
+
* @param buffers - Array containing buffers of data.
|
|
27
|
+
* @param accessor - accepts accessor index or accessor object.
|
|
28
|
+
* @returns {TypedArray} Typed array with type matching the type of data poited by the accessor.
|
|
29
|
+
*/
|
|
30
|
+
// eslint-disable-next-line complexity
|
|
17
31
|
export function getTypedArrayForAccessor(json, buffers, accessor) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
byteOffset
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
32
|
+
const gltfAccessor = typeof accessor === 'number' ? json.accessors?.[accessor] : accessor;
|
|
33
|
+
if (!gltfAccessor) {
|
|
34
|
+
throw new Error(`No gltf accessor ${JSON.stringify(accessor)}`);
|
|
35
|
+
}
|
|
36
|
+
const bufferView = json.bufferViews?.[gltfAccessor.bufferView || 0];
|
|
37
|
+
if (!bufferView) {
|
|
38
|
+
throw new Error(`No gltf buffer view for accessor ${bufferView}`);
|
|
39
|
+
}
|
|
40
|
+
// Get `arrayBuffer` the `bufferView` looks at
|
|
41
|
+
const { arrayBuffer, byteOffset: bufferByteOffset } = buffers[bufferView.buffer];
|
|
42
|
+
// Resulting byteOffset is sum of the buffer, accessor and bufferView byte offsets
|
|
43
|
+
const byteOffset = (bufferByteOffset || 0) + (gltfAccessor.byteOffset || 0) + (bufferView.byteOffset || 0);
|
|
44
|
+
// Deduce TypedArray type and its length from `accessor` and `bufferView` data
|
|
45
|
+
const { ArrayType, length, componentByteSize, numberOfComponentsInElement } = getAccessorArrayTypeAndLength(gltfAccessor, bufferView);
|
|
46
|
+
// 'length' is a whole number of components of all elements in the buffer pointed by the accessor
|
|
47
|
+
// Multiplier to calculate the address of the element in the arrayBuffer
|
|
48
|
+
const elementByteSize = componentByteSize * numberOfComponentsInElement;
|
|
49
|
+
const elementAddressScale = bufferView.byteStride || elementByteSize;
|
|
50
|
+
// Creare an array of component's type where all components (not just elements) will reside
|
|
51
|
+
if (typeof bufferView.byteStride === 'undefined' || bufferView.byteStride === elementByteSize) {
|
|
52
|
+
// No iterleaving
|
|
53
|
+
const result = new ArrayType(arrayBuffer, byteOffset, length);
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
56
|
+
// Iterleaving
|
|
57
|
+
const result = new ArrayType(length);
|
|
58
|
+
for (let i = 0; i < gltfAccessor.count; i++) {
|
|
59
|
+
const values = new ArrayType(arrayBuffer, byteOffset + i * elementAddressScale, numberOfComponentsInElement);
|
|
60
|
+
result.set(values, i * numberOfComponentsInElement);
|
|
61
|
+
}
|
|
42
62
|
return result;
|
|
43
|
-
}
|
|
44
|
-
const result = new ArrayType(length);
|
|
45
|
-
for (let i = 0; i < gltfAccessor.count; i++) {
|
|
46
|
-
const values = new ArrayType(arrayBuffer, byteOffset + i * elementAddressScale, numberOfComponentsInElement);
|
|
47
|
-
result.set(values, i * numberOfComponentsInElement);
|
|
48
|
-
}
|
|
49
|
-
return result;
|
|
50
63
|
}
|
|
51
|
-
//# sourceMappingURL=get-typed-array.js.map
|