minerender 2.1.0-alpha.140 → 2.1.0-alpha.142
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/esm/assets/BlockEntities.mjs +2 -0
- package/dist/browser/esm/assets/BlockEntities.mjs.map +1 -1
- package/dist/browser/esm/assets/Entities.mjs +29 -3
- package/dist/browser/esm/assets/Entities.mjs.map +1 -1
- package/dist/browser/esm/assets/MineRenderData.mjs +8 -17
- package/dist/browser/esm/assets/MineRenderData.mjs.map +1 -1
- package/dist/browser/esm/assets/_versions/DatasetVersions.mjs +22 -0
- package/dist/browser/esm/assets/_versions/DatasetVersions.mjs.map +1 -0
- package/dist/browser/esm/cache/Caching.mjs +2 -0
- package/dist/browser/esm/cache/Caching.mjs.map +1 -1
- package/dist/browser/esm/index.browser.d.mts +7 -0
- package/dist/browser/esm/world/SectionMesh.mjs +65 -9
- package/dist/browser/esm/world/SectionMesh.mjs.map +1 -1
- package/dist/browser/index.d.ts +7 -0
- package/dist/browser/index.js +240 -140
- package/dist/browser/index.js.map +1 -1
- package/dist/bundle.js +251 -147
- package/dist/bundle.js.map +1 -1
- package/dist/node/index.d.mts +7 -0
- package/dist/node/index.d.ts +7 -0
- package/dist/node/index.js +242 -140
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +258 -156
- package/dist/node/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/node/index.mjs
CHANGED
|
@@ -309,6 +309,9 @@ var init_Caching = __esm({
|
|
|
309
309
|
static {
|
|
310
310
|
this.blockEntityIndexCache = _Caching.createAssetCache();
|
|
311
311
|
}
|
|
312
|
+
static {
|
|
313
|
+
this.entityDatasetVersionCache = _Caching.createAssetCache();
|
|
314
|
+
}
|
|
312
315
|
static {
|
|
313
316
|
this.unihexCache = _Caching.createAssetCache();
|
|
314
317
|
}
|
|
@@ -353,6 +356,7 @@ var init_Caching = __esm({
|
|
|
353
356
|
this.entityTextureCache,
|
|
354
357
|
this.entityAnimationCache,
|
|
355
358
|
this.blockEntityIndexCache,
|
|
359
|
+
this.entityDatasetVersionCache,
|
|
356
360
|
this.fontCache,
|
|
357
361
|
this.unihexCache,
|
|
358
362
|
this.bannerPatternCache,
|
|
@@ -3331,23 +3335,39 @@ var init_MinecraftCubeTexture = __esm({
|
|
|
3331
3335
|
}
|
|
3332
3336
|
});
|
|
3333
3337
|
|
|
3338
|
+
// src/assets/_versions/DatasetVersions.ts
|
|
3339
|
+
var parseRelease, compare2, nearestRelease;
|
|
3340
|
+
var init_DatasetVersions = __esm({
|
|
3341
|
+
"src/assets/_versions/DatasetVersions.ts"() {
|
|
3342
|
+
parseRelease = (value) => /^\d+\.\d+(?:\.\d+)?$/.test(value) ? value.split(".").map(Number) : void 0;
|
|
3343
|
+
compare2 = (left, right) => {
|
|
3344
|
+
for (let i = 0; i < 3; i++) {
|
|
3345
|
+
const difference = (left[i] ?? 0) - (right[i] ?? 0);
|
|
3346
|
+
if (difference) return difference;
|
|
3347
|
+
}
|
|
3348
|
+
return 0;
|
|
3349
|
+
};
|
|
3350
|
+
nearestRelease = (requestedVersion, published) => {
|
|
3351
|
+
const requested = parseRelease(requestedVersion);
|
|
3352
|
+
if (!requested) return void 0;
|
|
3353
|
+
const versions = published.map((name) => ({ name, number: parseRelease(name) })).filter((entry) => !!entry.number).sort((left, right) => compare2(left.number, right.number));
|
|
3354
|
+
const sameLine = versions.filter((entry) => entry.number[0] === requested[0] && entry.number[1] === requested[1]);
|
|
3355
|
+
const selected = sameLine.sort((left, right) => Math.abs((left.number[2] ?? 0) - (requested[2] ?? 0)) - Math.abs((right.number[2] ?? 0) - (requested[2] ?? 0)) || compare2(left.number, right.number))[0] ?? versions.filter((entry) => compare2(entry.number, requested) <= 0).pop() ?? versions[0];
|
|
3356
|
+
return selected?.name;
|
|
3357
|
+
};
|
|
3358
|
+
}
|
|
3359
|
+
});
|
|
3360
|
+
|
|
3334
3361
|
// src/assets/MineRenderData.ts
|
|
3335
|
-
var object2,
|
|
3362
|
+
var object2, MineRenderData;
|
|
3336
3363
|
var init_MineRenderData = __esm({
|
|
3337
3364
|
"src/assets/MineRenderData.ts"() {
|
|
3365
|
+
init_DatasetVersions();
|
|
3338
3366
|
init_AssetKey();
|
|
3339
3367
|
init_AssetLoader();
|
|
3340
3368
|
init_AssetParsers();
|
|
3341
3369
|
init_Caching();
|
|
3342
3370
|
object2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
3343
|
-
release = (value) => /^\d+\.\d+(?:\.\d+)?$/.test(value) ? value.split(".").map(Number) : void 0;
|
|
3344
|
-
compare2 = (left, right) => {
|
|
3345
|
-
for (let i = 0; i < 3; i++) {
|
|
3346
|
-
const difference = (left[i] ?? 0) - (right[i] ?? 0);
|
|
3347
|
-
if (difference) return difference;
|
|
3348
|
-
}
|
|
3349
|
-
return 0;
|
|
3350
|
-
};
|
|
3351
3371
|
MineRenderData = class {
|
|
3352
3372
|
/** Loads one registry. Missing files and invalid data reject the request. */
|
|
3353
3373
|
static async get(dataset, root) {
|
|
@@ -3377,9 +3397,9 @@ var init_MineRenderData = __esm({
|
|
|
3377
3397
|
const scope = AssetLoader.persistentScope;
|
|
3378
3398
|
return this.cached(`resolve:${requestRoot === void 0 ? "sources" : "explicit"}:${root}`, scope, defaultRoot, async () => {
|
|
3379
3399
|
const requestedVersion = root.slice(root.lastIndexOf("/") + 1);
|
|
3380
|
-
let manifest = await this.manifest(root, requestRoot !== void 0 &&
|
|
3400
|
+
let manifest = await this.manifest(root, requestRoot !== void 0 && parseRelease(requestedVersion) ? requestedVersion : void 0, requestRoot);
|
|
3381
3401
|
if (manifest) return { requestedVersion, version: manifest.minecraftVersion, root, manifest };
|
|
3382
|
-
const requested =
|
|
3402
|
+
const requested = parseRelease(requestedVersion);
|
|
3383
3403
|
if (!requested) {
|
|
3384
3404
|
throw new Error(`No MineRender data is published for ${requestedVersion}; automatic fallback requires a release`);
|
|
3385
3405
|
}
|
|
@@ -3391,14 +3411,12 @@ var init_MineRenderData = __esm({
|
|
|
3391
3411
|
}
|
|
3392
3412
|
return value.versions;
|
|
3393
3413
|
});
|
|
3394
|
-
const
|
|
3395
|
-
const sameLine = versions.filter((entry) => entry.number[0] === requested[0] && entry.number[1] === requested[1]);
|
|
3396
|
-
const selected = sameLine.sort((left, right) => Math.abs((left.number[2] ?? 0) - (requested[2] ?? 0)) - Math.abs((right.number[2] ?? 0) - (requested[2] ?? 0)) || compare2(left.number, right.number))[0] ?? versions.filter((entry) => compare2(entry.number, requested) <= 0).pop() ?? versions[0];
|
|
3414
|
+
const selected = nearestRelease(requestedVersion, index.map((entry) => entry.name));
|
|
3397
3415
|
if (!selected) throw new Error(`No compatible MineRender data is published for ${requestedVersion}`);
|
|
3398
|
-
const resolvedRoot = `${base}/${selected
|
|
3399
|
-
manifest = await this.manifest(resolvedRoot, selected
|
|
3400
|
-
if (!manifest) throw new Error(`Missing MineRender manifest for published version ${selected
|
|
3401
|
-
return { requestedVersion, version: selected
|
|
3416
|
+
const resolvedRoot = `${base}/${selected}`;
|
|
3417
|
+
manifest = await this.manifest(resolvedRoot, selected, resolvedRoot);
|
|
3418
|
+
if (!manifest) throw new Error(`Missing MineRender manifest for published version ${selected}`);
|
|
3419
|
+
return { requestedVersion, version: selected, root: resolvedRoot, manifest };
|
|
3402
3420
|
});
|
|
3403
3421
|
}
|
|
3404
3422
|
static async manifest(root, expectedVersion, requestRoot) {
|
|
@@ -4520,118 +4538,12 @@ var init_Biomes = __esm({
|
|
|
4520
4538
|
}
|
|
4521
4539
|
});
|
|
4522
4540
|
|
|
4523
|
-
// src/assets/BlockEntities.ts
|
|
4524
|
-
import { Matrix4 as Matrix42 } from "three";
|
|
4525
|
-
var log9, BlockEntities;
|
|
4526
|
-
var init_BlockEntities = __esm({
|
|
4527
|
-
"src/assets/BlockEntities.ts"() {
|
|
4528
|
-
init_AssetKey();
|
|
4529
|
-
init_AssetLoader();
|
|
4530
|
-
init_source();
|
|
4531
|
-
init_Caching();
|
|
4532
|
-
init_log();
|
|
4533
|
-
log9 = logger("BlockEntities");
|
|
4534
|
-
BlockEntities = class {
|
|
4535
|
-
/**
|
|
4536
|
-
* Loads the block index of a version. Versions and sources without one yield an empty index, and so does
|
|
4537
|
-
* a failed load: the index is optional, and blocks must not retry or fail with it one by one. The empty
|
|
4538
|
-
* result is cached like any other; `Caching.clear()` or `AssetLoader.setVersion()` forces a new attempt.
|
|
4539
|
-
*/
|
|
4540
|
-
static async getIndex(root) {
|
|
4541
|
-
const key = new AssetKey("entity-models", "blocks", void 0, void 0, void 0, ".json", root);
|
|
4542
|
-
key.rootType = void 0;
|
|
4543
|
-
const index = await Caching.blockEntityIndexCache.get(key.serialize(), async () => {
|
|
4544
|
-
try {
|
|
4545
|
-
return await AssetLoader.get(key, "json" /* JSON */) ?? {};
|
|
4546
|
-
} catch (error) {
|
|
4547
|
-
log9.warn("Could not load the block entity index; block entities are drawn as plain block models", error);
|
|
4548
|
-
return {};
|
|
4549
|
-
}
|
|
4550
|
-
});
|
|
4551
|
-
return index ?? {};
|
|
4552
|
-
}
|
|
4553
|
-
/** The index entry of a block ID such as `minecraft:chest`. */
|
|
4554
|
-
static entry(index, block) {
|
|
4555
|
-
const entry = Object.prototype.hasOwnProperty.call(index, block) ? index[block] : void 0;
|
|
4556
|
-
return Array.isArray(entry?.parts) ? entry : void 0;
|
|
4557
|
-
}
|
|
4558
|
-
/** Selects the parts and placement for a block ID such as `minecraft:chest`; undefined when nothing is drawn. */
|
|
4559
|
-
static resolve(index, block, state = {}) {
|
|
4560
|
-
const entry = this.entry(index, block);
|
|
4561
|
-
if (!entry) return void 0;
|
|
4562
|
-
const value = (property) => String(state[property]).toLowerCase();
|
|
4563
|
-
const parts = entry.parts.filter((part) => Object.entries(part.when ?? {}).every(([property, values]) => String(values).split("|").includes(value(property))));
|
|
4564
|
-
if (!parts.length) return void 0;
|
|
4565
|
-
let rotation = 0;
|
|
4566
|
-
if (entry.rotation) {
|
|
4567
|
-
const selected = value(entry.rotation.property);
|
|
4568
|
-
rotation = "degrees" in entry.rotation ? entry.rotation.degrees[selected] : Number(selected) * entry.rotation.step;
|
|
4569
|
-
if (!Number.isFinite(rotation)) rotation = 0;
|
|
4570
|
-
}
|
|
4571
|
-
return { parts, rotation, translation: entry.translation ?? [0, 0, 0] };
|
|
4572
|
-
}
|
|
4573
|
-
/** Placement in block space (0..16 per axis), applied on top of the model's own transform. */
|
|
4574
|
-
static matrix(resolved, matrix = new Matrix42()) {
|
|
4575
|
-
return matrix.makeTranslation(8, 0, 8).multiply(new Matrix42().makeRotationY(resolved.rotation * Math.PI / 180)).multiply(new Matrix42().makeTranslation(resolved.translation[0] - 8, resolved.translation[1], resolved.translation[2] - 8));
|
|
4576
|
-
}
|
|
4577
|
-
};
|
|
4578
|
-
}
|
|
4579
|
-
});
|
|
4580
|
-
|
|
4581
|
-
// src/assets/DecoratedPots.ts
|
|
4582
|
-
var POTTERY_SHERDS, DecoratedPots;
|
|
4583
|
-
var init_DecoratedPots = __esm({
|
|
4584
|
-
"src/assets/DecoratedPots.ts"() {
|
|
4585
|
-
init_AssetKey();
|
|
4586
|
-
POTTERY_SHERDS = Object.freeze([
|
|
4587
|
-
"angler",
|
|
4588
|
-
"archer",
|
|
4589
|
-
"arms_up",
|
|
4590
|
-
"blade",
|
|
4591
|
-
"brewer",
|
|
4592
|
-
"burn",
|
|
4593
|
-
"danger",
|
|
4594
|
-
"explorer",
|
|
4595
|
-
"flow",
|
|
4596
|
-
"friend",
|
|
4597
|
-
"guster",
|
|
4598
|
-
"heart",
|
|
4599
|
-
"heartbreak",
|
|
4600
|
-
"howl",
|
|
4601
|
-
"miner",
|
|
4602
|
-
"mourner",
|
|
4603
|
-
"plenty",
|
|
4604
|
-
"prize",
|
|
4605
|
-
"scrape",
|
|
4606
|
-
"sheaf",
|
|
4607
|
-
"shelter",
|
|
4608
|
-
"skull",
|
|
4609
|
-
"snort"
|
|
4610
|
-
].map((pattern2) => `minecraft:${pattern2}_pottery_sherd`));
|
|
4611
|
-
DecoratedPots = class {
|
|
4612
|
-
/** Reads up to four item IDs in back, left, right, front order; missing and unmapped items use plain sides. */
|
|
4613
|
-
static getSideTextures(value, root) {
|
|
4614
|
-
const items = value === void 0 ? [] : value;
|
|
4615
|
-
if (!Array.isArray(items) || items.length > 4) throw new Error("pot_decorations must be an array of at most four item IDs");
|
|
4616
|
-
const textures = items.map((item) => {
|
|
4617
|
-
if (!isResourceLocation(item)) throw new Error("Pot decorations must be item identifiers");
|
|
4618
|
-
const id = item.includes(":") ? item : `minecraft:${item}`;
|
|
4619
|
-
return POTTERY_SHERDS.includes(id) ? id.slice("minecraft:".length).replace(/_sherd$/, "_pattern") : "decorated_pot_side";
|
|
4620
|
-
});
|
|
4621
|
-
return Object.fromEntries(["back", "left", "right", "front"].map((side, index) => [
|
|
4622
|
-
side,
|
|
4623
|
-
new AssetKey("minecraft", `decorated_pot/${textures[index] ?? "decorated_pot_side"}`, "textures", "entity", "assets", ".png", root)
|
|
4624
|
-
]));
|
|
4625
|
-
}
|
|
4626
|
-
};
|
|
4627
|
-
}
|
|
4628
|
-
});
|
|
4629
|
-
|
|
4630
4541
|
// src/assets/Entities.ts
|
|
4631
4542
|
var Entities;
|
|
4632
4543
|
var init_Entities = __esm({
|
|
4633
4544
|
"src/assets/Entities.ts"() {
|
|
4634
4545
|
init_AssetKey();
|
|
4546
|
+
init_DatasetVersions();
|
|
4635
4547
|
init_AssetLoader();
|
|
4636
4548
|
init_source();
|
|
4637
4549
|
init_Caching();
|
|
@@ -4639,11 +4551,36 @@ var init_Entities = __esm({
|
|
|
4639
4551
|
init_MineRenderError();
|
|
4640
4552
|
init_ModelTextures();
|
|
4641
4553
|
Entities = class {
|
|
4554
|
+
/**
|
|
4555
|
+
* Resolves `root` (default: the active version). Uses the exact dataset when published or when the
|
|
4556
|
+
* version is not a release; otherwise selects the nearest published release, like {@link MineRenderData.resolve}.
|
|
4557
|
+
* Textures keep the requested root.
|
|
4558
|
+
*/
|
|
4559
|
+
static async getDatasetRoot(root) {
|
|
4560
|
+
const requestRoot = (root ?? AssetLoader.ROOT).replace(/\/+$/, "");
|
|
4561
|
+
const requestedVersion = requestRoot.slice(requestRoot.lastIndexOf("/") + 1);
|
|
4562
|
+
const base = requestRoot.slice(0, requestRoot.lastIndexOf("/"));
|
|
4563
|
+
const selected = await Caching.entityDatasetVersionCache.get(root ?? `sources:${AssetLoader.ROOT}`, async () => {
|
|
4564
|
+
const key = new AssetKey("entity-models", "version", void 0, void 0, void 0, ".json", root);
|
|
4565
|
+
key.rootType = void 0;
|
|
4566
|
+
if (!parseRelease(requestedVersion) || await AssetLoader.get(key, "json" /* JSON */) !== void 0) return requestedVersion;
|
|
4567
|
+
const indexKey = new AssetKey("entity-models", "versions", void 0, void 0, void 0, ".json", base);
|
|
4568
|
+
indexKey.rootType = void 0;
|
|
4569
|
+
const index = await AssetLoader.get(indexKey, "json" /* JSON */);
|
|
4570
|
+
if (index === void 0) return requestedVersion;
|
|
4571
|
+
if (!index || typeof index !== "object" || Array.isArray(index) || !Array.isArray(index.versions) || !index.versions.every((entry) => entry && typeof entry === "object" && !Array.isArray(entry) && typeof entry.name === "string")) {
|
|
4572
|
+
throw new MineRenderError(`Invalid entity model version index at ${base}/entity-models/versions.json`);
|
|
4573
|
+
}
|
|
4574
|
+
return nearestRelease(requestedVersion, index.versions.map((entry) => entry.name)) ?? requestedVersion;
|
|
4575
|
+
});
|
|
4576
|
+
return selected === requestedVersion ? root : `${base}/${selected}`;
|
|
4577
|
+
}
|
|
4642
4578
|
/** Lists model paths in the `minecraft` namespace, including subdirectories and excluding `.json`. */
|
|
4643
4579
|
static async getEntityList() {
|
|
4580
|
+
const root = await this.getDatasetRoot();
|
|
4644
4581
|
const collect = async (path) => {
|
|
4645
4582
|
const prefix2 = path ? `${path}/` : "";
|
|
4646
|
-
const key = new AssetKey(DEFAULT_NAMESPACE, `${prefix2}_list`, void 0, void 0, "entity-models", ".json");
|
|
4583
|
+
const key = new AssetKey(DEFAULT_NAMESPACE, `${prefix2}_list`, void 0, void 0, "entity-models", ".json", root);
|
|
4647
4584
|
const list2 = await Caching.listAssetCache.get(key.serialize(), () => AssetLoader.get(key, "list" /* LIST */));
|
|
4648
4585
|
if (!list2) return [];
|
|
4649
4586
|
const files = list2.files.filter((file) => file.endsWith(".json") && file !== "_list.json").map((file) => `${prefix2}${file.slice(0, -5)}`);
|
|
@@ -4654,7 +4591,7 @@ var init_Entities = __esm({
|
|
|
4654
4591
|
}
|
|
4655
4592
|
static async getModelFile(modelKey) {
|
|
4656
4593
|
const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
|
|
4657
|
-
const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models", ".json", isAssetKey(modelKey) ? modelKey.root : void 0);
|
|
4594
|
+
const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models", ".json", await this.getDatasetRoot(isAssetKey(modelKey) ? modelKey.root : void 0));
|
|
4658
4595
|
return Caching.entityModelCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
|
|
4659
4596
|
}
|
|
4660
4597
|
/** Returns selectable geometry-layer names, or an empty list when the model is missing. */
|
|
@@ -4715,7 +4652,7 @@ var init_Entities = __esm({
|
|
|
4715
4652
|
*/
|
|
4716
4653
|
static async getAnimations(modelKey) {
|
|
4717
4654
|
const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
|
|
4718
|
-
const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models/animations", ".json", isAssetKey(modelKey) ? modelKey.root : void 0);
|
|
4655
|
+
const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models/animations", ".json", await this.getDatasetRoot(isAssetKey(modelKey) ? modelKey.root : void 0));
|
|
4719
4656
|
const file = await Caching.entityAnimationCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
|
|
4720
4657
|
return file?.animations;
|
|
4721
4658
|
}
|
|
@@ -4757,6 +4694,115 @@ var init_Entities = __esm({
|
|
|
4757
4694
|
}
|
|
4758
4695
|
});
|
|
4759
4696
|
|
|
4697
|
+
// src/assets/BlockEntities.ts
|
|
4698
|
+
import { Matrix4 as Matrix42 } from "three";
|
|
4699
|
+
var log9, BlockEntities;
|
|
4700
|
+
var init_BlockEntities = __esm({
|
|
4701
|
+
"src/assets/BlockEntities.ts"() {
|
|
4702
|
+
init_AssetKey();
|
|
4703
|
+
init_Entities();
|
|
4704
|
+
init_AssetLoader();
|
|
4705
|
+
init_source();
|
|
4706
|
+
init_Caching();
|
|
4707
|
+
init_log();
|
|
4708
|
+
log9 = logger("BlockEntities");
|
|
4709
|
+
BlockEntities = class {
|
|
4710
|
+
/**
|
|
4711
|
+
* Loads the block index of a version. Versions and sources without one yield an empty index, and so does
|
|
4712
|
+
* a failed load: the index is optional, and blocks must not retry or fail with it one by one. The empty
|
|
4713
|
+
* result is cached like any other; `Caching.clear()` or `AssetLoader.setVersion()` forces a new attempt.
|
|
4714
|
+
*/
|
|
4715
|
+
static async getIndex(root) {
|
|
4716
|
+
const key = new AssetKey("entity-models", "blocks", void 0, void 0, void 0, ".json", root);
|
|
4717
|
+
key.rootType = void 0;
|
|
4718
|
+
const index = await Caching.blockEntityIndexCache.get(key.serialize(), async () => {
|
|
4719
|
+
try {
|
|
4720
|
+
key.root = await Entities.getDatasetRoot(root);
|
|
4721
|
+
return await AssetLoader.get(key, "json" /* JSON */) ?? {};
|
|
4722
|
+
} catch (error) {
|
|
4723
|
+
log9.warn("Could not load the block entity index; block entities are drawn as plain block models", error);
|
|
4724
|
+
return {};
|
|
4725
|
+
}
|
|
4726
|
+
});
|
|
4727
|
+
return index ?? {};
|
|
4728
|
+
}
|
|
4729
|
+
/** The index entry of a block ID such as `minecraft:chest`. */
|
|
4730
|
+
static entry(index, block) {
|
|
4731
|
+
const entry = Object.prototype.hasOwnProperty.call(index, block) ? index[block] : void 0;
|
|
4732
|
+
return Array.isArray(entry?.parts) ? entry : void 0;
|
|
4733
|
+
}
|
|
4734
|
+
/** Selects the parts and placement for a block ID such as `minecraft:chest`; undefined when nothing is drawn. */
|
|
4735
|
+
static resolve(index, block, state = {}) {
|
|
4736
|
+
const entry = this.entry(index, block);
|
|
4737
|
+
if (!entry) return void 0;
|
|
4738
|
+
const value = (property) => String(state[property]).toLowerCase();
|
|
4739
|
+
const parts = entry.parts.filter((part) => Object.entries(part.when ?? {}).every(([property, values]) => String(values).split("|").includes(value(property))));
|
|
4740
|
+
if (!parts.length) return void 0;
|
|
4741
|
+
let rotation = 0;
|
|
4742
|
+
if (entry.rotation) {
|
|
4743
|
+
const selected = value(entry.rotation.property);
|
|
4744
|
+
rotation = "degrees" in entry.rotation ? entry.rotation.degrees[selected] : Number(selected) * entry.rotation.step;
|
|
4745
|
+
if (!Number.isFinite(rotation)) rotation = 0;
|
|
4746
|
+
}
|
|
4747
|
+
return { parts, rotation, translation: entry.translation ?? [0, 0, 0] };
|
|
4748
|
+
}
|
|
4749
|
+
/** Placement in block space (0..16 per axis), applied on top of the model's own transform. */
|
|
4750
|
+
static matrix(resolved, matrix = new Matrix42()) {
|
|
4751
|
+
return matrix.makeTranslation(8, 0, 8).multiply(new Matrix42().makeRotationY(resolved.rotation * Math.PI / 180)).multiply(new Matrix42().makeTranslation(resolved.translation[0] - 8, resolved.translation[1], resolved.translation[2] - 8));
|
|
4752
|
+
}
|
|
4753
|
+
};
|
|
4754
|
+
}
|
|
4755
|
+
});
|
|
4756
|
+
|
|
4757
|
+
// src/assets/DecoratedPots.ts
|
|
4758
|
+
var POTTERY_SHERDS, DecoratedPots;
|
|
4759
|
+
var init_DecoratedPots = __esm({
|
|
4760
|
+
"src/assets/DecoratedPots.ts"() {
|
|
4761
|
+
init_AssetKey();
|
|
4762
|
+
POTTERY_SHERDS = Object.freeze([
|
|
4763
|
+
"angler",
|
|
4764
|
+
"archer",
|
|
4765
|
+
"arms_up",
|
|
4766
|
+
"blade",
|
|
4767
|
+
"brewer",
|
|
4768
|
+
"burn",
|
|
4769
|
+
"danger",
|
|
4770
|
+
"explorer",
|
|
4771
|
+
"flow",
|
|
4772
|
+
"friend",
|
|
4773
|
+
"guster",
|
|
4774
|
+
"heart",
|
|
4775
|
+
"heartbreak",
|
|
4776
|
+
"howl",
|
|
4777
|
+
"miner",
|
|
4778
|
+
"mourner",
|
|
4779
|
+
"plenty",
|
|
4780
|
+
"prize",
|
|
4781
|
+
"scrape",
|
|
4782
|
+
"sheaf",
|
|
4783
|
+
"shelter",
|
|
4784
|
+
"skull",
|
|
4785
|
+
"snort"
|
|
4786
|
+
].map((pattern2) => `minecraft:${pattern2}_pottery_sherd`));
|
|
4787
|
+
DecoratedPots = class {
|
|
4788
|
+
/** Reads up to four item IDs in back, left, right, front order; missing and unmapped items use plain sides. */
|
|
4789
|
+
static getSideTextures(value, root) {
|
|
4790
|
+
const items = value === void 0 ? [] : value;
|
|
4791
|
+
if (!Array.isArray(items) || items.length > 4) throw new Error("pot_decorations must be an array of at most four item IDs");
|
|
4792
|
+
const textures = items.map((item) => {
|
|
4793
|
+
if (!isResourceLocation(item)) throw new Error("Pot decorations must be item identifiers");
|
|
4794
|
+
const id = item.includes(":") ? item : `minecraft:${item}`;
|
|
4795
|
+
return POTTERY_SHERDS.includes(id) ? id.slice("minecraft:".length).replace(/_sherd$/, "_pattern") : "decorated_pot_side";
|
|
4796
|
+
});
|
|
4797
|
+
return Object.fromEntries(["back", "left", "right", "front"].map((side, index) => [
|
|
4798
|
+
side,
|
|
4799
|
+
new AssetKey("minecraft", `decorated_pot/${textures[index] ?? "decorated_pot_side"}`, "textures", "entity", "assets", ".png", root)
|
|
4800
|
+
]));
|
|
4801
|
+
}
|
|
4802
|
+
};
|
|
4803
|
+
}
|
|
4804
|
+
});
|
|
4805
|
+
|
|
4760
4806
|
// src/assets/_fonts/Unihex.ts
|
|
4761
4807
|
var Unihex_exports = {};
|
|
4762
4808
|
__export(Unihex_exports, {
|
|
@@ -17835,7 +17881,7 @@ var AnvilWorldSource = class {
|
|
|
17835
17881
|
read.waiters++;
|
|
17836
17882
|
return new Promise((resolve, reject) => {
|
|
17837
17883
|
let finished = false;
|
|
17838
|
-
const
|
|
17884
|
+
const release = () => {
|
|
17839
17885
|
if (finished) return false;
|
|
17840
17886
|
finished = true;
|
|
17841
17887
|
signal?.removeEventListener("abort", abort);
|
|
@@ -17843,7 +17889,7 @@ var AnvilWorldSource = class {
|
|
|
17843
17889
|
return true;
|
|
17844
17890
|
};
|
|
17845
17891
|
const abort = () => {
|
|
17846
|
-
if (!
|
|
17892
|
+
if (!release()) return;
|
|
17847
17893
|
if (!read.waiters && !read.settled) {
|
|
17848
17894
|
if (this.pending.get(key) === read) this.pending.delete(key);
|
|
17849
17895
|
read.controller.abort(signal.reason);
|
|
@@ -17853,10 +17899,10 @@ var AnvilWorldSource = class {
|
|
|
17853
17899
|
signal?.addEventListener("abort", abort, { once: true });
|
|
17854
17900
|
read.promise.then(
|
|
17855
17901
|
(data) => {
|
|
17856
|
-
if (
|
|
17902
|
+
if (release()) resolve(data);
|
|
17857
17903
|
},
|
|
17858
17904
|
(error) => {
|
|
17859
|
-
if (
|
|
17905
|
+
if (release()) reject(error);
|
|
17860
17906
|
}
|
|
17861
17907
|
);
|
|
17862
17908
|
if (signal?.aborted) abort();
|
|
@@ -17878,7 +17924,7 @@ var AnvilWorldSource = class {
|
|
|
17878
17924
|
};
|
|
17879
17925
|
|
|
17880
17926
|
// src/world/Chunk.ts
|
|
17881
|
-
import { Color as Color13, Vector3 as
|
|
17927
|
+
import { Color as Color13, Vector3 as Vector321 } from "three";
|
|
17882
17928
|
init_BlockStates();
|
|
17883
17929
|
init_AssetKey();
|
|
17884
17930
|
|
|
@@ -19138,7 +19184,7 @@ init_BlockEntities();
|
|
|
19138
19184
|
// src/world/SectionMesh.ts
|
|
19139
19185
|
init_CanvasCompat();
|
|
19140
19186
|
init_Materials();
|
|
19141
|
-
import { BufferGeometry as BufferGeometry9, Color as Color12, DoubleSide as DoubleSide8, Float32BufferAttribute as Float32BufferAttribute10, FrontSide as FrontSide4, Group as Group3, Mesh as Mesh12, Uint32BufferAttribute } from "three";
|
|
19187
|
+
import { BufferGeometry as BufferGeometry9, Color as Color12, DoubleSide as DoubleSide8, DynamicDrawUsage, Float32BufferAttribute as Float32BufferAttribute10, FrontSide as FrontSide4, Group as Group3, Matrix4 as Matrix413, Mesh as Mesh12, Uint32BufferAttribute, Vector3 as Vector320 } from "three";
|
|
19142
19188
|
|
|
19143
19189
|
// src/world/SectionGeometry.ts
|
|
19144
19190
|
init_FluidQuads();
|
|
@@ -19465,6 +19511,9 @@ var SectionWorker = class _SectionWorker {
|
|
|
19465
19511
|
};
|
|
19466
19512
|
|
|
19467
19513
|
// src/world/SectionMesh.ts
|
|
19514
|
+
var BLOCK_SIZE = 16;
|
|
19515
|
+
var QUAD_VERTICES = 4;
|
|
19516
|
+
var QUAD_INDICES = 6;
|
|
19468
19517
|
var templateCache = /* @__PURE__ */ new WeakMap();
|
|
19469
19518
|
var WATER_TINT = new Color12(4159204).toArray();
|
|
19470
19519
|
function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
@@ -19501,8 +19550,8 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19501
19550
|
if (!data) {
|
|
19502
19551
|
const indices = template.geometry.getIndex();
|
|
19503
19552
|
const position = template.geometry.getAttribute("position");
|
|
19504
|
-
const quads = indices.count /
|
|
19505
|
-
if (indices.count %
|
|
19553
|
+
const quads = indices.count / QUAD_INDICES;
|
|
19554
|
+
if (indices.count % QUAD_INDICES !== 0 || position.count !== quads * QUAD_VERTICES) {
|
|
19506
19555
|
throw new RangeError("Section template geometry must hold four vertices and six indices per quad");
|
|
19507
19556
|
}
|
|
19508
19557
|
data = {
|
|
@@ -19512,8 +19561,8 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19512
19561
|
uvs: new Float32Array(quads * 8),
|
|
19513
19562
|
uvBounds: new Float32Array(quads * 16),
|
|
19514
19563
|
colors: new Float32Array(quads * 12),
|
|
19515
|
-
shade: new Float32Array(quads *
|
|
19516
|
-
indices: new Uint16Array(quads *
|
|
19564
|
+
shade: new Float32Array(quads * QUAD_VERTICES),
|
|
19565
|
+
indices: new Uint16Array(quads * QUAD_INDICES),
|
|
19517
19566
|
cullFaces: new Uint8Array(template.cullFaces),
|
|
19518
19567
|
biomeTint: template.biomeTint ? new Uint8Array(template.biomeTint) : void 0,
|
|
19519
19568
|
atlas: 0,
|
|
@@ -19525,7 +19574,7 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19525
19574
|
const bounds = template.geometry.getAttribute("uvBounds");
|
|
19526
19575
|
const color2 = template.geometry.getAttribute("color");
|
|
19527
19576
|
const shade = template.geometry.getAttribute("shade");
|
|
19528
|
-
for (let vertex = 0; vertex < quads *
|
|
19577
|
+
for (let vertex = 0; vertex < quads * QUAD_VERTICES; vertex++) {
|
|
19529
19578
|
data.positions.set([position.getX(vertex), position.getY(vertex), position.getZ(vertex)], vertex * 3);
|
|
19530
19579
|
data.normals.set([normal.getX(vertex), normal.getY(vertex), normal.getZ(vertex)], vertex * 3);
|
|
19531
19580
|
data.uvs.set([uv.getX(vertex), uv.getY(vertex)], vertex * 2);
|
|
@@ -19538,7 +19587,7 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19538
19587
|
data.colors.set([color2?.getX(vertex) ?? 1, color2?.getY(vertex) ?? 1, color2?.getZ(vertex) ?? 1], vertex * 3);
|
|
19539
19588
|
data.shade[vertex] = shade?.getX(vertex) ?? 1;
|
|
19540
19589
|
}
|
|
19541
|
-
for (let i2 = 0; i2 < data.indices.length; i2++) data.indices[i2] = indices.getX(i2) -
|
|
19590
|
+
for (let i2 = 0; i2 < data.indices.length; i2++) data.indices[i2] = indices.getX(i2) - QUAD_VERTICES * Math.floor(i2 / QUAD_INDICES);
|
|
19542
19591
|
templateCache.set(template, data);
|
|
19543
19592
|
}
|
|
19544
19593
|
id = input.templateData.length;
|
|
@@ -19571,6 +19620,54 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19571
19620
|
}
|
|
19572
19621
|
return { input, atlases: atlases2 };
|
|
19573
19622
|
}
|
|
19623
|
+
function sortTransparentQuads(mesh) {
|
|
19624
|
+
const index = mesh.geometry.getIndex();
|
|
19625
|
+
if (index.count <= QUAD_INDICES) return;
|
|
19626
|
+
index.setUsage(DynamicDrawUsage);
|
|
19627
|
+
const count = index.count / QUAD_INDICES;
|
|
19628
|
+
let source, centers, depths, order;
|
|
19629
|
+
const view = new Matrix413(), localCamera = new Vector320(), key = new Vector320(), previous = new Vector320();
|
|
19630
|
+
let previousOrthographic;
|
|
19631
|
+
mesh.onBeforeRender = (_renderer, _scene, camera) => {
|
|
19632
|
+
localCamera.setFromMatrixPosition(camera.matrixWorld).applyMatrix4(view.copy(mesh.matrixWorld).invert());
|
|
19633
|
+
const orthographic = !!camera.isOrthographicCamera;
|
|
19634
|
+
if (orthographic) {
|
|
19635
|
+
view.multiplyMatrices(camera.matrixWorldInverse, mesh.matrixWorld);
|
|
19636
|
+
key.set(view.elements[2], view.elements[6], view.elements[10]);
|
|
19637
|
+
} else {
|
|
19638
|
+
key.copy(localCamera).divideScalar(BLOCK_SIZE).floor();
|
|
19639
|
+
}
|
|
19640
|
+
if (orthographic === previousOrthographic && key.equals(previous)) return;
|
|
19641
|
+
previous.copy(key);
|
|
19642
|
+
previousOrthographic = orthographic;
|
|
19643
|
+
if (!centers) {
|
|
19644
|
+
source = new Uint32Array(index.array);
|
|
19645
|
+
centers = new Float32Array(count * 3);
|
|
19646
|
+
depths = new Float32Array(count);
|
|
19647
|
+
order = Uint32Array.from({ length: count }, (_, quad) => quad);
|
|
19648
|
+
const positions = mesh.geometry.getAttribute("position");
|
|
19649
|
+
for (let quad = 0; quad < count; quad++) {
|
|
19650
|
+
for (let axis = 0; axis < 3; axis++) {
|
|
19651
|
+
let center = 0;
|
|
19652
|
+
for (let corner = 0; corner < QUAD_VERTICES; corner++) center += positions.getComponent(quad * QUAD_VERTICES + corner, axis);
|
|
19653
|
+
centers[quad * 3 + axis] = center / QUAD_VERTICES;
|
|
19654
|
+
}
|
|
19655
|
+
}
|
|
19656
|
+
}
|
|
19657
|
+
for (let quad = 0; quad < count; quad++) {
|
|
19658
|
+
const x = centers[quad * 3], y = centers[quad * 3 + 1], z = centers[quad * 3 + 2];
|
|
19659
|
+
depths[quad] = orthographic ? key.x * x + key.y * y + key.z * z : -((x - localCamera.x) ** 2 + (y - localCamera.y) ** 2 + (z - localCamera.z) ** 2);
|
|
19660
|
+
}
|
|
19661
|
+
order.sort((a, b) => depths[a] - depths[b] || a - b);
|
|
19662
|
+
if (!order.some((quad, offset) => index.array[offset * QUAD_INDICES] !== source[quad * QUAD_INDICES])) return;
|
|
19663
|
+
for (let offset = 0; offset < count; offset++) {
|
|
19664
|
+
for (let indexOffset = 0; indexOffset < QUAD_INDICES; indexOffset++) {
|
|
19665
|
+
index.array[offset * QUAD_INDICES + indexOffset] = source[order[offset] * QUAD_INDICES + indexOffset];
|
|
19666
|
+
}
|
|
19667
|
+
}
|
|
19668
|
+
index.needsUpdate = true;
|
|
19669
|
+
};
|
|
19670
|
+
}
|
|
19574
19671
|
var SectionMesh = class _SectionMesh extends Group3 {
|
|
19575
19672
|
constructor() {
|
|
19576
19673
|
super(...arguments);
|
|
@@ -19580,7 +19677,11 @@ var SectionMesh = class _SectionMesh extends Group3 {
|
|
|
19580
19677
|
/** Returns the owning section cell for a triangle hit on this mesh's merged geometry. */
|
|
19581
19678
|
getBlockIndex(hit) {
|
|
19582
19679
|
if (hit.faceIndex === void 0 || hit.faceIndex === null) return void 0;
|
|
19583
|
-
|
|
19680
|
+
const mesh = hit.object;
|
|
19681
|
+
const owners = this.blockIndices.get(mesh);
|
|
19682
|
+
if (!owners) return void 0;
|
|
19683
|
+
const vertex = mesh.geometry.getIndex().getX(hit.faceIndex * 3);
|
|
19684
|
+
return owners[Math.floor(vertex / QUAD_VERTICES)];
|
|
19584
19685
|
}
|
|
19585
19686
|
/** Builds section-local meshes from visible quads. `maxAtlasSize` limits each atlas dimension in pixels. */
|
|
19586
19687
|
static build(entries, maxAtlasSize = 2048, fluids, lighting) {
|
|
@@ -19616,13 +19717,14 @@ var SectionMesh = class _SectionMesh extends Group3 {
|
|
|
19616
19717
|
const material = Materials.createShadedCanvasMaterial(canvas, transparent, false, true);
|
|
19617
19718
|
material.side = FrontSide4;
|
|
19618
19719
|
if (page.layer === 2) {
|
|
19720
|
+
material.depthWrite = !material.transparent;
|
|
19619
19721
|
material.side = DoubleSide8;
|
|
19620
19722
|
material.forceSinglePass = true;
|
|
19621
|
-
material.depthWrite = !material.transparent;
|
|
19622
19723
|
}
|
|
19623
19724
|
material.vertexColors = true;
|
|
19624
19725
|
const texture = material.uniforms?.map?.value ?? material.map;
|
|
19625
19726
|
const mesh = new Mesh12(geometry, material);
|
|
19727
|
+
if (transparent) sortTransparentQuads(mesh);
|
|
19626
19728
|
section.add(mesh);
|
|
19627
19729
|
section.blockIndices.set(mesh, page.blockIndices);
|
|
19628
19730
|
const unsubscribe = [];
|
|
@@ -19681,7 +19783,7 @@ var Chunk = class _Chunk {
|
|
|
19681
19783
|
this.sectionBlocks = /* @__PURE__ */ new Map();
|
|
19682
19784
|
this.hiddenBlocks = /* @__PURE__ */ new Set();
|
|
19683
19785
|
this.fluidCells = new Uint8Array(4096);
|
|
19684
|
-
this.blockPosition = new
|
|
19786
|
+
this.blockPosition = new Vector321();
|
|
19685
19787
|
this.meshDirty = false;
|
|
19686
19788
|
this.meshGeneration = 0;
|
|
19687
19789
|
this.blockChanges = /* @__PURE__ */ new Set();
|
|
@@ -19741,7 +19843,7 @@ var Chunk = class _Chunk {
|
|
|
19741
19843
|
const info = owner.chunk.renderedBlocks.get(owner.index);
|
|
19742
19844
|
if (!info) continue;
|
|
19743
19845
|
return {
|
|
19744
|
-
position: new
|
|
19846
|
+
position: new Vector321(
|
|
19745
19847
|
owner.chunk.x * 16 + owner.index % 16,
|
|
19746
19848
|
owner.chunk.y * 16 + Math.floor(owner.index / 256),
|
|
19747
19849
|
owner.chunk.z * 16 + Math.floor(owner.index / 16) % 16
|
|
@@ -19756,18 +19858,18 @@ var Chunk = class _Chunk {
|
|
|
19756
19858
|
}
|
|
19757
19859
|
getBlockAt(posOrX, y, z) {
|
|
19758
19860
|
if (typeof posOrX == "number") {
|
|
19759
|
-
return this.getBlockAt(new
|
|
19861
|
+
return this.getBlockAt(new Vector321(posOrX, y, z));
|
|
19760
19862
|
}
|
|
19761
19863
|
if (isTripleArray(posOrX)) {
|
|
19762
|
-
return this.getBlockAt(new
|
|
19864
|
+
return this.getBlockAt(new Vector321(posOrX[0], posOrX[1], posOrX[2]));
|
|
19763
19865
|
}
|
|
19764
19866
|
const pos = this.blockPosition.set(posOrX.x - this.x * 16, posOrX.y - this.y * 16, posOrX.z - this.z * 16);
|
|
19765
19867
|
const index = _Chunk.chunkPosToBlockIndex(pos);
|
|
19766
19868
|
return this.renderedBlocks.get(index);
|
|
19767
19869
|
}
|
|
19768
19870
|
getBiomeAt(posOrX, y, z) {
|
|
19769
|
-
if (typeof posOrX === "number") return this.getBiomeAt(new
|
|
19770
|
-
if (isTripleArray(posOrX)) return this.getBiomeAt(new
|
|
19871
|
+
if (typeof posOrX === "number") return this.getBiomeAt(new Vector321(posOrX, y, z));
|
|
19872
|
+
if (isTripleArray(posOrX)) return this.getBiomeAt(new Vector321(...posOrX));
|
|
19771
19873
|
const pos = this.worldPosToChunkPos(posOrX);
|
|
19772
19874
|
_Chunk.chunkPosToBlockIndex(pos);
|
|
19773
19875
|
return this.biomeAt ? this.biomeAt(posOrX.x, posOrX.y, posOrX.z) : this.biomes?.[Math.floor(pos.x / 4) + Math.floor(pos.z / 4) * 4 + Math.floor(pos.y / 4) * 16];
|
|
@@ -19845,17 +19947,17 @@ var Chunk = class _Chunk {
|
|
|
19845
19947
|
this.hiddenBlocks.add(index);
|
|
19846
19948
|
this.renderedBlocks.get(index)?.object?.setVisible(false);
|
|
19847
19949
|
}
|
|
19848
|
-
const positions = blocks.map(({ index }) => new
|
|
19950
|
+
const positions = blocks.map(({ index }) => new Vector321(...this.positionAt(index)));
|
|
19849
19951
|
if (this.onBlocksChanged) await this.onBlocksChanged(positions, deferCulling);
|
|
19850
19952
|
else await this.rebuildSectionMesh();
|
|
19851
19953
|
}
|
|
19852
19954
|
}
|
|
19853
19955
|
async setBlockAt(posOrX, yOrBlock, z, block) {
|
|
19854
19956
|
if (typeof posOrX == "number") {
|
|
19855
|
-
return this.setBlockAt(new
|
|
19957
|
+
return this.setBlockAt(new Vector321(posOrX, yOrBlock, z), block);
|
|
19856
19958
|
}
|
|
19857
19959
|
if (isTripleArray(posOrX)) {
|
|
19858
|
-
return this.setBlockAt(new
|
|
19960
|
+
return this.setBlockAt(new Vector321(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
|
|
19859
19961
|
}
|
|
19860
19962
|
const worldPos = posOrX;
|
|
19861
19963
|
const pos = this.worldPosToChunkPos(worldPos);
|
|
@@ -19928,7 +20030,7 @@ var Chunk = class _Chunk {
|
|
|
19928
20030
|
this.fluidCells[index] = 0;
|
|
19929
20031
|
this.renderedBlocks.delete(index);
|
|
19930
20032
|
this.objectBlocks.delete(index);
|
|
19931
|
-
const worldPos = new
|
|
20033
|
+
const worldPos = new Vector321(
|
|
19932
20034
|
this.x * 16 + index % 16,
|
|
19933
20035
|
this.y * 16 + Math.floor(index / 256),
|
|
19934
20036
|
this.z * 16 + Math.floor(index / 16) % 16
|
|
@@ -20066,7 +20168,7 @@ var Chunk = class _Chunk {
|
|
|
20066
20168
|
biome,
|
|
20067
20169
|
biomePosition: this.biomePosition(index, blockState3, this.data.stateAt(this.data.idAt(index)))
|
|
20068
20170
|
});
|
|
20069
|
-
object4.setPosition(new
|
|
20171
|
+
object4.setPosition(new Vector321(
|
|
20070
20172
|
this.x * 256 + index % 16 * 16,
|
|
20071
20173
|
this.y * 256 + Math.floor(index / 256) * 16,
|
|
20072
20174
|
this.z * 256 + Math.floor(index / 16) % 16 * 16
|
|
@@ -20373,7 +20475,7 @@ var Chunk = class _Chunk {
|
|
|
20373
20475
|
async clear(notify = true) {
|
|
20374
20476
|
if (this.blockChanges.size) await Promise.allSettled(this.blockChanges);
|
|
20375
20477
|
const positions = notify && this.onBlocksChanged ? [...this.renderedBlocks.keys()].map((index) => this.chunkPosToWorldPos(
|
|
20376
|
-
new
|
|
20478
|
+
new Vector321(index % 16, Math.floor(index / 256), Math.floor(index / 16) % 16)
|
|
20377
20479
|
)) : [];
|
|
20378
20480
|
for (const info of this.renderedBlocks.values()) info.object?.removeFromScene();
|
|
20379
20481
|
this.sectionBlocks.clear();
|
|
@@ -20409,14 +20511,14 @@ var Chunk = class _Chunk {
|
|
|
20409
20511
|
return pos.y * 16 * 16 + pos.z * 16 + pos.x;
|
|
20410
20512
|
}
|
|
20411
20513
|
worldPosToChunkPos(pos) {
|
|
20412
|
-
return new
|
|
20514
|
+
return new Vector321(
|
|
20413
20515
|
pos.x - this.x * 16,
|
|
20414
20516
|
pos.y - this.y * 16,
|
|
20415
20517
|
pos.z - this.z * 16
|
|
20416
20518
|
);
|
|
20417
20519
|
}
|
|
20418
20520
|
chunkPosToWorldPos(pos) {
|
|
20419
|
-
return new
|
|
20521
|
+
return new Vector321(
|
|
20420
20522
|
this.x * 16 + pos.x,
|
|
20421
20523
|
this.y * 16 + pos.y,
|
|
20422
20524
|
this.z * 16 + pos.z
|