0.2.6: the device slabs stay drawn on an official scene (GitHub #569) — 射击台, 特制水上平台 and 封印的地面 lived only in the procedural board's bucket that a scene replaces, so 战场#03's raised tiles by the blue gate were flat and 战场#05(上半)'s water platforms read as open water; buildBoard repeats them into buckets.raised / raisedDecal with sides reaching under the scene's ground and setStage draws just those on a scene (the 'h' high ground is the scenes' own and is not repeated); DESIGN §31.11, client §15; golden: unchanged
This commit is contained in:
1 parent
d8aab0a2db
commit
205f3bb7f7
7 files changed
+99
-8
No files matched your search
@@ -3,8 +3,11 @@
|
||||
// the buckets into merged BufferGeometries).
|
||||
//
|
||||
// const board = buildBoard(stage, { uv: resolveUvTable(tiles), crate?: objMesh, area?: AREAS.normal })
|
||||
// → { grid, buckets: { board, decal, pipe }, gates: [{ r, c, kind: 'start'|'end' }], devices: [...],
|
||||
// → { grid, buckets: { board, decal, pipe, glass, raised, raisedDecal }, gates: [{ r, c, kind: 'start'|'end' }], devices: [...],
|
||||
// terrain: { water, mire, smog, infection: [[r,c]…] }, edges: [...cyan field edge strips], bounds, stats }
|
||||
// `raised` / `raisedDecal` repeat only the device slabs — 射击台, 特制水上平台, 封印的地面 — with their side faces
|
||||
// reaching below the ground: those are runtime devices that an official scene (scene.js) does not contain, so they are
|
||||
// drawn on it (GitHub #569). The 'h' high ground is part of the scenes (act2 m01 / m02 model it) and is not repeated.
|
||||
// `devices` = the active stage devices standing on a built tile — separator walls included (act2 m01's blowers: the
|
||||
// row-13 ones at the top edge of the normal / 联防 field, the row-6 ones at its bottom edge and at the top edge of the
|
||||
// Final Assault field — user playtest #5 item 6 and its follow-up).
|
||||
@@ -40,6 +43,8 @@ export const CLIFF = 0.75;
|
||||
export const BEVEL = Object.freeze({ low: [0.035, 0.018], block: [0.04, 0.035] });
|
||||
/** Deep-sea basins: floor depth below the ground. */
|
||||
export const BASIN = 0.14;
|
||||
/** How far below the ground the device slabs' side faces reach on an official scene (its ground sits about z 0). */
|
||||
export const RAISED_FOOT = 0.08;
|
||||
|
||||
const CONTENT_OF = (g) => g !== '#' && g !== 'X';
|
||||
|
||||
@@ -321,6 +326,7 @@ export function buildBoard(stage, opts = {}) {
|
||||
const at = (r, c) => grid[r]?.[c] || null;
|
||||
const topZ = (t) => (t.glyph === 'd' ? -BASIN : t.h);
|
||||
const board = new Geom(), decal = new Geom(), pipe = new Geom(), glass = new Geom();
|
||||
const raised = new Geom(), raisedDecal = new Geom();
|
||||
const gates = [], terrain = { water: [], mire: [], smog: [], infection: [] };
|
||||
let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
|
||||
|
||||
@@ -441,12 +447,15 @@ export function buildBoard(stage, opts = {}) {
|
||||
|
||||
const devices = opts.devices === false ? [] : stageDevices(stage, grid);
|
||||
for (const d of devices) {
|
||||
if (d.kind === 'platform' || d.kind === 'sealedFloor' || d.kind === 'waterPlatform') slabDevice(board, decal, UVT, d, grid);
|
||||
if (d.kind === 'platform' || d.kind === 'sealedFloor' || d.kind === 'waterPlatform') {
|
||||
slabDevice(board, decal, UVT, d, grid);
|
||||
slabDevice(raised, raisedDecal, UVT, d, grid, RAISED_FOOT);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
grid, gates, devices, terrain, edges,
|
||||
buckets: { board: board.finish(), decal: decal.finish(), pipe: pipe.finish(), glass: glass.finish() },
|
||||
buckets: { board: board.finish(), decal: decal.finish(), pipe: pipe.finish(), glass: glass.finish(), raised: raised.finish(), raisedDecal: raisedDecal.finish() },
|
||||
bounds: { x0: minX, x1: maxX, y0: minY, y1: maxY },
|
||||
stats: { tiles: grid.flat().filter((t) => t.drawn).length, vertices: board.vertexCount + decal.vertexCount + pipe.vertexCount },
|
||||
};
|
||||
@@ -513,17 +522,18 @@ export function stageDevices(stage, grid) {
|
||||
/** Device heights on their tile (platform tops are standing surfaces: tiles.js heightAt adds them). */
|
||||
export const DEVICE_H = Object.freeze({ platform: TILE_H.platform, sealedFloor: 0.05, waterPlatform: 0.2 });
|
||||
|
||||
function slabDevice(board, decal, UVT, d, grid) {
|
||||
/** `foot` lowers the side faces' bottom (the scene-board copy reaches under an official scene's ground). */
|
||||
function slabDevice(board, decal, UVT, d, grid, foot = 0) {
|
||||
const size = d.kind === 'sealedFloor' ? 0.92 : 0.94;
|
||||
const h = DEVICE_H[d.kind] || 0.2;
|
||||
const z0 = grid[d.r][d.c].h, zt = z0 + h;
|
||||
const zt = grid[d.r][d.c].h + h, z0 = grid[d.r][d.c].h - foot;
|
||||
const a = size / 2, x0 = d.c - a, x1 = d.c + a, y0 = d.r - a, y1 = d.r + a;
|
||||
const topSurf = d.kind === 'sealedFloor' ? null : UVT.plateS;
|
||||
if (topSurf) board.quad([[x0, y0, zt], [x1, y0, zt], [x1, y1, zt], [x0, y1, zt]], surfaceUV(topSurf), [0, 0, 1], [1.02, 1.02, 1.02]);
|
||||
else decal.quad([[x0, y0, zt], [x1, y0, zt], [x1, y1, zt], [x0, y1, zt]], surfaceUV(UVT.hazardX), [0, 0, 1], [1, 1, 1]);
|
||||
const side = UVT.graySide;
|
||||
for (const dir of ['S', 'E', 'N', 'W']) {
|
||||
const uv = surfaceUV(side, sideRect(side, size, h));
|
||||
const uv = surfaceUV(side, sideRect(side, size, h + foot));
|
||||
board.quad(sideCorners(dir, x0, x1, y0, y1, z0, zt), uv, NRM[dir], [[0.5, 0.53, 0.56], [0.5, 0.53, 0.56], [0.85, 0.88, 0.9], [0.85, 0.88, 0.9]]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
// static crates (merged, same material),
|
||||
// decals (MT_autochess_common), fence pipes, blowers (merged, unlit), gate boxes (additive + alpha, merged per
|
||||
// material), cyan field edges, terrain overlays (≤ 4), background plane + its shadow catcher — ~12–16 in total.
|
||||
// An official scene replaces the tiles, glass, decals, pipes and background with one mesh per material and lightmap
|
||||
// An official scene replaces the tiles, glass, decals, pipes and background (all but the device slabs, layout.js
|
||||
// buckets.raised — GitHub #569) with one mesh per material and lightmap
|
||||
// page of the parts the built areas show (load.js mergeSceneChunks). Devices, gates, edges and terrain stay.
|
||||
// The key light's shadow map is rendered only when the geometry changes (autoUpdate off).
|
||||
|
||||
@@ -303,6 +304,11 @@ export class BoardScene {
|
||||
M.glass = this._mesh(board.buckets.glass, this.mat.glass);
|
||||
M.decal = this._mesh(board.buckets.decal, this.mat.decal, { cast: false });
|
||||
M.pipe = this._mesh(board.buckets.pipe, this.mat.pipe);
|
||||
} else {
|
||||
// the scene has no device slabs: the 射击台 / 特制水上平台 / 封印的地面 slabs stay drawn on it (units stand
|
||||
// on them at tiles.js heightAt; GitHub #569)
|
||||
M.raised = this._mesh(board.buckets.raised, this.mat.board);
|
||||
M.raisedDecal = this._mesh(board.buckets.raisedDecal, this.mat.decal, { cast: false });
|
||||
}
|
||||
this._buildDevices(board);
|
||||
this._buildGates(board);
|
||||
|
||||
Reference in new issue
Block a user