![]() |
||||||
|
|
||||||
|
Armature
This tutorial describes how to use the new Armature object to support bone systems. 1. Export a model from Blender For this step the Blenderexporter should be copied into the Blenders script directory,also a rigged and skinned model is needed. Here are some links: Cute Bear (the skinning is not good for quaternions) Katorlegaz Tux (works without reskinning) Load the model and select one or more mesh objects that should be exported. Select the Lumina exporter from File->Export->Lumina and enter a filename with *.lum extension. 2. Load the exported model in Lumina Open the exported File wit Lumina. A node with some objects should be shown in the tree. If changes on the model are needed, reexport the model from blender and open it in Lumina, the old tree contend and the new from the file will be merged in the tree. Stop all script that access the old objects. Delete the old objects and drag the new on theire place. Just remove unneeded nodes and save it as a new file. 3. Write a render script and vertex shader Luminas Armature support two different types of bone system interfaces. One is based on a array of 4x4 matrices that works with normal meshes. The 4x4 matrices supports rotation, translation, scale and shear. (Scale and shear makes trouble, because they deform the normal matrix) First the script:
The vertex shader:
That is simple to understand: Up to 4 matrices from Pose will be weighted. The fraction value of Bones[i] the weight and the integer part the index. (On ATI cards could it be that a int() cast is needed) All positions, normals and tangents must be multiplied with this matrix to applie the Bone deformations. Don't forged the brackets to avoid expensive matrix * matrix multiplictions. The position needs to be multiplied with the full 4x4 matrix. Normal and Tangent only with the upper left 3x3 part. (The mat3 cast could make problems on ATI cards) Update: It is recommend to use two different attributes for the Bone. The first should be a 4 dimensinal unsigned byte vector for the bone ID (use short if more than 255 bones are required) and the second should be 4 dimensional normalized unsigned byte vector for the weight. In that case use this code:
A small fragment shader displays the normal vector and white dots for the vertices:
The second one is quaternion and joint based, that needs a special mesh, where the vertex position is relative to joints encoded. (The Blender exporter creates that stream with name "RelToJoint") The advantage are that the vertex interpolation is not linear like the linear like the matrix variant, the position could be calculated on a circular curve. So knees and elbows didn't get unnatural deformed on sharp angles. The LERP (SLERP isn't needed in vertexshaders) interpolation is very fast because it needs only a few MADDs and a normalization. The disadvantages are that the handling of quaternions is more complex than matrices, but there are well known optimized functions, for multiply two quaternions and rotate a vector. To use a quaternion based transformation replace the Matrices function in the script by the joint and quaternion function and the "Vertex" by "RelToJoint":
The vertex shader is a little bit more complex, but faster than the matrix version:
First up to 4 quaternions will be weighted like the matrices, but that is 4 times faster, because for each quaternion is only a single MADD instruction needed. The normalization is needed for a correct rotation. The relative to the joint position Vertex will be rotated around that joint, by the weighted quaternion and the joint position will be added to get transformed position in post bone space. This vertex can be multiplied with the gl_ModelViewProjectionMatrix like every other vertex position. The normal and Tangent vectors must be rotated by the quaternion too. This is a little bit inefficient, but in later tutorial I will demonstrate how it's possible to replace the gl_NormalMatrix, gl_Normal, Tangent, Bitangend and the normalmaps by quaternions. 4. Animation To animate the model, the first step is to rename all bones with illegal chars like whitespaces and dots in their names. Each Bone has some methods: Rotate(x, y, z, w); Rotate a bone with quaternion (x;y;z;w) around the joint. (x;y;z) are the Vector part and w the Scalar part. Rotation(x, y, z, w); Set the rotation to quaternion (x;y;z;w). Example: Rotation(0, 0, 0, 1) rotates a bone into initial position. EulerRotate(a, b, c); This function rotates a bone by Euler angles in Radians. EulerRotation(a, b, c); This function set the rotation of a bone to Euler angles in Radians. To reset all Bones to initial position call the armatures Reset() function. With this functions it should be possible to write a script that could interpret simple mocap data files
The right leg is rotated by a (-SQRT(2),0,0,SQRT(2)) quaternion |
||||||
|
|
|
|
|
|
|
|