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 {
  var parser = this;
  var json = this.json;

  Map<String, dynamic> accessorDef = this.json["accessors"][accessorIndex];

  if (accessorDef["bufferView"] == null && accessorDef["sparse"] == null) {
    // Ignore empty accessors, which may be used to declare runtime
    // information about attributes coming from another source (e.g. Draco
    // compression extension).
    return null;
  }

  var bufferView;
  if (accessorDef["bufferView"] != null) {
    bufferView =
        await this.getDependency('bufferView', accessorDef["bufferView"]);
  } else {
    bufferView = null;
  }

  var sparseIndicesBufferView;
  var sparseValuesBufferView;

  if (accessorDef["sparse"] != null) {
    final _sparse = accessorDef["sparse"];
    sparseIndicesBufferView = await this
        .getDependency('bufferView', _sparse["indices"]["bufferView"]);
    sparseValuesBufferView = await this
        .getDependency('bufferView', _sparse["values"]["bufferView"]);
  }

  int itemSize = WEBGL_TYPE_SIZES[accessorDef["type"]]!;
  var typedArray = GLTypeData(accessorDef["componentType"]);

  // For VEC3: itemSize is 3, elementBytes is 4, itemBytes is 12.
  var elementBytes = typedArray.getBytesPerElement();
  var itemBytes = elementBytes * itemSize;
  var byteOffset = accessorDef["byteOffset"] ?? 0;
  var byteStride = accessorDef["bufferView"] != null
      ? json["bufferViews"][accessorDef["bufferView"]]["byteStride"]
      : null;
  var normalized = accessorDef["normalized"] == true;
  List<double> array;
  var 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
    var ibSlice = Math.floor(byteOffset / byteStride);
    var ibCacheKey =
        'InterleavedBuffer:${accessorDef["bufferView"]}:${accessorDef["componentType"]}:${ibSlice}:${accessorDef["count"]}';
    var ib = parser.cache.get(ibCacheKey);

    if (ib == null) {
      // array = TypedArray.view( bufferView, ibSlice * byteStride, accessorDef.count * byteStride / elementBytes );
      array = typedArray.view(bufferView, ibSlice * byteStride,
          accessorDef["count"] * byteStride / elementBytes);

      // Integer parameters to IB/IBA are in array elements, not bytes.
      ib = new InterleavedBuffer(Float32Array.fromList(array), byteStride / elementBytes);

      parser.cache.add(ibCacheKey, ib);
    }

    bufferAttribute = new InterleavedBufferAttribute(
        ib, itemSize, (byteOffset % byteStride) / elementBytes, normalized);
  } else {
    if (bufferView == null) {
      array = typedArray.createList(accessorDef["count"] * itemSize);
      bufferAttribute =
        GLTypeData.createBufferAttribute(array, itemSize, normalized);
    } else {
      var _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) {
    var itemSizeIndices = WEBGL_TYPE_SIZES["SCALAR"]!;
    var typedArrayIndices =
        GLTypeData(accessorDef["sparse"]["indices"]["componentType"]);

    var byteOffsetIndices =
        accessorDef["sparse"]["indices"]["byteOffset"] ?? 0;
    var byteOffsetValues = accessorDef["sparse"]["values"]["byteOffset"] ?? 0;

    var sparseIndices = typedArrayIndices.view(sparseIndicesBufferView,
        byteOffsetIndices, accessorDef["sparse"]["count"] * itemSizeIndices);
    var 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 (var i = 0, il = sparseIndices.length; i < il; i++) {
      var 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;
}