feat: Enhance IK handling in Model and IKInstance components with improved data structure and validation

This commit is contained in:
2025-07-09 13:38:06 +05:30
parent 8c69aa52db
commit 65ef6839a0
3 changed files with 40 additions and 32 deletions

View File

@@ -81,7 +81,8 @@ function Model({ asset }: { readonly asset: Asset }) {
if (!ikData && asset.eventData && asset.eventData.type === 'ArmBot') { if (!ikData && asset.eventData && asset.eventData.type === 'ArmBot') {
getAssetIksApi(asset.assetId).then((data) => { getAssetIksApi(asset.assetId).then((data) => {
if (data.iks) { if (data.iks) {
setIkData(data.iks); const iks: IK[] = data.iks;
setIkData(iks);
} }
}) })
} }
@@ -463,7 +464,7 @@ function Model({ asset }: { readonly asset: Asset }) {
position={asset.position} position={asset.position}
rotation={asset.rotation} rotation={asset.rotation}
visible={asset.isVisible} visible={asset.isVisible}
userData={asset} userData={{ ...asset, iks: ikData }}
onDoubleClick={(e) => { onDoubleClick={(e) => {
e.stopPropagation(); e.stopPropagation();
if (!toggleView) { if (!toggleView) {

View File

@@ -22,7 +22,7 @@ function IKInstance({ setIkSolver, armBot }: IKInstanceProps) {
const trySetup = () => { const trySetup = () => {
const targetMesh = scene?.getObjectByProperty("uuid", armBot.modelUuid); const targetMesh = scene?.getObjectByProperty("uuid", armBot.modelUuid);
if (!targetMesh) { if (!targetMesh || !targetMesh.userData.iks || targetMesh.userData.iks.length < 1) {
retryId = setTimeout(trySetup, 100); retryId = setTimeout(trySetup, 100);
return; return;
} }
@@ -33,34 +33,22 @@ function IKInstance({ setIkSolver, armBot }: IKInstanceProps) {
if (n.name === skinnedMeshName) OOI.Skinned_Mesh = n; if (n.name === skinnedMeshName) OOI.Skinned_Mesh = n;
}); });
if (!OOI.Target_Bone || !OOI.Skinned_Mesh) return; if (!OOI.Target_Bone || !OOI.Skinned_Mesh) return;
const iks = [
{ const rawIks: IK[] = targetMesh.userData.iks;
target: 7, const iks = rawIks.map((ik) => ({
effector: 6, target: ik.target,
links: [ effector: ik.effector,
{ links: ik.links.map((link) => ({
index: 5, index: link.index,
enabled: true, enabled: link.enabled,
rotationMin: new THREE.Vector3(-Math.PI / 2, 0, 0), rotationMin: link.rotationMin ? new THREE.Vector3(...link.rotationMin) : undefined,
rotationMax: new THREE.Vector3(Math.PI / 2, 0, 0), rotationMax: link.rotationMax ? new THREE.Vector3(...link.rotationMax) : undefined,
}, limitation: link.limitation ? new THREE.Vector3(...link.limitation) : undefined,
{ })),
index: 4, ringRadius: ik.ringRadius,
enabled: true, maxheight: ik.maxheight,
rotationMin: new THREE.Vector3(-Math.PI / 2, 0, 0), minheight: ik.minheight,
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); const solver = new CCDIKSolver(OOI.Skinned_Mesh, iks);
setIkSolver(solver); setIkSolver(solver);

View File

@@ -286,4 +286,23 @@ interface MaterialHistoryEntry {
removedAt: string; removedAt: string;
} }
type MaterialHistorySchema = MaterialHistoryEntry[]; type MaterialHistorySchema = MaterialHistoryEntry[];
//IK
type Link = {
index: number;
enabled: boolean;
rotationMin?: [number, number, number];
rotationMax?: [number, number, number];
limitation?: [number, number, number];
};
type IK = {
target: number;
effector: number;
links: Link[];
ringRadius?: number;
maxheight?: number;
minheight?: number;
} ;