<p dir="auto">When input GLTF file contains accessors with stride that doesn't match the expected stride based on the accessor type, GLTFLoader creates the interleaved attribute as follows:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="var ibCacheKey = 'InterleavedBuffer:' + accessorDef.bufferView + ':' + accessorDef.componentType;
var ib = parser.cache.get( ibCacheKey );

if ( ! ib ) {
    // Use the full buffer if it's interleaved.
    array = new TypedArray( bufferView );

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

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

bufferAttribute = new THREE.InterleavedBufferAttribute( ib, itemSize, byteOffset / elementBytes, normalized );"><pre class="notranslate"><code class="notranslate">var ibCacheKey = 'InterleavedBuffer:' + accessorDef.bufferView + ':' + accessorDef.componentType;
var ib = parser.cache.get( ibCacheKey );

if ( ! ib ) {
    // Use the full buffer if it's interleaved.
    array = new TypedArray( bufferView );

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

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

bufferAttribute = new THREE.InterleavedBufferAttribute( ib, itemSize, byteOffset / elementBytes, normalized );
</code></pre></div>
<p dir="auto">As a result, the attribute objects that are created have <code class="notranslate">.count</code> property reflect the full size of the buffer view. If multiple meshes share the same buffer view, then what will happen is that all of them will have the same <code class="notranslate">.count</code> (that is equal to the total vertex count across all meshes), but access to <code class="notranslate">.getX()</code> etc. will apply the byte offset for each mesh.</p>
<p dir="auto">This is a problem. For example, in this code in <code class="notranslate">computeBoundingSphere</code>:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="for ( var i = 0, il = position.count; i &lt; il; i ++ ) {
    vector.fromBufferAttribute( position, i );
    maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );
}"><pre class="notranslate"><code class="notranslate">for ( var i = 0, il = position.count; i &lt; il; i ++ ) {
    vector.fromBufferAttribute( position, i );
    maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );
}
</code></pre></div>
<p dir="auto">For each mesh we'll iterate over the number of elements in the buffer view, but during access in <code class="notranslate">fromBufferAttribute</code> an offset will be applied, which - for meshes with offset != 0 - will result in <code class="notranslate">vector</code> being undefined and <code class="notranslate">maxRadiusSq</code> equal to NaN.</p>
<p dir="auto">I'm considering options for how to fix this.</p>
<p dir="auto">One option is to make caching logic more involved by incorporating accessor count into the cache, and only storing a slice of the buffer view that matches the accessor count; something along these lines:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="var ibSlice = Math.floor( byteOffset / byteStride );
var ibCacheKey = 'InterleavedBuffer:' + accessorDef.bufferView + ':' + accessorDef.componentType + ':' + ibSlice + ':' + accessorDef.count;
var ib = parser.cache.get( ibCacheKey );

if ( ! ib ) {
    array = new TypedArray( bufferView, ibSlice * byteStride, accessorDef.count * byteStride / elementBytes );

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

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

bufferAttribute = new THREE.InterleavedBufferAttribute( ib, itemSize, (byteOffset - ibSlice * byteStride) / elementBytes, normalized );"><pre class="notranslate"><code class="notranslate">var ibSlice = Math.floor( byteOffset / byteStride );
var ibCacheKey = 'InterleavedBuffer:' + accessorDef.bufferView + ':' + accessorDef.componentType + ':' + ibSlice + ':' + accessorDef.count;
var ib = parser.cache.get( ibCacheKey );

if ( ! ib ) {
    array = new TypedArray( bufferView, ibSlice * byteStride, accessorDef.count * byteStride / elementBytes );

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

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

bufferAttribute = new THREE.InterleavedBufferAttribute( ib, itemSize, (byteOffset - ibSlice * byteStride) / elementBytes, normalized );
</code></pre></div>
<p dir="auto">Another option is to change <code class="notranslate">InterleavedBufferAttribute.count</code> to a field that's computed in the constructor from an optional extra <code class="notranslate">count</code> argument like this:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="function InterleavedBufferAttribute( interleavedBuffer, itemSize, offset, normalized, count ) {
    this.data = interleavedBuffer;
    this.itemSize = itemSize;
    this.offset = offset;
    this.count = count || interleavedBuffer.count;
    this.normalized = normalized === true;
}"><pre class="notranslate"><code class="notranslate">function InterleavedBufferAttribute( interleavedBuffer, itemSize, offset, normalized, count ) {
    this.data = interleavedBuffer;
    this.itemSize = itemSize;
    this.offset = offset;
    this.count = count || interleavedBuffer.count;
    this.normalized = normalized === true;
}
</code></pre></div>
<p dir="auto">Thoughts?</p>
<p dir="auto">The main source code has recently been ported to ES2015 modules (see <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="164650131" data-permission-text="Title is private" data-url="https://github.com/mrdoob/three.js/issues/9310" data-hovercard-type="pull_request" data-hovercard-url="/mrdoob/three.js/pull/9310/hovercard" href="https://github.com/mrdoob/three.js/pull/9310">#9310</a>); however, some parts are still relying on global namespace pollution and have thus become unusable.</p>
<p dir="auto">Specifically the things in <code class="notranslate">/examples/js/</code> haven't been transformed to support modules yet; this makes them currently unusable from within environments such as webpack or SystemJS.</p>
<p dir="auto">Edit, 11-20-2016: They <em>can</em> be used, but it requires a lot of setup: <a href="https://github.com/systemjs/systemjs/issues/666" data-hovercard-type="issue" data-hovercard-url="/systemjs/systemjs/issues/666/hovercard">SystemJS</a>, <a href="https://github.com/webpack/imports-loader">webpack</a>. If you need assistance with these: Sorry, but this is the wrong thread to announce it! 😄</p>