@adatechnology/game-floorplan-three 0.8.2 → 0.9.0
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.
- package/README.md +4 -0
- package/dist/chunk-QUVGWVEC.js +8882 -0
- package/dist/chunk-QUVGWVEC.js.map +1 -0
- package/dist/index.d.ts +6 -349
- package/dist/index.global.js +418 -96
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +23 -8627
- package/dist/index.js.map +1 -1
- package/dist/testing-ikPy2Nxl.d.ts +379 -0
- package/dist/testing.d.ts +3 -0
- package/dist/testing.js +19 -0
- package/dist/testing.js.map +1 -0
- package/package.json +20 -14
package/dist/index.global.js
CHANGED
|
@@ -70,7 +70,7 @@ var GameFloorplanThree = (() => {
|
|
|
70
70
|
shade: () => shade
|
|
71
71
|
});
|
|
72
72
|
|
|
73
|
-
// ../game-shapes/dist/chunk-
|
|
73
|
+
// ../game-shapes/dist/chunk-IFXQIDSA.js
|
|
74
74
|
function canonicalJson(value) {
|
|
75
75
|
if (value === null) return "null";
|
|
76
76
|
if (typeof value === "number") return Object.is(value, -0) ? "-0" : Number.isFinite(value) ? String(value) : JSON.stringify(String(value));
|
|
@@ -1538,6 +1538,107 @@ var GameFloorplanThree = (() => {
|
|
|
1538
1538
|
return { positions: positions2, normals, uvs };
|
|
1539
1539
|
}
|
|
1540
1540
|
|
|
1541
|
+
// ../game-contracts/dist/index.js
|
|
1542
|
+
var DEFAULT_COST_ALLOCATION_BYTES = 1024 * 1024;
|
|
1543
|
+
var DEFAULT_IGNITION_RULES = {
|
|
1544
|
+
fillCurve: [
|
|
1545
|
+
[0, 0.6],
|
|
1546
|
+
[0.1, 1],
|
|
1547
|
+
[0.35, 0.6],
|
|
1548
|
+
[0.65, 0.3],
|
|
1549
|
+
[0.9, 0.15],
|
|
1550
|
+
[1, 0.12]
|
|
1551
|
+
],
|
|
1552
|
+
flameFillInfluence: 0.5,
|
|
1553
|
+
flameDefaults: { incendiary: 0.7, tracer: 0.2 },
|
|
1554
|
+
sparkTarget: { steel: 1, iron: 1, aluminium: 0.25 },
|
|
1555
|
+
sparkMetalDefault: 0.5,
|
|
1556
|
+
sparkFluid: { diesel: 0.15 },
|
|
1557
|
+
fireNear: { radius: 1.5, chancePerSecond: 0.5 }
|
|
1558
|
+
};
|
|
1559
|
+
var resolveIgnitionRules = (rules) => ({
|
|
1560
|
+
...DEFAULT_IGNITION_RULES,
|
|
1561
|
+
...rules,
|
|
1562
|
+
flameDefaults: { ...DEFAULT_IGNITION_RULES.flameDefaults, ...rules?.flameDefaults },
|
|
1563
|
+
sparkTarget: { ...DEFAULT_IGNITION_RULES.sparkTarget, ...rules?.sparkTarget },
|
|
1564
|
+
sparkFluid: { ...DEFAULT_IGNITION_RULES.sparkFluid, ...rules?.sparkFluid },
|
|
1565
|
+
fireNear: { ...DEFAULT_IGNITION_RULES.fireNear, ...rules?.fireNear }
|
|
1566
|
+
});
|
|
1567
|
+
var fillFactor = (fill2, curve = DEFAULT_IGNITION_RULES.fillCurve) => {
|
|
1568
|
+
if (curve.length === 0) return 1;
|
|
1569
|
+
const f = Math.min(1, Math.max(0, fill2));
|
|
1570
|
+
if (f <= curve[0][0]) return curve[0][1];
|
|
1571
|
+
for (let i = 1; i < curve.length; i++) {
|
|
1572
|
+
const [x1, y1] = curve[i];
|
|
1573
|
+
const [x0, y0] = curve[i - 1];
|
|
1574
|
+
if (f <= x1) return x1 === x0 ? y1 : y0 + (y1 - y0) * (f - x0) / (x1 - x0);
|
|
1575
|
+
}
|
|
1576
|
+
return curve[curve.length - 1][1];
|
|
1577
|
+
};
|
|
1578
|
+
var sparkTargetFactor = (materialId, metal, rules = DEFAULT_IGNITION_RULES) => !metal ? 0 : rules.sparkTarget[materialId] ?? rules.sparkMetalDefault;
|
|
1579
|
+
var ignitionChance = (hit, target, rules = DEFAULT_IGNITION_RULES) => {
|
|
1580
|
+
const k = fillFactor(target.fill, rules.fillCurve);
|
|
1581
|
+
const spark = (hit.ignition?.spark ?? 0) * target.sparkTarget * (target.fluid === void 0 ? 1 : rules.sparkFluid[target.fluid] ?? 1) * k;
|
|
1582
|
+
const flameBase = hit.ignition?.flame ?? Math.max(hit.incendiary ? rules.flameDefaults.incendiary : 0, hit.tracer ? rules.flameDefaults.tracer : 0);
|
|
1583
|
+
const flame = flameBase * (1 - rules.flameFillInfluence * (1 - k));
|
|
1584
|
+
return 1 - (1 - Math.min(1, Math.max(0, spark))) * (1 - Math.min(1, Math.max(0, flame)));
|
|
1585
|
+
};
|
|
1586
|
+
var DEFERRED_QUEUE_ID = {
|
|
1587
|
+
DESTRUCTION_EVENTS: "destruction.events",
|
|
1588
|
+
BREACH_PAINT: "floorplan.breach-paint",
|
|
1589
|
+
AUDIO_VOICES: "audio.voices",
|
|
1590
|
+
VEHICLE_CREASE: "vehicles.crease"
|
|
1591
|
+
};
|
|
1592
|
+
var DEFERRED_PRIORITY = {
|
|
1593
|
+
[DEFERRED_QUEUE_ID.DESTRUCTION_EVENTS]: { priority: 300, phase: "present" },
|
|
1594
|
+
[DEFERRED_QUEUE_ID.BREACH_PAINT]: { priority: 250, phase: "present" },
|
|
1595
|
+
[DEFERRED_QUEUE_ID.AUDIO_VOICES]: { priority: 200, phase: "idle", reserveMs: 1 },
|
|
1596
|
+
[DEFERRED_QUEUE_ID.VEHICLE_CREASE]: { priority: 100, phase: "idle" }
|
|
1597
|
+
};
|
|
1598
|
+
var KIT_ORIGIN_KEY = "kitOrigin";
|
|
1599
|
+
function markKitOrigin(object2, origin) {
|
|
1600
|
+
const node = object2;
|
|
1601
|
+
node.userData = node.userData ?? {};
|
|
1602
|
+
node.userData[KIT_ORIGIN_KEY] = { ...origin };
|
|
1603
|
+
return object2;
|
|
1604
|
+
}
|
|
1605
|
+
var SURFACE_IDS = ["concrete", "asphalt", "wood", "tile", "dirt", "grass", "gravel", "sand", "metal", "water", "glass", "carpet"];
|
|
1606
|
+
var GAIT_IDS = ["walk", "run"];
|
|
1607
|
+
var LANDING_IDS = ["light", "heavy"];
|
|
1608
|
+
var BODY_SOUND_IDS = [
|
|
1609
|
+
"jump",
|
|
1610
|
+
"cloth_rustle",
|
|
1611
|
+
"body_fall",
|
|
1612
|
+
"fall_damage",
|
|
1613
|
+
"player_hurt",
|
|
1614
|
+
"player_breath_run",
|
|
1615
|
+
"player_death",
|
|
1616
|
+
"bite",
|
|
1617
|
+
"grab",
|
|
1618
|
+
"punch_swing",
|
|
1619
|
+
"punch_hit_body",
|
|
1620
|
+
"punch_hit_face",
|
|
1621
|
+
"punch_hit_object",
|
|
1622
|
+
"kick_swing",
|
|
1623
|
+
"kick_hit",
|
|
1624
|
+
"kick_hit_object",
|
|
1625
|
+
"shove_two_hands",
|
|
1626
|
+
"knife_swing",
|
|
1627
|
+
"knife_stab",
|
|
1628
|
+
"knife_slash",
|
|
1629
|
+
"knife_hit_object",
|
|
1630
|
+
"blunt_swing",
|
|
1631
|
+
"blunt_hit",
|
|
1632
|
+
"blunt_hit_object",
|
|
1633
|
+
"axe_swing",
|
|
1634
|
+
"axe_chop",
|
|
1635
|
+
"axe_hit_object"
|
|
1636
|
+
];
|
|
1637
|
+
var footstepSoundId = (surface, gait) => `footstep_${surface}_${gait}`;
|
|
1638
|
+
var FOOTSTEP_SOUND_IDS = SURFACE_IDS.flatMap((surface) => GAIT_IDS.map((gait) => footstepSoundId(surface, gait)));
|
|
1639
|
+
var LAND_SOUND_IDS = SURFACE_IDS.flatMap((surface) => LANDING_IDS.map((landing) => `land_${surface}_${landing}`));
|
|
1640
|
+
var BODY_FOLEY_IDS = [...FOOTSTEP_SOUND_IDS, ...LAND_SOUND_IDS, ...BODY_SOUND_IDS];
|
|
1641
|
+
|
|
1541
1642
|
// ../game-shapes-three/dist/index.js
|
|
1542
1643
|
var UV_BEFORE_NORMAL = /* @__PURE__ */ new Set(["LatheGeometry", "ExtrudeGeometry"]);
|
|
1543
1644
|
var INDEX_FIRST = /* @__PURE__ */ new Set(["BoxGeometry", "CylinderGeometry", "ConeGeometry", "SphereGeometry", "PlaneGeometry", "CircleGeometry", "RingGeometry", "LatheGeometry", "TorusGeometry"]);
|
|
@@ -8997,7 +9098,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
8997
9098
|
const em = w.emitters();
|
|
8998
9099
|
if (em.length && !IV.efx && K.IVK.effects) {
|
|
8999
9100
|
const g = h.houseGroup;
|
|
9000
|
-
IV.efx = ik.gfx.createEffects(g, { maxParticles: 1400, seed: 11, document: DOC });
|
|
9101
|
+
IV.efx = ik.gfx.createEffects(g, { maxParticles: 1400, seed: 11, document: DOC, ...K.IVK.effectSink ? { effects: K.IVK.effectSink } : {} });
|
|
9001
9102
|
}
|
|
9002
9103
|
if (IV.efx) {
|
|
9003
9104
|
const alive = IV.efx.stats().alive;
|
|
@@ -10614,7 +10715,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
10614
10715
|
return null;
|
|
10615
10716
|
}
|
|
10616
10717
|
const A = AD.plan ? AD : AD.create({ ...o.adapterOptions || {}, GameInteractables: GI, GameInteractablesHousehold: HH, locale: o.locale || cfg.locale, region: o.region, ...cfg.seedKey ? { seedKey: cfg.seedKey } : {} });
|
|
10617
|
-
return { GI, HH, GT, A, gfx: GT.createThreeAdapter(THREE, { document: DOC, Reflector }), items: o.items !== false, effects: o.effects !== false, camera: o.camera || null, onEvent: o.onEvent || null, onSeat: o.onSeat || null };
|
|
10718
|
+
return { GI, HH, GT, A, gfx: GT.createThreeAdapter(THREE, { document: DOC, Reflector }), items: o.items !== false, effects: o.effects !== false, effectSink: o.effectSink || null, camera: o.camera || null, onEvent: o.onEvent || null, onSeat: o.onSeat || null };
|
|
10618
10719
|
})();
|
|
10619
10720
|
const VEG = (() => {
|
|
10620
10721
|
const l = cfg.vegetation || null, G = l && (l.GameVegetation || (l.buildLot ? l : null)), S = l && (l.GameVegetationSpecies || (l.toSpec ? l : null));
|
|
@@ -10631,7 +10732,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
10631
10732
|
|
|
10632
10733
|
// src/lights/room-light.ts
|
|
10633
10734
|
function installLightsRoomLight(K, shared) {
|
|
10634
|
-
const { THREE, rectsOf: rectsOf2 } = K;
|
|
10735
|
+
const { THREE, rectsOf: rectsOf2, cfg } = K;
|
|
10635
10736
|
const MAX_LIGHTS = 12, EMPTY = [1e9, 1e9, -1e9, -1e9];
|
|
10636
10737
|
const LZU = { uRB0: { value: new Float32Array(MAX_LIGHTS * 4) }, uRB1: { value: new Float32Array(MAX_LIGHTS * 4) }, uRB2: { value: new Float32Array(MAX_LIGHTS * 4) }, uRBY: { value: new Float32Array(MAX_LIGHTS * 2) }, uREx: { value: new Float32Array(MAX_LIGHTS * 4) }, uIndK: { value: 0.06 } };
|
|
10637
10738
|
for (let i = 0; i < MAX_LIGHTS; i++) for (const k of ["uRB0", "uRB1", "uRB2", "uREx"]) LZU[k].value.set(EMPTY, i * 4);
|
|
@@ -10670,8 +10771,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
10670
10771
|
o = o || {};
|
|
10671
10772
|
const scene = o.scene, N = Math.max(1, Math.min(MAX_LIGHTS, o.n || 6)), NS = Math.max(0, Math.min(N, o.shadows != null ? o.shadows : 2)), size = o.shadowSize || 512, MAX_EXTERNAL = o.external != null ? o.external : 2;
|
|
10672
10773
|
for (const k of Object.keys(shared.mats)) roomLightMask(shared.mats[k]);
|
|
10774
|
+
const budget = o.budget, lease = budget ? budget.lease({ owner: "floorplan.rooms", point: N, shadows: NS }) : null;
|
|
10775
|
+
if (budget && !lease) throw new Error("lighting: the LightBudget has no " + N + " free point slots (" + NS + " with shadow) for the rooms");
|
|
10776
|
+
if (budget) for (const [key, width] of [["uRB0", 4], ["uRB1", 4], ["uRB2", 4], ["uRBY", 2], ["uREx", 4]]) {
|
|
10777
|
+
const next = new Float32Array(budget.sizes.point * width);
|
|
10778
|
+
if (width === 4) for (let i = 0; i < budget.sizes.point; i++) next.set(EMPTY, i * 4);
|
|
10779
|
+
LZU[key].value = next;
|
|
10780
|
+
}
|
|
10673
10781
|
const PL = [], sig = new Array(N).fill(""), seg = { n: 0 };
|
|
10674
|
-
for (let i = 0; i < N; i++) {
|
|
10782
|
+
if (!lease) for (let i = 0; i < N; i++) {
|
|
10675
10783
|
const l = new THREE.PointLight(16763008, 0, 8, 1.6);
|
|
10676
10784
|
l.visible = true;
|
|
10677
10785
|
l.castShadow = i < NS;
|
|
@@ -10687,12 +10795,30 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
10687
10795
|
if (scene) scene.add(l);
|
|
10688
10796
|
PL.push(l);
|
|
10689
10797
|
}
|
|
10690
|
-
const
|
|
10798
|
+
const slotOf = (i) => lease ? lease.handles[i].slot : i;
|
|
10799
|
+
const put = (i, v) => {
|
|
10800
|
+
if (lease) {
|
|
10801
|
+
lease.handles[i].update(v.color === void 0 || typeof v.color === "number" ? v : { ...v, color: new THREE.Color(v.color).getHex() });
|
|
10802
|
+
return;
|
|
10803
|
+
}
|
|
10804
|
+
const pl = PL[i];
|
|
10805
|
+
if (v.position) pl.position.set(v.position[0], v.position[1], v.position[2]);
|
|
10806
|
+
if (v.color !== void 0) pl.color.set(v.color);
|
|
10807
|
+
if (v.intensity !== void 0) pl.intensity = v.intensity;
|
|
10808
|
+
if (v.distance !== void 0) pl.distance = v.distance;
|
|
10809
|
+
if (v.decay !== void 0) pl.decay = v.decay;
|
|
10810
|
+
};
|
|
10811
|
+
const effects = lease ? effectLights({ budget, ours: lease.handles.map((h) => h.slot) }) : null;
|
|
10812
|
+
const A = { lights: lease ? lease.handles : PL, crates: new Array(N).fill(null), n: N, shadows: NS, stats: { rooms: 0, external: 0, shadows: 0, shadowChanged: false }, indirect: (v) => {
|
|
10691
10813
|
LZU.uIndK.value = v;
|
|
10692
10814
|
} };
|
|
10693
10815
|
const _p = new THREE.Vector3(), _f = new THREE.Vector3();
|
|
10694
10816
|
const lim = (v, a, b) => Math.max(a, Math.min(b, v));
|
|
10695
10817
|
A.invalidate = () => {
|
|
10818
|
+
if (lease) {
|
|
10819
|
+
lease.invalidateShadow();
|
|
10820
|
+
return;
|
|
10821
|
+
}
|
|
10696
10822
|
for (let i = 0; i < NS; i++) PL[i].shadow.needsUpdate = true;
|
|
10697
10823
|
};
|
|
10698
10824
|
A.update = function(houses2, focus, op) {
|
|
@@ -10800,47 +10926,44 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
10800
10926
|
A.stats.external = Ne;
|
|
10801
10927
|
let shadows = 0;
|
|
10802
10928
|
for (let i = 0; i < N; i++) {
|
|
10803
|
-
const
|
|
10929
|
+
const g = asg[i], at = slotOf(i), b0 = LZU.uRB0.value, b1 = LZU.uRB1.value, b2 = LZU.uRB2.value, by = LZU.uRBY.value, ex = LZU.uREx.value;
|
|
10804
10930
|
A.crates[i] = g ? { k: g.k, rects: g.rects, y: g.y, exterior: !!g.exterior, exclusion: g.exclusion || null, d: g.d } : null;
|
|
10805
10931
|
if (!g) {
|
|
10806
|
-
|
|
10807
|
-
for (const a of [b0, b1, b2, ex]) a.set(EMPTY,
|
|
10808
|
-
by.set([0, 0],
|
|
10932
|
+
put(i, { intensity: 0 });
|
|
10933
|
+
for (const a of [b0, b1, b2, ex]) a.set(EMPTY, at * 4);
|
|
10934
|
+
by.set([0, 0], at * 2);
|
|
10809
10935
|
continue;
|
|
10810
10936
|
}
|
|
10811
|
-
|
|
10812
|
-
|
|
10813
|
-
if (g.exterior) {
|
|
10814
|
-
pl.intensity = g.lumens;
|
|
10815
|
-
pl.distance = g.dist;
|
|
10816
|
-
pl.decay = g.decay;
|
|
10817
|
-
} else {
|
|
10818
|
-
pl.intensity = (7 + g.range * 0.8) * lim(1 + 0.4 * (Math.sqrt(g.n) - 1), 1, 2.2);
|
|
10819
|
-
pl.distance = Math.max(3, g.dm * 1.3 + 0.5);
|
|
10820
|
-
pl.decay = 1.6;
|
|
10821
|
-
}
|
|
10937
|
+
const lamp = g.exterior ? { intensity: g.lumens, distance: g.dist, decay: g.decay } : { intensity: (7 + g.range * 0.8) * lim(1 + 0.4 * (Math.sqrt(g.n) - 1), 1, 2.2), distance: Math.max(3, g.dm * 1.3 + 0.5), decay: 1.6 };
|
|
10938
|
+
put(i, { position: g.pos, color: g.color, ...lamp });
|
|
10822
10939
|
const rs = g.rects;
|
|
10823
|
-
b0.set(rs[0] || EMPTY,
|
|
10824
|
-
b1.set(rs[1] || EMPTY,
|
|
10825
|
-
b2.set(rs[2] || EMPTY,
|
|
10826
|
-
by.set(g.y,
|
|
10827
|
-
ex.set(g.exclusion || EMPTY,
|
|
10940
|
+
b0.set(rs[0] || EMPTY, at * 4);
|
|
10941
|
+
b1.set(rs[1] || EMPTY, at * 4);
|
|
10942
|
+
b2.set(rs[2] || EMPTY, at * 4);
|
|
10943
|
+
by.set(g.y, at * 2);
|
|
10944
|
+
ex.set(g.exclusion || EMPTY, at * 4);
|
|
10828
10945
|
if (i < NS) {
|
|
10829
10946
|
shadows++;
|
|
10830
10947
|
const s2 = g.house.group.uuid + "|" + g.k + "|" + g.pos.map((v) => v.toFixed(2)).join(",");
|
|
10831
10948
|
if (sig[i] !== s2) {
|
|
10832
10949
|
sig[i] = s2;
|
|
10833
|
-
|
|
10950
|
+
if (lease) lease.invalidateShadow(i);
|
|
10951
|
+
else PL[i].shadow.needsUpdate = true;
|
|
10834
10952
|
seg.n++;
|
|
10835
10953
|
A.stats.shadowChanged = true;
|
|
10836
10954
|
}
|
|
10837
|
-
|
|
10955
|
+
if (!lease) PL[i].shadow.camera.far = Math.max(4, lamp.distance);
|
|
10838
10956
|
}
|
|
10839
10957
|
}
|
|
10958
|
+
if (effects) effects.update(houses2);
|
|
10840
10959
|
A.stats.shadows = shadows;
|
|
10841
10960
|
return A.stats;
|
|
10842
10961
|
};
|
|
10843
10962
|
A.dispose = () => {
|
|
10963
|
+
if (lease) {
|
|
10964
|
+
lease.release();
|
|
10965
|
+
return;
|
|
10966
|
+
}
|
|
10844
10967
|
for (const l of PL) {
|
|
10845
10968
|
if (l.shadow && l.shadow.map) l.shadow.map.dispose();
|
|
10846
10969
|
l.removeFromParent();
|
|
@@ -10848,59 +10971,116 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
10848
10971
|
};
|
|
10849
10972
|
return A;
|
|
10850
10973
|
}
|
|
10851
|
-
|
|
10852
|
-
|
|
10853
|
-
|
|
10854
|
-
|
|
10855
|
-
|
|
10856
|
-
|
|
10857
|
-
|
|
10858
|
-
|
|
10859
|
-
[
|
|
10860
|
-
[
|
|
10861
|
-
|
|
10862
|
-
|
|
10863
|
-
|
|
10864
|
-
|
|
10865
|
-
|
|
10866
|
-
|
|
10867
|
-
|
|
10868
|
-
|
|
10869
|
-
|
|
10870
|
-
|
|
10871
|
-
|
|
10872
|
-
|
|
10873
|
-
|
|
10874
|
-
|
|
10875
|
-
|
|
10876
|
-
|
|
10877
|
-
|
|
10878
|
-
|
|
10879
|
-
|
|
10880
|
-
|
|
10881
|
-
|
|
10882
|
-
|
|
10883
|
-
|
|
10884
|
-
|
|
10885
|
-
|
|
10886
|
-
|
|
10974
|
+
const effectsByBudget = /* @__PURE__ */ new WeakMap();
|
|
10975
|
+
const OPENING_REACH = 2.5, OPENING_SIDE = 0.6;
|
|
10976
|
+
function effectLights(o) {
|
|
10977
|
+
o = o || {};
|
|
10978
|
+
const budget = o.budget;
|
|
10979
|
+
if (!budget) throw new Error("effectLights: a LightBudget is required");
|
|
10980
|
+
const known = effectsByBudget.get(budget);
|
|
10981
|
+
if (known && !o.ours) return known;
|
|
10982
|
+
const ours = new Set(o.ours || []), size = budget.sizes.point, _p = new THREE.Vector3(), P0 = new THREE.Vector3();
|
|
10983
|
+
for (const [key, width] of [["uRB0", 4], ["uRB1", 4], ["uRB2", 4], ["uRBY", 2], ["uREx", 4]]) {
|
|
10984
|
+
const had = LZU[key].value;
|
|
10985
|
+
if (had.length >= size * width) continue;
|
|
10986
|
+
const next = new Float32Array(size * width);
|
|
10987
|
+
if (width === 4) for (let i = 0; i < size; i++) next.set(EMPTY, i * 4);
|
|
10988
|
+
next.set(had);
|
|
10989
|
+
LZU[key].value = next;
|
|
10990
|
+
}
|
|
10991
|
+
const roomBoxes = (house, M) => {
|
|
10992
|
+
const list2 = [];
|
|
10993
|
+
for (const c of house.r.rooms) {
|
|
10994
|
+
if (c.type === "void") continue;
|
|
10995
|
+
const rs = [];
|
|
10996
|
+
for (const [a, b, c2, d] of rectsOf2(c)) {
|
|
10997
|
+
let x0 = 1e9, z0 = 1e9, x1 = -1e9, z1 = -1e9;
|
|
10998
|
+
for (const [u, v] of [[a, b], [c2, b], [a, d], [c2, d]]) {
|
|
10999
|
+
_p.set(u, 0, v).applyMatrix4(M);
|
|
11000
|
+
x0 = Math.min(x0, _p.x);
|
|
11001
|
+
x1 = Math.max(x1, _p.x);
|
|
11002
|
+
z0 = Math.min(z0, _p.z);
|
|
11003
|
+
z1 = Math.max(z1, _p.z);
|
|
11004
|
+
}
|
|
11005
|
+
rs.push([x0 - 0.08, z0 - 0.08, x1 + 0.08, z1 + 0.08]);
|
|
11006
|
+
}
|
|
11007
|
+
_p.set(0, house.y0(c.floor), 0).applyMatrix4(M);
|
|
11008
|
+
list2.push({ c, rs, y: [_p.y - 0.06, _p.y + (c.ceiling || 2.8) + 0.3] });
|
|
11009
|
+
}
|
|
11010
|
+
return list2;
|
|
11011
|
+
};
|
|
11012
|
+
const boxAt = (boxes, x, y, z) => boxes.find((q) => y >= q.y[0] && y <= q.y[1] && q.rs.some((r) => x >= r[0] && x <= r[2] && z >= r[1] && z <= r[3]));
|
|
11013
|
+
const openingSides = (house, M, boxes, into) => {
|
|
11014
|
+
const open = house.internal && house.internal.doorState || /* @__PURE__ */ new Map();
|
|
11015
|
+
const reach = (list2, isDoor) => {
|
|
11016
|
+
for (const p of list2 || []) {
|
|
11017
|
+
if (isDoor && !(open.has(p.id) ? open.get(p.id) : !!p.open)) continue;
|
|
11018
|
+
const alongU = p.axis === "u", y = house.y0(p.floor) + (isDoor ? 1 : ((p.y0 != null ? p.y0 : 0.9) + (p.y1 != null ? p.y1 : 2)) / 2);
|
|
11019
|
+
const at = (side) => _p.set(alongU ? p.at : p.pos + side, y, alongU ? p.pos + side : p.at).applyMatrix4(M).clone();
|
|
11020
|
+
if (at(0).distanceTo(P0) > OPENING_REACH) continue;
|
|
11021
|
+
for (const side of [-OPENING_SIDE, OPENING_SIDE]) {
|
|
11022
|
+
const w = at(side), hit = boxAt(boxes, w.x, w.y, w.z);
|
|
11023
|
+
if (hit) into.set(hit.c, hit);
|
|
11024
|
+
}
|
|
11025
|
+
}
|
|
11026
|
+
};
|
|
11027
|
+
reach(house.r.doors, true);
|
|
11028
|
+
reach(house.r.windows, false);
|
|
11029
|
+
};
|
|
11030
|
+
const clear = (at) => {
|
|
11031
|
+
for (const key of ["uRB0", "uRB1", "uRB2", "uREx"]) LZU[key].value.set(EMPTY, at * 4);
|
|
11032
|
+
LZU.uRBY.value.set([0, 0], at * 2);
|
|
11033
|
+
};
|
|
11034
|
+
const write = (at, into) => {
|
|
11035
|
+
const rs = [];
|
|
11036
|
+
let lo = 1e9, hi = -1e9;
|
|
11037
|
+
for (const q of into.values()) {
|
|
11038
|
+
rs.push(...q.rs);
|
|
11039
|
+
lo = Math.min(lo, q.y[0]);
|
|
11040
|
+
hi = Math.max(hi, q.y[1]);
|
|
11041
|
+
}
|
|
11042
|
+
while (rs.length > 3) {
|
|
11043
|
+
const r23 = rs.pop(), r1 = rs[rs.length - 1];
|
|
11044
|
+
rs[rs.length - 1] = [Math.min(r1[0], r23[0]), Math.min(r1[1], r23[1]), Math.max(r1[2], r23[2]), Math.max(r1[3], r23[3])];
|
|
11045
|
+
}
|
|
11046
|
+
LZU.uRB0.value.set(rs[0] || EMPTY, at * 4);
|
|
11047
|
+
LZU.uRB1.value.set(rs[1] || EMPTY, at * 4);
|
|
11048
|
+
LZU.uRB2.value.set(rs[2] || EMPTY, at * 4);
|
|
11049
|
+
LZU.uRBY.value.set([lo, hi], at * 2);
|
|
11050
|
+
LZU.uREx.value.set(EMPTY, at * 4);
|
|
11051
|
+
};
|
|
11052
|
+
const A = {
|
|
11053
|
+
/** Once per frame, after the budget's `present`: points the mask of every lit slot that is not the house's at the rooms its light reaches. */
|
|
11054
|
+
update(houses2) {
|
|
11055
|
+
const indoors = cfg.effectLightsIndoors !== false, list2 = (Array.isArray(houses2) ? houses2 : [houses2]).filter(Boolean), cache2 = /* @__PURE__ */ new Map();
|
|
11056
|
+
for (let at = 0; at < size; at++) {
|
|
11057
|
+
if (ours.has(at)) continue;
|
|
11058
|
+
const light = budget.group.children[at];
|
|
11059
|
+
if (!indoors || !light || !light.isPointLight || !(light.intensity > 0) || !light.visible) {
|
|
11060
|
+
clear(at);
|
|
11061
|
+
continue;
|
|
11062
|
+
}
|
|
11063
|
+
const into = /* @__PURE__ */ new Map();
|
|
11064
|
+
P0.set(light.position.x, light.position.y, light.position.z);
|
|
11065
|
+
for (const house of list2) {
|
|
11066
|
+
if (house.group && !house.group.visible) continue;
|
|
11067
|
+
house.house.updateMatrixWorld(true);
|
|
11068
|
+
const M = house.house.matrixWorld;
|
|
11069
|
+
let boxes = cache2.get(house);
|
|
11070
|
+
if (!boxes) cache2.set(house, boxes = roomBoxes(house, M));
|
|
11071
|
+
const here = boxAt(boxes, P0.x, P0.y, P0.z);
|
|
11072
|
+
if (here) into.set(here.c, here);
|
|
11073
|
+
openingSides(house, M, boxes, into);
|
|
11074
|
+
}
|
|
11075
|
+
if (into.size) write(at, into);
|
|
11076
|
+
else clear(at);
|
|
11077
|
+
}
|
|
11078
|
+
}
|
|
11079
|
+
};
|
|
11080
|
+
if (!o.ours) effectsByBudget.set(budget, A);
|
|
11081
|
+
return A;
|
|
10887
11082
|
}
|
|
10888
|
-
|
|
10889
|
-
};
|
|
10890
|
-
var sparkTargetFactor = (materialId, metal, rules = DEFAULT_IGNITION_RULES) => !metal ? 0 : rules.sparkTarget[materialId] ?? rules.sparkMetalDefault;
|
|
10891
|
-
var ignitionChance = (hit, target, rules = DEFAULT_IGNITION_RULES) => {
|
|
10892
|
-
const k = fillFactor(target.fill, rules.fillCurve);
|
|
10893
|
-
const spark = (hit.ignition?.spark ?? 0) * target.sparkTarget * (target.fluid === void 0 ? 1 : rules.sparkFluid[target.fluid] ?? 1) * k;
|
|
10894
|
-
const flameBase = hit.ignition?.flame ?? Math.max(hit.incendiary ? rules.flameDefaults.incendiary : 0, hit.tracer ? rules.flameDefaults.tracer : 0);
|
|
10895
|
-
const flame = flameBase * (1 - rules.flameFillInfluence * (1 - k));
|
|
10896
|
-
return 1 - (1 - Math.min(1, Math.max(0, spark))) * (1 - Math.min(1, Math.max(0, flame)));
|
|
10897
|
-
};
|
|
10898
|
-
var KIT_ORIGIN_KEY = "kitOrigin";
|
|
10899
|
-
function markKitOrigin(object2, origin) {
|
|
10900
|
-
const node = object2;
|
|
10901
|
-
node.userData = node.userData ?? {};
|
|
10902
|
-
node.userData[KIT_ORIGIN_KEY] = { ...origin };
|
|
10903
|
-
return object2;
|
|
11083
|
+
Object.assign(K, { MAX_LIGHTS, EMPTY, LZU, roomLightMask, lighting, effectLights });
|
|
10904
11084
|
}
|
|
10905
11085
|
|
|
10906
11086
|
// ../game-destruction/dist/index.js
|
|
@@ -13613,6 +13793,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
13613
13793
|
const ignitionRules = resolveIgnitionRules(options.ignition);
|
|
13614
13794
|
const breachBlastFactor = options.breach?.blastFactor ?? BREACH_BLAST_FACTOR;
|
|
13615
13795
|
const chipEnergy = options.breach?.chipEnergy ?? CHIP_ENERGY;
|
|
13796
|
+
const chainLinkCap = options.chainLinksPerUpdate !== void 0 && options.chainLinksPerUpdate >= 1 ? Math.floor(options.chainLinksPerUpdate) : Infinity;
|
|
13616
13797
|
const rng2 = createRng(options.seed ?? 1);
|
|
13617
13798
|
const rnd = () => rng2.next();
|
|
13618
13799
|
let time = 0;
|
|
@@ -14560,7 +14741,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
14560
14741
|
if (disc < 0) return true;
|
|
14561
14742
|
return -b - Math.sqrt(disc) > maxDist;
|
|
14562
14743
|
};
|
|
14563
|
-
const raycastInternal = (origin, dir, maxDist, ignore, worldOnly = false) => {
|
|
14744
|
+
const raycastInternal = (origin, dir, maxDist, ignore, worldOnly = false, precise = false) => {
|
|
14564
14745
|
const d = vec.normalize(dir);
|
|
14565
14746
|
let best = null;
|
|
14566
14747
|
for (const o of objects.values()) {
|
|
@@ -14575,13 +14756,25 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
14575
14756
|
}
|
|
14576
14757
|
}
|
|
14577
14758
|
for (const im of worldOnly ? [] : impls.values()) {
|
|
14759
|
+
let boxHit = null;
|
|
14578
14760
|
for (const ps of im.impl.describe().parts) {
|
|
14579
14761
|
if (ignore?.has(`${im.impl.id}\0${ps.id}`)) continue;
|
|
14580
14762
|
const ov = im.poses.get(ps.id);
|
|
14581
14763
|
const r = rayPartRaw(im.position, im.rotation, ps, ov?.q ?? quatFromEuler(...ps.rotation ?? [0, 0, 0]), origin, d, ov?.pos);
|
|
14582
|
-
if (!r || r.
|
|
14583
|
-
if (
|
|
14764
|
+
if (!r || r.t1 < 0 || r.t0 > maxDist) continue;
|
|
14765
|
+
if (r.t0 < 0) {
|
|
14766
|
+
if (precise && im.impl.surfaceRay) boxHit = boxHit ?? { object: im.impl.id, part: ps.id, point: origin, normal: r.n, distance: 0, pathLen: r.t1 };
|
|
14767
|
+
continue;
|
|
14768
|
+
}
|
|
14769
|
+
if (!boxHit || r.t0 < boxHit.distance) boxHit = { object: im.impl.id, part: ps.id, point: vec.madd(origin, d, r.t0), normal: r.n, distance: r.t0, pathLen: r.t1 - r.t0 };
|
|
14584
14770
|
}
|
|
14771
|
+
if (!boxHit) continue;
|
|
14772
|
+
if (precise && im.impl.surfaceRay) {
|
|
14773
|
+
const far = best ? Math.min(maxDist, best.distance) : maxDist;
|
|
14774
|
+
const implId = im.impl.id;
|
|
14775
|
+
const s = im.impl.surfaceRay({ origin, direction: d, maxDistance: far, ...ignore ? { ignored: (part) => ignore.has(`${implId}\0${part}`) } : {} });
|
|
14776
|
+
if (s && (!best || s.distance < best.distance)) best = { object: implId, part: s.part, point: s.point, normal: s.normal, distance: s.distance, pathLen: s.pathLen };
|
|
14777
|
+
} else if (!best || boxHit.distance < best.distance) best = boxHit;
|
|
14585
14778
|
}
|
|
14586
14779
|
return best;
|
|
14587
14780
|
};
|
|
@@ -16065,7 +16258,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
16065
16258
|
};
|
|
16066
16259
|
const detonatePrimed = (until) => {
|
|
16067
16260
|
const end = time;
|
|
16068
|
-
|
|
16261
|
+
let fired = 0;
|
|
16262
|
+
for (let next = nextPrimed(until); next && fired < chainLinkCap; next = nextPrimed(until)) {
|
|
16263
|
+
fired++;
|
|
16069
16264
|
primed.delete(next.p);
|
|
16070
16265
|
time = Math.max(0, Math.min(end, next.p.rt.chainDue));
|
|
16071
16266
|
next.p.rt.chainDue = void 0;
|
|
@@ -16135,6 +16330,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
16135
16330
|
updateBound(o);
|
|
16136
16331
|
},
|
|
16137
16332
|
remove(id) {
|
|
16333
|
+
impls.get(id)?.impl.dispose?.();
|
|
16138
16334
|
objects.delete(id);
|
|
16139
16335
|
impls.delete(id);
|
|
16140
16336
|
},
|
|
@@ -16210,7 +16406,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
16210
16406
|
return withCollapses(run(() => blastWorld(point, energy, radius, source, blast)));
|
|
16211
16407
|
},
|
|
16212
16408
|
raycast(origin, direction, maxDistance = Infinity) {
|
|
16213
|
-
const r = raycastInternal(origin, direction, maxDistance);
|
|
16409
|
+
const r = raycastInternal(origin, direction, maxDistance, void 0, false, true);
|
|
16214
16410
|
return r ? { object: r.object, part: r.part, point: r.point, normal: r.normal, distance: r.distance } : null;
|
|
16215
16411
|
},
|
|
16216
16412
|
sweepBox(box3, direction, distance2, options2 = {}) {
|
|
@@ -16235,11 +16431,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
16235
16431
|
let org = origin;
|
|
16236
16432
|
let E = energy;
|
|
16237
16433
|
for (let i = 0; i < 4 && E > 0; i++) {
|
|
16238
|
-
const rh = raycastInternal(org, d, Infinity, ignore);
|
|
16434
|
+
const rh = raycastInternal(org, d, Infinity, ignore, false, true);
|
|
16239
16435
|
if (!rh) break;
|
|
16240
16436
|
const im = impls.get(rh.object);
|
|
16241
16437
|
if (im) {
|
|
16242
|
-
const r = implHit(im, { type: "ballistic", point: rh.point, direction: d, energy: E, caliber, ...extras, ...source !== void 0 ? { source } : {} });
|
|
16438
|
+
const r = implHit(im, { type: "ballistic", point: rh.point, part: rh.part, normal: rh.normal, direction: d, energy: E, caliber, ...extras, ...source !== void 0 ? { source } : {} });
|
|
16243
16439
|
r.part = rh.part;
|
|
16244
16440
|
r.point = rh.point;
|
|
16245
16441
|
r.exitEnergy = r.penetrated ? E * 0.5 : 0;
|
|
@@ -16561,12 +16757,27 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
16561
16757
|
breach: { area: 0.1 }
|
|
16562
16758
|
}
|
|
16563
16759
|
];
|
|
16760
|
+
var SHIPPED = structuredClone(assemblies_default);
|
|
16564
16761
|
var ASSEMBLIES = assemblies_default;
|
|
16565
|
-
var
|
|
16762
|
+
var assembliesOver = (defs) => {
|
|
16763
|
+
const get = (id) => defs.find((a) => a.id === id);
|
|
16764
|
+
return {
|
|
16765
|
+
list: () => defs,
|
|
16766
|
+
get,
|
|
16767
|
+
register(def) {
|
|
16768
|
+
const at = defs.findIndex((a) => a.id === def.id);
|
|
16769
|
+
if (at >= 0) defs[at] = def;
|
|
16770
|
+
else defs.push(def);
|
|
16771
|
+
},
|
|
16772
|
+
part: (assemblyId, options) => buildAssemblyPart(get(assemblyId), assemblyId, options)
|
|
16773
|
+
};
|
|
16774
|
+
};
|
|
16775
|
+
var defaultSet;
|
|
16776
|
+
var defaultAssemblies = () => defaultSet ?? (defaultSet = assembliesOver(ASSEMBLIES));
|
|
16777
|
+
var getAssembly = (id) => defaultAssemblies().get(id);
|
|
16566
16778
|
var faceCount = (layer) => layer.faces === "both" ? 2 : 1;
|
|
16567
16779
|
var assemblyDepth = (def) => def.depth ?? def.core.thickness + (def.layers ?? []).reduce((sum, l) => sum + l.thickness * faceCount(l), 0);
|
|
16568
|
-
var
|
|
16569
|
-
const def = getAssembly(assemblyId);
|
|
16780
|
+
var buildAssemblyPart = (def, assemblyId, options) => {
|
|
16570
16781
|
if (!def) throw new Error(`unknown assembly "${assemblyId}"`);
|
|
16571
16782
|
const densityOf2 = (id) => {
|
|
16572
16783
|
const m = options.materials?.get(id) ?? MATERIALS2.find((x) => x.id === id);
|
|
@@ -16593,6 +16804,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
16593
16804
|
...options.extra
|
|
16594
16805
|
};
|
|
16595
16806
|
};
|
|
16807
|
+
var assemblyPart = (assemblyId, options) => defaultAssemblies().part(assemblyId, options);
|
|
16596
16808
|
var buildFrame = (o = {}) => {
|
|
16597
16809
|
const spanX = o.spanX ?? 8, spanZ = o.spanZ ?? 8;
|
|
16598
16810
|
const nx = Math.max(2, o.columnsX ?? 3), nz = Math.max(2, o.columnsZ ?? 3);
|
|
@@ -19774,6 +19986,34 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
19774
19986
|
}
|
|
19775
19987
|
function installDestructionBreach(K, _shared) {
|
|
19776
19988
|
const { THREE, fragmentMaterial, invalidate, invalidateShadow } = K;
|
|
19989
|
+
const paintState = { attached: false };
|
|
19990
|
+
const paintQueues = /* @__PURE__ */ new Set();
|
|
19991
|
+
const paintQueue = {
|
|
19992
|
+
id: DEFERRED_QUEUE_ID.BREACH_PAINT,
|
|
19993
|
+
pending: () => {
|
|
19994
|
+
let n = 0;
|
|
19995
|
+
for (const q of paintQueues) n += q.pending();
|
|
19996
|
+
return n;
|
|
19997
|
+
},
|
|
19998
|
+
run(deadline, clock) {
|
|
19999
|
+
let ran = 0;
|
|
20000
|
+
for (const q of [...paintQueues]) {
|
|
20001
|
+
if (q.pending() === 0) continue;
|
|
20002
|
+
if (ran > 0 && clock() >= deadline) break;
|
|
20003
|
+
ran += q.run(deadline, clock);
|
|
20004
|
+
}
|
|
20005
|
+
return ran;
|
|
20006
|
+
},
|
|
20007
|
+
flush() {
|
|
20008
|
+
for (const q of [...paintQueues]) q.flush();
|
|
20009
|
+
},
|
|
20010
|
+
attach() {
|
|
20011
|
+
paintState.attached = true;
|
|
20012
|
+
},
|
|
20013
|
+
detach() {
|
|
20014
|
+
paintState.attached = false;
|
|
20015
|
+
}
|
|
20016
|
+
};
|
|
19777
20017
|
function createBreachView(opts) {
|
|
19778
20018
|
const { house, structure } = opts;
|
|
19779
20019
|
const views = /* @__PURE__ */ new Map();
|
|
@@ -20088,8 +20328,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
20088
20328
|
else s.data = collapseRange(s.it.mesh, s.v0, s.it.v1);
|
|
20089
20329
|
}
|
|
20090
20330
|
}
|
|
20091
|
-
function flush(budgetMs
|
|
20331
|
+
function flush(budgetMs) {
|
|
20092
20332
|
if (dirty.size === 0) return 0;
|
|
20333
|
+
if (budgetMs === void 0 && paintState.attached) return dirty.size;
|
|
20334
|
+
budgetMs ?? (budgetMs = paintBudgetMs);
|
|
20093
20335
|
const deadline = performance.now() + budgetMs;
|
|
20094
20336
|
for (const view of dirty) {
|
|
20095
20337
|
dirty.delete(view);
|
|
@@ -20100,6 +20342,34 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
20100
20342
|
invalidateShadow();
|
|
20101
20343
|
return dirty.size;
|
|
20102
20344
|
}
|
|
20345
|
+
const queue = {
|
|
20346
|
+
id: DEFERRED_QUEUE_ID.BREACH_PAINT,
|
|
20347
|
+
pending: () => dirty.size,
|
|
20348
|
+
run(deadline, clock) {
|
|
20349
|
+
let ran = 0;
|
|
20350
|
+
for (const view of dirty) {
|
|
20351
|
+
dirty.delete(view);
|
|
20352
|
+
paint(view);
|
|
20353
|
+
ran++;
|
|
20354
|
+
if (clock() >= deadline) break;
|
|
20355
|
+
}
|
|
20356
|
+
if (ran > 0) {
|
|
20357
|
+
invalidate();
|
|
20358
|
+
invalidateShadow();
|
|
20359
|
+
}
|
|
20360
|
+
return ran;
|
|
20361
|
+
},
|
|
20362
|
+
flush() {
|
|
20363
|
+
flush(Infinity);
|
|
20364
|
+
},
|
|
20365
|
+
attach() {
|
|
20366
|
+
paintState.attached = true;
|
|
20367
|
+
},
|
|
20368
|
+
detach() {
|
|
20369
|
+
paintState.attached = false;
|
|
20370
|
+
}
|
|
20371
|
+
};
|
|
20372
|
+
paintQueues.add(queue);
|
|
20103
20373
|
function dispose(view) {
|
|
20104
20374
|
dirty.delete(view);
|
|
20105
20375
|
if (view.units) {
|
|
@@ -20134,6 +20404,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
20134
20404
|
*/
|
|
20135
20405
|
claim() {
|
|
20136
20406
|
var _a;
|
|
20407
|
+
paintQueues.add(queue);
|
|
20137
20408
|
for (const q of opts.spec()?.parts ?? []) {
|
|
20138
20409
|
if (!q.units) continue;
|
|
20139
20410
|
const host = hostOf(q.id);
|
|
@@ -20186,6 +20457,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
20186
20457
|
dropped.length = 0;
|
|
20187
20458
|
},
|
|
20188
20459
|
flush,
|
|
20460
|
+
/** Takes this house's painting out of the renderer's queue (the house goes away); `claim` puts it back. */
|
|
20461
|
+
release() {
|
|
20462
|
+
paintQueues.delete(queue);
|
|
20463
|
+
},
|
|
20464
|
+
/** The painting of this house alone. */
|
|
20465
|
+
deferredQueue: () => queue,
|
|
20189
20466
|
/** The wall has damage drawn. */
|
|
20190
20467
|
has(partId) {
|
|
20191
20468
|
return views.has(partId);
|
|
@@ -20200,7 +20477,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
20200
20477
|
})
|
|
20201
20478
|
};
|
|
20202
20479
|
}
|
|
20203
|
-
Object.assign(K, { createBreachView });
|
|
20480
|
+
Object.assign(K, { createBreachView, breachPaintQueue: paintQueue });
|
|
20204
20481
|
}
|
|
20205
20482
|
|
|
20206
20483
|
// src/destruction/world.ts
|
|
@@ -20455,6 +20732,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
20455
20732
|
if (R && D.id && D.active) R.unbind(D.id);
|
|
20456
20733
|
if (D.active && D.world.has(D.id)) D.world.remove(D.id);
|
|
20457
20734
|
D.active = false;
|
|
20735
|
+
breach.release();
|
|
20458
20736
|
};
|
|
20459
20737
|
D.follow = (world, id, spec) => {
|
|
20460
20738
|
D.spec = spec;
|
|
@@ -20489,6 +20767,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
20489
20767
|
return { restore: () => breach.restore(), dispose: () => {
|
|
20490
20768
|
offFollow();
|
|
20491
20769
|
breach.restore();
|
|
20770
|
+
breach.release();
|
|
20492
20771
|
}, update: () => {
|
|
20493
20772
|
breach.flush();
|
|
20494
20773
|
} };
|
|
@@ -21101,7 +21380,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
21101
21380
|
|
|
21102
21381
|
// src/build/api.ts
|
|
21103
21382
|
function buildApi(K, shared) {
|
|
21104
|
-
const { cfg, VERSION: VERSION2, ATLAS, TEX, applyPart, carGroup, carModel, props, TYPES, roomLightMask, lighting, newState, build } = K;
|
|
21383
|
+
const { cfg, VERSION: VERSION2, ATLAS, TEX, applyPart, carGroup, carModel, props, TYPES, roomLightMask, lighting, effectLights, newState, build } = K;
|
|
21105
21384
|
return {
|
|
21106
21385
|
version: VERSION2,
|
|
21107
21386
|
build,
|
|
@@ -21116,10 +21395,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
21116
21395
|
},
|
|
21117
21396
|
roomLightMask,
|
|
21118
21397
|
lighting,
|
|
21398
|
+
effectLights,
|
|
21119
21399
|
setNight(n) {
|
|
21120
21400
|
shared.mats.glass.emissive.set(n ? 9067040 : 0);
|
|
21121
21401
|
shared.mats.glass.opacity = n ? 0.4 : 0.24;
|
|
21122
21402
|
},
|
|
21403
|
+
/** The chipped-plaster painting of every house of this renderer as a `DeferredQueue` for a frame budget (id `floorplan.breach-paint`); asking for it changes nothing. */
|
|
21404
|
+
deferredQueue: () => K.breachPaintQueue,
|
|
21123
21405
|
cars: { model: carModel, group: carGroup, info: (k, seed) => {
|
|
21124
21406
|
const m = carModel(k, seed);
|
|
21125
21407
|
return m && { parts: m.parts.length, tris: m.tris, L: m.L, W: m.W, H: m.H };
|
|
@@ -21586,6 +21868,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
21586
21868
|
return { off, reset: () => navigator.undoChanges(houseId) };
|
|
21587
21869
|
}
|
|
21588
21870
|
|
|
21871
|
+
// ../game-render-three/dist/index.js
|
|
21872
|
+
var DEFAULT_ANGLE = Math.PI / 3;
|
|
21873
|
+
function isLightBudget(value) {
|
|
21874
|
+
const candidate = value;
|
|
21875
|
+
return typeof candidate === "object" && candidate !== null && typeof candidate.acquire === "function" && typeof candidate.addSource === "function" && typeof candidate.lease === "function" && typeof candidate.present === "function";
|
|
21876
|
+
}
|
|
21877
|
+
var EFFECT_STEP_SECONDS = 1 / 50;
|
|
21878
|
+
|
|
21589
21879
|
// src/test-area/text.ts
|
|
21590
21880
|
var TEXT = {
|
|
21591
21881
|
en: {
|
|
@@ -21608,7 +21898,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
21608
21898
|
hit: { burst_9mm: "9 mm burst", burst_762: "7.62 burst", sledge: "Sledgehammer", c4: "C4", rpg: "RPG warhead" },
|
|
21609
21899
|
state: { normal: "Normal", fortified: "Fortified", abandoned: "Abandoned" }
|
|
21610
21900
|
},
|
|
21611
|
-
layers: { roof: "Roof", lot: "Lot (ground, wall, gate)", night: "Night (lit windows and lamps)" },
|
|
21901
|
+
layers: { roof: "Roof", lot: "Lot (ground, wall, gate)", night: "Night (lit windows and lamps)", room_lights: "Room lights (one lamp per lit room, stopped by the walls)" },
|
|
21612
21902
|
metrics: { houses: "Houses", parts: "Parts", standing: "Standing", broken: "Broken", holes: "Holes", draw_calls: "Draw calls", triangles: "Triangles", lod: "Level of detail (nearest)", floor: "Your floor", doors_open: "Doors open", target: "You aim at", planned: "Planned draw calls" },
|
|
21613
21903
|
sheet: { kicker: "House", title: "House of the bench", template: "Typology", seed: "Seed", state: "State", floors: "Floors", size: "Size", parts: "Structure parts", look: "You aim at", none: "nothing to use", no_engine: "The page gave no floorplan engine" },
|
|
21614
21904
|
specimens: {
|
|
@@ -21674,7 +21964,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
21674
21964
|
hit: { burst_9mm: "Rajada de 9 mm", burst_762: "Rajada de 7,62", sledge: "Marreta", c4: "C4", rpg: "Ogiva de RPG" },
|
|
21675
21965
|
state: { normal: "Normal", fortified: "Fortificada", abandoned: "Abandonada" }
|
|
21676
21966
|
},
|
|
21677
|
-
layers: { roof: "Telhado", lot: "Lote (ch\xE3o, muro, port\xE3o)", night: "Noite (janelas e l\xE2mpadas acesas)" },
|
|
21967
|
+
layers: { roof: "Telhado", lot: "Lote (ch\xE3o, muro, port\xE3o)", night: "Noite (janelas e l\xE2mpadas acesas)", room_lights: "Luz por c\xF4modo (uma l\xE2mpada por c\xF4modo aceso, barrada pelas paredes)" },
|
|
21678
21968
|
metrics: { houses: "Casas", parts: "Pe\xE7as", standing: "De p\xE9", broken: "Quebradas", holes: "Furos", draw_calls: "Draw calls", triangles: "Tri\xE2ngulos", lod: "N\xEDvel de detalhe (a mais perto)", floor: "Seu andar", doors_open: "Portas abertas", target: "Voc\xEA mira em", planned: "Draw calls planejados" },
|
|
21679
21969
|
sheet: { kicker: "Casa", title: "Casa da bancada", template: "Tipologia", seed: "Semente", state: "Estado", floors: "Andares", size: "Tamanho", parts: "Pe\xE7as da estrutura", look: "Voc\xEA mira em", none: "nada para usar", no_engine: "A p\xE1gina n\xE3o deu o motor de plantas" },
|
|
21680
21970
|
specimens: {
|
|
@@ -21971,6 +22261,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
21971
22261
|
let THREE = null;
|
|
21972
22262
|
let houseRenderer = null;
|
|
21973
22263
|
let houseRendererKey = "";
|
|
22264
|
+
let stopPaintQueue;
|
|
22265
|
+
let roomLights = null;
|
|
21974
22266
|
const placed = [];
|
|
21975
22267
|
let time = 0;
|
|
21976
22268
|
let dirty = false;
|
|
@@ -21998,20 +22290,29 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
21998
22290
|
const rendererFor = () => {
|
|
21999
22291
|
const key = `${settings.quality}|${locale}`;
|
|
22000
22292
|
if (!houseRenderer || houseRendererKey !== key) {
|
|
22293
|
+
stopPaintQueue?.();
|
|
22294
|
+
dropRoomLights();
|
|
22001
22295
|
houseRenderer?.dispose?.();
|
|
22002
22296
|
houseRenderer = create3(THREE, {
|
|
22003
22297
|
locale,
|
|
22004
22298
|
lod: { interior: 10, hide: 40 },
|
|
22005
22299
|
breachPaintBudgetMs: 4,
|
|
22006
22300
|
...options.house,
|
|
22301
|
+
...options.house?.interactives ? { interactives: { effectSink: () => host?.effects, ...options.house.interactives } } : {},
|
|
22007
22302
|
quality: settings.quality,
|
|
22008
22303
|
...options.world ? { destruction: options.world } : {},
|
|
22009
22304
|
...options.renderer ? { destructionRenderer: options.renderer } : {}
|
|
22010
22305
|
});
|
|
22011
22306
|
houseRendererKey = key;
|
|
22307
|
+
const paintQueue = houseRenderer.deferredQueue?.();
|
|
22308
|
+
stopPaintQueue = paintQueue ? host?.defer?.(paintQueue, DEFERRED_PRIORITY[DEFERRED_QUEUE_ID.BREACH_PAINT]) : void 0;
|
|
22012
22309
|
}
|
|
22013
22310
|
return houseRenderer;
|
|
22014
22311
|
};
|
|
22312
|
+
const dropRoomLights = () => {
|
|
22313
|
+
roomLights?.dispose();
|
|
22314
|
+
roomLights = null;
|
|
22315
|
+
};
|
|
22015
22316
|
const clearHouses = () => {
|
|
22016
22317
|
for (const p of placed) p.house.dispose();
|
|
22017
22318
|
placed.length = 0;
|
|
@@ -22249,6 +22550,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
22249
22550
|
}
|
|
22250
22551
|
if (change.kind === "layer") {
|
|
22251
22552
|
if (change.id === "roof") showAll();
|
|
22553
|
+
else if (change.id === "room_lights") dropRoomLights();
|
|
22252
22554
|
else if (placed.length > 0) {
|
|
22253
22555
|
dirty = true;
|
|
22254
22556
|
dirtyAt = time;
|
|
@@ -22415,7 +22717,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
22415
22717
|
layers: () => [
|
|
22416
22718
|
{ id: "roof", name: text.layers.roof, default: true },
|
|
22417
22719
|
{ id: "lot", name: text.layers.lot, default: false },
|
|
22418
|
-
{ id: "night", name: text.layers.night, default: false }
|
|
22720
|
+
{ id: "night", name: text.layers.night, default: false },
|
|
22721
|
+
{ id: "room_lights", name: text.layers.room_lights, default: false }
|
|
22419
22722
|
],
|
|
22420
22723
|
metrics: () => [
|
|
22421
22724
|
{ id: "houses_built", name: text.metrics.houses, read: () => placed.length },
|
|
@@ -22461,6 +22764,21 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
22461
22764
|
updateSheet();
|
|
22462
22765
|
}
|
|
22463
22766
|
});
|
|
22767
|
+
const stopEffectLights = lent.onFrame(
|
|
22768
|
+
() => {
|
|
22769
|
+
const budget = lent.lights;
|
|
22770
|
+
if (!isLightBudget(budget) || placed.length === 0 || !houseRenderer) return;
|
|
22771
|
+
const houses2 = placed.map((p) => p.house);
|
|
22772
|
+
if (lent.bench?.layer("room_lights") ?? false) {
|
|
22773
|
+
roomLights ?? (roomLights = houseRenderer.lighting({ scene: lent.scene, n: 3, shadows: 0, budget }));
|
|
22774
|
+
roomLights.update(houses2, cameraWorld(), {});
|
|
22775
|
+
return;
|
|
22776
|
+
}
|
|
22777
|
+
dropRoomLights();
|
|
22778
|
+
houseRenderer.effectLights?.({ budget })?.update(houses2);
|
|
22779
|
+
},
|
|
22780
|
+
{ phase: "present", order: 20 }
|
|
22781
|
+
);
|
|
22464
22782
|
const onKey = (event) => {
|
|
22465
22783
|
if (event.code === "KeyE" && !event.repeat && placed.length > 0) useNearest();
|
|
22466
22784
|
};
|
|
@@ -22468,9 +22786,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
22468
22786
|
return () => {
|
|
22469
22787
|
stopChange?.();
|
|
22470
22788
|
stopFrame();
|
|
22789
|
+
stopEffectLights();
|
|
22790
|
+
dropRoomLights();
|
|
22471
22791
|
globalThis.removeEventListener?.("keydown", onKey);
|
|
22472
22792
|
for (const remove of removers.splice(0)) remove();
|
|
22473
22793
|
clearHouses();
|
|
22794
|
+
stopPaintQueue?.();
|
|
22795
|
+
stopPaintQueue = void 0;
|
|
22474
22796
|
houseRenderer?.dispose?.();
|
|
22475
22797
|
houseRenderer = null;
|
|
22476
22798
|
host = null;
|