Feat/map-environment #6
+1
-1
@@ -7,7 +7,7 @@ import tseslint from "typescript-eslint";
|
|||||||
import { defineConfig, globalIgnores } from "eslint/config";
|
import { defineConfig, globalIgnores } from "eslint/config";
|
||||||
|
|
||||||
export default defineConfig([
|
export default defineConfig([
|
||||||
globalIgnores(["dist", "POC-grass"]),
|
globalIgnores(["dist"]),
|
||||||
{
|
{
|
||||||
files: ["**/*.{ts,tsx}"],
|
files: ["**/*.{ts,tsx}"],
|
||||||
extends: [
|
extends: [
|
||||||
|
|||||||
+21
-71
@@ -40201,7 +40201,7 @@
|
|||||||
"scale": [1, 1, 1],
|
"scale": [1, 1, 1],
|
||||||
"children": [
|
"children": [
|
||||||
{
|
{
|
||||||
"name": "panneauxcentre",
|
"name": "panneauclassique",
|
||||||
"type": "Object3D",
|
"type": "Object3D",
|
||||||
"role": "group",
|
"role": "group",
|
||||||
"position": [0, 0, 0],
|
"position": [0, 0, 0],
|
||||||
@@ -40209,40 +40209,30 @@
|
|||||||
"scale": [1, 1, 1],
|
"scale": [1, 1, 1],
|
||||||
"children": [
|
"children": [
|
||||||
{
|
{
|
||||||
"name": "panneauxcentre",
|
"name": "panneauclassique",
|
||||||
"type": "Object3D",
|
"type": "Object3D",
|
||||||
"position": [-35.2895, 3.8515, 40.1864],
|
"position": [-35.2895, 3.8515, 40.1864],
|
||||||
"rotation": [-3.0988, 0.9934, -3.1367],
|
"rotation": [-3.0988, 0.9934, -3.1367],
|
||||||
"scale": [1, 1, 1],
|
"scale": [1, 1, 1],
|
||||||
"children": [
|
"children": [
|
||||||
{
|
{
|
||||||
"name": "panneauxcentre",
|
"name": "panneauclassique",
|
||||||
"type": "Mesh",
|
"type": "Mesh",
|
||||||
"position": [-35.2895, 3.8515, 40.1864],
|
"position": [-35.2895, 3.8515, 40.1864],
|
||||||
"rotation": [-3.0988, 0.9934, -3.1367],
|
"rotation": [-3.0988, 0.9934, -3.1367],
|
||||||
"scale": [1, 1, 1]
|
"scale": [1, 1, 1]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "panneauxdomaine",
|
|
||||||
"type": "Object3D",
|
|
||||||
"role": "group",
|
|
||||||
"position": [0, 0, 0],
|
|
||||||
"rotation": [0, 0, 0],
|
|
||||||
"scale": [1, 1, 1],
|
|
||||||
"children": [
|
|
||||||
{
|
{
|
||||||
"name": "panneauxdomaine",
|
"name": "panneauclassique",
|
||||||
"type": "Object3D",
|
"type": "Object3D",
|
||||||
"position": [-2.4347, 3.7803, -56.1439],
|
"position": [-2.4347, 3.7803, -56.1439],
|
||||||
"rotation": [0.0474, 0.2148, -0.0027],
|
"rotation": [0.0474, 0.2148, -0.0027],
|
||||||
"scale": [1, 1, 1],
|
"scale": [1, 1, 1],
|
||||||
"children": [
|
"children": [
|
||||||
{
|
{
|
||||||
"name": "panneauxdomaine",
|
"name": "panneauclassique",
|
||||||
"type": "Mesh",
|
"type": "Mesh",
|
||||||
"position": [-2.4347, 3.7803, -56.1439],
|
"position": [-2.4347, 3.7803, -56.1439],
|
||||||
"rotation": [0.0474, 0.2148, -0.0027],
|
"rotation": [0.0474, 0.2148, -0.0027],
|
||||||
@@ -40253,7 +40243,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "panneaudirresidences2",
|
"name": "panneaufleche",
|
||||||
"type": "Object3D",
|
"type": "Object3D",
|
||||||
"role": "group",
|
"role": "group",
|
||||||
"position": [0, 0, 0],
|
"position": [0, 0, 0],
|
||||||
@@ -40261,118 +40251,78 @@
|
|||||||
"scale": [1, 1, 1],
|
"scale": [1, 1, 1],
|
||||||
"children": [
|
"children": [
|
||||||
{
|
{
|
||||||
"name": "panneaudirresidences2",
|
"name": "panneaufleche",
|
||||||
"type": "Object3D",
|
"type": "Object3D",
|
||||||
"position": [30.1743, 7.1944, -13.5781],
|
"position": [30.1743, 7.1944, -13.5781],
|
||||||
"rotation": [0.0374, -1.297, -0.0099],
|
"rotation": [0.0374, -1.297, -0.0099],
|
||||||
"scale": [1, 1, 1],
|
"scale": [1, 1, 1],
|
||||||
"children": [
|
"children": [
|
||||||
{
|
{
|
||||||
"name": "panneaudirresidences2",
|
"name": "panneaufleche",
|
||||||
"type": "Mesh",
|
"type": "Mesh",
|
||||||
"position": [30.1743, 7.1944, -13.5781],
|
"position": [30.1743, 7.1944, -13.5781],
|
||||||
"rotation": [0.0374, -1.297, -0.0099],
|
"rotation": [0.0374, -1.297, -0.0099],
|
||||||
"scale": [1, 1, 1]
|
"scale": [1, 1, 1]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "panneaudirdomaine",
|
|
||||||
"type": "Object3D",
|
|
||||||
"role": "group",
|
|
||||||
"position": [0, 0, 0],
|
|
||||||
"rotation": [0, 0, 0],
|
|
||||||
"scale": [1, 1, 1],
|
|
||||||
"children": [
|
|
||||||
{
|
{
|
||||||
"name": "panneaudirdomaine",
|
"name": "panneaufleche",
|
||||||
"type": "Object3D",
|
"type": "Object3D",
|
||||||
"position": [8.1032, 7.1918, -23.0004],
|
"position": [8.1032, 7.1918, -23.0004],
|
||||||
"rotation": [0.0462, -0.2443, -0.0027],
|
"rotation": [0.0462, -0.2443, -0.0027],
|
||||||
"scale": [1, 1, 1],
|
"scale": [1, 1, 1],
|
||||||
"children": [
|
"children": [
|
||||||
{
|
{
|
||||||
"name": "panneaudirdomaine",
|
"name": "panneaufleche",
|
||||||
"type": "Mesh",
|
"type": "Mesh",
|
||||||
"position": [8.1032, 7.1918, -23.0004],
|
"position": [8.1032, 7.1918, -23.0004],
|
||||||
"rotation": [0.0462, -0.2443, -0.0027],
|
"rotation": [0.0462, -0.2443, -0.0027],
|
||||||
"scale": [1, 1, 1]
|
"scale": [1, 1, 1]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "panneaudirresidences1",
|
|
||||||
"type": "Object3D",
|
|
||||||
"role": "group",
|
|
||||||
"position": [0, 0, 0],
|
|
||||||
"rotation": [0, 0, 0],
|
|
||||||
"scale": [1, 1, 1],
|
|
||||||
"children": [
|
|
||||||
{
|
{
|
||||||
"name": "panneaudirresidences1",
|
"name": "panneaufleche",
|
||||||
"type": "Object3D",
|
"type": "Object3D",
|
||||||
"position": [-10.1125, 7.2582, -11.4511],
|
"position": [-10.1125, 7.2582, -11.4511],
|
||||||
"rotation": [0.0478, 0.3436, -0.0028],
|
"rotation": [0.0478, 0.3436, -0.0028],
|
||||||
"scale": [1, 1, 1],
|
"scale": [1, 1, 1],
|
||||||
"children": [
|
"children": [
|
||||||
{
|
{
|
||||||
"name": "panneaudirresidences1",
|
"name": "panneaufleche",
|
||||||
"type": "Mesh",
|
"type": "Mesh",
|
||||||
"position": [-10.1125, 7.2582, -11.4511],
|
"position": [-10.1125, 7.2582, -11.4511],
|
||||||
"rotation": [0.0478, 0.3436, -0.0028],
|
"rotation": [0.0478, 0.3436, -0.0028],
|
||||||
"scale": [1, 1, 1]
|
"scale": [1, 1, 1]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "panneaudircentre",
|
|
||||||
"type": "Object3D",
|
|
||||||
"role": "group",
|
|
||||||
"position": [0, 0, 0],
|
|
||||||
"rotation": [0, 0, 0],
|
|
||||||
"scale": [1, 1, 1],
|
|
||||||
"children": [
|
|
||||||
{
|
{
|
||||||
"name": "panneaudircentre",
|
"name": "panneaufleche",
|
||||||
"type": "Object3D",
|
"type": "Object3D",
|
||||||
"position": [-10.5207, 7.0874, 19.3819],
|
"position": [-10.5207, 7.0874, 19.3819],
|
||||||
"rotation": [-3.1416, 1.5139, -3.0947],
|
"rotation": [-3.1416, 1.5139, -3.0947],
|
||||||
"scale": [1, 1, 1],
|
"scale": [1, 1, 1],
|
||||||
"children": [
|
"children": [
|
||||||
{
|
{
|
||||||
"name": "panneaudircentre",
|
"name": "panneaufleche",
|
||||||
"type": "Mesh",
|
"type": "Mesh",
|
||||||
"position": [-10.5207, 7.0874, 19.3819],
|
"position": [-10.5207, 7.0874, 19.3819],
|
||||||
"rotation": [-3.1416, 1.5139, -3.0947],
|
"rotation": [-3.1416, 1.5139, -3.0947],
|
||||||
"scale": [1, 1, 1]
|
"scale": [1, 1, 1]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "panneaudirfabrik",
|
|
||||||
"type": "Object3D",
|
|
||||||
"role": "group",
|
|
||||||
"position": [0, 0, 0],
|
|
||||||
"rotation": [0, 0, 0],
|
|
||||||
"scale": [1, 1, 1],
|
|
||||||
"children": [
|
|
||||||
{
|
{
|
||||||
"name": "panneaudirfabrik",
|
"name": "panneaufleche",
|
||||||
"type": "Object3D",
|
"type": "Object3D",
|
||||||
"position": [29.0899, 6.9811, 23.4988],
|
"position": [29.0899, 6.9811, 23.4988],
|
||||||
"rotation": [3.1416, -0.8852, 3.1253],
|
"rotation": [3.1416, -0.8852, 3.1253],
|
||||||
"scale": [1, 1, 1],
|
"scale": [1, 1, 1],
|
||||||
"children": [
|
"children": [
|
||||||
{
|
{
|
||||||
"name": "panneaudirfabrik",
|
"name": "panneaufleche",
|
||||||
"type": "Mesh",
|
"type": "Mesh",
|
||||||
"position": [29.0899, 6.9811, 23.4988],
|
"position": [29.0899, 6.9811, 23.4988],
|
||||||
"rotation": [3.1416, -0.8852, 3.1253],
|
"rotation": [3.1416, -0.8852, 3.1253],
|
||||||
|
|||||||
@@ -10,6 +10,13 @@ const MESH_NAME_MAPPINGS = {
|
|||||||
eoliennes: "eolienne",
|
eoliennes: "eolienne",
|
||||||
immeuble_1: "immeuble1",
|
immeuble_1: "immeuble1",
|
||||||
buissons: "buisson",
|
buissons: "buisson",
|
||||||
|
panneauxcentre: "panneauclassique",
|
||||||
|
panneauxdomaine: "panneauclassique",
|
||||||
|
panneaudircentre: "panneaufleche",
|
||||||
|
panneaudirdomaine: "panneaufleche",
|
||||||
|
panneaudirfabrik: "panneaufleche",
|
||||||
|
panneaudirresidences1: "panneaufleche",
|
||||||
|
panneaudirresidences2: "panneaufleche",
|
||||||
panneauxquartier: "panneauaffichage",
|
panneauxquartier: "panneauaffichage",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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 = {
|
export const TERRAIN_COLORS = {
|
||||||
grass1: {
|
grass1: {
|
||||||
hex: "#84C66B",
|
hex: "#84C66B",
|
||||||
rgb: [132, 198, 107] as const,
|
rgb: [132, 198, 107] as const,
|
||||||
type: "grass" as const,
|
kind: "grass",
|
||||||
grassTipColor: "#84C66B",
|
grassTipColor: "#84C66B",
|
||||||
},
|
},
|
||||||
grass2: {
|
grass2: {
|
||||||
hex: "#67B058",
|
hex: "#67B058",
|
||||||
rgb: [103, 176, 88] as const,
|
rgb: [103, 176, 88] as const,
|
||||||
type: "grass" as const,
|
kind: "grass",
|
||||||
grassTipColor: "#67B058",
|
grassTipColor: "#67B058",
|
||||||
},
|
},
|
||||||
grass3: {
|
grass3: {
|
||||||
hex: "#A3CA5B",
|
hex: "#A3CA5B",
|
||||||
rgb: [163, 202, 91] as const,
|
rgb: [163, 202, 91] as const,
|
||||||
type: "grass" as const,
|
kind: "grass",
|
||||||
grassTipColor: "#A3CA5B",
|
grassTipColor: "#A3CA5B",
|
||||||
},
|
},
|
||||||
potager: {
|
potager: {
|
||||||
hex: "#342420",
|
hex: "#342420",
|
||||||
rgb: [52, 36, 32] as const,
|
rgb: [52, 36, 32] as const,
|
||||||
type: "tile" as const,
|
kind: "garden",
|
||||||
tileModel: "/models/potager/potager.gltf",
|
modelPath: "/models/potager/potager.gltf",
|
||||||
tileSize: 1,
|
tileSize: TERRAIN_TILE_SIZE,
|
||||||
},
|
},
|
||||||
terre: {
|
terre: {
|
||||||
hex: "#513E2C",
|
hex: "#513E2C",
|
||||||
rgb: [81, 62, 44] as const,
|
rgb: [81, 62, 44] as const,
|
||||||
type: "none" as const,
|
kind: "dirt",
|
||||||
},
|
},
|
||||||
chemin: {
|
chemin: {
|
||||||
hex: "#F5D896",
|
hex: "#F5D896",
|
||||||
rgb: [245, 216, 150] as const,
|
rgb: [245, 216, 150] as const,
|
||||||
type: "tile" as const,
|
kind: "path",
|
||||||
tileModel: "/models/chemins/model.gltf",
|
modelPath: "/models/chemins/model.gltf",
|
||||||
tileSize: 1,
|
tileSize: TERRAIN_TILE_SIZE,
|
||||||
},
|
},
|
||||||
eau: {
|
eau: {
|
||||||
hex: "#91DAF5",
|
hex: "#91DAF5",
|
||||||
rgb: [145, 218, 245] as const,
|
rgb: [145, 218, 245] as const,
|
||||||
type: "water" as const,
|
kind: "water",
|
||||||
},
|
},
|
||||||
cailloux: {
|
cailloux: {
|
||||||
hex: "#B6D3DE",
|
hex: "#B6D3DE",
|
||||||
rgb: [182, 211, 222] as const,
|
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 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;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user