minerender 2.1.0-alpha.126 → 2.1.0-alpha.128

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.
@@ -1264,118 +1264,6 @@ var init_Materials = __esm({
1264
1264
  }
1265
1265
  });
1266
1266
 
1267
- // src/model/Model.ts
1268
- function isDoubleArray(obj) {
1269
- return Array.isArray(obj) && obj.length === 2;
1270
- }
1271
- function isTripleArray(obj) {
1272
- return Array.isArray(obj) && obj.length === 3;
1273
- }
1274
- function isQuadArray(obj) {
1275
- return Array.isArray(obj) && obj.length === 4;
1276
- }
1277
- var ITEM_GENERATED, BUILTIN_GENERATED, BUILTIN_ENTITY, DEFAULT_ELEMENTS;
1278
- var init_Model = __esm({
1279
- "src/model/Model.ts"() {
1280
- ITEM_GENERATED = "item/generated";
1281
- BUILTIN_GENERATED = "builtin/generated";
1282
- BUILTIN_ENTITY = "builtin/entity";
1283
- DEFAULT_ELEMENTS = [];
1284
- }
1285
- });
1286
-
1287
- // ../../node_modules/ts-deepmerge/dist/index.js
1288
- var require_dist = __commonJS({
1289
- "../../node_modules/ts-deepmerge/dist/index.js"(exports) {
1290
- "use strict";
1291
- var __assign = exports && exports.__assign || function() {
1292
- __assign = Object.assign || function(t) {
1293
- for (var s, i = 1, n = arguments.length; i < n; i++) {
1294
- s = arguments[i];
1295
- for (var p10 in s) if (Object.prototype.hasOwnProperty.call(s, p10))
1296
- t[p10] = s[p10];
1297
- }
1298
- return t;
1299
- };
1300
- return __assign.apply(this, arguments);
1301
- };
1302
- var __read = exports && exports.__read || function(o, n) {
1303
- var m = typeof Symbol === "function" && o[Symbol.iterator];
1304
- if (!m) return o;
1305
- var i = m.call(o), r, ar = [], e;
1306
- try {
1307
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
1308
- } catch (error) {
1309
- e = { error };
1310
- } finally {
1311
- try {
1312
- if (r && !r.done && (m = i["return"])) m.call(i);
1313
- } finally {
1314
- if (e) throw e.error;
1315
- }
1316
- }
1317
- return ar;
1318
- };
1319
- var __spreadArray = exports && exports.__spreadArray || function(to, from, pack) {
1320
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
1321
- if (ar || !(i in from)) {
1322
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
1323
- ar[i] = from[i];
1324
- }
1325
- }
1326
- return to.concat(ar || Array.prototype.slice.call(from));
1327
- };
1328
- Object.defineProperty(exports, "__esModule", { value: true });
1329
- var isObject = function(obj) {
1330
- if (typeof obj === "object" && obj !== null) {
1331
- if (typeof Object.getPrototypeOf === "function") {
1332
- var prototype = Object.getPrototypeOf(obj);
1333
- return prototype === Object.prototype || prototype === null;
1334
- }
1335
- return Object.prototype.toString.call(obj) === "[object Object]";
1336
- }
1337
- return false;
1338
- };
1339
- var PROTECTED_KEYS = ["__proto__"];
1340
- var merge10 = function() {
1341
- var objects = [];
1342
- for (var _i = 0; _i < arguments.length; _i++) {
1343
- objects[_i] = arguments[_i];
1344
- }
1345
- return objects.reduce(function(result, current) {
1346
- Object.keys(current).forEach(function(key) {
1347
- if (PROTECTED_KEYS.includes(key)) {
1348
- return;
1349
- }
1350
- if (Array.isArray(result[key]) && Array.isArray(current[key])) {
1351
- result[key] = merge10.options.mergeArrays ? Array.from(new Set(result[key].concat(current[key]))) : current[key];
1352
- } else if (isObject(result[key]) && isObject(current[key])) {
1353
- result[key] = merge10(result[key], current[key]);
1354
- } else {
1355
- result[key] = current[key];
1356
- }
1357
- });
1358
- return result;
1359
- }, {});
1360
- };
1361
- var defaultOptions = {
1362
- mergeArrays: true
1363
- };
1364
- merge10.options = defaultOptions;
1365
- merge10.withOptions = function(options) {
1366
- var objects = [];
1367
- for (var _i = 1; _i < arguments.length; _i++) {
1368
- objects[_i - 1] = arguments[_i];
1369
- }
1370
- merge10.options = __assign({ mergeArrays: true }, options);
1371
- var result = merge10.apply(void 0, __spreadArray([], __read(objects), false));
1372
- merge10.options = defaultOptions;
1373
- return result;
1374
- };
1375
- exports.default = merge10;
1376
- }
1377
- });
1378
-
1379
1267
  // src/assets/AssetKey.ts
1380
1268
  function isResourceLocation(value) {
1381
1269
  return typeof value === "string" && /^(?:[a-z0-9_.-]+:)?[a-z0-9_./-]+$/.test(value);
@@ -1492,128 +1380,6 @@ var init_AssetKey = __esm({
1492
1380
  }
1493
1381
  });
1494
1382
 
1495
- // src/model/DisplayPosition.ts
1496
- var DisplayPosition, DISPLAY_POSITIONS;
1497
- var init_DisplayPosition = __esm({
1498
- "src/model/DisplayPosition.ts"() {
1499
- DisplayPosition = /* @__PURE__ */ ((DisplayPosition3) => {
1500
- DisplayPosition3["THIRDPERSON_RIGHTHAND"] = "thirdperson_righthand";
1501
- DisplayPosition3["THIRDPERSON_LEFTHAND"] = "thirdperson_lefthand";
1502
- DisplayPosition3["FIRSTPERSON_RIGHTHAND"] = "firstperson_righthand";
1503
- DisplayPosition3["FIRSTPERSON_LEFTHAND"] = "firstperson_lefthand";
1504
- DisplayPosition3["GUI"] = "gui";
1505
- DisplayPosition3["HEAD"] = "head";
1506
- DisplayPosition3["GROUND"] = "ground";
1507
- DisplayPosition3["FIXED"] = "fixed";
1508
- DisplayPosition3["ON_SHELF"] = "on_shelf";
1509
- return DisplayPosition3;
1510
- })(DisplayPosition || {});
1511
- DISPLAY_POSITIONS = Object.values(DisplayPosition);
1512
- }
1513
- });
1514
-
1515
- // src/model/DisplayTransforms.ts
1516
- import { Euler, Matrix4, Quaternion, Vector3 as Vector32 } from "three";
1517
- var DisplayTransforms;
1518
- var init_DisplayTransforms = __esm({
1519
- "src/model/DisplayTransforms.ts"() {
1520
- init_DisplayPosition();
1521
- init_util();
1522
- DisplayTransforms = class {
1523
- /** Resolve hand fallbacks within one model, before inheriting parent display entries. */
1524
- static withHandFallbacks(display) {
1525
- if (!display) return void 0;
1526
- const resolved = { ...display };
1527
- for (const [left, right] of [
1528
- ["thirdperson_lefthand" /* THIRDPERSON_LEFTHAND */, "thirdperson_righthand" /* THIRDPERSON_RIGHTHAND */],
1529
- ["firstperson_lefthand" /* FIRSTPERSON_LEFTHAND */, "firstperson_righthand" /* FIRSTPERSON_RIGHTHAND */]
1530
- ]) {
1531
- if (resolved[left] === void 0 && resolved[right] !== void 0) resolved[left] = resolved[right];
1532
- }
1533
- return resolved;
1534
- }
1535
- /** Build a display pose for geometry already centered at the model's [8, 8, 8] pivot. */
1536
- static getMatrix(display, position) {
1537
- const transform = this.getTransform(display, position);
1538
- return new Matrix4().compose(transform.position, transform.quaternion, transform.scale);
1539
- }
1540
- /** Position, rotation, and scale of a display pose for geometry already centered at the model's [8, 8, 8] pivot. */
1541
- static getTransform(display, position) {
1542
- const transform = this.withHandFallbacks(display)?.[position] ?? {};
1543
- const left = position === "firstperson_lefthand" /* FIRSTPERSON_LEFTHAND */ || position === "thirdperson_lefthand" /* THIRDPERSON_LEFTHAND */;
1544
- const sign = left ? -1 : 1;
1545
- const [x, y, z] = transform.rotation ?? [0, 0, 0];
1546
- const rotation = new Quaternion().setFromEuler(new Euler(toRadians(x), sign * toRadians(y), sign * toRadians(z), "XYZ"));
1547
- const translation = new Vector32(...transform.translation ?? [0, 0, 0]).clampScalar(-80, 80);
1548
- translation.x *= sign;
1549
- const scale = new Vector32(...transform.scale ?? [1, 1, 1]).clampScalar(-4, 4);
1550
- return { position: translation, quaternion: rotation, scale };
1551
- }
1552
- /** Transforms geometry in place and reverses triangle winding when the matrix reflects it. */
1553
- static apply(geometry, matrix) {
1554
- geometry.applyMatrix4(matrix);
1555
- if (matrix.determinant() < 0) {
1556
- if (!geometry.index) geometry.setIndex(Array.from({ length: geometry.getAttribute("position").count }, (_, i) => i));
1557
- const index = geometry.index;
1558
- for (let i = 0; i < index.count; i += 3) {
1559
- const second = index.getX(i + 1);
1560
- index.setX(i + 1, index.getX(i + 2));
1561
- index.setX(i + 2, second);
1562
- }
1563
- index.needsUpdate = true;
1564
- }
1565
- }
1566
- };
1567
- }
1568
- });
1569
-
1570
- // src/model/ModelMerger.ts
1571
- var import_ts_deepmerge, ModelMerger;
1572
- var init_ModelMerger = __esm({
1573
- "src/model/ModelMerger.ts"() {
1574
- init_Model();
1575
- init_Models();
1576
- import_ts_deepmerge = __toESM(require_dist());
1577
- init_AssetKey();
1578
- init_DisplayTransforms();
1579
- ModelMerger = class {
1580
- /** Loads the parent chain and returns a merged model without modifying the supplied definition. */
1581
- static async mergeWithParents(model) {
1582
- const parts = model.parts;
1583
- if (parts) return { ...model, parts: await Promise.all(parts.map((part) => this.mergeWithParents(part))) };
1584
- const models = await this.collectAllParents(model);
1585
- let merged = {};
1586
- for (const source of [...models, model]) {
1587
- const inheritedDisplay = merged.display;
1588
- merged = import_ts_deepmerge.default.withOptions({ mergeArrays: false }, merged, source);
1589
- if (source.display) {
1590
- merged.display = { ...inheritedDisplay, ...DisplayTransforms.withHandFallbacks(source.display) };
1591
- }
1592
- }
1593
- merged.hierarchy = models.map((m) => m.parent).filter((p10) => `${p10}`);
1594
- merged.hierarchy.push(`${merged.parent}`);
1595
- if (model.components) merged.components = model.components;
1596
- return merged;
1597
- }
1598
- static async collectAllParents(model) {
1599
- if (!model.parent) {
1600
- return [];
1601
- }
1602
- const models = [];
1603
- const parentKey = AssetKey.parse("models", model.parent);
1604
- if (parentKey.namespace === "minecraft" && parentKey.getFullPath() === BUILTIN_ENTITY) return models;
1605
- parentKey.root = model.key?.root;
1606
- const parentModel = await Models.getRaw(parentKey);
1607
- if (parentModel) {
1608
- models.unshift(parentModel);
1609
- models.unshift(...await this.collectAllParents(parentModel));
1610
- }
1611
- return models;
1612
- }
1613
- };
1614
- }
1615
- });
1616
-
1617
1383
  // src/assets/source/parser/AssetParsers.ts
1618
1384
  var AssetParser;
1619
1385
  var init_AssetParsers = __esm({
@@ -1731,7 +1497,9 @@ ${key}` : key, async () => {
1731
1497
  static validDataset(dataset, data) {
1732
1498
  if (!object(data)) return false;
1733
1499
  if (dataset === "potionColors") return object(data.effects) && Object.values(data.effects).every(Number.isInteger) && object(data.potions) && Object.values(data.potions).every((effects) => Array.isArray(effects) && effects.every((effect) => object(effect) && typeof effect.id === "string" && Number.isInteger(effect.amplifier)));
1500
+ if (dataset === "renames") return data.format === "data-fixer-renames" && Number.isInteger(data.baseDataVersion) && ["blocks", "items", "entities"].every((kind) => object(data[kind]) && Object.values(data[kind]).every((entry) => object(entry) && typeof entry.registered === "boolean" && Array.isArray(entry.ranges) && entry.ranges.length > 0 && entry.ranges.every((range) => object(range) && Number.isInteger(range.before) && typeof range.to === "string")));
1734
1501
  if (dataset === "legacyBlocks") return object(data.blocks) && Object.values(data.blocks).every((value) => typeof value === "string");
1502
+ if (dataset === "blockCulling") return Array.isArray(data.profiles) && data.profiles.every((profile) => object(profile) && typeof profile.type === "string") && object(data.blocks) && Object.values(data.blocks).every((index) => Number.isInteger(index) && index >= 0 && index < data.profiles.length) && (data.groups === void 0 || object(data.groups) && Object.values(data.groups).every((group) => Array.isArray(group) && group.every((type) => typeof type === "string")));
1735
1503
  return Object.values(data).every((value) => {
1736
1504
  if (!object(value)) return false;
1737
1505
  switch (dataset) {
@@ -1754,6 +1522,275 @@ ${key}` : key, async () => {
1754
1522
  }
1755
1523
  });
1756
1524
 
1525
+ // src/assets/Renames.ts
1526
+ var Renames;
1527
+ var init_Renames = __esm({
1528
+ "src/assets/Renames.ts"() {
1529
+ init_AssetKey();
1530
+ init_MineRenderData();
1531
+ Renames = class {
1532
+ /** Loads the selected version's rename table, or `undefined` when its published data has none. */
1533
+ static async get(root) {
1534
+ const resolved = await MineRenderData.resolve(root);
1535
+ return resolved.manifest.datasets.renames ? MineRenderData.get("renames", root) : void 0;
1536
+ }
1537
+ /**
1538
+ * Returns the ID that replaced `id`, or `undefined` when `id` keeps its meaning.
1539
+ * Without a data version, an ID that the selected version still registers keeps its meaning.
1540
+ */
1541
+ static async resolve(kind, id, dataVersion, root) {
1542
+ const data = await this.get(root);
1543
+ if (!data || !Object.prototype.hasOwnProperty.call(data[kind], id)) return void 0;
1544
+ const entry = data[kind][id];
1545
+ if (dataVersion === void 0) return entry.registered ? void 0 : entry.ranges[entry.ranges.length - 1].to;
1546
+ if (dataVersion < data.baseDataVersion) return void 0;
1547
+ return entry.ranges.find((range) => dataVersion < range.before)?.to;
1548
+ }
1549
+ /** Returns a copy of `key` for the replacement ID, or `undefined` when the ID keeps its meaning. */
1550
+ static async key(kind, key) {
1551
+ const renamed = await this.resolve(kind, `${key.namespace}:${key.path}`, void 0, key.root);
1552
+ if (!renamed) return void 0;
1553
+ const [namespace, path] = renamed.split(":");
1554
+ return new AssetKey(namespace, path, key.assetType, key.type, key.rootType, key.extension, key.root);
1555
+ }
1556
+ };
1557
+ }
1558
+ });
1559
+
1560
+ // src/model/Model.ts
1561
+ function isDoubleArray(obj) {
1562
+ return Array.isArray(obj) && obj.length === 2;
1563
+ }
1564
+ function isTripleArray(obj) {
1565
+ return Array.isArray(obj) && obj.length === 3;
1566
+ }
1567
+ function isQuadArray(obj) {
1568
+ return Array.isArray(obj) && obj.length === 4;
1569
+ }
1570
+ var ITEM_GENERATED, BUILTIN_GENERATED, BUILTIN_ENTITY, DEFAULT_ELEMENTS;
1571
+ var init_Model = __esm({
1572
+ "src/model/Model.ts"() {
1573
+ ITEM_GENERATED = "item/generated";
1574
+ BUILTIN_GENERATED = "builtin/generated";
1575
+ BUILTIN_ENTITY = "builtin/entity";
1576
+ DEFAULT_ELEMENTS = [];
1577
+ }
1578
+ });
1579
+
1580
+ // ../../node_modules/ts-deepmerge/dist/index.js
1581
+ var require_dist = __commonJS({
1582
+ "../../node_modules/ts-deepmerge/dist/index.js"(exports) {
1583
+ "use strict";
1584
+ var __assign = exports && exports.__assign || function() {
1585
+ __assign = Object.assign || function(t) {
1586
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
1587
+ s = arguments[i];
1588
+ for (var p10 in s) if (Object.prototype.hasOwnProperty.call(s, p10))
1589
+ t[p10] = s[p10];
1590
+ }
1591
+ return t;
1592
+ };
1593
+ return __assign.apply(this, arguments);
1594
+ };
1595
+ var __read = exports && exports.__read || function(o, n) {
1596
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
1597
+ if (!m) return o;
1598
+ var i = m.call(o), r, ar = [], e;
1599
+ try {
1600
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
1601
+ } catch (error) {
1602
+ e = { error };
1603
+ } finally {
1604
+ try {
1605
+ if (r && !r.done && (m = i["return"])) m.call(i);
1606
+ } finally {
1607
+ if (e) throw e.error;
1608
+ }
1609
+ }
1610
+ return ar;
1611
+ };
1612
+ var __spreadArray = exports && exports.__spreadArray || function(to, from, pack) {
1613
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
1614
+ if (ar || !(i in from)) {
1615
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
1616
+ ar[i] = from[i];
1617
+ }
1618
+ }
1619
+ return to.concat(ar || Array.prototype.slice.call(from));
1620
+ };
1621
+ Object.defineProperty(exports, "__esModule", { value: true });
1622
+ var isObject = function(obj) {
1623
+ if (typeof obj === "object" && obj !== null) {
1624
+ if (typeof Object.getPrototypeOf === "function") {
1625
+ var prototype = Object.getPrototypeOf(obj);
1626
+ return prototype === Object.prototype || prototype === null;
1627
+ }
1628
+ return Object.prototype.toString.call(obj) === "[object Object]";
1629
+ }
1630
+ return false;
1631
+ };
1632
+ var PROTECTED_KEYS = ["__proto__"];
1633
+ var merge10 = function() {
1634
+ var objects = [];
1635
+ for (var _i = 0; _i < arguments.length; _i++) {
1636
+ objects[_i] = arguments[_i];
1637
+ }
1638
+ return objects.reduce(function(result, current) {
1639
+ Object.keys(current).forEach(function(key) {
1640
+ if (PROTECTED_KEYS.includes(key)) {
1641
+ return;
1642
+ }
1643
+ if (Array.isArray(result[key]) && Array.isArray(current[key])) {
1644
+ result[key] = merge10.options.mergeArrays ? Array.from(new Set(result[key].concat(current[key]))) : current[key];
1645
+ } else if (isObject(result[key]) && isObject(current[key])) {
1646
+ result[key] = merge10(result[key], current[key]);
1647
+ } else {
1648
+ result[key] = current[key];
1649
+ }
1650
+ });
1651
+ return result;
1652
+ }, {});
1653
+ };
1654
+ var defaultOptions = {
1655
+ mergeArrays: true
1656
+ };
1657
+ merge10.options = defaultOptions;
1658
+ merge10.withOptions = function(options) {
1659
+ var objects = [];
1660
+ for (var _i = 1; _i < arguments.length; _i++) {
1661
+ objects[_i - 1] = arguments[_i];
1662
+ }
1663
+ merge10.options = __assign({ mergeArrays: true }, options);
1664
+ var result = merge10.apply(void 0, __spreadArray([], __read(objects), false));
1665
+ merge10.options = defaultOptions;
1666
+ return result;
1667
+ };
1668
+ exports.default = merge10;
1669
+ }
1670
+ });
1671
+
1672
+ // src/model/DisplayPosition.ts
1673
+ var DisplayPosition, DISPLAY_POSITIONS;
1674
+ var init_DisplayPosition = __esm({
1675
+ "src/model/DisplayPosition.ts"() {
1676
+ DisplayPosition = /* @__PURE__ */ ((DisplayPosition3) => {
1677
+ DisplayPosition3["THIRDPERSON_RIGHTHAND"] = "thirdperson_righthand";
1678
+ DisplayPosition3["THIRDPERSON_LEFTHAND"] = "thirdperson_lefthand";
1679
+ DisplayPosition3["FIRSTPERSON_RIGHTHAND"] = "firstperson_righthand";
1680
+ DisplayPosition3["FIRSTPERSON_LEFTHAND"] = "firstperson_lefthand";
1681
+ DisplayPosition3["GUI"] = "gui";
1682
+ DisplayPosition3["HEAD"] = "head";
1683
+ DisplayPosition3["GROUND"] = "ground";
1684
+ DisplayPosition3["FIXED"] = "fixed";
1685
+ DisplayPosition3["ON_SHELF"] = "on_shelf";
1686
+ return DisplayPosition3;
1687
+ })(DisplayPosition || {});
1688
+ DISPLAY_POSITIONS = Object.values(DisplayPosition);
1689
+ }
1690
+ });
1691
+
1692
+ // src/model/DisplayTransforms.ts
1693
+ import { Euler, Matrix4, Quaternion, Vector3 as Vector32 } from "three";
1694
+ var DisplayTransforms;
1695
+ var init_DisplayTransforms = __esm({
1696
+ "src/model/DisplayTransforms.ts"() {
1697
+ init_DisplayPosition();
1698
+ init_util();
1699
+ DisplayTransforms = class {
1700
+ /** Resolve hand fallbacks within one model, before inheriting parent display entries. */
1701
+ static withHandFallbacks(display) {
1702
+ if (!display) return void 0;
1703
+ const resolved = { ...display };
1704
+ for (const [left, right] of [
1705
+ ["thirdperson_lefthand" /* THIRDPERSON_LEFTHAND */, "thirdperson_righthand" /* THIRDPERSON_RIGHTHAND */],
1706
+ ["firstperson_lefthand" /* FIRSTPERSON_LEFTHAND */, "firstperson_righthand" /* FIRSTPERSON_RIGHTHAND */]
1707
+ ]) {
1708
+ if (resolved[left] === void 0 && resolved[right] !== void 0) resolved[left] = resolved[right];
1709
+ }
1710
+ return resolved;
1711
+ }
1712
+ /** Build a display pose for geometry already centered at the model's [8, 8, 8] pivot. */
1713
+ static getMatrix(display, position) {
1714
+ const transform = this.getTransform(display, position);
1715
+ return new Matrix4().compose(transform.position, transform.quaternion, transform.scale);
1716
+ }
1717
+ /** Position, rotation, and scale of a display pose for geometry already centered at the model's [8, 8, 8] pivot. */
1718
+ static getTransform(display, position) {
1719
+ const transform = this.withHandFallbacks(display)?.[position] ?? {};
1720
+ const left = position === "firstperson_lefthand" /* FIRSTPERSON_LEFTHAND */ || position === "thirdperson_lefthand" /* THIRDPERSON_LEFTHAND */;
1721
+ const sign = left ? -1 : 1;
1722
+ const [x, y, z] = transform.rotation ?? [0, 0, 0];
1723
+ const rotation = new Quaternion().setFromEuler(new Euler(toRadians(x), sign * toRadians(y), sign * toRadians(z), "XYZ"));
1724
+ const translation = new Vector32(...transform.translation ?? [0, 0, 0]).clampScalar(-80, 80);
1725
+ translation.x *= sign;
1726
+ const scale = new Vector32(...transform.scale ?? [1, 1, 1]).clampScalar(-4, 4);
1727
+ return { position: translation, quaternion: rotation, scale };
1728
+ }
1729
+ /** Transforms geometry in place and reverses triangle winding when the matrix reflects it. */
1730
+ static apply(geometry, matrix) {
1731
+ geometry.applyMatrix4(matrix);
1732
+ if (matrix.determinant() < 0) {
1733
+ if (!geometry.index) geometry.setIndex(Array.from({ length: geometry.getAttribute("position").count }, (_, i) => i));
1734
+ const index = geometry.index;
1735
+ for (let i = 0; i < index.count; i += 3) {
1736
+ const second = index.getX(i + 1);
1737
+ index.setX(i + 1, index.getX(i + 2));
1738
+ index.setX(i + 2, second);
1739
+ }
1740
+ index.needsUpdate = true;
1741
+ }
1742
+ }
1743
+ };
1744
+ }
1745
+ });
1746
+
1747
+ // src/model/ModelMerger.ts
1748
+ var import_ts_deepmerge, ModelMerger;
1749
+ var init_ModelMerger = __esm({
1750
+ "src/model/ModelMerger.ts"() {
1751
+ init_Model();
1752
+ init_Models();
1753
+ import_ts_deepmerge = __toESM(require_dist());
1754
+ init_AssetKey();
1755
+ init_DisplayTransforms();
1756
+ ModelMerger = class {
1757
+ /** Loads the parent chain and returns a merged model without modifying the supplied definition. */
1758
+ static async mergeWithParents(model) {
1759
+ const parts = model.parts;
1760
+ if (parts) return { ...model, parts: await Promise.all(parts.map((part) => this.mergeWithParents(part))) };
1761
+ const models = await this.collectAllParents(model);
1762
+ let merged = {};
1763
+ for (const source of [...models, model]) {
1764
+ const inheritedDisplay = merged.display;
1765
+ merged = import_ts_deepmerge.default.withOptions({ mergeArrays: false }, merged, source);
1766
+ if (source.display) {
1767
+ merged.display = { ...inheritedDisplay, ...DisplayTransforms.withHandFallbacks(source.display) };
1768
+ }
1769
+ }
1770
+ merged.hierarchy = models.map((m) => m.parent).filter((p10) => `${p10}`);
1771
+ merged.hierarchy.push(`${merged.parent}`);
1772
+ if (model.components) merged.components = model.components;
1773
+ return merged;
1774
+ }
1775
+ static async collectAllParents(model) {
1776
+ if (!model.parent) {
1777
+ return [];
1778
+ }
1779
+ const models = [];
1780
+ const parentKey = AssetKey.parse("models", model.parent);
1781
+ if (parentKey.namespace === "minecraft" && parentKey.getFullPath() === BUILTIN_ENTITY) return models;
1782
+ parentKey.root = model.key?.root;
1783
+ const parentModel = await Models.getRaw(parentKey);
1784
+ if (parentModel) {
1785
+ models.unshift(parentModel);
1786
+ models.unshift(...await this.collectAllParents(parentModel));
1787
+ }
1788
+ return models;
1789
+ }
1790
+ };
1791
+ }
1792
+ });
1793
+
1757
1794
  // src/assets/BannerPatterns.ts
1758
1795
  var DYE_COLORS, BannerPatterns;
1759
1796
  var init_BannerPatterns = __esm({
@@ -2076,6 +2113,7 @@ var init_ItemTints = __esm({
2076
2113
  var Models;
2077
2114
  var init_Models = __esm({
2078
2115
  "src/assets/Models.ts"() {
2116
+ init_Renames();
2079
2117
  init_Caching();
2080
2118
  init_ModelMerger();
2081
2119
  init_AssetLoader();
@@ -2409,6 +2447,11 @@ var init_Models = __esm({
2409
2447
  key.extension = ".json";
2410
2448
  }
2411
2449
  const preview = this.snapshotContext(key, context);
2450
+ if (key.type === "item") {
2451
+ const renamed = await Renames.key("items", key);
2452
+ const replacement = renamed && await this.getMerged(renamed, preview);
2453
+ if (replacement) return replacement;
2454
+ }
2412
2455
  const dataKey = await this.applyDefaults(key, preview);
2413
2456
  const keyStr = AssetLoader.persistentKey(key.serialize() + (key.type === "item" ? this.contextKey(preview) + dataKey : ""));
2414
2457
  const model = await Caching.mergedModelCache.get(keyStr, async () => {
@@ -2440,6 +2483,7 @@ var init_BlockStates = __esm({
2440
2483
  init_AssetKey();
2441
2484
  init_PersistentCache();
2442
2485
  init_AssetParsers();
2486
+ init_Renames();
2443
2487
  init_MineRenderData();
2444
2488
  BlockStates = class {
2445
2489
  static get PERSISTENT_CACHE() {
@@ -2480,6 +2524,9 @@ var init_BlockStates = __esm({
2480
2524
  if (!key.extension) {
2481
2525
  key.extension = ".json";
2482
2526
  }
2527
+ const renamed = await Renames.key("blocks", key);
2528
+ const replacement = renamed && await this.get(renamed);
2529
+ if (replacement) return replacement;
2483
2530
  const keyStr = key.serialize();
2484
2531
  return Caching.blockStateCache.get(keyStr, (k) => {
2485
2532
  return this.PERSISTENT_CACHE.getOrLoad(AssetLoader.persistentKey(keyStr), (k1) => {
@@ -8016,6 +8063,7 @@ var Fonts = class {
8016
8063
  init_MineRenderData();
8017
8064
  init_ModelTextures();
8018
8065
  init_Models();
8066
+ init_Renames();
8019
8067
  init_source();
8020
8068
 
8021
8069
  // src/cache/index.ts
@@ -17443,6 +17491,7 @@ var SectionModels = class {
17443
17491
  };
17444
17492
 
17445
17493
  // src/world/_entities/WorldEntities.ts
17494
+ init_Renames();
17446
17495
  init_Entities();
17447
17496
  init_EntityObject();
17448
17497
 
@@ -17602,8 +17651,10 @@ var WorldEntities = class {
17602
17651
  try {
17603
17652
  if (!current()) return;
17604
17653
  const models = await Entities.getEntityList();
17605
- if (!models.includes(placement.key.path) || !current()) return;
17606
- const model = await Entities.getEntity(placement.key, placement.texture, { when: placement.when });
17654
+ const renamed = models.includes(placement.key.path) ? void 0 : await Renames.key("entities", placement.key);
17655
+ const key = renamed && models.includes(renamed.path) ? renamed : placement.key;
17656
+ if (!models.includes(key.path) || !current()) return;
17657
+ const model = await Entities.getEntity(key, placement.texture, { when: placement.when });
17607
17658
  if (!model || !current()) return;
17608
17659
  let tints = placement.tints;
17609
17660
  if (placement.woolDye) {
@@ -17618,7 +17669,7 @@ var WorldEntities = class {
17618
17669
  object4.rotation.y = placement.yaw;
17619
17670
  await object4.init();
17620
17671
  if (!current()) return;
17621
- placement.owner.set(object4, { type: placement.key.toNamespacedString(), position: placement.position });
17672
+ placement.owner.set(object4, { type: key.toNamespacedString(), position: placement.position });
17622
17673
  this.scene.add(object4);
17623
17674
  } catch (error) {
17624
17675
  console.warn(`Could not draw saved entity ${placement.key.toNamespacedString()}, skipping it`, error);
@@ -17672,6 +17723,38 @@ function sampleSectionLight(light, index) {
17672
17723
  };
17673
17724
  }
17674
17725
 
17726
+ // src/world/_culling/BlockCulling.ts
17727
+ init_Assets();
17728
+ init_MineRenderData();
17729
+ init_CubeFace();
17730
+ async function loadBlockCulling(root) {
17731
+ const { manifest } = await MineRenderData.resolve(root);
17732
+ return manifest.datasets.blockCulling ? MineRenderData.get("blockCulling", root) : void 0;
17733
+ }
17734
+ function blockCullingRule(data, type) {
17735
+ if (!type.includes(":")) type = `${DEFAULT_NAMESPACE}:${type}`;
17736
+ return Object.prototype.hasOwnProperty.call(data.blocks, type) ? data.profiles[data.blocks[type]] : void 0;
17737
+ }
17738
+ function skipsBlockFace(data, rule, block, neighbor, face) {
17739
+ const type = block.type.includes(":") ? block.type : `${DEFAULT_NAMESPACE}:${block.type}`;
17740
+ const other = neighbor.type.includes(":") ? neighbor.type : `${DEFAULT_NAMESPACE}:${neighbor.type}`;
17741
+ const same = type === other;
17742
+ const vertical = CUBE_FACES[face] === "up" /* UP */ || CUBE_FACES[face] === "down" /* DOWN */;
17743
+ switch (rule.type) {
17744
+ case "same_block":
17745
+ return same;
17746
+ case "same_block_vertical":
17747
+ return same && vertical;
17748
+ case "connected": {
17749
+ if (vertical) return same;
17750
+ const group = rule.group ? data.groups?.[rule.group] : void 0;
17751
+ return (same || !!group?.includes(type) && group.includes(other)) && String(block.properties?.[CUBE_FACES[face]]) === "true" && String(neighbor.properties?.[CUBE_FACES[face ^ 1]]) === "true";
17752
+ }
17753
+ default:
17754
+ return false;
17755
+ }
17756
+ }
17757
+
17675
17758
  // src/world/MineRenderWorld.ts
17676
17759
  var MineRenderWorld = class {
17677
17760
  constructor(scene, options = {}) {
@@ -18060,15 +18143,23 @@ var MineRenderWorld = class {
18060
18143
  return this.culling ??= Promise.resolve().then(async () => {
18061
18144
  let sliceStart = performance.now();
18062
18145
  try {
18146
+ const culling = await loadBlockCulling();
18063
18147
  while (this.pendingCulling.size) {
18064
18148
  const batch = [...this.pendingCulling];
18065
18149
  this.pendingCulling.clear();
18066
18150
  for (const [chunk, indices] of batch) {
18067
18151
  const neighbors = CUBE_FACE_OFFSETS.map(([x, y, z]) => this._chunks.get(`${chunk.x + x}_${chunk.y + y}_${chunk.z + z}`));
18068
- const masks = chunk.updateCullMasks(indices === "all" ? void 0 : indices, (x, y, z) => {
18152
+ const neighborAt = (x, y, z) => {
18069
18153
  const lx = x - chunk.x * 16, ly = y - chunk.y * 16, lz = z - chunk.z * 16;
18070
18154
  const section = neighbors[lx >= 16 ? 0 : lx < 0 ? 1 : ly >= 16 ? 2 : ly < 0 ? 3 : lz >= 16 ? 4 : 5];
18071
- return section?.isOccludingIndex((ly & 15) * 256 + (lz & 15) * 16 + (lx & 15)) ?? false;
18155
+ return [section, (ly & 15) * 256 + (lz & 15) * 16 + (lx & 15)];
18156
+ };
18157
+ const masks = chunk.updateCullMasks(indices === "all" ? void 0 : indices, (x, y, z) => {
18158
+ const [section, i] = neighborAt(x, y, z);
18159
+ return section?.isOccludingIndex(i) ?? false;
18160
+ }, culling, (x, y, z) => {
18161
+ const [section, i] = neighborAt(x, y, z);
18162
+ return section?.visibleBlockIndex(i);
18072
18163
  });
18073
18164
  const fluidIndices = indices === "all" ? function* () {
18074
18165
  for (let index = 0; index < 4096; index++) yield index;
@@ -19184,6 +19275,10 @@ var Chunk = class _Chunk {
19184
19275
  isBlockVisibleIndex(index) {
19185
19276
  return this.renderedBlocks.has(index) && !this.hiddenBlocks.has(index);
19186
19277
  }
19278
+ /** Stored state of a rendered, visible cell, or `undefined`. */
19279
+ visibleBlockIndex(index) {
19280
+ return this.isBlockVisibleIndex(index) ? this.data.stateAt(this.data.idAt(index)) : void 0;
19281
+ }
19187
19282
  /** Fluid kind bits and level of a cell, or 0. Hidden cells report 0. */
19188
19283
  fluidByteIndex(index) {
19189
19284
  return this.hiddenBlocks.has(index) ? 0 : this.fluidCells[index];
@@ -19202,18 +19297,30 @@ var Chunk = class _Chunk {
19202
19297
  async setCullMaskAt(pos, mask) {
19203
19298
  await this.setCullMaskIndex(_Chunk.chunkPosToBlockIndex(this.worldPosToChunkPos(pos)), mask);
19204
19299
  }
19205
- /** Recomputes section masks and returns changed per-block masks. Omit indices to visit every cell. */
19206
- updateCullMasks(indices, occludes) {
19300
+ /**
19301
+ * Recomputes section masks and returns changed per-block masks. Omit indices to visit every cell.
19302
+ * `culling` supplies neighbor face rules; `blockAt` supplies visible states outside this chunk.
19303
+ */
19304
+ updateCullMasks(indices, occludes, culling, blockAt) {
19207
19305
  const changed = [];
19306
+ const rules = [];
19208
19307
  for (const index of indices ?? this.fluidCells.keys()) {
19209
19308
  if (!this.isBlockVisibleIndex(index)) continue;
19210
19309
  const x = index % 16, y = Math.floor(index / 256), z = Math.floor(index / 16) % 16;
19310
+ const id = this.data.idAt(index);
19311
+ let rule = rules[id];
19312
+ if (culling && rule === void 0) rules[id] = rule = blockCullingRule(culling, this.data.stateAt(id).type) ?? null;
19313
+ const block = rule ? this.data.stateAt(id) : void 0;
19211
19314
  let mask = 0;
19212
19315
  for (let face = 0; face < CUBE_FACE_OFFSETS.length; face++) {
19213
19316
  const [dx, dy, dz] = CUBE_FACE_OFFSETS[face];
19214
19317
  const nx = x + dx, ny = y + dy, nz = z + dz;
19215
19318
  const inner = nx >= 0 && nx < 16 && ny >= 0 && ny < 16 && nz >= 0 && nz < 16;
19216
19319
  if (inner ? this.isOccludingIndex(ny * 256 + nz * 16 + nx) : occludes(this.x * 16 + nx, this.y * 16 + ny, this.z * 16 + nz)) mask |= 1 << face;
19320
+ else if (rule) {
19321
+ const neighbor = inner ? this.visibleBlockIndex(ny * 256 + nz * 16 + nx) : blockAt?.(this.x * 16 + nx, this.y * 16 + ny, this.z * 16 + nz);
19322
+ if (neighbor && skipsBlockFace(culling, rule, block, neighbor, face)) mask |= 1 << face;
19323
+ }
19217
19324
  }
19218
19325
  if (this.fluidCells[index]) this.meshDirty = true;
19219
19326
  const entries = this.sectionBlocks.get(index);
@@ -19791,6 +19898,7 @@ export {
19791
19898
  PackMetadata,
19792
19899
  PersistentCache,
19793
19900
  PlayerHeadTextures,
19901
+ Renames,
19794
19902
  Renderer,
19795
19903
  RequestError,
19796
19904
  Requests,