private void CropEnd(float newAnimationLength) { foreach (var target in _clip.GetAllCurveTargets()) { foreach (var curve in target.GetCurves()) { var lastKeyframe = curve.GetLastFrame(); var lastCurveType = lastKeyframe.HasValue() ? lastKeyframe.curveType : CurveTypeValues.SmoothLocal; curve.AddKey(newAnimationLength, curve.Evaluate(newAnimationLength), lastCurveType); } target.dirty = true; var keyframesToDelete = target.GetAllKeyframesTime().Where(t => t > newAnimationLength); foreach (var t in keyframesToDelete) { target.DeleteFrame(t); } } foreach (var target in _clip.targetTriggers) { while (target.triggersMap.Count > 0) { var lastTrigger = target.triggersMap.Keys.Last(); if (lastTrigger / 1000f > newAnimationLength) { target.triggersMap.Remove(lastTrigger); continue; } break; } target.AddEdgeFramesIfMissing(newAnimationLength); } }
private void CropEnd(float newAnimationLength) { foreach (var target in _clip.GetAllCurveTargets()) { foreach (var curve in target.GetCurves()) { var key = curve.AddKey(newAnimationLength, curve.Evaluate(newAnimationLength)); } target.EnsureKeyframeSettings(newAnimationLength, target.settings.Last().Value.curveType); target.dirty = true; var keyframesToDelete = target.GetAllKeyframesTime().Where(t => t > newAnimationLength); foreach (var t in keyframesToDelete) { target.DeleteFrame(t); } } foreach (var target in _clip.targetTriggers) { while (target.triggersMap.Count > 0) { var lastTrigger = target.triggersMap.Keys.Last(); if (lastTrigger * 1000f > newAnimationLength) { target.triggersMap.Remove(lastTrigger); continue; } break; } target.AddEdgeFramesIfMissing(newAnimationLength); } }
public List <AtomAnimationClip> ImportClip(AtomAnimationClip clip) { var clips = new List <AtomAnimationClip>(); var matchingLayer = _animation.clips.FirstOrDefault(c => { // We only need to match float params and controllers, triggers can be in any layers if (!clip.targetFloatParams.All(t => c.targetFloatParams.Any(t.TargetsSameAs))) { return(false); } if (!clip.targetControllers.All(t => c.targetControllers.Any(t.TargetsSameAs))) { return(false); } return(true); }); if (matchingLayer != null) { clip.animationLayer = matchingLayer.animationLayer; // Add missing targets foreach (var target in matchingLayer.targetFloatParams) { if (!clip.targetFloatParams.Any(t => target.TargetsSameAs(t))) { var missing = new FloatParamAnimationTarget(target); missing.AddEdgeFramesIfMissing(clip.animationLength); clip.Add(missing); } } foreach (var target in matchingLayer.targetControllers) { if (!clip.targetControllers.Any(t => target.TargetsSameAs(t))) { var missing = new FreeControllerAnimationTarget(target.controller); missing.AddEdgeFramesIfMissing(clip.animationLength); clip.Add(missing); } } } else if (_animation.index.ByLayer(clip.animationLayer).Any()) { clip.animationLayer = new LayersOperations(_animation, clip).GetNewLayerName(); } foreach (var controller in clip.targetControllers.Select(t => t.controller)) { if (_animation.clips.Where(c => c.animationLayer != clip.animationLayer).Any(c => c.targetControllers.Any(t => t.controller == controller))) { if (!_silent) { SuperController.LogError($"Timeline: Imported animation contains controller {controller.name} in layer {clip.animationLayer}, but that controller is already used elsewhere in your animation. To import, a layer is needed with targets: {string.Join(", ", clip.GetAllCurveTargets().Select(c => c.GetShortName()).ToArray())}"); } return(clips); } } foreach (var floatParam in clip.targetFloatParams.Select(t => t.name)) { if (_animation.clips.Where(c => c.animationLayer != clip.animationLayer).Any(c => c.targetFloatParams.Any(t => t.name == floatParam))) { if (!_silent) { SuperController.LogError($"Timeline: Imported animation contains storable float {floatParam} in layer {clip.animationLayer}, but that storable is already used elsewhere in your animation. To import, a layer is needed with targets: {string.Join(", ", clip.GetAllCurveTargets().Select(c => c.GetShortName()).ToArray())}"); } return(clips); } } var existingClip = _animation.GetClip(clip.animationLayer, clip.animationName); if (existingClip != null) { if (existingClip.IsEmpty()) { _animation.clips.Remove(existingClip); existingClip.Dispose(); } else { var newAnimationName = GenerateUniqueAnimationName(clip.animationLayer, clip.animationName); if (!_silent) { SuperController.LogError($"Timeline: Imported clip '{clip.animationNameQualified}' already exists and will be imported with the name {newAnimationName}"); } clip.animationName = newAnimationName; } } clips.Add(clip); return(clips); }