99 lines
No EOL
2.9 KiB
TypeScript
99 lines
No EOL
2.9 KiB
TypeScript
import { Euler, Vector3, BufferGeometry, MaterialParameters, Side } from "three";
|
|
import { ThreeEvent } from "@react-three/fiber";
|
|
|
|
export interface BaseMeshProps {
|
|
geometry: BufferGeometry;
|
|
position?: Vector3;
|
|
rotation?: Euler;
|
|
colour?: string;
|
|
opacity?: number;
|
|
metalness?: number;
|
|
roughness?: number;
|
|
wireframe?: boolean;
|
|
frameColour?: string;
|
|
materialType?: "standard" | "basic";
|
|
materialProps?: Partial<MaterialParameters>;
|
|
materialOverride?: React.ReactNode;
|
|
side?: Side;
|
|
depthWrite?: boolean;
|
|
depthTest?: boolean;
|
|
renderOrder?: number;
|
|
onClick?: (event: ThreeEvent<MouseEvent>) => void;
|
|
}
|
|
|
|
export default function BaseMesh(props: BaseMeshProps) {
|
|
const {
|
|
geometry,
|
|
position,
|
|
rotation,
|
|
colour = "#fff",
|
|
opacity = 1,
|
|
metalness = 0,
|
|
roughness = 1,
|
|
wireframe = false,
|
|
frameColour = "black",
|
|
materialType,
|
|
materialProps,
|
|
materialOverride,
|
|
side,
|
|
depthWrite = true,
|
|
depthTest = true,
|
|
renderOrder = 0,
|
|
onClick,
|
|
} = props;
|
|
|
|
const isTransparent = opacity < 1;
|
|
|
|
const buildMaterial = () => {
|
|
if (materialOverride) return materialOverride;
|
|
switch (materialType) {
|
|
case "basic":
|
|
return (
|
|
<meshBasicMaterial
|
|
color={colour}
|
|
transparent={isTransparent}
|
|
opacity={opacity}
|
|
depthWrite={depthWrite}
|
|
depthTest={depthTest}
|
|
side={side}
|
|
{...materialProps}
|
|
/>
|
|
);
|
|
|
|
case "standard":
|
|
default:
|
|
return (
|
|
<meshStandardMaterial
|
|
color={colour}
|
|
metalness={metalness}
|
|
roughness={roughness}
|
|
transparent={isTransparent}
|
|
opacity={opacity}
|
|
depthWrite={depthWrite}
|
|
depthTest={depthTest}
|
|
side={side}
|
|
{...materialProps}
|
|
/>
|
|
);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<group position={position} rotation={rotation} renderOrder={renderOrder}>
|
|
{/* Main surface */}
|
|
<mesh geometry={geometry} onClick={onClick} renderOrder={renderOrder}>
|
|
{buildMaterial()}
|
|
</mesh>
|
|
|
|
{/* Optional wireframe overlay */}
|
|
{wireframe && (
|
|
<mesh geometry={geometry} renderOrder={renderOrder}>
|
|
<meshStandardMaterial
|
|
wireframe
|
|
color={frameColour}
|
|
/>
|
|
</mesh>
|
|
)}
|
|
</group>
|
|
);
|
|
} |