Subversion Repositories AndroidProjects

Rev

Rev 1442 | Rev 1448 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using BurutaruEditor.file;

using BauzoidNET.graphics;
using BauzoidNET.graphics.sprite;
using BauzoidNET.graphics.renderstates;
using BauzoidNET.math;

namespace BurutaruEditor.view
{
    public class DocumentView
    {
        public const float START_POSITION_SIZE = 10;
        public const float CHECKPOINT_SIZE = 10;

        public static readonly Vector4 CHECKPOINT_PATH_COLOR = new Vector4(0.3f, 0.8f, 0.3f, 1.0f);
        public static readonly Vector4 CHECKPOINT_FRAME_PATH_COLOR = new Vector4(0.8f, 0.3f, 0.3f, 1.0f);
        public static readonly Vector4 CHECKPOINT_FRAME_COLOR = new Vector4(0.3f, 0.5f, 0.5f, 1.0f);

        //========================================================================================================


        private MainForm mOwner = null;
        public MainForm Owner { get { return mOwner; } }

        ///< Current Camera Position relative to origin/startposition
        private Vector2 mCurrentPosition = new Vector2();
        private Vector2 mCurrentSnapPosition = new Vector2();
        public Vector2 CurrentPosition
        {
            get
            {
                if (Owner.SnapToPath)
                    return mCurrentSnapPosition;
                else
                    return mCurrentPosition;
            }
        }

        ///< Zoom Factor
        private float mZoomFactor = 1.0f;
        public float ZoomFactor
        {
            get { return mZoomFactor; }
            set
            {
                mZoomFactor = Math.Max(value, 0.1f);
                Owner.UpdateStatusBar();
                Owner.GlView.Refresh();
            }
        }

        public SimpleSprite StartPositionSprite { get; set; }
        public SimpleSprite CheckPointSprite { get; set; }

        private Grid mGrid = null;

        private static ViewResources mViewResources = null;
        public static ViewResources Resources { get { return mViewResources; } }

        //========================================================================================================

        public DocumentView(MainForm owner)
        {
            mOwner = owner;

            StartPositionSprite = new SimpleSprite(MainForm.App.getGraphics(), "data/textures/ui/startposition.png");
            CheckPointSprite = new SimpleSprite(MainForm.App.getGraphics(), "data/textures/ui/checkpoint.png");

            mGrid = new Grid(this);
        }

        public void Init()
        {
            mViewResources = new ViewResources(Owner);
            mViewResources.Init();

            StartPositionSprite.init();
            StartPositionSprite.getSpriteTransform().set(0, 0, START_POSITION_SIZE, START_POSITION_SIZE);

            CheckPointSprite.init();
            CheckPointSprite.getSpriteTransform().set(0, 0, CHECKPOINT_SIZE, CHECKPOINT_SIZE);

            ResetView();
        }

        public void Exit()
        {
            StartPositionSprite.dispose();
            CheckPointSprite.dispose();

            mViewResources.Exit();
            mViewResources = null;
        }

        public void ResetView()
        {
            mCurrentPosition.set(Owner.Doc.StartPosition.x, Owner.Doc.StartPosition.y);
        }

        public Vector2 SnapToPath()
        {
            Vector2 closestPt = null;
            Vector2 lastPt = new Vector2(0, 0);
            Vector2 curPos = new Vector2(-mCurrentPosition.x, -mCurrentPosition.y);
            for (int i = 0; i < Owner.Doc.CheckPoints.Count; i++)
            {
                Vector2 p = Owner.Doc.CheckPoints[i].Position;

                Line2 line = new Line2(lastPt, p);

                Vector2 pointOnLine = line.getClosestPointFrom(curPos);

                if (i == 0)
                {
                    closestPt = pointOnLine;
                }
                else
                {
                    Vector2 d1 = new Vector2(pointOnLine.x - curPos.x, pointOnLine.y - curPos.y);
                    Vector2 d2 = new Vector2(closestPt.x - curPos.x, closestPt.y - curPos.y);

                    if (d1.squaredLength() <= d2.squaredLength())
                    {
                        closestPt = pointOnLine;
                    }
                }

                lastPt = p;
            }

            if (closestPt == null)
                return new Vector2(0, 0);

            return new Vector2(-closestPt.x, -closestPt.y);
        }

        public void Render()
        {
            RenderStates rs = MainForm.App.getGraphics().renderStates;

            mGrid.Render(CurrentPosition.x, CurrentPosition.y);

            rs.pushViewMatrix();
            {
                Matrix4 translate1 = Matrix4.createTranslation(MainForm.App.getGraphics().getWidth() / 2,
                    MainForm.App.getGraphics().getHeight() / 2, 0);
                Matrix4 translate1a = Matrix4.createTranslation(-Document.VIRTUAL_WIDTH / 2, -Document.VIRTUAL_HEIGHT / 2, 0);
                Matrix4 translate2 = Matrix4.createTranslation(CurrentPosition.x, CurrentPosition.y, 0);
                Matrix4 translate2a = Matrix4.createTranslation(-CurrentPosition.x, -CurrentPosition.y, 0);
                Matrix4 scale = Matrix4.createScale(ZoomFactor);

                Matrix4 checkPointTransform = Matrix4.createIdentity();
                Matrix4 levelObjectTransform = Matrix4.createIdentity();

                checkPointTransform.multiply(translate2);
                checkPointTransform.multiply(scale);
                checkPointTransform.multiply(translate1);

                levelObjectTransform.multiply(translate1a);
                //levelObjectTransform.multiply(translate2);
                levelObjectTransform.multiply(scale);                
                levelObjectTransform.multiply(translate1);

                rs.view.copyFrom(levelObjectTransform);

                // render spawners
                for (int i = 0; i < Owner.Doc.Spawners.Count; i++)
                {
                    Owner.Doc.Spawners[i].Render();
                }

                // render level elements
                for (int i = 0; i < Owner.Doc.LevelElements.Count; i++)
                {
                    Owner.Doc.LevelElements[i].Render();
                }

                // render checkpoints
                rs.view.copyFrom(checkPointTransform);
                RenderCheckPoints();
            }

            rs.popViewMatrix();
        }

        public void RenderCheckPoints()
        {
            float halfW = Document.VIRTUAL_WIDTH / 2;
            float halfH = Document.VIRTUAL_HEIGHT / 2;

            Vector2 lastPt = new Vector2(0, 0);
            for (int i = 0; i < Owner.Doc.CheckPoints.Count; i++)
            {
                Vector2 p = Owner.Doc.CheckPoints[i].Position;

                RenderUtil.drawLine(MainForm.App.getGraphics(), lastPt.x, lastPt.y, p.x, p.y, CHECKPOINT_PATH_COLOR);

                // line from frame to frame
                RenderUtil.drawLine(MainForm.App.getGraphics(), lastPt.x - halfW, lastPt.y - halfH, p.x - halfW, p.y - halfH, CHECKPOINT_FRAME_PATH_COLOR);
                RenderUtil.drawLine(MainForm.App.getGraphics(), lastPt.x + halfW, lastPt.y - halfH, p.x + halfW, p.y - halfH, CHECKPOINT_FRAME_PATH_COLOR);
                RenderUtil.drawLine(MainForm.App.getGraphics(), lastPt.x - halfW, lastPt.y + halfH, p.x - halfW, p.y + halfH, CHECKPOINT_FRAME_PATH_COLOR);
                RenderUtil.drawLine(MainForm.App.getGraphics(), lastPt.x + halfW, lastPt.y + halfH, p.x + halfW, p.y + halfH, CHECKPOINT_FRAME_PATH_COLOR);

                lastPt = p;
            }

            for (int i = 0; i < Owner.Doc.CheckPoints.Count; i++)
            {
                RenderCheckPoint(Owner.Doc.CheckPoints[i].Position.x, Owner.Doc.CheckPoints[i].Position.y);
            }

            StartPositionSprite.render();
            RenderUtil.drawQuad(MainForm.App.getGraphics(), -halfW, -halfH, halfW, halfH, CHECKPOINT_FRAME_COLOR);

            //RenderUtil.drawLine(MainForm.App.getGraphics(), -mCurrentPosition.x, -mCurrentPosition.y, mCurrentSnapPosition.x, mCurrentSnapPosition.y, CHECKPOINT_FRAME_COLOR);
        }

        public void RenderCheckPoint(float x, float y)
        {
            float halfW = Document.VIRTUAL_WIDTH / 2;
            float halfH = Document.VIRTUAL_HEIGHT / 2;
            RenderUtil.drawQuad(MainForm.App.getGraphics(), x - halfW, y - halfH, x + halfW, y + halfH, CHECKPOINT_FRAME_COLOR);

            CheckPointSprite.getSpriteTransform().setPosition(x, y);
            CheckPointSprite.render();
        }

        public void Pan(float dx, float dy)
        {
            mCurrentPosition.x += dx;
            mCurrentPosition.y += dy;

            mCurrentSnapPosition = SnapToPath();

            Owner.GlView.Refresh();            
        }

        public LevelObject FindObjectAt(float x, float y)
        {
            switch (Owner.CurrentObjectMode)
            {
                case MainForm.ObjectMode.CHECKPOINTS:
                    {
                        float tx = x;
                        float ty = y;

                        tx -= MainForm.App.getGraphics().getWidth() / 2;
                        ty -= MainForm.App.getGraphics().getHeight() / 2;

                        tx /= ZoomFactor;
                        ty /= ZoomFactor;

                        tx -= mCurrentPosition.x;
                        ty -= mCurrentPosition.y;

                        for (int i = (Owner.Doc.CheckPoints.Count - 1); i >= 0; i--)
                        {
                            if (Owner.Doc.CheckPoints[i].IsInside(tx, ty))
                                return Owner.Doc.CheckPoints[i];
                        }
                    }
                    break;
                case MainForm.ObjectMode.SPAWNER:
                    {
                        // transform coordinates
                        float tx = x;
                        float ty = y;

                        tx -= MainForm.App.getGraphics().getWidth() / 2;
                        ty -= MainForm.App.getGraphics().getHeight() / 2;

                        tx /= ZoomFactor;
                        ty /= ZoomFactor;

                        tx -= mCurrentPosition.x;
                        ty -= mCurrentPosition.y;

                        for (int i = (Owner.Doc.CheckPoints.Count - 1); i >= 0; i--)
                        {
                            if (Owner.Doc.CheckPoints[i].IsInside(tx, ty))
                                return Owner.Doc.CheckPoints[i];
                        }
                    }
                    break;
                case MainForm.ObjectMode.ELEMENTS:
                    break;
            }

            return null;
        }


    }
}