Пример #1
0
        public void Update()
        {
            if (!animationEditContext.CanEdit())
            {
                return;
            }

            var grabbing         = GetCurrentlyGrabbing();
            var grabbingHasValue = grabbing != null;

            if (_grabbedTarget == null && grabbingHasValue && !grabbing.possessed)
            {
                _grabbedTarget = animationEditContext.current.targetControllers.FirstOrDefault(c => c.controller == grabbing);
            }
            if (_grabbedTarget != null && grabbingHasValue)
            {
                if (Input.GetKeyDown(KeyCode.Escape))
                {
                    _cancelNextGrabbedControllerRelease = true;
                }
            }
            else if (_grabbedTarget != null && !grabbingHasValue)
            {
                var grabbedTarget = _grabbedTarget;
                _grabbedTarget = null;
                if (_cancelNextGrabbedControllerRelease)
                {
                    _cancelNextGrabbedControllerRelease = false;
                    return;
                }

                RecordFreeControllerPosition(grabbedTarget);
            }
        }
Пример #2
0
        public override void Init(IAtomPlugin plugin, object arg)
        {
            base.Init(plugin, arg);

            if (arg == null)
            {
                arg = _lastArg;
            }
            else
            {
                _lastArg = (string)arg;
            }
            _target = current.targetControllers.FirstOrDefault(t => t.name == (string)arg);

            CreateChangeScreenButton("<b><</b> <i>Back</i>", TargetsScreen.ScreenName);

            prefabFactory.CreateHeader("Controller settings", 1);

            if (_target == null)
            {
                prefabFactory.CreateTextField(new JSONStorableString("", "Cannot show the selected target settings.\nPlease go back and re-enter this screen."));
                return;
            }
            prefabFactory.CreateHeader(_target.name, 2);

            prefabFactory.CreateHeader("Parenting", 1);

            InitParentUI();

            prefabFactory.CreateHeader("Options", 1);

            InitControlUI();
            InitWeightUI();
        }
Пример #3
0
        public void RecordFreeControllerPosition(FreeControllerAnimationTarget target)
        {
            var time = animationEditContext.clipTime.Snap();

            if (animationEditContext.autoKeyframeAllControllers)
            {
                foreach (var t in animationEditContext.GetAllOrSelectedTargets().OfType <FreeControllerAnimationTarget>())
                {
                    animationEditContext.SetKeyframeToCurrentTransform(target, time);
                }
            }
            else
            {
                animationEditContext.SetKeyframeToCurrentTransform(target, time);
            }

            if (animationEditContext.current.autoTransitionPrevious && time == 0)
            {
                animationEditContext.Sample();
            }
            else if (animationEditContext.current.autoTransitionNext && time == animationEditContext.current.animationLength)
            {
                animationEditContext.Sample();
            }
        }
Пример #4
0
        public void Update()
        {
            var sc = SuperController.singleton;

            if (sc.gameMode != SuperController.GameMode.Edit)
            {
                return;
            }

            var grabbing = sc.RightGrabbedController ?? sc.LeftGrabbedController ?? sc.RightFullGrabbedController ?? sc.LeftFullGrabbedController;

            if (grabbing != null && grabbing.containingAtom != containingAtom)
            {
                grabbing = null;
            }
            else if (Input.GetMouseButton(0) && grabbing == null)
            {
                grabbing = containingAtom.freeControllers.FirstOrDefault(c => _grabbingControllers.Contains(c.linkToRB?.gameObject.name));
            }

            if (_grabbedController == null && grabbing != null && !grabbing.possessed)
            {
                _grabbedController = animation.current.targetControllers.FirstOrDefault(c => c.controller == grabbing);
            }
            if (_grabbedController != null && grabbing != null)
            {
                if (Input.GetKeyDown(KeyCode.Escape))
                {
                    _cancelNextGrabbedControllerRelease = true;
                }
            }
            else if (_grabbedController != null && grabbing == null)
            {
                var grabbedController = _grabbedController;
                _grabbedController = null;
                if (_cancelNextGrabbedControllerRelease)
                {
                    _cancelNextGrabbedControllerRelease = false;
                    return;
                }

                var time = animation.clipTime.Snap();
                if (animation.autoKeyframeAllControllers)
                {
                    foreach (var target in animation.current.GetAllOrSelectedTargets().OfType <FreeControllerAnimationTarget>())
                    {
                        SetControllerKeyframe(time, target);
                    }
                }
                else
                {
                    SetControllerKeyframe(time, grabbedController);
                }

                if (animation.current.transition && (animation.clipTime == 0 || animation.clipTime == animation.current.animationLength))
                {
                    animation.Sample();
                }
            }
        }
Пример #5
0
 public FreeControllerAnimationTarget Add(FreeControllerAnimationTarget target)
 {
     if (targetControllers.Any(t => t.controller == target.controller))
     {
         return(null);
     }
     return(Add(targetControllers, new FreeControllerAnimationTarget.Comparer(), target));
 }
Пример #6
0
 private void SetControllerKeyframe(float time, FreeControllerAnimationTarget target)
 {
     animation.SetKeyframeToCurrentTransform(target, time);
     if (target.settings[time.ToMilliseconds()]?.curveType == CurveTypeValues.CopyPrevious)
     {
         animation.Current.ChangeCurve(time, CurveTypeValues.Smooth);
     }
 }
Пример #7
0
 public void Add(FreeControllerAnimationTarget target)
 {
     TargetControllers.Add(target);
     TargetControllers.Sort(new FreeControllerAnimationTarget.Comparer());
     target.onSelectedChanged.AddListener(OnTargetSelectionChanged);
     target.onAnimationKeyframesModified.AddListener(OnAnimationModified);
     onTargetsListChanged.Invoke();
 }
Пример #8
0
 public void SetKeyframeToCurrentTransform(FreeControllerAnimationTarget target, float time)
 {
     time = time.Snap();
     if (time > Current.animationLength)
     {
         time = Current.animationLength;
     }
     target.SetKeyframeToCurrentTransform(time);
 }
Пример #9
0
 public int SetKeyframeToCurrentTransform(FreeControllerAnimationTarget target, float time)
 {
     time = time.Snap();
     if (time > current.animationLength)
     {
         time = current.animationLength;
     }
     return(target.SetKeyframeToCurrentTransform(time));
 }
Пример #10
0
        public FreeControllerAnimationTarget Add(FreeControllerV3 controller)
        {
            if (TargetControllers.Any(c => c.controller == controller))
            {
                return(null);
            }
            var target = new FreeControllerAnimationTarget(controller);

            Add(target);
            return(target);
        }
Пример #11
0
 private bool TryMoveNext(IEnumerator enumerator, FreeControllerAnimationTarget target)
 {
     try
     {
         return(enumerator.MoveNext());
     }
     catch
     {
         target.EndBulkUpdates();
         throw;
     }
 }
Пример #12
0
 public FreeControllerAnimationTarget Add(FreeControllerAnimationTarget target)
 {
     if (targetControllers.Any(t => t.controller == target.controller))
     {
         return(null);
     }
     foreach (var curve in target.curves)
     {
         curve.loop = _loop;
     }
     return(Add(targetControllers, new FreeControllerAnimationTarget.Comparer(), target));
 }
Пример #13
0
        private void UpdateNotPlaying()
        {
            var sc       = SuperController.singleton;
            var grabbing = sc.RightGrabbedController ?? sc.LeftGrabbedController ?? sc.RightFullGrabbedController ?? sc.LeftFullGrabbedController;

            if (grabbing != null && grabbing.containingAtom != base.containingAtom)
            {
                grabbing = null;
            }
            else if (Input.GetMouseButton(0) && grabbing == null)
            {
                grabbing = base.containingAtom.freeControllers.FirstOrDefault(c => _grabbingControllers.Contains(c.linkToRB?.gameObject.name));
            }

            if (_grabbedController == null && grabbing != null)
            {
                _grabbedController = animation.Current.TargetControllers.FirstOrDefault(c => c.controller == grabbing);
            }
            if (_grabbedController != null && grabbing != null)
            {
                if (Input.GetKeyDown(KeyCode.Escape))
                {
                    _cancelNextGrabbedControllerRelease = true;
                }
            }
            else if (_grabbedController != null && grabbing == null)
            {
                var grabbedController = _grabbedController;
                _grabbedController = null;
                if (_cancelNextGrabbedControllerRelease)
                {
                    _cancelNextGrabbedControllerRelease = false;
                    return;
                }
                if (animation.Current.Transition)
                {
                    SampleAfterRebuild();
                }
                var time = animation.Time.Snap();
                if (autoKeyframeAllControllersJSON.val)
                {
                    foreach (var target in animation.Current.TargetControllers)
                    {
                        SetControllerKeyframe(time, target);
                    }
                }
                else
                {
                    SetControllerKeyframe(time, grabbedController);
                }
            }
        }
Пример #14
0
 private void RemoveAnimatedController(FreeControllerAnimationTarget target)
 {
     try
     {
         foreach (var clip in animation.clips.Where(c => c.animationLayer == current.animationLayer))
         {
             clip.Remove(target.controller);
         }
     }
     catch (Exception exc)
     {
         SuperController.LogError($"VamTimeline.{nameof(AddRemoveTargetsScreen)}.{nameof(RemoveAnimatedController)}: " + exc);
     }
 }
Пример #15
0
 private void RemoveAnimatedController(FreeControllerAnimationTarget target)
 {
     try
     {
         foreach (var clip in plugin.animation.Clips)
         {
             clip.Remove(target.controller);
         }
     }
     catch (Exception exc)
     {
         SuperController.LogError($"VamTimeline.{nameof(TargetsScreen)}.{nameof(RemoveAnimatedController)}: " + exc);
     }
 }
        private static FreeControllerAnimationTarget GivenAFreeController(TestContext context)
        {
            var controller = new GameObject("Test Controller");

            controller.SetActive(false);
            controller.transform.SetParent(context.gameObject.transform, false);
            var fc = controller.AddComponent <FreeControllerV3>();

            fc.UITransforms         = new Transform[0];
            fc.UITransformsPlayMode = new Transform[0];
            var target = new FreeControllerAnimationTarget(fc);

            return(target);
        }
Пример #17
0
        private IEnumerable ExtractFramesWithFpsTechnique(MotionAnimationClip clip, FreeControllerAnimationTarget target, FreeControllerV3 ctrl)
        {
            var minPositionDistanceForFlat = 0.01f;
            var batchStopwatch             = Stopwatch.StartNew();
            var containingAtom             = plugin.containingAtom;
            var frameLength = 1f / _reduceMaxFramesPerSecondJSON.val;

            var lastRecordedFrame            = float.MinValue;
            MotionAnimationStep previousStep = null;

            for (var stepIndex = 0; stepIndex < (clip.steps.Count - (current.loop ? 1 : 0)); stepIndex++)
            {
                try
                {
                    var step = clip.steps[stepIndex];
                    var time = step.timeStep.Snap(0.01f);
                    if (time - lastRecordedFrame < frameLength)
                    {
                        continue;
                    }
                    var k = ControllerKeyframe.FromStep(time, step, containingAtom, ctrl);
                    target.SetKeyframe(time, k.position, k.rotation);
                    if (previousStep != null && (target.controller.name == "lFootControl" || target.controller.name == "rFootControl") && Vector3.Distance(previousStep.position, step.position) <= minPositionDistanceForFlat)
                    {
                        KeyframeSettings settings;
                        if (target.settings.TryGetValue(previousStep.timeStep.Snap().ToMilliseconds(), out settings))
                        {
                            target.ChangeCurve(previousStep.timeStep, CurveTypeValues.Linear);
                        }
                    }
                    lastRecordedFrame = time;
                    previousStep      = step;
                }
                catch (Exception exc)
                {
                    SuperController.LogError($"VamTimeline.{nameof(MocapScreen)}.{nameof(ImportRecordedCoroutine)}[Step]: {exc}");
                    yield break;
                }

                if (batchStopwatch.ElapsedMilliseconds > 5)
                {
                    batchStopwatch.Reset();
                    yield return(0);

                    batchStopwatch.Start();
                }
            }
        }
Пример #18
0
        private ReducerBucket Scan(List <ControllerKeyframe> steps, FreeControllerAnimationTarget target, int from, int to)
        {
            var bucket = new ReducerBucket
            {
                from = from,
                to   = to
            };

            for (var i = from; i <= to; i++)
            {
                var step         = steps[i];
                var positionDiff = Vector3.Distance(
                    new Vector3(
                        target.x.Evaluate(step.time),
                        target.y.Evaluate(step.time),
                        target.z.Evaluate(step.time)
                        ),
                    step.position
                    );
                if (positionDiff > bucket.largestPositionDistance)
                {
                    bucket.largestPositionDistance        = positionDiff;
                    bucket.keyWithLargestPositionDistance = i;
                }

                var rotationAngle = Vector3.Angle(
                    new Quaternion(
                        target.rotX.Evaluate(step.time),
                        target.rotY.Evaluate(step.time),
                        target.rotZ.Evaluate(step.time),
                        target.rotW.Evaluate(step.time)
                        ).eulerAngles,
                    step.rotation.eulerAngles
                    );
                if (rotationAngle > bucket.largestRotationAngle)
                {
                    bucket.largestRotationAngle        = rotationAngle;
                    bucket.keyWithLargestRotationAngle = i;
                }
            }
            return(bucket);
        }
Пример #19
0
        protected IEnumerable ProcessController(MotionAnimationClip motClip, FreeControllerAnimationTarget target, FreeControllerV3 ctrl)
        {
            var frameLength = 0.001f;

            var lastRecordedFrame = float.MinValue;

            // Vector3? previousPosition = null;
            // var previousTime = 0f;
            for (var stepIndex = 0; stepIndex < motClip.steps.Count - (clip.loop ? 1 : 0); stepIndex++)
            {
                var step = motClip.steps[stepIndex];
                var time = step.timeStep.Snap(0.01f);
                if (time - lastRecordedFrame < frameLength)
                {
                    continue;
                }
                if (time > clip.animationLength)
                {
                    break;
                }
                if (Mathf.Abs(time - clip.animationLength) < 0.001f)
                {
                    time = clip.animationLength;
                }
                var k = ControllerKeyframe.FromStep(time, step, ctrl);
                target.SetKeyframe(time, k.position, k.rotation, CurveTypeValues.SmoothLocal);
                // SuperController.LogMessage($"{k.position.x:0.0000}, {k.position.y:0.0000},{k.position.z:0.0000}");
                // if (previousPosition.HasValue && (target.controller.name == "lFootControl" || target.controller.name == "rFootControl") && Vector3.Distance(previousPosition.Value, step.position) <= minPositionDistanceForFlat)
                // {
                //     target.ChangeCurve(previousTime, CurveTypeValues.Linear);
                // }
                lastRecordedFrame = time;
                // previousPosition = step.position;
                // previousTime = time;
            }

            target.AddEdgeFramesIfMissing(clip.animationLength);
            yield break;
        }
        public ICurveAnimationTarget Clone(bool copyKeyframes)
        {
            var clone = new FreeControllerAnimationTarget(controller);

            if (copyKeyframes)
            {
                clone.x.keys.AddRange(x.keys);
                clone.y.keys.AddRange(y.keys);
                clone.z.keys.AddRange(z.keys);
                clone.rotX.keys.AddRange(rotX.keys);
                clone.rotY.keys.AddRange(rotY.keys);
                clone.rotZ.keys.AddRange(rotZ.keys);
                clone.rotW.keys.AddRange(rotW.keys);
            }
            else
            {
                clone.SetKeyframe(0f, GetKeyframePosition(0), GetKeyframeRotation(0), CurveTypeValues.SmoothLocal);
                clone.SetKeyframe(GetKeyframeTime(x.length - 1), GetKeyframePosition(x.length - 1), GetKeyframeRotation(x.length - 1), CurveTypeValues.SmoothLocal);
                clone.ComputeCurves();
            }
            return(clone);
        }
Пример #21
0
        public FreeControllerAnimationTarget Add(FreeControllerV3 fc)
        {
            FreeControllerAnimationTarget target = _clip.targetControllers.FirstOrDefault(t => t.controller == fc);

            if (target != null)
            {
                return(target);
            }
            foreach (var clip in _animation.clips.Where(c => c.animationLayer == _clip.animationLayer))
            {
                var t = clip.Add(fc);
                if (t == null)
                {
                    continue;
                }
                t.SetKeyframeToCurrentTransform(0f);
                t.SetKeyframeToCurrentTransform(clip.animationLength);
                if (clip == _clip)
                {
                    target = t;
                }
            }
            return(target);
        }
Пример #22
0
        private IEnumerable ExtractFramesWithReductionTechnique(MotionAnimationClip clip, FreeControllerAnimationTarget target, FreeControllerV3 ctrl)
        {
            var minFrameDistance = 1f / _reduceMaxFramesPerSecondJSON.val;
            var maxIterations    = (int)(clip.clipLength * 10);

            var containingAtom = plugin.containingAtom;
            var steps          = clip.steps
                                 .Where(s => s.positionOn || s.rotationOn)
                                 .GroupBy(s => s.timeStep.Snap(minFrameDistance).ToMilliseconds())
                                 .Select(g =>
            {
                var step = g.OrderBy(s => Math.Abs(g.Key - s.timeStep)).First();
                return(ControllerKeyframe.FromStep((g.Key / 1000f).Snap(), step, containingAtom, ctrl));
            })
                                 .ToList();

            if (steps.Count < 2)
            {
                yield break;
            }

            target.SetKeyframe(0, steps[0].position, steps[0].rotation);
            target.SetKeyframe(current.animationLength, steps[steps.Count - 1].position, steps[steps.Count - 1].rotation);

            var buckets = new List <ReducerBucket>
            {
                Scan(steps, target, 1, steps.Count - 2)
            };

            for (var iteration = 0; iteration < maxIterations; iteration++)
            {
                // Scan for largest difference with curve
                var bucketWithLargestPositionDistance = -1;
                var keyWithLargestPositionDistance    = -1;
                var largestPositionDistance           = 0f;
                var bucketWithLargestRotationAngle    = -1;
                var keyWithLargestRotationAngle       = -1;
                var largestRotationAngle = 0f;
                for (var bucketIndex = 0; bucketIndex < buckets.Count; bucketIndex++)
                {
                    var bucket = buckets[bucketIndex];
                    if (bucket.largestPositionDistance > largestPositionDistance)
                    {
                        largestPositionDistance           = bucket.largestPositionDistance;
                        keyWithLargestPositionDistance    = bucket.keyWithLargestPositionDistance;
                        bucketWithLargestPositionDistance = bucketIndex;
                    }
                    if (bucket.largestRotationAngle > largestRotationAngle)
                    {
                        largestRotationAngle           = bucket.largestRotationAngle;
                        keyWithLargestRotationAngle    = bucket.keyWithLargestRotationAngle;
                        bucketWithLargestRotationAngle = bucketIndex;
                    }
                }

                // Cannot find large enough diffs, exit
                if (keyWithLargestRotationAngle == -1 || keyWithLargestPositionDistance == -1)
                {
                    break;
                }
                var posInRange = largestPositionDistance >= _reduceMinPosDistanceJSON.val;
                var rotInRange = largestRotationAngle >= _reduceMinRotationJSON.val;
                if (!posInRange && !rotInRange)
                {
                    break;
                }

                // This is an attempt to compare translations and rotations
                var normalizedPositionDistance = largestPositionDistance / 0.4f;
                var normalizedRotationAngle    = largestRotationAngle / 180f;
                var selectPosOverRot           = (normalizedPositionDistance > normalizedRotationAngle) && posInRange;
                var keyToApply = selectPosOverRot ? keyWithLargestPositionDistance : keyWithLargestRotationAngle;

                var step = steps[keyToApply];
                var key  = target.SetKeyframe(step.time, step.position, step.rotation);
                target.SmoothNeighbors(key);

                int bucketToSplitIndex;
                if (selectPosOverRot)
                {
                    bucketToSplitIndex = bucketWithLargestPositionDistance;
                }
                else
                {
                    bucketToSplitIndex = bucketWithLargestRotationAngle;
                }

                if (bucketToSplitIndex > -1)
                {
                    // Split buckets and exclude the scanned keyframe, we never have to scan it again.
                    var bucketToSplit = buckets[bucketToSplitIndex];
                    buckets.RemoveAt(bucketToSplitIndex);
                    if (bucketToSplit.to - keyToApply + 1 > 2)
                    {
                        buckets.Insert(bucketToSplitIndex, Scan(steps, target, keyToApply + 1, bucketToSplit.to));
                    }
                    if (keyToApply - 1 - bucketToSplit.from > 2)
                    {
                        buckets.Insert(bucketToSplitIndex, Scan(steps, target, bucketToSplit.from, keyToApply - 1));
                    }
                }

                yield return(0);
            }
        }
Пример #23
0
        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();
                }
            }
        }
Пример #24
0
 private void SetControllerKeyframe(float time, FreeControllerAnimationTarget target)
 {
     animation.SetKeyframeToCurrentTransform(target, time);
 }
Пример #25
0
        private static FreeControllerAnimationTarget CopyTarget(AtomAnimationClip clip, FreeControllerAnimationTarget origTarget)
        {
            var newTarget = clip.Add(origTarget.controller);

            newTarget.SetParent(origTarget.parentAtomId, origTarget.parentRigidbodyId);
            newTarget.weight          = origTarget.weight;
            newTarget.controlPosition = origTarget.controlPosition;
            newTarget.controlRotation = origTarget.controlPosition;
            return(newTarget);
        }
Пример #26
0
        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);
        }
        private void DeserializeClip(AtomAnimationClip clip, JSONClass clipJSON)
        {
            var animationPatternUID = clipJSON["AnimationPattern"]?.Value;

            if (!string.IsNullOrEmpty(animationPatternUID))
            {
                var animationPattern = SuperController.singleton.GetAtomByUid(animationPatternUID)?.GetComponentInChildren <AnimationPattern>();
                if (animationPattern == null)
                {
                    SuperController.LogError($"Animation Pattern '{animationPatternUID}' linked to animation '{clip.animationName}' of atom '{_atom.uid}' was not found in scene");
                }
                else
                {
                    clip.animationPattern = animationPattern;
                }
            }

            JSONArray controllersJSON = clipJSON["Controllers"].AsArray;

            if (controllersJSON != null)
            {
                foreach (JSONClass controllerJSON in controllersJSON)
                {
                    var controllerName = controllerJSON["Controller"].Value;
                    var controller     = _atom.freeControllers.Single(fc => fc.name == controllerName);
                    if (controller == null)
                    {
                        SuperController.LogError($"VamTimeline: Atom '{_atom.uid}' does not have a controller '{controllerName}'");
                        continue;
                    }
                    var target = new FreeControllerAnimationTarget(controller);
                    clip.Add(target);
                    DeserializeCurve(target.x, controllerJSON["X"], clip.animationLength, target.settings);
                    DeserializeCurve(target.y, controllerJSON["Y"], clip.animationLength);
                    DeserializeCurve(target.z, controllerJSON["Z"], clip.animationLength);
                    DeserializeCurve(target.rotX, controllerJSON["RotX"], clip.animationLength);
                    DeserializeCurve(target.rotY, controllerJSON["RotY"], clip.animationLength);
                    DeserializeCurve(target.rotZ, controllerJSON["RotZ"], clip.animationLength);
                    DeserializeCurve(target.rotW, controllerJSON["RotW"], clip.animationLength);
                    AddMissingKeyframeSettings(target);
                    target.AddEdgeFramesIfMissing(clip.animationLength);
                }
            }

            JSONArray floatParamsJSON = clipJSON["FloatParams"].AsArray;

            if (floatParamsJSON != null)
            {
                foreach (JSONClass paramJSON in floatParamsJSON)
                {
                    var storableId     = paramJSON["Storable"].Value;
                    var floatParamName = paramJSON["Name"].Value;
                    var target         = new FloatParamAnimationTarget(_atom, storableId, floatParamName);
                    clip.Add(target);
                    DeserializeCurve(target.value, paramJSON["Value"], clip.animationLength, target.settings);
                    AddMissingKeyframeSettings(target);
                    target.AddEdgeFramesIfMissing(clip.animationLength);
                }
            }

            JSONArray triggersJSON = clipJSON["Triggers"].AsArray;

            if (triggersJSON != null)
            {
                foreach (JSONClass triggerJSON in triggersJSON)
                {
                    var target = new TriggersAnimationTarget
                    {
                        name = DeserializeString(triggerJSON["Name"], "Trigger")
                    };
                    foreach (JSONClass entryJSON in triggerJSON["Triggers"].AsArray)
                    {
                        var trigger = new AtomAnimationTrigger();
                        trigger.RestoreFromJSON(entryJSON);
                        target.SetKeyframe(trigger.startTime, trigger);
                    }
                    target.AddEdgeFramesIfMissing(clip.animationLength);
                    clip.Add(target);
                }
            }
        }
Пример #28
0
        private IEnumerator ImportRecordedCoroutine()
        {
            var containingAtom = plugin.containingAtom;
            var totalStopwatch = Stopwatch.StartNew();

            yield return(0);

            var controlCounter = 0;
            var filterSelected = current.targetControllers.Any(c => c.selected);

            foreach (var mot in containingAtom.motionAnimationControls)
            {
                FreeControllerAnimationTarget target = null;
                FreeControllerV3 ctrl;

                _importRecordedUI.buttonText.text = $"Importing, please wait... ({++controlCounter} / {containingAtom.motionAnimationControls.Length})";

                try
                {
                    if (mot == null || mot.clip == null)
                    {
                        continue;
                    }
                    if (mot.clip.clipLength <= 0.1)
                    {
                        continue;
                    }
                    ctrl   = mot.controller;
                    target = current.targetControllers.FirstOrDefault(t => t.controller == ctrl);
                    if (filterSelected && (target == null || !target.selected))
                    {
                        continue;
                    }

                    if (animation.EnumerateLayers().Where(l => l != current.animationLayer).Select(l => animation.clips.First(c => c.animationLayer == l)).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)
                    {
                        if (!mot.clip.steps.Any(s => s.positionOn || s.rotationOn))
                        {
                            continue;
                        }
                        target = operations.Targets().Add(ctrl);
                        target.AddEdgeFramesIfMissing(current.animationLength);
                    }
                    target.Validate(current.animationLength);
                    target.StartBulkUpdates();
                    operations.Keyframes().RemoveAll(target);
                }
                catch (Exception exc)
                {
                    SuperController.LogError($"VamTimeline.{nameof(MocapScreen)}.{nameof(ImportRecordedCoroutine)}[Init]: {exc}");
                    target?.EndBulkUpdates();
                    yield break;
                }

                IEnumerator enumerator;
                try
                {
                    if (_importRecordedOptionsJSON.val == "Keyframe Reduction")
                    {
                        enumerator = ExtractFramesWithReductionTechnique(mot.clip, target, ctrl).GetEnumerator();
                    }
                    else
                    {
                        enumerator = ExtractFramesWithFpsTechnique(mot.clip, target, ctrl).GetEnumerator();
                    }
                }
                catch
                {
                    target.EndBulkUpdates();
                    throw;
                }

                while (TryMoveNext(enumerator, target))
                {
                    yield return(enumerator.Current);
                }

                target.EndBulkUpdates();
            }

            _importRecordedUI.buttonText.text     = "Import recorded animation (mocap)";
            _importRecordedUI.button.interactable = true;
        }
Пример #29
0
 public void Remove(FreeControllerAnimationTarget target)
 {
     Remove(targetControllers, target);
 }
Пример #30
0
        private IEnumerator ImportRecordedCoroutine()
        {
            var containingAtom = plugin.containingAtom;
            var totalStopwatch = Stopwatch.StartNew();

            yield return(0);

            var controlCounter = 0;

            foreach (var mot in containingAtom.motionAnimationControls)
            {
                FreeControllerAnimationTarget target = null;
                FreeControllerV3 ctrl;

                _importRecordedUI.buttonText.text = $"Importing, please wait... ({++controlCounter} / {containingAtom.motionAnimationControls.Length})";

                try
                {
                    if (mot == null || mot.clip == null)
                    {
                        continue;
                    }
                    if (mot.clip.clipLength <= 0.1)
                    {
                        continue;
                    }
                    ctrl = mot.controller;
                    current.Remove(ctrl);
                    target = current.Add(ctrl);
                    target.StartBulkUpdates();
                    target.SetKeyframeToCurrentTransform(0);
                    target.SetKeyframeToCurrentTransform(current.animationLength);
                }
                catch (Exception exc)
                {
                    SuperController.LogError($"VamTimeline.{nameof(MocapScreen)}.{nameof(ImportRecordedCoroutine)}[Init]: {exc}");
                    target?.EndBulkUpdates();
                    yield break;
                }

                IEnumerator enumerator;
                try
                {
                    if (_importRecordedOptionsJSON.val == "Keyframe Reduction")
                    {
                        enumerator = ExtractFramesWithReductionTechnique(mot.clip, target, ctrl).GetEnumerator();
                    }
                    else
                    {
                        enumerator = ExtractFramesWithFpsTechnique(mot.clip, target, ctrl).GetEnumerator();
                    }
                }
                catch
                {
                    target.EndBulkUpdates();
                    throw;
                }

                while (TryMoveNext(enumerator, target))
                {
                    yield return(enumerator.Current);
                }

                target.EndBulkUpdates();
            }

            _importRecordedUI.buttonText.text     = "Import Recorded Animation (Mocap)";
            _importRecordedUI.button.interactable = true;
        }