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

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 );
@@ -3743,6 +3822,8 @@ void main() {
3743
3822
 
3744
3823
  #ifdef USE_LIGHTMAP
3745
3824
  irradiance += texture2D(lightMap, UV_LIGHTMAP).rgb * lightMapIntensity;
3825
+ #else
3826
+ irradiance += vec3(1.);
3746
3827
  #endif
3747
3828
 
3748
3829
  float lod = roughnessFactor * (1.7 - 0.7 * roughnessFactor) * 6.;
@@ -3829,12 +3910,24 @@ class ReflectorMaterial extends THREE.ShaderMaterial {
3829
3910
  set roughnessMap(v) {
3830
3911
  this.uniforms.roughnessMap.value = v;
3831
3912
  }
3913
+ get roughnessScaleBias() {
3914
+ return this.uniforms.roughnessScaleBias.value;
3915
+ }
3916
+ set roughnessScaleBias(v) {
3917
+ this.uniforms.roughnessScaleBias.value.copy(v);
3918
+ }
3832
3919
  get normalMap() {
3833
3920
  return this.uniforms.normalMap.value;
3834
3921
  }
3835
3922
  set normalMap(v) {
3836
3923
  this.uniforms.normalMap.value = v;
3837
3924
  }
3925
+ get normalScaleBias() {
3926
+ return this.uniforms.normalScaleBias.value;
3927
+ }
3928
+ set normalScaleBias(v) {
3929
+ this.uniforms.normalScaleBias.value.copy(v);
3930
+ }
3838
3931
  get aoMap() {
3839
3932
  return this.uniforms.aoMap.value;
3840
3933
  }
@@ -3899,9 +3992,15 @@ class ReflectorMaterial extends THREE.ShaderMaterial {
3899
3992
  roughnessMap: {
3900
3993
  value: null
3901
3994
  },
3995
+ roughnessScaleBias: {
3996
+ value: new THREE.Vector4(1, 1, 0, 0)
3997
+ },
3902
3998
  normalMap: {
3903
3999
  value: null
3904
4000
  },
4001
+ normalScaleBias: {
4002
+ value: new THREE.Vector4(1, 1, 0, 0)
4003
+ },
3905
4004
  aoMap: {
3906
4005
  value: null
3907
4006
  },
@@ -3947,9 +4046,15 @@ __decorate([
3947
4046
  __decorate([
3948
4047
  property
3949
4048
  ], ReflectorMaterial.prototype, "roughnessMap", null);
4049
+ __decorate([
4050
+ property
4051
+ ], ReflectorMaterial.prototype, "roughnessScaleBias", null);
3950
4052
  __decorate([
3951
4053
  property
3952
4054
  ], ReflectorMaterial.prototype, "normalMap", null);
4055
+ __decorate([
4056
+ property
4057
+ ], ReflectorMaterial.prototype, "normalScaleBias", null);
3953
4058
  __decorate([
3954
4059
  property
3955
4060
  ], ReflectorMaterial.prototype, "aoMap", null);
@@ -4411,19 +4516,15 @@ class ResourceManager {
4411
4516
  }
4412
4517
  return loader;
4413
4518
  }
4414
- loadAsset({ url, buffer, ext, path, resourcePath, dracoPath, manager, onProgress, ...props }) {
4519
+ loadAsset({ url, ext, onProgress, ...props }) {
4415
4520
  return new Promise((resolve, reject)=>{
4416
4521
  const sel = ext || url && ResourceManager.extension(url) || "";
4417
4522
  const texSettings = ResourceManager._splitTextureSettings(props);
4418
4523
  if (this._loaders.has(sel)) {
4419
4524
  this._loaders.get(sel).load({
4420
4525
  url,
4421
- buffer,
4422
4526
  texSettings,
4423
- path,
4424
- resourcePath,
4425
- dracoPath,
4426
- manager,
4527
+ ...props,
4427
4528
  onProgress,
4428
4529
  onLoad: resolve,
4429
4530
  onError: (err)=>{
@@ -4880,6 +4981,9 @@ class Viewer extends EventEmitter {
4880
4981
  clearColor(renderTarget, color, alpha) {
4881
4982
  Viewer.ClearColor(this._renderer, renderTarget, color, alpha);
4882
4983
  }
4984
+ stash(renderTarget, callback, clearColor, clearAlpha) {
4985
+ Viewer.Stash(this._renderer, renderTarget, callback, clearColor, clearAlpha);
4986
+ }
4883
4987
  blur(blurLevel, shadingScale, inputBuffer, tempBuffer, outputBuffer, fixedOutput) {
4884
4988
  Viewer.Blur(this._renderer, blurLevel, shadingScale, inputBuffer, tempBuffer, outputBuffer, fixedOutput);
4885
4989
  }
@@ -4975,7 +5079,7 @@ class Viewer extends EventEmitter {
4975
5079
  renderer.autoClear = true;
4976
5080
  renderer.setRenderTarget(renderTarget);
4977
5081
  clearColor !== undefined && renderer.setClearColor(clearColor, clearAlpha);
4978
- callback && callback();
5082
+ callback && callback(renderer);
4979
5083
  renderer.autoClear = autoClear;
4980
5084
  renderer.setRenderTarget(RT);
4981
5085
  clearColor !== undefined && renderer.setClearColor(color, alpha);
@@ -5011,7 +5115,7 @@ class Viewer extends EventEmitter {
5011
5115
  near: 0.1,
5012
5116
  far: 1000,
5013
5117
  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 } = {}){
5118
+ }, 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
5119
  super(), this._instanceId = Viewer.instanceCount++, this._dpr = 1, this._width = 1, this._height = 1, this._viewport = {
5016
5120
  width: 1,
5017
5121
  height: 1,
@@ -5069,12 +5173,15 @@ class Viewer extends EventEmitter {
5069
5173
  path,
5070
5174
  resourcePath,
5071
5175
  dracoPath,
5176
+ transcoderPath,
5072
5177
  manager: this._loadingManager
5073
5178
  };
5074
5179
  this._mount = applyProps(new THREE.Object3D(), {
5075
5180
  name: "Mount"
5076
5181
  });
5077
- this._input = this.add(new DeviceInput(input || this._canvas));
5182
+ this._input = this.add(new DeviceInput(input || {
5183
+ source: this._canvas
5184
+ }));
5078
5185
  this.add(Renderer);
5079
5186
  this.addLoader(GLTFLoader);
5080
5187
  this.addLoader(HDRLoader);
@@ -5810,10 +5917,698 @@ function getFilesFromItemList(items, onDone) {
5810
5917
  }
5811
5918
  }
5812
5919
 
5920
+ const newline = /\n/;
5921
+ const newlineChar = '\n';
5922
+ const whitespace = /\s/;
5923
+ function wordwrap(text, opt) {
5924
+ opt = opt || {};
5925
+ //zero width results in nothing visible
5926
+ if (opt.width === 0 && opt.mode !== 'nowrap') return [];
5927
+ text = text || '';
5928
+ const width = typeof opt.width === 'number' ? opt.width : Number.MAX_VALUE;
5929
+ const start = Math.max(0, opt.start || 0);
5930
+ const end = typeof opt.end === 'number' ? opt.end : text.length;
5931
+ const mode = opt.mode;
5932
+ const letterSpacing = opt.letterSpacing || 0;
5933
+ const measure = opt.measure || monospace;
5934
+ if (mode === 'pre') return pre(measure, text, start, end, width, letterSpacing);
5935
+ else return greedy(measure, text, start, end, width, mode, letterSpacing);
5936
+ }
5937
+ function idxOf(text, chr, start, end) {
5938
+ var idx = text.indexOf(chr, start);
5939
+ if (idx === -1 || idx > end) return end;
5940
+ return idx;
5941
+ }
5942
+ function isWhitespace(chr) {
5943
+ return whitespace.test(chr);
5944
+ }
5945
+ function pre(measure, text, start, end, width, letterSpacing) {
5946
+ var lines = [];
5947
+ var lineStart = start;
5948
+ for(var i = start; i < end && i < text.length; i++){
5949
+ var chr = text.charAt(i);
5950
+ var isNewline = newline.test(chr);
5951
+ //If we've reached a newline, then step down a line
5952
+ //Or if we've reached the EOF
5953
+ if (isNewline || i === end - 1) {
5954
+ var lineEnd = isNewline ? i : i + 1;
5955
+ var measured = measure(text, lineStart, lineEnd, width, letterSpacing);
5956
+ lines.push(measured);
5957
+ lineStart = i + 1;
5958
+ }
5959
+ }
5960
+ return lines;
5961
+ }
5962
+ function greedy(measure, text, start, end, width, mode, letterSpacing) {
5963
+ //A greedy word wrapper based on LibGDX algorithm
5964
+ //https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g2d/BitmapFontCache.java
5965
+ var lines = [];
5966
+ var testWidth = width;
5967
+ //if 'nowrap' is specified, we only wrap on newline chars
5968
+ if (mode === 'nowrap') testWidth = Number.MAX_VALUE;
5969
+ while(start < end && start < text.length){
5970
+ //get next newline position
5971
+ var newLine = idxOf(text, newlineChar, start, end);
5972
+ //eat whitespace at start of line
5973
+ while(start < newLine){
5974
+ if (!isWhitespace(text.charAt(start))) break;
5975
+ start++;
5976
+ }
5977
+ //determine visible # of glyphs for the available width
5978
+ var measured = measure(text, start, newLine, testWidth, letterSpacing);
5979
+ var lineEnd = start + (measured.end - measured.start);
5980
+ var nextStart = lineEnd + newlineChar.length;
5981
+ //if we had to cut the line before the next newline...
5982
+ if (lineEnd < newLine) {
5983
+ //find char to break on
5984
+ while(lineEnd > start){
5985
+ if (isWhitespace(text.charAt(lineEnd))) break;
5986
+ lineEnd--;
5987
+ }
5988
+ if (lineEnd === start) {
5989
+ if (nextStart > start + newlineChar.length) nextStart--;
5990
+ lineEnd = nextStart; // If no characters to break, show all.
5991
+ } else {
5992
+ nextStart = lineEnd;
5993
+ //eat whitespace at end of line
5994
+ while(lineEnd > start){
5995
+ if (!isWhitespace(text.charAt(lineEnd - newlineChar.length))) break;
5996
+ lineEnd--;
5997
+ }
5998
+ }
5999
+ }
6000
+ if (lineEnd >= start) {
6001
+ var result = measure(text, start, lineEnd, testWidth);
6002
+ lines.push(result);
6003
+ }
6004
+ start = nextStart;
6005
+ }
6006
+ return lines;
6007
+ }
6008
+ //determines the visible number of glyphs within a given width
6009
+ function monospace(text, start, end, width) {
6010
+ var glyphs = Math.min(width, end - start);
6011
+ return {
6012
+ start: start,
6013
+ end: start + glyphs
6014
+ };
6015
+ }
6016
+
6017
+ const X_HEIGHTS = [
6018
+ 'x',
6019
+ 'e',
6020
+ 'a',
6021
+ 'o',
6022
+ 'n',
6023
+ 's',
6024
+ 'r',
6025
+ 'c',
6026
+ 'u',
6027
+ 'm',
6028
+ 'v',
6029
+ 'w',
6030
+ 'z'
6031
+ ];
6032
+ const M_WIDTHS = [
6033
+ 'm',
6034
+ 'w'
6035
+ ];
6036
+ const CAP_HEIGHTS = [
6037
+ 'H',
6038
+ 'I',
6039
+ 'N',
6040
+ 'E',
6041
+ 'F',
6042
+ 'K',
6043
+ 'L',
6044
+ 'T',
6045
+ 'U',
6046
+ 'V',
6047
+ 'W',
6048
+ 'X',
6049
+ 'Y',
6050
+ 'Z'
6051
+ ];
6052
+ const TAB_ID = '\t'.charCodeAt(0);
6053
+ const SPACE_ID = ' '.charCodeAt(0);
6054
+ const ALIGN_LEFT = 0, ALIGN_CENTER = 1, ALIGN_RIGHT = 2;
6055
+ function findChar(array, value, start) {
6056
+ start = start || 0;
6057
+ for(let i = start; i < array.length; i++){
6058
+ if (array[i].id === value) {
6059
+ return i;
6060
+ }
6061
+ }
6062
+ return -1;
6063
+ }
6064
+ function getGlyphById(font, id) {
6065
+ if (!font.chars || font.chars.length === 0) return null;
6066
+ let glyphIdx = findChar(font.chars, id);
6067
+ if (glyphIdx >= 0) return font.chars[glyphIdx];
6068
+ return null;
6069
+ }
6070
+ function getXHeight(font) {
6071
+ for(let i = 0; i < X_HEIGHTS.length; i++){
6072
+ let id = X_HEIGHTS[i].charCodeAt(0);
6073
+ let idx = findChar(font.chars, id);
6074
+ if (idx >= 0) return font.chars[idx].height;
6075
+ }
6076
+ return 0;
6077
+ }
6078
+ function getMGlyph(font) {
6079
+ for(let i = 0; i < M_WIDTHS.length; i++){
6080
+ let id = M_WIDTHS[i].charCodeAt(0);
6081
+ let idx = findChar(font.chars, id);
6082
+ if (idx >= 0) return font.chars[idx];
6083
+ }
6084
+ return 0;
6085
+ }
6086
+ function getCapHeight(font) {
6087
+ for(let i = 0; i < CAP_HEIGHTS.length; i++){
6088
+ let id = CAP_HEIGHTS[i].charCodeAt(0);
6089
+ let idx = findChar(font.chars, id);
6090
+ if (idx >= 0) return font.chars[idx].height;
6091
+ }
6092
+ return 0;
6093
+ }
6094
+ function getKerning(font, left, right) {
6095
+ if (!font.kernings || font.kernings.length === 0) return 0;
6096
+ let table = font.kernings;
6097
+ for(let i = 0; i < table.length; i++){
6098
+ let kern = table[i];
6099
+ if (kern.first === left && kern.second === right) return kern.amount;
6100
+ }
6101
+ return 0;
6102
+ }
6103
+ function getAlignType(align) {
6104
+ if (align === 'center') return ALIGN_CENTER;
6105
+ else if (align === 'right') return ALIGN_RIGHT;
6106
+ return ALIGN_LEFT;
6107
+ }
6108
+ class BMFontTextLayout {
6109
+ get width() {
6110
+ return this._width;
6111
+ }
6112
+ get height() {
6113
+ return this._height;
6114
+ }
6115
+ get descender() {
6116
+ return this._descender;
6117
+ }
6118
+ get ascender() {
6119
+ return this._ascender;
6120
+ }
6121
+ get xHeight() {
6122
+ return this._xHeight;
6123
+ }
6124
+ get baseline() {
6125
+ return this._baseline;
6126
+ }
6127
+ get capHeight() {
6128
+ return this._capHeight;
6129
+ }
6130
+ get lineHeight() {
6131
+ return this._lineHeight;
6132
+ }
6133
+ get glyphs() {
6134
+ return this._glyphs;
6135
+ }
6136
+ get linesTotal() {
6137
+ return this._linesTotal;
6138
+ }
6139
+ update(font, text, setting) {
6140
+ setting = Object.assign({
6141
+ tabSize: 4,
6142
+ width: 0,
6143
+ letterSpacing: 0,
6144
+ mode: "nowrap",
6145
+ align: "left"
6146
+ }, setting);
6147
+ this._font = font;
6148
+ const measure = this._computeMetrics.bind(this);
6149
+ const lines = wordwrap(text, {
6150
+ measure,
6151
+ ...setting
6152
+ });
6153
+ const minWidth = setting.width || 0;
6154
+ const glyphs = this._glyphs;
6155
+ const maxLineWidth = lines.reduce((prev, line)=>Math.max(prev, line.width, minWidth), 0);
6156
+ var _setting_lineHeight;
6157
+ //the pen position
6158
+ const lineHeight = (_setting_lineHeight = setting.lineHeight) != null ? _setting_lineHeight : font.common.lineHeight;
6159
+ const baseline = font.common.base;
6160
+ const descender = lineHeight - baseline;
6161
+ const letterSpacing = setting.letterSpacing || 0;
6162
+ const height = lineHeight * lines.length - descender;
6163
+ const align = getAlignType(setting.align);
6164
+ var _setting_anchor;
6165
+ const anchor = (_setting_anchor = setting.anchor) != null ? _setting_anchor : [
6166
+ 0.5,
6167
+ 0.5
6168
+ ];
6169
+ this._setupSpaceGlyphs(font, setting);
6170
+ //the metrics for this text layout
6171
+ this._width = maxLineWidth;
6172
+ this._height = height;
6173
+ this._descender = descender;
6174
+ this._baseline = baseline;
6175
+ this._xHeight = getXHeight(font);
6176
+ this._capHeight = getCapHeight(font);
6177
+ this._lineHeight = lineHeight;
6178
+ this._ascender = baseline - this._xHeight; //lineHeight - descender - this._xHeight
6179
+ const anchorOffset = [
6180
+ -maxLineWidth * anchor[0],
6181
+ 2 * lineHeight * anchor[1] - baseline
6182
+ ];
6183
+ let x = 0, y = 0;
6184
+ //draw text along baseline
6185
+ y -= height;
6186
+ glyphs.length = 0;
6187
+ for(let k = 0; k < lines.length; k++){
6188
+ const line = lines[k];
6189
+ let start = line.start;
6190
+ let end = line.end;
6191
+ let lineWidth = line.width;
6192
+ let lastGlyph;
6193
+ //for each glyph in that line...
6194
+ for(let i = start; i < end; i++){
6195
+ let id = text.charCodeAt(i);
6196
+ let glyph = this._getGlyph(font, id);
6197
+ if (glyph) {
6198
+ if (lastGlyph) x += getKerning(font, lastGlyph.id, glyph.id);
6199
+ let tx = x;
6200
+ if (align === ALIGN_CENTER) tx += (maxLineWidth - lineWidth) / 2;
6201
+ else if (align === ALIGN_RIGHT) tx += maxLineWidth - lineWidth;
6202
+ glyphs.push({
6203
+ position: [
6204
+ tx + anchorOffset[0],
6205
+ y + anchorOffset[1]
6206
+ ],
6207
+ data: glyph,
6208
+ index: i,
6209
+ line: k
6210
+ });
6211
+ //move pen forward
6212
+ x += glyph.xadvance + letterSpacing;
6213
+ lastGlyph = glyph;
6214
+ }
6215
+ }
6216
+ //next line down
6217
+ y += lineHeight;
6218
+ x = 0;
6219
+ }
6220
+ this._linesTotal = lines.length;
6221
+ }
6222
+ _setupSpaceGlyphs(font, setting) {
6223
+ //These are fallbacks, when the font doesn't include
6224
+ //' ' or '\t' glyphs
6225
+ if (!font.chars || font.chars.length === 0) return;
6226
+ //try to get space glyph
6227
+ //then fall back to the 'm' or 'w' glyphs
6228
+ //then fall back to the first glyph available
6229
+ const space = Object.assign({}, getGlyphById(font, SPACE_ID) || getMGlyph(font) || font.chars[0]);
6230
+ //and create a fallback for tab
6231
+ const tabWidth = setting.tabSize * space.xadvance;
6232
+ this._fallbackSpaceGlyph = space;
6233
+ this._fallbackTabGlyph = Object.assign(space, {
6234
+ x: 0,
6235
+ y: 0,
6236
+ xadvance: tabWidth,
6237
+ id: TAB_ID,
6238
+ xoffset: 0,
6239
+ yoffset: 0,
6240
+ width: 0,
6241
+ height: 0
6242
+ });
6243
+ }
6244
+ _getGlyph(font, id) {
6245
+ let glyph = getGlyphById(font, id);
6246
+ if (glyph) return glyph;
6247
+ else if (id === TAB_ID) return this._fallbackTabGlyph;
6248
+ else if (id === SPACE_ID) return this._fallbackSpaceGlyph;
6249
+ return null;
6250
+ }
6251
+ _computeMetrics(text, start, end, width, letterSpacing = 0) {
6252
+ let font = this._font;
6253
+ let curPen = 0;
6254
+ let curWidth = 0;
6255
+ let count = 0;
6256
+ let lastGlyph;
6257
+ if (!font.chars || font.chars.length === 0) {
6258
+ return {
6259
+ start: start,
6260
+ end: start,
6261
+ width: 0
6262
+ };
6263
+ }
6264
+ end = Math.min(text.length, end);
6265
+ for(let i = start; i < end; i++){
6266
+ let id = text.charCodeAt(i);
6267
+ let glyph = this._getGlyph(font, id);
6268
+ if (glyph) {
6269
+ //move pen forward
6270
+ glyph.xoffset;
6271
+ let kern = lastGlyph ? getKerning(font, lastGlyph.id, glyph.id) : 0;
6272
+ curPen += kern;
6273
+ let nextPen = curPen + glyph.xadvance + letterSpacing;
6274
+ let nextWidth = curPen + glyph.width;
6275
+ //we've hit our limit; we can't move onto the next glyph
6276
+ if (nextWidth >= width || nextPen >= width) break;
6277
+ //otherwise continue along our line
6278
+ curPen = nextPen;
6279
+ curWidth = nextWidth;
6280
+ lastGlyph = glyph;
6281
+ }
6282
+ count++;
6283
+ }
6284
+ //make sure rightmost edge lines up with rendered glyphs
6285
+ if (lastGlyph) curWidth += lastGlyph.xoffset;
6286
+ return {
6287
+ start: start,
6288
+ end: start + count,
6289
+ width: curWidth
6290
+ };
6291
+ }
6292
+ constructor(){
6293
+ this._width = 0;
6294
+ this._height = 0;
6295
+ this._descender = 0;
6296
+ this._ascender = 0;
6297
+ this._xHeight = 0;
6298
+ this._baseline = 0;
6299
+ this._capHeight = 0;
6300
+ this._lineHeight = 0;
6301
+ this._linesTotal = 0;
6302
+ this._glyphs = [];
6303
+ this._fallbackSpaceGlyph = null;
6304
+ this._fallbackTabGlyph = null;
6305
+ this._font = null;
6306
+ }
6307
+ }
6308
+
6309
+ const itemSize = 2;
6310
+ const box = {
6311
+ min: [
6312
+ 0,
6313
+ 0
6314
+ ],
6315
+ max: [
6316
+ 0,
6317
+ 0
6318
+ ]
6319
+ };
6320
+ function bounds(positions) {
6321
+ const count = positions.length / itemSize;
6322
+ box.min[0] = positions[0];
6323
+ box.min[1] = positions[1];
6324
+ box.max[0] = positions[0];
6325
+ box.max[1] = positions[1];
6326
+ for(let i = 0; i < count; i++){
6327
+ const x = positions[i * itemSize + 0];
6328
+ const y = positions[i * itemSize + 1];
6329
+ box.min[0] = Math.min(x, box.min[0]);
6330
+ box.min[1] = Math.min(y, box.min[1]);
6331
+ box.max[0] = Math.max(x, box.max[0]);
6332
+ box.max[1] = Math.max(y, box.max[1]);
6333
+ }
6334
+ }
6335
+ function computeBox(positions, output) {
6336
+ bounds(positions);
6337
+ output.min.set(box.min[0], box.min[1], 0);
6338
+ output.max.set(box.max[0], box.max[1], 0);
6339
+ }
6340
+ function computeSphere(positions, output) {
6341
+ bounds(positions);
6342
+ const minX = box.min[0];
6343
+ const minY = box.min[1];
6344
+ const maxX = box.max[0];
6345
+ const maxY = box.max[1];
6346
+ const width = maxX - minX;
6347
+ const height = maxY - minY;
6348
+ const length = Math.sqrt(width * width + height * height);
6349
+ output.center.set(minX + width / 2, minY + height / 2, 0);
6350
+ output.radius = length / 2;
6351
+ }
6352
+
6353
+ class BMFontTextGeometry extends THREE.BufferGeometry {
6354
+ update(fontAtlas, text, setting) {
6355
+ this.layout.update(fontAtlas.info, text, setting);
6356
+ const { indice, position, uv } = fontAtlas.build(this.layout, setting);
6357
+ this.setIndex(new THREE.BufferAttribute(indice, 1));
6358
+ this.setAttribute("position", new THREE.BufferAttribute(position, 2));
6359
+ this.setAttribute("uv", new THREE.BufferAttribute(uv, 2));
6360
+ }
6361
+ computeBoundingSphere() {
6362
+ if (this.boundingSphere === null) {
6363
+ this.boundingSphere = new THREE.Sphere();
6364
+ }
6365
+ const positions = this.attributes.position.array;
6366
+ const itemSize = this.attributes.position.itemSize;
6367
+ if (!positions || !itemSize || positions.length < 2) {
6368
+ this.boundingSphere.radius = 0;
6369
+ this.boundingSphere.center.set(0, 0, 0);
6370
+ return;
6371
+ }
6372
+ computeSphere(positions, this.boundingSphere);
6373
+ if (isNaN(this.boundingSphere.radius)) {
6374
+ console.error('THREE.BufferGeometry.computeBoundingSphere(): ' + 'Computed radius is NaN. The ' + '"position" attribute is likely to have NaN values.');
6375
+ }
6376
+ }
6377
+ computeBoundingBox() {
6378
+ if (this.boundingBox === null) {
6379
+ this.boundingBox = new THREE.Box3();
6380
+ }
6381
+ const bbox = this.boundingBox;
6382
+ const positions = this.attributes.position["array"];
6383
+ const itemSize = this.attributes.position.itemSize;
6384
+ if (!positions || !itemSize || positions.length < 2) {
6385
+ bbox.makeEmpty();
6386
+ return;
6387
+ }
6388
+ computeBox(positions, bbox);
6389
+ }
6390
+ constructor(...args){
6391
+ super(...args), this.layout = new BMFontTextLayout();
6392
+ }
6393
+ }
6394
+
6395
+ class Label extends Component {
6396
+ get text() {
6397
+ return this._text;
6398
+ }
6399
+ set text(v) {
6400
+ if (this._text !== v) {
6401
+ this._text = v;
6402
+ this.needsUpdate = true;
6403
+ }
6404
+ }
6405
+ get font() {
6406
+ return this._font;
6407
+ }
6408
+ set font(v) {
6409
+ if (this._font !== v) {
6410
+ this._font = v;
6411
+ this.needsUpdate = true;
6412
+ }
6413
+ }
6414
+ get setting() {
6415
+ return this._setting;
6416
+ }
6417
+ set setting(v) {
6418
+ if (JSON.stringify(this._setting) !== JSON.stringify(v)) {
6419
+ this._setting = v;
6420
+ this.needsUpdate = true;
6421
+ }
6422
+ }
6423
+ get layout() {
6424
+ return this.node.geometry.layout;
6425
+ }
6426
+ forceUpdate() {
6427
+ this.node.geometry.update(this.font, this.text, this.setting);
6428
+ }
6429
+ update(dt) {
6430
+ if (this.needsUpdate) {
6431
+ this.needsUpdate = false;
6432
+ this.forceUpdate();
6433
+ }
6434
+ }
6435
+ constructor({ text = "", font, material, ...setting }){
6436
+ super(), this.needsUpdate = false, this._text = "", this._font = null, this._setting = null;
6437
+ this.text = text;
6438
+ this.font = font;
6439
+ this.setting = setting;
6440
+ this.node = new THREE.Mesh(new BMFontTextGeometry(), material || font.material);
6441
+ this.node.geometry.update(this.font, this.text, this.setting);
6442
+ }
6443
+ }
6444
+
6445
+ const vert_MSDF = `
6446
+ varying vec2 v_uv;
6447
+
6448
+ void main() {
6449
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
6450
+ v_uv = uv;
6451
+ }
6452
+ `;
6453
+ const frag_MSDF = `
6454
+ uniform sampler2D u_fontTexture;
6455
+ varying vec2 v_uv;
6456
+
6457
+ uniform vec3 u_color;
6458
+ uniform float u_opacity;
6459
+ uniform vec3 u_strokeColor;
6460
+ uniform float u_strokeWidth;
6461
+ uniform vec3 u_shadowColor;
6462
+ uniform float u_shadowBlur;
6463
+ uniform vec2 u_shadowOffset;
6464
+ uniform float u_weight;
6465
+
6466
+ float median(in float r, in float g, in float b) {
6467
+ return max(min(r, g), min(max(r, g), b));
6468
+ }
6469
+
6470
+ float signedDistance(in vec2 uv) {
6471
+ vec4 texel = texture2D(u_fontTexture, uv);
6472
+ return median(texel.r, texel.g, texel.b) - 0.5;
6473
+ }
6474
+
6475
+ void main() {
6476
+ vec4 color = vec4(u_color, 1.);
6477
+ float d = signedDistance(v_uv) + u_weight;
6478
+ float w = fwidth(d);
6479
+
6480
+ vec4 stroke = vec4(u_strokeColor, smoothstep(-w, w, d));
6481
+ color.a *= smoothstep(-w, w, d - u_strokeWidth);
6482
+ color = mix(stroke, color, color.a);
6483
+
6484
+ float sd = signedDistance(v_uv + u_shadowOffset) + u_weight;
6485
+ vec4 shadow = vec4(u_shadowColor, smoothstep(-w - u_shadowBlur, w + u_shadowBlur, sd));
6486
+ color = mix(shadow, color, color.a);
6487
+
6488
+ color.a *= u_opacity;
6489
+ gl_FragColor = color;
6490
+ }
6491
+ `;
6492
+ class BMFontAtlas {
6493
+ build(layout, setting) {
6494
+ const info = this.info;
6495
+ const texWidth = info.common.scaleW;
6496
+ const texHeight = info.common.scaleH;
6497
+ const glyphs = layout.glyphs.filter((glyph)=>glyph.data.width * glyph.data.height > 0);
6498
+ const flipY = setting.flipY !== false;
6499
+ const position = new Float32Array(glyphs.length * 8);
6500
+ const uv = new Float32Array(glyphs.length * 8);
6501
+ const indice = new Uint16Array(glyphs.length * 6);
6502
+ for(let k = 0, i0 = 0, i1 = 0, i2 = 0, i = 0; i < glyphs.length; i++, k += 4){
6503
+ const glyph = glyphs[i];
6504
+ const bitmap = glyph.data;
6505
+ // bottom left position
6506
+ let x = glyph.position[0] + bitmap.xoffset;
6507
+ let y = glyph.position[1] + bitmap.yoffset;
6508
+ // quad size
6509
+ let w = bitmap.width;
6510
+ let h = bitmap.height;
6511
+ // BL
6512
+ position[i0++] = x;
6513
+ position[i0++] = y;
6514
+ // BR
6515
+ position[i0++] = x + w;
6516
+ position[i0++] = y;
6517
+ // TR
6518
+ position[i0++] = x + w;
6519
+ position[i0++] = y + h;
6520
+ // TL
6521
+ position[i0++] = x;
6522
+ position[i0++] = y + h;
6523
+ let bw = bitmap.x + bitmap.width;
6524
+ let bh = bitmap.y + bitmap.height;
6525
+ // top left position
6526
+ let u0 = bitmap.x / texWidth;
6527
+ let v0 = bitmap.y / texHeight;
6528
+ let u1 = bw / texWidth;
6529
+ let v1 = bh / texHeight;
6530
+ if (flipY) {
6531
+ v0 = 1 - v0;
6532
+ v1 = 1 - v1;
6533
+ }
6534
+ // BL
6535
+ uv[i1++] = u0;
6536
+ uv[i1++] = v0;
6537
+ // BR
6538
+ uv[i1++] = u1;
6539
+ uv[i1++] = v0;
6540
+ // TR
6541
+ uv[i1++] = u1;
6542
+ uv[i1++] = v1;
6543
+ // TL
6544
+ uv[i1++] = u0;
6545
+ uv[i1++] = v1;
6546
+ indice[i2++] = k + 0;
6547
+ indice[i2++] = k + 1;
6548
+ indice[i2++] = k + 2;
6549
+ indice[i2++] = k + 0;
6550
+ indice[i2++] = k + 2;
6551
+ indice[i2++] = k + 3;
6552
+ }
6553
+ return {
6554
+ position,
6555
+ uv,
6556
+ indice
6557
+ };
6558
+ }
6559
+ constructor({ info, texture, uniforms, ...props }){
6560
+ this.uniforms = {
6561
+ u_color: {
6562
+ value: new THREE.Color(0xffffff)
6563
+ },
6564
+ u_opacity: {
6565
+ value: 1
6566
+ },
6567
+ u_weight: {
6568
+ value: 0.2
6569
+ },
6570
+ u_strokeColor: {
6571
+ value: new THREE.Color(0xff0000)
6572
+ },
6573
+ u_strokeWidth: {
6574
+ value: 0
6575
+ },
6576
+ u_shadowColor: {
6577
+ value: new THREE.Color(0xff0000)
6578
+ },
6579
+ u_shadowBlur: {
6580
+ value: 0
6581
+ },
6582
+ u_shadowOffset: {
6583
+ value: new THREE.Vector2()
6584
+ },
6585
+ u_fontTexture: {
6586
+ value: null
6587
+ }
6588
+ };
6589
+ this.info = info;
6590
+ this.uniforms.u_fontTexture.value = texture;
6591
+ this.material = new THREE.ShaderMaterial(Object.assign({
6592
+ vertexShader: vert_MSDF,
6593
+ fragmentShader: frag_MSDF,
6594
+ transparent: true,
6595
+ depthWrite: false,
6596
+ blending: THREE.NormalBlending,
6597
+ uniforms: {
6598
+ ...this.uniforms,
6599
+ ...uniforms
6600
+ }
6601
+ }, props));
6602
+ }
6603
+ }
6604
+
5813
6605
  exports.AccumulativeShadows = AccumulativeShadows;
5814
6606
  exports.Animation = Animation;
5815
6607
  exports.AnimationCurve = AnimationCurve;
5816
6608
  exports.BINLoader = BINLoader;
6609
+ exports.BMFontAtlas = BMFontAtlas;
6610
+ exports.BMFontTextGeometry = BMFontTextGeometry;
6611
+ exports.BMFontTextLayout = BMFontTextLayout;
5817
6612
  exports.Box = Box;
5818
6613
  exports.BoxProjection = BoxProjection;
5819
6614
  exports.Center = Center;
@@ -5834,6 +6629,7 @@ exports.GLTFLoader = GLTFLoader;
5834
6629
  exports.HDRLoader = HDRLoader;
5835
6630
  exports.JSONLoader = JSONLoader;
5836
6631
  exports.KTX2Loader = KTX2Loader;
6632
+ exports.Label = Label;
5837
6633
  exports.Loader = Loader;
5838
6634
  exports.Logger = Logger;
5839
6635
  exports.ObjectInstance = ObjectInstance;