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.
@@ -1209,118 +1209,6 @@ var init_Materials = __esm({
1209
1209
  }
1210
1210
  });
1211
1211
 
1212
- // src/model/Model.ts
1213
- function isDoubleArray(obj) {
1214
- return Array.isArray(obj) && obj.length === 2;
1215
- }
1216
- function isTripleArray(obj) {
1217
- return Array.isArray(obj) && obj.length === 3;
1218
- }
1219
- function isQuadArray(obj) {
1220
- return Array.isArray(obj) && obj.length === 4;
1221
- }
1222
- var ITEM_GENERATED, BUILTIN_GENERATED, BUILTIN_ENTITY, DEFAULT_ELEMENTS;
1223
- var init_Model = __esm({
1224
- "src/model/Model.ts"() {
1225
- ITEM_GENERATED = "item/generated";
1226
- BUILTIN_GENERATED = "builtin/generated";
1227
- BUILTIN_ENTITY = "builtin/entity";
1228
- DEFAULT_ELEMENTS = [];
1229
- }
1230
- });
1231
-
1232
- // ../../node_modules/ts-deepmerge/dist/index.js
1233
- var require_dist = __commonJS({
1234
- "../../node_modules/ts-deepmerge/dist/index.js"(exports) {
1235
- "use strict";
1236
- var __assign = exports && exports.__assign || function() {
1237
- __assign = Object.assign || function(t) {
1238
- for (var s, i = 1, n = arguments.length; i < n; i++) {
1239
- s = arguments[i];
1240
- for (var p11 in s) if (Object.prototype.hasOwnProperty.call(s, p11))
1241
- t[p11] = s[p11];
1242
- }
1243
- return t;
1244
- };
1245
- return __assign.apply(this, arguments);
1246
- };
1247
- var __read = exports && exports.__read || function(o, n) {
1248
- var m = typeof Symbol === "function" && o[Symbol.iterator];
1249
- if (!m) return o;
1250
- var i = m.call(o), r, ar = [], e;
1251
- try {
1252
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
1253
- } catch (error) {
1254
- e = { error };
1255
- } finally {
1256
- try {
1257
- if (r && !r.done && (m = i["return"])) m.call(i);
1258
- } finally {
1259
- if (e) throw e.error;
1260
- }
1261
- }
1262
- return ar;
1263
- };
1264
- var __spreadArray = exports && exports.__spreadArray || function(to, from, pack) {
1265
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
1266
- if (ar || !(i in from)) {
1267
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
1268
- ar[i] = from[i];
1269
- }
1270
- }
1271
- return to.concat(ar || Array.prototype.slice.call(from));
1272
- };
1273
- Object.defineProperty(exports, "__esModule", { value: true });
1274
- var isObject = function(obj) {
1275
- if (typeof obj === "object" && obj !== null) {
1276
- if (typeof Object.getPrototypeOf === "function") {
1277
- var prototype = Object.getPrototypeOf(obj);
1278
- return prototype === Object.prototype || prototype === null;
1279
- }
1280
- return Object.prototype.toString.call(obj) === "[object Object]";
1281
- }
1282
- return false;
1283
- };
1284
- var PROTECTED_KEYS = ["__proto__"];
1285
- var merge10 = function() {
1286
- var objects = [];
1287
- for (var _i = 0; _i < arguments.length; _i++) {
1288
- objects[_i] = arguments[_i];
1289
- }
1290
- return objects.reduce(function(result, current) {
1291
- Object.keys(current).forEach(function(key) {
1292
- if (PROTECTED_KEYS.includes(key)) {
1293
- return;
1294
- }
1295
- if (Array.isArray(result[key]) && Array.isArray(current[key])) {
1296
- result[key] = merge10.options.mergeArrays ? Array.from(new Set(result[key].concat(current[key]))) : current[key];
1297
- } else if (isObject(result[key]) && isObject(current[key])) {
1298
- result[key] = merge10(result[key], current[key]);
1299
- } else {
1300
- result[key] = current[key];
1301
- }
1302
- });
1303
- return result;
1304
- }, {});
1305
- };
1306
- var defaultOptions = {
1307
- mergeArrays: true
1308
- };
1309
- merge10.options = defaultOptions;
1310
- merge10.withOptions = function(options) {
1311
- var objects = [];
1312
- for (var _i = 1; _i < arguments.length; _i++) {
1313
- objects[_i - 1] = arguments[_i];
1314
- }
1315
- merge10.options = __assign({ mergeArrays: true }, options);
1316
- var result = merge10.apply(void 0, __spreadArray([], __read(objects), false));
1317
- merge10.options = defaultOptions;
1318
- return result;
1319
- };
1320
- exports.default = merge10;
1321
- }
1322
- });
1323
-
1324
1212
  // src/assets/AssetKey.ts
1325
1213
  function isResourceLocation(value) {
1326
1214
  return typeof value === "string" && /^(?:[a-z0-9_.-]+:)?[a-z0-9_./-]+$/.test(value);
@@ -1437,128 +1325,6 @@ var init_AssetKey = __esm({
1437
1325
  }
1438
1326
  });
1439
1327
 
1440
- // src/model/DisplayPosition.ts
1441
- var DisplayPosition, DISPLAY_POSITIONS;
1442
- var init_DisplayPosition = __esm({
1443
- "src/model/DisplayPosition.ts"() {
1444
- DisplayPosition = /* @__PURE__ */ ((DisplayPosition3) => {
1445
- DisplayPosition3["THIRDPERSON_RIGHTHAND"] = "thirdperson_righthand";
1446
- DisplayPosition3["THIRDPERSON_LEFTHAND"] = "thirdperson_lefthand";
1447
- DisplayPosition3["FIRSTPERSON_RIGHTHAND"] = "firstperson_righthand";
1448
- DisplayPosition3["FIRSTPERSON_LEFTHAND"] = "firstperson_lefthand";
1449
- DisplayPosition3["GUI"] = "gui";
1450
- DisplayPosition3["HEAD"] = "head";
1451
- DisplayPosition3["GROUND"] = "ground";
1452
- DisplayPosition3["FIXED"] = "fixed";
1453
- DisplayPosition3["ON_SHELF"] = "on_shelf";
1454
- return DisplayPosition3;
1455
- })(DisplayPosition || {});
1456
- DISPLAY_POSITIONS = Object.values(DisplayPosition);
1457
- }
1458
- });
1459
-
1460
- // src/model/DisplayTransforms.ts
1461
- var import_three7, DisplayTransforms;
1462
- var init_DisplayTransforms = __esm({
1463
- "src/model/DisplayTransforms.ts"() {
1464
- import_three7 = require("three");
1465
- init_DisplayPosition();
1466
- init_util();
1467
- DisplayTransforms = class {
1468
- /** Resolve hand fallbacks within one model, before inheriting parent display entries. */
1469
- static withHandFallbacks(display) {
1470
- if (!display) return void 0;
1471
- const resolved = { ...display };
1472
- for (const [left, right] of [
1473
- ["thirdperson_lefthand" /* THIRDPERSON_LEFTHAND */, "thirdperson_righthand" /* THIRDPERSON_RIGHTHAND */],
1474
- ["firstperson_lefthand" /* FIRSTPERSON_LEFTHAND */, "firstperson_righthand" /* FIRSTPERSON_RIGHTHAND */]
1475
- ]) {
1476
- if (resolved[left] === void 0 && resolved[right] !== void 0) resolved[left] = resolved[right];
1477
- }
1478
- return resolved;
1479
- }
1480
- /** Build a display pose for geometry already centered at the model's [8, 8, 8] pivot. */
1481
- static getMatrix(display, position) {
1482
- const transform = this.getTransform(display, position);
1483
- return new import_three7.Matrix4().compose(transform.position, transform.quaternion, transform.scale);
1484
- }
1485
- /** Position, rotation, and scale of a display pose for geometry already centered at the model's [8, 8, 8] pivot. */
1486
- static getTransform(display, position) {
1487
- const transform = this.withHandFallbacks(display)?.[position] ?? {};
1488
- const left = position === "firstperson_lefthand" /* FIRSTPERSON_LEFTHAND */ || position === "thirdperson_lefthand" /* THIRDPERSON_LEFTHAND */;
1489
- const sign = left ? -1 : 1;
1490
- const [x, y, z] = transform.rotation ?? [0, 0, 0];
1491
- const rotation = new import_three7.Quaternion().setFromEuler(new import_three7.Euler(toRadians(x), sign * toRadians(y), sign * toRadians(z), "XYZ"));
1492
- const translation = new import_three7.Vector3(...transform.translation ?? [0, 0, 0]).clampScalar(-80, 80);
1493
- translation.x *= sign;
1494
- const scale = new import_three7.Vector3(...transform.scale ?? [1, 1, 1]).clampScalar(-4, 4);
1495
- return { position: translation, quaternion: rotation, scale };
1496
- }
1497
- /** Transforms geometry in place and reverses triangle winding when the matrix reflects it. */
1498
- static apply(geometry, matrix) {
1499
- geometry.applyMatrix4(matrix);
1500
- if (matrix.determinant() < 0) {
1501
- if (!geometry.index) geometry.setIndex(Array.from({ length: geometry.getAttribute("position").count }, (_, i) => i));
1502
- const index = geometry.index;
1503
- for (let i = 0; i < index.count; i += 3) {
1504
- const second = index.getX(i + 1);
1505
- index.setX(i + 1, index.getX(i + 2));
1506
- index.setX(i + 2, second);
1507
- }
1508
- index.needsUpdate = true;
1509
- }
1510
- }
1511
- };
1512
- }
1513
- });
1514
-
1515
- // src/model/ModelMerger.ts
1516
- var import_ts_deepmerge, ModelMerger;
1517
- var init_ModelMerger = __esm({
1518
- "src/model/ModelMerger.ts"() {
1519
- init_Model();
1520
- init_Models();
1521
- import_ts_deepmerge = __toESM(require_dist());
1522
- init_AssetKey();
1523
- init_DisplayTransforms();
1524
- ModelMerger = class {
1525
- /** Loads the parent chain and returns a merged model without modifying the supplied definition. */
1526
- static async mergeWithParents(model) {
1527
- const parts = model.parts;
1528
- if (parts) return { ...model, parts: await Promise.all(parts.map((part) => this.mergeWithParents(part))) };
1529
- const models = await this.collectAllParents(model);
1530
- let merged = {};
1531
- for (const source of [...models, model]) {
1532
- const inheritedDisplay = merged.display;
1533
- merged = import_ts_deepmerge.default.withOptions({ mergeArrays: false }, merged, source);
1534
- if (source.display) {
1535
- merged.display = { ...inheritedDisplay, ...DisplayTransforms.withHandFallbacks(source.display) };
1536
- }
1537
- }
1538
- merged.hierarchy = models.map((m) => m.parent).filter((p11) => `${p11}`);
1539
- merged.hierarchy.push(`${merged.parent}`);
1540
- if (model.components) merged.components = model.components;
1541
- return merged;
1542
- }
1543
- static async collectAllParents(model) {
1544
- if (!model.parent) {
1545
- return [];
1546
- }
1547
- const models = [];
1548
- const parentKey = AssetKey.parse("models", model.parent);
1549
- if (parentKey.namespace === "minecraft" && parentKey.getFullPath() === BUILTIN_ENTITY) return models;
1550
- parentKey.root = model.key?.root;
1551
- const parentModel = await Models.getRaw(parentKey);
1552
- if (parentModel) {
1553
- models.unshift(parentModel);
1554
- models.unshift(...await this.collectAllParents(parentModel));
1555
- }
1556
- return models;
1557
- }
1558
- };
1559
- }
1560
- });
1561
-
1562
1328
  // src/assets/source/parser/AssetParsers.ts
1563
1329
  var AssetParser;
1564
1330
  var init_AssetParsers = __esm({
@@ -1676,7 +1442,9 @@ ${key}` : key, async () => {
1676
1442
  static validDataset(dataset, data) {
1677
1443
  if (!object(data)) return false;
1678
1444
  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)));
1445
+ 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")));
1679
1446
  if (dataset === "legacyBlocks") return object(data.blocks) && Object.values(data.blocks).every((value) => typeof value === "string");
1447
+ 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")));
1680
1448
  return Object.values(data).every((value) => {
1681
1449
  if (!object(value)) return false;
1682
1450
  switch (dataset) {
@@ -1699,6 +1467,275 @@ ${key}` : key, async () => {
1699
1467
  }
1700
1468
  });
1701
1469
 
1470
+ // src/assets/Renames.ts
1471
+ var Renames;
1472
+ var init_Renames = __esm({
1473
+ "src/assets/Renames.ts"() {
1474
+ init_AssetKey();
1475
+ init_MineRenderData();
1476
+ Renames = class {
1477
+ /** Loads the selected version's rename table, or `undefined` when its published data has none. */
1478
+ static async get(root) {
1479
+ const resolved = await MineRenderData.resolve(root);
1480
+ return resolved.manifest.datasets.renames ? MineRenderData.get("renames", root) : void 0;
1481
+ }
1482
+ /**
1483
+ * Returns the ID that replaced `id`, or `undefined` when `id` keeps its meaning.
1484
+ * Without a data version, an ID that the selected version still registers keeps its meaning.
1485
+ */
1486
+ static async resolve(kind, id, dataVersion, root) {
1487
+ const data = await this.get(root);
1488
+ if (!data || !Object.prototype.hasOwnProperty.call(data[kind], id)) return void 0;
1489
+ const entry = data[kind][id];
1490
+ if (dataVersion === void 0) return entry.registered ? void 0 : entry.ranges[entry.ranges.length - 1].to;
1491
+ if (dataVersion < data.baseDataVersion) return void 0;
1492
+ return entry.ranges.find((range) => dataVersion < range.before)?.to;
1493
+ }
1494
+ /** Returns a copy of `key` for the replacement ID, or `undefined` when the ID keeps its meaning. */
1495
+ static async key(kind, key) {
1496
+ const renamed = await this.resolve(kind, `${key.namespace}:${key.path}`, void 0, key.root);
1497
+ if (!renamed) return void 0;
1498
+ const [namespace, path] = renamed.split(":");
1499
+ return new AssetKey(namespace, path, key.assetType, key.type, key.rootType, key.extension, key.root);
1500
+ }
1501
+ };
1502
+ }
1503
+ });
1504
+
1505
+ // src/model/Model.ts
1506
+ function isDoubleArray(obj) {
1507
+ return Array.isArray(obj) && obj.length === 2;
1508
+ }
1509
+ function isTripleArray(obj) {
1510
+ return Array.isArray(obj) && obj.length === 3;
1511
+ }
1512
+ function isQuadArray(obj) {
1513
+ return Array.isArray(obj) && obj.length === 4;
1514
+ }
1515
+ var ITEM_GENERATED, BUILTIN_GENERATED, BUILTIN_ENTITY, DEFAULT_ELEMENTS;
1516
+ var init_Model = __esm({
1517
+ "src/model/Model.ts"() {
1518
+ ITEM_GENERATED = "item/generated";
1519
+ BUILTIN_GENERATED = "builtin/generated";
1520
+ BUILTIN_ENTITY = "builtin/entity";
1521
+ DEFAULT_ELEMENTS = [];
1522
+ }
1523
+ });
1524
+
1525
+ // ../../node_modules/ts-deepmerge/dist/index.js
1526
+ var require_dist = __commonJS({
1527
+ "../../node_modules/ts-deepmerge/dist/index.js"(exports) {
1528
+ "use strict";
1529
+ var __assign = exports && exports.__assign || function() {
1530
+ __assign = Object.assign || function(t) {
1531
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
1532
+ s = arguments[i];
1533
+ for (var p11 in s) if (Object.prototype.hasOwnProperty.call(s, p11))
1534
+ t[p11] = s[p11];
1535
+ }
1536
+ return t;
1537
+ };
1538
+ return __assign.apply(this, arguments);
1539
+ };
1540
+ var __read = exports && exports.__read || function(o, n) {
1541
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
1542
+ if (!m) return o;
1543
+ var i = m.call(o), r, ar = [], e;
1544
+ try {
1545
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
1546
+ } catch (error) {
1547
+ e = { error };
1548
+ } finally {
1549
+ try {
1550
+ if (r && !r.done && (m = i["return"])) m.call(i);
1551
+ } finally {
1552
+ if (e) throw e.error;
1553
+ }
1554
+ }
1555
+ return ar;
1556
+ };
1557
+ var __spreadArray = exports && exports.__spreadArray || function(to, from, pack) {
1558
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
1559
+ if (ar || !(i in from)) {
1560
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
1561
+ ar[i] = from[i];
1562
+ }
1563
+ }
1564
+ return to.concat(ar || Array.prototype.slice.call(from));
1565
+ };
1566
+ Object.defineProperty(exports, "__esModule", { value: true });
1567
+ var isObject = function(obj) {
1568
+ if (typeof obj === "object" && obj !== null) {
1569
+ if (typeof Object.getPrototypeOf === "function") {
1570
+ var prototype = Object.getPrototypeOf(obj);
1571
+ return prototype === Object.prototype || prototype === null;
1572
+ }
1573
+ return Object.prototype.toString.call(obj) === "[object Object]";
1574
+ }
1575
+ return false;
1576
+ };
1577
+ var PROTECTED_KEYS = ["__proto__"];
1578
+ var merge10 = function() {
1579
+ var objects = [];
1580
+ for (var _i = 0; _i < arguments.length; _i++) {
1581
+ objects[_i] = arguments[_i];
1582
+ }
1583
+ return objects.reduce(function(result, current) {
1584
+ Object.keys(current).forEach(function(key) {
1585
+ if (PROTECTED_KEYS.includes(key)) {
1586
+ return;
1587
+ }
1588
+ if (Array.isArray(result[key]) && Array.isArray(current[key])) {
1589
+ result[key] = merge10.options.mergeArrays ? Array.from(new Set(result[key].concat(current[key]))) : current[key];
1590
+ } else if (isObject(result[key]) && isObject(current[key])) {
1591
+ result[key] = merge10(result[key], current[key]);
1592
+ } else {
1593
+ result[key] = current[key];
1594
+ }
1595
+ });
1596
+ return result;
1597
+ }, {});
1598
+ };
1599
+ var defaultOptions = {
1600
+ mergeArrays: true
1601
+ };
1602
+ merge10.options = defaultOptions;
1603
+ merge10.withOptions = function(options) {
1604
+ var objects = [];
1605
+ for (var _i = 1; _i < arguments.length; _i++) {
1606
+ objects[_i - 1] = arguments[_i];
1607
+ }
1608
+ merge10.options = __assign({ mergeArrays: true }, options);
1609
+ var result = merge10.apply(void 0, __spreadArray([], __read(objects), false));
1610
+ merge10.options = defaultOptions;
1611
+ return result;
1612
+ };
1613
+ exports.default = merge10;
1614
+ }
1615
+ });
1616
+
1617
+ // src/model/DisplayPosition.ts
1618
+ var DisplayPosition, DISPLAY_POSITIONS;
1619
+ var init_DisplayPosition = __esm({
1620
+ "src/model/DisplayPosition.ts"() {
1621
+ DisplayPosition = /* @__PURE__ */ ((DisplayPosition3) => {
1622
+ DisplayPosition3["THIRDPERSON_RIGHTHAND"] = "thirdperson_righthand";
1623
+ DisplayPosition3["THIRDPERSON_LEFTHAND"] = "thirdperson_lefthand";
1624
+ DisplayPosition3["FIRSTPERSON_RIGHTHAND"] = "firstperson_righthand";
1625
+ DisplayPosition3["FIRSTPERSON_LEFTHAND"] = "firstperson_lefthand";
1626
+ DisplayPosition3["GUI"] = "gui";
1627
+ DisplayPosition3["HEAD"] = "head";
1628
+ DisplayPosition3["GROUND"] = "ground";
1629
+ DisplayPosition3["FIXED"] = "fixed";
1630
+ DisplayPosition3["ON_SHELF"] = "on_shelf";
1631
+ return DisplayPosition3;
1632
+ })(DisplayPosition || {});
1633
+ DISPLAY_POSITIONS = Object.values(DisplayPosition);
1634
+ }
1635
+ });
1636
+
1637
+ // src/model/DisplayTransforms.ts
1638
+ var import_three7, DisplayTransforms;
1639
+ var init_DisplayTransforms = __esm({
1640
+ "src/model/DisplayTransforms.ts"() {
1641
+ import_three7 = require("three");
1642
+ init_DisplayPosition();
1643
+ init_util();
1644
+ DisplayTransforms = class {
1645
+ /** Resolve hand fallbacks within one model, before inheriting parent display entries. */
1646
+ static withHandFallbacks(display) {
1647
+ if (!display) return void 0;
1648
+ const resolved = { ...display };
1649
+ for (const [left, right] of [
1650
+ ["thirdperson_lefthand" /* THIRDPERSON_LEFTHAND */, "thirdperson_righthand" /* THIRDPERSON_RIGHTHAND */],
1651
+ ["firstperson_lefthand" /* FIRSTPERSON_LEFTHAND */, "firstperson_righthand" /* FIRSTPERSON_RIGHTHAND */]
1652
+ ]) {
1653
+ if (resolved[left] === void 0 && resolved[right] !== void 0) resolved[left] = resolved[right];
1654
+ }
1655
+ return resolved;
1656
+ }
1657
+ /** Build a display pose for geometry already centered at the model's [8, 8, 8] pivot. */
1658
+ static getMatrix(display, position) {
1659
+ const transform = this.getTransform(display, position);
1660
+ return new import_three7.Matrix4().compose(transform.position, transform.quaternion, transform.scale);
1661
+ }
1662
+ /** Position, rotation, and scale of a display pose for geometry already centered at the model's [8, 8, 8] pivot. */
1663
+ static getTransform(display, position) {
1664
+ const transform = this.withHandFallbacks(display)?.[position] ?? {};
1665
+ const left = position === "firstperson_lefthand" /* FIRSTPERSON_LEFTHAND */ || position === "thirdperson_lefthand" /* THIRDPERSON_LEFTHAND */;
1666
+ const sign = left ? -1 : 1;
1667
+ const [x, y, z] = transform.rotation ?? [0, 0, 0];
1668
+ const rotation = new import_three7.Quaternion().setFromEuler(new import_three7.Euler(toRadians(x), sign * toRadians(y), sign * toRadians(z), "XYZ"));
1669
+ const translation = new import_three7.Vector3(...transform.translation ?? [0, 0, 0]).clampScalar(-80, 80);
1670
+ translation.x *= sign;
1671
+ const scale = new import_three7.Vector3(...transform.scale ?? [1, 1, 1]).clampScalar(-4, 4);
1672
+ return { position: translation, quaternion: rotation, scale };
1673
+ }
1674
+ /** Transforms geometry in place and reverses triangle winding when the matrix reflects it. */
1675
+ static apply(geometry, matrix) {
1676
+ geometry.applyMatrix4(matrix);
1677
+ if (matrix.determinant() < 0) {
1678
+ if (!geometry.index) geometry.setIndex(Array.from({ length: geometry.getAttribute("position").count }, (_, i) => i));
1679
+ const index = geometry.index;
1680
+ for (let i = 0; i < index.count; i += 3) {
1681
+ const second = index.getX(i + 1);
1682
+ index.setX(i + 1, index.getX(i + 2));
1683
+ index.setX(i + 2, second);
1684
+ }
1685
+ index.needsUpdate = true;
1686
+ }
1687
+ }
1688
+ };
1689
+ }
1690
+ });
1691
+
1692
+ // src/model/ModelMerger.ts
1693
+ var import_ts_deepmerge, ModelMerger;
1694
+ var init_ModelMerger = __esm({
1695
+ "src/model/ModelMerger.ts"() {
1696
+ init_Model();
1697
+ init_Models();
1698
+ import_ts_deepmerge = __toESM(require_dist());
1699
+ init_AssetKey();
1700
+ init_DisplayTransforms();
1701
+ ModelMerger = class {
1702
+ /** Loads the parent chain and returns a merged model without modifying the supplied definition. */
1703
+ static async mergeWithParents(model) {
1704
+ const parts = model.parts;
1705
+ if (parts) return { ...model, parts: await Promise.all(parts.map((part) => this.mergeWithParents(part))) };
1706
+ const models = await this.collectAllParents(model);
1707
+ let merged = {};
1708
+ for (const source of [...models, model]) {
1709
+ const inheritedDisplay = merged.display;
1710
+ merged = import_ts_deepmerge.default.withOptions({ mergeArrays: false }, merged, source);
1711
+ if (source.display) {
1712
+ merged.display = { ...inheritedDisplay, ...DisplayTransforms.withHandFallbacks(source.display) };
1713
+ }
1714
+ }
1715
+ merged.hierarchy = models.map((m) => m.parent).filter((p11) => `${p11}`);
1716
+ merged.hierarchy.push(`${merged.parent}`);
1717
+ if (model.components) merged.components = model.components;
1718
+ return merged;
1719
+ }
1720
+ static async collectAllParents(model) {
1721
+ if (!model.parent) {
1722
+ return [];
1723
+ }
1724
+ const models = [];
1725
+ const parentKey = AssetKey.parse("models", model.parent);
1726
+ if (parentKey.namespace === "minecraft" && parentKey.getFullPath() === BUILTIN_ENTITY) return models;
1727
+ parentKey.root = model.key?.root;
1728
+ const parentModel = await Models.getRaw(parentKey);
1729
+ if (parentModel) {
1730
+ models.unshift(parentModel);
1731
+ models.unshift(...await this.collectAllParents(parentModel));
1732
+ }
1733
+ return models;
1734
+ }
1735
+ };
1736
+ }
1737
+ });
1738
+
1702
1739
  // src/assets/BannerPatterns.ts
1703
1740
  var DYE_COLORS, BannerPatterns;
1704
1741
  var init_BannerPatterns = __esm({
@@ -2021,6 +2058,7 @@ var init_ItemTints = __esm({
2021
2058
  var Models;
2022
2059
  var init_Models = __esm({
2023
2060
  "src/assets/Models.ts"() {
2061
+ init_Renames();
2024
2062
  init_Caching();
2025
2063
  init_ModelMerger();
2026
2064
  init_AssetLoader();
@@ -2350,6 +2388,11 @@ var init_Models = __esm({
2350
2388
  key.extension = ".json";
2351
2389
  }
2352
2390
  const preview = this.snapshotContext(key, context);
2391
+ if (key.type === "item") {
2392
+ const renamed = await Renames.key("items", key);
2393
+ const replacement = renamed && await this.getMerged(renamed, preview);
2394
+ if (replacement) return replacement;
2395
+ }
2353
2396
  const dataKey = await this.applyDefaults(key, preview);
2354
2397
  const keyStr = AssetLoader.persistentKey(key.serialize() + (key.type === "item" ? this.contextKey(preview) + dataKey : ""));
2355
2398
  const model = await Caching.mergedModelCache.get(keyStr, async () => {
@@ -2383,6 +2426,7 @@ var init_BlockStates = __esm({
2383
2426
  init_AssetKey();
2384
2427
  init_PersistentCache();
2385
2428
  init_AssetParsers();
2429
+ init_Renames();
2386
2430
  init_MineRenderData();
2387
2431
  BlockStates = class {
2388
2432
  static get PERSISTENT_CACHE() {
@@ -2423,6 +2467,9 @@ var init_BlockStates = __esm({
2423
2467
  if (!key.extension) {
2424
2468
  key.extension = ".json";
2425
2469
  }
2470
+ const renamed = await Renames.key("blocks", key);
2471
+ const replacement = renamed && await this.get(renamed);
2472
+ if (replacement) return replacement;
2426
2473
  const keyStr = key.serialize();
2427
2474
  return Caching.blockStateCache.get(keyStr, (k) => {
2428
2475
  return this.PERSISTENT_CACHE.getOrLoad(AssetLoader.persistentKey(keyStr), (k1) => {
@@ -7586,6 +7633,7 @@ __export(index_browser_exports, {
7586
7633
  PackMetadata: () => PackMetadata,
7587
7634
  PersistentCache: () => PersistentCache,
7588
7635
  PlayerHeadTextures: () => PlayerHeadTextures,
7636
+ Renames: () => Renames,
7589
7637
  Renderer: () => Renderer,
7590
7638
  RequestError: () => RequestError,
7591
7639
  Requests: () => Requests,
@@ -8195,6 +8243,7 @@ var Fonts = class {
8195
8243
  init_MineRenderData();
8196
8244
  init_ModelTextures();
8197
8245
  init_Models();
8246
+ init_Renames();
8198
8247
  init_source();
8199
8248
 
8200
8249
  // src/cache/index.ts
@@ -17570,6 +17619,7 @@ var SectionModels = class {
17570
17619
  };
17571
17620
 
17572
17621
  // src/world/_entities/WorldEntities.ts
17622
+ init_Renames();
17573
17623
  init_Entities();
17574
17624
  init_EntityObject();
17575
17625
 
@@ -17729,8 +17779,10 @@ var WorldEntities = class {
17729
17779
  try {
17730
17780
  if (!current()) return;
17731
17781
  const models = await Entities.getEntityList();
17732
- if (!models.includes(placement.key.path) || !current()) return;
17733
- const model = await Entities.getEntity(placement.key, placement.texture, { when: placement.when });
17782
+ const renamed = models.includes(placement.key.path) ? void 0 : await Renames.key("entities", placement.key);
17783
+ const key = renamed && models.includes(renamed.path) ? renamed : placement.key;
17784
+ if (!models.includes(key.path) || !current()) return;
17785
+ const model = await Entities.getEntity(key, placement.texture, { when: placement.when });
17734
17786
  if (!model || !current()) return;
17735
17787
  let tints = placement.tints;
17736
17788
  if (placement.woolDye) {
@@ -17745,7 +17797,7 @@ var WorldEntities = class {
17745
17797
  object4.rotation.y = placement.yaw;
17746
17798
  await object4.init();
17747
17799
  if (!current()) return;
17748
- placement.owner.set(object4, { type: placement.key.toNamespacedString(), position: placement.position });
17800
+ placement.owner.set(object4, { type: key.toNamespacedString(), position: placement.position });
17749
17801
  this.scene.add(object4);
17750
17802
  } catch (error) {
17751
17803
  console.warn(`Could not draw saved entity ${placement.key.toNamespacedString()}, skipping it`, error);
@@ -17799,6 +17851,38 @@ function sampleSectionLight(light, index) {
17799
17851
  };
17800
17852
  }
17801
17853
 
17854
+ // src/world/_culling/BlockCulling.ts
17855
+ init_Assets();
17856
+ init_MineRenderData();
17857
+ init_CubeFace();
17858
+ async function loadBlockCulling(root) {
17859
+ const { manifest } = await MineRenderData.resolve(root);
17860
+ return manifest.datasets.blockCulling ? MineRenderData.get("blockCulling", root) : void 0;
17861
+ }
17862
+ function blockCullingRule(data, type) {
17863
+ if (!type.includes(":")) type = `${DEFAULT_NAMESPACE}:${type}`;
17864
+ return Object.prototype.hasOwnProperty.call(data.blocks, type) ? data.profiles[data.blocks[type]] : void 0;
17865
+ }
17866
+ function skipsBlockFace(data, rule, block, neighbor, face) {
17867
+ const type = block.type.includes(":") ? block.type : `${DEFAULT_NAMESPACE}:${block.type}`;
17868
+ const other = neighbor.type.includes(":") ? neighbor.type : `${DEFAULT_NAMESPACE}:${neighbor.type}`;
17869
+ const same = type === other;
17870
+ const vertical = CUBE_FACES[face] === "up" /* UP */ || CUBE_FACES[face] === "down" /* DOWN */;
17871
+ switch (rule.type) {
17872
+ case "same_block":
17873
+ return same;
17874
+ case "same_block_vertical":
17875
+ return same && vertical;
17876
+ case "connected": {
17877
+ if (vertical) return same;
17878
+ const group = rule.group ? data.groups?.[rule.group] : void 0;
17879
+ return (same || !!group?.includes(type) && group.includes(other)) && String(block.properties?.[CUBE_FACES[face]]) === "true" && String(neighbor.properties?.[CUBE_FACES[face ^ 1]]) === "true";
17880
+ }
17881
+ default:
17882
+ return false;
17883
+ }
17884
+ }
17885
+
17802
17886
  // src/world/MineRenderWorld.ts
17803
17887
  var MineRenderWorld = class {
17804
17888
  constructor(scene, options = {}) {
@@ -18187,15 +18271,23 @@ var MineRenderWorld = class {
18187
18271
  return this.culling ?? (this.culling = Promise.resolve().then(async () => {
18188
18272
  let sliceStart = performance.now();
18189
18273
  try {
18274
+ const culling = await loadBlockCulling();
18190
18275
  while (this.pendingCulling.size) {
18191
18276
  const batch = [...this.pendingCulling];
18192
18277
  this.pendingCulling.clear();
18193
18278
  for (const [chunk, indices] of batch) {
18194
18279
  const neighbors = CUBE_FACE_OFFSETS.map(([x, y, z]) => this._chunks.get(`${chunk.x + x}_${chunk.y + y}_${chunk.z + z}`));
18195
- const masks = chunk.updateCullMasks(indices === "all" ? void 0 : indices, (x, y, z) => {
18280
+ const neighborAt = (x, y, z) => {
18196
18281
  const lx = x - chunk.x * 16, ly = y - chunk.y * 16, lz = z - chunk.z * 16;
18197
18282
  const section = neighbors[lx >= 16 ? 0 : lx < 0 ? 1 : ly >= 16 ? 2 : ly < 0 ? 3 : lz >= 16 ? 4 : 5];
18198
- return section?.isOccludingIndex((ly & 15) * 256 + (lz & 15) * 16 + (lx & 15)) ?? false;
18283
+ return [section, (ly & 15) * 256 + (lz & 15) * 16 + (lx & 15)];
18284
+ };
18285
+ const masks = chunk.updateCullMasks(indices === "all" ? void 0 : indices, (x, y, z) => {
18286
+ const [section, i] = neighborAt(x, y, z);
18287
+ return section?.isOccludingIndex(i) ?? false;
18288
+ }, culling, (x, y, z) => {
18289
+ const [section, i] = neighborAt(x, y, z);
18290
+ return section?.visibleBlockIndex(i);
18199
18291
  });
18200
18292
  const fluidIndices = indices === "all" ? function* () {
18201
18293
  for (let index = 0; index < 4096; index++) yield index;
@@ -19310,6 +19402,10 @@ var Chunk = class _Chunk {
19310
19402
  isBlockVisibleIndex(index) {
19311
19403
  return this.renderedBlocks.has(index) && !this.hiddenBlocks.has(index);
19312
19404
  }
19405
+ /** Stored state of a rendered, visible cell, or `undefined`. */
19406
+ visibleBlockIndex(index) {
19407
+ return this.isBlockVisibleIndex(index) ? this.data.stateAt(this.data.idAt(index)) : void 0;
19408
+ }
19313
19409
  /** Fluid kind bits and level of a cell, or 0. Hidden cells report 0. */
19314
19410
  fluidByteIndex(index) {
19315
19411
  return this.hiddenBlocks.has(index) ? 0 : this.fluidCells[index];
@@ -19328,18 +19424,30 @@ var Chunk = class _Chunk {
19328
19424
  async setCullMaskAt(pos, mask) {
19329
19425
  await this.setCullMaskIndex(_Chunk.chunkPosToBlockIndex(this.worldPosToChunkPos(pos)), mask);
19330
19426
  }
19331
- /** Recomputes section masks and returns changed per-block masks. Omit indices to visit every cell. */
19332
- updateCullMasks(indices, occludes) {
19427
+ /**
19428
+ * Recomputes section masks and returns changed per-block masks. Omit indices to visit every cell.
19429
+ * `culling` supplies neighbor face rules; `blockAt` supplies visible states outside this chunk.
19430
+ */
19431
+ updateCullMasks(indices, occludes, culling, blockAt) {
19333
19432
  const changed = [];
19433
+ const rules = [];
19334
19434
  for (const index of indices ?? this.fluidCells.keys()) {
19335
19435
  if (!this.isBlockVisibleIndex(index)) continue;
19336
19436
  const x = index % 16, y = Math.floor(index / 256), z = Math.floor(index / 16) % 16;
19437
+ const id = this.data.idAt(index);
19438
+ let rule = rules[id];
19439
+ if (culling && rule === void 0) rules[id] = rule = blockCullingRule(culling, this.data.stateAt(id).type) ?? null;
19440
+ const block = rule ? this.data.stateAt(id) : void 0;
19337
19441
  let mask = 0;
19338
19442
  for (let face = 0; face < CUBE_FACE_OFFSETS.length; face++) {
19339
19443
  const [dx, dy, dz] = CUBE_FACE_OFFSETS[face];
19340
19444
  const nx = x + dx, ny = y + dy, nz = z + dz;
19341
19445
  const inner = nx >= 0 && nx < 16 && ny >= 0 && ny < 16 && nz >= 0 && nz < 16;
19342
19446
  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;
19447
+ else if (rule) {
19448
+ const neighbor = inner ? this.visibleBlockIndex(ny * 256 + nz * 16 + nx) : blockAt?.(this.x * 16 + nx, this.y * 16 + ny, this.z * 16 + nz);
19449
+ if (neighbor && skipsBlockFace(culling, rule, block, neighbor, face)) mask |= 1 << face;
19450
+ }
19343
19451
  }
19344
19452
  if (this.fluidCells[index]) this.meshDirty = true;
19345
19453
  const entries = this.sectionBlocks.get(index);