@vyr/three 0.0.1

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.
Files changed (127) hide show
  1. package/package.json +26 -0
  2. package/src/actor/ComposerServiceActor.ts +107 -0
  3. package/src/actor/GeometryActor.ts +13 -0
  4. package/src/actor/HTMLConvertActor.ts +55 -0
  5. package/src/actor/MaterialActor.ts +13 -0
  6. package/src/actor/NodeActor.ts +25 -0
  7. package/src/actor/OrbitControllerActor.ts +110 -0
  8. package/src/actor/PassActor.ts +24 -0
  9. package/src/actor/SceneServiceActor.ts +122 -0
  10. package/src/actor/TextureActor.ts +13 -0
  11. package/src/actor/TransformControllerActor.ts +23 -0
  12. package/src/actor/index.ts +10 -0
  13. package/src/asset/index.ts +187 -0
  14. package/src/controls/CameraControls.ts +2360 -0
  15. package/src/controls/TransformControls.ts +1747 -0
  16. package/src/controls/index.ts +2 -0
  17. package/src/descriptor/ComposerServiceDescriptor.ts +47 -0
  18. package/src/descriptor/GeoMapDescriptor.ts +24 -0
  19. package/src/descriptor/HTMLConvertDescriptor.ts +12 -0
  20. package/src/descriptor/InstancedMeshDescriptor.ts +21 -0
  21. package/src/descriptor/MeshDescriptor.ts +16 -0
  22. package/src/descriptor/ModelDescriptor.ts +15 -0
  23. package/src/descriptor/OrbitControllerDescriptor.ts +84 -0
  24. package/src/descriptor/OrthographicCameraDescriptor.ts +12 -0
  25. package/src/descriptor/ParticleDescriptor.ts +88 -0
  26. package/src/descriptor/PassDescriptor.ts +33 -0
  27. package/src/descriptor/PerspectiveCameraDescriptor.ts +15 -0
  28. package/src/descriptor/PointsDescriptor.ts +16 -0
  29. package/src/descriptor/SceneServiceDescriptor.ts +39 -0
  30. package/src/descriptor/SpriteDescriptor.ts +16 -0
  31. package/src/descriptor/TextDescriptor.ts +41 -0
  32. package/src/descriptor/TransformControllerDescriptor.ts +32 -0
  33. package/src/descriptor/animation/AnimationActionDescriptor.ts +52 -0
  34. package/src/descriptor/geometry/BoxGeometryDescriptor.ts +26 -0
  35. package/src/descriptor/geometry/BufferGeometryDescriptor.ts +15 -0
  36. package/src/descriptor/geometry/CircleGeometryDescriptor.ts +22 -0
  37. package/src/descriptor/geometry/CylinderGeometryDescriptor.ts +30 -0
  38. package/src/descriptor/geometry/ExtrudeGeometryDescriptor.ts +35 -0
  39. package/src/descriptor/geometry/GeometryDescriptor.ts +8 -0
  40. package/src/descriptor/geometry/PlaneGeometryDescriptor.ts +22 -0
  41. package/src/descriptor/geometry/RingGeometryDescriptor.ts +26 -0
  42. package/src/descriptor/geometry/SphereGeometryDescriptor.ts +27 -0
  43. package/src/descriptor/geometry/SurfaceGeometryDescriptor.ts +15 -0
  44. package/src/descriptor/geometry/TubeGeometryDescriptor.ts +25 -0
  45. package/src/descriptor/helper/AxesHelperDescriptor.ts +8 -0
  46. package/src/descriptor/index.ts +45 -0
  47. package/src/descriptor/light/AmbientLightDescriptor.ts +8 -0
  48. package/src/descriptor/light/DirectionalLightDescriptor.ts +33 -0
  49. package/src/descriptor/light/HemisphereLightDescriptor.ts +16 -0
  50. package/src/descriptor/light/LightDescriptor.ts +16 -0
  51. package/src/descriptor/light/PointLightDescriptor.ts +24 -0
  52. package/src/descriptor/light/RectAreaLightDescriptor.ts +20 -0
  53. package/src/descriptor/light/SpotLightDescriptor.ts +30 -0
  54. package/src/descriptor/material/MaterialDescriptor.ts +84 -0
  55. package/src/descriptor/material/MeshBasicMaterialDescriptor.ts +53 -0
  56. package/src/descriptor/material/MeshPhongMaterialDescriptor.ts +102 -0
  57. package/src/descriptor/material/MeshStandardMaterialDescriptor.ts +99 -0
  58. package/src/descriptor/material/PointsMaterialDescriptor.ts +31 -0
  59. package/src/descriptor/material/ShaderMaterialDescriptor.ts +35 -0
  60. package/src/descriptor/material/ShadowMaterialDescriptor.ts +19 -0
  61. package/src/descriptor/material/SpriteMaterialDescriptor.ts +31 -0
  62. package/src/descriptor/texture/TextureDescriptor.ts +110 -0
  63. package/src/index.ts +9 -0
  64. package/src/interpreter/ComposerServiceInterpreter.ts +25 -0
  65. package/src/interpreter/GeoMapInterpreter.ts +253 -0
  66. package/src/interpreter/HTMLConvertInterpreter.ts +31 -0
  67. package/src/interpreter/InstancedMeshInterpreter.ts +76 -0
  68. package/src/interpreter/MeshInterpreter.ts +25 -0
  69. package/src/interpreter/ModelInterpreter.ts +61 -0
  70. package/src/interpreter/NodeInterpreter.ts +65 -0
  71. package/src/interpreter/OrbitControllerInterpreter.ts +47 -0
  72. package/src/interpreter/OrthographicCameraInterpreter.ts +13 -0
  73. package/src/interpreter/ParticleInterpreter.ts +221 -0
  74. package/src/interpreter/PassInterpreter.ts +43 -0
  75. package/src/interpreter/PerspectiveCameraInterpreter.ts +33 -0
  76. package/src/interpreter/PointsInterpreter.ts +61 -0
  77. package/src/interpreter/SceneServiceInterpreter.ts +119 -0
  78. package/src/interpreter/ServiceSchedulerInterpreter.ts +23 -0
  79. package/src/interpreter/SpriteInterpreter.ts +45 -0
  80. package/src/interpreter/TextInterpreter.ts +76 -0
  81. package/src/interpreter/TransformControllerInterpreter.ts +44 -0
  82. package/src/interpreter/animation/AnimationActionInterpreter.ts +66 -0
  83. package/src/interpreter/geometry/BoxGeometryInterpreter.ts +34 -0
  84. package/src/interpreter/geometry/BufferGeometryInterpreter.ts +47 -0
  85. package/src/interpreter/geometry/CircleGeometryInterpreter.ts +34 -0
  86. package/src/interpreter/geometry/CylinderGeometryInterpreter.ts +34 -0
  87. package/src/interpreter/geometry/ExtrudeGeometryInterpreter.ts +55 -0
  88. package/src/interpreter/geometry/PlaneGeometryInterpreter.ts +34 -0
  89. package/src/interpreter/geometry/RingGeometryInterpreter.ts +34 -0
  90. package/src/interpreter/geometry/SphereGeometryInterpreter.ts +34 -0
  91. package/src/interpreter/geometry/SurfaceGeometryInterpreter.ts +39 -0
  92. package/src/interpreter/geometry/TubeGeometryInterpreter.ts +42 -0
  93. package/src/interpreter/helper/AxesHelperInterpreter.ts +38 -0
  94. package/src/interpreter/index.ts +45 -0
  95. package/src/interpreter/light/AmbientLightInterpreter.ts +30 -0
  96. package/src/interpreter/light/DirectionalLightInterpreter.ts +84 -0
  97. package/src/interpreter/light/HemisphereLightInterpreter.ts +32 -0
  98. package/src/interpreter/light/PointLightInterpreter.ts +46 -0
  99. package/src/interpreter/light/RectAreaLightInterpreter.ts +34 -0
  100. package/src/interpreter/light/SpotLightInterpreter.ts +68 -0
  101. package/src/interpreter/material/MaterialInterpreter.ts +34 -0
  102. package/src/interpreter/material/MeshBasicMaterialInterpreter.ts +43 -0
  103. package/src/interpreter/material/MeshPhongMaterialInterpreter.ts +63 -0
  104. package/src/interpreter/material/MeshStandardMaterialInterpreter.ts +58 -0
  105. package/src/interpreter/material/PointsMaterialInterpreter.ts +36 -0
  106. package/src/interpreter/material/ShaderMaterialInterpreter.ts +51 -0
  107. package/src/interpreter/material/ShadowMaterialInterpreter.ts +31 -0
  108. package/src/interpreter/material/SpriteMaterialInterpreter.ts +36 -0
  109. package/src/interpreter/texture/TextureInterpreter.ts +59 -0
  110. package/src/locale/Language.ts +10 -0
  111. package/src/locale/LanguageProvider.ts +16 -0
  112. package/src/locale/index.ts +2 -0
  113. package/src/preset/execute/GeoMap/drilldown.ts +61 -0
  114. package/src/preset/execute/GeoMap/index.ts +1 -0
  115. package/src/preset/execute/index.ts +1 -0
  116. package/src/preset/index.ts +7 -0
  117. package/src/preset/routine/GeoMap/drilldown.ts +26 -0
  118. package/src/preset/routine/GeoMap/index.ts +1 -0
  119. package/src/preset/routine/index.ts +1 -0
  120. package/src/utils/dispose/index.ts +23 -0
  121. package/src/utils/geometry/index.ts +82 -0
  122. package/src/utils/index.ts +7 -0
  123. package/src/utils/material/index.ts +53 -0
  124. package/src/utils/pickup/index.ts +16 -0
  125. package/src/utils/random/index.ts +7 -0
  126. package/src/utils/text/index.ts +492 -0
  127. package/src/utils/texture/index.ts +19 -0
@@ -0,0 +1,492 @@
1
+ import { Box3, BufferGeometry } from 'three';
2
+ import { Font } from 'three/examples/jsm/loaders/FontLoader.js';
3
+ import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry.js';
4
+ import { mergeGeometries } from 'three/examples/jsm/utils/BufferGeometryUtils.js'
5
+
6
+ interface CharInfo {
7
+ geometry: BufferGeometry
8
+ width: number
9
+ height: number
10
+ depth: number
11
+ minX: number
12
+ minY: number
13
+ maxY: number
14
+ }
15
+
16
+ interface TextOptions {
17
+ size: number
18
+ letterSpacing: number
19
+ lineHeight: number
20
+ align: string
21
+ lineIndex: number
22
+ currentY: number
23
+ }
24
+
25
+ interface CharSizes {
26
+ [k: string]: number
27
+ }
28
+
29
+ interface TextLayout {
30
+ lines: string[]
31
+ charSizes: CharSizes
32
+ maxCharHeight: number
33
+ spaceWidth: number
34
+ }
35
+
36
+ interface CharDimensions {
37
+ width: number
38
+ height: number
39
+ depth: number
40
+ minX: number
41
+ minY: number
42
+ maxY: number
43
+ }
44
+
45
+ class TextUtils {
46
+ static charTemplateCache = new Map<string, CharInfo>()
47
+ static defaultOptions = {
48
+ size: 1,
49
+ depth: 1,
50
+ curveSegments: 12,
51
+ bevelEnabled: true,
52
+ bevelThickness: 0,
53
+ bevelSize: 0,
54
+ bevelOffset: 0,
55
+ bevelSegments: 5
56
+ }
57
+
58
+ /**
59
+ * 创建字符几何体(使用缓存优化)
60
+ */
61
+ static createCharGeometry(char: string, font: Font, options = {}) {
62
+ if (!char || char === '') {
63
+ return null;
64
+ }
65
+
66
+ try {
67
+ // 检查缓存
68
+ if (!this.charTemplateCache.has(char)) {
69
+ const geometry = new TextGeometry(char, {
70
+ ...TextUtils.defaultOptions,
71
+ font,
72
+ });
73
+
74
+ geometry.computeBoundingBox();
75
+ const bbox = geometry.boundingBox as Box3
76
+
77
+ if (bbox.isEmpty()) return null
78
+
79
+ this.charTemplateCache.set(char, {
80
+ geometry: geometry,
81
+ width: bbox.max.x - bbox.min.x,
82
+ height: bbox.max.y - bbox.min.y,
83
+ depth: bbox.max.z - bbox.min.z,
84
+ minX: bbox.min.x,
85
+ minY: bbox.min.y,
86
+ maxY: bbox.max.y,
87
+ });
88
+ }
89
+
90
+ const template = this.charTemplateCache.get(char) as CharInfo
91
+
92
+ return {
93
+ geometry: template.geometry.clone(),
94
+ width: template.width,
95
+ height: template.height,
96
+ depth: template.depth,
97
+ minX: template.minX,
98
+ minY: template.minY
99
+ };
100
+ } catch (error) {
101
+ console.error(`Error creating geometry for character "${char}":`, error);
102
+ return null;
103
+ }
104
+ }
105
+
106
+ /**
107
+ * 获取字符尺寸信息(包含字间距)
108
+ */
109
+ static getCharDimensions(char: string, font: Font, options: Partial<TextOptions> = {}): CharDimensions {
110
+ if (!char || char === '') {
111
+ return { width: 0, height: 0, depth: 0, minX: 0, minY: 0, maxY: 0 };
112
+ }
113
+
114
+ const { letterSpacing = 0.1 } = options
115
+
116
+ if (!this.charTemplateCache.has(char)) {
117
+ this.createCharGeometry(char, font, options);
118
+ }
119
+
120
+ const template = this.charTemplateCache.get(char);
121
+ if (!template) {
122
+ return { width: 0, height: 0, depth: 0, minX: 0, minY: 0, maxY: 0 };
123
+ }
124
+
125
+ // 在字符宽度基础上添加字间距
126
+ return {
127
+ width: template.width + letterSpacing,
128
+ height: template.height,
129
+ depth: template.depth,
130
+ minX: template.minX,
131
+ minY: template.minY,
132
+ maxY: template.maxY,
133
+ };
134
+ }
135
+
136
+ /**
137
+ * 计算文本行布局
138
+ */
139
+ static calculateLineLayout(text: string, maxWidth: number, font: Font, options: Partial<TextOptions> = {}): TextLayout {
140
+ if (!text || maxWidth <= 0) {
141
+ return { lines: [], charSizes: {}, maxCharHeight: 0, spaceWidth: 0 };
142
+ }
143
+
144
+ const paragraphs = text.split('\n');
145
+ const lines = [];
146
+ const charSizes: CharSizes = {};
147
+
148
+ // 预计算空格宽度(包含字间距)
149
+ const spaceDimensions = this.getCharDimensions(' ', font, options);
150
+ const spaceWidth = spaceDimensions.width;
151
+
152
+ // 计算最大字符高度
153
+ let minY = Infinity, maxY = 0;
154
+
155
+ for (const paragraph of paragraphs) {
156
+ const words = paragraph.split(' ');
157
+ let currentLine = '';
158
+ let currentLineWidth = 0;
159
+
160
+ for (const word of words) {
161
+ if (!word) continue;
162
+
163
+ let wordWidth = 0;
164
+ const chars = word.split('');
165
+
166
+ // 预计算单词中所有字符的尺寸
167
+ for (const char of chars) {
168
+ if (!charSizes[char]) {
169
+ const dim = this.getCharDimensions(char, font, options);
170
+ charSizes[char] = dim.width;
171
+ minY = Math.min(minY, dim.minY)
172
+ maxY = Math.max(maxY, dim.maxY)
173
+ }
174
+ wordWidth += charSizes[char];
175
+ }
176
+
177
+ // 处理超长单词
178
+ if (wordWidth > maxWidth && currentLine === '') {
179
+ this.handleLongWord(chars, maxWidth, charSizes, lines, font, options);
180
+ continue;
181
+ }
182
+
183
+ // 计算当前行加上这个单词后的宽度
184
+ const spaceWidthForWord = currentLine ? spaceWidth : 0;
185
+ const potentialLineWidth = currentLineWidth + spaceWidthForWord + wordWidth;
186
+
187
+ if (potentialLineWidth > maxWidth) {
188
+ if (currentLine) {
189
+ lines.push(currentLine);
190
+ currentLine = word;
191
+ currentLineWidth = wordWidth;
192
+ } else {
193
+ lines.push(word);
194
+ currentLine = '';
195
+ currentLineWidth = 0;
196
+ }
197
+ } else {
198
+ if (currentLine) {
199
+ currentLine += ' ' + word;
200
+ currentLineWidth += spaceWidth + wordWidth;
201
+ } else {
202
+ currentLine = word;
203
+ currentLineWidth = wordWidth;
204
+ }
205
+ }
206
+ }
207
+
208
+ if (currentLine) {
209
+ lines.push(currentLine);
210
+ }
211
+
212
+ if (paragraphs.length > 1 && paragraph !== paragraphs[paragraphs.length - 1]) {
213
+ lines.push('');
214
+ }
215
+ }
216
+
217
+ const maxCharHeight = maxY - minY;
218
+ return {
219
+ lines: lines.filter(line => line !== undefined && line !== null),
220
+ charSizes,
221
+ maxCharHeight: maxCharHeight > 0 ? maxCharHeight : 0,
222
+ spaceWidth
223
+ };
224
+ }
225
+
226
+ /**
227
+ * 处理超长单词
228
+ */
229
+ static handleLongWord(chars: string[], maxWidth: number, charSizes: CharSizes, lines: string[], font: Font, options: Partial<TextOptions>) {
230
+ const { letterSpacing = 0.1 } = options;
231
+ let currentSegment = '';
232
+ let segmentWidth = 0;
233
+
234
+ for (const char of chars) {
235
+ if (!charSizes[char]) {
236
+ const dim = this.getCharDimensions(char, font, options);
237
+ charSizes[char] = dim.width; // 这里已经包含了letterSpacing
238
+ }
239
+
240
+ const charWidth = charSizes[char];
241
+
242
+ if (charWidth > maxWidth && currentSegment === '') {
243
+ lines.push(char);
244
+ continue;
245
+ }
246
+
247
+ if (segmentWidth + charWidth > maxWidth && currentSegment) {
248
+ lines.push(currentSegment);
249
+ currentSegment = char;
250
+ segmentWidth = charWidth;
251
+ } else {
252
+ currentSegment += char;
253
+ segmentWidth += charWidth;
254
+ }
255
+ }
256
+
257
+ if (currentSegment) {
258
+ lines.push(currentSegment);
259
+ }
260
+ }
261
+
262
+ /**
263
+ * 创建单行文本几何体
264
+ */
265
+ static createSingleLineGeometry(line: string, layout: TextLayout, font: Font, options: Partial<TextOptions>) {
266
+ const {
267
+ align = 'left',
268
+ currentY = 0,
269
+ } = options;
270
+
271
+ if (!line || line.trim() === '') {
272
+ return null;
273
+ }
274
+
275
+ try {
276
+ // 计算行总宽度(这里已经包含了字间距)
277
+ let lineWidth = 0;
278
+ for (const char of line) {
279
+ if (char === ' ') {
280
+ lineWidth += layout.spaceWidth;
281
+ } else {
282
+ lineWidth += layout.charSizes[char] || 0;
283
+ }
284
+ }
285
+
286
+ // 根据对齐方式计算起始X坐标
287
+ let startX = 0;
288
+ switch (align) {
289
+ case 'center':
290
+ startX = -lineWidth / 2;
291
+ break;
292
+ case 'right':
293
+ startX = -lineWidth;
294
+ break;
295
+ default: // 'left'
296
+ startX = 0;
297
+ }
298
+
299
+ const charGeometries = [];
300
+ let currentX = startX;
301
+
302
+ // 计算这行字符的最大上升部和下降部
303
+ let maxAscent = 0;
304
+ let maxDescent = 0;
305
+
306
+ for (const char of line) {
307
+ if (char === ' ') continue;
308
+
309
+ const dim = this.getCharDimensions(char, font, options);
310
+ maxAscent = Math.max(maxAscent, dim.maxY);
311
+ maxDescent = Math.max(maxDescent, -dim.minY);
312
+ }
313
+
314
+ // 统一的基线位置
315
+ const baselineY = currentY;
316
+
317
+ // 创建每个字符的几何体
318
+ for (const char of line) {
319
+ if (char === ' ') {
320
+ currentX += layout.spaceWidth;
321
+ continue;
322
+ }
323
+
324
+ const charGeo = this.createCharGeometry(char, font, options);
325
+ if (!charGeo || !charGeo.geometry) continue;
326
+
327
+ const geometry = charGeo.geometry;
328
+
329
+ // 字符位置计算
330
+ const offsetX = currentX - charGeo.minX;
331
+ const offsetY = baselineY;
332
+
333
+ geometry.translate(offsetX, offsetY, 0);
334
+
335
+ charGeometries.push(geometry);
336
+
337
+ // 移动到下一个字符位置(这里使用包含letterSpacing的宽度)
338
+ currentX += layout.charSizes[char] || 0;
339
+ }
340
+
341
+ return this.mergeGeometries(charGeometries);
342
+ } catch (error) {
343
+ console.error('Error creating single line geometry:', error);
344
+ return null;
345
+ }
346
+ }
347
+
348
+ /**
349
+ * 合并多个几何体
350
+ */
351
+ static mergeGeometries(geometries: BufferGeometry[]) {
352
+ const validGeometries = geometries.filter(geo =>
353
+ geo && geo.isBufferGeometry && geo.attributes.position && geo.attributes.position.count > 0
354
+ );
355
+
356
+ if (validGeometries.length === 0) {
357
+ return new BufferGeometry();
358
+ }
359
+
360
+ if (validGeometries.length === 1) {
361
+ return validGeometries[0];
362
+ }
363
+
364
+ try {
365
+ const merged = mergeGeometries(validGeometries);
366
+ validGeometries.forEach(geo => geo.dispose());
367
+ return merged || new BufferGeometry();
368
+ } catch (error) {
369
+ console.error(error);
370
+ validGeometries.forEach(geo => geo.dispose());
371
+ return new BufferGeometry();
372
+ }
373
+ }
374
+
375
+ /**
376
+ * 清理缓存和释放内存
377
+ */
378
+ static dispose() {
379
+ for (const [key, template] of this.charTemplateCache) {
380
+ if (template.geometry && template.geometry.dispose) {
381
+ template.geometry.dispose();
382
+ }
383
+ }
384
+ this.charTemplateCache.clear();
385
+ }
386
+
387
+ /**
388
+ * 获取文本尺寸信息
389
+ */
390
+ static measureText(text: string, maxWidth: number, font: Font, options: Partial<TextOptions> = {}) {
391
+ if (!text || maxWidth <= 0) {
392
+ return { width: 0, height: 0, lineCount: 0, lines: [] };
393
+ }
394
+
395
+ const layout = this.calculateLineLayout(text, maxWidth, font, options);
396
+
397
+ if (layout.lines.length === 0) {
398
+ return { width: 0, height: 0, lineCount: 0, lines: [] };
399
+ }
400
+
401
+ let totalWidth = 0;
402
+ const nonEmptyLines = layout.lines.filter(line => line !== '');
403
+
404
+ for (const line of nonEmptyLines) {
405
+ let lineWidth = 0;
406
+ for (const char of line) {
407
+ if (char === ' ') {
408
+ lineWidth += layout.spaceWidth;
409
+ } else {
410
+ lineWidth += layout.charSizes[char] || 0;
411
+ }
412
+ }
413
+ totalWidth = Math.max(totalWidth, lineWidth);
414
+ }
415
+
416
+ const totalHeight = nonEmptyLines.length * layout.maxCharHeight * (options.lineHeight || 1.4);
417
+
418
+ return {
419
+ width: totalWidth,
420
+ height: totalHeight,
421
+ lineCount: nonEmptyLines.length,
422
+ lines: layout.lines
423
+ };
424
+ }
425
+
426
+ /**
427
+ * 创建换行文本的合并几何体
428
+ */
429
+ static createTextGeometry(text: string, maxWidth: number, font: Font, options: Partial<TextOptions> = {}) {
430
+ if (!text || text.trim() === '' || maxWidth <= 0) {
431
+ return new BufferGeometry();
432
+ }
433
+
434
+ const {
435
+ size = 1,
436
+ lineHeight = 1.02,
437
+ align = 'left'
438
+ } = options;
439
+
440
+ const layout = this.calculateLineLayout(text, maxWidth, font, options);
441
+
442
+ if (layout.lines.length === 0) {
443
+ return new BufferGeometry();
444
+ }
445
+
446
+ const lineGeometries: BufferGeometry[] = [];
447
+ const maxCharHeight = layout.maxCharHeight;
448
+
449
+ // 计算起始Y位置(从顶部开始)
450
+ const nonEmptyLines = layout.lines.filter(line => line !== '');
451
+ const totalHeight = (nonEmptyLines.length - 1) * maxCharHeight * lineHeight;
452
+ let currentY = totalHeight / 2;
453
+
454
+ // 为每一行创建几何体
455
+ for (let i = 0; i < layout.lines.length; i++) {
456
+ const line = layout.lines[i];
457
+ if (line === '') {
458
+ currentY -= maxCharHeight * lineHeight;
459
+ continue;
460
+ }
461
+
462
+ const lineGeometry = this.createSingleLineGeometry(line, layout, font, {
463
+ ...options,
464
+ align,
465
+ lineIndex: i,
466
+ currentY
467
+ });
468
+
469
+ if (lineGeometry) {
470
+ lineGeometries.push(lineGeometry);
471
+ }
472
+
473
+ currentY -= maxCharHeight * lineHeight;
474
+ }
475
+
476
+ // 合并所有几何体
477
+ const mergedGeometry = this.mergeGeometries(lineGeometries);
478
+ mergedGeometry.scale(size, size, 1)
479
+
480
+ // 计算边界框和边界球
481
+ if (mergedGeometry.attributes.position && mergedGeometry.attributes.position.count > 0) {
482
+ mergedGeometry.computeBoundingBox();
483
+ mergedGeometry.computeBoundingSphere();
484
+ }
485
+
486
+ return mergedGeometry;
487
+ }
488
+ }
489
+
490
+ export {
491
+ TextUtils
492
+ }
@@ -0,0 +1,19 @@
1
+ import { Material } from 'three'
2
+ import { Asset, Descriptor, Graphics, UpdateArgs } from '@vyr/engine'
3
+ import { TextureDescriptor } from '../../descriptor'
4
+ import { TextureActor } from '../../actor'
5
+
6
+ const setMap = <T extends Descriptor = Descriptor>(material: Material, key: keyof T, descriptor: T, graphics: Graphics, args: UpdateArgs) => {
7
+ const value = descriptor[key] as string
8
+ const texture = Asset.get(value)
9
+ if (texture instanceof TextureDescriptor) {
10
+ const textureActor = graphics.getActor<TextureActor>(texture, args)
11
+ //@ts-ignore
12
+ material[key] = textureActor.object
13
+ } else {
14
+ //@ts-ignore
15
+ material[key] = null
16
+ }
17
+ }
18
+
19
+ export { setMap }