@adatechnology/game-destruction-three 0.5.0 → 0.6.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 +2 -2
- package/dist/index.d.ts +67 -2
- package/dist/index.global.js +345 -9
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +214 -6
- package/dist/index.js.map +1 -1
- package/package.json +8 -6
package/dist/index.js
CHANGED
|
@@ -295,9 +295,9 @@ var FragmentSystem = class {
|
|
|
295
295
|
// src/ground.ts
|
|
296
296
|
var MAX_RADIUS = 1.2;
|
|
297
297
|
var GroundSpots = class {
|
|
298
|
-
constructor(THREE,
|
|
298
|
+
constructor(THREE, scene2, groundAt, cap) {
|
|
299
299
|
__publicField(this, "THREE", THREE);
|
|
300
|
-
__publicField(this, "scene",
|
|
300
|
+
__publicField(this, "scene", scene2);
|
|
301
301
|
__publicField(this, "groundAt", groundAt);
|
|
302
302
|
__publicField(this, "cap", cap);
|
|
303
303
|
__publicField(this, "spots", []);
|
|
@@ -699,9 +699,9 @@ var PieceSystem = class {
|
|
|
699
699
|
|
|
700
700
|
// src/rebar.ts
|
|
701
701
|
var RebarCages = class {
|
|
702
|
-
constructor(THREE,
|
|
702
|
+
constructor(THREE, scene2, radius = 4e-3) {
|
|
703
703
|
__publicField(this, "THREE", THREE);
|
|
704
|
-
__publicField(this, "scene",
|
|
704
|
+
__publicField(this, "scene", scene2);
|
|
705
705
|
__publicField(this, "cages", /* @__PURE__ */ new Map());
|
|
706
706
|
__publicField(this, "geometry");
|
|
707
707
|
__publicField(this, "material");
|
|
@@ -1517,10 +1517,10 @@ var Visuals = class {
|
|
|
1517
1517
|
const sy = lerp(1, 0.25, melt);
|
|
1518
1518
|
const sxz = 1 + 0.18 * melt;
|
|
1519
1519
|
for (let i = range[0] * 3, v = 0; i < range[1] * 3; i += 3, v++) {
|
|
1520
|
-
const
|
|
1520
|
+
const noise2 = (Math.imul(v + 1, 2654435761) >>> 0) % 1e3 / 1e3;
|
|
1521
1521
|
arr[i] = cx + (work[i] - cx) * sxz;
|
|
1522
1522
|
arr[i + 2] = cz + (work[i + 2] - cz) * sxz;
|
|
1523
|
-
arr[i + 1] = Math.max(minY, minY + (work[i + 1] - minY) * sy -
|
|
1523
|
+
arr[i + 1] = Math.max(minY, minY + (work[i + 1] - minY) * sy - noise2 * melt * h * 0.04);
|
|
1524
1524
|
}
|
|
1525
1525
|
}
|
|
1526
1526
|
/** The colour attribute of the host's current geometry (created white when there is none) with vertex colours switched on in its material. */
|
|
@@ -1845,6 +1845,8 @@ var Renderer = class {
|
|
|
1845
1845
|
__publicField(this, "cages");
|
|
1846
1846
|
__publicField(this, "active", /* @__PURE__ */ new Map());
|
|
1847
1847
|
__publicField(this, "fires", /* @__PURE__ */ new Map());
|
|
1848
|
+
/** Primed parts burning in the effects world until they go off: their burn loop ends when they are put out. */
|
|
1849
|
+
__publicField(this, "primedBurning", /* @__PURE__ */ new Set());
|
|
1848
1850
|
__publicField(this, "leaks", []);
|
|
1849
1851
|
__publicField(this, "homeTags", []);
|
|
1850
1852
|
__publicField(this, "throttles", /* @__PURE__ */ new Map());
|
|
@@ -2186,8 +2188,10 @@ var Renderer = class {
|
|
|
2186
2188
|
case "primed":
|
|
2187
2189
|
if (ev.trigger !== "explosion") {
|
|
2188
2190
|
this.vfx.fire({ point: ev.point, radius: PRIMED_FIRE_RADIUS, life: ev.delay });
|
|
2191
|
+
this.primedBurning.add(`${ev.object}|${ev.part}`);
|
|
2189
2192
|
this.activate(ev.object, ev.part);
|
|
2190
2193
|
this.sound("ignite", ev.point, 0.7);
|
|
2194
|
+
this.sound("burn_loop", ev.point, 0.5);
|
|
2191
2195
|
}
|
|
2192
2196
|
break;
|
|
2193
2197
|
case "spall":
|
|
@@ -2205,16 +2209,20 @@ var Renderer = class {
|
|
|
2205
2209
|
break;
|
|
2206
2210
|
case "extinguish": {
|
|
2207
2211
|
const f = this.fires.get(`${ev.object}|${ev.part}`);
|
|
2212
|
+
const primed = this.primedBurning.delete(`${ev.object}|${ev.part}`);
|
|
2208
2213
|
if (f) {
|
|
2209
2214
|
this.stopFire(`${ev.object}|${ev.part}`);
|
|
2210
2215
|
this.vfx.burst("steam", f.point, [0, 1, 0], 14, 1.2);
|
|
2211
2216
|
}
|
|
2217
|
+
if (f || primed) this.sound("burn_end", f?.point ?? this.rootPoint(ev.object), 0.5);
|
|
2212
2218
|
this.activate(ev.object, ev.part);
|
|
2213
2219
|
this.sound("extinguish", f?.point ?? this.rootPoint(ev.object), 0.6);
|
|
2214
2220
|
break;
|
|
2215
2221
|
}
|
|
2216
2222
|
case "burnout": {
|
|
2217
2223
|
this.stopFire(`${ev.object}|${ev.part}`);
|
|
2224
|
+
this.primedBurning.delete(`${ev.object}|${ev.part}`);
|
|
2225
|
+
this.sound("burn_end", ev.point, 0.5);
|
|
2218
2226
|
this.vfx.burst("ash", ev.point, [0, 1, 0], 16, 1);
|
|
2219
2227
|
this.vfx.burst("smoke", ev.point, [0, 1, 0], 6, 0.8, { color: SMOKE_TONES.grey });
|
|
2220
2228
|
const pv = this.partVis(ev.object, ev.part);
|
|
@@ -2256,6 +2264,7 @@ var Renderer = class {
|
|
|
2256
2264
|
break;
|
|
2257
2265
|
}
|
|
2258
2266
|
case "explode":
|
|
2267
|
+
this.primedBurning.delete(`${ev.object}|${ev.part}`);
|
|
2259
2268
|
this.onExplode(ev);
|
|
2260
2269
|
break;
|
|
2261
2270
|
case "destroyed":
|
|
@@ -2746,6 +2755,7 @@ var Renderer = class {
|
|
|
2746
2755
|
this.fragments.clear();
|
|
2747
2756
|
this.ground.clear();
|
|
2748
2757
|
this.cages.clear();
|
|
2758
|
+
this.primedBurning.clear();
|
|
2749
2759
|
this.vfx.sprites().clear();
|
|
2750
2760
|
this.ownVfx?.world.clear();
|
|
2751
2761
|
}
|
|
@@ -2774,8 +2784,206 @@ var Renderer = class {
|
|
|
2774
2784
|
this.disposed = true;
|
|
2775
2785
|
}
|
|
2776
2786
|
};
|
|
2787
|
+
|
|
2788
|
+
// src/audio/recipes.ts
|
|
2789
|
+
import { DISTANCE_CURVES } from "@adatechnology/game-audio";
|
|
2790
|
+
var ATTACK = 2e-3;
|
|
2791
|
+
var lengthOf = (d, attack) => {
|
|
2792
|
+
if (typeof d === "number") return attack + d;
|
|
2793
|
+
if (Array.isArray(d)) return [attack + d[0], attack + d[1]];
|
|
2794
|
+
return { ...d, add: (d.add ?? 0) + attack };
|
|
2795
|
+
};
|
|
2796
|
+
var envelope = (attack) => [
|
|
2797
|
+
[0, 1e-4, "set", "fixed"],
|
|
2798
|
+
[attack, 1, "exp"],
|
|
2799
|
+
["1d", 1e-4, "exp", "fixed"]
|
|
2800
|
+
];
|
|
2801
|
+
function noise(o) {
|
|
2802
|
+
const a = o.a ?? ATTACK;
|
|
2803
|
+
const over = typeof o.d === "number" ? o.d : 0;
|
|
2804
|
+
return {
|
|
2805
|
+
filters: {
|
|
2806
|
+
mode: "serial",
|
|
2807
|
+
bank: [{ type: o.type ?? "lowpass", frequency: o.f2 === void 0 ? { set: o.f } : { set: o.f, to: o.f2, curve: "exp", over }, q: o.q ?? 0.7 }]
|
|
2808
|
+
},
|
|
2809
|
+
duration: lengthOf(o.d, a),
|
|
2810
|
+
gain: o.vol,
|
|
2811
|
+
...o.delay === void 0 ? {} : { at: o.delay },
|
|
2812
|
+
...o.wet === void 0 ? {} : { wet: o.wet },
|
|
2813
|
+
source: { kind: "noise", offset: "random", offsetScale: 1.5, loop: true },
|
|
2814
|
+
envelope: envelope(a)
|
|
2815
|
+
};
|
|
2816
|
+
}
|
|
2817
|
+
function tone(o) {
|
|
2818
|
+
return {
|
|
2819
|
+
source: { kind: "osc", wave: o.wave ?? "sine", frequency: { from: o.f, to: o.f2 ?? "from", curve: "exp", over: "duration" } },
|
|
2820
|
+
duration: lengthOf(o.d, ATTACK),
|
|
2821
|
+
gain: o.vol,
|
|
2822
|
+
...o.delay === void 0 ? {} : { at: o.delay },
|
|
2823
|
+
...o.wet === void 0 ? {} : { wet: o.wet },
|
|
2824
|
+
envelope: envelope(ATTACK)
|
|
2825
|
+
};
|
|
2826
|
+
}
|
|
2827
|
+
var many = (count, make) => Array.from({ length: count }, make);
|
|
2828
|
+
var scene = (id, layers, line, vars) => ({
|
|
2829
|
+
id,
|
|
2830
|
+
bus: "world",
|
|
2831
|
+
pan: true,
|
|
2832
|
+
layers,
|
|
2833
|
+
falloff: DISTANCE_CURVES.art_scene,
|
|
2834
|
+
...vars ? { vars } : {},
|
|
2835
|
+
sources: [`cena:${line}`]
|
|
2836
|
+
});
|
|
2837
|
+
var boomLayers = (big) => [
|
|
2838
|
+
noise({ f: 1200, f2: 120, d: 1.8, vol: 2, wet: 1.2 }),
|
|
2839
|
+
tone({ f: 65, f2: 24, d: 1, vol: 1.8 }),
|
|
2840
|
+
noise({ type: "highpass", f: 1500, d: 0.2, vol: 0.8 }),
|
|
2841
|
+
...big ? [noise({ f: 500, f2: 90, a: 0.2, d: 2.4, vol: 1.2, wet: 1, delay: 0.15 })] : [],
|
|
2842
|
+
...many(8, () => tone({ f: [2600, 5600], d: 0.05, vol: 0.08, delay: [0.4, 1.6] }))
|
|
2843
|
+
];
|
|
2844
|
+
var SCENE_SOUNDS = [
|
|
2845
|
+
scene(
|
|
2846
|
+
"glass_shatter",
|
|
2847
|
+
[noise({ type: "highpass", f: 2800, d: 0.45, vol: 0.9, wet: 0.5 }), ...many(12, () => tone({ f: [3e3, 7500], d: [0.06, 0.14], vol: 0.18, delay: [0, 0.55] }))],
|
|
2848
|
+
"L1359 glass"
|
|
2849
|
+
),
|
|
2850
|
+
scene(
|
|
2851
|
+
"wood_hit",
|
|
2852
|
+
[noise({ type: "bandpass", f: 850, q: 1, d: 0.25, vol: 0.9, wet: 0.3 }), tone({ f: 210, f2: 90, d: 0.1, vol: 0.6 }), noise({ type: "highpass", f: 2e3, d: 0.04, vol: 0.5 })],
|
|
2853
|
+
"L1360 wood"
|
|
2854
|
+
),
|
|
2855
|
+
scene("thunk", [noise({ type: "bandpass", f: 700, q: 2, d: 0.07, vol: 0.4 })], "L1361 thunk"),
|
|
2856
|
+
scene("ping", [tone({ f: [2600, 3500], f2: 1400, d: 0.14, vol: 0.18, wet: 0.3 })], "L1362 ping"),
|
|
2857
|
+
scene("clang", [tone({ f: [520, 720], f2: 480, d: 0.5, vol: 0.35, wet: 0.4 }), tone({ f: 1370, f2: 1300, d: 0.3, vol: 0.15 }), noise({ type: "highpass", f: 2e3, d: 0.05, vol: 0.5 })], "L1363 clang"),
|
|
2858
|
+
scene("chip", [noise({ type: "bandpass", f: 1600, q: 1.2, d: 0.06, vol: 0.5 })], "L1364 chip"),
|
|
2859
|
+
scene(
|
|
2860
|
+
"crumble",
|
|
2861
|
+
[noise({ f: 900, f2: 200, d: 0.6, vol: 0.9, wet: 0.3 }), ...many(5, () => noise({ type: "bandpass", f: [500, 1400], q: 2, d: 0.05, vol: 0.4, delay: [0.1, 0.5] }))],
|
|
2862
|
+
"L1365 crumble"
|
|
2863
|
+
),
|
|
2864
|
+
// `thud(x, z, v)`: `v` is the `scale` param (default 1)
|
|
2865
|
+
scene("thud", [tone({ f: 75, f2: 38, d: 0.22, vol: { param: "scale", scale: 0.6 } }), noise({ f: 420, d: 0.16, vol: { param: "scale", scale: 0.45 } })], "L1358 thud", { scale: 1 }),
|
|
2866
|
+
// `hiss(x, z, d)`: `seconds` is the param `d` (default 1.2)
|
|
2867
|
+
scene("hiss", [noise({ type: "highpass", f: 3500, a: 0.05, d: { param: "seconds" }, vol: 0.35 })], "L1366 hiss", { seconds: 1.2 }),
|
|
2868
|
+
scene("boom", boomLayers(false), "L1367 boom"),
|
|
2869
|
+
scene("boom_big", boomLayers(true), "L1367 boom (big)"),
|
|
2870
|
+
scene("burst", [noise({ f: 700, f2: 120, d: 0.7, vol: 1.4, wet: 0.5 }), noise({ type: "highpass", f: 3e3, a: 0.05, d: 1.2, vol: 0.4, delay: 0.1 })], "L1357 burst"),
|
|
2871
|
+
scene("crack", [noise({ type: "highpass", f: 1800, d: 0.05, vol: 0.8 }), tone({ f: 420, f2: 180, d: 0.06, vol: 0.4 })], "L1354 crack")
|
|
2872
|
+
];
|
|
2873
|
+
var EXPLOSION_BOOM = {
|
|
2874
|
+
id: "explosion_boom",
|
|
2875
|
+
bus: "world",
|
|
2876
|
+
order: "boom",
|
|
2877
|
+
duration: 1.6,
|
|
2878
|
+
tail: 0.1,
|
|
2879
|
+
layers: [
|
|
2880
|
+
{
|
|
2881
|
+
source: { kind: "osc", wave: "sine", frequency: { from: 70, to: 28, curve: "exp", over: 1.2 } },
|
|
2882
|
+
envelope: [
|
|
2883
|
+
[0, 1, "set"],
|
|
2884
|
+
["1d", 1e-3, "exp", "fixed"]
|
|
2885
|
+
]
|
|
2886
|
+
}
|
|
2887
|
+
],
|
|
2888
|
+
falloff: DISTANCE_CURVES.game_boom,
|
|
2889
|
+
sources: ["jogo:L68278-68285 boom"]
|
|
2890
|
+
};
|
|
2891
|
+
var BURN_LOOP = {
|
|
2892
|
+
id: "burn_loop",
|
|
2893
|
+
bus: "world",
|
|
2894
|
+
order: "chain_loop",
|
|
2895
|
+
source: { kind: "noise", loop: true },
|
|
2896
|
+
filters: { mode: "serial", bank: [{ type: "bandpass", frequency: { set: 1800 }, q: 0.6 }] },
|
|
2897
|
+
volume: 0,
|
|
2898
|
+
sources: ["cena:L1316 fire loop (silent in the page: its gain is never raised)", "sdk: the level while burning"]
|
|
2899
|
+
};
|
|
2900
|
+
var DESTRUCTION_SOUND_BANK = { id: "destruction_three", sounds: [...SCENE_SOUNDS, EXPLOSION_BOOM], loops: [BURN_LOOP] };
|
|
2901
|
+
|
|
2902
|
+
// src/audio/sound.ts
|
|
2903
|
+
import { GAME_SFX_BANK } from "@adatechnology/game-audio";
|
|
2904
|
+
var DESTRUCTION_SOUND_KEYS = {
|
|
2905
|
+
art_scene: {
|
|
2906
|
+
impact_metal: { sound: "clang" },
|
|
2907
|
+
impact_wood: { sound: "wood_hit" },
|
|
2908
|
+
impact_glass: { sound: "ping" },
|
|
2909
|
+
impact_masonry: { sound: "chip" },
|
|
2910
|
+
impact_soft: { sound: "thud" },
|
|
2911
|
+
shatter_glass: { sound: "glass_shatter" },
|
|
2912
|
+
crumble: { sound: "crumble" },
|
|
2913
|
+
splinter: { sound: "crack" },
|
|
2914
|
+
ricochet: { sound: "ping" },
|
|
2915
|
+
unscrew: { sound: "chip" },
|
|
2916
|
+
detach: { sound: "thunk" },
|
|
2917
|
+
ignite: { sound: "hiss", params: { seconds: 0.5 } },
|
|
2918
|
+
extinguish: { sound: "hiss" },
|
|
2919
|
+
melt_sizzle: { sound: "hiss", params: { seconds: 0.6 } },
|
|
2920
|
+
explode: { sound: "boom", above: { volume: 0.9, sound: "boom_big" } }
|
|
2921
|
+
},
|
|
2922
|
+
game: {
|
|
2923
|
+
impact_metal: { sound: "sfx_impact" },
|
|
2924
|
+
impact_wood: { sound: "sfx_wood" },
|
|
2925
|
+
impact_glass: { sound: "sfx_glass" },
|
|
2926
|
+
impact_masonry: { sound: "sfx_impact" },
|
|
2927
|
+
impact_soft: { sound: "sfx_flesh" },
|
|
2928
|
+
shatter_glass: { sound: "sfx_glass" },
|
|
2929
|
+
crumble: { sound: "sfx_impact" },
|
|
2930
|
+
splinter: { sound: "sfx_wood" },
|
|
2931
|
+
explode: { sound: "explosion_boom" }
|
|
2932
|
+
}
|
|
2933
|
+
};
|
|
2934
|
+
var DEFAULT_FIRE = { perFire: 0.05, max: 0.2 };
|
|
2935
|
+
function createDestructionSound(engine, options = {}) {
|
|
2936
|
+
engine.register(DESTRUCTION_SOUND_BANK);
|
|
2937
|
+
engine.register(GAME_SFX_BANK);
|
|
2938
|
+
const fire = { ...DEFAULT_FIRE, ...options.fire };
|
|
2939
|
+
const rules = { ...DESTRUCTION_SOUND_KEYS.art_scene, ...options.style === "game" ? DESTRUCTION_SOUND_KEYS.game : {}, ...options.keys };
|
|
2940
|
+
let loop;
|
|
2941
|
+
let burning = 0;
|
|
2942
|
+
const setFire = () => {
|
|
2943
|
+
if (options.burnLoop === false) return;
|
|
2944
|
+
if (burning <= 0) {
|
|
2945
|
+
loop?.stop();
|
|
2946
|
+
loop = void 0;
|
|
2947
|
+
return;
|
|
2948
|
+
}
|
|
2949
|
+
loop ?? (loop = engine.loop("burn_loop"));
|
|
2950
|
+
loop.set({ volume: Math.min(fire.max, fire.perFire * burning) });
|
|
2951
|
+
};
|
|
2952
|
+
return {
|
|
2953
|
+
onSound(key, point, volume) {
|
|
2954
|
+
if (key === "burn_loop") {
|
|
2955
|
+
burning += 1;
|
|
2956
|
+
setFire();
|
|
2957
|
+
return;
|
|
2958
|
+
}
|
|
2959
|
+
if (key === "burn_end") {
|
|
2960
|
+
if (burning > 0) burning -= 1;
|
|
2961
|
+
setFire();
|
|
2962
|
+
return;
|
|
2963
|
+
}
|
|
2964
|
+
const rule = rules[key];
|
|
2965
|
+
if (!rule) return;
|
|
2966
|
+
const sound = rule.above && volume >= rule.above.volume ? rule.above.sound : rule.sound;
|
|
2967
|
+
engine.play(sound, { position: point, volume: volume * (rule.volumeScale ?? 1), ...rule.params ? { params: rule.params } : {} });
|
|
2968
|
+
},
|
|
2969
|
+
rule: (key) => rules[key] ?? void 0,
|
|
2970
|
+
burning: () => burning,
|
|
2971
|
+
dispose() {
|
|
2972
|
+
loop?.stop();
|
|
2973
|
+
loop = void 0;
|
|
2974
|
+
burning = 0;
|
|
2975
|
+
}
|
|
2976
|
+
};
|
|
2977
|
+
}
|
|
2777
2978
|
export {
|
|
2979
|
+
BURN_LOOP,
|
|
2980
|
+
DEFAULT_FIRE,
|
|
2981
|
+
DESTRUCTION_SOUND_BANK,
|
|
2982
|
+
DESTRUCTION_SOUND_KEYS,
|
|
2983
|
+
EXPLOSION_BOOM,
|
|
2984
|
+
SCENE_SOUNDS,
|
|
2778
2985
|
createDestructionRenderer,
|
|
2986
|
+
createDestructionSound,
|
|
2779
2987
|
heatColor,
|
|
2780
2988
|
specFromObject3D
|
|
2781
2989
|
};
|