Пример #1
0
 public void SetKeyframe(FloatParamAnimationTarget target, float time, float val)
 {
     time = time.Snap();
     if (time > Current.animationLength)
     {
         time = Current.animationLength;
     }
     target.SetKeyframe(time, val);
 }
Пример #2
0
        public FloatParamAnimationTarget Add(JSONStorable storable, JSONStorableFloat jsf)
        {
            if (TargetFloatParams.Any(s => s.storable.name == storable.name && s.name == jsf.name))
            {
                return(null);
            }
            var target = new FloatParamAnimationTarget(storable, jsf);

            Add(target);
            return(target);
        }
Пример #3
0
 public void Add(FloatParamAnimationTarget target)
 {
     if (target == null)
     {
         throw new NullReferenceException(nameof(target));
     }
     TargetFloatParams.Add(target);
     TargetFloatParams.Sort(new FloatParamAnimationTarget.Comparer());
     target.onSelectedChanged.AddListener(OnTargetSelectionChanged);
     target.onAnimationKeyframesModified.AddListener(OnAnimationModified);
     onTargetsListChanged.Invoke();
 }
Пример #4
0
 public FloatParamAnimationTarget(FloatParamAnimationTarget source)
 {
     if (source.storable != null)
     {
         storable   = source.storable;
         floatParam = source.floatParam;
         _available = true;
     }
     _atom          = source._atom;
     storableId     = source.storableId;
     floatParamName = source.floatParamName;
 }
Пример #5
0
 private void RemoveFloatParam(FloatParamAnimationTarget target)
 {
     try
     {
         foreach (var clip in animation.clips.Where(c => c.animationLayer == current.animationLayer))
         {
             clip.Remove(target.storable, target.floatParam);
         }
     }
     catch (Exception exc)
     {
         SuperController.LogError($"VamTimeline.{nameof(AddRemoveTargetsScreen)}.{nameof(RemoveFloatParam)}: " + exc);
     }
 }
Пример #6
0
 private void RemoveFloatParam(FloatParamAnimationTarget target)
 {
     try
     {
         foreach (var clip in plugin.animation.Clips)
         {
             clip.Remove(target.storable, target.floatParam);
         }
     }
     catch (Exception exc)
     {
         SuperController.LogError($"VamTimeline.{nameof(TargetsScreen)}.{nameof(RemoveFloatParam)}: " + exc);
     }
 }
Пример #7
0
        public ICurveAnimationTarget Clone(bool copyKeyframes)
        {
            var clone = new FloatParamAnimationTarget(_atom, storableId, floatParamName);

            if (copyKeyframes)
            {
                clone.value.keys.AddRange(value.keys);
            }
            else
            {
                clone.value.SetKeyframe(0f, value.keys[0].value, CurveTypeValues.SmoothLocal);
                clone.value.SetKeyframe(value.length - 1, value.keys[value.length - 1].value, CurveTypeValues.SmoothLocal);
                clone.value.ComputeCurves();
            }
            return(clone);
        }
Пример #8
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);
                }
            }
        }
Пример #10
0
 public void Remove(FloatParamAnimationTarget target)
 {
     Remove(targetFloatParams, target);
 }
Пример #11
0
 public FloatParamAnimationTarget Add(FloatParamAnimationTarget target)
 {
     return(Add(targetFloatParams, new FloatParamAnimationTarget.Comparer(), target));
 }
Пример #12
0
 public FloatParamAnimationTarget Add(FloatParamAnimationTarget target)
 {
     target.value.loop = _loop;
     return(Add(targetFloatParams, new FloatParamAnimationTarget.Comparer(), target));
 }
Пример #13
0
        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);
                    AnimationCurve leadCurve = target.GetLeadCurve();
                    for (var key = 0; key < leadCurve.length; key++)
                    {
                        var time = leadCurve[key].time;
                        var ms   = time.ToMilliseconds();
                        if (!target.settings.ContainsKey(ms))
                        {
                            target.settings.Add(ms, new KeyframeSettings {
                                curveType = CurveTypeValues.LeaveAsIs
                            });
                        }
                    }
                }
            }

            JSONArray paramsJSON = clipJSON["FloatParams"].AsArray;
            var       morphs     = GetMorphs();

            if (paramsJSON != null)
            {
                foreach (JSONClass paramJSON in paramsJSON)
                {
                    var storableId     = paramJSON["Storable"].Value;
                    var floatParamName = paramJSON["Name"].Value;
                    if (storableId == "geometry")
                    {
                        // This allows loading an animation even though the animatable option was checked off (e.g. loading a pose)
                        var morph = morphs.FirstOrDefault(m => m.jsonFloat.name == floatParamName);
                        if (morph == null)
                        {
                            SuperController.LogError($"VamTimeline: Atom '{_atom.uid}' does not have a morph (geometry) '{floatParamName}'");
                            continue;
                        }
                        if (!morph.animatable)
                        {
                            morph.animatable = true;
                        }
                    }
                    var storable = _atom.GetStorableByID(storableId);
                    if (storable == null)
                    {
                        SuperController.LogError($"VamTimeline: Atom '{_atom.uid}' does not have a storable '{storableId}'");
                        continue;
                    }
                    var jsf = storable.GetFloatJSONParam(floatParamName);
                    if (jsf == null)
                    {
                        SuperController.LogError($"VamTimeline: Atom '{_atom.uid}' does not have a param '{storableId}/{floatParamName}'");
                        continue;
                    }
                    var target = new FloatParamAnimationTarget(storable, jsf);
                    clip.Add(target);
                    DeserializeCurve(target.value, paramJSON["Value"], clip.animationLength);
                }
            }
        }