@adatechnology/game-destruction-three 0.11.0 → 0.11.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.
@@ -6390,6 +6390,24 @@ var GameDestructionThree = (() => {
6390
6390
  for (const decal2 of this.decals) decal2.on = false;
6391
6391
  this.count = 0;
6392
6392
  }
6393
+ /**
6394
+ * Takes away the marks inside a box: world `center`, `half` extents along the axes of the world `rotation` (a quaternion, x y z w; none means the
6395
+ * world axes). The surface they were on is gone (a brick came out of a wall with its bullet holes). Returns how many went.
6396
+ */
6397
+ clearInside(center, half, rotation = [0, 0, 0, 1]) {
6398
+ const qx = -rotation[0], qy = -rotation[1], qz = -rotation[2], qw = rotation[3];
6399
+ let gone = 0;
6400
+ for (const decal2 of this.decals) {
6401
+ if (!decal2.on) continue;
6402
+ const vx2 = decal2.x - center[0], vy2 = decal2.y - center[1], vz2 = decal2.z - center[2];
6403
+ const tx = 2 * (qy * vz2 - qz * vy2), ty = 2 * (qz * vx2 - qx * vz2), tz = 2 * (qx * vy2 - qy * vx2);
6404
+ const lx = vx2 + qw * tx + (qy * tz - qz * ty), ly = vy2 + qw * ty + (qz * tx - qx * tz), lz = vz2 + qw * tz + (qx * ty - qy * tx);
6405
+ if (Math.abs(lx) > half[0] || Math.abs(ly) > half[1] || Math.abs(lz) > half[2]) continue;
6406
+ decal2.on = false;
6407
+ gone++;
6408
+ }
6409
+ return gone;
6410
+ }
6393
6411
  update(dt) {
6394
6412
  this.count = 0;
6395
6413
  for (const decal2 of this.decals) {
@@ -10111,6 +10129,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
10111
10129
  },
10112
10130
  hitDebris: "chips",
10113
10131
  breakDebris: "dust",
10132
+ visual: { innerColor: 10197652 },
10114
10133
  thermal: {
10115
10134
  conductivity: 0.15,
10116
10135
  heatCapacity: 2.5
@@ -10141,6 +10160,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
10141
10160
  ],
10142
10161
  hitDebris: "chips",
10143
10162
  breakDebris: "dust",
10163
+ visual: { innerColor: 12085567 },
10144
10164
  thermal: {
10145
10165
  conductivity: 0.15,
10146
10166
  heatCapacity: 2.5
@@ -10171,6 +10191,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
10171
10191
  ],
10172
10192
  hitDebris: "dust",
10173
10193
  breakDebris: "dust",
10194
+ visual: { innerColor: 14999507 },
10174
10195
  thermal: {
10175
10196
  conductivity: 0.1,
10176
10197
  heatCapacity: 1.5
@@ -10196,6 +10217,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
10196
10217
  ],
10197
10218
  hitDebris: "chips",
10198
10219
  breakDebris: "dust",
10220
+ visual: { innerColor: 9407364 },
10199
10221
  thermal: {
10200
10222
  conductivity: 0.2,
10201
10223
  heatCapacity: 2.5
@@ -11559,6 +11581,21 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
11559
11581
  d.geometry?.dispose();
11560
11582
  this.decalCount = Math.max(0, this.decalCount - 1);
11561
11583
  }
11584
+ /**
11585
+ * Takes away the decals of a mesh that sit inside a box (world `center`, `half` extents along the axes of the world `rotation`): the surface they
11586
+ * marked is gone (a unit came out of the wall with its bullet holes and spalls).
11587
+ */
11588
+ clearDecals(mv, center, half, rotation) {
11589
+ const inv = rotation.clone().invert();
11590
+ const p = new this.THREE.Vector3();
11591
+ for (let i = mv.decals.length - 1; i >= 0; i--) {
11592
+ const d = mv.decals[i];
11593
+ d.obj.getWorldPosition(p).sub(center).applyQuaternion(inv);
11594
+ if (Math.abs(p.x) > half.x || Math.abs(p.y) > half.y || Math.abs(p.z) > half.z) continue;
11595
+ this.disposeDecal(d);
11596
+ mv.decals.splice(i, 1);
11597
+ }
11598
+ }
11562
11599
  addHole(mv, worldPoint, worldNormal, diameter) {
11563
11600
  const { s, pos, quat: quat2 } = this.decalPose(mv.mesh, worldPoint, worldNormal, 25e-4);
11564
11601
  const work = mv.host ? mv.host.work : mv.work;
@@ -12041,6 +12078,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
12041
12078
  // src/renderer.ts
12042
12079
  var rendererCount = 0;
12043
12080
  var COLLAPSE_CLOUD_KG = 1e3;
12081
+ var CHIP_DECAL_EDGE = 0.05;
12044
12082
  var IMPACT_TAGS = ["metal", "glass", "wood"];
12045
12083
  var GLOW_FROM_C = 430;
12046
12084
  var QUEUE_CAP = 4e3;
@@ -12604,7 +12642,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
12604
12642
  break;
12605
12643
  }
12606
12644
  case "debris":
12607
- this.vfx.burst(ev.kind, ev.point, ev.normal, ev.count, ev.speed > 0 ? ev.speed : DEFAULT_SPEED[ev.kind] ?? 1, this.debrisOptions(ev.kind, ev.object, ev.part));
12645
+ this.vfx.burst(ev.kind, ev.point, ev.normal, ev.count, ev.speed > 0 ? ev.speed : DEFAULT_SPEED[ev.kind] ?? 1, this.debrisOptions(ev.kind, ev.object, ev.part, ev.material));
12608
12646
  break;
12609
12647
  case "fracture":
12610
12648
  this.onFracture(ev);
@@ -12777,10 +12815,11 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
12777
12815
  }
12778
12816
  return def ? fallbackColor(def.id, def) : null;
12779
12817
  }
12780
- debrisOptions(kind, objectId, partId) {
12818
+ debrisOptions(kind, objectId, partId, material) {
12781
12819
  const pv = this.partVis(objectId, partId);
12782
- const def = pv ? this.world.materials.get(pv.material) : void 0;
12820
+ const def = this.world.materials.get(material ?? pv?.material ?? "");
12783
12821
  if (kind === "smoke") return { color: SMOKE_TONES[def?.thermal.smoke ?? "grey"] };
12822
+ if ((kind === "dust" || kind === "chips") && def?.visual?.innerColor !== void 0) return { color: def.visual.innerColor };
12784
12823
  if (kind === "fibers" || kind === "leaves") {
12785
12824
  if (def?.visual?.innerColor !== void 0) return { color: def.visual.innerColor };
12786
12825
  const c = pv ? this.visuals.baseColorHex(pv.meshes[0] ?? {}) : -1;
@@ -12888,8 +12927,11 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
12888
12927
  const mv = this.nearestMesh(pv, wp);
12889
12928
  if (!mv) return;
12890
12929
  const def = this.world.materials.get(pv.material);
12891
- this.playEvent({ kind: "spall", material: this.impactMaterial(def) }, ev.point);
12892
- this.visuals.addSpall(mv, wp, this.faceNormal(mv, wp), Math.sqrt(ev.area / Math.PI), fallbackColor(pv.material, def));
12930
+ const normal = this.faceNormal(mv, wp);
12931
+ const core = def?.visual?.innerColor;
12932
+ if (core !== void 0) this.vfx.burst("chips", ev.point, [normal.x, normal.y, normal.z], 5, 2.5, { color: core });
12933
+ else this.playEvent({ kind: "spall", material: this.impactMaterial(def) }, ev.point);
12934
+ this.visuals.addSpall(mv, wp, normal, Math.sqrt(ev.area / Math.PI), core ?? fallbackColor(pv.material, def));
12893
12935
  }
12894
12936
  /**
12895
12937
  * Stage 2 of a staged part: the unit-sized fragments come out and the part stays drawn (hiding it is what `fracture` does). The opening itself
@@ -12912,8 +12954,9 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
12912
12954
  this.sound(impactKey(def), ev.opening.center, 0.8);
12913
12955
  }
12914
12956
  /**
12915
- * A unit came out of a wall of units: the unit flies as a fragment with a puff of its dust. The gap itself is the drawing's (the house renderer redraws
12916
- * the wall as its courses without that unit); a part drawn as one box keeps its box.
12957
+ * A unit came out of a wall of units: the unit flies as a fragment with a puff of its dust, and the marks drawn on it (bullet holes, spalls, the impact
12958
+ * marks of the effects) go with it. The gap itself is the drawing's (the house renderer cuts the wall where the unit was); a part drawn as one box
12959
+ * keeps its box.
12917
12960
  */
12918
12961
  onChip(ev) {
12919
12962
  const pv = this.partVis(ev.object, ev.part);
@@ -12925,7 +12968,13 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
12925
12968
  const tone = fr.inner && fdef?.visual?.innerColor !== void 0 ? fdef.visual.innerColor : fdef === def ? color : fallbackColor(fr.material, fdef);
12926
12969
  this.fragments.spawn(fr, this.fragments.materialFor(fr.material, tone, false), ev.object, maxAlive);
12927
12970
  }
12928
- if (!this.playEvent({ kind: "spall", material: this.impactMaterial(def) }, ev.center)) this.vfx.burst("dust", ev.center, [0, 1, 0], 6, 0.8, { color });
12971
+ const T = this.THREE;
12972
+ const center = new T.Vector3(ev.center[0], ev.center[1], ev.center[2]);
12973
+ const half = new T.Vector3(ev.size[0] / 2 + CHIP_DECAL_EDGE, ev.size[1] / 2 + CHIP_DECAL_EDGE, ev.size[2] / 2 + CHIP_DECAL_EDGE);
12974
+ const rotation = new T.Quaternion(ev.rotation[0], ev.rotation[1], ev.rotation[2], ev.rotation[3]);
12975
+ for (const part of this.bounds.get(ev.object)?.parts.values() ?? []) for (const mv of part.meshes) this.visuals.clearDecals(mv, center, half, rotation);
12976
+ this.vfx.peekWorkshop()?.decals.clearInside(ev.center, [half.x, half.y, half.z], ev.rotation);
12977
+ this.vfx.burst("dust", ev.center, [0, 1, 0], 8, 0.8, { color });
12929
12978
  this.sound(impactKey(def), ev.center, 0.7);
12930
12979
  }
12931
12980
  onFracture(ev) {