Subscribe to GameDev.net Direct to receive the latest updates and exclusive content.
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.
Posted 15 December 2008 - 04:19 AM
Posted 15 December 2008 - 11:37 PM
A joint is a transform which is the basic node of a kinematic skeleton. A
hierarchy of joints is a kinematics skeleton. In a 3D view, a joint is drawn
as a combination of three circles perpendicular to each other. If a joint is
the child of another joint, a bone is drawn between them.
The joint node is derived from the transform node, so it inherits some of its
basic transformation from its parent node (see the documentation for transform
node for details). Many elements in the inherited transformation matrix have
been suppressed so the following invariances are maintained:
rotatePivot = 0
rotatePivotTranslate = 0
scalePivot = 0
scalePivotTranslate = 0
shear = 0
There are also attributes used only by joint nodes. The transformation matrix
for a joint node is below.
matrix = [S] * [RO] * [R] * [JO] * [IS] * [T]
(where '*' denotes matrix multiplication).
[S]: scale.
[RO]: Rotate Orient (attribute name is rotateAxis).
[R]: rotate.
[JO]: jointOrient.
[IS]: parentScaleInverse.
[T]: translate.
transform nodes are dagNodes that are used to group and transform other
dagNodes. All dagNodes that are not transform nodes in Maya must exist as a
child of some transform node.
Transformation Matrix (DAG)
transform nodes have many attributes that make up the final transformation
matrix as represented by the matrix attribute. This breakdown provides
animators fine control over the animation of these parameters. Therefore, it is
necessary to describe the order in which these attributes are applied to build
the final matrix attribute.
Note: matrices are post-multiplied in Maya. For example, to transform a point
p from object-space to world-space you would need to post-multiply by the
worldMatrix. (p' = p * wm)
-1 -1
matrix = SP * S * SH * SP * ST * RP * RA * R * RP * RT * T
(where '*' denotes matrix multiplication and '-1' denotes matrix inversion'
SP = | 1 0 0 0 | ST = | 1 0 0 0 |
| 0 1 0 0 | | 0 1 0 0 |
| 0 0 1 0 | | 0 0 1 0 |
| spx spy spz 1 | | sptx spty sptz 1 |
S = | sx 0 0 0 | SH = | 1 0 0 0 |
| 0 sy 0 0 | | shxy 1 0 0 |
| 0 0 sz 0 | | shxz shyz 1 0 |
| 0 0 0 1 | | 0 0 0 1 |
RP = | 1 0 0 0 | RT = | 1 0 0 0 |
| 0 1 0 0 | | 0 1 0 0 |
| 0 0 1 0 | | 0 0 1 0 |
| rpx rpy rpz 1 | | rptx rpty rptz 1 |
RA = AX * AY * AZ
AX = | 1 0 0 0 | AY = | cy 0 -sy 0 |
| 0 cx sx 0 | | 0 1 0 0 |
| 0 -sx cx 0 | | sy 0 cy 0 |
| 0 0 0 1 | | 0 0 0 1 |
AZ = | cz sz 0 0 | sx = sin(rax), cx = cos(rax)
| -sz cz 0 0 | sy = sin(ray), cx = cos(ray)
| 0 0 1 0 | sz = sin(raz), cz = cos(raz)
| 0 0 0 1 |
Rotate:
If the rotationInterpolation attribute specifies quaternion
interpolation, use the following OpenMaya API calls to construct
the matrix:
Mquaternion q( rx, ry, rz, rw )
R = q.asMatrix()
Otherwise, for Euler-angle rotation use:
R = RX * RY * RZ (Note: order is determined by rotateOrder)
RX = | 1 0 0 0 | RY = | cy 0 -sy 0 |
| 0 cx sx 0 | | 0 1 0 0 |
| 0 -sx cx 0 | | sy 0 cy 0 |
| 0 0 0 1 | | 0 0 0 1 |
RZ = | cz sz 0 0 | sx = sin(rx), cx = cos(rx)
| -sz cz 0 0 | sy = sin(ry), cx = cos(ry)
| 0 0 1 0 | sz = sin(rz), cz = cos(rz)
| 0 0 0 1 |
T = | 1 0 0 0 |
| 0 1 0 0 |
| 0 0 1 0 |
| tx ty tz 1 |
Posted 16 December 2008 - 03:56 AM
Posted 16 December 2008 - 11:21 PM
Quote:
Original post by texel3d
You say i have just have to that to get relative rotation:
TotalRot = Pre * Rot * Post
Quote:
If i use:
TotalRot = Pre * Rot * Post
to compute relative rotation of my bone at a given frame of animation i will have something different from the Identity Matrix because of the RotZ = 90 in the PreRotation.
Quote:
And a multiplication of 3 quaternions is a "cumulation of rotation". I will have a TotalRot with a rotation of 90 around Z.
Quote:
But i should have an identity matrix because joint1 never move in my animation and it's a relative rotation.
Posted 18 December 2008 - 04:00 AM
Posted 18 December 2008 - 04:26 AM
Posted 19 December 2008 - 03:51 AM
Quote:
1) All joint have a local space. And the local space of joint "n" is not the translation of the local space of joint "n-1" among the x axis + a rotation. It's not like in other program like Ligthwave (maybe because in this program, joint are more dependant from their parent).
Quote:
2) The rotation value stored in curves seems to be the relative rotation around the local space of each joint.
Quote:
3) The local space of joint seems to be defined with PreRotation...
Quote:
...If i take an animation with no relative rotation (all joint stay in BindPose), Prerotation should give me the Bind Pose of each joint. if i forget translation, and PostRotation (PostRotation is always 0 in my example) for the time beeing, i could find the BindPose orientation of each joint.
Quote:
4) If i transform a bone defined by the points [(0,0,0)(1,0,0)] with the preRotation of joint "n" converted to matrix, i should get a bone oriented in the same orientation as the bone of joint "n" (but not translated in the good place). It works with joint0 but not for the over joints. So "TotalRot = Pre * Rot * Post" seems to be a simplified way to mean something i do not understand.
Quote:
4) It seems that if i try to convert PreRotation to Quaternion and if i cumulate them and if i transform the world space axis using:
PreRotation(0)*PreRotation(1)*...*PreRotation(n) for joint n, i get the axis defining the local space. It works for joint 0,1,2 bur not for joint3. If think i am wrong. I don't know where. I try to compute my quaternion using AxisRotation to Quaternion with this order: "x" first, "z" after , and after "y" of PreRotation.
Even without any code, but just my mind, i don't succed in finding the local space of each joints from PreRotation. It seems to be the cumulation of each PreRotation (0 to n) where each PreRotation start around X, Z and after Y, but... not always.
Quote:
5) I will try to find what is PostRotation, but after having understand what PreRotation is exactly.
Posted 19 December 2008 - 05:07 AM
int frameNbr = 0;
GLGXVECTOR4 vec4Start; // Bone Start
GLGXVECTOR4 vec4End; // Bone End
GLGXVECTOR3 vec3Start(0.0f,0.0f,0.0f); // Bone Start
GLGXVECTOR3 vec3End(1.0f,0.0f,0.0f); // Bone End
for( int bone = 0; bone < int(m_vBones.size()); ++bone)
{
// Translation
GLGXMATRIX matTranslation;
if( m_vBones[bone]->Parent != NULL)
matTranslation._41 = 1.0f; // Length of bone = 1.0f
// Scale
// Alawys 1.0f => Identity Matrix => not usefull (for my example file)
// Pivot
// Always 0.0 => Identity Matrix => not usefull (for my example file)
// Rotation = PreRotation * Rotation * PostRotation
GLGXQUATERNION quaternion;
GLGXQuaternionMultiply(&quaternion,&m_vBones[bone]->vSequenceKeys[frameNbr].RelativeRotation,&m_vBones[bone]->m_QuatPreRotation);
GLGXQuaternionMultiply(&quaternion,&m_vBones[bone]->m_QuatPostRotation,&quaternion);
GLGXMATRIX matrixRotation;
GLGXMatrixRotationQuaternion( &matrixRotation, &quaternion );
// Combinaison of matrices
GLGXMATRIX matrix;
GLGXMatrixMultiply(&matrix,&matTranslation,&matrixRotation);
// Add parent matrix is parent exist
m_vBones[bone]->m_FinalMatrix = matrix;
if( m_vBones[bone]->Parent != NULL)
{
GLGXMatrixMultiply(&m_vBones[bone]->m_FinalMatrix,&m_vBones[bone]->Parent->m_FinalMatrix,&m_vBones[bone]->m_FinalMatrix);
}
GLGXVec3Transform(&vec4Start,&vec3Start,&m_vBones[bone]->m_FinalMatrix);
GLGXVec3Transform(&vec4End,&vec3End,&m_vBones[bone]->m_FinalMatrix);
}
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.
GameDev.net™, the GameDev.net logo, and GDNet™ are trademarks of GameDev.net, LLC.