decodeDracoGeometry = {
function decodeBuffer(decoder, data) {
const buffer = new draco.DecoderBuffer();
buffer.Init(new Int8Array(data), data.byteLength);
const geometryType = decoder.GetEncodedGeometryType(buffer);
let geometry, status;
if (geometryType === draco.TRIANGULAR_MESH) {
geometry = new draco.Mesh();
status = decoder.DecodeBufferToMesh(buffer, geometry);
} else if (geometryType === draco.POINT_CLOUD) {
geometry = new draco.PointCloud();
status = decoder.DecodeBufferToPointCloud(buffer, geometry);
} else {
draco.destroy(decoder);
draco.destroy(geometry);
draco.destroy(buffer);
throw new Error('Unknown geometry type.');
}
if (!status.ok() || geometry.ptr === 0) {
draco.destroy(decoder);
draco.destroy(geometry);
draco.destroy(buffer);
throw new Error('Decoding failed: ' + status.error_msg());
}
draco.destroy(buffer);
return geometry;
}
const ATTRIB_ID = {
position: draco.POSITION,
normal: draco.NORMAL,
color: draco.COLOR,
uv: draco.TEX_COORD
};
const DATA_TYPE = {
[Float32Array]: draco.DT_FLOAT32,
[Int8Array]: draco.DT_INT8,
[Int16Array]: draco.DT_INT16,
[Int32Array]: draco.DT_INT32,
[Uint8Array]: draco.DT_UINT8,
[Uint16Array]: draco.DT_UINT16,
[Uint32Array]: draco.DT_UINT32
};
function decodeAttribute(decoder, geometry, key, type) {
const attId = decoder.GetAttributeId(geometry, ATTRIB_ID[key]);
if (attId == -1)
return null;
const attribute = decoder.GetAttribute(geometry, attId);
const numComponents = attribute.num_components();
const numPoints = geometry.num_points();
const numValues = numPoints * numComponents;
const byteLength = numValues * type.BYTES_PER_ELEMENT;
const dataType = DATA_TYPE[type];
const ptr = draco._malloc( byteLength );
decoder.GetAttributeDataArrayForAllPoints(geometry, attribute, dataType, byteLength, ptr);
const array = new type(draco.HEAPF32.buffer, ptr, numValues).slice();
draco._free( ptr );
return array;
}
function decodeIndices(decoder, geometry) {
const numFaces = geometry.num_faces();
const numIndices = numFaces * 3;
const byteLength = numIndices * 4;
const ptr = draco._malloc(byteLength);
decoder.GetTrianglesUInt32Array(geometry, byteLength, ptr);
const index = new Uint32Array(draco.HEAPF32.buffer, ptr, numIndices).slice();
draco._free( ptr );
return index;
}
return (data, attribs) => {
const decoder = new draco.Decoder();
const geometry = decodeBuffer(decoder, data);
const mesh = {};
for (const key in attribs) {
mesh[key] = decodeAttribute(decoder, geometry, key, attribs[key]);
}
mesh["indices"] = decodeIndices(decoder, geometry);
draco.destroy(geometry);
draco.destroy(decoder);
return mesh;
}
}