Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 3x 3x 1x 5x 5x 5x 5x 5x 5x 5x 3x 3x 3x | /**
* Scene-level constants shared across VillageScene and its satellite
* modules (minorIslands, Boat, tests). Keeping them in a single module
* avoids an import cycle where VillageScene would import from a module
* that also imports from VillageScene.
*/
/** Radius of the zone ring (zones placed on a circle of this radius). */
export const ZONE_RING_RADIUS = 13;
/** Radius of the main (central) grass island. */
export const MAIN_ISLAND_RADIUS = ZONE_RING_RADIUS + 5;
/** Walkable grid resolution (cells per side). */
export const GRID_SIZE = 48;
/**
* Height of the main island cylinder. Pushed well below the water
* surface so the camera can dive and see solid land above the seabed
* rather than an empty void.
*/
export const MAIN_ISLAND_HEIGHT = 14;
/**
* World-space y of the seabed plane (ocean floor). Deep enough that
* the water column has real volume for fish to swim in.
*/
export const SEABED_Y = -18;
/** Radius of the seabed disc (also the scatter area for rocks/corals). */
export const SEABED_RADIUS = 100;
/**
* Camera y threshold below which the scene is considered "underwater".
* Matches `FishSchool`'s internal gate so the fish school and the
* underwater atmosphere toggle together on the exact same frame.
*/
export const UNDERWATER_CAMERA_Y = -0.2;
/**
* Fog + background colour used while the camera is underwater. A deep
* teal-blue that reads as "ocean depth" rather than "night sky".
*/
export const UNDERWATER_COLOR = 0x0a3a6b;
/**
* Exponential fog density underwater. FogExp2 attenuates by
* exp(-(density * distance)^2), so 0.06 opened to ~90 percent fog at
* 30 units - far too thick, the seabed's flowers and stones became
* unreadable on a deep dive. 0.022 keeps a noticeable blue tint close
* up, lets the seabed at ~30 units stay clearly visible, and still
* blurs distant minor-island trunks past 60 units.
*/
export const UNDERWATER_FOG_DENSITY = 0.022;
/**
* Pure helper for tests and callers that want to classify a camera
* height without pulling in three.js. Mirrors the inline check used in
* `UnderwaterAtmosphere` and `FishSchool`.
*/
export function isUnderwater(cameraY: number, threshold: number = UNDERWATER_CAMERA_Y): boolean {
return cameraY < threshold;
}
/**
* Refined underwater classification used by `UnderwaterAtmosphere`.
* A camera that is below the water-line threshold but still sits over
* the main island footprint is NOT considered "underwater" - it is
* just zoomed in tight against the island surface, and flipping the
* scene into underwater mode there would hide the sky dome while
* leaving the island in view, producing a bright/washed-out frame.
*
* We only treat the view as underwater when the camera is also outside
* the main island's horizontal footprint (so the camera is actually
* over the ocean). A small tolerance keeps the transition smooth when
* the user pans across the island edge.
*/
export function isUnderwaterView(
cameraX: number,
cameraY: number,
cameraZ: number,
threshold: number = UNDERWATER_CAMERA_Y,
islandRadius: number = MAIN_ISLAND_RADIUS
): boolean {
if (cameraY >= threshold) return false;
const horizontal = Math.hypot(cameraX, cameraZ);
// A 10% tolerance past the island rim avoids flicker when the user
// pans the camera right along the shoreline.
return horizontal > islandRadius * 1.1;
}
|