Exemplo n.º 1
0
        /// <summary>
        /// Render an ticked and annotated axis.
        /// </summary>
        /// <param name="from">From here.</param>
        /// <param name="to">To here.</param>
        /// <param name="tickres">Tick resolution; how often to annotate the axis.</param>
        /// <param name="name">Axis name, written on top the ticks.</param>
        /// <param name="vertical">This is a vertical axis, so move the anootations to the left.</param>
        private void renderAxisAnnotations(double[] from, double[] to, double tickres, string name, bool vertical)
        {
            double[] delta = to.Subtract(from);

            // if too small, don't annotate anything (otherwise it will just be a mess)
            double[] proj = camera.TransformH(delta).Submatrix(0, 1);
            if (proj.SquareEuclidean() < 1 * 1)
            {
                return;
            }

            double[] tickunit = tickres.Multiply(delta.Normalize());
            double   length   = delta.Euclidean();
            double   limit    = length / 2;      // [-limit, limit]
            int      nticks   = (int)(limit / tickres);

            double[] zero    = to.Add(from).Divide(2);
            double[] postick = zero.Add(tickunit);
            double[] negtick = zero.Subtract(tickunit);

            float a = SceneBuffer.Width / (MapClip[1] - MapClip[0]);
            float x = SceneBuffer.Width / 2;
            float y = SceneBuffer.Height / 2;

            float scale    = 1.5f;
            float rotangle = (float)(Util.NormalizeAngle(-Math.Atan2(proj[1], proj[0])));

            bool invertoffset = false;

            if (Math.Abs(rotangle) > Math.PI / 2 && !vertical)
            {
                rotangle    += (float)Math.PI;
                invertoffset = true;
            }

            double[] nproj = proj.Normalize();

            if (nproj[0] < 0)
            {
                nproj         = (-1).Multiply(nproj);
                invertoffset ^= true;
            }

            Vector2 t;

            if (vertical)
            {
                t = new Vector2((float)(x + 450 * scale * nproj[0] - 350 * nproj[1]),
                                (float)(y - 450 * scale * nproj[1] - 350 * nproj[0]));
            }
            else if (!invertoffset)
            {
                t = new Vector2((float)(x + ((name == "x [m]") ? 420 : 600) * scale * nproj[0] + 120 * nproj[1]),
                                (float)(y - ((name == "x [m]") ? 420 : 600) * scale * nproj[1] + 120 * nproj[0]));
            }
            else
            {
                t = new Vector2((float)(x + 580 * scale * nproj[0] - 120 * nproj[1]),
                                (float)(y - 580 * scale * nproj[1] - 120 * nproj[0]));
            }

            Flip.DrawString(fontaxis, name, t, Color.Black, rotangle,
                            new Vector2(0, 0), scale, SpriteEffects.None, 0);

            for (int i = 1; i <= nticks; i++)
            {
                double[] ppos = camera.TransformH(postick);
                double[] npos = camera.TransformH(negtick);

                Vector2 p = new Vector2(a * (float)ppos[0] + x, a * (float)-ppos[1] + y);
                Vector2 n = new Vector2(a * (float)npos[0] + x, a * (float)-npos[1] + y);

                string  ptext = (tickres * i).ToString("F0");
                Vector2 psize = fontaxis.MeasureString(ptext) * scale;

                string  ntext = (-tickres * i).ToString("F0");
                Vector2 nsize = fontaxis.MeasureString(ntext) * scale;

                p.X = p.X - psize.X / 2;
                n.X = n.X - nsize.X / 2;

                if (vertical)
                {
                    p.X = p.X - psize.X / 2 - 30 * scale;
                    n.X = n.X - nsize.X / 2 - 30 * scale;
                }

                if (SceneBuffer.Bounds.Contains(new Rectangle((int)p.X, (int)p.Y, (int)(psize.X), (int)(psize.Y))))
                {
                    Flip.DrawString(fontaxis, ptext, p, Color.Black, 0, new Vector2(0, 0), scale, SpriteEffects.None, 0);
                }

                if (SceneBuffer.Bounds.Contains(new Rectangle((int)n.X, (int)n.Y, (int)(nsize.X), (int)(nsize.Y))))
                {
                    Flip.DrawString(fontaxis, ntext, n, Color.Black, 0, new Vector2(0, 0), scale, SpriteEffects.None, 0);
                }

                postick = postick.Add(tickunit);
                negtick = negtick.Subtract(tickunit);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// This is called when the manipulator should draw itself.
        /// </summary>
        /// <param name="time">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime time)
        {
            // visualization
            Graphics.SetRenderTarget(SceneBuffer);
            Graphics.Clear(Color.White);

            Graphics.DepthStencilState = DepthStencilState.Default;

            foreach (EffectPass pass in effect.CurrentTechnique.Passes)
            {
                pass.Apply();

                Navigator.Render(camera);
            }

            Graphics.DepthStencilState = DepthStencilState.None;

            foreach (EffectPass pass in effect.CurrentTechnique.Passes)
            {
                pass.Apply();

                RenderHUD(camera);
            }

            Flip.Begin(SpriteSortMode.Immediate, BlendState.NonPremultiplied, SamplerState.LinearClamp,
                       DepthStencilState.Default, RasterizerState.CullNone);

            double limit = Config.AxisLimit;

            renderAxisAnnotations(new double[3] {
                -limit, 0, 0
            }, new double[3] {
                +limit, 0, 0
            }, 2, "x [m]", false);
            renderAxisAnnotations(new double[3] {
                0, -limit, 0
            }, new double[3] {
                0, +limit, 0
            }, 2, "y [m]", true);
            renderAxisAnnotations(new double[3] {
                0, 0, -limit
            }, new double[3] {
                0, 0, +limit
            }, 2, "z [m]", false);

            Flip.End();

            // sidebar
            Graphics.SetRenderTarget(SideBuffer);
            Graphics.Clear(Color.Black);

            Flip.Begin(SpriteSortMode.FrontToBack, BlendState.NonPremultiplied, SamplerState.LinearClamp,
                       DepthStencilState.Default, RasterizerState.CullNone);

            Explorer.RenderSide();

            Flip.End();

            // HUD
            foreach (EffectPass pass in hudeffect.CurrentTechnique.Passes)
            {
                pass.Apply();
                Explorer.RenderSideHUD();
            }

            // text and axes
            Graphics.SetRenderTarget(null);
            Flip.Begin(SpriteSortMode.Immediate, BlendState.NonPremultiplied, SamplerState.LinearClamp,
                       DepthStencilState.Default, RasterizerState.CullNone);

            Flip.Draw(SceneBuffer, SceneDest, SceneBuffer.Bounds, Color.White);
            Flip.Draw(SideBuffer, SideDest, SideBuffer.Bounds, Color.White);
            Flip.DrawString(font, Message, messagepos, Color.White);
            Flip.DrawString(font, TagMessage, TagMessagePos, TagColor);

            //double limit = Config.AxisLimit;
            //renderAxisAnnotations(new double[3] {-limit, 0, 0}, new double[3] {+limit, 0, 0}, 5);
            //renderAxisAnnotations(new double[3] {0, -limit, 0}, new double[3] {0, +limit, 0}, 5);
            //renderAxisAnnotations(new double[3] {0, 0, -limit}, new double[3] {0, 0, +limit}, 5);

            Flip.End();

            base.Draw(time);
        }