예제 #1
0
        // First pass: calculate the transofmration matrix for each vertex
        // here we must associate a matrix with each bone (maybe with each vertex_id??)
        // then we multiply the current_bone matrix with the one we had before
        // (perhaps it was identity, perhaps it was already some matrix (if
        // the bone influences many vertices) )
        // then we store this multiplied matrix.
        // in the render function we get a vertex_id, so we can find the matrix to apply
        // to the vertex, then we send the vertex to OpenGL
        public void RecursiveCalculateVertexTransform(Node nd, Matrix4x4 current)
        {
            Matrix4x4 current_node = current * nd.Transform;

            foreach (int mesh_id in nd.MeshIndices)
            {
                Mesh     cur_mesh  = _scene._inner.Meshes[mesh_id];
                MeshDraw mesh_draw = _mesh_id2mesh_draw[mesh_id];
                foreach (Bone bone in cur_mesh.Bones)
                {
                    // a bone transform is more than by what we need to trasnform the model
                    BoneNode  armature_node   = _scene.GetBoneNode(bone.Name);
                    Matrix4x4 bone_global_mat = armature_node.GlobTrans;
                    /// bind tells the original delta in global coord, so we can find current delta
                    Matrix4x4 bind         = bone.OffsetMatrix;
                    Matrix4x4 delta_roto   = bind * bone_global_mat;
                    Matrix4x4 current_bone = delta_roto * current_node;
                    foreach (var pair in bone.VertexWeights)
                    {
                        // Can apply bone weight here
                        mesh_draw._vertex_id2matrix[pair.VertexID] = current_bone;
                    }
                }
            }
            foreach (Node child in nd.Children)
            {
                RecursiveCalculateVertexTransform(child, current_node);
            }
        }
예제 #2
0
 /// <summary>
 /// Function to blend from one keyframe to another.
 /// </summary>
 public void ChangeLocalFixedDataBlend(ActionState st)
 {
     Debug.Assert(0 <= st.KfBlend && st.KfBlend <= 1);
     foreach (NodeAnimationChannel channel in _action.NodeAnimationChannels)
     {
         BoneNode bone_nd = _scene.GetBoneNode(channel.NodeName);
         // now rotation
         tk.Quaternion target_roto = tk.Quaternion.Identity;
         if (channel.RotationKeyCount > st.TargetKeyframe)
         {
             target_roto = channel.RotationKeys[st.TargetKeyframe].Value.eToOpenTK();
         }
         tk.Quaternion start_frame_roto = channel.RotationKeys[st.OriginKeyframe].Value.eToOpenTK();
         tk.Quaternion result_roto      = tk.Quaternion.Slerp(start_frame_roto, target_roto, (float)st.KfBlend);
         // now translation
         tk.Vector3 target_trans = tk.Vector3.Zero;
         if (channel.PositionKeyCount > st.TargetKeyframe)
         {
             target_trans = channel.PositionKeys[st.TargetKeyframe].Value.eToOpenTK();
         }
         tk.Vector3 cur_trans    = channel.PositionKeys[st.OriginKeyframe].Value.eToOpenTK();
         tk.Vector3 result_trans = cur_trans + tk.Vector3.Multiply(target_trans - cur_trans, (float)st.KfBlend);
         // combine rotation and translation
         tk.Matrix4 result = tk.Matrix4.CreateFromQuaternion(result_roto);
         result.Row3.Xyz  = result_trans;
         bone_nd.LocTrans = result.eToAssimp();
     }
 }