chore: add terrain surface config

This commit is contained in:
Tom Boullay
2026-05-25 15:51:02 +02:00
parent a52d57ae6c
commit 1f6d9659ed
6 changed files with 118 additions and 142 deletions
+20 -70
View File
@@ -1,108 +1,58 @@
import type { TerrainSurfaceColorConfig } from "@/types/world/terrainSurface";
export const TERRAIN_SURFACE_COLOR_TOLERANCE = 15;
export const TERRAIN_WATER_HEIGHT = 0;
export const TERRAIN_TILE_SIZE = 1;
export const GRASS_BASE_COLOR = "#1a3a1a";
export const TERRAIN_COLORS = {
grass1: {
hex: "#84C66B",
rgb: [132, 198, 107] as const,
type: "grass" as const,
kind: "grass",
grassTipColor: "#84C66B",
},
grass2: {
hex: "#67B058",
rgb: [103, 176, 88] as const,
type: "grass" as const,
kind: "grass",
grassTipColor: "#67B058",
},
grass3: {
hex: "#A3CA5B",
rgb: [163, 202, 91] as const,
type: "grass" as const,
kind: "grass",
grassTipColor: "#A3CA5B",
},
potager: {
hex: "#342420",
rgb: [52, 36, 32] as const,
type: "tile" as const,
tileModel: "/models/potager/potager.gltf",
tileSize: 1,
kind: "garden",
modelPath: "/models/potager/potager.gltf",
tileSize: TERRAIN_TILE_SIZE,
},
terre: {
hex: "#513E2C",
rgb: [81, 62, 44] as const,
type: "none" as const,
kind: "dirt",
},
chemin: {
hex: "#F5D896",
rgb: [245, 216, 150] as const,
type: "tile" as const,
tileModel: "/models/chemins/model.gltf",
tileSize: 1,
kind: "path",
modelPath: "/models/chemins/model.gltf",
tileSize: TERRAIN_TILE_SIZE,
},
eau: {
hex: "#91DAF5",
rgb: [145, 218, 245] as const,
type: "water" as const,
kind: "water",
},
cailloux: {
hex: "#B6D3DE",
rgb: [182, 211, 222] as const,
type: "none" as const,
kind: "rock",
},
} as const;
} satisfies Record<string, TerrainSurfaceColorConfig>;
export type TerrainColorKey = keyof typeof TERRAIN_COLORS;
export type TerrainType = "grass" | "tile" | "water" | "none";
export const GRASS_BASE_COLOR = "#1a3a1a";
export const COLOR_TOLERANCE = 15;
export function colorMatchesTerrain(
r: number,
g: number,
b: number,
targetRgb: readonly [number, number, number],
tolerance: number = COLOR_TOLERANCE,
): boolean {
return (
Math.abs(r - targetRgb[0]) <= tolerance &&
Math.abs(g - targetRgb[1]) <= tolerance &&
Math.abs(b - targetRgb[2]) <= tolerance
);
}
export function getTerrainTypeFromColor(
r: number,
g: number,
b: number,
): TerrainColorKey | null {
for (const [key, config] of Object.entries(TERRAIN_COLORS)) {
if (colorMatchesTerrain(r, g, b, config.rgb)) {
return key as TerrainColorKey;
}
}
return null;
}
export function isGrassZone(r: number, g: number, b: number): boolean {
return (
colorMatchesTerrain(r, g, b, TERRAIN_COLORS.grass1.rgb) ||
colorMatchesTerrain(r, g, b, TERRAIN_COLORS.grass2.rgb) ||
colorMatchesTerrain(r, g, b, TERRAIN_COLORS.grass3.rgb)
);
}
export function getGrassTipColor(
r: number,
g: number,
b: number,
): string | null {
if (colorMatchesTerrain(r, g, b, TERRAIN_COLORS.grass1.rgb)) {
return TERRAIN_COLORS.grass1.grassTipColor;
}
if (colorMatchesTerrain(r, g, b, TERRAIN_COLORS.grass2.rgb)) {
return TERRAIN_COLORS.grass2.grassTipColor;
}
if (colorMatchesTerrain(r, g, b, TERRAIN_COLORS.grass3.rgb)) {
return TERRAIN_COLORS.grass3.grassTipColor;
}
return null;
}
+18
View File
@@ -0,0 +1,18 @@
export type TerrainSurfaceKind =
| "grass"
| "path"
| "water"
| "garden"
| "dirt"
| "rock";
export type TerrainSurfaceRgb = readonly [number, number, number];
export interface TerrainSurfaceColorConfig {
hex: string;
rgb: TerrainSurfaceRgb;
kind: TerrainSurfaceKind;
grassTipColor?: string;
modelPath?: string;
tileSize?: number;
}
+51
View File
@@ -0,0 +1,51 @@
import {
TERRAIN_COLORS,
TERRAIN_SURFACE_COLOR_TOLERANCE,
type TerrainColorKey,
} from "@/data/world/terrainConfig";
import type { TerrainSurfaceRgb } from "@/types/world/terrainSurface";
export function colorMatchesTerrainSurface(
r: number,
g: number,
b: number,
targetRgb: TerrainSurfaceRgb,
tolerance: number = TERRAIN_SURFACE_COLOR_TOLERANCE,
): boolean {
return (
Math.abs(r - targetRgb[0]) <= tolerance &&
Math.abs(g - targetRgb[1]) <= tolerance &&
Math.abs(b - targetRgb[2]) <= tolerance
);
}
export function getTerrainColorKeyFromRgb(
r: number,
g: number,
b: number,
): TerrainColorKey | null {
for (const [key, config] of Object.entries(TERRAIN_COLORS)) {
if (colorMatchesTerrainSurface(r, g, b, config.rgb)) {
return key as TerrainColorKey;
}
}
return null;
}
export function isGrassTerrainColor(r: number, g: number, b: number): boolean {
const key = getTerrainColorKeyFromRgb(r, g, b);
return key !== null && TERRAIN_COLORS[key].kind === "grass";
}
export function getGrassTipColorFromRgb(
r: number,
g: number,
b: number,
): string | null {
const key = getTerrainColorKeyFromRgb(r, g, b);
if (key === null) return null;
const terrainColor = TERRAIN_COLORS[key];
return "grassTipColor" in terrainColor ? terrainColor.grassTipColor : null;
}