@adatechnology/game-vegetation-three 0.3.0 → 0.3.1

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.
@@ -41,7 +41,7 @@ var GameVegetationThree = (() => {
41
41
  scatterLot: () => scatterLot
42
42
  });
43
43
 
44
- // ../game-shapes/dist/chunk-IFXQIDSA.js
44
+ // ../game-shapes/dist/chunk-M5N2SHNL.js
45
45
  function canonicalJson(value) {
46
46
  if (value === null) return "null";
47
47
  if (typeof value === "number") return Object.is(value, -0) ? "-0" : Number.isFinite(value) ? String(value) : JSON.stringify(String(value));
@@ -1288,8 +1288,8 @@ var GameVegetationThree = (() => {
1288
1288
  groups: []
1289
1289
  };
1290
1290
  }
1291
- function make(kind, p) {
1292
- switch (kind) {
1291
+ function make(p) {
1292
+ switch (p.kind) {
1293
1293
  case "box": {
1294
1294
  const size = p.size ?? [1, 1, 1];
1295
1295
  const segments = p.segments ?? [1, 1, 1];
@@ -1318,7 +1318,7 @@ var GameVegetationThree = (() => {
1318
1318
  case "mesh":
1319
1319
  return mesh(p);
1320
1320
  default:
1321
- throw new Error(`game-shapes: unknown primitive kind "${String(kind)}"`);
1321
+ throw new Error(`game-shapes: unknown primitive kind "${String(p.kind)}"`);
1322
1322
  }
1323
1323
  }
1324
1324
  var templates = /* @__PURE__ */ new Map();
@@ -1326,7 +1326,7 @@ var GameVegetationThree = (() => {
1326
1326
  var stats = { hits: 0, misses: 0 };
1327
1327
  function buildPrimitive(node, options = {}) {
1328
1328
  const parameters = primitiveParameters(node, options);
1329
- if (node.kind === "mesh" || templateLimit === 0) return make(node.kind, parameters);
1329
+ if (node.kind === "mesh" || templateLimit === 0) return make({ ...node, ...parameters });
1330
1330
  const key = `${node.kind}:${canonicalJson(parameters)}`;
1331
1331
  const cached = templates.get(key);
1332
1332
  if (cached) {
@@ -1336,7 +1336,7 @@ var GameVegetationThree = (() => {
1336
1336
  return cached;
1337
1337
  }
1338
1338
  stats.misses++;
1339
- const built = make(node.kind, parameters);
1339
+ const built = make({ ...node, ...parameters });
1340
1340
  templates.set(key, built);
1341
1341
  if (templates.size > templateLimit) templates.delete(templates.keys().next().value);
1342
1342
  return built;
@@ -1721,7 +1721,7 @@ var GameVegetationThree = (() => {
1721
1721
  validateSpec: () => validateSpec
1722
1722
  });
1723
1723
 
1724
- // ../game-vegetation/dist/chunk-WNYTFZR4.js
1724
+ // ../game-vegetation/dist/chunk-CJRLKDWB.js
1725
1725
  var __defProp2 = Object.defineProperty;
1726
1726
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1727
1727
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
@@ -9502,6 +9502,7 @@ gl_Position = projectionMatrix * mvPosition;
9502
9502
  }
9503
9503
 
9504
9504
  // src/test-area/nursery.ts
9505
+ var isMesh = (o) => o.isMesh === true;
9505
9506
  var LOT = { W: 12, D: 20 };
9506
9507
  var HOUSE = { x0: 2.5, x1: 9.5, z0: 6.5, z1: 13 };
9507
9508
  var WAY = [[6, 1.2], [6, 5.4], [10.8, 5.4], [10.8, 14.2], [8, 18.6], [3, 18.6], [1.2, 14.2], [1.2, 5.4], [4, 3.2], [8, 3.2]];
@@ -9593,14 +9594,14 @@ gl_Position = projectionMatrix * mvPosition;
9593
9594
  let attached = false;
9594
9595
  const disposeObject = (object2) => {
9595
9596
  object2.traverse((child) => {
9596
- child.geometry?.dispose?.();
9597
+ if (isMesh(child)) child.geometry?.dispose?.();
9597
9598
  });
9598
9599
  };
9599
9600
  const clearGroup = (g) => {
9600
9601
  for (const child of [...g.children]) {
9601
9602
  g.remove(child);
9602
9603
  disposeObject(child);
9603
- child.material?.dispose?.();
9604
+ if (isMesh(child) && !Array.isArray(child.material)) child.material?.dispose?.();
9604
9605
  }
9605
9606
  };
9606
9607
  const ensure = () => {
@@ -9657,7 +9658,7 @@ gl_Position = projectionMatrix * mvPosition;
9657
9658
  const buildMs = Date.now() - t0;
9658
9659
  lotObject = sdk.createLotObject(THREE, data, materials);
9659
9660
  lotObject.traverse((c) => {
9660
- if (c.isMesh) {
9661
+ if (isMesh(c)) {
9661
9662
  c.castShadow = true;
9662
9663
  c.receiveShadow = true;
9663
9664
  }
@@ -9832,7 +9833,7 @@ gl_Position = projectionMatrix * mvPosition;
9832
9833
  return root;
9833
9834
  }
9834
9835
  function buildSpec(root, def) {
9835
- const meshes = root.children.filter((c) => c.isMesh && c.userData.veg);
9836
+ const meshes = root.children.filter((c) => c.isMesh === true && Boolean(c.userData.veg));
9836
9837
  const byId2 = {};
9837
9838
  for (const m of meshes) byId2[m.userData.veg.id] = m;
9838
9839
  const parts = [];
@@ -9961,6 +9962,7 @@ gl_Position = projectionMatrix * mvPosition;
9961
9962
  id: def.id,
9962
9963
  name: def.name ? def.name[loc === "en" ? 1 : 0] : species2.name(def.base ?? def.id, loc),
9963
9964
  build: (THREE) => buildObject(THREE, def),
9965
+ // the room hands its three.js namespace
9964
9966
  spec: (root) => {
9965
9967
  const spec = buildSpec(root, def);
9966
9968
  root.userData.vegSpec = spec;
@@ -10038,11 +10040,12 @@ gl_Position = projectionMatrix * mvPosition;
10038
10040
  };
10039
10041
  const crownsOf = (so) => specOf(so).parts.filter((p) => /^(s\d+_)?crown\d*$/.test(p.id)).map((p) => p.id);
10040
10042
  const jointPos = (so, jid) => {
10041
- const j = specOf(so).joints.filter((x) => x.id === jid)[0];
10043
+ const j = (specOf(so).joints ?? []).filter((x) => x.id === jid)[0];
10042
10044
  const a = partSpec(so, j.a);
10043
10045
  const b = partSpec(so, j.b);
10044
10046
  const box2 = (p) => {
10045
- const h = p.shape.kind === "box" ? p.shape.size.map((s) => s / 2) : [p.shape.radius, p.shape.height / 2, p.shape.radius];
10047
+ const sh = p.shape;
10048
+ const h = sh.kind === "box" ? [sh.size[0] / 2, sh.size[1] / 2, sh.size[2] / 2] : [sh.radius, (sh.kind === "cylinder" ? sh.height : sh.radius * 2) / 2, sh.radius];
10046
10049
  const r = p.rotation || [0, 0, 0];
10047
10050
  const cx = Math.cos(r[0]), sx = Math.sin(r[0]), cz = Math.cos(r[2]), sz = Math.sin(r[2]);
10048
10051
  const mn = [Infinity, Infinity, Infinity];
@@ -10069,6 +10072,16 @@ gl_Position = projectionMatrix * mvPosition;
10069
10072
  if (!p) return null;
10070
10073
  return { status: p.status, hp: p.hp, maxHp: p.maxHp, temperature: p.temperature, burning: p.burning, char: p.char || 0, fuel: p.fuel, holes: (p.holes || []).length, material: p.material };
10071
10074
  };
10075
+ const snapAt = (room, so, pid) => {
10076
+ const p = snap(room, so, pid);
10077
+ if (!p) throw new Error(`game-vegetation-three: no part "${pid}" in ${so.objectId}`);
10078
+ return p;
10079
+ };
10080
+ const stateAt = (room, id) => {
10081
+ const st = room.world.state(id);
10082
+ if (!st) throw new Error(`game-vegetation-three: no object ${id} in the world`);
10083
+ return st;
10084
+ };
10072
10085
  const logCount = (room, so, type) => room.log.entries({ type, objectId: so.objectId }).length;
10073
10086
  const jointsOpened = (room, so) => {
10074
10087
  let n = 0;
@@ -10080,7 +10093,11 @@ gl_Position = projectionMatrix * mvPosition;
10080
10093
  const spawn = (room, id, x, z) => room.spawn(id, [x, 0, z], 0);
10081
10094
  const split = (room, so) => {
10082
10095
  const home = room.world.snapshot(so.objectId);
10083
- const loose = room.world.ids().filter((i) => /^obj_/.test(i)).map((i) => ({ id: i, st: room.world.snapshot(i) }));
10096
+ if (!home) throw new Error(`game-vegetation-three: no object ${so.objectId} in the world`);
10097
+ const loose = room.world.ids().filter((i) => /^obj_/.test(i)).flatMap((i) => {
10098
+ const st = room.world.snapshot(i);
10099
+ return st ? [{ id: i, st }] : [];
10100
+ });
10084
10101
  const anchored = {};
10085
10102
  for (const p of specOf(so).parts) if (p.anchored) anchored[p.id] = true;
10086
10103
  const rooted = [];
@@ -10092,7 +10109,8 @@ gl_Position = projectionMatrix * mvPosition;
10092
10109
  const fell = (room, ctx, so, max) => {
10093
10110
  take(room, "axe");
10094
10111
  let swings = 0;
10095
- const h = partSpec(so, "trunk").shape.height;
10112
+ const trunkShape = partSpec(so, "trunk").shape;
10113
+ const h = trunkShape.kind === "cylinder" ? trunkShape.height : trunkShape.kind === "box" ? trunkShape.size[1] : trunkShape.radius * 2;
10096
10114
  for (let i = 0; i < max; i++) {
10097
10115
  aimPart(room, so, "trunk", 0.5, [0, Math.min(0.9, h / 3), 0]);
10098
10116
  room.use();
@@ -10101,7 +10119,7 @@ gl_Position = projectionMatrix * mvPosition;
10101
10119
  if (lost(room.world.part(so.objectId, "trunk"))) break;
10102
10120
  }
10103
10121
  ctx.step(5);
10104
- return { swings, trunk: snap(room, so, "trunk") };
10122
+ return { swings, trunk: snapAt(room, so, "trunk") };
10105
10123
  };
10106
10124
  const sc = (id, ptName, enName, run) => ({ id: `veg_${id}`, name: L(ptName, enName), run });
10107
10125
  const pct = (x) => `${Math.round((x || 0) * 100)}%`;
@@ -10117,7 +10135,7 @@ gl_Position = projectionMatrix * mvPosition;
10117
10135
  const r = fell(room, ctx, so, 60);
10118
10136
  const sp = split(room, so);
10119
10137
  const crownGone = lost(room.world.part(so.objectId, "crown")) || !sp.inHome("crown") || sp.rooted.indexOf("crown") < 0;
10120
- const branches = specOf(so).parts.filter((p) => p.tags.indexOf("branch") >= 0).map((p) => p.id);
10138
+ const branches = specOf(so).parts.filter((p) => (p.tags ?? []).indexOf("branch") >= 0).map((p) => p.id);
10121
10139
  const branchesFree = branches.every((b) => sp.rooted.indexOf(b) < 0);
10122
10140
  const detach = jointsOpened(room, so);
10123
10141
  ctx.expect(r.trunk.status === "broken" && r.swings >= 8 && r.swings <= 15, L(`Machado no tronco de 15 cm (hp ${Math.round(r.trunk.maxHp)}): tronco ${r.trunk.status} depois de ${r.swings} golpes (esperado: broken em 8 a 15 golpes)`, `Axe on a 15 cm trunk (hp ${Math.round(r.trunk.maxHp)}): trunk ${r.trunk.status} after ${r.swings} swings (expected: broken in 8 to 15 swings)`), { swings: r.swings, status: r.trunk.status, maxHp: r.trunk.maxHp });
@@ -10147,7 +10165,7 @@ gl_Position = projectionMatrix * mvPosition;
10147
10165
  detached = detachedJoint(room, so, jid);
10148
10166
  }
10149
10167
  ctx.step(3);
10150
- const trunk = snap(room, so, "trunk");
10168
+ const trunk = snapAt(room, so, "trunk");
10151
10169
  const sp = split(room, so);
10152
10170
  const branchOff = sp.inLoose("branch1") && !sp.inHome("branch1");
10153
10171
  const restStays = sp.inHome("trunk") && sp.rooted.indexOf("trunk") >= 0;
@@ -10165,7 +10183,7 @@ gl_Position = projectionMatrix * mvPosition;
10165
10183
  ctx.step(0.4);
10166
10184
  shots++;
10167
10185
  }
10168
- const trunk = snap(room, so, "trunk");
10186
+ const trunk = snapAt(room, so, "trunk");
10169
10187
  const sp = split(room, so);
10170
10188
  ctx.expect(trunk.status !== "broken" && trunk.hp > 0, L(`${shots} tiros de 9 mm no tronco de 15 cm: tronco ${trunk.status}, hp ${Math.round(trunk.hp)}/${Math.round(trunk.maxHp)} (esperado: n\xE3o quebrado)`, `${shots} 9 mm shots on the 15 cm trunk: trunk ${trunk.status}, hp ${Math.round(trunk.hp)}/${Math.round(trunk.maxHp)} (expected: not broken)`), { shots, hp: trunk.hp });
10171
10189
  ctx.expect(sp.loose.length === 0 && sp.inHome("trunk") && sp.rooted.indexOf("crown") >= 0, L(`A \xE1rvore continua de p\xE9: peda\xE7os soltos ${sp.loose.length}, copa presa ao ch\xE3o ${yn(sp.rooted.indexOf("crown") >= 0)} (esperado: 0, sim)`, `The tree still stands: loose pieces ${sp.loose.length}, crown rooted ${yn(sp.rooted.indexOf("crown") >= 0)} (expected: 0, yes)`), {});
@@ -10195,21 +10213,21 @@ gl_Position = projectionMatrix * mvPosition;
10195
10213
  take(room, "lighter");
10196
10214
  const a = aimPart(room, so, crownsOf(so), 0.08);
10197
10215
  room.use(6);
10198
- const crown = snap(room, so, a.pid);
10216
+ const crown = snapAt(room, so, a.pid);
10199
10217
  const lit = crown.burning || crown.temperature > 300;
10200
10218
  let peak = 0;
10201
10219
  let charMax = 0;
10202
10220
  for (let t = 0; t < 18; t++) {
10203
10221
  ctx.step(5);
10204
- for (const p of room.world.state(so.objectId).parts) {
10222
+ for (const p of stateAt(room, so.objectId).parts) {
10205
10223
  if (p.material === "green_wood") {
10206
10224
  peak = Math.max(peak, p.temperature);
10207
10225
  charMax = Math.max(charMax, p.char || 0);
10208
10226
  }
10209
10227
  }
10210
10228
  }
10211
- const st = room.world.state(so.objectId);
10212
- const burnt = st.parts.filter((p) => p.material === "foliage" && (p.burning || p.char > 0 || p.status === "ashes")).length;
10229
+ const st = stateAt(room, so.objectId);
10230
+ const burnt = st.parts.filter((p) => p.material === "foliage" && (p.burning || (p.char ?? 0) > 0 || p.status === "ashes")).length;
10213
10231
  ctx.expect(lit, L(`Isqueiro na copa: folhagem acesa ou acima de 300 \xB0C = ${yn(lit)} (${Math.round(crown.temperature)} \xB0C; esperado: sim)`, `Lighter on the crown: foliage lit or above 300 C = ${yn(lit)} (${Math.round(crown.temperature)} C; expected: yes)`), { temperature: crown.temperature });
10214
10232
  ctx.expect(burnt > 0, L(`Depois de 90 s: ${burnt} pe\xE7a(s) de folhagem queimando, carbonizada(s) ou em cinza (esperado: 1 ou mais)`, `After 90 s: ${burnt} foliage piece(s) burning, charred or ash (expected: 1+)`), { burnt });
10215
10233
  ctx.expect(peak > 150 || charMax > 0, L(`O fogo da folhagem passa para a madeira verde (tronco e galhos): pico de ${Math.round(peak)} \xB0C, carboniza\xE7\xE3o m\xE1xima ${pct(charMax)} (esperado: pico acima de 150 \xB0C ou carboniza\xE7\xE3o acima de 0; a madeira verde s\xF3 pega fogo acima de 400 \xB0C)`, `Foliage fire reaches the green wood (trunk and branches): peak ${Math.round(peak)} C, max char ${pct(charMax)} (expected: peak above 150 C or char above 0; green wood only ignites above 400 C)`), { peak, charMax });
@@ -10220,13 +10238,13 @@ gl_Position = projectionMatrix * mvPosition;
10220
10238
  const so = spawn(room, "mango_tree", 0, -6);
10221
10239
  take(room, "pistol_9mm");
10222
10240
  const tgt = aimPart(room, so, crownsOf(so), 2.5).pid;
10223
- const before = snap(room, so, tgt);
10241
+ const before = snapAt(room, so, tgt);
10224
10242
  for (let i = 0; i < 3; i++) {
10225
10243
  aimPart(room, so, tgt, 2.5);
10226
10244
  room.use();
10227
10245
  ctx.step(0.6);
10228
10246
  }
10229
- const crown = snap(room, so, tgt);
10247
+ const crown = snapAt(room, so, tgt);
10230
10248
  const leaves = room.log.entries({ type: "debris", objectId: so.objectId }).filter((e) => e.data && e.data.kind === "leaves").length;
10231
10249
  const hurt = crown.hp < before.hp || crown.status === "broken";
10232
10250
  ctx.expect(hurt && crown.status !== "intact", L(`Tr\xEAs tiros na copa: hp ${Math.round(before.hp)} para ${Math.round(crown.hp)}, estado ${crown.status} (esperado: hp menor, n\xE3o intacta)`, `Three shots into the crown: hp ${Math.round(before.hp)} to ${Math.round(crown.hp)}, status ${crown.status} (expected: lower hp, not intact)`), { hp: crown.hp });
@@ -10283,8 +10301,8 @@ gl_Position = projectionMatrix * mvPosition;
10283
10301
  const a = snap(room, so, arm);
10284
10302
  const sp = split(room, so);
10285
10303
  const armOff = !a || a.status === "broken" || sp.inLoose(arm) && !sp.inHome(arm);
10286
- const stemOk = sp.inHome("stem") && sp.rooted.indexOf("stem") >= 0 && room.world.part(so.objectId, "stem").status !== "broken";
10287
- const spines = specOf(so).parts.filter((p) => p.tags.indexOf("thorns") >= 0);
10304
+ const stemOk = sp.inHome("stem") && sp.rooted.indexOf("stem") >= 0 && room.world.part(so.objectId, "stem")?.status !== "broken";
10305
+ const spines = specOf(so).parts.filter((p) => (p.tags ?? []).indexOf("thorns") >= 0);
10288
10306
  const thorny = so.root.userData.thorny === true && spines.length > 0;
10289
10307
  const spinesOff = !sp.rooted.some((pid) => pid.indexOf(`${arm}_spines`) === 0);
10290
10308
  ctx.expect(armOff, L(`Machete na junta ${jid}: bra\xE7o ${a ? a.status : "solto como objeto pr\xF3prio"} depois de ${swings} golpe(s) (esperado: solto do caule pela junta)`, `Machete on joint ${jid}: arm ${a ? a.status : "loose as its own object"} after ${swings} swing(s) (expected: off the stem through the joint)`), { swings });
@@ -10319,11 +10337,11 @@ gl_Position = projectionMatrix * mvPosition;
10319
10337
  aimPart(room, so, "trunk", 0.08, [0, 0.8, 0]);
10320
10338
  room.use(8);
10321
10339
  }
10322
- const d0 = snap(room, dead, "trunk");
10323
- const l0 = snap(room, live, "trunk");
10340
+ const d0 = snapAt(room, dead, "trunk");
10341
+ const l0 = snapAt(room, live, "trunk");
10324
10342
  ctx.step(120);
10325
- const d = snap(room, dead, "trunk");
10326
- const l = snap(room, live, "trunk");
10343
+ const d = snapAt(room, dead, "trunk");
10344
+ const l = snapAt(room, live, "trunk");
10327
10345
  const score = (p) => p ? Math.max(p.char, p.burning ? 0.01 : 0, (p.temperature - 20) / 2e3) : 0;
10328
10346
  ctx.expect(d0.material === "wood_soft" && l0.material === "green_wood", L(`Materiais do tronco: \xE1rvore morta ${d0.material}, viva ${l0.material} (esperado: wood_soft, green_wood)`, `Trunk materials: dead tree ${d0.material}, living ${l0.material} (expected: wood_soft, green_wood)`), { dead: d0.material, live: l0.material });
10329
10347
  ctx.expect(score(d) > score(l), L(`Depois de 8 s de isqueiro e 120 s de espera: morta queimando ${yn(d.burning)}, ${Math.round(d.temperature)} \xB0C, carboniza\xE7\xE3o ${pct(d.char)}; viva queimando ${yn(l.burning)}, ${Math.round(l.temperature)} \xB0C, carboniza\xE7\xE3o ${pct(l.char)} (esperado: a morta mais queimada)`, `After 8 s of lighter and 120 s of waiting: dead burning ${yn(d.burning)}, ${Math.round(d.temperature)} C, char ${pct(d.char)}; living burning ${yn(l.burning)}, ${Math.round(l.temperature)} C, char ${pct(l.char)} (expected: dead burns more)`), { dead: score(d), live: score(l) });
@@ -10353,7 +10371,7 @@ gl_Position = projectionMatrix * mvPosition;
10353
10371
  const tuft = spawn(room, "lawn_tuft", 0, -3);
10354
10372
  const tree = spawn(room, "mango_tree", 4, -3);
10355
10373
  const noBlock = !tuft.root.userData.collider;
10356
- const treeBlock = !!(tree.root.userData.collider && tree.root.userData.collider.kind);
10374
+ const treeBlock = !!tree.root.userData.collider?.kind;
10357
10375
  ctx.expect(noBlock && treeBlock, L(`Colisor do SDK: touceira ${noBlock ? "nenhum" : "tem"}, tronco da mangueira ${treeBlock ? "tem" : "nenhum"} (esperado: nenhum, tem)`, `SDK collider: tuft ${noBlock ? "none" : "has one"}, mango trunk ${treeBlock ? "has one" : "none"} (expected: none, has one)`), {});
10358
10376
  room.look([0, 1.7, -0.5], [0, 1.7, -6]);
10359
10377
  const before = room.camera.position.z;
@@ -10437,6 +10455,7 @@ gl_Position = projectionMatrix * mvPosition;
10437
10455
  "veg_hedge_cut_pieces",
10438
10456
  "veg_walk_on_grass"
10439
10457
  ];
10458
+ var isMesh2 = (o) => o.isMesh === true;
10440
10459
  var defaultSdk = () => ({ ...dist_exports, ...three_exports });
10441
10460
  var AXIS_COLOURS = { trunk: 14254635, branch: 15057019, arm: 7327599, stem: 7327639, pad: 7321551 };
10442
10461
  function createVegetationTestModule(options = {}) {
@@ -10494,7 +10513,7 @@ gl_Position = projectionMatrix * mvPosition;
10494
10513
  }
10495
10514
  for (const mesh2 of root.children) {
10496
10515
  const v = mesh2.userData?.veg;
10497
- if (!v || !mesh2.geometry) continue;
10516
+ if (!v || !isMesh2(mesh2) || !mesh2.geometry) continue;
10498
10517
  if (host.bench.layer("piece_boxes")) {
10499
10518
  mesh2.geometry.computeBoundingBox();
10500
10519
  const box2 = mesh2.geometry.boundingBox.clone().translate(mesh2.position);
@@ -10598,7 +10617,7 @@ gl_Position = projectionMatrix * mvPosition;
10598
10617
  let pieces = 0;
10599
10618
  for (const entry of placed.values()) {
10600
10619
  entry.root.traverse((mesh2) => {
10601
- if (!mesh2.isMesh || mesh2.userData.helper) return;
10620
+ if (!isMesh2(mesh2) || mesh2.userData.helper) return;
10602
10621
  for (let p = mesh2; p; p = p.parent) if (p.visible === false) return;
10603
10622
  drawCalls += 1;
10604
10623
  if (mesh2.userData.veg) pieces += 1;
@@ -10611,7 +10630,7 @@ gl_Position = projectionMatrix * mvPosition;
10611
10630
  const lotCalls = () => {
10612
10631
  let calls = 0;
10613
10632
  nursery?.group.traverse((o) => {
10614
- if (o.isMesh && o.visible) calls += 1;
10633
+ if (isMesh2(o) && o.visible) calls += 1;
10615
10634
  });
10616
10635
  return calls;
10617
10636
  };