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.
@@ -1265,118 +1265,6 @@ var init_Materials = __esm({
1265
1265
  }
1266
1266
  });
1267
1267
 
1268
- // src/model/Model.ts
1269
- function isDoubleArray(obj) {
1270
- return Array.isArray(obj) && obj.length === 2;
1271
- }
1272
- function isTripleArray(obj) {
1273
- return Array.isArray(obj) && obj.length === 3;
1274
- }
1275
- function isQuadArray(obj) {
1276
- return Array.isArray(obj) && obj.length === 4;
1277
- }
1278
- var ITEM_GENERATED, BUILTIN_GENERATED, BUILTIN_ENTITY, DEFAULT_ELEMENTS;
1279
- var init_Model = __esm({
1280
- "src/model/Model.ts"() {
1281
- ITEM_GENERATED = "item/generated";
1282
- BUILTIN_GENERATED = "builtin/generated";
1283
- BUILTIN_ENTITY = "builtin/entity";
1284
- DEFAULT_ELEMENTS = [];
1285
- }
1286
- });
1287
-
1288
- // ../../node_modules/ts-deepmerge/dist/index.js
1289
- var require_dist = __commonJS({
1290
- "../../node_modules/ts-deepmerge/dist/index.js"(exports2) {
1291
- "use strict";
1292
- var __assign = exports2 && exports2.__assign || function() {
1293
- __assign = Object.assign || function(t) {
1294
- for (var s, i = 1, n = arguments.length; i < n; i++) {
1295
- s = arguments[i];
1296
- for (var p10 in s) if (Object.prototype.hasOwnProperty.call(s, p10))
1297
- t[p10] = s[p10];
1298
- }
1299
- return t;
1300
- };
1301
- return __assign.apply(this, arguments);
1302
- };
1303
- var __read = exports2 && exports2.__read || function(o, n) {
1304
- var m = typeof Symbol === "function" && o[Symbol.iterator];
1305
- if (!m) return o;
1306
- var i = m.call(o), r, ar = [], e;
1307
- try {
1308
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
1309
- } catch (error) {
1310
- e = { error };
1311
- } finally {
1312
- try {
1313
- if (r && !r.done && (m = i["return"])) m.call(i);
1314
- } finally {
1315
- if (e) throw e.error;
1316
- }
1317
- }
1318
- return ar;
1319
- };
1320
- var __spreadArray = exports2 && exports2.__spreadArray || function(to, from, pack) {
1321
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
1322
- if (ar || !(i in from)) {
1323
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
1324
- ar[i] = from[i];
1325
- }
1326
- }
1327
- return to.concat(ar || Array.prototype.slice.call(from));
1328
- };
1329
- Object.defineProperty(exports2, "__esModule", { value: true });
1330
- var isObject = function(obj) {
1331
- if (typeof obj === "object" && obj !== null) {
1332
- if (typeof Object.getPrototypeOf === "function") {
1333
- var prototype = Object.getPrototypeOf(obj);
1334
- return prototype === Object.prototype || prototype === null;
1335
- }
1336
- return Object.prototype.toString.call(obj) === "[object Object]";
1337
- }
1338
- return false;
1339
- };
1340
- var PROTECTED_KEYS = ["__proto__"];
1341
- var merge10 = function() {
1342
- var objects = [];
1343
- for (var _i = 0; _i < arguments.length; _i++) {
1344
- objects[_i] = arguments[_i];
1345
- }
1346
- return objects.reduce(function(result, current) {
1347
- Object.keys(current).forEach(function(key) {
1348
- if (PROTECTED_KEYS.includes(key)) {
1349
- return;
1350
- }
1351
- if (Array.isArray(result[key]) && Array.isArray(current[key])) {
1352
- result[key] = merge10.options.mergeArrays ? Array.from(new Set(result[key].concat(current[key]))) : current[key];
1353
- } else if (isObject(result[key]) && isObject(current[key])) {
1354
- result[key] = merge10(result[key], current[key]);
1355
- } else {
1356
- result[key] = current[key];
1357
- }
1358
- });
1359
- return result;
1360
- }, {});
1361
- };
1362
- var defaultOptions = {
1363
- mergeArrays: true
1364
- };
1365
- merge10.options = defaultOptions;
1366
- merge10.withOptions = function(options) {
1367
- var objects = [];
1368
- for (var _i = 1; _i < arguments.length; _i++) {
1369
- objects[_i - 1] = arguments[_i];
1370
- }
1371
- merge10.options = __assign({ mergeArrays: true }, options);
1372
- var result = merge10.apply(void 0, __spreadArray([], __read(objects), false));
1373
- merge10.options = defaultOptions;
1374
- return result;
1375
- };
1376
- exports2.default = merge10;
1377
- }
1378
- });
1379
-
1380
1268
  // src/assets/AssetKey.ts
1381
1269
  function isResourceLocation(value) {
1382
1270
  return typeof value === "string" && /^(?:[a-z0-9_.-]+:)?[a-z0-9_./-]+$/.test(value);
@@ -1493,128 +1381,6 @@ var init_AssetKey = __esm({
1493
1381
  }
1494
1382
  });
1495
1383
 
1496
- // src/model/DisplayPosition.ts
1497
- var DisplayPosition, DISPLAY_POSITIONS;
1498
- var init_DisplayPosition = __esm({
1499
- "src/model/DisplayPosition.ts"() {
1500
- DisplayPosition = /* @__PURE__ */ ((DisplayPosition3) => {
1501
- DisplayPosition3["THIRDPERSON_RIGHTHAND"] = "thirdperson_righthand";
1502
- DisplayPosition3["THIRDPERSON_LEFTHAND"] = "thirdperson_lefthand";
1503
- DisplayPosition3["FIRSTPERSON_RIGHTHAND"] = "firstperson_righthand";
1504
- DisplayPosition3["FIRSTPERSON_LEFTHAND"] = "firstperson_lefthand";
1505
- DisplayPosition3["GUI"] = "gui";
1506
- DisplayPosition3["HEAD"] = "head";
1507
- DisplayPosition3["GROUND"] = "ground";
1508
- DisplayPosition3["FIXED"] = "fixed";
1509
- DisplayPosition3["ON_SHELF"] = "on_shelf";
1510
- return DisplayPosition3;
1511
- })(DisplayPosition || {});
1512
- DISPLAY_POSITIONS = Object.values(DisplayPosition);
1513
- }
1514
- });
1515
-
1516
- // src/model/DisplayTransforms.ts
1517
- var import_three7, DisplayTransforms;
1518
- var init_DisplayTransforms = __esm({
1519
- "src/model/DisplayTransforms.ts"() {
1520
- import_three7 = require("three");
1521
- init_DisplayPosition();
1522
- init_util();
1523
- DisplayTransforms = class {
1524
- /** Resolve hand fallbacks within one model, before inheriting parent display entries. */
1525
- static withHandFallbacks(display) {
1526
- if (!display) return void 0;
1527
- const resolved = { ...display };
1528
- for (const [left, right] of [
1529
- ["thirdperson_lefthand" /* THIRDPERSON_LEFTHAND */, "thirdperson_righthand" /* THIRDPERSON_RIGHTHAND */],
1530
- ["firstperson_lefthand" /* FIRSTPERSON_LEFTHAND */, "firstperson_righthand" /* FIRSTPERSON_RIGHTHAND */]
1531
- ]) {
1532
- if (resolved[left] === void 0 && resolved[right] !== void 0) resolved[left] = resolved[right];
1533
- }
1534
- return resolved;
1535
- }
1536
- /** Build a display pose for geometry already centered at the model's [8, 8, 8] pivot. */
1537
- static getMatrix(display, position) {
1538
- const transform = this.getTransform(display, position);
1539
- return new import_three7.Matrix4().compose(transform.position, transform.quaternion, transform.scale);
1540
- }
1541
- /** Position, rotation, and scale of a display pose for geometry already centered at the model's [8, 8, 8] pivot. */
1542
- static getTransform(display, position) {
1543
- const transform = this.withHandFallbacks(display)?.[position] ?? {};
1544
- const left = position === "firstperson_lefthand" /* FIRSTPERSON_LEFTHAND */ || position === "thirdperson_lefthand" /* THIRDPERSON_LEFTHAND */;
1545
- const sign = left ? -1 : 1;
1546
- const [x, y, z] = transform.rotation ?? [0, 0, 0];
1547
- const rotation = new import_three7.Quaternion().setFromEuler(new import_three7.Euler(toRadians(x), sign * toRadians(y), sign * toRadians(z), "XYZ"));
1548
- const translation = new import_three7.Vector3(...transform.translation ?? [0, 0, 0]).clampScalar(-80, 80);
1549
- translation.x *= sign;
1550
- const scale = new import_three7.Vector3(...transform.scale ?? [1, 1, 1]).clampScalar(-4, 4);
1551
- return { position: translation, quaternion: rotation, scale };
1552
- }
1553
- /** Transforms geometry in place and reverses triangle winding when the matrix reflects it. */
1554
- static apply(geometry, matrix) {
1555
- geometry.applyMatrix4(matrix);
1556
- if (matrix.determinant() < 0) {
1557
- if (!geometry.index) geometry.setIndex(Array.from({ length: geometry.getAttribute("position").count }, (_, i) => i));
1558
- const index = geometry.index;
1559
- for (let i = 0; i < index.count; i += 3) {
1560
- const second = index.getX(i + 1);
1561
- index.setX(i + 1, index.getX(i + 2));
1562
- index.setX(i + 2, second);
1563
- }
1564
- index.needsUpdate = true;
1565
- }
1566
- }
1567
- };
1568
- }
1569
- });
1570
-
1571
- // src/model/ModelMerger.ts
1572
- var import_ts_deepmerge, ModelMerger;
1573
- var init_ModelMerger = __esm({
1574
- "src/model/ModelMerger.ts"() {
1575
- init_Model();
1576
- init_Models();
1577
- import_ts_deepmerge = __toESM(require_dist());
1578
- init_AssetKey();
1579
- init_DisplayTransforms();
1580
- ModelMerger = class {
1581
- /** Loads the parent chain and returns a merged model without modifying the supplied definition. */
1582
- static async mergeWithParents(model) {
1583
- const parts = model.parts;
1584
- if (parts) return { ...model, parts: await Promise.all(parts.map((part) => this.mergeWithParents(part))) };
1585
- const models = await this.collectAllParents(model);
1586
- let merged = {};
1587
- for (const source of [...models, model]) {
1588
- const inheritedDisplay = merged.display;
1589
- merged = import_ts_deepmerge.default.withOptions({ mergeArrays: false }, merged, source);
1590
- if (source.display) {
1591
- merged.display = { ...inheritedDisplay, ...DisplayTransforms.withHandFallbacks(source.display) };
1592
- }
1593
- }
1594
- merged.hierarchy = models.map((m) => m.parent).filter((p10) => `${p10}`);
1595
- merged.hierarchy.push(`${merged.parent}`);
1596
- if (model.components) merged.components = model.components;
1597
- return merged;
1598
- }
1599
- static async collectAllParents(model) {
1600
- if (!model.parent) {
1601
- return [];
1602
- }
1603
- const models = [];
1604
- const parentKey = AssetKey.parse("models", model.parent);
1605
- if (parentKey.namespace === "minecraft" && parentKey.getFullPath() === BUILTIN_ENTITY) return models;
1606
- parentKey.root = model.key?.root;
1607
- const parentModel = await Models.getRaw(parentKey);
1608
- if (parentModel) {
1609
- models.unshift(parentModel);
1610
- models.unshift(...await this.collectAllParents(parentModel));
1611
- }
1612
- return models;
1613
- }
1614
- };
1615
- }
1616
- });
1617
-
1618
1384
  // src/assets/source/parser/AssetParsers.ts
1619
1385
  var AssetParser;
1620
1386
  var init_AssetParsers = __esm({
@@ -1732,7 +1498,9 @@ ${key}` : key, async () => {
1732
1498
  static validDataset(dataset, data) {
1733
1499
  if (!object(data)) return false;
1734
1500
  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)));
1501
+ 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")));
1735
1502
  if (dataset === "legacyBlocks") return object(data.blocks) && Object.values(data.blocks).every((value) => typeof value === "string");
1503
+ 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")));
1736
1504
  return Object.values(data).every((value) => {
1737
1505
  if (!object(value)) return false;
1738
1506
  switch (dataset) {
@@ -1755,6 +1523,275 @@ ${key}` : key, async () => {
1755
1523
  }
1756
1524
  });
1757
1525
 
1526
+ // src/assets/Renames.ts
1527
+ var Renames;
1528
+ var init_Renames = __esm({
1529
+ "src/assets/Renames.ts"() {
1530
+ init_AssetKey();
1531
+ init_MineRenderData();
1532
+ Renames = class {
1533
+ /** Loads the selected version's rename table, or `undefined` when its published data has none. */
1534
+ static async get(root) {
1535
+ const resolved = await MineRenderData.resolve(root);
1536
+ return resolved.manifest.datasets.renames ? MineRenderData.get("renames", root) : void 0;
1537
+ }
1538
+ /**
1539
+ * Returns the ID that replaced `id`, or `undefined` when `id` keeps its meaning.
1540
+ * Without a data version, an ID that the selected version still registers keeps its meaning.
1541
+ */
1542
+ static async resolve(kind, id, dataVersion, root) {
1543
+ const data = await this.get(root);
1544
+ if (!data || !Object.prototype.hasOwnProperty.call(data[kind], id)) return void 0;
1545
+ const entry = data[kind][id];
1546
+ if (dataVersion === void 0) return entry.registered ? void 0 : entry.ranges[entry.ranges.length - 1].to;
1547
+ if (dataVersion < data.baseDataVersion) return void 0;
1548
+ return entry.ranges.find((range) => dataVersion < range.before)?.to;
1549
+ }
1550
+ /** Returns a copy of `key` for the replacement ID, or `undefined` when the ID keeps its meaning. */
1551
+ static async key(kind, key) {
1552
+ const renamed = await this.resolve(kind, `${key.namespace}:${key.path}`, void 0, key.root);
1553
+ if (!renamed) return void 0;
1554
+ const [namespace, path] = renamed.split(":");
1555
+ return new AssetKey(namespace, path, key.assetType, key.type, key.rootType, key.extension, key.root);
1556
+ }
1557
+ };
1558
+ }
1559
+ });
1560
+
1561
+ // src/model/Model.ts
1562
+ function isDoubleArray(obj) {
1563
+ return Array.isArray(obj) && obj.length === 2;
1564
+ }
1565
+ function isTripleArray(obj) {
1566
+ return Array.isArray(obj) && obj.length === 3;
1567
+ }
1568
+ function isQuadArray(obj) {
1569
+ return Array.isArray(obj) && obj.length === 4;
1570
+ }
1571
+ var ITEM_GENERATED, BUILTIN_GENERATED, BUILTIN_ENTITY, DEFAULT_ELEMENTS;
1572
+ var init_Model = __esm({
1573
+ "src/model/Model.ts"() {
1574
+ ITEM_GENERATED = "item/generated";
1575
+ BUILTIN_GENERATED = "builtin/generated";
1576
+ BUILTIN_ENTITY = "builtin/entity";
1577
+ DEFAULT_ELEMENTS = [];
1578
+ }
1579
+ });
1580
+
1581
+ // ../../node_modules/ts-deepmerge/dist/index.js
1582
+ var require_dist = __commonJS({
1583
+ "../../node_modules/ts-deepmerge/dist/index.js"(exports2) {
1584
+ "use strict";
1585
+ var __assign = exports2 && exports2.__assign || function() {
1586
+ __assign = Object.assign || function(t) {
1587
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
1588
+ s = arguments[i];
1589
+ for (var p10 in s) if (Object.prototype.hasOwnProperty.call(s, p10))
1590
+ t[p10] = s[p10];
1591
+ }
1592
+ return t;
1593
+ };
1594
+ return __assign.apply(this, arguments);
1595
+ };
1596
+ var __read = exports2 && exports2.__read || function(o, n) {
1597
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
1598
+ if (!m) return o;
1599
+ var i = m.call(o), r, ar = [], e;
1600
+ try {
1601
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
1602
+ } catch (error) {
1603
+ e = { error };
1604
+ } finally {
1605
+ try {
1606
+ if (r && !r.done && (m = i["return"])) m.call(i);
1607
+ } finally {
1608
+ if (e) throw e.error;
1609
+ }
1610
+ }
1611
+ return ar;
1612
+ };
1613
+ var __spreadArray = exports2 && exports2.__spreadArray || function(to, from, pack) {
1614
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
1615
+ if (ar || !(i in from)) {
1616
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
1617
+ ar[i] = from[i];
1618
+ }
1619
+ }
1620
+ return to.concat(ar || Array.prototype.slice.call(from));
1621
+ };
1622
+ Object.defineProperty(exports2, "__esModule", { value: true });
1623
+ var isObject = function(obj) {
1624
+ if (typeof obj === "object" && obj !== null) {
1625
+ if (typeof Object.getPrototypeOf === "function") {
1626
+ var prototype = Object.getPrototypeOf(obj);
1627
+ return prototype === Object.prototype || prototype === null;
1628
+ }
1629
+ return Object.prototype.toString.call(obj) === "[object Object]";
1630
+ }
1631
+ return false;
1632
+ };
1633
+ var PROTECTED_KEYS = ["__proto__"];
1634
+ var merge10 = function() {
1635
+ var objects = [];
1636
+ for (var _i = 0; _i < arguments.length; _i++) {
1637
+ objects[_i] = arguments[_i];
1638
+ }
1639
+ return objects.reduce(function(result, current) {
1640
+ Object.keys(current).forEach(function(key) {
1641
+ if (PROTECTED_KEYS.includes(key)) {
1642
+ return;
1643
+ }
1644
+ if (Array.isArray(result[key]) && Array.isArray(current[key])) {
1645
+ result[key] = merge10.options.mergeArrays ? Array.from(new Set(result[key].concat(current[key]))) : current[key];
1646
+ } else if (isObject(result[key]) && isObject(current[key])) {
1647
+ result[key] = merge10(result[key], current[key]);
1648
+ } else {
1649
+ result[key] = current[key];
1650
+ }
1651
+ });
1652
+ return result;
1653
+ }, {});
1654
+ };
1655
+ var defaultOptions = {
1656
+ mergeArrays: true
1657
+ };
1658
+ merge10.options = defaultOptions;
1659
+ merge10.withOptions = function(options) {
1660
+ var objects = [];
1661
+ for (var _i = 1; _i < arguments.length; _i++) {
1662
+ objects[_i - 1] = arguments[_i];
1663
+ }
1664
+ merge10.options = __assign({ mergeArrays: true }, options);
1665
+ var result = merge10.apply(void 0, __spreadArray([], __read(objects), false));
1666
+ merge10.options = defaultOptions;
1667
+ return result;
1668
+ };
1669
+ exports2.default = merge10;
1670
+ }
1671
+ });
1672
+
1673
+ // src/model/DisplayPosition.ts
1674
+ var DisplayPosition, DISPLAY_POSITIONS;
1675
+ var init_DisplayPosition = __esm({
1676
+ "src/model/DisplayPosition.ts"() {
1677
+ DisplayPosition = /* @__PURE__ */ ((DisplayPosition3) => {
1678
+ DisplayPosition3["THIRDPERSON_RIGHTHAND"] = "thirdperson_righthand";
1679
+ DisplayPosition3["THIRDPERSON_LEFTHAND"] = "thirdperson_lefthand";
1680
+ DisplayPosition3["FIRSTPERSON_RIGHTHAND"] = "firstperson_righthand";
1681
+ DisplayPosition3["FIRSTPERSON_LEFTHAND"] = "firstperson_lefthand";
1682
+ DisplayPosition3["GUI"] = "gui";
1683
+ DisplayPosition3["HEAD"] = "head";
1684
+ DisplayPosition3["GROUND"] = "ground";
1685
+ DisplayPosition3["FIXED"] = "fixed";
1686
+ DisplayPosition3["ON_SHELF"] = "on_shelf";
1687
+ return DisplayPosition3;
1688
+ })(DisplayPosition || {});
1689
+ DISPLAY_POSITIONS = Object.values(DisplayPosition);
1690
+ }
1691
+ });
1692
+
1693
+ // src/model/DisplayTransforms.ts
1694
+ var import_three7, DisplayTransforms;
1695
+ var init_DisplayTransforms = __esm({
1696
+ "src/model/DisplayTransforms.ts"() {
1697
+ import_three7 = require("three");
1698
+ init_DisplayPosition();
1699
+ init_util();
1700
+ DisplayTransforms = class {
1701
+ /** Resolve hand fallbacks within one model, before inheriting parent display entries. */
1702
+ static withHandFallbacks(display) {
1703
+ if (!display) return void 0;
1704
+ const resolved = { ...display };
1705
+ for (const [left, right] of [
1706
+ ["thirdperson_lefthand" /* THIRDPERSON_LEFTHAND */, "thirdperson_righthand" /* THIRDPERSON_RIGHTHAND */],
1707
+ ["firstperson_lefthand" /* FIRSTPERSON_LEFTHAND */, "firstperson_righthand" /* FIRSTPERSON_RIGHTHAND */]
1708
+ ]) {
1709
+ if (resolved[left] === void 0 && resolved[right] !== void 0) resolved[left] = resolved[right];
1710
+ }
1711
+ return resolved;
1712
+ }
1713
+ /** Build a display pose for geometry already centered at the model's [8, 8, 8] pivot. */
1714
+ static getMatrix(display, position) {
1715
+ const transform = this.getTransform(display, position);
1716
+ return new import_three7.Matrix4().compose(transform.position, transform.quaternion, transform.scale);
1717
+ }
1718
+ /** Position, rotation, and scale of a display pose for geometry already centered at the model's [8, 8, 8] pivot. */
1719
+ static getTransform(display, position) {
1720
+ const transform = this.withHandFallbacks(display)?.[position] ?? {};
1721
+ const left = position === "firstperson_lefthand" /* FIRSTPERSON_LEFTHAND */ || position === "thirdperson_lefthand" /* THIRDPERSON_LEFTHAND */;
1722
+ const sign = left ? -1 : 1;
1723
+ const [x, y, z] = transform.rotation ?? [0, 0, 0];
1724
+ const rotation = new import_three7.Quaternion().setFromEuler(new import_three7.Euler(toRadians(x), sign * toRadians(y), sign * toRadians(z), "XYZ"));
1725
+ const translation = new import_three7.Vector3(...transform.translation ?? [0, 0, 0]).clampScalar(-80, 80);
1726
+ translation.x *= sign;
1727
+ const scale = new import_three7.Vector3(...transform.scale ?? [1, 1, 1]).clampScalar(-4, 4);
1728
+ return { position: translation, quaternion: rotation, scale };
1729
+ }
1730
+ /** Transforms geometry in place and reverses triangle winding when the matrix reflects it. */
1731
+ static apply(geometry, matrix) {
1732
+ geometry.applyMatrix4(matrix);
1733
+ if (matrix.determinant() < 0) {
1734
+ if (!geometry.index) geometry.setIndex(Array.from({ length: geometry.getAttribute("position").count }, (_, i) => i));
1735
+ const index = geometry.index;
1736
+ for (let i = 0; i < index.count; i += 3) {
1737
+ const second = index.getX(i + 1);
1738
+ index.setX(i + 1, index.getX(i + 2));
1739
+ index.setX(i + 2, second);
1740
+ }
1741
+ index.needsUpdate = true;
1742
+ }
1743
+ }
1744
+ };
1745
+ }
1746
+ });
1747
+
1748
+ // src/model/ModelMerger.ts
1749
+ var import_ts_deepmerge, ModelMerger;
1750
+ var init_ModelMerger = __esm({
1751
+ "src/model/ModelMerger.ts"() {
1752
+ init_Model();
1753
+ init_Models();
1754
+ import_ts_deepmerge = __toESM(require_dist());
1755
+ init_AssetKey();
1756
+ init_DisplayTransforms();
1757
+ ModelMerger = class {
1758
+ /** Loads the parent chain and returns a merged model without modifying the supplied definition. */
1759
+ static async mergeWithParents(model) {
1760
+ const parts = model.parts;
1761
+ if (parts) return { ...model, parts: await Promise.all(parts.map((part) => this.mergeWithParents(part))) };
1762
+ const models = await this.collectAllParents(model);
1763
+ let merged = {};
1764
+ for (const source of [...models, model]) {
1765
+ const inheritedDisplay = merged.display;
1766
+ merged = import_ts_deepmerge.default.withOptions({ mergeArrays: false }, merged, source);
1767
+ if (source.display) {
1768
+ merged.display = { ...inheritedDisplay, ...DisplayTransforms.withHandFallbacks(source.display) };
1769
+ }
1770
+ }
1771
+ merged.hierarchy = models.map((m) => m.parent).filter((p10) => `${p10}`);
1772
+ merged.hierarchy.push(`${merged.parent}`);
1773
+ if (model.components) merged.components = model.components;
1774
+ return merged;
1775
+ }
1776
+ static async collectAllParents(model) {
1777
+ if (!model.parent) {
1778
+ return [];
1779
+ }
1780
+ const models = [];
1781
+ const parentKey = AssetKey.parse("models", model.parent);
1782
+ if (parentKey.namespace === "minecraft" && parentKey.getFullPath() === BUILTIN_ENTITY) return models;
1783
+ parentKey.root = model.key?.root;
1784
+ const parentModel = await Models.getRaw(parentKey);
1785
+ if (parentModel) {
1786
+ models.unshift(parentModel);
1787
+ models.unshift(...await this.collectAllParents(parentModel));
1788
+ }
1789
+ return models;
1790
+ }
1791
+ };
1792
+ }
1793
+ });
1794
+
1758
1795
  // src/assets/BannerPatterns.ts
1759
1796
  var DYE_COLORS, BannerPatterns;
1760
1797
  var init_BannerPatterns = __esm({
@@ -2077,6 +2114,7 @@ var init_ItemTints = __esm({
2077
2114
  var Models;
2078
2115
  var init_Models = __esm({
2079
2116
  "src/assets/Models.ts"() {
2117
+ init_Renames();
2080
2118
  init_Caching();
2081
2119
  init_ModelMerger();
2082
2120
  init_AssetLoader();
@@ -2410,6 +2448,11 @@ var init_Models = __esm({
2410
2448
  key.extension = ".json";
2411
2449
  }
2412
2450
  const preview = this.snapshotContext(key, context);
2451
+ if (key.type === "item") {
2452
+ const renamed = await Renames.key("items", key);
2453
+ const replacement = renamed && await this.getMerged(renamed, preview);
2454
+ if (replacement) return replacement;
2455
+ }
2413
2456
  const dataKey = await this.applyDefaults(key, preview);
2414
2457
  const keyStr = AssetLoader.persistentKey(key.serialize() + (key.type === "item" ? this.contextKey(preview) + dataKey : ""));
2415
2458
  const model = await Caching.mergedModelCache.get(keyStr, async () => {
@@ -2441,6 +2484,7 @@ var init_BlockStates = __esm({
2441
2484
  init_AssetKey();
2442
2485
  init_PersistentCache();
2443
2486
  init_AssetParsers();
2487
+ init_Renames();
2444
2488
  init_MineRenderData();
2445
2489
  BlockStates = class {
2446
2490
  static get PERSISTENT_CACHE() {
@@ -2481,6 +2525,9 @@ var init_BlockStates = __esm({
2481
2525
  if (!key.extension) {
2482
2526
  key.extension = ".json";
2483
2527
  }
2528
+ const renamed = await Renames.key("blocks", key);
2529
+ const replacement = renamed && await this.get(renamed);
2530
+ if (replacement) return replacement;
2484
2531
  const keyStr = key.serialize();
2485
2532
  return Caching.blockStateCache.get(keyStr, (k) => {
2486
2533
  return this.PERSISTENT_CACHE.getOrLoad(AssetLoader.persistentKey(keyStr), (k1) => {
@@ -7687,6 +7734,7 @@ __export(index_node_exports, {
7687
7734
  PackMetadata: () => PackMetadata,
7688
7735
  PersistentCache: () => PersistentCache,
7689
7736
  PlayerHeadTextures: () => PlayerHeadTextures,
7737
+ Renames: () => Renames,
7690
7738
  Renderer: () => Renderer,
7691
7739
  RequestError: () => RequestError,
7692
7740
  Requests: () => Requests,
@@ -8227,6 +8275,7 @@ var Fonts = class {
8227
8275
  init_MineRenderData();
8228
8276
  init_ModelTextures();
8229
8277
  init_Models();
8278
+ init_Renames();
8230
8279
  init_source();
8231
8280
 
8232
8281
  // src/cache/index.ts
@@ -17605,6 +17654,7 @@ var SectionModels = class {
17605
17654
  };
17606
17655
 
17607
17656
  // src/world/_entities/WorldEntities.ts
17657
+ init_Renames();
17608
17658
  init_Entities();
17609
17659
  init_EntityObject();
17610
17660
 
@@ -17764,8 +17814,10 @@ var WorldEntities = class {
17764
17814
  try {
17765
17815
  if (!current()) return;
17766
17816
  const models = await Entities.getEntityList();
17767
- if (!models.includes(placement.key.path) || !current()) return;
17768
- const model = await Entities.getEntity(placement.key, placement.texture, { when: placement.when });
17817
+ const renamed = models.includes(placement.key.path) ? void 0 : await Renames.key("entities", placement.key);
17818
+ const key = renamed && models.includes(renamed.path) ? renamed : placement.key;
17819
+ if (!models.includes(key.path) || !current()) return;
17820
+ const model = await Entities.getEntity(key, placement.texture, { when: placement.when });
17769
17821
  if (!model || !current()) return;
17770
17822
  let tints = placement.tints;
17771
17823
  if (placement.woolDye) {
@@ -17780,7 +17832,7 @@ var WorldEntities = class {
17780
17832
  object4.rotation.y = placement.yaw;
17781
17833
  await object4.init();
17782
17834
  if (!current()) return;
17783
- placement.owner.set(object4, { type: placement.key.toNamespacedString(), position: placement.position });
17835
+ placement.owner.set(object4, { type: key.toNamespacedString(), position: placement.position });
17784
17836
  this.scene.add(object4);
17785
17837
  } catch (error) {
17786
17838
  console.warn(`Could not draw saved entity ${placement.key.toNamespacedString()}, skipping it`, error);
@@ -17834,6 +17886,38 @@ function sampleSectionLight(light, index) {
17834
17886
  };
17835
17887
  }
17836
17888
 
17889
+ // src/world/_culling/BlockCulling.ts
17890
+ init_Assets();
17891
+ init_MineRenderData();
17892
+ init_CubeFace();
17893
+ async function loadBlockCulling(root) {
17894
+ const { manifest } = await MineRenderData.resolve(root);
17895
+ return manifest.datasets.blockCulling ? MineRenderData.get("blockCulling", root) : void 0;
17896
+ }
17897
+ function blockCullingRule(data, type) {
17898
+ if (!type.includes(":")) type = `${DEFAULT_NAMESPACE}:${type}`;
17899
+ return Object.prototype.hasOwnProperty.call(data.blocks, type) ? data.profiles[data.blocks[type]] : void 0;
17900
+ }
17901
+ function skipsBlockFace(data, rule, block, neighbor, face) {
17902
+ const type = block.type.includes(":") ? block.type : `${DEFAULT_NAMESPACE}:${block.type}`;
17903
+ const other = neighbor.type.includes(":") ? neighbor.type : `${DEFAULT_NAMESPACE}:${neighbor.type}`;
17904
+ const same = type === other;
17905
+ const vertical = CUBE_FACES[face] === "up" /* UP */ || CUBE_FACES[face] === "down" /* DOWN */;
17906
+ switch (rule.type) {
17907
+ case "same_block":
17908
+ return same;
17909
+ case "same_block_vertical":
17910
+ return same && vertical;
17911
+ case "connected": {
17912
+ if (vertical) return same;
17913
+ const group = rule.group ? data.groups?.[rule.group] : void 0;
17914
+ return (same || !!group?.includes(type) && group.includes(other)) && String(block.properties?.[CUBE_FACES[face]]) === "true" && String(neighbor.properties?.[CUBE_FACES[face ^ 1]]) === "true";
17915
+ }
17916
+ default:
17917
+ return false;
17918
+ }
17919
+ }
17920
+
17837
17921
  // src/world/MineRenderWorld.ts
17838
17922
  var MineRenderWorld = class {
17839
17923
  constructor(scene, options = {}) {
@@ -18222,15 +18306,23 @@ var MineRenderWorld = class {
18222
18306
  return this.culling ??= Promise.resolve().then(async () => {
18223
18307
  let sliceStart = performance.now();
18224
18308
  try {
18309
+ const culling = await loadBlockCulling();
18225
18310
  while (this.pendingCulling.size) {
18226
18311
  const batch = [...this.pendingCulling];
18227
18312
  this.pendingCulling.clear();
18228
18313
  for (const [chunk, indices] of batch) {
18229
18314
  const neighbors = CUBE_FACE_OFFSETS.map(([x, y, z]) => this._chunks.get(`${chunk.x + x}_${chunk.y + y}_${chunk.z + z}`));
18230
- const masks = chunk.updateCullMasks(indices === "all" ? void 0 : indices, (x, y, z) => {
18315
+ const neighborAt = (x, y, z) => {
18231
18316
  const lx = x - chunk.x * 16, ly = y - chunk.y * 16, lz = z - chunk.z * 16;
18232
18317
  const section = neighbors[lx >= 16 ? 0 : lx < 0 ? 1 : ly >= 16 ? 2 : ly < 0 ? 3 : lz >= 16 ? 4 : 5];
18233
- return section?.isOccludingIndex((ly & 15) * 256 + (lz & 15) * 16 + (lx & 15)) ?? false;
18318
+ return [section, (ly & 15) * 256 + (lz & 15) * 16 + (lx & 15)];
18319
+ };
18320
+ const masks = chunk.updateCullMasks(indices === "all" ? void 0 : indices, (x, y, z) => {
18321
+ const [section, i] = neighborAt(x, y, z);
18322
+ return section?.isOccludingIndex(i) ?? false;
18323
+ }, culling, (x, y, z) => {
18324
+ const [section, i] = neighborAt(x, y, z);
18325
+ return section?.visibleBlockIndex(i);
18234
18326
  });
18235
18327
  const fluidIndices = indices === "all" ? function* () {
18236
18328
  for (let index = 0; index < 4096; index++) yield index;
@@ -19346,6 +19438,10 @@ var Chunk = class _Chunk {
19346
19438
  isBlockVisibleIndex(index) {
19347
19439
  return this.renderedBlocks.has(index) && !this.hiddenBlocks.has(index);
19348
19440
  }
19441
+ /** Stored state of a rendered, visible cell, or `undefined`. */
19442
+ visibleBlockIndex(index) {
19443
+ return this.isBlockVisibleIndex(index) ? this.data.stateAt(this.data.idAt(index)) : void 0;
19444
+ }
19349
19445
  /** Fluid kind bits and level of a cell, or 0. Hidden cells report 0. */
19350
19446
  fluidByteIndex(index) {
19351
19447
  return this.hiddenBlocks.has(index) ? 0 : this.fluidCells[index];
@@ -19364,18 +19460,30 @@ var Chunk = class _Chunk {
19364
19460
  async setCullMaskAt(pos, mask) {
19365
19461
  await this.setCullMaskIndex(_Chunk.chunkPosToBlockIndex(this.worldPosToChunkPos(pos)), mask);
19366
19462
  }
19367
- /** Recomputes section masks and returns changed per-block masks. Omit indices to visit every cell. */
19368
- updateCullMasks(indices, occludes) {
19463
+ /**
19464
+ * Recomputes section masks and returns changed per-block masks. Omit indices to visit every cell.
19465
+ * `culling` supplies neighbor face rules; `blockAt` supplies visible states outside this chunk.
19466
+ */
19467
+ updateCullMasks(indices, occludes, culling, blockAt) {
19369
19468
  const changed = [];
19469
+ const rules = [];
19370
19470
  for (const index of indices ?? this.fluidCells.keys()) {
19371
19471
  if (!this.isBlockVisibleIndex(index)) continue;
19372
19472
  const x = index % 16, y = Math.floor(index / 256), z = Math.floor(index / 16) % 16;
19473
+ const id = this.data.idAt(index);
19474
+ let rule = rules[id];
19475
+ if (culling && rule === void 0) rules[id] = rule = blockCullingRule(culling, this.data.stateAt(id).type) ?? null;
19476
+ const block = rule ? this.data.stateAt(id) : void 0;
19373
19477
  let mask = 0;
19374
19478
  for (let face = 0; face < CUBE_FACE_OFFSETS.length; face++) {
19375
19479
  const [dx, dy, dz] = CUBE_FACE_OFFSETS[face];
19376
19480
  const nx = x + dx, ny = y + dy, nz = z + dz;
19377
19481
  const inner = nx >= 0 && nx < 16 && ny >= 0 && ny < 16 && nz >= 0 && nz < 16;
19378
19482
  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;
19483
+ else if (rule) {
19484
+ const neighbor = inner ? this.visibleBlockIndex(ny * 256 + nz * 16 + nx) : blockAt?.(this.x * 16 + nx, this.y * 16 + ny, this.z * 16 + nz);
19485
+ if (neighbor && skipsBlockFace(culling, rule, block, neighbor, face)) mask |= 1 << face;
19486
+ }
19379
19487
  }
19380
19488
  if (this.fluidCells[index]) this.meshDirty = true;
19381
19489
  const entries = this.sectionBlocks.get(index);
@@ -19954,6 +20062,7 @@ var NodeRenderer = class _NodeRenderer extends Renderer {
19954
20062
  PackMetadata,
19955
20063
  PersistentCache,
19956
20064
  PlayerHeadTextures,
20065
+ Renames,
19957
20066
  Renderer,
19958
20067
  RequestError,
19959
20068
  Requests,