Esempio n. 1
0
        private void RenderAnimationPreview(RenderComposer c)
        {
            AnimatedSprite             currentFileContext = _currentAsset !.Content !;
            SpriteAnimationFrameSource frameSource        = currentFileContext.FrameSource;

            if (_animatedPreviewInvalidated)
            {
                var size = new Vector2();
                for (var i = 0; i < frameSource.GetFrameCount(); i++)
                {
                    Rectangle frameUV = frameSource.GetFrameUV(i);

                    size.X = MathF.Max(size.X, frameUV.Width);
                    size.Y = MathF.Max(size.Y, frameUV.Height);
                }

                if (size.X > size.Y)
                {
                    size.Y = size.X;
                }
                else if (size.Y > size.X)
                {
                    size.X = size.Y;
                }

                size *= 2;

                GLThread.ExecuteGLThreadAsync(() =>
                {
                    if (_animatedPreviewFb == null)
                    {
                        _animatedPreviewFb = new FrameBuffer(size).WithColor();
                    }
                    else
                    {
                        _animatedPreviewFb.Resize(size, true);
                    }
                });

                _animatedPreviewInvalidated = false;
            }

            if (_animatedPreviewFb != null)
            {
                c.RenderToAndClear(_animatedPreviewFb);

                Vector2 size = _animatedPreviewFb.Size;
                c.RenderSprite(Vector3.Zero, size, new Color(32, 32, 32));
                c.RenderLine(new Vector2(0, size.Y / 2), new Vector2(size.X, size.Y / 2), Color.White * 0.2f);
                c.RenderLine(new Vector2(size.X / 2, 0), new Vector2(size.X / 2, size.Y), Color.White * 0.2f);

                if (_animatedPreviewAnchorMode)
                {
                    // Draw a shadow of the previous frame.
                    if (_frameAnchor != 0)
                    {
                        _controller.GetRenderDataForFrame(_frameAnchor - 1, out Vector3 renderPosSh, out Texture textureSh, out Rectangle uvSh);
                        renderPosSh = renderPosSh.RoundClosest();
                        c.RenderSprite((size / 2f).RoundClosest().ToVec3() + renderPosSh, uvSh.Size, Color.White * 0.3f, textureSh, uvSh);
                    }

                    _controller.GetRenderDataForFrame(_frameAnchor, out Vector3 renderPos, out Texture texture, out Rectangle uv);
                    renderPos = renderPos.RoundClosest();
                    c.RenderSprite((size / 2f).RoundClosest().ToVec3() + renderPos, uv.Size, Color.White, texture, uv);
                }
                else
                {
                    _controller.GetRenderData(out Vector3 renderPos, out Texture texture, out Rectangle uv);
                    renderPos = renderPos.RoundClosest();
                    c.RenderSprite((size / 2f).RoundClosest().ToVec3() + renderPos, uv.Size, Color.White, texture, uv);
                }

                c.RenderTo(null);
            }
        }
Esempio n. 2
0
        private void FrameAnchorTab()
        {
            if (_currentAsset == null)
            {
                return;
            }
            _animatedPreviewAnchorMode = true;

            SpriteAnimationFrameSource frameSource = _currentAsset.Content.FrameSource;
            int frameCount = frameSource.GetFrameCount();

            // Ensure data is of correct length. It's possible for it to be malformed if frames were re-detected or
            // user did something wacky.
            frameSource.FrameOrigins ??= new OriginPosition[frameCount];
            if (frameSource.FrameOrigins.Length != frameCount)
            {
                Array.Resize(ref frameSource.FrameOrigins, frameCount);
            }

            frameSource.FrameOffsets ??= new Vector2[frameCount];
            if (frameSource.FrameOffsets.Length != frameCount)
            {
                Array.Resize(ref frameSource.FrameOffsets, frameCount);
            }

            if (frameCount == 0)
            {
                return;
            }

            ImGui.InputInt("Zoom", ref _zoomLevel);

            ImGui.Text("Frame ");
            ImGui.SameLine();
            ImGui.SetNextItemWidth(130);
            ImGui.InputInt("", ref _frameAnchor);
            ImGui.SameLine();
            ImGui.Text($"/{frameCount}");

            if (_frameAnchor < 0)
            {
                _frameAnchor = 0;
            }
            if (_frameAnchor > frameCount - 1)
            {
                _frameAnchor = frameCount - 1;
            }

            var anchorType = (int)frameSource.FrameOrigins[_frameAnchor];

            if (ImGui.Combo("Anchor Type", ref anchorType, string.Join('\0', Enum.GetNames(typeof(OriginPosition)))))
            {
                frameSource.FrameOrigins[_frameAnchor] = (OriginPosition)anchorType;
                _controller.Reset();
                UnsavedChanges();
            }

            ImGui.SameLine();
            if (ImGui.Button("Apply To All"))
            {
                for (var i = 0; i < frameSource.FrameOrigins.Length; i++)
                {
                    frameSource.FrameOrigins[i] = (OriginPosition)anchorType;
                }

                UnsavedChanges();
            }

            if (ImGui.InputFloat2("Additional Offset", ref frameSource.FrameOffsets[_frameAnchor]))
            {
                UnsavedChanges();
            }

            if (_animatedPreviewFb != null)
            {
                FrameBufferTexture texture = _animatedPreviewFb.ColorAttachment;
                (Vector2 uv1, Vector2 uv2) = texture.GetImGuiUV();
                ImGui.Image((IntPtr)texture.Pointer, texture.Size * _zoomLevel, uv1, uv2);
            }
        }
Esempio n. 3
0
        private void AnimationFrameEditor(Dictionary <string, SpriteAnimationData> anims)
        {
            AnimatedSprite      currentFileContext = _currentAsset !.Content !;
            SpriteAnimationData selAnim            = anims[_selectedAnimation];

            ImGui.BeginChild("Animation", new Vector2(-1, -1), true);
            ImGui.Text("Frames: (Drag and Drop to rearrange)");

            SpriteAnimationFrameSource frameSource = currentFileContext.FrameSource;

            _draggedFrame = EditorHelpers.DragAndDropList(selAnim.FrameIndices, _draggedFrame, true);
            if (selAnim.FrameIndices.Length == 0)
            {
                EditorHelpers.ButtonSizedHole("");
            }

            ImGui.PushItemWidth(150);
            if (ImGui.InputInt("", ref _addFrameInput))
            {
                _addFrameInput = Maths.Clamp(_addFrameInput, 0, frameSource.GetFrameCount() - 1);
            }
            ImGui.SameLine();
            if (ImGui.Button("Add Frame"))
            {
                selAnim.FrameIndices = selAnim.FrameIndices.AddToArray(_addFrameInput);
                if (_addFrameInput < frameSource.GetFrameCount() - 2)
                {
                    _addFrameInput++;
                }
                _controller.Reset();
                UnsavedChanges();
            }

            ImGui.SameLine();
            ImGui.Button("Remove (Drop Here)");
            if (ImGui.BeginDragDropTarget())
            {
                ImGuiPayloadPtr dataPtr = ImGui.AcceptDragDropPayload("UNUSED");
                unsafe
                {
                    if ((IntPtr)dataPtr.NativePtr != IntPtr.Zero && dataPtr.IsDelivery())
                    {
                        int[] indices = selAnim.FrameIndices;
                        for (int i = _draggedFrame; i < indices.Length - 1; i++)
                        {
                            indices[i] = indices[i + 1];
                        }

                        Array.Resize(ref selAnim.FrameIndices, selAnim.FrameIndices.Length - 1);
                        _controller.Reset();
                        _draggedFrame = -1;
                        UnsavedChanges();
                    }
                }

                ImGui.EndDragDropTarget();
            }

            ImGui.PushItemWidth(150);
            ImGui.Text("Duration");
            ImGui.SameLine();
            if (ImGui.InputInt("###DurInput", ref selAnim.TimeBetweenFrames))
            {
                _controller.Reset();
                UnsavedChanges();
            }

            ImGui.SameLine();
            if (selAnim.FrameIndices.Length > 0)
            {
                ImGui.Text($"Total Duration: {selAnim.TimeBetweenFrames * selAnim.FrameIndices.Length}");
            }

            var loopType = (int)selAnim.LoopType;

            if (ImGui.Combo("Loop Type", ref loopType, string.Join('\0', Enum.GetNames(typeof(AnimationLoopType)))))
            {
                selAnim.LoopType = (AnimationLoopType)loopType;
                _controller.Reset();
                UnsavedChanges();
            }
        }
Esempio n. 4
0
        private void FrameOrderTab()
        {
            AnimatedSprite             currentFileContext = _currentAsset !.Content !;
            SpriteAnimationFrameSource frameSource        = currentFileContext.FrameSource;

            var arraySource = frameSource as SpriteArrayFrameSource;
            var gridSource  = frameSource as SpriteGridFrameSource;

            if (frameSource != null)
            {
                ImGui.Text($"Frames: {currentFileContext.FrameSource.GetFrameCount()}");

                if (arraySource != null)
                {
                    ImGui.SameLine();
                    ImGui.Checkbox("Show Frame Indices", ref _showFrameIdx);
                    ImGui.SameLine();
                    if (ImGui.Button("Re-detect Frames"))
                    {
                        currentFileContext.FrameSource = new SpriteArrayFrameSource(_currentAssetTexture);
                        UnsavedChanges();
                    }
                }

                if (gridSource != null)
                {
                    if (ImGui.InputFloat2("FrameSize", ref gridSource.FrameSize))
                    {
                        _animatedPreviewInvalidated = true;
                        UnsavedChanges();
                    }

                    if (ImGui.InputFloat2("Frame Spacing", ref gridSource.Spacing))
                    {
                        _animatedPreviewInvalidated = true;
                        UnsavedChanges();
                    }
                }
            }

            ImGui.InputInt("Zoom", ref _zoomLevel);
            if (arraySource != null)
            {
                ImGui.Text("Right-click on a frame to select it, and then on another frame to swap their positions.");
            }

            ImGui.BeginChild("FramePreview", new Vector2(-1, -1), true, ImGuiWindowFlags.HorizontalScrollbar);

            // Array source being unordered allows for frames to be reordered.
            if (_textureFb != null && frameSource != null)
            {
                Vector2 winPos = ImGui.GetCursorScreenPos();

                FrameBufferTexture texture = _textureFb.ColorAttachment;
                (Vector2 uv1, Vector2 uv2) = texture.GetImGuiUV();
                ImGui.Image((IntPtr)texture.Pointer, texture.Size * _zoomLevel, uv1, uv2);

                if (arraySource != null && arraySource.Frames != null && ImGui.IsWindowFocused() && Engine.Host.IsKeyDown(Key.MouseKeyRight))
                {
                    Vector2 mPos = ImGui.GetMousePos();
                    mPos -= winPos;

                    int clickedOn = -1;
                    for (var i = 0; i < frameSource.GetFrameCount(); i++)
                    {
                        Rectangle uv = frameSource.GetFrameUV(i);
                        uv *= _zoomLevel;
                        if (!uv.Contains(mPos))
                        {
                            continue;
                        }
                        clickedOn = i;
                        break;
                    }

                    if (clickedOn != -1)
                    {
                        if (_selectedFrame == -1)
                        {
                            _selectedFrame = clickedOn;
                        }
                        else
                        {
                            Rectangle uvSelected = frameSource.GetFrameUV(_selectedFrame);
                            Rectangle uvNew      = frameSource.GetFrameUV(clickedOn);
                            arraySource.Frames[_selectedFrame] = uvNew;
                            arraySource.Frames[clickedOn]      = uvSelected;
                            _selectedFrame = -1;
                            UnsavedChanges();
                        }
                    }
                }
            }

            ImGui.EndChild();
        }
Esempio n. 5
0
        protected override bool RenderInternal(RenderComposer c)
        {
            var open = true;

            ImGui.SetNextWindowPos(new Vector2(0, 20), ImGuiCond.Always);
            ImGui.SetNextWindowSize(c.CurrentTarget.Size - new Vector2(0, 20));
            ImGui.Begin(Title, ref open, ImGuiWindowFlags.MenuBar | ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoMove);

            RenderImGui();

            ImGui.End();

            Position = Vector3.Zero;
            Size     = c.CurrentTarget.Size;
            if (!open)
            {
                Parent?.RemoveChild(this);
                return(false);
            }

            if (_textureFb?.ColorAttachment == null)
            {
                return(true);                                     // Disposed or uninitialized fb
            }
            if (_currentAssetTexture == null)
            {
                return(true);
            }

            _textureFb.ColorAttachment.Smooth = false;
            c.RenderToAndClear(_textureFb);
            c.RenderSprite(Vector3.Zero, _currentAssetTexture.Size, _currentAssetTexture);

            // Render meta overlay on the spritesheet texture.
            if (_currentAsset != null)
            {
                AnimatedSprite             currentFileContext = _currentAsset.Content !;
                SpriteAnimationFrameSource frameSource        = currentFileContext.FrameSource;
                if (frameSource != null)
                {
                    for (var i = 0; i < frameSource.GetFrameCount(); i++)
                    {
                        Rectangle frameUv = frameSource.GetFrameUV(i);
                        c.RenderOutline(frameUv, _selectedFrame == i ? Color.Green : Color.Red);

                        if (_showFrameIdx && frameSource is SpriteArrayFrameSource)
                        {
                            Vector3           stringPos = frameUv.Position.ToVec3();
                            DrawableFontAtlas atlas     = _debugFont.GetAtlas(20);
                            c.RenderString(stringPos + new Vector3(1), Color.Black, i.ToString(), atlas);
                            c.RenderString(stringPos, Color.Red, i.ToString(), atlas);
                        }
                    }
                }
            }

            c.RenderTo(null);

            RenderAnimationPreview(c);

            return(true);
        }