From e4170bee62b9b32baccf585d28ec2b48458706c6 Mon Sep 17 00:00:00 2001 From: Richard Zink Date: Thu, 8 Oct 2026 10:29:08 +0200 Subject: [PATCH] X-swap via arrangement, no image X-flip User clarified: the X-swap should be in the ARRANGEMENT (east tiles on screen right), NOT in the image (so map content is readable). Previous attempts had it the other way around. Combined state: - canvasX = -perp + ... (X-swap): east (1102) on screen right, west (1098) on screen left. x increases left to right. - drawImage with positive width: no image X-flip. Map content reads normally, place names not mirrored. - Labels in normal orientation. So the X mirror is in the corridor arrangement, not in the satellite image content. The user can read the map normally. --- vendor/clouds3d.js | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/vendor/clouds3d.js b/vendor/clouds3d.js index 3d14551..5b3b5e1 100644 --- a/vendor/clouds3d.js +++ b/vendor/clouds3d.js @@ -337,10 +337,12 @@ function drawTileAt(lng, perp, dx, dz, centerTileX, centerTileY) { // UNPACK_FLIP_Y_WEBGL=true inverts V: canvas top -> texture V=1 (top). // For lng axis (Y): invert canvasY so lng=+12 (corridor front in // N flight) lands at small canvasY (= screen top after flip). - // === NO X-SWAP, NO X-FLIP BUILD v5 === - // Natural order, no swap. East (perp=-2) -> canvasX 128 (left), - // west (perp=+2) -> canvasX 1152 (right). No image X-flip. - var canvasX = (perp + halfPerp + 0.5) * GROUND_TILE_SIZE; + // === X-SWAP ARRANGEMENT, NO IMAGE FLIP BUILD v6 === + // X-swap via arrangement: east (perp=-2) -> canvasX 1152 (right), + // west (perp=+2) -> canvasX 128 (left). So x INCREASES left-to-right. + // No image X-flip: map content reads normally (place names not + // mirrored). Labels in normal orientation. + var canvasX = (-perp + halfPerp + 0.5) * GROUND_TILE_SIZE; var canvasY = (lng + halfLong + 0.5) * GROUND_TILE_SIZE; if (canvasX < 0 || canvasX >= groundCanvas.width || canvasY < 0 || canvasY >= groundCanvas.height) { return Promise.resolve(false); @@ -350,12 +352,12 @@ function drawTileAt(lng, perp, dx, dz, centerTileX, centerTileY) { // the corridor orientation (east tiles have their image east // on the left of the drawn area, west tiles on the right). // Labels are drawn separately in normal orientation, so the - // X-flip activated: draw with negative width to mirror - // horizontally. The image is anchored at the right edge - // (canvasX + TILE_SIZE) and extends leftward, producing a - // horizontally mirrored image. - groundCtx.drawImage(img, canvasX + GROUND_TILE_SIZE, canvasY, - -GROUND_TILE_SIZE, GROUND_TILE_SIZE); + // Normal orientation (no X-flip). The X-swap is done via the + // arrangement formula (canvasX = -perp + ...) so east tiles + // are on the right of the screen. The map content within each + // tile reads normally. + groundCtx.drawImage(img, canvasX, canvasY, + GROUND_TILE_SIZE, GROUND_TILE_SIZE); groundLoadedTiles[tileX + '_' + tileY] = true; // Thin border so the user can see where one tile ends and the