pmndrs / gltfjsx

🎮 Turns GLTFs into JSX components
https://gltf.pmnd.rs
MIT License
4.41k stars 290 forks source link

[🐞 Bug Fix] 6.2.8 breaks parsing of models with interleaved buffers #214

Closed billykwok closed 6 months ago

billykwok commented 11 months ago

Issue

After updating to 6.2.8, parsing 3D models with interleaved buffer always gives the following error.

TypeError: Cannot set property count of #<InterleavedBufferAttribute> which has only a getter
    at file:///<redacted>/node_modules/.pnpm/gltfjsx@6.2.8/node_modules/gltfjsx/src/bin/GLTFLoader.js:1675:27
    at async Promise.all (index 0)
    at async Promise.all (index 0)
    at async Promise.all (index 0)
    at async Promise.all (index 1)
    at async Promise.all (index 0)
    at async Promise.all (index 1)
    at async Promise.all (index 0)
    at async Promise.all (index 0)

Investigation

In /src/bin/GLTFLoader.js#L1675, the count property of bufferAttribute is assigned an updated value.

// ...
bufferAttribute.count = accessorDef.count
// ...

Prior to the assignment, bufferAttribute was instantiated as either BufferAttribute or InterleavedBufferAttribute. This is fine for BufferAttribute as its count property is mutable.

However, in InterleavedBufferAttribute, count is just a getter that returns the count of the underlying InterleavedBuffer. Attempting to assign a new value to count will throw an error.

https://github.com/mrdoob/three.js/blob/master/src/core/InterleavedBufferAttribute.js#L23

get count() {
  return this.data.count;
}

This issue doesn't apply to versions prior to 6.2.8 because the line was newly added to this version.

Solution

I made a very small fix to update count differently if the bufferAttribute is a InterleavedBufferAttribute.

if (bufferAttribute.isInterleavedBufferAttribute) {
  bufferAttribute.data.count = accessorDef.count
} else {
  bufferAttribute.count = accessorDef.count
}
drcmda commented 6 months ago

thanks!