import { ThreeElements } from "@react-three/fiber";
import { type FC, type PropsWithChildren, useRef, useState, useMemo } from "react";
import { Vector3, DoubleSide } from "three";
import { HexCoordProps } from "../../lib/hex";
import { MAP_HEIGHT } from "../../lib/map";
export type HexTileProps = {
// todo
} & HexCoordProps & ThreeElements['group'] & PropsWithChildren;
const HexTile: FC<HexTileProps> = ({ children, q = 0, r = 0, ...props }) => {
const hexRef = useRef<THREE.Mesh>(null!);
const [hovered, setHovered] = useState(false);
const vertices: Vector3[] = [];
for (var i = 0; i < 6; ++i) {
// generate vertices of a perfect hexagonal plane based on a center point (q, r) and radius
const angle = (i / 6) * Math.PI * 2;
const x = q + 1 * Math.cos(angle);
const z = r + 1 * Math.sin(angle);
vertices.push(new Vector3(x, MAP_HEIGHT, z));
}
const memoizeVertices = useMemo(() => {
return Float32Array.from(
new Array(vertices.length)
.fill(0)
.flatMap((_, index) => vertices[index].toArray()));
}, [q, r])
return (
<group {...props} position={[q, MAP_HEIGHT, r]}>
<mesh
ref={hexRef}
onPointerOver={() => setHovered(true)}
onPointerOut={() => setHovered(false)}
>
<bufferGeometry attach="geometry">
<bufferAttribute
args={[memoizeVertices, 7]}
attach={"attributes-position"}
itemSize={3}
count={vertices.length}
/>
</bufferGeometry>
<meshBasicMaterial attach="material" side={DoubleSide} color={hovered ? '#85e6c5': '#c8ffe0'} />
</mesh>
{children}
</group>
);
};
export default HexTile;