From 7c8b016fd0762cc4e01f6630d90f9cacbf199d85 Mon Sep 17 00:00:00 2001 From: agustin-littlehat Date: Sun, 14 Jun 2026 23:13:58 -0300 Subject: [PATCH 1/8] Reduce shootable prewarm latency --- src/runtime/shootables/prewarm.ts | 19 ++++- test/shootablePrewarm.test.mjs | 126 ++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+), 4 deletions(-) create mode 100644 test/shootablePrewarm.test.mjs diff --git a/src/runtime/shootables/prewarm.ts b/src/runtime/shootables/prewarm.ts index 564f821..f7a0deb 100644 --- a/src/runtime/shootables/prewarm.ts +++ b/src/runtime/shootables/prewarm.ts @@ -8,6 +8,9 @@ interface QuakePrewarmShootableState { visible: boolean; } +const QUAKE_SHOOTABLE_PREWARM_MIN_IDLE_MS = 4; +const QUAKE_SHOOTABLE_PREWARM_MAX_DRAIN_PER_CALLBACK = 3; + export interface QuakeShootablePrewarmQueues { animationFrameQueueLength(): number; cancel(): void; @@ -92,8 +95,9 @@ export function createQuakeShootablePrewarmQueues 0) { const entityIndex = prewarmQueue.shift() as number; queuedPrewarmIndexes.delete(entityIndex); @@ -103,7 +107,8 @@ export function createQuakeShootablePrewarmQueues= QUAKE_SHOOTABLE_PREWARM_MAX_DRAIN_PER_CALLBACK || !canContinuePrewarmDrain(deadline)) break; } if (prewarmQueue.length > 0) schedulePrewarmDrain(); } @@ -143,8 +148,9 @@ export function createQuakeShootablePrewarmQueues 0) { const item = animationFramePrewarmQueue.shift(); if (!item) break; @@ -154,11 +160,16 @@ export function createQuakeShootablePrewarmQueues= QUAKE_SHOOTABLE_PREWARM_MAX_DRAIN_PER_CALLBACK || !canContinuePrewarmDrain(deadline)) break; } if (animationFramePrewarmQueue.length > 0) scheduleAnimationFramePrewarmDrain(); } + function canContinuePrewarmDrain(deadline: QuakeIdleDeadline): boolean { + return deadline.didTimeout || deadline.timeRemaining() >= QUAKE_SHOOTABLE_PREWARM_MIN_IDLE_MS; + } + function animationFramePrewarmKey(entityIndex: number, frameIndex: number): string { return `${entityIndex}:${frameIndex}`; } diff --git a/test/shootablePrewarm.test.mjs b/test/shootablePrewarm.test.mjs new file mode 100644 index 0000000..769e2b8 --- /dev/null +++ b/test/shootablePrewarm.test.mjs @@ -0,0 +1,126 @@ +import assert from "node:assert/strict"; +import test from "node:test"; + +import { importTsModule } from "./importTsModule.mjs"; + +const { + createQuakeShootablePrewarmQueues, +} = await importTsModule("src/runtime/shootables/prewarm.ts"); + +test("timed-out shootable prewarm drain mounts the selected small batch", () => { + const previousWindow = globalThis.window; + const idleCallbacks = []; + globalThis.window = { + requestIdleCallback(callback) { + idleCallbacks.push(callback); + return idleCallbacks.length; + }, + cancelIdleCallback() {}, + setTimeout: globalThis.setTimeout.bind(globalThis), + clearTimeout: globalThis.clearTimeout.bind(globalThis), + }; + + try { + const states = new Map([ + [1, shootableState(1)], + [2, shootableState(2)], + [3, shootableState(3)], + ]); + const mounted = []; + const queues = createQuakeShootablePrewarmQueues({ + canPoolAnimationFrame: () => false, + canPrewarmShootable: () => true, + ensureAnimationFrame: () => undefined, + getShootable: (entityIndex) => states.get(entityIndex), + mountShootable: (shootable) => { + shootable.handle = {}; + mounted.push(shootable.entity.index); + }, + setShootableVisible: (shootable, visible) => { + shootable.visible = visible; + }, + timeoutMs: 250, + trimAnimationFrameHandles: () => undefined, + }); + + queues.setDesiredPrewarmIndexes(new Set([1, 2, 3])); + for (const shootable of states.values()) queues.scheduleShootable(shootable); + + assert.equal(idleCallbacks.length, 1); + idleCallbacks[0]({ didTimeout: true, timeRemaining: () => 0 }); + + assert.deepEqual(mounted, [1, 2, 3]); + assert.equal(queues.prewarmQueueLength(), 0); + for (const shootable of states.values()) { + assert.equal(shootable.handle !== null, true); + assert.equal(shootable.visible, false); + } + } finally { + if (previousWindow === undefined) { + delete globalThis.window; + } else { + globalThis.window = previousWindow; + } + } +}); + +test("prewarm drain keeps one-mesh minimum when idle time is exhausted", () => { + const previousWindow = globalThis.window; + const idleCallbacks = []; + globalThis.window = { + requestIdleCallback(callback) { + idleCallbacks.push(callback); + return idleCallbacks.length; + }, + cancelIdleCallback() {}, + setTimeout: globalThis.setTimeout.bind(globalThis), + clearTimeout: globalThis.clearTimeout.bind(globalThis), + }; + + try { + const states = new Map([ + [1, shootableState(1)], + [2, shootableState(2)], + ]); + const mounted = []; + const queues = createQuakeShootablePrewarmQueues({ + canPoolAnimationFrame: () => false, + canPrewarmShootable: () => true, + ensureAnimationFrame: () => undefined, + getShootable: (entityIndex) => states.get(entityIndex), + mountShootable: (shootable) => { + shootable.handle = {}; + mounted.push(shootable.entity.index); + }, + setShootableVisible: (shootable, visible) => { + shootable.visible = visible; + }, + timeoutMs: 250, + trimAnimationFrameHandles: () => undefined, + }); + + queues.setDesiredPrewarmIndexes(new Set([1, 2])); + for (const shootable of states.values()) queues.scheduleShootable(shootable); + + idleCallbacks[0]({ didTimeout: false, timeRemaining: () => 0 }); + + assert.deepEqual(mounted, [1]); + assert.equal(queues.prewarmQueueLength(), 1); + } finally { + if (previousWindow === undefined) { + delete globalThis.window; + } else { + globalThis.window = previousWindow; + } + } +}); + +function shootableState(entityIndex) { + return { + dead: false, + entity: { index: entityIndex }, + frameHandles: new Map(), + handle: null, + visible: false, + }; +} From 5c87df5c0c294969adcfa82a34175022a6b05ae7 Mon Sep 17 00:00:00 2001 From: agustin-littlehat Date: Sun, 14 Jun 2026 23:30:05 -0300 Subject: [PATCH 2/8] Preserve viewmodel bob during ramp sync --- src/runtime/viewmodel.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/runtime/viewmodel.ts b/src/runtime/viewmodel.ts index a1c61b4..31c640e 100644 --- a/src/runtime/viewmodel.ts +++ b/src/runtime/viewmodel.ts @@ -7,7 +7,7 @@ import { worldPositionToPolyCss, } from "@layoutit/polycss"; -import { QUAKE_COLLISION_UNIT_SCALE } from "./constants"; +import { COLLISION_EPSILON, QUAKE_COLLISION_UNIT_SCALE } from "./constants"; import { crossVec3, normalizeVec3 } from "./math"; import { createQuakeViewmodelRasterLayer, @@ -549,6 +549,9 @@ export function createQuakeViewmodelController({ const elapsed = (now - walkBobAt) / 1000; const horizontalDistance = Math.hypot(origin[0] - walkBobOrigin[0], origin[1] - walkBobOrigin[1]); syncWalkBobOrigin(origin, now); + if (horizontalDistance <= COLLISION_EPSILON && elapsed < QUAKE_WEAPON_BOB_MIN_DT) { + return walkBob; + } if ( !Number.isFinite(elapsed) || elapsed <= 0 || From dd75952ea924a16aeb50134eb04c14cf3cae6c4e Mon Sep 17 00:00:00 2001 From: agustin-littlehat Date: Mon, 15 Jun 2026 00:17:48 -0300 Subject: [PATCH 3/8] Use PNG asset for cssQuake logo --- index.html | 1270 +--------------------------------- src/assets/cssquake-logo.png | Bin 16872 -> 9026 bytes 2 files changed, 2 insertions(+), 1268 deletions(-) diff --git a/index.html b/index.html index 4b9c825..44711d4 100644 --- a/index.html +++ b/index.html @@ -3,6 +3,7 @@ +
- +
diff --git a/src/assets/cssquake-logo.png b/src/assets/cssquake-logo.png index 08dc0bd0bbeb774bbc2e6c57195ec2fabf9785e8..6078deb5f4e2dec0d33e856428688d1f16352cf5 100644 GIT binary patch literal 9026 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 literal 16872 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 OMgOshHtONC*Z&{o?W~~y From c520cb9e4ba6354d2068c2d6da24624a5e535546 Mon Sep 17 00:00:00 2001 From: agustin-littlehat Date: Mon, 15 Jun 2026 00:26:56 -0300 Subject: [PATCH 4/8] Use prepared weapon render bundles --- src/prepare/assets.mjs | 128 +++++-- src/quake.css | 9 - src/runtime/debug/statsPanel.ts | 44 +-- src/runtime/viewmodel.ts | 131 ++----- src/runtime/viewmodelRaster.ts | 629 -------------------------------- 5 files changed, 139 insertions(+), 802 deletions(-) delete mode 100644 src/runtime/viewmodelRaster.ts diff --git a/src/prepare/assets.mjs b/src/prepare/assets.mjs index 6dc99bb..2325915 100644 --- a/src/prepare/assets.mjs +++ b/src/prepare/assets.mjs @@ -617,14 +617,12 @@ try { logLevel: "silent", })); - if (!quakePrepareWeaponOnly) { - renderBundleBuilder = await runPrepareStep("render engine init", () => createQuakeRenderBundleBuilder({ - concurrency: quakePrepareModelsOnly - ? normalizedQuakeRenderBundleModelConcurrency() - : normalizedQuakeRenderBundleConcurrency(), - engine: quakeRenderBundleEngine, - })); - } + renderBundleBuilder = await runPrepareStep("render engine init", () => createQuakeRenderBundleBuilder({ + concurrency: quakePrepareModelsOnly + ? normalizedQuakeRenderBundleModelConcurrency() + : normalizedQuakeRenderBundleConcurrency(), + engine: quakeRenderBundleEngine, + })); const { buildQuakeLightstyleOverlayPolygons, @@ -640,7 +638,7 @@ try { const uiAssets = loadQuakeHudAssets(pak, parseQuakePakDirectory); const weaponModelOutputPaths = await runPrepareStep( "weapon models", - () => writeQuakeWeaponModelFiles(uiAssets, sourceProgramFacts), + () => writeQuakeWeaponModelFiles(uiAssets, sourceProgramFacts, renderBundleBuilder), ); for (const outputPath of weaponModelOutputPaths) { console.log(`Wrote ${path.relative(projectRoot, outputPath)}`); @@ -880,7 +878,7 @@ try { const programMetadata = buildQuakeProgramMetadata(uiAssets, sourceProgramFacts); const weaponModelOutputPaths = await runPrepareStep( "weapon models", - () => writeQuakeWeaponModelFiles(uiAssets, sourceProgramFacts), + () => writeQuakeWeaponModelFiles(uiAssets, sourceProgramFacts, renderBundleBuilder), ); await writeFile(progsOutputPath, JSON.stringify(programMetadata)); const modelRenderBundleConcurrency = normalizedQuakeRenderBundleModelConcurrency(); @@ -991,6 +989,7 @@ async function createQuakeRenderBundleBuilder({ concurrency, engine }) { outlineKind, deferAssetWrites = false, primaryAssetMime = "image/avif", + textureQuality = 1, }) { const assetDir = path.join(renderBundleOutputDir, name); await rm(assetDir, { recursive: true, force: true }); @@ -1084,7 +1083,7 @@ async function createQuakeRenderBundleBuilder({ concurrency, engine }) { kind: "polycss-mesh", polycssVersion: polycssPackage.version, textureLighting: "baked", - textureQuality: 1, + textureQuality, meshHtml, ...(styleUrl ? { styleUrl } : {}), ...(styleClassName ? { styleClassName } : {}), @@ -1161,6 +1160,7 @@ async function createQuakeRenderBundleBuilder({ concurrency, engine }) { outlineKind, deferAssetWrites, primaryAssetMime, + textureQuality, }); console.log( `Built render bundle for ${name}: ${result.leafCount} leaves, ` + @@ -3383,8 +3383,8 @@ async function restoreGeneratedTextureFile(urlPath, filePath) { return true; } -async function writeQuakeWeaponModelFiles(assets, sourceProgramFacts) { - const models = buildQuakeWeaponModels(assets, sourceProgramFacts); +async function writeQuakeWeaponModelFiles(assets, sourceProgramFacts, renderBundleBuilder) { + const models = await buildQuakeWeaponModels(assets, sourceProgramFacts, renderBundleBuilder); const primaryModel = models.find((model) => model.source === QUAKE_DEFAULT_WEAPON_VIEWMODEL_PATH) ?? models[0]; const outputPaths = []; await mkdir(path.dirname(weaponOutputPath), { recursive: true }); @@ -3400,9 +3400,11 @@ async function writeQuakeWeaponModelFiles(assets, sourceProgramFacts) { return outputPaths; } -function buildQuakeWeaponModels(assets, sourceProgramFacts) { - return quakePlayerWeaponViewModelPaths(sourceProgramFacts) - .map((modelPath) => buildQuakeWeaponModel(assets, modelPath)); +function buildQuakeWeaponModels(assets, sourceProgramFacts, renderBundleBuilder) { + return Promise.all( + quakePlayerWeaponViewModelPaths(sourceProgramFacts) + .map((modelPath) => buildQuakeWeaponModel(assets, renderBundleBuilder, modelPath)), + ); } function quakePlayerWeaponViewModelPaths(sourceProgramFacts) { @@ -3460,40 +3462,76 @@ function quakeWeaponModelUrlMap(sourceProgramFacts) { return urls; } -function buildQuakeWeaponModel(assets, modelPath = QUAKE_DEFAULT_WEAPON_VIEWMODEL_PATH) { +async function buildQuakeWeaponModel(assets, renderBundleBuilder, modelPath = QUAKE_DEFAULT_WEAPON_VIEWMODEL_PATH) { const model = parseQuakeAliasModel(assets, modelPath); const idleFrame = model.frames[0]; + const fireFrame = model.frames[1] ?? idleFrame; + const textureBrightness = 1.5; if (!idleFrame) throw new Error("Quake weapon viewmodel has no frames."); + const texture = await encodeTextureFileUrl({ + width: model.skinWidth, + height: model.skinHeight, + pixels: quakeAliasPaddedSkin(model), + palette: assets.palette, + brightness: textureBrightness, + }); + const polygons = model.triangles.map((triangle) => { + const uvs = triangle.indices.map((index) => quakeAliasUv(model, triangle, index)); + const isNozzle = isQuakeWeaponNozzlePolygon(uvs); + const frame = isNozzle ? fireFrame : idleFrame; + const vertices = triangle.indices.map((index) => quakeWeaponVertex(frame.vertices[index])); + if (isNozzle) { + return { + vertices, + color: quakeWeaponNozzleColor(vertices), + data: { nozzle: true }, + }; + } + return { + vertices, + texture, + textureAlphaMode: "opaque", + uvs, + }; + }); + const tightenWeaponDom = quakeDomTighteningEnabled("other", false); return { source: modelPath, - rasterModel: buildQuakeWeaponRasterModel(assets, model, modelPath), + renderBundle: await renderBundleBuilder.build({ + bundleName: quakeWeaponRenderBundleName(modelPath), + polygons: anchorQuakeWeaponPolygons(polygons), + extractLeafStyles: true, + tightenAtlasLeaves: tightenWeaponDom, + optimizeAtlasLeafBasis: tightenWeaponDom, + optimizeAtlasLeafHomography: tightenWeaponDom, + }), }; } -function buildQuakeWeaponRasterModel(assets, model, modelPath) { +function quakeWeaponRenderBundleName(modelPath) { + return modelPath === QUAKE_DEFAULT_WEAPON_VIEWMODEL_PATH + ? "w" + : `w/${path.basename(modelPath, path.extname(modelPath)).toLowerCase().replace(/[^a-z0-9_-]+/g, "_")}`; +} + +function quakeWeaponNozzleColor(vertices) { + const x = vertices.reduce((sum, vertex) => sum + vertex[0], 0) / vertices.length; + if (x > 4.3) return "#fff4bf"; + if (x > 4.1) return "#ffd02a"; + if (x > 3.8) return "#ff6a13"; + return "#d71916"; +} + +function anchorQuakeWeaponPolygons(polygons) { const [px, py, pz] = QUAKE_WEAPON_MODEL_PIVOT; - const frames = model.frames.slice(0, 2).map((frame) => ({ - name: frame.name, - vertices: frame.vertices.map((vertex) => { - const [x, y, z] = quakeWeaponVertex(vertex); - return [x - px, y - py, z - pz]; - }), - normalIndices: frame.normalIndices ?? [], + return polygons.map((polygon) => ({ + ...polygon, + vertices: polygon.vertices.map((vertex) => [ + vertex[0] - px, + vertex[1] - py, + vertex[2] - pz, + ]), })); - return { - version: 1, - source: modelPath, - skinWidth: model.skinWidth, - skinHeight: model.skinHeight, - skin: Buffer.from(quakeAliasPaddedSkin(model)).toString("base64"), - palette: Buffer.from(assets.palette).toString("base64"), - triangles: model.triangles.map((triangle) => ({ - facesfront: Boolean(triangle.facesfront), - indices: [...triangle.indices], - uvs: triangle.indices.map((index) => quakeAliasUv(model, triangle, index)), - })), - frames, - }; } async function buildQuakePickupModels(assets, buildBspModel, programMetadata, renderBundleBuilder, options = {}) { @@ -4248,6 +4286,16 @@ function isQuakeEntityFunctionName(name) { name === "worldspawn"; } +function isQuakeWeaponNozzlePolygon(uvs) { + const minU = Math.min(...uvs.map((uv) => uv[0])); + const maxU = Math.max(...uvs.map((uv) => uv[0])); + const maxV = Math.max(...uvs.map((uv) => uv[1])); + return maxV < 0.35 && ( + (minU < 0.22 && maxU < 0.22) || + (minU > 0.5 && maxU < 0.72) + ); +} + function loadQuakeHudAssets(pak, parsePakDirectory) { const entries = new Map(parsePakDirectory(pak).map((entry) => [ entry.name, diff --git a/src/quake.css b/src/quake.css index 4c64a1c..dfbee7d 100644 --- a/src/quake.css +++ b/src/quake.css @@ -103,15 +103,6 @@ body.quake-debug-labels #quake-app .polycss-mesh :is(b, i, s, u)[data-qpid]::aft transform-style: preserve-3d; will-change: transform; } -#quake-viewmodel-raster { - position: absolute; - inset: 0; - width: 100%; - height: 100%; - z-index: 5; - pointer-events: none; - image-rendering: auto; -} #quake-hud { --quake-notify-top: calc(8px + min(45px, calc((100vw - 92px) * 0.1951)) + 12px); --quake-notify-stack-height: 96px; diff --git a/src/runtime/debug/statsPanel.ts b/src/runtime/debug/statsPanel.ts index f745843..1fb8e15 100644 --- a/src/runtime/debug/statsPanel.ts +++ b/src/runtime/debug/statsPanel.ts @@ -1,18 +1,14 @@ interface QuakeStatsPanel { value: HTMLElement; - canvas: HTMLCanvasElement; - context: CanvasRenderingContext2D; + bars: HTMLElement[]; history: number[]; max: number; label: string; - fg: string; } const FPS_SAMPLE_MS = 1000; const MS_SAMPLE_MS = 500; const STATS_GRAPH_COLUMNS = 40; -const STATS_GRAPH_COLUMN_WIDTH = 2; -const STATS_GRAPH_WIDTH = STATS_GRAPH_COLUMNS * STATS_GRAPH_COLUMN_WIDTH; const STATS_GRAPH_HEIGHT = 30; const STATS_OVERLAY_BACKGROUND = "#050302"; const STATS_GRAPH_BACKGROUND = "#050302"; @@ -102,22 +98,25 @@ function createStatsPanel(label: string, fg: string, bg: string, max: number): Q const graph = document.createElement("div"); graph.style.position = "relative"; + graph.style.display = "grid"; + graph.style.gridTemplateColumns = `repeat(${STATS_GRAPH_COLUMNS}, 1fr)`; + graph.style.alignItems = "end"; + graph.style.gap = "0"; graph.style.height = `${STATS_GRAPH_HEIGHT}px`; graph.style.background = STATS_GRAPH_BACKGROUND; graph.style.overflow = "hidden"; - const canvas = document.createElement("canvas"); - canvas.width = STATS_GRAPH_WIDTH; - canvas.height = STATS_GRAPH_HEIGHT; - canvas.style.display = "block"; - canvas.style.width = "100%"; - canvas.style.height = `${STATS_GRAPH_HEIGHT}px`; - canvas.style.imageRendering = "pixelated"; - const context = canvas.getContext("2d"); - if (!context) throw new Error("Stats panel canvas context unavailable."); - graph.appendChild(canvas); + const bars = Array.from({ length: STATS_GRAPH_COLUMNS }, () => { + const bar = document.createElement("span"); + bar.style.display = "block"; + bar.style.width = "100%"; + bar.style.height = "0"; + bar.style.background = fg; + graph.appendChild(bar); + return bar; + }); element.append(value, graph); - const panel = { element, value, canvas, context, history: [], max, label, fg }; + const panel = { element, value, bars, history: [], max, label }; drawStatsPanelGraph(panel); return panel; } @@ -131,17 +130,10 @@ function updateStatsPanel(panel: QuakeStatsPanel, value: number): void { } function drawStatsPanelGraph(panel: QuakeStatsPanel): void { - const { context } = panel; - context.clearRect(0, 0, STATS_GRAPH_WIDTH, STATS_GRAPH_HEIGHT); - context.fillStyle = STATS_GRAPH_BACKGROUND; - context.fillRect(0, 0, STATS_GRAPH_WIDTH, STATS_GRAPH_HEIGHT); - context.fillStyle = panel.fg; const offset = STATS_GRAPH_COLUMNS - panel.history.length; - for (let index = 0; index < panel.history.length; index++) { - const value = panel.history[index] ?? 0; + for (let index = 0; index < panel.bars.length; index++) { + const value = index >= offset ? panel.history[index - offset] ?? 0 : 0; const height = Math.round((value / panel.max) * STATS_GRAPH_HEIGHT); - const x = (offset + index) * STATS_GRAPH_COLUMN_WIDTH; - const y = STATS_GRAPH_HEIGHT - height; - context.fillRect(x, y, STATS_GRAPH_COLUMN_WIDTH, height); + panel.bars[index].style.height = `${height}px`; } } diff --git a/src/runtime/viewmodel.ts b/src/runtime/viewmodel.ts index 31c640e..004f811 100644 --- a/src/runtime/viewmodel.ts +++ b/src/runtime/viewmodel.ts @@ -2,19 +2,16 @@ import { buildPolySceneTransform, polyCssDistanceToWorld, type PolyFirstPersonControlsHandle, + type PolyMeshHandle, type PolySceneHandle, type Vec3, worldPositionToPolyCss, } from "@layoutit/polycss"; +import type { QuakePreparedRenderBundle } from "../prepare/scene"; import { COLLISION_EPSILON, QUAKE_COLLISION_UNIT_SCALE } from "./constants"; import { crossVec3, normalizeVec3 } from "./math"; -import { - createQuakeViewmodelRasterLayer, - type QuakeViewmodelRasterLayer, - type QuakeViewmodelRasterModel, - type QuakeViewmodelRasterPostTransform, -} from "./viewmodelRaster"; +import { mountQuakeRenderBundleMesh, stripPolyMeshMetadata } from "./renderBundleMesh"; export interface QuakeViewmodelController { mount(model: QuakeViewmodelModel): void; @@ -57,15 +54,6 @@ export interface QuakeViewmodelTuning { screenYOffsetPx?: number; screenScaleX?: number; screenScaleY?: number; - rasterPostOriginXPx?: number; - rasterPostOriginYPx?: number; - rasterPostTranslateXPx?: number; - rasterPostTranslateYPx?: number; - rasterPostRotateDeg?: number; - rasterPostSkewXDeg?: number; - rasterPostSkewYDeg?: number; - rasterPostScaleX?: number; - rasterPostScaleY?: number; perspectiveScale?: number; stageOffsetPx?: number; perspectiveOriginXOffsetPx?: number; @@ -76,7 +64,7 @@ export type QuakeResolvedViewmodelTuning = Required; export interface QuakeViewmodelModel { source: string; - rasterModel: QuakeViewmodelRasterModel; + renderBundle: QuakePreparedRenderBundle; } export interface QuakeViewmodelDebugSnapshot { @@ -193,15 +181,6 @@ const QUAKE_WEAPON_DEFAULT_TUNING: QuakeResolvedViewmodelTuning = { screenYOffsetPx: 12.5, screenScaleX: 0.98, screenScaleY: 1, - rasterPostOriginXPx: 640, - rasterPostOriginYPx: 360, - rasterPostTranslateXPx: 0, - rasterPostTranslateYPx: 0, - rasterPostRotateDeg: 0, - rasterPostSkewXDeg: 0, - rasterPostSkewYDeg: 0, - rasterPostScaleX: 1, - rasterPostScaleY: 1, perspectiveScale: 0.8, stageOffsetPx: QUAKE_WEAPON_REFERENCE_STAGE_OFFSET_PX, perspectiveOriginXOffsetPx: 0, @@ -214,15 +193,6 @@ const QUAKE_WEAPON_MODEL_TUNING_OVERRIDES: Record screenYOffsetPx: 15, screenScaleX: 0.866, screenScaleY: 0.972, - // The axe head exposes a small residual canvas/vkQuake alias projection drift. - rasterPostOriginXPx: 767, - rasterPostOriginYPx: 455, - rasterPostTranslateXPx: -1.3, - rasterPostTranslateYPx: 1.1, - rasterPostRotateDeg: -1.5, - rasterPostSkewYDeg: -6.5, - rasterPostScaleX: 0.97, - rasterPostScaleY: 1.03, }, "progs/v_shot2.mdl": { screenScaleX: 1.149, @@ -247,12 +217,6 @@ const QUAKE_WEAPON_MODEL_TUNING_OVERRIDES: Record "progs/v_light.mdl": { screenScaleX: 0.916, screenScaleY: 0.922, - rasterPostOriginXPx: 637, - rasterPostOriginYPx: 508, - rasterPostTranslateXPx: 0.6, - rasterPostTranslateYPx: 1.8, - rasterPostScaleX: 0.967, - rasterPostScaleY: 0.995, }, }; const QUAKE_WEAPON_SCREEN_ROT_X = 90; @@ -283,7 +247,7 @@ export function createQuakeViewmodelController({ layer, }: QuakeViewmodelControllerOptions): QuakeViewmodelController { const stage = layer ? createQuakeViewmodelStage(layer) : null; - const raster: QuakeViewmodelRasterLayer | null = layer ? createQuakeViewmodelRasterLayer(layer) : null; + let handle: PolyMeshHandle | null = null; let carrier: HTMLElement | null = null; let viewportSyncFrame = 0; let cachedLayerScale = 1; @@ -319,13 +283,17 @@ export function createQuakeViewmodelController({ clearFireAnimation(); resetWalkBob(); invalidateViewportLayer(); - carrier?.remove(); + handle?.remove(); + handle = null; + carrier = null; if (!stage) throw new Error("Quake viewmodel mount requires a viewmodel stage."); - carrier = createQuakeViewmodelTransformCarrier(stage); + handle = mountQuakeRenderBundleMesh(stage, model.renderBundle); + carrier = handle.element; + carrier.classList.add("viewmodel", "quake-viewmodel-transform"); + stripPolyMeshMetadata(carrier); appliedLocalTransform = ""; - if (!raster) throw new Error("Quake viewmodel raster mount requires a viewmodel layer."); - raster.mount(model.rasterModel); mountedSource = source; + prepareNozzleLeaves(); syncTransform(); setNozzleVisible(false); } @@ -333,9 +301,9 @@ export function createQuakeViewmodelController({ function remove(): void { clearFireAnimation(); resetWalkBob(); - carrier?.remove(); + handle?.remove(); + handle = null; carrier = null; - raster?.remove(); appliedLocalTransform = ""; mountedSource = null; } @@ -440,7 +408,6 @@ export function createQuakeViewmodelController({ const weapon = weaponTransform(origin, rotX, rotY, bob); syncCarrierTransform(weapon); syncLayer(); - syncRasterLayer(rotY); } function queueViewportSync(): void { @@ -513,29 +480,29 @@ export function createQuakeViewmodelController({ } function setNozzleVisible(visible: boolean): void { - setWeaponFrameIndex(visible ? 1 : 0); + if (!carrier) return; + carrier.classList.toggle("quake-nozzle-visible", visible); } function setWeaponFrameIndex(frameIndex: number): void { - raster?.setFrameIndex(frameIndex); + setNozzleVisible(frameIndex > 0); } - function syncRasterLayer(rotY: number): void { - if (!raster || !layer || !stage || !carrier) return; - const currentTuning = activeTuning(); - raster.sync({ - width: QUAKE_WEAPON_REFERENCE_VIEWPORT_WIDTH_PX, - height: QUAKE_WEAPON_REFERENCE_VIEWPORT_HEIGHT_PX, - stageLeftPx: QUAKE_WEAPON_REFERENCE_VIEWPORT_WIDTH_PX / 2, - stageTopPx: QUAKE_WEAPON_REFERENCE_VIEWPORT_HEIGHT_PX / 2 + currentTuning.stageOffsetPx, - stageTransform: stage.style.transform, - meshTransform: carrier.style.transform, - perspectivePx: weaponPerspectivePx(), - perspectiveOriginX: QUAKE_WEAPON_REFERENCE_VIEWPORT_WIDTH_PX / 2 + currentTuning.perspectiveOriginXOffsetPx, - perspectiveOriginY: QUAKE_WEAPON_REFERENCE_VIEWPORT_HEIGHT_PX / 2 + currentTuning.perspectiveOriginYOffsetPx, - rotY, - postTransform: weaponRasterPostTransform(currentTuning), - }); + function prepareNozzleLeaves(): void { + if (!carrier) return; + let nozzleGroup = carrier.querySelector(".quake-nozzle-group"); + if (!nozzleGroup) { + nozzleGroup = carrier.ownerDocument.createElement("span"); + nozzleGroup.className = "quake-nozzle-group"; + } + for (const leaf of carrier.querySelectorAll("[data-weapon]")) { + leaf.removeAttribute("data-weapon"); + } + for (const leaf of carrier.querySelectorAll("[data-nozzle]")) { + nozzleGroup.appendChild(leaf); + leaf.removeAttribute("data-nozzle"); + } + carrier.appendChild(nozzleGroup); } function updateWalkBob(origin: Vec3): number { @@ -805,31 +772,6 @@ function weaponLocalTransform(tuning: QuakeResolvedViewmodelTuning): string { ].filter(Boolean).join(" "); } -function weaponRasterPostTransform(tuning: QuakeResolvedViewmodelTuning): QuakeViewmodelRasterPostTransform | null { - if ( - Math.abs(tuning.rasterPostTranslateXPx) <= 0.001 && - Math.abs(tuning.rasterPostTranslateYPx) <= 0.001 && - Math.abs(tuning.rasterPostRotateDeg) <= 0.001 && - Math.abs(tuning.rasterPostSkewXDeg) <= 0.001 && - Math.abs(tuning.rasterPostSkewYDeg) <= 0.001 && - Math.abs(tuning.rasterPostScaleX - 1) <= 0.001 && - Math.abs(tuning.rasterPostScaleY - 1) <= 0.001 - ) { - return null; - } - return { - originX: tuning.rasterPostOriginXPx, - originY: tuning.rasterPostOriginYPx, - translateX: tuning.rasterPostTranslateXPx, - translateY: tuning.rasterPostTranslateYPx, - rotateDeg: tuning.rasterPostRotateDeg, - skewXDeg: tuning.rasterPostSkewXDeg, - skewYDeg: tuning.rasterPostSkewYDeg, - scaleX: tuning.rasterPostScaleX, - scaleY: tuning.rasterPostScaleY, - }; -} - function weaponTransformCss(weapon: QuakeViewmodelDebugSnapshot["weapon"]): string { const [x, y, z] = weapon.position; const cssPosition = worldPositionToPolyCss([x, y, z]); @@ -964,13 +906,6 @@ function createQuakeViewmodelStage(layer: HTMLElement): HTMLElement { return stage; } -function createQuakeViewmodelTransformCarrier(stage: HTMLElement): HTMLElement { - const carrier = stage.ownerDocument.createElement("div"); - carrier.className = "polycss-mesh viewmodel quake-viewmodel-transform"; - stage.appendChild(carrier); - return carrier; -} - function forwardDirection(rotX: number, rotY: number): Vec3 { const rx = (rotX * Math.PI) / 180; const ry = (rotY * Math.PI) / 180; diff --git a/src/runtime/viewmodelRaster.ts b/src/runtime/viewmodelRaster.ts deleted file mode 100644 index 03f2fa8..0000000 --- a/src/runtime/viewmodelRaster.ts +++ /dev/null @@ -1,629 +0,0 @@ -import { type Vec3, worldPositionToPolyCss } from "@layoutit/polycss"; - -export interface QuakeViewmodelRasterModel { - version: 1; - source: string; - skinWidth: number; - skinHeight: number; - skin: string; - palette: string; - triangles: QuakeViewmodelRasterTriangle[]; - frames: QuakeViewmodelRasterFrame[]; -} - -export interface QuakeViewmodelRasterTriangle { - facesfront: boolean; - indices: [number, number, number]; - uvs: [number, number][]; -} - -export interface QuakeViewmodelRasterFrame { - name: string; - vertices: Vec3[]; - normalIndices: number[]; -} - -export interface QuakeViewmodelRasterSyncState { - width: number; - height: number; - stageLeftPx: number; - stageTopPx: number; - stageTransform: string; - meshTransform: string; - perspectivePx: number; - perspectiveOriginX: number; - perspectiveOriginY: number; - rotY: number; - postTransform?: QuakeViewmodelRasterPostTransform | null; -} - -export interface QuakeViewmodelRasterPostTransform { - originX: number; - originY: number; - translateX: number; - translateY: number; - rotateDeg: number; - skewXDeg: number; - skewYDeg: number; - scaleX: number; - scaleY: number; -} - -export interface QuakeViewmodelRasterLayer { - mount(model: QuakeViewmodelRasterModel): void; - remove(): void; - sync(state: QuakeViewmodelRasterSyncState): void; - setFrameIndex(frameIndex: number): void; -} - -interface DecodedQuakeViewmodelRasterModel { - source: string; - skinWidth: number; - skinHeight: number; - skin: Uint8Array; - palette: Uint8Array; - skinR: Uint8Array; - skinG: Uint8Array; - skinB: Uint8Array; - skinFullbright: Uint8Array; - triangles: QuakeViewmodelRasterTriangle[]; - frames: QuakeViewmodelRasterFrame[]; -} - -interface ProjectedVertex { - x: number; - y: number; - z: number; - q: number; - shade: number; -} - -interface ProjectedTriangle { - triangle: QuakeViewmodelRasterTriangle; - vertices: [ProjectedVertex, ProjectedVertex, ProjectedVertex]; -} - -interface RasterDirtyRect { - x: number; - y: number; - width: number; - height: number; -} - -interface RasterBuffer { - image: ImageData; - zBuffer: Float32Array; - width: number; - height: number; -} - -const QUAKE_ALIAS_VIEWMODEL_LIGHT_COLOR = 96 / 200; -const QUAKE_ALIAS_SHADER_LIGHT_SCALE = 2; -const QUAKE_RASTER_POSTPROCESS_GAMMA = 0.9; -const QUAKE_RASTER_POSTPROCESS_CONTRAST = 1.4; -const QUAKE_RASTER_MIN_DENOMINATOR = 1e-3; -const QUAKE_RASTER_EDGE_EPSILON = 1e-5; -const QUAKE_ALIAS_NORMALS = decodeAliasNormals([ - "-0.525731,0.000000,0.850651,-0.442863,0.238856,0.864188,-0.295242,0.000000,0.955423,-0.309017,", - "0.500000,0.809017,-0.162460,0.262866,0.951056,0.000000,0.000000,1.000000,0.000000,0.850651,0.5", - "25731,-0.147621,0.716567,0.681718,0.147621,0.716567,0.681718,0.000000,0.525731,0.850651,0.3090", - "17,0.500000,0.809017,0.525731,0.000000,0.850651,0.295242,0.000000,0.955423,0.442863,0.238856,0", - ".864188,0.162460,0.262866,0.951056,-0.681718,0.147621,0.716567,-0.809017,0.309017,0.500000,-0.", - "587785,0.425325,0.688191,-0.850651,0.525731,0.000000,-0.864188,0.442863,0.238856,-0.716567,0.6", - "81718,0.147621,-0.688191,0.587785,0.425325,-0.500000,0.809017,0.309017,-0.238856,0.864188,0.44", - "2863,-0.425325,0.688191,0.587785,-0.716567,0.681718,-0.147621,-0.500000,0.809017,-0.309017,-0.", - "525731,0.850651,0.000000,0.000000,0.850651,-0.525731,-0.238856,0.864188,-0.442863,0.000000,0.9", - "55423,-0.295242,-0.262866,0.951056,-0.162460,0.000000,1.000000,0.000000,0.000000,0.955423,0.29", - "5242,-0.262866,0.951056,0.162460,0.238856,0.864188,0.442863,0.262866,0.951056,0.162460,0.50000", - "0,0.809017,0.309017,0.238856,0.864188,-0.442863,0.262866,0.951056,-0.162460,0.500000,0.809017,", - "-0.309017,0.850651,0.525731,0.000000,0.716567,0.681718,0.147621,0.716567,0.681718,-0.147621,0.", - "525731,0.850651,0.000000,0.425325,0.688191,0.587785,0.864188,0.442863,0.238856,0.688191,0.5877", - "85,0.425325,0.809017,0.309017,0.500000,0.681718,0.147621,0.716567,0.587785,0.425325,0.688191,0", - ".955423,0.295242,0.000000,1.000000,0.000000,0.000000,0.951056,0.162460,0.262866,0.850651,-0.52", - "5731,0.000000,0.955423,-0.295242,0.000000,0.864188,-0.442863,0.238856,0.951056,-0.162460,0.262", - "866,0.809017,-0.309017,0.500000,0.681718,-0.147621,0.716567,0.850651,0.000000,0.525731,0.86418", - "8,0.442863,-0.238856,0.809017,0.309017,-0.500000,0.951056,0.162460,-0.262866,0.525731,0.000000", - ",-0.850651,0.681718,0.147621,-0.716567,0.681718,-0.147621,-0.716567,0.850651,0.000000,-0.52573", - "1,0.809017,-0.309017,-0.500000,0.864188,-0.442863,-0.238856,0.951056,-0.162460,-0.262866,0.147", - "621,0.716567,-0.681718,0.309017,0.500000,-0.809017,0.425325,0.688191,-0.587785,0.442863,0.2388", - "56,-0.864188,0.587785,0.425325,-0.688191,0.688191,0.587785,-0.425325,-0.147621,0.716567,-0.681", - "718,-0.309017,0.500000,-0.809017,0.000000,0.525731,-0.850651,-0.525731,0.000000,-0.850651,-0.4", - "42863,0.238856,-0.864188,-0.295242,0.000000,-0.955423,-0.162460,0.262866,-0.951056,0.000000,0.", - "000000,-1.000000,0.295242,0.000000,-0.955423,0.162460,0.262866,-0.951056,-0.442863,-0.238856,-", - "0.864188,-0.309017,-0.500000,-0.809017,-0.162460,-0.262866,-0.951056,0.000000,-0.850651,-0.525", - "731,-0.147621,-0.716567,-0.681718,0.147621,-0.716567,-0.681718,0.000000,-0.525731,-0.850651,0.", - "309017,-0.500000,-0.809017,0.442863,-0.238856,-0.864188,0.162460,-0.262866,-0.951056,0.238856,", - "-0.864188,-0.442863,0.500000,-0.809017,-0.309017,0.425325,-0.688191,-0.587785,0.716567,-0.6817", - "18,-0.147621,0.688191,-0.587785,-0.425325,0.587785,-0.425325,-0.688191,0.000000,-0.955423,-0.2", - "95242,0.000000,-1.000000,0.000000,0.262866,-0.951056,-0.162460,0.000000,-0.850651,0.525731,0.0", - "00000,-0.955423,0.295242,0.238856,-0.864188,0.442863,0.262866,-0.951056,0.162460,0.500000,-0.8", - "09017,0.309017,0.716567,-0.681718,0.147621,0.525731,-0.850651,0.000000,-0.238856,-0.864188,-0.", - "442863,-0.500000,-0.809017,-0.309017,-0.262866,-0.951056,-0.162460,-0.850651,-0.525731,0.00000", - "0,-0.716567,-0.681718,-0.147621,-0.716567,-0.681718,0.147621,-0.525731,-0.850651,0.000000,-0.5", - "00000,-0.809017,0.309017,-0.238856,-0.864188,0.442863,-0.262866,-0.951056,0.162460,-0.864188,-", - "0.442863,0.238856,-0.809017,-0.309017,0.500000,-0.688191,-0.587785,0.425325,-0.681718,-0.14762", - "1,0.716567,-0.442863,-0.238856,0.864188,-0.587785,-0.425325,0.688191,-0.309017,-0.500000,0.809", - "017,-0.147621,-0.716567,0.681718,-0.425325,-0.688191,0.587785,-0.162460,-0.262866,0.951056,0.4", - "42863,-0.238856,0.864188,0.162460,-0.262866,0.951056,0.309017,-0.500000,0.809017,0.147621,-0.7", - "16567,0.681718,0.000000,-0.525731,0.850651,0.425325,-0.688191,0.587785,0.587785,-0.425325,0.68", - "8191,0.688191,-0.587785,0.425325,-0.955423,0.295242,0.000000,-0.951056,0.162460,0.262866,-1.00", - "0000,0.000000,0.000000,-0.850651,0.000000,0.525731,-0.955423,-0.295242,0.000000,-0.951056,-0.1", - "62460,0.262866,-0.864188,0.442863,-0.238856,-0.951056,0.162460,-0.262866,-0.809017,0.309017,-0", - ".500000,-0.864188,-0.442863,-0.238856,-0.951056,-0.162460,-0.262866,-0.809017,-0.309017,-0.500", - "000,-0.681718,0.147621,-0.716567,-0.681718,-0.147621,-0.716567,-0.850651,0.000000,-0.525731,-0", - ".688191,0.587785,-0.425325,-0.587785,0.425325,-0.688191,-0.425325,0.688191,-0.587785,-0.425325", - ",-0.688191,-0.587785,-0.587785,-0.425325,-0.688191,-0.688191,-0.587785,-0.425325", -].join("")); - -export function createQuakeViewmodelRasterLayer(layer: HTMLElement): QuakeViewmodelRasterLayer { - const canvas = layer.ownerDocument.createElement("canvas"); - const context = canvas.getContext("2d"); - let decoded: DecodedQuakeViewmodelRasterModel | null = null; - let currentState: QuakeViewmodelRasterSyncState | null = null; - let rasterBuffer: RasterBuffer | null = null; - let frameIndex = 0; - - canvas.id = "quake-viewmodel-raster"; - canvas.width = 1; - canvas.height = 1; - canvas.style.left = "0px"; - canvas.style.top = "0px"; - canvas.style.right = "auto"; - canvas.style.bottom = "auto"; - canvas.style.width = "1px"; - canvas.style.height = "1px"; - - function mount(model: QuakeViewmodelRasterModel): void { - if (!context) throw new Error("Quake viewmodel raster requires a 2D canvas context."); - decoded = decodeRasterModel(model); - frameIndex = 0; - if (canvas.parentElement !== layer) layer.appendChild(canvas); - layer.classList.add("quake-viewmodel-raster-active"); - if (currentState) draw(currentState); - } - - function remove(): void { - decoded = null; - currentState = null; - frameIndex = 0; - layer.classList.remove("quake-viewmodel-raster-active"); - canvas.remove(); - } - - function sync(state: QuakeViewmodelRasterSyncState): void { - currentState = state; - if (!decoded || !context || canvas.parentElement !== layer) return; - draw(state); - } - - function setFrameIndex(nextFrameIndex: number): void { - frameIndex = Math.max(0, Math.floor(nextFrameIndex)); - if (currentState) draw(currentState); - } - - function draw(state: QuakeViewmodelRasterSyncState): void { - if (!decoded || !context) return; - const width = Math.max(1, Math.round(state.width)); - const height = Math.max(1, Math.round(state.height)); - - let meshMatrix: DOMMatrix; - let stageMatrix: DOMMatrix; - try { - meshMatrix = cssTransformMatrix(state.meshTransform); - stageMatrix = cssTransformMatrix(state.stageTransform); - } catch { - context.clearRect(0, 0, canvas.width, canvas.height); - return; - } - - const frame = decoded.frames[Math.min(frameIndex, decoded.frames.length - 1)] ?? decoded.frames[0]; - if (!frame) { - context.clearRect(0, 0, canvas.width, canvas.height); - return; - } - const shadeVector = quakeAliasShadeVector(state.rotY); - const projectedVertices: (ProjectedVertex | null)[] = new Array(frame.vertices.length); - for (let vertexIndex = 0; vertexIndex < frame.vertices.length; vertexIndex++) { - projectedVertices[vertexIndex] = projectVertex( - frame.vertices[vertexIndex], - meshMatrix, - stageMatrix, - state, - quakeAliasVertexLight(frame.normalIndices[vertexIndex], shadeVector), - ); - } - - const projectedTriangles: ProjectedTriangle[] = []; - let minX = Infinity; - let minY = Infinity; - let maxX = -Infinity; - let maxY = -Infinity; - for (let triangleIndex = 0; triangleIndex < decoded.triangles.length; triangleIndex++) { - const triangle = decoded.triangles[triangleIndex]; - const v0 = projectedVertices[triangle.indices[0]]; - const v1 = projectedVertices[triangle.indices[1]]; - const v2 = projectedVertices[triangle.indices[2]]; - if (!v0 || !v1 || !v2) continue; - const vertices: [ProjectedVertex, ProjectedVertex, ProjectedVertex] = [v0, v1, v2]; - projectedTriangles.push({ triangle, vertices }); - for (const vertex of vertices) { - minX = Math.min(minX, vertex.x); - minY = Math.min(minY, vertex.y); - maxX = Math.max(maxX, vertex.x); - maxY = Math.max(maxY, vertex.y); - } - } - - const dirtyRect = rasterDirtyRect(minX, minY, maxX, maxY, width, height); - if (!dirtyRect) { - context.clearRect(0, 0, canvas.width, canvas.height); - return; - } - - rasterBuffer = rasterBufferFor(context, rasterBuffer, dirtyRect.width, dirtyRect.height); - syncCanvasBounds(canvas, rasterBuffer, dirtyRect); - syncCanvasPostTransform(canvas, state.postTransform ?? null, dirtyRect); - context.clearRect(0, 0, canvas.width, canvas.height); - clearRasterBuffer(rasterBuffer, dirtyRect.width, dirtyRect.height); - for (const projected of projectedTriangles) { - drawTriangle( - rasterBuffer.image.data, - rasterBuffer.zBuffer, - rasterBuffer.width, - dirtyRect.width, - dirtyRect.height, - decoded, - projected.triangle, - projected.vertices, - dirtyRect.x, - dirtyRect.y, - ); - } - context.putImageData(rasterBuffer.image, 0, 0, 0, 0, dirtyRect.width, dirtyRect.height); - } - - return { mount, remove, sync, setFrameIndex }; -} - -function decodeRasterModel(model: QuakeViewmodelRasterModel): DecodedQuakeViewmodelRasterModel { - const skin = decodeBase64Bytes(model.skin); - const palette = decodeBase64Bytes(model.palette); - const texelCount = model.skinWidth * model.skinHeight; - const skinR = new Uint8Array(texelCount); - const skinG = new Uint8Array(texelCount); - const skinB = new Uint8Array(texelCount); - const skinFullbright = new Uint8Array(texelCount); - for (let index = 0; index < texelCount; index++) { - const skinIndex = skin[index] ?? 0; - const paletteIndex = skinIndex * 3; - skinR[index] = palette[paletteIndex] ?? 0; - skinG[index] = palette[paletteIndex + 1] ?? 0; - skinB[index] = palette[paletteIndex + 2] ?? 0; - skinFullbright[index] = skinIndex >= 224 ? 1 : 0; - } - - return { - source: model.source, - skinWidth: model.skinWidth, - skinHeight: model.skinHeight, - skin, - palette, - skinR, - skinG, - skinB, - skinFullbright, - triangles: model.triangles, - frames: model.frames, - }; -} - -function projectVertex( - vertex: Vec3 | undefined, - meshMatrix: DOMMatrix, - stageMatrix: DOMMatrix, - state: QuakeViewmodelRasterSyncState, - shade: number, -): ProjectedVertex | null { - if (!vertex) return null; - const [x, y, z] = worldPositionToPolyCss(vertex); - const local = new DOMPoint(x, y, z, 1); - const transformed = local.matrixTransform(meshMatrix).matrixTransform(stageMatrix); - const layerX = state.stageLeftPx + transformed.x; - const layerY = state.stageTopPx + transformed.y; - const denominator = state.perspectivePx - transformed.z; - if (!Number.isFinite(denominator) || denominator <= QUAKE_RASTER_MIN_DENOMINATOR) return null; - const q = state.perspectivePx / denominator; - return { - x: state.perspectiveOriginX + (layerX - state.perspectiveOriginX) * q, - y: state.perspectiveOriginY + (layerY - state.perspectiveOriginY) * q, - z: transformed.z, - q, - shade, - }; -} - -function rasterDirtyRect( - minX: number, - minY: number, - maxX: number, - maxY: number, - width: number, - height: number, -): RasterDirtyRect | null { - if ( - !Number.isFinite(minX) || - !Number.isFinite(minY) || - !Number.isFinite(maxX) || - !Number.isFinite(maxY) - ) { - return null; - } - const left = clampInt(Math.floor(minX) - 2, 0, width); - const top = clampInt(Math.floor(minY) - 2, 0, height); - const right = clampInt(Math.ceil(maxX) + 2, 0, width); - const bottom = clampInt(Math.ceil(maxY) + 2, 0, height); - if (right <= left || bottom <= top) return null; - return { - x: left, - y: top, - width: right - left, - height: bottom - top, - }; -} - -function rasterBufferFor( - context: CanvasRenderingContext2D, - current: RasterBuffer | null, - width: number, - height: number, -): RasterBuffer { - if (current && current.width >= width && current.height >= height) return current; - const nextWidth = alignInt(Math.max(width, current?.width ?? 0), 32); - const nextHeight = alignInt(Math.max(height, current?.height ?? 0), 32); - return { - image: context.createImageData(nextWidth, nextHeight), - zBuffer: new Float32Array(nextWidth * nextHeight), - width: nextWidth, - height: nextHeight, - }; -} - -function syncCanvasBounds(canvas: HTMLCanvasElement, buffer: RasterBuffer, rect: RasterDirtyRect): void { - if (canvas.width !== buffer.width) canvas.width = buffer.width; - if (canvas.height !== buffer.height) canvas.height = buffer.height; - canvas.style.left = `${rect.x}px`; - canvas.style.top = `${rect.y}px`; - canvas.style.width = `${buffer.width}px`; - canvas.style.height = `${buffer.height}px`; -} - -function syncCanvasPostTransform( - canvas: HTMLCanvasElement, - transform: QuakeViewmodelRasterPostTransform | null, - rect: RasterDirtyRect, -): void { - if (!transform) { - canvas.style.removeProperty("transform"); - canvas.style.removeProperty("transform-origin"); - return; - } - canvas.style.transformOrigin = `${transform.originX - rect.x}px ${transform.originY - rect.y}px`; - const transforms = [ - Math.abs(transform.translateX) > 0.001 || Math.abs(transform.translateY) > 0.001 - ? `translate(${transform.translateX}px, ${transform.translateY}px)` - : "", - Math.abs(transform.rotateDeg) > 0.001 ? `rotate(${transform.rotateDeg}deg)` : "", - Math.abs(transform.skewXDeg) > 0.001 ? `skewX(${transform.skewXDeg}deg)` : "", - Math.abs(transform.skewYDeg) > 0.001 ? `skewY(${transform.skewYDeg}deg)` : "", - Math.abs(transform.scaleX - 1) > 0.001 || Math.abs(transform.scaleY - 1) > 0.001 - ? `scale(${transform.scaleX}, ${transform.scaleY})` - : "", - ]; - canvas.style.transform = transforms.filter(Boolean).join(" "); -} - -function clearRasterBuffer(buffer: RasterBuffer, width: number, height: number): void { - const rgbaStride = buffer.width * 4; - const rgbaRowBytes = width * 4; - const rgba = buffer.image.data; - const zBuffer = buffer.zBuffer; - if (width === buffer.width && height === buffer.height) { - rgba.fill(0); - zBuffer.fill(-Infinity); - return; - } - for (let y = 0; y < height; y++) { - const rgbaStart = y * rgbaStride; - rgba.fill(0, rgbaStart, rgbaStart + rgbaRowBytes); - const zStart = y * buffer.width; - zBuffer.fill(-Infinity, zStart, zStart + width); - } -} - -function drawTriangle( - rgba: Uint8ClampedArray, - zBuffer: Float32Array, - stride: number, - width: number, - height: number, - model: DecodedQuakeViewmodelRasterModel, - triangle: QuakeViewmodelRasterTriangle, - vertices: [ProjectedVertex, ProjectedVertex, ProjectedVertex], - offsetX = 0, - offsetY = 0, -): void { - const [a, b, c] = vertices; - const ax = a.x - offsetX; - const ay = a.y - offsetY; - const bx = b.x - offsetX; - const by = b.y - offsetY; - const cx = c.x - offsetX; - const cy = c.y - offsetY; - const area = edgeFunction(ax, ay, bx, by, cx, cy); - if (Math.abs(area) <= QUAKE_RASTER_EDGE_EPSILON) return; - const sign = area < 0 ? -1 : 1; - const invAreaAbs = 1 / Math.abs(area); - const minX = clampInt(Math.floor(Math.min(ax, bx, cx)), 0, width - 1); - const maxX = clampInt(Math.ceil(Math.max(ax, bx, cx)), 0, width - 1); - const minY = clampInt(Math.floor(Math.min(ay, by, cy)), 0, height - 1); - const maxY = clampInt(Math.ceil(Math.max(ay, by, cy)), 0, height - 1); - const uv0 = triangle.uvs[0] ?? [0, 0]; - const uv1 = triangle.uvs[1] ?? [0, 0]; - const uv2 = triangle.uvs[2] ?? [0, 0]; - const stepX0 = sign * (cy - by); - const stepY0 = sign * -(cx - bx); - const stepX1 = sign * (ay - cy); - const stepY1 = sign * -(ax - cx); - const stepX2 = sign * (by - ay); - const stepY2 = sign * -(bx - ax); - const startX = minX + 0.5; - let rowW0 = sign * edgeFunction(bx, by, cx, cy, startX, minY + 0.5); - let rowW1 = sign * edgeFunction(cx, cy, ax, ay, startX, minY + 0.5); - let rowW2 = sign * edgeFunction(ax, ay, bx, by, startX, minY + 0.5); - - for (let y = minY; y <= maxY; y++) { - let w0 = rowW0; - let w1 = rowW1; - let w2 = rowW2; - for (let x = minX; x <= maxX; x++) { - if (w0 < -QUAKE_RASTER_EDGE_EPSILON || w1 < -QUAKE_RASTER_EDGE_EPSILON || w2 < -QUAKE_RASTER_EDGE_EPSILON) { - w0 += stepX0; - w1 += stepX1; - w2 += stepX2; - continue; - } - - const b0 = w0 * invAreaAbs; - const b1 = w1 * invAreaAbs; - const b2 = w2 * invAreaAbs; - const q0 = b0 * a.q; - const q1 = b1 * b.q; - const q2 = b2 * c.q; - const q = q0 + q1 + q2; - if (Math.abs(q) <= QUAKE_RASTER_EDGE_EPSILON) { - w0 += stepX0; - w1 += stepX1; - w2 += stepX2; - continue; - } - const z = (q0 * a.z + q1 * b.z + q2 * c.z) / q; - const pixelIndex = y * stride + x; - if (z <= zBuffer[pixelIndex]) { - w0 += stepX0; - w1 += stepX1; - w2 += stepX2; - continue; - } - zBuffer[pixelIndex] = z; - - const u = (q0 * uv0[0] + q1 * uv1[0] + q2 * uv2[0]) / q; - const v = (q0 * uv0[1] + q1 * uv1[1] + q2 * uv2[1]) / q; - const skinX = clampNumber(u * model.skinWidth - 0.5, 0, model.skinWidth - 1); - const skinY = clampNumber((1 - v) * model.skinHeight - 0.5, 0, model.skinHeight - 1); - const x0 = Math.floor(skinX); - const y0 = Math.floor(skinY); - const x1 = Math.min(model.skinWidth - 1, x0 + 1); - const y1 = Math.min(model.skinHeight - 1, y0 + 1); - const tx = skinX - x0; - const ty = skinY - y0; - const row0 = y0 * model.skinWidth; - const row1 = y1 * model.skinWidth; - const i00 = row0 + x0; - const i10 = row0 + x1; - const i01 = row1 + x0; - const i11 = row1 + x1; - const r = bilerpNumber(model.skinR[i00], model.skinR[i10], model.skinR[i01], model.skinR[i11], tx, ty); - const g = bilerpNumber(model.skinG[i00], model.skinG[i10], model.skinG[i01], model.skinG[i11], tx, ty); - const blue = bilerpNumber(model.skinB[i00], model.skinB[i10], model.skinB[i01], model.skinB[i11], tx, ty); - const fullbright = - model.skinFullbright[i00] || model.skinFullbright[i10] || model.skinFullbright[i01] || model.skinFullbright[i11]; - const light = fullbright ? 1 : (q0 * a.shade + q1 * b.shade + q2 * c.shade) / q; - const out = pixelIndex * 4; - rgba[out] = postprocessChannel(r, light); - rgba[out + 1] = postprocessChannel(g, light); - rgba[out + 2] = postprocessChannel(blue, light); - rgba[out + 3] = 255; - w0 += stepX0; - w1 += stepX1; - w2 += stepX2; - } - rowW0 += stepY0; - rowW1 += stepY1; - rowW2 += stepY2; - } -} - -function quakeAliasVertexLight(normalIndex: number | undefined, shadeVector: Vec3): number { - const normal = QUAKE_ALIAS_NORMALS[normalIndex ?? -1] ?? [0, 0, 1]; - const dot = normal[0] * shadeVector[0] + normal[1] * shadeVector[1] + normal[2] * shadeVector[2]; - const shadeDot = dot < 0 ? 1 + dot * (13 / 44) : 1 + dot; - return QUAKE_ALIAS_VIEWMODEL_LIGHT_COLOR * shadeDot * QUAKE_ALIAS_SHADER_LIGHT_SCALE; -} - -function quakeAliasShadeVector(rotY: number): Vec3 { - const quakeYaw = normalizeAngleDegrees(rotY - 180); - const quantized = Math.floor(quakeYaw * (16 / 360)) / 16; - const angle = quantized * Math.PI * 2; - return normalizeVec3([Math.cos(-angle), Math.sin(-angle), 1]); -} - -function postprocessChannel(value: number, light: number): number { - const lit = (value / 255) * light; - const contrasted = lit * QUAKE_RASTER_POSTPROCESS_CONTRAST; - const corrected = Math.pow(clampNumber(contrasted, 0, 1), QUAKE_RASTER_POSTPROCESS_GAMMA); - return clampInt(Math.round(corrected * 255), 0, 255); -} - -function cssTransformMatrix(transform: string): DOMMatrix { - const trimmed = transform.trim(); - return trimmed && trimmed !== "none" ? new DOMMatrix(trimmed) : new DOMMatrix(); -} - -function edgeFunction(ax: number, ay: number, bx: number, by: number, cx: number, cy: number): number { - return (cx - ax) * (by - ay) - (cy - ay) * (bx - ax); -} - -function decodeBase64Bytes(value: string): Uint8Array { - const binary = atob(value); - const bytes = new Uint8Array(binary.length); - for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i); - return bytes; -} - -function normalizeVec3(value: Vec3): Vec3 { - const length = Math.hypot(value[0], value[1], value[2]); - return length > 1e-8 ? [value[0] / length, value[1] / length, value[2] / length] : [0, 0, 1]; -} - -function normalizeAngleDegrees(value: number): number { - return ((value % 360) + 360) % 360; -} - -function decodeAliasNormals(value: string): Vec3[] { - const numbers = value.split(",").map((part) => Number.parseFloat(part)); - const normals: Vec3[] = []; - for (let index = 0; index + 2 < numbers.length; index += 3) { - normals.push(normalizeVec3([numbers[index], numbers[index + 1], numbers[index + 2]])); - } - return normals; -} - -function lerpNumber(a: number, b: number, t: number): number { - return a + (b - a) * t; -} - -function bilerpNumber(c00: number, c10: number, c01: number, c11: number, tx: number, ty: number): number { - return lerpNumber(lerpNumber(c00, c10, tx), lerpNumber(c01, c11, tx), ty); -} - -function clampNumber(value: number, min: number, max: number): number { - return Math.min(max, Math.max(min, value)); -} - -function clampInt(value: number, min: number, max: number): number { - return Math.min(max, Math.max(min, value | 0)); -} - -function alignInt(value: number, alignment: number): number { - return Math.max(alignment, Math.ceil(value / alignment) * alignment); -} From d197443e6eb5fbcc6b913fcf75686d668af462b5 Mon Sep 17 00:00:00 2001 From: agustin-littlehat Date: Mon, 15 Jun 2026 00:36:10 -0300 Subject: [PATCH 5/8] Add cheap impact particles --- index.html | 8 + src/App.ts | 71 +++++ src/quake.css | 52 +++- src/runtime/app/dom.ts | 4 + src/runtime/app/impactParticleFlow.ts | 384 ++++++++++++++++++++++++++ src/runtime/app/optionsFlow.ts | 16 ++ src/runtime/weapons.ts | 147 ++++++++-- 7 files changed, 662 insertions(+), 20 deletions(-) create mode 100644 src/runtime/app/impactParticleFlow.ts diff --git a/index.html b/index.html index 44711d4..9565611 100644 --- a/index.html +++ b/index.html @@ -594,6 +594,7 @@
+ @@ -864,6 +865,13 @@

off on + - -
-
Record
-
-
Capture
-
-
Visible
-
-
DOM
-
-
Enemies
-
-
Pickups
-
-
-
- World - Special - Objects/items - Enemies -
-

- -
Debug alt="" /> +
@@ -1112,137 +1099,31 @@

Debug

- + +
+ +
+
diff --git a/src/App.ts b/src/App.ts index 8b7c88b..206d254 100644 --- a/src/App.ts +++ b/src/App.ts @@ -239,8 +239,9 @@ const QUAKE_DOOR_MESSAGE_COOLDOWN_MS = 2000; const quakeDom = queryQuakeAppDom(); const { app: quakeApp, - ui: quakeUi, - viewmodelLayer, + scene: quakeSceneRoot, + menu: quakeMenu, + weapon, mainMenu, mainMenuArt, versionLabel, @@ -274,6 +275,7 @@ const { crosshair, crosshairOption, crosshairOptionValue, + debugStack, debugPanel, debugShowMenuOption, debugEnabledOption, @@ -285,7 +287,6 @@ const { debugFlyModeOption, debugShowOutlinesOption, debugShowLabelsOption, - debugRecordButton, debugStatElements, loadingOverlay, loadingStatus, @@ -817,6 +818,26 @@ let quakeShowGun = showGunOption?.checked ?? true; let quakeDynamicLighting = dynamicLightingOption?.checked ?? true; let quakeImpactParticles = impactParticlesOption?.checked ?? true; +function installInspectableQuakePolycssCamera( + sceneHandle: { applyCamera(): void }, + cameraElement: HTMLElement, +): void { + const applyCamera = sceneHandle.applyCamera.bind(sceneHandle); + sceneHandle.applyCamera = () => { + applyCamera(); + stripQuakePolycssCameraDataAttributes(cameraElement); + }; + stripQuakePolycssCameraDataAttributes(cameraElement); +} + +function stripQuakePolycssCameraDataAttributes(cameraElement: HTMLElement): void { + for (const attribute of Array.from(cameraElement.attributes)) { + if (attribute.name.startsWith("data-polycss-camera-")) { + cameraElement.removeAttribute(attribute.name); + } + } +} + function quakeUrlRouteFromLocation(): QuakeUrlRoute { return quakeRoute.routeFromLocation(); } @@ -1199,8 +1220,13 @@ const scene = createPolyScene(quakeApp, { autoCenter: false, }); const host = scene.cameraEl as HTMLElement; -quakeApp.insertBefore(host, viewmodelLayer ?? quakeUi); +if (quakeSceneRoot) { + quakeSceneRoot.appendChild(host); +} else { + quakeApp.insertBefore(host, weapon ?? quakeMenu); +} host.tabIndex = 0; +installInspectableQuakePolycssCamera(scene, host); // PolyCSS controls read scene.host when they are created; keep that target on the inspectable camera node. (scene as unknown as { host: HTMLElement }).host = host; const sceneElement = scene.sceneElement; @@ -1434,13 +1460,14 @@ const quakeDebugPanelFlow = createQuakeDebugPanelFlow({ debugShowLabelsOption, debugShowMenuOption, debugShowOutlinesOption, + debugStack, debugShowTexturesOption, debugStatElements, hideMainMenu: () => menu.hideMainMenu(), initialHideTextures: debugShowTexturesOption ? !debugShowTexturesOption.checked : false, initialAnimationsEnabled: quakeEnemyAnimationsEnabled, initialMode: quakeUrlBoolean("debugPolys"), - initialShowFps: debugShowFpsOption?.checked ?? true, + initialShowFps: debugShowFpsOption?.checked ?? false, initialShowLabels: debugShowLabelsOption?.checked ?? false, initialShowMenu: debugShowMenuOption?.checked ?? true, initialShowOutlines: debugShowOutlinesOption?.checked ?? false, @@ -1547,7 +1574,6 @@ const quakeDebugRecordingSnapshot = createQuakeDebugRecordingSnapshotFlow({ }); const quakeDebugRecorder = createQuakeDebugRecorder({ appVersion: __CSSQUAKE_VERSION__, - button: debugRecordButton, currentMapName: () => currentMapName, entityManifest: () => currentResult?.entityManifest ?? null, snapshot: () => quakeDebugRecordingSnapshot.capture(), @@ -1595,7 +1621,7 @@ viewmodel = createQuakeViewmodelController({ controls, getRenderOrigin: quakeCameraView.currentRenderOrigin, host, - layer: viewmodelLayer, + layer: weapon, }); const quakeViewmodelAssets = createQuakeViewmodelAssetFlow({ activeWeapon: () => player?.inventory().activeWeapon ?? null, @@ -1852,6 +1878,7 @@ const weapons = createQuakeWeaponsController({ damagePlayer: (amount, context) => getPlayer().damage(amount, context), canDamageTargetOrigin: (start, targetOrigin) => shootables.canDamageTargetOrigin(start, targetOrigin), damageMultiplier: () => quakePowerups.damageMultiplier(), + onFire: sendQuakeMultiplayerFireIntent, onDamageImpact: (event) => { quakeImpactParticleFlow.spawnBlood({ damage: event.damage, @@ -1859,7 +1886,6 @@ const weapons = createQuakeWeaponsController({ origin: event.origin, }); }, - onFire: sendQuakeMultiplayerFireIntent, onHit: () => quakeWeaponPresentation.flashCrosshairHit(), onWallImpact: (event) => { quakeImpactParticleFlow.spawnWallImpact({ @@ -1935,7 +1961,7 @@ quakeStatsOverlay = createQuakeStatsOverlayFlow({ isDisposed: () => quakeAppDisposed, isLoading: () => quakeAppLoading, isMobileAvailable: quakePointerGameplay.isMobileAvailable, - root: quakeUi ?? quakeApp, + root: quakeMenu ?? quakeApp, showFpsEnabled: () => quakeDebugPanelFlow.showFpsEnabled(), }); @@ -2438,7 +2464,7 @@ function canShowQuakeImpactParticles(): boolean { currentResult !== null && !quakePlayerDead && !hasQuakeBodyClass("quake-level-complete") && - !hasQuakeBodyClass("quake-ui-unlocked") && + !hasQuakeBodyClass("quake-menu-unlocked") && !menu.isMainMenuOpen() && !menu.isMenuPanelOpen() ); @@ -2472,7 +2498,7 @@ function syncQuakeInteractionPresentation(): void { const debugPointerUnlocked = quakeDebugPanelFlow.isModeEnabled() && document.pointerLockElement !== host; setQuakeBodyClass("quake-debug-active", quakeDebugPanelFlow.isModeEnabled()); setQuakeBodyClass("quake-debug-pointer-unlocked", debugPointerUnlocked); - setQuakeBodyClass("quake-ui-unlocked", menuSurfaceOpen || debugPointerUnlocked); + setQuakeBodyClass("quake-menu-unlocked", menuSurfaceOpen || debugPointerUnlocked); } function handleQuakeMenuDebugToggle(): void { @@ -2497,10 +2523,14 @@ function quitQuakeToMainMenu(): void { function setQuakeDebugFlyMode(enabled: boolean): void { quakeDebugFly.setEnabled(enabled); + world.setDebugShellVisible(enabled); + world.syncVisibility(true); } function syncQuakeDebugFlyMode(): void { quakeDebugFly.syncMode(); + world.setDebugShellVisible(quakeDebugFly.isEnabled()); + world.syncVisibility(true); } function respawnQuakePlayerFromFlyMode(): boolean { @@ -4210,6 +4240,12 @@ async function completeQuakeSceneReadiness( modelPromise = quakeViewmodelAssets.preload(), progress?: QuakeLoadingProgressTracker, ): Promise { + const completeWorldTexturesTask = progress?.startTask("World textures"); + try { + await world.waitForVisibleAtlasPages(); + } finally { + completeWorldTexturesTask?.(); + } await quakeLoading.completeSceneReadiness(modelPromise, quakeViewmodelAssets.mount, progress); } @@ -4459,14 +4495,8 @@ const quakeInput = createQuakeAppInputController({ showMainMenu: () => menu.showMainMenu(), syncViewmodelTransform: () => viewmodel.syncTransform(), toggleAudioMuted: toggleQuakeAudioMuted, - toggleDebugRecording: () => { - if (quakeDebugRecorder.isRecording()) { - quakeDebugRecorder.stop(); - } else { - quakeDebugRecorder.start(); - } - }, toggleDebugMode: toggleQuakeDebugMode, + toggleOutlineTextureMode: () => quakeDebugPanelFlow.toggleOutlineTextureMode(), }); const quakeAppRuntime = createQuakeAppRuntimeContext({ diff --git a/src/assets/source-port-conback.lmp b/src/assets/source-port-conback.lmp deleted file mode 100644 index 09d68e6f3accbb56bef4450e07ba905597042848..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 327688 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 lW>6<G^IT1gG(qZ|0tTWneod_jeExUfcjfO7 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

Wp8^m-UI5Q`)Zh%hE*Z9do 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 diff --git a/src/assets/source-port-conback.png b/src/assets/source-port-conback.png new file mode 100644 index 0000000000000000000000000000000000000000..d2a67981b4f7f2fd14f139121012bd960fd1f56f GIT binary patch literal 60206 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

RkI>{Yk8ZO_+;cqcxz254^mV9gX%=md zo#DH&X>$FrEVJ^xBq32_&~S0bh?RrUh$fQsfYL{yN5NFYIj+04^JDa6o1Darx_Cc7sNXD$8z6ffd$l#od#ObLf;2 zB)67J_gC`h+Xv~6bb$lT#er*FPXUW)Lc!w6tP^-$I5doyu&;M2h2b6FDnaaWrH$RE zpO5L-%gS?q9M2#G{giQ6pFL}&4WFNE-7@zyXRpI=pP^JpgIfUj9ErLUwj(#q`oyi6 z7`(iF88yqToP<@~*qgUU_PsCN5N-12buT(sVFG|--KrKU^FH%3w>jW}ig0*9dX;;Z z$Y^sm$Ww#}Ri9fq!oq@FJS97g{phbi2lO?=oGM0AAP7eV5)t{9yOIaJa zSTEif7IY!lonZRyn+5jM`snR%{;?Zj=QBFE?$M}^swN$ed1V8!gB+y)+q21r{5xl` z$iMhk`kM*$R1umE&MjA*K$e37j2Kk`A>nlvf&pI~{als%83nFnQ9!*2EXQ3xB@7@& zq>Xz&uh^dd31wpJDg?7vm+c$F5?e~WZ5<0)(6I^BunTA?&2tIon6PqXzc{inyEpiv zR%Rg;jMF5~z0&4#8&E5HV4V>Q;gwPuAFVuGl^)VWb9JTvjq$!{#Z0RIEjCbA