Skip to content

Commit db95ded

Browse files
authored
Improved compatibility of draco encoded meshes (playcanvas#2016)
1 parent 9ebadaa commit db95ded

File tree

1 file changed

+40
-41
lines changed

1 file changed

+40
-41
lines changed

src/resources/parser/glb-parser.js

Lines changed: 40 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -258,46 +258,48 @@ Object.assign(pc, function () {
258258
var numPoints = outputGeometry.num_points();
259259

260260
// helper function to decode data stream with id to TypedArray of appropriate type
261-
var extractDracoAttributeInfo = function (uniqueId, storageType, componentSizeInBytes, normalize) {
261+
var extractDracoAttributeInfo = function (uniqueId) {
262262
var attribute = decoder.GetAttributeByUniqueId(outputGeometry, uniqueId);
263263
var numValues = numPoints * attribute.num_components();
264-
componentSizeInBytes = normalize ? 4 : componentSizeInBytes; // if normalized, always decompress to float32 buffer
265-
var dataSize = numValues * componentSizeInBytes;
266-
var ptr = decoderModule._malloc( dataSize );
267-
var values, k;
268-
269-
switch (storageType) {
270-
case pc.TYPE_FLOAT32:
271-
decoder.GetAttributeDataArrayForAllPoints(outputGeometry, attribute, decoderModule.DT_FLOAT32, dataSize, ptr);
272-
values = new Float32Array(decoderModule.HEAPF32.buffer, ptr, numValues).slice();
264+
var dracoFormat = attribute.data_type();
265+
var ptr, values, componentSizeInBytes, storageType;
266+
267+
// storage format is based on draco attribute data type
268+
switch (dracoFormat) {
269+
270+
case decoderModule.DT_UINT8:
271+
storageType = pc.TYPE_UINT8;
272+
componentSizeInBytes = 1;
273+
ptr = decoderModule._malloc(numValues * componentSizeInBytes);
274+
decoder.GetAttributeDataArrayForAllPoints(outputGeometry, attribute, decoderModule.DT_UINT8, numValues * componentSizeInBytes, ptr);
275+
values = new Uint8Array(decoderModule.HEAPU8.buffer, ptr, numValues).slice();
273276
break;
274277

275-
case pc.TYPE_UINT8:
276-
if (normalize) {
277-
decoder.GetAttributeDataArrayForAllPoints(outputGeometry, attribute, decoderModule.DT_FLOAT32, dataSize, ptr);
278-
valuesFloat32 = new Float32Array(decoderModule.HEAPF32.buffer, ptr, numValues).slice();
279-
280-
values = new Uint8ClampedArray(numValues);
281-
for (k = 0; k < numValues; k++)
282-
values[k] = valuesFloat32[k] * 255;
283-
} else {
284-
decoder.GetAttributeDataArrayForAllPoints(outputGeometry, attribute, decoderModule.DT_UINT8, dataSize, ptr);
285-
values = new Uint8Array(decoderModule.HEAPU8.buffer, ptr, numValues).slice();
286-
}
278+
case decoderModule.DT_UINT16:
279+
storageType = pc.TYPE_UINT16;
280+
componentSizeInBytes = 2;
281+
ptr = decoderModule._malloc(numValues * componentSizeInBytes);
282+
decoder.GetAttributeDataArrayForAllPoints(outputGeometry, attribute, decoderModule.DT_UINT16, numValues * componentSizeInBytes, ptr);
283+
values = new Uint16Array(decoderModule.HEAPU16.buffer, ptr, numValues).slice();
287284
break;
288285

286+
case decoderModule.DT_FLOAT32:
289287
default:
290-
// #ifdef DEBUG
291-
console.error("Element type not implemented: " + storageType);
292-
// #endif
288+
storageType = pc.TYPE_FLOAT32;
289+
componentSizeInBytes = 4;
290+
ptr = decoderModule._malloc(numValues * componentSizeInBytes);
291+
decoder.GetAttributeDataArrayForAllPoints(outputGeometry, attribute, decoderModule.DT_FLOAT32, numValues * componentSizeInBytes, ptr);
292+
values = new Float32Array(decoderModule.HEAPF32.buffer, ptr, numValues).slice();
293293
break;
294294
}
295295

296296
decoderModule._free(ptr);
297297

298298
return {
299299
values: values,
300-
numComponents: attribute.num_components()
300+
numComponents: attribute.num_components(),
301+
componentSizeInBytes: componentSizeInBytes,
302+
storageType: storageType
301303
};
302304
};
303305

@@ -309,20 +311,17 @@ Object.assign(pc, function () {
309311
if (attributes.hasOwnProperty(attrib) && semanticMap.hasOwnProperty(attrib)) {
310312
var semanticInfo = semanticMap[attrib];
311313
var semantic = semanticInfo.semantic;
312-
var storageType = semanticInfo.storageType;
313-
var componentSizeInBytes = semanticInfo.byteSize;
314-
var normalize = semanticMap[attrib].normalize;
315-
var attributeInfo = extractDracoAttributeInfo(attributes[attrib], storageType, componentSizeInBytes, normalize);
314+
var attributeInfo = extractDracoAttributeInfo(attributes[attrib]);
316315

317316
vertexDesc.push({
318317
semantic: semantic,
319318
components: attributeInfo.numComponents,
320-
type: storageType,
319+
type: attributeInfo.storageType,
321320
normalize: semanticMap[attrib].normalize
322321
});
323322

324323
// store the info we'll need to copy this data into the vertex buffer
325-
var size = attributeInfo.numComponents * componentSizeInBytes;
324+
var size = attributeInfo.numComponents * attributeInfo.componentSizeInBytes;
326325
sourceDesc[semantic] = {
327326
values: attributeInfo.values,
328327
buffer: attributeInfo.values.buffer,
@@ -396,15 +395,15 @@ Object.assign(pc, function () {
396395
var meshes = [];
397396

398397
var semanticMap = {
399-
'POSITION': { semantic: pc.SEMANTIC_POSITION, storageType: pc.TYPE_FLOAT32, byteSize: 4 },
400-
'NORMAL': { semantic: pc.SEMANTIC_NORMAL, storageType: pc.TYPE_FLOAT32, byteSize: 4 },
401-
'TANGENT': { semantic: pc.SEMANTIC_TANGENT, storageType: pc.TYPE_FLOAT32, byteSize: 4 },
402-
'BINORMAL': { semantic: pc.SEMANTIC_BINORMAL, storageType: pc.TYPE_FLOAT32, byteSize: 4 },
403-
'COLOR_0': { semantic: pc.SEMANTIC_COLOR, storageType: pc.TYPE_UINT8, byteSize: 1, normalize: true },
404-
'JOINTS_0': { semantic: pc.SEMANTIC_BLENDINDICES, storageType: pc.TYPE_UINT8, byteSize: 1 },
405-
'WEIGHTS_0': { semantic: pc.SEMANTIC_BLENDWEIGHT, storageType: pc.TYPE_FLOAT32, byteSize: 4 },
406-
'TEXCOORD_0': { semantic: pc.SEMANTIC_TEXCOORD0, storageType: pc.TYPE_FLOAT32, byteSize: 4 },
407-
'TEXCOORD_1': { semantic: pc.SEMANTIC_TEXCOORD1, storageType: pc.TYPE_FLOAT32, byteSize: 4 }
398+
'POSITION': { semantic: pc.SEMANTIC_POSITION },
399+
'NORMAL': { semantic: pc.SEMANTIC_NORMAL },
400+
'TANGENT': { semantic: pc.SEMANTIC_TANGENT },
401+
'BINORMAL': { semantic: pc.SEMANTIC_BINORMAL },
402+
'COLOR_0': { semantic: pc.SEMANTIC_COLOR },
403+
'JOINTS_0': { semantic: pc.SEMANTIC_BLENDINDICES },
404+
'WEIGHTS_0': { semantic: pc.SEMANTIC_BLENDWEIGHT },
405+
'TEXCOORD_0': { semantic: pc.SEMANTIC_TEXCOORD0 },
406+
'TEXCOORD_1': { semantic: pc.SEMANTIC_TEXCOORD1 }
408407
};
409408

410409
meshData.primitives.forEach(function (primitive) {

0 commit comments

Comments
 (0)