feat: Remove unused GLB models and enhance asset reset functionality

This commit is contained in:
2025-07-07 16:21:21 +05:30
parent 5070ff4060
commit 82ba6d24bc
9 changed files with 105 additions and 87 deletions

View File

@@ -1,83 +1,84 @@
import { useEffect, useMemo } from 'react'
import { useEffect } from 'react'
import * as THREE from "three";
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { clone } from "three/examples/jsm/utils/SkeletonUtils";
import { useLoader } from "@react-three/fiber";
import { useThree } from "@react-three/fiber";
import { CCDIKSolver, CCDIKHelper } from "three/examples/jsm/animation/CCDIKSolver";
import { usePlayButtonStore, useResetButtonStore } from '../../../../../store/usePlayButtonStore';
type IKInstanceProps = {
modelUrl: string;
setIkSolver: any
armBot: ArmBotStatus;
groupRef: any;
};
function IKInstance({ modelUrl, setIkSolver, armBot, groupRef }: IKInstanceProps) {
const gltf = useLoader(GLTFLoader, modelUrl, (loader) => {
const draco = new DRACOLoader();
draco.setDecoderPath("https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/");
loader.setDRACOLoader(draco);
});
const cloned = useMemo(() => clone(gltf?.scene), [gltf]);
function IKInstance({ setIkSolver, armBot }: IKInstanceProps) {
const { scene } = useThree();
const { isPlaying } = usePlayButtonStore();
const { isReset } = useResetButtonStore();
const targetBoneName = "Target";
const skinnedMeshName = "link_0";
useEffect(() => {
if (!gltf) return;
const OOI: any = {};
cloned.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) },
],
},
];
let retryId: NodeJS.Timeout | null = null;
const solver = new CCDIKSolver(OOI.Skinned_Mesh, iks);
setIkSolver(solver);
const trySetup = () => {
const targetMesh = scene?.getObjectByProperty("uuid", armBot.modelUuid);
// const helper = new CCDIKHelper(OOI.Skinned_Mesh, iks, 0.05)
if (!targetMesh) {
retryId = setTimeout(trySetup, 100);
return;
}
// scene.add(helper);
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) },
],
},
];
}, [cloned, gltf]);
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 (
<group ref={groupRef} position={armBot.position} rotation={armBot.rotation}>
<primitive
uuid={`${armBot.modelUuid}_IK`}
object={cloned}
scale={[1, 1, 1]}
name={armBot.modelName}
/>
</group>
<>
</>
)
}