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: Add thrown errors #27060

Merged
merged 9 commits into from
Oct 26, 2023
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 82 additions & 33 deletions examples/jsm/objects/BatchedMesh.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ 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,
0, 0, 0, 1,
);

// Custom shaders
const batchingParsVertex = `
const batchingParsVertex = /* glsl */`
#ifdef BATCHING
attribute float ${ ID_ATTR_NAME };
uniform highp sampler2D batchingTexture;
Expand All @@ -40,13 +40,13 @@ const batchingParsVertex = `
#endif
`;

const batchingbaseVertex = `
const batchingbaseVertex = /* glsl */`
#ifdef BATCHING
mat4 batchingMatrix = getBatchingMatrix( ${ ID_ATTR_NAME } );
#endif
`;

const batchingnormalVertex = `
const batchingnormalVertex = /* glsl */`
#ifdef BATCHING
objectNormal = vec4( batchingMatrix * vec4( objectNormal, 0.0 ) ).xyz;
#ifdef USE_TANGENT
Expand All @@ -55,7 +55,7 @@ const batchingnormalVertex = `
#endif
`;

const batchingVertex = `
const batchingVertex = /* glsl */`
#ifdef BATCHING
transformed = ( batchingMatrix * vec4( transformed, 1.0 ) ).xyz;
#endif
Expand Down Expand Up @@ -91,7 +91,6 @@ class BatchedMesh extends Mesh {
// @TODO: Support uniform parameter per geometry

this._matrices = [];
this._matricesArray = null;
this._matricesTexture = null;

// @TODO: Calculate the entire binding box and make frustumCulled true
Expand Down Expand Up @@ -123,9 +122,7 @@ class BatchedMesh extends Mesh {
const matricesArray = new Float32Array( size * size * 4 ); // 4 floats per RGBA pixel
const matricesTexture = new DataTexture( matricesArray, size, size, RGBAFormat, FloatType );

this._matricesArray = matricesArray;
this._matricesTexture = matricesTexture;

this._customUniforms.batchingTexture.value = this._matricesTexture;
this._customUniforms.batchingTextureSize.value = size;

Expand Down Expand Up @@ -215,10 +212,6 @@ class BatchedMesh extends Mesh {

this._geometryInitialized = true;

} else {

// @TODO: Check if geometry has the same attributes set

}

}
Expand All @@ -245,21 +238,75 @@ class BatchedMesh extends Mesh {

this._initializeGeometry( geometry );

// @TODO: Error handling if exceeding maxVertexCount or maxIndexCount
// ensure we're not over geometry
if ( this._geometryCount >= this._maxGeometryCount ) {

// @TODO: Error handling
throw new Error( 'BatchedMesh: Maximum geometry count reached.' );

}

// check that the geometry doesn't have a version of our reserved id attribute
if ( geometry.getAttribute( ID_ATTR_NAME ) ) {

throw new Error( `BatchedMesh: Geometry cannot use attribute "${ ID_ATTR_NAME }"` );

}

// check to ensure the geometries are using consistent attributes and indices
const batchGeometry = this.geometry;
if ( Boolean( geometry.getIndex() ) !== Boolean( batchGeometry.getIndex() ) ) {

throw new Error( 'BatchedMesh: All geometries must consistently have "index".' );

}

for ( const attributeName in batchGeometry.attributes ) {

if ( attributeName === ID_ATTR_NAME ) {

continue;

}

if ( ! geometry.hasAttribute( attributeName ) ) {

throw new Error( `BatchedMesh: Added geometry missing "${ attributeName }". All geometries must have consistent attributes.` );

}

const srcAttribute = geometry.getAttribute( attributeName );
const dstAttribute = batchGeometry.getAttribute( attributeName );
if ( srcAttribute.itemSize !== dstAttribute.itemSize || srcAttribute.normalized !== dstAttribute.normalized ) {

throw new Error( 'BatchedMesh: All attributes must have a consistent itemSize and normalized value.' );

}

}

// Assuming geometry has position attribute
const srcPositionAttribute = geometry.getAttribute( 'position' );
const vertexCount = this._vertexCount;
const indexCount = this._indexCount;
const maxVertexCount = this._maxVertexCount;
const maxIndexCount = this._maxIndexCount;

// check if we're going over our maximum buffer capacity
if (
geometry.getIndex() !== null &&
indexCount + geometry.getIndex().count > maxIndexCount ||
vertexCount + srcPositionAttribute.count > maxVertexCount
) {

throw new Error( 'BatchedMesh: Added geometry is larger than available buffer capacity.' );

}

const visible = this._visible;
const active = this._active;
const matricesTexture = this._matricesTexture;
const matrices = this._matrices;
const matricesArray = this._matricesTexture.image.data;
const vertexCount = this._vertexCount;
const indexCount = this._indexCount;

const indexCounts = this._indexCounts;
const indexStarts = this._indexStarts;
Expand All @@ -270,16 +317,18 @@ class BatchedMesh extends Mesh {
const dstIndex = batchGeometry.getIndex();
const srcIndex = geometry.getIndex();

// Assuming geometry has position attribute
const srcPositionAttribute = geometry.getAttribute( 'position' );

// push new geometry data range
vertexStarts.push( vertexCount );
vertexCounts.push( srcPositionAttribute.count );

// copy attribute data over
// @TODO: Handle case where geometry does not have common attributes
for ( const attributeName in geometry.attributes ) {
for ( const attributeName in batchGeometry.attributes ) {

if ( attributeName === ID_ATTR_NAME ) {

continue;

}

const srcAttribute = geometry.getAttribute( attributeName );
const dstAttribute = batchGeometry.getAttribute( attributeName );
Expand Down Expand Up @@ -359,9 +408,7 @@ class BatchedMesh extends Mesh {

optimize() {

// @TODO: Implement

return this;
throw new Error( 'BatchedMesh: Optimize function not implemented.' );

}

Expand Down Expand Up @@ -461,21 +508,23 @@ class BatchedMesh extends Mesh {

}

copy( source ) {
raycast() {

super.copy( source );
console.warn( 'BatchedMesh: Raycast function not implemented.' );

// @TODO: Implement
}

return this;
copy() {

}
// super.copy( source );

throw new Error( 'BatchedMesh: Copy function not implemented.' );

toJSON( meta ) {
}

// @TODO: Implement
toJSON() {

return super.toJSON( meta );
throw new Error( 'BatchedMesh: toJSON function not implemented.' );

}

Expand Down
2 changes: 1 addition & 1 deletion examples/webgl_mesh_batch.html
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@
geometries = [
new THREE.ConeGeometry( 1.0, 2.0 ),
new THREE.BoxGeometry( 2.0, 2.0, 2.0 ),
new THREE.SphereGeometry( 1.0 ),
new THREE.SphereGeometry( 1.0, 16, 8 ),
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the errors I found that we were overwriting the end of BatchedMesh geometry index in the example - so I simplified the sphere so it has fewer vertices to avoid that case.

];

}
Expand Down