add 3d to srebot (#1351)

This commit is contained in:
NotSoToothless
2026-06-21 08:06:30 -07:00
committed by GitHub
parent 8a084fb644
commit ea5494bce0
2 changed files with 59752 additions and 19 deletions
+20 -19
View File
@@ -18,7 +18,6 @@ const DRONE_COLOR = '#cbd5e1'
const DIRECTION_SAMPLE_MS = 700
const DIRECTION_BLEND = 0.22
const KILL_LINE_WINDOW_MS = 3000
const CAP_INTERP_MAX_GAP_MS = 4000
const FLIP_MAP_TEXTURE_Z = true
function coordsAreValid(c) {
@@ -80,6 +79,7 @@ class ReplayCanvas3D {
this.players = {}
for (const p of data.players || []) this.players[p.id] = p
this.teamWon = data.teamWon
this.winnerSlot = Number(data.winnerSlot) || 0
this._buildEntities()
this._buildCaptureModel()
@@ -466,32 +466,33 @@ class ReplayCanvas3D {
}
}
// Step interpolation, matching the 2D engine's _interpSeries(series, t, true).
_captureValueAt(zone, t) {
if (!zone.cap.length) return 0
if (t <= zone.cap[0][0]) return zone.cap[0][1]
for (let i = 1; i < zone.cap.length; i++) {
const prev = zone.cap[i - 1]
const cur = zone.cap[i]
if (t <= cur[0]) {
const gap = cur[0] - prev[0]
if (gap > CAP_INTERP_MAX_GAP_MS) return prev[1]
const alpha = (t - prev[0]) / Math.max(1, gap)
return THREE.MathUtils.lerp(prev[1], cur[1], THREE.MathUtils.clamp(alpha, 0, 1))
}
const cap = zone.cap
if (!cap.length) return 0
if (t <= cap[0][0]) return cap[0][1]
const last = cap[cap.length - 1]
if (t >= last[0]) return last[1]
for (let i = 1; i < cap.length; i++) {
if (cap[i][0] >= t) return cap[i - 1][1]
}
return zone.cap[zone.cap.length - 1][1]
return last[1]
}
_updateCaptureZones() {
for (const group of this.zoneGroup.children) {
const { zone, fill } = group.userData
if (!zone || !fill) continue
const value = THREE.MathUtils.clamp(this._captureValueAt(zone, this.currentT), -100, 100)
const amount = Math.abs(value) / 100
fill.visible = value !== 0
fill.material.color.set(value > 0 ? LOSE_COLOR : value < 0 ? WIN_COLOR : 0xd8dee9)
fill.material.opacity = value === 0 ? 0 : 0.18 + amount * 0.34
const s = value === 0 ? 0 : Math.sqrt(amount)
// Same logic as the 2D engine: owner is slot 2 if value>0 else slot 1,
// coloured green when it matches the winning slot, red otherwise.
const value = this._captureValueAt(zone, this.currentT)
const frac = Math.min(1, Math.abs(value) / 100)
if (frac <= 0.01) { fill.visible = false; continue }
const ownerSlot = value > 0 ? 2 : 1
fill.visible = true
fill.material.color.set(ownerSlot === this.winnerSlot ? WIN_COLOR : LOSE_COLOR)
fill.material.opacity = 0.18 + frac * 0.34
const s = Math.sqrt(frac)
fill.scale.set(s, s, 1)
}
}
File diff suppressed because one or more lines are too long