Monday, October 22, 2012

Silverlight 5 3d view position change by mouse move

MainPage.cs

using System.Windows.Controls;
using System.Windows.Graphics;
using System.Windows;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using System;
using System.Windows.Input;

namespace Silverlight3dApp
{
    public static class State
    {
        public static float sliderYawVal = new float();
        public static float sliderPitchVal = new float();
        public static float sliderRollVal = new float();
    }

    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
        }

        const float zoomZ = 400;
        const float targetY = 50;
        float cameraX = 0;
        float cameraY = zoomZ;
        float cameraZ = zoomZ;

        ContentManager contentManager;
        Machine machine;
       
        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            contentManager = new ContentManager(null)
            {
                RootDirectory = "Content"
            };

            machine = new Machine();
            machine.Load(contentManager);
           
            string sb = string.Empty;

            hoDrawingSurface.SizeChanged += new SizeChangedEventHandler(hoDrawingSurface_SizeChanged);
        }

        void hoDrawingSurface_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            if (machine != null)
            {
                machine.AspectRatio = (float)(hoDrawingSurface.ActualWidth / hoDrawingSurface.ActualHeight);
            }
        }

        void machine_Events(object sender, EventArgs e)
        {
            title.Text = sender.ToString();
        }
       
        private void OnViewportDraw(object sender, DrawEventArgs e)
        {
            GraphicsDevice graphicsDevice = GraphicsDeviceManager.Current.GraphicsDevice;
            Color cornflowerBlue = new Color(0x64, 0x95, 0xED, 0xFF);
            graphicsDevice.Clear(cornflowerBlue);

            float time = (float)e.TotalTime.TotalSeconds;

            Matrix world = Matrix.Identity;

            Matrix view = Matrix.CreateLookAt(new Vector3(cameraX, cameraY, cameraZ),
                                              new Vector3(0, targetY, 0),
                                              Vector3.Up);
           
           
            Matrix projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4,
                                                                    graphicsDevice.Viewport.AspectRatio,
                                                                    100,
                                                                    10000);

            machine.Draw(graphicsDevice, world, view, projection, e.TotalTime);
           
            e.InvalidateSurface();
        }
       
        private double oldPositionX;
        private double oldPositionY;
        private bool clicked;
        double WorldDegreesX = 0;
        double WorldDegreesY = 0;
        double WorldDegreesZ = 0;
        float currentZoom = zoomZ;
        bool zoomChanged = false;
        float zoomInMax = 230;
        float zoomOutMax = 600;

        private void OnMouseLeftDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            oldPositionX = e.GetPosition(hoDrawingSurface).X;
            oldPositionY = e.GetPosition(hoDrawingSurface).Y;
            clicked = true;
        }

        private void OnMouseLeftUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            oldPositionX = 0;
            oldPositionY = 0;
            clicked = false;
        }

        private void OnMouseMove(object sender, System.Windows.Input.MouseEventArgs e)
        {
            if (clicked)
            {
                rotateManual(e.GetPosition(hoDrawingSurface).X, e.GetPosition(hoDrawingSurface).Y);
            }
        }

        void rotateManual(double posX, double posY)
        {
            float x = System.Convert.ToSingle(oldPositionX - posX);
            float y = System.Convert.ToSingle(oldPositionY - posY);

            float num = (2 * MathHelper.Pi * currentZoom) / 360;
            double xxyy = Math.Sqrt(x * x + y * y);

            if (Math.Abs(x) > num || zoomChanged)
            {
                if (!zoomChanged)
                {
                    oldPositionX = posX;

                    double gradus = (x / num);

                    WorldDegreesX += gradus;
                    if (WorldDegreesX < 0) WorldDegreesX = 360;
                    if (WorldDegreesX > 360) WorldDegreesX = WorldDegreesX % 360;
                    double angle = Math.PI * WorldDegreesX / 180.0;
                    double sin = Math.Sin(angle);
                    cameraX = (float)(sin * currentZoom);

                    WorldDegreesZ += gradus;
                    if (WorldDegreesZ < 0) WorldDegreesZ = 360;
                    if (WorldDegreesZ > 360) WorldDegreesZ = WorldDegreesZ % 360;
                    double angleZ = Math.PI * WorldDegreesZ / 180.0;
                    double cos = Math.Cos(angleZ);
                    cameraZ = (float)(cos * currentZoom);
                }
                else
                {
                    double angle = Math.PI * WorldDegreesX / 180.0;
                    double sin = Math.Sin(angle);
                    cameraX = (float)(sin * currentZoom);

                    double angleZ = Math.PI * WorldDegreesZ / 180.0;
                    double cos = Math.Cos(angleZ);
                    cameraZ = (float)(cos * currentZoom);
                }
            }

            if (Math.Abs(y) > num || zoomChanged)
            {
                if (!zoomChanged)
                {
                    oldPositionY = posY;

                    double gradus = (y / num);

                    WorldDegreesY += gradus;
                    if (WorldDegreesY < 0) WorldDegreesY = 360;
                    if (WorldDegreesY > 360) WorldDegreesY = WorldDegreesY % 360;
                    double angle = Math.PI * WorldDegreesY / 180.0;
                    double cosY = Math.Cos(angle);
                    cameraY = (float)(cosY * currentZoom);
                }
                else
                {
                    double angle = Math.PI * WorldDegreesY / 180.0;
                    double cosY = Math.Cos(angle);
                    cameraY = (float)(cosY * currentZoom);
                }
                //WorldDegreesZ += gradus;
                //if (WorldDegreesZ < 0) WorldDegreesZ = 360;
                //if (WorldDegreesZ > 360) WorldDegreesZ = WorldDegreesZ % 360;
                //double angleZ = Math.PI * WorldDegreesZ / 180.0;
                //double cos = Math.Sin(angleZ);
                //cameraZ = (float)(cos * currentZoom);
            }

            hoDrawingSurface.Invalidate();
        }

        private void OnMouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
        {
            currentZoom += (e.Delta / 10);
            if (currentZoom < zoomInMax) currentZoom = zoomInMax;
            if (currentZoom > zoomOutMax) currentZoom = zoomOutMax;

            zoomChanged = true;
            rotateManual(0, 0);
            zoomChanged = false;
        }

        private void OnSelectCarColor(object sender, RoutedEventArgs e)
        {
            string[] colorSs = (sender as Button).Tag.ToString().Split(new char[] { ',' });
            Color color = Color.FromNonPremultiplied(
                Convert.ToInt32(colorSs[0]), Convert.ToInt32(colorSs[1]), Convert.ToInt32(colorSs[2]), 255);
            if (machine != null)
            {
                if (machine.ChangeColors.ContainsKey(Machine.CARCOLOR))
                    machine.ChangeColors[Machine.CARCOLOR] = color;
                else
                    machine.ChangeColors.Add(Machine.CARCOLOR, color);
            }
        }

        private void OnSelectRimColor(object sender, RoutedEventArgs e)
        {
            string[] colorSs = (sender as Button).Tag.ToString().Split(new char[] { ',' });
            Color color = Color.FromNonPremultiplied(
                Convert.ToInt32(colorSs[0]), Convert.ToInt32(colorSs[1]), Convert.ToInt32(colorSs[2]), 255);
            if (machine != null)
            {
                if (machine.ChangeColors.ContainsKey(Machine.RIMCOLOR))
                    machine.ChangeColors[Machine.RIMCOLOR] = color;
                else
                    machine.ChangeColors.Add(Machine.RIMCOLOR, color);
            }
        }
    }
}

No comments: