// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. using FlaxEditor.GUI.ContextMenu; using FlaxEditor.GUI.Input; using FlaxEngine; using FlaxEditor.Viewport.Widgets; using FlaxEngine.GUI; namespace FlaxEditor.Viewport.Previews { /// /// Animation asset preview editor viewport. /// /// public class AnimationPreview : AnimatedModelPreview { private ViewportWidgetButton _playPauseButton; /// /// Gets or sets a value indicating whether enable root motion. /// public bool RootMotion { get => !_snapToOrigin; set { if (!_snapToOrigin == value) return; _snapToOrigin = !value; } } /// /// Initializes a new instance of the class. /// /// if set to true use widgets. public AnimationPreview(bool useWidgets) : base(useWidgets) { PlayAnimation = true; PlayAnimationChanged += OnPlayAnimationChanged; _snapToOrigin = false; // Playback Speed { var playbackSpeed = ViewWidgetButtonMenu.AddButton("Playback Speed"); var playbackSpeedValue = new FloatValueBox(-1, 90, 2, 70.0f, -10000.0f, 10000.0f, 0.001f) { Parent = playbackSpeed }; playbackSpeedValue.ValueChanged += () => PlaySpeed = playbackSpeedValue.Value; ViewWidgetButtonMenu.VisibleChanged += control => playbackSpeedValue.Value = PlaySpeed; } // Play/Pause widget { var playPauseWidget = new ViewportWidgetsContainer(ViewportWidgetLocation.UpperRight); _playPauseButton = new ViewportWidgetButton(null, Editor.Instance.Icons.Pause64) { TooltipText = "Animation playback play (F5) or pause (F6)", Parent = playPauseWidget, }; _playPauseButton.Clicked += button => PlayAnimation = !PlayAnimation; playPauseWidget.Parent = this; } // Play Root Motion { var button = ViewWidgetButtonMenu.AddButton("Root Motion"); var buttonValue = new CheckBox(90, 2, !_snapToOrigin) { Parent = button }; buttonValue.StateChanged += checkbox => RootMotion = !RootMotion; ViewWidgetButtonMenu.VisibleChanged += control => buttonValue.Checked = RootMotion; } // Enable shadows PreviewLight.ShadowsMode = ShadowsCastingMode.All; PreviewLight.CascadeCount = 2; PreviewLight.ShadowsDistance = 1000.0f; Task.ViewFlags |= ViewFlags.Shadows; } private void OnPlayAnimationChanged() { _playPauseButton.Icon = PlayAnimation ? Editor.Instance.Icons.Pause64 : Editor.Instance.Icons.Play64; } /// public override void Draw() { base.Draw(); var style = Style.Current; var skinnedModel = SkinnedModel; if (skinnedModel == null) { Render2D.DrawText(style.FontLarge, "Missing Base Model", new Rectangle(Float2.Zero, Size), Color.Red, TextAlignment.Center, TextAlignment.Center, TextWrapping.WrapWords); } else if (!skinnedModel.IsLoaded) { Render2D.DrawText(style.FontLarge, "Loading...", new Rectangle(Float2.Zero, Size), style.ForegroundDisabled, TextAlignment.Center, TextAlignment.Center); } } /// public override bool OnKeyDown(KeyboardKeys key) { var inputOptions = Editor.Instance.Options.Options.Input; if (inputOptions.Play.Process(this, key)) { PlayAnimation = true; return true; } if (inputOptions.Pause.Process(this, key)) { PlayAnimation = false; return true; } return base.OnKeyDown(key); } /// public override void OnDestroy() { _playPauseButton = null; base.OnDestroy(); } } }