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); } }
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(); }
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(); } }
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(); } } }
public FreeControllerAnimationTarget Add(FreeControllerAnimationTarget target) { if (targetControllers.Any(t => t.controller == target.controller)) { return(null); } return(Add(targetControllers, new FreeControllerAnimationTarget.Comparer(), target)); }
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); } }
public void Add(FreeControllerAnimationTarget target) { TargetControllers.Add(target); TargetControllers.Sort(new FreeControllerAnimationTarget.Comparer()); target.onSelectedChanged.AddListener(OnTargetSelectionChanged); target.onAnimationKeyframesModified.AddListener(OnAnimationModified); onTargetsListChanged.Invoke(); }
public void SetKeyframeToCurrentTransform(FreeControllerAnimationTarget target, float time) { time = time.Snap(); if (time > Current.animationLength) { time = Current.animationLength; } target.SetKeyframeToCurrentTransform(time); }
public int SetKeyframeToCurrentTransform(FreeControllerAnimationTarget target, float time) { time = time.Snap(); if (time > current.animationLength) { time = current.animationLength; } return(target.SetKeyframeToCurrentTransform(time)); }
public FreeControllerAnimationTarget Add(FreeControllerV3 controller) { if (TargetControllers.Any(c => c.controller == controller)) { return(null); } var target = new FreeControllerAnimationTarget(controller); Add(target); return(target); }
private bool TryMoveNext(IEnumerator enumerator, FreeControllerAnimationTarget target) { try { return(enumerator.MoveNext()); } catch { target.EndBulkUpdates(); throw; } }
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)); }
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); } } }
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); } }
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); }
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(); } } }
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); }
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); }
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); }
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); } }
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(); } } }
private void SetControllerKeyframe(float time, FreeControllerAnimationTarget target) { animation.SetKeyframeToCurrentTransform(target, time); }
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); }
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); } } }
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; }
public void Remove(FreeControllerAnimationTarget target) { Remove(targetControllers, target); }
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; }