@damienmortini/three 0.1.180 → 0.1.181

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.
@@ -53,6 +53,7 @@ import {
53
53
  SkinnedMesh,
54
54
  Sphere,
55
55
  SpotLight,
56
+ TangentSpaceNormalMap,
56
57
  Texture,
57
58
  TextureLoader,
58
59
  TriangleFanDrawMode,
@@ -368,6 +369,10 @@ class GLTFLoader extends Loader {
368
369
  extensions[ extensionName ] = new GLTFMaterialsUnlitExtension();
369
370
  break;
370
371
 
372
+ case EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS:
373
+ extensions[ extensionName ] = new GLTFMaterialsPbrSpecularGlossinessExtension();
374
+ break;
375
+
371
376
  case EXTENSIONS.KHR_DRACO_MESH_COMPRESSION:
372
377
  extensions[ extensionName ] = new GLTFDracoMeshCompressionExtension( json, this.dracoLoader );
373
378
  break;
@@ -460,6 +465,7 @@ const EXTENSIONS = {
460
465
  KHR_LIGHTS_PUNCTUAL: 'KHR_lights_punctual',
461
466
  KHR_MATERIALS_CLEARCOAT: 'KHR_materials_clearcoat',
462
467
  KHR_MATERIALS_IOR: 'KHR_materials_ior',
468
+ KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS: 'KHR_materials_pbrSpecularGlossiness',
463
469
  KHR_MATERIALS_SHEEN: 'KHR_materials_sheen',
464
470
  KHR_MATERIALS_SPECULAR: 'KHR_materials_specular',
465
471
  KHR_MATERIALS_TRANSMISSION: 'KHR_materials_transmission',
@@ -570,8 +576,6 @@ class GLTFLightsExtension {
570
576
 
571
577
  lightNode.decay = 2;
572
578
 
573
- assignExtrasToUserData( lightNode, lightDef );
574
-
575
579
  if ( lightDef.intensity !== undefined ) lightNode.intensity = lightDef.intensity;
576
580
 
577
581
  lightNode.name = parser.createUniqueName( lightDef.name || ( 'light_' + lightIndex ) );
@@ -584,14 +588,6 @@ class GLTFLightsExtension {
584
588
 
585
589
  }
586
590
 
587
- getDependency( type, index ) {
588
-
589
- if ( type !== 'light' ) return;
590
-
591
- return this._loadLight( index );
592
-
593
- }
594
-
595
591
  createNodeAttachment( nodeIndex ) {
596
592
 
597
593
  const self = this;
@@ -1762,6 +1758,335 @@ class GLTFTextureTransformExtension {
1762
1758
 
1763
1759
  }
1764
1760
 
1761
+ /**
1762
+ * Specular-Glossiness Extension
1763
+ *
1764
+ * Specification: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Archived/KHR_materials_pbrSpecularGlossiness
1765
+ */
1766
+
1767
+ /**
1768
+ * A sub class of StandardMaterial with some of the functionality
1769
+ * changed via the `onBeforeCompile` callback
1770
+ * @pailhead
1771
+ */
1772
+ class GLTFMeshStandardSGMaterial extends MeshStandardMaterial {
1773
+
1774
+ constructor( params ) {
1775
+
1776
+ super();
1777
+
1778
+ this.isGLTFSpecularGlossinessMaterial = true;
1779
+
1780
+ //various chunks that need replacing
1781
+ const specularMapParsFragmentChunk = [
1782
+ '#ifdef USE_SPECULARMAP',
1783
+ ' uniform sampler2D specularMap;',
1784
+ '#endif'
1785
+ ].join( '\n' );
1786
+
1787
+ const glossinessMapParsFragmentChunk = [
1788
+ '#ifdef USE_GLOSSINESSMAP',
1789
+ ' uniform sampler2D glossinessMap;',
1790
+ '#endif'
1791
+ ].join( '\n' );
1792
+
1793
+ const specularMapFragmentChunk = [
1794
+ 'vec3 specularFactor = specular;',
1795
+ '#ifdef USE_SPECULARMAP',
1796
+ ' vec4 texelSpecular = texture2D( specularMap, vUv );',
1797
+ ' // reads channel RGB, compatible with a glTF Specular-Glossiness (RGBA) texture',
1798
+ ' specularFactor *= texelSpecular.rgb;',
1799
+ '#endif'
1800
+ ].join( '\n' );
1801
+
1802
+ const glossinessMapFragmentChunk = [
1803
+ 'float glossinessFactor = glossiness;',
1804
+ '#ifdef USE_GLOSSINESSMAP',
1805
+ ' vec4 texelGlossiness = texture2D( glossinessMap, vUv );',
1806
+ ' // reads channel A, compatible with a glTF Specular-Glossiness (RGBA) texture',
1807
+ ' glossinessFactor *= texelGlossiness.a;',
1808
+ '#endif'
1809
+ ].join( '\n' );
1810
+
1811
+ const lightPhysicalFragmentChunk = [
1812
+ 'PhysicalMaterial material;',
1813
+ 'material.diffuseColor = diffuseColor.rgb * ( 1. - max( specularFactor.r, max( specularFactor.g, specularFactor.b ) ) );',
1814
+ 'vec3 dxy = max( abs( dFdx( geometryNormal ) ), abs( dFdy( geometryNormal ) ) );',
1815
+ 'float geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );',
1816
+ 'material.roughness = max( 1.0 - glossinessFactor, 0.0525 ); // 0.0525 corresponds to the base mip of a 256 cubemap.',
1817
+ 'material.roughness += geometryRoughness;',
1818
+ 'material.roughness = min( material.roughness, 1.0 );',
1819
+ 'material.specularColor = specularFactor;',
1820
+ ].join( '\n' );
1821
+
1822
+ const uniforms = {
1823
+ specular: { value: new Color().setHex( 0xffffff ) },
1824
+ glossiness: { value: 1 },
1825
+ specularMap: { value: null },
1826
+ glossinessMap: { value: null }
1827
+ };
1828
+
1829
+ this._extraUniforms = uniforms;
1830
+
1831
+ this.onBeforeCompile = function ( shader ) {
1832
+
1833
+ for ( const uniformName in uniforms ) {
1834
+
1835
+ shader.uniforms[ uniformName ] = uniforms[ uniformName ];
1836
+
1837
+ }
1838
+
1839
+ shader.fragmentShader = shader.fragmentShader
1840
+ .replace( 'uniform float roughness;', 'uniform vec3 specular;' )
1841
+ .replace( 'uniform float metalness;', 'uniform float glossiness;' )
1842
+ .replace( '#include <roughnessmap_pars_fragment>', specularMapParsFragmentChunk )
1843
+ .replace( '#include <metalnessmap_pars_fragment>', glossinessMapParsFragmentChunk )
1844
+ .replace( '#include <roughnessmap_fragment>', specularMapFragmentChunk )
1845
+ .replace( '#include <metalnessmap_fragment>', glossinessMapFragmentChunk )
1846
+ .replace( '#include <lights_physical_fragment>', lightPhysicalFragmentChunk );
1847
+
1848
+ };
1849
+
1850
+ Object.defineProperties( this, {
1851
+
1852
+ specular: {
1853
+ get: function () {
1854
+
1855
+ return uniforms.specular.value;
1856
+
1857
+ },
1858
+ set: function ( v ) {
1859
+
1860
+ uniforms.specular.value = v;
1861
+
1862
+ }
1863
+ },
1864
+
1865
+ specularMap: {
1866
+ get: function () {
1867
+
1868
+ return uniforms.specularMap.value;
1869
+
1870
+ },
1871
+ set: function ( v ) {
1872
+
1873
+ uniforms.specularMap.value = v;
1874
+
1875
+ if ( v ) {
1876
+
1877
+ this.defines.USE_SPECULARMAP = ''; // USE_UV is set by the renderer for specular maps
1878
+
1879
+ } else {
1880
+
1881
+ delete this.defines.USE_SPECULARMAP;
1882
+
1883
+ }
1884
+
1885
+ }
1886
+ },
1887
+
1888
+ glossiness: {
1889
+ get: function () {
1890
+
1891
+ return uniforms.glossiness.value;
1892
+
1893
+ },
1894
+ set: function ( v ) {
1895
+
1896
+ uniforms.glossiness.value = v;
1897
+
1898
+ }
1899
+ },
1900
+
1901
+ glossinessMap: {
1902
+ get: function () {
1903
+
1904
+ return uniforms.glossinessMap.value;
1905
+
1906
+ },
1907
+ set: function ( v ) {
1908
+
1909
+ uniforms.glossinessMap.value = v;
1910
+
1911
+ if ( v ) {
1912
+
1913
+ this.defines.USE_GLOSSINESSMAP = '';
1914
+ this.defines.USE_UV = '';
1915
+
1916
+ } else {
1917
+
1918
+ delete this.defines.USE_GLOSSINESSMAP;
1919
+ delete this.defines.USE_UV;
1920
+
1921
+ }
1922
+
1923
+ }
1924
+ }
1925
+
1926
+ } );
1927
+
1928
+ delete this.metalness;
1929
+ delete this.roughness;
1930
+ delete this.metalnessMap;
1931
+ delete this.roughnessMap;
1932
+
1933
+ this.setValues( params );
1934
+
1935
+ }
1936
+
1937
+ copy( source ) {
1938
+
1939
+ super.copy( source );
1940
+
1941
+ this.specularMap = source.specularMap;
1942
+ this.specular.copy( source.specular );
1943
+ this.glossinessMap = source.glossinessMap;
1944
+ this.glossiness = source.glossiness;
1945
+ delete this.metalness;
1946
+ delete this.roughness;
1947
+ delete this.metalnessMap;
1948
+ delete this.roughnessMap;
1949
+ return this;
1950
+
1951
+ }
1952
+
1953
+ }
1954
+
1955
+
1956
+ class GLTFMaterialsPbrSpecularGlossinessExtension {
1957
+
1958
+ constructor() {
1959
+
1960
+ this.name = EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS;
1961
+
1962
+ this.specularGlossinessParams = [
1963
+ 'color',
1964
+ 'map',
1965
+ 'lightMap',
1966
+ 'lightMapIntensity',
1967
+ 'aoMap',
1968
+ 'aoMapIntensity',
1969
+ 'emissive',
1970
+ 'emissiveIntensity',
1971
+ 'emissiveMap',
1972
+ 'bumpMap',
1973
+ 'bumpScale',
1974
+ 'normalMap',
1975
+ 'normalMapType',
1976
+ 'displacementMap',
1977
+ 'displacementScale',
1978
+ 'displacementBias',
1979
+ 'specularMap',
1980
+ 'specular',
1981
+ 'glossinessMap',
1982
+ 'glossiness',
1983
+ 'alphaMap',
1984
+ 'envMap',
1985
+ 'envMapIntensity'
1986
+ ];
1987
+
1988
+ }
1989
+
1990
+ getMaterialType() {
1991
+
1992
+ return GLTFMeshStandardSGMaterial;
1993
+
1994
+ }
1995
+
1996
+ extendParams( materialParams, materialDef, parser ) {
1997
+
1998
+ const pbrSpecularGlossiness = materialDef.extensions[ this.name ];
1999
+
2000
+ materialParams.color = new Color( 1.0, 1.0, 1.0 );
2001
+ materialParams.opacity = 1.0;
2002
+
2003
+ const pending = [];
2004
+
2005
+ if ( Array.isArray( pbrSpecularGlossiness.diffuseFactor ) ) {
2006
+
2007
+ const array = pbrSpecularGlossiness.diffuseFactor;
2008
+
2009
+ materialParams.color.fromArray( array );
2010
+ materialParams.opacity = array[ 3 ];
2011
+
2012
+ }
2013
+
2014
+ if ( pbrSpecularGlossiness.diffuseTexture !== undefined ) {
2015
+
2016
+ pending.push( parser.assignTexture( materialParams, 'map', pbrSpecularGlossiness.diffuseTexture, sRGBEncoding ) );
2017
+
2018
+ }
2019
+
2020
+ materialParams.emissive = new Color( 0.0, 0.0, 0.0 );
2021
+ materialParams.glossiness = pbrSpecularGlossiness.glossinessFactor !== undefined ? pbrSpecularGlossiness.glossinessFactor : 1.0;
2022
+ materialParams.specular = new Color( 1.0, 1.0, 1.0 );
2023
+
2024
+ if ( Array.isArray( pbrSpecularGlossiness.specularFactor ) ) {
2025
+
2026
+ materialParams.specular.fromArray( pbrSpecularGlossiness.specularFactor );
2027
+
2028
+ }
2029
+
2030
+ if ( pbrSpecularGlossiness.specularGlossinessTexture !== undefined ) {
2031
+
2032
+ const specGlossMapDef = pbrSpecularGlossiness.specularGlossinessTexture;
2033
+ pending.push( parser.assignTexture( materialParams, 'glossinessMap', specGlossMapDef ) );
2034
+ pending.push( parser.assignTexture( materialParams, 'specularMap', specGlossMapDef, sRGBEncoding ) );
2035
+
2036
+ }
2037
+
2038
+ return Promise.all( pending );
2039
+
2040
+ }
2041
+
2042
+ createMaterial( materialParams ) {
2043
+
2044
+ const material = new GLTFMeshStandardSGMaterial( materialParams );
2045
+ material.fog = true;
2046
+
2047
+ material.color = materialParams.color;
2048
+
2049
+ material.map = materialParams.map === undefined ? null : materialParams.map;
2050
+
2051
+ material.lightMap = null;
2052
+ material.lightMapIntensity = 1.0;
2053
+
2054
+ material.aoMap = materialParams.aoMap === undefined ? null : materialParams.aoMap;
2055
+ material.aoMapIntensity = 1.0;
2056
+
2057
+ material.emissive = materialParams.emissive;
2058
+ material.emissiveIntensity = materialParams.emissiveIntensity === undefined ? 1.0 : materialParams.emissiveIntensity;
2059
+ material.emissiveMap = materialParams.emissiveMap === undefined ? null : materialParams.emissiveMap;
2060
+
2061
+ material.bumpMap = materialParams.bumpMap === undefined ? null : materialParams.bumpMap;
2062
+ material.bumpScale = 1;
2063
+
2064
+ material.normalMap = materialParams.normalMap === undefined ? null : materialParams.normalMap;
2065
+ material.normalMapType = TangentSpaceNormalMap;
2066
+
2067
+ if ( materialParams.normalScale ) material.normalScale = materialParams.normalScale;
2068
+
2069
+ material.displacementMap = null;
2070
+ material.displacementScale = 1;
2071
+ material.displacementBias = 0;
2072
+
2073
+ material.specularMap = materialParams.specularMap === undefined ? null : materialParams.specularMap;
2074
+ material.specular = materialParams.specular;
2075
+
2076
+ material.glossinessMap = materialParams.glossinessMap === undefined ? null : materialParams.glossinessMap;
2077
+ material.glossiness = materialParams.glossiness;
2078
+
2079
+ material.alphaMap = null;
2080
+
2081
+ material.envMap = materialParams.envMap === undefined ? null : materialParams.envMap;
2082
+ material.envMapIntensity = 1.0;
2083
+
2084
+ return material;
2085
+
2086
+ }
2087
+
2088
+ }
2089
+
1765
2090
  /**
1766
2091
  * Mesh Quantization Extension
1767
2092
  *
@@ -2229,8 +2554,6 @@ function getImageURIMimeType( uri ) {
2229
2554
 
2230
2555
  }
2231
2556
 
2232
- const _identityMatrix = new Matrix4();
2233
-
2234
2557
  /* GLTF PARSER */
2235
2558
 
2236
2559
  class GLTFParser {
@@ -2264,18 +2587,10 @@ class GLTFParser {
2264
2587
 
2265
2588
  // Use an ImageBitmapLoader if imageBitmaps are supported. Moves much of the
2266
2589
  // expensive work of uploading a texture to the GPU off the main thread.
2267
-
2268
- let isSafari = false;
2269
- let isFirefox = false;
2270
- let firefoxVersion = - 1;
2271
2590
 
2272
- if ( typeof navigator !== 'undefined' ) {
2273
-
2274
- isSafari = /^((?!chrome|android).)*safari/i.test( navigator.userAgent ) === true;
2275
- isFirefox = navigator.userAgent.indexOf( 'Firefox' ) > - 1;
2276
- firefoxVersion = isFirefox ? navigator.userAgent.match( /Firefox\/([0-9]+)\./ )[ 1 ] : - 1;
2277
-
2278
- }
2591
+ const isSafari = /^((?!chrome|android).)*safari/i.test( navigator.userAgent ) === true;
2592
+ const isFirefox = navigator.userAgent.indexOf( 'Firefox' ) > - 1;
2593
+ const firefoxVersion = isFirefox ? navigator.userAgent.match( /Firefox\/([0-9]+)\./ )[ 1 ] : - 1;
2279
2594
 
2280
2595
  if ( typeof createImageBitmap === 'undefined' || isSafari || ( isFirefox && firefoxVersion < 98 ) ) {
2281
2596
 
@@ -2540,11 +2855,7 @@ class GLTFParser {
2540
2855
  break;
2541
2856
 
2542
2857
  case 'node':
2543
- dependency = this._invokeOne( function ( ext ) {
2544
-
2545
- return ext.loadNode && ext.loadNode( index );
2546
-
2547
- } );
2858
+ dependency = this.loadNode( index );
2548
2859
  break;
2549
2860
 
2550
2861
  case 'mesh':
@@ -2604,19 +2915,7 @@ class GLTFParser {
2604
2915
  break;
2605
2916
 
2606
2917
  default:
2607
- dependency = this._invokeOne( function ( ext ) {
2608
-
2609
- return ext != this && ext.getDependency && ext.getDependency( type, index );
2610
-
2611
- } );
2612
-
2613
- if ( ! dependency ) {
2614
-
2615
- throw new Error( 'Unknown type: ' + type );
2616
-
2617
- }
2618
-
2619
- break;
2918
+ throw new Error( 'Unknown type: ' + type );
2620
2919
 
2621
2920
  }
2622
2921
 
@@ -2726,12 +3025,10 @@ class GLTFParser {
2726
3025
 
2727
3026
  if ( accessorDef.bufferView === undefined && accessorDef.sparse === undefined ) {
2728
3027
 
2729
- const itemSize = WEBGL_TYPE_SIZES[ accessorDef.type ];
2730
- const TypedArray = WEBGL_COMPONENT_TYPES[ accessorDef.componentType ];
2731
- const normalized = accessorDef.normalized === true;
2732
-
2733
- const array = new TypedArray( accessorDef.count * itemSize );
2734
- return Promise.resolve( new BufferAttribute( array, itemSize, normalized ) );
3028
+ // Ignore empty accessors, which may be used to declare runtime
3029
+ // information about attributes coming from another source (e.g. Draco
3030
+ // compression extension).
3031
+ return Promise.resolve( null );
2735
3032
 
2736
3033
  }
2737
3034
 
@@ -2849,7 +3146,7 @@ class GLTFParser {
2849
3146
  /**
2850
3147
  * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#textures
2851
3148
  * @param {number} textureIndex
2852
- * @return {Promise<THREE.Texture|null>}
3149
+ * @return {Promise<THREE.Texture>}
2853
3150
  */
2854
3151
  loadTexture( textureIndex ) {
2855
3152
 
@@ -3019,8 +3316,6 @@ class GLTFParser {
3019
3316
 
3020
3317
  return this.getDependency( 'texture', mapDef.index ).then( function ( texture ) {
3021
3318
 
3022
- if ( ! texture ) return null;
3023
-
3024
3319
  // Materials sample aoMap from UV set 1 and other maps from UV set 0 - this can't be configured
3025
3320
  // However, we will copy UV set 0 to UV set 1 on demand for aoMap
3026
3321
  if ( mapDef.texCoord !== undefined && mapDef.texCoord != 0 && ! ( mapName === 'aoMap' && mapDef.texCoord == 1 ) ) {
@@ -3119,6 +3414,7 @@ class GLTFParser {
3119
3414
 
3120
3415
  let cacheKey = 'ClonedMaterial:' + material.uuid + ':';
3121
3416
 
3417
+ if ( material.isGLTFSpecularGlossinessMaterial ) cacheKey += 'specular-glossiness:';
3122
3418
  if ( useDerivativeTangents ) cacheKey += 'derivative-tangents:';
3123
3419
  if ( useVertexColors ) cacheKey += 'vertex-colors:';
3124
3420
  if ( useFlatShading ) cacheKey += 'flat-shading:';
@@ -3186,7 +3482,13 @@ class GLTFParser {
3186
3482
 
3187
3483
  const pending = [];
3188
3484
 
3189
- if ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ] ) {
3485
+ if ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ] ) {
3486
+
3487
+ const sgExtension = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ];
3488
+ materialType = sgExtension.getMaterialType();
3489
+ pending.push( sgExtension.extendParams( materialParams, materialDef, parser ) );
3490
+
3491
+ } else if ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ] ) {
3190
3492
 
3191
3493
  const kmuExtension = extensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ];
3192
3494
  materialType = kmuExtension.getMaterialType();
@@ -3310,7 +3612,17 @@ class GLTFParser {
3310
3612
 
3311
3613
  return Promise.all( pending ).then( function () {
3312
3614
 
3313
- const material = new materialType( materialParams );
3615
+ let material;
3616
+
3617
+ if ( materialType === GLTFMeshStandardSGMaterial ) {
3618
+
3619
+ material = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].createMaterial( materialParams );
3620
+
3621
+ } else {
3622
+
3623
+ material = new materialType( materialParams );
3624
+
3625
+ }
3314
3626
 
3315
3627
  if ( materialDef.name ) material.name = materialDef.name;
3316
3628
 
@@ -3599,65 +3911,25 @@ class GLTFParser {
3599
3911
  /**
3600
3912
  * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#skins
3601
3913
  * @param {number} skinIndex
3602
- * @return {Promise<Skeleton>}
3914
+ * @return {Promise<Object>}
3603
3915
  */
3604
3916
  loadSkin( skinIndex ) {
3605
3917
 
3606
3918
  const skinDef = this.json.skins[ skinIndex ];
3607
3919
 
3608
- const pending = [];
3920
+ const skinEntry = { joints: skinDef.joints };
3609
3921
 
3610
- for ( let i = 0, il = skinDef.joints.length; i < il; i ++ ) {
3922
+ if ( skinDef.inverseBindMatrices === undefined ) {
3611
3923
 
3612
- pending.push( this.getDependency( 'node', skinDef.joints[ i ] ) );
3924
+ return Promise.resolve( skinEntry );
3613
3925
 
3614
3926
  }
3615
3927
 
3616
- if ( skinDef.inverseBindMatrices !== undefined ) {
3617
-
3618
- pending.push( this.getDependency( 'accessor', skinDef.inverseBindMatrices ) );
3619
-
3620
- } else {
3621
-
3622
- pending.push( null );
3623
-
3624
- }
3625
-
3626
- return Promise.all( pending ).then( function ( results ) {
3627
-
3628
- const inverseBindMatrices = results.pop();
3629
- const jointNodes = results;
3630
-
3631
- const bones = [];
3632
- const boneInverses = [];
3633
-
3634
- for ( let i = 0, il = jointNodes.length; i < il; i ++ ) {
3635
-
3636
- const jointNode = jointNodes[ i ];
3637
-
3638
- if ( jointNode ) {
3639
-
3640
- bones.push( jointNode );
3641
-
3642
- const mat = new Matrix4();
3643
-
3644
- if ( inverseBindMatrices !== null ) {
3645
-
3646
- mat.fromArray( inverseBindMatrices.array, i * 16 );
3928
+ return this.getDependency( 'accessor', skinDef.inverseBindMatrices ).then( function ( accessor ) {
3647
3929
 
3648
- }
3649
-
3650
- boneInverses.push( mat );
3651
-
3652
- } else {
3653
-
3654
- console.warn( 'THREE.GLTFLoader: Joint "%s" could not be found.', skinDef.joints[ i ] );
3655
-
3656
- }
3657
-
3658
- }
3930
+ skinEntry.inverseBindMatrices = accessor;
3659
3931
 
3660
- return new Skeleton( bones, boneInverses );
3932
+ return skinEntry;
3661
3933
 
3662
3934
  } );
3663
3935
 
@@ -3887,7 +4159,7 @@ class GLTFParser {
3887
4159
 
3888
4160
  return ( function () {
3889
4161
 
3890
- const objectPending = [];
4162
+ const pending = [];
3891
4163
 
3892
4164
  const meshPromise = parser._invokeOne( function ( ext ) {
3893
4165
 
@@ -3897,13 +4169,13 @@ class GLTFParser {
3897
4169
 
3898
4170
  if ( meshPromise ) {
3899
4171
 
3900
- objectPending.push( meshPromise );
4172
+ pending.push( meshPromise );
3901
4173
 
3902
4174
  }
3903
4175
 
3904
4176
  if ( nodeDef.camera !== undefined ) {
3905
4177
 
3906
- objectPending.push( parser.getDependency( 'camera', nodeDef.camera ).then( function ( camera ) {
4178
+ pending.push( parser.getDependency( 'camera', nodeDef.camera ).then( function ( camera ) {
3907
4179
 
3908
4180
  return parser._getNodeRef( parser.cameraCache, nodeDef.camera, camera );
3909
4181
 
@@ -3917,34 +4189,13 @@ class GLTFParser {
3917
4189
 
3918
4190
  } ).forEach( function ( promise ) {
3919
4191
 
3920
- objectPending.push( promise );
4192
+ pending.push( promise );
3921
4193
 
3922
4194
  } );
3923
4195
 
3924
- const childPending = [];
3925
- const childrenDef = nodeDef.children || [];
4196
+ return Promise.all( pending );
3926
4197
 
3927
- for ( let i = 0, il = childrenDef.length; i < il; i ++ ) {
3928
-
3929
- childPending.push( parser.getDependency( 'node', childrenDef[ i ] ) );
3930
-
3931
- }
3932
-
3933
- const skeletonPending = nodeDef.skin === undefined
3934
- ? Promise.resolve( null )
3935
- : parser.getDependency( 'skin', nodeDef.skin );
3936
-
3937
- return Promise.all( [
3938
- Promise.all( objectPending ),
3939
- Promise.all( childPending ),
3940
- skeletonPending
3941
- ] );
3942
-
3943
- }() ).then( function ( results ) {
3944
-
3945
- const objects = results[ 0 ];
3946
- const children = results[ 1 ];
3947
- const skeleton = results[ 2 ];
4198
+ }() ).then( function ( objects ) {
3948
4199
 
3949
4200
  let node;
3950
4201
 
@@ -4024,26 +4275,6 @@ class GLTFParser {
4024
4275
 
4025
4276
  parser.associations.get( node ).nodes = nodeIndex;
4026
4277
 
4027
- if ( skeleton !== null ) {
4028
-
4029
- // This full traverse should be fine because
4030
- // child glTF nodes have not been added to this node yet.
4031
- node.traverse( function ( mesh ) {
4032
-
4033
- if ( ! mesh.isSkinnedMesh ) return;
4034
-
4035
- mesh.bind( skeleton, _identityMatrix );
4036
-
4037
- } );
4038
-
4039
- }
4040
-
4041
- for ( let i = 0, il = children.length; i < il; i ++ ) {
4042
-
4043
- node.add( children[ i ] );
4044
-
4045
- }
4046
-
4047
4278
  return node;
4048
4279
 
4049
4280
  } );
@@ -4057,6 +4288,7 @@ class GLTFParser {
4057
4288
  */
4058
4289
  loadScene( sceneIndex ) {
4059
4290
 
4291
+ const json = this.json;
4060
4292
  const extensions = this.extensions;
4061
4293
  const sceneDef = this.json.scenes[ sceneIndex ];
4062
4294
  const parser = this;
@@ -4076,17 +4308,11 @@ class GLTFParser {
4076
4308
 
4077
4309
  for ( let i = 0, il = nodeIds.length; i < il; i ++ ) {
4078
4310
 
4079
- pending.push( parser.getDependency( 'node', nodeIds[ i ] ) );
4311
+ pending.push( buildNodeHierarchy( nodeIds[ i ], scene, json, parser ) );
4080
4312
 
4081
4313
  }
4082
4314
 
4083
- return Promise.all( pending ).then( function ( nodes ) {
4084
-
4085
- for ( let i = 0, il = nodes.length; i < il; i ++ ) {
4086
-
4087
- scene.add( nodes[ i ] );
4088
-
4089
- }
4315
+ return Promise.all( pending ).then( function () {
4090
4316
 
4091
4317
  // Removes dangling associations, associations that reference a node that
4092
4318
  // didn't make it into the scene.
@@ -4130,6 +4356,102 @@ class GLTFParser {
4130
4356
 
4131
4357
  }
4132
4358
 
4359
+ function buildNodeHierarchy( nodeId, parentObject, json, parser ) {
4360
+
4361
+ const nodeDef = json.nodes[ nodeId ];
4362
+
4363
+ return parser.getDependency( 'node', nodeId ).then( function ( node ) {
4364
+
4365
+ if ( nodeDef.skin === undefined ) return node;
4366
+
4367
+ // build skeleton here as well
4368
+
4369
+ let skinEntry;
4370
+
4371
+ return parser.getDependency( 'skin', nodeDef.skin ).then( function ( skin ) {
4372
+
4373
+ skinEntry = skin;
4374
+
4375
+ const pendingJoints = [];
4376
+
4377
+ for ( let i = 0, il = skinEntry.joints.length; i < il; i ++ ) {
4378
+
4379
+ pendingJoints.push( parser.getDependency( 'node', skinEntry.joints[ i ] ) );
4380
+
4381
+ }
4382
+
4383
+ return Promise.all( pendingJoints );
4384
+
4385
+ } ).then( function ( jointNodes ) {
4386
+
4387
+ node.traverse( function ( mesh ) {
4388
+
4389
+ if ( ! mesh.isMesh ) return;
4390
+
4391
+ const bones = [];
4392
+ const boneInverses = [];
4393
+
4394
+ for ( let j = 0, jl = jointNodes.length; j < jl; j ++ ) {
4395
+
4396
+ const jointNode = jointNodes[ j ];
4397
+
4398
+ if ( jointNode ) {
4399
+
4400
+ bones.push( jointNode );
4401
+
4402
+ const mat = new Matrix4();
4403
+
4404
+ if ( skinEntry.inverseBindMatrices !== undefined ) {
4405
+
4406
+ mat.fromArray( skinEntry.inverseBindMatrices.array, j * 16 );
4407
+
4408
+ }
4409
+
4410
+ boneInverses.push( mat );
4411
+
4412
+ } else {
4413
+
4414
+ console.warn( 'THREE.GLTFLoader: Joint "%s" could not be found.', skinEntry.joints[ j ] );
4415
+
4416
+ }
4417
+
4418
+ }
4419
+
4420
+ mesh.bind( new Skeleton( bones, boneInverses ), mesh.matrixWorld );
4421
+
4422
+ } );
4423
+
4424
+ return node;
4425
+
4426
+ } );
4427
+
4428
+ } ).then( function ( node ) {
4429
+
4430
+ // build node hierachy
4431
+
4432
+ parentObject.add( node );
4433
+
4434
+ const pending = [];
4435
+
4436
+ if ( nodeDef.children ) {
4437
+
4438
+ const children = nodeDef.children;
4439
+
4440
+ for ( let i = 0, il = children.length; i < il; i ++ ) {
4441
+
4442
+ const child = children[ i ];
4443
+ pending.push( buildNodeHierarchy( child, node, json, parser ) );
4444
+
4445
+ }
4446
+
4447
+ }
4448
+
4449
+ return Promise.all( pending );
4450
+
4451
+ } );
4452
+
4453
+ }
4454
+
4133
4455
  /**
4134
4456
  * @param {BufferGeometry} geometry
4135
4457
  * @param {GLTF.Primitive} primitiveDef
@@ -1225,112 +1225,6 @@ function mergeGroups( geometry ) {
1225
1225
 
1226
1226
  }
1227
1227
 
1228
-
1229
- // Creates a new, non-indexed geometry with smooth normals everywhere except faces that meet at
1230
- // an angle greater than the crease angle.
1231
- function toCreasedNormals( geometry, creaseAngle = Math.PI / 3 /* 60 degrees */ ) {
1232
-
1233
- const creaseDot = Math.cos( creaseAngle );
1234
- const hashMultiplier = ( 1 + 1e-10 ) * 1e2;
1235
-
1236
- // reusable vertors
1237
- const verts = [ new Vector3(), new Vector3(), new Vector3() ];
1238
- const tempVec1 = new Vector3();
1239
- const tempVec2 = new Vector3();
1240
- const tempNorm = new Vector3();
1241
- const tempNorm2 = new Vector3();
1242
-
1243
- // hashes a vector
1244
- function hashVertex( v ) {
1245
-
1246
- const x = ~ ~ ( v.x * hashMultiplier );
1247
- const y = ~ ~ ( v.y * hashMultiplier );
1248
- const z = ~ ~ ( v.z * hashMultiplier );
1249
- return `${x},${y},${z}`;
1250
-
1251
- }
1252
-
1253
- const resultGeometry = geometry.toNonIndexed();
1254
- const posAttr = resultGeometry.attributes.position;
1255
- const vertexMap = {};
1256
-
1257
- // find all the normals shared by commonly located vertices
1258
- for ( let i = 0, l = posAttr.count / 3; i < l; i ++ ) {
1259
-
1260
- const i3 = 3 * i;
1261
- const a = verts[ 0 ].fromBufferAttribute( posAttr, i3 + 0 );
1262
- const b = verts[ 1 ].fromBufferAttribute( posAttr, i3 + 1 );
1263
- const c = verts[ 2 ].fromBufferAttribute( posAttr, i3 + 2 );
1264
-
1265
- tempVec1.subVectors( c, b );
1266
- tempVec2.subVectors( a, b );
1267
-
1268
- // add the normal to the map for all vertices
1269
- const normal = new Vector3().crossVectors( tempVec1, tempVec2 ).normalize();
1270
- for ( let n = 0; n < 3; n ++ ) {
1271
-
1272
- const vert = verts[ n ];
1273
- const hash = hashVertex( vert );
1274
- if ( ! ( hash in vertexMap ) ) {
1275
-
1276
- vertexMap[ hash ] = [];
1277
-
1278
- }
1279
-
1280
- vertexMap[ hash ].push( normal );
1281
-
1282
- }
1283
-
1284
- }
1285
-
1286
- // average normals from all vertices that share a common location if they are within the
1287
- // provided crease threshold
1288
- const normalArray = new Float32Array( posAttr.count * 3 );
1289
- const normAttr = new BufferAttribute( normalArray, 3, false );
1290
- for ( let i = 0, l = posAttr.count / 3; i < l; i ++ ) {
1291
-
1292
- // get the face normal for this vertex
1293
- const i3 = 3 * i;
1294
- const a = verts[ 0 ].fromBufferAttribute( posAttr, i3 + 0 );
1295
- const b = verts[ 1 ].fromBufferAttribute( posAttr, i3 + 1 );
1296
- const c = verts[ 2 ].fromBufferAttribute( posAttr, i3 + 2 );
1297
-
1298
- tempVec1.subVectors( c, b );
1299
- tempVec2.subVectors( a, b );
1300
-
1301
- tempNorm.crossVectors( tempVec1, tempVec2 ).normalize();
1302
-
1303
- // average all normals that meet the threshold and set the normal value
1304
- for ( let n = 0; n < 3; n ++ ) {
1305
-
1306
- const vert = verts[ n ];
1307
- const hash = hashVertex( vert );
1308
- const otherNormals = vertexMap[ hash ];
1309
- tempNorm2.set( 0, 0, 0 );
1310
-
1311
- for ( let k = 0, lk = otherNormals.length; k < lk; k ++ ) {
1312
-
1313
- const otherNorm = otherNormals[ k ];
1314
- if ( tempNorm.dot( otherNorm ) > creaseDot ) {
1315
-
1316
- tempNorm2.add( otherNorm );
1317
-
1318
- }
1319
-
1320
- }
1321
-
1322
- tempNorm2.normalize();
1323
- normAttr.setXYZ( i3 + n, tempNorm2.x, tempNorm2.y, tempNorm2.z );
1324
-
1325
- }
1326
-
1327
- }
1328
-
1329
- resultGeometry.setAttribute( 'normal', normAttr );
1330
- return resultGeometry;
1331
-
1332
- }
1333
-
1334
1228
  export {
1335
1229
  computeTangents,
1336
1230
  computeMikkTSpaceTangents,
@@ -1341,6 +1235,5 @@ export {
1341
1235
  mergeVertices,
1342
1236
  toTrianglesDrawMode,
1343
1237
  computeMorphedAttributes,
1344
- mergeGroups,
1345
- toCreasedNormals
1238
+ mergeGroups
1346
1239
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@damienmortini/three",
3
- "version": "0.1.180",
3
+ "version": "0.1.181",
4
4
  "description": "Three.js helpers",
5
5
  "scripts": {
6
6
  "install": "npm run copyexamples",
@@ -30,7 +30,7 @@
30
30
  "dependencies": {
31
31
  "@damienmortini/core": "^0.2.142",
32
32
  "fs-extra": "^11.1.0",
33
- "three": "0.148.0"
33
+ "three": "0.149.0"
34
34
  },
35
- "gitHead": "be306794087844509e0948db0f148ec16ee829a6"
35
+ "gitHead": "3786e86afb461622bcd3c8c50c44bdd1fc10309e"
36
36
  }