export function padBuffer()

in modules/core/src/lib/attribute/attribute-transition-utils.js [87:138]


export function padBuffer({
  buffer,
  numInstances,
  attribute,
  fromLength,
  fromStartIndices,
  getData = x => x
}) {
  // TODO: move the precisionMultiplier logic to the attribute when retrieving
  // its `size` and `elementOffset`?
  const precisionMultiplier = attribute.doublePrecision ? 2 : 1;
  const size = attribute.size * precisionMultiplier;
  const byteOffset = attribute.byteOffset;
  const toStartIndices = attribute.startIndices;
  const hasStartIndices = fromStartIndices && toStartIndices;
  const toLength = getAttributeBufferLength(attribute, numInstances);
  const isConstant = attribute.state.constant;

  // check if buffer needs to be padded
  if (!hasStartIndices && fromLength >= toLength) {
    return;
  }

  const toData = isConstant
    ? attribute.value
    : attribute.getBuffer().getData({srcByteOffset: byteOffset});
  if (attribute.settings.normalized && !isConstant) {
    const getter = getData;
    getData = (value, chunk) => attribute._normalizeConstant(getter(value, chunk));
  }

  const getMissingData = isConstant
    ? (i, chunk) => getData(toData, chunk)
    : (i, chunk) => getData(toData.subarray(i, i + size), chunk);

  const source = buffer.getData({length: fromLength});
  const data = new Float32Array(toLength);
  padArray({
    source,
    target: data,
    sourceStartIndices: fromStartIndices,
    targetStartIndices: toStartIndices,
    size,
    getData: getMissingData
  });

  // TODO: support offset in buffer.setData?
  if (buffer.byteLength < data.byteLength + byteOffset) {
    buffer.reallocate(data.byteLength + byteOffset);
  }
  buffer.subData({data, offset: byteOffset});
}