Hi there, I’m really hoping that someone can help me.
I’m new to threeJS / React Fiber. I have a model of an animal which I am trying to animate. Essentially when the cursor moves, the animal moves it’s head to watch it. Relatively simple.
I exported the model from Blender in the glb format, used gltfjsx to create a react-friendly format. Everything seems to be working as intended re: rendering.
Where I run into trouble is that when I am attempting to move the skeletal frame (i.e. nodes) it will only work on some nodes (rotates based on cursor position). It seems that as soon as I am targeting a deeply nested node it stops working.
For example:
const boneToModify = nodes["MCH-torsoparent"].children[0].children[0];
// will work fine
const boneToModify = nodes["MCH-torsoparent"].children[0].children[0].children[0].children[0];
// will not work
const boneToModify = nodes["MCH-torsoparent"].getByObjectId(20); // or similar getMethod
// will also not work
I’m wondering if it is something to do with how my glb file is structured but I feel if that were the case then none of the nodes would be able to be modified?
I would really appreciate any help or advice anyone can give. I’ve attached a screenshot showing the structure of my glb file and below you can find the generated jsx file.
Thank you in advance.
Best,
David
import { useRef } from "react";
import { useGLTF, useAnimations } from "@react-three/drei";
import { useFrame, useThree } from "@react-three/fiber";
import { getMouseDegrees } from '@/utils/getMouseDegrees';
import { MathUtils } from "three";
export default function Model({mouse, ...props}) {
const group = useRef()
const { nodes, materials, animations } = useGLTF('/azura3d-transformed.glb')
const { actions } = useAnimations(animations, group);
const moveHead = (mouse, bone, degreeLimit = 40) => {
const degrees = getMouseDegrees(mouse.x,mouse.y,degreeLimit);
bone.rotation.xD = MathUtils.lerp(bone.rotation.xD || 0, degrees.y, 0.1)
bone.rotation.yD = MathUtils.lerp(bone.rotation.yD || 0, degrees.x, 0.1)
bone.rotation.x = MathUtils.degToRad(bone.rotation.xD)
bone.rotation.y = MathUtils.degToRad(bone.rotation.yD)
}
const {size} = useThree();
const boneToModify = nodes['DEF-spine011'];
// const boneToModify = nodes["MCH-torsoparent"].children[0].children[3].children[0];
useFrame((state,delta) => {
const mouse = {x: size.width / 2 + (state.mouse.x * size.width) / 2, y: size.height / 2 + (-state.mouse.y * size.height) / 2}
moveHead(mouse,boneToModify);
boneToModify.rotation.x += 0.01;
// boneToModify.scale.x += 0.01;
})
return (
<group ref={group} {...props} dispose={null}>
<group name="Scene">
<group name="metarig" position={[0, -4.07, 0]} rotation={[0, Math.PI / 2, 0]} scale={6.1}>
<group name="spine004" position={[0, 0.8, -0.44]} rotation={[1.45, 0, 0]}>
<group name="spine003_1" rotation={[-3.03, 0.22, -0.04]}>
<group name="spine002_1" position={[0, 0.13, 0]} rotation={[-0.26, 0.28, -0.14]}>
<group name="spine001_1" position={[0, 0.31, 0]} rotation={[-0.21, 0.39, 0.19]}>
<group name="spine_1" position={[0, 0.16, 0]} rotation={[-0.09, 0.08, -0.26]} />
</group>
</group>
</group>
<group name="spine005" position={[0, 0.09, 0]} rotation={[0.28, 0, 0]}>
<group name="spine006" position={[0, 0.18, 0]} rotation={[-0.12, 0, 0]}>
<group name="spine007" position={[0, 0.15, 0]} rotation={[-0.06, 0, 0]}>
<group name="spine008" position={[0, 0.19, 0]} rotation={[-0.05, 0, 0]}>
<group name="spine009" position={[0, 0.23, 0]} rotation={[-0.48, 0.04, -0.02]}>
<group name="spine010" position={[0, 0.07, 0]} rotation={[-0.03, -0.04, -0.06]}>
<group name="spine011" position={[0, 0.06, 0]} rotation={[0.17, -0.02, 0.1]} />
</group>
</group>
<group name="shoulderL_1" position={[0.06, 0.11, -0.1]} rotation={[1.25, 0.16, -0.33]}>
<group name="front_thighL" position={[0, 0.21, 0.13]} rotation={[0.15, -0.12, 0.35]}>
<group name="front_shinL" position={[0, 0.24, 0]} rotation={[0.5, -0.02, 0.31]}>
<group name="front_footL" position={[0, 0.18, 0]} rotation={[-0.43, 0.16, -0.32]}>
<group name="front_toeL_1" position={[0, 0.27, 0]} rotation={[1.92, 0, -2.56]} />
</group>
</group>
</group>
</group>
<group name="shoulderR_1" position={[-0.06, 0.11, -0.1]} rotation={[1.25, -0.16, 0.33]}>
<group name="front_thighR" position={[0.03, 0.22, 0.12]} rotation={[0.37, 0.04, -0.3]}>
<group name="front_shinR" position={[0, 0.23, 0]} rotation={[0.58, -0.07, -0.3]}>
<group name="front_footR" position={[0, 0.18, 0]} rotation={[-0.78, -0.22, 0.08]}>
<group name="front_toeR_1" position={[0, 0.26, 0]} rotation={[2.09, 0.12, 2.91]} />
</group>
</group>
</group>
</group>
<group name="breastL_1" position={[0.03, 0, 0.11]} rotation={[0.84, 0, 0]} />
<group name="breastR_1" position={[-0.03, 0, 0.11]} rotation={[0.84, 0, 0]} />
</group>
</group>
</group>
<group name="pelvisL" position={[0, 0.01, 0.2]} rotation={[2.34, -1.08, -2.53]} />
<group name="pelvisR" position={[0, 0.01, 0.2]} rotation={[2.34, 1.08, 2.53]} />
<group name="thighL" position={[0.12, 0.02, 0.06]} rotation={[1.49, -0.04, 0.06]}>
<group name="shinL" position={[0, 0.41, 0]} rotation={[1.26, -0.17, -0.07]}>
<group name="footL" position={[0, 0.2, 0]} rotation={[-1.61, 0.06, 0.15]}>
<group name="toeL_1" position={[0, 0.27, 0]} rotation={[2.05, -0.07, -2.94]} />
</group>
</group>
</group>
<group name="thighR" position={[-0.14, 0.02, 0.07]} rotation={[1.16, 0.13, -0.12]}>
<group name="shinR" position={[0, 0.4, 0]} rotation={[0.77, 0.18, -0.02]}>
<group name="footR" position={[0, 0.11, 0]} rotation={[-0.81, 0, 0.05]}>
<group name="toeR_1" position={[0, 0.23, 0]} rotation={[2.04, 0.06, -2.93]} />
</group>
</group>
</group>
</group>
</group>
</group>
<group name="rig" position={[0.01, -4.11, 0]} rotation={[0, 1.57, 0]} scale={5.95}>
<primitive object={nodes.root} />
<primitive object={nodes['MCH-torsoparent']} />
<primitive object={nodes['MCH-front_foot_ikparentL']} />
<primitive object={nodes['MCH-front_thigh_ik_targetparentL']} />
<primitive object={nodes['MCH-front_foot_ikparentR']} />
<primitive object={nodes['MCH-front_thigh_ik_targetparentR']} />
<primitive object={nodes['MCH-foot_ikparentL']} />
<primitive object={nodes['MCH-thigh_ik_targetparentL']} />
<primitive object={nodes['MCH-foot_ikparentR']} />
<primitive object={nodes['MCH-thigh_ik_targetparentR']} />
<group name="Plane">
<skinnedMesh name="Plane_1" geometry={nodes.Plane_1.geometry} material={materials['Material.005']} skeleton={nodes.Plane_1.skeleton} />
<skinnedMesh name="Plane_2" geometry={nodes.Plane_2.geometry} material={materials['Material.002']} skeleton={nodes.Plane_2.skeleton} />
<skinnedMesh name="Plane_3" geometry={nodes.Plane_3.geometry} material={materials['Material.003']} skeleton={nodes.Plane_3.skeleton} />
<skinnedMesh name="Plane_4" geometry={nodes.Plane_4.geometry} material={materials['Material.004']} skeleton={nodes.Plane_4.skeleton} />
</group>
</group>
</group>
</group>
)
}
useGLTF.preload('/azura3d-transformed.glb')