Grid to editor
This commit is contained in:
@@ -105,6 +105,46 @@ const ChunkTerrain = (() => {
|
|||||||
return new Float32Array(out);
|
return new Float32Array(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Four edges (SW-SE, SE-NE, NE-NW, NW-SW) of a tile's quad as line
|
||||||
|
// segments, lifted slightly above the terrain surface to avoid
|
||||||
|
// z-fighting - same corner-height convention as pushTileQuad().
|
||||||
|
function pushTileGridLines(out, fx, fy, swZ, seZ, neZ, nwZ) {
|
||||||
|
const eps = 0.01;
|
||||||
|
const sw = [fx, fy, swZ + eps];
|
||||||
|
const se = [fx + 1, fy, seZ + eps];
|
||||||
|
const ne = [fx + 1, fy + 1, neZ + eps];
|
||||||
|
const nw = [fx, fy + 1, nwZ + eps];
|
||||||
|
const edges = [sw, se, se, ne, ne, nw, nw, sw];
|
||||||
|
for(const [x, y, z] of edges) out.push(0, 0, x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate grid-outline line segments for every non-null tile, following
|
||||||
|
// the same per-corner heights as buildTerrainVerts() so lines hug ramps
|
||||||
|
// instead of cutting through them. Returns a Float32Array of interleaved
|
||||||
|
// [u, v, x, y, z] vertices meant to be drawn with gl.LINES (pairs).
|
||||||
|
function buildGridLines(tiles) {
|
||||||
|
const out = [];
|
||||||
|
for(let z = 0; z < CHUNK_DEPTH; z++) {
|
||||||
|
for(let y = 0; y < CHUNK_HEIGHT; y++) {
|
||||||
|
for(let x = 0; x < CHUNK_WIDTH; x++) {
|
||||||
|
const type = tiles[tileIndex(x, y, z)] || TILE_SHAPE_NULL;
|
||||||
|
const corners = RAMP_CORNERS[type];
|
||||||
|
if(!corners) continue;
|
||||||
|
|
||||||
|
const [sw, se, ne, nw] = corners;
|
||||||
|
pushTileGridLines(
|
||||||
|
out, x, y,
|
||||||
|
(z + sw) * WORLD_LAYER_HEIGHT,
|
||||||
|
(z + se) * WORLD_LAYER_HEIGHT,
|
||||||
|
(z + ne) * WORLD_LAYER_HEIGHT,
|
||||||
|
(z + nw) * WORLD_LAYER_HEIGHT
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Float32Array(out);
|
||||||
|
}
|
||||||
|
|
||||||
return Object.freeze({
|
return Object.freeze({
|
||||||
CHUNK_WIDTH, CHUNK_HEIGHT, CHUNK_DEPTH, TILE_COUNT, WORLD_LAYER_HEIGHT,
|
CHUNK_WIDTH, CHUNK_HEIGHT, CHUNK_DEPTH, TILE_COUNT, WORLD_LAYER_HEIGHT,
|
||||||
TILE_SHAPE_NULL, TILE_SHAPE_GROUND,
|
TILE_SHAPE_NULL, TILE_SHAPE_GROUND,
|
||||||
@@ -114,6 +154,6 @@ const ChunkTerrain = (() => {
|
|||||||
TILE_SHAPE_RAMP_SOUTHEAST, TILE_SHAPE_RAMP_SOUTHWEST,
|
TILE_SHAPE_RAMP_SOUTHEAST, TILE_SHAPE_RAMP_SOUTHWEST,
|
||||||
TILE_SHAPE_RAMP_NORTHEAST_INNER, TILE_SHAPE_RAMP_NORTHWEST_INNER,
|
TILE_SHAPE_RAMP_NORTHEAST_INNER, TILE_SHAPE_RAMP_NORTHWEST_INNER,
|
||||||
TILE_SHAPE_RAMP_SOUTHEAST_INNER, TILE_SHAPE_RAMP_SOUTHWEST_INNER,
|
TILE_SHAPE_RAMP_SOUTHEAST_INNER, TILE_SHAPE_RAMP_SOUTHWEST_INNER,
|
||||||
RAMP_CORNERS, tileIndex, buildTerrainVerts,
|
RAMP_CORNERS, tileIndex, buildTerrainVerts, buildGridLines,
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -146,6 +146,7 @@
|
|||||||
|
|
||||||
let mapRenderer = null;
|
let mapRenderer = null;
|
||||||
let terrainMesh = null;
|
let terrainMesh = null;
|
||||||
|
let gridLinesMesh = null;
|
||||||
let terrainTexturePromise = null;
|
let terrainTexturePromise = null;
|
||||||
let modelIndex = null;
|
let modelIndex = null;
|
||||||
let neighborChunks = [];
|
let neighborChunks = [];
|
||||||
@@ -496,7 +497,7 @@
|
|||||||
const sy = (ChunkTerrain.CHUNK_HEIGHT - 1 - y) * cell;
|
const sy = (ChunkTerrain.CHUNK_HEIGHT - 1 - y) * cell;
|
||||||
ctx.fillStyle = SHAPE_COLORS[type] || "#15171b";
|
ctx.fillStyle = SHAPE_COLORS[type] || "#15171b";
|
||||||
ctx.fillRect(x * cell, sy, cell, cell);
|
ctx.fillRect(x * cell, sy, cell, cell);
|
||||||
ctx.strokeStyle = "rgba(255, 255, 255, 0.08)";
|
ctx.strokeStyle = "rgba(255, 255, 255, 0.25)";
|
||||||
ctx.strokeRect(x * cell, sy, cell, cell);
|
ctx.strokeRect(x * cell, sy, cell, cell);
|
||||||
|
|
||||||
const dir = SHAPE_DIRECTIONS[type];
|
const dir = SHAPE_DIRECTIONS[type];
|
||||||
@@ -599,6 +600,9 @@
|
|||||||
function rebuildTerrainMesh() {
|
function rebuildTerrainMesh() {
|
||||||
const floats = ChunkTerrain.buildTerrainVerts(tiles);
|
const floats = ChunkTerrain.buildTerrainVerts(tiles);
|
||||||
terrainMesh = floats.length ? mapRenderer.createMesh(floats) : null;
|
terrainMesh = floats.length ? mapRenderer.createMesh(floats) : null;
|
||||||
|
|
||||||
|
const lineFloats = ChunkTerrain.buildGridLines(tiles);
|
||||||
|
gridLinesMesh = lineFloats.length ? mapRenderer.createMesh(lineFloats) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keeps the preview canvas's backing-store resolution matched to its
|
// Keeps the preview canvas's backing-store resolution matched to its
|
||||||
@@ -649,6 +653,7 @@
|
|||||||
target: [ChunkTerrain.CHUNK_WIDTH / 2, ChunkTerrain.CHUNK_HEIGHT / 2, zLevelHeight],
|
target: [ChunkTerrain.CHUNK_WIDTH / 2, ChunkTerrain.CHUNK_HEIGHT / 2, zLevelHeight],
|
||||||
worldH: zoomWorldH,
|
worldH: zoomWorldH,
|
||||||
terrain: terrainMesh ? { mesh: terrainMesh, texture: terrainTexture } : null,
|
terrain: terrainMesh ? { mesh: terrainMesh, texture: terrainTexture } : null,
|
||||||
|
gridLines: gridLinesMesh ? { mesh: gridLinesMesh } : null,
|
||||||
models,
|
models,
|
||||||
neighbors,
|
neighbors,
|
||||||
highlight: hoverTile ? { x: hoverTile.x, y: hoverTile.y, z: zLevelHeight } : null,
|
highlight: hoverTile ? { x: hoverTile.x, y: hoverTile.y, z: zLevelHeight } : null,
|
||||||
|
|||||||
@@ -221,6 +221,7 @@ const MapRenderer = (() => {
|
|||||||
// scene = {
|
// scene = {
|
||||||
// target: [x, y, z], worldH: number,
|
// target: [x, y, z], worldH: number,
|
||||||
// terrain: { mesh, texture } | null,
|
// terrain: { mesh, texture } | null,
|
||||||
|
// gridLines: { mesh } | null,
|
||||||
// models: [{ mesh, texture, color: [r,g,b,a in 0..1], offset: [x,y,z] }],
|
// models: [{ mesh, texture, color: [r,g,b,a in 0..1], offset: [x,y,z] }],
|
||||||
// neighbors: [{
|
// neighbors: [{
|
||||||
// offset: [x,y,z],
|
// offset: [x,y,z],
|
||||||
@@ -248,6 +249,10 @@ const MapRenderer = (() => {
|
|||||||
drawMesh(scene.terrain.mesh, identity, scene.terrain.texture, [1, 1, 1, 1], true);
|
drawMesh(scene.terrain.mesh, identity, scene.terrain.texture, [1, 1, 1, 1], true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(scene.gridLines) {
|
||||||
|
drawMesh(scene.gridLines.mesh, identity, null, [0, 0, 0, 0.35], false, gl.LINES);
|
||||||
|
}
|
||||||
|
|
||||||
for(const model of scene.models) {
|
for(const model of scene.models) {
|
||||||
const modelMatrix = mat4Translation(new Float32Array(16), model.offset);
|
const modelMatrix = mat4Translation(new Float32Array(16), model.offset);
|
||||||
drawMesh(model.mesh, modelMatrix, model.texture, model.color, true);
|
drawMesh(model.mesh, modelMatrix, model.texture, model.color, true);
|
||||||
|
|||||||
Reference in New Issue
Block a user