/// <summary> /// For each mesh object in the viewport, this method calculates the vertex that when mapped to 2D is closest to the given 2D point on the screen /// </summary> /// <param name="pointToHitTest"> The point in screen coordinates to calculate the closest vertices for. </param> /// <returns> A ClosestVertexResult containing the distance to the 2D point and the closest 3D vertex point for each geometry/model </returns> public IEnumerable <ClosestVertexResult> FindClosestHits(Point pointToHitTest) { ProjectionCamera camera = mViewPort3D.Camera as ProjectionCamera; if (camera == null) { throw new InvalidOperationException("No projection camera defined. Cannot find rectangle hits."); } List <ClosestVertexResult> results = new List <ClosestVertexResult>(); mViewPort3D.Children.Traverse <GeometryModel3D>( (model, transform) => { MeshGeometry3D geometry = model.Geometry as MeshGeometry3D; if (geometry == null || geometry.Positions == null || geometry.TriangleIndices == null) { return; } Point3D[] point3Ds; if (geometry.Positions.Count <= mMaximumVerticesPerMesh) { point3Ds = geometry.Positions.Select(transform.Transform).ToArray(); } else { Rect3D bounds = geometry.Bounds; point3Ds = GetBoundaryPointsBoundingBox(bounds).Select(transform.Transform).ToArray(); } // transform the positions of the mesh to screen coordinates Point[] point2Ds = mViewPort3D.Point3DtoPoint2D(point3Ds).ToArray(); double minSquaredDistanceToPoint = double.PositiveInfinity; Point3D closestPoint = point3Ds[0]; Point closestPointIn2D = point2Ds[0]; for (int i = 0; i < point2Ds.Length; i++) { Point point = point2Ds[i]; double xDiff = point.X - pointToHitTest.X; double yDiff = point.Y - pointToHitTest.Y; double squaredDistance = xDiff * xDiff + yDiff * yDiff; if (squaredDistance < minSquaredDistanceToPoint) { minSquaredDistanceToPoint = squaredDistance; closestPoint = point3Ds[i]; closestPointIn2D = point; } } ClosestVertexResult hitTestResult = new ClosestVertexResult(model, geometry, closestPoint, closestPointIn2D, Math.Sqrt(minSquaredDistanceToPoint)); results.Add(hitTestResult); }); return(results); }
public TranslatePartGizmo(Viewport3D viewport) { this.viewport = viewport; x = new TranslatePartVisual3D(); y = new TranslatePartVisual3D(); x1 = new TranslationVisual3D(new Point3D(0, 0, 0), new Vector3D(1, 0, 0)); y1 = new TranslationVisual3D(new Point3D(0, 0, 0), new Vector3D(1, 0, 0)); x2 = new TranslationVisual3D(new Point3D(0, 0, 0), new Vector3D(-1, 0, 0)); y2 = new TranslationVisual3D(new Point3D(0, 0, 0), new Vector3D(-1, 0, 0)); containerX = new ContainerUIElement3D(); containerX.Children.Add(x); containerY = new ContainerUIElement3D(); containerY.Children.Add(y); containerX1 = new ContainerUIElement3D(); containerY1 = new ContainerUIElement3D(); containerX1.Children.Add(x1); containerY1.Children.Add(y1); containerX2 = new ContainerUIElement3D(); containerY2 = new ContainerUIElement3D(); containerX2.Children.Add(x2); containerY2.Children.Add(y2); x.Material = new DiffuseMaterial(Brushes.LightCoral.MakeTransparent(0.6)); y.Material = new DiffuseMaterial(Brushes.LightSkyBlue.MakeTransparent(0.6)); x1.Material = new DiffuseMaterial(Brushes.Red); y1.Material = new DiffuseMaterial(Brushes.Blue); x2.Material = new DiffuseMaterial(Brushes.Red); y2.Material = new DiffuseMaterial(Brushes.Blue); var scales = new[] { x, y }; var containers = new[] { containerX, containerY }; for (int i = 0; i < 2; i++) { int iCopy = i; var scale = scales[i]; var container = containers[i]; var curMat = scale.Material; container.MouseEnter += (sender, args) => { scale.Material = new DiffuseMaterial(Brushes.Yellow); }; container.MouseLeave += (sender, args) => { scale.Material = curMat; }; container.MouseDown += (sender, args) => { Mouse.Capture(container); whichAxis = iCopy + 1; lastPosition = args.GetPosition(container); }; container.MouseMove += (sender, args) => { if (whichAxis != 0) { Point curPosition = args.GetPosition(container); // double dy = Math.Pow(2,(curPosition.Y - lastPosition.Y)/200); // double dx = Math.Pow(2, (curPosition.X - lastPosition.X)/200); Point screenCenter = viewport.Point3DtoPoint2D(center); Viewport3DHelper.Point3DtoPoint2D(viewport, center); Vector sX = viewport.Point3DtoPoint2D(center + xAxis) - screenCenter; Vector sY = viewport.Point3DtoPoint2D(center + yAxis) - screenCenter; ScaleTransform scaling = null; if (whichAxis == 1) { //scale along x Vector offset = curPosition - lastPosition; double proj = sX * offset / sX.Length; scaling = new ScaleTransform(0.4 * proj, 0); } else if (whichAxis == 2) { //scale along y Vector offset = curPosition - lastPosition; double proj = sY * offset / sY.Length; scaling = new ScaleTransform(0, 0.4 * proj); } if (Scaled != null) { Scaled(scaling); } lastPosition = curPosition; } }; container.MouseUp += (sender, args) => { Mouse.Capture(null); whichAxis = 0; }; } }