85 lines
2.8 KiB
TypeScript
85 lines
2.8 KiB
TypeScript
import { useEffect } from 'react'
|
|
import * as THREE from "three";
|
|
import { useThree } from "@react-three/fiber";
|
|
import { CCDIKSolver, CCDIKHelper } from "three/examples/jsm/animation/CCDIKSolver";
|
|
import { usePlayButtonStore, useResetButtonStore } from '../../../../../store/usePlayButtonStore';
|
|
|
|
type IKInstanceProps = {
|
|
setIkSolver: any
|
|
armBot: ArmBotStatus;
|
|
};
|
|
|
|
function IKInstance({ setIkSolver, armBot }: IKInstanceProps) {
|
|
const { scene } = useThree();
|
|
const { isPlaying } = usePlayButtonStore();
|
|
const { isReset } = useResetButtonStore();
|
|
const targetBoneName = "Target";
|
|
const skinnedMeshName = "link_0";
|
|
|
|
useEffect(() => {
|
|
let retryId: NodeJS.Timeout | null = null;
|
|
|
|
const trySetup = () => {
|
|
const targetMesh = scene?.getObjectByProperty("uuid", armBot.modelUuid);
|
|
|
|
if (!targetMesh) {
|
|
retryId = setTimeout(trySetup, 100);
|
|
return;
|
|
}
|
|
|
|
const OOI: any = {};
|
|
targetMesh.traverse((n: any) => {
|
|
if (n.name === targetBoneName) OOI.Target_Bone = n;
|
|
if (n.name === skinnedMeshName) OOI.Skinned_Mesh = n;
|
|
});
|
|
if (!OOI.Target_Bone || !OOI.Skinned_Mesh) return;
|
|
const iks = [
|
|
{
|
|
target: 7,
|
|
effector: 6,
|
|
links: [
|
|
{
|
|
index: 5,
|
|
enabled: true,
|
|
rotationMin: new THREE.Vector3(-Math.PI / 2, 0, 0),
|
|
rotationMax: new THREE.Vector3(Math.PI / 2, 0, 0),
|
|
},
|
|
{
|
|
index: 4,
|
|
enabled: true,
|
|
rotationMin: new THREE.Vector3(-Math.PI / 2, 0, 0),
|
|
rotationMax: new THREE.Vector3(0, 0, 0),
|
|
},
|
|
{
|
|
index: 3,
|
|
enabled: true,
|
|
rotationMin: new THREE.Vector3(0, 0, 0),
|
|
rotationMax: new THREE.Vector3(2, 0, 0),
|
|
},
|
|
{ index: 1, enabled: true, limitation: new THREE.Vector3(0, 1, 0) },
|
|
{ index: 0, enabled: false, limitation: new THREE.Vector3(0, 0, 0) },
|
|
],
|
|
},
|
|
];
|
|
|
|
const solver = new CCDIKSolver(OOI.Skinned_Mesh, iks);
|
|
setIkSolver(solver);
|
|
|
|
// const helper = new CCDIKHelper(OOI.Skinned_Mesh, iks, 0.05)
|
|
// scene.add(helper);
|
|
};
|
|
|
|
trySetup();
|
|
|
|
return () => {
|
|
if (retryId) clearTimeout(retryId);
|
|
};
|
|
}, [isPlaying, isReset]);
|
|
|
|
return (
|
|
<>
|
|
</>
|
|
)
|
|
}
|
|
|
|
export default IKInstance; |