Skip to content

Commit

Permalink
fix(core): Avoid spreading long arrays (#1573)
Browse files Browse the repository at this point in the history
For large arrays, `results.push(...array)` may lead to "Maximum call stack size exceeded" errors. In the example fixed here, I/O concatenates some 1M+ accessors from 1800+ animations.
  • Loading branch information
donmccurdy authored Nov 29, 2024
1 parent 3d61426 commit 0d6025e
Showing 1 changed file with 15 additions and 5 deletions.
20 changes: 15 additions & 5 deletions packages/core/src/io/writer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -483,32 +483,42 @@ export class GLTFWriter {
// (1) Interleaved vertex attributes.
const result = interleaveAccessors(groupAccessors, bufferIndex, bufferByteLength);
bufferByteLength += result.byteLength;
buffers.push(...result.buffers);
for (const buffer of result.buffers) {
buffers.push(buffer);
}
} else if (usage === BufferViewUsage.ARRAY_BUFFER) {
// (2) Non-interleaved vertex attributes.
for (const accessor of groupAccessors) {
// We 'interleave' a single accessor because the method pads to
// 4-byte boundaries, which concatAccessors() does not.
const result = interleaveAccessors([accessor], bufferIndex, bufferByteLength);
bufferByteLength += result.byteLength;
buffers.push(...result.buffers);
for (const buffer of result.buffers) {
buffers.push(buffer);
}
}
} else if (usage === BufferViewUsage.SPARSE) {
// (3) Sparse accessors.
const result = concatSparseAccessors(groupAccessors, bufferIndex, bufferByteLength);
bufferByteLength += result.byteLength;
buffers.push(...result.buffers);
for (const buffer of result.buffers) {
buffers.push(buffer);
}
} else if (usage === BufferViewUsage.ELEMENT_ARRAY_BUFFER) {
// (4) Indices.
const target = WriterContext.BufferViewTarget.ELEMENT_ARRAY_BUFFER;
const result = concatAccessors(groupAccessors, bufferIndex, bufferByteLength, target);
bufferByteLength += result.byteLength;
buffers.push(...result.buffers);
for (const buffer of result.buffers) {
buffers.push(buffer);
}
} else {
// (5) Other.
const result = concatAccessors(groupAccessors, bufferIndex, bufferByteLength);
bufferByteLength += result.byteLength;
buffers.push(...result.buffers);
for (const buffer of result.buffers) {
buffers.push(buffer);
}
}
}

Expand Down

0 comments on commit 0d6025e

Please sign in to comment.