feat: Implement robotic arm material animation and simulation product and event management.

This commit is contained in:
2025-12-29 13:33:06 +05:30
parent d3f82e0cfd
commit 1bb1c31bb8
2 changed files with 35 additions and 43 deletions

View File

@@ -79,13 +79,6 @@ function Products() {
} else {
// SOCKET
console.log({
productName: name,
productUuid: id,
projectId: projectId || "",
versionId: selectedVersion.versionId,
});
simulationSocket.emit("v1:model-product:upsert", {
productName: name,
productUuid: id,

View File

@@ -1,7 +1,6 @@
import { useFrame } from '@react-three/fiber';
import { useEffect, useRef, useState } from 'react';
import * as THREE from 'three';
import { MaterialModel } from '../../../materials/instances/material/materialModel';
import { useEffect, useRef, useState } from "react";
import * as THREE from "three";
import { MaterialModel } from "../../../materials/instances/material/materialModel";
type MaterialAnimatorProps = {
ikSolver: any;
@@ -21,46 +20,46 @@ export default function MaterialAnimator({ ikSolver, armBot, currentPhase }: Rea
}
}, [currentPhase]);
useFrame(() => {
if (!ikSolver || !materialRef.current) return;
useEffect(() => {
if (!isRendered || !materialRef.current || !ikSolver) return;
const boneTarget = ikSolver.mesh.skeleton.bones.find((b: any) => b.name === "Bone004");
const bone = ikSolver.mesh.skeleton.bones.find((b: any) => b.name === "Effector");
if (!boneTarget || !bone) return;
if (!bone || !boneTarget) return;
if (currentPhase === "start-to-end") {
// Get world positions
const boneTargetWorldPos = new THREE.Vector3();
const boneWorldPos = new THREE.Vector3();
boneTarget.getWorldPosition(boneTargetWorldPos);
bone.getWorldPosition(boneWorldPos);
// Calculate initial alignment
const boneTargetWorldPos = new THREE.Vector3();
const boneWorldPos = new THREE.Vector3();
boneTarget.getWorldPosition(boneTargetWorldPos);
bone.getWorldPosition(boneWorldPos);
// Calculate direction
const direction = new THREE.Vector3();
direction.subVectors(boneWorldPos, boneTargetWorldPos).normalize();
const direction = new THREE.Vector3();
direction.subVectors(boneWorldPos, boneTargetWorldPos).normalize();
const adjustedPosition = boneWorldPos.clone().addScaledVector(direction, 0.01);
const adjustedPosition = boneWorldPos.clone().addScaledVector(direction, 0.01);
//set position
materialRef.current.position.copy(adjustedPosition);
// Position material in World Space first to ensure correct snap point
materialRef.current.position.copy(adjustedPosition);
// Set rotation
const worldQuaternion = new THREE.Quaternion();
bone.getWorldQuaternion(worldQuaternion);
materialRef.current.quaternion.copy(worldQuaternion);
}
});
const worldQuaternion = new THREE.Quaternion();
bone.getWorldQuaternion(worldQuaternion);
materialRef.current.quaternion.copy(worldQuaternion);
return (
<>
{isRendered && (
<MaterialModel
materialId={armBot.currentAction?.materialId ?? ''}
matRef={materialRef}
materialType={armBot.currentAction?.materialType ?? 'Default material'}
/>
)}
</>
);
// Attach to Bone to follow it automatically via scene graph
bone.attach(materialRef.current);
// Cleanup on unmount or change: ensure we detach/remove to prevent ghost objects on the bone
return () => {
if (materialRef.current && bone) {
// If the material is still parented to the bone, remove it.
// React will handle the unmounting of the component, but standard parent removal is safer for reparented nodes.
if (materialRef.current.parent === bone) {
bone.remove(materialRef.current);
}
}
};
}, [isRendered, ikSolver]);
return <>{isRendered && <MaterialModel materialId={armBot.currentAction?.materialId ?? ""} matRef={materialRef} materialType={armBot.currentAction?.materialType ?? "Default material"} />}</>;
}