diff --git a/app/src/assets/gltf-glb/rigged/ik_arm_4.glb b/app/src/assets/gltf-glb/rigged/ik_arm_4.glb new file mode 100644 index 0000000..92ea5f6 Binary files /dev/null and b/app/src/assets/gltf-glb/rigged/ik_arm_4.glb differ diff --git a/app/src/modules/scene/world/world.tsx b/app/src/modules/scene/world/world.tsx index df7f9c0..8743030 100644 --- a/app/src/modules/scene/world/world.tsx +++ b/app/src/modules/scene/world/world.tsx @@ -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(); // 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() { + {/* replacing exsisting arms with rigged ones */} + + ); } diff --git a/app/src/modules/simulation/ik/ArmReplace.tsx b/app/src/modules/simulation/ik/ArmReplace.tsx new file mode 100644 index 0000000..092f781 --- /dev/null +++ b/app/src/modules/simulation/ik/ArmReplace.tsx @@ -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([]); + + 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 ( + <> + {useModuleStore.getState().activeModule === "simulation" && + count.map((_, i: number) => ( + + ))} + + ); +}; + +export default ArmReplace; diff --git a/app/src/modules/simulation/ik/MultiGLTFInstances.tsx b/app/src/modules/simulation/ik/MultiGLTFInstances.tsx new file mode 100644 index 0000000..7a1812d --- /dev/null +++ b/app/src/modules/simulation/ik/MultiGLTFInstances.tsx @@ -0,0 +1,43 @@ +import { useLoader } from "@react-three/fiber"; +import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader"; +import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"; +import { clone } from "three/examples/jsm/utils/SkeletonUtils"; + +interface MultiGLTFInstancesProps { + index: number; + modelUrl: string; + position: [number, number, number]; + rotation: [number, number, number]; +} + +export const MultiGLTFInstances: React.FC = ({ + index, + modelUrl, + position, + rotation, +}) => { + // Load GLTF model with DRACO loader for compression + 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); + }); + + // Clone the model for independent transformations + const cloned = clone(originalGltf.scene); + + // Render the cloned model + return ( + + + + ); +}; diff --git a/app/src/modules/simulation/ik/functions/findLinkObjects.ts b/app/src/modules/simulation/ik/functions/findLinkObjects.ts new file mode 100644 index 0000000..bd38dd7 --- /dev/null +++ b/app/src/modules/simulation/ik/functions/findLinkObjects.ts @@ -0,0 +1,43 @@ +import { Object3D, Vector3 } 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>, + 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 && object.type !== "SkinnedMesh") { + // 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); +};