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:
BIN
app/src/assets/gltf-glb/rigged/ik_arm_4.glb
Normal file
BIN
app/src/assets/gltf-glb/rigged/ik_arm_4.glb
Normal file
Binary file not shown.
@@ -55,6 +55,7 @@ import DrieHtmlTemp from "../mqttTemp/drieHtmlTemp";
|
|||||||
import ZoneGroup from "../../builder/groups/zoneGroup";
|
import ZoneGroup from "../../builder/groups/zoneGroup";
|
||||||
import useModuleStore from "../../../store/useModuleStore";
|
import useModuleStore from "../../../store/useModuleStore";
|
||||||
import NavMeshCreator from "../../builder/agv/navMeshCreator";
|
import NavMeshCreator from "../../builder/agv/navMeshCreator";
|
||||||
|
import ArmReplace from "../../simulation/ik/ArmReplace";
|
||||||
|
|
||||||
export default function World() {
|
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.
|
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} />
|
<NavMeshCreator lines={lines} />
|
||||||
|
|
||||||
|
{/* replacing exsisting arms with rigged ones */}
|
||||||
|
<ArmReplace />
|
||||||
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
56
app/src/modules/simulation/ik/ArmReplace.tsx
Normal file
56
app/src/modules/simulation/ik/ArmReplace.tsx
Normal 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;
|
||||||
42
app/src/modules/simulation/ik/MultiGLTFInstances.tsx
Normal file
42
app/src/modules/simulation/ik/MultiGLTFInstances.tsx
Normal 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}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
43
app/src/modules/simulation/ik/functions/findLinkObjects.ts
Normal file
43
app/src/modules/simulation/ik/functions/findLinkObjects.ts
Normal 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);
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user