@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 +857 -61
- package/dist/main.cjs.map +1 -1
- package/dist/module.js +854 -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 +11 -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 );
|
|
@@ -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,
|
|
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
|
-
|
|
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 ||
|
|
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;
|