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';