// alternative to base.HitTest(rayWS, ref hits); protected bool MyHitTest(Ray rayWS, ref List <HitTestResult> hits) { LineGeometry3D lineGeometry3D = this.Geometry as LineGeometry3D; Viewport3DX viewport = FindVisualAncestor <Viewport3DX>(this.renderHost as DependencyObject); if (this.Visibility == System.Windows.Visibility.Collapsed || this.IsHitTestVisible == false || viewport == null || lineGeometry3D == null) { return(false); } var result = new HitTestResult { IsValid = false, Distance = double.MaxValue }; var lastDist = double.MaxValue; var index = 0; foreach (var line in lineGeometry3D.Lines) { var t0 = Vector3.TransformCoordinate(line.P0, this.ModelMatrix); var t1 = Vector3.TransformCoordinate(line.P1, this.ModelMatrix); Vector3 sp, tp; float sc, tc; var distance = GetRayToLineDistance(rayWS, t0, t1, out sp, out tp, out sc, out tc); var svpm = viewport.GetScreenViewProjectionMatrix(); Vector4 sp4; Vector4 tp4; Vector3.Transform(ref sp, ref svpm, out sp4); Vector3.Transform(ref tp, ref svpm, out tp4); var sp3 = sp4.ToVector3(); var tp3 = tp4.ToVector3(); var tv2 = new Vector2(tp3.X - sp3.X, tp3.Y - sp3.Y); var dist = tv2.Length(); if (dist < lastDist && dist <= this.HitTestThickness) { lastDist = dist; result.PointHit = sp.ToPoint3D(); result.NormalAtHit = (sp - tp).ToVector3D(); // not normalized to get length result.Distance = distance; result.ModelHit = this; result.IsValid = true; result.Tag = index; // ToDo: LineHitTag with additional info } index++; } if (result.IsValid) { hits.Add(result); } this.hResult = result; return(result.IsValid); }
private static Ray Point2DToRay(this Viewport3DX viewport, Vector2 point2D) { var camera = viewport.Camera as ProjectionCamera; if (camera != null) { var p = new Vector3(point2D.X, point2D.Y, 1); var vp = viewport.GetScreenViewProjectionMatrix(); var vpi = Matrix.Invert(vp); var test = 1f / ((p.X * vpi.M14) + (p.Y * vpi.M24) + (p.Z * vpi.M34) + vpi.M44); if (double.IsInfinity(test)) { vpi.M44 = vpi.M44 + 0.000001f; } var worldToModelMatrix = WorldToModelMatrix(); p.Z = 0; var zn = Vector3.TransformCoordinate(p, vpi); zn = Vector3.TransformCoordinate(zn, worldToModelMatrix); p.Z = 1; var zf = Vector3.TransformCoordinate(p, vpi); zf = Vector3.TransformCoordinate(zf, worldToModelMatrix); Vector3 r = zf - zn; r.Normalize(); if (camera is PerspectiveCamera) { var pos = Vector3.TransformCoordinate(camera.Position.ToVector3(), worldToModelMatrix); return(new Ray(pos, r)); } if (camera is OrthographicCamera) { return(new Ray(zn, r)); } } throw new HelixToolkitException("Unproject camera error."); }
public static Matrix3D GetScreenViewProjectionMatrix3D(this Viewport3DX viewport) { return(viewport.GetScreenViewProjectionMatrix().ToMatrix3D()); }