示例#1
0
        /**
         * @brief Stores the current clip into a Unity .anim file
         * Important: If you use your own character with blend shapes, you have to make sure it is
         * set to 'legacy' animation type. You can do this by the following steps in Unity3D:
         * 1. In the 'project' window in the Assets hierarchy, click on your fbx model
         * 2. In the Inspector, you should see now the Import Settings of your model.
         * 3. Select in these Import Settings in the 'Rig' tab for the 'Animation Type' the value 'Legacy'
         */
        public AnimationClip GetClipAsAnim(string path)
        {
            bool have_t_pose = false;

            if (m_TPose != null && m_TPose.m_joints != null)
            {
                if (m_TPose.m_joints.Count != m_GameObjectTransformations.Count)
                {
                    Debug.LogError("tpose and model do not have the same number of transformations (" + m_TPose.m_joints.Count + "!="
                                   + m_GameObjectTransformations.Count + ")");
                    return(null);
                }
                have_t_pose = true;
            }
            else
            {
                Debug.LogWarning("tpose missing");
            }

            AnimationClip animation_clip = new AnimationClip();

            // Not all of them might actually be used, since not all of them might be a target
            AnimationCurve [] translation_x_curves = new AnimationCurve[m_GameObjectTransformations.Count];
            AnimationCurve [] translation_y_curves = new AnimationCurve[m_GameObjectTransformations.Count];
            AnimationCurve [] translation_z_curves = new AnimationCurve[m_GameObjectTransformations.Count];
            AnimationCurve [] rotation_x_curves    = new AnimationCurve[m_GameObjectTransformations.Count];
            AnimationCurve [] rotation_y_curves    = new AnimationCurve[m_GameObjectTransformations.Count];
            AnimationCurve [] rotation_z_curves    = new AnimationCurve[m_GameObjectTransformations.Count];
            AnimationCurve [] rotation_w_curves    = new AnimationCurve[m_GameObjectTransformations.Count];
            AnimationCurve [] bs_curves            = new AnimationCurve[m_GameObjectBlendshapes.Count];

            Clip clip = m_clip.Duplicate();

            if (m_normalize_headpose)
            {
                clip.NormalizeHeadPoseAllClip();
            }

            Debug.Log("nr of clip states: " + clip.NumStates());
            for (int frame_nr = 0; frame_nr < clip.NumStates(); frame_nr++)
            {
                if (!clip[frame_nr].TrackingSuccessful())
                {
                    Debug.Log("skipping clip state");
                    continue;
                }

                // get frame time
                float time = (float)(clip[frame_nr].Timestamp() - clip[0].Timestamp()) * 0.001f;                 // time is in ms

                // evaluate transformation
                TransformationValue [] transformation_values = null;
                if (have_t_pose)
                {
                    transformation_values = Utils.EvaluateTargetTransformations(m_Retargeting, clip.Rig(), clip[frame_nr], m_TPose.m_joints);
                }
                else
                {
                    transformation_values = Utils.EvaluateTargetTransformations(m_Retargeting, clip.Rig(), clip[frame_nr], m_GameObjectTransformations);
                }

                int key_index = -1;
                if (transformation_values.Length == m_GameObjectTransformations.Count)
                {
                    for (int index = 0; index < transformation_values.Length; index++)
                    {
                        // Apply the value for this target
                        if (transformation_values[index] != null)
                        {
                            // Apply the translation value for this target
                            if (translation_x_curves[index] == null)
                            {
                                translation_x_curves[index] = new AnimationCurve();
                                translation_y_curves[index] = new AnimationCurve();
                                translation_z_curves[index] = new AnimationCurve();
                            }
                            key_index = translation_x_curves[index].AddKey(time, transformation_values[index].m_translation.x);
                            if (key_index < 0)
                            {
                                Debug.LogError("Could not add key at time " + time);
                            }
                            key_index = translation_y_curves[index].AddKey(time, transformation_values[index].m_translation.y);
                            if (key_index < 0)
                            {
                                Debug.LogError("Could not add key at time " + time);
                            }
                            key_index = translation_z_curves[index].AddKey(time, transformation_values[index].m_translation.z);
                            if (key_index < 0)
                            {
                                Debug.LogError("Could not add key at time " + time);
                            }

                            if (rotation_x_curves[index] == null)
                            {
                                rotation_x_curves[index] = new AnimationCurve();
                                rotation_y_curves[index] = new AnimationCurve();
                                rotation_z_curves[index] = new AnimationCurve();
                                rotation_w_curves[index] = new AnimationCurve();
                            }
                            // Add to curve for the animation
                            key_index = rotation_x_curves[index].AddKey(time, transformation_values[index].m_rotation.x);
                            if (key_index < 0)
                            {
                                Debug.LogError("Could not add key at time " + time);
                            }
                            key_index = rotation_y_curves[index].AddKey(time, transformation_values[index].m_rotation.y);
                            if (key_index < 0)
                            {
                                Debug.LogError("Could not add key at time " + time);
                            }
                            key_index = rotation_z_curves[index].AddKey(time, transformation_values[index].m_rotation.z);
                            if (key_index < 0)
                            {
                                Debug.LogError("Could not add key at time " + time);
                            }
                            key_index = rotation_w_curves[index].AddKey(time, transformation_values[index].m_rotation.w);
                            if (key_index < 0)
                            {
                                Debug.LogError("Could not add key at time " + time);
                            }
                        }
                    }
                }
                else
                {
                    Debug.LogError("Cannot create transformation as evaluated shape size is incorrect");
                }

                // evaluate blendshapes
                BlendshapeValue [] blendshape_values = Utils.EvaluateTargetBlendshapes(m_Retargeting, clip.Rig(), clip[frame_nr], m_GameObjectBlendshapes);

                if (blendshape_values.Length == m_GameObjectBlendshapes.Count)
                {
                    for (int index = 0; index < m_GameObjectBlendshapes.Count; index++)
                    {
                        // Apply the value for this target
                        if (blendshape_values[index] != null)
                        {
                            if (bs_curves[index] == null)
                            {
                                bs_curves[index] = new AnimationCurve();
                            }
                            bs_curves[index].AddKey(time, (float)blendshape_values[index].m_value);
                        }
                    }
                }
                else
                {
                    Debug.LogError("Cannot create blendshapes as evaluated shape size is incorrect");
                }
            }

            // Set all transformation curves for all transformations that are animated
            for (int target_nr = 0; target_nr < m_GameObjectTransformations.Count; target_nr++)
            {
                // Extract path:
                string path_to_transformation = ((TransformationInformation)m_GameObjectTransformations[target_nr]).transformPath;
                // Apply translation curve, if there is one
                if (translation_x_curves[target_nr] != null)
                {
                    animation_clip.SetCurve(path_to_transformation, typeof(Transform), "localPosition.x", translation_x_curves[target_nr]);
                    animation_clip.SetCurve(path_to_transformation, typeof(Transform), "localPosition.y", translation_y_curves[target_nr]);
                    animation_clip.SetCurve(path_to_transformation, typeof(Transform), "localPosition.z", translation_z_curves[target_nr]);
                }
                // Apply rotation curve, if there is one
                if (rotation_x_curves[target_nr] != null)
                {
                    animation_clip.SetCurve(path_to_transformation, typeof(Transform), "localRotation.x", rotation_x_curves[target_nr]);
                    animation_clip.SetCurve(path_to_transformation, typeof(Transform), "localRotation.y", rotation_y_curves[target_nr]);
                    animation_clip.SetCurve(path_to_transformation, typeof(Transform), "localRotation.z", rotation_z_curves[target_nr]);
                    animation_clip.SetCurve(path_to_transformation, typeof(Transform), "localRotation.w", rotation_w_curves[target_nr]);
                }
            }

            // Without this, there are some weird jumps (rotation) in the animation:
            animation_clip.EnsureQuaternionContinuity();

            // Set all blendshape curves for all blendshapes that are animated
            for (int i = 0; i < m_GameObjectBlendshapes.Count; i++)
            {
                if (bs_curves[i] != null)
                {
                    BlendshapeInfo bs_info = (BlendshapeInfo)(m_GameObjectBlendshapes[i]);
                    // Debug.Log("bs_curves[" + i + "].length=" + bs_curves[i].length);
                    string bs_path = bs_info.m_path;
                    string bs_name = bs_info.m_name;
                    animation_clip.SetCurve(bs_path, typeof(SkinnedMeshRenderer), "blendShape." + bs_name, bs_curves[i]);
                }
            }

            Debug.Log("Animation clip = " + animation_clip.length);

            // animation clip asset
            string animation_name = Path.GetFileNameWithoutExtension(path);

            animation_clip.name = animation_name;
            AnimationEvent animation_event = new AnimationEvent();

            animation_event.functionName = "AnimationClipEventCallback";
            animation_event.time         = animation_clip.length;
                        #if UNITY_EDITOR
            AnimationEvent[] animation_events = { animation_event };
            AnimationUtility.SetAnimationEvents(animation_clip, animation_events);
            AssetDatabase.CreateAsset(animation_clip, path);
                        #endif

            Debug.Log("Wrote animation with length " + (1000.0 * animation_clip.length) + " milliseconds");
            return(animation_clip);
        }