Files @ 65c134a3d619
Branch filter:

Location: seniordesign-ui/Testing/Demo.StreetView/PanoramaViewer.cs

mkanning@CL-ENS241-10.cedarville.edu
Initial import of mapping source (huge commit)
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Media3D;

namespace Demo.StreetView
{
   public class PanoramaViewer : Viewport3D
   {
      public double FieldOfView
      {
         get
         {
            return (double) GetValue(FieldOfViewProperty);
         }
         set
         {
            SetValue(FieldOfViewProperty, value);
         }
      }

      // Using a DependencyProperty as the backing store for FieldOfView.  This enables animation, styling, binding, etc...
      public static readonly DependencyProperty FieldOfViewProperty =
            DependencyProperty.Register("FieldOfView", typeof(double), typeof(PanoramaViewer), new PropertyMetadata(
                  (double) 0, new PropertyChangedCallback(OnFieldOfViewChanged)));

      internal static void OnFieldOfViewChanged(Object sender, DependencyPropertyChangedEventArgs e)
      {
         PanoramaViewer Viewer = ((PanoramaViewer) sender);
         PerspectiveCamera Camera = Viewer.Camera as PerspectiveCamera;
         Camera.FieldOfView = Viewer.FieldOfView;
      }

      public ImageSource PanoramaImage
      {
         get
         {
            return (ImageSource) GetValue(PanoramaImageProperty);
         }
         set
         {
            SetValue(PanoramaImageProperty, value);
         }
      }

      // Using a DependencyProperty as the backing store for PanoramaImage.  This enables animation, styling, binding, etc...
      public static readonly DependencyProperty PanoramaImageProperty =
            DependencyProperty.Register("PanoramaImage", typeof(ImageSource), typeof(PanoramaViewer), new PropertyMetadata(
                  null, new PropertyChangedCallback(OnPanoramaImageChanged)));

      internal static void OnPanoramaImageChanged(Object sender, DependencyPropertyChangedEventArgs e)
      {
         PanoramaViewer Viewer = ((PanoramaViewer) sender);
         ImageBrush PanoramaBrush = new ImageBrush(Viewer.PanoramaImage);
         Viewer.PanoramaGeometry.BackMaterial = new DiffuseMaterial(PanoramaBrush);
      }

      #region Rotation

      static private readonly Vector3D AxisX = new Vector3D(1, 0, 0);
      static private readonly Vector3D AxisY = new Vector3D(0, 1, 0);
      static private readonly Vector3D AxisZ = new Vector3D(0, 0, 1);

      public static readonly DependencyProperty RotationXProperty =
            DependencyProperty.Register("RotationX", typeof(double), typeof(PanoramaViewer), new UIPropertyMetadata(0.0, (d, args) => ((PanoramaViewer) d).UpdateRotation()));
      public static readonly DependencyProperty RotationYProperty =
            DependencyProperty.Register("RotationY", typeof(double), typeof(PanoramaViewer), new UIPropertyMetadata(0.0, (d, args) => ((PanoramaViewer) d).UpdateRotation()));
      public static readonly DependencyProperty RotationZProperty =
            DependencyProperty.Register("RotationZ", typeof(double), typeof(PanoramaViewer), new UIPropertyMetadata(0.0, (d, args) => ((PanoramaViewer) d).UpdateRotation()));


      public double RotationX
      {
         get
         {
            return (double) GetValue(RotationXProperty);
         }
         set
         {
            SetValue(RotationXProperty, value);
         }
      }

      public double RotationY
      {
         get
         {
            return (double) GetValue(RotationYProperty);
         }
         set
         {
            SetValue(RotationYProperty, value);
         }
      }

      public double RotationZ
      {
         get
         {
            return (double) GetValue(RotationZProperty);
         }
         set
         {
            SetValue(RotationZProperty, value);
         }
      }

      private void UpdateRotation()
      {
         Quaternion qx = new Quaternion(AxisX, RotationX);
         Quaternion qy = new Quaternion(AxisY, RotationY);
         Quaternion qz = new Quaternion(AxisZ, RotationZ);
         PanoramaRotation.Quaternion = qx * qy * qz;
      }

      QuaternionRotation3D PanoramaRotation
      {
         get;
         set;
      }
      #endregion

      public PanoramaViewer()
      {
         InitializeViewer();
      }

      public ModelVisual3D PanoramaObject
      {
         get;
         set;
      }
      public GeometryModel3D PanoramaGeometry
      {
         get;
         set;
      }

      public void InitializeViewer()
      {
         ///////////////////////////////////////////
         // Camera Initialize
         ///////////////////////////////////////////
         PerspectiveCamera PanoramaCamera = new PerspectiveCamera();
         PanoramaCamera.Position = new Point3D(0, -0.0, 0);
         PanoramaCamera.UpDirection = new Vector3D(0, 1, 0);
         PanoramaCamera.LookDirection = new Vector3D(0, 0, 1);
         PanoramaCamera.FieldOfView = 80;
         this.Camera = PanoramaCamera;

         FieldOfView = 80;

         ///////////////////////////////////////////
         // Light Initialize
         ///////////////////////////////////////////
         ModelVisual3D LightModel = new ModelVisual3D();
         LightModel.Content = new DirectionalLight(Colors.White, new Vector3D(0, 0, 1));
         this.Children.Add(LightModel);

         ///////////////////////////////////////////
         // Panorama Object Initialize
         ///////////////////////////////////////////

         PanoramaObject = new ModelVisual3D();
         PanoramaGeometry = new GeometryModel3D();
         PanoramaGeometry.Geometry = CreateGeometry();
         PanoramaObject.Content = PanoramaGeometry;

         RotateTransform3D RotateTransform = new RotateTransform3D();

         double x = 1.0;
         ScaleTransform3D ScaleTransform = new ScaleTransform3D()
         {
            ScaleX = x*1,
            ScaleY = x*1.65,
            ScaleZ = x*1
         };

         Transform3DGroup Group = new Transform3DGroup();
         PanoramaRotation = new QuaternionRotation3D();
         Group.Children.Add(ScaleTransform);
         Group.Children.Add(RotateTransform);

         RotateTransform.Rotation = PanoramaRotation;
         PanoramaObject.Transform = Group;

         this.Children.Add(PanoramaObject);
      }

      private Geometry3D CreateGeometry()
      {
         int tDiv = 64;
         int yDiv = 64;
         double maxTheta = (360.0 / 180.0) * Math.PI;
         double minY = -1.0;
         double maxY = 1.0;

         double dt = maxTheta / tDiv;
         double dy = (maxY - minY) / yDiv;

         MeshGeometry3D mesh = new MeshGeometry3D();

         for(int yi = 0; yi <= yDiv; yi++)
         {
            double y = minY + yi * dy;

            for(int ti = 0; ti <= tDiv; ti++)
            {
               double t = ti * dt;

               mesh.Positions.Add(GetPosition(t, y));
               mesh.Normals.Add(GetNormal(t, y));
               mesh.TextureCoordinates.Add(GetTextureCoordinate(t, y));
            }
         }

         for(int yi = 0; yi < yDiv; yi++)
         {
            for(int ti = 0; ti < tDiv; ti++)
            {
               int x0 = ti;
               int x1 = (ti + 1);
               int y0 = yi * (tDiv + 1);
               int y1 = (yi + 1) * (tDiv + 1);

               mesh.TriangleIndices.Add(x0 + y0);
               mesh.TriangleIndices.Add(x0 + y1);
               mesh.TriangleIndices.Add(x1 + y0);

               mesh.TriangleIndices.Add(x1 + y0);
               mesh.TriangleIndices.Add(x0 + y1);
               mesh.TriangleIndices.Add(x1 + y1);
            }
         }

         mesh.Freeze();
         return mesh;
      }

      internal Point3D GetPosition(double t, double y)
      {
         double r = Math.Sqrt(1 - y * y);
         double x = r * Math.Cos(t);
         double z = r * Math.Sin(t);

         return new Point3D(x, y, z);
      }

      private Vector3D GetNormal(double t, double y)
      {
         return (Vector3D) GetPosition(t, y);
      }

      private Point GetTextureCoordinate(double t, double y)
      {
         Matrix TYtoUV = new Matrix();
         TYtoUV.Scale(1 / (2 * Math.PI), -0.5);

         Point p = new Point(t, y);
         p = p * TYtoUV;

         return p;
      }
   }
}