Spaces:
Sleeping
Sleeping
File size: 2,315 Bytes
1afe868 ca23eb9 1afe868 7994c21 1afe868 fce499e 1afe868 e95d66b 7994c21 e95d66b ca23eb9 e95d66b 7994c21 ca23eb9 ec43676 20ba9a1 ec43676 7994c21 7f7b2cc ca23eb9 5438f67 8d694b6 ca23eb9 7f7b2cc c6ef322 8d694b6 7f7b2cc 1bc1cd0 e95d66b 7994c21 e95d66b 1afe868 e95d66b 1bc1cd0 ca23eb9 c6ef322 1bc1cd0 c6ef322 fce499e c6ef322 1bc1cd0 1afe868 1bc1cd0 e95d66b 7994c21 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
'use client';
import { RoundedBox } from '@react-three/drei';
import { forwardRef, useEffect, useImperativeHandle, useRef } from 'react';
import { Mesh } from 'three';
import { Color2Index, CubeColors, FacingDirection, Rotations } from './consts';
import { rotationController } from './rotation-controller';
export type CubePieceRef = {
resetPosition: () => void;
};
type CubePieceProps = {
roughness: number;
initialPosition: [number, number, number];
};
export const CubePiece = forwardRef<CubePieceRef, CubePieceProps>(({ roughness, initialPosition }, ref) => {
const [x, y, z] = initialPosition;
const meshRef = useRef<Mesh | null>(null);
useEffect(() => {
if (meshRef.current) {
rotationController.addCube(meshRef.current);
}
}, [meshRef]);
useImperativeHandle(ref, () => ({
resetPosition: () => {
meshRef.current?.position.set(x, y, z);
meshRef.current?.rotation.set(0, 0, 0);
},
}));
const visibleFaces: Record<FacingDirection, boolean> = {
front: z > 0,
back: z < 0,
left: x < 0,
right: x > 0,
up: y > 0,
down: y < 0,
};
const positions: Record<FacingDirection, [number, number, number]> = {
front: [0, 0, 0.48],
back: [0, 0, -0.48],
right: [0.48, 0, 0],
left: [-0.48, 0, 0],
up: [0, 0.48, 0],
down: [0, -0.48, 0],
};
return (
<mesh position={[x, y, z]} ref={meshRef}>
<RoundedBox args={[0.95, 0.95, 0.95]} radius={0.05} smoothness={4}>
<meshStandardMaterial color="#2a2a2a" metalness={1} roughness={roughness} />
</RoundedBox>
{Object.entries(visibleFaces).map(([face, isVisible]) => {
if (!isVisible) return null;
const color = CubeColors[face as keyof typeof CubeColors];
return (
<mesh
key={face}
position={positions[face as FacingDirection]}
rotation={Rotations[face as FacingDirection]}
userData={{
isFace: true,
faceColor: color,
faceColorIndex: Color2Index[color],
}}
>
<planeGeometry args={[0.8, 0.8]} />
<meshStandardMaterial color={color} metalness={1} roughness={roughness} />
</mesh>
);
})}
</mesh>
);
});
CubePiece.displayName = 'CubePiece';
|