@damienmortini/three 0.1.166 → 0.1.167
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -626,7 +626,7 @@ class GLTFMaterialsUnlitExtension {
|
|
|
626
626
|
|
|
627
627
|
if ( metallicRoughness.baseColorTexture !== undefined ) {
|
|
628
628
|
|
|
629
|
-
pending.push( parser.assignTexture( materialParams, 'map', metallicRoughness.baseColorTexture ) );
|
|
629
|
+
pending.push( parser.assignTexture( materialParams, 'map', metallicRoughness.baseColorTexture, sRGBEncoding ) );
|
|
630
630
|
|
|
631
631
|
}
|
|
632
632
|
|
|
@@ -780,7 +780,7 @@ class GLTFMaterialsSheenExtension {
|
|
|
780
780
|
|
|
781
781
|
if ( extension.sheenColorTexture !== undefined ) {
|
|
782
782
|
|
|
783
|
-
pending.push( parser.assignTexture( materialParams, 'sheenColorMap', extension.sheenColorTexture ) );
|
|
783
|
+
pending.push( parser.assignTexture( materialParams, 'sheenColorMap', extension.sheenColorTexture, sRGBEncoding ) );
|
|
784
784
|
|
|
785
785
|
}
|
|
786
786
|
|
|
@@ -1013,11 +1013,7 @@ class GLTFMaterialsSpecularExtension {
|
|
|
1013
1013
|
|
|
1014
1014
|
if ( extension.specularColorTexture !== undefined ) {
|
|
1015
1015
|
|
|
1016
|
-
pending.push( parser.assignTexture( materialParams, 'specularColorMap', extension.specularColorTexture )
|
|
1017
|
-
|
|
1018
|
-
texture.encoding = sRGBEncoding;
|
|
1019
|
-
|
|
1020
|
-
} ) );
|
|
1016
|
+
pending.push( parser.assignTexture( materialParams, 'specularColorMap', extension.specularColorTexture, sRGBEncoding ) );
|
|
1021
1017
|
|
|
1022
1018
|
}
|
|
1023
1019
|
|
|
@@ -1055,7 +1051,6 @@ class GLTFTextureBasisUExtension {
|
|
|
1055
1051
|
}
|
|
1056
1052
|
|
|
1057
1053
|
const extension = textureDef.extensions[ this.name ];
|
|
1058
|
-
const source = json.images[ extension.source ];
|
|
1059
1054
|
const loader = parser.options.ktx2Loader;
|
|
1060
1055
|
|
|
1061
1056
|
if ( ! loader ) {
|
|
@@ -1073,7 +1068,7 @@ class GLTFTextureBasisUExtension {
|
|
|
1073
1068
|
|
|
1074
1069
|
}
|
|
1075
1070
|
|
|
1076
|
-
return parser.loadTextureImage( textureIndex, source, loader );
|
|
1071
|
+
return parser.loadTextureImage( textureIndex, extension.source, loader );
|
|
1077
1072
|
|
|
1078
1073
|
}
|
|
1079
1074
|
|
|
@@ -1665,8 +1660,7 @@ class GLTFMaterialsPbrSpecularGlossinessExtension {
|
|
|
1665
1660
|
'glossiness',
|
|
1666
1661
|
'alphaMap',
|
|
1667
1662
|
'envMap',
|
|
1668
|
-
'envMapIntensity'
|
|
1669
|
-
'refractionRatio',
|
|
1663
|
+
'envMapIntensity'
|
|
1670
1664
|
];
|
|
1671
1665
|
|
|
1672
1666
|
}
|
|
@@ -1697,7 +1691,7 @@ class GLTFMaterialsPbrSpecularGlossinessExtension {
|
|
|
1697
1691
|
|
|
1698
1692
|
if ( pbrSpecularGlossiness.diffuseTexture !== undefined ) {
|
|
1699
1693
|
|
|
1700
|
-
pending.push( parser.assignTexture( materialParams, 'map', pbrSpecularGlossiness.diffuseTexture ) );
|
|
1694
|
+
pending.push( parser.assignTexture( materialParams, 'map', pbrSpecularGlossiness.diffuseTexture, sRGBEncoding ) );
|
|
1701
1695
|
|
|
1702
1696
|
}
|
|
1703
1697
|
|
|
@@ -1715,7 +1709,7 @@ class GLTFMaterialsPbrSpecularGlossinessExtension {
|
|
|
1715
1709
|
|
|
1716
1710
|
const specGlossMapDef = pbrSpecularGlossiness.specularGlossinessTexture;
|
|
1717
1711
|
pending.push( parser.assignTexture( materialParams, 'glossinessMap', specGlossMapDef ) );
|
|
1718
|
-
pending.push( parser.assignTexture( materialParams, 'specularMap', specGlossMapDef ) );
|
|
1712
|
+
pending.push( parser.assignTexture( materialParams, 'specularMap', specGlossMapDef, sRGBEncoding ) );
|
|
1719
1713
|
|
|
1720
1714
|
}
|
|
1721
1715
|
|
|
@@ -1765,8 +1759,6 @@ class GLTFMaterialsPbrSpecularGlossinessExtension {
|
|
|
1765
1759
|
material.envMap = materialParams.envMap === undefined ? null : materialParams.envMap;
|
|
1766
1760
|
material.envMapIntensity = 1.0;
|
|
1767
1761
|
|
|
1768
|
-
material.refractionRatio = 0.98;
|
|
1769
|
-
|
|
1770
1762
|
return material;
|
|
1771
1763
|
|
|
1772
1764
|
}
|
|
@@ -2052,6 +2044,7 @@ function addMorphTargets( geometry, targets, parser ) {
|
|
|
2052
2044
|
|
|
2053
2045
|
let hasMorphPosition = false;
|
|
2054
2046
|
let hasMorphNormal = false;
|
|
2047
|
+
let hasMorphColor = false;
|
|
2055
2048
|
|
|
2056
2049
|
for ( let i = 0, il = targets.length; i < il; i ++ ) {
|
|
2057
2050
|
|
|
@@ -2059,15 +2052,17 @@ function addMorphTargets( geometry, targets, parser ) {
|
|
|
2059
2052
|
|
|
2060
2053
|
if ( target.POSITION !== undefined ) hasMorphPosition = true;
|
|
2061
2054
|
if ( target.NORMAL !== undefined ) hasMorphNormal = true;
|
|
2055
|
+
if ( target.COLOR_0 !== undefined ) hasMorphColor = true;
|
|
2062
2056
|
|
|
2063
|
-
if ( hasMorphPosition && hasMorphNormal ) break;
|
|
2057
|
+
if ( hasMorphPosition && hasMorphNormal && hasMorphColor ) break;
|
|
2064
2058
|
|
|
2065
2059
|
}
|
|
2066
2060
|
|
|
2067
|
-
if ( ! hasMorphPosition && ! hasMorphNormal ) return Promise.resolve( geometry );
|
|
2061
|
+
if ( ! hasMorphPosition && ! hasMorphNormal && ! hasMorphColor ) return Promise.resolve( geometry );
|
|
2068
2062
|
|
|
2069
2063
|
const pendingPositionAccessors = [];
|
|
2070
2064
|
const pendingNormalAccessors = [];
|
|
2065
|
+
const pendingColorAccessors = [];
|
|
2071
2066
|
|
|
2072
2067
|
for ( let i = 0, il = targets.length; i < il; i ++ ) {
|
|
2073
2068
|
|
|
@@ -2093,18 +2088,31 @@ function addMorphTargets( geometry, targets, parser ) {
|
|
|
2093
2088
|
|
|
2094
2089
|
}
|
|
2095
2090
|
|
|
2091
|
+
if ( hasMorphColor ) {
|
|
2092
|
+
|
|
2093
|
+
const pendingAccessor = target.COLOR_0 !== undefined
|
|
2094
|
+
? parser.getDependency( 'accessor', target.COLOR_0 )
|
|
2095
|
+
: geometry.attributes.color;
|
|
2096
|
+
|
|
2097
|
+
pendingColorAccessors.push( pendingAccessor );
|
|
2098
|
+
|
|
2099
|
+
}
|
|
2100
|
+
|
|
2096
2101
|
}
|
|
2097
2102
|
|
|
2098
2103
|
return Promise.all( [
|
|
2099
2104
|
Promise.all( pendingPositionAccessors ),
|
|
2100
|
-
Promise.all( pendingNormalAccessors )
|
|
2105
|
+
Promise.all( pendingNormalAccessors ),
|
|
2106
|
+
Promise.all( pendingColorAccessors )
|
|
2101
2107
|
] ).then( function ( accessors ) {
|
|
2102
2108
|
|
|
2103
2109
|
const morphPositions = accessors[ 0 ];
|
|
2104
2110
|
const morphNormals = accessors[ 1 ];
|
|
2111
|
+
const morphColors = accessors[ 2 ];
|
|
2105
2112
|
|
|
2106
2113
|
if ( hasMorphPosition ) geometry.morphAttributes.position = morphPositions;
|
|
2107
2114
|
if ( hasMorphNormal ) geometry.morphAttributes.normal = morphNormals;
|
|
2115
|
+
if ( hasMorphColor ) geometry.morphAttributes.color = morphColors;
|
|
2108
2116
|
geometry.morphTargetsRelative = true;
|
|
2109
2117
|
|
|
2110
2118
|
return geometry;
|
|
@@ -2219,6 +2227,15 @@ function getNormalizedComponentScale( constructor ) {
|
|
|
2219
2227
|
|
|
2220
2228
|
}
|
|
2221
2229
|
|
|
2230
|
+
function getImageURIMimeType( uri ) {
|
|
2231
|
+
|
|
2232
|
+
if ( uri.search( /\.jpe?g($|\?)/i ) > 0 || uri.search( /^data\:image\/jpeg/ ) === 0 ) return 'image/jpeg';
|
|
2233
|
+
if ( uri.search( /\.webp($|\?)/i ) > 0 || uri.search( /^data\:image\/webp/ ) === 0 ) return 'image/webp';
|
|
2234
|
+
|
|
2235
|
+
return 'image/png';
|
|
2236
|
+
|
|
2237
|
+
}
|
|
2238
|
+
|
|
2222
2239
|
/* GLTF PARSER */
|
|
2223
2240
|
|
|
2224
2241
|
class GLTFParser {
|
|
@@ -2244,6 +2261,7 @@ class GLTFParser {
|
|
|
2244
2261
|
this.cameraCache = { refs: {}, uses: {} };
|
|
2245
2262
|
this.lightCache = { refs: {}, uses: {} };
|
|
2246
2263
|
|
|
2264
|
+
this.sourceCache = {};
|
|
2247
2265
|
this.textureCache = {};
|
|
2248
2266
|
|
|
2249
2267
|
// Track node names, to ensure no duplicates
|
|
@@ -2251,7 +2269,7 @@ class GLTFParser {
|
|
|
2251
2269
|
|
|
2252
2270
|
// Use an ImageBitmapLoader if imageBitmaps are supported. Moves much of the
|
|
2253
2271
|
// expensive work of uploading a texture to the GPU off the main thread.
|
|
2254
|
-
if ( typeof createImageBitmap !== 'undefined' &&
|
|
2272
|
+
if ( typeof createImageBitmap !== 'undefined' && /^((?!chrome|android).)*safari/i.test( navigator.userAgent ) === false ) {
|
|
2255
2273
|
|
|
2256
2274
|
this.textureLoader = new ImageBitmapLoader( this.options.manager );
|
|
2257
2275
|
|
|
@@ -2808,30 +2826,31 @@ class GLTFParser {
|
|
|
2808
2826
|
const json = this.json;
|
|
2809
2827
|
const options = this.options;
|
|
2810
2828
|
const textureDef = json.textures[ textureIndex ];
|
|
2811
|
-
const
|
|
2829
|
+
const sourceIndex = textureDef.source;
|
|
2830
|
+
const sourceDef = json.images[ sourceIndex ];
|
|
2812
2831
|
|
|
2813
2832
|
let loader = this.textureLoader;
|
|
2814
2833
|
|
|
2815
|
-
if (
|
|
2834
|
+
if ( sourceDef.uri ) {
|
|
2816
2835
|
|
|
2817
|
-
const handler = options.manager.getHandler(
|
|
2836
|
+
const handler = options.manager.getHandler( sourceDef.uri );
|
|
2818
2837
|
if ( handler !== null ) loader = handler;
|
|
2819
2838
|
|
|
2820
2839
|
}
|
|
2821
2840
|
|
|
2822
|
-
return this.loadTextureImage( textureIndex,
|
|
2841
|
+
return this.loadTextureImage( textureIndex, sourceIndex, loader );
|
|
2823
2842
|
|
|
2824
2843
|
}
|
|
2825
2844
|
|
|
2826
|
-
loadTextureImage( textureIndex,
|
|
2845
|
+
loadTextureImage( textureIndex, sourceIndex, loader ) {
|
|
2827
2846
|
|
|
2828
2847
|
const parser = this;
|
|
2829
2848
|
const json = this.json;
|
|
2830
|
-
const options = this.options;
|
|
2831
2849
|
|
|
2832
2850
|
const textureDef = json.textures[ textureIndex ];
|
|
2851
|
+
const sourceDef = json.images[ sourceIndex ];
|
|
2833
2852
|
|
|
2834
|
-
const cacheKey = (
|
|
2853
|
+
const cacheKey = ( sourceDef.uri || sourceDef.bufferView ) + ':' + textureDef.sampler;
|
|
2835
2854
|
|
|
2836
2855
|
if ( this.textureCache[ cacheKey ] ) {
|
|
2837
2856
|
|
|
@@ -2840,27 +2859,71 @@ class GLTFParser {
|
|
|
2840
2859
|
|
|
2841
2860
|
}
|
|
2842
2861
|
|
|
2862
|
+
const promise = this.loadImageSource( sourceIndex, loader ).then( function ( texture ) {
|
|
2863
|
+
|
|
2864
|
+
texture.flipY = false;
|
|
2865
|
+
|
|
2866
|
+
if ( textureDef.name ) texture.name = textureDef.name;
|
|
2867
|
+
|
|
2868
|
+
const samplers = json.samplers || {};
|
|
2869
|
+
const sampler = samplers[ textureDef.sampler ] || {};
|
|
2870
|
+
|
|
2871
|
+
texture.magFilter = WEBGL_FILTERS[ sampler.magFilter ] || LinearFilter;
|
|
2872
|
+
texture.minFilter = WEBGL_FILTERS[ sampler.minFilter ] || LinearMipmapLinearFilter;
|
|
2873
|
+
texture.wrapS = WEBGL_WRAPPINGS[ sampler.wrapS ] || RepeatWrapping;
|
|
2874
|
+
texture.wrapT = WEBGL_WRAPPINGS[ sampler.wrapT ] || RepeatWrapping;
|
|
2875
|
+
|
|
2876
|
+
parser.associations.set( texture, { textures: textureIndex } );
|
|
2877
|
+
|
|
2878
|
+
return texture;
|
|
2879
|
+
|
|
2880
|
+
} ).catch( function () {
|
|
2881
|
+
|
|
2882
|
+
return null;
|
|
2883
|
+
|
|
2884
|
+
} );
|
|
2885
|
+
|
|
2886
|
+
this.textureCache[ cacheKey ] = promise;
|
|
2887
|
+
|
|
2888
|
+
return promise;
|
|
2889
|
+
|
|
2890
|
+
}
|
|
2891
|
+
|
|
2892
|
+
loadImageSource( sourceIndex, loader ) {
|
|
2893
|
+
|
|
2894
|
+
const parser = this;
|
|
2895
|
+
const json = this.json;
|
|
2896
|
+
const options = this.options;
|
|
2897
|
+
|
|
2898
|
+
if ( this.sourceCache[ sourceIndex ] !== undefined ) {
|
|
2899
|
+
|
|
2900
|
+
return this.sourceCache[ sourceIndex ].then( ( texture ) => texture.clone() );
|
|
2901
|
+
|
|
2902
|
+
}
|
|
2903
|
+
|
|
2904
|
+
const sourceDef = json.images[ sourceIndex ];
|
|
2905
|
+
|
|
2843
2906
|
const URL = self.URL || self.webkitURL;
|
|
2844
2907
|
|
|
2845
|
-
let sourceURI =
|
|
2908
|
+
let sourceURI = sourceDef.uri || '';
|
|
2846
2909
|
let isObjectURL = false;
|
|
2847
2910
|
|
|
2848
|
-
if (
|
|
2911
|
+
if ( sourceDef.bufferView !== undefined ) {
|
|
2849
2912
|
|
|
2850
2913
|
// Load binary image data from bufferView, if provided.
|
|
2851
2914
|
|
|
2852
|
-
sourceURI = parser.getDependency( 'bufferView',
|
|
2915
|
+
sourceURI = parser.getDependency( 'bufferView', sourceDef.bufferView ).then( function ( bufferView ) {
|
|
2853
2916
|
|
|
2854
2917
|
isObjectURL = true;
|
|
2855
|
-
const blob = new Blob( [ bufferView ], { type:
|
|
2918
|
+
const blob = new Blob( [ bufferView ], { type: sourceDef.mimeType } );
|
|
2856
2919
|
sourceURI = URL.createObjectURL( blob );
|
|
2857
2920
|
return sourceURI;
|
|
2858
2921
|
|
|
2859
2922
|
} );
|
|
2860
2923
|
|
|
2861
|
-
} else if (
|
|
2924
|
+
} else if ( sourceDef.uri === undefined ) {
|
|
2862
2925
|
|
|
2863
|
-
throw new Error( 'THREE.GLTFLoader: Image ' +
|
|
2926
|
+
throw new Error( 'THREE.GLTFLoader: Image ' + sourceIndex + ' is missing URI and bufferView' );
|
|
2864
2927
|
|
|
2865
2928
|
}
|
|
2866
2929
|
|
|
@@ -2897,31 +2960,18 @@ class GLTFParser {
|
|
|
2897
2960
|
|
|
2898
2961
|
}
|
|
2899
2962
|
|
|
2900
|
-
texture.
|
|
2901
|
-
|
|
2902
|
-
if ( textureDef.name ) texture.name = textureDef.name;
|
|
2903
|
-
|
|
2904
|
-
const samplers = json.samplers || {};
|
|
2905
|
-
const sampler = samplers[ textureDef.sampler ] || {};
|
|
2906
|
-
|
|
2907
|
-
texture.magFilter = WEBGL_FILTERS[ sampler.magFilter ] || LinearFilter;
|
|
2908
|
-
texture.minFilter = WEBGL_FILTERS[ sampler.minFilter ] || LinearMipmapLinearFilter;
|
|
2909
|
-
texture.wrapS = WEBGL_WRAPPINGS[ sampler.wrapS ] || RepeatWrapping;
|
|
2910
|
-
texture.wrapT = WEBGL_WRAPPINGS[ sampler.wrapT ] || RepeatWrapping;
|
|
2911
|
-
|
|
2912
|
-
parser.associations.set( texture, { textures: textureIndex } );
|
|
2963
|
+
texture.userData.mimeType = sourceDef.mimeType || getImageURIMimeType( sourceDef.uri );
|
|
2913
2964
|
|
|
2914
2965
|
return texture;
|
|
2915
2966
|
|
|
2916
|
-
} ).catch( function () {
|
|
2967
|
+
} ).catch( function ( error ) {
|
|
2917
2968
|
|
|
2918
2969
|
console.error( 'THREE.GLTFLoader: Couldn\'t load texture', sourceURI );
|
|
2919
|
-
|
|
2970
|
+
throw error;
|
|
2920
2971
|
|
|
2921
2972
|
} );
|
|
2922
2973
|
|
|
2923
|
-
this.
|
|
2924
|
-
|
|
2974
|
+
this.sourceCache[ sourceIndex ] = promise;
|
|
2925
2975
|
return promise;
|
|
2926
2976
|
|
|
2927
2977
|
}
|
|
@@ -2933,7 +2983,7 @@ class GLTFParser {
|
|
|
2933
2983
|
* @param {Object} mapDef
|
|
2934
2984
|
* @return {Promise<Texture>}
|
|
2935
2985
|
*/
|
|
2936
|
-
assignTexture( materialParams, mapName, mapDef ) {
|
|
2986
|
+
assignTexture( materialParams, mapName, mapDef, encoding ) {
|
|
2937
2987
|
|
|
2938
2988
|
const parser = this;
|
|
2939
2989
|
|
|
@@ -2961,6 +3011,12 @@ class GLTFParser {
|
|
|
2961
3011
|
|
|
2962
3012
|
}
|
|
2963
3013
|
|
|
3014
|
+
if ( encoding !== undefined ) {
|
|
3015
|
+
|
|
3016
|
+
texture.encoding = encoding;
|
|
3017
|
+
|
|
3018
|
+
}
|
|
3019
|
+
|
|
2964
3020
|
materialParams[ mapName ] = texture;
|
|
2965
3021
|
|
|
2966
3022
|
return texture;
|
|
@@ -3132,7 +3188,7 @@ class GLTFParser {
|
|
|
3132
3188
|
|
|
3133
3189
|
if ( metallicRoughness.baseColorTexture !== undefined ) {
|
|
3134
3190
|
|
|
3135
|
-
pending.push( parser.assignTexture( materialParams, 'map', metallicRoughness.baseColorTexture ) );
|
|
3191
|
+
pending.push( parser.assignTexture( materialParams, 'map', metallicRoughness.baseColorTexture, sRGBEncoding ) );
|
|
3136
3192
|
|
|
3137
3193
|
}
|
|
3138
3194
|
|
|
@@ -3223,7 +3279,7 @@ class GLTFParser {
|
|
|
3223
3279
|
|
|
3224
3280
|
if ( materialDef.emissiveTexture !== undefined && materialType !== MeshBasicMaterial ) {
|
|
3225
3281
|
|
|
3226
|
-
pending.push( parser.assignTexture( materialParams, 'emissiveMap', materialDef.emissiveTexture ) );
|
|
3282
|
+
pending.push( parser.assignTexture( materialParams, 'emissiveMap', materialDef.emissiveTexture, sRGBEncoding ) );
|
|
3227
3283
|
|
|
3228
3284
|
}
|
|
3229
3285
|
|
|
@@ -3243,10 +3299,6 @@ class GLTFParser {
|
|
|
3243
3299
|
|
|
3244
3300
|
if ( materialDef.name ) material.name = materialDef.name;
|
|
3245
3301
|
|
|
3246
|
-
// baseColorTexture, emissiveTexture, and specularGlossinessTexture use sRGB encoding.
|
|
3247
|
-
if ( material.map ) material.map.encoding = sRGBEncoding;
|
|
3248
|
-
if ( material.emissiveMap ) material.emissiveMap.encoding = sRGBEncoding;
|
|
3249
|
-
|
|
3250
3302
|
assignExtrasToUserData( material, materialDef );
|
|
3251
3303
|
|
|
3252
3304
|
parser.associations.set( material, { materials: materialIndex } );
|
|
@@ -106,15 +106,6 @@ class KTX2Loader extends Loader {
|
|
|
106
106
|
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
dispose() {
|
|
110
|
-
|
|
111
|
-
this.workerPool.dispose();
|
|
112
|
-
if ( this.workerSourceURL ) URL.revokeObjectURL( this.workerSourceURL );
|
|
113
|
-
|
|
114
|
-
return this;
|
|
115
|
-
|
|
116
|
-
}
|
|
117
|
-
|
|
118
109
|
init() {
|
|
119
110
|
|
|
120
111
|
if ( ! this.transcoderPending ) {
|
|
@@ -270,8 +261,8 @@ class KTX2Loader extends Loader {
|
|
|
270
261
|
|
|
271
262
|
dispose() {
|
|
272
263
|
|
|
273
|
-
URL.revokeObjectURL( this.workerSourceURL );
|
|
274
264
|
this.workerPool.dispose();
|
|
265
|
+
if ( this.workerSourceURL ) URL.revokeObjectURL( this.workerSourceURL );
|
|
275
266
|
|
|
276
267
|
_activeLoaders --;
|
|
277
268
|
|
|
@@ -4,25 +4,91 @@ import {
|
|
|
4
4
|
Float32BufferAttribute,
|
|
5
5
|
InterleavedBuffer,
|
|
6
6
|
InterleavedBufferAttribute,
|
|
7
|
+
MathUtils,
|
|
7
8
|
TriangleFanDrawMode,
|
|
8
9
|
TriangleStripDrawMode,
|
|
9
10
|
TrianglesDrawMode,
|
|
10
|
-
Vector3
|
|
11
|
+
Vector3,
|
|
11
12
|
} from '../../../../three/src/Three.js';
|
|
13
|
+
import { generateTangents } from '../libs/mikktspace.module.js';
|
|
12
14
|
|
|
13
15
|
|
|
14
|
-
function computeTangents( geometry ) {
|
|
16
|
+
function computeTangents( geometry, negateSign = true ) {
|
|
15
17
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
function getAttributeArray( attribute ) {
|
|
19
|
+
|
|
20
|
+
if ( attribute.normalized || attribute.isInterleavedBufferAttribute ) {
|
|
21
|
+
|
|
22
|
+
const srcArray = attribute.isInterleavedBufferAttribute ? attribute.data.array : attribute.array;
|
|
23
|
+
const dstArray = new Float32Array( attribute.getCount() * attribute.itemSize );
|
|
24
|
+
|
|
25
|
+
for ( let i = 0, j = 0; i < attribute.getCount(); i ++ ) {
|
|
26
|
+
|
|
27
|
+
dstArray[ j ++ ] = MathUtils.denormalize( attribute.getX( i ), srcArray );
|
|
28
|
+
dstArray[ j ++ ] = MathUtils.denormalize( attribute.getY( i ), srcArray );
|
|
29
|
+
|
|
30
|
+
if ( attribute.itemSize > 2 ) {
|
|
31
|
+
|
|
32
|
+
dstArray[ j ++ ] = MathUtils.denormalize( attribute.getZ( i ), srcArray );
|
|
33
|
+
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return dstArray;
|
|
39
|
+
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if ( attribute.array instanceof Float32Array ) {
|
|
43
|
+
|
|
44
|
+
return attribute.array;
|
|
45
|
+
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return new Float32Array( attribute.array );
|
|
49
|
+
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// MikkTSpace algorithm requires non-indexed input.
|
|
53
|
+
|
|
54
|
+
const _geometry = geometry.index ? geometry.toNonIndexed() : geometry;
|
|
55
|
+
|
|
56
|
+
// Compute vertex tangents.
|
|
57
|
+
|
|
58
|
+
const tangents = generateTangents(
|
|
59
|
+
|
|
60
|
+
getAttributeArray( _geometry.attributes.position ),
|
|
61
|
+
getAttributeArray( _geometry.attributes.normal ),
|
|
62
|
+
getAttributeArray( _geometry.attributes.uv )
|
|
63
|
+
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
// Texture coordinate convention of glTF differs from the apparent
|
|
67
|
+
// default of the MikkTSpace library; .w component must be flipped.
|
|
68
|
+
|
|
69
|
+
if ( negateSign ) {
|
|
70
|
+
|
|
71
|
+
for ( let i = 3; i < tangents.length; i += 4 ) {
|
|
72
|
+
|
|
73
|
+
tangents[ i ] *= - 1;
|
|
74
|
+
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
//
|
|
80
|
+
|
|
81
|
+
_geometry.setAttribute( 'tangent', new BufferAttribute( tangents, 4 ) );
|
|
82
|
+
|
|
83
|
+
return geometry.copy( _geometry );
|
|
18
84
|
|
|
19
85
|
}
|
|
20
86
|
|
|
21
87
|
/**
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
88
|
+
* @param {Array<BufferGeometry>} geometries
|
|
89
|
+
* @param {Boolean} useGroups
|
|
90
|
+
* @return {BufferGeometry}
|
|
91
|
+
*/
|
|
26
92
|
function mergeBufferGeometries( geometries, useGroups = false ) {
|
|
27
93
|
|
|
28
94
|
const isIndexed = geometries[ 0 ].index !== null;
|
|
@@ -834,7 +900,7 @@ function computeMorphedAttributes( object ) {
|
|
|
834
900
|
|
|
835
901
|
}
|
|
836
902
|
|
|
837
|
-
} else
|
|
903
|
+
} else {
|
|
838
904
|
|
|
839
905
|
// non-indexed buffer geometry
|
|
840
906
|
|
|
@@ -929,7 +995,107 @@ function computeMorphedAttributes( object ) {
|
|
|
929
995
|
|
|
930
996
|
}
|
|
931
997
|
|
|
998
|
+
function mergeGroups( geometry ) {
|
|
999
|
+
|
|
1000
|
+
if ( geometry.groups.length === 0 ) {
|
|
1001
|
+
|
|
1002
|
+
console.warn( 'THREE.BufferGeometryUtils.mergeGroups(): No groups are defined. Nothing to merge.' );
|
|
1003
|
+
return geometry;
|
|
1004
|
+
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
let groups = geometry.groups;
|
|
1008
|
+
|
|
1009
|
+
// sort groups by material index
|
|
1010
|
+
|
|
1011
|
+
groups = groups.sort( ( a, b ) => {
|
|
1012
|
+
|
|
1013
|
+
if ( a.materialIndex !== b.materialIndex ) return a.materialIndex - b.materialIndex;
|
|
1014
|
+
|
|
1015
|
+
return a.start - b.start;
|
|
932
1016
|
|
|
1017
|
+
} );
|
|
1018
|
+
|
|
1019
|
+
// create index for non-indexed geometries
|
|
1020
|
+
|
|
1021
|
+
if ( geometry.getIndex() === null ) {
|
|
1022
|
+
|
|
1023
|
+
const positionAttribute = geometry.getAttribute( 'position' );
|
|
1024
|
+
const indices = [];
|
|
1025
|
+
|
|
1026
|
+
for ( let i = 0; i < positionAttribute.count; i += 3 ) {
|
|
1027
|
+
|
|
1028
|
+
indices.push( i, i + 1, i + 2 );
|
|
1029
|
+
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
geometry.setIndex( indices );
|
|
1033
|
+
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
// sort index
|
|
1037
|
+
|
|
1038
|
+
const index = geometry.getIndex();
|
|
1039
|
+
|
|
1040
|
+
const newIndices = [];
|
|
1041
|
+
|
|
1042
|
+
for ( let i = 0; i < groups.length; i ++ ) {
|
|
1043
|
+
|
|
1044
|
+
const group = groups[ i ];
|
|
1045
|
+
|
|
1046
|
+
const groupStart = group.start;
|
|
1047
|
+
const groupLength = groupStart + group.count;
|
|
1048
|
+
|
|
1049
|
+
for ( let j = groupStart; j < groupLength; j ++ ) {
|
|
1050
|
+
|
|
1051
|
+
newIndices.push( index.getX( j ) );
|
|
1052
|
+
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
geometry.dispose(); // Required to force buffer recreation
|
|
1058
|
+
geometry.setIndex( newIndices );
|
|
1059
|
+
|
|
1060
|
+
// update groups indices
|
|
1061
|
+
|
|
1062
|
+
let start = 0;
|
|
1063
|
+
|
|
1064
|
+
for ( let i = 0; i < groups.length; i ++ ) {
|
|
1065
|
+
|
|
1066
|
+
const group = groups[ i ];
|
|
1067
|
+
|
|
1068
|
+
group.start = start;
|
|
1069
|
+
start += group.count;
|
|
1070
|
+
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
// merge groups
|
|
1074
|
+
|
|
1075
|
+
let currentGroup = groups[ 0 ];
|
|
1076
|
+
|
|
1077
|
+
geometry.groups = [ currentGroup ];
|
|
1078
|
+
|
|
1079
|
+
for ( let i = 1; i < groups.length; i ++ ) {
|
|
1080
|
+
|
|
1081
|
+
const group = groups[ i ];
|
|
1082
|
+
|
|
1083
|
+
if ( currentGroup.materialIndex === group.materialIndex ) {
|
|
1084
|
+
|
|
1085
|
+
currentGroup.count += group.count;
|
|
1086
|
+
|
|
1087
|
+
} else {
|
|
1088
|
+
|
|
1089
|
+
currentGroup = group;
|
|
1090
|
+
geometry.groups.push( currentGroup );
|
|
1091
|
+
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
return geometry;
|
|
1097
|
+
|
|
1098
|
+
}
|
|
933
1099
|
|
|
934
1100
|
export {
|
|
935
1101
|
computeTangents,
|
|
@@ -940,4 +1106,5 @@ export {
|
|
|
940
1106
|
mergeVertices,
|
|
941
1107
|
toTrianglesDrawMode,
|
|
942
1108
|
computeMorphedAttributes,
|
|
1109
|
+
mergeGroups
|
|
943
1110
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@damienmortini/three",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.167",
|
|
4
4
|
"description": "Three.js helpers",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"install": "npm run copyexamples",
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
"bugs": "https://github.com/damienmortini/lib/issues",
|
|
26
26
|
"homepage": "https://github.com/damienmortini/lib/tree/main/packages/three",
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@damienmortini/core": "^0.2.
|
|
29
|
-
"fs-extra": "^10.0.
|
|
30
|
-
"three": "0.
|
|
28
|
+
"@damienmortini/core": "^0.2.131",
|
|
29
|
+
"fs-extra": "^10.0.1",
|
|
30
|
+
"three": "0.139.0"
|
|
31
31
|
},
|
|
32
|
-
"gitHead": "
|
|
32
|
+
"gitHead": "212228c077e3dd31b65117e24ec84c80a9bfb984"
|
|
33
33
|
}
|