Cambridge Part IIA Project
GF5 — Animating 3D Characters
From skeletons and skinning to a complete animated scene
Built and extended a 3D character-animation pipeline, progressing from forward kinematics and skinning to motion generation, retargeting, scene composition, camera control and final rendering.
The Return
A short martial-arts scene between a former student and his old master. The interesting work was the technical pipeline that made the scene hold together — generating, sequencing and blending motion, routing characters through the world and rendering it as a finished film.
Animation pipeline
Skeletons & forward kinematics
We first built the underlying animation system: a hierarchical skeleton where child joints inherit their parents' transforms. Forward kinematics propagates local joint rotations and translations through the skeleton to give world-space joint positions.
Skinning
We implemented and compared one-hot skinning, which binds each vertex to a single dominant joint, and linear blend skinning, where several joints influence a vertex through weighted transforms for smoother deformation around joints. We also visualised skinning weights to see how each joint influenced the mesh.
Custom motion
A custom 15-keyframe backflip was an early stress test for the whole stack — FK propagation, large joint rotations, root motion, skinning deformation and arm / leg / spine behaviour.
Motion generation
For the final animation, almost all fight motion was generated with HY-Motion 1.0 rather than relying only on the provided library. We:
- Broke the fight into individual physical actions
- Wrote and refined motion prompts
- Generated several motion variants
- Selected the best clips
- Converted them into the GF5 24-joint motion format
- Combined the clips into a coherent fight
Motion composition & synchronisation
Generating clips was not enough — they had to be composed. We separated body motion from character root paths so the same action could be positioned, rotated and timed independently in the world, letting the two fighters meet at the same contact points and react to punches, falls and knockbacks on time.
Camera system
A major extension: we replaced the preset camera with a keyframed camera system. Each key controls time, position, look-at target and field of view, interpolated to pace the scene.
3D root motion / Z-axis
Personal contribution
The original scene editor only allowed root paths in X and Y. I extended it to full X, Y and Z root positions, so we could animate falls, lifts, knockbacks and characters leaving the ground.
I also debugged an FK issue where the renderer mishandled the root joint because its parent index was stored as -1, leaving characters floating at the wrong height. I fixed the root-joint handling and normalised every root waypoint to [x, y, z] — a fix that spanned animation data, FK and the renderer.
SMPL / SMPL-X
The course system used a coarse 24-joint SMPL skeleton. For the final scene we also worked on an optional 55-joint SMPL-X path adding finger chains, jaw and eyes — useful because the martial-arts motion relied on open palms, fists, grabbing and hand gestures. I worked on retargeting between the 24-joint motion representation and the richer SMPL-X skeleton.
Avatars & assets
We generated custom avatars with UP2You and connected them to the existing animation skeleton. We also adapted the asset pipeline so imported .obj / .mtl objects could be converted into the GF5 asset format and attached to character joints.
Environment rendering
Rather than a flat background, we projected background images onto floor, walls and sky, with perspective projection and clipping so the environment stayed aligned with the camera during movement. The engineering goal was that editor preview and final render should match.
Problems I actually had to solve
Floating characters
Traced to incorrect root handling in forward kinematics and missing Z-axis scene controls.
Mesh / skeleton misalignment
Fixed by correctly accounting for the rest-pose joint position during skinning transforms.
Motion timing
Adjusted clip start, trim and blend windows repeatedly until attacks and reactions aligned.
Preview vs final render
Debugged inconsistencies so camera, root paths and backgrounds behaved consistently in both.
What I personally worked on
- Debugging and fixing floating-character / root-placement problems
- Implementing Z-axis root-path editing
- Improving forward-kinematics handling
- Motion timing and synchronisation
- Tuning clip trims and blend windows
- Prompt engineering for difficult HY-Motion actions
- Working on the SMPL-X 55-joint extension
- Understanding and debugging skinning / FK code
- Experimenting with GLB asset importing
- Investigating the MotionX motion-capture dataset
- Final video editing
- Music and audio integration
I had earlier implemented the core FK and skinning pipeline, which made it possible to debug these later issues across the entire animation stack.
Experiments that did not ship
GLB Import
I prototyped direct .glb loading so mesh, materials and textures came in one file. It worked, but the lightweight editor preview couldn't display the geometry reliably enough, so we kept the OBJ/MTL pipeline.
MotionX
I obtained access to the MotionX dataset for its richer 55-joint motion including fingers, but there wasn't time to integrate and retarget it properly before submission, so HY-Motion stayed the practical choice.
What the project built up
3D Animation / Graphics
Motion
Character Systems
Scene & Rendering
Engineering / Development
Creative / Production
Department of Engineering Third-Year Project Prize
Top-scoring GF5 project in the cohort · Competition winner