|
@@ -1,8 +1,11 @@
|
|
import {
|
|
import {
|
|
BufferAttribute,
|
|
BufferAttribute,
|
|
BufferGeometry,
|
|
BufferGeometry,
|
|
|
|
+ Color,
|
|
FileLoader,
|
|
FileLoader,
|
|
- Loader
|
|
|
|
|
|
+ Loader,
|
|
|
|
+ LinearSRGBColorSpace,
|
|
|
|
+ SRGBColorSpace
|
|
} from 'three';
|
|
} from 'three';
|
|
|
|
|
|
const _taskCache = new WeakMap();
|
|
const _taskCache = new WeakMap();
|
|
@@ -73,18 +76,25 @@ class DRACOLoader extends Loader {
|
|
|
|
|
|
loader.load( url, ( buffer ) => {
|
|
loader.load( url, ( buffer ) => {
|
|
|
|
|
|
- this.decodeDracoFile( buffer, onLoad ).catch( onError );
|
|
|
|
|
|
+ this.parse( buffer, onLoad, onError );
|
|
|
|
|
|
}, onProgress, onError );
|
|
}, onProgress, onError );
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- decodeDracoFile( buffer, callback, attributeIDs, attributeTypes ) {
|
|
|
|
|
|
+ parse ( buffer, onLoad, onError ) {
|
|
|
|
+
|
|
|
|
+ this.decodeDracoFile( buffer, onLoad, null, null, SRGBColorSpace ).catch( onError );
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ decodeDracoFile( buffer, callback, attributeIDs, attributeTypes, vertexColorSpace = LinearSRGBColorSpace ) {
|
|
|
|
|
|
const taskConfig = {
|
|
const taskConfig = {
|
|
attributeIDs: attributeIDs || this.defaultAttributeIDs,
|
|
attributeIDs: attributeIDs || this.defaultAttributeIDs,
|
|
attributeTypes: attributeTypes || this.defaultAttributeTypes,
|
|
attributeTypes: attributeTypes || this.defaultAttributeTypes,
|
|
- useUniqueIDs: !! attributeIDs
|
|
|
|
|
|
+ useUniqueIDs: !! attributeIDs,
|
|
|
|
+ vertexColorSpace: vertexColorSpace,
|
|
};
|
|
};
|
|
|
|
|
|
return this.decodeGeometry( buffer, taskConfig ).then( callback );
|
|
return this.decodeGeometry( buffer, taskConfig ).then( callback );
|
|
@@ -188,12 +198,20 @@ class DRACOLoader extends Loader {
|
|
|
|
|
|
for ( let i = 0; i < geometryData.attributes.length; i ++ ) {
|
|
for ( let i = 0; i < geometryData.attributes.length; i ++ ) {
|
|
|
|
|
|
- const attribute = geometryData.attributes[ i ];
|
|
|
|
- const name = attribute.name;
|
|
|
|
- const array = attribute.array;
|
|
|
|
- const itemSize = attribute.itemSize;
|
|
|
|
|
|
+ const result = geometryData.attributes[ i ];
|
|
|
|
+ const name = result.name;
|
|
|
|
+ const array = result.array;
|
|
|
|
+ const itemSize = result.itemSize;
|
|
|
|
+
|
|
|
|
+ const attribute = new BufferAttribute( array, itemSize );
|
|
|
|
+
|
|
|
|
+ if ( name === 'color' ) {
|
|
|
|
|
|
- geometry.setAttribute( name, new BufferAttribute( array, itemSize ) );
|
|
|
|
|
|
+ this._assignVertexColorSpace( attribute, result.vertexColorSpace );
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ geometry.setAttribute( name, attribute );
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
@@ -201,6 +219,26 @@ class DRACOLoader extends Loader {
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ _assignVertexColorSpace( attribute, inputColorSpace ) {
|
|
|
|
+
|
|
|
|
+ // While .drc files do not specify colorspace, the only 'official' tooling
|
|
|
|
+ // is PLY and OBJ converters, which use sRGB. We'll assume sRGB when a .drc
|
|
|
|
+ // file is passed into .load() or .parse(). GLTFLoader uses internal APIs
|
|
|
|
+ // to decode geometry, and vertex colors are already Linear-sRGB in there.
|
|
|
|
+
|
|
|
|
+ if ( inputColorSpace !== SRGBColorSpace ) return;
|
|
|
|
+
|
|
|
|
+ const _color = new Color();
|
|
|
|
+
|
|
|
|
+ for ( let i = 0, il = attribute.count; i < il; i ++ ) {
|
|
|
|
+
|
|
|
|
+ _color.fromBufferAttribute( attribute, i ).convertSRGBToLinear();
|
|
|
|
+ attribute.setXYZ( i, _color.r, _color.g, _color.b );
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
_loadLibrary( url, responseType ) {
|
|
_loadLibrary( url, responseType ) {
|
|
|
|
|
|
const loader = new FileLoader( this.manager );
|
|
const loader = new FileLoader( this.manager );
|
|
@@ -493,7 +531,15 @@ function DRACOWorker() {
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- geometry.attributes.push( decodeAttribute( draco, decoder, dracoGeometry, attributeName, attributeType, attribute ) );
|
|
|
|
|
|
+ const attributeResult = decodeAttribute( draco, decoder, dracoGeometry, attributeName, attributeType, attribute );
|
|
|
|
+
|
|
|
|
+ if ( attributeName === 'color' ) {
|
|
|
|
+
|
|
|
|
+ attributeResult.vertexColorSpace = taskConfig.vertexColorSpace;
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ geometry.attributes.push( attributeResult );
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|