170 likes | 342 Vues
Explore the fundamentals of BVH (Biovision Hierarchy) animation, which consists of motion capture data structured in two parts: hierarchy and motion data. The hierarchy is formatted like a scene graph, depicting parent-child relationships, while the motion data quantifies the movement through frames and associated floating-point values. This guide delves into the process of parsing BVH data, rendering skeletal animation using shaders, and implementing motion with efficient GPU handling. Ideal for those keen on animation technology and motion capture systems.
E N D
Animation from BVH Andrew Slatton
Biovision Hierarchy (BVH) • Contains motion capture data • 2 Major Components: • Hierarchy • Formatted like a scene graph with parents, children, etc. • Motion data • Number of frames, frame time • A list of floating point values associated with “channels” of the hierarchy nodes
BVH • Example of Hierarchy: HIERARCHY ROOT Hips { OFFSET -0.347901 96.7718 1.79791 CHANNELS 6 Xposition Yposition Zposition Zrotation Xrotation Yrotation JOINT LeftUpLeg { OFFSET 8.91 -6.27 -2.145 CHANNELS 3 Zrotation Xrotation Yrotation JOINT LeftUpLegRoll { OFFSET 0 -22.7323 0 CHANNELS 3 Zrotation Xrotation Yrotation } … }
BVH • Motion data example: MOTION Frames: 119 Frame Time: 0.0416667 -0.347901 96.7718 1.79791 3.45611 -6.10769 -4.18959 -9.22955 -11.0645 -5.78911 6.6312e-019 -6.8208e-017 1.11403 -8.04373e-008 27.9673 4.94512 1.63315e-017 -3.38117e-016 5.53064 1.94131 -9.21066 0.156389 1.74467e-007 -1.06026e-007 3.22852e-016 -6.86092 -9.75453 -1.61311 8.22385e-018 -2.40073e-016 3.92388 -7.54458e-006 75.9784 0.826967 …
BVH Motion Data • List of values • Each value corresponds to a rotation or translation channel • Listed in same order as hierarchy was parsed • [Joint0, Channel0] [Joint0, Channel1] [Joint1, Channel0] [Joint1, Channel1] [Joint1, Channel2] … • [X, Y, Z] x [Rotation, Translation]
Project Steps • BVH Parser • Needs to read in and handle hierarchy, motion data • Similar to writing any other parser, so no need to discuss • Skeleton drawing • Could handle this mostly in CPU or mostly in GPU • I chose GPU
Drawing the Skeleton • High level implementation: • On CPU: • Send skeleton object a time • Skeleton object computes what frame should be displayed at that time • Skeleton object sends appropriate data to shader • Shaders handle everything else
Drawing the Skeleton • Vertex Shader • Given motion and hierarchy data • Computes positions of joints for the desired frame • Geometry Shader • Given joint locations • Computes vertex positions and normals for limbs • Fragment Shader • Phong illumination of limbs
Drawing the Skeleton • Shader uniform variables: • Motion data for desired frame • Joint offsets • Channel ordering • Could be Xrot, Yrot, Zrot, OR Zrot, Yrot, Xrot (or any other order) • Parent pointers • Must apply ancestors’ transforms to find a joint’s location • Motion data pointers • Some joints span six indices of motion data, some three, and some zero
Generating Limbs: Simplest Method: Draw a sphere at the location of each joint Doesn’t give a vivid picture of the motion Drawing the Skeleton
Drawing the Skeleton • Generating Limbs: • Could make a cylinder about each ParentJoint-ChildJoint segment • Notice the discontinuities at joints. This is ugly.
Drawing the Skeleton • Generating Limbs: • Quick fix for final result • Rotate y = x*x – 1 about each limb axis
Odds and Ends • Could implement animation as loop that stops only when animation is complete: while(!skel.last_frame()) { skel.set_frame(elapsed_time); DrawScene(); } • This locks up CPU • No good if we want to allow keyboard/mouse inputs during animation • Also, won’t work with glutPostRedisplay() because we must exit the loop before glutMainLoop can call glutDisplayFunction
Odds and Ends • Use glutTimerFunc ! Animate(int delay){ skel.set_frame(elapsed_time); glutPostRedisplay(); if(!skel.last_frame()) { glutTimerFunc(delay,Animate,delay); }} • Will call Animate once every delay milliseconds until we reach end of animation • Allows glutMainLoop to continue execution during this delay time