feat: expose terrain surface data
🔍 Lint / 🪄 Check lint (pull_request) Has been cancelled
🔍 Lint / 🎨 Check format (pull_request) Has been cancelled
🔍 Lint / 🔎 Typecheck (pull_request) Has been cancelled
📊 Quality / 🔒 Security Audit (pull_request) Has been cancelled
📊 Quality / 📋 Dependency Freshness (pull_request) Has been cancelled
📊 Quality / 📦 Bundle Size (pull_request) Has been cancelled
🔍 Lint / 🏗 Build (pull_request) Has been cancelled
🔍 Lint / 🪄 Check lint (pull_request) Has been cancelled
🔍 Lint / 🎨 Check format (pull_request) Has been cancelled
🔍 Lint / 🔎 Typecheck (pull_request) Has been cancelled
📊 Quality / 🔒 Security Audit (pull_request) Has been cancelled
📊 Quality / 📋 Dependency Freshness (pull_request) Has been cancelled
📊 Quality / 📦 Bundle Size (pull_request) Has been cancelled
🔍 Lint / 🏗 Build (pull_request) Has been cancelled
This commit is contained in:
@@ -2,10 +2,10 @@ import { useEffect, useMemo, useRef } from "react";
|
|||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
import { useGLTF } from "@react-three/drei";
|
import { useGLTF } from "@react-three/drei";
|
||||||
import { useThree } from "@react-three/fiber";
|
import { useThree } from "@react-three/fiber";
|
||||||
|
import { TERRAIN_MODEL_PATH } from "@/data/world/terrainConfig";
|
||||||
import type { Vector3Tuple } from "@/types/three/three";
|
import type { Vector3Tuple } from "@/types/three/three";
|
||||||
import { optimizeGLTFSceneTextures } from "@/utils/three/optimizeGLTFScene";
|
import { optimizeGLTFSceneTextures } from "@/utils/three/optimizeGLTFScene";
|
||||||
|
|
||||||
const TERRAIN_MODEL_PATH = "/models/terrain/model.gltf";
|
|
||||||
const TERRAIN_DEFAULT_POSITION: Vector3Tuple = [0, 0, 0];
|
const TERRAIN_DEFAULT_POSITION: Vector3Tuple = [0, 0, 0];
|
||||||
|
|
||||||
interface TerrainModelProps {
|
interface TerrainModelProps {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import type { TerrainSurfaceColorConfig } from "@/types/world/terrainSurface";
|
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_SURFACE_COLOR_TOLERANCE = 15;
|
||||||
export const TERRAIN_WATER_HEIGHT = 0;
|
export const TERRAIN_WATER_HEIGHT = 0;
|
||||||
export const TERRAIN_TILE_SIZE = 1;
|
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;
|
key: string | null;
|
||||||
config: TerrainSurfaceColorConfig | null;
|
config: TerrainSurfaceColorConfig | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface TerrainSurfaceData {
|
||||||
|
bounds: TerrainSurfaceBounds;
|
||||||
|
imageData: ImageData;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user