111 lines
2.5 KiB
TypeScript
111 lines
2.5 KiB
TypeScript
import * as THREE from "three";
|
|
import { useLoader } from "@react-three/fiber";
|
|
import { CoinProps } from "@/types/coin";
|
|
import { Suspense, useEffect, useMemo } from "react";
|
|
|
|
const SafeEdgeMaterial = ({
|
|
color,
|
|
edge,
|
|
}: Pick<CoinProps, "edge" | "color">) => {
|
|
try {
|
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
const edgeTexture: THREE.Texture = useLoader(
|
|
THREE.TextureLoader,
|
|
edge.picture,
|
|
);
|
|
edgeTexture.repeat = new THREE.Vector2(2, 1);
|
|
edgeTexture.offset = new THREE.Vector2(0.5, 0);
|
|
edgeTexture.wrapS = THREE.MirroredRepeatWrapping;
|
|
edgeTexture.wrapT = THREE.MirroredRepeatWrapping;
|
|
|
|
return (
|
|
<Suspense
|
|
fallback={
|
|
<meshStandardMaterial
|
|
metalness={1}
|
|
roughness={0.5}
|
|
color={color}
|
|
attach="material-0"
|
|
/>
|
|
}
|
|
>
|
|
<meshStandardMaterial
|
|
map={edgeTexture}
|
|
metalness={1}
|
|
roughness={0.5}
|
|
attach="material-0"
|
|
/>
|
|
</Suspense>
|
|
);
|
|
} catch {
|
|
return (
|
|
<meshStandardMaterial
|
|
metalness={1}
|
|
roughness={0.5}
|
|
color={color}
|
|
attach="material-0"
|
|
/>
|
|
);
|
|
}
|
|
};
|
|
|
|
export const CoinInstance = ({
|
|
orientation,
|
|
size,
|
|
thickness,
|
|
color,
|
|
obverse,
|
|
shape,
|
|
reverse,
|
|
edge,
|
|
}: CoinProps) => {
|
|
const sides = useMemo(() => {
|
|
return 32;
|
|
const parsed = Number(/(\d+)/.exec(shape)?.[0]);
|
|
return Math.min(32, Math.max(4, isNaN(parsed) ? 32 : parsed));
|
|
}, [shape]);
|
|
//const edgeTexture = useLoader(THREE.TextureLoader, edge.picture);
|
|
const obverseTexture: THREE.Texture = useLoader(
|
|
THREE.TextureLoader,
|
|
obverse.picture,
|
|
);
|
|
const reverseTexture: THREE.Texture = useLoader(
|
|
THREE.TextureLoader,
|
|
reverse.picture,
|
|
);
|
|
|
|
useEffect(() => {
|
|
if (orientation === "medal") {
|
|
reverseTexture.center = new THREE.Vector2(0.5, 0.5);
|
|
reverseTexture.rotation = Math.PI;
|
|
}
|
|
}, [orientation, reverseTexture]);
|
|
|
|
return (
|
|
<>
|
|
<cylinderBufferGeometry
|
|
attach="geometry"
|
|
args={[
|
|
(size ?? 16) / 16,
|
|
(size ?? 16) / 16,
|
|
(thickness ?? 2) / 16,
|
|
sides,
|
|
]}
|
|
/>
|
|
<SafeEdgeMaterial color={color} edge={edge} />
|
|
<meshStandardMaterial
|
|
metalness={1}
|
|
roughness={0.5}
|
|
map={obverseTexture}
|
|
attach="material-1"
|
|
/>
|
|
<meshStandardMaterial
|
|
metalness={1}
|
|
roughness={0.5}
|
|
map={reverseTexture}
|
|
attach="material-2"
|
|
/>
|
|
</>
|
|
);
|
|
};
|