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.
@@ -1208,118 +1208,6 @@ var init_Materials = __esm({
1208
1208
  }
1209
1209
  });
1210
1210
 
1211
- // src/model/Model.ts
1212
- function isDoubleArray(obj) {
1213
- return Array.isArray(obj) && obj.length === 2;
1214
- }
1215
- function isTripleArray(obj) {
1216
- return Array.isArray(obj) && obj.length === 3;
1217
- }
1218
- function isQuadArray(obj) {
1219
- return Array.isArray(obj) && obj.length === 4;
1220
- }
1221
- var ITEM_GENERATED, BUILTIN_GENERATED, BUILTIN_ENTITY, DEFAULT_ELEMENTS;
1222
- var init_Model = __esm({
1223
- "src/model/Model.ts"() {
1224
- ITEM_GENERATED = "item/generated";
1225
- BUILTIN_GENERATED = "builtin/generated";
1226
- BUILTIN_ENTITY = "builtin/entity";
1227
- DEFAULT_ELEMENTS = [];
1228
- }
1229
- });
1230
-
1231
- // ../../node_modules/ts-deepmerge/dist/index.js
1232
- var require_dist = __commonJS({
1233
- "../../node_modules/ts-deepmerge/dist/index.js"(exports) {
1234
- "use strict";
1235
- var __assign = exports && exports.__assign || function() {
1236
- __assign = Object.assign || function(t) {
1237
- for (var s, i = 1, n = arguments.length; i < n; i++) {
1238
- s = arguments[i];
1239
- for (var p11 in s) if (Object.prototype.hasOwnProperty.call(s, p11))
1240
- t[p11] = s[p11];
1241
- }
1242
- return t;
1243
- };
1244
- return __assign.apply(this, arguments);
1245
- };
1246
- var __read = exports && exports.__read || function(o, n) {
1247
- var m = typeof Symbol === "function" && o[Symbol.iterator];
1248
- if (!m) return o;
1249
- var i = m.call(o), r, ar = [], e;
1250
- try {
1251
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
1252
- } catch (error) {
1253
- e = { error };
1254
- } finally {
1255
- try {
1256
- if (r && !r.done && (m = i["return"])) m.call(i);
1257
- } finally {
1258
- if (e) throw e.error;
1259
- }
1260
- }
1261
- return ar;
1262
- };
1263
- var __spreadArray = exports && exports.__spreadArray || function(to, from, pack) {
1264
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
1265
- if (ar || !(i in from)) {
1266
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
1267
- ar[i] = from[i];
1268
- }
1269
- }
1270
- return to.concat(ar || Array.prototype.slice.call(from));
1271
- };
1272
- Object.defineProperty(exports, "__esModule", { value: true });
1273
- var isObject = function(obj) {
1274
- if (typeof obj === "object" && obj !== null) {
1275
- if (typeof Object.getPrototypeOf === "function") {
1276
- var prototype = Object.getPrototypeOf(obj);
1277
- return prototype === Object.prototype || prototype === null;
1278
- }
1279
- return Object.prototype.toString.call(obj) === "[object Object]";
1280
- }
1281
- return false;
1282
- };
1283
- var PROTECTED_KEYS = ["__proto__"];
1284
- var merge10 = function() {
1285
- var objects = [];
1286
- for (var _i = 0; _i < arguments.length; _i++) {
1287
- objects[_i] = arguments[_i];
1288
- }
1289
- return objects.reduce(function(result, current) {
1290
- Object.keys(current).forEach(function(key) {
1291
- if (PROTECTED_KEYS.includes(key)) {
1292
- return;
1293
- }
1294
- if (Array.isArray(result[key]) && Array.isArray(current[key])) {
1295
- result[key] = merge10.options.mergeArrays ? Array.from(new Set(result[key].concat(current[key]))) : current[key];
1296
- } else if (isObject(result[key]) && isObject(current[key])) {
1297
- result[key] = merge10(result[key], current[key]);
1298
- } else {
1299
- result[key] = current[key];
1300
- }
1301
- });
1302
- return result;
1303
- }, {});
1304
- };
1305
- var defaultOptions = {
1306
- mergeArrays: true
1307
- };
1308
- merge10.options = defaultOptions;
1309
- merge10.withOptions = function(options) {
1310
- var objects = [];
1311
- for (var _i = 1; _i < arguments.length; _i++) {
1312
- objects[_i - 1] = arguments[_i];
1313
- }
1314
- merge10.options = __assign({ mergeArrays: true }, options);
1315
- var result = merge10.apply(void 0, __spreadArray([], __read(objects), false));
1316
- merge10.options = defaultOptions;
1317
- return result;
1318
- };
1319
- exports.default = merge10;
1320
- }
1321
- });
1322
-
1323
1211
  // src/assets/AssetKey.ts
1324
1212
  function isResourceLocation(value) {
1325
1213
  return typeof value === "string" && /^(?:[a-z0-9_.-]+:)?[a-z0-9_./-]+$/.test(value);
@@ -1436,128 +1324,6 @@ var init_AssetKey = __esm({
1436
1324
  }
1437
1325
  });
1438
1326
 
1439
- // src/model/DisplayPosition.ts
1440
- var DisplayPosition, DISPLAY_POSITIONS;
1441
- var init_DisplayPosition = __esm({
1442
- "src/model/DisplayPosition.ts"() {
1443
- DisplayPosition = /* @__PURE__ */ ((DisplayPosition3) => {
1444
- DisplayPosition3["THIRDPERSON_RIGHTHAND"] = "thirdperson_righthand";
1445
- DisplayPosition3["THIRDPERSON_LEFTHAND"] = "thirdperson_lefthand";
1446
- DisplayPosition3["FIRSTPERSON_RIGHTHAND"] = "firstperson_righthand";
1447
- DisplayPosition3["FIRSTPERSON_LEFTHAND"] = "firstperson_lefthand";
1448
- DisplayPosition3["GUI"] = "gui";
1449
- DisplayPosition3["HEAD"] = "head";
1450
- DisplayPosition3["GROUND"] = "ground";
1451
- DisplayPosition3["FIXED"] = "fixed";
1452
- DisplayPosition3["ON_SHELF"] = "on_shelf";
1453
- return DisplayPosition3;
1454
- })(DisplayPosition || {});
1455
- DISPLAY_POSITIONS = Object.values(DisplayPosition);
1456
- }
1457
- });
1458
-
1459
- // src/model/DisplayTransforms.ts
1460
- import { Euler, Matrix4, Quaternion, Vector3 as Vector32 } from "three";
1461
- var DisplayTransforms;
1462
- var init_DisplayTransforms = __esm({
1463
- "src/model/DisplayTransforms.ts"() {
1464
- init_DisplayPosition();
1465
- init_util();
1466
- DisplayTransforms = class {
1467
- /** Resolve hand fallbacks within one model, before inheriting parent display entries. */
1468
- static withHandFallbacks(display) {
1469
- if (!display) return void 0;
1470
- const resolved = { ...display };
1471
- for (const [left, right] of [
1472
- ["thirdperson_lefthand" /* THIRDPERSON_LEFTHAND */, "thirdperson_righthand" /* THIRDPERSON_RIGHTHAND */],
1473
- ["firstperson_lefthand" /* FIRSTPERSON_LEFTHAND */, "firstperson_righthand" /* FIRSTPERSON_RIGHTHAND */]
1474
- ]) {
1475
- if (resolved[left] === void 0 && resolved[right] !== void 0) resolved[left] = resolved[right];
1476
- }
1477
- return resolved;
1478
- }
1479
- /** Build a display pose for geometry already centered at the model's [8, 8, 8] pivot. */
1480
- static getMatrix(display, position) {
1481
- const transform = this.getTransform(display, position);
1482
- return new Matrix4().compose(transform.position, transform.quaternion, transform.scale);
1483
- }
1484
- /** Position, rotation, and scale of a display pose for geometry already centered at the model's [8, 8, 8] pivot. */
1485
- static getTransform(display, position) {
1486
- const transform = this.withHandFallbacks(display)?.[position] ?? {};
1487
- const left = position === "firstperson_lefthand" /* FIRSTPERSON_LEFTHAND */ || position === "thirdperson_lefthand" /* THIRDPERSON_LEFTHAND */;
1488
- const sign = left ? -1 : 1;
1489
- const [x, y, z] = transform.rotation ?? [0, 0, 0];
1490
- const rotation = new Quaternion().setFromEuler(new Euler(toRadians(x), sign * toRadians(y), sign * toRadians(z), "XYZ"));
1491
- const translation = new Vector32(...transform.translation ?? [0, 0, 0]).clampScalar(-80, 80);
1492
- translation.x *= sign;
1493
- const scale = new Vector32(...transform.scale ?? [1, 1, 1]).clampScalar(-4, 4);
1494
- return { position: translation, quaternion: rotation, scale };
1495
- }
1496
- /** Transforms geometry in place and reverses triangle winding when the matrix reflects it. */
1497
- static apply(geometry, matrix) {
1498
- geometry.applyMatrix4(matrix);
1499
- if (matrix.determinant() < 0) {
1500
- if (!geometry.index) geometry.setIndex(Array.from({ length: geometry.getAttribute("position").count }, (_, i) => i));
1501
- const index = geometry.index;
1502
- for (let i = 0; i < index.count; i += 3) {
1503
- const second = index.getX(i + 1);
1504
- index.setX(i + 1, index.getX(i + 2));
1505
- index.setX(i + 2, second);
1506
- }
1507
- index.needsUpdate = true;
1508
- }
1509
- }
1510
- };
1511
- }
1512
- });
1513
-
1514
- // src/model/ModelMerger.ts
1515
- var import_ts_deepmerge, ModelMerger;
1516
- var init_ModelMerger = __esm({
1517
- "src/model/ModelMerger.ts"() {
1518
- init_Model();
1519
- init_Models();
1520
- import_ts_deepmerge = __toESM(require_dist());
1521
- init_AssetKey();
1522
- init_DisplayTransforms();
1523
- ModelMerger = class {
1524
- /** Loads the parent chain and returns a merged model without modifying the supplied definition. */
1525
- static async mergeWithParents(model) {
1526
- const parts = model.parts;
1527
- if (parts) return { ...model, parts: await Promise.all(parts.map((part) => this.mergeWithParents(part))) };
1528
- const models = await this.collectAllParents(model);
1529
- let merged = {};
1530
- for (const source of [...models, model]) {
1531
- const inheritedDisplay = merged.display;
1532
- merged = import_ts_deepmerge.default.withOptions({ mergeArrays: false }, merged, source);
1533
- if (source.display) {
1534
- merged.display = { ...inheritedDisplay, ...DisplayTransforms.withHandFallbacks(source.display) };
1535
- }
1536
- }
1537
- merged.hierarchy = models.map((m) => m.parent).filter((p11) => `${p11}`);
1538
- merged.hierarchy.push(`${merged.parent}`);
1539
- if (model.components) merged.components = model.components;
1540
- return merged;
1541
- }
1542
- static async collectAllParents(model) {
1543
- if (!model.parent) {
1544
- return [];
1545
- }
1546
- const models = [];
1547
- const parentKey = AssetKey.parse("models", model.parent);
1548
- if (parentKey.namespace === "minecraft" && parentKey.getFullPath() === BUILTIN_ENTITY) return models;
1549
- parentKey.root = model.key?.root;
1550
- const parentModel = await Models.getRaw(parentKey);
1551
- if (parentModel) {
1552
- models.unshift(parentModel);
1553
- models.unshift(...await this.collectAllParents(parentModel));
1554
- }
1555
- return models;
1556
- }
1557
- };
1558
- }
1559
- });
1560
-
1561
1327
  // src/assets/source/parser/AssetParsers.ts
1562
1328
  var AssetParser;
1563
1329
  var init_AssetParsers = __esm({
@@ -1675,7 +1441,9 @@ ${key}` : key, async () => {
1675
1441
  static validDataset(dataset, data) {
1676
1442
  if (!object(data)) return false;
1677
1443
  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)));
1444
+ 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")));
1678
1445
  if (dataset === "legacyBlocks") return object(data.blocks) && Object.values(data.blocks).every((value) => typeof value === "string");
1446
+ 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")));
1679
1447
  return Object.values(data).every((value) => {
1680
1448
  if (!object(value)) return false;
1681
1449
  switch (dataset) {
@@ -1698,6 +1466,275 @@ ${key}` : key, async () => {
1698
1466
  }
1699
1467
  });
1700
1468
 
1469
+ // src/assets/Renames.ts
1470
+ var Renames;
1471
+ var init_Renames = __esm({
1472
+ "src/assets/Renames.ts"() {
1473
+ init_AssetKey();
1474
+ init_MineRenderData();
1475
+ Renames = class {
1476
+ /** Loads the selected version's rename table, or `undefined` when its published data has none. */
1477
+ static async get(root) {
1478
+ const resolved = await MineRenderData.resolve(root);
1479
+ return resolved.manifest.datasets.renames ? MineRenderData.get("renames", root) : void 0;
1480
+ }
1481
+ /**
1482
+ * Returns the ID that replaced `id`, or `undefined` when `id` keeps its meaning.
1483
+ * Without a data version, an ID that the selected version still registers keeps its meaning.
1484
+ */
1485
+ static async resolve(kind, id, dataVersion, root) {
1486
+ const data = await this.get(root);
1487
+ if (!data || !Object.prototype.hasOwnProperty.call(data[kind], id)) return void 0;
1488
+ const entry = data[kind][id];
1489
+ if (dataVersion === void 0) return entry.registered ? void 0 : entry.ranges[entry.ranges.length - 1].to;
1490
+ if (dataVersion < data.baseDataVersion) return void 0;
1491
+ return entry.ranges.find((range) => dataVersion < range.before)?.to;
1492
+ }
1493
+ /** Returns a copy of `key` for the replacement ID, or `undefined` when the ID keeps its meaning. */
1494
+ static async key(kind, key) {
1495
+ const renamed = await this.resolve(kind, `${key.namespace}:${key.path}`, void 0, key.root);
1496
+ if (!renamed) return void 0;
1497
+ const [namespace, path] = renamed.split(":");
1498
+ return new AssetKey(namespace, path, key.assetType, key.type, key.rootType, key.extension, key.root);
1499
+ }
1500
+ };
1501
+ }
1502
+ });
1503
+
1504
+ // src/model/Model.ts
1505
+ function isDoubleArray(obj) {
1506
+ return Array.isArray(obj) && obj.length === 2;
1507
+ }
1508
+ function isTripleArray(obj) {
1509
+ return Array.isArray(obj) && obj.length === 3;
1510
+ }
1511
+ function isQuadArray(obj) {
1512
+ return Array.isArray(obj) && obj.length === 4;
1513
+ }
1514
+ var ITEM_GENERATED, BUILTIN_GENERATED, BUILTIN_ENTITY, DEFAULT_ELEMENTS;
1515
+ var init_Model = __esm({
1516
+ "src/model/Model.ts"() {
1517
+ ITEM_GENERATED = "item/generated";
1518
+ BUILTIN_GENERATED = "builtin/generated";
1519
+ BUILTIN_ENTITY = "builtin/entity";
1520
+ DEFAULT_ELEMENTS = [];
1521
+ }
1522
+ });
1523
+
1524
+ // ../../node_modules/ts-deepmerge/dist/index.js
1525
+ var require_dist = __commonJS({
1526
+ "../../node_modules/ts-deepmerge/dist/index.js"(exports) {
1527
+ "use strict";
1528
+ var __assign = exports && exports.__assign || function() {
1529
+ __assign = Object.assign || function(t) {
1530
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
1531
+ s = arguments[i];
1532
+ for (var p11 in s) if (Object.prototype.hasOwnProperty.call(s, p11))
1533
+ t[p11] = s[p11];
1534
+ }
1535
+ return t;
1536
+ };
1537
+ return __assign.apply(this, arguments);
1538
+ };
1539
+ var __read = exports && exports.__read || function(o, n) {
1540
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
1541
+ if (!m) return o;
1542
+ var i = m.call(o), r, ar = [], e;
1543
+ try {
1544
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
1545
+ } catch (error) {
1546
+ e = { error };
1547
+ } finally {
1548
+ try {
1549
+ if (r && !r.done && (m = i["return"])) m.call(i);
1550
+ } finally {
1551
+ if (e) throw e.error;
1552
+ }
1553
+ }
1554
+ return ar;
1555
+ };
1556
+ var __spreadArray = exports && exports.__spreadArray || function(to, from, pack) {
1557
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
1558
+ if (ar || !(i in from)) {
1559
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
1560
+ ar[i] = from[i];
1561
+ }
1562
+ }
1563
+ return to.concat(ar || Array.prototype.slice.call(from));
1564
+ };
1565
+ Object.defineProperty(exports, "__esModule", { value: true });
1566
+ var isObject = function(obj) {
1567
+ if (typeof obj === "object" && obj !== null) {
1568
+ if (typeof Object.getPrototypeOf === "function") {
1569
+ var prototype = Object.getPrototypeOf(obj);
1570
+ return prototype === Object.prototype || prototype === null;
1571
+ }
1572
+ return Object.prototype.toString.call(obj) === "[object Object]";
1573
+ }
1574
+ return false;
1575
+ };
1576
+ var PROTECTED_KEYS = ["__proto__"];
1577
+ var merge10 = function() {
1578
+ var objects = [];
1579
+ for (var _i = 0; _i < arguments.length; _i++) {
1580
+ objects[_i] = arguments[_i];
1581
+ }
1582
+ return objects.reduce(function(result, current) {
1583
+ Object.keys(current).forEach(function(key) {
1584
+ if (PROTECTED_KEYS.includes(key)) {
1585
+ return;
1586
+ }
1587
+ if (Array.isArray(result[key]) && Array.isArray(current[key])) {
1588
+ result[key] = merge10.options.mergeArrays ? Array.from(new Set(result[key].concat(current[key]))) : current[key];
1589
+ } else if (isObject(result[key]) && isObject(current[key])) {
1590
+ result[key] = merge10(result[key], current[key]);
1591
+ } else {
1592
+ result[key] = current[key];
1593
+ }
1594
+ });
1595
+ return result;
1596
+ }, {});
1597
+ };
1598
+ var defaultOptions = {
1599
+ mergeArrays: true
1600
+ };
1601
+ merge10.options = defaultOptions;
1602
+ merge10.withOptions = function(options) {
1603
+ var objects = [];
1604
+ for (var _i = 1; _i < arguments.length; _i++) {
1605
+ objects[_i - 1] = arguments[_i];
1606
+ }
1607
+ merge10.options = __assign({ mergeArrays: true }, options);
1608
+ var result = merge10.apply(void 0, __spreadArray([], __read(objects), false));
1609
+ merge10.options = defaultOptions;
1610
+ return result;
1611
+ };
1612
+ exports.default = merge10;
1613
+ }
1614
+ });
1615
+
1616
+ // src/model/DisplayPosition.ts
1617
+ var DisplayPosition, DISPLAY_POSITIONS;
1618
+ var init_DisplayPosition = __esm({
1619
+ "src/model/DisplayPosition.ts"() {
1620
+ DisplayPosition = /* @__PURE__ */ ((DisplayPosition3) => {
1621
+ DisplayPosition3["THIRDPERSON_RIGHTHAND"] = "thirdperson_righthand";
1622
+ DisplayPosition3["THIRDPERSON_LEFTHAND"] = "thirdperson_lefthand";
1623
+ DisplayPosition3["FIRSTPERSON_RIGHTHAND"] = "firstperson_righthand";
1624
+ DisplayPosition3["FIRSTPERSON_LEFTHAND"] = "firstperson_lefthand";
1625
+ DisplayPosition3["GUI"] = "gui";
1626
+ DisplayPosition3["HEAD"] = "head";
1627
+ DisplayPosition3["GROUND"] = "ground";
1628
+ DisplayPosition3["FIXED"] = "fixed";
1629
+ DisplayPosition3["ON_SHELF"] = "on_shelf";
1630
+ return DisplayPosition3;
1631
+ })(DisplayPosition || {});
1632
+ DISPLAY_POSITIONS = Object.values(DisplayPosition);
1633
+ }
1634
+ });
1635
+
1636
+ // src/model/DisplayTransforms.ts
1637
+ import { Euler, Matrix4, Quaternion, Vector3 as Vector32 } from "three";
1638
+ var DisplayTransforms;
1639
+ var init_DisplayTransforms = __esm({
1640
+ "src/model/DisplayTransforms.ts"() {
1641
+ init_DisplayPosition();
1642
+ init_util();
1643
+ DisplayTransforms = class {
1644
+ /** Resolve hand fallbacks within one model, before inheriting parent display entries. */
1645
+ static withHandFallbacks(display) {
1646
+ if (!display) return void 0;
1647
+ const resolved = { ...display };
1648
+ for (const [left, right] of [
1649
+ ["thirdperson_lefthand" /* THIRDPERSON_LEFTHAND */, "thirdperson_righthand" /* THIRDPERSON_RIGHTHAND */],
1650
+ ["firstperson_lefthand" /* FIRSTPERSON_LEFTHAND */, "firstperson_righthand" /* FIRSTPERSON_RIGHTHAND */]
1651
+ ]) {
1652
+ if (resolved[left] === void 0 && resolved[right] !== void 0) resolved[left] = resolved[right];
1653
+ }
1654
+ return resolved;
1655
+ }
1656
+ /** Build a display pose for geometry already centered at the model's [8, 8, 8] pivot. */
1657
+ static getMatrix(display, position) {
1658
+ const transform = this.getTransform(display, position);
1659
+ return new Matrix4().compose(transform.position, transform.quaternion, transform.scale);
1660
+ }
1661
+ /** Position, rotation, and scale of a display pose for geometry already centered at the model's [8, 8, 8] pivot. */
1662
+ static getTransform(display, position) {
1663
+ const transform = this.withHandFallbacks(display)?.[position] ?? {};
1664
+ const left = position === "firstperson_lefthand" /* FIRSTPERSON_LEFTHAND */ || position === "thirdperson_lefthand" /* THIRDPERSON_LEFTHAND */;
1665
+ const sign = left ? -1 : 1;
1666
+ const [x, y, z] = transform.rotation ?? [0, 0, 0];
1667
+ const rotation = new Quaternion().setFromEuler(new Euler(toRadians(x), sign * toRadians(y), sign * toRadians(z), "XYZ"));
1668
+ const translation = new Vector32(...transform.translation ?? [0, 0, 0]).clampScalar(-80, 80);
1669
+ translation.x *= sign;
1670
+ const scale = new Vector32(...transform.scale ?? [1, 1, 1]).clampScalar(-4, 4);
1671
+ return { position: translation, quaternion: rotation, scale };
1672
+ }
1673
+ /** Transforms geometry in place and reverses triangle winding when the matrix reflects it. */
1674
+ static apply(geometry, matrix) {
1675
+ geometry.applyMatrix4(matrix);
1676
+ if (matrix.determinant() < 0) {
1677
+ if (!geometry.index) geometry.setIndex(Array.from({ length: geometry.getAttribute("position").count }, (_, i) => i));
1678
+ const index = geometry.index;
1679
+ for (let i = 0; i < index.count; i += 3) {
1680
+ const second = index.getX(i + 1);
1681
+ index.setX(i + 1, index.getX(i + 2));
1682
+ index.setX(i + 2, second);
1683
+ }
1684
+ index.needsUpdate = true;
1685
+ }
1686
+ }
1687
+ };
1688
+ }
1689
+ });
1690
+
1691
+ // src/model/ModelMerger.ts
1692
+ var import_ts_deepmerge, ModelMerger;
1693
+ var init_ModelMerger = __esm({
1694
+ "src/model/ModelMerger.ts"() {
1695
+ init_Model();
1696
+ init_Models();
1697
+ import_ts_deepmerge = __toESM(require_dist());
1698
+ init_AssetKey();
1699
+ init_DisplayTransforms();
1700
+ ModelMerger = class {
1701
+ /** Loads the parent chain and returns a merged model without modifying the supplied definition. */
1702
+ static async mergeWithParents(model) {
1703
+ const parts = model.parts;
1704
+ if (parts) return { ...model, parts: await Promise.all(parts.map((part) => this.mergeWithParents(part))) };
1705
+ const models = await this.collectAllParents(model);
1706
+ let merged = {};
1707
+ for (const source of [...models, model]) {
1708
+ const inheritedDisplay = merged.display;
1709
+ merged = import_ts_deepmerge.default.withOptions({ mergeArrays: false }, merged, source);
1710
+ if (source.display) {
1711
+ merged.display = { ...inheritedDisplay, ...DisplayTransforms.withHandFallbacks(source.display) };
1712
+ }
1713
+ }
1714
+ merged.hierarchy = models.map((m) => m.parent).filter((p11) => `${p11}`);
1715
+ merged.hierarchy.push(`${merged.parent}`);
1716
+ if (model.components) merged.components = model.components;
1717
+ return merged;
1718
+ }
1719
+ static async collectAllParents(model) {
1720
+ if (!model.parent) {
1721
+ return [];
1722
+ }
1723
+ const models = [];
1724
+ const parentKey = AssetKey.parse("models", model.parent);
1725
+ if (parentKey.namespace === "minecraft" && parentKey.getFullPath() === BUILTIN_ENTITY) return models;
1726
+ parentKey.root = model.key?.root;
1727
+ const parentModel = await Models.getRaw(parentKey);
1728
+ if (parentModel) {
1729
+ models.unshift(parentModel);
1730
+ models.unshift(...await this.collectAllParents(parentModel));
1731
+ }
1732
+ return models;
1733
+ }
1734
+ };
1735
+ }
1736
+ });
1737
+
1701
1738
  // src/assets/BannerPatterns.ts
1702
1739
  var DYE_COLORS, BannerPatterns;
1703
1740
  var init_BannerPatterns = __esm({
@@ -2020,6 +2057,7 @@ var init_ItemTints = __esm({
2020
2057
  var Models;
2021
2058
  var init_Models = __esm({
2022
2059
  "src/assets/Models.ts"() {
2060
+ init_Renames();
2023
2061
  init_Caching();
2024
2062
  init_ModelMerger();
2025
2063
  init_AssetLoader();
@@ -2349,6 +2387,11 @@ var init_Models = __esm({
2349
2387
  key.extension = ".json";
2350
2388
  }
2351
2389
  const preview = this.snapshotContext(key, context);
2390
+ if (key.type === "item") {
2391
+ const renamed = await Renames.key("items", key);
2392
+ const replacement = renamed && await this.getMerged(renamed, preview);
2393
+ if (replacement) return replacement;
2394
+ }
2352
2395
  const dataKey = await this.applyDefaults(key, preview);
2353
2396
  const keyStr = AssetLoader.persistentKey(key.serialize() + (key.type === "item" ? this.contextKey(preview) + dataKey : ""));
2354
2397
  const model = await Caching.mergedModelCache.get(keyStr, async () => {
@@ -2382,6 +2425,7 @@ var init_BlockStates = __esm({
2382
2425
  init_AssetKey();
2383
2426
  init_PersistentCache();
2384
2427
  init_AssetParsers();
2428
+ init_Renames();
2385
2429
  init_MineRenderData();
2386
2430
  BlockStates = class {
2387
2431
  static get PERSISTENT_CACHE() {
@@ -2422,6 +2466,9 @@ var init_BlockStates = __esm({
2422
2466
  if (!key.extension) {
2423
2467
  key.extension = ".json";
2424
2468
  }
2469
+ const renamed = await Renames.key("blocks", key);
2470
+ const replacement = renamed && await this.get(renamed);
2471
+ if (replacement) return replacement;
2425
2472
  const keyStr = key.serialize();
2426
2473
  return Caching.blockStateCache.get(keyStr, (k) => {
2427
2474
  return this.PERSISTENT_CACHE.getOrLoad(AssetLoader.persistentKey(keyStr), (k1) => {
@@ -7983,6 +8030,7 @@ var Fonts = class {
7983
8030
  init_MineRenderData();
7984
8031
  init_ModelTextures();
7985
8032
  init_Models();
8033
+ init_Renames();
7986
8034
  init_source();
7987
8035
 
7988
8036
  // src/cache/index.ts
@@ -17407,6 +17455,7 @@ var SectionModels = class {
17407
17455
  };
17408
17456
 
17409
17457
  // src/world/_entities/WorldEntities.ts
17458
+ init_Renames();
17410
17459
  init_Entities();
17411
17460
  init_EntityObject();
17412
17461
 
@@ -17566,8 +17615,10 @@ var WorldEntities = class {
17566
17615
  try {
17567
17616
  if (!current()) return;
17568
17617
  const models = await Entities.getEntityList();
17569
- if (!models.includes(placement.key.path) || !current()) return;
17570
- const model = await Entities.getEntity(placement.key, placement.texture, { when: placement.when });
17618
+ const renamed = models.includes(placement.key.path) ? void 0 : await Renames.key("entities", placement.key);
17619
+ const key = renamed && models.includes(renamed.path) ? renamed : placement.key;
17620
+ if (!models.includes(key.path) || !current()) return;
17621
+ const model = await Entities.getEntity(key, placement.texture, { when: placement.when });
17571
17622
  if (!model || !current()) return;
17572
17623
  let tints = placement.tints;
17573
17624
  if (placement.woolDye) {
@@ -17582,7 +17633,7 @@ var WorldEntities = class {
17582
17633
  object4.rotation.y = placement.yaw;
17583
17634
  await object4.init();
17584
17635
  if (!current()) return;
17585
- placement.owner.set(object4, { type: placement.key.toNamespacedString(), position: placement.position });
17636
+ placement.owner.set(object4, { type: key.toNamespacedString(), position: placement.position });
17586
17637
  this.scene.add(object4);
17587
17638
  } catch (error) {
17588
17639
  console.warn(`Could not draw saved entity ${placement.key.toNamespacedString()}, skipping it`, error);
@@ -17636,6 +17687,38 @@ function sampleSectionLight(light, index) {
17636
17687
  };
17637
17688
  }
17638
17689
 
17690
+ // src/world/_culling/BlockCulling.ts
17691
+ init_Assets();
17692
+ init_MineRenderData();
17693
+ init_CubeFace();
17694
+ async function loadBlockCulling(root) {
17695
+ const { manifest } = await MineRenderData.resolve(root);
17696
+ return manifest.datasets.blockCulling ? MineRenderData.get("blockCulling", root) : void 0;
17697
+ }
17698
+ function blockCullingRule(data, type) {
17699
+ if (!type.includes(":")) type = `${DEFAULT_NAMESPACE}:${type}`;
17700
+ return Object.prototype.hasOwnProperty.call(data.blocks, type) ? data.profiles[data.blocks[type]] : void 0;
17701
+ }
17702
+ function skipsBlockFace(data, rule, block, neighbor, face) {
17703
+ const type = block.type.includes(":") ? block.type : `${DEFAULT_NAMESPACE}:${block.type}`;
17704
+ const other = neighbor.type.includes(":") ? neighbor.type : `${DEFAULT_NAMESPACE}:${neighbor.type}`;
17705
+ const same = type === other;
17706
+ const vertical = CUBE_FACES[face] === "up" /* UP */ || CUBE_FACES[face] === "down" /* DOWN */;
17707
+ switch (rule.type) {
17708
+ case "same_block":
17709
+ return same;
17710
+ case "same_block_vertical":
17711
+ return same && vertical;
17712
+ case "connected": {
17713
+ if (vertical) return same;
17714
+ const group = rule.group ? data.groups?.[rule.group] : void 0;
17715
+ return (same || !!group?.includes(type) && group.includes(other)) && String(block.properties?.[CUBE_FACES[face]]) === "true" && String(neighbor.properties?.[CUBE_FACES[face ^ 1]]) === "true";
17716
+ }
17717
+ default:
17718
+ return false;
17719
+ }
17720
+ }
17721
+
17639
17722
  // src/world/MineRenderWorld.ts
17640
17723
  var MineRenderWorld = class {
17641
17724
  constructor(scene, options = {}) {
@@ -18024,15 +18107,23 @@ var MineRenderWorld = class {
18024
18107
  return this.culling ?? (this.culling = Promise.resolve().then(async () => {
18025
18108
  let sliceStart = performance.now();
18026
18109
  try {
18110
+ const culling = await loadBlockCulling();
18027
18111
  while (this.pendingCulling.size) {
18028
18112
  const batch = [...this.pendingCulling];
18029
18113
  this.pendingCulling.clear();
18030
18114
  for (const [chunk, indices] of batch) {
18031
18115
  const neighbors = CUBE_FACE_OFFSETS.map(([x, y, z]) => this._chunks.get(`${chunk.x + x}_${chunk.y + y}_${chunk.z + z}`));
18032
- const masks = chunk.updateCullMasks(indices === "all" ? void 0 : indices, (x, y, z) => {
18116
+ const neighborAt = (x, y, z) => {
18033
18117
  const lx = x - chunk.x * 16, ly = y - chunk.y * 16, lz = z - chunk.z * 16;
18034
18118
  const section = neighbors[lx >= 16 ? 0 : lx < 0 ? 1 : ly >= 16 ? 2 : ly < 0 ? 3 : lz >= 16 ? 4 : 5];
18035
- return section?.isOccludingIndex((ly & 15) * 256 + (lz & 15) * 16 + (lx & 15)) ?? false;
18119
+ return [section, (ly & 15) * 256 + (lz & 15) * 16 + (lx & 15)];
18120
+ };
18121
+ const masks = chunk.updateCullMasks(indices === "all" ? void 0 : indices, (x, y, z) => {
18122
+ const [section, i] = neighborAt(x, y, z);
18123
+ return section?.isOccludingIndex(i) ?? false;
18124
+ }, culling, (x, y, z) => {
18125
+ const [section, i] = neighborAt(x, y, z);
18126
+ return section?.visibleBlockIndex(i);
18036
18127
  });
18037
18128
  const fluidIndices = indices === "all" ? function* () {
18038
18129
  for (let index = 0; index < 4096; index++) yield index;
@@ -19147,6 +19238,10 @@ var Chunk = class _Chunk {
19147
19238
  isBlockVisibleIndex(index) {
19148
19239
  return this.renderedBlocks.has(index) && !this.hiddenBlocks.has(index);
19149
19240
  }
19241
+ /** Stored state of a rendered, visible cell, or `undefined`. */
19242
+ visibleBlockIndex(index) {
19243
+ return this.isBlockVisibleIndex(index) ? this.data.stateAt(this.data.idAt(index)) : void 0;
19244
+ }
19150
19245
  /** Fluid kind bits and level of a cell, or 0. Hidden cells report 0. */
19151
19246
  fluidByteIndex(index) {
19152
19247
  return this.hiddenBlocks.has(index) ? 0 : this.fluidCells[index];
@@ -19165,18 +19260,30 @@ var Chunk = class _Chunk {
19165
19260
  async setCullMaskAt(pos, mask) {
19166
19261
  await this.setCullMaskIndex(_Chunk.chunkPosToBlockIndex(this.worldPosToChunkPos(pos)), mask);
19167
19262
  }
19168
- /** Recomputes section masks and returns changed per-block masks. Omit indices to visit every cell. */
19169
- updateCullMasks(indices, occludes) {
19263
+ /**
19264
+ * Recomputes section masks and returns changed per-block masks. Omit indices to visit every cell.
19265
+ * `culling` supplies neighbor face rules; `blockAt` supplies visible states outside this chunk.
19266
+ */
19267
+ updateCullMasks(indices, occludes, culling, blockAt) {
19170
19268
  const changed = [];
19269
+ const rules = [];
19171
19270
  for (const index of indices ?? this.fluidCells.keys()) {
19172
19271
  if (!this.isBlockVisibleIndex(index)) continue;
19173
19272
  const x = index % 16, y = Math.floor(index / 256), z = Math.floor(index / 16) % 16;
19273
+ const id = this.data.idAt(index);
19274
+ let rule = rules[id];
19275
+ if (culling && rule === void 0) rules[id] = rule = blockCullingRule(culling, this.data.stateAt(id).type) ?? null;
19276
+ const block = rule ? this.data.stateAt(id) : void 0;
19174
19277
  let mask = 0;
19175
19278
  for (let face = 0; face < CUBE_FACE_OFFSETS.length; face++) {
19176
19279
  const [dx, dy, dz] = CUBE_FACE_OFFSETS[face];
19177
19280
  const nx = x + dx, ny = y + dy, nz = z + dz;
19178
19281
  const inner = nx >= 0 && nx < 16 && ny >= 0 && ny < 16 && nz >= 0 && nz < 16;
19179
19282
  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;
19283
+ else if (rule) {
19284
+ const neighbor = inner ? this.visibleBlockIndex(ny * 256 + nz * 16 + nx) : blockAt?.(this.x * 16 + nx, this.y * 16 + ny, this.z * 16 + nz);
19285
+ if (neighbor && skipsBlockFace(culling, rule, block, neighbor, face)) mask |= 1 << face;
19286
+ }
19180
19287
  }
19181
19288
  if (this.fluidCells[index]) this.meshDirty = true;
19182
19289
  const entries = this.sectionBlocks.get(index);
@@ -19589,6 +19696,7 @@ export {
19589
19696
  PackMetadata,
19590
19697
  PersistentCache,
19591
19698
  PlayerHeadTextures,
19699
+ Renames,
19592
19700
  Renderer,
19593
19701
  RequestError,
19594
19702
  Requests,