<template></template>

<script lang="ts" setup>
import {
  FrontSide,
  Mesh,
  MeshPhysicalMaterial,
  PlaneGeometry,
  RepeatWrapping,
  TextureLoader,
  Vector2,
} from "three";
import { useRender, useTree } from "../hook/use-stage";
import { subgroupName } from "../container";
import { useLineBBox } from "../hook/use-getter";
import { EXRLoader } from "three/examples/jsm/Addons.js";
import { pickPromise } from "@/utils/shared";

const geometry = new PlaneGeometry(1, 1);
const padding = 100;
const tileSize = 100;
const bbox = useLineBBox();
const size = bbox.value.size.clone().add({ x: padding * 2, y: padding * 2 });
const tileCount = size.clone().multiplyScalar(1 / tileSize);

const texloads: Promise<void>[] = [];
const loadTex = (loader: TextureLoader | EXRLoader, url: string) => {
  const { promise, resolve, reject } = pickPromise<void>();
  texloads.push(promise);
  const tex = loader.load(
    `/static/models/texture/ground/${url}`,
    () => resolve(),
    undefined,
    reject
  );

  tex.wrapS = RepeatWrapping;
  tex.wrapT = RepeatWrapping;
  tex.repeat.copy(tileCount);

  return tex;
};

const texLoader = new TextureLoader();
const exrLoader = new EXRLoader();

const diffuseMap = loadTex(texLoader, "laminate_floor_02_diff_1k.jpg");
const displacementMap = loadTex(texLoader, "laminate_floor_02_disp_1k.png");
const normalMap = loadTex(exrLoader, "laminate_floor_02_nor_gl_1k.exr");
const roughnessMap = loadTex(exrLoader, "laminate_floor_02_rough_1k.exr");

const render = useRender();
Promise.all(texloads).then(render);

const material = new MeshPhysicalMaterial({
  // 基础属性
  color: 0xffffff, // 基础颜色（会被贴图覆盖）
  map: diffuseMap, // 颜色贴图

  // 物理渲染属性
  roughness: 0.7, // 基础粗糙度（会被粗糙度贴图调整）
  metalness: 0.0, // 木材无金属性
  clearcoat: 0.1, // 轻微清漆效果
  clearcoatRoughness: 0.2,

  // 贴图增强
  normalMap: normalMap, // 法线贴图
  normalScale: new Vector2(1, 1), // 法线强度

  displacementMap: displacementMap, // 置换贴图
  displacementScale: 0.05, // 置换强度（根据实际效果调整）
  displacementBias: -0.02,

  roughnessMap: roughnessMap, // 粗糙度贴图

  // 其他设置
  side: FrontSide,
  transparent: false,
  premultipliedAlpha: false,
});

const ground = new Mesh(geometry, material);
ground.receiveShadow = true;
ground.name = subgroupName;
ground.scale.set(size.x, size.y, 1);
ground.rotateX(-Math.PI / 2);

useTree().value = ground;
</script>
