Example #1
0
        //============================================================================================

        /**
         *  @brief
         *
         *********************************************************************************************/
        public static void SetData(SerializedObject a_soAnimationModule, AnimationModule a_animModule, int a_categoryId)
        {
            if (a_soAnimationModule == null || a_animModule == null)
            {
                return;
            }

            m_data             = null;
            m_moduleData       = a_animModule;
            m_soPreProcessData = a_soAnimationModule;
            m_categoryId       = a_categoryId;
        }
Example #2
0
        //============================================================================================

        /**
         *  @brief
         *
         *********************************************************************************************/

        public static void SetData(SerializedObject a_soPreProcessData, MxMPreProcessData a_preProcessData, int a_categoryId)
        {
            if (a_soPreProcessData == null || a_preProcessData == null)
            {
                return;
            }

            m_data             = a_preProcessData;
            m_moduleData       = null;
            m_soPreProcessData = a_soPreProcessData;
            m_categoryId       = a_categoryId;
        }
        private void DrawSettings(Rect a_rect)
        {
            GUILayout.BeginArea(a_rect);

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Require", GUILayout.Width(50f));

            MxMPreProcessData preProcessData = m_spTargetPreProcessData.objectReferenceValue as MxMPreProcessData;
            AnimationModule   animModule     = m_spTargetAnimationModule.objectReferenceValue as AnimationModule;

            if (preProcessData != null)
            {
                EditorFunctions.DrawTagFlagFieldWithCustomNames(preProcessData.TagNames.ToArray(), m_spTags, 75f);
            }
            else if (animModule != null && animModule.TagNames != null)
            {
                EditorFunctions.DrawTagFlagFieldWithCustomNames(animModule.TagNames.ToArray(), m_spTags, 75f);
            }
            else
            {
                m_spTags.intValue = (int)(ETags)EditorGUILayout.EnumFlagsField((ETags)m_spTags.intValue);
            }


            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Favour", GUILayout.Width(50f));

            if (preProcessData != null)
            {
                EditorFunctions.DrawTagFlagFieldWithCustomNames(preProcessData.FavourTagNames.ToArray(), m_spFavourTags, 75f);
            }
            else if (animModule != null && animModule.FavourTagNames != null)
            {
                EditorFunctions.DrawTagFlagFieldWithCustomNames(animModule.FavourTagNames.ToArray(), m_spFavourTags, 75f);
            }
            else
            {
                m_spFavourTags.intValue = (int)(ETags)EditorGUILayout.EnumFlagsField((ETags)m_spFavourTags.intValue);
            }

            EditorGUILayout.EndHorizontal();

            EditorGUILayout.PrefixLabel("Min Loops:");
            m_spMinLoops.intValue = EditorGUILayout.IntField(m_spMinLoops.intValue);
            EditorGUILayout.PrefixLabel("Max Loops:");
            m_spMaxLoops.intValue = EditorGUILayout.IntField(m_spMaxLoops.intValue);

            GUILayout.EndArea();
        }
        public void SetTargetAnimModule(AnimationModule a_animModule)
        {
            if(a_animModule != null)
            {
                m_targetAnimModule = a_animModule;

                if(a_animModule.Prefab != null)
                {
                    m_targetPrefab = a_animModule.Prefab;
                }

                m_targetPreProcessData = null;
            }
        }
        public void SetTargetPreProcessor(MxMPreProcessData a_preProcessor)
        {
            if (a_preProcessor != null)
            {
                m_targetPreProcessData = a_preProcessor;

                if (a_preProcessor.Prefab != null)
                {
                    m_targetPrefab = a_preProcessor.Prefab;
                }

                m_targetAnimModule = null;
            }
        }
        public void CopyData(MxMAnimationIdleSet a_copy)
        {
            PrimaryClip = a_copy.PrimaryClip;
            SecondaryClips = new List<AnimationClip>(a_copy.SecondaryClips);
            TransitionClips = new List<AnimationClip>(a_copy.TransitionClips);
            Tags = a_copy.Tags;
            FavourTags = a_copy.FavourTags;
            MinLoops = a_copy.MinLoops;
            MaxLoops = a_copy.MaxLoops;

            m_targetPreProcessData = a_copy.m_targetPreProcessData;
            m_targetAnimModule = a_copy.m_targetAnimModule;

            PoseList = null;
        }
        private void NextComposite()
        {
            MxMPreProcessData preProcessData = m_spTargetPreProcessData.objectReferenceValue as MxMPreProcessData;
            AnimationModule   animModule     = m_spTargetAnimModule.objectReferenceValue as AnimationModule;

            List <MxMAnimationClipComposite> compList = null;

            if (preProcessData != null)
            {
                compList = preProcessData.GetCompositeCategoryList(m_data.CategoryId);
            }
            else if (animModule != null)
            {
                compList = animModule.GetCompositeCategoryList(m_data.CategoryId);
            }

            if (compList != null)
            {
                for (int i = 0; i < compList.Count; ++i)
                {
                    if (compList[i] == m_data)
                    {
                        if (i < compList.Count - 1)
                        {
                            compList[i + 1].ValidateBaseData();
                            SetData(compList[i + 1]);
                        }
                        else
                        {
                            compList[0].ValidateBaseData();
                            SetData(compList[0]);
                        }

                        if (MxMTaggingWindow.Exists())
                        {
                            MxMTaggingWindow.Inst().ClipChanged();
                        }

                        break;
                    }
                }
            }
        }
        public CompositeCategory(CompositeCategory a_copy, ScriptableObject a_parentObj)
        {
            CatagoryName = a_copy.CatagoryName;
            Composites   = new List <MxMAnimationClipComposite>(a_copy.Composites.Count + 1);

            IgnoreEdges_default       = a_copy.IgnoreEdges_default;
            Extrapolate_default       = a_copy.Extrapolate_default;
            FlattenTrajectory_default = a_copy.FlattenTrajectory_default;
            RuntimeSplicing_default   = a_copy.RuntimeSplicing_default;
            RequireTags_default       = a_copy.RequireTags_default;
            FavourTags_default        = a_copy.FavourTags_default;

            foreach (MxMAnimationClipComposite sourceComposite in a_copy.Composites)
            {
                MxMAnimationClipComposite newComposite = ScriptableObject.CreateInstance <MxMAnimationClipComposite>();
                newComposite.CopyData(sourceComposite);
                newComposite.name      = sourceComposite.name;
                newComposite.hideFlags = HideFlags.HideInHierarchy;

                MxMPreProcessData targetPreProcess = a_parentObj as MxMPreProcessData;
                AnimationModule   targetAnimModule = a_parentObj as AnimationModule;

                if (targetPreProcess != null)
                {
                    newComposite.TargetPreProcess = targetPreProcess;
                    newComposite.TargetAnimModule = null;
                }
                else if (targetAnimModule != null)
                {
                    newComposite.TargetPreProcess = null;
                    newComposite.TargetAnimModule = targetAnimModule;
                }

                EditorUtility.SetDirty(newComposite);

                if (a_parentObj != null)
                {
                    AssetDatabase.AddObjectToAsset(newComposite, a_parentObj);
                }

                Composites.Add(newComposite);
            }
        }
        //===========================================================================================

        /**
         *  @brief
         *
         *********************************************************************************************/
        private void NextBlendSpace()
        {
            MxMPreProcessData preProcessData = m_spTargetPreProcessData.objectReferenceValue as MxMPreProcessData;
            AnimationModule   animModule     = m_spTargetAnimModule.objectReferenceValue as AnimationModule;

            List <MxMBlendSpace> blendSpaceList = null;


            if (preProcessData != null)
            {
                blendSpaceList = preProcessData.BlendSpaces;
            }
            else if (animModule != null)
            {
                blendSpaceList = animModule.BlendSpaces;
            }

            if (blendSpaceList != null)
            {
                for (int i = 0; i < blendSpaceList.Count; ++i)
                {
                    if (blendSpaceList[i] == m_data)
                    {
                        if (i < blendSpaceList.Count - 1)
                        {
                            blendSpaceList[i + 1].ValidateBaseData();
                            SetData(blendSpaceList[i + 1]);
                        }
                        else
                        {
                            blendSpaceList[0].ValidateBaseData();
                            SetData(blendSpaceList[0]);
                        }

                        break;
                    }
                }
            }
        }
        private void LastComposite()
        {
            MxMPreProcessData preProcessData = m_spTargetPreProcessData.objectReferenceValue as MxMPreProcessData;
            AnimationModule   animModule     = m_spTargetAnimModule.objectReferenceValue as AnimationModule;

            List <MxMAnimationClipComposite> compList = null;

            if (preProcessData != null)
            {
                compList = preProcessData.GetCompositeCategoryList(m_data.CategoryId);
            }
            else if (animModule != null)
            {
                compList = animModule.GetCompositeCategoryList(m_data.CategoryId);
            }

            if (compList != null)
            {
                for (int i = 0; i < compList.Count; ++i)
                {
                    if (compList[i] == m_data)
                    {
                        if (i == 0)
                        {
                            compList[compList.Count - 1].ValidateBaseData();
                            SetData(compList[compList.Count - 1]);
                        }
                        else
                        {
                            compList[i - 1].ValidateBaseData();
                            SetData(compList[i - 1]);
                        }

                        break;
                    }
                }
            }
        }
        //===========================================================================================

        /**
         *  @brief
         *
         *********************************************************************************************/
        public void OnGUI(Rect a_position)
        {
            if (m_data == null)
            {
                MxMSettings settings = MxMSettings.Instance();
                if (settings != null)
                {
                    m_data = settings.ActiveBlendSpace;

                    if (m_data != null)
                    {
                        SetData(m_data);
                    }
                }
            }

            if (m_data != null)
            {
                Event evt = Event.current;

                float labelWidth = EditorGUIUtility.labelWidth;

                if (evt.type == EventType.Repaint)
                {
                    if (m_queueDeleteIndex >= 0 && m_queueDeleteIndex < m_spClips.arraySize)
                    {
                        if (m_selectId == m_queueDeleteIndex)
                        {
                            m_selectId = -1;
                        }

                        if (m_spClips.GetArrayElementAtIndex(m_queueDeleteIndex).objectReferenceValue != null)
                        {
                            m_spClips.DeleteArrayElementAtIndex(m_queueDeleteIndex);
                        }

                        m_spClips.DeleteArrayElementAtIndex(m_queueDeleteIndex);
                        m_spPositions.DeleteArrayElementAtIndex(m_queueDeleteIndex);

                        m_queueDeleteIndex = -1;
                    }
                }

                EditorGUILayout.BeginVertical();
                EditorGUILayout.BeginHorizontal(EditorStyles.toolbar, GUILayout.Height(20f), GUILayout.ExpandWidth(true));

                EditorGUI.BeginChangeCheck();
                m_previewActive = GUILayout.Toggle(m_previewActive, "Preview", EditorStyles.toolbarButton, GUILayout.Width(60f));
                if (EditorGUI.EndChangeCheck())
                {
                    if (m_previewActive)
                    {
                        BeginPreview();
                    }
                    else
                    {
                        EndPreview();
                    }
                }



                if (m_previewActive && MxMPreviewScene.IsSceneLoaded)
                {
                    EditorGUIUtility.labelWidth = 20f;

                    EditorGUI.BeginChangeCheck();
                    m_previewPos.x = EditorGUILayout.FloatField("X: ", m_previewPos.x, EditorStyles.toolbarTextField);
                    m_previewPos.y = EditorGUILayout.FloatField("Y: ", m_previewPos.y, EditorStyles.toolbarTextField);
                    if (EditorGUI.EndChangeCheck())
                    {
                        m_previewPos.x = Mathf.Clamp(m_previewPos.x, -1f, 1f);
                        m_previewPos.y = Mathf.Clamp(m_previewPos.y, -1f, 1f);

                        CalculateBlendWeights();
                        ApplyBlendWeights();
                    }
                    EditorGUIUtility.labelWidth = labelWidth;

                    UpdatePreview();
                    MxMAnimConfigWindow.Inst().Repaint();
                }

                GUILayout.FlexibleSpace();

                m_spNormalizeTime.boolValue = GUILayout.Toggle(m_spNormalizeTime.boolValue, "Normalize Time",
                                                               EditorStyles.toolbarButton, GUILayout.Width(90f));

                EditorGUILayout.LabelField("Type:", GUILayout.Width(40f));
                m_spScatterSpace.enumValueIndex = (int)(EBlendSpaceType)EditorGUILayout.EnumPopup(
                    (EBlendSpaceType)m_spScatterSpace.enumValueIndex, GUILayout.Width(70f));
                GUILayout.Space(5f);

                switch ((EBlendSpaceType)m_spScatterSpace.enumValueIndex)
                {
                case EBlendSpaceType.Standard:
                {
                    EditorGUILayout.LabelField("Magnitude ", GUILayout.Width(62f));
                    m_spMagnitude.vector2Value = EditorGUILayout.Vector2Field("", m_spMagnitude.vector2Value, GUILayout.Width(100f));
                    EditorGUILayout.LabelField("Smoothing ", GUILayout.Width(65f));
                    m_spSmoothing.vector2Value = EditorGUILayout.Vector2Field("", m_spSmoothing.vector2Value, GUILayout.Width(100f));
                }
                break;

                case EBlendSpaceType.Scatter:
                {
                    EditorGUILayout.LabelField("Spacing", GUILayout.Width(50f));
                    m_spScatterSpacing.vector2Value = EditorGUILayout.Vector2Field("", m_spScatterSpacing.vector2Value, GUILayout.Width(100f));
                }
                break;

                case EBlendSpaceType.ScatterX:
                {
                    EditorGUILayout.LabelField("Spacing X", GUILayout.Width(60f));
                    float spacingX = EditorGUILayout.FloatField(m_spScatterSpacing.vector2Value.x, GUILayout.Width(35f));

                    m_spScatterSpacing.vector2Value = new Vector2(spacingX, m_spScatterSpacing.vector2Value.y);
                }
                break;

                case EBlendSpaceType.ScatterY:
                {
                    EditorGUILayout.LabelField("Spacing Y", GUILayout.Width(60f));
                    float spacingY = EditorGUILayout.FloatField(m_spScatterSpacing.vector2Value.y, GUILayout.Width(35f));

                    m_spScatterSpacing.vector2Value = new Vector2(m_spScatterSpacing.vector2Value.x, spacingY);
                }
                break;
                }



                GUILayout.Space(2f);
                m_showClipNames = GUILayout.Toggle(m_showClipNames, "Show Clips", EditorStyles.toolbarButton, GUILayout.Width(80f));
                GUILayout.Space(5f);
                m_snapActive = GUILayout.Toggle(m_snapActive, "Snap", EditorStyles.toolbarButton, GUILayout.Width(40f));

                if (m_snapActive)
                {
                    m_snapInterval = EditorGUILayout.FloatField(m_snapInterval, EditorStyles.toolbarTextField, GUILayout.Width(30f));
                }

                EditorGUILayout.EndHorizontal();
                GUILayout.FlexibleSpace();

                EditorGUILayout.BeginHorizontal(EditorStyles.toolbar, GUILayout.Height(20f), GUILayout.ExpandWidth(true));

                if (m_selectId >= 0 && m_selectId < m_spClips.arraySize)
                {
                    AnimationClip      clip       = m_spClips.GetArrayElementAtIndex(m_selectId).objectReferenceValue as AnimationClip;
                    SerializedProperty spPosition = m_spPositions.GetArrayElementAtIndex(m_selectId);

                    if (clip != null && spPosition != null)
                    {
                        EditorGUILayout.LabelField(clip.name, GUILayout.Width(GUI.skin.label.CalcSize(new GUIContent(clip.name)).x + 4f));

                        EditorGUI.BeginChangeCheck();
                        spPosition.vector2Value = EditorGUILayout.Vector2Field("", spPosition.vector2Value);
                        if (EditorGUI.EndChangeCheck())
                        {
                            if (m_previewActive && MxMPreviewScene.IsSceneLoaded)
                            {
                                CalculateBlendWeights();
                                ApplyBlendWeights();
                            }
                        }
                    }
                }

                EditorGUILayout.LabelField("Require", GUILayout.Width(50f));
                MxMPreProcessData preProcessData = m_spTargetPreProcessData.objectReferenceValue as MxMPreProcessData;
                AnimationModule   animModule     = m_spTargetAnimModule.objectReferenceValue as AnimationModule;

                if (preProcessData != null)
                {
                    EditorFunctions.DrawTagFlagFieldWithCustomNames(preProcessData.TagNames.ToArray(), m_spGlobalTags, 100f);
                }
                else if (animModule != null && animModule.TagNames != null)
                {
                    EditorFunctions.DrawTagFlagFieldWithCustomNames(animModule.TagNames.ToArray(), m_spGlobalTags, 100f);
                }
                else
                {
                    m_spGlobalTags.intValue = (int)(ETags)EditorGUILayout.EnumFlagsField((ETags)m_spGlobalTags.intValue);
                }

                EditorGUILayout.LabelField("Favour", GUILayout.Width(45f));

                if (preProcessData != null)
                {
                    EditorFunctions.DrawTagFlagFieldWithCustomNames(preProcessData.FavourTagNames.ToArray(), m_spGlobalFavourTags, 100f);
                }
                else if (animModule != null && animModule.FavourTagNames != null)
                {
                    EditorFunctions.DrawTagFlagFieldWithCustomNames(animModule.FavourTagNames.ToArray(), m_spGlobalFavourTags, 100f);
                }
                else
                {
                    m_spGlobalFavourTags.intValue = (int)(ETags)EditorGUILayout.EnumFlagsField((ETags)m_spGlobalFavourTags.intValue);
                }

                GUILayout.FlexibleSpace();

                if (GUILayout.Button(new GUIContent("Open Timeline"), EditorStyles.toolbarButton))
                {
                    MxMTaggingWindow.ShowWindow();
                }

                GUILayout.Space(5f);

                if (m_spTargetPreProcessData.objectReferenceValue != null ||
                    m_spTargetAnimModule.objectReferenceValue != null)
                {
                    if (GUILayout.Button(EditorGUIUtility.IconContent("back").image, EditorStyles.toolbarButton))
                    {
                        LastBlendSpace();
                    }

                    if (GUILayout.Button(EditorGUIUtility.IconContent("forward").image, EditorStyles.toolbarButton))
                    {
                        NextBlendSpace();
                    }
                }

                EditorGUI.BeginDisabledGroup(true);

                EditorGUIUtility.labelWidth = 110f;
                if (preProcessData != null)
                {
                    EditorGUILayout.ObjectField(m_spTargetPreProcessData, new GUIContent("Target PreProcess"));
                }
                else if (animModule != null)
                {
                    EditorGUILayout.ObjectField(m_spTargetAnimModule, new GUIContent("Target Anim Module"));
                }

                EditorGUIUtility.labelWidth = 95f;
                EditorGUILayout.ObjectField(m_spTargetPrefab, new GUIContent("Preview Prefab"));

                EditorGUI.EndDisabledGroup();

                EditorGUIUtility.labelWidth = labelWidth;

                EditorGUILayout.EndHorizontal();
                EditorGUILayout.EndVertical();

                Rect blendSpaceRect = new Rect(30f, 40f, a_position.width - 60f, a_position.height - 90f);

                GUI.Box(blendSpaceRect, "");

                Rect labelRect = new Rect(blendSpaceRect.x - 18f, blendSpaceRect.y, 18f, 18f);

                GUI.Label(labelRect, "1");
                labelRect.y += blendSpaceRect.height / 2f - 9f;
                GUI.Label(labelRect, "0");
                labelRect.y = blendSpaceRect.y + blendSpaceRect.height - 18f;
                GUI.Label(labelRect, "-1");
                labelRect.y += labelRect.height;
                labelRect.x += labelRect.width;
                GUI.Label(labelRect, "-1");
                labelRect.x += blendSpaceRect.width / 2f - 9f;
                GUI.Label(labelRect, "0");
                labelRect.x = blendSpaceRect.x + blendSpaceRect.width - 18f;
                GUI.Label(labelRect, "1");

                float spacingH = blendSpaceRect.width / 10f;
                float spacingV = blendSpaceRect.height / 10f;

                float top    = blendSpaceRect.y;
                float bottom = blendSpaceRect.y + blendSpaceRect.height;
                float left   = blendSpaceRect.x;
                float right  = blendSpaceRect.x + blendSpaceRect.width;

                Handles.color = Color.grey;
                for (int i = 1; i < 10; ++i)
                {
                    float horizontal = i * spacingH + blendSpaceRect.x;
                    float vertical   = i * spacingV + blendSpaceRect.y;

                    Handles.DrawLine(new Vector3(horizontal, top), new Vector3(horizontal, bottom));
                    Handles.DrawLine(new Vector3(left, vertical), new Vector3(right, vertical));
                }

                Handles.color = Color.black;
                Handles.DrawLine(new Vector3(blendSpaceRect.x + blendSpaceRect.width / 2f, top),
                                 new Vector3(blendSpaceRect.x + blendSpaceRect.width / 2f, bottom));

                Handles.DrawLine(new Vector3(left, blendSpaceRect.y + blendSpaceRect.height / 2f),
                                 new Vector3(right, blendSpaceRect.y + blendSpaceRect.height / 2f));

                Rect    animDrawRect    = new Rect(0f, 0f, 18f, 18f);
                Vector2 blendSpaceRatio = new Vector2(2f / blendSpaceRect.width, 2f / blendSpaceRect.height);

                Texture blendKey         = EditorGUIUtility.IconContent("blendKey").image;
                Texture blendKeySelected = EditorGUIUtility.IconContent("blendKeySelected").image;
                Texture previewPointTex  = EditorGUIUtility.IconContent("d_P4_AddedLocal").image;

                Vector2 centerPos = blendSpaceRect.position;
                centerPos.x += blendSpaceRect.width / 2f;
                centerPos.y += blendSpaceRect.height / 2f;

                //Draw Points
                for (int i = 0; i < m_spClips.arraySize; ++i)
                {
                    Vector2 normalizedPos = m_spPositions.GetArrayElementAtIndex(i).vector2Value;
                    normalizedPos.y *= -1f;

                    animDrawRect.position = (normalizedPos / blendSpaceRatio) + centerPos;

                    animDrawRect.size = new Vector2(14f, 14f);

                    if (m_previewActive && MxMPreviewScene.IsSceneLoaded)
                    {
                        float size = 9f + 5f * m_blendWeights[i];
                        animDrawRect.size = new Vector2(size, size);
                    }
                    else
                    {
                        animDrawRect.size = new Vector2(14f, 14f);
                    }

                    animDrawRect.position -= (animDrawRect.size / 2f);

                    if (m_selectId == i)
                    {
                        GUI.DrawTexture(animDrawRect, blendKeySelected);
                    }
                    else
                    {
                        GUI.DrawTexture(animDrawRect, blendKey);
                    }

                    if (m_showClipNames)
                    {
                        AnimationClip clip = m_spClips.GetArrayElementAtIndex(i).objectReferenceValue as AnimationClip;

                        Vector2 labelSize = GUI.skin.label.CalcSize(new GUIContent(clip.name));

                        Rect clipNameRect = new Rect(animDrawRect.x + (animDrawRect.width / 2f) - labelSize.x / 2f,
                                                     animDrawRect.y - labelSize.y, labelSize.x, labelSize.y);

                        GUI.Label(clipNameRect, clip.name);
                    }

                    if (evt.type == EventType.MouseDown && evt.button == 0)
                    {
                        if (animDrawRect.Contains(evt.mousePosition))
                        {
                            m_selectId       = i;
                            m_dragging       = true;
                            m_cumulativeDrag = m_spPositions.GetArrayElementAtIndex(i).vector2Value;

                            if (evt.clickCount >= 2)
                            {
                                EditorGUIUtility.PingObject(m_spClips.GetArrayElementAtIndex(i).objectReferenceValue);
                            }

                            evt.Use();
                            MxMAnimConfigWindow.Inst().Repaint();
                        }
                    }
                }

                //Draw Preview Point
                if (m_previewActive && MxMPreviewScene.IsSceneLoaded)
                {
                    Vector3 previewDrawPos = m_previewPos;
                    previewDrawPos.y *= -1f;

                    animDrawRect.size     = new Vector2(18f, 18f);
                    animDrawRect.position = (previewDrawPos / blendSpaceRatio) + centerPos - (animDrawRect.size / 2f);

                    GUI.DrawTexture(animDrawRect, previewPointTex);
                }

                switch (evt.type)
                {
                case EventType.MouseDown:
                {
                    if (m_previewActive && blendSpaceRect.Contains(evt.mousePosition) && MxMPreviewScene.IsSceneLoaded)
                    {
                        Vector2 blendSpacePos = evt.mousePosition - (blendSpaceRect.position + (blendSpaceRect.size / 2f));
                        m_previewPos    = blendSpacePos * blendSpaceRatio;
                        m_previewPos.y *= -1f;

                        m_previewPos.x = Mathf.Clamp(m_previewPos.x, -1f, 1f);
                        m_previewPos.y = Mathf.Clamp(m_previewPos.y, -1f, 1f);

                        CalculateBlendWeights();
                        ApplyBlendWeights();


                        m_draggingPreview = true;
                    }

                    m_dragging = false;
                    m_selectId = -1;
                    evt.Use();
                }
                break;

                case EventType.MouseUp:
                {
                    if (m_dragging || m_draggingPreview)
                    {
                        m_draggingPreview = false;
                        m_dragging        = false;
                        m_cumulativeDrag  = Vector2.zero;
                        evt.Use();
                    }
                }
                break;

                case EventType.MouseDrag:
                {
                    if (m_dragging)
                    {
                        if (m_selectId >= 0 && m_selectId < m_spPositions.arraySize)
                        {
                            SerializedProperty spPosition = m_spPositions.GetArrayElementAtIndex(m_selectId);
                            Vector2            moveDelta  = evt.delta;
                            moveDelta.y *= -1f;

                            if (m_snapActive)
                            {
                                m_cumulativeDrag += moveDelta * blendSpaceRatio;

                                m_cumulativeDrag.x = Mathf.Clamp(m_cumulativeDrag.x, -1f, 1f);
                                m_cumulativeDrag.y = Mathf.Clamp(m_cumulativeDrag.y, -1f, 1f);

                                spPosition.vector2Value = m_cumulativeDrag;
                                SnapClip(m_selectId);
                            }
                            else
                            {
                                Vector2 newPos = spPosition.vector2Value + moveDelta * blendSpaceRatio;

                                newPos.x = Mathf.Clamp(newPos.x, -1f, 1f);
                                newPos.y = Mathf.Clamp(newPos.y, -1f, 1f);
                                spPosition.vector2Value = newPos;
                            }

                            if (m_previewActive && MxMPreviewScene.IsSceneLoaded)
                            {
                                CalculateBlendWeights();
                                ApplyBlendWeights();
                            }

                            evt.Use();
                        }
                        else
                        {
                            m_dragging = false;
                        }
                    }
                    else if (m_previewActive && m_draggingPreview && MxMPreviewScene.IsSceneLoaded)
                    {
                        Vector2 blendSpacePos = evt.mousePosition - (blendSpaceRect.position + (blendSpaceRect.size / 2f));
                        m_previewPos    = blendSpacePos * blendSpaceRatio;
                        m_previewPos.y *= -1f;

                        m_previewPos.x = Mathf.Clamp(m_previewPos.x, -1f, 1f);
                        m_previewPos.y = Mathf.Clamp(m_previewPos.y, -1f, 1f);

                        CalculateBlendWeights();
                        ApplyBlendWeights();

                        if (m_snapActive)
                        {
                            SnapPreview();
                        }

                        evt.Use();
                    }
                }
                break;

                case EventType.KeyDown:
                {
                    if (m_selectId >= 0 && m_selectId < m_spClips.arraySize)
                    {
                        if (evt.keyCode == KeyCode.Delete)
                        {
                            m_queueDeleteIndex = m_selectId;
                            MxMAnimConfigWindow.Inst().Repaint();
                            evt.Use();
                        }
                    }
                }
                break;
                }

                DragDropAnimations(blendSpaceRect);

                if (m_soData != null)
                {
                    m_soData.ApplyModifiedProperties();
                }
            }
            else
            {
                GUILayout.Space(18f);
                EditorGUILayout.BeginHorizontal();
                GUILayout.FlexibleSpace();
                EditorGUILayout.LabelField("No Blend Space Selected.", EditorStyles.boldLabel);
                GUILayout.FlexibleSpace();
                EditorGUILayout.EndHorizontal();
            }
        }
        private void DrawSettings(Rect a_rect)
        {
            GUILayout.BeginArea(a_rect);

            m_spLooping.boolValue = EditorGUILayout.ToggleLeft(new GUIContent(
                                                                   "Loop", "Check if this animation loops"), m_spLooping.boolValue);

            if (!m_spLooping.boolValue)
            {
                m_spIgnoreEdges.boolValue = EditorGUILayout.ToggleLeft(new GUIContent(
                                                                           "Ignore Edges", "Clip edges will be marked as DoNotUse"), m_spIgnoreEdges.boolValue);

                if (!m_spIgnoreEdges.boolValue)
                {
                    m_spExtrapolateTrajectory.boolValue = EditorGUILayout.ToggleLeft(new GUIContent(
                                                                                         "Extrapolate", "Trajectory will be extrapolated"), m_spExtrapolateTrajectory.boolValue);
                }
            }

            m_spFlattenTrajectory.boolValue = EditorGUILayout.ToggleLeft(new GUIContent(
                                                                             "Flatten Trajectory", "Flatten the trejectory so that the 'y' axis component is always zero"),
                                                                         m_spFlattenTrajectory.boolValue);

            if (m_spAfterClips.arraySize > 0)
            {
                m_spRuntimeSplicing.boolValue = EditorGUILayout.ToggleLeft(new GUIContent(
                                                                               "Runtime Splicing", "Splice together the primary clip and first after clip at runtime to ensure continuity"),
                                                                           m_spRuntimeSplicing.boolValue);
            }

            MxMPreProcessData preProcessData = m_spTargetPreProcessData.objectReferenceValue as MxMPreProcessData;
            AnimationModule   animModule     = m_spTargetAnimModule.objectReferenceValue as AnimationModule;


            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Require", GUILayout.Width(50f));
            if (preProcessData != null)
            {
                EditorFunctions.DrawTagFlagFieldWithCustomNames(preProcessData.TagNames.ToArray(), m_spGlobalTags, 75f);
            }
            else if (animModule != null && animModule.FavourTagNames != null)
            {
                EditorFunctions.DrawTagFlagFieldWithCustomNames(animModule.TagNames.ToArray(), m_spGlobalTags, 75f);
            }
            else
            {
                m_spGlobalTags.intValue = (int)(ETags)EditorGUILayout.EnumFlagsField((ETags)m_spGlobalTags.intValue);
            }

            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Favour", GUILayout.Width(50f));
            if (preProcessData != null)
            {
                EditorFunctions.DrawTagFlagFieldWithCustomNames(preProcessData.FavourTagNames.ToArray(), m_spGlobalFavourTags, 75f);
            }
            else if (animModule != null && animModule.FavourTagNames != null)
            {
                EditorFunctions.DrawTagFlagFieldWithCustomNames(animModule.FavourTagNames.ToArray(), m_spGlobalFavourTags, 75f);
            }
            else
            {
                m_spGlobalFavourTags.intValue = (int)(ETags)EditorGUILayout.EnumFlagsField((ETags)m_spGlobalFavourTags.intValue);
            }

            EditorGUILayout.EndHorizontal();

            GUILayout.EndArea();
        }
        public void CopyData(MxMAnimationClipComposite a_copy)
        {
            PrimaryClip = a_copy.PrimaryClip;
            BeforeClips = new List<AnimationClip>(a_copy.BeforeClips);
            AfterClips = new List<AnimationClip>(a_copy.AfterClips);

            Looping= a_copy.Looping;
            IgnoreEdges = a_copy.IgnoreEdges;
            ExtrapolateTrajectory = a_copy.ExtrapolateTrajectory;
            FlattenTrajectory = a_copy.FlattenTrajectory;
            RuntimeSplicing = a_copy.RuntimeSplicing;
            UseSpeedMods = a_copy.UseSpeedMods;

            GlobalTags = a_copy.GlobalTags;
            GlobalFavourTags = a_copy.GlobalFavourTags;

            TagTracks = new List<TagTrack>(a_copy.TagTracks.Count + 1);
            foreach(TagTrack track in a_copy.TagTracks)
            {
                TagTracks.Add(new TagTrack(track));
            }

            for (int i = 0; i < a_copy.TagTracks.Count; ++i)
            {
                TagTracks.Add(new TagTrack(a_copy.TagTracks[i]));
            }

            FavourTagTracks = new List<TagTrack>(a_copy.FavourTagTracks.Count + 1);
            foreach(TagTrack track  in a_copy.FavourTagTracks)
            {
                FavourTagTracks.Add(new TagTrack(track));
            }

            UserBoolTracks = new List<TagTrackBase>(a_copy.UserBoolTracks.Count + 1);
            foreach(TagTrackBase track in a_copy.UserBoolTracks)
            {
                UserBoolTracks.Add(new TagTrackBase(track));
            }

            Events = new List<EventMarker>(a_copy.Events.Count + 1);
            foreach(EventMarker marker in a_copy.Events)
            {
                Events.Add(new EventMarker(marker));
            }

            m_targetPreProcessData = a_copy.m_targetPreProcessData;
            m_targetAnimModule = a_copy.m_targetAnimModule;
            m_targetPrefab = a_copy.m_targetPrefab;

            PoseList = null;

            LeftFootStepTrack = new FootStepTagTrack(a_copy.LeftFootStepTrack);
            RightFootStepTrack = new FootStepTagTrack(a_copy.RightFootStepTrack);
            WarpPositionTrack = new TagTrackBase(a_copy.WarpPositionTrack);
            WarpRotationTrack = new TagTrackBase(a_copy.WarpRotationTrack);
            EnableRootMotionTrack = new TagTrackBase(a_copy.EnableRootMotionTrack);
            PoseFavourTrack = new FloatTagTrack(a_copy.PoseFavourTrack);
            WarpTrajLatTrack = new TagTrackBase(a_copy.WarpTrajLatTrack);
            WarpTrajLongTrack = new TagTrackBase(a_copy.WarpTrajLongTrack);

            MotionModifier = new MotionModifyData(a_copy.MotionModifier, this);
        }
Example #14
0
        public static void DetectFootsteps(IMxMAnim a_mxmAnim, GameObject a_targetModel, MxMPreProcessData a_preProcessData,
                                           AnimationModule a_animModule, float a_groundingThreshold, float a_minSpacing, float a_minDuration, float a_maxFootSpeed)
        {
            if ((a_preProcessData == null && a_animModule == null) || a_mxmAnim == null)
            {
                return;
            }

            AnimationClip targetClip = a_mxmAnim.TargetClip;

            if (targetClip == null)
            {
                return;
            }

            if (a_targetModel == null)
            {
                if (a_preProcessData == null)
                {
                    a_targetModel = a_preProcessData.Prefab;
                }
                else if (a_animModule == null)
                {
                    a_targetModel = a_animModule.Prefab;
                }

                if (a_targetModel == null)
                {
                    Debug.LogError("MxM Footstep Detection - The MxMAnim you are trying to detect footsteps for has no target" +
                                   "model. This could occur if your target model is not set on the pre-processor, or your animation module" +
                                   "doesn't have a MotionMatch Config referenced.");
                    return;
                }
            }

            List <FootStepData> leftFootStepData      = new List <FootStepData>();
            List <Vector2>      leftFootStepPositions = new List <Vector2>();

            List <FootStepData> rightFootStepData      = new List <FootStepData>();
            List <Vector2>      rightFootStepPositions = new List <Vector2>();

            GameObject model = GameObject.Instantiate(a_targetModel);

            model.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity);

            Animator animator = model.GetComponent <Animator>();

            if (animator == null)
            {
                animator = model.AddComponent <Animator>();
            }

            animator.applyRootMotion = true;
            animator.cullingMode     = AnimatorCullingMode.AlwaysAnimate;

            Transform leftToeJoint  = null;
            Transform rightToeJoint = null;

            bool getBonesByName = false;

            if (a_preProcessData != null)
            {
                getBonesByName = a_preProcessData.GetBonesByName;
            }
            else if (a_animModule != null)
            {
                getBonesByName = a_animModule.GetBonesByName;
            }

            if (!getBonesByName)
            {
                leftToeJoint  = animator.GetBoneTransform(HumanBodyBones.LeftToes);
                rightToeJoint = animator.GetBoneTransform(HumanBodyBones.RightToes);
            }
            else
            {
                //Get generic joints?
                Debug.LogWarning("Automatic detection of footsteps is not currently supported for generic rigs");
                return;
            }

            PlayableGraph playableGraph = PlayableGraph.Create();

            playableGraph.SetTimeUpdateMode(DirectorUpdateMode.Manual);
            var playableOutput = AnimationPlayableOutput.Create(playableGraph, "Animation", animator);
            var animationMixer = AnimationMixerPlayable.Create(playableGraph, 1, true);

            playableOutput.SetSourcePlayable(animationMixer);

            var clipPlayable = AnimationClipPlayable.Create(playableGraph, targetClip);

            animationMixer.ConnectInput(0, clipPlayable, 0);
            animationMixer.SetInputWeight(0, 1f);

            clipPlayable.SetTime(0.0);
            clipPlayable.SetTime(0.0);
            playableGraph.Evaluate(0f);
            model.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity);

            const float SixtyHz = 1f / 60f;

            float leftFootLowestY  = leftToeJoint.position.y;
            float rightFootLowestY = rightToeJoint.position.y;

            for (float time = 0f; time <= targetClip.length; time += SixtyHz)
            {
                float leftFootY  = leftToeJoint.position.y;
                float rightFootY = rightToeJoint.position.y;

                if (leftFootY < leftFootLowestY)
                {
                    leftFootLowestY = leftFootY;
                }

                if (rightFootY < rightFootLowestY)
                {
                    rightFootLowestY = rightFootY;
                }

                playableGraph.Evaluate(SixtyHz);
            }

            clipPlayable.SetTime(0.0);
            clipPlayable.SetTime(0.0);
            playableGraph.Evaluate(0f);
            bool leftFootGrounded  = false;
            bool rightFootGrounded = false;

            float leftStepStartTime = 0f;
            float leftStepEndTime   = 0f;

            float rightStepStartTime = 0f;
            float rightStepEndTime   = 0f;

            model.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity);

            float leftToeSpeed  = 0f;
            float rightToeSpeed = 0f;

            Vector3 leftToeLastPos  = leftToeJoint.position;
            Vector3 rightToeLastPos = rightToeJoint.position;

            for (float time = 0f; time <= targetClip.length; time += SixtyHz)
            {
                //Velocities
                leftToeSpeed    = Vector3.Distance(leftToeLastPos, leftToeJoint.position) / SixtyHz;
                rightToeSpeed   = Vector3.Distance(rightToeLastPos, rightToeJoint.position) / SixtyHz;
                leftToeLastPos  = leftToeJoint.position;
                rightToeLastPos = rightToeJoint.position;

                //LEFT FOOT
                float leftFootDif = leftToeJoint.position.y - leftFootLowestY;
                if (leftFootDif < a_groundingThreshold && leftToeSpeed < a_maxFootSpeed)
                {
                    if (leftFootGrounded == false)
                    {
                        leftStepStartTime = time;
                    }

                    leftFootGrounded = true;
                }
                else
                {
                    if (leftFootGrounded == true)
                    {
                        leftStepEndTime = time;

                        leftFootStepData.Add(new FootStepData());
                        leftFootStepPositions.Add(new Vector2(leftStepStartTime, leftStepEndTime));
                    }

                    leftFootGrounded = false;
                }

                //RIGHT FOOT
                float rightFootDif = rightToeJoint.position.y - rightFootLowestY;

                if (rightFootDif < a_groundingThreshold && rightToeSpeed < a_maxFootSpeed)
                {
                    if (rightFootGrounded == false)
                    {
                        rightStepStartTime = time;
                    }

                    rightFootGrounded = true;
                }
                else
                {
                    if (rightFootGrounded == true)
                    {
                        rightStepEndTime = time;

                        rightFootStepData.Add(new FootStepData());
                        rightFootStepPositions.Add(new Vector2(rightStepStartTime, rightStepEndTime));
                    }

                    rightFootGrounded = false;
                }

                playableGraph.Evaluate(SixtyHz);
            }

            List <TagTrackBase> genericTagTracks = a_mxmAnim.GenericTagTracks;
            FootStepTagTrack    leftFootTagTrack = genericTagTracks[0] as FootStepTagTrack;

            leftFootTagTrack.RemoveAllTags();

            for (int i = 0; i < leftFootStepPositions.Count; ++i)
            {
                Vector2 footStepPosition = leftFootStepPositions[i];

                //Combine footsteps that are too close to be real (This should be recursive)
                if (i + 1 < leftFootStepPositions.Count)
                {
                    for (int k = i + 1; k < leftFootStepPositions.Count; ++k)
                    {
                        Vector2 nextFootStepPos = leftFootStepPositions[k];

                        if (nextFootStepPos.x - footStepPosition.y < a_minSpacing)
                        {
                            footStepPosition.y = nextFootStepPos.y;
                            leftFootStepPositions.RemoveAt(k);
                            --k;
                        }
                        else
                        {
                            break;
                        }
                    }
                }

                //Ignore footsteps that are too short to be real
                if (footStepPosition.y - footStepPosition.x < a_minDuration)
                {
                    continue;
                }

                leftFootTagTrack.AddTag(footStepPosition.x, footStepPosition.y);
            }

            FootStepTagTrack rightFootTagTrack = genericTagTracks[1] as FootStepTagTrack;

            rightFootTagTrack.RemoveAllTags();

            for (int i = 0; i < rightFootStepPositions.Count; ++i)
            {
                Vector3 footStepPosition = rightFootStepPositions[i];

                //Combine footsteps that are too close to be real (This should be recursive)
                if (i + 1 < rightFootStepPositions.Count)
                {
                    for (int k = i + 1; k < rightFootStepPositions.Count; ++k)
                    {
                        Vector2 nextFootStepPos = rightFootStepPositions[k];

                        if (nextFootStepPos.x - footStepPosition.y < a_minSpacing)
                        {
                            footStepPosition.y = nextFootStepPos.y;
                            rightFootStepPositions.RemoveAt(k);
                            --k;
                        }
                        else
                        {
                            break;
                        }
                    }
                }

                //Ignore footsteps that are too short to be real
                if (footStepPosition.y - footStepPosition.x < a_minDuration)
                {
                    continue;
                }

                rightFootTagTrack.AddTag(footStepPosition.x, footStepPosition.y);
            }

            GameObject.DestroyImmediate(model);
        }