@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/main.cjs CHANGED
@@ -8,7 +8,7 @@ var meshopt_decoder_module_js = require('three/examples/jsm/libs/meshopt_decoder
8
8
  var THREE = require('three');
9
9
  var RGBELoader_js = require('three/examples/jsm/loaders/RGBELoader.js');
10
10
  var SVGLoader_js = require('three/examples/jsm/loaders/SVGLoader.js');
11
- var KTX2Loader$1 = require('three/examples/jsm/loaders/KTX2Loader');
11
+ var KTX2Loader_js = require('three/examples/jsm/loaders/KTX2Loader.js');
12
12
  var Addons_js = require('three/examples/jsm/Addons.js');
13
13
 
14
14
  function _interopNamespaceDefault(e) {
@@ -165,7 +165,6 @@ function getClassInstance(constructor, args = []) {
165
165
 
166
166
  class Loader {
167
167
  static _setUserData(node) {
168
- const keys = Loader._texKeys;
169
168
  const meshes = [];
170
169
  const textures = {};
171
170
  const materials = {};
@@ -183,7 +182,7 @@ class Loader {
183
182
  queue.push(...object.children);
184
183
  }
185
184
  Object.values(materials).forEach((mat)=>{
186
- keys.forEach((k)=>{
185
+ Loader._texKeys.forEach((k)=>{
187
186
  let tex = mat[k];
188
187
  if (tex) {
189
188
  textures[tex.uuid] = tex;
@@ -244,13 +243,10 @@ class FBXLoader extends Loader {
244
243
  loader.manager = manager;
245
244
  loader.setPath(path);
246
245
  loader.setResourcePath(resourcePath);
247
- const loadCallback = (node)=>{
248
- onLoad(Loader._setUserData(node));
249
- };
250
246
  if (buffer) {
251
- loadCallback(loader.parse(buffer, resourcePath));
247
+ onLoad(loader.parse(buffer, resourcePath));
252
248
  } else {
253
- loader.load(url, loadCallback, onProgress, onError);
249
+ loader.load(url, onLoad, onProgress, onError);
254
250
  }
255
251
  }
256
252
  constructor(...args){
@@ -277,15 +273,10 @@ class GLTFLoader extends Loader {
277
273
  loader.manager = manager;
278
274
  loader.setPath(path);
279
275
  loader.setResourcePath(resourcePath);
280
- const loadCallback = (gltf)=>{
281
- const node = gltf.scene;
282
- node.animations.push(...gltf.animations);
283
- onLoad(Loader._setUserData(node));
284
- };
285
276
  if (buffer) {
286
- loader.parse(buffer, resourcePath, loadCallback, onError);
277
+ loader.parse(buffer, resourcePath, onLoad, onError);
287
278
  } else {
288
- loader.load(url, loadCallback, onProgress, onError);
279
+ loader.load(url, onLoad, onProgress, onError);
289
280
  }
290
281
  }
291
282
  constructor(...args){
@@ -379,15 +370,10 @@ class BINLoader extends Loader {
379
370
  loader.manager = manager;
380
371
  loader.setPath(path);
381
372
  loader.setResourcePath(resourcePath);
382
- const loadCallback = (gltf)=>{
383
- const node = gltf.scene;
384
- node.animations.push(...gltf.animations);
385
- onLoad(Loader._setUserData(node));
386
- };
387
373
  if (buffer) {
388
- loader.parse(buffer, resourcePath, loadCallback, onError);
374
+ loader.parse(buffer, resourcePath, onLoad, onError);
389
375
  } else {
390
- loader.load(url, loadCallback, onProgress, onError);
376
+ loader.load(url, onLoad, onProgress, onError);
391
377
  }
392
378
  }
393
379
  constructor(...args){
@@ -459,11 +445,11 @@ class SVGLoader extends Loader {
459
445
  SVGLoader.Primitive = SVGLoader_js.SVGLoader;
460
446
 
461
447
  class KTX2Loader extends Loader {
462
- load({ url, path, resourcePath, manager, texSettings, onLoad, onProgress, onError }) {
448
+ load({ url, path, resourcePath, transcoderPath, manager, texSettings, onLoad, onProgress, onError }) {
463
449
  let loader = this._loader;
464
450
  if (loader === undefined) {
465
- loader = this._loader = new KTX2Loader$1.KTX2Loader();
466
- loader.setTranscoderPath("three/examples/js/libs/basis/");
451
+ loader = this._loader = new KTX2Loader_js.KTX2Loader();
452
+ loader.setTranscoderPath(transcoderPath);
467
453
  loader.detectSupport(this.viewer.renderer);
468
454
  }
469
455
  loader.manager = manager;
@@ -2245,8 +2231,7 @@ class ComponentScheduler {
2245
2231
  if (comp.onEnable) {
2246
2232
  comp.onEnable();
2247
2233
  }
2248
- if (typeof comp.start === "function" && !comp.flags.isStartCalled) {
2249
- comp.flags.isStartCalled = true;
2234
+ if (typeof comp.start === "function") {
2250
2235
  this.startInvoker.add(comp);
2251
2236
  }
2252
2237
  if (typeof comp.update === "function") {
@@ -2476,12 +2461,12 @@ ComponentManager._infoMap = new Map();
2476
2461
 
2477
2462
  class Renderer extends Component {
2478
2463
  render(dt) {
2479
- const { renderer, scene, camera } = this.context;
2464
+ const { renderer, scene, camera } = this.viewer;
2480
2465
  renderer.setRenderTarget(null);
2481
2466
  renderer.render(scene, camera);
2482
2467
  }
2483
2468
  resize(width, height) {
2484
- const { renderer } = this.context;
2469
+ const { renderer } = this.viewer;
2485
2470
  renderer.setSize(width, height);
2486
2471
  }
2487
2472
  constructor(...args){
@@ -2601,6 +2586,60 @@ class Pressability {
2601
2586
  }
2602
2587
  }
2603
2588
 
2589
+ const PIXEL_STEP = 10;
2590
+ const LINE_HEIGHT = 40;
2591
+ const PAGE_HEIGHT = 800;
2592
+ function normalizeWheel(/*object*/ event) /*object*/ {
2593
+ let sX = 0, sY = 0, pX = 0, pY = 0; // pixelX, pixelY
2594
+ // Legacy
2595
+ if ('detail' in event) {
2596
+ sY = event.detail;
2597
+ }
2598
+ if ('wheelDelta' in event) {
2599
+ sY = -event.wheelDelta / 120;
2600
+ }
2601
+ if ('wheelDeltaY' in event) {
2602
+ sY = -event.wheelDeltaY / 120;
2603
+ }
2604
+ if ('wheelDeltaX' in event) {
2605
+ sX = -event.wheelDeltaX / 120;
2606
+ }
2607
+ // side scrolling on FF with DOMMouseScroll
2608
+ if ('axis' in event && event.axis === event.HORIZONTAL_AXIS) {
2609
+ sX = sY;
2610
+ sY = 0;
2611
+ }
2612
+ pX = sX * PIXEL_STEP;
2613
+ pY = sY * PIXEL_STEP;
2614
+ if ('deltaY' in event) {
2615
+ pY = event.deltaY;
2616
+ }
2617
+ if ('deltaX' in event) {
2618
+ pX = event.deltaX;
2619
+ }
2620
+ if ((pX || pY) && event.deltaMode) {
2621
+ if (event.deltaMode == 1) {
2622
+ pX *= LINE_HEIGHT;
2623
+ pY *= LINE_HEIGHT;
2624
+ } else {
2625
+ pX *= PAGE_HEIGHT;
2626
+ pY *= PAGE_HEIGHT;
2627
+ }
2628
+ }
2629
+ // Fall-back if spin cannot be determined
2630
+ if (pX && !sX) {
2631
+ sX = pX < 1 ? -1 : 1;
2632
+ }
2633
+ if (pY && !sY) {
2634
+ sY = pY < 1 ? -1 : 1;
2635
+ }
2636
+ return {
2637
+ spinX: sX,
2638
+ spinY: sY,
2639
+ pixelX: pX,
2640
+ pixelY: pY
2641
+ };
2642
+ }
2604
2643
  class DeviceInput extends Component {
2605
2644
  get pointer() {
2606
2645
  return this._pointer;
@@ -2617,9 +2656,18 @@ class DeviceInput extends Component {
2617
2656
  get prePointerPixel() {
2618
2657
  return this._prePointerPixel;
2619
2658
  }
2659
+ get preTouches() {
2660
+ return this._preTouches;
2661
+ }
2620
2662
  get mouseWheel() {
2621
2663
  return this._mouseWheel;
2622
2664
  }
2665
+ get touchStart() {
2666
+ return this._touchStart;
2667
+ }
2668
+ get touchMoving() {
2669
+ return this._touchMoving;
2670
+ }
2623
2671
  get touchCount() {
2624
2672
  return this._touchCount;
2625
2673
  }
@@ -2683,7 +2731,12 @@ class DeviceInput extends Component {
2683
2731
  lastUpdate(dt) {
2684
2732
  this._prePointer.copy(this._pointer);
2685
2733
  this._prePointerPixel.copy(this._pointerPixel);
2734
+ for(let i = this._touchCount; i--;){
2735
+ this._preTouches[i].id = this._touches[i].id;
2736
+ this._preTouches[i].position.copy(this._touches[i].position);
2737
+ }
2686
2738
  this._mouseWheel = 0;
2739
+ this._touchStart = false;
2687
2740
  }
2688
2741
  connect(target, event) {
2689
2742
  switch(event){
@@ -2754,14 +2807,16 @@ class DeviceInput extends Component {
2754
2807
  const isDocument = target instanceof Document;
2755
2808
  const width = isDocument ? window.innerWidth : target.offsetWidth;
2756
2809
  const height = isDocument ? window.innerHeight : target.offsetHeight;
2757
- this._pointer.x = e.clientX / width * 2 - 1;
2758
- this._pointer.y = 1 - e.clientY / height * 2;
2759
- this._pointerPixel.set(e.clientX, e.clientY);
2810
+ this._pointer.x = e.pageX / width * 2 - 1;
2811
+ this._pointer.y = 1 - e.pageY / height * 2;
2812
+ this._pointerPixel.set(e.pageX, e.pageY);
2760
2813
  }
2761
2814
  _onPointerDown(e) {
2762
2815
  e = this._remapPointer(e);
2763
2816
  this._pointerButton = e.button;
2764
2817
  this._computePointer(e);
2818
+ this._prePointer.copy(this._pointer);
2819
+ this._prePointerPixel.copy(this._pointerPixel);
2765
2820
  this._pressability.pointerDown(this._pointer, this.viewer.camera);
2766
2821
  this.viewer.emit(DeviceInput.POINTER_DOWN, e);
2767
2822
  }
@@ -2779,33 +2834,54 @@ class DeviceInput extends Component {
2779
2834
  this.viewer.emit(DeviceInput.POINTER_MOVE, e);
2780
2835
  }
2781
2836
  _onMouseWheel(e) {
2782
- this._mouseWheel = e.deltaY || e.wheelDelta;
2837
+ this._mouseWheel = this._normalizeWheel(e).pixelY;
2783
2838
  this.viewer.emit(DeviceInput.MOUSE_WHEEL, e);
2784
2839
  }
2785
2840
  _onTouchStart(e) {
2841
+ this._touchStart = true;
2786
2842
  e = this._remapTouch(e);
2843
+ const curr = e.touches;
2844
+ const touches = this._touches;
2845
+ const preTouches = this._preTouches;
2846
+ for(let i = curr.length; i--;){
2847
+ if (touches[i] === undefined) {
2848
+ touches[i] = {
2849
+ id: -1,
2850
+ position: new THREE.Vector2()
2851
+ };
2852
+ }
2853
+ const touch = curr[i];
2854
+ touches[i].id = touch.identifier;
2855
+ touches[i].position.set(touch.pageX, touch.pageY);
2856
+ if (preTouches[i] === undefined) {
2857
+ preTouches[i] = {
2858
+ id: touches[i].id,
2859
+ position: touches[i].position.clone()
2860
+ };
2861
+ } else {
2862
+ preTouches[i].id = touches[i].id;
2863
+ preTouches[i].position.copy(touches[i].position);
2864
+ }
2865
+ }
2866
+ this._touchCount = curr.length;
2787
2867
  this.viewer.emit(DeviceInput.TOUCH_START, e);
2788
2868
  }
2789
2869
  _onTouchEnd(e) {
2870
+ this._touchMoving = false;
2790
2871
  e = this._remapTouch(e);
2791
2872
  this.viewer.emit(DeviceInput.TOUCH_END, e);
2792
2873
  }
2793
2874
  _onTouchMove(e) {
2875
+ this._touchMoving = true;
2794
2876
  e = this._remapTouch(e);
2795
- const touches = e.touches;
2796
- const touchesTo = this._touches;
2797
- for(let i = touches.length; i--;){
2798
- if (touchesTo[i] == undefined) {
2799
- touchesTo[i] = {
2800
- id: -1,
2801
- position: new THREE.Vector2()
2802
- };
2803
- }
2804
- const touch = touches[i];
2805
- touchesTo[i].id = touch.identifier;
2806
- touchesTo[i].position.set(touch.pageX, touch.pageY);
2807
- }
2808
- this._touchCount = touches.length;
2877
+ const curr = e.touches;
2878
+ const touches = this._touches;
2879
+ for(let i = curr.length; i--;){
2880
+ const touch = curr[i];
2881
+ touches[i].id = touch.identifier;
2882
+ touches[i].position.set(touch.pageX, touch.pageY);
2883
+ }
2884
+ this._touchCount = curr.length;
2809
2885
  this.viewer.emit(DeviceInput.TOUCH_MOVE, e);
2810
2886
  }
2811
2887
  _onKeyDown(e) {
@@ -2820,9 +2896,10 @@ class DeviceInput extends Component {
2820
2896
  this._keys[e.key] = false;
2821
2897
  this.viewer.emit(DeviceInput.KEYUP, e);
2822
2898
  }
2823
- constructor(target){
2824
- super(), this._listeners = [], this._touches = [], this._touchCount = 0, this._pointer = new THREE.Vector2(), this._pointerPixel = new THREE.Vector2(), this._pointerButton = -1, this._prePointer = new THREE.Vector2(), this._prePointerPixel = new THREE.Vector2(), this._mouseWheel = 0, this._keys = {}, this._pressability = new Pressability();
2825
- this._target = target;
2899
+ constructor(option){
2900
+ super(), this._listeners = [], this._touches = [], this._touchCount = 0, this._touchStart = false, this._touchMoving = false, this._pointer = new THREE.Vector2(), this._pointerPixel = new THREE.Vector2(), this._pointerButton = -1, this._prePointer = new THREE.Vector2(), this._prePointerPixel = new THREE.Vector2(), this._preTouches = [], this._mouseWheel = 0, this._keys = {}, this._pressability = new Pressability();
2901
+ this._target = option.source;
2902
+ this._normalizeWheel = option.normalizeWheel || normalizeWheel;
2826
2903
  }
2827
2904
  }
2828
2905
  DeviceInput.CLICK = "click";
@@ -3666,7 +3743,9 @@ uniform float roughness;
3666
3743
  uniform float metalness;
3667
3744
  uniform sampler2D map;
3668
3745
  uniform sampler2D normalMap;
3746
+ uniform vec4 normalScaleBias;
3669
3747
  uniform sampler2D roughnessMap;
3748
+ uniform vec4 roughnessScaleBias;
3670
3749
  uniform sampler2D aoMap;
3671
3750
  uniform float aoMapIntensity;
3672
3751
  uniform sampler2D lightMap;
@@ -3704,7 +3783,7 @@ void main() {
3704
3783
  vec2 reflectUv = coord.xy;
3705
3784
 
3706
3785
  #ifdef USE_NORMALMAP
3707
- vec4 texelNormal = texture2D(normalMap, UV_NORMAL);
3786
+ vec4 texelNormal = texture2D(normalMap, UV_NORMAL * normalScaleBias.xy + normalScaleBias.zw);
3708
3787
  vec3 normal = normalize(vec3(texelNormal.r * 2.0 - 1.0, texelNormal.b, texelNormal.g * 2.0 - 1.0));
3709
3788
  reflectUv += coord.z * normal.xz * 0.05;
3710
3789
  #endif
@@ -3731,7 +3810,7 @@ void main() {
3731
3810
  float roughnessFactor = roughness;
3732
3811
 
3733
3812
  #ifdef USE_ROUGHNESSMAP
3734
- roughnessFactor *= texture2D(roughnessMap, UV_ROUGHNESS).g * roughness;
3813
+ roughnessFactor *= texture2D(roughnessMap, UV_ROUGHNESS * roughnessScaleBias.xy + roughnessScaleBias.zw).g * roughness;
3735
3814
  #endif
3736
3815
 
3737
3816
  computeMultiscattering( geometryNormal, geometryViewDir, specularColor, specularF90, roughnessFactor, singleScattering, multiScattering );
@@ -3829,12 +3908,24 @@ class ReflectorMaterial extends THREE.ShaderMaterial {
3829
3908
  set roughnessMap(v) {
3830
3909
  this.uniforms.roughnessMap.value = v;
3831
3910
  }
3911
+ get roughnessScaleBias() {
3912
+ return this.uniforms.roughnessScaleBias.value;
3913
+ }
3914
+ set roughnessScaleBias(v) {
3915
+ this.uniforms.roughnessScaleBias.value.copy(v);
3916
+ }
3832
3917
  get normalMap() {
3833
3918
  return this.uniforms.normalMap.value;
3834
3919
  }
3835
3920
  set normalMap(v) {
3836
3921
  this.uniforms.normalMap.value = v;
3837
3922
  }
3923
+ get normalScaleBias() {
3924
+ return this.uniforms.normalScaleBias.value;
3925
+ }
3926
+ set normalScaleBias(v) {
3927
+ this.uniforms.normalScaleBias.value.copy(v);
3928
+ }
3838
3929
  get aoMap() {
3839
3930
  return this.uniforms.aoMap.value;
3840
3931
  }
@@ -3899,9 +3990,15 @@ class ReflectorMaterial extends THREE.ShaderMaterial {
3899
3990
  roughnessMap: {
3900
3991
  value: null
3901
3992
  },
3993
+ roughnessScaleBias: {
3994
+ value: new THREE.Vector4(1, 1, 0, 0)
3995
+ },
3902
3996
  normalMap: {
3903
3997
  value: null
3904
3998
  },
3999
+ normalScaleBias: {
4000
+ value: new THREE.Vector4(1, 1, 0, 0)
4001
+ },
3905
4002
  aoMap: {
3906
4003
  value: null
3907
4004
  },
@@ -3947,9 +4044,15 @@ __decorate([
3947
4044
  __decorate([
3948
4045
  property
3949
4046
  ], ReflectorMaterial.prototype, "roughnessMap", null);
4047
+ __decorate([
4048
+ property
4049
+ ], ReflectorMaterial.prototype, "roughnessScaleBias", null);
3950
4050
  __decorate([
3951
4051
  property
3952
4052
  ], ReflectorMaterial.prototype, "normalMap", null);
4053
+ __decorate([
4054
+ property
4055
+ ], ReflectorMaterial.prototype, "normalScaleBias", null);
3953
4056
  __decorate([
3954
4057
  property
3955
4058
  ], ReflectorMaterial.prototype, "aoMap", null);
@@ -4411,19 +4514,15 @@ class ResourceManager {
4411
4514
  }
4412
4515
  return loader;
4413
4516
  }
4414
- loadAsset({ url, buffer, ext, path, resourcePath, dracoPath, manager, onProgress, ...props }) {
4517
+ loadAsset({ url, ext, onProgress, ...props }) {
4415
4518
  return new Promise((resolve, reject)=>{
4416
4519
  const sel = ext || url && ResourceManager.extension(url) || "";
4417
4520
  const texSettings = ResourceManager._splitTextureSettings(props);
4418
4521
  if (this._loaders.has(sel)) {
4419
4522
  this._loaders.get(sel).load({
4420
4523
  url,
4421
- buffer,
4422
4524
  texSettings,
4423
- path,
4424
- resourcePath,
4425
- dracoPath,
4426
- manager,
4525
+ ...props,
4427
4526
  onProgress,
4428
4527
  onLoad: resolve,
4429
4528
  onError: (err)=>{
@@ -4880,6 +4979,9 @@ class Viewer extends EventEmitter {
4880
4979
  clearColor(renderTarget, color, alpha) {
4881
4980
  Viewer.ClearColor(this._renderer, renderTarget, color, alpha);
4882
4981
  }
4982
+ stash(renderTarget, callback, clearColor, clearAlpha) {
4983
+ Viewer.Stash(this._renderer, renderTarget, callback, clearColor, clearAlpha);
4984
+ }
4883
4985
  blur(blurLevel, shadingScale, inputBuffer, tempBuffer, outputBuffer, fixedOutput) {
4884
4986
  Viewer.Blur(this._renderer, blurLevel, shadingScale, inputBuffer, tempBuffer, outputBuffer, fixedOutput);
4885
4987
  }
@@ -4975,7 +5077,7 @@ class Viewer extends EventEmitter {
4975
5077
  renderer.autoClear = true;
4976
5078
  renderer.setRenderTarget(renderTarget);
4977
5079
  clearColor !== undefined && renderer.setClearColor(clearColor, clearAlpha);
4978
- callback && callback();
5080
+ callback && callback(renderer);
4979
5081
  renderer.autoClear = autoClear;
4980
5082
  renderer.setRenderTarget(RT);
4981
5083
  clearColor !== undefined && renderer.setClearColor(color, alpha);
@@ -5011,7 +5113,7 @@ class Viewer extends EventEmitter {
5011
5113
  near: 0.1,
5012
5114
  far: 1000,
5013
5115
  position: new THREE.Vector3(0, 0, 4)
5014
- }, targetFrameRate = -1, fixedFrameTime = false, colorSpace = THREE.SRGBColorSpace, toneMapping = THREE.LinearToneMapping, toneMappingExposure = 1, maxDPR = 1.5, path = "", resourcePath = "", dracoPath = "https://www.gstatic.com/draco/v1/decoders/", orientation = Orientation.AUTO, loader = {}, tasker = {}, ...webglOpts } = {}){
5116
+ }, targetFrameRate = -1, fixedFrameTime = false, colorSpace = THREE.SRGBColorSpace, toneMapping = THREE.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 } = {}){
5015
5117
  super(), this._instanceId = Viewer.instanceCount++, this._dpr = 1, this._width = 1, this._height = 1, this._viewport = {
5016
5118
  width: 1,
5017
5119
  height: 1,
@@ -5069,12 +5171,15 @@ class Viewer extends EventEmitter {
5069
5171
  path,
5070
5172
  resourcePath,
5071
5173
  dracoPath,
5174
+ transcoderPath,
5072
5175
  manager: this._loadingManager
5073
5176
  };
5074
5177
  this._mount = applyProps(new THREE.Object3D(), {
5075
5178
  name: "Mount"
5076
5179
  });
5077
- this._input = this.add(new DeviceInput(input || this._canvas));
5180
+ this._input = this.add(new DeviceInput(input || {
5181
+ source: this._canvas
5182
+ }));
5078
5183
  this.add(Renderer);
5079
5184
  this.addLoader(GLTFLoader);
5080
5185
  this.addLoader(HDRLoader);
@@ -5810,10 +5915,698 @@ function getFilesFromItemList(items, onDone) {
5810
5915
  }
5811
5916
  }
5812
5917
 
5918
+ const newline = /\n/;
5919
+ const newlineChar = '\n';
5920
+ const whitespace = /\s/;
5921
+ function wordwrap(text, opt) {
5922
+ opt = opt || {};
5923
+ //zero width results in nothing visible
5924
+ if (opt.width === 0 && opt.mode !== 'nowrap') return [];
5925
+ text = text || '';
5926
+ const width = typeof opt.width === 'number' ? opt.width : Number.MAX_VALUE;
5927
+ const start = Math.max(0, opt.start || 0);
5928
+ const end = typeof opt.end === 'number' ? opt.end : text.length;
5929
+ const mode = opt.mode;
5930
+ const letterSpacing = opt.letterSpacing || 0;
5931
+ const measure = opt.measure || monospace;
5932
+ if (mode === 'pre') return pre(measure, text, start, end, width, letterSpacing);
5933
+ else return greedy(measure, text, start, end, width, mode, letterSpacing);
5934
+ }
5935
+ function idxOf(text, chr, start, end) {
5936
+ var idx = text.indexOf(chr, start);
5937
+ if (idx === -1 || idx > end) return end;
5938
+ return idx;
5939
+ }
5940
+ function isWhitespace(chr) {
5941
+ return whitespace.test(chr);
5942
+ }
5943
+ function pre(measure, text, start, end, width, letterSpacing) {
5944
+ var lines = [];
5945
+ var lineStart = start;
5946
+ for(var i = start; i < end && i < text.length; i++){
5947
+ var chr = text.charAt(i);
5948
+ var isNewline = newline.test(chr);
5949
+ //If we've reached a newline, then step down a line
5950
+ //Or if we've reached the EOF
5951
+ if (isNewline || i === end - 1) {
5952
+ var lineEnd = isNewline ? i : i + 1;
5953
+ var measured = measure(text, lineStart, lineEnd, width, letterSpacing);
5954
+ lines.push(measured);
5955
+ lineStart = i + 1;
5956
+ }
5957
+ }
5958
+ return lines;
5959
+ }
5960
+ function greedy(measure, text, start, end, width, mode, letterSpacing) {
5961
+ //A greedy word wrapper based on LibGDX algorithm
5962
+ //https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g2d/BitmapFontCache.java
5963
+ var lines = [];
5964
+ var testWidth = width;
5965
+ //if 'nowrap' is specified, we only wrap on newline chars
5966
+ if (mode === 'nowrap') testWidth = Number.MAX_VALUE;
5967
+ while(start < end && start < text.length){
5968
+ //get next newline position
5969
+ var newLine = idxOf(text, newlineChar, start, end);
5970
+ //eat whitespace at start of line
5971
+ while(start < newLine){
5972
+ if (!isWhitespace(text.charAt(start))) break;
5973
+ start++;
5974
+ }
5975
+ //determine visible # of glyphs for the available width
5976
+ var measured = measure(text, start, newLine, testWidth, letterSpacing);
5977
+ var lineEnd = start + (measured.end - measured.start);
5978
+ var nextStart = lineEnd + newlineChar.length;
5979
+ //if we had to cut the line before the next newline...
5980
+ if (lineEnd < newLine) {
5981
+ //find char to break on
5982
+ while(lineEnd > start){
5983
+ if (isWhitespace(text.charAt(lineEnd))) break;
5984
+ lineEnd--;
5985
+ }
5986
+ if (lineEnd === start) {
5987
+ if (nextStart > start + newlineChar.length) nextStart--;
5988
+ lineEnd = nextStart; // If no characters to break, show all.
5989
+ } else {
5990
+ nextStart = lineEnd;
5991
+ //eat whitespace at end of line
5992
+ while(lineEnd > start){
5993
+ if (!isWhitespace(text.charAt(lineEnd - newlineChar.length))) break;
5994
+ lineEnd--;
5995
+ }
5996
+ }
5997
+ }
5998
+ if (lineEnd >= start) {
5999
+ var result = measure(text, start, lineEnd, testWidth);
6000
+ lines.push(result);
6001
+ }
6002
+ start = nextStart;
6003
+ }
6004
+ return lines;
6005
+ }
6006
+ //determines the visible number of glyphs within a given width
6007
+ function monospace(text, start, end, width) {
6008
+ var glyphs = Math.min(width, end - start);
6009
+ return {
6010
+ start: start,
6011
+ end: start + glyphs
6012
+ };
6013
+ }
6014
+
6015
+ const X_HEIGHTS = [
6016
+ 'x',
6017
+ 'e',
6018
+ 'a',
6019
+ 'o',
6020
+ 'n',
6021
+ 's',
6022
+ 'r',
6023
+ 'c',
6024
+ 'u',
6025
+ 'm',
6026
+ 'v',
6027
+ 'w',
6028
+ 'z'
6029
+ ];
6030
+ const M_WIDTHS = [
6031
+ 'm',
6032
+ 'w'
6033
+ ];
6034
+ const CAP_HEIGHTS = [
6035
+ 'H',
6036
+ 'I',
6037
+ 'N',
6038
+ 'E',
6039
+ 'F',
6040
+ 'K',
6041
+ 'L',
6042
+ 'T',
6043
+ 'U',
6044
+ 'V',
6045
+ 'W',
6046
+ 'X',
6047
+ 'Y',
6048
+ 'Z'
6049
+ ];
6050
+ const TAB_ID = '\t'.charCodeAt(0);
6051
+ const SPACE_ID = ' '.charCodeAt(0);
6052
+ const ALIGN_LEFT = 0, ALIGN_CENTER = 1, ALIGN_RIGHT = 2;
6053
+ function findChar(array, value, start) {
6054
+ start = start || 0;
6055
+ for(let i = start; i < array.length; i++){
6056
+ if (array[i].id === value) {
6057
+ return i;
6058
+ }
6059
+ }
6060
+ return -1;
6061
+ }
6062
+ function getGlyphById(font, id) {
6063
+ if (!font.chars || font.chars.length === 0) return null;
6064
+ let glyphIdx = findChar(font.chars, id);
6065
+ if (glyphIdx >= 0) return font.chars[glyphIdx];
6066
+ return null;
6067
+ }
6068
+ function getXHeight(font) {
6069
+ for(let i = 0; i < X_HEIGHTS.length; i++){
6070
+ let id = X_HEIGHTS[i].charCodeAt(0);
6071
+ let idx = findChar(font.chars, id);
6072
+ if (idx >= 0) return font.chars[idx].height;
6073
+ }
6074
+ return 0;
6075
+ }
6076
+ function getMGlyph(font) {
6077
+ for(let i = 0; i < M_WIDTHS.length; i++){
6078
+ let id = M_WIDTHS[i].charCodeAt(0);
6079
+ let idx = findChar(font.chars, id);
6080
+ if (idx >= 0) return font.chars[idx];
6081
+ }
6082
+ return 0;
6083
+ }
6084
+ function getCapHeight(font) {
6085
+ for(let i = 0; i < CAP_HEIGHTS.length; i++){
6086
+ let id = CAP_HEIGHTS[i].charCodeAt(0);
6087
+ let idx = findChar(font.chars, id);
6088
+ if (idx >= 0) return font.chars[idx].height;
6089
+ }
6090
+ return 0;
6091
+ }
6092
+ function getKerning(font, left, right) {
6093
+ if (!font.kernings || font.kernings.length === 0) return 0;
6094
+ let table = font.kernings;
6095
+ for(let i = 0; i < table.length; i++){
6096
+ let kern = table[i];
6097
+ if (kern.first === left && kern.second === right) return kern.amount;
6098
+ }
6099
+ return 0;
6100
+ }
6101
+ function getAlignType(align) {
6102
+ if (align === 'center') return ALIGN_CENTER;
6103
+ else if (align === 'right') return ALIGN_RIGHT;
6104
+ return ALIGN_LEFT;
6105
+ }
6106
+ class BMFontTextLayout {
6107
+ get width() {
6108
+ return this._width;
6109
+ }
6110
+ get height() {
6111
+ return this._height;
6112
+ }
6113
+ get descender() {
6114
+ return this._descender;
6115
+ }
6116
+ get ascender() {
6117
+ return this._ascender;
6118
+ }
6119
+ get xHeight() {
6120
+ return this._xHeight;
6121
+ }
6122
+ get baseline() {
6123
+ return this._baseline;
6124
+ }
6125
+ get capHeight() {
6126
+ return this._capHeight;
6127
+ }
6128
+ get lineHeight() {
6129
+ return this._lineHeight;
6130
+ }
6131
+ get glyphs() {
6132
+ return this._glyphs;
6133
+ }
6134
+ get linesTotal() {
6135
+ return this._linesTotal;
6136
+ }
6137
+ update(font, text, setting) {
6138
+ setting = Object.assign({
6139
+ tabSize: 4,
6140
+ width: 0,
6141
+ letterSpacing: 0,
6142
+ mode: "nowrap",
6143
+ align: "left"
6144
+ }, setting);
6145
+ this._font = font;
6146
+ const measure = this._computeMetrics.bind(this);
6147
+ const lines = wordwrap(text, {
6148
+ measure,
6149
+ ...setting
6150
+ });
6151
+ const minWidth = setting.width || 0;
6152
+ const glyphs = this._glyphs;
6153
+ const maxLineWidth = lines.reduce((prev, line)=>Math.max(prev, line.width, minWidth), 0);
6154
+ var _setting_lineHeight;
6155
+ //the pen position
6156
+ const lineHeight = (_setting_lineHeight = setting.lineHeight) != null ? _setting_lineHeight : font.common.lineHeight;
6157
+ const baseline = font.common.base;
6158
+ const descender = lineHeight - baseline;
6159
+ const letterSpacing = setting.letterSpacing || 0;
6160
+ const height = lineHeight * lines.length - descender;
6161
+ const align = getAlignType(setting.align);
6162
+ var _setting_anchor;
6163
+ const anchor = (_setting_anchor = setting.anchor) != null ? _setting_anchor : [
6164
+ 0.5,
6165
+ 0.5
6166
+ ];
6167
+ this._setupSpaceGlyphs(font, setting);
6168
+ //the metrics for this text layout
6169
+ this._width = maxLineWidth;
6170
+ this._height = height;
6171
+ this._descender = descender;
6172
+ this._baseline = baseline;
6173
+ this._xHeight = getXHeight(font);
6174
+ this._capHeight = getCapHeight(font);
6175
+ this._lineHeight = lineHeight;
6176
+ this._ascender = baseline - this._xHeight; //lineHeight - descender - this._xHeight
6177
+ const anchorOffset = [
6178
+ -maxLineWidth * anchor[0],
6179
+ 2 * lineHeight * anchor[1] - baseline
6180
+ ];
6181
+ let x = 0, y = 0;
6182
+ //draw text along baseline
6183
+ y -= height;
6184
+ glyphs.length = 0;
6185
+ for(let k = 0; k < lines.length; k++){
6186
+ const line = lines[k];
6187
+ let start = line.start;
6188
+ let end = line.end;
6189
+ let lineWidth = line.width;
6190
+ let lastGlyph;
6191
+ //for each glyph in that line...
6192
+ for(let i = start; i < end; i++){
6193
+ let id = text.charCodeAt(i);
6194
+ let glyph = this._getGlyph(font, id);
6195
+ if (glyph) {
6196
+ if (lastGlyph) x += getKerning(font, lastGlyph.id, glyph.id);
6197
+ let tx = x;
6198
+ if (align === ALIGN_CENTER) tx += (maxLineWidth - lineWidth) / 2;
6199
+ else if (align === ALIGN_RIGHT) tx += maxLineWidth - lineWidth;
6200
+ glyphs.push({
6201
+ position: [
6202
+ tx + anchorOffset[0],
6203
+ y + anchorOffset[1]
6204
+ ],
6205
+ data: glyph,
6206
+ index: i,
6207
+ line: k
6208
+ });
6209
+ //move pen forward
6210
+ x += glyph.xadvance + letterSpacing;
6211
+ lastGlyph = glyph;
6212
+ }
6213
+ }
6214
+ //next line down
6215
+ y += lineHeight;
6216
+ x = 0;
6217
+ }
6218
+ this._linesTotal = lines.length;
6219
+ }
6220
+ _setupSpaceGlyphs(font, setting) {
6221
+ //These are fallbacks, when the font doesn't include
6222
+ //' ' or '\t' glyphs
6223
+ if (!font.chars || font.chars.length === 0) return;
6224
+ //try to get space glyph
6225
+ //then fall back to the 'm' or 'w' glyphs
6226
+ //then fall back to the first glyph available
6227
+ const space = Object.assign({}, getGlyphById(font, SPACE_ID) || getMGlyph(font) || font.chars[0]);
6228
+ //and create a fallback for tab
6229
+ const tabWidth = setting.tabSize * space.xadvance;
6230
+ this._fallbackSpaceGlyph = space;
6231
+ this._fallbackTabGlyph = Object.assign(space, {
6232
+ x: 0,
6233
+ y: 0,
6234
+ xadvance: tabWidth,
6235
+ id: TAB_ID,
6236
+ xoffset: 0,
6237
+ yoffset: 0,
6238
+ width: 0,
6239
+ height: 0
6240
+ });
6241
+ }
6242
+ _getGlyph(font, id) {
6243
+ let glyph = getGlyphById(font, id);
6244
+ if (glyph) return glyph;
6245
+ else if (id === TAB_ID) return this._fallbackTabGlyph;
6246
+ else if (id === SPACE_ID) return this._fallbackSpaceGlyph;
6247
+ return null;
6248
+ }
6249
+ _computeMetrics(text, start, end, width, letterSpacing = 0) {
6250
+ let font = this._font;
6251
+ let curPen = 0;
6252
+ let curWidth = 0;
6253
+ let count = 0;
6254
+ let lastGlyph;
6255
+ if (!font.chars || font.chars.length === 0) {
6256
+ return {
6257
+ start: start,
6258
+ end: start,
6259
+ width: 0
6260
+ };
6261
+ }
6262
+ end = Math.min(text.length, end);
6263
+ for(let i = start; i < end; i++){
6264
+ let id = text.charCodeAt(i);
6265
+ let glyph = this._getGlyph(font, id);
6266
+ if (glyph) {
6267
+ //move pen forward
6268
+ glyph.xoffset;
6269
+ let kern = lastGlyph ? getKerning(font, lastGlyph.id, glyph.id) : 0;
6270
+ curPen += kern;
6271
+ let nextPen = curPen + glyph.xadvance + letterSpacing;
6272
+ let nextWidth = curPen + glyph.width;
6273
+ //we've hit our limit; we can't move onto the next glyph
6274
+ if (nextWidth >= width || nextPen >= width) break;
6275
+ //otherwise continue along our line
6276
+ curPen = nextPen;
6277
+ curWidth = nextWidth;
6278
+ lastGlyph = glyph;
6279
+ }
6280
+ count++;
6281
+ }
6282
+ //make sure rightmost edge lines up with rendered glyphs
6283
+ if (lastGlyph) curWidth += lastGlyph.xoffset;
6284
+ return {
6285
+ start: start,
6286
+ end: start + count,
6287
+ width: curWidth
6288
+ };
6289
+ }
6290
+ constructor(){
6291
+ this._width = 0;
6292
+ this._height = 0;
6293
+ this._descender = 0;
6294
+ this._ascender = 0;
6295
+ this._xHeight = 0;
6296
+ this._baseline = 0;
6297
+ this._capHeight = 0;
6298
+ this._lineHeight = 0;
6299
+ this._linesTotal = 0;
6300
+ this._glyphs = [];
6301
+ this._fallbackSpaceGlyph = null;
6302
+ this._fallbackTabGlyph = null;
6303
+ this._font = null;
6304
+ }
6305
+ }
6306
+
6307
+ const itemSize = 2;
6308
+ const box = {
6309
+ min: [
6310
+ 0,
6311
+ 0
6312
+ ],
6313
+ max: [
6314
+ 0,
6315
+ 0
6316
+ ]
6317
+ };
6318
+ function bounds(positions) {
6319
+ const count = positions.length / itemSize;
6320
+ box.min[0] = positions[0];
6321
+ box.min[1] = positions[1];
6322
+ box.max[0] = positions[0];
6323
+ box.max[1] = positions[1];
6324
+ for(let i = 0; i < count; i++){
6325
+ const x = positions[i * itemSize + 0];
6326
+ const y = positions[i * itemSize + 1];
6327
+ box.min[0] = Math.min(x, box.min[0]);
6328
+ box.min[1] = Math.min(y, box.min[1]);
6329
+ box.max[0] = Math.max(x, box.max[0]);
6330
+ box.max[1] = Math.max(y, box.max[1]);
6331
+ }
6332
+ }
6333
+ function computeBox(positions, output) {
6334
+ bounds(positions);
6335
+ output.min.set(box.min[0], box.min[1], 0);
6336
+ output.max.set(box.max[0], box.max[1], 0);
6337
+ }
6338
+ function computeSphere(positions, output) {
6339
+ bounds(positions);
6340
+ const minX = box.min[0];
6341
+ const minY = box.min[1];
6342
+ const maxX = box.max[0];
6343
+ const maxY = box.max[1];
6344
+ const width = maxX - minX;
6345
+ const height = maxY - minY;
6346
+ const length = Math.sqrt(width * width + height * height);
6347
+ output.center.set(minX + width / 2, minY + height / 2, 0);
6348
+ output.radius = length / 2;
6349
+ }
6350
+
6351
+ class BMFontTextGeometry extends THREE.BufferGeometry {
6352
+ update(fontAtlas, text, setting) {
6353
+ this.layout.update(fontAtlas.info, text, setting);
6354
+ const { indice, position, uv } = fontAtlas.build(this.layout, setting);
6355
+ this.setIndex(new THREE.BufferAttribute(indice, 1));
6356
+ this.setAttribute("position", new THREE.BufferAttribute(position, 2));
6357
+ this.setAttribute("uv", new THREE.BufferAttribute(uv, 2));
6358
+ }
6359
+ computeBoundingSphere() {
6360
+ if (this.boundingSphere === null) {
6361
+ this.boundingSphere = new THREE.Sphere();
6362
+ }
6363
+ const positions = this.attributes.position.array;
6364
+ const itemSize = this.attributes.position.itemSize;
6365
+ if (!positions || !itemSize || positions.length < 2) {
6366
+ this.boundingSphere.radius = 0;
6367
+ this.boundingSphere.center.set(0, 0, 0);
6368
+ return;
6369
+ }
6370
+ computeSphere(positions, this.boundingSphere);
6371
+ if (isNaN(this.boundingSphere.radius)) {
6372
+ console.error('THREE.BufferGeometry.computeBoundingSphere(): ' + 'Computed radius is NaN. The ' + '"position" attribute is likely to have NaN values.');
6373
+ }
6374
+ }
6375
+ computeBoundingBox() {
6376
+ if (this.boundingBox === null) {
6377
+ this.boundingBox = new THREE.Box3();
6378
+ }
6379
+ const bbox = this.boundingBox;
6380
+ const positions = this.attributes.position["array"];
6381
+ const itemSize = this.attributes.position.itemSize;
6382
+ if (!positions || !itemSize || positions.length < 2) {
6383
+ bbox.makeEmpty();
6384
+ return;
6385
+ }
6386
+ computeBox(positions, bbox);
6387
+ }
6388
+ constructor(...args){
6389
+ super(...args), this.layout = new BMFontTextLayout();
6390
+ }
6391
+ }
6392
+
6393
+ class Label extends Component {
6394
+ get text() {
6395
+ return this._text;
6396
+ }
6397
+ set text(v) {
6398
+ if (this._text !== v) {
6399
+ this._text = v;
6400
+ this.needsUpdate = true;
6401
+ }
6402
+ }
6403
+ get font() {
6404
+ return this._font;
6405
+ }
6406
+ set font(v) {
6407
+ if (this._font !== v) {
6408
+ this._font = v;
6409
+ this.needsUpdate = true;
6410
+ }
6411
+ }
6412
+ get setting() {
6413
+ return this._setting;
6414
+ }
6415
+ set setting(v) {
6416
+ if (JSON.stringify(this._setting) !== JSON.stringify(v)) {
6417
+ this._setting = v;
6418
+ this.needsUpdate = true;
6419
+ }
6420
+ }
6421
+ get layout() {
6422
+ return this.node.geometry.layout;
6423
+ }
6424
+ forceUpdate() {
6425
+ this.node.geometry.update(this.font, this.text, this.setting);
6426
+ }
6427
+ update(dt) {
6428
+ if (this.needsUpdate) {
6429
+ this.needsUpdate = false;
6430
+ this.forceUpdate();
6431
+ }
6432
+ }
6433
+ constructor({ text = "", font, material, ...setting }){
6434
+ super(), this.needsUpdate = false, this._text = "", this._font = null, this._setting = null;
6435
+ this.text = text;
6436
+ this.font = font;
6437
+ this.setting = setting;
6438
+ this.node = new THREE.Mesh(new BMFontTextGeometry(), material || font.material);
6439
+ this.node.geometry.update(this.font, this.text, this.setting);
6440
+ }
6441
+ }
6442
+
6443
+ const vert_MSDF = `
6444
+ varying vec2 v_uv;
6445
+
6446
+ void main() {
6447
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
6448
+ v_uv = uv;
6449
+ }
6450
+ `;
6451
+ const frag_MSDF = `
6452
+ uniform sampler2D u_fontTexture;
6453
+ varying vec2 v_uv;
6454
+
6455
+ uniform vec3 u_color;
6456
+ uniform float u_opacity;
6457
+ uniform vec3 u_strokeColor;
6458
+ uniform float u_strokeWidth;
6459
+ uniform vec3 u_shadowColor;
6460
+ uniform float u_shadowBlur;
6461
+ uniform vec2 u_shadowOffset;
6462
+ uniform float u_weight;
6463
+
6464
+ float median(in float r, in float g, in float b) {
6465
+ return max(min(r, g), min(max(r, g), b));
6466
+ }
6467
+
6468
+ float signedDistance(in vec2 uv) {
6469
+ vec4 texel = texture2D(u_fontTexture, uv);
6470
+ return median(texel.r, texel.g, texel.b) - 0.5;
6471
+ }
6472
+
6473
+ void main() {
6474
+ vec4 color = vec4(u_color, 1.);
6475
+ float d = signedDistance(v_uv) + u_weight;
6476
+ float w = fwidth(d);
6477
+
6478
+ vec4 stroke = vec4(u_strokeColor, smoothstep(-w, w, d));
6479
+ color.a *= smoothstep(-w, w, d - u_strokeWidth);
6480
+ color = mix(stroke, color, color.a);
6481
+
6482
+ float sd = signedDistance(v_uv + u_shadowOffset) + u_weight;
6483
+ vec4 shadow = vec4(u_shadowColor, smoothstep(-w - u_shadowBlur, w + u_shadowBlur, sd));
6484
+ color = mix(shadow, color, color.a);
6485
+
6486
+ color.a *= u_opacity;
6487
+ gl_FragColor = color;
6488
+ }
6489
+ `;
6490
+ class BMFontAtlas {
6491
+ build(layout, setting) {
6492
+ const info = this.info;
6493
+ const texWidth = info.common.scaleW;
6494
+ const texHeight = info.common.scaleH;
6495
+ const glyphs = layout.glyphs.filter((glyph)=>glyph.data.width * glyph.data.height > 0);
6496
+ const flipY = setting.flipY !== false;
6497
+ const position = new Float32Array(glyphs.length * 8);
6498
+ const uv = new Float32Array(glyphs.length * 8);
6499
+ const indice = new Uint16Array(glyphs.length * 6);
6500
+ for(let k = 0, i0 = 0, i1 = 0, i2 = 0, i = 0; i < glyphs.length; i++, k += 4){
6501
+ const glyph = glyphs[i];
6502
+ const bitmap = glyph.data;
6503
+ // bottom left position
6504
+ let x = glyph.position[0] + bitmap.xoffset;
6505
+ let y = glyph.position[1] + bitmap.yoffset;
6506
+ // quad size
6507
+ let w = bitmap.width;
6508
+ let h = bitmap.height;
6509
+ // BL
6510
+ position[i0++] = x;
6511
+ position[i0++] = y;
6512
+ // BR
6513
+ position[i0++] = x + w;
6514
+ position[i0++] = y;
6515
+ // TR
6516
+ position[i0++] = x + w;
6517
+ position[i0++] = y + h;
6518
+ // TL
6519
+ position[i0++] = x;
6520
+ position[i0++] = y + h;
6521
+ let bw = bitmap.x + bitmap.width;
6522
+ let bh = bitmap.y + bitmap.height;
6523
+ // top left position
6524
+ let u0 = bitmap.x / texWidth;
6525
+ let v0 = bitmap.y / texHeight;
6526
+ let u1 = bw / texWidth;
6527
+ let v1 = bh / texHeight;
6528
+ if (flipY) {
6529
+ v0 = 1 - v0;
6530
+ v1 = 1 - v1;
6531
+ }
6532
+ // BL
6533
+ uv[i1++] = u0;
6534
+ uv[i1++] = v0;
6535
+ // BR
6536
+ uv[i1++] = u1;
6537
+ uv[i1++] = v0;
6538
+ // TR
6539
+ uv[i1++] = u1;
6540
+ uv[i1++] = v1;
6541
+ // TL
6542
+ uv[i1++] = u0;
6543
+ uv[i1++] = v1;
6544
+ indice[i2++] = k + 0;
6545
+ indice[i2++] = k + 1;
6546
+ indice[i2++] = k + 2;
6547
+ indice[i2++] = k + 0;
6548
+ indice[i2++] = k + 2;
6549
+ indice[i2++] = k + 3;
6550
+ }
6551
+ return {
6552
+ position,
6553
+ uv,
6554
+ indice
6555
+ };
6556
+ }
6557
+ constructor({ info, texture, uniforms, ...props }){
6558
+ this.uniforms = {
6559
+ u_color: {
6560
+ value: new THREE.Color(0xffffff)
6561
+ },
6562
+ u_opacity: {
6563
+ value: 1
6564
+ },
6565
+ u_weight: {
6566
+ value: 0.2
6567
+ },
6568
+ u_strokeColor: {
6569
+ value: new THREE.Color(0xff0000)
6570
+ },
6571
+ u_strokeWidth: {
6572
+ value: 0
6573
+ },
6574
+ u_shadowColor: {
6575
+ value: new THREE.Color(0xff0000)
6576
+ },
6577
+ u_shadowBlur: {
6578
+ value: 0
6579
+ },
6580
+ u_shadowOffset: {
6581
+ value: new THREE.Vector2()
6582
+ },
6583
+ u_fontTexture: {
6584
+ value: null
6585
+ }
6586
+ };
6587
+ this.info = info;
6588
+ this.uniforms.u_fontTexture.value = texture;
6589
+ this.material = new THREE.ShaderMaterial(Object.assign({
6590
+ vertexShader: vert_MSDF,
6591
+ fragmentShader: frag_MSDF,
6592
+ transparent: true,
6593
+ depthWrite: false,
6594
+ blending: THREE.NormalBlending,
6595
+ uniforms: {
6596
+ ...this.uniforms,
6597
+ ...uniforms
6598
+ }
6599
+ }, props));
6600
+ }
6601
+ }
6602
+
5813
6603
  exports.AccumulativeShadows = AccumulativeShadows;
5814
6604
  exports.Animation = Animation;
5815
6605
  exports.AnimationCurve = AnimationCurve;
5816
6606
  exports.BINLoader = BINLoader;
6607
+ exports.BMFontAtlas = BMFontAtlas;
6608
+ exports.BMFontTextGeometry = BMFontTextGeometry;
6609
+ exports.BMFontTextLayout = BMFontTextLayout;
5817
6610
  exports.Box = Box;
5818
6611
  exports.BoxProjection = BoxProjection;
5819
6612
  exports.Center = Center;
@@ -5834,6 +6627,7 @@ exports.GLTFLoader = GLTFLoader;
5834
6627
  exports.HDRLoader = HDRLoader;
5835
6628
  exports.JSONLoader = JSONLoader;
5836
6629
  exports.KTX2Loader = KTX2Loader;
6630
+ exports.Label = Label;
5837
6631
  exports.Loader = Loader;
5838
6632
  exports.Logger = Logger;
5839
6633
  exports.ObjectInstance = ObjectInstance;