@damienmortini/three 0.1.178 → 0.1.180

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,7 +53,6 @@ import {
53
53
  SkinnedMesh,
54
54
  Sphere,
55
55
  SpotLight,
56
- TangentSpaceNormalMap,
57
56
  Texture,
58
57
  TextureLoader,
59
58
  TriangleFanDrawMode,
@@ -369,10 +368,6 @@ class GLTFLoader extends Loader {
369
368
  extensions[ extensionName ] = new GLTFMaterialsUnlitExtension();
370
369
  break;
371
370
 
372
- case EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS:
373
- extensions[ extensionName ] = new GLTFMaterialsPbrSpecularGlossinessExtension();
374
- break;
375
-
376
371
  case EXTENSIONS.KHR_DRACO_MESH_COMPRESSION:
377
372
  extensions[ extensionName ] = new GLTFDracoMeshCompressionExtension( json, this.dracoLoader );
378
373
  break;
@@ -465,7 +460,6 @@ const EXTENSIONS = {
465
460
  KHR_LIGHTS_PUNCTUAL: 'KHR_lights_punctual',
466
461
  KHR_MATERIALS_CLEARCOAT: 'KHR_materials_clearcoat',
467
462
  KHR_MATERIALS_IOR: 'KHR_materials_ior',
468
- KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS: 'KHR_materials_pbrSpecularGlossiness',
469
463
  KHR_MATERIALS_SHEEN: 'KHR_materials_sheen',
470
464
  KHR_MATERIALS_SPECULAR: 'KHR_materials_specular',
471
465
  KHR_MATERIALS_TRANSMISSION: 'KHR_materials_transmission',
@@ -576,6 +570,8 @@ class GLTFLightsExtension {
576
570
 
577
571
  lightNode.decay = 2;
578
572
 
573
+ assignExtrasToUserData( lightNode, lightDef );
574
+
579
575
  if ( lightDef.intensity !== undefined ) lightNode.intensity = lightDef.intensity;
580
576
 
581
577
  lightNode.name = parser.createUniqueName( lightDef.name || ( 'light_' + lightIndex ) );
@@ -588,6 +584,14 @@ class GLTFLightsExtension {
588
584
 
589
585
  }
590
586
 
587
+ getDependency( type, index ) {
588
+
589
+ if ( type !== 'light' ) return;
590
+
591
+ return this._loadLight( index );
592
+
593
+ }
594
+
591
595
  createNodeAttachment( nodeIndex ) {
592
596
 
593
597
  const self = this;
@@ -1758,335 +1762,6 @@ class GLTFTextureTransformExtension {
1758
1762
 
1759
1763
  }
1760
1764
 
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
-
2090
1765
  /**
2091
1766
  * Mesh Quantization Extension
2092
1767
  *
@@ -2554,6 +2229,8 @@ function getImageURIMimeType( uri ) {
2554
2229
 
2555
2230
  }
2556
2231
 
2232
+ const _identityMatrix = new Matrix4();
2233
+
2557
2234
  /* GLTF PARSER */
2558
2235
 
2559
2236
  class GLTFParser {
@@ -2587,10 +2264,18 @@ class GLTFParser {
2587
2264
 
2588
2265
  // Use an ImageBitmapLoader if imageBitmaps are supported. Moves much of the
2589
2266
  // 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;
2590
2271
 
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;
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
+ }
2594
2279
 
2595
2280
  if ( typeof createImageBitmap === 'undefined' || isSafari || ( isFirefox && firefoxVersion < 98 ) ) {
2596
2281
 
@@ -2855,7 +2540,11 @@ class GLTFParser {
2855
2540
  break;
2856
2541
 
2857
2542
  case 'node':
2858
- dependency = this.loadNode( index );
2543
+ dependency = this._invokeOne( function ( ext ) {
2544
+
2545
+ return ext.loadNode && ext.loadNode( index );
2546
+
2547
+ } );
2859
2548
  break;
2860
2549
 
2861
2550
  case 'mesh':
@@ -2915,7 +2604,19 @@ class GLTFParser {
2915
2604
  break;
2916
2605
 
2917
2606
  default:
2918
- throw new Error( 'Unknown type: ' + type );
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;
2919
2620
 
2920
2621
  }
2921
2622
 
@@ -3025,10 +2726,12 @@ class GLTFParser {
3025
2726
 
3026
2727
  if ( accessorDef.bufferView === undefined && accessorDef.sparse === undefined ) {
3027
2728
 
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 );
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 ) );
3032
2735
 
3033
2736
  }
3034
2737
 
@@ -3146,7 +2849,7 @@ class GLTFParser {
3146
2849
  /**
3147
2850
  * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#textures
3148
2851
  * @param {number} textureIndex
3149
- * @return {Promise<THREE.Texture>}
2852
+ * @return {Promise<THREE.Texture|null>}
3150
2853
  */
3151
2854
  loadTexture( textureIndex ) {
3152
2855
 
@@ -3316,6 +3019,8 @@ class GLTFParser {
3316
3019
 
3317
3020
  return this.getDependency( 'texture', mapDef.index ).then( function ( texture ) {
3318
3021
 
3022
+ if ( ! texture ) return null;
3023
+
3319
3024
  // Materials sample aoMap from UV set 1 and other maps from UV set 0 - this can't be configured
3320
3025
  // However, we will copy UV set 0 to UV set 1 on demand for aoMap
3321
3026
  if ( mapDef.texCoord !== undefined && mapDef.texCoord != 0 && ! ( mapName === 'aoMap' && mapDef.texCoord == 1 ) ) {
@@ -3414,7 +3119,6 @@ class GLTFParser {
3414
3119
 
3415
3120
  let cacheKey = 'ClonedMaterial:' + material.uuid + ':';
3416
3121
 
3417
- if ( material.isGLTFSpecularGlossinessMaterial ) cacheKey += 'specular-glossiness:';
3418
3122
  if ( useDerivativeTangents ) cacheKey += 'derivative-tangents:';
3419
3123
  if ( useVertexColors ) cacheKey += 'vertex-colors:';
3420
3124
  if ( useFlatShading ) cacheKey += 'flat-shading:';
@@ -3482,13 +3186,7 @@ class GLTFParser {
3482
3186
 
3483
3187
  const pending = [];
3484
3188
 
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 ] ) {
3189
+ if ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ] ) {
3492
3190
 
3493
3191
  const kmuExtension = extensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ];
3494
3192
  materialType = kmuExtension.getMaterialType();
@@ -3612,17 +3310,7 @@ class GLTFParser {
3612
3310
 
3613
3311
  return Promise.all( pending ).then( function () {
3614
3312
 
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
- }
3313
+ const material = new materialType( materialParams );
3626
3314
 
3627
3315
  if ( materialDef.name ) material.name = materialDef.name;
3628
3316
 
@@ -3911,25 +3599,65 @@ class GLTFParser {
3911
3599
  /**
3912
3600
  * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#skins
3913
3601
  * @param {number} skinIndex
3914
- * @return {Promise<Object>}
3602
+ * @return {Promise<Skeleton>}
3915
3603
  */
3916
3604
  loadSkin( skinIndex ) {
3917
3605
 
3918
3606
  const skinDef = this.json.skins[ skinIndex ];
3919
3607
 
3920
- const skinEntry = { joints: skinDef.joints };
3608
+ const pending = [];
3921
3609
 
3922
- if ( skinDef.inverseBindMatrices === undefined ) {
3610
+ for ( let i = 0, il = skinDef.joints.length; i < il; i ++ ) {
3923
3611
 
3924
- return Promise.resolve( skinEntry );
3612
+ pending.push( this.getDependency( 'node', skinDef.joints[ i ] ) );
3925
3613
 
3926
3614
  }
3927
3615
 
3928
- return this.getDependency( 'accessor', skinDef.inverseBindMatrices ).then( function ( accessor ) {
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 );
3929
3647
 
3930
- skinEntry.inverseBindMatrices = accessor;
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
+ }
3931
3659
 
3932
- return skinEntry;
3660
+ return new Skeleton( bones, boneInverses );
3933
3661
 
3934
3662
  } );
3935
3663
 
@@ -4159,7 +3887,7 @@ class GLTFParser {
4159
3887
 
4160
3888
  return ( function () {
4161
3889
 
4162
- const pending = [];
3890
+ const objectPending = [];
4163
3891
 
4164
3892
  const meshPromise = parser._invokeOne( function ( ext ) {
4165
3893
 
@@ -4169,13 +3897,13 @@ class GLTFParser {
4169
3897
 
4170
3898
  if ( meshPromise ) {
4171
3899
 
4172
- pending.push( meshPromise );
3900
+ objectPending.push( meshPromise );
4173
3901
 
4174
3902
  }
4175
3903
 
4176
3904
  if ( nodeDef.camera !== undefined ) {
4177
3905
 
4178
- pending.push( parser.getDependency( 'camera', nodeDef.camera ).then( function ( camera ) {
3906
+ objectPending.push( parser.getDependency( 'camera', nodeDef.camera ).then( function ( camera ) {
4179
3907
 
4180
3908
  return parser._getNodeRef( parser.cameraCache, nodeDef.camera, camera );
4181
3909
 
@@ -4189,13 +3917,34 @@ class GLTFParser {
4189
3917
 
4190
3918
  } ).forEach( function ( promise ) {
4191
3919
 
4192
- pending.push( promise );
3920
+ objectPending.push( promise );
4193
3921
 
4194
3922
  } );
4195
3923
 
4196
- return Promise.all( pending );
3924
+ const childPending = [];
3925
+ const childrenDef = nodeDef.children || [];
4197
3926
 
4198
- }() ).then( function ( objects ) {
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 ];
4199
3948
 
4200
3949
  let node;
4201
3950
 
@@ -4275,6 +4024,26 @@ class GLTFParser {
4275
4024
 
4276
4025
  parser.associations.get( node ).nodes = nodeIndex;
4277
4026
 
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
+
4278
4047
  return node;
4279
4048
 
4280
4049
  } );
@@ -4288,7 +4057,6 @@ class GLTFParser {
4288
4057
  */
4289
4058
  loadScene( sceneIndex ) {
4290
4059
 
4291
- const json = this.json;
4292
4060
  const extensions = this.extensions;
4293
4061
  const sceneDef = this.json.scenes[ sceneIndex ];
4294
4062
  const parser = this;
@@ -4308,11 +4076,17 @@ class GLTFParser {
4308
4076
 
4309
4077
  for ( let i = 0, il = nodeIds.length; i < il; i ++ ) {
4310
4078
 
4311
- pending.push( buildNodeHierarchy( nodeIds[ i ], scene, json, parser ) );
4079
+ pending.push( parser.getDependency( 'node', nodeIds[ i ] ) );
4312
4080
 
4313
4081
  }
4314
4082
 
4315
- return Promise.all( pending ).then( function () {
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
+ }
4316
4090
 
4317
4091
  // Removes dangling associations, associations that reference a node that
4318
4092
  // didn't make it into the scene.
@@ -4356,102 +4130,6 @@ class GLTFParser {
4356
4130
 
4357
4131
  }
4358
4132
 
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
-
4455
4133
  /**
4456
4134
  * @param {BufferGeometry} geometry
4457
4135
  * @param {GLTF.Primitive} primitiveDef
@@ -1225,6 +1225,112 @@ 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
+
1228
1334
  export {
1229
1335
  computeTangents,
1230
1336
  computeMikkTSpaceTangents,
@@ -1235,5 +1341,6 @@ export {
1235
1341
  mergeVertices,
1236
1342
  toTrianglesDrawMode,
1237
1343
  computeMorphedAttributes,
1238
- mergeGroups
1344
+ mergeGroups,
1345
+ toCreasedNormals
1239
1346
  };
package/index.js ADDED
@@ -0,0 +1 @@
1
+ export { WebGLRenderTarget2D } from './renderer/WebGLRenderTarget2D.js'
package/package.json CHANGED
@@ -1,11 +1,14 @@
1
1
  {
2
2
  "name": "@damienmortini/three",
3
- "version": "0.1.178",
3
+ "version": "0.1.180",
4
4
  "description": "Three.js helpers",
5
5
  "scripts": {
6
6
  "install": "npm run copyexamples",
7
- "copyexamples": "node copyExamples.js"
7
+ "copyexamples": "node copyExamples.js",
8
+ "generateTypes": "npx -p typescript tsc index.js --declaration --allowJs --emitDeclarationOnly --outDir types"
8
9
  },
10
+ "main": "index.js",
11
+ "types": "types/index.d.ts",
9
12
  "publishConfig": {
10
13
  "access": "public"
11
14
  },
@@ -25,9 +28,9 @@
25
28
  "bugs": "https://github.com/damienmortini/lib/issues",
26
29
  "homepage": "https://github.com/damienmortini/lib/tree/main/packages/three",
27
30
  "dependencies": {
28
- "@damienmortini/core": "^0.2.140",
29
- "fs-extra": "^10.1.0",
30
- "three": "0.146.0"
31
+ "@damienmortini/core": "^0.2.142",
32
+ "fs-extra": "^11.1.0",
33
+ "three": "0.148.0"
31
34
  },
32
- "gitHead": "61f6ec91c7c8b4cdc7cbfe6f0f99ec6eb9a522be"
35
+ "gitHead": "be306794087844509e0948db0f148ec16ee829a6"
33
36
  }
@@ -1,12 +1,10 @@
1
- import {
2
- Scene,
3
- Mesh,
4
- PlaneBufferGeometry,
5
- WebGLRenderTarget,
6
- OrthographicCamera,
7
- } from '../../../three/src/Three.js'
1
+ import { Scene, Mesh, PlaneGeometry, WebGLRenderTarget, OrthographicCamera } from 'three'
2
+
3
+ export class WebGLRenderTarget2D extends WebGLRenderTarget {
4
+ #scene
5
+ #camera
6
+ #quad
8
7
 
9
- export default class THREEWebGLRenderTarget2D extends WebGLRenderTarget {
10
8
  constructor({
11
9
  renderer,
12
10
  material = undefined,
@@ -42,24 +40,24 @@ export default class THREEWebGLRenderTarget2D extends WebGLRenderTarget {
42
40
 
43
41
  this.renderer = renderer
44
42
 
45
- this._scene = new Scene()
46
- this._camera = new OrthographicCamera(-1, 1, 1, -1, 0, 1)
43
+ this.#scene = new Scene()
44
+ this.#camera = new OrthographicCamera(-1, 1, 1, -1, 0, 1)
47
45
 
48
- this._quad = new Mesh(new PlaneBufferGeometry(2, 2), material)
49
- this._scene.add(this._quad)
46
+ this.#quad = new Mesh(new PlaneGeometry(2, 2), material)
47
+ this.#scene.add(this.#quad)
50
48
  }
51
49
 
52
50
  get material() {
53
- return this._quad.material
51
+ return this.#quad.material
54
52
  }
55
53
 
56
54
  set material(value) {
57
- this._quad.material = value
55
+ this.#quad.material = value
58
56
  }
59
57
 
60
58
  render({ debug = false } = {}) {
61
59
  if (!debug) this.renderer.setRenderTarget(this)
62
- this.renderer.render(this._scene, this._camera)
60
+ this.renderer.render(this.#scene, this.#camera)
63
61
  this.renderer.setRenderTarget(null)
64
62
  }
65
63
  }
@@ -0,0 +1 @@
1
+ export { WebGLRenderTarget2D } from "./renderer/WebGLRenderTarget2D.js";
@@ -0,0 +1,42 @@
1
+ export class WebGLRenderTarget2D {
2
+ constructor({
3
+ renderer,
4
+ material,
5
+ width,
6
+ height,
7
+ wrapS,
8
+ wrapT,
9
+ magFilter,
10
+ minFilter,
11
+ format,
12
+ type,
13
+ anisotropy,
14
+ encoding,
15
+ generateMipmaps,
16
+ depthBuffer,
17
+ stencilBuffer,
18
+ depthTexture,
19
+ }: {
20
+ renderer: any
21
+ material?: any
22
+ width?: number
23
+ height?: number
24
+ wrapS?: any
25
+ wrapT?: any
26
+ magFilter?: any
27
+ minFilter?: any
28
+ format?: any
29
+ type?: any
30
+ anisotropy?: any
31
+ encoding?: any
32
+ generateMipmaps?: any
33
+ depthBuffer?: any
34
+ stencilBuffer?: any
35
+ depthTexture?: any
36
+ })
37
+ renderer: any
38
+ set material(arg: any)
39
+ get material(): any
40
+ render({ debug }?: { debug?: boolean }): void
41
+ #private
42
+ }