loadAccessor method

dynamic loadAccessor(
  1. 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;
}