Example #1
0
        private void CropAt(float delta, float time)
        {
            var keyframeOps = new KeyframesOperations(_clip);

            foreach (var target in _clip.GetAllTargets())
            {
                // TODO: Create new keyframe if missing from evaluate curve
                var snapshots = target
                                .GetAllKeyframesTime()
                                .Where(t => t <= time || t >= time - delta)
                                .Select(t =>
                {
                    var newTime = t <= time ? t : t + delta;
                    return(new SnapshotAt {
                        time = newTime, snapshot = target.GetSnapshot(t)
                    });
                })
                                .ToList();
                keyframeOps.RemoveAll(target, true);

                foreach (var s in snapshots)
                {
                    target.SetSnapshot(s.time, s.snapshot);
                }

                target.AddEdgeFramesIfMissing(_clip.animationLength);
            }
        }
Example #2
0
        public void Loop(float newAnimationLength)
        {
            var keyframeOps             = new KeyframesOperations(_clip);
            var originalAnimationLength = _clip.animationLength;

            _clip.animationLength = newAnimationLength;
            foreach (var target in _clip.GetAllTargets())
            {
                var snapshots = target
                                .GetAllKeyframesTime()
                                .Select(t => new SnapshotAt {
                    time = t, snapshot = target.GetSnapshot(t)
                })
                                .ToList();
                snapshots.RemoveAt(snapshots.Count - 1);
                keyframeOps.RemoveAll(target, true);

                var iteration = 0;
                var i         = 0;
                while (true)
                {
                    var snapshot = snapshots[i++];
                    var time     = snapshot.time + iteration * originalAnimationLength;
                    if (time > newAnimationLength)
                    {
                        break;
                    }
                    target.SetSnapshot(time, snapshot.snapshot);
                    if (i >= snapshots.Count)
                    {
                        i = 0; iteration++;
                    }
                }

                target.AddEdgeFramesIfMissing(_clip.animationLength);
            }
        }
Example #3
0
        public void Stretch(float newAnimationLength)
        {
            var keyframeOps             = new KeyframesOperations(_clip);
            var originalAnimationLength = _clip.animationLength;

            _clip.animationLength = newAnimationLength;
            var ratio = newAnimationLength / originalAnimationLength;

            foreach (var target in _clip.GetAllTargets())
            {
                var snapshots = target
                                .GetAllKeyframesTime()
                                .Select(t => new SnapshotAt {
                    time = t, snapshot = target.GetSnapshot(t)
                })
                                .ToList();
                keyframeOps.RemoveAll(target, true);

                foreach (var s in snapshots)
                {
                    target.SetSnapshot((s.time * ratio).Snap(), s.snapshot);
                }
            }
        }
        public IEnumerator Execute(List <FreeControllerV3> controllers)
        {
            var containingAtom = _containingAtom;
            var keyOps         = new KeyframesOperations(clip);
            var targetOps      = new TargetsOperations(_containingAtom, _animation, clip);

            yield return(0);

            var controlCounter = 0;
            var motControls    = containingAtom.motionAnimationControls
                                 .Where(m => m?.clip?.clipLength > 0.1f)
                                 .Where(m => controllers.Count == 0 || controllers.Contains(m.controller))
                                 .Where(m => m.clip.steps.Any(s => s.positionOn || s.rotationOn))
                                 .ToList();

            foreach (var mot in motControls)
            {
                FreeControllerAnimationTarget target = null;
                FreeControllerV3 ctrl;

                yield return(new Progress {
                    controllersProcessed = ++controlCounter, controllersTotal = motControls.Count
                });

                try
                {
                    ctrl   = mot.controller;
                    target = clip.targetControllers.FirstOrDefault(t => t.controller == ctrl);

                    if (_animation.index.ByLayer().Where(l => l.Key != clip.animationLayer).Select(l => l.Value.First()).SelectMany(c => c.targetControllers).Any(t2 => t2.controller == ctrl))
                    {
                        SuperController.LogError($"Skipping controller {ctrl.name} because it was used in another layer.");
                        continue;
                    }

                    if (target == null)
                    {
                        target = targetOps.Add(ctrl);
                        target.AddEdgeFramesIfMissing(clip.animationLength);
                    }
                    else
                    {
                        keyOps.RemoveAll(target);
                    }
                    target.StartBulkUpdates();
                    target.Validate(clip.animationLength);

                    var enumerator = ProcessController(mot.clip, target, ctrl).GetEnumerator();
                    while (enumerator.MoveNext())
                    {
                        yield return(enumerator.Current);
                    }
                }
                finally
                {
                    // NOTE: This should not be necessary, but for some reason dirty is set back to false too early and some changes are not picked up
                    target.dirty = true;
                    target?.EndBulkUpdates();
                }
            }
        }
Example #5
0
        public IEnumerator StartRecording(List <FreeControllerAnimationTarget> controllers, List <FloatParamAnimationTarget> floatParams)
        {
            // TODO: Handle stopping in the middle of it
            // TODO: Handle starting while it's already recording
            // TODO: Counter should use in-game rather than helptext

            _animation.StopAll();
            _animation.ResetAll();

            var keyframesOps = new KeyframesOperations(_clip);

            for (var i = 5; i > 0; i--)
            {
                SuperController.singleton.helpText = $"Start recording in {i}...";
                var next = Time.realtimeSinceStartup + 1f;
                while (Time.realtimeSinceStartup < next)
                {
                    yield return(0);

                    if (Input.GetKeyDown(KeyCode.Escape))
                    {
                        yield break;
                    }
                }
            }

            SuperController.singleton.helpText = "Recording...";

            foreach (var target in controllers)
            {
                keyframesOps.RemoveAll(target);
            }
            foreach (var target in floatParams)
            {
                keyframesOps.RemoveAll(target);
            }

            _clip.DirtyAll();
            _animation.RebuildAnimationNow();

            yield return(0);

            foreach (var target in controllers)
            {
                target.recording = true;
                target.StartBulkUpdates();
            }
            foreach (var target in floatParams)
            {
                target.recording = true;
                target.StartBulkUpdates();
            }

            _animation.PlayClip(_clip, false);

            while (_animation.playTime <= _clip.animationLength && _animation.isPlaying)
            {
                if (Input.GetKeyDown(KeyCode.Escape))
                {
                    break;
                }
                yield return(0);
            }

            _animation.StopAll();
            _animation.ResetAll();
            SuperController.singleton.helpText = "";

            // TODO: This needs to be guaranteed. We could register the enumerator inside a disposable class, dispose being called in different cancel situations
            foreach (var target in controllers)
            {
                target.recording = false;
                target.EndBulkUpdates();
            }
            foreach (var target in floatParams)
            {
                target.recording = false;
                target.EndBulkUpdates();
            }

            _clip.DirtyAll();
        }