public void GenerateModifiedAnimation(MxMPreProcessData a_preProcessData, string a_directory) { EditorUtility.DisplayProgressBar("Generate Modified Animations", "Scraping Old Anims", 0f); if (a_preProcessData != null) m_targetPreProcessData = a_preProcessData; ScrapGeneratedClips(); List<MotionSection> motionList = MotionModifier.MotionSections; MotionTimingPresets presets = m_targetPreProcessData.MotionTimingPresets; if (UseSpeedMods && m_clips != null && m_targetPreProcessData != null) { int blendSpaceId = 0; for (int i = 0; i < m_targetPreProcessData.BlendSpaces.Count; ++i) { if(this == m_targetPreProcessData.BlendSpaces[i]) { blendSpaceId = i; break; } } float cumTimeShift = 0f; //This is the cumulative amount of time shift at the point of modification; float curStartTime = 0f; //The start time for the current motion section //Loop clips and generate ndes ones foreach (AnimationClip clip in m_clips) { EditorUtility.DisplayProgressBar("Generate Modified Animation", "Copying Clip " + clip.name, 0f); var generatedClip = new AnimationClip(); EditorUtility.CopySerialized(clip, generatedClip); generatedClip.name = clip.name + "_MxM_MOD_" + blendSpaceId; var curveBindings = AnimationUtility.GetCurveBindings(generatedClip); List<AnimationCurve> workingCurves = new List<AnimationCurve>(curveBindings.Length + 1); List<AnimationEvent> newEvents = new List<AnimationEvent>(); //Create curves but don't add keys for (int i = 0; i < curveBindings.Length; ++i) { workingCurves.Add(new AnimationCurve()); } cumTimeShift = 0f; curStartTime = 0f; int[] startKeyIndex = new int[workingCurves.Count]; //The start key for the current motion section for (int i = 0; i < motionList.Count; ++i) { EditorUtility.DisplayProgressBar("Generate Modified Animation", "Modifying Section " + i + " of " + clip.name, ((float)i) / ((float)motionList.Count)); MotionSection motionSection = motionList[i]; float startWarpTime = curStartTime; float endWarpTime = motionSection.EndTime; float warpScale = motionSection.GetSpeedMod(curStartTime, presets, this); float localTimeShift = (endWarpTime - startWarpTime) - (endWarpTime - startWarpTime) * warpScale; //Shift Curve Keys for (int k = 0; k < curveBindings.Length; ++k) { EditorCurveBinding binding = curveBindings[k]; AnimationCurve originalCurve = AnimationUtility.GetEditorCurve(clip, binding); AnimationCurve workingCurve = workingCurves[k]; //Make a cut at the end only int endKeyIndex = originalCurve.AddKey(endWarpTime, originalCurve.Evaluate(endWarpTime)); if (endKeyIndex == -1) endKeyIndex = originalCurve.keys.Length - 1; //Add in the intermediate keys scaled relative to the start and shifted by the cumulative time shift for (int keyIndex = startKeyIndex[k]; i < motionList.Count - 1 ? keyIndex < endKeyIndex : keyIndex <= endKeyIndex; ++keyIndex) { Keyframe key = originalCurve.keys[keyIndex]; key.time = startWarpTime + ((key.time - startWarpTime) * warpScale) - cumTimeShift; key.inTangent /= warpScale; key.outTangent /= warpScale; workingCurve.AddKey(key); } startKeyIndex[k] = endKeyIndex; } //Shift Animation Clip EventsEvents foreach (AnimationEvent evt in generatedClip.events) { if (evt.time > startWarpTime && evt.time < endWarpTime) { //Scale & Shift evt.time = startWarpTime + ((evt.time - startWarpTime) * warpScale) - cumTimeShift; } newEvents.Add(evt); } } for (int i = 0; i < workingCurves.Count; ++i) { EditorUtility.DisplayProgressBar("Generate Modified Animation", "Generating Curves for clip: " + clip.name, ((float)i) / ((float)workingCurves.Count)); AnimationUtility.SetEditorCurve(generatedClip, curveBindings[i], workingCurves[i]); } AnimationUtility.SetAnimationEvents(generatedClip, newEvents.ToArray()); EditorUtility.SetDirty(generatedClip); AssetDatabase.CreateAsset(generatedClip, a_directory + "/" + generatedClip.name + ".anim"); AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(generatedClip)); GeneratedClips.Add(generatedClip); } //End loop clips. Generations is complete //Go through Motion Sections again and modify tag tracks and events cumTimeShift = 0f; //This is the cumulative amount of time shift at the point of modification; curStartTime = 0f; //The start time for the current motion section for (int i = 0; i < motionList.Count; ++i) { MotionSection motionSection = motionList[i]; float startWarpTime = curStartTime; float endWarpTime = motionSection.EndTime; float warpScale = motionSection.GetSpeedMod(curStartTime, presets, this); float localTimeShift = (endWarpTime - startWarpTime) - (endWarpTime - startWarpTime) * warpScale; //Shift MXM Tag Points foreach (TagTrack track in TagTracks) { TagTrack newTrack = new TagTrack(track); List<Vector2> tagList = newTrack.Tags; for (int k = 0; k < tagList.Count; ++k) { Vector2 newTag = tagList[k]; if (newTag.x > startWarpTime && newTag.x < endWarpTime) { newTag.x = startWarpTime + ((newTag.x - startWarpTime) * warpScale) - cumTimeShift; } if (newTag.y > startWarpTime && newTag.y < endWarpTime) { newTag.y = startWarpTime + ((newTag.y - startWarpTime) * warpScale) - cumTimeShift; } tagList[k] = newTag; } GeneratedTagTracks.Add(newTrack); } cumTimeShift += localTimeShift; curStartTime = endWarpTime; } } EditorUtility.SetDirty(this); EditorUtility.ClearProgressBar(); }
//============================================================================================ /** * @brief Copy constructor for the TagTrack class * * @param [TagTrack] _copy - the track to copy from * *********************************************************************************************/ public TagTrack(TagTrack _copy) { m_tagId = _copy.m_tagId; m_clipLength = _copy.m_clipLength; m_tags = new List <Vector2>(_copy.m_tags); }