@xviewer.js/core 1.0.4-alpha.8 → 1.0.4
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 +751 -35
- package/dist/main.cjs.map +1 -1
- package/dist/module.js +749 -37
- package/dist/module.js.map +1 -1
- package/package.json +1 -1
- package/types/Task.d.ts +3 -3
- package/types/TaskManager.d.ts +1 -2
- package/types/Viewer.d.ts +3 -0
- 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/materials/MSDFMaterial.d.ts +20 -0
- package/types/materials/ReflectorMaterial.d.ts +11 -2
package/dist/module.js
CHANGED
|
@@ -4,7 +4,7 @@ import { GLTFLoader as GLTFLoader$1 } from 'three/examples/jsm/loaders/GLTFLoade
|
|
|
4
4
|
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
|
|
5
5
|
import { MeshoptDecoder } from 'three/examples/jsm/libs/meshopt_decoder.module.js';
|
|
6
6
|
import * as THREE from 'three';
|
|
7
|
-
import { EquirectangularReflectionMapping, FileLoader, TextureLoader as TextureLoader$1, SRGBColorSpace, CubeUVReflectionMapping, Mesh, BoxGeometry, SphereGeometry, PlaneGeometry, MathUtils, Vector3, Vector2, LinearInterpolant, Object3D, Plane as Plane$1, Matrix4, Vector4, PerspectiveCamera, WebGLRenderTarget, LinearMipMapLinearFilter, LinearFilter, HalfFloatType, AnimationMixer, Color, OrthographicCamera, MeshDepthMaterial, ShaderMaterial, Euler, Group, REVISION, Box3, Sphere as Sphere$1, Raycaster, Quaternion, Spherical, UniformsUtils, NoBlending, AdditiveBlending, FloatType, UnsignedByteType, LinearSRGBColorSpace, NearestFilter, ClampToEdgeWrapping, WebGLCubeRenderTarget, DataTexture, RGBAFormat, UVMapping, BufferGeometry, Float32BufferAttribute, Scene, WebGLRenderer, LinearToneMapping, PCFSoftShadowMap, LoadingManager, PMREMGenerator, CubeCamera, ShaderLib, ShaderChunk } from 'three';
|
|
7
|
+
import { EquirectangularReflectionMapping, FileLoader, TextureLoader as TextureLoader$1, SRGBColorSpace, CubeUVReflectionMapping, Mesh, BoxGeometry, SphereGeometry, PlaneGeometry, MathUtils, Vector3, Vector2, LinearInterpolant, Object3D, Plane as Plane$1, Matrix4, Vector4, PerspectiveCamera, WebGLRenderTarget, LinearMipMapLinearFilter, LinearFilter, HalfFloatType, AnimationMixer, Color, OrthographicCamera, MeshDepthMaterial, ShaderMaterial, Euler, Group, REVISION, Box3, Sphere as Sphere$1, Raycaster, Quaternion, Spherical, UniformsUtils, NoBlending, AdditiveBlending, FloatType, UnsignedByteType, LinearSRGBColorSpace, NearestFilter, ClampToEdgeWrapping, WebGLCubeRenderTarget, DataTexture, RGBAFormat, UVMapping, BufferGeometry, Float32BufferAttribute, Scene, WebGLRenderer, LinearToneMapping, PCFSoftShadowMap, LoadingManager, PMREMGenerator, CubeCamera, ShaderLib, ShaderChunk, BufferAttribute, NormalBlending } from 'three';
|
|
8
8
|
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js';
|
|
9
9
|
import { SVGLoader as SVGLoader$1 } from 'three/examples/jsm/loaders/SVGLoader.js';
|
|
10
10
|
import { KTX2Loader as KTX2Loader$1 } from 'three/examples/jsm/loaders/KTX2Loader.js';
|
|
@@ -3723,7 +3723,9 @@ uniform float roughness;
|
|
|
3723
3723
|
uniform float metalness;
|
|
3724
3724
|
uniform sampler2D map;
|
|
3725
3725
|
uniform sampler2D normalMap;
|
|
3726
|
+
uniform vec4 normalScaleBias;
|
|
3726
3727
|
uniform sampler2D roughnessMap;
|
|
3728
|
+
uniform vec4 roughnessScaleBias;
|
|
3727
3729
|
uniform sampler2D aoMap;
|
|
3728
3730
|
uniform float aoMapIntensity;
|
|
3729
3731
|
uniform sampler2D lightMap;
|
|
@@ -3761,7 +3763,7 @@ void main() {
|
|
|
3761
3763
|
vec2 reflectUv = coord.xy;
|
|
3762
3764
|
|
|
3763
3765
|
#ifdef USE_NORMALMAP
|
|
3764
|
-
vec4 texelNormal = texture2D(normalMap, UV_NORMAL);
|
|
3766
|
+
vec4 texelNormal = texture2D(normalMap, UV_NORMAL * normalScaleBias.xy + normalScaleBias.zw);
|
|
3765
3767
|
vec3 normal = normalize(vec3(texelNormal.r * 2.0 - 1.0, texelNormal.b, texelNormal.g * 2.0 - 1.0));
|
|
3766
3768
|
reflectUv += coord.z * normal.xz * 0.05;
|
|
3767
3769
|
#endif
|
|
@@ -3788,7 +3790,7 @@ void main() {
|
|
|
3788
3790
|
float roughnessFactor = roughness;
|
|
3789
3791
|
|
|
3790
3792
|
#ifdef USE_ROUGHNESSMAP
|
|
3791
|
-
roughnessFactor *= texture2D(roughnessMap, UV_ROUGHNESS).g * roughness;
|
|
3793
|
+
roughnessFactor *= texture2D(roughnessMap, UV_ROUGHNESS * roughnessScaleBias.xy + roughnessScaleBias.zw).g * roughness;
|
|
3792
3794
|
#endif
|
|
3793
3795
|
|
|
3794
3796
|
computeMultiscattering( geometryNormal, geometryViewDir, specularColor, specularF90, roughnessFactor, singleScattering, multiScattering );
|
|
@@ -3800,6 +3802,8 @@ void main() {
|
|
|
3800
3802
|
|
|
3801
3803
|
#ifdef USE_LIGHTMAP
|
|
3802
3804
|
irradiance += texture2D(lightMap, UV_LIGHTMAP).rgb * lightMapIntensity;
|
|
3805
|
+
#else
|
|
3806
|
+
irradiance += vec3(1.);
|
|
3803
3807
|
#endif
|
|
3804
3808
|
|
|
3805
3809
|
float lod = roughnessFactor * (1.7 - 0.7 * roughnessFactor) * 6.;
|
|
@@ -3886,12 +3890,24 @@ class ReflectorMaterial extends ShaderMaterial {
|
|
|
3886
3890
|
set roughnessMap(v) {
|
|
3887
3891
|
this.uniforms.roughnessMap.value = v;
|
|
3888
3892
|
}
|
|
3893
|
+
get roughnessScaleBias() {
|
|
3894
|
+
return this.uniforms.roughnessScaleBias.value;
|
|
3895
|
+
}
|
|
3896
|
+
set roughnessScaleBias(v) {
|
|
3897
|
+
this.uniforms.roughnessScaleBias.value.copy(v);
|
|
3898
|
+
}
|
|
3889
3899
|
get normalMap() {
|
|
3890
3900
|
return this.uniforms.normalMap.value;
|
|
3891
3901
|
}
|
|
3892
3902
|
set normalMap(v) {
|
|
3893
3903
|
this.uniforms.normalMap.value = v;
|
|
3894
3904
|
}
|
|
3905
|
+
get normalScaleBias() {
|
|
3906
|
+
return this.uniforms.normalScaleBias.value;
|
|
3907
|
+
}
|
|
3908
|
+
set normalScaleBias(v) {
|
|
3909
|
+
this.uniforms.normalScaleBias.value.copy(v);
|
|
3910
|
+
}
|
|
3895
3911
|
get aoMap() {
|
|
3896
3912
|
return this.uniforms.aoMap.value;
|
|
3897
3913
|
}
|
|
@@ -3956,9 +3972,15 @@ class ReflectorMaterial extends ShaderMaterial {
|
|
|
3956
3972
|
roughnessMap: {
|
|
3957
3973
|
value: null
|
|
3958
3974
|
},
|
|
3975
|
+
roughnessScaleBias: {
|
|
3976
|
+
value: new Vector4(1, 1, 0, 0)
|
|
3977
|
+
},
|
|
3959
3978
|
normalMap: {
|
|
3960
3979
|
value: null
|
|
3961
3980
|
},
|
|
3981
|
+
normalScaleBias: {
|
|
3982
|
+
value: new Vector4(1, 1, 0, 0)
|
|
3983
|
+
},
|
|
3962
3984
|
aoMap: {
|
|
3963
3985
|
value: null
|
|
3964
3986
|
},
|
|
@@ -4004,9 +4026,15 @@ __decorate([
|
|
|
4004
4026
|
__decorate([
|
|
4005
4027
|
property
|
|
4006
4028
|
], ReflectorMaterial.prototype, "roughnessMap", null);
|
|
4029
|
+
__decorate([
|
|
4030
|
+
property
|
|
4031
|
+
], ReflectorMaterial.prototype, "roughnessScaleBias", null);
|
|
4007
4032
|
__decorate([
|
|
4008
4033
|
property
|
|
4009
4034
|
], ReflectorMaterial.prototype, "normalMap", null);
|
|
4035
|
+
__decorate([
|
|
4036
|
+
property
|
|
4037
|
+
], ReflectorMaterial.prototype, "normalScaleBias", null);
|
|
4010
4038
|
__decorate([
|
|
4011
4039
|
property
|
|
4012
4040
|
], ReflectorMaterial.prototype, "aoMap", null);
|
|
@@ -4323,10 +4351,13 @@ class TaskManager {
|
|
|
4323
4351
|
destroy() {
|
|
4324
4352
|
this._tasks = [];
|
|
4325
4353
|
this._taskIndex = 0;
|
|
4326
|
-
clearInterval(this._interval);
|
|
4327
4354
|
}
|
|
4328
4355
|
add(task) {
|
|
4329
4356
|
this._tasks.push(task);
|
|
4357
|
+
if (this._onStartCalled === false) {
|
|
4358
|
+
this._onStartCalled = true;
|
|
4359
|
+
this.onStart && this.onStart();
|
|
4360
|
+
}
|
|
4330
4361
|
}
|
|
4331
4362
|
update() {
|
|
4332
4363
|
let task = this._tasks[this._taskIndex];
|
|
@@ -4338,13 +4369,9 @@ class TaskManager {
|
|
|
4338
4369
|
this.onError && this.onError(task);
|
|
4339
4370
|
}
|
|
4340
4371
|
++this._taskIndex;
|
|
4341
|
-
if (this._onstartCalled === false) {
|
|
4342
|
-
this._onstartCalled = true;
|
|
4343
|
-
this.onStart && this.onStart();
|
|
4344
|
-
}
|
|
4345
4372
|
this.onProgress && this.onProgress(task, this._taskIndex, this._tasks.length);
|
|
4346
4373
|
if (this._taskIndex === this._tasks.length) {
|
|
4347
|
-
this.
|
|
4374
|
+
this._onStartCalled = false;
|
|
4348
4375
|
this.onComplete && this.onComplete();
|
|
4349
4376
|
}
|
|
4350
4377
|
}
|
|
@@ -4355,9 +4382,7 @@ class TaskManager {
|
|
|
4355
4382
|
this.onError = onError;
|
|
4356
4383
|
this._tasks = [];
|
|
4357
4384
|
this._taskIndex = 0;
|
|
4358
|
-
this.
|
|
4359
|
-
this._onstartCalled = false;
|
|
4360
|
-
this._interval = setInterval(()=>this.update());
|
|
4385
|
+
this._onStartCalled = false;
|
|
4361
4386
|
}
|
|
4362
4387
|
}
|
|
4363
4388
|
|
|
@@ -4510,10 +4535,11 @@ ResourceManager._texSettingKeys = [
|
|
|
4510
4535
|
];
|
|
4511
4536
|
|
|
4512
4537
|
class Task {
|
|
4513
|
-
constructor(excute, name
|
|
4514
|
-
this.excute = excute;
|
|
4515
|
-
this.name = name;
|
|
4538
|
+
constructor(excute, name){
|
|
4516
4539
|
this.instanceId = Task._instanceCount++;
|
|
4540
|
+
this.name = "task" + this.instanceId;
|
|
4541
|
+
this.excute = excute;
|
|
4542
|
+
this.name = name || this.name;
|
|
4517
4543
|
}
|
|
4518
4544
|
}
|
|
4519
4545
|
Task._instanceCount = 0;
|
|
@@ -4704,16 +4730,22 @@ class Viewer extends EventEmitter {
|
|
|
4704
4730
|
}
|
|
4705
4731
|
}
|
|
4706
4732
|
loop(dt) {
|
|
4707
|
-
|
|
4708
|
-
this.
|
|
4709
|
-
|
|
4710
|
-
|
|
4733
|
+
this._taskManager.update();
|
|
4734
|
+
if (!this._loading && !this._tasking && this._running > 0) {
|
|
4735
|
+
this._running--;
|
|
4736
|
+
}
|
|
4737
|
+
if (this._running <= 0) {
|
|
4738
|
+
dt = Math.min(dt, 0.067);
|
|
4739
|
+
this._renderer.info.reset();
|
|
4740
|
+
this._componentManager.update(dt);
|
|
4741
|
+
this._componentManager.render(dt);
|
|
4742
|
+
}
|
|
4711
4743
|
}
|
|
4712
4744
|
start() {
|
|
4713
|
-
if (this.
|
|
4714
|
-
this.
|
|
4745
|
+
if (this._active == false) {
|
|
4746
|
+
this._active = true;
|
|
4715
4747
|
const frameCallback = (time)=>{
|
|
4716
|
-
if (this.
|
|
4748
|
+
if (this._active) {
|
|
4717
4749
|
this._frame(time * 0.001);
|
|
4718
4750
|
}
|
|
4719
4751
|
};
|
|
@@ -4722,7 +4754,8 @@ class Viewer extends EventEmitter {
|
|
|
4722
4754
|
return this;
|
|
4723
4755
|
}
|
|
4724
4756
|
stop() {
|
|
4725
|
-
this.
|
|
4757
|
+
this._active = false;
|
|
4758
|
+
this._running = 4;
|
|
4726
4759
|
this._time = this._lastTime = 0;
|
|
4727
4760
|
return this;
|
|
4728
4761
|
}
|
|
@@ -5072,7 +5105,8 @@ class Viewer extends EventEmitter {
|
|
|
5072
5105
|
width: 1,
|
|
5073
5106
|
height: 1,
|
|
5074
5107
|
factor: 1
|
|
5075
|
-
}, this.
|
|
5108
|
+
}, this._active = false, this._loading = false, this._tasking = false, this._running = 4 //延迟4帧执行
|
|
5109
|
+
, this._rootRotated = false, this._time = 0, this._lastTime = 0, this._lastFrameTime = 0, this._targetFrameRate = -1, this._fixedFrameTime = false, this._windowSize = ()=>[
|
|
5076
5110
|
window.innerWidth,
|
|
5077
5111
|
window.innerHeight
|
|
5078
5112
|
], this._orientation = Orientation.AUTO;
|
|
@@ -5104,21 +5138,14 @@ class Viewer extends EventEmitter {
|
|
|
5104
5138
|
this._renderer.sortObjects = sortObjects;
|
|
5105
5139
|
this._targetFrameRate = targetFrameRate;
|
|
5106
5140
|
this._windowSize = typeof resize === "function" ? resize : resize === ResizeMode.AUTO ? this._windowSize : null;
|
|
5107
|
-
const states = {
|
|
5108
|
-
tasking: false,
|
|
5109
|
-
loading: false};
|
|
5110
|
-
const start = ()=>{
|
|
5111
|
-
!states.tasking && !states.loading && this.start();
|
|
5112
|
-
};
|
|
5113
5141
|
const complete = (set, cb)=>{
|
|
5114
5142
|
set();
|
|
5115
5143
|
cb && cb();
|
|
5116
|
-
!this._running && setTimeout(start);
|
|
5117
5144
|
};
|
|
5118
|
-
this._taskManager = new TaskManager(()=>complete(()=>
|
|
5119
|
-
this._taskManager.onStart = ()=>
|
|
5120
|
-
this._loadingManager = new LoadingManager(()=>complete(()=>
|
|
5121
|
-
this._loadingManager.onStart = ()=>
|
|
5145
|
+
this._taskManager = new TaskManager(()=>complete(()=>this._tasking = false, tasker.onComplete), tasker.onProgress, tasker.onError);
|
|
5146
|
+
this._taskManager.onStart = ()=>this._tasking = true;
|
|
5147
|
+
this._loadingManager = new LoadingManager(()=>complete(()=>this._loading = false, loader.onComplete), loader.onProgress, loader.onError);
|
|
5148
|
+
this._loadingManager.onStart = ()=>this._loading = true;
|
|
5122
5149
|
this._resourceManager = new ResourceManager(this);
|
|
5123
5150
|
this._componentManager = new ComponentManager(this);
|
|
5124
5151
|
this._resourceOptions = {
|
|
@@ -5145,7 +5172,7 @@ class Viewer extends EventEmitter {
|
|
|
5145
5172
|
setTimeout(()=>{
|
|
5146
5173
|
this.rotate();
|
|
5147
5174
|
this.resize();
|
|
5148
|
-
start();
|
|
5175
|
+
this.start();
|
|
5149
5176
|
});
|
|
5150
5177
|
}
|
|
5151
5178
|
}
|
|
@@ -5869,5 +5896,690 @@ function getFilesFromItemList(items, onDone) {
|
|
|
5869
5896
|
}
|
|
5870
5897
|
}
|
|
5871
5898
|
|
|
5872
|
-
|
|
5899
|
+
const newline = /\n/;
|
|
5900
|
+
const newlineChar = '\n';
|
|
5901
|
+
const whitespace = /\s/;
|
|
5902
|
+
function wordwrap(text, opt) {
|
|
5903
|
+
opt = opt || {};
|
|
5904
|
+
//zero width results in nothing visible
|
|
5905
|
+
if (opt.width === 0 && opt.mode !== 'nowrap') return [];
|
|
5906
|
+
text = text || '';
|
|
5907
|
+
const width = typeof opt.width === 'number' ? opt.width : Number.MAX_VALUE;
|
|
5908
|
+
const start = Math.max(0, opt.start || 0);
|
|
5909
|
+
const end = typeof opt.end === 'number' ? opt.end : text.length;
|
|
5910
|
+
const mode = opt.mode;
|
|
5911
|
+
const letterSpacing = opt.letterSpacing || 0;
|
|
5912
|
+
const measure = opt.measure || monospace;
|
|
5913
|
+
if (mode === 'pre') return pre(measure, text, start, end, width, letterSpacing);
|
|
5914
|
+
else return greedy(measure, text, start, end, width, mode, letterSpacing);
|
|
5915
|
+
}
|
|
5916
|
+
function idxOf(text, chr, start, end) {
|
|
5917
|
+
var idx = text.indexOf(chr, start);
|
|
5918
|
+
if (idx === -1 || idx > end) return end;
|
|
5919
|
+
return idx;
|
|
5920
|
+
}
|
|
5921
|
+
function isWhitespace(chr) {
|
|
5922
|
+
return whitespace.test(chr);
|
|
5923
|
+
}
|
|
5924
|
+
function pre(measure, text, start, end, width, letterSpacing) {
|
|
5925
|
+
var lines = [];
|
|
5926
|
+
var lineStart = start;
|
|
5927
|
+
for(var i = start; i < end && i < text.length; i++){
|
|
5928
|
+
var chr = text.charAt(i);
|
|
5929
|
+
var isNewline = newline.test(chr);
|
|
5930
|
+
//If we've reached a newline, then step down a line
|
|
5931
|
+
//Or if we've reached the EOF
|
|
5932
|
+
if (isNewline || i === end - 1) {
|
|
5933
|
+
var lineEnd = isNewline ? i : i + 1;
|
|
5934
|
+
var measured = measure(text, lineStart, lineEnd, width, letterSpacing);
|
|
5935
|
+
lines.push(measured);
|
|
5936
|
+
lineStart = i + 1;
|
|
5937
|
+
}
|
|
5938
|
+
}
|
|
5939
|
+
return lines;
|
|
5940
|
+
}
|
|
5941
|
+
function greedy(measure, text, start, end, width, mode, letterSpacing) {
|
|
5942
|
+
//A greedy word wrapper based on LibGDX algorithm
|
|
5943
|
+
//https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g2d/BitmapFontCache.java
|
|
5944
|
+
var lines = [];
|
|
5945
|
+
var testWidth = width;
|
|
5946
|
+
//if 'nowrap' is specified, we only wrap on newline chars
|
|
5947
|
+
if (mode === 'nowrap') testWidth = Number.MAX_VALUE;
|
|
5948
|
+
while(start < end && start < text.length){
|
|
5949
|
+
//get next newline position
|
|
5950
|
+
var newLine = idxOf(text, newlineChar, start, end);
|
|
5951
|
+
//eat whitespace at start of line
|
|
5952
|
+
while(start < newLine){
|
|
5953
|
+
if (!isWhitespace(text.charAt(start))) break;
|
|
5954
|
+
start++;
|
|
5955
|
+
}
|
|
5956
|
+
//determine visible # of glyphs for the available width
|
|
5957
|
+
var measured = measure(text, start, newLine, testWidth, letterSpacing);
|
|
5958
|
+
var lineEnd = start + (measured.end - measured.start);
|
|
5959
|
+
var nextStart = lineEnd + newlineChar.length;
|
|
5960
|
+
//if we had to cut the line before the next newline...
|
|
5961
|
+
if (lineEnd < newLine) {
|
|
5962
|
+
//find char to break on
|
|
5963
|
+
while(lineEnd > start){
|
|
5964
|
+
if (isWhitespace(text.charAt(lineEnd))) break;
|
|
5965
|
+
lineEnd--;
|
|
5966
|
+
}
|
|
5967
|
+
if (lineEnd === start) {
|
|
5968
|
+
if (nextStart > start + newlineChar.length) nextStart--;
|
|
5969
|
+
lineEnd = nextStart; // If no characters to break, show all.
|
|
5970
|
+
} else {
|
|
5971
|
+
nextStart = lineEnd;
|
|
5972
|
+
//eat whitespace at end of line
|
|
5973
|
+
while(lineEnd > start){
|
|
5974
|
+
if (!isWhitespace(text.charAt(lineEnd - newlineChar.length))) break;
|
|
5975
|
+
lineEnd--;
|
|
5976
|
+
}
|
|
5977
|
+
}
|
|
5978
|
+
}
|
|
5979
|
+
if (lineEnd >= start) {
|
|
5980
|
+
var result = measure(text, start, lineEnd, testWidth);
|
|
5981
|
+
lines.push(result);
|
|
5982
|
+
}
|
|
5983
|
+
start = nextStart;
|
|
5984
|
+
}
|
|
5985
|
+
return lines;
|
|
5986
|
+
}
|
|
5987
|
+
//determines the visible number of glyphs within a given width
|
|
5988
|
+
function monospace(text, start, end, width) {
|
|
5989
|
+
var glyphs = Math.min(width, end - start);
|
|
5990
|
+
return {
|
|
5991
|
+
start: start,
|
|
5992
|
+
end: start + glyphs
|
|
5993
|
+
};
|
|
5994
|
+
}
|
|
5995
|
+
|
|
5996
|
+
const X_HEIGHTS = [
|
|
5997
|
+
'x',
|
|
5998
|
+
'e',
|
|
5999
|
+
'a',
|
|
6000
|
+
'o',
|
|
6001
|
+
'n',
|
|
6002
|
+
's',
|
|
6003
|
+
'r',
|
|
6004
|
+
'c',
|
|
6005
|
+
'u',
|
|
6006
|
+
'm',
|
|
6007
|
+
'v',
|
|
6008
|
+
'w',
|
|
6009
|
+
'z'
|
|
6010
|
+
];
|
|
6011
|
+
const M_WIDTHS = [
|
|
6012
|
+
'm',
|
|
6013
|
+
'w'
|
|
6014
|
+
];
|
|
6015
|
+
const CAP_HEIGHTS = [
|
|
6016
|
+
'H',
|
|
6017
|
+
'I',
|
|
6018
|
+
'N',
|
|
6019
|
+
'E',
|
|
6020
|
+
'F',
|
|
6021
|
+
'K',
|
|
6022
|
+
'L',
|
|
6023
|
+
'T',
|
|
6024
|
+
'U',
|
|
6025
|
+
'V',
|
|
6026
|
+
'W',
|
|
6027
|
+
'X',
|
|
6028
|
+
'Y',
|
|
6029
|
+
'Z'
|
|
6030
|
+
];
|
|
6031
|
+
const TAB_ID = '\t'.charCodeAt(0);
|
|
6032
|
+
const SPACE_ID = ' '.charCodeAt(0);
|
|
6033
|
+
const ALIGN_LEFT = 0, ALIGN_CENTER = 1, ALIGN_RIGHT = 2;
|
|
6034
|
+
function findChar(array, value, start) {
|
|
6035
|
+
start = start || 0;
|
|
6036
|
+
for(let i = start; i < array.length; i++){
|
|
6037
|
+
if (array[i].id === value) {
|
|
6038
|
+
return i;
|
|
6039
|
+
}
|
|
6040
|
+
}
|
|
6041
|
+
return -1;
|
|
6042
|
+
}
|
|
6043
|
+
function getGlyphById(font, id) {
|
|
6044
|
+
if (!font.chars || font.chars.length === 0) return null;
|
|
6045
|
+
let glyphIdx = findChar(font.chars, id);
|
|
6046
|
+
if (glyphIdx >= 0) return font.chars[glyphIdx];
|
|
6047
|
+
return null;
|
|
6048
|
+
}
|
|
6049
|
+
function getXHeight(font) {
|
|
6050
|
+
for(let i = 0; i < X_HEIGHTS.length; i++){
|
|
6051
|
+
let id = X_HEIGHTS[i].charCodeAt(0);
|
|
6052
|
+
let idx = findChar(font.chars, id);
|
|
6053
|
+
if (idx >= 0) return font.chars[idx].height;
|
|
6054
|
+
}
|
|
6055
|
+
return 0;
|
|
6056
|
+
}
|
|
6057
|
+
function getMGlyph(font) {
|
|
6058
|
+
for(let i = 0; i < M_WIDTHS.length; i++){
|
|
6059
|
+
let id = M_WIDTHS[i].charCodeAt(0);
|
|
6060
|
+
let idx = findChar(font.chars, id);
|
|
6061
|
+
if (idx >= 0) return font.chars[idx];
|
|
6062
|
+
}
|
|
6063
|
+
return 0;
|
|
6064
|
+
}
|
|
6065
|
+
function getCapHeight(font) {
|
|
6066
|
+
for(let i = 0; i < CAP_HEIGHTS.length; i++){
|
|
6067
|
+
let id = CAP_HEIGHTS[i].charCodeAt(0);
|
|
6068
|
+
let idx = findChar(font.chars, id);
|
|
6069
|
+
if (idx >= 0) return font.chars[idx].height;
|
|
6070
|
+
}
|
|
6071
|
+
return 0;
|
|
6072
|
+
}
|
|
6073
|
+
function getKerning(font, left, right) {
|
|
6074
|
+
if (!font.kernings || font.kernings.length === 0) return 0;
|
|
6075
|
+
let table = font.kernings;
|
|
6076
|
+
for(let i = 0; i < table.length; i++){
|
|
6077
|
+
let kern = table[i];
|
|
6078
|
+
if (kern.first === left && kern.second === right) return kern.amount;
|
|
6079
|
+
}
|
|
6080
|
+
return 0;
|
|
6081
|
+
}
|
|
6082
|
+
function getAlignType(align) {
|
|
6083
|
+
if (align === 'center') return ALIGN_CENTER;
|
|
6084
|
+
else if (align === 'right') return ALIGN_RIGHT;
|
|
6085
|
+
return ALIGN_LEFT;
|
|
6086
|
+
}
|
|
6087
|
+
class BMFontTextLayout {
|
|
6088
|
+
get width() {
|
|
6089
|
+
return this._width;
|
|
6090
|
+
}
|
|
6091
|
+
get height() {
|
|
6092
|
+
return this._height;
|
|
6093
|
+
}
|
|
6094
|
+
get descender() {
|
|
6095
|
+
return this._descender;
|
|
6096
|
+
}
|
|
6097
|
+
get ascender() {
|
|
6098
|
+
return this._ascender;
|
|
6099
|
+
}
|
|
6100
|
+
get xHeight() {
|
|
6101
|
+
return this._xHeight;
|
|
6102
|
+
}
|
|
6103
|
+
get baseline() {
|
|
6104
|
+
return this._baseline;
|
|
6105
|
+
}
|
|
6106
|
+
get capHeight() {
|
|
6107
|
+
return this._capHeight;
|
|
6108
|
+
}
|
|
6109
|
+
get lineHeight() {
|
|
6110
|
+
return this._lineHeight;
|
|
6111
|
+
}
|
|
6112
|
+
get glyphs() {
|
|
6113
|
+
return this._glyphs;
|
|
6114
|
+
}
|
|
6115
|
+
get linesTotal() {
|
|
6116
|
+
return this._linesTotal;
|
|
6117
|
+
}
|
|
6118
|
+
update(font, text, setting) {
|
|
6119
|
+
setting = Object.assign({
|
|
6120
|
+
tabSize: 4,
|
|
6121
|
+
width: 0,
|
|
6122
|
+
letterSpacing: 0,
|
|
6123
|
+
mode: "nowrap",
|
|
6124
|
+
align: "left"
|
|
6125
|
+
}, setting);
|
|
6126
|
+
this._font = font;
|
|
6127
|
+
const measure = this._computeMetrics.bind(this);
|
|
6128
|
+
const lines = wordwrap(text, {
|
|
6129
|
+
measure,
|
|
6130
|
+
...setting
|
|
6131
|
+
});
|
|
6132
|
+
const minWidth = setting.width || 0;
|
|
6133
|
+
const glyphs = this._glyphs;
|
|
6134
|
+
const maxLineWidth = lines.reduce((prev, line)=>Math.max(prev, line.width, minWidth), 0);
|
|
6135
|
+
var _setting_lineHeight;
|
|
6136
|
+
//the pen position
|
|
6137
|
+
const lineHeight = (_setting_lineHeight = setting.lineHeight) != null ? _setting_lineHeight : font.common.lineHeight;
|
|
6138
|
+
const baseline = font.common.base;
|
|
6139
|
+
const descender = lineHeight - baseline;
|
|
6140
|
+
const letterSpacing = setting.letterSpacing || 0;
|
|
6141
|
+
const height = lineHeight * lines.length - descender;
|
|
6142
|
+
const align = getAlignType(setting.align);
|
|
6143
|
+
var _setting_anchor;
|
|
6144
|
+
const anchor = (_setting_anchor = setting.anchor) != null ? _setting_anchor : [
|
|
6145
|
+
0.5,
|
|
6146
|
+
0.5
|
|
6147
|
+
];
|
|
6148
|
+
this._setupSpaceGlyphs(font, setting);
|
|
6149
|
+
//the metrics for this text layout
|
|
6150
|
+
this._width = maxLineWidth;
|
|
6151
|
+
this._height = height;
|
|
6152
|
+
this._descender = descender;
|
|
6153
|
+
this._baseline = baseline;
|
|
6154
|
+
this._xHeight = getXHeight(font);
|
|
6155
|
+
this._capHeight = getCapHeight(font);
|
|
6156
|
+
this._lineHeight = lineHeight;
|
|
6157
|
+
this._ascender = baseline - this._xHeight; //lineHeight - descender - this._xHeight
|
|
6158
|
+
const anchorOffset = [
|
|
6159
|
+
-maxLineWidth * anchor[0],
|
|
6160
|
+
2 * lineHeight * anchor[1] - baseline
|
|
6161
|
+
];
|
|
6162
|
+
let x = 0, y = 0;
|
|
6163
|
+
//draw text along baseline
|
|
6164
|
+
y -= height;
|
|
6165
|
+
glyphs.length = 0;
|
|
6166
|
+
for(let k = 0; k < lines.length; k++){
|
|
6167
|
+
const line = lines[k];
|
|
6168
|
+
let start = line.start;
|
|
6169
|
+
let end = line.end;
|
|
6170
|
+
let lineWidth = line.width;
|
|
6171
|
+
let lastGlyph;
|
|
6172
|
+
//for each glyph in that line...
|
|
6173
|
+
for(let i = start; i < end; i++){
|
|
6174
|
+
let id = text.charCodeAt(i);
|
|
6175
|
+
let glyph = this._getGlyph(font, id);
|
|
6176
|
+
if (glyph) {
|
|
6177
|
+
if (lastGlyph) x += getKerning(font, lastGlyph.id, glyph.id);
|
|
6178
|
+
let tx = x;
|
|
6179
|
+
if (align === ALIGN_CENTER) tx += (maxLineWidth - lineWidth) / 2;
|
|
6180
|
+
else if (align === ALIGN_RIGHT) tx += maxLineWidth - lineWidth;
|
|
6181
|
+
glyphs.push({
|
|
6182
|
+
position: [
|
|
6183
|
+
tx + anchorOffset[0],
|
|
6184
|
+
y + anchorOffset[1]
|
|
6185
|
+
],
|
|
6186
|
+
data: glyph,
|
|
6187
|
+
index: i,
|
|
6188
|
+
line: k
|
|
6189
|
+
});
|
|
6190
|
+
//move pen forward
|
|
6191
|
+
x += glyph.xadvance + letterSpacing;
|
|
6192
|
+
lastGlyph = glyph;
|
|
6193
|
+
}
|
|
6194
|
+
}
|
|
6195
|
+
//next line down
|
|
6196
|
+
y += lineHeight;
|
|
6197
|
+
x = 0;
|
|
6198
|
+
}
|
|
6199
|
+
this._linesTotal = lines.length;
|
|
6200
|
+
}
|
|
6201
|
+
_setupSpaceGlyphs(font, setting) {
|
|
6202
|
+
//These are fallbacks, when the font doesn't include
|
|
6203
|
+
//' ' or '\t' glyphs
|
|
6204
|
+
if (!font.chars || font.chars.length === 0) return;
|
|
6205
|
+
//try to get space glyph
|
|
6206
|
+
//then fall back to the 'm' or 'w' glyphs
|
|
6207
|
+
//then fall back to the first glyph available
|
|
6208
|
+
const space = Object.assign({}, getGlyphById(font, SPACE_ID) || getMGlyph(font) || font.chars[0]);
|
|
6209
|
+
//and create a fallback for tab
|
|
6210
|
+
const tabWidth = setting.tabSize * space.xadvance;
|
|
6211
|
+
this._fallbackSpaceGlyph = space;
|
|
6212
|
+
this._fallbackTabGlyph = Object.assign(space, {
|
|
6213
|
+
x: 0,
|
|
6214
|
+
y: 0,
|
|
6215
|
+
xadvance: tabWidth,
|
|
6216
|
+
id: TAB_ID,
|
|
6217
|
+
xoffset: 0,
|
|
6218
|
+
yoffset: 0,
|
|
6219
|
+
width: 0,
|
|
6220
|
+
height: 0
|
|
6221
|
+
});
|
|
6222
|
+
}
|
|
6223
|
+
_getGlyph(font, id) {
|
|
6224
|
+
let glyph = getGlyphById(font, id);
|
|
6225
|
+
if (glyph) return glyph;
|
|
6226
|
+
else if (id === TAB_ID) return this._fallbackTabGlyph;
|
|
6227
|
+
else if (id === SPACE_ID) return this._fallbackSpaceGlyph;
|
|
6228
|
+
return null;
|
|
6229
|
+
}
|
|
6230
|
+
_computeMetrics(text, start, end, width, letterSpacing = 0) {
|
|
6231
|
+
let font = this._font;
|
|
6232
|
+
let curPen = 0;
|
|
6233
|
+
let curWidth = 0;
|
|
6234
|
+
let count = 0;
|
|
6235
|
+
let lastGlyph;
|
|
6236
|
+
if (!font.chars || font.chars.length === 0) {
|
|
6237
|
+
return {
|
|
6238
|
+
start: start,
|
|
6239
|
+
end: start,
|
|
6240
|
+
width: 0
|
|
6241
|
+
};
|
|
6242
|
+
}
|
|
6243
|
+
end = Math.min(text.length, end);
|
|
6244
|
+
for(let i = start; i < end; i++){
|
|
6245
|
+
let id = text.charCodeAt(i);
|
|
6246
|
+
let glyph = this._getGlyph(font, id);
|
|
6247
|
+
if (glyph) {
|
|
6248
|
+
//move pen forward
|
|
6249
|
+
glyph.xoffset;
|
|
6250
|
+
let kern = lastGlyph ? getKerning(font, lastGlyph.id, glyph.id) : 0;
|
|
6251
|
+
curPen += kern;
|
|
6252
|
+
let nextPen = curPen + glyph.xadvance + letterSpacing;
|
|
6253
|
+
let nextWidth = curPen + glyph.width;
|
|
6254
|
+
//we've hit our limit; we can't move onto the next glyph
|
|
6255
|
+
if (nextWidth >= width || nextPen >= width) break;
|
|
6256
|
+
//otherwise continue along our line
|
|
6257
|
+
curPen = nextPen;
|
|
6258
|
+
curWidth = nextWidth;
|
|
6259
|
+
lastGlyph = glyph;
|
|
6260
|
+
}
|
|
6261
|
+
count++;
|
|
6262
|
+
}
|
|
6263
|
+
//make sure rightmost edge lines up with rendered glyphs
|
|
6264
|
+
if (lastGlyph) curWidth += lastGlyph.xoffset;
|
|
6265
|
+
return {
|
|
6266
|
+
start: start,
|
|
6267
|
+
end: start + count,
|
|
6268
|
+
width: curWidth
|
|
6269
|
+
};
|
|
6270
|
+
}
|
|
6271
|
+
constructor(){
|
|
6272
|
+
this._width = 0;
|
|
6273
|
+
this._height = 0;
|
|
6274
|
+
this._descender = 0;
|
|
6275
|
+
this._ascender = 0;
|
|
6276
|
+
this._xHeight = 0;
|
|
6277
|
+
this._baseline = 0;
|
|
6278
|
+
this._capHeight = 0;
|
|
6279
|
+
this._lineHeight = 0;
|
|
6280
|
+
this._linesTotal = 0;
|
|
6281
|
+
this._glyphs = [];
|
|
6282
|
+
this._fallbackSpaceGlyph = null;
|
|
6283
|
+
this._fallbackTabGlyph = null;
|
|
6284
|
+
this._font = null;
|
|
6285
|
+
}
|
|
6286
|
+
}
|
|
6287
|
+
|
|
6288
|
+
const itemSize = 2;
|
|
6289
|
+
const box = {
|
|
6290
|
+
min: [
|
|
6291
|
+
0,
|
|
6292
|
+
0
|
|
6293
|
+
],
|
|
6294
|
+
max: [
|
|
6295
|
+
0,
|
|
6296
|
+
0
|
|
6297
|
+
]
|
|
6298
|
+
};
|
|
6299
|
+
function bounds(positions) {
|
|
6300
|
+
const count = positions.length / itemSize;
|
|
6301
|
+
box.min[0] = positions[0];
|
|
6302
|
+
box.min[1] = positions[1];
|
|
6303
|
+
box.max[0] = positions[0];
|
|
6304
|
+
box.max[1] = positions[1];
|
|
6305
|
+
for(let i = 0; i < count; i++){
|
|
6306
|
+
const x = positions[i * itemSize + 0];
|
|
6307
|
+
const y = positions[i * itemSize + 1];
|
|
6308
|
+
box.min[0] = Math.min(x, box.min[0]);
|
|
6309
|
+
box.min[1] = Math.min(y, box.min[1]);
|
|
6310
|
+
box.max[0] = Math.max(x, box.max[0]);
|
|
6311
|
+
box.max[1] = Math.max(y, box.max[1]);
|
|
6312
|
+
}
|
|
6313
|
+
}
|
|
6314
|
+
function computeBox(positions, output) {
|
|
6315
|
+
bounds(positions);
|
|
6316
|
+
output.min.set(box.min[0], box.min[1], 0);
|
|
6317
|
+
output.max.set(box.max[0], box.max[1], 0);
|
|
6318
|
+
}
|
|
6319
|
+
function computeSphere(positions, output) {
|
|
6320
|
+
bounds(positions);
|
|
6321
|
+
const minX = box.min[0];
|
|
6322
|
+
const minY = box.min[1];
|
|
6323
|
+
const maxX = box.max[0];
|
|
6324
|
+
const maxY = box.max[1];
|
|
6325
|
+
const width = maxX - minX;
|
|
6326
|
+
const height = maxY - minY;
|
|
6327
|
+
const length = Math.sqrt(width * width + height * height);
|
|
6328
|
+
output.center.set(minX + width / 2, minY + height / 2, 0);
|
|
6329
|
+
output.radius = length / 2;
|
|
6330
|
+
}
|
|
6331
|
+
|
|
6332
|
+
class BMFontTextGeometry extends BufferGeometry {
|
|
6333
|
+
update(fontAtlas, text, setting) {
|
|
6334
|
+
this.layout.update(fontAtlas.info, text, setting);
|
|
6335
|
+
const { indice, position, uv } = fontAtlas.build(this.layout, setting);
|
|
6336
|
+
this.setIndex(new BufferAttribute(indice, 1));
|
|
6337
|
+
this.setAttribute("position", new BufferAttribute(position, 2));
|
|
6338
|
+
this.setAttribute("uv", new BufferAttribute(uv, 2));
|
|
6339
|
+
}
|
|
6340
|
+
computeBoundingSphere() {
|
|
6341
|
+
if (this.boundingSphere === null) {
|
|
6342
|
+
this.boundingSphere = new Sphere$1();
|
|
6343
|
+
}
|
|
6344
|
+
const positions = this.attributes.position.array;
|
|
6345
|
+
const itemSize = this.attributes.position.itemSize;
|
|
6346
|
+
if (!positions || !itemSize || positions.length < 2) {
|
|
6347
|
+
this.boundingSphere.radius = 0;
|
|
6348
|
+
this.boundingSphere.center.set(0, 0, 0);
|
|
6349
|
+
return;
|
|
6350
|
+
}
|
|
6351
|
+
computeSphere(positions, this.boundingSphere);
|
|
6352
|
+
if (isNaN(this.boundingSphere.radius)) {
|
|
6353
|
+
console.error('THREE.BufferGeometry.computeBoundingSphere(): ' + 'Computed radius is NaN. The ' + '"position" attribute is likely to have NaN values.');
|
|
6354
|
+
}
|
|
6355
|
+
}
|
|
6356
|
+
computeBoundingBox() {
|
|
6357
|
+
if (this.boundingBox === null) {
|
|
6358
|
+
this.boundingBox = new Box3();
|
|
6359
|
+
}
|
|
6360
|
+
const bbox = this.boundingBox;
|
|
6361
|
+
const positions = this.attributes.position["array"];
|
|
6362
|
+
const itemSize = this.attributes.position.itemSize;
|
|
6363
|
+
if (!positions || !itemSize || positions.length < 2) {
|
|
6364
|
+
bbox.makeEmpty();
|
|
6365
|
+
return;
|
|
6366
|
+
}
|
|
6367
|
+
computeBox(positions, bbox);
|
|
6368
|
+
}
|
|
6369
|
+
constructor(...args){
|
|
6370
|
+
super(...args), this.layout = new BMFontTextLayout();
|
|
6371
|
+
}
|
|
6372
|
+
}
|
|
6373
|
+
|
|
6374
|
+
class Label extends Component {
|
|
6375
|
+
get text() {
|
|
6376
|
+
return this._text;
|
|
6377
|
+
}
|
|
6378
|
+
set text(v) {
|
|
6379
|
+
if (this._text !== v) {
|
|
6380
|
+
this._text = v;
|
|
6381
|
+
this.needsUpdate = true;
|
|
6382
|
+
}
|
|
6383
|
+
}
|
|
6384
|
+
get font() {
|
|
6385
|
+
return this._font;
|
|
6386
|
+
}
|
|
6387
|
+
set font(v) {
|
|
6388
|
+
if (this._font !== v) {
|
|
6389
|
+
this._font = v;
|
|
6390
|
+
this.needsUpdate = true;
|
|
6391
|
+
}
|
|
6392
|
+
}
|
|
6393
|
+
get setting() {
|
|
6394
|
+
return this._setting;
|
|
6395
|
+
}
|
|
6396
|
+
set setting(v) {
|
|
6397
|
+
if (JSON.stringify(this._setting) !== JSON.stringify(v)) {
|
|
6398
|
+
this._setting = v;
|
|
6399
|
+
this.needsUpdate = true;
|
|
6400
|
+
}
|
|
6401
|
+
}
|
|
6402
|
+
get layout() {
|
|
6403
|
+
return this.node.geometry.layout;
|
|
6404
|
+
}
|
|
6405
|
+
forceUpdate() {
|
|
6406
|
+
this.node.geometry.update(this.font, this.text, this.setting);
|
|
6407
|
+
}
|
|
6408
|
+
update(dt) {
|
|
6409
|
+
if (this.needsUpdate) {
|
|
6410
|
+
this.needsUpdate = false;
|
|
6411
|
+
this.forceUpdate();
|
|
6412
|
+
}
|
|
6413
|
+
}
|
|
6414
|
+
constructor({ text = "", font, material, ...setting }){
|
|
6415
|
+
super(), this.needsUpdate = false, this._text = "", this._font = null, this._setting = null;
|
|
6416
|
+
this.text = text;
|
|
6417
|
+
this.font = font;
|
|
6418
|
+
this.setting = setting;
|
|
6419
|
+
this.node = new Mesh(new BMFontTextGeometry(), material || font.material);
|
|
6420
|
+
this.node.geometry.update(this.font, this.text, this.setting);
|
|
6421
|
+
}
|
|
6422
|
+
}
|
|
6423
|
+
|
|
6424
|
+
const vert_MSDF = `
|
|
6425
|
+
varying vec2 v_uv;
|
|
6426
|
+
|
|
6427
|
+
void main() {
|
|
6428
|
+
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
6429
|
+
v_uv = uv;
|
|
6430
|
+
}
|
|
6431
|
+
`;
|
|
6432
|
+
const frag_MSDF = `
|
|
6433
|
+
uniform sampler2D u_fontTexture;
|
|
6434
|
+
varying vec2 v_uv;
|
|
6435
|
+
|
|
6436
|
+
uniform vec3 u_color;
|
|
6437
|
+
uniform float u_opacity;
|
|
6438
|
+
uniform vec3 u_strokeColor;
|
|
6439
|
+
uniform float u_strokeWidth;
|
|
6440
|
+
uniform vec3 u_shadowColor;
|
|
6441
|
+
uniform float u_shadowBlur;
|
|
6442
|
+
uniform vec2 u_shadowOffset;
|
|
6443
|
+
uniform float u_weight;
|
|
6444
|
+
|
|
6445
|
+
float median(in float r, in float g, in float b) {
|
|
6446
|
+
return max(min(r, g), min(max(r, g), b));
|
|
6447
|
+
}
|
|
6448
|
+
|
|
6449
|
+
float signedDistance(in vec2 uv) {
|
|
6450
|
+
vec4 texel = texture2D(u_fontTexture, uv);
|
|
6451
|
+
return median(texel.r, texel.g, texel.b) - 0.5;
|
|
6452
|
+
}
|
|
6453
|
+
|
|
6454
|
+
void main() {
|
|
6455
|
+
vec4 color = vec4(u_color, 1.);
|
|
6456
|
+
float d = signedDistance(v_uv) + u_weight;
|
|
6457
|
+
float w = fwidth(d);
|
|
6458
|
+
|
|
6459
|
+
vec4 stroke = vec4(u_strokeColor, smoothstep(-w, w, d));
|
|
6460
|
+
color.a *= smoothstep(-w, w, d - u_strokeWidth);
|
|
6461
|
+
color = mix(stroke, color, color.a);
|
|
6462
|
+
|
|
6463
|
+
float sd = signedDistance(v_uv + u_shadowOffset) + u_weight;
|
|
6464
|
+
vec4 shadow = vec4(u_shadowColor, smoothstep(-w - u_shadowBlur, w + u_shadowBlur, sd));
|
|
6465
|
+
color = mix(shadow, color, color.a);
|
|
6466
|
+
|
|
6467
|
+
color.a *= u_opacity;
|
|
6468
|
+
gl_FragColor = color;
|
|
6469
|
+
}
|
|
6470
|
+
`;
|
|
6471
|
+
class BMFontAtlas {
|
|
6472
|
+
build(layout, setting) {
|
|
6473
|
+
const info = this.info;
|
|
6474
|
+
const texWidth = info.common.scaleW;
|
|
6475
|
+
const texHeight = info.common.scaleH;
|
|
6476
|
+
const glyphs = layout.glyphs.filter((glyph)=>glyph.data.width * glyph.data.height > 0);
|
|
6477
|
+
const flipY = setting.flipY !== false;
|
|
6478
|
+
const position = new Float32Array(glyphs.length * 8);
|
|
6479
|
+
const uv = new Float32Array(glyphs.length * 8);
|
|
6480
|
+
const indice = new Uint16Array(glyphs.length * 6);
|
|
6481
|
+
for(let k = 0, i0 = 0, i1 = 0, i2 = 0, i = 0; i < glyphs.length; i++, k += 4){
|
|
6482
|
+
const glyph = glyphs[i];
|
|
6483
|
+
const bitmap = glyph.data;
|
|
6484
|
+
// bottom left position
|
|
6485
|
+
let x = glyph.position[0] + bitmap.xoffset;
|
|
6486
|
+
let y = glyph.position[1] + bitmap.yoffset;
|
|
6487
|
+
// quad size
|
|
6488
|
+
let w = bitmap.width;
|
|
6489
|
+
let h = bitmap.height;
|
|
6490
|
+
// BL
|
|
6491
|
+
position[i0++] = x;
|
|
6492
|
+
position[i0++] = y;
|
|
6493
|
+
// BR
|
|
6494
|
+
position[i0++] = x + w;
|
|
6495
|
+
position[i0++] = y;
|
|
6496
|
+
// TR
|
|
6497
|
+
position[i0++] = x + w;
|
|
6498
|
+
position[i0++] = y + h;
|
|
6499
|
+
// TL
|
|
6500
|
+
position[i0++] = x;
|
|
6501
|
+
position[i0++] = y + h;
|
|
6502
|
+
let bw = bitmap.x + bitmap.width;
|
|
6503
|
+
let bh = bitmap.y + bitmap.height;
|
|
6504
|
+
// top left position
|
|
6505
|
+
let u0 = bitmap.x / texWidth;
|
|
6506
|
+
let v0 = bitmap.y / texHeight;
|
|
6507
|
+
let u1 = bw / texWidth;
|
|
6508
|
+
let v1 = bh / texHeight;
|
|
6509
|
+
if (flipY) {
|
|
6510
|
+
v0 = 1 - v0;
|
|
6511
|
+
v1 = 1 - v1;
|
|
6512
|
+
}
|
|
6513
|
+
// BL
|
|
6514
|
+
uv[i1++] = u0;
|
|
6515
|
+
uv[i1++] = v0;
|
|
6516
|
+
// BR
|
|
6517
|
+
uv[i1++] = u1;
|
|
6518
|
+
uv[i1++] = v0;
|
|
6519
|
+
// TR
|
|
6520
|
+
uv[i1++] = u1;
|
|
6521
|
+
uv[i1++] = v1;
|
|
6522
|
+
// TL
|
|
6523
|
+
uv[i1++] = u0;
|
|
6524
|
+
uv[i1++] = v1;
|
|
6525
|
+
indice[i2++] = k + 0;
|
|
6526
|
+
indice[i2++] = k + 1;
|
|
6527
|
+
indice[i2++] = k + 2;
|
|
6528
|
+
indice[i2++] = k + 0;
|
|
6529
|
+
indice[i2++] = k + 2;
|
|
6530
|
+
indice[i2++] = k + 3;
|
|
6531
|
+
}
|
|
6532
|
+
return {
|
|
6533
|
+
position,
|
|
6534
|
+
uv,
|
|
6535
|
+
indice
|
|
6536
|
+
};
|
|
6537
|
+
}
|
|
6538
|
+
constructor({ info, texture, uniforms, ...props }){
|
|
6539
|
+
this.uniforms = {
|
|
6540
|
+
u_color: {
|
|
6541
|
+
value: new Color(0xffffff)
|
|
6542
|
+
},
|
|
6543
|
+
u_opacity: {
|
|
6544
|
+
value: 1
|
|
6545
|
+
},
|
|
6546
|
+
u_weight: {
|
|
6547
|
+
value: 0.2
|
|
6548
|
+
},
|
|
6549
|
+
u_strokeColor: {
|
|
6550
|
+
value: new Color(0xff0000)
|
|
6551
|
+
},
|
|
6552
|
+
u_strokeWidth: {
|
|
6553
|
+
value: 0
|
|
6554
|
+
},
|
|
6555
|
+
u_shadowColor: {
|
|
6556
|
+
value: new Color(0xff0000)
|
|
6557
|
+
},
|
|
6558
|
+
u_shadowBlur: {
|
|
6559
|
+
value: 0
|
|
6560
|
+
},
|
|
6561
|
+
u_shadowOffset: {
|
|
6562
|
+
value: new Vector2()
|
|
6563
|
+
},
|
|
6564
|
+
u_fontTexture: {
|
|
6565
|
+
value: null
|
|
6566
|
+
}
|
|
6567
|
+
};
|
|
6568
|
+
this.info = info;
|
|
6569
|
+
this.uniforms.u_fontTexture.value = texture;
|
|
6570
|
+
this.material = new ShaderMaterial(Object.assign({
|
|
6571
|
+
vertexShader: vert_MSDF,
|
|
6572
|
+
fragmentShader: frag_MSDF,
|
|
6573
|
+
transparent: true,
|
|
6574
|
+
depthWrite: false,
|
|
6575
|
+
blending: NormalBlending,
|
|
6576
|
+
uniforms: {
|
|
6577
|
+
...this.uniforms,
|
|
6578
|
+
...uniforms
|
|
6579
|
+
}
|
|
6580
|
+
}, props));
|
|
6581
|
+
}
|
|
6582
|
+
}
|
|
6583
|
+
|
|
6584
|
+
export { AccumulativeShadows, Animation, AnimationCurve, BINLoader, BMFontAtlas, BMFontTextGeometry, BMFontTextLayout, Box, BoxProjection, Center, Component, ContactShadows, DependentMode, DeviceInput, DropFile, EXRLoader, Easing, Environment, EventEmitter, FBXLoader, FInterpConstantTo, FInterpTo, FreelookVirtualCamera, GLTFLoader, HDRLoader, JSONLoader, KTX2Loader, Label, Loader, Logger, ObjectInstance, Orientation, PerformanceMonitor, Perlin, Plane, PropertyManager, QInterpConstantTo, QInterpTo, Quat_AngularDistance, Quat_Equals, Quat_exponentialDamp, Quat_quarticDamp, Quat_smoothDamp, RandomizedLight, Reflector, ReflectorMaterial, RenderTexture, Renderer, ResizeMode, ResourceManager, SVGLoader, ShadowMaterial, Sphere, SystemInfo, Task, TextureLoader, VInterpConstantTo, VInterpTo, Vec3_smoothDamp, Vector3_NEG_ONE, Vector3_ONE, Vector3_RIGHT, Vector3_UNIT_X, Vector3_UNIT_Y, Vector3_UNIT_Z, Vector3_UP, Vector3_ZERO, Viewer, applyProps, dependencies, exponentialDamp, find, frag_BoxfilterBlur, frag_cubeMapToPanorama, frag_panoramaToCubeMap, getChildByName, getChildren, getClassInstance, getShaderMaterial, mixin, property, quarticDamp, queryValues, smoothDamp, vert_fullscreen };
|
|
5873
6585
|
//# sourceMappingURL=module.js.map
|