Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BatchedMesh: Make data copying more robust, handle interleaved attributes #27066

Merged
merged 13 commits into from
Oct 27, 2023
38 changes: 33 additions & 5 deletions examples/jsm/objects/BatchedMesh.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import {
} from 'three';

const ID_ATTR_NAME = '_batch_id_';
const _identityMatrix = new Matrix4();
const _zeroScaleMatrix = new Matrix4().set(
const _identityMatrix = /* @__PURE__ */ new Matrix4();
const _zeroScaleMatrix = /* @__PURE__ */ new Matrix4().set(
gkjohnson marked this conversation as resolved.
Show resolved Hide resolved
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
Expand Down Expand Up @@ -64,6 +64,36 @@ const batchingVertex = /* glsl */`
// @TODO: SkinnedMesh support?
// @TODO: Future work if needed. Move into the core. Can be optimized more with WEBGL_multi_draw.

// copies data from attribute "src" into "target" starting at "targetOffset"
function copyAttributeData( src, target, targetOffset = 0 ) {

const itemSize = target.itemSize;
if ( src.isInterleavedBufferAttribute || src.array.constructor !== target.array.constructor ) {

// use the component getters and setters if the array data cannot
// be copied directly
const vertexCount = src.count;
for ( let i = 0; i < vertexCount; i ++ ) {

for ( let c = 0; c < itemSize; c ++ ) {

target.setComponent( i + targetOffset, c, src.getComponent( i, c ) );

}

}

} else {

// faster copy approach using typed array set function
target.array.set( src.array, targetOffset * itemSize );

}

target.needsUpdate = true;

}

class BatchedMesh extends Mesh {

constructor( maxGeometryCount, maxVertexCount, maxIndexCount = maxVertexCount * 2, material ) {
Expand Down Expand Up @@ -332,9 +362,7 @@ class BatchedMesh extends Mesh {

const srcAttribute = geometry.getAttribute( attributeName );
const dstAttribute = batchGeometry.getAttribute( attributeName );

dstAttribute.array.set( srcAttribute.array, vertexCount * dstAttribute.itemSize );
dstAttribute.needsUpdate = true;
copyAttributeData( srcAttribute, dstAttribute, vertexCount );

}

Expand Down