|
@@ -14,169 +14,198 @@ function arrayNeedsUint32( array ) {
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
-class WebGPUGeometries {
|
|
|
|
|
|
+function getWireframeVersion( geometry ) {
|
|
|
|
|
|
- constructor( attributes, info ) {
|
|
|
|
|
|
+ return ( geometry.index !== null ) ? geometry.index.version : geometry.attributes.position.version;
|
|
|
|
|
|
- this.attributes = attributes;
|
|
|
|
- this.info = info;
|
|
|
|
|
|
+}
|
|
|
|
|
|
- this.geometries = new WeakMap();
|
|
|
|
- this.wireframeGeometries = new WeakMap();
|
|
|
|
|
|
+function getWireframeIndex( geometry ) {
|
|
|
|
|
|
- }
|
|
|
|
|
|
+ const indices = [];
|
|
|
|
|
|
- has( geometry ) {
|
|
|
|
|
|
+ const geometryIndex = geometry.index;
|
|
|
|
+ const geometryPosition = geometry.attributes.position;
|
|
|
|
|
|
- return this.geometries.has( geometry );
|
|
|
|
|
|
+ if ( geometryIndex !== null ) {
|
|
|
|
|
|
- }
|
|
|
|
|
|
+ const array = geometryIndex.array;
|
|
|
|
+
|
|
|
|
+ for ( let i = 0, l = array.length; i < l; i += 3 ) {
|
|
|
|
+
|
|
|
|
+ const a = array[ i + 0 ];
|
|
|
|
+ const b = array[ i + 1 ];
|
|
|
|
+ const c = array[ i + 2 ];
|
|
|
|
|
|
- update( geometry, wireframe = false ) {
|
|
|
|
|
|
+ indices.push( a, b, b, c, c, a );
|
|
|
|
|
|
- const { geometries, attributes, info } = this;
|
|
|
|
|
|
+ }
|
|
|
|
|
|
- if ( geometries.has( geometry ) === false ) {
|
|
|
|
|
|
+ } else {
|
|
|
|
|
|
- const disposeCallback = onGeometryDispose.bind( this );
|
|
|
|
|
|
+ const array = geometryPosition.array;
|
|
|
|
|
|
- geometries.set( geometry, disposeCallback );
|
|
|
|
|
|
+ for ( let i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) {
|
|
|
|
|
|
- info.memory.geometries ++;
|
|
|
|
|
|
+ const a = i + 0;
|
|
|
|
+ const b = i + 1;
|
|
|
|
+ const c = i + 2;
|
|
|
|
|
|
- geometry.addEventListener( 'dispose', disposeCallback );
|
|
|
|
|
|
+ indices.push( a, b, b, c, c, a );
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- const geometryAttributes = geometry.attributes;
|
|
|
|
|
|
+ }
|
|
|
|
|
|
- for ( const name in geometryAttributes ) {
|
|
|
|
|
|
+ const attribute = new ( arrayNeedsUint32( indices ) ? Uint32BufferAttribute : Uint16BufferAttribute )( indices, 1 );
|
|
|
|
+ attribute.version = getWireframeVersion( geometry );
|
|
|
|
|
|
- attributes.update( geometryAttributes[ name ] );
|
|
|
|
|
|
+ return attribute;
|
|
|
|
|
|
- }
|
|
|
|
|
|
+}
|
|
|
|
|
|
- const index = this.getIndex( geometry, wireframe );
|
|
|
|
|
|
+class WebGPUGeometries {
|
|
|
|
|
|
- if ( index !== null ) {
|
|
|
|
|
|
+ constructor( attributes, properties, info ) {
|
|
|
|
|
|
- attributes.update( index, true );
|
|
|
|
|
|
+ this.attributes = attributes;
|
|
|
|
+ this.properties = properties;
|
|
|
|
+ this.info = info;
|
|
|
|
|
|
- }
|
|
|
|
|
|
+ this.wireframes = new WeakMap();
|
|
|
|
+ this.geometryFrame = new WeakMap();
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- getIndex( geometry, wireframe = false ) {
|
|
|
|
|
|
+ has( renderObject ) {
|
|
|
|
|
|
- let index = geometry.index;
|
|
|
|
|
|
+ const geometry = renderObject.geometry;
|
|
|
|
|
|
- if ( wireframe ) {
|
|
|
|
|
|
+ return this.properties.has( geometry ) && this.properties.get( geometry ).initialized === true;
|
|
|
|
|
|
- const wireframeGeometries = this.wireframeGeometries;
|
|
|
|
|
|
+ }
|
|
|
|
|
|
- let wireframeAttribute = wireframeGeometries.get( geometry );
|
|
|
|
|
|
+ update( renderObject ) {
|
|
|
|
|
|
- if ( wireframeAttribute === undefined ) {
|
|
|
|
|
|
+ if ( this.has( renderObject ) === false ) this.initGeometry( renderObject );
|
|
|
|
|
|
- wireframeAttribute = this.getWireframeIndex( geometry );
|
|
|
|
|
|
+ this.updateFrameAttributes( renderObject );
|
|
|
|
|
|
- wireframeGeometries.set( geometry, wireframeAttribute );
|
|
|
|
|
|
+ }
|
|
|
|
|
|
- } else if ( wireframeAttribute.version !== this.getWireframeVersion( geometry ) ) {
|
|
|
|
|
|
+ initGeometry( renderObject ) {
|
|
|
|
|
|
- this.attributes.remove( wireframeAttribute );
|
|
|
|
|
|
+ const geometry = renderObject.geometry;
|
|
|
|
+ const geometryProperties = this.properties.get( geometry );
|
|
|
|
|
|
- wireframeAttribute = this.getWireframeIndex( geometry );
|
|
|
|
|
|
+ geometryProperties.initialized = true;
|
|
|
|
|
|
- wireframeGeometries.set( geometry, wireframeAttribute );
|
|
|
|
|
|
+ const dispose = () => {
|
|
|
|
+
|
|
|
|
+ this.info.memory.geometries --;
|
|
|
|
+
|
|
|
|
+ const index = geometry.index;
|
|
|
|
+ const geometryAttributes = geometry.attributes;
|
|
|
|
+
|
|
|
|
+ if ( index !== null ) {
|
|
|
|
+
|
|
|
|
+ this.attributes.remove( index );
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- index = wireframeAttribute;
|
|
|
|
|
|
+ for ( const name in geometryAttributes ) {
|
|
|
|
|
|
- }
|
|
|
|
|
|
+ this.attributes.remove( geometryAttributes[ name ] );
|
|
|
|
|
|
- return index;
|
|
|
|
|
|
+ }
|
|
|
|
|
|
- }
|
|
|
|
|
|
+ const wireframeAttribute = this.wireframes.get( geometry );
|
|
|
|
|
|
- getWireframeIndex( geometry ) {
|
|
|
|
|
|
+ if ( wireframeAttribute !== undefined ) {
|
|
|
|
|
|
- const indices = [];
|
|
|
|
|
|
+ this.attributes.remove( wireframeAttribute );
|
|
|
|
|
|
- const geometryIndex = geometry.index;
|
|
|
|
- const geometryPosition = geometry.attributes.position;
|
|
|
|
|
|
+ }
|
|
|
|
|
|
- if ( geometryIndex !== null ) {
|
|
|
|
|
|
+ geometry.removeEventListener( 'dispose', dispose );
|
|
|
|
|
|
- const array = geometryIndex.array;
|
|
|
|
|
|
+ };
|
|
|
|
|
|
- for ( let i = 0, l = array.length; i < l; i += 3 ) {
|
|
|
|
|
|
+ this.info.memory.geometries ++;
|
|
|
|
|
|
- const a = array[ i + 0 ];
|
|
|
|
- const b = array[ i + 1 ];
|
|
|
|
- const c = array[ i + 2 ];
|
|
|
|
|
|
+ geometry.addEventListener( 'dispose', dispose );
|
|
|
|
|
|
- indices.push( a, b, b, c, c, a );
|
|
|
|
|
|
+ }
|
|
|
|
|
|
- }
|
|
|
|
|
|
+ updateFrameAttributes( renderObject ) {
|
|
|
|
|
|
- } else {
|
|
|
|
|
|
+ const frame = this.info.render.frame;
|
|
|
|
+ const geometry = renderObject.geometry;
|
|
|
|
|
|
- const array = geometryPosition.array;
|
|
|
|
|
|
+ if ( this.geometryFrame.get( geometry ) !== frame ) {
|
|
|
|
|
|
- for ( let i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) {
|
|
|
|
|
|
+ this.updateAttributes( renderObject );
|
|
|
|
|
|
- const a = i + 0;
|
|
|
|
- const b = i + 1;
|
|
|
|
- const c = i + 2;
|
|
|
|
|
|
+ this.geometryFrame.set( geometry, frame );
|
|
|
|
|
|
- indices.push( a, b, b, c, c, a );
|
|
|
|
|
|
+ }
|
|
|
|
|
|
- }
|
|
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ updateAttributes( renderObject ) {
|
|
|
|
+
|
|
|
|
+ const geometry = renderObject.geometry;
|
|
|
|
+ const geometryAttributes = geometry.attributes;
|
|
|
|
+
|
|
|
|
+ for ( const name in geometryAttributes ) {
|
|
|
|
+
|
|
|
|
+ this.attributes.update( geometryAttributes[ name ] );
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- const attribute = new ( arrayNeedsUint32( indices ) ? Uint32BufferAttribute : Uint16BufferAttribute )( indices, 1 );
|
|
|
|
- attribute.version = this.getWireframeVersion( geometry );
|
|
|
|
|
|
+ const index = this.getIndex( renderObject );
|
|
|
|
|
|
- return attribute;
|
|
|
|
|
|
+ if ( index !== null ) {
|
|
|
|
+
|
|
|
|
+ this.attributes.update( index, true );
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- getWireframeVersion( geometry ) {
|
|
|
|
|
|
+ getIndex( renderObject ) {
|
|
|
|
|
|
- return ( geometry.index !== null ) ? geometry.index.version : geometry.attributes.position.version;
|
|
|
|
|
|
+ const { geometry, material } = renderObject;
|
|
|
|
|
|
- }
|
|
|
|
|
|
+ let index = geometry.index;
|
|
|
|
|
|
-}
|
|
|
|
|
|
+ if ( material.wireframe === true ) {
|
|
|
|
|
|
-function onGeometryDispose( event ) {
|
|
|
|
|
|
+ const wireframes = this.wireframes;
|
|
|
|
|
|
- const geometry = event.target;
|
|
|
|
- const disposeCallback = this.geometries.get( geometry );
|
|
|
|
|
|
+ let wireframeAttribute = wireframes.get( geometry );
|
|
|
|
|
|
- this.geometries.delete( geometry );
|
|
|
|
|
|
+ if ( wireframeAttribute === undefined ) {
|
|
|
|
|
|
- this.info.memory.geometries --;
|
|
|
|
|
|
+ wireframeAttribute = getWireframeIndex( geometry );
|
|
|
|
|
|
- geometry.removeEventListener( 'dispose', disposeCallback );
|
|
|
|
|
|
+ wireframes.set( geometry, wireframeAttribute );
|
|
|
|
|
|
- //
|
|
|
|
|
|
+ } else if ( wireframeAttribute.version !== getWireframeVersion( geometry ) ) {
|
|
|
|
|
|
- const index = geometry.index;
|
|
|
|
- const geometryAttributes = geometry.attributes;
|
|
|
|
|
|
+ this.attributes.remove( wireframeAttribute );
|
|
|
|
|
|
- if ( index !== null ) {
|
|
|
|
|
|
+ wireframeAttribute = getWireframeIndex( geometry );
|
|
|
|
|
|
- this.attributes.remove( index );
|
|
|
|
|
|
+ wireframes.set( geometry, wireframeAttribute );
|
|
|
|
|
|
- }
|
|
|
|
|
|
+ }
|
|
|
|
|
|
- for ( const name in geometryAttributes ) {
|
|
|
|
|
|
+ index = wireframeAttribute;
|
|
|
|
|
|
- this.attributes.remove( geometryAttributes[ name ] );
|
|
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return index;
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|