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/browser/index.mjs
CHANGED
|
@@ -258,7 +258,8 @@ var init_Caching = __esm({
|
|
|
258
258
|
this.entityModelCache,
|
|
259
259
|
this.entityTextureCache,
|
|
260
260
|
this.entityAnimationCache,
|
|
261
|
-
this.blockEntityIndexCache
|
|
261
|
+
this.blockEntityIndexCache,
|
|
262
|
+
this.fontCache
|
|
262
263
|
];
|
|
263
264
|
}
|
|
264
265
|
static clear() {
|
|
@@ -305,6 +306,7 @@ var init_Caching = __esm({
|
|
|
305
306
|
_Caching.entityTextureCache = _Caching.createAssetCache();
|
|
306
307
|
_Caching.entityAnimationCache = _Caching.createAssetCache();
|
|
307
308
|
_Caching.blockEntityIndexCache = _Caching.createAssetCache();
|
|
309
|
+
_Caching.fontCache = _Caching.createAssetCache();
|
|
308
310
|
Caching = _Caching;
|
|
309
311
|
}
|
|
310
312
|
});
|
|
@@ -4247,8 +4249,8 @@ var init_EntityObject = __esm({
|
|
|
4247
4249
|
// src/three/BufferGeometryUtils.js
|
|
4248
4250
|
import {
|
|
4249
4251
|
BufferAttribute as BufferAttribute4,
|
|
4250
|
-
BufferGeometry as
|
|
4251
|
-
Float32BufferAttribute as
|
|
4252
|
+
BufferGeometry as BufferGeometry4,
|
|
4253
|
+
Float32BufferAttribute as Float32BufferAttribute6,
|
|
4252
4254
|
InterleavedBuffer,
|
|
4253
4255
|
InterleavedBufferAttribute,
|
|
4254
4256
|
TriangleFanDrawMode,
|
|
@@ -4267,7 +4269,7 @@ function mergeBufferGeometries(geometries, useGroups = false) {
|
|
|
4267
4269
|
const attributes = {};
|
|
4268
4270
|
const morphAttributes = {};
|
|
4269
4271
|
const morphTargetsRelative = geometries[0].morphTargetsRelative;
|
|
4270
|
-
const mergedGeometry = new
|
|
4272
|
+
const mergedGeometry = new BufferGeometry4();
|
|
4271
4273
|
let offset = 0;
|
|
4272
4274
|
for (let i = 0; i < geometries.length; ++i) {
|
|
4273
4275
|
const geometry = geometries[i];
|
|
@@ -4776,8 +4778,8 @@ function computeMorphedAttributes(object) {
|
|
|
4776
4778
|
}
|
|
4777
4779
|
}
|
|
4778
4780
|
}
|
|
4779
|
-
const morphedPositionAttribute = new
|
|
4780
|
-
const morphedNormalAttribute = new
|
|
4781
|
+
const morphedPositionAttribute = new Float32BufferAttribute6(modifiedPosition, 3);
|
|
4782
|
+
const morphedNormalAttribute = new Float32BufferAttribute6(modifiedNormal, 3);
|
|
4781
4783
|
return {
|
|
4782
4784
|
positionAttribute,
|
|
4783
4785
|
normalAttribute,
|
|
@@ -5027,7 +5029,7 @@ var init_ItemTints = __esm({
|
|
|
5027
5029
|
});
|
|
5028
5030
|
|
|
5029
5031
|
// src/model/scene/ModelObject.ts
|
|
5030
|
-
import { BoxGeometry as BoxGeometry5, BufferAttribute as BufferAttribute5, Color as
|
|
5032
|
+
import { BoxGeometry as BoxGeometry5, BufferAttribute as BufferAttribute5, Color as Color9, Euler as Euler7, Matrix4 as Matrix49 } from "three";
|
|
5031
5033
|
function isModelObject(obj) {
|
|
5032
5034
|
return obj.isModelObject;
|
|
5033
5035
|
}
|
|
@@ -5141,7 +5143,7 @@ var init_ModelObject = __esm({
|
|
|
5141
5143
|
if (tintIndex === void 0 || tintIndex < 0) continue;
|
|
5142
5144
|
const tint = this.options.tints[tintIndex];
|
|
5143
5145
|
if (tint === void 0) continue;
|
|
5144
|
-
const color = new
|
|
5146
|
+
const color = new Color9(tint);
|
|
5145
5147
|
for (let vertex = 0; vertex < 4; vertex++) {
|
|
5146
5148
|
color.toArray(colors, (faceIndex * 4 + vertex) * 3);
|
|
5147
5149
|
}
|
|
@@ -5270,7 +5272,7 @@ var init_fluidBlocks = __esm({
|
|
|
5270
5272
|
});
|
|
5271
5273
|
|
|
5272
5274
|
// src/model/fluid/FluidGeometry.ts
|
|
5273
|
-
import { BufferGeometry as
|
|
5275
|
+
import { BufferGeometry as BufferGeometry6, Float32BufferAttribute as Float32BufferAttribute7 } from "three";
|
|
5274
5276
|
function getBlockFluidState(key, state) {
|
|
5275
5277
|
const rule = key && fluidRules[key.toNamespacedString()];
|
|
5276
5278
|
if (rule) return {
|
|
@@ -5288,7 +5290,7 @@ function ownHeight(sample) {
|
|
|
5288
5290
|
return (level === 0 || level >= 8 ? 8 : 8 - level) / 9;
|
|
5289
5291
|
}
|
|
5290
5292
|
function createFluidGeometry(kind, sample) {
|
|
5291
|
-
const geometry = new
|
|
5293
|
+
const geometry = new BufferGeometry6();
|
|
5292
5294
|
const positions = [], normals = [], uvs = [], indices = [];
|
|
5293
5295
|
const self = sample(0, 0, 0);
|
|
5294
5296
|
const height = (x, z) => {
|
|
@@ -5387,9 +5389,9 @@ function createFluidGeometry(kind, sample) {
|
|
|
5387
5389
|
1
|
|
5388
5390
|
);
|
|
5389
5391
|
}
|
|
5390
|
-
geometry.setAttribute("position", new
|
|
5391
|
-
geometry.setAttribute("normal", new
|
|
5392
|
-
geometry.setAttribute("uv", new
|
|
5392
|
+
geometry.setAttribute("position", new Float32BufferAttribute7(positions, 3));
|
|
5393
|
+
geometry.setAttribute("normal", new Float32BufferAttribute7(normals, 3));
|
|
5394
|
+
geometry.setAttribute("uv", new Float32BufferAttribute7(uvs, 2));
|
|
5393
5395
|
geometry.setIndex(indices);
|
|
5394
5396
|
return geometry;
|
|
5395
5397
|
}
|
|
@@ -5409,7 +5411,7 @@ __export(FluidModelObject_exports, {
|
|
|
5409
5411
|
FluidModelObject: () => FluidModelObject,
|
|
5410
5412
|
sampleFluid: () => sampleFluid
|
|
5411
5413
|
});
|
|
5412
|
-
import { BufferAttribute as BufferAttribute6, Color as
|
|
5414
|
+
import { BufferAttribute as BufferAttribute6, Color as Color10, DoubleSide as DoubleSide4 } from "three";
|
|
5413
5415
|
function sampleFluid(kind, sample) {
|
|
5414
5416
|
const cells = [];
|
|
5415
5417
|
const key = [];
|
|
@@ -5460,7 +5462,7 @@ var init_FluidModelObject = __esm({
|
|
|
5460
5462
|
}
|
|
5461
5463
|
}
|
|
5462
5464
|
geometry.clearGroups();
|
|
5463
|
-
const color = new
|
|
5465
|
+
const color = new Color10(this.options.tints?.[0] ?? (this.kind === "water" ? 4159204 : 16777215));
|
|
5464
5466
|
const colors = new Float32Array(geometry.getAttribute("position").count * 3);
|
|
5465
5467
|
for (let i = 0; i < colors.length; i += 3) color.toArray(colors, i);
|
|
5466
5468
|
geometry.setAttribute("color", new BufferAttribute6(colors, 3));
|
|
@@ -5477,7 +5479,7 @@ var init_FluidModelObject = __esm({
|
|
|
5477
5479
|
super.applyTextures();
|
|
5478
5480
|
this.iterateAllMeshes((mesh) => {
|
|
5479
5481
|
const material = mesh.material;
|
|
5480
|
-
material.side =
|
|
5482
|
+
material.side = DoubleSide4;
|
|
5481
5483
|
material.forceSinglePass = true;
|
|
5482
5484
|
material.depthWrite = !material.transparent;
|
|
5483
5485
|
});
|
|
@@ -5731,6 +5733,101 @@ var BlockEntities = class {
|
|
|
5731
5733
|
// src/assets/index.ts
|
|
5732
5734
|
init_BlockStates();
|
|
5733
5735
|
init_Entities();
|
|
5736
|
+
|
|
5737
|
+
// src/assets/Fonts.ts
|
|
5738
|
+
init_AssetKey();
|
|
5739
|
+
init_AssetLoader();
|
|
5740
|
+
init_AssetParsers();
|
|
5741
|
+
init_ModelTextures();
|
|
5742
|
+
init_Caching();
|
|
5743
|
+
var Fonts = class {
|
|
5744
|
+
static async get(key = "minecraft:default") {
|
|
5745
|
+
const fontKey = typeof key === "string" ? AssetKey.parse("font", key) : key;
|
|
5746
|
+
return await Caching.fontCache.get(fontKey.serialize(), () => this.load(fontKey, []));
|
|
5747
|
+
}
|
|
5748
|
+
static relatedKey(assetType, id, origin) {
|
|
5749
|
+
const key = AssetKey.parse(assetType, id);
|
|
5750
|
+
key.root = origin.root;
|
|
5751
|
+
return key;
|
|
5752
|
+
}
|
|
5753
|
+
static async load(key, parents) {
|
|
5754
|
+
const serialized = key.serialize();
|
|
5755
|
+
if (parents.includes(serialized)) throw new Error(`Cyclic font reference: ${key.toNamespacedString()}`);
|
|
5756
|
+
const stack = await AssetLoader.getAll(key, "json" /* JSON */);
|
|
5757
|
+
if (stack.length === 0) throw new Error(`Could not load font ${key.toNamespacedString()}`);
|
|
5758
|
+
const glyphs = /* @__PURE__ */ new Map();
|
|
5759
|
+
for (const asset of stack) {
|
|
5760
|
+
for (const provider of asset.providers) {
|
|
5761
|
+
if (provider.filter?.uniform || provider.filter?.jp) continue;
|
|
5762
|
+
let provided;
|
|
5763
|
+
switch (provider.type) {
|
|
5764
|
+
case "bitmap":
|
|
5765
|
+
case "minecraft:bitmap":
|
|
5766
|
+
provided = await this.bitmap(provider, key);
|
|
5767
|
+
break;
|
|
5768
|
+
case "space":
|
|
5769
|
+
case "minecraft:space":
|
|
5770
|
+
provided = new Map(Object.entries(provider.advances).map(([character, advance]) => [
|
|
5771
|
+
character,
|
|
5772
|
+
{ x: 0, y: 0, width: 0, height: 0, scale: 1, ascent: 0, advance }
|
|
5773
|
+
]));
|
|
5774
|
+
break;
|
|
5775
|
+
case "reference":
|
|
5776
|
+
case "minecraft:reference":
|
|
5777
|
+
provided = (await this.load(this.relatedKey("font", provider.id, key), [...parents, serialized])).glyphs;
|
|
5778
|
+
break;
|
|
5779
|
+
default:
|
|
5780
|
+
continue;
|
|
5781
|
+
}
|
|
5782
|
+
for (const [character, glyph] of provided) {
|
|
5783
|
+
if (character !== "\0" && !glyphs.has(character)) glyphs.set(character, glyph);
|
|
5784
|
+
}
|
|
5785
|
+
}
|
|
5786
|
+
}
|
|
5787
|
+
return { glyphs };
|
|
5788
|
+
}
|
|
5789
|
+
static async bitmap(provider, fontKey) {
|
|
5790
|
+
const rows = provider.chars.map((row) => [...row]);
|
|
5791
|
+
const columns = rows[0]?.length;
|
|
5792
|
+
if (!columns || rows.some((row) => row.length !== columns)) {
|
|
5793
|
+
throw new Error(`Invalid character grid in font ${fontKey.toNamespacedString()}`);
|
|
5794
|
+
}
|
|
5795
|
+
const key = this.relatedKey("textures", provider.file, fontKey);
|
|
5796
|
+
const image = await ModelTextures.get(key);
|
|
5797
|
+
if (!image) throw new Error(`Could not load font texture ${key.toNamespacedString()}`);
|
|
5798
|
+
const width = Math.floor(image.width / columns), height = Math.floor(image.height / rows.length);
|
|
5799
|
+
if (!width || !height) throw new Error(`Font texture ${key.toNamespacedString()} is smaller than its character grid`);
|
|
5800
|
+
const scale = (provider.height ?? 8) / height;
|
|
5801
|
+
const pixels = image.data.getImageData(0, 0, image.width, image.height).data;
|
|
5802
|
+
const glyphs = /* @__PURE__ */ new Map();
|
|
5803
|
+
rows.forEach((row, rowIndex) => row.forEach((character, columnIndex) => {
|
|
5804
|
+
if (character === "\0") return;
|
|
5805
|
+
const x = columnIndex * width, y = rowIndex * height;
|
|
5806
|
+
let occupiedWidth = 0;
|
|
5807
|
+
for (let column = width - 1; column >= 0 && !occupiedWidth; column--) {
|
|
5808
|
+
for (let row2 = 0; row2 < height; row2++) {
|
|
5809
|
+
if (pixels[((y + row2) * image.width + x + column) * 4 + 3] !== 0) {
|
|
5810
|
+
occupiedWidth = column + 1;
|
|
5811
|
+
break;
|
|
5812
|
+
}
|
|
5813
|
+
}
|
|
5814
|
+
}
|
|
5815
|
+
glyphs.set(character, {
|
|
5816
|
+
image: image.data.canvas,
|
|
5817
|
+
x,
|
|
5818
|
+
y,
|
|
5819
|
+
width,
|
|
5820
|
+
height,
|
|
5821
|
+
scale,
|
|
5822
|
+
ascent: provider.ascent,
|
|
5823
|
+
advance: Math.floor(occupiedWidth * scale + 0.5) + 1
|
|
5824
|
+
});
|
|
5825
|
+
}));
|
|
5826
|
+
return glyphs;
|
|
5827
|
+
}
|
|
5828
|
+
};
|
|
5829
|
+
|
|
5830
|
+
// src/assets/index.ts
|
|
5734
5831
|
init_ModelTextures();
|
|
5735
5832
|
init_Models();
|
|
5736
5833
|
init_source();
|
|
@@ -8729,7 +8826,137 @@ function copyDataTexture(source) {
|
|
|
8729
8826
|
|
|
8730
8827
|
// src/gui/GuiHelper.ts
|
|
8731
8828
|
init_AssetKey();
|
|
8829
|
+
|
|
8830
|
+
// src/gui/GuiText.ts
|
|
8831
|
+
import { BufferGeometry as BufferGeometry2, Color as Color8, Float32BufferAttribute as Float32BufferAttribute4 } from "three";
|
|
8832
|
+
async function layoutGuiText(text, options = {}) {
|
|
8833
|
+
const maxWidth = options.maxWidth ?? Infinity, lineHeight = options.lineHeight ?? 9;
|
|
8834
|
+
if (!(maxWidth > 0) || !Number.isFinite(lineHeight) || lineHeight <= 0) {
|
|
8835
|
+
throw new Error("Text wrap width and line height must be positive");
|
|
8836
|
+
}
|
|
8837
|
+
const font = await Fonts.get(options.font);
|
|
8838
|
+
const runs = typeof text === "string" ? [{ text }] : text;
|
|
8839
|
+
const glyphs = [], lineWidths = [];
|
|
8840
|
+
let line = [], width = 0;
|
|
8841
|
+
let trailingNewline = false;
|
|
8842
|
+
const finishLine = (entries) => {
|
|
8843
|
+
let x = 0;
|
|
8844
|
+
for (const entry of entries) {
|
|
8845
|
+
glyphs.push({ ...entry, x, y: lineWidths.length * lineHeight });
|
|
8846
|
+
x += entry.advance;
|
|
8847
|
+
}
|
|
8848
|
+
lineWidths.push(x);
|
|
8849
|
+
};
|
|
8850
|
+
for (const run of runs) {
|
|
8851
|
+
const style = {
|
|
8852
|
+
color: run.color ?? options.color ?? 16777215,
|
|
8853
|
+
bold: run.bold ?? options.bold ?? false,
|
|
8854
|
+
italic: run.italic ?? options.italic ?? false
|
|
8855
|
+
};
|
|
8856
|
+
for (const character of run.text.replace(/\r\n?/g, "\n")) {
|
|
8857
|
+
trailingNewline = character === "\n";
|
|
8858
|
+
if (character === "\n") {
|
|
8859
|
+
finishLine(line);
|
|
8860
|
+
line = [];
|
|
8861
|
+
width = 0;
|
|
8862
|
+
continue;
|
|
8863
|
+
}
|
|
8864
|
+
const glyph = font.glyphs.get(character);
|
|
8865
|
+
const advance = (glyph?.advance ?? 6) + (style.bold ? 1 : 0);
|
|
8866
|
+
line.push({ character, glyph, advance, style, x: 0, y: 0 });
|
|
8867
|
+
width += advance;
|
|
8868
|
+
while (width > maxWidth && line.length > 1) {
|
|
8869
|
+
let space = -1;
|
|
8870
|
+
for (let i = 0; i < line.length; i++) if (line[i].character === " ") space = i;
|
|
8871
|
+
const split = space >= 0 ? space : line.length - 1;
|
|
8872
|
+
if (split > 0) finishLine(line.slice(0, split));
|
|
8873
|
+
line = line.slice(split + (space >= 0 ? 1 : 0));
|
|
8874
|
+
width = line.reduce((sum, entry) => sum + entry.advance, 0);
|
|
8875
|
+
}
|
|
8876
|
+
}
|
|
8877
|
+
}
|
|
8878
|
+
if (line.length || !lineWidths.length || trailingNewline) finishLine(line);
|
|
8879
|
+
return { glyphs, lineWidths, width: Math.max(0, ...lineWidths), height: lineWidths.length * lineHeight };
|
|
8880
|
+
}
|
|
8881
|
+
function createGuiTextGeometry(layout, shadow = true) {
|
|
8882
|
+
const batches = [];
|
|
8883
|
+
for (const isShadow of shadow ? [true, false] : [false]) {
|
|
8884
|
+
let batch;
|
|
8885
|
+
for (const entry of layout.glyphs) {
|
|
8886
|
+
const { glyph, style } = entry;
|
|
8887
|
+
if (glyph && !glyph.image) continue;
|
|
8888
|
+
if (!batch || batch.image !== glyph?.image) {
|
|
8889
|
+
batch = { image: glyph?.image, positions: [], uvs: [], colors: [], indices: [] };
|
|
8890
|
+
batches.push(batch);
|
|
8891
|
+
}
|
|
8892
|
+
const color = new Color8(isShadow ? (style.color & 16579836) >> 2 : style.color);
|
|
8893
|
+
const offset = isShadow ? 1 : 0;
|
|
8894
|
+
const top = glyph ? 7 - glyph.ascent : 0;
|
|
8895
|
+
const height = glyph ? glyph.height * glyph.scale : 8;
|
|
8896
|
+
const width = glyph ? glyph.width * glyph.scale : 5;
|
|
8897
|
+
const shear = (y) => style.italic ? 1 - 0.25 * y : 0;
|
|
8898
|
+
const quad = (left, upper, right, lower, boldOffset) => {
|
|
8899
|
+
const base = batch.positions.length / 3;
|
|
8900
|
+
const x = entry.x + offset + boldOffset, y = entry.y + offset;
|
|
8901
|
+
batch.positions.push(
|
|
8902
|
+
x + left + shear(upper),
|
|
8903
|
+
-y - upper,
|
|
8904
|
+
0,
|
|
8905
|
+
x + right + shear(upper),
|
|
8906
|
+
-y - upper,
|
|
8907
|
+
0,
|
|
8908
|
+
x + left + shear(lower),
|
|
8909
|
+
-y - lower,
|
|
8910
|
+
0,
|
|
8911
|
+
x + right + shear(lower),
|
|
8912
|
+
-y - lower,
|
|
8913
|
+
0
|
|
8914
|
+
);
|
|
8915
|
+
const u0 = glyph ? glyph.x / glyph.image.width : 0;
|
|
8916
|
+
const u1 = glyph ? (glyph.x + glyph.width) / glyph.image.width : 1;
|
|
8917
|
+
const v0 = glyph ? 1 - glyph.y / glyph.image.height : 1;
|
|
8918
|
+
const v1 = glyph ? 1 - (glyph.y + glyph.height) / glyph.image.height : 0;
|
|
8919
|
+
batch.uvs.push(u0, v0, u1, v0, u0, v1, u1, v1);
|
|
8920
|
+
for (let i = 0; i < 4; i++) batch.colors.push(color.r, color.g, color.b);
|
|
8921
|
+
batch.indices.push(base, base + 2, base + 1, base + 2, base + 3, base + 1);
|
|
8922
|
+
};
|
|
8923
|
+
for (const boldOffset of style.bold ? [0, 1] : [0]) {
|
|
8924
|
+
if (glyph) quad(0, top, width, top + height, boldOffset);
|
|
8925
|
+
else {
|
|
8926
|
+
quad(0, 0, 5, 1, boldOffset);
|
|
8927
|
+
quad(0, 7, 5, 8, boldOffset);
|
|
8928
|
+
quad(0, 1, 1, 7, boldOffset);
|
|
8929
|
+
quad(4, 1, 5, 7, boldOffset);
|
|
8930
|
+
}
|
|
8931
|
+
}
|
|
8932
|
+
}
|
|
8933
|
+
}
|
|
8934
|
+
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) }));
|
|
8935
|
+
}
|
|
8936
|
+
|
|
8937
|
+
// src/gui/GuiHelper.ts
|
|
8732
8938
|
var GuiHelper = class {
|
|
8939
|
+
/** Sizes a tooltip around supplied text; the first entry is its title. */
|
|
8940
|
+
static async tooltip(lines, options = {}) {
|
|
8941
|
+
if (!lines.length) return [];
|
|
8942
|
+
const { position = [0, 0], titleGap = 2, lineHeight = 10, shadow = true, ...style } = options;
|
|
8943
|
+
const textOptions = { ...style, lineHeight, shadow };
|
|
8944
|
+
const layouts = await Promise.all(lines.map((line) => layoutGuiText(line, textOptions)));
|
|
8945
|
+
const width = Math.max(...layouts.map((layout) => layout.width));
|
|
8946
|
+
const height = layouts.reduce((sum, layout) => sum + layout.height, 0) - 2 + (lines.length > 1 ? titleGap : 0);
|
|
8947
|
+
const layers = ["background", "frame"].map((part) => ({
|
|
8948
|
+
name: `tooltip-${part}`,
|
|
8949
|
+
texture: `minecraft:gui/sprites/tooltip/${part}`,
|
|
8950
|
+
position: [position[0] - 12, position[1] - 12],
|
|
8951
|
+
size: [width + 24, height + 24]
|
|
8952
|
+
}));
|
|
8953
|
+
let y = position[1];
|
|
8954
|
+
lines.forEach((text, index) => {
|
|
8955
|
+
layers.push({ ...textOptions, name: `tooltip-line-${index}`, text, position: [position[0], y] });
|
|
8956
|
+
y += layouts[index].height + (index === 0 ? titleGap : 0);
|
|
8957
|
+
});
|
|
8958
|
+
return layers;
|
|
8959
|
+
}
|
|
8733
8960
|
static inventorySlot(slot, origin = [0, 0], offset = [18, 18], rowSize = 9) {
|
|
8734
8961
|
const [column, row] = typeof slot === "number" ? [slot % rowSize, Math.floor(slot / rowSize)] : slot;
|
|
8735
8962
|
return [origin[0] + column * offset[0], origin[1] + row * offset[1]];
|
|
@@ -8793,6 +9020,85 @@ var GuiHelper = class {
|
|
|
8793
9020
|
}
|
|
8794
9021
|
};
|
|
8795
9022
|
|
|
9023
|
+
// src/gui/GuiTextureGeometry.ts
|
|
9024
|
+
import { BufferGeometry as BufferGeometry3, Float32BufferAttribute as Float32BufferAttribute5, PlaneGeometry } from "three";
|
|
9025
|
+
function createGuiTextureGeometry(width, height, imageWidth, imageHeight, crop, scaling) {
|
|
9026
|
+
if (crop || !scaling || scaling.type === "stretch") {
|
|
9027
|
+
const [x, y, w, h] = crop ?? [0, 0, imageWidth, imageHeight];
|
|
9028
|
+
const geometry = new PlaneGeometry(width, height);
|
|
9029
|
+
const uv = geometry.getAttribute("uv");
|
|
9030
|
+
for (let i = 0; i < uv.count; i++) {
|
|
9031
|
+
uv.setXY(
|
|
9032
|
+
i,
|
|
9033
|
+
(x + uv.getX(i) * w) / imageWidth,
|
|
9034
|
+
1 - (y + (1 - uv.getY(i)) * h) / imageHeight
|
|
9035
|
+
);
|
|
9036
|
+
}
|
|
9037
|
+
return geometry;
|
|
9038
|
+
}
|
|
9039
|
+
const sw = scaling.width, sh = scaling.height;
|
|
9040
|
+
if (![sw, sh].every((value) => Number.isInteger(value) && value > 0)) {
|
|
9041
|
+
throw new Error("GUI sprite dimensions must be positive integers");
|
|
9042
|
+
}
|
|
9043
|
+
if (![width, height].every((value) => Number.isFinite(value) && value >= 0)) {
|
|
9044
|
+
throw new Error("GUI output dimensions must be finite and nonnegative");
|
|
9045
|
+
}
|
|
9046
|
+
const positions = [], uvs = [], normals = [], indices = [];
|
|
9047
|
+
function quad(x, y, w, h, u, v, uw, vh) {
|
|
9048
|
+
if (w <= 0 || h <= 0) return;
|
|
9049
|
+
const index = positions.length / 3;
|
|
9050
|
+
const left = x - width / 2, top = height / 2 - y;
|
|
9051
|
+
positions.push(left, top, 0, left + w, top, 0, left, top - h, 0, left + w, top - h, 0);
|
|
9052
|
+
uvs.push(
|
|
9053
|
+
u / sw,
|
|
9054
|
+
1 - v / sh,
|
|
9055
|
+
(u + uw) / sw,
|
|
9056
|
+
1 - v / sh,
|
|
9057
|
+
u / sw,
|
|
9058
|
+
1 - (v + vh) / sh,
|
|
9059
|
+
(u + uw) / sw,
|
|
9060
|
+
1 - (v + vh) / sh
|
|
9061
|
+
);
|
|
9062
|
+
normals.push(0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1);
|
|
9063
|
+
indices.push(index, index + 2, index + 1, index + 2, index + 3, index + 1);
|
|
9064
|
+
}
|
|
9065
|
+
function tile(x, y, w, h, u, v, tw, th) {
|
|
9066
|
+
for (let dy = 0; dy < h; dy += th) {
|
|
9067
|
+
for (let dx = 0; dx < w; dx += tw) {
|
|
9068
|
+
const cw = Math.min(tw, w - dx), ch = Math.min(th, h - dy);
|
|
9069
|
+
quad(x + dx, y + dy, cw, ch, u, v, cw, ch);
|
|
9070
|
+
}
|
|
9071
|
+
}
|
|
9072
|
+
}
|
|
9073
|
+
if (scaling.type === "tile") {
|
|
9074
|
+
tile(0, 0, width, height, 0, 0, sw, sh);
|
|
9075
|
+
} else {
|
|
9076
|
+
let segments = function(size, sourceSize, start, end) {
|
|
9077
|
+
if (size === sourceSize) return [[0, size, 0, sourceSize]];
|
|
9078
|
+
start = Math.min(start, Math.floor(size / 2));
|
|
9079
|
+
end = Math.min(end, Math.floor(size / 2));
|
|
9080
|
+
return [
|
|
9081
|
+
[0, start, 0, start],
|
|
9082
|
+
[start, size - start - end, start, sourceSize - start - end],
|
|
9083
|
+
[size - end, end, sourceSize - end, end]
|
|
9084
|
+
];
|
|
9085
|
+
};
|
|
9086
|
+
const border = typeof scaling.border === "number" ? { left: scaling.border, top: scaling.border, right: scaling.border, bottom: scaling.border } : scaling.border;
|
|
9087
|
+
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) {
|
|
9088
|
+
throw new Error("GUI nine-slice borders must be nonnegative integers with a nonempty center");
|
|
9089
|
+
}
|
|
9090
|
+
const columns = segments(width, sw, border.left, border.right);
|
|
9091
|
+
const rows = segments(height, sh, border.top, border.bottom);
|
|
9092
|
+
for (const [y, h, v, vh] of rows) {
|
|
9093
|
+
for (const [x, w, u, uw] of columns) {
|
|
9094
|
+
if (w <= 0 || h <= 0) continue;
|
|
9095
|
+
(scaling.stretch_inner ? quad : tile)(x, y, w, h, u, v, uw, vh);
|
|
9096
|
+
}
|
|
9097
|
+
}
|
|
9098
|
+
}
|
|
9099
|
+
return new BufferGeometry3().setAttribute("position", new Float32BufferAttribute5(positions, 3)).setAttribute("normal", new Float32BufferAttribute5(normals, 3)).setAttribute("uv", new Float32BufferAttribute5(uvs, 2)).setIndex(indices);
|
|
9100
|
+
}
|
|
9101
|
+
|
|
8796
9102
|
// src/gui/scene/GuiObject.ts
|
|
8797
9103
|
init_AssetKey();
|
|
8798
9104
|
init_ModelTextures();
|
|
@@ -8803,7 +9109,7 @@ init_Materials();
|
|
|
8803
9109
|
init_ModelObject();
|
|
8804
9110
|
init_DisplayPosition();
|
|
8805
9111
|
init_GuiLight();
|
|
8806
|
-
import { Box2, Box3 as Box32, Matrix4 as Matrix410, Mesh as Mesh6,
|
|
9112
|
+
import { Box2, Box3 as Box32, DoubleSide as DoubleSide3, Group, Matrix4 as Matrix410, Mesh as Mesh6, MeshBasicMaterial as MeshBasicMaterial5, Vector2 as Vector23 } from "three";
|
|
8807
9113
|
var GuiObject = class extends SceneObject {
|
|
8808
9114
|
constructor(textureLayers, options) {
|
|
8809
9115
|
super({ ...options, instanceMeshes: false, mergeMeshes: false });
|
|
@@ -8813,6 +9119,7 @@ var GuiObject = class extends SceneObject {
|
|
|
8813
9119
|
this.bounds = new Box2();
|
|
8814
9120
|
this.geometries = /* @__PURE__ */ new Set();
|
|
8815
9121
|
this.ownedMaterials = /* @__PURE__ */ new Set();
|
|
9122
|
+
this.textMaterials = /* @__PURE__ */ new Map();
|
|
8816
9123
|
this.initialized = false;
|
|
8817
9124
|
}
|
|
8818
9125
|
async init() {
|
|
@@ -8821,6 +9128,43 @@ var GuiObject = class extends SceneObject {
|
|
|
8821
9128
|
let depth = 0;
|
|
8822
9129
|
for (const [index, layer] of this.textureLayers.entries()) {
|
|
8823
9130
|
const [x, y] = layer.position ?? [0, 0];
|
|
9131
|
+
if ("text" in layer) {
|
|
9132
|
+
const layout = await layoutGuiText(layer.text, layer);
|
|
9133
|
+
const group = new Group();
|
|
9134
|
+
group.name = `group:${layer.name ?? index}`;
|
|
9135
|
+
group.position.set(x, -y, depth);
|
|
9136
|
+
const [width2, height2] = layer.size ?? [layout.width, layout.height];
|
|
9137
|
+
group.scale.set(layout.width ? width2 / layout.width : 1, height2 / layout.height, 1);
|
|
9138
|
+
this.add(group);
|
|
9139
|
+
const parts = createGuiTextGeometry(layout, layer.shadow);
|
|
9140
|
+
const bounds = new Box32();
|
|
9141
|
+
for (const [partIndex, { image: image2, geometry: geometry2 }] of parts.entries()) {
|
|
9142
|
+
this.geometries.add(geometry2);
|
|
9143
|
+
geometry2.computeBoundingBox();
|
|
9144
|
+
bounds.union(geometry2.boundingBox);
|
|
9145
|
+
let material2 = this.textMaterials.get(image2);
|
|
9146
|
+
if (!material2) {
|
|
9147
|
+
material2 = image2 ? Materials.createGuiCanvasMaterial(image2) : new MeshBasicMaterial5({ transparent: true, depthWrite: false, side: DoubleSide3, toneMapped: false });
|
|
9148
|
+
material2.vertexColors = true;
|
|
9149
|
+
this.textMaterials.set(image2, material2);
|
|
9150
|
+
this.ownedMaterials.add(material2);
|
|
9151
|
+
}
|
|
9152
|
+
const mesh2 = new Mesh6(geometry2, material2);
|
|
9153
|
+
mesh2.name = `mesh:${layer.name ?? index}:${partIndex}`;
|
|
9154
|
+
mesh2.renderOrder = index + partIndex / (parts.length + 1) * 0.5;
|
|
9155
|
+
group.add(mesh2);
|
|
9156
|
+
}
|
|
9157
|
+
group.updateMatrix();
|
|
9158
|
+
bounds.applyMatrix4(group.matrix);
|
|
9159
|
+
this.bounds.expandByPoint(new Vector23(x, y));
|
|
9160
|
+
this.bounds.expandByPoint(new Vector23(x + width2, y + height2));
|
|
9161
|
+
if (!bounds.isEmpty()) {
|
|
9162
|
+
this.bounds.expandByPoint(new Vector23(bounds.min.x, -bounds.max.y));
|
|
9163
|
+
this.bounds.expandByPoint(new Vector23(bounds.max.x, -bounds.min.y));
|
|
9164
|
+
}
|
|
9165
|
+
depth += 0.01;
|
|
9166
|
+
continue;
|
|
9167
|
+
}
|
|
8824
9168
|
if ("item" in layer) {
|
|
8825
9169
|
const [width2, height2] = layer.size ?? [16, 16];
|
|
8826
9170
|
const item = await this.createItem(layer, index);
|
|
@@ -8844,18 +9188,10 @@ var GuiObject = class extends SceneObject {
|
|
|
8844
9188
|
const key = typeof layer.texture === "string" ? AssetKey.parse("textures", layer.texture) : layer.texture;
|
|
8845
9189
|
const material = await this.loadMaterial(key);
|
|
8846
9190
|
const image = material.map.image;
|
|
8847
|
-
const
|
|
8848
|
-
const [width, height] = layer.size ?? [
|
|
8849
|
-
const geometry =
|
|
9191
|
+
const scaling = layer.crop ? void 0 : (await ModelTextures.getMeta(key))?.gui?.scaling;
|
|
9192
|
+
const [width, height] = layer.size ?? (layer.crop ? layer.crop.slice(2) : scaling && scaling.type !== "stretch" ? [scaling.width, scaling.height] : [image.width, image.height]);
|
|
9193
|
+
const geometry = createGuiTextureGeometry(width, height, image.width, image.height, layer.crop, scaling);
|
|
8850
9194
|
this.geometries.add(geometry);
|
|
8851
|
-
const uv = geometry.getAttribute("uv");
|
|
8852
|
-
for (let i = 0; i < uv.count; i++) {
|
|
8853
|
-
uv.setXY(
|
|
8854
|
-
i,
|
|
8855
|
-
(cropX + uv.getX(i) * cropWidth) / image.width,
|
|
8856
|
-
1 - (cropY + (1 - uv.getY(i)) * cropHeight) / image.height
|
|
8857
|
-
);
|
|
8858
|
-
}
|
|
8859
9195
|
const mesh = new Mesh6(geometry, material);
|
|
8860
9196
|
mesh.name = `mesh:${layer.name ?? index}`;
|
|
8861
9197
|
mesh.position.set(x + width / 2, -y - height / 2, depth);
|
|
@@ -8920,10 +9256,11 @@ var GuiObject = class extends SceneObject {
|
|
|
8920
9256
|
for (const geometry of this.geometries) geometry.dispose();
|
|
8921
9257
|
this.geometries.clear();
|
|
8922
9258
|
for (const material of this.ownedMaterials) {
|
|
8923
|
-
material.map
|
|
9259
|
+
material.map?.dispose();
|
|
8924
9260
|
material.dispose();
|
|
8925
9261
|
}
|
|
8926
9262
|
this.ownedMaterials.clear();
|
|
9263
|
+
this.textMaterials.clear();
|
|
8927
9264
|
this.bounds.makeEmpty();
|
|
8928
9265
|
this.initialized = false;
|
|
8929
9266
|
super.disposeAndRemoveAllChildren();
|
|
@@ -12489,7 +12826,7 @@ init_util();
|
|
|
12489
12826
|
init_Caching();
|
|
12490
12827
|
init_CacheKey();
|
|
12491
12828
|
init_MineRenderError();
|
|
12492
|
-
import { DataTexture as DataTexture2, DoubleSide as
|
|
12829
|
+
import { DataTexture as DataTexture2, DoubleSide as DoubleSide5, FrontSide as FrontSide2, MeshBasicMaterial as MeshBasicMaterial6, SRGBColorSpace as SRGBColorSpace6 } from "three";
|
|
12493
12830
|
|
|
12494
12831
|
// src/skin/SkinImage.ts
|
|
12495
12832
|
init_Caching();
|
|
@@ -12574,7 +12911,7 @@ var SkinTextures = class {
|
|
|
12574
12911
|
texture.colorSpace = SRGBColorSpace6;
|
|
12575
12912
|
texture.flipY = true;
|
|
12576
12913
|
texture.needsUpdate = true;
|
|
12577
|
-
return new MeshBasicMaterial6({ map: texture, transparent, side: transparent ?
|
|
12914
|
+
return new MeshBasicMaterial6({ map: texture, transparent, side: transparent ? DoubleSide5 : FrontSide2, alphaTest: transparent ? 0.1 : 0 });
|
|
12578
12915
|
}
|
|
12579
12916
|
static isSlim(image, scale) {
|
|
12580
12917
|
for (const [x, y] of [[46, 52], [54, 20]]) {
|
|
@@ -14782,8 +15119,8 @@ init_Model();
|
|
|
14782
15119
|
// src/world/SectionMesh.ts
|
|
14783
15120
|
init_CanvasCompat();
|
|
14784
15121
|
init_Materials();
|
|
14785
|
-
import { BufferGeometry as
|
|
14786
|
-
var SectionMesh = class _SectionMesh extends
|
|
15122
|
+
import { BufferGeometry as BufferGeometry8, Float32BufferAttribute as Float32BufferAttribute8, Group as Group2, Mesh as Mesh9 } from "three";
|
|
15123
|
+
var SectionMesh = class _SectionMesh extends Group2 {
|
|
14787
15124
|
constructor() {
|
|
14788
15125
|
super(...arguments);
|
|
14789
15126
|
this.ownedMeshes = [];
|
|
@@ -14856,11 +15193,11 @@ var SectionMesh = class _SectionMesh extends Group {
|
|
|
14856
15193
|
for (let corner = 0; corner < 6; corner++) indices.push(start + sourceIndices.getX(face * 6 + corner) - face * 4);
|
|
14857
15194
|
}
|
|
14858
15195
|
}
|
|
14859
|
-
const geometry = new
|
|
14860
|
-
geometry.setAttribute("position", new
|
|
14861
|
-
geometry.setAttribute("normal", new
|
|
14862
|
-
geometry.setAttribute("uv", new
|
|
14863
|
-
geometry.setAttribute("color", new
|
|
15196
|
+
const geometry = new BufferGeometry8();
|
|
15197
|
+
geometry.setAttribute("position", new Float32BufferAttribute8(positions, 3));
|
|
15198
|
+
geometry.setAttribute("normal", new Float32BufferAttribute8(normals, 3));
|
|
15199
|
+
geometry.setAttribute("uv", new Float32BufferAttribute8(uvs, 2));
|
|
15200
|
+
geometry.setAttribute("color", new Float32BufferAttribute8(colors, 3));
|
|
14864
15201
|
geometry.setIndex(indices);
|
|
14865
15202
|
geometry.computeBoundingBox();
|
|
14866
15203
|
geometry.computeBoundingSphere();
|
|
@@ -15114,6 +15451,7 @@ export {
|
|
|
15114
15451
|
EntityObject,
|
|
15115
15452
|
Env,
|
|
15116
15453
|
FluidModelObject,
|
|
15454
|
+
Fonts,
|
|
15117
15455
|
Geometries,
|
|
15118
15456
|
GuiHelper,
|
|
15119
15457
|
GuiLight,
|
|
@@ -15185,6 +15523,8 @@ export {
|
|
|
15185
15523
|
computeTangents,
|
|
15186
15524
|
createCanvas,
|
|
15187
15525
|
createFluidGeometry,
|
|
15526
|
+
createGuiTextGeometry,
|
|
15527
|
+
createGuiTextureGeometry,
|
|
15188
15528
|
createImage,
|
|
15189
15529
|
entityAnimationTime,
|
|
15190
15530
|
estimateBytesUsed,
|
|
@@ -15213,6 +15553,7 @@ export {
|
|
|
15213
15553
|
isTransformable,
|
|
15214
15554
|
isTripleArray,
|
|
15215
15555
|
isVector3,
|
|
15556
|
+
layoutGuiText,
|
|
15216
15557
|
md5,
|
|
15217
15558
|
mergeBufferAttributes,
|
|
15218
15559
|
mergeBufferGeometries,
|