65 lines
1.4 KiB
TypeScript
65 lines
1.4 KiB
TypeScript
import React, { useRef } from "react";
|
|
import * as THREE from "three";
|
|
import { ThreeEvent } from "@react-three/fiber";
|
|
|
|
interface PickDropProps {
|
|
position: number[];
|
|
modelUuid: string;
|
|
pointUuid: string;
|
|
actionType: "pick" | "drop";
|
|
actionUuid: string;
|
|
gltfScene: THREE.Group;
|
|
|
|
handlePointerDown: (e: ThreeEvent<PointerEvent>) => void;
|
|
isSelected: boolean;
|
|
}
|
|
|
|
const PickDropPoints: React.FC<PickDropProps> = ({
|
|
position,
|
|
modelUuid,
|
|
pointUuid,
|
|
actionType,
|
|
actionUuid,
|
|
gltfScene,
|
|
handlePointerDown,
|
|
isSelected,
|
|
}) => {
|
|
|
|
|
|
const groupRef = useRef<THREE.Group>(null);
|
|
|
|
return (
|
|
<group
|
|
ref={groupRef}
|
|
position={
|
|
Array.isArray(position) && position.length === 3
|
|
? new THREE.Vector3(...position)
|
|
: new THREE.Vector3(0, 0, 0)
|
|
}
|
|
onPointerDown={(e) => {
|
|
|
|
e.stopPropagation(); // Prevent event bubbling
|
|
if (!isSelected) return;
|
|
handlePointerDown(e);
|
|
}}
|
|
userData={{ modelUuid, pointUuid, actionType, actionUuid }}
|
|
>
|
|
<primitive
|
|
object={(() => {
|
|
const cloned = gltfScene.clone();
|
|
cloned.traverse((child: any) => {
|
|
if (child.isMesh) {
|
|
child.userData = { modelUuid, pointUuid, actionType, actionUuid };
|
|
}
|
|
});
|
|
return cloned;
|
|
})()}
|
|
position={[0, 0, 0]}
|
|
scale={[0.5, 0.5, 0.5]}
|
|
/>
|
|
</group>
|
|
);
|
|
};
|
|
|
|
export default PickDropPoints;
|