feat: Implement ArmReplace component with MultiGLTFInstances for dynamic arm rendering

- Added ArmReplace component to manage the rendering of arm models based on scene objects.
- Integrated MultiGLTFInstances for loading and displaying multiple GLTF models.
- Created findLinkObjects function to traverse the scene and extract positions, rotations, and visibility settings for objects named 'link_0'.
- Utilized useModuleStore to manage active module state and control visibility of arm models.
This commit is contained in:
Vishnu 2025-04-11 13:35:26 +05:30
parent 8ed035b969
commit 0e552f645a
5 changed files with 145 additions and 0 deletions

Binary file not shown.

View File

@ -55,6 +55,7 @@ import DrieHtmlTemp from "../mqttTemp/drieHtmlTemp";
import ZoneGroup from "../../builder/groups/zoneGroup";
import useModuleStore from "../../../store/useModuleStore";
import NavMeshCreator from "../../builder/agv/navMeshCreator";
import ArmReplace from "../../simulation/ik/ArmReplace";
export default function World() {
const state = useThree<Types.ThreeState>(); // Importing the state from the useThree hook, which contains the scene, camera, and other Three.js elements.
@ -370,6 +371,9 @@ export default function World() {
<NavMeshCreator lines={lines} />
{/* replacing exsisting arms with rigged ones */}
<ArmReplace />
</>
);
}

View File

@ -0,0 +1,56 @@
import React, { useEffect } from "react";
import { useThree } from "@react-three/fiber";
// store
import useModuleStore from "../../../store/useModuleStore";
// functions
import { findLinkObjects } from "./functions/findLinkObjects";
// components
import { MultiGLTFInstances } from "./MultiGLTFInstances";
// impory model from model folder
import armModel from "../../../assets/gltf-glb/rigged/ik_arm_4.glb";
// Main component to include the logic
const ArmReplace: React.FC = () => {
const { activeModule } = useModuleStore();
const { scene } = useThree(); // Access the Three.js scene from the React Fiber context
// State to store positions, rotations, and count
const [positions, setPositions] = React.useState<[number, number, number][]>(
[]
);
const [rotations, setRotations] = React.useState<[number, number, number][]>(
[]
);
const [count, setCount] = React.useState<string[]>([]);
useEffect(() => {
// Call the function to find objects and update states
findLinkObjects(
scene,
setPositions,
setRotations,
setCount,
activeModule === "simulation" ? false : true
);
}, [scene, activeModule]); // Re-run this effect if the scene changes or activeModule changes
return (
<>
{count.map((_, i: number) => (
<MultiGLTFInstances
index={i}
modelUrl={armModel}
position={positions[i]}
rotation={rotations[i]}
visibility={activeModule === "simulation" ? false : true}
/>
))}
</>
);
};
export default ArmReplace;

View File

@ -0,0 +1,42 @@
import { useLoader } from "@react-three/fiber";
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
interface MultiGLTFInstancesProps {
index: number;
modelUrl: string;
position: [number, number, number];
rotation: [number, number, number];
visibility?: boolean;
}
export const MultiGLTFInstances: React.FC<MultiGLTFInstancesProps> = ({
index,
modelUrl,
position,
rotation,
visibility
}) => {
const originalGltf = 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 = originalGltf.scene.clone();
cloned.name = `rigged_arm_${index}`; // Set the name of the cloned object
console.log(index);
return (
<>
<primitive
key={index}
object={cloned}
position={position}
scale={[1, 1, 1]}
rotation={rotation}
visible={visibility}
/>
</>
);
};

View File

@ -0,0 +1,43 @@
import { Object3D } from "three";
// Function to find objects named 'link_0' and update positions, rotations, and count
export const findLinkObjects = (
scene: Object3D,
setPositions: React.Dispatch<
React.SetStateAction<[number, number, number][]>
>,
setRotations: React.Dispatch<
React.SetStateAction<[number, number, number][]>
>,
setCount: React.Dispatch<React.SetStateAction<string[]>>,
visibility: boolean
) => {
const positions: [number, number, number][] = [];
const rotations: [number, number, number][] = [];
const count: string[] = [];
let i = 0;
scene.traverse((object) => {
if (object.name === "link_0") {
if (object.parent) {
// count
count[i] = object.uuid;
i++;
// Save the position and rotation of the parent object
const { x: px, y: py, z: pz } = object.parent.position;
positions.push([px, py, pz]);
const { x: rx, y: ry, z: rz } = object.parent.rotation;
rotations.push([rx, ry, rz]);
// Change visibility of the object
object.visible = visibility;
}
}
});
// Update the state with the collected positions, rotations, and count
setPositions(positions);
setRotations(rotations);
setCount(count);
};