private void Expand(GeometryModel3D model, Transform3D transformation)
        {
            Transform3D ot;
            if (originalTransforms.ContainsKey(model))
                ot = originalTransforms[model];
            else
            {
                ot = model.Transform;
                originalTransforms.Add(model, ot);
            }

            Transform3D totalTransform = Transform3DHelper.CombineTransform(transformation, ot);

            var mesh = model.Geometry as MeshGeometry3D;
            if (mesh == null)
                return;
            var bounds = new Rect3D();
            foreach (int i in mesh.TriangleIndices)
                bounds.Union(totalTransform.Transform(mesh.Positions[i]));

            Point3D p = bounds.Location;
            Vector3D d = p - actualExpandOrigin;
            d *= Expansion;
            Point3D p2 = actualExpandOrigin + d;
            var t = new TranslateTransform3D(p2 - p);

            model.Transform = Transform3DHelper.CombineTransform(ot, t);
        }
		private void OnBoundsChanged(Rect3D bounds)
		{
			Children.Clear();

			double x0 = bounds.X;
			double x1 = x0 + bounds.SizeX;
			double y0 = bounds.Y;
			double y1 = y0 + bounds.SizeY;
			double z0 = bounds.Z;
			double z1 = z0 + bounds.SizeZ;

			// bottom lines
			AddLine(x0, y0, z0, x1, y0, z0);
			AddLine(x1, y0, z0, x1, y1, z0);
			AddLine(x1, y1, z0, x0, y1, z0);
			AddLine(x0, y1, z0, x0, y0, z0);

			// top lines
			AddLine(x0, y0, z1, x1, y0, z1);
			AddLine(x1, y0, z1, x1, y1, z1);
			AddLine(x1, y1, z1, x0, y1, z1);
			AddLine(x0, y1, z1, x0, y0, z1);

			// vertical lines
			AddLine(x0, y0, z0, x0, y0, z1);
			AddLine(x1, y0, z0, x1, y0, z1);
			AddLine(x0, y1, z0, x0, y1, z1);
			AddLine(x1, y1, z0, x1, y1, z1);
		}
		public static Point3D TransformToBounds(this Point3D point, Rect3D bounds)
		{
			point.X = point.X * bounds.SizeX + bounds.X;
			point.Y = point.Y * bounds.SizeY + bounds.Y;
			point.Z = point.Z * bounds.SizeZ + bounds.Z;

			return point;
		}
		public static Point3D TransformTo01(this Point3D point, Rect3D bounds)
		{
			point.X = (point.X - bounds.X) / bounds.SizeX;
			point.Y = (point.Y - bounds.Y) / bounds.SizeY;
			point.Z = (point.Z - bounds.Z) / bounds.SizeZ;

			return point;
		}
 /// <summary>
 /// Initializes a new instance of the <see cref="ClothingItemBase"/> class.
 /// </summary>
 /// <param name="model">3D model</param>
 /// <param name="tolerance">Tolerance of the model scale</param>
 /// <param name="deltaPosition">Factor to move the model in Y coordinate</param>
 protected ClothingItemBase(Model3DGroup model, double tolerance, double deltaPosition)
 {
     Model = model;
     _basicBounds = model.Bounds;
     Tolerance = tolerance;
     _widthScale = _heightScale = 1;
     DeltaPosition = deltaPosition;
 }
		public static Vector3D TransformToBounds(this Vector3D vector, Rect3D bounds)
		{
			vector.X = vector.X * bounds.SizeX + bounds.X;
			vector.Y = vector.Y * bounds.SizeY + bounds.Y;
			vector.Z = vector.Z * bounds.SizeZ + bounds.Z;

			return vector;
		}
Exemple #7
0
 public Potree(Uri location)
 {
     ReadSettings(location);
     Compilation = new TreeCompilation();
     BoundingBox = Settings.BoundingBox;
     Filename = "r";
     BuiltHierarchy();
     UpdateCompilation();
 }
        public TestModelVisual3D()
        {
            _visualChild = new ModelVisual3D();
            Children.Add(_visualChild);

            _realRect3D = new Rect3D(-1, -0.75, -0.5, 2, 1.5, 1);

            TopBrush = new ImageBrush(new BitmapImage(new Uri("pack://application:,,,/pz.bmp")));

            UpdateModel();
        }
    public MainWindow() {
      var args = System.Environment.GetCommandLineArgs();
        if (args != null)
            foreach (var arg in args)
            {
                if (arg == "/S") SCALABLE = true;
                if (arg == "/A") SYNCHRONOUS = false;
            };

      this.Title = (SCALABLE) ? "SCALABLE" : "LOCKBASED";

      this.Title += (SYNCHRONOUS) ? " SYNCHRONOUS" : " ASYNCHRONOUS";
      BoidModels = new ModelVisual3D[NumBoids];
      Timer = new DispatcherTimer();
      boids = new Boid[NumBoids];
      Space = new Rect3D(0.0, 0.0, 0.0, 600.0, 200.0, 800.0);
      CurrentData = new Data[NumBoids];
      InitializeComponent();
      
      InitJoin();

      // The color combinations to use for boids.  At least one combination is necessary,
      // but more can be added to get more variations.
      var colorCombinations = new Tuple<Color, Color>[]
            {
                Tuple.Create(Colors.SeaGreen, Colors.Silver),
                Tuple.Create(Colors.Pink, Colors.Purple),
                Tuple.Create(Colors.Yellow, Colors.Gold),
                Tuple.Create(Colors.Red, Colors.Tomato),
                Tuple.Create(Colors.Blue,Colors.BlueViolet),
                Tuple.Create(Colors.Green,Colors.LightGreen),
                Tuple.Create(Colors.Aqua,Colors.Aquamarine)
            };

      for (var i = 0; i < NumBoids; i++) {
        BoidModels[i] = new ModelVisual3D();
        var content = (System.Windows.Media.Media3D.GeometryModel3D)boidMain.Content.Clone();
        content.BackMaterial = new DiffuseMaterial(new SolidColorBrush(colorCombinations[i % colorCombinations.Length].Item2));
        content.Material = new DiffuseMaterial(new  SolidColorBrush(colorCombinations[i % colorCombinations.Length].Item1));
        BoidModels[i].Content = content;
        BoidModels[i].Transform = new TranslateTransform3D(CurrentData[i].position);
        viewport3D.Children.Add(BoidModels[i]);
      }

      
      System.Threading.ThreadPool.QueueUserWorkItem(_ => {
        while (true) {
         var d = Tick();
         Dispatcher.Invoke((Action<Data[]>) Animate,DispatcherPriority.Input, d);
        }
      });
    }
        public void HighlightBounds(SharpDX.BoundingBox bounds)
        {
            var r3d = new Media3D.Rect3D(bounds.Minimum.ToPoint3D(), bounds.Size.ToSize3D());
            var b   = new Helix.MeshBuilder();

            b.AddBoundingBox(r3d, 0.1);
            b.AddSphere(bounds.Center, 0.1);
            var geom = b.ToMeshGeometry3D();

            box.Geometry = geom;
            if (!Viewport.Items.Contains(box))
            {
                Viewport.Items.Add(box);
            }
        }
 public static Rect3D GetBounds(IDictionary dictionary)
 {
     var localToParent = GetLocalToParent(dictionary);
     var bounds = new Rect3D(localToParent.Transform(new Point3D(0, 0, 0)), new Size3D(0, 0, 0));
     foreach(var key in dictionary.Keys)
     {
         var childDictionary = dictionary[key] as IDictionary;
         if(childDictionary != null)
         {
             var childBounds = GetBounds(childDictionary);
             bounds.Union(localToParent.Transform(childBounds.Location));
         }
     }
     return bounds;
 }
Exemple #12
0
        internal static IEnumerable<Point3D> TransformPoints(ref Rect3D bounds, Point3DCollection points, ref Vector3D dir)
        {
            if (dir == MathUtils.YAxis)
            {
                return points;
            }

            Vector3D rotAxis = Vector3D.CrossProduct(dir, MathUtils.YAxis);
            double rotAngle = Vector3D.AngleBetween(dir, MathUtils.YAxis);
            Quaternion q;

            if (rotAxis.X != 0 || rotAxis.Y != 0 || rotAxis.Z != 0)
            {
                Debug.Assert(rotAngle != 0);

                q = new Quaternion(rotAxis, rotAngle);
            }
            else
            {
                Debug.Assert(dir == -MathUtils.YAxis);

                q = new Quaternion(MathUtils.XAxis, rotAngle);
            }

            Vector3D center = new Vector3D(
                bounds.X + bounds.SizeX / 2,
                bounds.Y + bounds.SizeY / 2,
                bounds.Z + bounds.SizeZ / 2
                );

            Matrix3D t = Matrix3D.Identity;
            t.Translate(-center);
            t.Rotate(q);

            int count = points.Count;
            Point3D[] transformedPoints = new Point3D[count];

            for (int i = 0; i < count; i++)
            {
                transformedPoints[i] = t.Transform(points[i]);
            }

            // Finally, transform the bounds too
            bounds = MathUtils.TransformBounds(bounds, t);

            return transformedPoints;
        }
    private void Window_Loaded(object sender, EventArgs e) {
      int Xmargin = (int)Math.Round(Space.SizeX / 10.0);
      int Ymargin = (int)Math.Round(Space.SizeY / 10.0);
      int Zmargin = (int)Math.Round(Space.SizeZ / 10.0);
      Rect3D aviary = new Rect3D((double)Xmargin, (double)Ymargin, (double)Zmargin, Space.SizeX - (2 * Xmargin), Space.SizeY - (2 * Ymargin), Space.SizeZ - (2 * Zmargin));
      Random random = new Random();
      Vector3D place = new Vector3D(Space.SizeX / 2.0, Space.SizeY / 2.0, Space.SizeZ / 2.0);
      for (var i = 0; i < NumBoids; i++) {
        boids[i] = new Boid(aviary, place, NumBoids, i, this);
        boids[i].position = new Vector3D((double)random.Next(Xmargin, (int)Math.Round((double)(Space.SizeX - (2 * Xmargin)))), (double)random.Next(Ymargin, (int)Math.Round((double)(Space.SizeY - (2 * Ymargin)))), (double)random.Next(Zmargin, (int)Math.Round((double)(Space.SizeZ - (2 * Zmargin)))));
        boids[i].velocity = new Vector3D(0.0, 0.1, 0.0);
      }

      foreach (Boid boid in boids) {
        boid.Start();
      }
    }
Exemple #14
0
        // Helper method for compiting the bounds of a set of points.  The given point
        // is added to the bounds of the given Rect3D.  The point/bounds are both passed 
        // by reference for perf.  Only the bounds may be modified.
        private static void AddPointToBounds(ref Point3D point, ref Rect3D bounds) 
        { 
            Debug.Assert(!bounds.IsEmpty,
                "Caller should construct the Rect3D from the first point before calling this method."); 

            if (point.X < bounds.X)
            {
                bounds.SizeX += (bounds.X - point.X); 
                bounds.X = point.X;
            } 
            else if (point.X > (bounds.X + bounds.SizeX)) 
            {
                bounds.SizeX = point.X - bounds.X; 
            }

            if (point.Y < bounds.Y)
            { 
                bounds.SizeY += (bounds.Y - point.Y);
                bounds.Y = point.Y; 
            } 
            else if (point.Y > (bounds.Y + bounds.SizeY))
            { 
                bounds.SizeY = point.Y - bounds.Y;
            }

            if (point.Z < bounds.Z) 
            {
                bounds.SizeZ += (bounds.Z - point.Z); 
                bounds.Z = point.Z; 
            }
            else if (point.Z > (bounds.Z + bounds.SizeZ)) 
            {
                bounds.SizeZ = point.Z - bounds.Z;
            }
 
#if NEVER
            // Because we do not store rectangles as TLRB (+ another dimension in 3D) 
            // we need to compute SizeX/Y/Z which involves subtraction and introduces 
            // cancelation so this assert isn't accurate.
            Debug.Assert(bounds.Contains(point), 
                "Error detect - bounds did not contain point on exit.");
#endif
        }
        /// <summary>
        /// 盤などのサイズを設定します。
        /// </summary>
        private void InitializeBounds(Rect3D banBounds, Rect3D komaboxBounds,
                                      Rect3D komadai0Bounds, Rect3D komadai1Bounds)
        {
            // 駒の表示サイズを設定
            CellSize = new Size(
                banBounds.SizeX / (Board.BoardSize + BanBorderRate * 2),
                banBounds.SizeY / (Board.BoardSize + BanBorderRate * 2));

            // 盤サイズの設定
            BanBounds = new Rect(
                banBounds.X + CellSize.Width * BanBorderRate,
                banBounds.Y + CellSize.Height * BanBorderRate,
                CellSize.Width * Board.BoardSize,
                CellSize.Height * Board.BoardSize);

            // index=0が駒箱の駒となります。
            this.capturedPieceBoxBounds[0] = WPFUtil.MakeRectXY(komaboxBounds);
            this.capturedPieceBoxBounds[1] = WPFUtil.MakeRectXY(komadai0Bounds);
            this.capturedPieceBoxBounds[2] = WPFUtil.MakeRectXY(komadai1Bounds);
        }
Exemple #16
0
        public static PointCollection GeneratePlanarTextureCoordinates(MeshGeometry3D mesh, Rect3D bounds, Vector3D dir)
        {
            if (mesh == null)
                return null;

            //if (!bounds.Contains(mesh.Bounds))
            //    throw new ArgumentException("bounds must fully contain mesh.Bounds", "bounds");

            int count = mesh.Positions.Count;
            PointCollection texcoords = new PointCollection(count);
            IEnumerable<Point3D> positions = TransformPoints(ref bounds, mesh.Positions, ref dir);

            foreach (Point3D vertex in positions)
            {
                // The plane is looking along positive Y, so Z is really Y

                texcoords.Add(new Point(
                    GetPlanarCoordinate(vertex.X, bounds.X, bounds.SizeX),
                    GetPlanarCoordinate(vertex.Z, bounds.Z, bounds.SizeZ)
                    ));
            }

            return texcoords;
        }
        public CubeViewModel()
        {
            ImageBox = new Rect3D(0, 0, 0, 1, 0.75, 0.5);

            XPBrush = new ImageBrush(new BitmapImage(new Uri("pack://application:,,,/surfaces/px.bmp", UriKind.Absolute)));
            XNBrush = new ImageBrush(new BitmapImage(new Uri("pack://application:,,,/surfaces/nx.bmp", UriKind.Absolute)));
            YPBrush = new ImageBrush(new BitmapImage(new Uri("pack://application:,,,/surfaces/py.bmp", UriKind.Absolute)));
            YNBrush = new ImageBrush(new BitmapImage(new Uri("pack://application:,,,/surfaces/ny.bmp", UriKind.Absolute)));
            ZPBrush = new ImageBrush(new BitmapImage(new Uri("pack://application:,,,/surfaces/pz.bmp", UriKind.Absolute)));
            ZNBrush = new ImageBrush(new BitmapImage(new Uri("pack://application:,,,/surfaces/nz.bmp", UriKind.Absolute)));

            ExpendedBrush = new ImageBrush(new BitmapImage(new Uri("pack://application:,,,/surfaces/exp.bmp", UriKind.Absolute)));

            SliderPosition = 0.4;

            SliderDirection = CooridinateDirection.ZN;

            CylindarMode = false;

            IntersectionMode = false;

            Radius = 0.3;
            Centre = new Point(0.3, 0.4);
        }
        private Model3D CreateModel()
        {
            var plotModel = new Model3DGroup();

            int rows = Points.GetUpperBound(0) + 1;
            int columns = Points.GetUpperBound(1) + 1;
            double minX = double.MaxValue;
            double maxX = double.MinValue;
            double minY = double.MaxValue;
            double maxY = double.MinValue;
            double minZ = double.MaxValue;
            double maxZ = double.MinValue;
            double minColorValue = double.MaxValue;
            double maxColorValue = double.MinValue;
            for (int i = 0; i < rows; i++)
                for (int j = 0; j < columns; j++)
                {
                    double x = Points[i, j].X;
                    double y = Points[i, j].Y;
                    double z = Points[i, j].Z;
                    maxX = Math.Max(maxX, x);
                    maxY = Math.Max(maxY, y);
                    maxZ = Math.Max(maxZ, z);
                    minX = Math.Min(minX, x);
                    minY = Math.Min(minY, y);
                    minZ = Math.Min(minZ, z);
                    if (ColorValues != null)
                    {
                        maxColorValue = Math.Max(maxColorValue, ColorValues[i, j]);
                        minColorValue = Math.Min(minColorValue, ColorValues[i, j]);
                    }
                }

            // make color value 0 at texture coordinate 0.5
            if (Math.Abs(minColorValue) < Math.Abs(maxColorValue))
                minColorValue = -maxColorValue;
            else
                maxColorValue = -minColorValue;

            // set the texture coordinates by z-value or ColorValue
            var texcoords = new Point[rows,columns];
            for (int i = 0; i < rows; i++)
                for (int j = 0; j < columns; j++)
                {
                    double u = (Points[i, j].Z - minZ)/(maxZ - minZ);
                    if (ColorValues != null)
                        u = (ColorValues[i, j] - minColorValue)/(maxColorValue - minColorValue);
                    texcoords[i, j] = new Point(u, u);
                }

            var surfaceMeshBuilder = new MeshBuilder();
            surfaceMeshBuilder.AddRectangularMesh(Points, texcoords);

            var surfaceModel = new GeometryModel3D(surfaceMeshBuilder.ToMesh(),
                                                   MaterialHelper.CreateMaterial(SurfaceBrush, null, null, 1, 0));
            surfaceModel.BackMaterial = surfaceModel.Material;

            var axesMeshBuilder = new MeshBuilder();
            for (double x = minX; x <= maxX; x += IntervalX)
            {
                double j = (x - minX)/(maxX - minX)*(columns - 1);
                var path = new List<Point3D> {new Point3D(x, minY, minZ)};
                for (int i = 0; i < rows; i++)
                {
                    path.Add(BilinearInterpolation(Points, i, j));
                }
                path.Add(new Point3D(x, maxY, minZ));

                axesMeshBuilder.AddTube(path, LineThickness, 9, false);
                GeometryModel3D label = TextCreator.CreateTextLabelModel3D(x.ToString(), Brushes.Black, true, FontSize,
                                                                           new Point3D(x, minY - FontSize*2.5, minZ),
                                                                           new Vector3D(1, 0, 0), new Vector3D(0, 1, 0));
                plotModel.Children.Add(label);
            }

            {
                GeometryModel3D label = TextCreator.CreateTextLabelModel3D("X-axis", Brushes.Black, true, FontSize,
                                                                           new Point3D((minX + maxX)*0.5,
                                                                                       minY - FontSize*6, minZ),
                                                                           new Vector3D(1, 0, 0), new Vector3D(0, 1, 0));
                plotModel.Children.Add(label);
            }

            for (double y = minY; y <= maxY; y += IntervalY)
            {
                double i = (y - minY)/(maxY - minY)*(rows - 1);
                var path = new List<Point3D> {new Point3D(minX, y, minZ)};
                for (int j = 0; j < columns; j++)
                {
                    path.Add(BilinearInterpolation(Points, i, j));
                }
                path.Add(new Point3D(maxX, y, minZ));

                axesMeshBuilder.AddTube(path, LineThickness, 9, false);
                GeometryModel3D label = TextCreator.CreateTextLabelModel3D(y.ToString(), Brushes.Black, true, FontSize,
                                                                           new Point3D(minX - FontSize*3, y, minZ),
                                                                           new Vector3D(1, 0, 0), new Vector3D(0, 1, 0));
                plotModel.Children.Add(label);
            }
            {
                GeometryModel3D label = TextCreator.CreateTextLabelModel3D("Y-axis", Brushes.Black, true, FontSize,
                                                                           new Point3D(minX - FontSize*10,
                                                                                       (minY + maxY)*0.5, minZ),
                                                                           new Vector3D(0, 1, 0), new Vector3D(-1, 0, 0));
                plotModel.Children.Add(label);
            }
            double z0 = (int) (minZ/IntervalZ)*IntervalZ;
            for (double z = z0; z <= maxZ + double.Epsilon; z += IntervalZ)
            {
                GeometryModel3D label = TextCreator.CreateTextLabelModel3D(z.ToString(), Brushes.Black, true, FontSize,
                                                                           new Point3D(minX - FontSize*3, maxY, z),
                                                                           new Vector3D(1, 0, 0), new Vector3D(0, 0, 1));
                plotModel.Children.Add(label);
            }
            {
                GeometryModel3D label = TextCreator.CreateTextLabelModel3D("Z-axis", Brushes.Black, true, FontSize,
                                                                           new Point3D(minX - FontSize*10, maxY,
                                                                                       (minZ + maxZ)*0.5),
                                                                           new Vector3D(0, 0, 1), new Vector3D(1, 0, 0));
                plotModel.Children.Add(label);
            }


            var bb = new Rect3D(minX, minY, minZ, maxX - minX, maxY - minY, 0*(maxZ - minZ));
            axesMeshBuilder.AddBoundingBox(bb, LineThickness);

            var axesModel = new GeometryModel3D(axesMeshBuilder.ToMesh(), Materials.Black);

            plotModel.Children.Add(surfaceModel);
            plotModel.Children.Add(axesModel);

            return plotModel;
        }
 /// <summary>
 /// Transform a Rect3D to a Rect.  If this transformation cannot be completed Rect.Empty is returned.
 /// </summary>
 /// <param name="rect3D">Input 3D bounding box</param>
 /// <returns>The 2D bounding box of the projection of these points</returns>
 public Rect TransformBounds(Rect3D rect3D)
 {
     if (_transformBetween2D != null)
     {
         return _transformBetween2D.TransformBounds(MILUtilities.ProjectBounds(ref _projectionTransform, ref rect3D));            
     }
     else
     {
         return Rect.Empty;
     }
 }
        /// <summary>
        /// Constructor
        /// </summary>
        public ucGraph3DViewer()
        {
            InitializeComponent();
            try
            {
                if (LicenseManager.UsageMode != LicenseUsageMode.Designtime)
                {
                    log4net.Config.XmlConfigurator.Configure(new System.IO.FileInfo("Graph3DLib.dll.config"));
                    _ResManager = new ResourceManager(typeof(global::Graph3DLib.Properties.Resources));
                    _Log4NetClass = new LogClass(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

                    Point3D camerapos = new Point3D(MachineConfig.ReadDoubleValue("CamX"),
                                                   MachineConfig.ReadDoubleValue("CamY"),
                                                   MachineConfig.ReadDoubleValue("CamZ"));
                    sliderCamX.Value = camerapos.X;
                    sliderCamY.Value = camerapos.Y;
                    sliderCamZ.Value = camerapos.Z;
                    txtCamX.Text = sliderCamX.Value.ToString();
                    txtCamY.Text = sliderCamY.Value.ToString();
                    txtCamZ.Text = sliderCamZ.Value.ToString();
                    _RotateSpeed = 7.5;

                    SetCamera(camerapos);

                    _ZoomValue = 0;
                    _MaxZoom = MachineConfig.ReadIntValue("MaxZoom");
                    _MinZoom = MachineConfig.ReadIntValue("MinZoom");

                    _TransparentValue = MachineConfig.ReadDoubleValue("TranparentValue");
                    _InitSize = camera.Position;

                    _MachineModel = new MachineModel();
                    _MachineModel.Create();
                    _TopPlateBasePos = _MachineModel.UpperPlatePos;
                    _BottomPlateBasePos = _MachineModel.LowerPlatePos;

                    viewport.Children.Add(_MachineModel.CurrentModel);

                    Color background = MachineConfig.ReadColorValue("ColorBackground");
                    SolidColorBrush backgroundbrush = new SolidColorBrush(background);
                    backgroundbrush.Freeze();
                    this.Background = backgroundbrush;

                    _AnimationSpeed = 1;

                    _ThreadAnimation = new ThreadAnimation();
                    _ThreadAnimation.OnAnimationCreated += OnAnimationCreated;
                    _GraphController = new GraphController(_MachineModel);

                    ReadConfigSensorHighLowValue();

                    _MeterTimer = new System.Timers.Timer();
                    _MeterTimer.Elapsed += new System.Timers.ElapsedEventHandler(MeterTimer_Elapsed);
                    _MeterTimer.Interval = 1;
                    circularMeter.OutOfRangeComplete += new EventHandler(circularGraph1_OutOfRangeComplete);

                    this.IsPanelShow = Convert.ToBoolean(MachineConfig.ReadStringValue("IsPanelShow"));
                    this.SelectLanguage = LanguageMode.Japanese;

                }

            }
            catch (Exception ex)
            {
                _Log4NetClass.ShowError(ex.ToString(), "Mainform Consturctor");
            }
        }
Exemple #21
0
 /// <summary>
 /// Transforms the bounding box to the smallest axis aligned bounding box
 /// that contains all the points in the original bounding box
 /// </summary>
 /// <param name="rect">Bounding box</param>
 /// <returns>The transformed bounding box</returns>
 public override Rect3D TransformBounds(Rect3D rect)
 {
     return(M3DUtil.ComputeTransformedAxisAlignedBoundingBox(ref rect, this));
 }
 public BindableSize3DModel(Rect3D size)
 {
     _size = size.IsEmpty ? new Size3D() : new Size3D(size.SizeX, size.SizeY, size.SizeZ);
 }
Exemple #23
0
 /// <summary>
 /// Offset - return the result of offsetting rect by the offset provided
 /// If this is Empty, this method is illegal.
 /// </summary>
 /// <param name="rect"></param>
 /// <param name="offsetVector"></param>
 /// <returns></returns>
 public static Rect3D Offset(Rect3D rect, Vector3D offsetVector)
 {
     rect.Offset(offsetVector._x, offsetVector._y, offsetVector._z);
     return(rect);
 }
        internal override RayHitTestParameters RayFromViewportPoint(Point p, Size viewSize, Rect3D boundingRect, out double distanceAdjustment)
        {
            //
            //  Compute rayParameters
            //
            
            // Find the point on the projection plane in post-projective space where
            // the viewport maps to a 2x2 square from (-1,1)-(1,-1).
            Point np = M3DUtil.GetNormalizedPoint(p, viewSize);

            // 

            
            // So (conceptually) the user clicked on the point (np.X,
            // np.Y, 0) in post-projection clipping space and the ray
            // extends in the direction (0, 0, 1) because our ray
            // after projection looks down the positive z axis.  We
            // need to convert this ray and direction back to world
            // space.

            Matrix3D worldToCamera = GetViewMatrix() * ProjectionMatrix;
            Matrix3D cameraToWorld = worldToCamera;

            if (!cameraToWorld.HasInverse)
            {
                // 




                // NTRAID#Longhorn-1180933-2004/07/30-danwo - Need to handle singular matrix cameras
                throw new NotSupportedException(SR.Get(SRID.HitTest_Singular));
            }
            
            cameraToWorld.Invert();

            Point4D origin4D = new Point4D(np.X,np.Y,0,1) * cameraToWorld;
            Point3D origin = new Point3D( origin4D.X/origin4D.W,
                                          origin4D.Y/origin4D.W,
                                          origin4D.Z/origin4D.W );

            // To transform the direction we use the Jacobian of
            // cameraToWorld at the point np.X,np.Y,0 that we just
            // transformed.
            //
            // The Jacobian of the homogeneous matrix M is a 3x3 matrix.
            //
            // Let x be the point we are computing the Jacobian at, and y be the
            // result of transforming x by M, i.e.
            // (wy w) = (x 1) M
            // Where (wy w) is the homogeneous point representing y with w as its homogeneous coordinate
            // And (x 1) is the homogeneous point representing x with 1 as its homogeneous coordinate
            //
            // Then the i,j component of the Jacobian (at x) is
            // (M_ij - M_i4 y_j) / w
            //
            // Since we're only concerned with the direction of the
            // transformed vector and not its magnitude, we can scale
            // this matrix by a POSITIVE factor.  The computation
            // below computes the Jacobian scaled by 1/w and then
            // after we normalize the final vector we flip it around
            // if w is negative.
            //
            // To transform a vector we just right multiply it by this Jacobian matrix.
            //
            // Compute the Jacobian at np.X,np.Y,0 ignoring the constant factor of w.
            // Here's the pattern
            //
            // double Jij = cameraToWorld.Mij - cameraToWorld.Mi4 * origin.j
            //
            // but we only need J31,J32,&J33 because we're only
            // transforming the vector 0,0,1

            double J31 = cameraToWorld.M31 - cameraToWorld.M34 * origin.X;
            double J32 = cameraToWorld.M32 - cameraToWorld.M34 * origin.Y;
            double J33 = cameraToWorld.M33 - cameraToWorld.M34 * origin.Z;

            // Then multiply that matrix by (0, 0, 1) which is
            // the direction of the ray in post-projection space.
            Vector3D direction = new Vector3D( J31, J32, J33 );
            direction.Normalize();

            // We multiplied by the Jacobian times W, so we need to
            // account for whether that flipped our result or not.
            if (origin4D.W < 0)
            {
                direction = -direction;
            }
            
            RayHitTestParameters rayParameters = new RayHitTestParameters(origin, direction);

            //
            //  Compute HitTestProjectionMatrix
            //

            // The viewportMatrix will take normalized clip space into
            // viewport coordinates, with an additional 2D translation
            // to put the ray at the origin.
            Matrix3D viewportMatrix = new Matrix3D();
            viewportMatrix.TranslatePrepend(new Vector3D(-p.X,viewSize.Height-p.Y,0));
            viewportMatrix.ScalePrepend(new Vector3D(viewSize.Width/2,-viewSize.Height/2,1));
            viewportMatrix.TranslatePrepend(new Vector3D(1,1,0));
            
            // `First world-to-camera, then camera's projection, then normalized clip space to viewport.
            rayParameters.HitTestProjectionMatrix = 
                worldToCamera *
                viewportMatrix;

            // 
            // MatrixCamera does not allow for Near/Far plane adjustment, so
            // the distanceAdjustment remains 0.
            //
            distanceAdjustment = 0.0;

            return rayParameters;
        }
 public System.Windows.Rect TransformBounds(Rect3D rect3D)
 {
     return(default(System.Windows.Rect));
 }
Exemple #26
0
        /// <summary>
        /// Precompute pass.
        /// </summary>
        internal void PrecomputeRecursive(out Rect3D bboxSubgraph)
        {
            if (CheckFlagsAnd(VisualFlags.IsSubtreeDirtyForPrecompute))
            {
                //
                // Update the subgraph bounding box which includes the content bounds
                // and the bounds of our children.
                //
                
                _bboxSubgraph = GetContentBounds();

                for (int i = 0, count = Visual3DChildrenCount; i < count; i++)
                {
                    Visual3D child = GetVisual3DChild(i);

                    Rect3D bboxSubgraphChild;
                    child.PrecomputeRecursive(out bboxSubgraphChild);
                    _bboxSubgraph.Union(bboxSubgraphChild);
                }

                SetFlags(false, VisualFlags.IsSubtreeDirtyForPrecompute);
            }

            bboxSubgraph = M3DUtil.ComputeTransformedAxisAlignedBoundingBox(ref _bboxSubgraph, Transform);
       }
Exemple #27
0
 /// <summary>
 /// Return the result of the intersection of rect1 and rect2.
 /// If either this or rect are Empty, the result is Empty as well.
 /// </summary>
 /// <param name="rect1">First rectangle.</param>
 /// <param name="rect2">Second rectangle.</param>
 /// <returns>The result of the intersection of rect1 and rect2.</returns>
 public static Rect3D Intersect(Rect3D rect1, Rect3D rect2)
 {
     rect1.Intersect(rect2);
     return(rect1);
 }
Exemple #28
0
        // Returns a new axis aligned bounding box that contains the old 
        // bounding box post the given transformation.
        internal static Rect3D ComputeTransformedAxisAlignedBoundingBox(/* IN */ ref Rect3D originalBox, Transform3D transform) 
        { 
            if (transform == null || transform == Transform3D.Identity)
            { 
                return originalBox;
            }

            Matrix3D matrix = transform.Value; 

            return ComputeTransformedAxisAlignedBoundingBox(ref originalBox, ref matrix); 
        } 
Exemple #29
0
        //------------------------------------------------------
        //
        //  Public Methods
        //
        //------------------------------------------------------

        //------------------------------------------------------
        //
        //  Public Properties
        //
        //------------------------------------------------------

        //------------------------------------------------------
        //
        //  Public Events
        //
        //------------------------------------------------------

        //------------------------------------------------------
        //
        //  Internal Methods
        //
        //------------------------------------------------------

        #region Internal Methods

        // Creates a ray by projecting the given point on the viewport into the scene.
        // Used for bridging 2D -> 3D hit testing.
        //
        // The latter two parameters in this method are used to deal with the
        // case where the camera's near plane is far away from the viewport
        // contents. In these cases, we can sometimes construct a new, closer,
        // near plane and start the ray on that plane. To do this, we need an
        // axis-aligned bounding box of the viewport's contents (boundingRect).
        // We also need to return the distance between the original an new near
        // planes (distanceAdjustment), so we can correct the hit-test
        // distances before handing them back to the user. For more
        // information, see WindowsOS

        internal abstract RayHitTestParameters RayFromViewportPoint(Point point, Size viewSize, Rect3D boundingRect, out double distanceAdjustment);
Exemple #30
0
 /// <summary>
 /// Return the result of the union of rect1 and rect2.
 /// </summary>
 /// <param name="rect1">First rectangle.</param>
 /// <param name="rect2">Second rectangle.</param>
 /// <returns>The result of the union of the two rectangles.</returns>
 public static Rect3D Union(Rect3D rect1, Rect3D rect2)
 {
     rect1.Union(rect2);
     return(rect1);
 }
Exemple #31
0
        internal override RayHitTestParameters RayFromViewportPoint(Point p, Size viewSize, Rect3D boundingRect, out double distanceAdjustment)
        {
            //
            //  Compute rayParameters
            //

            // Find the point on the projection plane in post-projective space where
            // the viewport maps to a 2x2 square from (-1,1)-(1,-1).
            Point np = M3DUtil.GetNormalizedPoint(p, viewSize);

            // This ray is consistent with a left-handed camera
            // MatrixCamera should be right-handed and should be updated to be so.

            // So (conceptually) the user clicked on the point (np.X,
            // np.Y, 0) in post-projection clipping space and the ray
            // extends in the direction (0, 0, 1) because our ray
            // after projection looks down the positive z axis.  We
            // need to convert this ray and direction back to world
            // space.

            Matrix3D worldToCamera = GetViewMatrix() * ProjectionMatrix;
            Matrix3D cameraToWorld = worldToCamera;

            if (!cameraToWorld.HasInverse)
            {
                // When the following issue is addressed we should
                //   investigate if the custom code paths in Orthographic and PerspectiveCamera
                //   are worth keeping.  They may not be buying us anything aside from handling
                //   singular matrices.

                // Need to handle singular matrix cameras
                throw new NotSupportedException(SR.Get(SRID.HitTest_Singular));
            }

            cameraToWorld.Invert();

            Point4D origin4D = new Point4D(np.X, np.Y, 0, 1) * cameraToWorld;
            Point3D origin   = new Point3D(origin4D.X / origin4D.W,
                                           origin4D.Y / origin4D.W,
                                           origin4D.Z / origin4D.W);

            // To transform the direction we use the Jacobian of
            // cameraToWorld at the point np.X,np.Y,0 that we just
            // transformed.
            //
            // The Jacobian of the homogeneous matrix M is a 3x3 matrix.
            //
            // Let x be the point we are computing the Jacobian at, and y be the
            // result of transforming x by M, i.e.
            // (wy w) = (x 1) M
            // Where (wy w) is the homogeneous point representing y with w as its homogeneous coordinate
            // And (x 1) is the homogeneous point representing x with 1 as its homogeneous coordinate
            //
            // Then the i,j component of the Jacobian (at x) is
            // (M_ij - M_i4 y_j) / w
            //
            // Since we're only concerned with the direction of the
            // transformed vector and not its magnitude, we can scale
            // this matrix by a POSITIVE factor.  The computation
            // below computes the Jacobian scaled by 1/w and then
            // after we normalize the final vector we flip it around
            // if w is negative.
            //
            // To transform a vector we just right multiply it by this Jacobian matrix.
            //
            // Compute the Jacobian at np.X,np.Y,0 ignoring the constant factor of w.
            // Here's the pattern
            //
            // double Jij = cameraToWorld.Mij - cameraToWorld.Mi4 * origin.j
            //
            // but we only need J31,J32,&J33 because we're only
            // transforming the vector 0,0,1

            double J31 = cameraToWorld.M31 - cameraToWorld.M34 * origin.X;
            double J32 = cameraToWorld.M32 - cameraToWorld.M34 * origin.Y;
            double J33 = cameraToWorld.M33 - cameraToWorld.M34 * origin.Z;

            // Then multiply that matrix by (0, 0, 1) which is
            // the direction of the ray in post-projection space.
            Vector3D direction = new Vector3D(J31, J32, J33);

            direction.Normalize();

            // We multiplied by the Jacobian times W, so we need to
            // account for whether that flipped our result or not.
            if (origin4D.W < 0)
            {
                direction = -direction;
            }

            RayHitTestParameters rayParameters = new RayHitTestParameters(origin, direction);

            //
            //  Compute HitTestProjectionMatrix
            //

            // The viewportMatrix will take normalized clip space into
            // viewport coordinates, with an additional 2D translation
            // to put the ray at the origin.
            Matrix3D viewportMatrix = new Matrix3D();

            viewportMatrix.TranslatePrepend(new Vector3D(-p.X, viewSize.Height - p.Y, 0));
            viewportMatrix.ScalePrepend(new Vector3D(viewSize.Width / 2, -viewSize.Height / 2, 1));
            viewportMatrix.TranslatePrepend(new Vector3D(1, 1, 0));

            // First, world-to-camera, then camera's projection, then normalized clip space to viewport.
            rayParameters.HitTestProjectionMatrix =
                worldToCamera *
                viewportMatrix;

            //
            // MatrixCamera does not allow for Near/Far plane adjustment, so
            // the distanceAdjustment remains 0.
            //
            distanceAdjustment = 0.0;

            return(rayParameters);
        }
Exemple #32
0
 /// <summary>
 /// Return the result of the union of rect and point.
 /// </summary>
 /// <param name="rect">Rectangle.</param>
 /// <param name="point">Point.</param>
 /// <returns>The result of the union of rect and point.</returns>
 public static Rect3D Union(Rect3D rect, Point3D point)
 {
     rect.Union(new Rect3D(point, point));
     return(rect);
 }
Exemple #33
0
        internal void Debug_VerifyBoundsEqual(Rect3D bounds1, Rect3D bounds2, string errorString)
        {
            // The funny boolean logic below avoids asserts when the cached
            // bounds contain NaNs.  (NaN != NaN)
            bool boundsAreEqual =
                !(bounds1.X < bounds2.X || bounds1.X > bounds2.X) &&
                !(bounds1.Y < bounds2.Y || bounds1.Y > bounds2.Y) &&
                !(bounds1.Z < bounds2.Z || bounds1.Z > bounds2.Z) &&
                !(bounds1.SizeX < bounds2.SizeX || bounds1.SizeX > bounds2.SizeX) &&
                !(bounds1.SizeY < bounds2.SizeY || bounds1.SizeY > bounds2.SizeY) &&
                !(bounds1.SizeZ < bounds2.SizeZ || bounds1.SizeZ > bounds2.SizeZ);

            Debug.Assert(boundsAreEqual, errorString);
        }
Exemple #34
0
        internal override RayHitTestParameters RayFromViewportPoint(Point p, Size viewSize, Rect3D boundingRect, out double distanceAdjustment)
        {
            // The camera may be animating.  Take a snapshot of the current value
            // and get the property values we need. (Window OS #992662)
            Point3D     position      = Position;
            Vector3D    lookDirection = LookDirection;
            Vector3D    upDirection   = UpDirection;
            Transform3D transform     = Transform;
            double      zn            = NearPlaneDistance;
            double      zf            = FarPlaneDistance;
            double      fov           = M3DUtil.DegreesToRadians(FieldOfView);

            //
            //  Compute rayParameters
            //

            // Find the point on the projection plane in post-projective space where
            // the viewport maps to a 2x2 square from (-1,1)-(1,-1).
            Point np = M3DUtil.GetNormalizedPoint(p, viewSize);

            // Note: h and w are 1/2 of the inverse of the width/height ratios:
            //
            //  h = 1/(heightDepthRatio) * (1/2)
            //  w = 1/(widthDepthRatio) * (1/2)
            //
            // Computation for h is a bit different than what you will find in
            // D3DXMatrixPerspectiveFovRH because we have a horizontal rather
            // than vertical FoV.
            double aspectRatio         = M3DUtil.GetAspectRatio(viewSize);
            double halfWidthDepthRatio = Math.Tan(fov / 2);
            double h = aspectRatio / halfWidthDepthRatio;
            double w = 1 / halfWidthDepthRatio;

            // To get from projective space to camera space we apply the
            // width/height ratios to find our normalized point at 1 unit
            // in front of the camera.  (1 is convenient, but has no other
            // special significance.) See note above about the construction
            // of w and h.
            Vector3D rayDirection = new Vector3D(np.X / w, np.Y / h, -1);

            // Apply the inverse of the view matrix to our rayDirection vector
            // to convert it from camera to world space.
            //
            // NOTE: Because our construction of the ray assumes that the
            //       viewMatrix translates the position to the origin we pass
            //       null for the Camera.Transform below and account for it
            //       later.

            Matrix3D viewMatrix = CreateViewMatrix(/* trasform = */ null, ref position, ref lookDirection, ref upDirection);
            Matrix3D invView    = viewMatrix;

            invView.Invert();
            invView.MultiplyVector(ref rayDirection);

            // The we have the ray direction, now we need the origin.  The camera's
            // position would work except that we would intersect geometry between
            // the camera plane and the near plane so instead we must find the
            // point on the project plane where the ray (position, rayDirection)
            // intersect (Windows OS #1005064):
            //
            //                     | _.>       p = camera position
            //                rd  _+"          ld = camera look direction
            //                 .-" |ro         pp = projection plane
            //             _.-"    |           rd = ray direction
            //         p +"--------+--->       ro = desired ray origin on pp
            //                ld   |
            //                     pp
            //
            // Above we constructed the direction such that it's length projects to
            // 1 unit on the lookDirection vector.
            //
            //
            //                rd  _.>
            //                 .-"        rd = unnormalized rayDirection
            //             _.-"           ld = normalized lookDirection (length = 1)
            //           -"--------->
            //                 ld
            //
            // So to find the desired rayOrigin on the projection plane we simply do:
            Point3D rayOrigin = position + zn * rayDirection;

            rayDirection.Normalize();

            // Account for the Camera.Transform we ignored during ray construction above.
            if (transform != null && transform != Transform3D.Identity)
            {
                Matrix3D m = transform.Value;
                m.MultiplyPoint(ref rayOrigin);
                m.MultiplyVector(ref rayDirection);

                PrependInverseTransform(m, ref viewMatrix);
            }

            RayHitTestParameters rayParameters = new RayHitTestParameters(rayOrigin, rayDirection);

            //
            //  Compute HitTestProjectionMatrix
            //

            Matrix3D projectionMatrix = GetProjectionMatrix(aspectRatio, zn, zf);

            // The projectionMatrix takes camera-space 3D points into normalized clip
            // space.

            // The viewportMatrix will take normalized clip space into
            // viewport coordinates, with an additional 2D translation
            // to put the ray at the rayOrigin.
            Matrix3D viewportMatrix = new Matrix3D();

            viewportMatrix.TranslatePrepend(new Vector3D(-p.X, viewSize.Height - p.Y, 0));
            viewportMatrix.ScalePrepend(new Vector3D(viewSize.Width / 2, -viewSize.Height / 2, 1));
            viewportMatrix.TranslatePrepend(new Vector3D(1, 1, 0));

            // `First world-to-camera, then camera's projection, then normalized clip space to viewport.
            rayParameters.HitTestProjectionMatrix =
                viewMatrix *
                projectionMatrix *
                viewportMatrix;

            //
            // Perspective camera doesn't allow negative NearPlanes, so there's
            // not much point in adjusting the ray origin. Hence, the
            // distanceAdjustment remains 0.
            //
            distanceAdjustment = 0.0;

            return(rayParameters);
        }
Exemple #35
0
        /// <summary>
        ///     Returns the bounds of the Model3D subgraph rooted at this Model3D.
        ///
        ///     Outer space refers to the space after this Model's Transform is
        ///     applied -- or said another way, applying a transform to this Model
        ///     affects it's outer bounds.  (While its inner bounds remain unchanged.)
        /// </summary>
        internal Rect3D CalculateSubgraphBoundsOuterSpace()
        {
            Rect3D innerBounds = CalculateSubgraphBoundsInnerSpace();

            return(M3DUtil.ComputeTransformedAxisAlignedBoundingBox(ref innerBounds, Transform));
        }
Exemple #36
0
        internal override RayHitTestParameters RayFromViewportPoint(Point p, Size viewSize, Rect3D boundingRect, out double distanceAdjustment)
        {
            // The camera may be animating.  Take a snapshot of the current value
            // and get the property values we need. (Window OS #992662)
            Point3D  position      = Position;
            Vector3D lookDirection = LookDirection;
            Vector3D upDirection   = UpDirection;
            double   zn            = NearPlaneDistance;
            double   zf            = FarPlaneDistance;
            double   width         = Width;

            //
            //  Compute rayParameters
            //

            // Find the point on the projection plane in post-projective space where
            // the viewport maps to a 2x2 square from (-1,1)-(1,-1).
            Point np = M3DUtil.GetNormalizedPoint(p, viewSize);

            double aspectRatio = M3DUtil.GetAspectRatio(viewSize);
            double w           = width;
            double h           = w / aspectRatio;

            // Direction is always perpendicular to the viewing surface.
            Vector3D direction = new Vector3D(0, 0, -1);

            // Apply the inverse of the view matrix to our ray.
            Matrix3D viewMatrix = CreateViewMatrix(Transform, ref position, ref lookDirection, ref upDirection);
            Matrix3D invView    = viewMatrix;

            invView.Invert();

            // We construct our ray such that the origin resides on the near
            // plane.  If our near plane is too far from our the bounding box
            // of our scene then the results will be inaccurate.  (e.g.,
            // OrthographicCameras permit negative near planes, so the near
            // plane could be at -Inf.)
            //
            // However, it is permissable to move the near plane nearer to
            // the scene bounds without changing what the ray intersects.
            // If the near plane is sufficiently far from the scene bounds
            // we make this adjustment below to increase precision.

            Rect3D transformedBoundingBox =
                M3DUtil.ComputeTransformedAxisAlignedBoundingBox(
                    ref boundingRect,
                    ref viewMatrix);

            // DANGER:  The NearPlaneDistance property is specified as a
            //          distance from the camera position along the
            //          LookDirection with (Near < Far).
            //
            //          However, when we transform our scene bounds so that
            //          the camera is aligned with the negative Z-axis the
            //          relationship inverts (Near > Far) as illustrated
            //          below:
            //
            //            NearPlane    Y                      FarPlane
            //                |        ^                          |
            //                |        |                          |
            //                |        | (rect.Z + rect.SizeZ)    |
            //                |        |           o____          |
            //                |        |           |    |         |
            //                |        |           |    |         |
            //                |        |            ____o         |
            //                |        |             (rect.Z)     |
            //                |     Camera ->                     |
            //          +Z  <----------+----------------------------> -Z
            //                |        0                          |
            //
            //          It is surprising, but its the "far" side of the
            //          transformed scene bounds that determines the near
            //          plane distance.

            double zn2 = -AddEpsilon(transformedBoundingBox.Z + transformedBoundingBox.SizeZ);

            if (zn2 > zn)
            {
                //
                // Our near plane is far from our children. Construct a new
                // near plane that's closer. Note that this will modify our
                // distance computations, so we have to be sure to adjust our
                // distances appropriately.
                //
                distanceAdjustment = zn2 - zn;

                zn = zn2;
            }
            else
            {
                //
                // Our near plane is either close to or in front of our
                // children, so let's keep it -- no distance adjustment needed.
                //
                distanceAdjustment = 0.0;
            }

            // Our origin is the point normalized to the front of our viewing volume.
            // To find our origin's x/y we just need to scale the normalize point by our
            // width/height.  In camera space we are looking down the negative Z axis
            // so we just set Z to be -zn which puts us on the projection plane
            // (Windows OS #1005064).
            Point3D origin = new Point3D(np.X * (w / 2), np.Y * (h / 2), -zn);

            invView.MultiplyPoint(ref origin);
            invView.MultiplyVector(ref direction);

            RayHitTestParameters rayParameters = new RayHitTestParameters(origin, direction);

            //
            //  Compute HitTestProjectionMatrix
            //

            Matrix3D projectionMatrix = GetProjectionMatrix(aspectRatio, zn, zf);

            // The projectionMatrix takes camera-space 3D points into normalized clip
            // space.

            // The viewportMatrix will take normalized clip space into
            // viewport coordinates, with an additional 2D translation
            // to put the ray at the origin.
            Matrix3D viewportMatrix = new Matrix3D();

            viewportMatrix.TranslatePrepend(new Vector3D(-p.X, viewSize.Height - p.Y, 0));
            viewportMatrix.ScalePrepend(new Vector3D(viewSize.Width / 2, -viewSize.Height / 2, 1));
            viewportMatrix.TranslatePrepend(new Vector3D(1, 1, 0));

            // `First world-to-camera, then camera's projection, then normalized clip space to viewport.
            rayParameters.HitTestProjectionMatrix =
                viewMatrix *
                projectionMatrix *
                viewportMatrix;

            return(rayParameters);
        }
Exemple #37
0
        //------------------------------------------------------ 
        //
        //  Public Methods 
        // 
        //-----------------------------------------------------
 
        //------------------------------------------------------
        //
        //  Public Properties
        // 
        //------------------------------------------------------
 
        //----------------------------------------------------- 
        //
        //  Public Events 
        //
        //------------------------------------------------------

        //----------------------------------------------------- 
        //
        //  Internal Methods 
        // 
        //-----------------------------------------------------
 
        #region Internal Methods

        // Creates a ray by projecting the given point on the viewport into the scene.
        // Used for bridging 2D -> 3D hit testing. 
        //
        // The latter two parameters in this method are used to deal with the 
        // case where the camera's near plane is far away from the viewport 
        // contents. In these cases, we can sometimes construct a new, closer,
        // near plane and start the ray on that plane. To do this, we need an 
        // axis-aligned bounding box of the viewport's contents (boundingRect).
        // We also need to return the distance between the original an new near
        // planes (distanceAdjustment), so we can correct the hit-test
        // distances before handing them back to the user. For more 
        // information, see WindowsOS Bug #1329733.
        // 
        internal abstract RayHitTestParameters RayFromViewportPoint(Point point, Size viewSize, Rect3D boundingRect, out double distanceAdjustment); 
 /// <summary>
 /// Zooms to the extents of the specified bounding box.
 /// </summary>
 /// <param name="viewport">The viewport.</param>
 /// <param name="bounds">The bounding rectangle.</param>
 /// <param name="animationTime">The animation time.</param>
 public static void ZoomExtents(this Viewport3DX viewport, Rect3D bounds, double animationTime = 0)
 {
     var diagonal = new Vector3D(bounds.SizeX, bounds.SizeY, bounds.SizeZ);
     var center = bounds.Location + (diagonal * 0.5);
     double radius = diagonal.Length * 0.5;
     ZoomExtents(viewport, center, radius, animationTime);
 }
Exemple #39
0
        // CTAABB for an affine transforms
        internal static Rect3D ComputeTransformedAxisAlignedBoundingBoxAffine(/* IN */ ref Rect3D originalBox, /* IN */ ref Matrix3D matrix)
        {
            Debug.Assert(matrix.IsAffine); 

            // Based on Arvo's paper "Transforming Axis-Aligned Bounding Boxes" 
            // from the original Graphics Gems book. Specifically, this code 
            // is based on Figure 1 which is for a box stored as min and
            // max points. Our bounding boxes are stored as a min point and 
            // a diagonal so we'll convert when needed. Also, we have row
            // vectors.
            //
            // Mapping Arvo's variables to ours: 
            // A - the untransformed box (originalBox)
            // B - the transformed box (what we return at the end) 
            // M - the rotation + scale (matrix.Mji) 
            // T - the translation (matrix.Offset?)
            // 
            // for i = 1 ... 3
            //     Bmin_i = Bmax_i = T_i
            //         for j = 1 ... 3
            //             a = M_ij * Amin_j 
            //             b = M_ij * Amax_j
            //             Bmin_i += min(a, b) 
            //             Bmax_i += max(a, b) 
            //
            // Matrix3D doesn't have indexers because they're too slow so we'll 
            // have to unroll the loops. A complete unroll of both loops was
            // found to be the fastest.

            double oldMaxX = originalBox.X + originalBox.SizeX; 
            double oldMaxY = originalBox.Y + originalBox.SizeY;
            double oldMaxZ = originalBox.Z + originalBox.SizeZ; 
 
            // i = 1 (X)
            double newMinX = matrix.OffsetX; 
            double newMaxX = matrix.OffsetX;
            {
                // i = 1 (X), j = 1 (X)
                double a = matrix.M11 * originalBox.X; 
                double b = matrix.M11 * oldMaxX;
                if (b > a) 
                { 
                    newMinX += a;
                    newMaxX += b; 
                }
                else
                {
                    newMinX += b; 
                    newMaxX += a;
                } 
 
                // i = 1 (X), j = 2 (Y)
                a = matrix.M21 * originalBox.Y; 
                b = matrix.M21 * oldMaxY;
                if (b > a)
                {
                    newMinX += a; 
                    newMaxX += b;
                } 
                else 
                {
                    newMinX += b; 
                    newMaxX += a;
                }

                // i = 1 (X), j = 3 (Z) 
                a = matrix.M31 * originalBox.Z;
                b = matrix.M31 * oldMaxZ; 
                if (b > a) 
                {
                    newMinX += a; 
                    newMaxX += b;
                }
                else
                { 
                    newMinX += b;
                    newMaxX += a; 
                } 
            }
 
            // i = 2 (Y)
            double newMinY = matrix.OffsetY;
            double newMaxY = matrix.OffsetY;
            { 
                // i = 2 (Y), j = 1 (X)
                double a = matrix.M12 * originalBox.X; 
                double b = matrix.M12 * oldMaxX; 
                if (b > a)
                { 
                    newMinY += a;
                    newMaxY += b;
                }
                else 
                {
                    newMinY += b; 
                    newMaxY += a; 
                }
 
                // i = 2 (Y), j = 2 (Y)
                a = matrix.M22 * originalBox.Y;
                b = matrix.M22 * oldMaxY;
                if (b > a) 
                {
                    newMinY += a; 
                    newMaxY += b; 
                }
                else 
                {
                    newMinY += b;
                    newMaxY += a;
                } 

                // i = 2 (Y), j = 3 (Z) 
                a = matrix.M32 * originalBox.Z; 
                b = matrix.M32 * oldMaxZ;
                if (b > a) 
                {
                    newMinY += a;
                    newMaxY += b;
                } 
                else
                { 
                    newMinY += b; 
                    newMaxY += a;
                } 
            }

            // i = 3 (Z)
            double newMinZ = matrix.OffsetZ; 
            double newMaxZ = matrix.OffsetZ;
            { 
                // i = 3 (Z), j = 1 (X) 
                double a = matrix.M13 * originalBox.X;
                double b = matrix.M13 * oldMaxX; 
                if (b > a)
                {
                    newMinZ += a;
                    newMaxZ += b; 
                }
                else 
                { 
                    newMinZ += b;
                    newMaxZ += a; 
                }

                // i = 3 (Z), j = 2 (Y)
                a = matrix.M23 * originalBox.Y; 
                b = matrix.M23 * oldMaxY;
                if (b > a) 
                { 
                    newMinZ += a;
                    newMaxZ += b; 
                }
                else
                {
                    newMinZ += b; 
                    newMaxZ += a;
                } 
 
                // i = 3 (Z), j = 3 (Z)
                a = matrix.M33 * originalBox.Z; 
                b = matrix.M33 * oldMaxZ;
                if (b > a)
                {
                    newMinZ += a; 
                    newMaxZ += b;
                } 
                else 
                {
                    newMinZ += b; 
                    newMaxZ += a;
                }
            }
 
            return new Rect3D(newMinX, newMinY, newMinZ, newMaxX - newMinX, newMaxY - newMinY, newMaxZ - newMinZ);
        } 
Exemple #40
0
 /// <summary>
 /// Offset - return the result of offsetting rect by the offset provided
 /// If this is Empty, this method is illegal.
 /// </summary>
 /// <param name="rect"></param>
 /// <param name="offsetX"></param>
 /// <param name="offsetY"></param>
 /// <param name="offsetZ"></param>
 /// <returns></returns>
 public static Rect3D Offset(Rect3D rect, double offsetX, double offsetY, double offsetZ)
 {
     rect.Offset(offsetX, offsetY, offsetZ);
     return(rect);
 }
Exemple #41
0
        // Returns a new axis aligned bounding box that contains the old 
        // bounding box post the given transformation.
        internal static Rect3D ComputeTransformedAxisAlignedBoundingBox( /* IN */ ref Rect3D originalBox, /* IN */ ref Matrix3D matrix)
        {
            if (originalBox.IsEmpty) 
            {
                return originalBox; 
            } 

            if (matrix.IsAffine) 
            {
                return ComputeTransformedAxisAlignedBoundingBoxAffine(ref originalBox, ref matrix);
            }
            else 
            {
                return ComputeTransformedAxisAlignedBoundingBoxNonAffine(ref originalBox, ref matrix); 
            } 
        }
Exemple #42
0
 /// <summary>
 /// Equals - compares this Rect3D with the passed in object.  In this equality
 /// Double.NaN is equal to itself, unlike in numeric equality.
 /// Note that double values can acquire error when operated upon, such that
 /// an exact comparison between two values which
 /// are logically equal may fail.
 /// </summary>
 /// <returns>
 /// bool - true if "value" is equal to "this".
 /// </returns>
 /// <param name='value'>The Rect3D to compare to "this"</param>
 public bool Equals(Rect3D value)
 {
     return(Rect3D.Equals(this, value));
 }
Exemple #43
0
        // CTAABB for non-affine transformations
        internal static Rect3D ComputeTransformedAxisAlignedBoundingBoxNonAffine(/* IN */ ref Rect3D originalBox, /* IN */ ref Matrix3D matrix) 
        {
            Debug.Assert(!matrix.IsAffine);

            double x1 = originalBox.X; 
            double y1 = originalBox.Y;
            double z1 = originalBox.Z; 
            double x2 = originalBox.X + originalBox.SizeX; 
            double y2 = originalBox.Y + originalBox.SizeY;
            double z2 = originalBox.Z + originalBox.SizeZ; 

            Point3D[] points = new Point3D[] {
                new Point3D(x1, y1, z1),
                new Point3D(x1, y1, z2), 
                new Point3D(x1, y2, z1),
                new Point3D(x1, y2, z2), 
                new Point3D(x2, y1, z1), 
                new Point3D(x2, y1, z2),
                new Point3D(x2, y2, z1), 
                new Point3D(x2, y2, z2),
            };

            matrix.Transform(points); 

            Point3D p = points[0]; 
            Rect3D newBounds = new Rect3D(p.X, p.Y, p.Z, 0, 0, 0); 

            // Traverse the entire mesh and compute bounding box. 
            for(int i = 1; i < points.Length; i++)
            {
                p = points[i];
 
                AddPointToBounds(ref p, ref newBounds);
            } 
 
            return newBounds;
        } 
 public override Rect3D TransformBounds(Rect3D rect)
 {
     return(default(Rect3D));
 }
Exemple #45
0
        // Computes an axis aligned bounding box that contains the given set of points.
        internal static Rect3D ComputeAxisAlignedBoundingBox(Point3DCollection positions) 
        { 
            if (positions != null)
            { 
                FrugalStructList<Point3D> points = positions._collection;

                if (points.Count != 0)
                { 
                    Point3D p = points[0];
                    Rect3D newBounds = new Rect3D(p.X, p.Y, p.Z, 0, 0, 0); 
 
                    for(int i = 1; i < points.Count; i++)
                    { 
                        p = points[i];

                        M3DUtil.AddPointToBounds(ref p, ref newBounds);
                    } 

                    return newBounds; 
                } 
            }
 
            return Rect3D.Empty;
        }
 /// <summary>
 /// Transforms the bounding box to the smallest axis aligned bounding box
 /// that contains all the points in the original bounding box
 /// </summary>
 /// <param name="rect">Bounding box</param>
 /// <returns>The transformed bounding box</returns>
 public abstract Rect3D TransformBounds(Rect3D rect);