Refactor Human3DSkeleton component to support frame-based animation, allowing for customizable start frame and frame rate. Remove deprecated Joints component for cleaner code. Update instance in Scene to reflect new props.

This commit is contained in:
2025-03-27 16:14:27 +08:00
parent eaee23df40
commit 8bcefd93bc

View File

@ -256,15 +256,39 @@ const Scene = () => {
} }
interface Human3DSkeletonProps { interface Human3DSkeletonProps {
index: number startFrame?: number
jointRadius?: number jointRadius?: number
boneRadius?: number boneRadius?: number
showJoints?: boolean showJoints?: boolean
showBones?: boolean showBones?: boolean
frameRate?: number
} }
const Human3DSkeleton = ({ index, jointRadius = 0.01, boneRadius = 0.005, showJoints = true, showBones = true }: Human3DSkeletonProps) => { const Human3DSkeleton = ({
const joints = POSE_3D[index] startFrame = 0,
jointRadius = 0.01,
boneRadius = 0.005,
showJoints = true,
showBones = true,
frameRate = 30
}: Human3DSkeletonProps) => {
const [frameIndex, setFrameIndex] = useState(startFrame)
const totalFrames = POSE_3D.length
// Use frame to animate through the skeleton poses
useFrame((state, delta) => {
// Calculate next frame based on desired frame rate and delta time
setFrameIndex(prevFrame => {
// Calculate next frame
const nextFrame = prevFrame + frameRate * delta
// Loop back to start if we reach the end
return nextFrame >= totalFrames ? 0 : nextFrame
})
})
// Get the current frame joints - use Math.floor to get the nearest frame
const currentFrame = Math.floor(frameIndex) % totalFrames
const joints = POSE_3D[currentFrame]
// Function to get appropriate color for a joint index // Function to get appropriate color for a joint index
const getJointColor = (idx: number) => { const getJointColor = (idx: number) => {
@ -370,16 +394,6 @@ const Scene = () => {
) )
} }
interface JointsProps {
index: number
radius?: number
}
// Keep the old Joints component for compatibility
const Joints = ({ index, radius }: JointsProps) => {
return <Human3DSkeleton index={index} jointRadius={radius} />
}
const scene = (<group> const scene = (<group>
{/* <OrbitControls /> */} {/* <OrbitControls /> */}
<ambientLight intensity={0.05} /> <ambientLight intensity={0.05} />
@ -393,14 +407,13 @@ const Scene = () => {
return <CameraViewFromExtrinsic key={key} name={`${key}(${fov_x.toFixed(1)})`} extrinsic={preProcessExtrinsic(value)} fov={fov_x} aspect={IMAGE_WIDTH / IMAGE_HEIGHT} far={far} /> return <CameraViewFromExtrinsic key={key} name={`${key}(${fov_x.toFixed(1)})`} extrinsic={preProcessExtrinsic(value)} fov={fov_x} aspect={IMAGE_WIDTH / IMAGE_HEIGHT} far={far} />
})} })}
<Axes /> <Axes />
<Human3DSkeleton index={12} jointRadius={0.01} boneRadius={0.005} /> <Human3DSkeleton jointRadius={0.005} boneRadius={0.0025} frameRate={24} />
</group>) </group>)
return ( return (
// Note that we don't need to import anything, All three.js objects will be treated // Note that we don't need to import anything, All three.js objects will be treated
// as native JSX elements, just like you can just write <div /> or <span /> in // as native JSX elements, just like you can just write <div /> or <span /> in
// regular ReactDOM. The general rule is that Fiber components are available under // regular ReactDOM. The general rule is that Fiber components are available under
// the camel-case version of their name in three.js. // the camel-case version of their name in three.js.
<> <>
<CameraControls /> <CameraControls />
<Stats /> <Stats />