Feat/map-environment #6
@@ -2,10 +2,10 @@ import { useEffect, useMemo, useRef } from "react";
|
||||
import * as THREE from "three";
|
||||
import { useGLTF } from "@react-three/drei";
|
||||
import { useThree } from "@react-three/fiber";
|
||||
import { TERRAIN_MODEL_PATH } from "@/data/world/terrainConfig";
|
||||
import type { Vector3Tuple } from "@/types/three/three";
|
||||
import { optimizeGLTFSceneTextures } from "@/utils/three/optimizeGLTFScene";
|
||||
|
||||
const TERRAIN_MODEL_PATH = "/models/terrain/model.gltf";
|
||||
const TERRAIN_DEFAULT_POSITION: Vector3Tuple = [0, 0, 0];
|
||||
|
||||
interface TerrainModelProps {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { TerrainSurfaceColorConfig } from "@/types/world/terrainSurface";
|
||||
|
||||
export const TERRAIN_MODEL_PATH = "/models/terrain/model.gltf";
|
||||
export const TERRAIN_SURFACE_COLOR_TOLERANCE = 15;
|
||||
export const TERRAIN_WATER_HEIGHT = 0;
|
||||
export const TERRAIN_TILE_SIZE = 1;
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
import { useMemo } from "react";
|
||||
import * as THREE from "three";
|
||||
import { useGLTF } from "@react-three/drei";
|
||||
import { TERRAIN_MODEL_PATH } from "@/data/world/terrainConfig";
|
||||
import type {
|
||||
TerrainSurfaceBounds,
|
||||
TerrainSurfaceData,
|
||||
} from "@/types/world/terrainSurface";
|
||||
import { createTerrainSurfaceImageData } from "@/utils/world/terrainSurfaceSampler";
|
||||
|
||||
function findTerrainBaseColorTexture(
|
||||
scene: THREE.Object3D,
|
||||
): THREE.Texture | null {
|
||||
let texture: THREE.Texture | null = null;
|
||||
|
||||
scene.traverse((child) => {
|
||||
if (texture || !(child instanceof THREE.Mesh)) return;
|
||||
|
||||
const materials = Array.isArray(child.material)
|
||||
? child.material
|
||||
: [child.material];
|
||||
|
||||
for (const material of materials) {
|
||||
if (material instanceof THREE.MeshStandardMaterial && material.map) {
|
||||
texture = material.map;
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
function createTerrainSurfaceBounds(
|
||||
scene: THREE.Object3D,
|
||||
): TerrainSurfaceBounds {
|
||||
scene.updateWorldMatrix(true, true);
|
||||
|
||||
const box = new THREE.Box3().setFromObject(scene);
|
||||
return {
|
||||
minX: box.min.x,
|
||||
maxX: box.max.x,
|
||||
minZ: box.min.z,
|
||||
maxZ: box.max.z,
|
||||
};
|
||||
}
|
||||
|
||||
export function useTerrainSurfaceData(): TerrainSurfaceData | null {
|
||||
const { scene } = useGLTF(TERRAIN_MODEL_PATH);
|
||||
|
||||
return useMemo(() => {
|
||||
const texture = findTerrainBaseColorTexture(scene);
|
||||
if (!texture) return null;
|
||||
|
||||
const imageData = createTerrainSurfaceImageData(texture);
|
||||
if (!imageData) return null;
|
||||
|
||||
return {
|
||||
bounds: createTerrainSurfaceBounds(scene),
|
||||
imageData,
|
||||
};
|
||||
}, [scene]);
|
||||
}
|
||||
@@ -34,3 +34,8 @@ export interface TerrainSurfaceSample {
|
||||
key: string | null;
|
||||
config: TerrainSurfaceColorConfig | null;
|
||||
}
|
||||
|
||||
export interface TerrainSurfaceData {
|
||||
bounds: TerrainSurfaceBounds;
|
||||
imageData: ImageData;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user