@adatechnology/game-destruction-three 0.15.0 → 0.15.2

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 CHANGED
@@ -104,7 +104,7 @@ loose meshes. An invalid range (outside the geometry or empty) throws from `bind
104
104
  |---|---|---|
105
105
  | `dent` | vertices within `dent.radius` pushed in by `depth * (1 - (d/r)^2)^2` (skipped on `low` for meshes over 20k vertices); sparks on metal | `impact_*` |
106
106
  | `hole` | dark disc decal on the surface (and on the exit side of a through hole); a crack star on transparent materials; sparks on metal | `impact_*` |
107
- | `crack` | star of jagged lines, white on glass, dark otherwise | `impact_*` |
107
+ | `crack` | star of jagged white lines on glass (transparent materials) only; an opaque body draws no lines, its damage shows as chips, holes and dents | `impact_*` |
108
108
  | `ricochet` | sparks along the reflected direction | `ricochet` |
109
109
  | `debris` | a burst of the requested kind (`sparks`, `dust`, `shards`, `splinters`, `chips`, `fibers`, `leaves`, `drips`, `ash`, `smoke`, `steam`) | |
110
110
  | `fracture` | part hidden; fragments (boxes, thin irregular prisms for shards) with gravity, ground bounce, settling, sleep and shrink-away; debris burst by style | `shatter_glass`, `crumble`, `splinter`, `impact_*` |
@@ -115,6 +115,7 @@ var GameDestructionThree = (() => {
115
115
  const length = Math.hypot(direction[0], direction[1], direction[2]);
116
116
  return { speed, direction: [direction[0] / length, direction[1] / length, direction[2] / length], distance, falloff };
117
117
  }
118
+ var DEFAULT_BLAST_IMPULSE = { bodyArea: 0.7, lift: 0.15, minSpeed: 0.3, tntPerJoule: 0.24 / 2e5 };
118
119
  var DEFAULT_COST_ALLOCATION_BYTES = 1024 * 1024;
119
120
  var DEFERRED_QUEUE_ID = {
120
121
  DESTRUCTION_EVENTS: "destruction.events",
@@ -13021,7 +13022,6 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
13021
13022
  var rendererCount = 0;
13022
13023
  var COLLAPSE_CLOUD_KG = 1e3;
13023
13024
  var CHIP_DECAL_EDGE = 0.05;
13024
- var OPAQUE_CRACK = 0.1;
13025
13025
  var WOOD_RIM = 1.5;
13026
13026
  var IMPACT_TAGS = ["metal", "glass", "wood"];
13027
13027
  var GLOW_FROM_C = 430;
@@ -13957,14 +13957,11 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
13957
13957
  const pv = b?.parts.get(ev.part);
13958
13958
  if (!b || !pv) return;
13959
13959
  const def = this.world.materials.get(pv.material);
13960
- const wp = new this.THREE.Vector3(ev.worldPoint[0], ev.worldPoint[1], ev.worldPoint[2]);
13961
- const mv = this.nearestMesh(pv, wp);
13962
- if (mv) {
13963
- const glass2 = !!def?.visual?.transparent;
13964
- const own = this.partColor(pv, def) ?? fallbackColor(pv.material, def);
13965
- const color = glass2 ? 15267071 : new this.THREE.Color(own).multiplyScalar(0.45).getHex();
13966
- const length = glass2 ? ev.crack.length : Math.min(ev.crack.length, OPAQUE_CRACK);
13967
- this.visuals.addCrack(mv, wp, this.worldDir(b, ev.crack.normal), ev.crack.rays, length, color, hashNumbers(ev.time, ev.worldPoint[0], ev.worldPoint[1], ev.worldPoint[2]));
13960
+ if (def?.visual?.transparent) {
13961
+ const wp = new this.THREE.Vector3(ev.worldPoint[0], ev.worldPoint[1], ev.worldPoint[2]);
13962
+ const mv = this.nearestMesh(pv, wp);
13963
+ const seed = hashNumbers(ev.time, ev.worldPoint[0], ev.worldPoint[1], ev.worldPoint[2]);
13964
+ if (mv) this.visuals.addCrack(mv, wp, this.worldDir(b, ev.crack.normal), ev.crack.rays, ev.crack.length, 15267071, seed);
13968
13965
  }
13969
13966
  this.impactSound(pv.material, ev.worldPoint, 0.5, ev.blow);
13970
13967
  }
@@ -14544,7 +14541,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
14544
14541
  }
14545
14542
  };
14546
14543
 
14547
- // ../game-audio/dist/chunk-7TLFY7VO.js
14544
+ // ../game-audio/dist/chunk-KBTUANNG.js
14548
14545
  var DISTANCE_CURVES = {
14549
14546
  /** The game's `sfx`: `vol / (1 + d² × 0.004)`, cutoff `/ (1 + d × 0.01)`, silent below 0.01 (jogo L62091–62092, L62101). */
14550
14547
  game_sfx: { model: "inverse_square", k: 4e-3, cutoffK: 0.01, minGain: 0.01 },
@@ -14757,7 +14754,11 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
14757
14754
  ["casing_drop_terra_pistol", 1],
14758
14755
  ["casing_drop_terra_rifle", 1],
14759
14756
  ["casing_drop_terra_shell", 1],
14760
- ["rocket_fire", 2]
14757
+ ["rocket_fire", 2],
14758
+ ["smg_45_auto", 2, "sfx_pistol"],
14759
+ ["weapon_draw", 2],
14760
+ ["suppressor_attach", 3],
14761
+ ["suppressor_detach", 3]
14761
14762
  ]),
14762
14763
  ...entries("explosoes-fogo", [
14763
14764
  ["explosion_grenade", 1, "boom"],
@@ -14771,7 +14772,11 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
14771
14772
  ["fire_loop_large", 1],
14772
14773
  ["fire_extinguish", 2, "hiss"],
14773
14774
  ["gas_leak_hiss", 2],
14774
- ["structure_collapse", 2, "crumble"]
14775
+ ["structure_collapse", 2, "crumble"],
14776
+ ["grenade_bounce", 1],
14777
+ ["c4_plant", 2],
14778
+ ["c4_beep", 2],
14779
+ ["c4_disarm", 2]
14775
14780
  ]),
14776
14781
  ...entries("personagem", [
14777
14782
  ["footstep_concrete_walk", 1, "sfx_step"],
@@ -14787,7 +14792,19 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
14787
14792
  ["blunt_hit", 1],
14788
14793
  ["bite", 1, "sfx_flesh"],
14789
14794
  ["body_fall", 1],
14790
- ["player_hurt", 2]
14795
+ ["player_hurt", 2],
14796
+ ["footstep_tile_walk", 1, "sfx_step"],
14797
+ ["footstep_water_walk", 1, "sfx_step"],
14798
+ ["footstep_grate_walk", 2, "sfx_step"],
14799
+ ["footstep_duct_walk", 3, "sfx_step"],
14800
+ ["ladder_climb", 2],
14801
+ ["swim", 2],
14802
+ ["zombie_groan", 1],
14803
+ ["zombie_alert", 1],
14804
+ ["zombie_attack", 1],
14805
+ ["zombie_pain", 1],
14806
+ ["zombie_claw_hit", 1, "sfx_flesh"],
14807
+ ["zombie_claw_miss", 2]
14791
14808
  ]),
14792
14809
  ...entries("veiculos", [
14793
14810
  ["engine_loop_car", 1],
@@ -14815,7 +14832,8 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
14815
14832
  ["wind_loop", 2],
14816
14833
  ["thunder_near", 2],
14817
14834
  ["thunder_far", 2],
14818
- ["water_splash", 2]
14835
+ ["water_splash", 2],
14836
+ ["helicopter_loop", 3]
14819
14837
  ])
14820
14838
  ];
14821
14839
  var SFX_MATERIALS = [
@@ -14897,6 +14915,60 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
14897
14915
  burst: 20,
14898
14916
  burstSpacing: 0.06
14899
14917
  };
14918
+ var SFX_TIERS = { light: 0, medium: 0.34, heavy: 0.67 };
14919
+ function splitTier(id) {
14920
+ const match = /^(.*)_(light|medium|heavy)$/.exec(id);
14921
+ return match ? { base: match[1], tier: match[2] } : { base: id };
14922
+ }
14923
+ var refsOf = (entries2, baseUrl) => (entries2 ?? []).map((entry) => ({ url: `${baseUrl}${entry.file}` }));
14924
+ function sampleBankFromManifest(manifest, options) {
14925
+ const baseUrl = options.baseUrl ?? "";
14926
+ const samples = [];
14927
+ const tiersOf = /* @__PURE__ */ new Map();
14928
+ for (const sound of manifest.sounds) {
14929
+ const { base, tier } = splitTier(sound.id);
14930
+ if (tier) tiersOf.set(base, [...tiersOf.get(base) ?? [], sound]);
14931
+ }
14932
+ const bases = /* @__PURE__ */ new Map();
14933
+ for (const sound of manifest.sounds) {
14934
+ if (!splitTier(sound.id).tier) bases.set(sound.id, sound);
14935
+ }
14936
+ for (const [base, tiers] of tiersOf) {
14937
+ if (!bases.has(base)) bases.set(base, { id: base, category: tiers[0]?.category ?? "", layers: { close: tiers[0]?.layers.close ?? [] } });
14938
+ }
14939
+ for (const sound of bases.values()) {
14940
+ const numbers = options.sounds?.[sound.id] ?? options.defaults?.(sound);
14941
+ const close = refsOf(sound.layers.close, baseUrl);
14942
+ if (!numbers || close.length === 0) continue;
14943
+ const tiers = (tiersOf.get(sound.id) ?? []).map((tier) => {
14944
+ const name = splitTier(tier.id).tier;
14945
+ const tierFar = refsOf(tier.layers.far, baseUrl);
14946
+ return { name, from: SFX_TIERS[name] ?? 0, close: refsOf(tier.layers.close, baseUrl), ...tierFar.length > 0 ? { far: tierFar } : {} };
14947
+ }).sort((a, b) => a.from - b.from);
14948
+ const far = refsOf(sound.layers.far, baseUrl);
14949
+ const indoor = refsOf(sound.layers.tail_in, baseUrl);
14950
+ const outdoor = refsOf(sound.layers.tail_out, baseUrl);
14951
+ const files = [sound, ...tiersOf.get(sound.id) ?? []].flatMap((entry) => Object.values(entry.layers).flatMap((entries2) => entries2 ?? []));
14952
+ samples.push({
14953
+ id: sound.id,
14954
+ bus: numbers.bus,
14955
+ close,
14956
+ ...far.length > 0 ? { far } : {},
14957
+ ...tiers.length > 0 ? { tiers } : {},
14958
+ ...numbers.crossover ? { crossover: numbers.crossover } : {},
14959
+ ...indoor.length > 0 || outdoor.length > 0 ? { tail: { ...indoor.length > 0 ? { indoor } : {}, ...outdoor.length > 0 ? { outdoor } : {}, ...numbers.tailGain === void 0 ? {} : { gain: numbers.tailGain } } } : {},
14960
+ ...numbers.pitch === void 0 ? {} : { pitch: numbers.pitch },
14961
+ ...numbers.gain === void 0 ? {} : { gain: numbers.gain },
14962
+ ...numbers.falloff ? { falloff: numbers.falloff } : {},
14963
+ ...numbers.cutoffK === void 0 ? {} : { cutoffK: numbers.cutoffK },
14964
+ ...numbers.group ? { group: numbers.group } : {},
14965
+ ...numbers.priority === void 0 ? {} : { priority: numbers.priority },
14966
+ ...numbers.fallback ? { fallback: numbers.fallback } : {},
14967
+ sources: files.map((file) => `${file.file}: ${file.source} ${file.author} ${file.license}`)
14968
+ });
14969
+ }
14970
+ return { id: options.id, samples };
14971
+ }
14900
14972
  var PT = {
14901
14973
  group: "Som",
14902
14974
  name: "Painel de som (arquivos e C1\u2013C10)",
@@ -14904,6 +14976,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
14904
14976
  category: "1 \xB7 Categoria",
14905
14977
  sound: "1 \xB7 Som",
14906
14978
  play: "1 \xB7 \u25B6 Tocar",
14979
+ play_user: "1 \xB7 \u25B6 Tocar o seu",
14907
14980
  material: "2 \xB7 Material",
14908
14981
  blow: "2 \xB7 Golpe",
14909
14982
  strike: "2 \xB7 \u25B6 Tocar golpe",
@@ -14925,6 +14998,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
14925
14998
  approve: "5 \xB7 Aprovo (C10)"
14926
14999
  },
14927
15000
  hints: {
15001
+ play_user: "Toca a sua grava\xE7\xE3o deste som (dos seus pacotes, fora do git), mesmo quando o SDK tem uma melhor e toca na frente.",
14928
15002
  sound: "A = arquivo, S = sintetizado, F = faltando. O que tem arquivo toca o arquivo; o resto toca o som atual.",
14929
15003
  strike: "Toca impact_<material>_<golpe>: o arquivo se existir, sen\xE3o o som atual daquele material.",
14930
15004
  wall: "P\xF5e a parede de casa entre voc\xEA e a fonte: o som fica abafado (C4).",
@@ -14969,9 +15043,10 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
14969
15043
  strengths: { light: "leve", medium: "m\xE9dio", heavy: "forte" },
14970
15044
  states: { file: "A", synth: "S", missing: "F" },
14971
15045
  criteria: { C1: "C1 Sincronia", C2: "C2 Certo p/ a\xE7\xE3o", C3: "C3 Dist\xE2ncia", C4: "C4 Posi\xE7\xE3o", C5: "C5 Varia\xE7\xE3o", C6: "C6 Volume", C7: "C7 Intensidade", C8: "C8 Cauda", C9: "C9 Rajada", C10: "C10 Escuta" },
14972
- metrics: { chosen: "1 \xB7 Escolhido", matrix: "2 \xB7 Matriz", last: "\xDAltimo tocado", ab: "4 \xB7 A \xD7 B", blind: "4 \xB7 X", verdicts: "4 \xB7 Prefer\xEAncias", state: "5 \xB7 Medi\xE7\xE3o", count: "1 \xB7 Cat\xE1logo" },
15046
+ metrics: { source: "1 \xB7 Fonte do que tocou", chosen: "1 \xB7 Escolhido", matrix: "2 \xB7 Matriz", last: "\xDAltimo tocado", ab: "4 \xB7 A \xD7 B", blind: "4 \xB7 X", verdicts: "4 \xB7 Prefer\xEAncias", state: "5 \xB7 Medi\xE7\xE3o", count: "1 \xB7 Cat\xE1logo" },
14973
15047
  run: { idle: "parada", measuring: "medindo\u2026", done: "pronta", failed: "falhou", recording: "gravando\u2026", recorded: "grava\xE7\xE3o baixada" },
14974
15048
  words: { none: "\u2014", hidden: "? (revele)", prefers: "prefere", approved: "aprovado pelo dono" },
15049
+ sources: { sdk: "SDK", user: "seu som", synth: "sintetizado" },
14975
15050
  probe: "Fonte do som",
14976
15051
  wall: "Parede (oclus\xE3o)",
14977
15052
  scenarios: { pipeline: "Arquivo \u2192 decodifica \u2192 toca (round-robin, cauda)", criteria: "Crit\xE9rios C1\u2013C9 no som de calibra\xE7\xE3o", loop: "Loop de arquivo: emenda sem buraco (crossfade)", panel: "Painel: categorias, matriz, A/B e parede" }
@@ -14984,6 +15059,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
14984
15059
  category: "1 \xB7 Category",
14985
15060
  sound: "1 \xB7 Sound",
14986
15061
  play: "1 \xB7 \u25B6 Play",
15062
+ play_user: "1 \xB7 \u25B6 Play yours",
14987
15063
  material: "2 \xB7 Material",
14988
15064
  blow: "2 \xB7 Blow",
14989
15065
  strike: "2 \xB7 \u25B6 Play blow",
@@ -15005,6 +15081,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
15005
15081
  approve: "5 \xB7 Approve (C10)"
15006
15082
  },
15007
15083
  hints: {
15084
+ play_user: "Plays your own take of this sound (from your packs, kept out of git), even where the SDK has a better one that plays first.",
15008
15085
  sound: "A = file, S = synthesized, F = missing. A file plays the file; the rest plays the current sound.",
15009
15086
  strike: "Plays impact_<material>_<blow>: the file if there is one, else the current sound of that material.",
15010
15087
  wall: "Puts the house wall between you and the source: the sound is muffled (C4).",
@@ -15039,69 +15116,16 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
15039
15116
  environments: { indoor: "indoor", outdoor: "outdoor" },
15040
15117
  strengths: { light: "light", medium: "medium", heavy: "heavy" },
15041
15118
  criteria: { C1: "C1 Sync", C2: "C2 Right sound", C3: "C3 Distance", C4: "C4 Position", C5: "C5 Variation", C6: "C6 Level", C7: "C7 Strength", C8: "C8 Tail", C9: "C9 Burst", C10: "C10 Listening" },
15042
- metrics: { chosen: "1 \xB7 Chosen", matrix: "2 \xB7 Matrix", last: "Last played", ab: "4 \xB7 A \xD7 B", blind: "4 \xB7 X", verdicts: "4 \xB7 Preferences", state: "5 \xB7 Measurement", count: "1 \xB7 Catalogue" },
15119
+ metrics: { source: "1 \xB7 Source of what played", chosen: "1 \xB7 Chosen", matrix: "2 \xB7 Matrix", last: "Last played", ab: "4 \xB7 A \xD7 B", blind: "4 \xB7 X", verdicts: "4 \xB7 Preferences", state: "5 \xB7 Measurement", count: "1 \xB7 Catalogue" },
15043
15120
  run: { idle: "idle", measuring: "measuring\u2026", done: "done", failed: "failed", recording: "recording\u2026", recorded: "recording downloaded" },
15044
15121
  words: { none: "\u2014", hidden: "? (reveal)", prefers: "prefers", approved: "approved by the owner" },
15122
+ sources: { sdk: "SDK", user: "your sound", synth: "synthesized" },
15045
15123
  probe: "Sound source",
15046
15124
  wall: "Wall (occlusion)",
15047
15125
  scenarios: { pipeline: "File \u2192 decode \u2192 play (round-robin, tail)", criteria: "Criteria C1\u2013C9 on the calibration sound", loop: "File loop: seamless joins (crossfade)", panel: "Panel: categories, matrix, A/B and wall" }
15048
15126
  };
15049
15127
 
15050
15128
  // ../game-audio/dist/index.js
15051
- var SFX_TIERS = { light: 0, medium: 0.34, heavy: 0.67 };
15052
- function splitTier(id) {
15053
- const match = /^(.*)_(light|medium|heavy)$/.exec(id);
15054
- return match ? { base: match[1], tier: match[2] } : { base: id };
15055
- }
15056
- var refsOf = (entries2, baseUrl) => (entries2 ?? []).map((entry) => ({ url: `${baseUrl}${entry.file}` }));
15057
- function sampleBankFromManifest(manifest, options) {
15058
- const baseUrl = options.baseUrl ?? "";
15059
- const samples = [];
15060
- const tiersOf = /* @__PURE__ */ new Map();
15061
- for (const sound of manifest.sounds) {
15062
- const { base, tier } = splitTier(sound.id);
15063
- if (tier) tiersOf.set(base, [...tiersOf.get(base) ?? [], sound]);
15064
- }
15065
- const bases = /* @__PURE__ */ new Map();
15066
- for (const sound of manifest.sounds) {
15067
- if (!splitTier(sound.id).tier) bases.set(sound.id, sound);
15068
- }
15069
- for (const [base, tiers] of tiersOf) {
15070
- if (!bases.has(base)) bases.set(base, { id: base, category: tiers[0]?.category ?? "", layers: { close: tiers[0]?.layers.close ?? [] } });
15071
- }
15072
- for (const sound of bases.values()) {
15073
- const numbers = options.sounds?.[sound.id] ?? options.defaults?.(sound);
15074
- const close = refsOf(sound.layers.close, baseUrl);
15075
- if (!numbers || close.length === 0) continue;
15076
- const tiers = (tiersOf.get(sound.id) ?? []).map((tier) => {
15077
- const name = splitTier(tier.id).tier;
15078
- const tierFar = refsOf(tier.layers.far, baseUrl);
15079
- return { name, from: SFX_TIERS[name] ?? 0, close: refsOf(tier.layers.close, baseUrl), ...tierFar.length > 0 ? { far: tierFar } : {} };
15080
- }).sort((a, b) => a.from - b.from);
15081
- const far = refsOf(sound.layers.far, baseUrl);
15082
- const indoor = refsOf(sound.layers.tail_in, baseUrl);
15083
- const outdoor = refsOf(sound.layers.tail_out, baseUrl);
15084
- const files = [sound, ...tiersOf.get(sound.id) ?? []].flatMap((entry) => Object.values(entry.layers).flatMap((entries2) => entries2 ?? []));
15085
- samples.push({
15086
- id: sound.id,
15087
- bus: numbers.bus,
15088
- close,
15089
- ...far.length > 0 ? { far } : {},
15090
- ...tiers.length > 0 ? { tiers } : {},
15091
- ...numbers.crossover ? { crossover: numbers.crossover } : {},
15092
- ...indoor.length > 0 || outdoor.length > 0 ? { tail: { ...indoor.length > 0 ? { indoor } : {}, ...outdoor.length > 0 ? { outdoor } : {}, ...numbers.tailGain === void 0 ? {} : { gain: numbers.tailGain } } } : {},
15093
- ...numbers.pitch === void 0 ? {} : { pitch: numbers.pitch },
15094
- ...numbers.gain === void 0 ? {} : { gain: numbers.gain },
15095
- ...numbers.falloff ? { falloff: numbers.falloff } : {},
15096
- ...numbers.cutoffK === void 0 ? {} : { cutoffK: numbers.cutoffK },
15097
- ...numbers.group ? { group: numbers.group } : {},
15098
- ...numbers.priority === void 0 ? {} : { priority: numbers.priority },
15099
- ...numbers.fallback ? { fallback: numbers.fallback } : {},
15100
- sources: files.map((file) => `${file.file}: ${file.source} ${file.author} ${file.license}`)
15101
- });
15102
- }
15103
- return { id: options.id, samples };
15104
- }
15105
15129
  var ATTACK = 2e-3;
15106
15130
  function lengthOf(d, attack) {
15107
15131
  if (typeof d === "number") return attack + d;