@xviewer.js/core 1.0.4-alpha.1 → 1.0.4-alpha.10

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/module.js CHANGED
@@ -4,10 +4,10 @@ import { GLTFLoader as GLTFLoader$1 } from 'three/examples/jsm/loaders/GLTFLoade
4
4
  import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
5
5
  import { MeshoptDecoder } from 'three/examples/jsm/libs/meshopt_decoder.module.js';
6
6
  import * as THREE from 'three';
7
- import { EquirectangularReflectionMapping, FileLoader, TextureLoader as TextureLoader$1, SRGBColorSpace, CubeUVReflectionMapping, Mesh, BoxGeometry, SphereGeometry, PlaneGeometry, MathUtils, Vector3, Vector2, LinearInterpolant, Object3D, Plane as Plane$1, Matrix4, Vector4, PerspectiveCamera, WebGLRenderTarget, LinearMipMapLinearFilter, LinearFilter, HalfFloatType, AnimationMixer, Color, OrthographicCamera, MeshDepthMaterial, ShaderMaterial, Euler, Group, REVISION, Box3, Sphere as Sphere$1, Raycaster, Quaternion, Spherical, UniformsUtils, NoBlending, AdditiveBlending, FloatType, UnsignedByteType, LinearSRGBColorSpace, NearestFilter, ClampToEdgeWrapping, WebGLCubeRenderTarget, DataTexture, RGBAFormat, UVMapping, BufferGeometry, Float32BufferAttribute, Scene, WebGLRenderer, LinearToneMapping, PCFSoftShadowMap, LoadingManager, PMREMGenerator, CubeCamera, ShaderLib, ShaderChunk } from 'three';
7
+ import { EquirectangularReflectionMapping, FileLoader, TextureLoader as TextureLoader$1, SRGBColorSpace, CubeUVReflectionMapping, Mesh, BoxGeometry, SphereGeometry, PlaneGeometry, MathUtils, Vector3, Vector2, LinearInterpolant, Object3D, Plane as Plane$1, Matrix4, Vector4, PerspectiveCamera, WebGLRenderTarget, LinearMipMapLinearFilter, LinearFilter, HalfFloatType, AnimationMixer, Color, OrthographicCamera, MeshDepthMaterial, ShaderMaterial, Euler, Group, REVISION, Box3, Sphere as Sphere$1, Raycaster, Quaternion, Spherical, UniformsUtils, NoBlending, AdditiveBlending, FloatType, UnsignedByteType, LinearSRGBColorSpace, NearestFilter, ClampToEdgeWrapping, WebGLCubeRenderTarget, DataTexture, RGBAFormat, UVMapping, BufferGeometry, Float32BufferAttribute, Scene, WebGLRenderer, LinearToneMapping, PCFSoftShadowMap, LoadingManager, PMREMGenerator, CubeCamera, ShaderLib, ShaderChunk, BufferAttribute, NormalBlending } from 'three';
8
8
  import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js';
9
9
  import { SVGLoader as SVGLoader$1 } from 'three/examples/jsm/loaders/SVGLoader.js';
10
- import { KTX2Loader as KTX2Loader$1 } from 'three/examples/jsm/loaders/KTX2Loader';
10
+ import { KTX2Loader as KTX2Loader$1 } from 'three/examples/jsm/loaders/KTX2Loader.js';
11
11
  import { HorizontalBlurShader, VerticalBlurShader } from 'three/examples/jsm/Addons.js';
12
12
 
13
13
  class EventEmitter {
@@ -145,7 +145,6 @@ function getClassInstance(constructor, args = []) {
145
145
 
146
146
  class Loader {
147
147
  static _setUserData(node) {
148
- const keys = Loader._texKeys;
149
148
  const meshes = [];
150
149
  const textures = {};
151
150
  const materials = {};
@@ -163,7 +162,7 @@ class Loader {
163
162
  queue.push(...object.children);
164
163
  }
165
164
  Object.values(materials).forEach((mat)=>{
166
- keys.forEach((k)=>{
165
+ Loader._texKeys.forEach((k)=>{
167
166
  let tex = mat[k];
168
167
  if (tex) {
169
168
  textures[tex.uuid] = tex;
@@ -224,13 +223,10 @@ class FBXLoader extends Loader {
224
223
  loader.manager = manager;
225
224
  loader.setPath(path);
226
225
  loader.setResourcePath(resourcePath);
227
- const loadCallback = (node)=>{
228
- onLoad(Loader._setUserData(node));
229
- };
230
226
  if (buffer) {
231
- loadCallback(loader.parse(buffer, resourcePath));
227
+ onLoad(loader.parse(buffer, resourcePath));
232
228
  } else {
233
- loader.load(url, loadCallback, onProgress, onError);
229
+ loader.load(url, onLoad, onProgress, onError);
234
230
  }
235
231
  }
236
232
  constructor(...args){
@@ -257,15 +253,10 @@ class GLTFLoader extends Loader {
257
253
  loader.manager = manager;
258
254
  loader.setPath(path);
259
255
  loader.setResourcePath(resourcePath);
260
- const loadCallback = (gltf)=>{
261
- const node = gltf.scene;
262
- node.animations.push(...gltf.animations);
263
- onLoad(Loader._setUserData(node));
264
- };
265
256
  if (buffer) {
266
- loader.parse(buffer, resourcePath, loadCallback, onError);
257
+ loader.parse(buffer, resourcePath, onLoad, onError);
267
258
  } else {
268
- loader.load(url, loadCallback, onProgress, onError);
259
+ loader.load(url, onLoad, onProgress, onError);
269
260
  }
270
261
  }
271
262
  constructor(...args){
@@ -359,15 +350,10 @@ class BINLoader extends Loader {
359
350
  loader.manager = manager;
360
351
  loader.setPath(path);
361
352
  loader.setResourcePath(resourcePath);
362
- const loadCallback = (gltf)=>{
363
- const node = gltf.scene;
364
- node.animations.push(...gltf.animations);
365
- onLoad(Loader._setUserData(node));
366
- };
367
353
  if (buffer) {
368
- loader.parse(buffer, resourcePath, loadCallback, onError);
354
+ loader.parse(buffer, resourcePath, onLoad, onError);
369
355
  } else {
370
- loader.load(url, loadCallback, onProgress, onError);
356
+ loader.load(url, onLoad, onProgress, onError);
371
357
  }
372
358
  }
373
359
  constructor(...args){
@@ -439,11 +425,11 @@ class SVGLoader extends Loader {
439
425
  SVGLoader.Primitive = SVGLoader$1;
440
426
 
441
427
  class KTX2Loader extends Loader {
442
- load({ url, path, resourcePath, manager, texSettings, onLoad, onProgress, onError }) {
428
+ load({ url, path, resourcePath, transcoderPath, manager, texSettings, onLoad, onProgress, onError }) {
443
429
  let loader = this._loader;
444
430
  if (loader === undefined) {
445
431
  loader = this._loader = new KTX2Loader$1();
446
- loader.setTranscoderPath("three/examples/js/libs/basis/");
432
+ loader.setTranscoderPath(transcoderPath);
447
433
  loader.detectSupport(this.viewer.renderer);
448
434
  }
449
435
  loader.manager = manager;
@@ -2225,8 +2211,7 @@ class ComponentScheduler {
2225
2211
  if (comp.onEnable) {
2226
2212
  comp.onEnable();
2227
2213
  }
2228
- if (typeof comp.start === "function" && !comp.flags.isStartCalled) {
2229
- comp.flags.isStartCalled = true;
2214
+ if (typeof comp.start === "function") {
2230
2215
  this.startInvoker.add(comp);
2231
2216
  }
2232
2217
  if (typeof comp.update === "function") {
@@ -2456,12 +2441,12 @@ ComponentManager._infoMap = new Map();
2456
2441
 
2457
2442
  class Renderer extends Component {
2458
2443
  render(dt) {
2459
- const { renderer, scene, camera } = this.context;
2444
+ const { renderer, scene, camera } = this.viewer;
2460
2445
  renderer.setRenderTarget(null);
2461
2446
  renderer.render(scene, camera);
2462
2447
  }
2463
2448
  resize(width, height) {
2464
- const { renderer } = this.context;
2449
+ const { renderer } = this.viewer;
2465
2450
  renderer.setSize(width, height);
2466
2451
  }
2467
2452
  constructor(...args){
@@ -2581,6 +2566,60 @@ class Pressability {
2581
2566
  }
2582
2567
  }
2583
2568
 
2569
+ const PIXEL_STEP = 10;
2570
+ const LINE_HEIGHT = 40;
2571
+ const PAGE_HEIGHT = 800;
2572
+ function normalizeWheel(/*object*/ event) /*object*/ {
2573
+ let sX = 0, sY = 0, pX = 0, pY = 0; // pixelX, pixelY
2574
+ // Legacy
2575
+ if ('detail' in event) {
2576
+ sY = event.detail;
2577
+ }
2578
+ if ('wheelDelta' in event) {
2579
+ sY = -event.wheelDelta / 120;
2580
+ }
2581
+ if ('wheelDeltaY' in event) {
2582
+ sY = -event.wheelDeltaY / 120;
2583
+ }
2584
+ if ('wheelDeltaX' in event) {
2585
+ sX = -event.wheelDeltaX / 120;
2586
+ }
2587
+ // side scrolling on FF with DOMMouseScroll
2588
+ if ('axis' in event && event.axis === event.HORIZONTAL_AXIS) {
2589
+ sX = sY;
2590
+ sY = 0;
2591
+ }
2592
+ pX = sX * PIXEL_STEP;
2593
+ pY = sY * PIXEL_STEP;
2594
+ if ('deltaY' in event) {
2595
+ pY = event.deltaY;
2596
+ }
2597
+ if ('deltaX' in event) {
2598
+ pX = event.deltaX;
2599
+ }
2600
+ if ((pX || pY) && event.deltaMode) {
2601
+ if (event.deltaMode == 1) {
2602
+ pX *= LINE_HEIGHT;
2603
+ pY *= LINE_HEIGHT;
2604
+ } else {
2605
+ pX *= PAGE_HEIGHT;
2606
+ pY *= PAGE_HEIGHT;
2607
+ }
2608
+ }
2609
+ // Fall-back if spin cannot be determined
2610
+ if (pX && !sX) {
2611
+ sX = pX < 1 ? -1 : 1;
2612
+ }
2613
+ if (pY && !sY) {
2614
+ sY = pY < 1 ? -1 : 1;
2615
+ }
2616
+ return {
2617
+ spinX: sX,
2618
+ spinY: sY,
2619
+ pixelX: pX,
2620
+ pixelY: pY
2621
+ };
2622
+ }
2584
2623
  class DeviceInput extends Component {
2585
2624
  get pointer() {
2586
2625
  return this._pointer;
@@ -2597,9 +2636,18 @@ class DeviceInput extends Component {
2597
2636
  get prePointerPixel() {
2598
2637
  return this._prePointerPixel;
2599
2638
  }
2639
+ get preTouches() {
2640
+ return this._preTouches;
2641
+ }
2600
2642
  get mouseWheel() {
2601
2643
  return this._mouseWheel;
2602
2644
  }
2645
+ get touchStart() {
2646
+ return this._touchStart;
2647
+ }
2648
+ get touchMoving() {
2649
+ return this._touchMoving;
2650
+ }
2603
2651
  get touchCount() {
2604
2652
  return this._touchCount;
2605
2653
  }
@@ -2663,7 +2711,12 @@ class DeviceInput extends Component {
2663
2711
  lastUpdate(dt) {
2664
2712
  this._prePointer.copy(this._pointer);
2665
2713
  this._prePointerPixel.copy(this._pointerPixel);
2714
+ for(let i = this._touchCount; i--;){
2715
+ this._preTouches[i].id = this._touches[i].id;
2716
+ this._preTouches[i].position.copy(this._touches[i].position);
2717
+ }
2666
2718
  this._mouseWheel = 0;
2719
+ this._touchStart = false;
2667
2720
  }
2668
2721
  connect(target, event) {
2669
2722
  switch(event){
@@ -2734,14 +2787,16 @@ class DeviceInput extends Component {
2734
2787
  const isDocument = target instanceof Document;
2735
2788
  const width = isDocument ? window.innerWidth : target.offsetWidth;
2736
2789
  const height = isDocument ? window.innerHeight : target.offsetHeight;
2737
- this._pointer.x = e.clientX / width * 2 - 1;
2738
- this._pointer.y = 1 - e.clientY / height * 2;
2739
- this._pointerPixel.set(e.clientX, e.clientY);
2790
+ this._pointer.x = e.pageX / width * 2 - 1;
2791
+ this._pointer.y = 1 - e.pageY / height * 2;
2792
+ this._pointerPixel.set(e.pageX, e.pageY);
2740
2793
  }
2741
2794
  _onPointerDown(e) {
2742
2795
  e = this._remapPointer(e);
2743
2796
  this._pointerButton = e.button;
2744
2797
  this._computePointer(e);
2798
+ this._prePointer.copy(this._pointer);
2799
+ this._prePointerPixel.copy(this._pointerPixel);
2745
2800
  this._pressability.pointerDown(this._pointer, this.viewer.camera);
2746
2801
  this.viewer.emit(DeviceInput.POINTER_DOWN, e);
2747
2802
  }
@@ -2759,33 +2814,54 @@ class DeviceInput extends Component {
2759
2814
  this.viewer.emit(DeviceInput.POINTER_MOVE, e);
2760
2815
  }
2761
2816
  _onMouseWheel(e) {
2762
- this._mouseWheel = e.deltaY || e.wheelDelta;
2817
+ this._mouseWheel = this._normalizeWheel(e).pixelY;
2763
2818
  this.viewer.emit(DeviceInput.MOUSE_WHEEL, e);
2764
2819
  }
2765
2820
  _onTouchStart(e) {
2821
+ this._touchStart = true;
2766
2822
  e = this._remapTouch(e);
2823
+ const curr = e.touches;
2824
+ const touches = this._touches;
2825
+ const preTouches = this._preTouches;
2826
+ for(let i = curr.length; i--;){
2827
+ if (touches[i] === undefined) {
2828
+ touches[i] = {
2829
+ id: -1,
2830
+ position: new Vector2()
2831
+ };
2832
+ }
2833
+ const touch = curr[i];
2834
+ touches[i].id = touch.identifier;
2835
+ touches[i].position.set(touch.pageX, touch.pageY);
2836
+ if (preTouches[i] === undefined) {
2837
+ preTouches[i] = {
2838
+ id: touches[i].id,
2839
+ position: touches[i].position.clone()
2840
+ };
2841
+ } else {
2842
+ preTouches[i].id = touches[i].id;
2843
+ preTouches[i].position.copy(touches[i].position);
2844
+ }
2845
+ }
2846
+ this._touchCount = curr.length;
2767
2847
  this.viewer.emit(DeviceInput.TOUCH_START, e);
2768
2848
  }
2769
2849
  _onTouchEnd(e) {
2850
+ this._touchMoving = false;
2770
2851
  e = this._remapTouch(e);
2771
2852
  this.viewer.emit(DeviceInput.TOUCH_END, e);
2772
2853
  }
2773
2854
  _onTouchMove(e) {
2855
+ this._touchMoving = true;
2774
2856
  e = this._remapTouch(e);
2775
- const touches = e.touches;
2776
- const touchesTo = this._touches;
2777
- for(let i = touches.length; i--;){
2778
- if (touchesTo[i] == undefined) {
2779
- touchesTo[i] = {
2780
- id: -1,
2781
- position: new Vector2()
2782
- };
2783
- }
2784
- const touch = touches[i];
2785
- touchesTo[i].id = touch.identifier;
2786
- touchesTo[i].position.set(touch.pageX, touch.pageY);
2787
- }
2788
- this._touchCount = touches.length;
2857
+ const curr = e.touches;
2858
+ const touches = this._touches;
2859
+ for(let i = curr.length; i--;){
2860
+ const touch = curr[i];
2861
+ touches[i].id = touch.identifier;
2862
+ touches[i].position.set(touch.pageX, touch.pageY);
2863
+ }
2864
+ this._touchCount = curr.length;
2789
2865
  this.viewer.emit(DeviceInput.TOUCH_MOVE, e);
2790
2866
  }
2791
2867
  _onKeyDown(e) {
@@ -2800,9 +2876,10 @@ class DeviceInput extends Component {
2800
2876
  this._keys[e.key] = false;
2801
2877
  this.viewer.emit(DeviceInput.KEYUP, e);
2802
2878
  }
2803
- constructor(target){
2804
- super(), this._listeners = [], this._touches = [], this._touchCount = 0, this._pointer = new Vector2(), this._pointerPixel = new Vector2(), this._pointerButton = -1, this._prePointer = new Vector2(), this._prePointerPixel = new Vector2(), this._mouseWheel = 0, this._keys = {}, this._pressability = new Pressability();
2805
- this._target = target;
2879
+ constructor(option){
2880
+ super(), this._listeners = [], this._touches = [], this._touchCount = 0, this._touchStart = false, this._touchMoving = false, this._pointer = new Vector2(), this._pointerPixel = new Vector2(), this._pointerButton = -1, this._prePointer = new Vector2(), this._prePointerPixel = new Vector2(), this._preTouches = [], this._mouseWheel = 0, this._keys = {}, this._pressability = new Pressability();
2881
+ this._target = option.source;
2882
+ this._normalizeWheel = option.normalizeWheel || normalizeWheel;
2806
2883
  }
2807
2884
  }
2808
2885
  DeviceInput.CLICK = "click";
@@ -3646,7 +3723,9 @@ uniform float roughness;
3646
3723
  uniform float metalness;
3647
3724
  uniform sampler2D map;
3648
3725
  uniform sampler2D normalMap;
3726
+ uniform vec4 normalScaleBias;
3649
3727
  uniform sampler2D roughnessMap;
3728
+ uniform vec4 roughnessScaleBias;
3650
3729
  uniform sampler2D aoMap;
3651
3730
  uniform float aoMapIntensity;
3652
3731
  uniform sampler2D lightMap;
@@ -3684,7 +3763,7 @@ void main() {
3684
3763
  vec2 reflectUv = coord.xy;
3685
3764
 
3686
3765
  #ifdef USE_NORMALMAP
3687
- vec4 texelNormal = texture2D(normalMap, UV_NORMAL);
3766
+ vec4 texelNormal = texture2D(normalMap, UV_NORMAL * normalScaleBias.xy + normalScaleBias.zw);
3688
3767
  vec3 normal = normalize(vec3(texelNormal.r * 2.0 - 1.0, texelNormal.b, texelNormal.g * 2.0 - 1.0));
3689
3768
  reflectUv += coord.z * normal.xz * 0.05;
3690
3769
  #endif
@@ -3711,7 +3790,7 @@ void main() {
3711
3790
  float roughnessFactor = roughness;
3712
3791
 
3713
3792
  #ifdef USE_ROUGHNESSMAP
3714
- roughnessFactor *= texture2D(roughnessMap, UV_ROUGHNESS).g * roughness;
3793
+ roughnessFactor *= texture2D(roughnessMap, UV_ROUGHNESS * roughnessScaleBias.xy + roughnessScaleBias.zw).g * roughness;
3715
3794
  #endif
3716
3795
 
3717
3796
  computeMultiscattering( geometryNormal, geometryViewDir, specularColor, specularF90, roughnessFactor, singleScattering, multiScattering );
@@ -3809,12 +3888,24 @@ class ReflectorMaterial extends ShaderMaterial {
3809
3888
  set roughnessMap(v) {
3810
3889
  this.uniforms.roughnessMap.value = v;
3811
3890
  }
3891
+ get roughnessScaleBias() {
3892
+ return this.uniforms.roughnessScaleBias.value;
3893
+ }
3894
+ set roughnessScaleBias(v) {
3895
+ this.uniforms.roughnessScaleBias.value.copy(v);
3896
+ }
3812
3897
  get normalMap() {
3813
3898
  return this.uniforms.normalMap.value;
3814
3899
  }
3815
3900
  set normalMap(v) {
3816
3901
  this.uniforms.normalMap.value = v;
3817
3902
  }
3903
+ get normalScaleBias() {
3904
+ return this.uniforms.normalScaleBias.value;
3905
+ }
3906
+ set normalScaleBias(v) {
3907
+ this.uniforms.normalScaleBias.value.copy(v);
3908
+ }
3818
3909
  get aoMap() {
3819
3910
  return this.uniforms.aoMap.value;
3820
3911
  }
@@ -3879,9 +3970,15 @@ class ReflectorMaterial extends ShaderMaterial {
3879
3970
  roughnessMap: {
3880
3971
  value: null
3881
3972
  },
3973
+ roughnessScaleBias: {
3974
+ value: new Vector4(1, 1, 0, 0)
3975
+ },
3882
3976
  normalMap: {
3883
3977
  value: null
3884
3978
  },
3979
+ normalScaleBias: {
3980
+ value: new Vector4(1, 1, 0, 0)
3981
+ },
3885
3982
  aoMap: {
3886
3983
  value: null
3887
3984
  },
@@ -3927,9 +4024,15 @@ __decorate([
3927
4024
  __decorate([
3928
4025
  property
3929
4026
  ], ReflectorMaterial.prototype, "roughnessMap", null);
4027
+ __decorate([
4028
+ property
4029
+ ], ReflectorMaterial.prototype, "roughnessScaleBias", null);
3930
4030
  __decorate([
3931
4031
  property
3932
4032
  ], ReflectorMaterial.prototype, "normalMap", null);
4033
+ __decorate([
4034
+ property
4035
+ ], ReflectorMaterial.prototype, "normalScaleBias", null);
3933
4036
  __decorate([
3934
4037
  property
3935
4038
  ], ReflectorMaterial.prototype, "aoMap", null);
@@ -4391,19 +4494,15 @@ class ResourceManager {
4391
4494
  }
4392
4495
  return loader;
4393
4496
  }
4394
- loadAsset({ url, buffer, ext, path, resourcePath, dracoPath, manager, onProgress, ...props }) {
4497
+ loadAsset({ url, ext, onProgress, ...props }) {
4395
4498
  return new Promise((resolve, reject)=>{
4396
4499
  const sel = ext || url && ResourceManager.extension(url) || "";
4397
4500
  const texSettings = ResourceManager._splitTextureSettings(props);
4398
4501
  if (this._loaders.has(sel)) {
4399
4502
  this._loaders.get(sel).load({
4400
4503
  url,
4401
- buffer,
4402
4504
  texSettings,
4403
- path,
4404
- resourcePath,
4405
- dracoPath,
4406
- manager,
4505
+ ...props,
4407
4506
  onProgress,
4408
4507
  onLoad: resolve,
4409
4508
  onError: (err)=>{
@@ -4860,6 +4959,9 @@ class Viewer extends EventEmitter {
4860
4959
  clearColor(renderTarget, color, alpha) {
4861
4960
  Viewer.ClearColor(this._renderer, renderTarget, color, alpha);
4862
4961
  }
4962
+ stash(renderTarget, callback, clearColor, clearAlpha) {
4963
+ Viewer.Stash(this._renderer, renderTarget, callback, clearColor, clearAlpha);
4964
+ }
4863
4965
  blur(blurLevel, shadingScale, inputBuffer, tempBuffer, outputBuffer, fixedOutput) {
4864
4966
  Viewer.Blur(this._renderer, blurLevel, shadingScale, inputBuffer, tempBuffer, outputBuffer, fixedOutput);
4865
4967
  }
@@ -4955,7 +5057,7 @@ class Viewer extends EventEmitter {
4955
5057
  renderer.autoClear = true;
4956
5058
  renderer.setRenderTarget(renderTarget);
4957
5059
  clearColor !== undefined && renderer.setClearColor(clearColor, clearAlpha);
4958
- callback && callback();
5060
+ callback && callback(renderer);
4959
5061
  renderer.autoClear = autoClear;
4960
5062
  renderer.setRenderTarget(RT);
4961
5063
  clearColor !== undefined && renderer.setClearColor(color, alpha);
@@ -4991,7 +5093,7 @@ class Viewer extends EventEmitter {
4991
5093
  near: 0.1,
4992
5094
  far: 1000,
4993
5095
  position: new Vector3(0, 0, 4)
4994
- }, targetFrameRate = -1, fixedFrameTime = false, colorSpace = SRGBColorSpace, toneMapping = LinearToneMapping, toneMappingExposure = 1, maxDPR = 1.5, path = "", resourcePath = "", dracoPath = "https://www.gstatic.com/draco/v1/decoders/", orientation = Orientation.AUTO, loader = {}, tasker = {}, ...webglOpts } = {}){
5096
+ }, targetFrameRate = -1, fixedFrameTime = false, colorSpace = SRGBColorSpace, toneMapping = LinearToneMapping, toneMappingExposure = 1, maxDPR = 1.5, path = "", resourcePath = "", dracoPath = "https://www.gstatic.com/draco/v1/decoders/", transcoderPath = "three/examples/js/libs/basis/", orientation = Orientation.AUTO, loader = {}, tasker = {}, ...webglOpts } = {}){
4995
5097
  super(), this._instanceId = Viewer.instanceCount++, this._dpr = 1, this._width = 1, this._height = 1, this._viewport = {
4996
5098
  width: 1,
4997
5099
  height: 1,
@@ -5049,12 +5151,15 @@ class Viewer extends EventEmitter {
5049
5151
  path,
5050
5152
  resourcePath,
5051
5153
  dracoPath,
5154
+ transcoderPath,
5052
5155
  manager: this._loadingManager
5053
5156
  };
5054
5157
  this._mount = applyProps(new Object3D(), {
5055
5158
  name: "Mount"
5056
5159
  });
5057
- this._input = this.add(new DeviceInput(input || this._canvas));
5160
+ this._input = this.add(new DeviceInput(input || {
5161
+ source: this._canvas
5162
+ }));
5058
5163
  this.add(Renderer);
5059
5164
  this.addLoader(GLTFLoader);
5060
5165
  this.addLoader(HDRLoader);
@@ -5790,5 +5895,690 @@ function getFilesFromItemList(items, onDone) {
5790
5895
  }
5791
5896
  }
5792
5897
 
5793
- export { AccumulativeShadows, Animation, AnimationCurve, BINLoader, Box, BoxProjection, Center, Component, ContactShadows, DependentMode, DeviceInput, DropFile, EXRLoader, Easing, Environment, EventEmitter, FBXLoader, FInterpConstantTo, FInterpTo, FreelookVirtualCamera, GLTFLoader, HDRLoader, JSONLoader, KTX2Loader, Loader, Logger, ObjectInstance, Orientation, PerformanceMonitor, Perlin, Plane, PropertyManager, QInterpConstantTo, QInterpTo, Quat_AngularDistance, Quat_Equals, Quat_exponentialDamp, Quat_quarticDamp, Quat_smoothDamp, RandomizedLight, Reflector, ReflectorMaterial, RenderTexture, Renderer, ResizeMode, ResourceManager, SVGLoader, ShadowMaterial, Sphere, SystemInfo, Task, TextureLoader, VInterpConstantTo, VInterpTo, Vec3_smoothDamp, Vector3_NEG_ONE, Vector3_ONE, Vector3_RIGHT, Vector3_UNIT_X, Vector3_UNIT_Y, Vector3_UNIT_Z, Vector3_UP, Vector3_ZERO, Viewer, applyProps, dependencies, exponentialDamp, find, frag_BoxfilterBlur, frag_cubeMapToPanorama, frag_panoramaToCubeMap, getChildByName, getChildren, getClassInstance, getShaderMaterial, mixin, property, quarticDamp, queryValues, smoothDamp, vert_fullscreen };
5898
+ const newline = /\n/;
5899
+ const newlineChar = '\n';
5900
+ const whitespace = /\s/;
5901
+ function wordwrap(text, opt) {
5902
+ opt = opt || {};
5903
+ //zero width results in nothing visible
5904
+ if (opt.width === 0 && opt.mode !== 'nowrap') return [];
5905
+ text = text || '';
5906
+ const width = typeof opt.width === 'number' ? opt.width : Number.MAX_VALUE;
5907
+ const start = Math.max(0, opt.start || 0);
5908
+ const end = typeof opt.end === 'number' ? opt.end : text.length;
5909
+ const mode = opt.mode;
5910
+ const letterSpacing = opt.letterSpacing || 0;
5911
+ const measure = opt.measure || monospace;
5912
+ if (mode === 'pre') return pre(measure, text, start, end, width, letterSpacing);
5913
+ else return greedy(measure, text, start, end, width, mode, letterSpacing);
5914
+ }
5915
+ function idxOf(text, chr, start, end) {
5916
+ var idx = text.indexOf(chr, start);
5917
+ if (idx === -1 || idx > end) return end;
5918
+ return idx;
5919
+ }
5920
+ function isWhitespace(chr) {
5921
+ return whitespace.test(chr);
5922
+ }
5923
+ function pre(measure, text, start, end, width, letterSpacing) {
5924
+ var lines = [];
5925
+ var lineStart = start;
5926
+ for(var i = start; i < end && i < text.length; i++){
5927
+ var chr = text.charAt(i);
5928
+ var isNewline = newline.test(chr);
5929
+ //If we've reached a newline, then step down a line
5930
+ //Or if we've reached the EOF
5931
+ if (isNewline || i === end - 1) {
5932
+ var lineEnd = isNewline ? i : i + 1;
5933
+ var measured = measure(text, lineStart, lineEnd, width, letterSpacing);
5934
+ lines.push(measured);
5935
+ lineStart = i + 1;
5936
+ }
5937
+ }
5938
+ return lines;
5939
+ }
5940
+ function greedy(measure, text, start, end, width, mode, letterSpacing) {
5941
+ //A greedy word wrapper based on LibGDX algorithm
5942
+ //https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g2d/BitmapFontCache.java
5943
+ var lines = [];
5944
+ var testWidth = width;
5945
+ //if 'nowrap' is specified, we only wrap on newline chars
5946
+ if (mode === 'nowrap') testWidth = Number.MAX_VALUE;
5947
+ while(start < end && start < text.length){
5948
+ //get next newline position
5949
+ var newLine = idxOf(text, newlineChar, start, end);
5950
+ //eat whitespace at start of line
5951
+ while(start < newLine){
5952
+ if (!isWhitespace(text.charAt(start))) break;
5953
+ start++;
5954
+ }
5955
+ //determine visible # of glyphs for the available width
5956
+ var measured = measure(text, start, newLine, testWidth, letterSpacing);
5957
+ var lineEnd = start + (measured.end - measured.start);
5958
+ var nextStart = lineEnd + newlineChar.length;
5959
+ //if we had to cut the line before the next newline...
5960
+ if (lineEnd < newLine) {
5961
+ //find char to break on
5962
+ while(lineEnd > start){
5963
+ if (isWhitespace(text.charAt(lineEnd))) break;
5964
+ lineEnd--;
5965
+ }
5966
+ if (lineEnd === start) {
5967
+ if (nextStart > start + newlineChar.length) nextStart--;
5968
+ lineEnd = nextStart; // If no characters to break, show all.
5969
+ } else {
5970
+ nextStart = lineEnd;
5971
+ //eat whitespace at end of line
5972
+ while(lineEnd > start){
5973
+ if (!isWhitespace(text.charAt(lineEnd - newlineChar.length))) break;
5974
+ lineEnd--;
5975
+ }
5976
+ }
5977
+ }
5978
+ if (lineEnd >= start) {
5979
+ var result = measure(text, start, lineEnd, testWidth);
5980
+ lines.push(result);
5981
+ }
5982
+ start = nextStart;
5983
+ }
5984
+ return lines;
5985
+ }
5986
+ //determines the visible number of glyphs within a given width
5987
+ function monospace(text, start, end, width) {
5988
+ var glyphs = Math.min(width, end - start);
5989
+ return {
5990
+ start: start,
5991
+ end: start + glyphs
5992
+ };
5993
+ }
5994
+
5995
+ const X_HEIGHTS = [
5996
+ 'x',
5997
+ 'e',
5998
+ 'a',
5999
+ 'o',
6000
+ 'n',
6001
+ 's',
6002
+ 'r',
6003
+ 'c',
6004
+ 'u',
6005
+ 'm',
6006
+ 'v',
6007
+ 'w',
6008
+ 'z'
6009
+ ];
6010
+ const M_WIDTHS = [
6011
+ 'm',
6012
+ 'w'
6013
+ ];
6014
+ const CAP_HEIGHTS = [
6015
+ 'H',
6016
+ 'I',
6017
+ 'N',
6018
+ 'E',
6019
+ 'F',
6020
+ 'K',
6021
+ 'L',
6022
+ 'T',
6023
+ 'U',
6024
+ 'V',
6025
+ 'W',
6026
+ 'X',
6027
+ 'Y',
6028
+ 'Z'
6029
+ ];
6030
+ const TAB_ID = '\t'.charCodeAt(0);
6031
+ const SPACE_ID = ' '.charCodeAt(0);
6032
+ const ALIGN_LEFT = 0, ALIGN_CENTER = 1, ALIGN_RIGHT = 2;
6033
+ function findChar(array, value, start) {
6034
+ start = start || 0;
6035
+ for(let i = start; i < array.length; i++){
6036
+ if (array[i].id === value) {
6037
+ return i;
6038
+ }
6039
+ }
6040
+ return -1;
6041
+ }
6042
+ function getGlyphById(font, id) {
6043
+ if (!font.chars || font.chars.length === 0) return null;
6044
+ let glyphIdx = findChar(font.chars, id);
6045
+ if (glyphIdx >= 0) return font.chars[glyphIdx];
6046
+ return null;
6047
+ }
6048
+ function getXHeight(font) {
6049
+ for(let i = 0; i < X_HEIGHTS.length; i++){
6050
+ let id = X_HEIGHTS[i].charCodeAt(0);
6051
+ let idx = findChar(font.chars, id);
6052
+ if (idx >= 0) return font.chars[idx].height;
6053
+ }
6054
+ return 0;
6055
+ }
6056
+ function getMGlyph(font) {
6057
+ for(let i = 0; i < M_WIDTHS.length; i++){
6058
+ let id = M_WIDTHS[i].charCodeAt(0);
6059
+ let idx = findChar(font.chars, id);
6060
+ if (idx >= 0) return font.chars[idx];
6061
+ }
6062
+ return 0;
6063
+ }
6064
+ function getCapHeight(font) {
6065
+ for(let i = 0; i < CAP_HEIGHTS.length; i++){
6066
+ let id = CAP_HEIGHTS[i].charCodeAt(0);
6067
+ let idx = findChar(font.chars, id);
6068
+ if (idx >= 0) return font.chars[idx].height;
6069
+ }
6070
+ return 0;
6071
+ }
6072
+ function getKerning(font, left, right) {
6073
+ if (!font.kernings || font.kernings.length === 0) return 0;
6074
+ let table = font.kernings;
6075
+ for(let i = 0; i < table.length; i++){
6076
+ let kern = table[i];
6077
+ if (kern.first === left && kern.second === right) return kern.amount;
6078
+ }
6079
+ return 0;
6080
+ }
6081
+ function getAlignType(align) {
6082
+ if (align === 'center') return ALIGN_CENTER;
6083
+ else if (align === 'right') return ALIGN_RIGHT;
6084
+ return ALIGN_LEFT;
6085
+ }
6086
+ class BMFontTextLayout {
6087
+ get width() {
6088
+ return this._width;
6089
+ }
6090
+ get height() {
6091
+ return this._height;
6092
+ }
6093
+ get descender() {
6094
+ return this._descender;
6095
+ }
6096
+ get ascender() {
6097
+ return this._ascender;
6098
+ }
6099
+ get xHeight() {
6100
+ return this._xHeight;
6101
+ }
6102
+ get baseline() {
6103
+ return this._baseline;
6104
+ }
6105
+ get capHeight() {
6106
+ return this._capHeight;
6107
+ }
6108
+ get lineHeight() {
6109
+ return this._lineHeight;
6110
+ }
6111
+ get glyphs() {
6112
+ return this._glyphs;
6113
+ }
6114
+ get linesTotal() {
6115
+ return this._linesTotal;
6116
+ }
6117
+ update(font, text, setting) {
6118
+ setting = Object.assign({
6119
+ tabSize: 4,
6120
+ width: 0,
6121
+ letterSpacing: 0,
6122
+ mode: "nowrap",
6123
+ align: "left"
6124
+ }, setting);
6125
+ this._font = font;
6126
+ const measure = this._computeMetrics.bind(this);
6127
+ const lines = wordwrap(text, {
6128
+ measure,
6129
+ ...setting
6130
+ });
6131
+ const minWidth = setting.width || 0;
6132
+ const glyphs = this._glyphs;
6133
+ const maxLineWidth = lines.reduce((prev, line)=>Math.max(prev, line.width, minWidth), 0);
6134
+ var _setting_lineHeight;
6135
+ //the pen position
6136
+ const lineHeight = (_setting_lineHeight = setting.lineHeight) != null ? _setting_lineHeight : font.common.lineHeight;
6137
+ const baseline = font.common.base;
6138
+ const descender = lineHeight - baseline;
6139
+ const letterSpacing = setting.letterSpacing || 0;
6140
+ const height = lineHeight * lines.length - descender;
6141
+ const align = getAlignType(setting.align);
6142
+ var _setting_anchor;
6143
+ const anchor = (_setting_anchor = setting.anchor) != null ? _setting_anchor : [
6144
+ 0.5,
6145
+ 0.5
6146
+ ];
6147
+ this._setupSpaceGlyphs(font, setting);
6148
+ //the metrics for this text layout
6149
+ this._width = maxLineWidth;
6150
+ this._height = height;
6151
+ this._descender = descender;
6152
+ this._baseline = baseline;
6153
+ this._xHeight = getXHeight(font);
6154
+ this._capHeight = getCapHeight(font);
6155
+ this._lineHeight = lineHeight;
6156
+ this._ascender = baseline - this._xHeight; //lineHeight - descender - this._xHeight
6157
+ const anchorOffset = [
6158
+ -maxLineWidth * anchor[0],
6159
+ 2 * lineHeight * anchor[1] - baseline
6160
+ ];
6161
+ let x = 0, y = 0;
6162
+ //draw text along baseline
6163
+ y -= height;
6164
+ glyphs.length = 0;
6165
+ for(let k = 0; k < lines.length; k++){
6166
+ const line = lines[k];
6167
+ let start = line.start;
6168
+ let end = line.end;
6169
+ let lineWidth = line.width;
6170
+ let lastGlyph;
6171
+ //for each glyph in that line...
6172
+ for(let i = start; i < end; i++){
6173
+ let id = text.charCodeAt(i);
6174
+ let glyph = this._getGlyph(font, id);
6175
+ if (glyph) {
6176
+ if (lastGlyph) x += getKerning(font, lastGlyph.id, glyph.id);
6177
+ let tx = x;
6178
+ if (align === ALIGN_CENTER) tx += (maxLineWidth - lineWidth) / 2;
6179
+ else if (align === ALIGN_RIGHT) tx += maxLineWidth - lineWidth;
6180
+ glyphs.push({
6181
+ position: [
6182
+ tx + anchorOffset[0],
6183
+ y + anchorOffset[1]
6184
+ ],
6185
+ data: glyph,
6186
+ index: i,
6187
+ line: k
6188
+ });
6189
+ //move pen forward
6190
+ x += glyph.xadvance + letterSpacing;
6191
+ lastGlyph = glyph;
6192
+ }
6193
+ }
6194
+ //next line down
6195
+ y += lineHeight;
6196
+ x = 0;
6197
+ }
6198
+ this._linesTotal = lines.length;
6199
+ }
6200
+ _setupSpaceGlyphs(font, setting) {
6201
+ //These are fallbacks, when the font doesn't include
6202
+ //' ' or '\t' glyphs
6203
+ if (!font.chars || font.chars.length === 0) return;
6204
+ //try to get space glyph
6205
+ //then fall back to the 'm' or 'w' glyphs
6206
+ //then fall back to the first glyph available
6207
+ const space = Object.assign({}, getGlyphById(font, SPACE_ID) || getMGlyph(font) || font.chars[0]);
6208
+ //and create a fallback for tab
6209
+ const tabWidth = setting.tabSize * space.xadvance;
6210
+ this._fallbackSpaceGlyph = space;
6211
+ this._fallbackTabGlyph = Object.assign(space, {
6212
+ x: 0,
6213
+ y: 0,
6214
+ xadvance: tabWidth,
6215
+ id: TAB_ID,
6216
+ xoffset: 0,
6217
+ yoffset: 0,
6218
+ width: 0,
6219
+ height: 0
6220
+ });
6221
+ }
6222
+ _getGlyph(font, id) {
6223
+ let glyph = getGlyphById(font, id);
6224
+ if (glyph) return glyph;
6225
+ else if (id === TAB_ID) return this._fallbackTabGlyph;
6226
+ else if (id === SPACE_ID) return this._fallbackSpaceGlyph;
6227
+ return null;
6228
+ }
6229
+ _computeMetrics(text, start, end, width, letterSpacing = 0) {
6230
+ let font = this._font;
6231
+ let curPen = 0;
6232
+ let curWidth = 0;
6233
+ let count = 0;
6234
+ let lastGlyph;
6235
+ if (!font.chars || font.chars.length === 0) {
6236
+ return {
6237
+ start: start,
6238
+ end: start,
6239
+ width: 0
6240
+ };
6241
+ }
6242
+ end = Math.min(text.length, end);
6243
+ for(let i = start; i < end; i++){
6244
+ let id = text.charCodeAt(i);
6245
+ let glyph = this._getGlyph(font, id);
6246
+ if (glyph) {
6247
+ //move pen forward
6248
+ glyph.xoffset;
6249
+ let kern = lastGlyph ? getKerning(font, lastGlyph.id, glyph.id) : 0;
6250
+ curPen += kern;
6251
+ let nextPen = curPen + glyph.xadvance + letterSpacing;
6252
+ let nextWidth = curPen + glyph.width;
6253
+ //we've hit our limit; we can't move onto the next glyph
6254
+ if (nextWidth >= width || nextPen >= width) break;
6255
+ //otherwise continue along our line
6256
+ curPen = nextPen;
6257
+ curWidth = nextWidth;
6258
+ lastGlyph = glyph;
6259
+ }
6260
+ count++;
6261
+ }
6262
+ //make sure rightmost edge lines up with rendered glyphs
6263
+ if (lastGlyph) curWidth += lastGlyph.xoffset;
6264
+ return {
6265
+ start: start,
6266
+ end: start + count,
6267
+ width: curWidth
6268
+ };
6269
+ }
6270
+ constructor(){
6271
+ this._width = 0;
6272
+ this._height = 0;
6273
+ this._descender = 0;
6274
+ this._ascender = 0;
6275
+ this._xHeight = 0;
6276
+ this._baseline = 0;
6277
+ this._capHeight = 0;
6278
+ this._lineHeight = 0;
6279
+ this._linesTotal = 0;
6280
+ this._glyphs = [];
6281
+ this._fallbackSpaceGlyph = null;
6282
+ this._fallbackTabGlyph = null;
6283
+ this._font = null;
6284
+ }
6285
+ }
6286
+
6287
+ const itemSize = 2;
6288
+ const box = {
6289
+ min: [
6290
+ 0,
6291
+ 0
6292
+ ],
6293
+ max: [
6294
+ 0,
6295
+ 0
6296
+ ]
6297
+ };
6298
+ function bounds(positions) {
6299
+ const count = positions.length / itemSize;
6300
+ box.min[0] = positions[0];
6301
+ box.min[1] = positions[1];
6302
+ box.max[0] = positions[0];
6303
+ box.max[1] = positions[1];
6304
+ for(let i = 0; i < count; i++){
6305
+ const x = positions[i * itemSize + 0];
6306
+ const y = positions[i * itemSize + 1];
6307
+ box.min[0] = Math.min(x, box.min[0]);
6308
+ box.min[1] = Math.min(y, box.min[1]);
6309
+ box.max[0] = Math.max(x, box.max[0]);
6310
+ box.max[1] = Math.max(y, box.max[1]);
6311
+ }
6312
+ }
6313
+ function computeBox(positions, output) {
6314
+ bounds(positions);
6315
+ output.min.set(box.min[0], box.min[1], 0);
6316
+ output.max.set(box.max[0], box.max[1], 0);
6317
+ }
6318
+ function computeSphere(positions, output) {
6319
+ bounds(positions);
6320
+ const minX = box.min[0];
6321
+ const minY = box.min[1];
6322
+ const maxX = box.max[0];
6323
+ const maxY = box.max[1];
6324
+ const width = maxX - minX;
6325
+ const height = maxY - minY;
6326
+ const length = Math.sqrt(width * width + height * height);
6327
+ output.center.set(minX + width / 2, minY + height / 2, 0);
6328
+ output.radius = length / 2;
6329
+ }
6330
+
6331
+ class BMFontTextGeometry extends BufferGeometry {
6332
+ update(fontAtlas, text, setting) {
6333
+ this.layout.update(fontAtlas.info, text, setting);
6334
+ const { indice, position, uv } = fontAtlas.build(this.layout, setting);
6335
+ this.setIndex(new BufferAttribute(indice, 1));
6336
+ this.setAttribute("position", new BufferAttribute(position, 2));
6337
+ this.setAttribute("uv", new BufferAttribute(uv, 2));
6338
+ }
6339
+ computeBoundingSphere() {
6340
+ if (this.boundingSphere === null) {
6341
+ this.boundingSphere = new Sphere$1();
6342
+ }
6343
+ const positions = this.attributes.position.array;
6344
+ const itemSize = this.attributes.position.itemSize;
6345
+ if (!positions || !itemSize || positions.length < 2) {
6346
+ this.boundingSphere.radius = 0;
6347
+ this.boundingSphere.center.set(0, 0, 0);
6348
+ return;
6349
+ }
6350
+ computeSphere(positions, this.boundingSphere);
6351
+ if (isNaN(this.boundingSphere.radius)) {
6352
+ console.error('THREE.BufferGeometry.computeBoundingSphere(): ' + 'Computed radius is NaN. The ' + '"position" attribute is likely to have NaN values.');
6353
+ }
6354
+ }
6355
+ computeBoundingBox() {
6356
+ if (this.boundingBox === null) {
6357
+ this.boundingBox = new Box3();
6358
+ }
6359
+ const bbox = this.boundingBox;
6360
+ const positions = this.attributes.position["array"];
6361
+ const itemSize = this.attributes.position.itemSize;
6362
+ if (!positions || !itemSize || positions.length < 2) {
6363
+ bbox.makeEmpty();
6364
+ return;
6365
+ }
6366
+ computeBox(positions, bbox);
6367
+ }
6368
+ constructor(...args){
6369
+ super(...args), this.layout = new BMFontTextLayout();
6370
+ }
6371
+ }
6372
+
6373
+ class Label extends Component {
6374
+ get text() {
6375
+ return this._text;
6376
+ }
6377
+ set text(v) {
6378
+ if (this._text !== v) {
6379
+ this._text = v;
6380
+ this.needsUpdate = true;
6381
+ }
6382
+ }
6383
+ get font() {
6384
+ return this._font;
6385
+ }
6386
+ set font(v) {
6387
+ if (this._font !== v) {
6388
+ this._font = v;
6389
+ this.needsUpdate = true;
6390
+ }
6391
+ }
6392
+ get setting() {
6393
+ return this._setting;
6394
+ }
6395
+ set setting(v) {
6396
+ if (JSON.stringify(this._setting) !== JSON.stringify(v)) {
6397
+ this._setting = v;
6398
+ this.needsUpdate = true;
6399
+ }
6400
+ }
6401
+ get layout() {
6402
+ return this.node.geometry.layout;
6403
+ }
6404
+ forceUpdate() {
6405
+ this.node.geometry.update(this.font, this.text, this.setting);
6406
+ }
6407
+ update(dt) {
6408
+ if (this.needsUpdate) {
6409
+ this.needsUpdate = false;
6410
+ this.forceUpdate();
6411
+ }
6412
+ }
6413
+ constructor({ text = "", font, material, ...setting }){
6414
+ super(), this.needsUpdate = false, this._text = "", this._font = null, this._setting = null;
6415
+ this.text = text;
6416
+ this.font = font;
6417
+ this.setting = setting;
6418
+ this.node = new Mesh(new BMFontTextGeometry(), material || font.material);
6419
+ this.node.geometry.update(this.font, this.text, this.setting);
6420
+ }
6421
+ }
6422
+
6423
+ const vert_MSDF = `
6424
+ varying vec2 v_uv;
6425
+
6426
+ void main() {
6427
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
6428
+ v_uv = uv;
6429
+ }
6430
+ `;
6431
+ const frag_MSDF = `
6432
+ uniform sampler2D u_fontTexture;
6433
+ varying vec2 v_uv;
6434
+
6435
+ uniform vec3 u_color;
6436
+ uniform float u_opacity;
6437
+ uniform vec3 u_strokeColor;
6438
+ uniform float u_strokeWidth;
6439
+ uniform vec3 u_shadowColor;
6440
+ uniform float u_shadowBlur;
6441
+ uniform vec2 u_shadowOffset;
6442
+ uniform float u_weight;
6443
+
6444
+ float median(in float r, in float g, in float b) {
6445
+ return max(min(r, g), min(max(r, g), b));
6446
+ }
6447
+
6448
+ float signedDistance(in vec2 uv) {
6449
+ vec4 texel = texture2D(u_fontTexture, uv);
6450
+ return median(texel.r, texel.g, texel.b) - 0.5;
6451
+ }
6452
+
6453
+ void main() {
6454
+ vec4 color = vec4(u_color, 1.);
6455
+ float d = signedDistance(v_uv) + u_weight;
6456
+ float w = fwidth(d);
6457
+
6458
+ vec4 stroke = vec4(u_strokeColor, smoothstep(-w, w, d));
6459
+ color.a *= smoothstep(-w, w, d - u_strokeWidth);
6460
+ color = mix(stroke, color, color.a);
6461
+
6462
+ float sd = signedDistance(v_uv + u_shadowOffset) + u_weight;
6463
+ vec4 shadow = vec4(u_shadowColor, smoothstep(-w - u_shadowBlur, w + u_shadowBlur, sd));
6464
+ color = mix(shadow, color, color.a);
6465
+
6466
+ color.a *= u_opacity;
6467
+ gl_FragColor = color;
6468
+ }
6469
+ `;
6470
+ class BMFontAtlas {
6471
+ build(layout, setting) {
6472
+ const info = this.info;
6473
+ const texWidth = info.common.scaleW;
6474
+ const texHeight = info.common.scaleH;
6475
+ const glyphs = layout.glyphs.filter((glyph)=>glyph.data.width * glyph.data.height > 0);
6476
+ const flipY = setting.flipY !== false;
6477
+ const position = new Float32Array(glyphs.length * 8);
6478
+ const uv = new Float32Array(glyphs.length * 8);
6479
+ const indice = new Uint16Array(glyphs.length * 6);
6480
+ for(let k = 0, i0 = 0, i1 = 0, i2 = 0, i = 0; i < glyphs.length; i++, k += 4){
6481
+ const glyph = glyphs[i];
6482
+ const bitmap = glyph.data;
6483
+ // bottom left position
6484
+ let x = glyph.position[0] + bitmap.xoffset;
6485
+ let y = glyph.position[1] + bitmap.yoffset;
6486
+ // quad size
6487
+ let w = bitmap.width;
6488
+ let h = bitmap.height;
6489
+ // BL
6490
+ position[i0++] = x;
6491
+ position[i0++] = y;
6492
+ // BR
6493
+ position[i0++] = x + w;
6494
+ position[i0++] = y;
6495
+ // TR
6496
+ position[i0++] = x + w;
6497
+ position[i0++] = y + h;
6498
+ // TL
6499
+ position[i0++] = x;
6500
+ position[i0++] = y + h;
6501
+ let bw = bitmap.x + bitmap.width;
6502
+ let bh = bitmap.y + bitmap.height;
6503
+ // top left position
6504
+ let u0 = bitmap.x / texWidth;
6505
+ let v0 = bitmap.y / texHeight;
6506
+ let u1 = bw / texWidth;
6507
+ let v1 = bh / texHeight;
6508
+ if (flipY) {
6509
+ v0 = 1 - v0;
6510
+ v1 = 1 - v1;
6511
+ }
6512
+ // BL
6513
+ uv[i1++] = u0;
6514
+ uv[i1++] = v0;
6515
+ // BR
6516
+ uv[i1++] = u1;
6517
+ uv[i1++] = v0;
6518
+ // TR
6519
+ uv[i1++] = u1;
6520
+ uv[i1++] = v1;
6521
+ // TL
6522
+ uv[i1++] = u0;
6523
+ uv[i1++] = v1;
6524
+ indice[i2++] = k + 0;
6525
+ indice[i2++] = k + 1;
6526
+ indice[i2++] = k + 2;
6527
+ indice[i2++] = k + 0;
6528
+ indice[i2++] = k + 2;
6529
+ indice[i2++] = k + 3;
6530
+ }
6531
+ return {
6532
+ position,
6533
+ uv,
6534
+ indice
6535
+ };
6536
+ }
6537
+ constructor({ info, texture, uniforms, ...props }){
6538
+ this.uniforms = {
6539
+ u_color: {
6540
+ value: new Color(0xffffff)
6541
+ },
6542
+ u_opacity: {
6543
+ value: 1
6544
+ },
6545
+ u_weight: {
6546
+ value: 0.2
6547
+ },
6548
+ u_strokeColor: {
6549
+ value: new Color(0xff0000)
6550
+ },
6551
+ u_strokeWidth: {
6552
+ value: 0
6553
+ },
6554
+ u_shadowColor: {
6555
+ value: new Color(0xff0000)
6556
+ },
6557
+ u_shadowBlur: {
6558
+ value: 0
6559
+ },
6560
+ u_shadowOffset: {
6561
+ value: new Vector2()
6562
+ },
6563
+ u_fontTexture: {
6564
+ value: null
6565
+ }
6566
+ };
6567
+ this.info = info;
6568
+ this.uniforms.u_fontTexture.value = texture;
6569
+ this.material = new ShaderMaterial(Object.assign({
6570
+ vertexShader: vert_MSDF,
6571
+ fragmentShader: frag_MSDF,
6572
+ transparent: true,
6573
+ depthWrite: false,
6574
+ blending: NormalBlending,
6575
+ uniforms: {
6576
+ ...this.uniforms,
6577
+ ...uniforms
6578
+ }
6579
+ }, props));
6580
+ }
6581
+ }
6582
+
6583
+ export { AccumulativeShadows, Animation, AnimationCurve, BINLoader, BMFontAtlas, BMFontTextGeometry, BMFontTextLayout, Box, BoxProjection, Center, Component, ContactShadows, DependentMode, DeviceInput, DropFile, EXRLoader, Easing, Environment, EventEmitter, FBXLoader, FInterpConstantTo, FInterpTo, FreelookVirtualCamera, GLTFLoader, HDRLoader, JSONLoader, KTX2Loader, Label, Loader, Logger, ObjectInstance, Orientation, PerformanceMonitor, Perlin, Plane, PropertyManager, QInterpConstantTo, QInterpTo, Quat_AngularDistance, Quat_Equals, Quat_exponentialDamp, Quat_quarticDamp, Quat_smoothDamp, RandomizedLight, Reflector, ReflectorMaterial, RenderTexture, Renderer, ResizeMode, ResourceManager, SVGLoader, ShadowMaterial, Sphere, SystemInfo, Task, TextureLoader, VInterpConstantTo, VInterpTo, Vec3_smoothDamp, Vector3_NEG_ONE, Vector3_ONE, Vector3_RIGHT, Vector3_UNIT_X, Vector3_UNIT_Y, Vector3_UNIT_Z, Vector3_UP, Vector3_ZERO, Viewer, applyProps, dependencies, exponentialDamp, find, frag_BoxfilterBlur, frag_cubeMapToPanorama, frag_panoramaToCubeMap, getChildByName, getChildren, getClassInstance, getShaderMaterial, mixin, property, quarticDamp, queryValues, smoothDamp, vert_fullscreen };
5794
6584
  //# sourceMappingURL=module.js.map