loadAccessor method
dynamic
loadAccessor(
- dynamic accessorIndex
Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#accessors @param {number} accessorIndex @return {Promise<BufferAttribute|InterleavedBufferAttribute>}
Implementation
loadAccessor(accessorIndex) async {
final parser = this;
final json = this.json;
Map<String, dynamic> accessorDef = this.json["accessors"][accessorIndex];
if (accessorDef["bufferView"] == null && accessorDef["sparse"] == null) {
final itemSize = webglTypeSize[ accessorDef['type'] ];
final TypedArray = webglComponentTypes[ accessorDef['componentType'] ]!;
final normalized = accessorDef['normalized'] == true;
final array = TypedArray( accessorDef['count'] * itemSize );
return BufferAttribute.fromUnknown(array, itemSize!, normalized );
}
dynamic bufferView;
if (accessorDef["bufferView"] != null) {
bufferView = await getDependency('bufferView', accessorDef["bufferView"]);
}
else {
bufferView = null;
}
dynamic sparseIndicesBufferView;
dynamic sparseValuesBufferView;
if (accessorDef["sparse"] != null) {
final sparse = accessorDef["sparse"];
sparseIndicesBufferView = await getDependency('bufferView', sparse["indices"]["bufferView"]);
sparseValuesBufferView = await getDependency('bufferView', sparse["values"]["bufferView"]);
}
int itemSize = webglTypeSize[accessorDef["type"]]!;
final typedArray = GLTypeData(accessorDef["componentType"]);
// For VEC3: itemSize is 3, elementBytes is 4, itemBytes is 12.
final elementBytes = typedArray.getBytesPerElement() ?? 0;
final itemBytes = elementBytes * itemSize;
final byteOffset = accessorDef["byteOffset"] ?? 0;
final int? byteStride = accessorDef["bufferView"] != null
? json["bufferViews"][accessorDef["bufferView"]]["byteStride"]
: null;
final normalized = accessorDef["normalized"] == true;
dynamic array;
dynamic bufferAttribute;
// The buffer is not interleaved if the stride is the item size in bytes.
if (byteStride != null && byteStride != itemBytes) {
// Each "slice" of the buffer, as defined by 'count' elements of 'byteStride' bytes, gets its own InterleavedBuffer
// This makes sure that IBA.count reflects accessor.count properly
final ibSlice = (byteOffset / byteStride).floor();
final ibCacheKey = 'InterleavedBuffer:${accessorDef["bufferView"]}:${accessorDef["componentType"]}:$ibSlice:${accessorDef["count"]}';
dynamic ib = parser.cache.get(ibCacheKey);
if (ib == null) {
array = typedArray.view(
bufferView,
ibSlice * byteStride,
(accessorDef["count"] * byteStride) ~/ elementBytes
);
final int stride = byteStride ~/ elementBytes;
int totalLen = array.length;
if(array is Uint8List){
ib = InterleavedBuffer(Uint8Array(totalLen).set(array.buffer.asUint8List()), 1);
}
else if(array is Int8List){
ib = InterleavedBuffer(Int8Array(totalLen).set(array.buffer.asInt8List()), 1);
}
else{
ib = InterleavedBuffer(Float32Array(totalLen).set(array.buffer.asFloat32List()), stride);
}
parser.cache.add(ibCacheKey, ib);
}
bufferAttribute = InterleavedBufferAttribute(ib, itemSize, (byteOffset % byteStride) ~/ elementBytes, normalized);
}
else {
if (bufferView == null) {
array = typedArray.createList(accessorDef["count"] * itemSize);
}
else {
array = typedArray.view(bufferView, byteOffset, accessorDef["count"] * itemSize);
}
bufferAttribute = GLTypeData.createBufferAttribute(array, itemSize, normalized);
}
// https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#sparse-accessors
if (accessorDef["sparse"] != null) {
final itemSizeIndices = webglTypeSize["SCALAR"]!;
final typedArrayIndices = GLTypeData(accessorDef["sparse"]["indices"]["componentType"]);
final byteOffsetIndices = accessorDef["sparse"]["indices"]["byteOffset"] ?? 0;
final byteOffsetValues = accessorDef["sparse"]["values"]["byteOffset"] ?? 0;
final sparseIndices = typedArrayIndices.view(sparseIndicesBufferView,
byteOffsetIndices, accessorDef["sparse"]["count"] * itemSizeIndices);
final sparseValues = typedArray.view(sparseValuesBufferView,
byteOffsetValues, accessorDef["sparse"]["count"] * itemSize);
if (bufferView != null) {
// Avoid modifying the original ArrayBuffer, if the bufferView wasn't initialized with zeroes.
bufferAttribute = Float32BufferAttribute(bufferAttribute.array.clone(),
bufferAttribute.itemSize, bufferAttribute.normalized);
}
for (int i = 0, il = sparseIndices.length; i < il; i++) {
final index = sparseIndices[i];
bufferAttribute.setX(index, sparseValues[i * itemSize]);
if (itemSize >= 2){
bufferAttribute.setY(index, sparseValues[i * itemSize + 1]);
}
if (itemSize >= 3){
bufferAttribute.setZ(index, sparseValues[i * itemSize + 2]);
}
if (itemSize >= 4){
bufferAttribute.setW(index, sparseValues[i * itemSize + 3]);
}
if (itemSize >= 5){
throw ('THREE.GLTFLoader: Unsupported itemSize in sparse BufferAttribute.');
}
}
}
return bufferAttribute;
}