private static bool _HitTest(GLPanel3D viewport, PointF pointInWpf, float sensitive, List <HitResult> results, IHitTestSource model) { if (model is GLModel3DGroup) { var group = model as GLModel3DGroup; foreach (var child in group.Children) { if (_HitTest(viewport, pointInWpf, sensitive, results, child)) { return(true); } } return(false); } else { //var meshModel = model as GLMeshModel3D; var bounds3D = model.Bounds; var bounds2D = Math3DHelper.Transform(bounds3D, viewport); var sensity = sensitive; switch (model.Mode) { case GLPrimitiveMode.GL_POINTS: case GLPrimitiveMode.GL_LINES: case GLPrimitiveMode.GL_LINE_LOOP: case GLPrimitiveMode.GL_LINE_STRIP: if (!bounds2D.IsEmpty) { sensity += model.Mode == GLPrimitiveMode.GL_POINTS ? model.PointSize / 2 : model.LineWidth / 2; bounds2D.Extents(sensity); } break; case GLPrimitiveMode.GL_TRIANGLES: case GLPrimitiveMode.GL_TRIANGLE_STRIP: case GLPrimitiveMode.GL_TRIANGLE_FAN: break; } if (!bounds2D.Contains(pointInWpf)) { return(false); } var points = model.GetHitTestPoints().ToArray(); var pointsTransformed = new LazyArray <Point3F, Point3F>(points, p => viewport.Point3DToPointInWpfWithZDpeth(p)); switch (model.Mode) { case GLPrimitiveMode.GL_POINTS: { if (model.Pairs == null) { if (_HitTestPointResult(model, new DataPair(0, points.Length), points, pointsTransformed, results, pointInWpf, sensity)) { return(true); } } else { foreach (var pair in model.Pairs) { if (_HitTestPointResult(model, pair, points, pointsTransformed, results, pointInWpf, sensity)) { return(true); } } } } break; case GLPrimitiveMode.GL_LINES: case GLPrimitiveMode.GL_LINE_STRIP: case GLPrimitiveMode.GL_LINE_LOOP: { if (model.Pairs == null) { if (_HitTestLinesResult(model, new DataPair(0, points.Length), points, pointsTransformed, results, pointInWpf, sensity)) { return(true); } } else { foreach (var pair in model.Pairs) { if (_HitTestLinesResult(model, pair, points, pointsTransformed, results, pointInWpf, sensity)) { return(true); } } } } break; case GLPrimitiveMode.GL_TRIANGLES: case GLPrimitiveMode.GL_TRIANGLE_STRIP: { if (model.Pairs == null) { if (_HitTestTrianglesResult(model, new DataPair(0, points.Length), points, pointsTransformed, results, pointInWpf)) { return(true); } } else { foreach (var pair in model.Pairs) { if (_HitTestTrianglesResult(model, pair, points, pointsTransformed, results, pointInWpf)) { return(true); } } } } break; case GLPrimitiveMode.GL_TRIANGLE_FAN: { if (model.Pairs == null) { if (_HitTestTriangleFansResult(model, new DataPair(0, points.Length), points, pointsTransformed, results, pointInWpf)) { return(true); } } else { foreach (var pair in model.Pairs) { if (_HitTestTriangleFansResult(model, pair, points, pointsTransformed, results, pointInWpf)) { return(true); } } } } break; } return(false); } }
private static bool _HitTest(GLPanel3D viewport, RectF rectInWpf, IHitTestSource model, List <RectHitResult> results, bool isFullContain) { if (model is GLModel3DGroup) { var group = model as GLModel3DGroup; if (isFullContain) { foreach (var child in group.Children) { if (!_HitTest(viewport, rectInWpf, child, results, isFullContain)) { return(false); } } if (model.Parent == null) { results.Add(new RectHitResult(model)); } return(true); } else { foreach (var child in group.Children) { if (_HitTest(viewport, rectInWpf, child, results, isFullContain)) { return(true); } } return(false); } } else { //var meshModel = model as GLMeshModel3D; var bounds3D = model.Bounds; var bounds2D = Math3DHelper.Transform(bounds3D, viewport); var sensity = model.Mode == GLPrimitiveMode.GL_POINTS ? model.PointSize / 2 : model.LineWidth; switch (model.Mode) { case GLPrimitiveMode.GL_POINTS: case GLPrimitiveMode.GL_LINES: case GLPrimitiveMode.GL_LINE_LOOP: case GLPrimitiveMode.GL_LINE_STRIP: if (!bounds2D.IsEmpty) { bounds2D.Extents(sensity); } break; } if ((isFullContain && bounds2D.IsEmpty) || rectInWpf.Contains(bounds2D)) { if (!isFullContain || model.Parent == null) { results.Add(new RectHitResult(model)); } return(true); } else { if (!rectInWpf.IntersectsWith(bounds2D)) { return(false); } var flag1 = false; var flag2 = true; var pointsTransformed = new LazyArray <Point3F, PointF>(model.GetHitTestPoints(), p => viewport.Point3DToPointInWpf(p)); switch (model.Mode) { case GLPrimitiveMode.GL_POINTS: { if (model.Pairs == null) { _HitTestPointResult(new DataPair(0, pointsTransformed.Length), pointsTransformed, rectInWpf, isFullContain, sensity, ref flag1, ref flag2); } else { foreach (var pair in model.Pairs) { if (_HitTestPointResult(pair, pointsTransformed, rectInWpf, isFullContain, sensity, ref flag1, ref flag2)) { break; } } } } break; case GLPrimitiveMode.GL_LINES: case GLPrimitiveMode.GL_LINE_LOOP: case GLPrimitiveMode.GL_LINE_STRIP: { if (model.Pairs == null) { _HitTestLinesResult(model, new DataPair(0, pointsTransformed.Length), pointsTransformed, rectInWpf, isFullContain, sensity, ref flag1, ref flag2); } else { foreach (var pair in model.Pairs) { if (_HitTestLinesResult(model, pair, pointsTransformed, rectInWpf, isFullContain, sensity, ref flag1, ref flag2)) { break; } } } } break; case GLPrimitiveMode.GL_TRIANGLES: case GLPrimitiveMode.GL_TRIANGLE_STRIP: { if (model.Pairs == null) { _HitTestTrianglesResult(model, new DataPair(0, pointsTransformed.Length), pointsTransformed, rectInWpf, isFullContain, ref flag1, ref flag2); } else { foreach (var pair in model.Pairs) { if (_HitTestTrianglesResult(model, pair, pointsTransformed, rectInWpf, isFullContain, ref flag1, ref flag2)) { break; } } } } break; case GLPrimitiveMode.GL_TRIANGLE_FAN: { if (model.Pairs == null) { _HitTestTriangleFansResult(new DataPair(0, pointsTransformed.Length), pointsTransformed, rectInWpf, isFullContain, ref flag1, ref flag2); } else { foreach (var pair in model.Pairs) { if (_HitTestTriangleFansResult(pair, pointsTransformed, rectInWpf, isFullContain, ref flag1, ref flag2)) { break; } } } } break; } if (flag1 && !isFullContain) { results.Add(new RectHitResult(model)); return(true); } else if (flag2 && isFullContain) { if (model.Parent == null) { results.Add(new RectHitResult(model)); } return(true); } return(false); } } }