@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 +855 -61
- package/dist/main.cjs.map +1 -1
- package/dist/module.js +852 -62
- package/dist/module.js.map +1 -1
- package/package.json +1 -1
- package/types/Component.d.ts +0 -1
- package/types/DeviceInput.d.ts +20 -1
- package/types/Viewer.d.ts +7 -4
- package/types/asset/Loader.d.ts +1 -0
- package/types/asset/ResourceManager.d.ts +2 -1
- package/types/bmfont/BMFontAtlas.d.ts +44 -0
- package/types/bmfont/BMFontTextGeometry.d.ts +9 -0
- package/types/bmfont/BMFontTextLayout.d.ts +93 -0
- package/types/bmfont/index.d.ts +3 -0
- package/types/bmfont/utils.d.ts +2 -0
- package/types/bmfont/wordwrap.d.ts +8 -0
- package/types/components/Label.d.ts +26 -0
- package/types/components/index.d.ts +1 -0
- package/types/index.d.ts +1 -0
- package/types/loaders/KTX2Loader.d.ts +1 -1
- package/types/materials/MSDFMaterial.d.ts +20 -0
- package/types/materials/ReflectorMaterial.d.ts +10 -2
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
|
|
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
|
-
|
|
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
|
-
|
|
247
|
+
onLoad(loader.parse(buffer, resourcePath));
|
|
252
248
|
} else {
|
|
253
|
-
loader.load(url,
|
|
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,
|
|
277
|
+
loader.parse(buffer, resourcePath, onLoad, onError);
|
|
287
278
|
} else {
|
|
288
|
-
loader.load(url,
|
|
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,
|
|
374
|
+
loader.parse(buffer, resourcePath, onLoad, onError);
|
|
389
375
|
} else {
|
|
390
|
-
loader.load(url,
|
|
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
|
|
466
|
-
loader.setTranscoderPath(
|
|
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"
|
|
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.
|
|
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.
|
|
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.
|
|
2758
|
-
this._pointer.y = 1 - e.
|
|
2759
|
-
this._pointerPixel.set(e.
|
|
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 =
|
|
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
|
|
2796
|
-
const
|
|
2797
|
-
for(let i =
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
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(
|
|
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 =
|
|
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,
|
|
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
|
-
|
|
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 ||
|
|
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;
|