//============================================================================================ /** * @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; }
//============================================================================================ /** * @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); }
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); }