minerender 2.1.0-alpha.67 → 2.1.0-alpha.69
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/browser/index.d.mts +106 -5
- package/dist/browser/index.d.ts +106 -5
- package/dist/browser/index.js +520 -179
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/index.mjs +379 -38
- package/dist/browser/index.mjs.map +1 -1
- package/dist/bundle.js +363 -13
- package/dist/bundle.js.map +1 -1
- package/dist/node/index.d.mts +106 -5
- package/dist/node/index.d.ts +106 -5
- package/dist/node/index.js +526 -179
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +381 -38
- package/dist/node/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/bundle.js
CHANGED
|
@@ -41421,7 +41421,8 @@ void main() {
|
|
|
41421
41421
|
this.entityModelCache,
|
|
41422
41422
|
this.entityTextureCache,
|
|
41423
41423
|
this.entityAnimationCache,
|
|
41424
|
-
this.blockEntityIndexCache
|
|
41424
|
+
this.blockEntityIndexCache,
|
|
41425
|
+
this.fontCache
|
|
41425
41426
|
];
|
|
41426
41427
|
}
|
|
41427
41428
|
static clear() {
|
|
@@ -41468,6 +41469,7 @@ void main() {
|
|
|
41468
41469
|
_Caching.entityTextureCache = _Caching.createAssetCache();
|
|
41469
41470
|
_Caching.entityAnimationCache = _Caching.createAssetCache();
|
|
41470
41471
|
_Caching.blockEntityIndexCache = _Caching.createAssetCache();
|
|
41472
|
+
_Caching.fontCache = _Caching.createAssetCache();
|
|
41471
41473
|
Caching = _Caching;
|
|
41472
41474
|
}
|
|
41473
41475
|
});
|
|
@@ -93313,6 +93315,7 @@ ${shader.fragmentShader}`.replace(
|
|
|
93313
93315
|
EntityObject: () => EntityObject,
|
|
93314
93316
|
Env: () => Env,
|
|
93315
93317
|
FluidModelObject: () => FluidModelObject,
|
|
93318
|
+
Fonts: () => Fonts,
|
|
93316
93319
|
Geometries: () => Geometries,
|
|
93317
93320
|
GuiHelper: () => GuiHelper,
|
|
93318
93321
|
GuiLight: () => GuiLight,
|
|
@@ -93384,6 +93387,8 @@ ${shader.fragmentShader}`.replace(
|
|
|
93384
93387
|
computeTangents: () => computeTangents,
|
|
93385
93388
|
createCanvas: () => createCanvas,
|
|
93386
93389
|
createFluidGeometry: () => createFluidGeometry,
|
|
93390
|
+
createGuiTextGeometry: () => createGuiTextGeometry,
|
|
93391
|
+
createGuiTextureGeometry: () => createGuiTextureGeometry,
|
|
93387
93392
|
createImage: () => createImage,
|
|
93388
93393
|
entityAnimationTime: () => entityAnimationTime,
|
|
93389
93394
|
estimateBytesUsed: () => estimateBytesUsed,
|
|
@@ -93412,6 +93417,7 @@ ${shader.fragmentShader}`.replace(
|
|
|
93412
93417
|
isTransformable: () => isTransformable,
|
|
93413
93418
|
isTripleArray: () => isTripleArray,
|
|
93414
93419
|
isVector3: () => isVector3,
|
|
93420
|
+
layoutGuiText: () => layoutGuiText,
|
|
93415
93421
|
md5: () => md5,
|
|
93416
93422
|
mergeBufferAttributes: () => mergeBufferAttributes,
|
|
93417
93423
|
mergeBufferGeometries: () => mergeBufferGeometries,
|
|
@@ -93759,6 +93765,104 @@ ${shader.fragmentShader}`.replace(
|
|
|
93759
93765
|
// src/assets/index.ts
|
|
93760
93766
|
init_BlockStates();
|
|
93761
93767
|
init_Entities();
|
|
93768
|
+
|
|
93769
|
+
// src/assets/Fonts.ts
|
|
93770
|
+
init_dirname();
|
|
93771
|
+
init_buffer2();
|
|
93772
|
+
init_process2();
|
|
93773
|
+
init_AssetKey();
|
|
93774
|
+
init_AssetLoader();
|
|
93775
|
+
init_AssetParsers();
|
|
93776
|
+
init_ModelTextures();
|
|
93777
|
+
init_Caching();
|
|
93778
|
+
var Fonts = class {
|
|
93779
|
+
static async get(key = "minecraft:default") {
|
|
93780
|
+
const fontKey = typeof key === "string" ? AssetKey.parse("font", key) : key;
|
|
93781
|
+
return await Caching.fontCache.get(fontKey.serialize(), () => this.load(fontKey, []));
|
|
93782
|
+
}
|
|
93783
|
+
static relatedKey(assetType, id, origin) {
|
|
93784
|
+
const key = AssetKey.parse(assetType, id);
|
|
93785
|
+
key.root = origin.root;
|
|
93786
|
+
return key;
|
|
93787
|
+
}
|
|
93788
|
+
static async load(key, parents) {
|
|
93789
|
+
const serialized = key.serialize();
|
|
93790
|
+
if (parents.includes(serialized)) throw new Error(`Cyclic font reference: ${key.toNamespacedString()}`);
|
|
93791
|
+
const stack = await AssetLoader.getAll(key, "json" /* JSON */);
|
|
93792
|
+
if (stack.length === 0) throw new Error(`Could not load font ${key.toNamespacedString()}`);
|
|
93793
|
+
const glyphs = /* @__PURE__ */ new Map();
|
|
93794
|
+
for (const asset of stack) {
|
|
93795
|
+
for (const provider of asset.providers) {
|
|
93796
|
+
if (provider.filter?.uniform || provider.filter?.jp) continue;
|
|
93797
|
+
let provided;
|
|
93798
|
+
switch (provider.type) {
|
|
93799
|
+
case "bitmap":
|
|
93800
|
+
case "minecraft:bitmap":
|
|
93801
|
+
provided = await this.bitmap(provider, key);
|
|
93802
|
+
break;
|
|
93803
|
+
case "space":
|
|
93804
|
+
case "minecraft:space":
|
|
93805
|
+
provided = new Map(Object.entries(provider.advances).map(([character, advance]) => [
|
|
93806
|
+
character,
|
|
93807
|
+
{ x: 0, y: 0, width: 0, height: 0, scale: 1, ascent: 0, advance }
|
|
93808
|
+
]));
|
|
93809
|
+
break;
|
|
93810
|
+
case "reference":
|
|
93811
|
+
case "minecraft:reference":
|
|
93812
|
+
provided = (await this.load(this.relatedKey("font", provider.id, key), [...parents, serialized])).glyphs;
|
|
93813
|
+
break;
|
|
93814
|
+
default:
|
|
93815
|
+
continue;
|
|
93816
|
+
}
|
|
93817
|
+
for (const [character, glyph] of provided) {
|
|
93818
|
+
if (character !== "\0" && !glyphs.has(character)) glyphs.set(character, glyph);
|
|
93819
|
+
}
|
|
93820
|
+
}
|
|
93821
|
+
}
|
|
93822
|
+
return { glyphs };
|
|
93823
|
+
}
|
|
93824
|
+
static async bitmap(provider, fontKey) {
|
|
93825
|
+
const rows = provider.chars.map((row) => [...row]);
|
|
93826
|
+
const columns = rows[0]?.length;
|
|
93827
|
+
if (!columns || rows.some((row) => row.length !== columns)) {
|
|
93828
|
+
throw new Error(`Invalid character grid in font ${fontKey.toNamespacedString()}`);
|
|
93829
|
+
}
|
|
93830
|
+
const key = this.relatedKey("textures", provider.file, fontKey);
|
|
93831
|
+
const image = await ModelTextures.get(key);
|
|
93832
|
+
if (!image) throw new Error(`Could not load font texture ${key.toNamespacedString()}`);
|
|
93833
|
+
const width = Math.floor(image.width / columns), height = Math.floor(image.height / rows.length);
|
|
93834
|
+
if (!width || !height) throw new Error(`Font texture ${key.toNamespacedString()} is smaller than its character grid`);
|
|
93835
|
+
const scale = (provider.height ?? 8) / height;
|
|
93836
|
+
const pixels = image.data.getImageData(0, 0, image.width, image.height).data;
|
|
93837
|
+
const glyphs = /* @__PURE__ */ new Map();
|
|
93838
|
+
rows.forEach((row, rowIndex) => row.forEach((character, columnIndex) => {
|
|
93839
|
+
if (character === "\0") return;
|
|
93840
|
+
const x4 = columnIndex * width, y5 = rowIndex * height;
|
|
93841
|
+
let occupiedWidth = 0;
|
|
93842
|
+
for (let column = width - 1; column >= 0 && !occupiedWidth; column--) {
|
|
93843
|
+
for (let row2 = 0; row2 < height; row2++) {
|
|
93844
|
+
if (pixels[((y5 + row2) * image.width + x4 + column) * 4 + 3] !== 0) {
|
|
93845
|
+
occupiedWidth = column + 1;
|
|
93846
|
+
break;
|
|
93847
|
+
}
|
|
93848
|
+
}
|
|
93849
|
+
}
|
|
93850
|
+
glyphs.set(character, {
|
|
93851
|
+
image: image.data.canvas,
|
|
93852
|
+
x: x4,
|
|
93853
|
+
y: y5,
|
|
93854
|
+
width,
|
|
93855
|
+
height,
|
|
93856
|
+
scale,
|
|
93857
|
+
ascent: provider.ascent,
|
|
93858
|
+
advance: Math.floor(occupiedWidth * scale + 0.5) + 1
|
|
93859
|
+
});
|
|
93860
|
+
}));
|
|
93861
|
+
return glyphs;
|
|
93862
|
+
}
|
|
93863
|
+
};
|
|
93864
|
+
|
|
93865
|
+
// src/assets/index.ts
|
|
93762
93866
|
init_ModelTextures();
|
|
93763
93867
|
init_Models();
|
|
93764
93868
|
init_source();
|
|
@@ -96789,7 +96893,140 @@ property list uchar int vertex_index
|
|
|
96789
96893
|
init_buffer2();
|
|
96790
96894
|
init_process2();
|
|
96791
96895
|
init_AssetKey();
|
|
96896
|
+
|
|
96897
|
+
// src/gui/GuiText.ts
|
|
96898
|
+
init_dirname();
|
|
96899
|
+
init_buffer2();
|
|
96900
|
+
init_process2();
|
|
96901
|
+
init_three_module();
|
|
96902
|
+
async function layoutGuiText(text, options = {}) {
|
|
96903
|
+
const maxWidth = options.maxWidth ?? Infinity, lineHeight = options.lineHeight ?? 9;
|
|
96904
|
+
if (!(maxWidth > 0) || !Number.isFinite(lineHeight) || lineHeight <= 0) {
|
|
96905
|
+
throw new Error("Text wrap width and line height must be positive");
|
|
96906
|
+
}
|
|
96907
|
+
const font = await Fonts.get(options.font);
|
|
96908
|
+
const runs = typeof text === "string" ? [{ text }] : text;
|
|
96909
|
+
const glyphs = [], lineWidths = [];
|
|
96910
|
+
let line = [], width = 0;
|
|
96911
|
+
let trailingNewline = false;
|
|
96912
|
+
const finishLine = (entries) => {
|
|
96913
|
+
let x4 = 0;
|
|
96914
|
+
for (const entry of entries) {
|
|
96915
|
+
glyphs.push({ ...entry, x: x4, y: lineWidths.length * lineHeight });
|
|
96916
|
+
x4 += entry.advance;
|
|
96917
|
+
}
|
|
96918
|
+
lineWidths.push(x4);
|
|
96919
|
+
};
|
|
96920
|
+
for (const run of runs) {
|
|
96921
|
+
const style = {
|
|
96922
|
+
color: run.color ?? options.color ?? 16777215,
|
|
96923
|
+
bold: run.bold ?? options.bold ?? false,
|
|
96924
|
+
italic: run.italic ?? options.italic ?? false
|
|
96925
|
+
};
|
|
96926
|
+
for (const character of run.text.replace(/\r\n?/g, "\n")) {
|
|
96927
|
+
trailingNewline = character === "\n";
|
|
96928
|
+
if (character === "\n") {
|
|
96929
|
+
finishLine(line);
|
|
96930
|
+
line = [];
|
|
96931
|
+
width = 0;
|
|
96932
|
+
continue;
|
|
96933
|
+
}
|
|
96934
|
+
const glyph = font.glyphs.get(character);
|
|
96935
|
+
const advance = (glyph?.advance ?? 6) + (style.bold ? 1 : 0);
|
|
96936
|
+
line.push({ character, glyph, advance, style, x: 0, y: 0 });
|
|
96937
|
+
width += advance;
|
|
96938
|
+
while (width > maxWidth && line.length > 1) {
|
|
96939
|
+
let space = -1;
|
|
96940
|
+
for (let i4 = 0; i4 < line.length; i4++) if (line[i4].character === " ") space = i4;
|
|
96941
|
+
const split = space >= 0 ? space : line.length - 1;
|
|
96942
|
+
if (split > 0) finishLine(line.slice(0, split));
|
|
96943
|
+
line = line.slice(split + (space >= 0 ? 1 : 0));
|
|
96944
|
+
width = line.reduce((sum, entry) => sum + entry.advance, 0);
|
|
96945
|
+
}
|
|
96946
|
+
}
|
|
96947
|
+
}
|
|
96948
|
+
if (line.length || !lineWidths.length || trailingNewline) finishLine(line);
|
|
96949
|
+
return { glyphs, lineWidths, width: Math.max(0, ...lineWidths), height: lineWidths.length * lineHeight };
|
|
96950
|
+
}
|
|
96951
|
+
function createGuiTextGeometry(layout, shadow = true) {
|
|
96952
|
+
const batches = [];
|
|
96953
|
+
for (const isShadow of shadow ? [true, false] : [false]) {
|
|
96954
|
+
let batch;
|
|
96955
|
+
for (const entry of layout.glyphs) {
|
|
96956
|
+
const { glyph, style } = entry;
|
|
96957
|
+
if (glyph && !glyph.image) continue;
|
|
96958
|
+
if (!batch || batch.image !== glyph?.image) {
|
|
96959
|
+
batch = { image: glyph?.image, positions: [], uvs: [], colors: [], indices: [] };
|
|
96960
|
+
batches.push(batch);
|
|
96961
|
+
}
|
|
96962
|
+
const color2 = new Color(isShadow ? (style.color & 16579836) >> 2 : style.color);
|
|
96963
|
+
const offset = isShadow ? 1 : 0;
|
|
96964
|
+
const top = glyph ? 7 - glyph.ascent : 0;
|
|
96965
|
+
const height = glyph ? glyph.height * glyph.scale : 8;
|
|
96966
|
+
const width = glyph ? glyph.width * glyph.scale : 5;
|
|
96967
|
+
const shear = (y5) => style.italic ? 1 - 0.25 * y5 : 0;
|
|
96968
|
+
const quad = (left, upper, right, lower, boldOffset) => {
|
|
96969
|
+
const base = batch.positions.length / 3;
|
|
96970
|
+
const x4 = entry.x + offset + boldOffset, y5 = entry.y + offset;
|
|
96971
|
+
batch.positions.push(
|
|
96972
|
+
x4 + left + shear(upper),
|
|
96973
|
+
-y5 - upper,
|
|
96974
|
+
0,
|
|
96975
|
+
x4 + right + shear(upper),
|
|
96976
|
+
-y5 - upper,
|
|
96977
|
+
0,
|
|
96978
|
+
x4 + left + shear(lower),
|
|
96979
|
+
-y5 - lower,
|
|
96980
|
+
0,
|
|
96981
|
+
x4 + right + shear(lower),
|
|
96982
|
+
-y5 - lower,
|
|
96983
|
+
0
|
|
96984
|
+
);
|
|
96985
|
+
const u0 = glyph ? glyph.x / glyph.image.width : 0;
|
|
96986
|
+
const u1 = glyph ? (glyph.x + glyph.width) / glyph.image.width : 1;
|
|
96987
|
+
const v0 = glyph ? 1 - glyph.y / glyph.image.height : 1;
|
|
96988
|
+
const v1 = glyph ? 1 - (glyph.y + glyph.height) / glyph.image.height : 0;
|
|
96989
|
+
batch.uvs.push(u0, v0, u1, v0, u0, v1, u1, v1);
|
|
96990
|
+
for (let i4 = 0; i4 < 4; i4++) batch.colors.push(color2.r, color2.g, color2.b);
|
|
96991
|
+
batch.indices.push(base, base + 2, base + 1, base + 2, base + 3, base + 1);
|
|
96992
|
+
};
|
|
96993
|
+
for (const boldOffset of style.bold ? [0, 1] : [0]) {
|
|
96994
|
+
if (glyph) quad(0, top, width, top + height, boldOffset);
|
|
96995
|
+
else {
|
|
96996
|
+
quad(0, 0, 5, 1, boldOffset);
|
|
96997
|
+
quad(0, 7, 5, 8, boldOffset);
|
|
96998
|
+
quad(0, 1, 1, 7, boldOffset);
|
|
96999
|
+
quad(4, 1, 5, 7, boldOffset);
|
|
97000
|
+
}
|
|
97001
|
+
}
|
|
97002
|
+
}
|
|
97003
|
+
}
|
|
97004
|
+
return batches.map(({ image, positions, uvs, colors, indices }) => ({ image, geometry: new BufferGeometry().setAttribute("position", new Float32BufferAttribute(positions, 3)).setAttribute("uv", new Float32BufferAttribute(uvs, 2)).setAttribute("color", new Float32BufferAttribute(colors, 3)).setIndex(indices) }));
|
|
97005
|
+
}
|
|
97006
|
+
|
|
97007
|
+
// src/gui/GuiHelper.ts
|
|
96792
97008
|
var GuiHelper = class {
|
|
97009
|
+
/** Sizes a tooltip around supplied text; the first entry is its title. */
|
|
97010
|
+
static async tooltip(lines, options = {}) {
|
|
97011
|
+
if (!lines.length) return [];
|
|
97012
|
+
const { position = [0, 0], titleGap = 2, lineHeight = 10, shadow = true, ...style } = options;
|
|
97013
|
+
const textOptions = { ...style, lineHeight, shadow };
|
|
97014
|
+
const layouts = await Promise.all(lines.map((line) => layoutGuiText(line, textOptions)));
|
|
97015
|
+
const width = Math.max(...layouts.map((layout) => layout.width));
|
|
97016
|
+
const height = layouts.reduce((sum, layout) => sum + layout.height, 0) - 2 + (lines.length > 1 ? titleGap : 0);
|
|
97017
|
+
const layers = ["background", "frame"].map((part) => ({
|
|
97018
|
+
name: `tooltip-${part}`,
|
|
97019
|
+
texture: `minecraft:gui/sprites/tooltip/${part}`,
|
|
97020
|
+
position: [position[0] - 12, position[1] - 12],
|
|
97021
|
+
size: [width + 24, height + 24]
|
|
97022
|
+
}));
|
|
97023
|
+
let y5 = position[1];
|
|
97024
|
+
lines.forEach((text, index) => {
|
|
97025
|
+
layers.push({ ...textOptions, name: `tooltip-line-${index}`, text, position: [position[0], y5] });
|
|
97026
|
+
y5 += layouts[index].height + (index === 0 ? titleGap : 0);
|
|
97027
|
+
});
|
|
97028
|
+
return layers;
|
|
97029
|
+
}
|
|
96793
97030
|
static inventorySlot(slot, origin = [0, 0], offset = [18, 18], rowSize = 9) {
|
|
96794
97031
|
const [column, row] = typeof slot === "number" ? [slot % rowSize, Math.floor(slot / rowSize)] : slot;
|
|
96795
97032
|
return [origin[0] + column * offset[0], origin[1] + row * offset[1]];
|
|
@@ -96858,6 +97095,88 @@ property list uchar int vertex_index
|
|
|
96858
97095
|
init_buffer2();
|
|
96859
97096
|
init_process2();
|
|
96860
97097
|
|
|
97098
|
+
// src/gui/GuiTextureGeometry.ts
|
|
97099
|
+
init_dirname();
|
|
97100
|
+
init_buffer2();
|
|
97101
|
+
init_process2();
|
|
97102
|
+
init_three_module();
|
|
97103
|
+
function createGuiTextureGeometry(width, height, imageWidth, imageHeight, crop, scaling) {
|
|
97104
|
+
if (crop || !scaling || scaling.type === "stretch") {
|
|
97105
|
+
const [x4, y5, w4, h5] = crop ?? [0, 0, imageWidth, imageHeight];
|
|
97106
|
+
const geometry = new PlaneGeometry(width, height);
|
|
97107
|
+
const uv = geometry.getAttribute("uv");
|
|
97108
|
+
for (let i4 = 0; i4 < uv.count; i4++) {
|
|
97109
|
+
uv.setXY(
|
|
97110
|
+
i4,
|
|
97111
|
+
(x4 + uv.getX(i4) * w4) / imageWidth,
|
|
97112
|
+
1 - (y5 + (1 - uv.getY(i4)) * h5) / imageHeight
|
|
97113
|
+
);
|
|
97114
|
+
}
|
|
97115
|
+
return geometry;
|
|
97116
|
+
}
|
|
97117
|
+
const sw = scaling.width, sh = scaling.height;
|
|
97118
|
+
if (![sw, sh].every((value) => Number.isInteger(value) && value > 0)) {
|
|
97119
|
+
throw new Error("GUI sprite dimensions must be positive integers");
|
|
97120
|
+
}
|
|
97121
|
+
if (![width, height].every((value) => Number.isFinite(value) && value >= 0)) {
|
|
97122
|
+
throw new Error("GUI output dimensions must be finite and nonnegative");
|
|
97123
|
+
}
|
|
97124
|
+
const positions = [], uvs = [], normals = [], indices = [];
|
|
97125
|
+
function quad(x4, y5, w4, h5, u4, v5, uw, vh) {
|
|
97126
|
+
if (w4 <= 0 || h5 <= 0) return;
|
|
97127
|
+
const index = positions.length / 3;
|
|
97128
|
+
const left = x4 - width / 2, top = height / 2 - y5;
|
|
97129
|
+
positions.push(left, top, 0, left + w4, top, 0, left, top - h5, 0, left + w4, top - h5, 0);
|
|
97130
|
+
uvs.push(
|
|
97131
|
+
u4 / sw,
|
|
97132
|
+
1 - v5 / sh,
|
|
97133
|
+
(u4 + uw) / sw,
|
|
97134
|
+
1 - v5 / sh,
|
|
97135
|
+
u4 / sw,
|
|
97136
|
+
1 - (v5 + vh) / sh,
|
|
97137
|
+
(u4 + uw) / sw,
|
|
97138
|
+
1 - (v5 + vh) / sh
|
|
97139
|
+
);
|
|
97140
|
+
normals.push(0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1);
|
|
97141
|
+
indices.push(index, index + 2, index + 1, index + 2, index + 3, index + 1);
|
|
97142
|
+
}
|
|
97143
|
+
function tile(x4, y5, w4, h5, u4, v5, tw, th) {
|
|
97144
|
+
for (let dy = 0; dy < h5; dy += th) {
|
|
97145
|
+
for (let dx = 0; dx < w4; dx += tw) {
|
|
97146
|
+
const cw = Math.min(tw, w4 - dx), ch = Math.min(th, h5 - dy);
|
|
97147
|
+
quad(x4 + dx, y5 + dy, cw, ch, u4, v5, cw, ch);
|
|
97148
|
+
}
|
|
97149
|
+
}
|
|
97150
|
+
}
|
|
97151
|
+
if (scaling.type === "tile") {
|
|
97152
|
+
tile(0, 0, width, height, 0, 0, sw, sh);
|
|
97153
|
+
} else {
|
|
97154
|
+
let segments = function(size, sourceSize, start, end) {
|
|
97155
|
+
if (size === sourceSize) return [[0, size, 0, sourceSize]];
|
|
97156
|
+
start = Math.min(start, Math.floor(size / 2));
|
|
97157
|
+
end = Math.min(end, Math.floor(size / 2));
|
|
97158
|
+
return [
|
|
97159
|
+
[0, start, 0, start],
|
|
97160
|
+
[start, size - start - end, start, sourceSize - start - end],
|
|
97161
|
+
[size - end, end, sourceSize - end, end]
|
|
97162
|
+
];
|
|
97163
|
+
};
|
|
97164
|
+
const border2 = typeof scaling.border === "number" ? { left: scaling.border, top: scaling.border, right: scaling.border, bottom: scaling.border } : scaling.border;
|
|
97165
|
+
if (!border2 || typeof scaling.border === "number" && scaling.border <= 0 || ![border2.left, border2.top, border2.right, border2.bottom].every((value) => Number.isInteger(value) && value >= 0) || border2.left + border2.right >= sw || border2.top + border2.bottom >= sh) {
|
|
97166
|
+
throw new Error("GUI nine-slice borders must be nonnegative integers with a nonempty center");
|
|
97167
|
+
}
|
|
97168
|
+
const columns = segments(width, sw, border2.left, border2.right);
|
|
97169
|
+
const rows = segments(height, sh, border2.top, border2.bottom);
|
|
97170
|
+
for (const [y5, h5, v5, vh] of rows) {
|
|
97171
|
+
for (const [x4, w4, u4, uw] of columns) {
|
|
97172
|
+
if (w4 <= 0 || h5 <= 0) continue;
|
|
97173
|
+
(scaling.stretch_inner ? quad : tile)(x4, y5, w4, h5, u4, v5, uw, vh);
|
|
97174
|
+
}
|
|
97175
|
+
}
|
|
97176
|
+
}
|
|
97177
|
+
return new BufferGeometry().setAttribute("position", new Float32BufferAttribute(positions, 3)).setAttribute("normal", new Float32BufferAttribute(normals, 3)).setAttribute("uv", new Float32BufferAttribute(uvs, 2)).setIndex(indices);
|
|
97178
|
+
}
|
|
97179
|
+
|
|
96861
97180
|
// src/gui/scene/index.ts
|
|
96862
97181
|
init_dirname();
|
|
96863
97182
|
init_buffer2();
|
|
@@ -96886,6 +97205,7 @@ property list uchar int vertex_index
|
|
|
96886
97205
|
this.bounds = new Box2();
|
|
96887
97206
|
this.geometries = /* @__PURE__ */ new Set();
|
|
96888
97207
|
this.ownedMaterials = /* @__PURE__ */ new Set();
|
|
97208
|
+
this.textMaterials = /* @__PURE__ */ new Map();
|
|
96889
97209
|
this.initialized = false;
|
|
96890
97210
|
}
|
|
96891
97211
|
async init() {
|
|
@@ -96894,6 +97214,43 @@ property list uchar int vertex_index
|
|
|
96894
97214
|
let depth = 0;
|
|
96895
97215
|
for (const [index, layer] of this.textureLayers.entries()) {
|
|
96896
97216
|
const [x4, y5] = layer.position ?? [0, 0];
|
|
97217
|
+
if ("text" in layer) {
|
|
97218
|
+
const layout = await layoutGuiText(layer.text, layer);
|
|
97219
|
+
const group = new Group();
|
|
97220
|
+
group.name = `group:${layer.name ?? index}`;
|
|
97221
|
+
group.position.set(x4, -y5, depth);
|
|
97222
|
+
const [width2, height2] = layer.size ?? [layout.width, layout.height];
|
|
97223
|
+
group.scale.set(layout.width ? width2 / layout.width : 1, height2 / layout.height, 1);
|
|
97224
|
+
this.add(group);
|
|
97225
|
+
const parts = createGuiTextGeometry(layout, layer.shadow);
|
|
97226
|
+
const bounds = new Box3();
|
|
97227
|
+
for (const [partIndex, { image: image2, geometry: geometry2 }] of parts.entries()) {
|
|
97228
|
+
this.geometries.add(geometry2);
|
|
97229
|
+
geometry2.computeBoundingBox();
|
|
97230
|
+
bounds.union(geometry2.boundingBox);
|
|
97231
|
+
let material2 = this.textMaterials.get(image2);
|
|
97232
|
+
if (!material2) {
|
|
97233
|
+
material2 = image2 ? Materials.createGuiCanvasMaterial(image2) : new MeshBasicMaterial({ transparent: true, depthWrite: false, side: DoubleSide, toneMapped: false });
|
|
97234
|
+
material2.vertexColors = true;
|
|
97235
|
+
this.textMaterials.set(image2, material2);
|
|
97236
|
+
this.ownedMaterials.add(material2);
|
|
97237
|
+
}
|
|
97238
|
+
const mesh2 = new Mesh(geometry2, material2);
|
|
97239
|
+
mesh2.name = `mesh:${layer.name ?? index}:${partIndex}`;
|
|
97240
|
+
mesh2.renderOrder = index + partIndex / (parts.length + 1) * 0.5;
|
|
97241
|
+
group.add(mesh2);
|
|
97242
|
+
}
|
|
97243
|
+
group.updateMatrix();
|
|
97244
|
+
bounds.applyMatrix4(group.matrix);
|
|
97245
|
+
this.bounds.expandByPoint(new Vector2(x4, y5));
|
|
97246
|
+
this.bounds.expandByPoint(new Vector2(x4 + width2, y5 + height2));
|
|
97247
|
+
if (!bounds.isEmpty()) {
|
|
97248
|
+
this.bounds.expandByPoint(new Vector2(bounds.min.x, -bounds.max.y));
|
|
97249
|
+
this.bounds.expandByPoint(new Vector2(bounds.max.x, -bounds.min.y));
|
|
97250
|
+
}
|
|
97251
|
+
depth += 0.01;
|
|
97252
|
+
continue;
|
|
97253
|
+
}
|
|
96897
97254
|
if ("item" in layer) {
|
|
96898
97255
|
const [width2, height2] = layer.size ?? [16, 16];
|
|
96899
97256
|
const item = await this.createItem(layer, index);
|
|
@@ -96917,18 +97274,10 @@ property list uchar int vertex_index
|
|
|
96917
97274
|
const key = typeof layer.texture === "string" ? AssetKey.parse("textures", layer.texture) : layer.texture;
|
|
96918
97275
|
const material = await this.loadMaterial(key);
|
|
96919
97276
|
const image = material.map.image;
|
|
96920
|
-
const
|
|
96921
|
-
const [width, height] = layer.size ?? [
|
|
96922
|
-
const geometry =
|
|
97277
|
+
const scaling = layer.crop ? void 0 : (await ModelTextures.getMeta(key))?.gui?.scaling;
|
|
97278
|
+
const [width, height] = layer.size ?? (layer.crop ? layer.crop.slice(2) : scaling && scaling.type !== "stretch" ? [scaling.width, scaling.height] : [image.width, image.height]);
|
|
97279
|
+
const geometry = createGuiTextureGeometry(width, height, image.width, image.height, layer.crop, scaling);
|
|
96923
97280
|
this.geometries.add(geometry);
|
|
96924
|
-
const uv = geometry.getAttribute("uv");
|
|
96925
|
-
for (let i4 = 0; i4 < uv.count; i4++) {
|
|
96926
|
-
uv.setXY(
|
|
96927
|
-
i4,
|
|
96928
|
-
(cropX + uv.getX(i4) * cropWidth) / image.width,
|
|
96929
|
-
1 - (cropY + (1 - uv.getY(i4)) * cropHeight) / image.height
|
|
96930
|
-
);
|
|
96931
|
-
}
|
|
96932
97281
|
const mesh = new Mesh(geometry, material);
|
|
96933
97282
|
mesh.name = `mesh:${layer.name ?? index}`;
|
|
96934
97283
|
mesh.position.set(x4 + width / 2, -y5 - height / 2, depth);
|
|
@@ -96993,10 +97342,11 @@ property list uchar int vertex_index
|
|
|
96993
97342
|
for (const geometry of this.geometries) geometry.dispose();
|
|
96994
97343
|
this.geometries.clear();
|
|
96995
97344
|
for (const material of this.ownedMaterials) {
|
|
96996
|
-
material.map
|
|
97345
|
+
material.map?.dispose();
|
|
96997
97346
|
material.dispose();
|
|
96998
97347
|
}
|
|
96999
97348
|
this.ownedMaterials.clear();
|
|
97349
|
+
this.textMaterials.clear();
|
|
97000
97350
|
this.bounds.makeEmpty();
|
|
97001
97351
|
this.initialized = false;
|
|
97002
97352
|
super.disposeAndRemoveAllChildren();
|