|
@@ -1,3 +1,19 @@
|
|
|
|
+import { Uint32BufferAttribute, Uint16BufferAttribute } from 'three';
|
|
|
|
+
|
|
|
|
+function arrayNeedsUint32( array ) {
|
|
|
|
+
|
|
|
|
+ // assumes larger values usually on last
|
|
|
|
+
|
|
|
|
+ for ( let i = array.length - 1; i >= 0; -- i ) {
|
|
|
|
+
|
|
|
|
+ if ( array[ i ] >= 65535 ) return true; // account for PRIMITIVE_RESTART_FIXED_INDEX, #24565
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return false;
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
class WebGPUGeometries {
|
|
class WebGPUGeometries {
|
|
|
|
|
|
constructor( attributes, info ) {
|
|
constructor( attributes, info ) {
|
|
@@ -6,6 +22,7 @@ class WebGPUGeometries {
|
|
this.info = info;
|
|
this.info = info;
|
|
|
|
|
|
this.geometries = new WeakMap();
|
|
this.geometries = new WeakMap();
|
|
|
|
+ this.wireframeGeometries = new WeakMap();
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
@@ -15,15 +32,17 @@ class WebGPUGeometries {
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- update( geometry ) {
|
|
|
|
|
|
+ update( geometry, wireframe = false ) {
|
|
|
|
+
|
|
|
|
+ const { geometries, attributes, info } = this;
|
|
|
|
|
|
- if ( this.geometries.has( geometry ) === false ) {
|
|
|
|
|
|
+ if ( geometries.has( geometry ) === false ) {
|
|
|
|
|
|
const disposeCallback = onGeometryDispose.bind( this );
|
|
const disposeCallback = onGeometryDispose.bind( this );
|
|
|
|
|
|
- this.geometries.set( geometry, disposeCallback );
|
|
|
|
|
|
+ geometries.set( geometry, disposeCallback );
|
|
|
|
|
|
- this.info.memory.geometries ++;
|
|
|
|
|
|
+ info.memory.geometries ++;
|
|
|
|
|
|
geometry.addEventListener( 'dispose', disposeCallback );
|
|
geometry.addEventListener( 'dispose', disposeCallback );
|
|
|
|
|
|
@@ -33,18 +52,102 @@ class WebGPUGeometries {
|
|
|
|
|
|
for ( const name in geometryAttributes ) {
|
|
for ( const name in geometryAttributes ) {
|
|
|
|
|
|
- this.attributes.update( geometryAttributes[ name ] );
|
|
|
|
|
|
+ attributes.update( geometryAttributes[ name ] );
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- const index = geometry.index;
|
|
|
|
|
|
+ const index = this.getIndex( geometry, wireframe );
|
|
|
|
|
|
if ( index !== null ) {
|
|
if ( index !== null ) {
|
|
|
|
|
|
- this.attributes.update( index, true );
|
|
|
|
|
|
+ attributes.update( index, true );
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ getIndex( geometry, wireframe = false ) {
|
|
|
|
+
|
|
|
|
+ let index = geometry.index;
|
|
|
|
+
|
|
|
|
+ if ( wireframe ) {
|
|
|
|
+
|
|
|
|
+ const wireframeGeometries = this.wireframeGeometries;
|
|
|
|
+
|
|
|
|
+ let wireframeAttribute = wireframeGeometries.get( geometry );
|
|
|
|
+
|
|
|
|
+ if ( wireframeAttribute === undefined ) {
|
|
|
|
+
|
|
|
|
+ wireframeAttribute = this.getWireframeIndex( geometry );
|
|
|
|
+
|
|
|
|
+ wireframeGeometries.set( geometry, wireframeAttribute );
|
|
|
|
+
|
|
|
|
+ } else if ( wireframeAttribute.version !== this.getWireframeVersion( geometry ) ) {
|
|
|
|
+
|
|
|
|
+ this.attributes.remove( wireframeAttribute );
|
|
|
|
+
|
|
|
|
+ wireframeAttribute = this.getWireframeIndex( geometry );
|
|
|
|
+
|
|
|
|
+ wireframeGeometries.set( geometry, wireframeAttribute );
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ index = wireframeAttribute;
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ return index;
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ getWireframeIndex( geometry ) {
|
|
|
|
+
|
|
|
|
+ const indices = [];
|
|
|
|
+
|
|
|
|
+ const geometryIndex = geometry.index;
|
|
|
|
+ const geometryPosition = geometry.attributes.position;
|
|
|
|
+
|
|
|
|
+ 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 ];
|
|
|
|
+
|
|
|
|
+ indices.push( a, b, b, c, c, a );
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ } else {
|
|
|
|
+
|
|
|
|
+ const array = geometryPosition.array;
|
|
|
|
+
|
|
|
|
+ for ( let i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) {
|
|
|
|
+
|
|
|
|
+ const a = i + 0;
|
|
|
|
+ const b = i + 1;
|
|
|
|
+ const c = i + 2;
|
|
|
|
+
|
|
|
|
+ indices.push( a, b, b, c, c, a );
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const attribute = new ( arrayNeedsUint32( indices ) ? Uint32BufferAttribute : Uint16BufferAttribute )( indices, 1 );
|
|
|
|
+ attribute.version = this.getWireframeVersion( geometry );
|
|
|
|
+
|
|
|
|
+ return attribute;
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ getWireframeVersion( geometry ) {
|
|
|
|
+
|
|
|
|
+ return ( geometry.index !== null ) ? geometry.index.version : geometry.attributes.position.version;
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
}
|