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/node/index.mjs
CHANGED
|
@@ -296,6 +296,9 @@ var init_Caching = __esm({
|
|
|
296
296
|
static {
|
|
297
297
|
this.blockEntityIndexCache = _Caching.createAssetCache();
|
|
298
298
|
}
|
|
299
|
+
static {
|
|
300
|
+
this.fontCache = _Caching.createAssetCache();
|
|
301
|
+
}
|
|
299
302
|
static createAssetCache() {
|
|
300
303
|
return Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
|
|
301
304
|
}
|
|
@@ -322,7 +325,8 @@ var init_Caching = __esm({
|
|
|
322
325
|
this.entityModelCache,
|
|
323
326
|
this.entityTextureCache,
|
|
324
327
|
this.entityAnimationCache,
|
|
325
|
-
this.blockEntityIndexCache
|
|
328
|
+
this.blockEntityIndexCache,
|
|
329
|
+
this.fontCache
|
|
326
330
|
];
|
|
327
331
|
}
|
|
328
332
|
static clear() {
|
|
@@ -4335,8 +4339,8 @@ var init_EntityObject = __esm({
|
|
|
4335
4339
|
// src/three/BufferGeometryUtils.js
|
|
4336
4340
|
import {
|
|
4337
4341
|
BufferAttribute as BufferAttribute4,
|
|
4338
|
-
BufferGeometry as
|
|
4339
|
-
Float32BufferAttribute as
|
|
4342
|
+
BufferGeometry as BufferGeometry4,
|
|
4343
|
+
Float32BufferAttribute as Float32BufferAttribute6,
|
|
4340
4344
|
InterleavedBuffer,
|
|
4341
4345
|
InterleavedBufferAttribute,
|
|
4342
4346
|
TriangleFanDrawMode,
|
|
@@ -4355,7 +4359,7 @@ function mergeBufferGeometries(geometries, useGroups = false) {
|
|
|
4355
4359
|
const attributes = {};
|
|
4356
4360
|
const morphAttributes = {};
|
|
4357
4361
|
const morphTargetsRelative = geometries[0].morphTargetsRelative;
|
|
4358
|
-
const mergedGeometry = new
|
|
4362
|
+
const mergedGeometry = new BufferGeometry4();
|
|
4359
4363
|
let offset = 0;
|
|
4360
4364
|
for (let i = 0; i < geometries.length; ++i) {
|
|
4361
4365
|
const geometry = geometries[i];
|
|
@@ -4864,8 +4868,8 @@ function computeMorphedAttributes(object) {
|
|
|
4864
4868
|
}
|
|
4865
4869
|
}
|
|
4866
4870
|
}
|
|
4867
|
-
const morphedPositionAttribute = new
|
|
4868
|
-
const morphedNormalAttribute = new
|
|
4871
|
+
const morphedPositionAttribute = new Float32BufferAttribute6(modifiedPosition, 3);
|
|
4872
|
+
const morphedNormalAttribute = new Float32BufferAttribute6(modifiedNormal, 3);
|
|
4869
4873
|
return {
|
|
4870
4874
|
positionAttribute,
|
|
4871
4875
|
normalAttribute,
|
|
@@ -5115,7 +5119,7 @@ var init_ItemTints = __esm({
|
|
|
5115
5119
|
});
|
|
5116
5120
|
|
|
5117
5121
|
// src/model/scene/ModelObject.ts
|
|
5118
|
-
import { BoxGeometry as BoxGeometry5, BufferAttribute as BufferAttribute5, Color as
|
|
5122
|
+
import { BoxGeometry as BoxGeometry5, BufferAttribute as BufferAttribute5, Color as Color9, Euler as Euler7, Matrix4 as Matrix49 } from "three";
|
|
5119
5123
|
function isModelObject(obj) {
|
|
5120
5124
|
return obj.isModelObject;
|
|
5121
5125
|
}
|
|
@@ -5232,7 +5236,7 @@ var init_ModelObject = __esm({
|
|
|
5232
5236
|
if (tintIndex === void 0 || tintIndex < 0) continue;
|
|
5233
5237
|
const tint = this.options.tints[tintIndex];
|
|
5234
5238
|
if (tint === void 0) continue;
|
|
5235
|
-
const color = new
|
|
5239
|
+
const color = new Color9(tint);
|
|
5236
5240
|
for (let vertex = 0; vertex < 4; vertex++) {
|
|
5237
5241
|
color.toArray(colors, (faceIndex * 4 + vertex) * 3);
|
|
5238
5242
|
}
|
|
@@ -5359,7 +5363,7 @@ var init_fluidBlocks = __esm({
|
|
|
5359
5363
|
});
|
|
5360
5364
|
|
|
5361
5365
|
// src/model/fluid/FluidGeometry.ts
|
|
5362
|
-
import { BufferGeometry as
|
|
5366
|
+
import { BufferGeometry as BufferGeometry6, Float32BufferAttribute as Float32BufferAttribute7 } from "three";
|
|
5363
5367
|
function getBlockFluidState(key, state) {
|
|
5364
5368
|
const rule = key && fluidRules[key.toNamespacedString()];
|
|
5365
5369
|
if (rule) return {
|
|
@@ -5377,7 +5381,7 @@ function ownHeight(sample) {
|
|
|
5377
5381
|
return (level === 0 || level >= 8 ? 8 : 8 - level) / 9;
|
|
5378
5382
|
}
|
|
5379
5383
|
function createFluidGeometry(kind, sample) {
|
|
5380
|
-
const geometry = new
|
|
5384
|
+
const geometry = new BufferGeometry6();
|
|
5381
5385
|
const positions = [], normals = [], uvs = [], indices = [];
|
|
5382
5386
|
const self = sample(0, 0, 0);
|
|
5383
5387
|
const height = (x, z) => {
|
|
@@ -5476,9 +5480,9 @@ function createFluidGeometry(kind, sample) {
|
|
|
5476
5480
|
1
|
|
5477
5481
|
);
|
|
5478
5482
|
}
|
|
5479
|
-
geometry.setAttribute("position", new
|
|
5480
|
-
geometry.setAttribute("normal", new
|
|
5481
|
-
geometry.setAttribute("uv", new
|
|
5483
|
+
geometry.setAttribute("position", new Float32BufferAttribute7(positions, 3));
|
|
5484
|
+
geometry.setAttribute("normal", new Float32BufferAttribute7(normals, 3));
|
|
5485
|
+
geometry.setAttribute("uv", new Float32BufferAttribute7(uvs, 2));
|
|
5482
5486
|
geometry.setIndex(indices);
|
|
5483
5487
|
return geometry;
|
|
5484
5488
|
}
|
|
@@ -5498,7 +5502,7 @@ __export(FluidModelObject_exports, {
|
|
|
5498
5502
|
FluidModelObject: () => FluidModelObject,
|
|
5499
5503
|
sampleFluid: () => sampleFluid
|
|
5500
5504
|
});
|
|
5501
|
-
import { BufferAttribute as BufferAttribute6, Color as
|
|
5505
|
+
import { BufferAttribute as BufferAttribute6, Color as Color10, DoubleSide as DoubleSide4 } from "three";
|
|
5502
5506
|
function sampleFluid(kind, sample) {
|
|
5503
5507
|
const cells = [];
|
|
5504
5508
|
const key = [];
|
|
@@ -5549,7 +5553,7 @@ var init_FluidModelObject = __esm({
|
|
|
5549
5553
|
}
|
|
5550
5554
|
}
|
|
5551
5555
|
geometry.clearGroups();
|
|
5552
|
-
const color = new
|
|
5556
|
+
const color = new Color10(this.options.tints?.[0] ?? (this.kind === "water" ? 4159204 : 16777215));
|
|
5553
5557
|
const colors = new Float32Array(geometry.getAttribute("position").count * 3);
|
|
5554
5558
|
for (let i = 0; i < colors.length; i += 3) color.toArray(colors, i);
|
|
5555
5559
|
geometry.setAttribute("color", new BufferAttribute6(colors, 3));
|
|
@@ -5566,7 +5570,7 @@ var init_FluidModelObject = __esm({
|
|
|
5566
5570
|
super.applyTextures();
|
|
5567
5571
|
this.iterateAllMeshes((mesh) => {
|
|
5568
5572
|
const material = mesh.material;
|
|
5569
|
-
material.side =
|
|
5573
|
+
material.side = DoubleSide4;
|
|
5570
5574
|
material.forceSinglePass = true;
|
|
5571
5575
|
material.depthWrite = !material.transparent;
|
|
5572
5576
|
});
|
|
@@ -5782,6 +5786,101 @@ var BlockEntities = class {
|
|
|
5782
5786
|
// src/assets/index.ts
|
|
5783
5787
|
init_BlockStates();
|
|
5784
5788
|
init_Entities();
|
|
5789
|
+
|
|
5790
|
+
// src/assets/Fonts.ts
|
|
5791
|
+
init_AssetKey();
|
|
5792
|
+
init_AssetLoader();
|
|
5793
|
+
init_AssetParsers();
|
|
5794
|
+
init_ModelTextures();
|
|
5795
|
+
init_Caching();
|
|
5796
|
+
var Fonts = class {
|
|
5797
|
+
static async get(key = "minecraft:default") {
|
|
5798
|
+
const fontKey = typeof key === "string" ? AssetKey.parse("font", key) : key;
|
|
5799
|
+
return await Caching.fontCache.get(fontKey.serialize(), () => this.load(fontKey, []));
|
|
5800
|
+
}
|
|
5801
|
+
static relatedKey(assetType, id, origin) {
|
|
5802
|
+
const key = AssetKey.parse(assetType, id);
|
|
5803
|
+
key.root = origin.root;
|
|
5804
|
+
return key;
|
|
5805
|
+
}
|
|
5806
|
+
static async load(key, parents) {
|
|
5807
|
+
const serialized = key.serialize();
|
|
5808
|
+
if (parents.includes(serialized)) throw new Error(`Cyclic font reference: ${key.toNamespacedString()}`);
|
|
5809
|
+
const stack = await AssetLoader.getAll(key, "json" /* JSON */);
|
|
5810
|
+
if (stack.length === 0) throw new Error(`Could not load font ${key.toNamespacedString()}`);
|
|
5811
|
+
const glyphs = /* @__PURE__ */ new Map();
|
|
5812
|
+
for (const asset of stack) {
|
|
5813
|
+
for (const provider of asset.providers) {
|
|
5814
|
+
if (provider.filter?.uniform || provider.filter?.jp) continue;
|
|
5815
|
+
let provided;
|
|
5816
|
+
switch (provider.type) {
|
|
5817
|
+
case "bitmap":
|
|
5818
|
+
case "minecraft:bitmap":
|
|
5819
|
+
provided = await this.bitmap(provider, key);
|
|
5820
|
+
break;
|
|
5821
|
+
case "space":
|
|
5822
|
+
case "minecraft:space":
|
|
5823
|
+
provided = new Map(Object.entries(provider.advances).map(([character, advance]) => [
|
|
5824
|
+
character,
|
|
5825
|
+
{ x: 0, y: 0, width: 0, height: 0, scale: 1, ascent: 0, advance }
|
|
5826
|
+
]));
|
|
5827
|
+
break;
|
|
5828
|
+
case "reference":
|
|
5829
|
+
case "minecraft:reference":
|
|
5830
|
+
provided = (await this.load(this.relatedKey("font", provider.id, key), [...parents, serialized])).glyphs;
|
|
5831
|
+
break;
|
|
5832
|
+
default:
|
|
5833
|
+
continue;
|
|
5834
|
+
}
|
|
5835
|
+
for (const [character, glyph] of provided) {
|
|
5836
|
+
if (character !== "\0" && !glyphs.has(character)) glyphs.set(character, glyph);
|
|
5837
|
+
}
|
|
5838
|
+
}
|
|
5839
|
+
}
|
|
5840
|
+
return { glyphs };
|
|
5841
|
+
}
|
|
5842
|
+
static async bitmap(provider, fontKey) {
|
|
5843
|
+
const rows = provider.chars.map((row) => [...row]);
|
|
5844
|
+
const columns = rows[0]?.length;
|
|
5845
|
+
if (!columns || rows.some((row) => row.length !== columns)) {
|
|
5846
|
+
throw new Error(`Invalid character grid in font ${fontKey.toNamespacedString()}`);
|
|
5847
|
+
}
|
|
5848
|
+
const key = this.relatedKey("textures", provider.file, fontKey);
|
|
5849
|
+
const image = await ModelTextures.get(key);
|
|
5850
|
+
if (!image) throw new Error(`Could not load font texture ${key.toNamespacedString()}`);
|
|
5851
|
+
const width = Math.floor(image.width / columns), height = Math.floor(image.height / rows.length);
|
|
5852
|
+
if (!width || !height) throw new Error(`Font texture ${key.toNamespacedString()} is smaller than its character grid`);
|
|
5853
|
+
const scale = (provider.height ?? 8) / height;
|
|
5854
|
+
const pixels = image.data.getImageData(0, 0, image.width, image.height).data;
|
|
5855
|
+
const glyphs = /* @__PURE__ */ new Map();
|
|
5856
|
+
rows.forEach((row, rowIndex) => row.forEach((character, columnIndex) => {
|
|
5857
|
+
if (character === "\0") return;
|
|
5858
|
+
const x = columnIndex * width, y = rowIndex * height;
|
|
5859
|
+
let occupiedWidth = 0;
|
|
5860
|
+
for (let column = width - 1; column >= 0 && !occupiedWidth; column--) {
|
|
5861
|
+
for (let row2 = 0; row2 < height; row2++) {
|
|
5862
|
+
if (pixels[((y + row2) * image.width + x + column) * 4 + 3] !== 0) {
|
|
5863
|
+
occupiedWidth = column + 1;
|
|
5864
|
+
break;
|
|
5865
|
+
}
|
|
5866
|
+
}
|
|
5867
|
+
}
|
|
5868
|
+
glyphs.set(character, {
|
|
5869
|
+
image: image.data.canvas,
|
|
5870
|
+
x,
|
|
5871
|
+
y,
|
|
5872
|
+
width,
|
|
5873
|
+
height,
|
|
5874
|
+
scale,
|
|
5875
|
+
ascent: provider.ascent,
|
|
5876
|
+
advance: Math.floor(occupiedWidth * scale + 0.5) + 1
|
|
5877
|
+
});
|
|
5878
|
+
}));
|
|
5879
|
+
return glyphs;
|
|
5880
|
+
}
|
|
5881
|
+
};
|
|
5882
|
+
|
|
5883
|
+
// src/assets/index.ts
|
|
5785
5884
|
init_ModelTextures();
|
|
5786
5885
|
init_Models();
|
|
5787
5886
|
init_source();
|
|
@@ -8780,7 +8879,137 @@ function copyDataTexture(source) {
|
|
|
8780
8879
|
|
|
8781
8880
|
// src/gui/GuiHelper.ts
|
|
8782
8881
|
init_AssetKey();
|
|
8882
|
+
|
|
8883
|
+
// src/gui/GuiText.ts
|
|
8884
|
+
import { BufferGeometry as BufferGeometry2, Color as Color8, Float32BufferAttribute as Float32BufferAttribute4 } from "three";
|
|
8885
|
+
async function layoutGuiText(text, options = {}) {
|
|
8886
|
+
const maxWidth = options.maxWidth ?? Infinity, lineHeight = options.lineHeight ?? 9;
|
|
8887
|
+
if (!(maxWidth > 0) || !Number.isFinite(lineHeight) || lineHeight <= 0) {
|
|
8888
|
+
throw new Error("Text wrap width and line height must be positive");
|
|
8889
|
+
}
|
|
8890
|
+
const font = await Fonts.get(options.font);
|
|
8891
|
+
const runs = typeof text === "string" ? [{ text }] : text;
|
|
8892
|
+
const glyphs = [], lineWidths = [];
|
|
8893
|
+
let line = [], width = 0;
|
|
8894
|
+
let trailingNewline = false;
|
|
8895
|
+
const finishLine = (entries) => {
|
|
8896
|
+
let x = 0;
|
|
8897
|
+
for (const entry of entries) {
|
|
8898
|
+
glyphs.push({ ...entry, x, y: lineWidths.length * lineHeight });
|
|
8899
|
+
x += entry.advance;
|
|
8900
|
+
}
|
|
8901
|
+
lineWidths.push(x);
|
|
8902
|
+
};
|
|
8903
|
+
for (const run of runs) {
|
|
8904
|
+
const style = {
|
|
8905
|
+
color: run.color ?? options.color ?? 16777215,
|
|
8906
|
+
bold: run.bold ?? options.bold ?? false,
|
|
8907
|
+
italic: run.italic ?? options.italic ?? false
|
|
8908
|
+
};
|
|
8909
|
+
for (const character of run.text.replace(/\r\n?/g, "\n")) {
|
|
8910
|
+
trailingNewline = character === "\n";
|
|
8911
|
+
if (character === "\n") {
|
|
8912
|
+
finishLine(line);
|
|
8913
|
+
line = [];
|
|
8914
|
+
width = 0;
|
|
8915
|
+
continue;
|
|
8916
|
+
}
|
|
8917
|
+
const glyph = font.glyphs.get(character);
|
|
8918
|
+
const advance = (glyph?.advance ?? 6) + (style.bold ? 1 : 0);
|
|
8919
|
+
line.push({ character, glyph, advance, style, x: 0, y: 0 });
|
|
8920
|
+
width += advance;
|
|
8921
|
+
while (width > maxWidth && line.length > 1) {
|
|
8922
|
+
let space = -1;
|
|
8923
|
+
for (let i = 0; i < line.length; i++) if (line[i].character === " ") space = i;
|
|
8924
|
+
const split = space >= 0 ? space : line.length - 1;
|
|
8925
|
+
if (split > 0) finishLine(line.slice(0, split));
|
|
8926
|
+
line = line.slice(split + (space >= 0 ? 1 : 0));
|
|
8927
|
+
width = line.reduce((sum, entry) => sum + entry.advance, 0);
|
|
8928
|
+
}
|
|
8929
|
+
}
|
|
8930
|
+
}
|
|
8931
|
+
if (line.length || !lineWidths.length || trailingNewline) finishLine(line);
|
|
8932
|
+
return { glyphs, lineWidths, width: Math.max(0, ...lineWidths), height: lineWidths.length * lineHeight };
|
|
8933
|
+
}
|
|
8934
|
+
function createGuiTextGeometry(layout, shadow = true) {
|
|
8935
|
+
const batches = [];
|
|
8936
|
+
for (const isShadow of shadow ? [true, false] : [false]) {
|
|
8937
|
+
let batch;
|
|
8938
|
+
for (const entry of layout.glyphs) {
|
|
8939
|
+
const { glyph, style } = entry;
|
|
8940
|
+
if (glyph && !glyph.image) continue;
|
|
8941
|
+
if (!batch || batch.image !== glyph?.image) {
|
|
8942
|
+
batch = { image: glyph?.image, positions: [], uvs: [], colors: [], indices: [] };
|
|
8943
|
+
batches.push(batch);
|
|
8944
|
+
}
|
|
8945
|
+
const color = new Color8(isShadow ? (style.color & 16579836) >> 2 : style.color);
|
|
8946
|
+
const offset = isShadow ? 1 : 0;
|
|
8947
|
+
const top = glyph ? 7 - glyph.ascent : 0;
|
|
8948
|
+
const height = glyph ? glyph.height * glyph.scale : 8;
|
|
8949
|
+
const width = glyph ? glyph.width * glyph.scale : 5;
|
|
8950
|
+
const shear = (y) => style.italic ? 1 - 0.25 * y : 0;
|
|
8951
|
+
const quad = (left, upper, right, lower, boldOffset) => {
|
|
8952
|
+
const base = batch.positions.length / 3;
|
|
8953
|
+
const x = entry.x + offset + boldOffset, y = entry.y + offset;
|
|
8954
|
+
batch.positions.push(
|
|
8955
|
+
x + left + shear(upper),
|
|
8956
|
+
-y - upper,
|
|
8957
|
+
0,
|
|
8958
|
+
x + right + shear(upper),
|
|
8959
|
+
-y - upper,
|
|
8960
|
+
0,
|
|
8961
|
+
x + left + shear(lower),
|
|
8962
|
+
-y - lower,
|
|
8963
|
+
0,
|
|
8964
|
+
x + right + shear(lower),
|
|
8965
|
+
-y - lower,
|
|
8966
|
+
0
|
|
8967
|
+
);
|
|
8968
|
+
const u0 = glyph ? glyph.x / glyph.image.width : 0;
|
|
8969
|
+
const u1 = glyph ? (glyph.x + glyph.width) / glyph.image.width : 1;
|
|
8970
|
+
const v0 = glyph ? 1 - glyph.y / glyph.image.height : 1;
|
|
8971
|
+
const v1 = glyph ? 1 - (glyph.y + glyph.height) / glyph.image.height : 0;
|
|
8972
|
+
batch.uvs.push(u0, v0, u1, v0, u0, v1, u1, v1);
|
|
8973
|
+
for (let i = 0; i < 4; i++) batch.colors.push(color.r, color.g, color.b);
|
|
8974
|
+
batch.indices.push(base, base + 2, base + 1, base + 2, base + 3, base + 1);
|
|
8975
|
+
};
|
|
8976
|
+
for (const boldOffset of style.bold ? [0, 1] : [0]) {
|
|
8977
|
+
if (glyph) quad(0, top, width, top + height, boldOffset);
|
|
8978
|
+
else {
|
|
8979
|
+
quad(0, 0, 5, 1, boldOffset);
|
|
8980
|
+
quad(0, 7, 5, 8, boldOffset);
|
|
8981
|
+
quad(0, 1, 1, 7, boldOffset);
|
|
8982
|
+
quad(4, 1, 5, 7, boldOffset);
|
|
8983
|
+
}
|
|
8984
|
+
}
|
|
8985
|
+
}
|
|
8986
|
+
}
|
|
8987
|
+
return batches.map(({ image, positions, uvs, colors, indices }) => ({ image, geometry: new BufferGeometry2().setAttribute("position", new Float32BufferAttribute4(positions, 3)).setAttribute("uv", new Float32BufferAttribute4(uvs, 2)).setAttribute("color", new Float32BufferAttribute4(colors, 3)).setIndex(indices) }));
|
|
8988
|
+
}
|
|
8989
|
+
|
|
8990
|
+
// src/gui/GuiHelper.ts
|
|
8783
8991
|
var GuiHelper = class {
|
|
8992
|
+
/** Sizes a tooltip around supplied text; the first entry is its title. */
|
|
8993
|
+
static async tooltip(lines, options = {}) {
|
|
8994
|
+
if (!lines.length) return [];
|
|
8995
|
+
const { position = [0, 0], titleGap = 2, lineHeight = 10, shadow = true, ...style } = options;
|
|
8996
|
+
const textOptions = { ...style, lineHeight, shadow };
|
|
8997
|
+
const layouts = await Promise.all(lines.map((line) => layoutGuiText(line, textOptions)));
|
|
8998
|
+
const width = Math.max(...layouts.map((layout) => layout.width));
|
|
8999
|
+
const height = layouts.reduce((sum, layout) => sum + layout.height, 0) - 2 + (lines.length > 1 ? titleGap : 0);
|
|
9000
|
+
const layers = ["background", "frame"].map((part) => ({
|
|
9001
|
+
name: `tooltip-${part}`,
|
|
9002
|
+
texture: `minecraft:gui/sprites/tooltip/${part}`,
|
|
9003
|
+
position: [position[0] - 12, position[1] - 12],
|
|
9004
|
+
size: [width + 24, height + 24]
|
|
9005
|
+
}));
|
|
9006
|
+
let y = position[1];
|
|
9007
|
+
lines.forEach((text, index) => {
|
|
9008
|
+
layers.push({ ...textOptions, name: `tooltip-line-${index}`, text, position: [position[0], y] });
|
|
9009
|
+
y += layouts[index].height + (index === 0 ? titleGap : 0);
|
|
9010
|
+
});
|
|
9011
|
+
return layers;
|
|
9012
|
+
}
|
|
8784
9013
|
static inventorySlot(slot, origin = [0, 0], offset = [18, 18], rowSize = 9) {
|
|
8785
9014
|
const [column, row] = typeof slot === "number" ? [slot % rowSize, Math.floor(slot / rowSize)] : slot;
|
|
8786
9015
|
return [origin[0] + column * offset[0], origin[1] + row * offset[1]];
|
|
@@ -8844,6 +9073,85 @@ var GuiHelper = class {
|
|
|
8844
9073
|
}
|
|
8845
9074
|
};
|
|
8846
9075
|
|
|
9076
|
+
// src/gui/GuiTextureGeometry.ts
|
|
9077
|
+
import { BufferGeometry as BufferGeometry3, Float32BufferAttribute as Float32BufferAttribute5, PlaneGeometry } from "three";
|
|
9078
|
+
function createGuiTextureGeometry(width, height, imageWidth, imageHeight, crop, scaling) {
|
|
9079
|
+
if (crop || !scaling || scaling.type === "stretch") {
|
|
9080
|
+
const [x, y, w, h] = crop ?? [0, 0, imageWidth, imageHeight];
|
|
9081
|
+
const geometry = new PlaneGeometry(width, height);
|
|
9082
|
+
const uv = geometry.getAttribute("uv");
|
|
9083
|
+
for (let i = 0; i < uv.count; i++) {
|
|
9084
|
+
uv.setXY(
|
|
9085
|
+
i,
|
|
9086
|
+
(x + uv.getX(i) * w) / imageWidth,
|
|
9087
|
+
1 - (y + (1 - uv.getY(i)) * h) / imageHeight
|
|
9088
|
+
);
|
|
9089
|
+
}
|
|
9090
|
+
return geometry;
|
|
9091
|
+
}
|
|
9092
|
+
const sw = scaling.width, sh = scaling.height;
|
|
9093
|
+
if (![sw, sh].every((value) => Number.isInteger(value) && value > 0)) {
|
|
9094
|
+
throw new Error("GUI sprite dimensions must be positive integers");
|
|
9095
|
+
}
|
|
9096
|
+
if (![width, height].every((value) => Number.isFinite(value) && value >= 0)) {
|
|
9097
|
+
throw new Error("GUI output dimensions must be finite and nonnegative");
|
|
9098
|
+
}
|
|
9099
|
+
const positions = [], uvs = [], normals = [], indices = [];
|
|
9100
|
+
function quad(x, y, w, h, u, v, uw, vh) {
|
|
9101
|
+
if (w <= 0 || h <= 0) return;
|
|
9102
|
+
const index = positions.length / 3;
|
|
9103
|
+
const left = x - width / 2, top = height / 2 - y;
|
|
9104
|
+
positions.push(left, top, 0, left + w, top, 0, left, top - h, 0, left + w, top - h, 0);
|
|
9105
|
+
uvs.push(
|
|
9106
|
+
u / sw,
|
|
9107
|
+
1 - v / sh,
|
|
9108
|
+
(u + uw) / sw,
|
|
9109
|
+
1 - v / sh,
|
|
9110
|
+
u / sw,
|
|
9111
|
+
1 - (v + vh) / sh,
|
|
9112
|
+
(u + uw) / sw,
|
|
9113
|
+
1 - (v + vh) / sh
|
|
9114
|
+
);
|
|
9115
|
+
normals.push(0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1);
|
|
9116
|
+
indices.push(index, index + 2, index + 1, index + 2, index + 3, index + 1);
|
|
9117
|
+
}
|
|
9118
|
+
function tile(x, y, w, h, u, v, tw, th) {
|
|
9119
|
+
for (let dy = 0; dy < h; dy += th) {
|
|
9120
|
+
for (let dx = 0; dx < w; dx += tw) {
|
|
9121
|
+
const cw = Math.min(tw, w - dx), ch = Math.min(th, h - dy);
|
|
9122
|
+
quad(x + dx, y + dy, cw, ch, u, v, cw, ch);
|
|
9123
|
+
}
|
|
9124
|
+
}
|
|
9125
|
+
}
|
|
9126
|
+
if (scaling.type === "tile") {
|
|
9127
|
+
tile(0, 0, width, height, 0, 0, sw, sh);
|
|
9128
|
+
} else {
|
|
9129
|
+
let segments = function(size, sourceSize, start, end) {
|
|
9130
|
+
if (size === sourceSize) return [[0, size, 0, sourceSize]];
|
|
9131
|
+
start = Math.min(start, Math.floor(size / 2));
|
|
9132
|
+
end = Math.min(end, Math.floor(size / 2));
|
|
9133
|
+
return [
|
|
9134
|
+
[0, start, 0, start],
|
|
9135
|
+
[start, size - start - end, start, sourceSize - start - end],
|
|
9136
|
+
[size - end, end, sourceSize - end, end]
|
|
9137
|
+
];
|
|
9138
|
+
};
|
|
9139
|
+
const border = typeof scaling.border === "number" ? { left: scaling.border, top: scaling.border, right: scaling.border, bottom: scaling.border } : scaling.border;
|
|
9140
|
+
if (!border || typeof scaling.border === "number" && scaling.border <= 0 || ![border.left, border.top, border.right, border.bottom].every((value) => Number.isInteger(value) && value >= 0) || border.left + border.right >= sw || border.top + border.bottom >= sh) {
|
|
9141
|
+
throw new Error("GUI nine-slice borders must be nonnegative integers with a nonempty center");
|
|
9142
|
+
}
|
|
9143
|
+
const columns = segments(width, sw, border.left, border.right);
|
|
9144
|
+
const rows = segments(height, sh, border.top, border.bottom);
|
|
9145
|
+
for (const [y, h, v, vh] of rows) {
|
|
9146
|
+
for (const [x, w, u, uw] of columns) {
|
|
9147
|
+
if (w <= 0 || h <= 0) continue;
|
|
9148
|
+
(scaling.stretch_inner ? quad : tile)(x, y, w, h, u, v, uw, vh);
|
|
9149
|
+
}
|
|
9150
|
+
}
|
|
9151
|
+
}
|
|
9152
|
+
return new BufferGeometry3().setAttribute("position", new Float32BufferAttribute5(positions, 3)).setAttribute("normal", new Float32BufferAttribute5(normals, 3)).setAttribute("uv", new Float32BufferAttribute5(uvs, 2)).setIndex(indices);
|
|
9153
|
+
}
|
|
9154
|
+
|
|
8847
9155
|
// src/gui/scene/GuiObject.ts
|
|
8848
9156
|
init_AssetKey();
|
|
8849
9157
|
init_ModelTextures();
|
|
@@ -8854,7 +9162,7 @@ init_Materials();
|
|
|
8854
9162
|
init_ModelObject();
|
|
8855
9163
|
init_DisplayPosition();
|
|
8856
9164
|
init_GuiLight();
|
|
8857
|
-
import { Box2, Box3 as Box32, Matrix4 as Matrix410, Mesh as Mesh6,
|
|
9165
|
+
import { Box2, Box3 as Box32, DoubleSide as DoubleSide3, Group, Matrix4 as Matrix410, Mesh as Mesh6, MeshBasicMaterial as MeshBasicMaterial5, Vector2 as Vector23 } from "three";
|
|
8858
9166
|
var GuiObject = class extends SceneObject {
|
|
8859
9167
|
constructor(textureLayers, options) {
|
|
8860
9168
|
super({ ...options, instanceMeshes: false, mergeMeshes: false });
|
|
@@ -8864,6 +9172,7 @@ var GuiObject = class extends SceneObject {
|
|
|
8864
9172
|
this.bounds = new Box2();
|
|
8865
9173
|
this.geometries = /* @__PURE__ */ new Set();
|
|
8866
9174
|
this.ownedMaterials = /* @__PURE__ */ new Set();
|
|
9175
|
+
this.textMaterials = /* @__PURE__ */ new Map();
|
|
8867
9176
|
this.initialized = false;
|
|
8868
9177
|
}
|
|
8869
9178
|
async init() {
|
|
@@ -8872,6 +9181,43 @@ var GuiObject = class extends SceneObject {
|
|
|
8872
9181
|
let depth = 0;
|
|
8873
9182
|
for (const [index, layer] of this.textureLayers.entries()) {
|
|
8874
9183
|
const [x, y] = layer.position ?? [0, 0];
|
|
9184
|
+
if ("text" in layer) {
|
|
9185
|
+
const layout = await layoutGuiText(layer.text, layer);
|
|
9186
|
+
const group = new Group();
|
|
9187
|
+
group.name = `group:${layer.name ?? index}`;
|
|
9188
|
+
group.position.set(x, -y, depth);
|
|
9189
|
+
const [width2, height2] = layer.size ?? [layout.width, layout.height];
|
|
9190
|
+
group.scale.set(layout.width ? width2 / layout.width : 1, height2 / layout.height, 1);
|
|
9191
|
+
this.add(group);
|
|
9192
|
+
const parts = createGuiTextGeometry(layout, layer.shadow);
|
|
9193
|
+
const bounds = new Box32();
|
|
9194
|
+
for (const [partIndex, { image: image2, geometry: geometry2 }] of parts.entries()) {
|
|
9195
|
+
this.geometries.add(geometry2);
|
|
9196
|
+
geometry2.computeBoundingBox();
|
|
9197
|
+
bounds.union(geometry2.boundingBox);
|
|
9198
|
+
let material2 = this.textMaterials.get(image2);
|
|
9199
|
+
if (!material2) {
|
|
9200
|
+
material2 = image2 ? Materials.createGuiCanvasMaterial(image2) : new MeshBasicMaterial5({ transparent: true, depthWrite: false, side: DoubleSide3, toneMapped: false });
|
|
9201
|
+
material2.vertexColors = true;
|
|
9202
|
+
this.textMaterials.set(image2, material2);
|
|
9203
|
+
this.ownedMaterials.add(material2);
|
|
9204
|
+
}
|
|
9205
|
+
const mesh2 = new Mesh6(geometry2, material2);
|
|
9206
|
+
mesh2.name = `mesh:${layer.name ?? index}:${partIndex}`;
|
|
9207
|
+
mesh2.renderOrder = index + partIndex / (parts.length + 1) * 0.5;
|
|
9208
|
+
group.add(mesh2);
|
|
9209
|
+
}
|
|
9210
|
+
group.updateMatrix();
|
|
9211
|
+
bounds.applyMatrix4(group.matrix);
|
|
9212
|
+
this.bounds.expandByPoint(new Vector23(x, y));
|
|
9213
|
+
this.bounds.expandByPoint(new Vector23(x + width2, y + height2));
|
|
9214
|
+
if (!bounds.isEmpty()) {
|
|
9215
|
+
this.bounds.expandByPoint(new Vector23(bounds.min.x, -bounds.max.y));
|
|
9216
|
+
this.bounds.expandByPoint(new Vector23(bounds.max.x, -bounds.min.y));
|
|
9217
|
+
}
|
|
9218
|
+
depth += 0.01;
|
|
9219
|
+
continue;
|
|
9220
|
+
}
|
|
8875
9221
|
if ("item" in layer) {
|
|
8876
9222
|
const [width2, height2] = layer.size ?? [16, 16];
|
|
8877
9223
|
const item = await this.createItem(layer, index);
|
|
@@ -8895,18 +9241,10 @@ var GuiObject = class extends SceneObject {
|
|
|
8895
9241
|
const key = typeof layer.texture === "string" ? AssetKey.parse("textures", layer.texture) : layer.texture;
|
|
8896
9242
|
const material = await this.loadMaterial(key);
|
|
8897
9243
|
const image = material.map.image;
|
|
8898
|
-
const
|
|
8899
|
-
const [width, height] = layer.size ?? [
|
|
8900
|
-
const geometry =
|
|
9244
|
+
const scaling = layer.crop ? void 0 : (await ModelTextures.getMeta(key))?.gui?.scaling;
|
|
9245
|
+
const [width, height] = layer.size ?? (layer.crop ? layer.crop.slice(2) : scaling && scaling.type !== "stretch" ? [scaling.width, scaling.height] : [image.width, image.height]);
|
|
9246
|
+
const geometry = createGuiTextureGeometry(width, height, image.width, image.height, layer.crop, scaling);
|
|
8901
9247
|
this.geometries.add(geometry);
|
|
8902
|
-
const uv = geometry.getAttribute("uv");
|
|
8903
|
-
for (let i = 0; i < uv.count; i++) {
|
|
8904
|
-
uv.setXY(
|
|
8905
|
-
i,
|
|
8906
|
-
(cropX + uv.getX(i) * cropWidth) / image.width,
|
|
8907
|
-
1 - (cropY + (1 - uv.getY(i)) * cropHeight) / image.height
|
|
8908
|
-
);
|
|
8909
|
-
}
|
|
8910
9248
|
const mesh = new Mesh6(geometry, material);
|
|
8911
9249
|
mesh.name = `mesh:${layer.name ?? index}`;
|
|
8912
9250
|
mesh.position.set(x + width / 2, -y - height / 2, depth);
|
|
@@ -8971,10 +9309,11 @@ var GuiObject = class extends SceneObject {
|
|
|
8971
9309
|
for (const geometry of this.geometries) geometry.dispose();
|
|
8972
9310
|
this.geometries.clear();
|
|
8973
9311
|
for (const material of this.ownedMaterials) {
|
|
8974
|
-
material.map
|
|
9312
|
+
material.map?.dispose();
|
|
8975
9313
|
material.dispose();
|
|
8976
9314
|
}
|
|
8977
9315
|
this.ownedMaterials.clear();
|
|
9316
|
+
this.textMaterials.clear();
|
|
8978
9317
|
this.bounds.makeEmpty();
|
|
8979
9318
|
this.initialized = false;
|
|
8980
9319
|
super.disposeAndRemoveAllChildren();
|
|
@@ -12541,7 +12880,7 @@ init_util();
|
|
|
12541
12880
|
init_Caching();
|
|
12542
12881
|
init_CacheKey();
|
|
12543
12882
|
init_MineRenderError();
|
|
12544
|
-
import { DataTexture as DataTexture2, DoubleSide as
|
|
12883
|
+
import { DataTexture as DataTexture2, DoubleSide as DoubleSide5, FrontSide as FrontSide2, MeshBasicMaterial as MeshBasicMaterial6, SRGBColorSpace as SRGBColorSpace6 } from "three";
|
|
12545
12884
|
|
|
12546
12885
|
// src/skin/SkinImage.ts
|
|
12547
12886
|
init_Caching();
|
|
@@ -12626,7 +12965,7 @@ var SkinTextures = class {
|
|
|
12626
12965
|
texture.colorSpace = SRGBColorSpace6;
|
|
12627
12966
|
texture.flipY = true;
|
|
12628
12967
|
texture.needsUpdate = true;
|
|
12629
|
-
return new MeshBasicMaterial6({ map: texture, transparent, side: transparent ?
|
|
12968
|
+
return new MeshBasicMaterial6({ map: texture, transparent, side: transparent ? DoubleSide5 : FrontSide2, alphaTest: transparent ? 0.1 : 0 });
|
|
12630
12969
|
}
|
|
12631
12970
|
static isSlim(image, scale) {
|
|
12632
12971
|
for (const [x, y] of [[46, 52], [54, 20]]) {
|
|
@@ -14836,8 +15175,8 @@ init_Model();
|
|
|
14836
15175
|
// src/world/SectionMesh.ts
|
|
14837
15176
|
init_CanvasCompat();
|
|
14838
15177
|
init_Materials();
|
|
14839
|
-
import { BufferGeometry as
|
|
14840
|
-
var SectionMesh = class _SectionMesh extends
|
|
15178
|
+
import { BufferGeometry as BufferGeometry8, Float32BufferAttribute as Float32BufferAttribute8, Group as Group2, Mesh as Mesh9 } from "three";
|
|
15179
|
+
var SectionMesh = class _SectionMesh extends Group2 {
|
|
14841
15180
|
constructor() {
|
|
14842
15181
|
super(...arguments);
|
|
14843
15182
|
this.ownedMeshes = [];
|
|
@@ -14910,11 +15249,11 @@ var SectionMesh = class _SectionMesh extends Group {
|
|
|
14910
15249
|
for (let corner = 0; corner < 6; corner++) indices.push(start + sourceIndices.getX(face * 6 + corner) - face * 4);
|
|
14911
15250
|
}
|
|
14912
15251
|
}
|
|
14913
|
-
const geometry = new
|
|
14914
|
-
geometry.setAttribute("position", new
|
|
14915
|
-
geometry.setAttribute("normal", new
|
|
14916
|
-
geometry.setAttribute("uv", new
|
|
14917
|
-
geometry.setAttribute("color", new
|
|
15252
|
+
const geometry = new BufferGeometry8();
|
|
15253
|
+
geometry.setAttribute("position", new Float32BufferAttribute8(positions, 3));
|
|
15254
|
+
geometry.setAttribute("normal", new Float32BufferAttribute8(normals, 3));
|
|
15255
|
+
geometry.setAttribute("uv", new Float32BufferAttribute8(uvs, 2));
|
|
15256
|
+
geometry.setAttribute("color", new Float32BufferAttribute8(colors, 3));
|
|
14918
15257
|
geometry.setIndex(indices);
|
|
14919
15258
|
geometry.computeBoundingBox();
|
|
14920
15259
|
geometry.computeBoundingSphere();
|
|
@@ -15166,6 +15505,7 @@ export {
|
|
|
15166
15505
|
EntityObject,
|
|
15167
15506
|
Env,
|
|
15168
15507
|
FluidModelObject,
|
|
15508
|
+
Fonts,
|
|
15169
15509
|
Geometries,
|
|
15170
15510
|
GuiHelper,
|
|
15171
15511
|
GuiLight,
|
|
@@ -15239,6 +15579,8 @@ export {
|
|
|
15239
15579
|
computeTangents,
|
|
15240
15580
|
createCanvas2 as createCanvas,
|
|
15241
15581
|
createFluidGeometry,
|
|
15582
|
+
createGuiTextGeometry,
|
|
15583
|
+
createGuiTextureGeometry,
|
|
15242
15584
|
createImage,
|
|
15243
15585
|
entityAnimationTime,
|
|
15244
15586
|
estimateBytesUsed,
|
|
@@ -15267,6 +15609,7 @@ export {
|
|
|
15267
15609
|
isTransformable,
|
|
15268
15610
|
isTripleArray,
|
|
15269
15611
|
isVector3,
|
|
15612
|
+
layoutGuiText,
|
|
15270
15613
|
md5,
|
|
15271
15614
|
mergeBufferAttributes,
|
|
15272
15615
|
mergeBufferGeometries,
|