@luminocity/lemonate-engine 26.4.8 → 26.5.0
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.
- package/dist/Renderer.d.ts +6 -6
- package/dist/items/CompositionItem.d.ts +1 -1
- package/dist/items/ImageItem.d.ts +1 -1
- package/dist/items/MeshItem.d.ts +1 -1
- package/dist/items/PointsItem.d.ts +1 -1
- package/dist/lemonate.es.js +1284 -280
- package/dist/lemonate.js +40199 -60667
- package/dist/lemonate.min.js +21 -16
- package/dist/lemonate.umd.js +1285 -282
- package/dist/player.zip +0 -0
- package/dist/scenegraph/SgLightsource.d.ts +1 -1
- package/dist/scenegraph/SgNavMesh.d.ts +2 -2
- package/dist/scenegraph/SgProceduralGeometryItem.d.ts +1 -1
- package/dist/scenegraph/SgSky.d.ts +1 -0
- package/dist/subsystems/composer/composernode.d.ts +2 -2
- package/dist/subsystems/gridmap/GridMapBuilder.d.ts +4 -4
- package/dist/subsystems/particlesystem/ParticleSystem.d.ts +1 -1
- package/dist/subsystems/particlesystem/Simulation.d.ts +2 -2
- package/package.json +4 -4
package/dist/lemonate.es.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { tools as tools$1, Field, EventEmitter, Proxifier, Block, Script, TemplateFactory, getDatatypeByName, InvalidArgumentException, LoaderException, InvalidStateException, ItemVisibility, QuotaExceededException, ApiClient, Storage } from '@luminocity/lemonate-gateway';
|
|
2
2
|
export * from '@luminocity/lemonate-gateway';
|
|
3
3
|
import * as THREE from 'three';
|
|
4
|
-
import { Vector3, Object3D, BufferGeometry, MeshBasicMaterial, Mesh, BufferAttribute, BoxGeometry, CylinderGeometry, Raycaster, Quaternion, Euler, Matrix4, LineBasicMaterial, Float32BufferAttribute, OctahedronGeometry, Line, TorusGeometry, SphereGeometry, PlaneGeometry, DoubleSide, Vector2, LineSegments, Box3, TrianglesDrawMode, TriangleFanDrawMode, TriangleStripDrawMode, EdgesGeometry, Uint16BufferAttribute, Color, PointLightHelper as PointLightHelper$1, DirectionalLightHelper as DirectionalLightHelper$1, SpotLightHelper as SpotLightHelper$1, HemisphereLightHelper as HemisphereLightHelper$1, CameraHelper as CameraHelper$1, AxesHelper, Scene, SkinnedMesh, CanvasTexture, RepeatWrapping, LinearFilter, UnsignedIntType, UnsignedByteType, FloatType, HalfFloatType, PMREMGenerator, Vector4, ShaderMaterial, OrthographicCamera, AddEquation, OneMinusSrcAlphaFactor, SrcAlphaFactor, CustomBlending, DataTextureLoader, DataUtils, LinearSRGBColorSpace, AudioLoader, NoColorSpace, SRGBColorSpace, ImageBitmapLoader, TextureLoader, NoBlending, Uniform, RGBADepthPacking, PerspectiveCamera,
|
|
4
|
+
import { Vector3, Object3D, BufferGeometry, MeshBasicMaterial, Mesh, BufferAttribute, BoxGeometry, CylinderGeometry, Raycaster, Quaternion, Euler, Matrix4, LineBasicMaterial, Float32BufferAttribute, OctahedronGeometry, Line, TorusGeometry, SphereGeometry, PlaneGeometry, DoubleSide, Vector2, LineSegments, Box3, TrianglesDrawMode, TriangleFanDrawMode, TriangleStripDrawMode, EdgesGeometry, Uint16BufferAttribute, Color, PointLightHelper as PointLightHelper$1, DirectionalLightHelper as DirectionalLightHelper$1, SpotLightHelper as SpotLightHelper$1, HemisphereLightHelper as HemisphereLightHelper$1, CameraHelper as CameraHelper$1, AxesHelper, Scene, SkinnedMesh, CanvasTexture, RepeatWrapping, LinearFilter, UnsignedIntType, UnsignedByteType, FloatType, HalfFloatType, PMREMGenerator, Vector4, ShaderMaterial, OrthographicCamera, AddEquation, OneMinusSrcAlphaFactor, SrcAlphaFactor, CustomBlending, DataTextureLoader, DataUtils, LinearSRGBColorSpace, AudioLoader, NoColorSpace, SRGBColorSpace, ImageBitmapLoader, TextureLoader, NoBlending, Uniform, RGBADepthPacking, PerspectiveCamera, Timer as Timer$1, UniformsUtils, GLSL3, WebGLRenderTarget, RGBAFormat, NearestFilter, MeshNormalMaterial, MeshDepthMaterial, DataTexture, RedFormat, RGFormat, REVISION, LessDepth, GreaterDepth, GreaterEqualDepth, LessEqualDepth, NotEqualDepth, EqualDepth, AlwaysDepth, NeverDepth, IcosahedronGeometry, Light, DepthTexture, DepthFormat, LinearMipMapLinearFilter, MirroredRepeatWrapping, ClampToEdgeWrapping, LinearMipMapNearestFilter, NearestMipmapLinearFilter, NearestMipMapNearestFilter, FileLoader, GLSL1, SpriteMaterial, Loader, MeshPhysicalMaterial, Points, PointsMaterial, MeshToonMaterial, MeshMatcapMaterial, MeshLambertMaterial, MeshPhongMaterial, Matrix3, TangentSpaceNormalMap, ObjectSpaceNormalMap, FrontSide, BackSide, MultiplyBlending, SubtractiveBlending, AdditiveBlending, NormalBlending, SrcAlphaSaturateFactor, OneMinusDstColorFactor, DstColorFactor, OneMinusDstAlphaFactor, DstAlphaFactor, OneMinusSrcColorFactor, SrcColorFactor, OneFactor, ZeroFactor, MaxEquation, MinEquation, ReverseSubtractEquation, SubtractEquation, AddOperation, MixOperation, MultiplyOperation, Group, Material, LoaderUtils, SpotLight, PointLight, DirectionalLight, InstancedMesh, InstancedBufferAttribute, InterleavedBuffer, InterleavedBufferAttribute, LinearMipmapLinearFilter, LinearMipmapNearestFilter, NearestMipmapNearestFilter, MeshStandardMaterial, PropertyBinding, LineLoop, MathUtils, Skeleton, AnimationClip, Bone, InterpolateDiscrete, InterpolateLinear, Texture, VectorKeyframeTrack, NumberKeyframeTrack, QuaternionKeyframeTrack, ColorManagement, Interpolant, Sphere, Curve, EquirectangularReflectionMapping, AmbientLight, ShapeUtils, CompressedCubeTexture, CompressedArrayTexture, CompressedTexture, RGBA_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGBA_BPTC_Format, RED_GREEN_RGTC2_Format, SIGNED_RED_GREEN_RGTC2_Format, RED_RGTC1_Format, SIGNED_RED_RGTC1_Format, RGBA_S3TC_DXT5_Format, RGB_S3TC_DXT1_Format, RGBA_S3TC_DXT1_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_4x4_Format, SIGNED_RG11_EAC_Format, RG11_EAC_Format, SIGNED_R11_EAC_Format, R11_EAC_Format, RGB_ETC2_Format, RGBA_ETC2_EAC_Format, RGBFormat, UnsignedInt101111Type, UnsignedInt5999Type, UnsignedShortType, Data3DTexture, RGB_PVRTC_4BPPV1_Format, RGB_ETC1_Format, RGB_BPTC_UNSIGNED_Format, LOD as LOD$1, UniformsLib, UniformsGroup, Compatibility, Sprite, WebGLRenderer, VSMShadowMap, PCFSoftShadowMap, PCFShadowMap, BasicShadowMap, ReinhardToneMapping, LoadingManager as LoadingManager$1, ACESFilmicToneMapping, CineonToneMapping, LinearToneMapping, NoToneMapping, SkeletonHelper, AnimationMixer, LoopOnce, LoopRepeat, HemisphereLight, Camera, ShapePath, ExtrudeGeometry, ConeGeometry, RingGeometry, ShaderChunk, RawShaderMaterial, Audio, PositionalAudio, DynamicDrawUsage, EventDispatcher, MOUSE, TOUCH, Spherical, VideoTexture, AudioListener, Source, ImageUtils, NearestMipMapLinearFilter } from 'three';
|
|
5
5
|
import { diff } from 'deep-diff';
|
|
6
6
|
import * as opentype from 'opentype.js';
|
|
7
|
-
import {
|
|
7
|
+
import { workingToColorSpace, context, reference, fog, densityFogFactor, rangeFogFactor, cubeTexture, texture } from 'three/tsl';
|
|
8
|
+
import { NodeFrame, WebGLCapabilities, InspectorBase, BasicNodeLibrary, Lighting, NodeUtils, GLSLNodeBuilder } from 'three/webgpu';
|
|
8
9
|
import { WebIO } from '@gltf-transform/core';
|
|
9
10
|
import { KHRDracoMeshCompression } from '@gltf-transform/extensions';
|
|
10
11
|
|
|
@@ -6187,8 +6188,7 @@ function mergeGeometries$1( geometries, useGroups = false ) {
|
|
|
6187
6188
|
for ( const name in morphAttributes ) {
|
|
6188
6189
|
|
|
6189
6190
|
const numMorphTargets = morphAttributes[ name ][ 0 ].length;
|
|
6190
|
-
|
|
6191
|
-
if ( numMorphTargets === 0 ) break;
|
|
6191
|
+
if ( numMorphTargets === 0 ) continue;
|
|
6192
6192
|
|
|
6193
6193
|
mergedGeometry.morphAttributes = mergedGeometry.morphAttributes || {};
|
|
6194
6194
|
mergedGeometry.morphAttributes[ name ] = [];
|
|
@@ -11390,12 +11390,12 @@ class Item extends EventEmitter {
|
|
|
11390
11390
|
}
|
|
11391
11391
|
}
|
|
11392
11392
|
|
|
11393
|
-
var engine$1 = "26.
|
|
11393
|
+
var engine$1 = "26.5.0";
|
|
11394
11394
|
var bullet = "3.26";
|
|
11395
11395
|
var lua = "5.4.3";
|
|
11396
11396
|
var packageVersionInfo = {
|
|
11397
11397
|
engine: engine$1,
|
|
11398
|
-
"three.js": "0.
|
|
11398
|
+
"three.js": "0.184.0",
|
|
11399
11399
|
bullet: bullet,
|
|
11400
11400
|
lua: lua
|
|
11401
11401
|
};
|
|
@@ -11493,7 +11493,7 @@ class HDRLoader extends DataTextureLoader {
|
|
|
11493
11493
|
|
|
11494
11494
|
s += chunk; len += chunk.length;
|
|
11495
11495
|
p += chunkSize;
|
|
11496
|
-
chunk
|
|
11496
|
+
chunk = String.fromCharCode.apply( null, new Uint16Array( buffer.subarray( p, p + chunkSize ) ) );
|
|
11497
11497
|
|
|
11498
11498
|
}
|
|
11499
11499
|
|
|
@@ -17928,7 +17928,7 @@ class ComposerNodeClass {
|
|
|
17928
17928
|
webGlRenderer;
|
|
17929
17929
|
connections = [];
|
|
17930
17930
|
dependencies = new Map();
|
|
17931
|
-
|
|
17931
|
+
timer = new Timer$1();
|
|
17932
17932
|
nameField;
|
|
17933
17933
|
name = "";
|
|
17934
17934
|
extendBaseShader = false;
|
|
@@ -17948,12 +17948,7 @@ class ComposerNodeClass {
|
|
|
17948
17948
|
this.engine = engine;
|
|
17949
17949
|
this.renderer = this.engine.renderer;
|
|
17950
17950
|
this.webGlRenderer = this.renderer.webGlRenderer;
|
|
17951
|
-
this.connections = [];
|
|
17952
|
-
this.dependencies = new Map();
|
|
17953
|
-
this.clock = new Clock$1();
|
|
17954
17951
|
this.nameField = this.block.getField("Name");
|
|
17955
|
-
this.extendBaseShader = false;
|
|
17956
|
-
this.blendMode = null;
|
|
17957
17952
|
}
|
|
17958
17953
|
dispose() {
|
|
17959
17954
|
if (this.fsQuad) {
|
|
@@ -18092,7 +18087,7 @@ class ComposerNodeClass {
|
|
|
18092
18087
|
this.uniforms.aspect.value = width / height;
|
|
18093
18088
|
}
|
|
18094
18089
|
_getDeltaTime() {
|
|
18095
|
-
return this.
|
|
18090
|
+
return this.timer.getDelta();
|
|
18096
18091
|
}
|
|
18097
18092
|
_allocateTarget(name, width, height, needsDepthTexture) {
|
|
18098
18093
|
return this.composer._allocateTarget(this, name, width, height, needsDepthTexture);
|
|
@@ -49141,7 +49136,7 @@ class OBJLoader extends Loader {
|
|
|
49141
49136
|
/**
|
|
49142
49137
|
* A loader for the glTF 2.0 format.
|
|
49143
49138
|
*
|
|
49144
|
-
* [glTF](https://www.khronos.org/gltf/
|
|
49139
|
+
* [glTF](https://www.khronos.org/gltf/) (GL Transmission Format) is an [open format specification]{@link https://github.com/KhronosGroup/glTF/tree/main/specification/2.0)
|
|
49145
49140
|
* for efficient delivery and loading of 3D content. Assets may be provided either in JSON (.gltf) or binary (.glb)
|
|
49146
49141
|
* format. External files store textures (.jpg, .png) and additional binary data (.bin). A glTF asset may deliver
|
|
49147
49142
|
* one or more scenes, including meshes, materials, textures, skins, skeletons, morph targets, animations, lights,
|
|
@@ -49153,8 +49148,11 @@ class OBJLoader extends Loader {
|
|
|
49153
49148
|
*
|
|
49154
49149
|
* `GLTFLoader` supports the following glTF 2.0 extensions:
|
|
49155
49150
|
* - KHR_draco_mesh_compression
|
|
49151
|
+
* - KHR_lights_punctual
|
|
49152
|
+
* - KHR_materials_anisotropy
|
|
49156
49153
|
* - KHR_materials_clearcoat
|
|
49157
49154
|
* - KHR_materials_dispersion
|
|
49155
|
+
* - KHR_materials_emissive_strength
|
|
49158
49156
|
* - KHR_materials_ior
|
|
49159
49157
|
* - KHR_materials_specular
|
|
49160
49158
|
* - KHR_materials_transmission
|
|
@@ -49162,12 +49160,14 @@ class OBJLoader extends Loader {
|
|
|
49162
49160
|
* - KHR_materials_unlit
|
|
49163
49161
|
* - KHR_materials_volume
|
|
49164
49162
|
* - KHR_mesh_quantization
|
|
49165
|
-
* -
|
|
49163
|
+
* - KHR_meshopt_compression
|
|
49166
49164
|
* - KHR_texture_basisu
|
|
49167
49165
|
* - KHR_texture_transform
|
|
49168
|
-
* -
|
|
49166
|
+
* - EXT_materials_bump
|
|
49169
49167
|
* - EXT_meshopt_compression
|
|
49170
49168
|
* - EXT_mesh_gpu_instancing
|
|
49169
|
+
* - EXT_texture_avif
|
|
49170
|
+
* - EXT_texture_webp
|
|
49171
49171
|
*
|
|
49172
49172
|
* The following glTF 2.0 extension is supported by an external user plugin:
|
|
49173
49173
|
* - [KHR_materials_variants](https://github.com/takahirox/three-gltf-extensions)
|
|
@@ -49299,7 +49299,13 @@ class GLTFLoader extends Loader {
|
|
|
49299
49299
|
|
|
49300
49300
|
this.register( function ( parser ) {
|
|
49301
49301
|
|
|
49302
|
-
return new GLTFMeshoptCompression( parser );
|
|
49302
|
+
return new GLTFMeshoptCompression( parser, EXTENSIONS.EXT_MESHOPT_COMPRESSION );
|
|
49303
|
+
|
|
49304
|
+
} );
|
|
49305
|
+
|
|
49306
|
+
this.register( function ( parser ) {
|
|
49307
|
+
|
|
49308
|
+
return new GLTFMeshoptCompression( parser, EXTENSIONS.KHR_MESHOPT_COMPRESSION );
|
|
49303
49309
|
|
|
49304
49310
|
} );
|
|
49305
49311
|
|
|
@@ -49478,7 +49484,7 @@ class GLTFLoader extends Loader {
|
|
|
49478
49484
|
}
|
|
49479
49485
|
|
|
49480
49486
|
/**
|
|
49481
|
-
* Parses the given
|
|
49487
|
+
* Parses the given glTF data and returns the resulting group.
|
|
49482
49488
|
*
|
|
49483
49489
|
* @param {string|ArrayBuffer} data - The raw glTF data.
|
|
49484
49490
|
* @param {string} path - The URL base path.
|
|
@@ -49670,6 +49676,20 @@ function GLTFRegistry() {
|
|
|
49670
49676
|
/********** EXTENSIONS ***********/
|
|
49671
49677
|
/*********************************/
|
|
49672
49678
|
|
|
49679
|
+
function getMaterialExtension( parser, materialIndex, extensionName ) {
|
|
49680
|
+
|
|
49681
|
+
const materialDef = parser.json.materials[ materialIndex ];
|
|
49682
|
+
|
|
49683
|
+
if ( materialDef.extensions && materialDef.extensions[ extensionName ] ) {
|
|
49684
|
+
|
|
49685
|
+
return materialDef.extensions[ extensionName ];
|
|
49686
|
+
|
|
49687
|
+
}
|
|
49688
|
+
|
|
49689
|
+
return null;
|
|
49690
|
+
|
|
49691
|
+
}
|
|
49692
|
+
|
|
49673
49693
|
const EXTENSIONS = {
|
|
49674
49694
|
KHR_BINARY_GLTF: 'KHR_binary_glTF',
|
|
49675
49695
|
KHR_DRACO_MESH_COMPRESSION: 'KHR_draco_mesh_compression',
|
|
@@ -49692,6 +49712,7 @@ const EXTENSIONS = {
|
|
|
49692
49712
|
EXT_TEXTURE_WEBP: 'EXT_texture_webp',
|
|
49693
49713
|
EXT_TEXTURE_AVIF: 'EXT_texture_avif',
|
|
49694
49714
|
EXT_MESHOPT_COMPRESSION: 'EXT_meshopt_compression',
|
|
49715
|
+
KHR_MESHOPT_COMPRESSION: 'KHR_meshopt_compression',
|
|
49695
49716
|
EXT_MESH_GPU_INSTANCING: 'EXT_mesh_gpu_instancing'
|
|
49696
49717
|
};
|
|
49697
49718
|
|
|
@@ -49906,20 +49927,13 @@ let GLTFMaterialsEmissiveStrengthExtension$1 = class GLTFMaterialsEmissiveStreng
|
|
|
49906
49927
|
|
|
49907
49928
|
extendMaterialParams( materialIndex, materialParams ) {
|
|
49908
49929
|
|
|
49909
|
-
const
|
|
49910
|
-
const materialDef = parser.json.materials[ materialIndex ];
|
|
49911
|
-
|
|
49912
|
-
if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {
|
|
49930
|
+
const extension = getMaterialExtension( this.parser, materialIndex, this.name );
|
|
49913
49931
|
|
|
49914
|
-
|
|
49932
|
+
if ( extension === null ) return Promise.resolve();
|
|
49915
49933
|
|
|
49916
|
-
|
|
49917
|
-
|
|
49918
|
-
const emissiveStrength = materialDef.extensions[ this.name ].emissiveStrength;
|
|
49919
|
-
|
|
49920
|
-
if ( emissiveStrength !== undefined ) {
|
|
49934
|
+
if ( extension.emissiveStrength !== undefined ) {
|
|
49921
49935
|
|
|
49922
|
-
materialParams.emissiveIntensity = emissiveStrength;
|
|
49936
|
+
materialParams.emissiveIntensity = extension.emissiveStrength;
|
|
49923
49937
|
|
|
49924
49938
|
}
|
|
49925
49939
|
|
|
@@ -49947,30 +49961,20 @@ let GLTFMaterialsClearcoatExtension$1 = class GLTFMaterialsClearcoatExtension {
|
|
|
49947
49961
|
|
|
49948
49962
|
getMaterialType( materialIndex ) {
|
|
49949
49963
|
|
|
49950
|
-
const
|
|
49951
|
-
const materialDef = parser.json.materials[ materialIndex ];
|
|
49952
|
-
|
|
49953
|
-
if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) return null;
|
|
49964
|
+
const extension = getMaterialExtension( this.parser, materialIndex, this.name );
|
|
49954
49965
|
|
|
49955
|
-
return MeshPhysicalMaterial;
|
|
49966
|
+
return extension !== null ? MeshPhysicalMaterial : null;
|
|
49956
49967
|
|
|
49957
49968
|
}
|
|
49958
49969
|
|
|
49959
49970
|
extendMaterialParams( materialIndex, materialParams ) {
|
|
49960
49971
|
|
|
49961
|
-
const
|
|
49962
|
-
const materialDef = parser.json.materials[ materialIndex ];
|
|
49963
|
-
|
|
49964
|
-
if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {
|
|
49972
|
+
const extension = getMaterialExtension( this.parser, materialIndex, this.name );
|
|
49965
49973
|
|
|
49966
|
-
|
|
49967
|
-
|
|
49968
|
-
}
|
|
49974
|
+
if ( extension === null ) return Promise.resolve();
|
|
49969
49975
|
|
|
49970
49976
|
const pending = [];
|
|
49971
49977
|
|
|
49972
|
-
const extension = materialDef.extensions[ this.name ];
|
|
49973
|
-
|
|
49974
49978
|
if ( extension.clearcoatFactor !== undefined ) {
|
|
49975
49979
|
|
|
49976
49980
|
materialParams.clearcoat = extension.clearcoatFactor;
|
|
@@ -49979,7 +49983,7 @@ let GLTFMaterialsClearcoatExtension$1 = class GLTFMaterialsClearcoatExtension {
|
|
|
49979
49983
|
|
|
49980
49984
|
if ( extension.clearcoatTexture !== undefined ) {
|
|
49981
49985
|
|
|
49982
|
-
pending.push( parser.assignTexture( materialParams, 'clearcoatMap', extension.clearcoatTexture ) );
|
|
49986
|
+
pending.push( this.parser.assignTexture( materialParams, 'clearcoatMap', extension.clearcoatTexture ) );
|
|
49983
49987
|
|
|
49984
49988
|
}
|
|
49985
49989
|
|
|
@@ -49991,13 +49995,13 @@ let GLTFMaterialsClearcoatExtension$1 = class GLTFMaterialsClearcoatExtension {
|
|
|
49991
49995
|
|
|
49992
49996
|
if ( extension.clearcoatRoughnessTexture !== undefined ) {
|
|
49993
49997
|
|
|
49994
|
-
pending.push( parser.assignTexture( materialParams, 'clearcoatRoughnessMap', extension.clearcoatRoughnessTexture ) );
|
|
49998
|
+
pending.push( this.parser.assignTexture( materialParams, 'clearcoatRoughnessMap', extension.clearcoatRoughnessTexture ) );
|
|
49995
49999
|
|
|
49996
50000
|
}
|
|
49997
50001
|
|
|
49998
50002
|
if ( extension.clearcoatNormalTexture !== undefined ) {
|
|
49999
50003
|
|
|
50000
|
-
pending.push( parser.assignTexture( materialParams, 'clearcoatNormalMap', extension.clearcoatNormalTexture ) );
|
|
50004
|
+
pending.push( this.parser.assignTexture( materialParams, 'clearcoatNormalMap', extension.clearcoatNormalTexture ) );
|
|
50001
50005
|
|
|
50002
50006
|
if ( extension.clearcoatNormalTexture.scale !== undefined ) {
|
|
50003
50007
|
|
|
@@ -50033,27 +50037,17 @@ let GLTFMaterialsDispersionExtension$1 = class GLTFMaterialsDispersionExtension
|
|
|
50033
50037
|
|
|
50034
50038
|
getMaterialType( materialIndex ) {
|
|
50035
50039
|
|
|
50036
|
-
const
|
|
50037
|
-
const materialDef = parser.json.materials[ materialIndex ];
|
|
50038
|
-
|
|
50039
|
-
if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) return null;
|
|
50040
|
+
const extension = getMaterialExtension( this.parser, materialIndex, this.name );
|
|
50040
50041
|
|
|
50041
|
-
return MeshPhysicalMaterial;
|
|
50042
|
+
return extension !== null ? MeshPhysicalMaterial : null;
|
|
50042
50043
|
|
|
50043
50044
|
}
|
|
50044
50045
|
|
|
50045
50046
|
extendMaterialParams( materialIndex, materialParams ) {
|
|
50046
50047
|
|
|
50047
|
-
const
|
|
50048
|
-
const materialDef = parser.json.materials[ materialIndex ];
|
|
50048
|
+
const extension = getMaterialExtension( this.parser, materialIndex, this.name );
|
|
50049
50049
|
|
|
50050
|
-
if (
|
|
50051
|
-
|
|
50052
|
-
return Promise.resolve();
|
|
50053
|
-
|
|
50054
|
-
}
|
|
50055
|
-
|
|
50056
|
-
const extension = materialDef.extensions[ this.name ];
|
|
50050
|
+
if ( extension === null ) return Promise.resolve();
|
|
50057
50051
|
|
|
50058
50052
|
materialParams.dispersion = extension.dispersion !== undefined ? extension.dispersion : 0;
|
|
50059
50053
|
|
|
@@ -50081,30 +50075,20 @@ let GLTFMaterialsIridescenceExtension$1 = class GLTFMaterialsIridescenceExtensio
|
|
|
50081
50075
|
|
|
50082
50076
|
getMaterialType( materialIndex ) {
|
|
50083
50077
|
|
|
50084
|
-
const
|
|
50085
|
-
const materialDef = parser.json.materials[ materialIndex ];
|
|
50078
|
+
const extension = getMaterialExtension( this.parser, materialIndex, this.name );
|
|
50086
50079
|
|
|
50087
|
-
|
|
50088
|
-
|
|
50089
|
-
return MeshPhysicalMaterial;
|
|
50080
|
+
return extension !== null ? MeshPhysicalMaterial : null;
|
|
50090
50081
|
|
|
50091
50082
|
}
|
|
50092
50083
|
|
|
50093
50084
|
extendMaterialParams( materialIndex, materialParams ) {
|
|
50094
50085
|
|
|
50095
|
-
const
|
|
50096
|
-
const materialDef = parser.json.materials[ materialIndex ];
|
|
50097
|
-
|
|
50098
|
-
if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {
|
|
50099
|
-
|
|
50100
|
-
return Promise.resolve();
|
|
50086
|
+
const extension = getMaterialExtension( this.parser, materialIndex, this.name );
|
|
50101
50087
|
|
|
50102
|
-
|
|
50088
|
+
if ( extension === null ) return Promise.resolve();
|
|
50103
50089
|
|
|
50104
50090
|
const pending = [];
|
|
50105
50091
|
|
|
50106
|
-
const extension = materialDef.extensions[ this.name ];
|
|
50107
|
-
|
|
50108
50092
|
if ( extension.iridescenceFactor !== undefined ) {
|
|
50109
50093
|
|
|
50110
50094
|
materialParams.iridescence = extension.iridescenceFactor;
|
|
@@ -50113,7 +50097,7 @@ let GLTFMaterialsIridescenceExtension$1 = class GLTFMaterialsIridescenceExtensio
|
|
|
50113
50097
|
|
|
50114
50098
|
if ( extension.iridescenceTexture !== undefined ) {
|
|
50115
50099
|
|
|
50116
|
-
pending.push( parser.assignTexture( materialParams, 'iridescenceMap', extension.iridescenceTexture ) );
|
|
50100
|
+
pending.push( this.parser.assignTexture( materialParams, 'iridescenceMap', extension.iridescenceTexture ) );
|
|
50117
50101
|
|
|
50118
50102
|
}
|
|
50119
50103
|
|
|
@@ -50143,7 +50127,7 @@ let GLTFMaterialsIridescenceExtension$1 = class GLTFMaterialsIridescenceExtensio
|
|
|
50143
50127
|
|
|
50144
50128
|
if ( extension.iridescenceThicknessTexture !== undefined ) {
|
|
50145
50129
|
|
|
50146
|
-
pending.push( parser.assignTexture( materialParams, 'iridescenceThicknessMap', extension.iridescenceThicknessTexture ) );
|
|
50130
|
+
pending.push( this.parser.assignTexture( materialParams, 'iridescenceThicknessMap', extension.iridescenceThicknessTexture ) );
|
|
50147
50131
|
|
|
50148
50132
|
}
|
|
50149
50133
|
|
|
@@ -50171,25 +50155,17 @@ let GLTFMaterialsSheenExtension$1 = class GLTFMaterialsSheenExtension {
|
|
|
50171
50155
|
|
|
50172
50156
|
getMaterialType( materialIndex ) {
|
|
50173
50157
|
|
|
50174
|
-
const
|
|
50175
|
-
const materialDef = parser.json.materials[ materialIndex ];
|
|
50176
|
-
|
|
50177
|
-
if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) return null;
|
|
50158
|
+
const extension = getMaterialExtension( this.parser, materialIndex, this.name );
|
|
50178
50159
|
|
|
50179
|
-
return MeshPhysicalMaterial;
|
|
50160
|
+
return extension !== null ? MeshPhysicalMaterial : null;
|
|
50180
50161
|
|
|
50181
50162
|
}
|
|
50182
50163
|
|
|
50183
50164
|
extendMaterialParams( materialIndex, materialParams ) {
|
|
50184
50165
|
|
|
50185
|
-
const
|
|
50186
|
-
const materialDef = parser.json.materials[ materialIndex ];
|
|
50187
|
-
|
|
50188
|
-
if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {
|
|
50166
|
+
const extension = getMaterialExtension( this.parser, materialIndex, this.name );
|
|
50189
50167
|
|
|
50190
|
-
|
|
50191
|
-
|
|
50192
|
-
}
|
|
50168
|
+
if ( extension === null ) return Promise.resolve();
|
|
50193
50169
|
|
|
50194
50170
|
const pending = [];
|
|
50195
50171
|
|
|
@@ -50197,8 +50173,6 @@ let GLTFMaterialsSheenExtension$1 = class GLTFMaterialsSheenExtension {
|
|
|
50197
50173
|
materialParams.sheenRoughness = 0;
|
|
50198
50174
|
materialParams.sheen = 1;
|
|
50199
50175
|
|
|
50200
|
-
const extension = materialDef.extensions[ this.name ];
|
|
50201
|
-
|
|
50202
50176
|
if ( extension.sheenColorFactor !== undefined ) {
|
|
50203
50177
|
|
|
50204
50178
|
const colorFactor = extension.sheenColorFactor;
|
|
@@ -50214,13 +50188,13 @@ let GLTFMaterialsSheenExtension$1 = class GLTFMaterialsSheenExtension {
|
|
|
50214
50188
|
|
|
50215
50189
|
if ( extension.sheenColorTexture !== undefined ) {
|
|
50216
50190
|
|
|
50217
|
-
pending.push( parser.assignTexture( materialParams, 'sheenColorMap', extension.sheenColorTexture, SRGBColorSpace ) );
|
|
50191
|
+
pending.push( this.parser.assignTexture( materialParams, 'sheenColorMap', extension.sheenColorTexture, SRGBColorSpace ) );
|
|
50218
50192
|
|
|
50219
50193
|
}
|
|
50220
50194
|
|
|
50221
50195
|
if ( extension.sheenRoughnessTexture !== undefined ) {
|
|
50222
50196
|
|
|
50223
|
-
pending.push( parser.assignTexture( materialParams, 'sheenRoughnessMap', extension.sheenRoughnessTexture ) );
|
|
50197
|
+
pending.push( this.parser.assignTexture( materialParams, 'sheenRoughnessMap', extension.sheenRoughnessTexture ) );
|
|
50224
50198
|
|
|
50225
50199
|
}
|
|
50226
50200
|
|
|
@@ -50249,30 +50223,20 @@ let GLTFMaterialsTransmissionExtension$1 = class GLTFMaterialsTransmissionExtens
|
|
|
50249
50223
|
|
|
50250
50224
|
getMaterialType( materialIndex ) {
|
|
50251
50225
|
|
|
50252
|
-
const
|
|
50253
|
-
const materialDef = parser.json.materials[ materialIndex ];
|
|
50254
|
-
|
|
50255
|
-
if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) return null;
|
|
50226
|
+
const extension = getMaterialExtension( this.parser, materialIndex, this.name );
|
|
50256
50227
|
|
|
50257
|
-
return MeshPhysicalMaterial;
|
|
50228
|
+
return extension !== null ? MeshPhysicalMaterial : null;
|
|
50258
50229
|
|
|
50259
50230
|
}
|
|
50260
50231
|
|
|
50261
50232
|
extendMaterialParams( materialIndex, materialParams ) {
|
|
50262
50233
|
|
|
50263
|
-
const
|
|
50264
|
-
const materialDef = parser.json.materials[ materialIndex ];
|
|
50265
|
-
|
|
50266
|
-
if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {
|
|
50234
|
+
const extension = getMaterialExtension( this.parser, materialIndex, this.name );
|
|
50267
50235
|
|
|
50268
|
-
|
|
50269
|
-
|
|
50270
|
-
}
|
|
50236
|
+
if ( extension === null ) return Promise.resolve();
|
|
50271
50237
|
|
|
50272
50238
|
const pending = [];
|
|
50273
50239
|
|
|
50274
|
-
const extension = materialDef.extensions[ this.name ];
|
|
50275
|
-
|
|
50276
50240
|
if ( extension.transmissionFactor !== undefined ) {
|
|
50277
50241
|
|
|
50278
50242
|
materialParams.transmission = extension.transmissionFactor;
|
|
@@ -50281,7 +50245,7 @@ let GLTFMaterialsTransmissionExtension$1 = class GLTFMaterialsTransmissionExtens
|
|
|
50281
50245
|
|
|
50282
50246
|
if ( extension.transmissionTexture !== undefined ) {
|
|
50283
50247
|
|
|
50284
|
-
pending.push( parser.assignTexture( materialParams, 'transmissionMap', extension.transmissionTexture ) );
|
|
50248
|
+
pending.push( this.parser.assignTexture( materialParams, 'transmissionMap', extension.transmissionTexture ) );
|
|
50285
50249
|
|
|
50286
50250
|
}
|
|
50287
50251
|
|
|
@@ -50309,35 +50273,25 @@ let GLTFMaterialsVolumeExtension$1 = class GLTFMaterialsVolumeExtension {
|
|
|
50309
50273
|
|
|
50310
50274
|
getMaterialType( materialIndex ) {
|
|
50311
50275
|
|
|
50312
|
-
const
|
|
50313
|
-
const materialDef = parser.json.materials[ materialIndex ];
|
|
50314
|
-
|
|
50315
|
-
if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) return null;
|
|
50276
|
+
const extension = getMaterialExtension( this.parser, materialIndex, this.name );
|
|
50316
50277
|
|
|
50317
|
-
return MeshPhysicalMaterial;
|
|
50278
|
+
return extension !== null ? MeshPhysicalMaterial : null;
|
|
50318
50279
|
|
|
50319
50280
|
}
|
|
50320
50281
|
|
|
50321
50282
|
extendMaterialParams( materialIndex, materialParams ) {
|
|
50322
50283
|
|
|
50323
|
-
const
|
|
50324
|
-
const materialDef = parser.json.materials[ materialIndex ];
|
|
50325
|
-
|
|
50326
|
-
if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {
|
|
50284
|
+
const extension = getMaterialExtension( this.parser, materialIndex, this.name );
|
|
50327
50285
|
|
|
50328
|
-
|
|
50329
|
-
|
|
50330
|
-
}
|
|
50286
|
+
if ( extension === null ) return Promise.resolve();
|
|
50331
50287
|
|
|
50332
50288
|
const pending = [];
|
|
50333
50289
|
|
|
50334
|
-
const extension = materialDef.extensions[ this.name ];
|
|
50335
|
-
|
|
50336
50290
|
materialParams.thickness = extension.thicknessFactor !== undefined ? extension.thicknessFactor : 0;
|
|
50337
50291
|
|
|
50338
50292
|
if ( extension.thicknessTexture !== undefined ) {
|
|
50339
50293
|
|
|
50340
|
-
pending.push( parser.assignTexture( materialParams, 'thicknessMap', extension.thicknessTexture ) );
|
|
50294
|
+
pending.push( this.parser.assignTexture( materialParams, 'thicknessMap', extension.thicknessTexture ) );
|
|
50341
50295
|
|
|
50342
50296
|
}
|
|
50343
50297
|
|
|
@@ -50370,30 +50324,22 @@ let GLTFMaterialsIorExtension$1 = class GLTFMaterialsIorExtension {
|
|
|
50370
50324
|
|
|
50371
50325
|
getMaterialType( materialIndex ) {
|
|
50372
50326
|
|
|
50373
|
-
const
|
|
50374
|
-
const materialDef = parser.json.materials[ materialIndex ];
|
|
50375
|
-
|
|
50376
|
-
if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) return null;
|
|
50327
|
+
const extension = getMaterialExtension( this.parser, materialIndex, this.name );
|
|
50377
50328
|
|
|
50378
|
-
return MeshPhysicalMaterial;
|
|
50329
|
+
return extension !== null ? MeshPhysicalMaterial : null;
|
|
50379
50330
|
|
|
50380
50331
|
}
|
|
50381
50332
|
|
|
50382
50333
|
extendMaterialParams( materialIndex, materialParams ) {
|
|
50383
50334
|
|
|
50384
|
-
const
|
|
50385
|
-
const materialDef = parser.json.materials[ materialIndex ];
|
|
50386
|
-
|
|
50387
|
-
if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {
|
|
50388
|
-
|
|
50389
|
-
return Promise.resolve();
|
|
50335
|
+
const extension = getMaterialExtension( this.parser, materialIndex, this.name );
|
|
50390
50336
|
|
|
50391
|
-
|
|
50392
|
-
|
|
50393
|
-
const extension = materialDef.extensions[ this.name ];
|
|
50337
|
+
if ( extension === null ) return Promise.resolve();
|
|
50394
50338
|
|
|
50395
50339
|
materialParams.ior = extension.ior !== undefined ? extension.ior : 1.5;
|
|
50396
50340
|
|
|
50341
|
+
if ( materialParams.ior === 0 ) materialParams.ior = 1000; // see #26167
|
|
50342
|
+
|
|
50397
50343
|
return Promise.resolve();
|
|
50398
50344
|
|
|
50399
50345
|
}
|
|
@@ -50418,35 +50364,25 @@ let GLTFMaterialsSpecularExtension$1 = class GLTFMaterialsSpecularExtension {
|
|
|
50418
50364
|
|
|
50419
50365
|
getMaterialType( materialIndex ) {
|
|
50420
50366
|
|
|
50421
|
-
const
|
|
50422
|
-
const materialDef = parser.json.materials[ materialIndex ];
|
|
50423
|
-
|
|
50424
|
-
if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) return null;
|
|
50367
|
+
const extension = getMaterialExtension( this.parser, materialIndex, this.name );
|
|
50425
50368
|
|
|
50426
|
-
return MeshPhysicalMaterial;
|
|
50369
|
+
return extension !== null ? MeshPhysicalMaterial : null;
|
|
50427
50370
|
|
|
50428
50371
|
}
|
|
50429
50372
|
|
|
50430
50373
|
extendMaterialParams( materialIndex, materialParams ) {
|
|
50431
50374
|
|
|
50432
|
-
const
|
|
50433
|
-
const materialDef = parser.json.materials[ materialIndex ];
|
|
50434
|
-
|
|
50435
|
-
if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {
|
|
50436
|
-
|
|
50437
|
-
return Promise.resolve();
|
|
50375
|
+
const extension = getMaterialExtension( this.parser, materialIndex, this.name );
|
|
50438
50376
|
|
|
50439
|
-
|
|
50377
|
+
if ( extension === null ) return Promise.resolve();
|
|
50440
50378
|
|
|
50441
50379
|
const pending = [];
|
|
50442
50380
|
|
|
50443
|
-
const extension = materialDef.extensions[ this.name ];
|
|
50444
|
-
|
|
50445
50381
|
materialParams.specularIntensity = extension.specularFactor !== undefined ? extension.specularFactor : 1.0;
|
|
50446
50382
|
|
|
50447
50383
|
if ( extension.specularTexture !== undefined ) {
|
|
50448
50384
|
|
|
50449
|
-
pending.push( parser.assignTexture( materialParams, 'specularIntensityMap', extension.specularTexture ) );
|
|
50385
|
+
pending.push( this.parser.assignTexture( materialParams, 'specularIntensityMap', extension.specularTexture ) );
|
|
50450
50386
|
|
|
50451
50387
|
}
|
|
50452
50388
|
|
|
@@ -50455,7 +50391,7 @@ let GLTFMaterialsSpecularExtension$1 = class GLTFMaterialsSpecularExtension {
|
|
|
50455
50391
|
|
|
50456
50392
|
if ( extension.specularColorTexture !== undefined ) {
|
|
50457
50393
|
|
|
50458
|
-
pending.push( parser.assignTexture( materialParams, 'specularColorMap', extension.specularColorTexture, SRGBColorSpace ) );
|
|
50394
|
+
pending.push( this.parser.assignTexture( materialParams, 'specularColorMap', extension.specularColorTexture, SRGBColorSpace ) );
|
|
50459
50395
|
|
|
50460
50396
|
}
|
|
50461
50397
|
|
|
@@ -50484,35 +50420,25 @@ let GLTFMaterialsBumpExtension$1 = class GLTFMaterialsBumpExtension {
|
|
|
50484
50420
|
|
|
50485
50421
|
getMaterialType( materialIndex ) {
|
|
50486
50422
|
|
|
50487
|
-
const
|
|
50488
|
-
const materialDef = parser.json.materials[ materialIndex ];
|
|
50423
|
+
const extension = getMaterialExtension( this.parser, materialIndex, this.name );
|
|
50489
50424
|
|
|
50490
|
-
|
|
50491
|
-
|
|
50492
|
-
return MeshPhysicalMaterial;
|
|
50425
|
+
return extension !== null ? MeshPhysicalMaterial : null;
|
|
50493
50426
|
|
|
50494
50427
|
}
|
|
50495
50428
|
|
|
50496
50429
|
extendMaterialParams( materialIndex, materialParams ) {
|
|
50497
50430
|
|
|
50498
|
-
const
|
|
50499
|
-
const materialDef = parser.json.materials[ materialIndex ];
|
|
50500
|
-
|
|
50501
|
-
if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {
|
|
50431
|
+
const extension = getMaterialExtension( this.parser, materialIndex, this.name );
|
|
50502
50432
|
|
|
50503
|
-
|
|
50504
|
-
|
|
50505
|
-
}
|
|
50433
|
+
if ( extension === null ) return Promise.resolve();
|
|
50506
50434
|
|
|
50507
50435
|
const pending = [];
|
|
50508
50436
|
|
|
50509
|
-
const extension = materialDef.extensions[ this.name ];
|
|
50510
|
-
|
|
50511
50437
|
materialParams.bumpScale = extension.bumpFactor !== undefined ? extension.bumpFactor : 1.0;
|
|
50512
50438
|
|
|
50513
50439
|
if ( extension.bumpTexture !== undefined ) {
|
|
50514
50440
|
|
|
50515
|
-
pending.push( parser.assignTexture( materialParams, 'bumpMap', extension.bumpTexture ) );
|
|
50441
|
+
pending.push( this.parser.assignTexture( materialParams, 'bumpMap', extension.bumpTexture ) );
|
|
50516
50442
|
|
|
50517
50443
|
}
|
|
50518
50444
|
|
|
@@ -50540,30 +50466,20 @@ let GLTFMaterialsAnisotropyExtension$1 = class GLTFMaterialsAnisotropyExtension
|
|
|
50540
50466
|
|
|
50541
50467
|
getMaterialType( materialIndex ) {
|
|
50542
50468
|
|
|
50543
|
-
const
|
|
50544
|
-
const materialDef = parser.json.materials[ materialIndex ];
|
|
50545
|
-
|
|
50546
|
-
if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) return null;
|
|
50469
|
+
const extension = getMaterialExtension( this.parser, materialIndex, this.name );
|
|
50547
50470
|
|
|
50548
|
-
return MeshPhysicalMaterial;
|
|
50471
|
+
return extension !== null ? MeshPhysicalMaterial : null;
|
|
50549
50472
|
|
|
50550
50473
|
}
|
|
50551
50474
|
|
|
50552
50475
|
extendMaterialParams( materialIndex, materialParams ) {
|
|
50553
50476
|
|
|
50554
|
-
const
|
|
50555
|
-
const materialDef = parser.json.materials[ materialIndex ];
|
|
50556
|
-
|
|
50557
|
-
if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {
|
|
50477
|
+
const extension = getMaterialExtension( this.parser, materialIndex, this.name );
|
|
50558
50478
|
|
|
50559
|
-
|
|
50560
|
-
|
|
50561
|
-
}
|
|
50479
|
+
if ( extension === null ) return Promise.resolve();
|
|
50562
50480
|
|
|
50563
50481
|
const pending = [];
|
|
50564
50482
|
|
|
50565
|
-
const extension = materialDef.extensions[ this.name ];
|
|
50566
|
-
|
|
50567
50483
|
if ( extension.anisotropyStrength !== undefined ) {
|
|
50568
50484
|
|
|
50569
50485
|
materialParams.anisotropy = extension.anisotropyStrength;
|
|
@@ -50578,7 +50494,7 @@ let GLTFMaterialsAnisotropyExtension$1 = class GLTFMaterialsAnisotropyExtension
|
|
|
50578
50494
|
|
|
50579
50495
|
if ( extension.anisotropyTexture !== undefined ) {
|
|
50580
50496
|
|
|
50581
|
-
pending.push( parser.assignTexture( materialParams, 'anisotropyMap', extension.anisotropyTexture ) );
|
|
50497
|
+
pending.push( this.parser.assignTexture( materialParams, 'anisotropyMap', extension.anisotropyTexture ) );
|
|
50582
50498
|
|
|
50583
50499
|
}
|
|
50584
50500
|
|
|
@@ -50744,9 +50660,9 @@ class GLTFTextureAVIFExtension {
|
|
|
50744
50660
|
*/
|
|
50745
50661
|
class GLTFMeshoptCompression {
|
|
50746
50662
|
|
|
50747
|
-
constructor( parser ) {
|
|
50663
|
+
constructor( parser, name ) {
|
|
50748
50664
|
|
|
50749
|
-
this.name =
|
|
50665
|
+
this.name = name;
|
|
50750
50666
|
this.parser = parser;
|
|
50751
50667
|
|
|
50752
50668
|
}
|
|
@@ -51720,7 +51636,7 @@ class GLTFParser {
|
|
|
51720
51636
|
let isFirefox = false;
|
|
51721
51637
|
let firefoxVersion = -1;
|
|
51722
51638
|
|
|
51723
|
-
if ( typeof navigator !== 'undefined' ) {
|
|
51639
|
+
if ( typeof navigator !== 'undefined' && typeof navigator.userAgent !== 'undefined' ) {
|
|
51724
51640
|
|
|
51725
51641
|
const userAgent = navigator.userAgent;
|
|
51726
51642
|
|
|
@@ -53377,6 +53293,28 @@ class GLTFParser {
|
|
|
53377
53293
|
|
|
53378
53294
|
}
|
|
53379
53295
|
|
|
53296
|
+
// Reconstruct pivot from container pattern created by GLTFExporter
|
|
53297
|
+
// The container has position+pivot, rotation, scale; child has -pivot offset and mesh
|
|
53298
|
+
if ( node.userData.pivot !== undefined && children.length > 0 ) {
|
|
53299
|
+
|
|
53300
|
+
const pivot = node.userData.pivot;
|
|
53301
|
+
const pivotChild = children[ 0 ];
|
|
53302
|
+
|
|
53303
|
+
// Set pivot on container and adjust transforms
|
|
53304
|
+
node.pivot = new Vector3().fromArray( pivot );
|
|
53305
|
+
|
|
53306
|
+
// Adjust container position: stored as position + pivot, so subtract pivot
|
|
53307
|
+
node.position.x -= pivot[ 0 ];
|
|
53308
|
+
node.position.y -= pivot[ 1 ];
|
|
53309
|
+
node.position.z -= pivot[ 2 ];
|
|
53310
|
+
|
|
53311
|
+
// Remove the child's -pivot offset since pivot now handles it
|
|
53312
|
+
pivotChild.position.set( 0, 0, 0 );
|
|
53313
|
+
|
|
53314
|
+
delete node.userData.pivot;
|
|
53315
|
+
|
|
53316
|
+
}
|
|
53317
|
+
|
|
53380
53318
|
return node;
|
|
53381
53319
|
|
|
53382
53320
|
} );
|
|
@@ -53568,7 +53506,20 @@ class GLTFParser {
|
|
|
53568
53506
|
|
|
53569
53507
|
for ( let i = 0, il = nodes.length; i < il; i ++ ) {
|
|
53570
53508
|
|
|
53571
|
-
|
|
53509
|
+
const node = nodes[ i ];
|
|
53510
|
+
|
|
53511
|
+
// If the node already has a parent, it means it's being reused across multiple scenes.
|
|
53512
|
+
// Clone it to avoid the second scene's add() removing it from the first scene.
|
|
53513
|
+
// See: https://github.com/mrdoob/three.js/issues/27993
|
|
53514
|
+
if ( node.parent !== null ) {
|
|
53515
|
+
|
|
53516
|
+
scene.add( clone( node ) );
|
|
53517
|
+
|
|
53518
|
+
} else {
|
|
53519
|
+
|
|
53520
|
+
scene.add( node );
|
|
53521
|
+
|
|
53522
|
+
}
|
|
53572
53523
|
|
|
53573
53524
|
}
|
|
53574
53525
|
|
|
@@ -53619,17 +53570,28 @@ class GLTFParser {
|
|
|
53619
53570
|
const targetName = node.name ? node.name : node.uuid;
|
|
53620
53571
|
const targetNames = [];
|
|
53621
53572
|
|
|
53573
|
+
function collectMorphTargets( object ) {
|
|
53574
|
+
|
|
53575
|
+
if ( object.morphTargetInfluences ) {
|
|
53576
|
+
|
|
53577
|
+
targetNames.push( object.name ? object.name : object.uuid );
|
|
53578
|
+
|
|
53579
|
+
}
|
|
53580
|
+
|
|
53581
|
+
}
|
|
53582
|
+
|
|
53583
|
+
|
|
53622
53584
|
if ( PATH_PROPERTIES$1[ target.path ] === PATH_PROPERTIES$1.weights ) {
|
|
53623
53585
|
|
|
53624
|
-
|
|
53586
|
+
collectMorphTargets( node );
|
|
53625
53587
|
|
|
53626
|
-
|
|
53588
|
+
// for multi-primitive meshes, the node is a Group containing the sub-meshes
|
|
53627
53589
|
|
|
53628
|
-
|
|
53590
|
+
if ( node.isGroup ) {
|
|
53629
53591
|
|
|
53630
|
-
|
|
53592
|
+
node.children.forEach( collectMorphTargets );
|
|
53631
53593
|
|
|
53632
|
-
}
|
|
53594
|
+
}
|
|
53633
53595
|
|
|
53634
53596
|
} else {
|
|
53635
53597
|
|
|
@@ -57157,7 +57119,8 @@ class FBXTreeParser {
|
|
|
57157
57119
|
|
|
57158
57120
|
}
|
|
57159
57121
|
|
|
57160
|
-
// the transparency handling is implemented based on Blender
|
|
57122
|
+
// the transparency handling is implemented based on Blender's approach:
|
|
57123
|
+
// https://github.com/blender/blender/blob/main/scripts/addons_core/io_scene_fbx/import_fbx.py
|
|
57161
57124
|
|
|
57162
57125
|
parameters.opacity = 1 - ( materialNode.TransparencyFactor ? parseFloat( materialNode.TransparencyFactor.value ) : 0 );
|
|
57163
57126
|
|
|
@@ -57167,7 +57130,10 @@ class FBXTreeParser {
|
|
|
57167
57130
|
|
|
57168
57131
|
if ( parameters.opacity === null ) {
|
|
57169
57132
|
|
|
57170
|
-
|
|
57133
|
+
// Default to opaque. Some exporters (e.g. 3ds Max) define TransparentColor
|
|
57134
|
+
// as white (1,1,1) without intending transparency, which makes the Unity-style
|
|
57135
|
+
// fallback of `1 - TransparentColor.r` produce incorrect zero opacity.
|
|
57136
|
+
parameters.opacity = 1;
|
|
57171
57137
|
|
|
57172
57138
|
}
|
|
57173
57139
|
|
|
@@ -57380,8 +57346,6 @@ class FBXTreeParser {
|
|
|
57380
57346
|
indices: [],
|
|
57381
57347
|
weights: [],
|
|
57382
57348
|
transformLink: new Matrix4().fromArray( boneNode.TransformLink.a ),
|
|
57383
|
-
// transform: new Matrix4().fromArray( boneNode.Transform.a ),
|
|
57384
|
-
// linkMode: boneNode.Mode,
|
|
57385
57349
|
|
|
57386
57350
|
};
|
|
57387
57351
|
|
|
@@ -57474,8 +57438,6 @@ class FBXTreeParser {
|
|
|
57474
57438
|
|
|
57475
57439
|
} );
|
|
57476
57440
|
|
|
57477
|
-
this.bindSkeleton( deformers.skeletons, geometryMap, modelMap );
|
|
57478
|
-
|
|
57479
57441
|
this.addGlobalSceneSettings();
|
|
57480
57442
|
|
|
57481
57443
|
sceneGraph.traverse( function ( node ) {
|
|
@@ -57498,6 +57460,64 @@ class FBXTreeParser {
|
|
|
57498
57460
|
|
|
57499
57461
|
} );
|
|
57500
57462
|
|
|
57463
|
+
// Like Blender's FBX importer, use the BindPose section to set the
|
|
57464
|
+
// rest pose for bones that are not part of a skin cluster. The BindPose
|
|
57465
|
+
// provides a more authoritative rest pose than the Lcl properties which
|
|
57466
|
+
// may represent an animation frame rather than the true rest state.
|
|
57467
|
+
// Bones WITH clusters will get their bind pose from TransformLink
|
|
57468
|
+
// (set via bindSkeleton below), which takes priority.
|
|
57469
|
+
const bindPoseMatrices = this.parsePoseNodes();
|
|
57470
|
+
const clusterBoneIDs = new Set();
|
|
57471
|
+
|
|
57472
|
+
for ( const ID in deformers.skeletons ) {
|
|
57473
|
+
|
|
57474
|
+
deformers.skeletons[ ID ].rawBones.forEach( function ( _, i ) {
|
|
57475
|
+
|
|
57476
|
+
const bone = deformers.skeletons[ ID ].bones[ i ];
|
|
57477
|
+
if ( bone ) clusterBoneIDs.add( bone.ID );
|
|
57478
|
+
|
|
57479
|
+
} );
|
|
57480
|
+
|
|
57481
|
+
}
|
|
57482
|
+
|
|
57483
|
+
const tempMatrix = new Matrix4();
|
|
57484
|
+
|
|
57485
|
+
sceneGraph.traverse( function ( node ) {
|
|
57486
|
+
|
|
57487
|
+
if ( node.isBone && node.ID !== undefined && ! clusterBoneIDs.has( node.ID ) ) {
|
|
57488
|
+
|
|
57489
|
+
const bindPose = bindPoseMatrices[ node.ID ];
|
|
57490
|
+
|
|
57491
|
+
if ( bindPose !== undefined ) {
|
|
57492
|
+
|
|
57493
|
+
if ( node.parent ) {
|
|
57494
|
+
|
|
57495
|
+
tempMatrix.copy( node.parent.matrixWorld ).invert();
|
|
57496
|
+
tempMatrix.multiply( bindPose );
|
|
57497
|
+
|
|
57498
|
+
} else {
|
|
57499
|
+
|
|
57500
|
+
tempMatrix.copy( bindPose );
|
|
57501
|
+
|
|
57502
|
+
}
|
|
57503
|
+
|
|
57504
|
+
tempMatrix.decompose( node.position, node.quaternion, node.scale );
|
|
57505
|
+
node.updateMatrix();
|
|
57506
|
+
node.matrixWorld.copy( bindPose );
|
|
57507
|
+
|
|
57508
|
+
}
|
|
57509
|
+
|
|
57510
|
+
}
|
|
57511
|
+
|
|
57512
|
+
} );
|
|
57513
|
+
|
|
57514
|
+
// Bind skeletons after transforms are applied so that bind matrices
|
|
57515
|
+
// are computed from the final scene state. This ensures the rest pose
|
|
57516
|
+
// is correct even when the FBX file's Cluster TransformLink matrices
|
|
57517
|
+
// differ from the reconstructed bone transforms (common in files
|
|
57518
|
+
// without a BindPose section).
|
|
57519
|
+
this.bindSkeleton( deformers.skeletons, geometryMap, modelMap );
|
|
57520
|
+
|
|
57501
57521
|
const animations = new AnimationParser().parse();
|
|
57502
57522
|
|
|
57503
57523
|
// if all the models where already combined in a single group, just return that
|
|
@@ -57510,6 +57530,24 @@ class FBXTreeParser {
|
|
|
57510
57530
|
|
|
57511
57531
|
sceneGraph.animations = animations;
|
|
57512
57532
|
|
|
57533
|
+
// Apply coordinate system correction. FBX files can use different
|
|
57534
|
+
// up-axis conventions (Y-up or Z-up). Three.js uses Y-up, so rotate
|
|
57535
|
+
// the scene when the file uses Z-up (UpAxis === 2).
|
|
57536
|
+
|
|
57537
|
+
if ( 'GlobalSettings' in fbxTree && 'UpAxis' in fbxTree.GlobalSettings ) {
|
|
57538
|
+
|
|
57539
|
+
const upAxis = fbxTree.GlobalSettings.UpAxis.value;
|
|
57540
|
+
|
|
57541
|
+
if ( upAxis === 2 ) {
|
|
57542
|
+
|
|
57543
|
+
console.warn( 'THREE.FBXLoader: You are loading an asset with a Z-UP coordinate system. The loader just rotates the asset to transform it into Y-UP. The vertex data are not converted.' );
|
|
57544
|
+
|
|
57545
|
+
sceneGraph.rotation.set( - Math.PI / 2, 0, 0 );
|
|
57546
|
+
|
|
57547
|
+
}
|
|
57548
|
+
|
|
57549
|
+
}
|
|
57550
|
+
|
|
57513
57551
|
}
|
|
57514
57552
|
|
|
57515
57553
|
// parse nodes in FBXTree.Objects.Model
|
|
@@ -57792,21 +57830,24 @@ class FBXTreeParser {
|
|
|
57792
57830
|
|
|
57793
57831
|
case 2: // Spot
|
|
57794
57832
|
let angle = Math.PI / 3;
|
|
57833
|
+
let penumbra = 0;
|
|
57795
57834
|
|
|
57796
|
-
if ( lightAttribute.
|
|
57835
|
+
if ( lightAttribute.OuterAngle !== undefined ) {
|
|
57797
57836
|
|
|
57798
|
-
angle = MathUtils.degToRad( lightAttribute.
|
|
57837
|
+
angle = MathUtils.degToRad( lightAttribute.OuterAngle.value );
|
|
57799
57838
|
|
|
57800
|
-
|
|
57839
|
+
if ( lightAttribute.InnerAngle !== undefined ) {
|
|
57801
57840
|
|
|
57802
|
-
|
|
57803
|
-
|
|
57841
|
+
penumbra = 1 - ( lightAttribute.InnerAngle.value / lightAttribute.OuterAngle.value );
|
|
57842
|
+
penumbra = Math.max( 0, penumbra ); // penumbra must be in the range [0,1]
|
|
57843
|
+
|
|
57844
|
+
}
|
|
57845
|
+
|
|
57846
|
+
} else if ( lightAttribute.InnerAngle !== undefined ) {
|
|
57804
57847
|
|
|
57805
|
-
//
|
|
57806
|
-
|
|
57807
|
-
|
|
57808
|
-
penumbra = MathUtils.degToRad( lightAttribute.OuterAngle.value );
|
|
57809
|
-
penumbra = Math.max( penumbra, 1 );
|
|
57848
|
+
// fallback if only InnerAngle is defined
|
|
57849
|
+
|
|
57850
|
+
angle = MathUtils.degToRad( lightAttribute.InnerAngle.value );
|
|
57810
57851
|
|
|
57811
57852
|
}
|
|
57812
57853
|
|
|
@@ -58016,12 +58057,30 @@ class FBXTreeParser {
|
|
|
58016
58057
|
|
|
58017
58058
|
bindSkeleton( skeletons, geometryMap, modelMap ) {
|
|
58018
58059
|
|
|
58019
|
-
const bindMatrices = this.parsePoseNodes();
|
|
58020
|
-
|
|
58021
58060
|
for ( const ID in skeletons ) {
|
|
58022
58061
|
|
|
58023
58062
|
const skeleton = skeletons[ ID ];
|
|
58024
58063
|
|
|
58064
|
+
// Compute bone inverses from TransformLink rather than from the
|
|
58065
|
+
// bones' current matrixWorld. The TransformLink matrices represent
|
|
58066
|
+
// each bone's global transform at the time the skin weights were
|
|
58067
|
+
// painted, which may differ from the scene-reconstructed transforms.
|
|
58068
|
+
const boneInverses = [];
|
|
58069
|
+
|
|
58070
|
+
for ( let i = 0, l = skeleton.bones.length; i < l; i ++ ) {
|
|
58071
|
+
|
|
58072
|
+
const inverse = new Matrix4();
|
|
58073
|
+
|
|
58074
|
+
if ( skeleton.bones[ i ] && skeleton.rawBones[ i ] ) {
|
|
58075
|
+
|
|
58076
|
+
inverse.copy( skeleton.rawBones[ i ].transformLink ).invert();
|
|
58077
|
+
|
|
58078
|
+
}
|
|
58079
|
+
|
|
58080
|
+
boneInverses.push( inverse );
|
|
58081
|
+
|
|
58082
|
+
}
|
|
58083
|
+
|
|
58025
58084
|
const parents = connections.get( parseInt( skeleton.ID ) ).parents;
|
|
58026
58085
|
|
|
58027
58086
|
parents.forEach( function ( parent ) {
|
|
@@ -58037,7 +58096,16 @@ class FBXTreeParser {
|
|
|
58037
58096
|
|
|
58038
58097
|
const model = modelMap.get( geoConnParent.ID );
|
|
58039
58098
|
|
|
58040
|
-
|
|
58099
|
+
// Use the mesh's current matrixWorld as bind matrix.
|
|
58100
|
+
// The BindPose section is intentionally not used here
|
|
58101
|
+
// since it may contain scale/rotation from the model
|
|
58102
|
+
// hierarchy that is inconsistent with the TransformLink-
|
|
58103
|
+
// based bone inverses. Always provide a bind matrix to
|
|
58104
|
+
// prevent bind() from calling calculateInverses() which
|
|
58105
|
+
// would overwrite the bone inverses computed above.
|
|
58106
|
+
model.updateMatrixWorld( true );
|
|
58107
|
+
|
|
58108
|
+
model.bind( new Skeleton( skeleton.bones, boneInverses ), model.matrixWorld );
|
|
58041
58109
|
|
|
58042
58110
|
}
|
|
58043
58111
|
|
|
@@ -58051,6 +58119,7 @@ class FBXTreeParser {
|
|
|
58051
58119
|
|
|
58052
58120
|
}
|
|
58053
58121
|
|
|
58122
|
+
// Parse BindPose nodes and return a map of node ID to bind matrix.
|
|
58054
58123
|
parsePoseNodes() {
|
|
58055
58124
|
|
|
58056
58125
|
const bindMatrices = {};
|
|
@@ -58813,6 +58882,13 @@ class GeometryParser {
|
|
|
58813
58882
|
parentGeo.morphAttributes.position = [];
|
|
58814
58883
|
// parentGeo.morphAttributes.normal = []; // not implemented
|
|
58815
58884
|
|
|
58885
|
+
// Morph attribute positions are stored as deltas (morphTargetsRelative = true), so the
|
|
58886
|
+
// translation component of the geometric transform must not be applied to them — only the
|
|
58887
|
+
// rotation/scale part. Otherwise every delta gets the geometric translation added, which
|
|
58888
|
+
// shifts morphed vertices away from their intended position by `weight * translation` as
|
|
58889
|
+
// the influence increases.
|
|
58890
|
+
const morphPreTransform = preTransform.clone().setPosition( 0, 0, 0 );
|
|
58891
|
+
|
|
58816
58892
|
const scope = this;
|
|
58817
58893
|
morphTargets.forEach( function ( morphTarget ) {
|
|
58818
58894
|
|
|
@@ -58822,7 +58898,7 @@ class GeometryParser {
|
|
|
58822
58898
|
|
|
58823
58899
|
if ( morphGeoNode !== undefined ) {
|
|
58824
58900
|
|
|
58825
|
-
scope.genMorphGeometry( parentGeo, parentGeoNode, morphGeoNode,
|
|
58901
|
+
scope.genMorphGeometry( parentGeo, parentGeoNode, morphGeoNode, morphPreTransform, rawTarget.name );
|
|
58826
58902
|
|
|
58827
58903
|
}
|
|
58828
58904
|
|
|
@@ -59217,11 +59293,15 @@ class AnimationParser {
|
|
|
59217
59293
|
|
|
59218
59294
|
if ( layerCurveNodes[ i ] === undefined ) {
|
|
59219
59295
|
|
|
59220
|
-
const
|
|
59296
|
+
const filteredParents = connections.get( child.ID ).parents.filter( function ( parent ) {
|
|
59221
59297
|
|
|
59222
59298
|
return parent.relationship !== undefined;
|
|
59223
59299
|
|
|
59224
|
-
} )
|
|
59300
|
+
} );
|
|
59301
|
+
|
|
59302
|
+
if ( filteredParents.length === 0 ) return;
|
|
59303
|
+
|
|
59304
|
+
const modelID = filteredParents[ 0 ].ID;
|
|
59225
59305
|
|
|
59226
59306
|
if ( modelID !== undefined ) {
|
|
59227
59307
|
|
|
@@ -59250,7 +59330,13 @@ class AnimationParser {
|
|
|
59250
59330
|
|
|
59251
59331
|
node.transform = child.matrix;
|
|
59252
59332
|
|
|
59253
|
-
if ( child.userData.transformData )
|
|
59333
|
+
if ( child.userData.transformData ) {
|
|
59334
|
+
|
|
59335
|
+
node.eulerOrder = child.userData.transformData.eulerOrder;
|
|
59336
|
+
|
|
59337
|
+
if ( child.userData.transformData.rotation ) node.initialRotation = child.userData.transformData.rotation;
|
|
59338
|
+
|
|
59339
|
+
}
|
|
59254
59340
|
|
|
59255
59341
|
}
|
|
59256
59342
|
|
|
@@ -59275,11 +59361,15 @@ class AnimationParser {
|
|
|
59275
59361
|
|
|
59276
59362
|
if ( layerCurveNodes[ i ] === undefined ) {
|
|
59277
59363
|
|
|
59278
|
-
const
|
|
59364
|
+
const filteredParents = connections.get( child.ID ).parents.filter( function ( parent ) {
|
|
59279
59365
|
|
|
59280
59366
|
return parent.relationship !== undefined;
|
|
59281
59367
|
|
|
59282
|
-
} )
|
|
59368
|
+
} );
|
|
59369
|
+
|
|
59370
|
+
if ( filteredParents.length === 0 ) return;
|
|
59371
|
+
|
|
59372
|
+
const deformerID = filteredParents[ 0 ].ID;
|
|
59283
59373
|
|
|
59284
59374
|
const morpherID = connections.get( deformerID ).parents[ 0 ].ID;
|
|
59285
59375
|
const geoID = connections.get( morpherID ).parents[ 0 ].ID;
|
|
@@ -59390,7 +59480,7 @@ class AnimationParser {
|
|
|
59390
59480
|
|
|
59391
59481
|
if ( rawTracks.R !== undefined && Object.keys( rawTracks.R.curves ).length > 0 ) {
|
|
59392
59482
|
|
|
59393
|
-
const rotationTrack = this.generateRotationTrack( rawTracks.modelName, rawTracks.R.curves, rawTracks.preRotation, rawTracks.postRotation, rawTracks.eulerOrder );
|
|
59483
|
+
const rotationTrack = this.generateRotationTrack( rawTracks.modelName, rawTracks.R.curves, rawTracks.preRotation, rawTracks.postRotation, rawTracks.eulerOrder, rawTracks.initialRotation );
|
|
59394
59484
|
if ( rotationTrack !== undefined ) tracks.push( rotationTrack );
|
|
59395
59485
|
|
|
59396
59486
|
}
|
|
@@ -59422,17 +59512,33 @@ class AnimationParser {
|
|
|
59422
59512
|
|
|
59423
59513
|
}
|
|
59424
59514
|
|
|
59425
|
-
generateRotationTrack( modelName, curves, preRotation, postRotation, eulerOrder ) {
|
|
59515
|
+
generateRotationTrack( modelName, curves, preRotation, postRotation, eulerOrder, initialRotation ) {
|
|
59426
59516
|
|
|
59427
59517
|
let times;
|
|
59428
59518
|
let values;
|
|
59429
59519
|
|
|
59430
|
-
if ( curves.x !== undefined
|
|
59520
|
+
if ( curves.x !== undefined || curves.y !== undefined || curves.z !== undefined ) {
|
|
59431
59521
|
|
|
59432
|
-
|
|
59522
|
+
// Get merged, sorted, unique times from all available curves
|
|
59523
|
+
const mergedTimes = this.getTimesForAllAxes( curves );
|
|
59433
59524
|
|
|
59434
|
-
|
|
59435
|
-
|
|
59525
|
+
if ( mergedTimes.length > 0 ) {
|
|
59526
|
+
|
|
59527
|
+
const initialRot = initialRotation || [ 0, 0, 0 ];
|
|
59528
|
+
|
|
59529
|
+
// Synchronize all curves to the merged time array.
|
|
59530
|
+
// Missing axes are filled with constant values from the initial rotation (Lcl Rotation).
|
|
59531
|
+
// Existing curves at different times are linearly interpolated.
|
|
59532
|
+
const syncX = this.synchronizeCurve( curves.x, mergedTimes, initialRot[ 0 ] );
|
|
59533
|
+
const syncY = this.synchronizeCurve( curves.y, mergedTimes, initialRot[ 1 ] );
|
|
59534
|
+
const syncZ = this.synchronizeCurve( curves.z, mergedTimes, initialRot[ 2 ] );
|
|
59535
|
+
|
|
59536
|
+
const result = this.interpolateRotations( syncX, syncY, syncZ, eulerOrder );
|
|
59537
|
+
|
|
59538
|
+
times = result[ 0 ];
|
|
59539
|
+
values = result[ 1 ];
|
|
59540
|
+
|
|
59541
|
+
}
|
|
59436
59542
|
|
|
59437
59543
|
}
|
|
59438
59544
|
|
|
@@ -59464,7 +59570,7 @@ class AnimationParser {
|
|
|
59464
59570
|
|
|
59465
59571
|
const quaternionValues = [];
|
|
59466
59572
|
|
|
59467
|
-
if ( ! values || ! times ) return
|
|
59573
|
+
if ( ! values || ! times ) return undefined;
|
|
59468
59574
|
|
|
59469
59575
|
for ( let i = 0; i < values.length; i += 3 ) {
|
|
59470
59576
|
|
|
@@ -59617,6 +59723,62 @@ class AnimationParser {
|
|
|
59617
59723
|
|
|
59618
59724
|
}
|
|
59619
59725
|
|
|
59726
|
+
// Synchronize a curve to a target time array using linear interpolation.
|
|
59727
|
+
// If the curve is undefined (axis not animated), returns constant values from initialValue.
|
|
59728
|
+
synchronizeCurve( curve, targetTimes, initialValue ) {
|
|
59729
|
+
|
|
59730
|
+
if ( curve === undefined ) {
|
|
59731
|
+
|
|
59732
|
+
return { times: targetTimes, values: targetTimes.map( () => initialValue ) };
|
|
59733
|
+
|
|
59734
|
+
}
|
|
59735
|
+
|
|
59736
|
+
// If the curve already has the same number of keyframes as the target, assume times match
|
|
59737
|
+
if ( curve.times.length === targetTimes.length ) return curve;
|
|
59738
|
+
|
|
59739
|
+
// Linearly interpolate curve values at each target time
|
|
59740
|
+
const values = [];
|
|
59741
|
+
|
|
59742
|
+
for ( let i = 0; i < targetTimes.length; i ++ ) {
|
|
59743
|
+
|
|
59744
|
+
values.push( this.sampleCurveValue( curve, targetTimes[ i ], initialValue ) );
|
|
59745
|
+
|
|
59746
|
+
}
|
|
59747
|
+
|
|
59748
|
+
return { times: targetTimes, values: values };
|
|
59749
|
+
|
|
59750
|
+
}
|
|
59751
|
+
|
|
59752
|
+
// Sample a single value from a curve at a given time using linear interpolation
|
|
59753
|
+
sampleCurveValue( curve, time, initialValue ) {
|
|
59754
|
+
|
|
59755
|
+
const times = curve.times;
|
|
59756
|
+
const values = curve.values;
|
|
59757
|
+
|
|
59758
|
+
// Before first keyframe
|
|
59759
|
+
if ( time <= times[ 0 ] ) return values[ 0 ];
|
|
59760
|
+
|
|
59761
|
+
// After last keyframe
|
|
59762
|
+
if ( time >= times[ times.length - 1 ] ) return values[ values.length - 1 ];
|
|
59763
|
+
|
|
59764
|
+
// Find surrounding keyframes and linearly interpolate
|
|
59765
|
+
for ( let i = 0; i < times.length - 1; i ++ ) {
|
|
59766
|
+
|
|
59767
|
+
if ( time >= times[ i ] && time <= times[ i + 1 ] ) {
|
|
59768
|
+
|
|
59769
|
+
if ( times[ i ] === time ) return values[ i ];
|
|
59770
|
+
|
|
59771
|
+
const alpha = ( time - times[ i ] ) / ( times[ i + 1 ] - times[ i ] );
|
|
59772
|
+
return values[ i ] * ( 1 - alpha ) + values[ i + 1 ] * alpha;
|
|
59773
|
+
|
|
59774
|
+
}
|
|
59775
|
+
|
|
59776
|
+
}
|
|
59777
|
+
|
|
59778
|
+
return initialValue;
|
|
59779
|
+
|
|
59780
|
+
}
|
|
59781
|
+
|
|
59620
59782
|
// Rotations are defined as Euler angles which can have values of any size
|
|
59621
59783
|
// These will be converted to quaternions which don't support values greater than
|
|
59622
59784
|
// PI, so we'll interpolate large rotations
|
|
@@ -59686,7 +59848,7 @@ class AnimationParser {
|
|
|
59686
59848
|
const Q2 = new Quaternion().setFromEuler( E2 );
|
|
59687
59849
|
|
|
59688
59850
|
// Check unroll
|
|
59689
|
-
if ( Q1.dot( Q2 ) ) {
|
|
59851
|
+
if ( Q1.dot( Q2 ) < 0 ) {
|
|
59690
59852
|
|
|
59691
59853
|
Q2.set( - Q2.x, - Q2.y, - Q2.z, - Q2.w );
|
|
59692
59854
|
|
|
@@ -61100,7 +61262,7 @@ class WorkerPool {
|
|
|
61100
61262
|
|
|
61101
61263
|
}
|
|
61102
61264
|
|
|
61103
|
-
const t=0,n=2,u=1,y=2,S=0,E=1,X=10,it=0,ht=9,gt=15,xt=16,dt=22,Ft=37,Et=43,te=76,ae=83,ue=97,ye=100,de=103,Ae=109,We=122,He=123,qe=131,Je=132,Qe=133,Ze=134,en=137,nn=138,sn=139,an=140,rn=141,on=142,cn=145,Un=146,pn=148,xn=152,yn=153,bn=154,mn=155,dn=156,Dn=157,wn=158,Vn=165,Cn=166,ri=1000054e3,oi=1000054001,ci=1000054004,Ui=1000054005,_i=1000066e3,yi=1000066004;class Ci{constructor(t,e,n,i){this._dataView=void 0,this._littleEndian=void 0,this._offset=void 0,this._dataView=new DataView(t.buffer,t.byteOffset+e,n),this._littleEndian=i,this._offset=0;}_nextUint8(){const t=this._dataView.getUint8(this._offset);return this._offset+=1,t}_nextUint16(){const t=this._dataView.getUint16(this._offset,this._littleEndian);return this._offset+=2,t}_nextUint32(){const t=this._dataView.getUint32(this._offset,this._littleEndian);return this._offset+=4,t}_nextUint64(){const t=this._dataView.getUint32(this._offset,this._littleEndian)+2**32*this._dataView.getUint32(this._offset+4,this._littleEndian);return this._offset+=8,t}_nextInt32(){const t=this._dataView.getInt32(this._offset,this._littleEndian);return this._offset+=4,t}_nextUint8Array(t){const e=new Uint8Array(this._dataView.buffer,this._dataView.byteOffset+this._offset,t);return this._offset+=t,e}_skip(t){return this._offset+=t,this}_scan(t,e=0){const n=this._offset;let i=0;for(;this._dataView.getUint8(this._offset)!==e&&i<t;)i++,this._offset++;return i<t&&this._offset++,new Uint8Array(this._dataView.buffer,this._dataView.byteOffset+n,i)}}const Oi=[171,75,84,88,32,50,48,187,13,10,26,10];function Si(t){return (new TextDecoder).decode(t)}function Mi(t){const e=new Uint8Array(t.buffer,t.byteOffset,Oi.length);if(e[0]!==Oi[0]||e[1]!==Oi[1]||e[2]!==Oi[2]||e[3]!==Oi[3]||e[4]!==Oi[4]||e[5]!==Oi[5]||e[6]!==Oi[6]||e[7]!==Oi[7]||e[8]!==Oi[8]||e[9]!==Oi[9]||e[10]!==Oi[10]||e[11]!==Oi[11])throw new Error("Missing KTX 2.0 identifier.");const n={vkFormat:0,typeSize:1,pixelWidth:0,pixelHeight:0,pixelDepth:0,layerCount:0,faceCount:1,levelCount:0,supercompressionScheme:0,levels:[],dataFormatDescriptor:[{vendorId:0,descriptorType:0,versionNumber:2,colorModel:0,colorPrimaries:1,transferFunction:2,flags:0,texelBlockDimension:[0,0,0,0],bytesPlane:[0,0,0,0,0,0,0,0],samples:[]}],keyValue:{},globalData:null},i=17*Uint32Array.BYTES_PER_ELEMENT,s=new Ci(t,Oi.length,i,true);n.vkFormat=s._nextUint32(),n.typeSize=s._nextUint32(),n.pixelWidth=s._nextUint32(),n.pixelHeight=s._nextUint32(),n.pixelDepth=s._nextUint32(),n.layerCount=s._nextUint32(),n.faceCount=s._nextUint32(),n.levelCount=s._nextUint32(),n.supercompressionScheme=s._nextUint32();const a=s._nextUint32(),r=s._nextUint32(),o=s._nextUint32(),l=s._nextUint32(),f=s._nextUint64(),c=s._nextUint64(),U=3*Math.max(n.levelCount,1)*8,h=new Ci(t,Oi.length+i,U,true);for(let e=0,i=Math.max(n.levelCount,1);e<i;e++)n.levels.push({levelData:new Uint8Array(t.buffer,t.byteOffset+h._nextUint64(),h._nextUint64()),uncompressedByteLength:h._nextUint64()});const p=new Ci(t,a,r,true);p._skip(4);const _=p._nextUint16(),u=p._nextUint16(),g=p._nextUint16(),x=p._nextUint16(),y={vendorId:_,descriptorType:u,versionNumber:g,colorModel:p._nextUint8(),colorPrimaries:p._nextUint8(),transferFunction:p._nextUint8(),flags:p._nextUint8(),texelBlockDimension:[p._nextUint8(),p._nextUint8(),p._nextUint8(),p._nextUint8()],bytesPlane:[p._nextUint8(),p._nextUint8(),p._nextUint8(),p._nextUint8(),p._nextUint8(),p._nextUint8(),p._nextUint8(),p._nextUint8()],samples:[]},b=(x/4-6)/4;for(let t=0;t<b;t++){const e={bitOffset:p._nextUint16(),bitLength:p._nextUint8(),channelType:p._nextUint8(),samplePosition:[p._nextUint8(),p._nextUint8(),p._nextUint8(),p._nextUint8()],sampleLower:Number.NEGATIVE_INFINITY,sampleUpper:Number.POSITIVE_INFINITY};64&e.channelType?(e.sampleLower=p._nextInt32(),e.sampleUpper=p._nextInt32()):(e.sampleLower=p._nextUint32(),e.sampleUpper=p._nextUint32()),y.samples[t]=e;}n.dataFormatDescriptor.length=0,n.dataFormatDescriptor.push(y);const m=new Ci(t,o,l,true);for(;m._offset<l;){const t=m._nextUint32(),e=m._scan(t),i=Si(e);if(n.keyValue[i]=m._nextUint8Array(t-e.byteLength-1),i.match(/^ktx/i)){const t=Si(n.keyValue[i]);n.keyValue[i]=t.substring(0,t.lastIndexOf("\0"));}m._skip(t%4?4-t%4:0);}if(c<=0)return n;const d=new Ci(t,f,c,true),D=d._nextUint16(),w=d._nextUint16(),v=d._nextUint32(),B=d._nextUint32(),L=d._nextUint32(),A=d._nextUint32(),k=[];for(let t=0,e=Math.max(n.levelCount,1);t<e;t++)k.push({imageFlags:d._nextUint32(),rgbSliceByteOffset:d._nextUint32(),rgbSliceByteLength:d._nextUint32(),alphaSliceByteOffset:d._nextUint32(),alphaSliceByteLength:d._nextUint32()});const I=f+d._offset,V=I+v,C=V+B,F=C+L,O=new Uint8Array(t.buffer,t.byteOffset+I,v),T=new Uint8Array(t.buffer,t.byteOffset+V,B),S=new Uint8Array(t.buffer,t.byteOffset+C,L),E=new Uint8Array(t.buffer,t.byteOffset+F,A);return n.globalData={endpointCount:D,selectorCount:w,imageDescs:k,endpointsData:O,selectorsData:T,tablesData:S,extendedData:E},n}
|
|
61265
|
+
const t=0,n=2,u=1,y=2,S=0,E=1,X=10,it=0,ht=9,gt=15,xt=16,dt=22,Ft=37,Et=43,te=76,ae=83,Ue=91,ue=97,ye=100,de=103,Ae=109,We=122,He=123,qe=131,Je=132,Qe=133,Ze=134,en=137,nn=138,sn=139,an=140,rn=141,on=142,cn=145,Un=146,pn=148,xn=152,yn=153,bn=154,mn=155,dn=156,Dn=157,wn=158,Vn=165,Cn=166,ri=1000054e3,oi=1000054001,ci=1000054004,Ui=1000054005,_i=1000066e3,yi=1000066004;class Ci{constructor(t,e,n,i){this._dataView=void 0,this._littleEndian=void 0,this._offset=void 0,this._dataView=new DataView(t.buffer,t.byteOffset+e,n),this._littleEndian=i,this._offset=0;}_nextUint8(){const t=this._dataView.getUint8(this._offset);return this._offset+=1,t}_nextUint16(){const t=this._dataView.getUint16(this._offset,this._littleEndian);return this._offset+=2,t}_nextUint32(){const t=this._dataView.getUint32(this._offset,this._littleEndian);return this._offset+=4,t}_nextUint64(){const t=this._dataView.getUint32(this._offset,this._littleEndian)+2**32*this._dataView.getUint32(this._offset+4,this._littleEndian);return this._offset+=8,t}_nextInt32(){const t=this._dataView.getInt32(this._offset,this._littleEndian);return this._offset+=4,t}_nextUint8Array(t){const e=new Uint8Array(this._dataView.buffer,this._dataView.byteOffset+this._offset,t);return this._offset+=t,e}_skip(t){return this._offset+=t,this}_scan(t,e=0){const n=this._offset;let i=0;for(;this._dataView.getUint8(this._offset)!==e&&i<t;)i++,this._offset++;return i<t&&this._offset++,new Uint8Array(this._dataView.buffer,this._dataView.byteOffset+n,i)}}const Oi=[171,75,84,88,32,50,48,187,13,10,26,10];function Si(t){return (new TextDecoder).decode(t)}function Mi(t){const e=new Uint8Array(t.buffer,t.byteOffset,Oi.length);if(e[0]!==Oi[0]||e[1]!==Oi[1]||e[2]!==Oi[2]||e[3]!==Oi[3]||e[4]!==Oi[4]||e[5]!==Oi[5]||e[6]!==Oi[6]||e[7]!==Oi[7]||e[8]!==Oi[8]||e[9]!==Oi[9]||e[10]!==Oi[10]||e[11]!==Oi[11])throw new Error("Missing KTX 2.0 identifier.");const n={vkFormat:0,typeSize:1,pixelWidth:0,pixelHeight:0,pixelDepth:0,layerCount:0,faceCount:1,levelCount:0,supercompressionScheme:0,levels:[],dataFormatDescriptor:[{vendorId:0,descriptorType:0,versionNumber:2,colorModel:0,colorPrimaries:1,transferFunction:2,flags:0,texelBlockDimension:[0,0,0,0],bytesPlane:[0,0,0,0,0,0,0,0],samples:[]}],keyValue:{},globalData:null},i=17*Uint32Array.BYTES_PER_ELEMENT,s=new Ci(t,Oi.length,i,true);n.vkFormat=s._nextUint32(),n.typeSize=s._nextUint32(),n.pixelWidth=s._nextUint32(),n.pixelHeight=s._nextUint32(),n.pixelDepth=s._nextUint32(),n.layerCount=s._nextUint32(),n.faceCount=s._nextUint32(),n.levelCount=s._nextUint32(),n.supercompressionScheme=s._nextUint32();const a=s._nextUint32(),r=s._nextUint32(),o=s._nextUint32(),l=s._nextUint32(),f=s._nextUint64(),c=s._nextUint64(),U=3*Math.max(n.levelCount,1)*8,h=new Ci(t,Oi.length+i,U,true);for(let e=0,i=Math.max(n.levelCount,1);e<i;e++)n.levels.push({levelData:new Uint8Array(t.buffer,t.byteOffset+h._nextUint64(),h._nextUint64()),uncompressedByteLength:h._nextUint64()});const p=new Ci(t,a,r,true);p._skip(4);const _=p._nextUint16(),u=p._nextUint16(),g=p._nextUint16(),x=p._nextUint16(),y={vendorId:_,descriptorType:u,versionNumber:g,colorModel:p._nextUint8(),colorPrimaries:p._nextUint8(),transferFunction:p._nextUint8(),flags:p._nextUint8(),texelBlockDimension:[p._nextUint8(),p._nextUint8(),p._nextUint8(),p._nextUint8()],bytesPlane:[p._nextUint8(),p._nextUint8(),p._nextUint8(),p._nextUint8(),p._nextUint8(),p._nextUint8(),p._nextUint8(),p._nextUint8()],samples:[]},b=(x/4-6)/4;for(let t=0;t<b;t++){const e={bitOffset:p._nextUint16(),bitLength:p._nextUint8(),channelType:p._nextUint8(),samplePosition:[p._nextUint8(),p._nextUint8(),p._nextUint8(),p._nextUint8()],sampleLower:Number.NEGATIVE_INFINITY,sampleUpper:Number.POSITIVE_INFINITY};64&e.channelType?(e.sampleLower=p._nextInt32(),e.sampleUpper=p._nextInt32()):(e.sampleLower=p._nextUint32(),e.sampleUpper=p._nextUint32()),y.samples[t]=e;}n.dataFormatDescriptor.length=0,n.dataFormatDescriptor.push(y);const m=new Ci(t,o,l,true);for(;m._offset<l;){const t=m._nextUint32(),e=m._scan(t),i=Si(e);if(n.keyValue[i]=m._nextUint8Array(t-e.byteLength-1),i.match(/^ktx/i)){const t=Si(n.keyValue[i]);n.keyValue[i]=t.substring(0,t.lastIndexOf("\0"));}m._skip(t%4?4-t%4:0);}if(c<=0)return n;const d=new Ci(t,f,c,true),D=d._nextUint16(),w=d._nextUint16(),v=d._nextUint32(),B=d._nextUint32(),L=d._nextUint32(),A=d._nextUint32(),k=[];for(let t=0,e=Math.max(n.levelCount,1);t<e;t++)k.push({imageFlags:d._nextUint32(),rgbSliceByteOffset:d._nextUint32(),rgbSliceByteLength:d._nextUint32(),alphaSliceByteOffset:d._nextUint32(),alphaSliceByteLength:d._nextUint32()});const I=f+d._offset,V=I+v,C=V+B,F=C+L,O=new Uint8Array(t.buffer,t.byteOffset+I,v),T=new Uint8Array(t.buffer,t.byteOffset+V,B),S=new Uint8Array(t.buffer,t.byteOffset+C,L),E=new Uint8Array(t.buffer,t.byteOffset+F,A);return n.globalData={endpointCount:D,selectorCount:w,imageDescs:k,endpointsData:O,selectorsData:T,tablesData:S,extendedData:E},n}
|
|
61104
61266
|
|
|
61105
61267
|
var global$1 = (typeof global !== "undefined" ? global :
|
|
61106
61268
|
typeof self !== "undefined" ? self :
|
|
@@ -63273,6 +63435,7 @@ class KTX2Loader extends Loader {
|
|
|
63273
63435
|
};
|
|
63274
63436
|
|
|
63275
63437
|
if ( typeof navigator !== 'undefined' &&
|
|
63438
|
+
typeof navigator.platform !== 'undefined' && typeof navigator.userAgent !== 'undefined' &&
|
|
63276
63439
|
navigator.platform.indexOf( 'Linux' ) >= 0 && navigator.userAgent.indexOf( 'Firefox' ) >= 0 &&
|
|
63277
63440
|
this.workerConfig.astcSupported && this.workerConfig.etc2Supported &&
|
|
63278
63441
|
this.workerConfig.bptcSupported && this.workerConfig.dxtSupported ) {
|
|
@@ -63985,6 +64148,8 @@ const FORMAT_MAP = {
|
|
|
63985
64148
|
[ ae ]: RGFormat,
|
|
63986
64149
|
[ te ]: RedFormat,
|
|
63987
64150
|
|
|
64151
|
+
[ Ue ]: RGBAFormat,
|
|
64152
|
+
|
|
63988
64153
|
[ Et ]: RGBAFormat,
|
|
63989
64154
|
[ Ft ]: RGBAFormat,
|
|
63990
64155
|
[ dt ]: RGFormat,
|
|
@@ -64014,8 +64179,8 @@ const FORMAT_MAP = {
|
|
|
64014
64179
|
[ Je ]: RGB_S3TC_DXT1_Format,
|
|
64015
64180
|
[ qe ]: RGB_S3TC_DXT1_Format,
|
|
64016
64181
|
|
|
64017
|
-
[ nn ]:
|
|
64018
|
-
[ en ]:
|
|
64182
|
+
[ nn ]: RGBA_S3TC_DXT5_Format,
|
|
64183
|
+
[ en ]: RGBA_S3TC_DXT5_Format,
|
|
64019
64184
|
|
|
64020
64185
|
[ an ]: SIGNED_RED_RGTC1_Format,
|
|
64021
64186
|
[ sn ]: RED_RGTC1_Format,
|
|
@@ -64043,6 +64208,8 @@ const TYPE_MAP = {
|
|
|
64043
64208
|
[ ae ]: HalfFloatType,
|
|
64044
64209
|
[ te ]: HalfFloatType,
|
|
64045
64210
|
|
|
64211
|
+
[ Ue ]: UnsignedShortType,
|
|
64212
|
+
|
|
64046
64213
|
[ Et ]: UnsignedByteType,
|
|
64047
64214
|
[ Ft ]: UnsignedByteType,
|
|
64048
64215
|
[ dt ]: UnsignedByteType,
|
|
@@ -64056,9 +64223,9 @@ const TYPE_MAP = {
|
|
|
64056
64223
|
[ xn ]: UnsignedByteType,
|
|
64057
64224
|
[ pn ]: UnsignedByteType,
|
|
64058
64225
|
[ yn ]: UnsignedByteType,
|
|
64059
|
-
[
|
|
64060
|
-
[ mn ]: UnsignedByteType,
|
|
64226
|
+
[ bn ]: UnsignedByteType,
|
|
64061
64227
|
[ mn ]: UnsignedByteType,
|
|
64228
|
+
[ dn ]: UnsignedByteType,
|
|
64062
64229
|
|
|
64063
64230
|
[ _i ]: HalfFloatType,
|
|
64064
64231
|
[ wn ]: UnsignedByteType,
|
|
@@ -64170,7 +64337,7 @@ async function createRawTexture( container ) {
|
|
|
64170
64337
|
|
|
64171
64338
|
);
|
|
64172
64339
|
|
|
64173
|
-
} else if ( TYPE_MAP[ vkFormat ] === HalfFloatType ) {
|
|
64340
|
+
} else if ( TYPE_MAP[ vkFormat ] === HalfFloatType || TYPE_MAP[ vkFormat ] === UnsignedShortType ) {
|
|
64174
64341
|
|
|
64175
64342
|
data = new Uint16Array(
|
|
64176
64343
|
|
|
@@ -64270,14 +64437,14 @@ function parseColorSpace( container ) {
|
|
|
64270
64437
|
}
|
|
64271
64438
|
|
|
64272
64439
|
// This file is part of meshoptimizer library and is distributed under the terms of MIT License.
|
|
64273
|
-
// Copyright (C) 2016-
|
|
64440
|
+
// Copyright (C) 2016-2026, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
|
|
64274
64441
|
var MeshoptDecoder = (function () {
|
|
64275
|
-
// Built with clang version
|
|
64276
|
-
// Built from meshoptimizer
|
|
64442
|
+
// Built with clang version 22.1.0-wasi-sdk
|
|
64443
|
+
// Built from meshoptimizer 1.1
|
|
64277
64444
|
var wasm_base =
|
|
64278
|
-
'
|
|
64445
|
+
'b9H79Tebbbe8Fv9Gbb9Gvuuuuueu9Giuuub9Geueu9Giuuueuixkbeeeddddillviebeoweuecj:Gdkr;Neqo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9F9KW9J9V9KW9wWVtW949c919M9MWVbeY9TW79O9V9Wt9F9KW9J9V9KW69U9KW949c919M9MWVbdE9TW79O9V9Wt9F9KW9J9V9KW69U9KW949tWG91W9U9JWbiL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9p9JtblK9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9r919HtbvL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWVT949WboY9TW79O9V9Wt9F9KW9J9V9KWS9P2tWVJ9V29VVbrl79IV9Rbwq:VZkdbk:XYi5ud9:du8Jjjjjbcj;kb9Rgv8Kjjjjbc9:hodnalTmbcuhoaiRbbgrc;WeGc:Ge9hmbarcsGgwce0mbc9:hoalcufadcd4cbawEgDadfgrcKcaawEgqaraq0Egk6mbaicefhxcj;abad9Uc;WFbGcjdadca0EhmaialfgPar9Rgoadfhsavaoadz:jjjjbgzceVhHcbhOdndninaeaO9nmeaPax9RaD6mdamaeaO9RaOamfgoae6EgAcsfglc9WGhCabaOad2fhXaAcethQaxaDfhiaOaeaoaeao6E9RhLalcl4cifcd4hKazcj;cbfaAfhYcbh8AazcjdfhEaHh3incbh5dnawTmbaxa8Acd4fRbbh5kcbh8Eazcj;cbfhqinaih8Fdndndndna5a8Ecet4ciGgoc9:fPdebdkaPa8F9RaA6mrazcj;cbfa8EaA2fa8FaAz:jjjjb8Aa8FaAfhixdkazcj;cbfa8EaA2fcbaAz:kjjjb8Aa8FhixekaPa8F9RaK6mva8FaKfhidnaCTmbaPai9RcK6mbaocdtc:q:G:cjbfcj:G:cjbawEhaczhrcbhlinargoc9Wfghaqfhrdndndndndndnaaa8Fahco4fRbbalcoG4ciGcdtfydbPDbedvivvvlvkar9cb83bwar9cb83bbxlkarcbaiRbdai8Xbb9c:c:qj:bw9:9c:q;c1:I1e:d9c:b:c:e1z9:gg9cjjjjjz:dg8J9qE86bbaqaofgrcGfcbaicdfa8J9c8N1:NfghRbbag9cjjjjjw:dg8J9qE86bbarcVfcbaha8J9c8M1:NfghRbbag9cjjjjjl:dg8J9qE86bbarc7fcbaha8J9c8L1:NfghRbbag9cjjjjjd:dg8J9qE86bbarctfcbaha8J9c8K1:NfghRbbag9cjjjjje:dg8J9qE86bbarc91fcbaha8J9c8J1:NfghRbbag9cjjjj;ab:dg8J9qE86bbarc4fcbaha8J9cg1:NfghRbbag9cjjjja:dg8J9qE86bbarc93fcbaha8J9ch1:NfghRbbag9cjjjjz:dgg9qE86bbarc94fcbahag9ca1:NfghRbbai8Xbe9c:c:qj:bw9:9c:q;c1:I1e:d9c:b:c:e1z9:gg9cjjjjjz:dg8J9qE86bbarc95fcbaha8J9c8N1:NfgiRbbag9cjjjjjw:dg8J9qE86bbarc96fcbaia8J9c8M1:NfgiRbbag9cjjjjjl:dg8J9qE86bbarc97fcbaia8J9c8L1:NfgiRbbag9cjjjjjd:dg8J9qE86bbarc98fcbaia8J9c8K1:NfgiRbbag9cjjjjje:dg8J9qE86bbarc99fcbaia8J9c8J1:NfgiRbbag9cjjjj;ab:dg8J9qE86bbarc9:fcbaia8J9cg1:NfgiRbbag9cjjjja:dg8J9qE86bbarcufcbaia8J9ch1:NfgiRbbag9cjjjjz:dgg9qE86bbaiag9ca1:NfhixikaraiRblaiRbbghco4g8Ka8KciSg8KE86bbaqaofgrcGfaiclfa8Kfg8KRbbahcl4ciGg8La8LciSg8LE86bbarcVfa8Ka8Lfg8KRbbahcd4ciGg8La8LciSg8LE86bbarc7fa8Ka8Lfg8KRbbahciGghahciSghE86bbarctfa8Kahfg8KRbbaiRbeghco4g8La8LciSg8LE86bbarc91fa8Ka8Lfg8KRbbahcl4ciGg8La8LciSg8LE86bbarc4fa8Ka8Lfg8KRbbahcd4ciGg8La8LciSg8LE86bbarc93fa8Ka8Lfg8KRbbahciGghahciSghE86bbarc94fa8Kahfg8KRbbaiRbdghco4g8La8LciSg8LE86bbarc95fa8Ka8Lfg8KRbbahcl4ciGg8La8LciSg8LE86bbarc96fa8Ka8Lfg8KRbbahcd4ciGg8La8LciSg8LE86bbarc97fa8Ka8Lfg8KRbbahciGghahciSghE86bbarc98fa8KahfghRbbaiRbigico4g8Ka8KciSg8KE86bbarc99faha8KfghRbbaicl4ciGg8Ka8KciSg8KE86bbarc9:faha8KfghRbbaicd4ciGg8Ka8KciSg8KE86bbarcufaha8KfgrRbbaiciGgiaiciSgiE86bbaraifhixdkaraiRbwaiRbbghcl4g8Ka8KcsSg8KE86bbaqaofgrcGfaicwfa8Kfg8KRbbahcsGghahcsSghE86bbarcVfa8KahfghRbbaiRbeg8Kcl4g8La8LcsSg8LE86bbarc7faha8LfghRbba8KcsGg8Ka8KcsSg8KE86bbarctfaha8KfghRbbaiRbdg8Kcl4g8La8LcsSg8LE86bbarc91faha8LfghRbba8KcsGg8Ka8KcsSg8KE86bbarc4faha8KfghRbbaiRbig8Kcl4g8La8LcsSg8LE86bbarc93faha8LfghRbba8KcsGg8Ka8KcsSg8KE86bbarc94faha8KfghRbbaiRblg8Kcl4g8La8LcsSg8LE86bbarc95faha8LfghRbba8KcsGg8Ka8KcsSg8KE86bbarc96faha8KfghRbbaiRbvg8Kcl4g8La8LcsSg8LE86bbarc97faha8LfghRbba8KcsGg8Ka8KcsSg8KE86bbarc98faha8KfghRbbaiRbog8Kcl4g8La8LcsSg8LE86bbarc99faha8LfghRbba8KcsGg8Ka8KcsSg8KE86bbarc9:faha8KfghRbbaiRbrgicl4g8Ka8KcsSg8KE86bbarcufaha8KfgrRbbaicsGgiaicsSgiE86bbaraifhixekarai8Pbw83bwarai8Pbb83bbaiczfhikdnaoaC9pmbalcdfhlaoczfhraPai9RcL0mekkaoaC6moaimexokaCmva8FTmvkaqaAfhqa8Ecefg8Ecl9hmbkdndndndnawTmbasa8Acd4fRbbgociGPlbedrbkaATmdaza8Afh8Fazcj;cbfhhcbh8EaEhaina8FRbbhraahocbhlinaoahalfRbbgqce4cbaqceG9R7arfgr86bbaoadfhoaAalcefgl9hmbkaacefhaa8Fcefh8FahaAfhha8Ecefg8Ecl9hmbxikkaATmeaza8Afhaazcj;cbfhhcbhoceh8EaYh8FinaEaofhlaa8Vbbhrcbhoinala8FaofRbbcwtahaofRbbgqVc;:FiGce4cbaqceG9R7arfgr87bbaladfhlaLaocefgofmbka8FaQfh8FcdhoaacdfhaahaQfhha8EceGhlcbh8EalmbxdkkaATmbaocl4h8Eaza8AfRbbhqcwhoa3hlinalRbbaotaqVhqalcefhlaocwfgoca9hmbkcbhhaEh8FaYhainazcj;cbfahfRbbhrcwhoaahlinalRbbaotarVhralaAfhlaocwfgoca9hmbkara8E94aq7hqcbhoa8Fhlinalaqao486bbalcefhlaocwfgoca9hmbka8Fadfh8FaacefhaahcefghaA9hmbkkaEclfhEa3clfh3a8Aclfg8Aad6mbkaXazcjdfaAad2z:jjjjb8AazazcjdfaAcufad2fadz:jjjjb8AaAaOfhOaihxaimbkc9:hoxdkcbc99aPax9RakSEhoxekc9:hokavcj;kbf8Kjjjjbaok:ysezu8Jjjjjbc;ae9Rgv8Kjjjjbc9:hodnalaeci9UgrcHf6mbcuhoaiRbbgwc;WeGc;Ge9hmbawcsGgDce0mbavc;abfcFecjez:kjjjb8Aav9cu83iUav9cu83i8Wav9cu83iyav9cu83iaav9cu83iKav9cu83izav9cu83iwav9cu83ibaialfc9WfhqaicefgwarfhldnaeTmbcmcsaDceSEhkcbhxcbhmcbhrcbhicbhoindnalaq9nmbc9:hoxikdndnawRbbgDc;Ve0mbavc;abfaoaDcu7gPcl4fcsGcitfgsydlhzasydbhHdndnaDcsGgsak9pmbavaiaPfcsGcdtfydbaxasEhDaxasTgOfhxxekdndnascsSmbcehOasc987asamffcefhDxekalcefhDal8SbbgscFeGhPdndnascu9mmbaDhlxekalcvfhlaPcFbGhPcrhsdninaD8SbbgOcFbGastaPVhPaOcu9kmeaDcefhDascrfgsc8J9hmbxdkkaDcefhlkcehOaPce4cbaPceG9R7amfhDkaDhmkavc;abfaocitfgsaDBdbasazBdlavaicdtfaDBdbavc;abfaocefcsGcitfgsaHBdbasaDBdlaocdfhoaOaifhidnadcd9hmbabarcetfgsaH87ebasclfaD87ebascdfaz87ebxdkabarcdtfgsaHBdbascwfaDBdbasclfazBdbxekdnaDcpe0mbavaiaqaDcsGfRbbgscl4gP9RcsGcdtfydbaxcefgOaPEhDavaias9RcsGcdtfydbaOaPTgzfgOascsGgPEhsaPThPdndnadcd9hmbabarcetfgHax87ebaHclfas87ebaHcdfaD87ebxekabarcdtfgHaxBdbaHcwfasBdbaHclfaDBdbkavaicdtfaxBdbavc;abfaocitfgHaDBdbaHaxBdlavaicefgicsGcdtfaDBdbavc;abfaocefcsGcitfgHasBdbaHaDBdlavaiazfgicsGcdtfasBdbavc;abfaocdfcsGcitfgDaxBdbaDasBdlaocifhoaiaPfhiaOaPfhxxekaxcbalRbbgsEgHaDc;:eSgDfhOascsGhAdndnascl4gCmbaOcefhzxekaOhzavaiaC9RcsGcdtfydbhOkdndnaAmbazcefhxxekazhxavaias9RcsGcdtfydbhzkdndnaDTmbalcefhDxekalcdfhDal8SbegPcFeGhsdnaPcu9kmbalcofhHascFbGhscrhldninaD8SbbgPcFbGaltasVhsaPcu9kmeaDcefhDalcrfglc8J9hmbkaHhDxekaDcefhDkasce4cbasceG9R7amfgmhHkdndnaCcsSmbaDhsxekaDcefhsaD8SbbglcFeGhPdnalcu9kmbaDcvfhOaPcFbGhPcrhldninas8SbbgDcFbGaltaPVhPaDcu9kmeascefhsalcrfglc8J9hmbkaOhsxekascefhskaPce4cbaPceG9R7amfgmhOkdndnaAcsSmbashlxekascefhlas8SbbgDcFeGhPdnaDcu9kmbascvfhzaPcFbGhPcrhDdninal8SbbgscFbGaDtaPVhPascu9kmealcefhlaDcrfgDc8J9hmbkazhlxekalcefhlkaPce4cbaPceG9R7amfgmhzkdndnadcd9hmbabarcetfgDaH87ebaDclfaz87ebaDcdfaO87ebxekabarcdtfgDaHBdbaDcwfazBdbaDclfaOBdbkavc;abfaocitfgDaOBdbaDaHBdlavaicdtfaHBdbavc;abfaocefcsGcitfgDazBdbaDaOBdlavaicefgicsGcdtfaOBdbavc;abfaocdfcsGcitfgDaHBdbaDazBdlavaiaCTaCcsSVfgicsGcdtfazBdbaiaATaAcsSVfhiaocifhokawcefhwaocsGhoaicsGhiarcifgrae6mbkkcbc99alaqSEhokavc;aef8Kjjjjbaok:clevu8Jjjjjbcz9Rhvdnalaecvf9pmbc9:skdnaiRbbc;:eGc;qeSmbcuskav9cb83iwaicefhoaialfc98fhrdnaeTmbdnadcdSmbcbhwindnaoar6mbc9:skaocefhlao8SbbgicFeGhddndnaicu9mmbalhoxekaocvfhoadcFbGhdcrhidninal8SbbgDcFbGaitadVhdaDcu9kmealcefhlaicrfgic8J9hmbxdkkalcefhokabawcdtfadc8Etc8F91adcd47avcwfadceGcdtVglydbfgiBdbalaiBdbawcefgwae9hmbxdkkcbhwindnaoar6mbc9:skaocefhlao8SbbgicFeGhddndnaicu9mmbalhoxekaocvfhoadcFbGhdcrhidninal8SbbgDcFbGaitadVhdaDcu9kmealcefhlaicrfgic8J9hmbxdkkalcefhokabawcetfadc8Etc8F91adcd47avcwfadceGcdtVglydbfgi87ebalaiBdbawcefgwae9hmbkkcbc99aoarSEk:Lvoeue99dud99eud99dndnadcl9hmbaeTmeindndnabcdfgd8Sbb:Yab8Sbbgi:Ygl:l:tabcefgv8Sbbgo:Ygr:l:tgwJbb;:9cawawNJbbbbawawJbbbb9GgDEgq:mgkaqaicb9iEalMgwawNakaqaocb9iEarMgqaqNMM:r:vglNJbbbZJbbb:;aDEMgr:lJbbb9p9DTmbar:Ohixekcjjjj94hikadai86bbdndnaqalNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohdxekcjjjj94hdkavad86bbdndnawalNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohdxekcjjjj94hdkabad86bbabclfhbaecufgembxdkkaeTmbindndnabclfgd8Ueb:Yab8Uebgi:Ygl:l:tabcdfgv8Uebgo:Ygr:l:tgwJb;:FSawawNJbbbbawawJbbbb9GgDEgq:mgkaqaicb9iEalMgwawNakaqaocb9iEarMgqaqNMM:r:vglNJbbbZJbbb:;aDEMgr:lJbbb9p9DTmbar:Ohixekcjjjj94hikadai87ebdndnaqalNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohdxekcjjjj94hdkavad87ebdndnawalNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohdxekcjjjj94hdkabad87ebabcwfhbaecufgembkkk:4ioiue99dud99dud99dnaeTmbcbhiabhlindndnal8Uebgv:YgoJ:ji:1Salcof8UebgrciVgw:Y:vgDNJbbbZJbbb:;avcu9kEMgq:lJbbb9p9DTmbaq:Ohkxekcjjjj94hkkalclf8Uebhvalcdf8UebhxalarcefciGcetfak87ebdndnax:YgqaDNJbbbZJbbb:;axcu9kEMgm:lJbbb9p9DTmbam:Ohxxekcjjjj94hxkabaiarciGgkfcd7cetfax87ebdndnav:YgmaDNJbbbZJbbb:;avcu9kEMgP:lJbbb9p9DTmbaP:Ohvxekcjjjj94hvkalarcufciGcetfav87ebdndnawaw2:ZgPaPMaoaoN:taqaqN:tamamN:tgoJbbbbaoJbbbb9GE:raDNJbbbZMgD:lJbbb9p9DTmbaD:Ohrxekcjjjj94hrkalakcetfar87ebalcwfhlaiclfhiaecufgembkkk9mbdnadcd4ae2gdTmbinababydbgecwtcw91:Yaece91cjjj98Gcjjj;8if::NUdbabclfhbadcufgdmbkkk:Tvirud99eudndnadcl9hmbaeTmeindndnabRbbgiabcefgl8Sbbgvabcdfgo8Sbbgrf9R:YJbbuJabcifgwRbbgdce4adVgDcd4aDVgDcl4aDVgD:Z:vgqNJbbbZMgk:lJbbb9p9DTmbak:Ohxxekcjjjj94hxkaoax86bbdndnaraif:YaqNJbbbZMgk:lJbbb9p9DTmbak:Ohoxekcjjjj94hokalao86bbdndnavaifar9R:YaqNJbbbZMgk:lJbbb9p9DTmbak:Ohixekcjjjj94hikabai86bbdndnaDadcetGadceGV:ZaqNJbbbZMgq:lJbbb9p9DTmbaq:Ohdxekcjjjj94hdkawad86bbabclfhbaecufgembxdkkaeTmbindndnab8Vebgiabcdfgl8Uebgvabclfgo8Uebgrf9R:YJbFu9habcofgw8Vebgdce4adVgDcd4aDVgDcl4aDVgDcw4aDVgD:Z:vgqNJbbbZMgk:lJbbb9p9DTmbak:Ohxxekcjjjj94hxkaoax87ebdndnaraif:YaqNJbbbZMgk:lJbbb9p9DTmbak:Ohoxekcjjjj94hokalao87ebdndnavaifar9R:YaqNJbbbZMgk:lJbbb9p9DTmbak:Ohixekcjjjj94hikabai87ebdndnaDadcetGadceGV:ZaqNJbbbZMgq:lJbbb9p9DTmbaq:Ohdxekcjjjj94hdkawad87ebabcwfhbaecufgembkkk9teiucbcbyd:K:G:cjbgeabcifc98GfgbBd:K:G:cjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabkk83dbcj:Gdk8Kbbbbdbbblbbbwbbbbbbbebbbdbbblbbbwbbbbc:K:Gdkl8W:qbb'; // embed! base
|
|
64279
64446
|
var wasm_simd =
|
|
64280
|
-
'b9H79TebbbeKl9Gbb9Gvuuuuueu9Giuuub9Geueuikqbbebeedddilve9Weeeviebeoweuec:q:6dkr;leDo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9F9KW9J9V9KW9wWVtW949c919M9MWVbdY9TW79O9V9Wt9F9KW9J9V9KW69U9KW949c919M9MWVblE9TW79O9V9Wt9F9KW9J9V9KW69U9KW949tWG91W9U9JWbvL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9p9JtboK9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9r919HtbrL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWVT949Wbwl79IV9RbDq:p9sqlbzik9:evu8Jjjjjbcz9Rhbcbheincbhdcbhiinabcwfadfaicjuaead4ceGglE86bbaialfhiadcefgdcw9hmbkaec:q:yjjbfai86bbaecitc:q1jjbfab8Piw83ibaecefgecjd9hmbkk:N8JlHud97euo978Jjjjjbcj;kb9Rgv8Kjjjjbc9:hodnadcefal0mbcuhoaiRbbc:Ge9hmbavaialfgrad9Rad;8qbbcj;abad9UhlaicefhodnaeTmbadTmbalc;WFbGglcjdalcjd6EhwcbhDinawaeaD9RaDawfae6Egqcsfglc9WGgkci2hxakcethmalcl4cifcd4hPabaDad2fhsakc;ab6hzcbhHincbhOaohAdndninaraA9RaP6meavcj;cbfaOak2fhCaAaPfhocbhidnazmbarao9Rc;Gb6mbcbhlinaCalfhidndndndndnaAalco4fRbbgXciGPlbedibkaipxbbbbbbbbbbbbbbbbpklbxikaiaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbaoclfaYpQbfaKc:q:yjjbfRbbfhoxdkaiaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbaocwfaYpQbfaKc:q:yjjbfRbbfhoxekaiaopbbbpklbaoczfhokdndndndndnaXcd4ciGPlbedibkaipxbbbbbbbbbbbbbbbbpklzxikaiaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklzaoclfaYpQbfaKc:q:yjjbfRbbfhoxdkaiaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklzaocwfaYpQbfaKc:q:yjjbfRbbfhoxekaiaopbbbpklzaoczfhokdndndndndnaXcl4ciGPlbedibkaipxbbbbbbbbbbbbbbbbpklaxikaiaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklaaoclfaYpQbfaKc:q:yjjbfRbbfhoxdkaiaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklaaocwfaYpQbfaKc:q:yjjbfRbbfhoxekaiaopbbbpklaaoczfhokdndndndndnaXco4Plbedibkaipxbbbbbbbbbbbbbbbbpkl8WxikaiaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibaXc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkl8WaoclfaYpQbfaXc:q:yjjbfRbbfhoxdkaiaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibaXc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkl8WaocwfaYpQbfaXc:q:yjjbfRbbfhoxekaiaopbbbpkl8Waoczfhokalc;abfhialcjefak0meaihlarao9Rc;Fb0mbkkdnaiak9pmbaici4hlinarao9RcK6miaCaifhXdndndndndnaAaico4fRbbalcoG4ciGPlbedibkaXpxbbbbbbbbbbbbbbbbpkbbxikaXaopbblaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkbbaoclfaYpQbfaKc:q:yjjbfRbbfhoxdkaXaopbbwaopbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkbbaocwfaYpQbfaKc:q:yjjbfRbbfhoxekaXaopbbbpkbbaoczfhokalcdfhlaiczfgiak6mbkkaoTmeaohAaOcefgOclSmdxbkkc9:hoxlkdnakTmbavcjdfaHfhiavaHfpbdbhYcbhXinaiavcj;cbfaXfglpblbgLcep9TaLpxeeeeeeeeeeeeeeeegQp9op9Hp9rgLalakfpblbg8Acep9Ta8AaQp9op9Hp9rg8ApmbzeHdOiAlCvXoQrLgEalamfpblbg3cep9Ta3aQp9op9Hp9rg3alaxfpblbg5cep9Ta5aQp9op9Hp9rg5pmbzeHdOiAlCvXoQrLg8EpmbezHdiOAlvCXorQLgQaQpmbedibedibedibediaYp9UgYp9AdbbaiadfglaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaladfglaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaladfglaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaladfglaYaEa8EpmwDKYqk8AExm35Ps8E8FgQaQpmbedibedibedibedip9UgYp9AdbbaladfglaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaladfglaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaladfglaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaladfglaYaLa8ApmwKDYq8AkEx3m5P8Es8FgLa3a5pmwKDYq8AkEx3m5P8Es8Fg8ApmbezHdiOAlvCXorQLgQaQpmbedibedibedibedip9UgYp9AdbbaladfglaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaladfglaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaladfglaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaladfglaYaLa8ApmwDKYqk8AExm35Ps8E8FgQaQpmbedibedibedibedip9UgYp9AdbbaladfglaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaladfglaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaladfglaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaladfhiaXczfgXak6mbkkaHclfgHad6mbkasavcjdfaqad2;8qbbavavcjdfaqcufad2fad;8qbbaqaDfgDae6mbkkcbc99arao9Radcaadca0ESEhokavcj;kbf8Kjjjjbaokwbz:bjjjbk::seHu8Jjjjjbc;ae9Rgv8Kjjjjbc9:hodnaeci9UgrcHfal0mbcuhoaiRbbgwc;WeGc;Ge9hmbawcsGgwce0mbavc;abfcFecje;8kbavcUf9cu83ibavc8Wf9cu83ibavcyf9cu83ibavcaf9cu83ibavcKf9cu83ibavczf9cu83ibav9cu83iwav9cu83ibaialfc9WfhDaicefgqarfhidnaeTmbcmcsawceSEhkcbhxcbhmcbhPcbhwcbhlindnaiaD9nmbc9:hoxikdndnaqRbbgoc;Ve0mbavc;abfalaocu7gscl4fcsGcitfgzydlhrazydbhzdnaocsGgHak9pmbavawasfcsGcdtfydbaxaHEhoaHThsdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkaxasfhxcdhHavawcdtfaoBdbawasfhwcehsalhOxdkdndnaHcsSmbaHc987aHamffcefhoxekaicefhoai8SbbgHcFeGhsdndnaHcu9mmbaohixekaicvfhiascFbGhscrhHdninao8SbbgOcFbGaHtasVhsaOcu9kmeaocefhoaHcrfgHc8J9hmbxdkkaocefhikasce4cbasceG9R7amfhokdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkcdhHavawcdtfaoBdbcehsawcefhwalhOaohmxekdnaocpe0mbaxcefgHavawaDaocsGfRbbgocl49RcsGcdtfydbaocz6gzEhravawao9RcsGcdtfydbaHazfgAaocsGgHEhoaHThCdndnadcd9hmbabaPcetfgHax87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHaxBdbaHcwfaoBdbaHclfarBdbkcdhsavawcdtfaxBdbavawcefgwcsGcdtfarBdbcihHavc;abfalcitfgOaxBdlaOarBdbavawazfgwcsGcdtfaoBdbalcefcsGhOawaCfhwaxhzaAaCfhxxekaxcbaiRbbgOEgzaoc;:eSgHfhraOcsGhCaOcl4hAdndnaOcs0mbarcefhoxekarhoavawaA9RcsGcdtfydbhrkdndnaCmbaocefhxxekaohxavawaO9RcsGcdtfydbhokdndnaHTmbaicefhHxekaicdfhHai8SbegscFeGhzdnascu9kmbaicofhXazcFbGhzcrhidninaH8SbbgscFbGaitazVhzascu9kmeaHcefhHaicrfgic8J9hmbkaXhHxekaHcefhHkazce4cbazceG9R7amfgmhzkdndnaAcsSmbaHhsxekaHcefhsaH8SbbgicFeGhrdnaicu9kmbaHcvfhXarcFbGhrcrhidninas8SbbgHcFbGaitarVhraHcu9kmeascefhsaicrfgic8J9hmbkaXhsxekascefhskarce4cbarceG9R7amfgmhrkdndnaCcsSmbashixekascefhias8SbbgocFeGhHdnaocu9kmbascvfhXaHcFbGhHcrhodninai8SbbgscFbGaotaHVhHascu9kmeaicefhiaocrfgoc8J9hmbkaXhixekaicefhikaHce4cbaHceG9R7amfgmhokdndnadcd9hmbabaPcetfgHaz87ebaHclfao87ebaHcdfar87ebxekabaPcdtfgHazBdbaHcwfaoBdbaHclfarBdbkcdhsavawcdtfazBdbavawcefgwcsGcdtfarBdbcihHavc;abfalcitfgXazBdlaXarBdbavawaOcz6aAcsSVfgwcsGcdtfaoBdbawaCTaCcsSVfhwalcefcsGhOkaqcefhqavc;abfaOcitfgOarBdlaOaoBdbavc;abfalasfcsGcitfgraoBdlarazBdbawcsGhwalaHfcsGhlaPcifgPae6mbkkcbc99aiaDSEhokavc;aef8Kjjjjbaok:flevu8Jjjjjbcz9Rhvc9:hodnaecvfal0mbcuhoaiRbbc;:eGc;qe9hmbav9cb83iwaicefhraialfc98fhwdnaeTmbdnadcdSmbcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcdtfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfglBdbaoalBdbaDcefgDae9hmbxdkkcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcetfaic8Etc8F91aicd47avcwfaiceGcdtVgoydbfgl87ebaoalBdbaDcefgDae9hmbkkcbc99arawSEhokaok:wPliuo97eue978Jjjjjbca9Rhiaec98Ghldndnadcl9hmbdnalTmbcbhvabhdinadadpbbbgocKp:RecKp:Sep;6egraocwp:RecKp:Sep;6earp;Geaoczp:RecKp:Sep;6egwp;Gep;Kep;LegDpxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgkp9op9rp;Kegrpxbb;:9cbb;:9cbb;:9cbb;:9cararp;MeaDaDp;Meawaqawakp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFbbbFbbbFbbbFbbbp9oaopxbbbFbbbFbbbFbbbFp9op9qarawp;Meaqp;Kecwp:RepxbFbbbFbbbFbbbFbbp9op9qaDawp;Meaqp;Keczp:RepxbbFbbbFbbbFbbbFbp9op9qpkbbadczfhdavclfgval6mbkkalaeSmeaipxbbbbbbbbbbbbbbbbgqpklbaiabalcdtfgdaeciGglcdtgv;8qbbdnalTmbaiaipblbgocKp:RecKp:Sep;6egraocwp:RecKp:Sep;6earp;Geaoczp:RecKp:Sep;6egwp;Gep;Kep;LegDaqp:2egqarpxbbbjbbbjbbbjbbbjgkp9op9rp;Kegrpxbb;:9cbb;:9cbb;:9cbb;:9cararp;MeaDaDp;Meawaqawakp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFbbbFbbbFbbbFbbbp9oaopxbbbFbbbFbbbFbbbFp9op9qarawp;Meaqp;Kecwp:RepxbFbbbFbbbFbbbFbbp9op9qaDawp;Meaqp;Keczp:RepxbbFbbbFbbbFbbbFbp9op9qpklbkadaiav;8qbbskdnalTmbcbhvabhdinadczfgxaxpbbbgopxbbbbbbFFbbbbbbFFgkp9oadpbbbgDaopmbediwDqkzHOAKY8AEgwczp:Reczp:Sep;6egraDaopmlvorxmPsCXQL358E8FpxFubbFubbFubbFubbp9op;6eawczp:Sep;6egwp;Gearp;Gep;Kep;Legopxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgmp9op9rp;Kegrpxb;:FSb;:FSb;:FSb;:FSararp;Meaoaop;Meawaqawamp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFFbbFFbbFFbbFFbbp9oaoawp;Meaqp;Keczp:Rep9qgoarawp;Meaqp;KepxFFbbFFbbFFbbFFbbp9ogrpmwDKYqk8AExm35Ps8E8Fp9qpkbbadaDakp9oaoarpmbezHdiOAlvCXorQLp9qpkbbadcafhdavclfgval6mbkkalaeSmbaiaeciGgvcitgdfcbcaad9R;8kbaiabalcitfglad;8qbbdnavTmbaiaipblzgopxbbbbbbFFbbbbbbFFgkp9oaipblbgDaopmbediwDqkzHOAKY8AEgwczp:Reczp:Sep;6egraDaopmlvorxmPsCXQL358E8FpxFubbFubbFubbFubbp9op;6eawczp:Sep;6egwp;Gearp;Gep;Kep;Legopxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgmp9op9rp;Kegrpxb;:FSb;:FSb;:FSb;:FSararp;Meaoaop;Meawaqawamp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFFbbFFbbFFbbFFbbp9oaoawp;Meaqp;Keczp:Rep9qgoarawp;Meaqp;KepxFFbbFFbbFFbbFFbbp9ogrpmwDKYqk8AExm35Ps8E8Fp9qpklzaiaDakp9oaoarpmbezHdiOAlvCXorQLp9qpklbkalaiad;8qbbkk;4wllue97euv978Jjjjjbc8W9Rhidnaec98GglTmbcbhvabhoinaiaopbbbgraoczfgwpbbbgDpmlvorxmPsCXQL358E8Fgqczp:Segkclp:RepklbaopxbbjZbbjZbbjZbbjZpx;Zl81Z;Zl81Z;Zl81Z;Zl81Zakpxibbbibbbibbbibbbp9qp;6ep;NegkaraDpmbediwDqkzHOAKY8AEgrczp:Reczp:Sep;6ep;MegDaDp;Meakarczp:Sep;6ep;Megxaxp;Meakaqczp:Reczp:Sep;6ep;Megqaqp;Mep;Kep;Kep;Lepxbbbbbbbbbbbbbbbbp:4ep;Jepxb;:FSb;:FSb;:FSb;:FSgkp;Mepxbbn0bbn0bbn0bbn0grp;KepxFFbbFFbbFFbbFFbbgmp9oaxakp;Mearp;Keczp:Rep9qgxaDakp;Mearp;Keamp9oaqakp;Mearp;Keczp:Rep9qgkpmbezHdiOAlvCXorQLgrp5baipblbpEb:T:j83ibaocwfarp5eaipblbpEe:T:j83ibawaxakpmwDKYqk8AExm35Ps8E8Fgkp5baipblbpEd:T:j83ibaocKfakp5eaipblbpEi:T:j83ibaocafhoavclfgval6mbkkdnalaeSmbaiaeciGgvcitgofcbcaao9R;8kbaiabalcitfgwao;8qbbdnavTmbaiaipblbgraipblzgDpmlvorxmPsCXQL358E8Fgqczp:Segkclp:RepklaaipxbbjZbbjZbbjZbbjZpx;Zl81Z;Zl81Z;Zl81Z;Zl81Zakpxibbbibbbibbbibbbp9qp;6ep;NegkaraDpmbediwDqkzHOAKY8AEgrczp:Reczp:Sep;6ep;MegDaDp;Meakarczp:Sep;6ep;Megxaxp;Meakaqczp:Reczp:Sep;6ep;Megqaqp;Mep;Kep;Kep;Lepxbbbbbbbbbbbbbbbbp:4ep;Jepxb;:FSb;:FSb;:FSb;:FSgkp;Mepxbbn0bbn0bbn0bbn0grp;KepxFFbbFFbbFFbbFFbbgmp9oaxakp;Mearp;Keczp:Rep9qgxaDakp;Mearp;Keamp9oaqakp;Mearp;Keczp:Rep9qgkpmbezHdiOAlvCXorQLgrp5baipblapEb:T:j83ibaiarp5eaipblapEe:T:j83iwaiaxakpmwDKYqk8AExm35Ps8E8Fgkp5baipblapEd:T:j83izaiakp5eaipblapEi:T:j83iKkawaiao;8qbbkk:Pddiue978Jjjjjbc;ab9Rhidnadcd4ae2glc98GgvTmbcbheabhdinadadpbbbgocwp:Recwp:Sep;6eaocep:SepxbbjFbbjFbbjFbbjFp9opxbbjZbbjZbbjZbbjZp:Uep;Mepkbbadczfhdaeclfgeav6mbkkdnavalSmbaialciGgecdtgdVcbc;abad9R;8kbaiabavcdtfgvad;8qbbdnaeTmbaiaipblbgocwp:Recwp:Sep;6eaocep:SepxbbjFbbjFbbjFbbjFp9opxbbjZbbjZbbjZbbjZp:Uep;Mepklbkavaiad;8qbbkk9teiucbcbydj1jjbgeabcifc98GfgbBdj1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaikkkebcjwklz:Dbb'; // embed! simd
|
|
64447
|
+
'b9H79TebbbeKl9Gbb9Gvuuuuueu9Giuuub9Geueuixkbbebeeddddilve9Weeeviebeoweuecj:Gdkr;Neqo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9F9KW9J9V9KW9wWVtW949c919M9MWVbdY9TW79O9V9Wt9F9KW9J9V9KW69U9KW949c919M9MWVblE9TW79O9V9Wt9F9KW9J9V9KW69U9KW949tWG91W9U9JWbvL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9p9JtboK9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9r919HtbrL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWVT949WbwY9TW79O9V9Wt9F9KW9J9V9KWS9P2tWVJ9V29VVbDl79IV9Rbqq:W9Dklbzik94evu8Jjjjjbcz9Rhbcbheincbhdcbhiinabcwfadfaicjuaead4ceGglE86bbaialfhiadcefgdcw9hmbkaeai86b:q:W:cjbaecitab8Piw83i:q:G:cjbaecefgecjd9hmbkk:JBl8Aud97dur978Jjjjjbcj;kb9Rgv8Kjjjjbc9:hodnalTmbcuhoaiRbbgrc;WeGc:Ge9hmbarcsGgwce0mbc9:hoalcufadcd4cbawEgDadfgrcKcaawEgqaraq0Egk6mbaialfgxar9RhodnadTgmmbavaoad;8qbbkaicefhPcj;abad9Uc;WFbGcjdadca0EhsdndndnadTmbaoadfhzcbhHinaeaH9nmdaxaP9RaD6miabaHad2fhOaPaDfhAasaeaH9RaHasfae6EgCcsfgocl4cifcd4hXavcj;cbfaoc9WGgQcetfhLavcj;cbfaQci2fhKavcj;cbfaQfhYcbh8Aaoc;ab6hEincbh3dnawTmbaPa8Acd4fRbbh3kcbh5avcj;cbfh8Eindndndndna3a5cet4ciGgoc9:fPdebdkaxaA9RaQ6mwdnaQTmbavcj;cbfa5aQ2faAaQ;8qbbkaAaCfhAxdkaQTmeavcj;cbfa5aQ2fcbaQ;8kbxekaxaA9RaX6moaoclVcbawEhraAaXfhocbhidnaEmbaxao9Rc;Gb6mbcbhlina8EalfhidndndndndndnaAalco4fRbbgqciGarfPDbedibledibkaipxbbbbbbbbbbbbbbbbpklbxlkaiaopbblaopbbbg8Fclp:mea8FpmbzeHdOiAlCvXoQrLg8Fcdp:mea8FpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogapxiiiiiiiiiiiiiiiip8Jg8Fp5b9cjF;8;4;W;G;ab9:9cU1:Nghcitpbi:q:G:cjbahRb:q:W:cjbghpsa8Fp5e9cjF;8;4;W;G;ab9:9cU1:Nggcitpbi:q:G:cjbp9UpmbedilvorzHOACXQLpPaaa8Fp9spklbahaoclffagRb:q:W:cjbfhoxikaiaopbbwaopbbbg8Fclp:mea8FpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogapxssssssssssssssssp8Jg8Fp5b9cjF;8;4;W;G;ab9:9cU1:Nghcitpbi:q:G:cjbahRb:q:W:cjbghpsa8Fp5e9cjF;8;4;W;G;ab9:9cU1:Nggcitpbi:q:G:cjbp9UpmbedilvorzHOACXQLpPaaa8Fp9spklbahaocwffagRb:q:W:cjbfhoxdkaiaopbbbpklbaoczfhoxekaiaopbbdaoRbbghcitpbi:q:G:cjbahRb:q:W:cjbghpsaoRbeggcitpbi:q:G:cjbp9UpmbedilvorzHOACXQLpPpklbahaocdffagRb:q:W:cjbfhokdndndndndndnaqcd4ciGarfPDbedibledibkaiczfpxbbbbbbbbbbbbbbbbpklbxlkaiczfaopbblaopbbbg8Fclp:mea8FpmbzeHdOiAlCvXoQrLg8Fcdp:mea8FpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogapxiiiiiiiiiiiiiiiip8Jg8Fp5b9cjF;8;4;W;G;ab9:9cU1:Nghcitpbi:q:G:cjbahRb:q:W:cjbghpsa8Fp5e9cjF;8;4;W;G;ab9:9cU1:Nggcitpbi:q:G:cjbp9UpmbedilvorzHOACXQLpPaaa8Fp9spklbahaoclffagRb:q:W:cjbfhoxikaiczfaopbbwaopbbbg8Fclp:mea8FpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogapxssssssssssssssssp8Jg8Fp5b9cjF;8;4;W;G;ab9:9cU1:Nghcitpbi:q:G:cjbahRb:q:W:cjbghpsa8Fp5e9cjF;8;4;W;G;ab9:9cU1:Nggcitpbi:q:G:cjbp9UpmbedilvorzHOACXQLpPaaa8Fp9spklbahaocwffagRb:q:W:cjbfhoxdkaiczfaopbbbpklbaoczfhoxekaiczfaopbbdaoRbbghcitpbi:q:G:cjbahRb:q:W:cjbghpsaoRbeggcitpbi:q:G:cjbp9UpmbedilvorzHOACXQLpPpklbahaocdffagRb:q:W:cjbfhokdndndndndndnaqcl4ciGarfPDbedibledibkaicafpxbbbbbbbbbbbbbbbbpklbxlkaicafaopbblaopbbbg8Fclp:mea8FpmbzeHdOiAlCvXoQrLg8Fcdp:mea8FpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogapxiiiiiiiiiiiiiiiip8Jg8Fp5b9cjF;8;4;W;G;ab9:9cU1:Nghcitpbi:q:G:cjbahRb:q:W:cjbghpsa8Fp5e9cjF;8;4;W;G;ab9:9cU1:Nggcitpbi:q:G:cjbp9UpmbedilvorzHOACXQLpPaaa8Fp9spklbahaoclffagRb:q:W:cjbfhoxikaicafaopbbwaopbbbg8Fclp:mea8FpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogapxssssssssssssssssp8Jg8Fp5b9cjF;8;4;W;G;ab9:9cU1:Nghcitpbi:q:G:cjbahRb:q:W:cjbghpsa8Fp5e9cjF;8;4;W;G;ab9:9cU1:Nggcitpbi:q:G:cjbp9UpmbedilvorzHOACXQLpPaaa8Fp9spklbahaocwffagRb:q:W:cjbfhoxdkaicafaopbbbpklbaoczfhoxekaicafaopbbdaoRbbghcitpbi:q:G:cjbahRb:q:W:cjbghpsaoRbeggcitpbi:q:G:cjbp9UpmbedilvorzHOACXQLpPpklbahaocdffagRb:q:W:cjbfhokdndndndndndnaqco4arfPDbedibledibkaic8Wfpxbbbbbbbbbbbbbbbbpklbxlkaic8Wfaopbblaopbbbg8Fclp:mea8FpmbzeHdOiAlCvXoQrLg8Fcdp:mea8FpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogapxiiiiiiiiiiiiiiiip8Jg8Fp5b9cjF;8;4;W;G;ab9:9cU1:Ngicitpbi:q:G:cjbaiRb:q:W:cjbgipsa8Fp5e9cjF;8;4;W;G;ab9:9cU1:Ngqcitpbi:q:G:cjbp9UpmbedilvorzHOACXQLpPaaa8Fp9spklbaiaoclffaqRb:q:W:cjbfhoxikaic8Wfaopbbwaopbbbg8Fclp:mea8FpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogapxssssssssssssssssp8Jg8Fp5b9cjF;8;4;W;G;ab9:9cU1:Ngicitpbi:q:G:cjbaiRb:q:W:cjbgipsa8Fp5e9cjF;8;4;W;G;ab9:9cU1:Ngqcitpbi:q:G:cjbp9UpmbedilvorzHOACXQLpPaaa8Fp9spklbaiaocwffaqRb:q:W:cjbfhoxdkaic8Wfaopbbbpklbaoczfhoxekaic8WfaopbbdaoRbbgicitpbi:q:G:cjbaiRb:q:W:cjbgipsaoRbegqcitpbi:q:G:cjbp9UpmbedilvorzHOACXQLpPpklbaiaocdffaqRb:q:W:cjbfhokalc;abfhialcjefaQ0meaihlaxao9Rc;Fb0mbkkdnaiaQ9pmbaici4hlinaxao9RcK6mwa8EaifhqdndndndndndnaAaico4fRbbalcoG4ciGarfPDbedibledibkaqpxbbbbbbbbbbbbbbbbpkbbxlkaqaopbblaopbbbg8Fclp:mea8FpmbzeHdOiAlCvXoQrLg8Fcdp:mea8FpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogapxiiiiiiiiiiiiiiiip8Jg8Fp5b9cjF;8;4;W;G;ab9:9cU1:Nghcitpbi:q:G:cjbahRb:q:W:cjbghpsa8Fp5e9cjF;8;4;W;G;ab9:9cU1:Nggcitpbi:q:G:cjbp9UpmbedilvorzHOACXQLpPaaa8Fp9spkbbahaoclffagRb:q:W:cjbfhoxikaqaopbbwaopbbbg8Fclp:mea8FpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogapxssssssssssssssssp8Jg8Fp5b9cjF;8;4;W;G;ab9:9cU1:Nghcitpbi:q:G:cjbahRb:q:W:cjbghpsa8Fp5e9cjF;8;4;W;G;ab9:9cU1:Nggcitpbi:q:G:cjbp9UpmbedilvorzHOACXQLpPaaa8Fp9spkbbahaocwffagRb:q:W:cjbfhoxdkaqaopbbbpkbbaoczfhoxekaqaopbbdaoRbbghcitpbi:q:G:cjbahRb:q:W:cjbghpsaoRbeggcitpbi:q:G:cjbp9UpmbedilvorzHOACXQLpPpkbbahaocdffagRb:q:W:cjbfhokalcdfhlaiczfgiaQ6mbkkaohAaoTmoka8EaQfh8Ea5cefg5cl9hmbkdndndndnawTmbaza8Acd4fRbbglciGPlbedwbkaQTmdavcjdfa8Afhlava8Afpbdbh8Jcbhoinalavcj;cbfaofpblbg8KaYaofpblbg8LpmbzeHdOiAlCvXoQrLg8MaLaofpblbg8NaKaofpblbgypmbzeHdOiAlCvXoQrLg8PpmbezHdiOAlvCXorQLg8Fcep9Ta8Fpxeeeeeeeeeeeeeeeegap9op9Hp9rg8Fa8Jp9Ug8Jp9Abbbaladfgla8Ja8Fa8Fpmlvorlvorlvorlvorp9Ug8Jp9Abbbaladfgla8Ja8Fa8FpmwDqkwDqkwDqkwDqkp9Ug8Jp9Abbbaladfgla8Ja8Fa8FpmxmPsxmPsxmPsxmPsp9Ug8Jp9Abbbaladfgla8Ja8Ma8PpmwDKYqk8AExm35Ps8E8Fg8Fcep9Ta8Faap9op9Hp9rg8Fp9Ug8Jp9Abbbaladfgla8Ja8Fa8Fpmlvorlvorlvorlvorp9Ug8Jp9Abbbaladfgla8Ja8Fa8FpmwDqkwDqkwDqkwDqkp9Ug8Jp9Abbbaladfgla8Ja8Fa8FpmxmPsxmPsxmPsxmPsp9Ug8Jp9Abbbaladfgla8Ja8Ka8LpmwKDYq8AkEx3m5P8Es8Fg8Ka8NaypmwKDYq8AkEx3m5P8Es8Fg8LpmbezHdiOAlvCXorQLg8Fcep9Ta8Faap9op9Hp9rg8Fp9Ug8Jp9Abbbaladfgla8Ja8Fa8Fpmlvorlvorlvorlvorp9Ug8Jp9Abbbaladfgla8Ja8Fa8FpmwDqkwDqkwDqkwDqkp9Ug8Jp9Abbbaladfgla8Ja8Fa8FpmxmPsxmPsxmPsxmPsp9Ug8Jp9Abbbaladfgla8Ja8Ka8LpmwDKYqk8AExm35Ps8E8Fg8Fcep9Ta8Faap9op9Hp9rg8Fp9Ugap9Abbbaladfglaaa8Fa8Fpmlvorlvorlvorlvorp9Ugap9Abbbaladfglaaa8Fa8FpmwDqkwDqkwDqkwDqkp9Ugap9Abbbaladfglaaa8Fa8FpmxmPsxmPsxmPsxmPsp9Ug8Jp9AbbbaladfhlaoczfgoaQ6mbxikkaQTmeavcjdfa8Afhlava8Afpbdbh8Jcbhoinalavcj;cbfaofpblbg8KaYaofpblbg8LpmbzeHdOiAlCvXoQrLg8MaLaofpblbg8NaKaofpblbgypmbzeHdOiAlCvXoQrLg8PpmbezHdiOAlvCXorQLg8Fcep:nea8Fpxebebebebebebebebgap9op:bep9rg8Fa8Jp:oeg8Jp9Abbbaladfgla8Ja8Fa8Fpmlvorlvorlvorlvorp:oeg8Jp9Abbbaladfgla8Ja8Fa8FpmwDqkwDqkwDqkwDqkp:oeg8Jp9Abbbaladfgla8Ja8Fa8FpmxmPsxmPsxmPsxmPsp:oeg8Jp9Abbbaladfgla8Ja8Ma8PpmwDKYqk8AExm35Ps8E8Fg8Fcep:nea8Faap9op:bep9rg8Fp:oeg8Jp9Abbbaladfgla8Ja8Fa8Fpmlvorlvorlvorlvorp:oeg8Jp9Abbbaladfgla8Ja8Fa8FpmwDqkwDqkwDqkwDqkp:oeg8Jp9Abbbaladfgla8Ja8Fa8FpmxmPsxmPsxmPsxmPsp:oeg8Jp9Abbbaladfgla8Ja8Ka8LpmwKDYq8AkEx3m5P8Es8Fg8Ka8NaypmwKDYq8AkEx3m5P8Es8Fg8LpmbezHdiOAlvCXorQLg8Fcep:nea8Faap9op:bep9rg8Fp:oeg8Jp9Abbbaladfgla8Ja8Fa8Fpmlvorlvorlvorlvorp:oeg8Jp9Abbbaladfgla8Ja8Fa8FpmwDqkwDqkwDqkwDqkp:oeg8Jp9Abbbaladfgla8Ja8Fa8FpmxmPsxmPsxmPsxmPsp:oeg8Jp9Abbbaladfgla8Ja8Ka8LpmwDKYqk8AExm35Ps8E8Fg8Fcep:nea8Faap9op:bep9rg8Fp:oegap9Abbbaladfglaaa8Fa8Fpmlvorlvorlvorlvorp:oegap9Abbbaladfglaaa8Fa8FpmwDqkwDqkwDqkwDqkp:oegap9Abbbaladfglaaa8Fa8FpmxmPsxmPsxmPsxmPsp:oeg8Jp9AbbbaladfhlaoczfgoaQ6mbxdkkaQTmbcbhocbalcl4gl9Rc8FGhiavcjdfa8Afhrava8Afpbdbhainaravcj;cbfaofpblbg8JaYaofpblbg8KpmbzeHdOiAlCvXoQrLg8LaLaofpblbg8MaKaofpblbg8NpmbzeHdOiAlCvXoQrLgypmbezHdiOAlvCXorQLg8Faip:Rea8Falp:Tep9qg8Faap9rgap9Abbbaradfgraaa8Fa8Fpmlvorlvorlvorlvorp9rgap9Abbbaradfgraaa8Fa8FpmwDqkwDqkwDqkwDqkp9rgap9Abbbaradfgraaa8Fa8FpmxmPsxmPsxmPsxmPsp9rgap9Abbbaradfgraaa8LaypmwDKYqk8AExm35Ps8E8Fg8Faip:Rea8Falp:Tep9qg8Fp9rgap9Abbbaradfgraaa8Fa8Fpmlvorlvorlvorlvorp9rgap9Abbbaradfgraaa8Fa8FpmwDqkwDqkwDqkwDqkp9rgap9Abbbaradfgraaa8Fa8FpmxmPsxmPsxmPsxmPsp9rgap9Abbbaradfgraaa8Ja8KpmwKDYq8AkEx3m5P8Es8Fg8Ja8Ma8NpmwKDYq8AkEx3m5P8Es8Fg8KpmbezHdiOAlvCXorQLg8Faip:Rea8Falp:Tep9qg8Fp9rgap9Abbbaradfgraaa8Fa8Fpmlvorlvorlvorlvorp9rgap9Abbbaradfgraaa8Fa8FpmwDqkwDqkwDqkwDqkp9rgap9Abbbaradfgraaa8Fa8FpmxmPsxmPsxmPsxmPsp9rgap9Abbbaradfgraaa8Ja8KpmwDKYqk8AExm35Ps8E8Fg8Faip:Rea8Falp:Tep9qg8Fp9rgap9Abbbaradfgraaa8Fa8Fpmlvorlvorlvorlvorp9rgap9Abbbaradfgraaa8Fa8FpmwDqkwDqkwDqkwDqkp9rgap9Abbbaradfgraaa8Fa8FpmxmPsxmPsxmPsxmPsp9rgap9AbbbaradfhraoczfgoaQ6mbkka8Aclfg8Aad6mbkdnaCad2goTmbaOavcjdfao;8qbbkdnammbavavcjdfaCcufad2fad;8qbbkaCaHfhHc9:hoaAhPaAmbxlkkaeTmbaDalfhrcbhocuhlinaralaD9RglfaD6mdasaeao9Raoasfae6Eaofgoae6mbkaial9RhPkcbc99axaP9RakSEhoxekc9:hokavcj;kbf8Kjjjjbaokwbz:bjjjbkNsezu8Jjjjjbc;ae9Rgv8Kjjjjbc9:hodnalaeci9UgrcHf6mbcuhoaiRbbgwc;WeGc;Ge9hmbawcsGgDce0mbavc;abfcFecje;8kbav9cu83iUav9cu83i8Wav9cu83iyav9cu83iaav9cu83iKav9cu83izav9cu83iwav9cu83ibaialfc9WfhqaicefgwarfhldnaeTmbcmcsaDceSEhkcbhxcbhmcbhrcbhicbhoindnalaq9nmbc9:hoxikdndnawRbbgDc;Ve0mbavc;abfaoaDcu7gPcl4fcsGcitfgsydlhzasydbhHdndnaDcsGgsak9pmbavaiaPfcsGcdtfydbaxasEhDaxasTgOfhxxekdndnascsSmbcehOasc987asamffcefhDxekalcefhDal8SbbgscFeGhPdndnascu9mmbaDhlxekalcvfhlaPcFbGhPcrhsdninaD8SbbgOcFbGastaPVhPaOcu9kmeaDcefhDascrfgsc8J9hmbxdkkaDcefhlkcehOaPce4cbaPceG9R7amfhDkaDhmkavc;abfaocitfgsaDBdbasazBdlavaicdtfaDBdbavc;abfaocefcsGcitfgsaHBdbasaDBdlaocdfhoaOaifhidnadcd9hmbabarcetfgsaH87ebasclfaD87ebascdfaz87ebxdkabarcdtfgsaHBdbascwfaDBdbasclfazBdbxekdnaDcpe0mbavaiaqaDcsGfRbbgscl4gP9RcsGcdtfydbaxcefgOaPEhDavaias9RcsGcdtfydbaOaPTgzfgOascsGgPEhsaPThPdndnadcd9hmbabarcetfgHax87ebaHclfas87ebaHcdfaD87ebxekabarcdtfgHaxBdbaHcwfasBdbaHclfaDBdbkavaicdtfaxBdbavc;abfaocitfgHaDBdbaHaxBdlavaicefgicsGcdtfaDBdbavc;abfaocefcsGcitfgHasBdbaHaDBdlavaiazfgicsGcdtfasBdbavc;abfaocdfcsGcitfgDaxBdbaDasBdlaocifhoaiaPfhiaOaPfhxxekaxcbalRbbgsEgHaDc;:eSgDfhOascsGhAdndnascl4gCmbaOcefhzxekaOhzavaiaC9RcsGcdtfydbhOkdndnaAmbazcefhxxekazhxavaias9RcsGcdtfydbhzkdndnaDTmbalcefhDxekalcdfhDal8SbegPcFeGhsdnaPcu9kmbalcofhHascFbGhscrhldninaD8SbbgPcFbGaltasVhsaPcu9kmeaDcefhDalcrfglc8J9hmbkaHhDxekaDcefhDkasce4cbasceG9R7amfgmhHkdndnaCcsSmbaDhsxekaDcefhsaD8SbbglcFeGhPdnalcu9kmbaDcvfhOaPcFbGhPcrhldninas8SbbgDcFbGaltaPVhPaDcu9kmeascefhsalcrfglc8J9hmbkaOhsxekascefhskaPce4cbaPceG9R7amfgmhOkdndnaAcsSmbashlxekascefhlas8SbbgDcFeGhPdnaDcu9kmbascvfhzaPcFbGhPcrhDdninal8SbbgscFbGaDtaPVhPascu9kmealcefhlaDcrfgDc8J9hmbkazhlxekalcefhlkaPce4cbaPceG9R7amfgmhzkdndnadcd9hmbabarcetfgDaH87ebaDclfaz87ebaDcdfaO87ebxekabarcdtfgDaHBdbaDcwfazBdbaDclfaOBdbkavc;abfaocitfgDaOBdbaDaHBdlavaicdtfaHBdbavc;abfaocefcsGcitfgDazBdbaDaOBdlavaicefgicsGcdtfaOBdbavc;abfaocdfcsGcitfgDaHBdbaDazBdlavaiaCTaCcsSVfgicsGcdtfazBdbaiaATaAcsSVfhiaocifhokawcefhwaocsGhoaicsGhiarcifgrae6mbkkcbc99alaqSEhokavc;aef8Kjjjjbaok:clevu8Jjjjjbcz9Rhvdnalaecvf9pmbc9:skdnaiRbbc;:eGc;qeSmbcuskav9cb83iwaicefhoaialfc98fhrdnaeTmbdnadcdSmbcbhwindnaoar6mbc9:skaocefhlao8SbbgicFeGhddndnaicu9mmbalhoxekaocvfhoadcFbGhdcrhidninal8SbbgDcFbGaitadVhdaDcu9kmealcefhlaicrfgic8J9hmbxdkkalcefhokabawcdtfadc8Etc8F91adcd47avcwfadceGcdtVglydbfgiBdbalaiBdbawcefgwae9hmbxdkkcbhwindnaoar6mbc9:skaocefhlao8SbbgicFeGhddndnaicu9mmbalhoxekaocvfhoadcFbGhdcrhidninal8SbbgDcFbGaitadVhdaDcu9kmealcefhlaicrfgic8J9hmbxdkkalcefhokabawcetfadc8Etc8F91adcd47avcwfadceGcdtVglydbfgi87ebalaiBdbawcefgwae9hmbkkcbc99aoarSEk;Toio97eue97aec98Ghedndnadcl9hmbaeTmecbhdinababpbbbgicKp:RecKp:Sep;6eglaicwp:RecKp:Sep;6ealp;Geaiczp:RecKp:Sep;6egvp;Gep;Kep;Legopxbbbbbbbbbbbbbbbbp:2egralpxbbbjbbbjbbbjbbbjgwp9op9rp;Keglpxbb;:9cbb;:9cbb;:9cbb;:9calalp;Meaoaop;Meavaravawp9op9rp;Keglalp;Mep;Kep;Kep;Jep;Negvp;Mepxbbn0bbn0bbn0bbn0grp;KepxFbbbFbbbFbbbFbbbp9oaipxbbbFbbbFbbbFbbbFp9op9qalavp;Mearp;Kecwp:RepxbFbbbFbbbFbbbFbbp9op9qaoavp;Mearp;Keczp:RepxbbFbbbFbbbFbbbFbp9op9qpkbbabczfhbadclfgdae6mbxdkkaeTmbcbhdinabczfgDaDpbbbgipxbbbbbbFFbbbbbbFFgwp9oabpbbbgoaipmbediwDqkzHOAKY8AEgvczp:Reczp:Sep;6eglaoaipmlvorxmPsCXQL358E8FpxFubbFubbFubbFubbp9op;6eavczp:Sep;6egvp;Gealp;Gep;Kep;Legipxbbbbbbbbbbbbbbbbp:2egralpxbbbjbbbjbbbjbbbjgqp9op9rp;Keglpxb;:FSb;:FSb;:FSb;:FSalalp;Meaiaip;Meavaravaqp9op9rp;Keglalp;Mep;Kep;Kep;Jep;Negvp;Mepxbbn0bbn0bbn0bbn0grp;KepxFFbbFFbbFFbbFFbbp9oaiavp;Mearp;Keczp:Rep9qgialavp;Mearp;KepxFFbbFFbbFFbbFFbbp9oglpmwDKYqk8AExm35Ps8E8Fp9qpkbbabaoawp9oaialpmbezHdiOAlvCXorQLp9qpkbbabcafhbadclfgdae6mbkkk;2ileue97euo97dnaec98GgiTmbcbheinabcKfpx:ji:1S:ji:1S:ji:1S:ji:1SabpbbbglabczfgvpbbbgopmlvorxmPsCXQL358E8Fgrczp:Segwpxibbbibbbibbbibbbp9qp;6egDp;NegqaDaDp;MegDaDp;KealaopmbediwDqkzHOAKY8AEgDczp:Reczp:Sep;6eglalp;MeaDczp:Sep;6egoaop;Mearczp:Reczp:Sep;6egrarp;Mep;Kep;Kep;Lepxbbbbbbbbbbbbbbbbp:4ep;Jep;Mepxbbn0bbn0bbn0bbn0gDp;KepxFFbbFFbbFFbbFFbbgkp9oaqaop;MeaDp;Keczp:Rep9qgoaqalp;MeaDp;Keakp9oaqarp;MeaDp;Keczp:Rep9qgDpmwDKYqk8AExm35Ps8E8Fglp5eawclp:RegqpEi:T:j83ibavalp5baqpEd:T:j83ibabcwfaoaDpmbezHdiOAlvCXorQLgDp5eaqpEe:T:j83ibabaDp5baqpEb:T:j83ibabcafhbaeclfgeai6mbkkkuee97dnadcd4ae2c98GgeTmbcbhdinababpbbbgicwp:Recwp:Sep;6eaicep:SepxbbjFbbjFbbjFbbjFp9opxbbjZbbjZbbjZbbjZp:Uep;Mepkbbabczfhbadclfgdae6mbkkk:Sodw97euaec98Ghedndnadcl9hmbaeTmecbhdinabpxbbuJbbuJbbuJbbuJabpbbbgicKp:TeglaicYp:Tep9qgvcdp:Teavp9qgvclp:Teavp9qgop;6ep;Negvaicwp:RecKp:SegraipxFbbbFbbbFbbbFbbbgwp9ogDp:Uep;6ep;Mepxbbn0bbn0bbn0bbn0gqp;Kecwp:RepxbFbbbFbbbFbbbFbbp9oavaDarp:Xeaiczp:RecKp:Segip:Uep;6ep;Meaqp;Keawp9op9qavaDaraip:Uep:Xep;6ep;Meaqp;Keczp:RepxbbFbbbFbbbFbbbFbp9op9qavaoalcep:Rep9oalpxebbbebbbebbbebbbp9op9qp;6ep;Meaqp;KecKp:Rep9qpkbbabczfhbadclfgdae6mbxdkkaeTmbcbhdinabczfgkpxbFu9hbFu9hbFu9hbFu9habpbbbglakpbbbgrpmlvorxmPsCXQL358E8Fgvczp:TegqavcHp:Tep9qgicdp:Teaip9qgiclp:Teaip9qgicwp:Teaip9qgop;6ep;NegialarpmbediwDqkzHOAKY8AEgDpxFFbbFFbbFFbbFFbbglp9ograDczp:Segwp:Ueavczp:Reczp:SegDp:Xep;6ep;Mepxbbn0bbn0bbn0bbn0gvp;Kealp9oaiarawaDp:Uep:Xep;6ep;Meavp;Keczp:Rep9qgwaiaoaqcep:Rep9oaqpxebbbebbbebbbebbbp9op9qp;6ep;Meavp;Keczp:ReaiaDarp:Uep;6ep;Meavp;Kealp9op9qgipmwDKYqk8AExm35Ps8E8FpkbbabawaipmbezHdiOAlvCXorQLpkbbabcafhbadclfgdae6mbkkk9teiucbcbydj:G:cjbgeabcifc98GfgbBdj:G:cjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaikkxebcj:Gdklz:zbb'; // embed! simd
|
|
64281
64448
|
|
|
64282
64449
|
var detector = new Uint8Array([
|
|
64283
64450
|
0, 97, 115, 109, 1, 0, 0, 0, 1, 4, 1, 96, 0, 0, 3, 3, 2, 0, 0, 5, 3, 1, 0, 1, 12, 1, 0, 10, 22, 2, 12, 0, 65, 0, 65, 0, 65, 0, 252, 10, 0, 0,
|
|
@@ -64339,6 +64506,7 @@ var MeshoptDecoder = (function () {
|
|
|
64339
64506
|
OCTAHEDRAL: 'meshopt_decodeFilterOct',
|
|
64340
64507
|
QUATERNION: 'meshopt_decodeFilterQuat',
|
|
64341
64508
|
EXPONENTIAL: 'meshopt_decodeFilterExp',
|
|
64509
|
+
COLOR: 'meshopt_decodeFilterColor',
|
|
64342
64510
|
};
|
|
64343
64511
|
|
|
64344
64512
|
var decoders = {
|
|
@@ -64417,10 +64585,10 @@ var MeshoptDecoder = (function () {
|
|
|
64417
64585
|
|
|
64418
64586
|
function workerProcess(event) {
|
|
64419
64587
|
var data = event.data;
|
|
64420
|
-
if (!data.id) {
|
|
64421
|
-
return self.close();
|
|
64422
|
-
}
|
|
64423
64588
|
self.ready.then(function (instance) {
|
|
64589
|
+
if (!data.id) {
|
|
64590
|
+
return self.close();
|
|
64591
|
+
}
|
|
64424
64592
|
try {
|
|
64425
64593
|
var target = new Uint8Array(data.count * data.size);
|
|
64426
64594
|
decode(instance, instance.exports[data.mode], target, data.count, data.size, data.source, instance.exports[data.filter]);
|
|
@@ -66341,6 +66509,584 @@ const _Stats = class _Stats2 {
|
|
|
66341
66509
|
_Stats.Panel = Panel;
|
|
66342
66510
|
let Stats = _Stats;
|
|
66343
66511
|
|
|
66512
|
+
// Limitations
|
|
66513
|
+
// - VSM shadows not supported
|
|
66514
|
+
// - MRT not supported
|
|
66515
|
+
// - Transmission not supported
|
|
66516
|
+
// - WebGPU postprocessing stack not supported
|
|
66517
|
+
// - Storage textures not supported
|
|
66518
|
+
// - Fog / environment do not automatically update - must call "dispose"
|
|
66519
|
+
// - instanced mesh geometry cannot be shared
|
|
66520
|
+
// - Node materials cannot be used with "compile" function
|
|
66521
|
+
|
|
66522
|
+
// hash any object parameters that will impact the resulting shader so we can force
|
|
66523
|
+
// a program update
|
|
66524
|
+
function getObjectHash( object ) {
|
|
66525
|
+
|
|
66526
|
+
return '' + object.receiveShadow;
|
|
66527
|
+
|
|
66528
|
+
}
|
|
66529
|
+
|
|
66530
|
+
// Mirrors WebGLUniforms.seqWithValue from WebGLRenderer
|
|
66531
|
+
function generateUniformsList( program, uniforms ) {
|
|
66532
|
+
|
|
66533
|
+
const progUniforms = program.getUniforms();
|
|
66534
|
+
const uniformsList = [];
|
|
66535
|
+
|
|
66536
|
+
for ( let i = 0; i < progUniforms.seq.length; i ++ ) {
|
|
66537
|
+
|
|
66538
|
+
const u = progUniforms.seq[ i ];
|
|
66539
|
+
if ( u.id in uniforms ) uniformsList.push( u );
|
|
66540
|
+
|
|
66541
|
+
}
|
|
66542
|
+
|
|
66543
|
+
return uniformsList;
|
|
66544
|
+
|
|
66545
|
+
}
|
|
66546
|
+
|
|
66547
|
+
// overrides shadow nodes to use the built in shadow textures
|
|
66548
|
+
class WebGLNodeBuilder extends GLSLNodeBuilder {
|
|
66549
|
+
|
|
66550
|
+
addNode( node ) {
|
|
66551
|
+
|
|
66552
|
+
if ( node.isShadowNode ) {
|
|
66553
|
+
|
|
66554
|
+
node.setupRenderTarget = shadow => {
|
|
66555
|
+
|
|
66556
|
+
return { shadowMap: shadow.map, depthTexture: shadow.map.depthTexture };
|
|
66557
|
+
|
|
66558
|
+
};
|
|
66559
|
+
|
|
66560
|
+
node.updateBefore = () => {
|
|
66561
|
+
|
|
66562
|
+
// no need to rerender shadows since WebGLRenderer is handling it
|
|
66563
|
+
|
|
66564
|
+
};
|
|
66565
|
+
|
|
66566
|
+
}
|
|
66567
|
+
|
|
66568
|
+
super.addNode( node );
|
|
66569
|
+
|
|
66570
|
+
}
|
|
66571
|
+
|
|
66572
|
+
}
|
|
66573
|
+
|
|
66574
|
+
// produce and update reusable nodes for a scene
|
|
66575
|
+
class SceneContext {
|
|
66576
|
+
|
|
66577
|
+
constructor( renderer, scene ) {
|
|
66578
|
+
|
|
66579
|
+
// TODO: can / should we update the fog and environment node every frame for recompile?
|
|
66580
|
+
this.renderer = renderer;
|
|
66581
|
+
this.scene = scene;
|
|
66582
|
+
this.lightsNode = renderer.lighting.getNode( scene );
|
|
66583
|
+
this.fogNode = null;
|
|
66584
|
+
this.environmentNode = null;
|
|
66585
|
+
this.prevFog = null;
|
|
66586
|
+
this.prevEnvironment = null;
|
|
66587
|
+
|
|
66588
|
+
}
|
|
66589
|
+
|
|
66590
|
+
getCacheKey() {
|
|
66591
|
+
|
|
66592
|
+
const { lightsNode, environmentNode, fogNode } = this;
|
|
66593
|
+
const lightsHash = lightsNode.getCacheKey();
|
|
66594
|
+
const envHash = environmentNode ? environmentNode.getCacheKey : 0;
|
|
66595
|
+
const fogHash = fogNode ? fogNode.getCacheKey() : 0;
|
|
66596
|
+
return NodeUtils.hashArray( [ lightsHash, envHash, fogHash ] );
|
|
66597
|
+
|
|
66598
|
+
}
|
|
66599
|
+
|
|
66600
|
+
update() {
|
|
66601
|
+
|
|
66602
|
+
const { scene, lightsNode } = this;
|
|
66603
|
+
|
|
66604
|
+
// update lighting
|
|
66605
|
+
const sceneLights = [];
|
|
66606
|
+
scene.traverse( object => {
|
|
66607
|
+
|
|
66608
|
+
if ( object.isLight ) {
|
|
66609
|
+
|
|
66610
|
+
sceneLights.push( object );
|
|
66611
|
+
|
|
66612
|
+
}
|
|
66613
|
+
|
|
66614
|
+
} );
|
|
66615
|
+
|
|
66616
|
+
lightsNode.setLights( sceneLights );
|
|
66617
|
+
|
|
66618
|
+
// update fog
|
|
66619
|
+
if ( this.prevFog !== scene.fog ) {
|
|
66620
|
+
|
|
66621
|
+
this.fogNode = this.getFogNode();
|
|
66622
|
+
this.prevFog = scene.fog;
|
|
66623
|
+
|
|
66624
|
+
}
|
|
66625
|
+
|
|
66626
|
+
// update environment
|
|
66627
|
+
if ( this.prevEnvironment !== scene.environment ) {
|
|
66628
|
+
|
|
66629
|
+
this.environmentNode = this.getEnvironmentNode();
|
|
66630
|
+
this.prevEnvironment = scene.environment;
|
|
66631
|
+
|
|
66632
|
+
}
|
|
66633
|
+
|
|
66634
|
+
}
|
|
66635
|
+
|
|
66636
|
+
getFogNode() {
|
|
66637
|
+
|
|
66638
|
+
const { scene } = this;
|
|
66639
|
+
if ( scene.fog && scene.fog.isFogExp2 ) {
|
|
66640
|
+
|
|
66641
|
+
const color = reference( 'color', 'color', scene.fog );
|
|
66642
|
+
const density = reference( 'density', 'float', scene.fog );
|
|
66643
|
+
return fog( color, densityFogFactor( density ) );
|
|
66644
|
+
|
|
66645
|
+
} else if ( scene.fog && scene.fog.isFog ) {
|
|
66646
|
+
|
|
66647
|
+
const color = reference( 'color', 'color', scene.fog );
|
|
66648
|
+
const near = reference( 'near', 'float', scene.fog );
|
|
66649
|
+
const far = reference( 'far', 'float', scene.fog );
|
|
66650
|
+
return fog( color, rangeFogFactor( near, far ) );
|
|
66651
|
+
|
|
66652
|
+
} else {
|
|
66653
|
+
|
|
66654
|
+
return null;
|
|
66655
|
+
|
|
66656
|
+
}
|
|
66657
|
+
|
|
66658
|
+
}
|
|
66659
|
+
|
|
66660
|
+
getEnvironmentNode() {
|
|
66661
|
+
|
|
66662
|
+
const { scene } = this;
|
|
66663
|
+
if ( scene.environment && scene.environment.isCubeTexture ) {
|
|
66664
|
+
|
|
66665
|
+
return cubeTexture( scene.environment );
|
|
66666
|
+
|
|
66667
|
+
} else if ( scene.environment && scene.environment.isTexture ) {
|
|
66668
|
+
|
|
66669
|
+
return texture( scene.environment );
|
|
66670
|
+
|
|
66671
|
+
} else {
|
|
66672
|
+
|
|
66673
|
+
return null;
|
|
66674
|
+
|
|
66675
|
+
}
|
|
66676
|
+
|
|
66677
|
+
}
|
|
66678
|
+
|
|
66679
|
+
}
|
|
66680
|
+
|
|
66681
|
+
class RendererProxy {
|
|
66682
|
+
|
|
66683
|
+
constructor( renderer ) {
|
|
66684
|
+
|
|
66685
|
+
const backend = {
|
|
66686
|
+
isWebGPUBackend: false,
|
|
66687
|
+
extensions: renderer.extensions,
|
|
66688
|
+
gl: renderer.getContext(),
|
|
66689
|
+
capabilities: null,
|
|
66690
|
+
};
|
|
66691
|
+
|
|
66692
|
+
backend.capabilities = new WebGLCapabilities( backend );
|
|
66693
|
+
|
|
66694
|
+
this.contextNode = context();
|
|
66695
|
+
this.inspector = new InspectorBase();
|
|
66696
|
+
this.library = new BasicNodeLibrary();
|
|
66697
|
+
this.lighting = new Lighting();
|
|
66698
|
+
this.backend = backend;
|
|
66699
|
+
|
|
66700
|
+
const self = this;
|
|
66701
|
+
return new Proxy( renderer, {
|
|
66702
|
+
|
|
66703
|
+
get( target, property ) {
|
|
66704
|
+
|
|
66705
|
+
return Reflect.get( property in self ? self : target, property );
|
|
66706
|
+
|
|
66707
|
+
},
|
|
66708
|
+
|
|
66709
|
+
set( target, property, value ) {
|
|
66710
|
+
|
|
66711
|
+
return Reflect.set( property in self ? self : target, property, value );
|
|
66712
|
+
|
|
66713
|
+
}
|
|
66714
|
+
|
|
66715
|
+
} );
|
|
66716
|
+
|
|
66717
|
+
}
|
|
66718
|
+
|
|
66719
|
+
hasInitialized() {
|
|
66720
|
+
|
|
66721
|
+
return true;
|
|
66722
|
+
|
|
66723
|
+
}
|
|
66724
|
+
|
|
66725
|
+
getMRT() {
|
|
66726
|
+
|
|
66727
|
+
return null;
|
|
66728
|
+
|
|
66729
|
+
}
|
|
66730
|
+
|
|
66731
|
+
hasCompatibility( name ) {
|
|
66732
|
+
|
|
66733
|
+
if ( name === Compatibility.TEXTURE_COMPARE ) {
|
|
66734
|
+
|
|
66735
|
+
return true;
|
|
66736
|
+
|
|
66737
|
+
}
|
|
66738
|
+
|
|
66739
|
+
return false;
|
|
66740
|
+
|
|
66741
|
+
}
|
|
66742
|
+
|
|
66743
|
+
getCacheKey() {
|
|
66744
|
+
|
|
66745
|
+
return this.toneMapping + this.outputColorSpace;
|
|
66746
|
+
|
|
66747
|
+
}
|
|
66748
|
+
|
|
66749
|
+
}
|
|
66750
|
+
|
|
66751
|
+
/**
|
|
66752
|
+
* Compatibility loader and builder for TSL Node materials in WebGLRenderer.
|
|
66753
|
+
*/
|
|
66754
|
+
class WebGLNodesHandler {
|
|
66755
|
+
|
|
66756
|
+
/**
|
|
66757
|
+
* Constructs a new WebGL node adapter.
|
|
66758
|
+
*/
|
|
66759
|
+
constructor() {
|
|
66760
|
+
|
|
66761
|
+
this.renderer = null;
|
|
66762
|
+
this.nodeFrame = new NodeFrame();
|
|
66763
|
+
this.sceneContexts = new WeakMap();
|
|
66764
|
+
this.programCache = new Map();
|
|
66765
|
+
this.renderStack = [];
|
|
66766
|
+
|
|
66767
|
+
const self = this;
|
|
66768
|
+
this.onDisposeMaterialCallback = function () {
|
|
66769
|
+
|
|
66770
|
+
// dispose of all the uniform groups
|
|
66771
|
+
const { programCache } = self;
|
|
66772
|
+
if ( programCache.has( this ) ) {
|
|
66773
|
+
|
|
66774
|
+
self.programCache.get( this ).forEach( ( { uniformsGroups } ) => {
|
|
66775
|
+
|
|
66776
|
+
uniformsGroups.forEach( u => u.dispose() );
|
|
66777
|
+
|
|
66778
|
+
} );
|
|
66779
|
+
|
|
66780
|
+
self.programCache.delete( this );
|
|
66781
|
+
|
|
66782
|
+
}
|
|
66783
|
+
|
|
66784
|
+
this.removeEventListener( 'dispose', self.onDisposeMaterialCallback );
|
|
66785
|
+
|
|
66786
|
+
};
|
|
66787
|
+
|
|
66788
|
+
this.getOutputCallback = function ( outputNode ) {
|
|
66789
|
+
|
|
66790
|
+
// apply tone mapping and color spaces to the output
|
|
66791
|
+
const { outputColorSpace, toneMapping } = self.renderer;
|
|
66792
|
+
outputNode = outputNode.toneMapping( toneMapping );
|
|
66793
|
+
outputNode = workingToColorSpace( outputNode, outputColorSpace );
|
|
66794
|
+
|
|
66795
|
+
return outputNode;
|
|
66796
|
+
|
|
66797
|
+
};
|
|
66798
|
+
|
|
66799
|
+
this.onBeforeRenderCallback = function ( renderer, scene, camera, geometry, object ) {
|
|
66800
|
+
|
|
66801
|
+
// update node frame references for update nodes
|
|
66802
|
+
const { nodeFrame } = self;
|
|
66803
|
+
nodeFrame.material = this;
|
|
66804
|
+
nodeFrame.object = object;
|
|
66805
|
+
|
|
66806
|
+
// increment "frame" here to force uniform buffers to update for the material, which otherwise only get
|
|
66807
|
+
// updated once per frame.
|
|
66808
|
+
renderer.info.render.frame ++;
|
|
66809
|
+
|
|
66810
|
+
// update the uniform groups and nodes for the program if they're available before rendering
|
|
66811
|
+
if ( renderer.properties.has( this ) ) {
|
|
66812
|
+
|
|
66813
|
+
const currentProgram = renderer.properties.get( this ).currentProgram;
|
|
66814
|
+
const programs = self.programCache.get( this );
|
|
66815
|
+
if ( programs && programs.has( currentProgram ) ) {
|
|
66816
|
+
|
|
66817
|
+
// update the nodes for the current object
|
|
66818
|
+
const { updateNodes } = programs.get( currentProgram );
|
|
66819
|
+
self.updateNodes( updateNodes );
|
|
66820
|
+
|
|
66821
|
+
}
|
|
66822
|
+
|
|
66823
|
+
}
|
|
66824
|
+
|
|
66825
|
+
const objectHash = getObjectHash( object );
|
|
66826
|
+
if ( this.prevObjectHash !== objectHash ) {
|
|
66827
|
+
|
|
66828
|
+
this.prevObjectHash = objectHash;
|
|
66829
|
+
this.needsUpdate = true;
|
|
66830
|
+
|
|
66831
|
+
}
|
|
66832
|
+
|
|
66833
|
+
};
|
|
66834
|
+
|
|
66835
|
+
this.customProgramCacheKeyCallback = function () {
|
|
66836
|
+
|
|
66837
|
+
const { renderStack, renderer, nodeFrame } = self;
|
|
66838
|
+
const sceneHash = renderStack[ renderStack.length - 1 ].sceneContext.getCacheKey();
|
|
66839
|
+
const materialHash = this.constructor.prototype.customProgramCacheKey.call( this );
|
|
66840
|
+
const rendererHash = renderer.getCacheKey();
|
|
66841
|
+
|
|
66842
|
+
return materialHash + sceneHash + rendererHash + getObjectHash( nodeFrame.object );
|
|
66843
|
+
|
|
66844
|
+
};
|
|
66845
|
+
|
|
66846
|
+
}
|
|
66847
|
+
|
|
66848
|
+
setRenderer( renderer ) {
|
|
66849
|
+
|
|
66850
|
+
const rendererProxy = new RendererProxy( renderer );
|
|
66851
|
+
this.nodeFrame.renderer = rendererProxy;
|
|
66852
|
+
this.renderer = rendererProxy;
|
|
66853
|
+
|
|
66854
|
+
}
|
|
66855
|
+
|
|
66856
|
+
onUpdateProgram( material, program, materialProperties ) {
|
|
66857
|
+
|
|
66858
|
+
const { programCache } = this;
|
|
66859
|
+
if ( ! programCache.has( material ) ) {
|
|
66860
|
+
|
|
66861
|
+
programCache.set( material, new Map() );
|
|
66862
|
+
|
|
66863
|
+
}
|
|
66864
|
+
|
|
66865
|
+
const programs = programCache.get( material );
|
|
66866
|
+
if ( ! programs.has( program ) ) {
|
|
66867
|
+
|
|
66868
|
+
const builder = material._latestBuilder;
|
|
66869
|
+
const uniforms = materialProperties.uniforms;
|
|
66870
|
+
programs.set( program, {
|
|
66871
|
+
uniformsGroups: this.collectUniformsGroups( builder ),
|
|
66872
|
+
uniforms: uniforms,
|
|
66873
|
+
uniformsList: generateUniformsList( program, uniforms ),
|
|
66874
|
+
updateNodes: builder.updateNodes,
|
|
66875
|
+
} );
|
|
66876
|
+
|
|
66877
|
+
}
|
|
66878
|
+
|
|
66879
|
+
const { uniformsGroups, uniforms, uniformsList, updateNodes } = programs.get( program );
|
|
66880
|
+
material.uniformsGroups = uniformsGroups;
|
|
66881
|
+
materialProperties.uniforms = uniforms;
|
|
66882
|
+
materialProperties.uniformsList = uniformsList;
|
|
66883
|
+
this.updateNodes( updateNodes );
|
|
66884
|
+
|
|
66885
|
+
}
|
|
66886
|
+
|
|
66887
|
+
|
|
66888
|
+
renderStart( scene, camera ) {
|
|
66889
|
+
|
|
66890
|
+
const { nodeFrame, renderStack, renderer, sceneContexts } = this;
|
|
66891
|
+
nodeFrame.update();
|
|
66892
|
+
nodeFrame.camera = camera;
|
|
66893
|
+
nodeFrame.scene = scene;
|
|
66894
|
+
nodeFrame.frameId ++;
|
|
66895
|
+
|
|
66896
|
+
let sceneContext = sceneContexts.get( scene );
|
|
66897
|
+
if ( ! sceneContext ) {
|
|
66898
|
+
|
|
66899
|
+
sceneContext = new SceneContext( renderer, scene );
|
|
66900
|
+
sceneContexts.set( scene, sceneContext );
|
|
66901
|
+
|
|
66902
|
+
}
|
|
66903
|
+
|
|
66904
|
+
sceneContext.update();
|
|
66905
|
+
renderStack.push( { sceneContext, camera } );
|
|
66906
|
+
|
|
66907
|
+
// ensure all node material callbacks are initialized before
|
|
66908
|
+
// traversal and build
|
|
66909
|
+
const {
|
|
66910
|
+
customProgramCacheKeyCallback,
|
|
66911
|
+
onBeforeRenderCallback,
|
|
66912
|
+
} = this;
|
|
66913
|
+
|
|
66914
|
+
scene.traverse( object => {
|
|
66915
|
+
|
|
66916
|
+
if ( object.material && object.material.isNodeMaterial ) {
|
|
66917
|
+
|
|
66918
|
+
object.material.customProgramCacheKey = customProgramCacheKeyCallback;
|
|
66919
|
+
object.material.onBeforeRender = onBeforeRenderCallback;
|
|
66920
|
+
|
|
66921
|
+
}
|
|
66922
|
+
|
|
66923
|
+
} );
|
|
66924
|
+
|
|
66925
|
+
}
|
|
66926
|
+
|
|
66927
|
+
renderEnd() {
|
|
66928
|
+
|
|
66929
|
+
const { nodeFrame, renderStack } = this;
|
|
66930
|
+
|
|
66931
|
+
renderStack.pop();
|
|
66932
|
+
|
|
66933
|
+
const frame = renderStack[ renderStack.length - 1 ];
|
|
66934
|
+
if ( frame ) {
|
|
66935
|
+
|
|
66936
|
+
const { camera, sceneContext } = frame;
|
|
66937
|
+
nodeFrame.camera = camera;
|
|
66938
|
+
nodeFrame.scene = sceneContext.scene;
|
|
66939
|
+
|
|
66940
|
+
}
|
|
66941
|
+
|
|
66942
|
+
}
|
|
66943
|
+
|
|
66944
|
+
build( material, object, parameters ) {
|
|
66945
|
+
|
|
66946
|
+
const {
|
|
66947
|
+
nodeFrame,
|
|
66948
|
+
renderer,
|
|
66949
|
+
getOutputCallback,
|
|
66950
|
+
onDisposeMaterialCallback,
|
|
66951
|
+
renderStack,
|
|
66952
|
+
} = this;
|
|
66953
|
+
|
|
66954
|
+
const {
|
|
66955
|
+
camera,
|
|
66956
|
+
sceneContext,
|
|
66957
|
+
} = renderStack[ renderStack.length - 1 ];
|
|
66958
|
+
|
|
66959
|
+
const {
|
|
66960
|
+
fogNode,
|
|
66961
|
+
environmentNode,
|
|
66962
|
+
lightsNode,
|
|
66963
|
+
scene,
|
|
66964
|
+
} = sceneContext;
|
|
66965
|
+
|
|
66966
|
+
// prepare the frame
|
|
66967
|
+
nodeFrame.material = material;
|
|
66968
|
+
nodeFrame.object = object;
|
|
66969
|
+
|
|
66970
|
+
// create & run the builder
|
|
66971
|
+
const builder = new WebGLNodeBuilder( object, renderer );
|
|
66972
|
+
builder.scene = scene;
|
|
66973
|
+
builder.camera = camera;
|
|
66974
|
+
builder.material = material;
|
|
66975
|
+
builder.fogNode = fogNode;
|
|
66976
|
+
builder.environmentNode = environmentNode;
|
|
66977
|
+
builder.lightsNode = lightsNode;
|
|
66978
|
+
builder.context.getOutput = getOutputCallback;
|
|
66979
|
+
builder.build();
|
|
66980
|
+
|
|
66981
|
+
// update the shader parameters and geometry for program creation and rendering
|
|
66982
|
+
this.updateShaderParameters( builder, parameters );
|
|
66983
|
+
this.updateGeometryAttributes( builder, object.geometry );
|
|
66984
|
+
|
|
66985
|
+
// reset node frame settings to account for any intermediate renders
|
|
66986
|
+
nodeFrame.material = material;
|
|
66987
|
+
nodeFrame.object = object;
|
|
66988
|
+
|
|
66989
|
+
// set up callbacks for uniforms and node updates
|
|
66990
|
+
material._latestBuilder = builder;
|
|
66991
|
+
material.addEventListener( 'dispose', onDisposeMaterialCallback );
|
|
66992
|
+
this.updateNodes( builder.updateNodes );
|
|
66993
|
+
|
|
66994
|
+
}
|
|
66995
|
+
|
|
66996
|
+
updateGeometryAttributes( builder, geometry ) {
|
|
66997
|
+
|
|
66998
|
+
// TODO: this may cause issues if the material / geometry is used in multiple places
|
|
66999
|
+
|
|
67000
|
+
// add instancing attributes
|
|
67001
|
+
builder.bufferAttributes.forEach( v => {
|
|
67002
|
+
|
|
67003
|
+
geometry.setAttribute( v.name, v.node.attribute );
|
|
67004
|
+
|
|
67005
|
+
} );
|
|
67006
|
+
|
|
67007
|
+
// force WebGLAttributes & WebGLBindingStates to refresh
|
|
67008
|
+
// could be fixed by running "build" sooner? Or calling "WebGLAttributes" separately for those
|
|
67009
|
+
// associated with a material?
|
|
67010
|
+
queueMicrotask( () => geometry.dispose() );
|
|
67011
|
+
|
|
67012
|
+
}
|
|
67013
|
+
|
|
67014
|
+
updateShaderParameters( builder, parameters ) {
|
|
67015
|
+
|
|
67016
|
+
// set up shaders
|
|
67017
|
+
parameters.isRawShaderMaterial = true;
|
|
67018
|
+
parameters.glslVersion = GLSL3;
|
|
67019
|
+
parameters.vertexShader = builder.vertexShader.replace( /#version 300 es/, '' );
|
|
67020
|
+
parameters.fragmentShader = builder.fragmentShader.replace( /#version 300 es/, '' );
|
|
67021
|
+
|
|
67022
|
+
// add uniforms accessed by WebGLRenderer
|
|
67023
|
+
parameters.uniforms = {
|
|
67024
|
+
fogColor: { value: new Color() },
|
|
67025
|
+
fogNear: { value: 0 },
|
|
67026
|
+
fogFar: { value: 0 },
|
|
67027
|
+
envMapIntensity: { value: 0 },
|
|
67028
|
+
...UniformsUtils.clone( UniformsLib.lights )
|
|
67029
|
+
};
|
|
67030
|
+
|
|
67031
|
+
// init uniforms
|
|
67032
|
+
const builderUniforms = [ ...builder.uniforms.vertex, ...builder.uniforms.fragment ];
|
|
67033
|
+
for ( const uniform of builderUniforms ) {
|
|
67034
|
+
|
|
67035
|
+
parameters.uniforms[ uniform.name ] = uniform.node;
|
|
67036
|
+
|
|
67037
|
+
}
|
|
67038
|
+
|
|
67039
|
+
}
|
|
67040
|
+
|
|
67041
|
+
collectUniformsGroups( builder ) {
|
|
67042
|
+
|
|
67043
|
+
// create UniformsGroups for regular grouped uniforms
|
|
67044
|
+
const uniformsGroups = [];
|
|
67045
|
+
for ( const key in builder.uniformGroups ) {
|
|
67046
|
+
|
|
67047
|
+
const { uniforms } = builder.uniformGroups[ key ];
|
|
67048
|
+
const group = new UniformsGroup();
|
|
67049
|
+
group.name = key;
|
|
67050
|
+
group.uniforms = uniforms.map( node => node.nodeUniform );
|
|
67051
|
+
uniformsGroups.push( group );
|
|
67052
|
+
|
|
67053
|
+
}
|
|
67054
|
+
|
|
67055
|
+
// init uniforms
|
|
67056
|
+
const builderUniforms = [ ...builder.uniforms.vertex, ...builder.uniforms.fragment ];
|
|
67057
|
+
for ( const uniform of builderUniforms ) {
|
|
67058
|
+
|
|
67059
|
+
if ( uniform.type === 'buffer' ) {
|
|
67060
|
+
|
|
67061
|
+
// buffer uniforms are all nested in groups
|
|
67062
|
+
const group = new UniformsGroup();
|
|
67063
|
+
group.name = uniform.node.name;
|
|
67064
|
+
group.uniforms = [ uniform ];
|
|
67065
|
+
uniformsGroups.push( group );
|
|
67066
|
+
|
|
67067
|
+
}
|
|
67068
|
+
|
|
67069
|
+
}
|
|
67070
|
+
|
|
67071
|
+
return uniformsGroups;
|
|
67072
|
+
|
|
67073
|
+
}
|
|
67074
|
+
|
|
67075
|
+
updateNodes( updateNodes ) {
|
|
67076
|
+
|
|
67077
|
+
// update nodes for render
|
|
67078
|
+
const { nodeFrame } = this;
|
|
67079
|
+
nodeFrame.renderId ++;
|
|
67080
|
+
for ( const node of updateNodes ) {
|
|
67081
|
+
|
|
67082
|
+
nodeFrame.updateNode( node );
|
|
67083
|
+
|
|
67084
|
+
}
|
|
67085
|
+
|
|
67086
|
+
}
|
|
67087
|
+
|
|
67088
|
+
}
|
|
67089
|
+
|
|
66344
67090
|
// -----------------------------------------------------------------------------------------------------------
|
|
66345
67091
|
// __ ______ __ __ ______ __ __ ______ ______ ______
|
|
66346
67092
|
// /\ \ /\ ___\ /\ "-./ \ /\ __ \ /\ "-.\ \ /\ __ \ /\__ _\ /\ ___\
|
|
@@ -68260,7 +69006,7 @@ class Renderer {
|
|
|
68260
69006
|
options;
|
|
68261
69007
|
renderView = null;
|
|
68262
69008
|
webGlRenderer;
|
|
68263
|
-
|
|
69009
|
+
webGlNodesHandler;
|
|
68264
69010
|
raycaster;
|
|
68265
69011
|
renderers = {};
|
|
68266
69012
|
requestFrameFuncs = [];
|
|
@@ -68337,7 +69083,8 @@ class Renderer {
|
|
|
68337
69083
|
this.layers.push(`Layer ${i + 1}`);
|
|
68338
69084
|
}
|
|
68339
69085
|
this.webGlRenderer = this._createWebGlRenderer(options);
|
|
68340
|
-
|
|
69086
|
+
this.webGlNodesHandler = new WebGLNodesHandler();
|
|
69087
|
+
this.webGlRenderer.setNodesHandler(this.webGlNodesHandler);
|
|
68341
69088
|
this.setDevicePixelRatio();
|
|
68342
69089
|
this.setShadowType(ShadowMode.Pcf);
|
|
68343
69090
|
this.setRendererSettings();
|
|
@@ -68410,22 +69157,6 @@ class Renderer {
|
|
|
68410
69157
|
webGlRenderer.setSize(this.width, this.height);
|
|
68411
69158
|
return webGlRenderer;
|
|
68412
69159
|
}
|
|
68413
|
-
_createWebGpuRenderer() {
|
|
68414
|
-
const gl = this.webGlRenderer.getContext();
|
|
68415
|
-
if (!gl) {
|
|
68416
|
-
throw new Error('Renderer._createWebGpuRenderer: WebGL2 context required.');
|
|
68417
|
-
}
|
|
68418
|
-
const webGpuRenderer = new WebGPURenderer({
|
|
68419
|
-
forceWebGL: true,
|
|
68420
|
-
canvas: this.webGlRenderer.domElement,
|
|
68421
|
-
context: gl,
|
|
68422
|
-
depth: true,
|
|
68423
|
-
antialias: false,
|
|
68424
|
-
alpha: true
|
|
68425
|
-
});
|
|
68426
|
-
webGpuRenderer.setSize(this.width, this.height);
|
|
68427
|
-
return webGpuRenderer;
|
|
68428
|
-
}
|
|
68429
69160
|
async init() {
|
|
68430
69161
|
try {
|
|
68431
69162
|
await loadFontFace("OpenSansRegular", openSansRegularUrl);
|
|
@@ -68438,9 +69169,6 @@ class Renderer {
|
|
|
68438
69169
|
getWebGLRenderer() {
|
|
68439
69170
|
return this.webGlRenderer;
|
|
68440
69171
|
}
|
|
68441
|
-
/*getWebGPURenderer(): WebGPURenderer {
|
|
68442
|
-
return this.webGpuRenderer;
|
|
68443
|
-
}*/
|
|
68444
69172
|
hookEvents() {
|
|
68445
69173
|
if (this.renderView) {
|
|
68446
69174
|
// We have to remember the pressed buttons of the pointer controller because we will only ever receive a single
|
|
@@ -76649,6 +77377,22 @@ class TextGeometry extends ExtrudeGeometry {
|
|
|
76649
77377
|
|
|
76650
77378
|
}
|
|
76651
77379
|
|
|
77380
|
+
toJSON() {
|
|
77381
|
+
|
|
77382
|
+
const data = super.toJSON();
|
|
77383
|
+
return data;
|
|
77384
|
+
|
|
77385
|
+
}
|
|
77386
|
+
|
|
77387
|
+
static fromJSON( data ) {
|
|
77388
|
+
|
|
77389
|
+
const options = data.options;
|
|
77390
|
+
|
|
77391
|
+
options.font = new Font( options.font.data );
|
|
77392
|
+
return new TextGeometry( options.text, options );
|
|
77393
|
+
|
|
77394
|
+
}
|
|
77395
|
+
|
|
76652
77396
|
}
|
|
76653
77397
|
|
|
76654
77398
|
var glyphs = {
|
|
@@ -80733,6 +81477,16 @@ class SgTorus extends SgProceduralGeometryItem {
|
|
|
80733
81477
|
* sky.scale.setScalar( 10000 );
|
|
80734
81478
|
* scene.add( sky );
|
|
80735
81479
|
* ```
|
|
81480
|
+
*
|
|
81481
|
+
* It can be useful to hide the sun disc when generating an environment map to avoid artifacts
|
|
81482
|
+
*
|
|
81483
|
+
* ```js
|
|
81484
|
+
* // disable before rendering environment map
|
|
81485
|
+
* sky.material.uniforms.showSunDisc.value = false;
|
|
81486
|
+
* // ...
|
|
81487
|
+
* // re-enable before scene sky box rendering
|
|
81488
|
+
* sky.material.uniforms.showSunDisc.value = true;
|
|
81489
|
+
* ```
|
|
80736
81490
|
*
|
|
80737
81491
|
* @augments Mesh
|
|
80738
81492
|
* @three_import import { Sky } from 'three/addons/objects/Sky.js';
|
|
@@ -80780,7 +81534,14 @@ Sky.SkyShader = {
|
|
|
80780
81534
|
'mieCoefficient': { value: 0.005 },
|
|
80781
81535
|
'mieDirectionalG': { value: 0.8 },
|
|
80782
81536
|
'sunPosition': { value: new Vector3() },
|
|
80783
|
-
'up': { value: new Vector3( 0, 1, 0 ) }
|
|
81537
|
+
'up': { value: new Vector3( 0, 1, 0 ) },
|
|
81538
|
+
'cloudScale': { value: 0.0002 },
|
|
81539
|
+
'cloudSpeed': { value: 0.0001 },
|
|
81540
|
+
'cloudCoverage': { value: 0.4 },
|
|
81541
|
+
'cloudDensity': { value: 0.4 },
|
|
81542
|
+
'cloudElevation': { value: 0.5 },
|
|
81543
|
+
'showSunDisc': { value: 1 },
|
|
81544
|
+
'time': { value: 0.0 }
|
|
80784
81545
|
},
|
|
80785
81546
|
|
|
80786
81547
|
vertexShader: /* glsl */`
|
|
@@ -80858,13 +81619,46 @@ Sky.SkyShader = {
|
|
|
80858
81619
|
fragmentShader: /* glsl */`
|
|
80859
81620
|
varying vec3 vWorldPosition;
|
|
80860
81621
|
varying vec3 vSunDirection;
|
|
80861
|
-
varying float vSunfade;
|
|
80862
81622
|
varying vec3 vBetaR;
|
|
80863
81623
|
varying vec3 vBetaM;
|
|
80864
81624
|
varying float vSunE;
|
|
80865
81625
|
|
|
80866
81626
|
uniform float mieDirectionalG;
|
|
80867
81627
|
uniform vec3 up;
|
|
81628
|
+
uniform float cloudScale;
|
|
81629
|
+
uniform float cloudSpeed;
|
|
81630
|
+
uniform float cloudCoverage;
|
|
81631
|
+
uniform float cloudDensity;
|
|
81632
|
+
uniform float cloudElevation;
|
|
81633
|
+
uniform float showSunDisc;
|
|
81634
|
+
uniform float time;
|
|
81635
|
+
|
|
81636
|
+
// Cloud noise functions
|
|
81637
|
+
float hash( vec2 p ) {
|
|
81638
|
+
return fract( sin( dot( p, vec2( 127.1, 311.7 ) ) ) * 43758.5453123 );
|
|
81639
|
+
}
|
|
81640
|
+
|
|
81641
|
+
float noise( vec2 p ) {
|
|
81642
|
+
vec2 i = floor( p );
|
|
81643
|
+
vec2 f = fract( p );
|
|
81644
|
+
f = f * f * ( 3.0 - 2.0 * f );
|
|
81645
|
+
float a = hash( i );
|
|
81646
|
+
float b = hash( i + vec2( 1.0, 0.0 ) );
|
|
81647
|
+
float c = hash( i + vec2( 0.0, 1.0 ) );
|
|
81648
|
+
float d = hash( i + vec2( 1.0, 1.0 ) );
|
|
81649
|
+
return mix( mix( a, b, f.x ), mix( c, d, f.x ), f.y );
|
|
81650
|
+
}
|
|
81651
|
+
|
|
81652
|
+
float fbm( vec2 p ) {
|
|
81653
|
+
float value = 0.0;
|
|
81654
|
+
float amplitude = 0.5;
|
|
81655
|
+
for ( int i = 0; i < 5; i ++ ) {
|
|
81656
|
+
value += amplitude * noise( p );
|
|
81657
|
+
p *= 2.0;
|
|
81658
|
+
amplitude *= 0.5;
|
|
81659
|
+
}
|
|
81660
|
+
return value;
|
|
81661
|
+
}
|
|
80868
81662
|
|
|
80869
81663
|
// constants for atmospheric scattering
|
|
80870
81664
|
const float pi = 3.141592653589793238462643383279502884197169;
|
|
@@ -80926,14 +81720,48 @@ Sky.SkyShader = {
|
|
|
80926
81720
|
vec3 L0 = vec3( 0.1 ) * Fex;
|
|
80927
81721
|
|
|
80928
81722
|
// composition + solar disc
|
|
80929
|
-
float
|
|
80930
|
-
L0 += ( vSunE * 19000.0 * Fex ) *
|
|
81723
|
+
float sundisc = smoothstep( sunAngularDiameterCos, sunAngularDiameterCos + 0.00002, cosTheta ) * showSunDisc;
|
|
81724
|
+
L0 += ( vSunE * 19000.0 * Fex ) * sundisc;
|
|
80931
81725
|
|
|
80932
81726
|
vec3 texColor = ( Lin + L0 ) * 0.04 + vec3( 0.0, 0.0003, 0.00075 );
|
|
80933
81727
|
|
|
80934
|
-
|
|
81728
|
+
// Clouds
|
|
81729
|
+
if ( direction.y > 0.0 && cloudCoverage > 0.0 ) {
|
|
81730
|
+
|
|
81731
|
+
// Project to cloud plane (higher elevation = clouds appear lower/closer)
|
|
81732
|
+
float elevation = mix( 1.0, 0.1, cloudElevation );
|
|
81733
|
+
vec2 cloudUV = direction.xz / ( direction.y * elevation );
|
|
81734
|
+
cloudUV *= cloudScale;
|
|
81735
|
+
cloudUV += time * cloudSpeed;
|
|
81736
|
+
|
|
81737
|
+
// Multi-octave noise for fluffy clouds
|
|
81738
|
+
float cloudNoise = fbm( cloudUV * 1000.0 );
|
|
81739
|
+
cloudNoise += 0.5 * fbm( cloudUV * 2000.0 + 3.7 );
|
|
81740
|
+
cloudNoise = cloudNoise * 0.5 + 0.5;
|
|
81741
|
+
|
|
81742
|
+
// Apply coverage threshold
|
|
81743
|
+
float cloudMask = smoothstep( 1.0 - cloudCoverage, 1.0 - cloudCoverage + 0.3, cloudNoise );
|
|
81744
|
+
|
|
81745
|
+
// Fade clouds near horizon (adjusted by elevation)
|
|
81746
|
+
float horizonFade = smoothstep( 0.0, 0.1 + 0.2 * cloudElevation, direction.y );
|
|
81747
|
+
cloudMask *= horizonFade;
|
|
81748
|
+
|
|
81749
|
+
// Cloud lighting based on sun position
|
|
81750
|
+
float sunInfluence = dot( direction, vSunDirection ) * 0.5 + 0.5;
|
|
81751
|
+
float daylight = max( 0.0, vSunDirection.y * 2.0 );
|
|
80935
81752
|
|
|
80936
|
-
|
|
81753
|
+
// Base cloud color affected by atmosphere
|
|
81754
|
+
vec3 atmosphereColor = Lin * 0.04;
|
|
81755
|
+
vec3 cloudColor = mix( vec3( 0.3 ), vec3( 1.0 ), daylight );
|
|
81756
|
+
cloudColor = mix( cloudColor, atmosphereColor + vec3( 1.0 ), sunInfluence * 0.5 );
|
|
81757
|
+
cloudColor *= vSunE * 0.00002;
|
|
81758
|
+
|
|
81759
|
+
// Blend clouds with sky
|
|
81760
|
+
texColor = mix( texColor, cloudColor, cloudMask * cloudDensity );
|
|
81761
|
+
|
|
81762
|
+
}
|
|
81763
|
+
|
|
81764
|
+
gl_FragColor = vec4( texColor, 1.0 );
|
|
80937
81765
|
|
|
80938
81766
|
#include <tonemapping_fragment>
|
|
80939
81767
|
#include <colorspace_fragment>
|
|
@@ -80992,12 +81820,24 @@ class SgSky extends SgItem {
|
|
|
80992
81820
|
const mieDirectionalG = this.getFieldValue("MieDirectionalG");
|
|
80993
81821
|
const inclination = this.getFieldValue("Inclination");
|
|
80994
81822
|
const azimuth = this.getFieldValue("Azimuth");
|
|
81823
|
+
const showSunDisc = this.getFieldValue("ShowSunDisc");
|
|
81824
|
+
const cloudScale = this.getFieldValue("CloudScale");
|
|
81825
|
+
const cloudSpeed = this.getFieldValue("CloudSpeed");
|
|
81826
|
+
const cloudCoverage = this.getFieldValue("CloudCoverage");
|
|
81827
|
+
const cloudDensity = this.getFieldValue("CloudDensity");
|
|
81828
|
+
const cloudElevation = this.getFieldValue("CloudElevation");
|
|
80995
81829
|
await this.recreateObject(async () => {
|
|
80996
81830
|
this.mesh = new Sky();
|
|
80997
81831
|
this.mesh.scale.setScalar(size);
|
|
80998
81832
|
this.inclination = inclination;
|
|
80999
81833
|
this.azimuth = azimuth;
|
|
81000
81834
|
this.size = size;
|
|
81835
|
+
this.setUniformValue("cloudScale", cloudScale / 100);
|
|
81836
|
+
this.setUniformValue("cloudSpeed", cloudSpeed / 100);
|
|
81837
|
+
this.setUniformValue("cloudCoverage", cloudCoverage);
|
|
81838
|
+
this.setUniformValue("cloudDensity", cloudDensity);
|
|
81839
|
+
this.setUniformValue("cloudElevation", cloudElevation);
|
|
81840
|
+
this.setUniformValue("showSunDisc", showSunDisc);
|
|
81001
81841
|
this.setUniformValue("turbidity", turbidity);
|
|
81002
81842
|
this.setUniformValue("rayleigh", rayleigh);
|
|
81003
81843
|
this.setUniformValue("mieCoefficient", mieCoefficient);
|
|
@@ -81027,6 +81867,9 @@ class SgSky extends SgItem {
|
|
|
81027
81867
|
console.log("Could not find object to set uniform on");
|
|
81028
81868
|
}
|
|
81029
81869
|
}
|
|
81870
|
+
update(deltaTimeMs) {
|
|
81871
|
+
this.setUniformValue("time", performance.now() * 0.001);
|
|
81872
|
+
}
|
|
81030
81873
|
updateEvent(field, value, type, oldValue) {
|
|
81031
81874
|
if (super.updateEvent(field, value, type, oldValue))
|
|
81032
81875
|
return true;
|
|
@@ -81058,6 +81901,24 @@ class SgSky extends SgItem {
|
|
|
81058
81901
|
this.azimuth = value;
|
|
81059
81902
|
this.setSunPosition(this.inclination, this.azimuth);
|
|
81060
81903
|
break;
|
|
81904
|
+
case "ShowSunDisc":
|
|
81905
|
+
this.setUniformValue("showSunDisc", value);
|
|
81906
|
+
break;
|
|
81907
|
+
case "CloudScale":
|
|
81908
|
+
this.setUniformValue("cloudScale", value / 100);
|
|
81909
|
+
break;
|
|
81910
|
+
case "CloudSpeed":
|
|
81911
|
+
this.setUniformValue("cloudSpeed", value / 100);
|
|
81912
|
+
break;
|
|
81913
|
+
case "CloudCoverage":
|
|
81914
|
+
this.setUniformValue("cloudCoverage", value);
|
|
81915
|
+
break;
|
|
81916
|
+
case "CloudDensity":
|
|
81917
|
+
this.setUniformValue("cloudDensity", value);
|
|
81918
|
+
break;
|
|
81919
|
+
case "CloudElevation":
|
|
81920
|
+
this.setUniformValue("cloudElevation", value);
|
|
81921
|
+
break;
|
|
81061
81922
|
default:
|
|
81062
81923
|
return false;
|
|
81063
81924
|
}
|
|
@@ -84018,7 +84879,7 @@ class ParticleSystem {
|
|
|
84018
84879
|
particleCount;
|
|
84019
84880
|
width;
|
|
84020
84881
|
height;
|
|
84021
|
-
|
|
84882
|
+
timer = new Timer$1();
|
|
84022
84883
|
elapsedTime = 0;
|
|
84023
84884
|
timeSinceLastSpawn = 0;
|
|
84024
84885
|
isRunning = true;
|
|
@@ -84610,7 +85471,7 @@ class ParticleSystem {
|
|
|
84610
85471
|
this.elapsedTime = 0;
|
|
84611
85472
|
this.timeSinceLastSpawn = this.spawnRate; // force spawn at the next update
|
|
84612
85473
|
this.emissionCounter = 0;
|
|
84613
|
-
this.
|
|
85474
|
+
this.timer.reset(); // reset the simulation clock
|
|
84614
85475
|
}
|
|
84615
85476
|
killAllParticles() {
|
|
84616
85477
|
this.simulation.killAllParticles();
|
|
@@ -84636,7 +85497,7 @@ class ParticleSystem {
|
|
|
84636
85497
|
render(delta) {
|
|
84637
85498
|
if (!this.isRunning || this.isPaused)
|
|
84638
85499
|
return;
|
|
84639
|
-
delta ??= this.
|
|
85500
|
+
delta ??= this.timer.getDelta();
|
|
84640
85501
|
if (this.duration !== -1 && this.elapsedTime > this.duration) {
|
|
84641
85502
|
this.killAllParticles();
|
|
84642
85503
|
this.hideParticles();
|
|
@@ -85949,7 +86810,7 @@ class SgAudio extends SgItem {
|
|
|
85949
86810
|
if (!this.stereoPanner) {
|
|
85950
86811
|
this.stereoPanner = this.audio.context.createStereoPanner();
|
|
85951
86812
|
}
|
|
85952
|
-
this.audio.
|
|
86813
|
+
this.audio.setFilters([this.stereoPanner]);
|
|
85953
86814
|
}
|
|
85954
86815
|
}
|
|
85955
86816
|
enumerateItemChildren() {
|
|
@@ -86131,7 +86992,7 @@ class SgAudio extends SgItem {
|
|
|
86131
86992
|
_setAudioProps() {
|
|
86132
86993
|
if (!this.audio)
|
|
86133
86994
|
return;
|
|
86134
|
-
this.audio.
|
|
86995
|
+
this.audio.setLoop(this.getFieldValue("Loop"));
|
|
86135
86996
|
const loopSection = this.getFieldValue("LoopSection");
|
|
86136
86997
|
if (loopSection) {
|
|
86137
86998
|
this.audio.setLoopStart(this.getFieldValue("LoopStart"));
|
|
@@ -111063,6 +111924,7 @@ const KHR_mesh_quantization_ExtraAttrTypes = {
|
|
|
111063
111924
|
* - KHR_texture_transform
|
|
111064
111925
|
* - EXT_materials_bump
|
|
111065
111926
|
* - EXT_mesh_gpu_instancing
|
|
111927
|
+
* - EXT_texture_webp
|
|
111066
111928
|
*
|
|
111067
111929
|
* The following glTF 2.0 extension is supported by an external user plugin:
|
|
111068
111930
|
*
|
|
@@ -112505,15 +113367,30 @@ class GLTFWriter {
|
|
|
112505
113367
|
|
|
112506
113368
|
}
|
|
112507
113369
|
|
|
112508
|
-
|
|
113370
|
+
const mimeType = map.userData.mimeType;
|
|
112509
113371
|
|
|
112510
|
-
|
|
113372
|
+
const imageIndex = this.processImage( map.image, map.format, map.flipY, mimeType );
|
|
112511
113373
|
|
|
112512
113374
|
const textureDef = {
|
|
112513
|
-
sampler: this.processSampler( map )
|
|
112514
|
-
source: this.processImage( map.image, map.format, map.flipY, mimeType )
|
|
113375
|
+
sampler: this.processSampler( map )
|
|
112515
113376
|
};
|
|
112516
113377
|
|
|
113378
|
+
if ( mimeType === 'image/webp' ) {
|
|
113379
|
+
|
|
113380
|
+
textureDef.extensions = textureDef.extensions || {};
|
|
113381
|
+
textureDef.extensions[ 'EXT_texture_webp' ] = {
|
|
113382
|
+
source: imageIndex
|
|
113383
|
+
};
|
|
113384
|
+
|
|
113385
|
+
this.extensionsUsed[ 'EXT_texture_webp' ] = true;
|
|
113386
|
+
this.extensionsRequired[ 'EXT_texture_webp' ] = true;
|
|
113387
|
+
|
|
113388
|
+
} else {
|
|
113389
|
+
|
|
113390
|
+
textureDef.source = imageIndex;
|
|
113391
|
+
|
|
113392
|
+
}
|
|
113393
|
+
|
|
112517
113394
|
if ( map.name ) textureDef.name = map.name;
|
|
112518
113395
|
|
|
112519
113396
|
await this._invokeAllAsync( async function ( ext ) {
|
|
@@ -112804,7 +113681,7 @@ class GLTFWriter {
|
|
|
112804
113681
|
const validVertexAttributes =
|
|
112805
113682
|
/^(POSITION|NORMAL|TANGENT|TEXCOORD_\d+|COLOR_\d+|JOINTS_\d+|WEIGHTS_\d+)$/;
|
|
112806
113683
|
|
|
112807
|
-
if ( ! validVertexAttributes.test( attributeName ) ) attributeName = '_' + attributeName;
|
|
113684
|
+
if ( ! validVertexAttributes.test( attributeName ) && ! attributeName.startsWith( '_' ) ) attributeName = '_' + attributeName;
|
|
112808
113685
|
|
|
112809
113686
|
if ( cache.attributes.has( this.getUID( attribute ) ) ) {
|
|
112810
113687
|
|
|
@@ -112824,12 +113701,12 @@ class GLTFWriter {
|
|
|
112824
113701
|
! ( array instanceof Uint8Array ) ) {
|
|
112825
113702
|
|
|
112826
113703
|
console.warn( 'GLTFExporter: Attribute "skinIndex" converted to type UNSIGNED_SHORT.' );
|
|
112827
|
-
modifiedAttribute =
|
|
113704
|
+
modifiedAttribute = GLTFExporter.Utils.toTypedBufferAttribute( attribute, Uint16Array );
|
|
112828
113705
|
|
|
112829
113706
|
} else if ( ( array instanceof Uint32Array || array instanceof Int32Array ) && ! attributeName.startsWith( '_' ) ) {
|
|
112830
113707
|
|
|
112831
113708
|
console.warn( `GLTFExporter: Attribute "${ attributeName }" converted to type FLOAT.` );
|
|
112832
|
-
modifiedAttribute = GLTFExporter.Utils.
|
|
113709
|
+
modifiedAttribute = GLTFExporter.Utils.toTypedBufferAttribute( attribute, Float32Array );
|
|
112833
113710
|
|
|
112834
113711
|
}
|
|
112835
113712
|
|
|
@@ -113327,6 +114204,13 @@ class GLTFWriter {
|
|
|
113327
114204
|
|
|
113328
114205
|
if ( ! json.nodes ) json.nodes = [];
|
|
113329
114206
|
|
|
114207
|
+
// Handle pivot by creating a container node
|
|
114208
|
+
if ( object.pivot !== null ) {
|
|
114209
|
+
|
|
114210
|
+
return await this._processNodeWithPivotAsync( object );
|
|
114211
|
+
|
|
114212
|
+
}
|
|
114213
|
+
|
|
113330
114214
|
const nodeDef = {};
|
|
113331
114215
|
|
|
113332
114216
|
if ( options.trs ) {
|
|
@@ -113423,6 +114307,126 @@ class GLTFWriter {
|
|
|
113423
114307
|
|
|
113424
114308
|
}
|
|
113425
114309
|
|
|
114310
|
+
/**
|
|
114311
|
+
* Process Object3D node with pivot using container approach
|
|
114312
|
+
* @param {THREE.Object3D} object Object3D with pivot
|
|
114313
|
+
* @return {Promise<number>} Index of the container node
|
|
114314
|
+
*/
|
|
114315
|
+
async _processNodeWithPivotAsync( object ) {
|
|
114316
|
+
|
|
114317
|
+
const json = this.json;
|
|
114318
|
+
const options = this.options;
|
|
114319
|
+
const nodeMap = this.nodeMap;
|
|
114320
|
+
|
|
114321
|
+
const pivot = object.pivot;
|
|
114322
|
+
|
|
114323
|
+
// Container node: holds position + pivot offset, rotation, scale
|
|
114324
|
+
// Animations will target this node
|
|
114325
|
+
const containerDef = {};
|
|
114326
|
+
|
|
114327
|
+
const rotation = object.quaternion.toArray();
|
|
114328
|
+
const position = [
|
|
114329
|
+
object.position.x + pivot.x,
|
|
114330
|
+
object.position.y + pivot.y,
|
|
114331
|
+
object.position.z + pivot.z
|
|
114332
|
+
];
|
|
114333
|
+
const scale = object.scale.toArray();
|
|
114334
|
+
|
|
114335
|
+
if ( ! equalArray( rotation, [ 0, 0, 0, 1 ] ) ) {
|
|
114336
|
+
|
|
114337
|
+
containerDef.rotation = rotation;
|
|
114338
|
+
|
|
114339
|
+
}
|
|
114340
|
+
|
|
114341
|
+
if ( ! equalArray( position, [ 0, 0, 0 ] ) ) {
|
|
114342
|
+
|
|
114343
|
+
containerDef.translation = position;
|
|
114344
|
+
|
|
114345
|
+
}
|
|
114346
|
+
|
|
114347
|
+
if ( ! equalArray( scale, [ 1, 1, 1 ] ) ) {
|
|
114348
|
+
|
|
114349
|
+
containerDef.scale = scale;
|
|
114350
|
+
|
|
114351
|
+
}
|
|
114352
|
+
|
|
114353
|
+
// Store pivot in extras for round-trip reconstruction
|
|
114354
|
+
containerDef.extras = { pivot: pivot.toArray() };
|
|
114355
|
+
|
|
114356
|
+
if ( object.name !== '' ) containerDef.name = String( object.name );
|
|
114357
|
+
|
|
114358
|
+
this.serializeUserData( object, containerDef );
|
|
114359
|
+
|
|
114360
|
+
const containerIndex = json.nodes.push( containerDef ) - 1;
|
|
114361
|
+
|
|
114362
|
+
// Map original object to container so animations target it
|
|
114363
|
+
nodeMap.set( object, containerIndex );
|
|
114364
|
+
|
|
114365
|
+
// Child node: holds mesh with -pivot offset
|
|
114366
|
+
const childDef = {};
|
|
114367
|
+
|
|
114368
|
+
const childPosition = [ - pivot.x, - pivot.y, - pivot.z ];
|
|
114369
|
+
|
|
114370
|
+
if ( ! equalArray( childPosition, [ 0, 0, 0 ] ) ) {
|
|
114371
|
+
|
|
114372
|
+
childDef.translation = childPosition;
|
|
114373
|
+
|
|
114374
|
+
}
|
|
114375
|
+
|
|
114376
|
+
if ( object.isMesh || object.isLine || object.isPoints ) {
|
|
114377
|
+
|
|
114378
|
+
const meshIndex = await this.processMeshAsync( object );
|
|
114379
|
+
|
|
114380
|
+
if ( meshIndex !== null ) childDef.mesh = meshIndex;
|
|
114381
|
+
|
|
114382
|
+
} else if ( object.isCamera ) {
|
|
114383
|
+
|
|
114384
|
+
childDef.camera = this.processCamera( object );
|
|
114385
|
+
|
|
114386
|
+
}
|
|
114387
|
+
|
|
114388
|
+
if ( object.isSkinnedMesh ) this.skins.push( object );
|
|
114389
|
+
|
|
114390
|
+
const childIndex = json.nodes.push( childDef ) - 1;
|
|
114391
|
+
|
|
114392
|
+
// Build children array for container
|
|
114393
|
+
const containerChildren = [ childIndex ];
|
|
114394
|
+
|
|
114395
|
+
// Process object's children as children of the child node
|
|
114396
|
+
if ( object.children.length > 0 ) {
|
|
114397
|
+
|
|
114398
|
+
const grandchildren = [];
|
|
114399
|
+
|
|
114400
|
+
for ( let i = 0, l = object.children.length; i < l; i ++ ) {
|
|
114401
|
+
|
|
114402
|
+
const child = object.children[ i ];
|
|
114403
|
+
|
|
114404
|
+
if ( child.visible || options.onlyVisible === false ) {
|
|
114405
|
+
|
|
114406
|
+
const childNodeIndex = await this.processNodeAsync( child );
|
|
114407
|
+
|
|
114408
|
+
if ( childNodeIndex !== null ) grandchildren.push( childNodeIndex );
|
|
114409
|
+
|
|
114410
|
+
}
|
|
114411
|
+
|
|
114412
|
+
}
|
|
114413
|
+
|
|
114414
|
+
if ( grandchildren.length > 0 ) childDef.children = grandchildren;
|
|
114415
|
+
|
|
114416
|
+
}
|
|
114417
|
+
|
|
114418
|
+
containerDef.children = containerChildren;
|
|
114419
|
+
|
|
114420
|
+
await this._invokeAllAsync( function ( ext ) {
|
|
114421
|
+
|
|
114422
|
+
ext.writeNode && ext.writeNode( object, containerDef );
|
|
114423
|
+
|
|
114424
|
+
} );
|
|
114425
|
+
|
|
114426
|
+
return containerIndex;
|
|
114427
|
+
|
|
114428
|
+
}
|
|
114429
|
+
|
|
113426
114430
|
/**
|
|
113427
114431
|
* Process Scene
|
|
113428
114432
|
* @param {Scene} scene Scene to process
|
|
@@ -114510,9 +115514,9 @@ GLTFExporter.Utils = {
|
|
|
114510
115514
|
|
|
114511
115515
|
},
|
|
114512
115516
|
|
|
114513
|
-
|
|
115517
|
+
toTypedBufferAttribute: function ( srcAttribute, TypedArray ) {
|
|
114514
115518
|
|
|
114515
|
-
const dstAttribute = new BufferAttribute( new
|
|
115519
|
+
const dstAttribute = new BufferAttribute( new TypedArray( srcAttribute.count * srcAttribute.itemSize ), srcAttribute.itemSize, false );
|
|
114516
115520
|
|
|
114517
115521
|
if ( ! srcAttribute.normalized && ! srcAttribute.isInterleavedBufferAttribute ) {
|
|
114518
115522
|
|