public List <Intersection> Intersect(Ray3 ray) { List <Intersection> Intersections = new List <Intersection>(); float ScaledSize = (float)Size * MainWindow.Options.PixelScale.X / 2f; if (Depiction == PointDepiction.Mesh && DepictionMesh != null) { ScaledSize = DepictionMesh.BoundingBoxCorners[7].X; ScaledSize = Math.Max(ScaledSize, DepictionMesh.BoundingBoxCorners[7].Y); ScaledSize = Math.Max(ScaledSize, DepictionMesh.BoundingBoxCorners[7].Z); } Parallel.ForEach(Points, p => { float Distance = p.DistanceFromRay(ray); if (Distance <= ScaledSize) { lock (Intersections) Intersections.Add(new Intersection { Position = p.Position, Distance = Distance, Ray = ray, Target = p }); } }); return(Intersections); }
private void Viewport_MouseMove(Ray3 ray, System.Windows.Forms.MouseEventArgs e) { if (SurfaceMesh == null) { return; } List <Intersection> Intersections = new List <Intersection>(); Intersections.AddRange(SurfaceMesh.Intersect(ray)); if (Intersections.Count == 0 && IsMouseOver) { IsMouseOver = false; MouseLeave?.Invoke(this, e); } else if (Intersections.Count > 0) { Intersections.Sort((i1, i2) => i1.Distance.CompareTo(i2.Distance)); if (!IsMouseOver) { IsMouseOver = true; MouseEnter?.Invoke(this, Intersections, e); } MouseMove?.Invoke(this, Intersections, e); } }
private void Viewport_MouseUp(Ray3 ray, MouseEventArgs e) { if (SurfaceMesh == null) { return; } List <Intersection> Intersections = new List <Intersection>(); Intersections.AddRange(SurfaceMesh.Intersect(ray)); foreach (var group in PointGroups) { if (group.IsVisible) { Intersections.AddRange(group.Intersect(ray)); } } if (Intersections.Count > 0) { Intersections.Sort((i1, i2) => i1.Distance.CompareTo(i2.Distance)); MouseUp?.Invoke(this, Intersections, e); } }
public float DistanceFromRay(Ray3 ray) { Vector3 ToPoint = (Position - ray.Origin); float DotP = Vector3.Dot(ray.Direction.Normalized(), ToPoint); if (DotP <= 0) { return(float.PositiveInfinity); } Vector3 Closest = ray.Origin + ray.Direction.Normalized() * DotP; return((Closest - Position).Length); }
private void Viewport_MouseClick(Ray3 ray, System.Windows.Forms.MouseEventArgs e) { if (SurfaceMesh == null) { return; } List <Intersection> Intersections = new List <Intersection>(); Intersections.AddRange(SurfaceMesh.Intersect(ray)); if (Intersections.Count > 0) { Intersections.Sort((i1, i2) => i1.Distance.CompareTo(i2.Distance)); MouseClick?.Invoke(this, Intersections, e); } }
/// <summary> /// Calculates the intersection between the triangle and a ray, if they intersect. /// Adapted from https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm. /// </summary> /// <param name="ray">Ray to intersect with</param> /// <returns>Null if no intersection; intersection data otherwise</returns> public Intersection Intersect(Ray3 ray) { float Epsilon = 1e-5f; Vector3 e1, e2; //Edge1, Edge2 Vector3 P, Q, T; float det, inv_det, u, v; float t; //Find vectors for two edges sharing V1 e1 = V1.Position - V0.Position; e2 = V2.Position - V0.Position; //Begin calculating determinant - also used to calculate u parameter P = Vector3.Cross(ray.Direction, e2); //if determinant is near zero, ray lies in plane of triangle det = Vector3.Dot(e1, P); //NOT CULLING if (det > -Epsilon && det < Epsilon) { return(null); } inv_det = 1f / det; //calculate distance from V1 to ray origin T = ray.Origin - V0.Position; //Calculate u parameter and test bound u = Vector3.Dot(T, P) * inv_det; //The intersection lies outside of the triangle if (u < 0f || u > 1f) { return(null); } //Prepare to test v parameter Q = Vector3.Cross(T, e1); //Calculate V parameter and test bound v = Vector3.Dot(ray.Direction, Q) * inv_det; //The intersection lies outside of the triangle if (v < 0f || u + v > 1f) { return(null); } t = Vector3.Dot(e2, Q) * inv_det; if (t > Epsilon) //ray intersection { Intersection I = new Intersection(); I.Distance = t; I.Position = ray.Origin + ray.Direction * t; I.Ray = ray; I.Target = this; return(I); } // No hit, no win return(null); }
public List<Intersection> Intersect(Ray3 ray) { List<Intersection> Intersections = new List<Intersection>(); Parallel.ForEach(ProcessedTriangles.Where(t => t.IsVisible && t.Patch == null), t => { Intersection I = t.Intersect(ray); if (I != null) { I.Target = ProcessedTriangleMapping[(Triangle)I.Target]; lock (Intersections) Intersections.Add(I); } }); return Intersections; }
/// <summary> /// Calculates the intersection between the triangle and a ray, if they intersect. /// Adapted from https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm. /// </summary> /// <param name="ray">Ray to intersect with</param> /// <returns>Null if no intersection; intersection data otherwise</returns> public Intersection Intersect(Ray3 ray) { float Epsilon = 1e-5f; Vector3 e1, e2; //Edge1, Edge2 Vector3 P, Q, T; float det, inv_det, u, v; float t; //Find vectors for two edges sharing V1 e1 = V1.Position - V0.Position; e2 = V2.Position - V0.Position; //Begin calculating determinant - also used to calculate u parameter P = Vector3.Cross(ray.Direction, e2); //if determinant is near zero, ray lies in plane of triangle det = Vector3.Dot(e1, P); //NOT CULLING if(det > -Epsilon && det < Epsilon) return null; inv_det = 1f / det; //calculate distance from V1 to ray origin T = ray.Origin - V0.Position; //Calculate u parameter and test bound u = Vector3.Dot(T, P) * inv_det; //The intersection lies outside of the triangle if(u < 0f || u > 1f) return null; //Prepare to test v parameter Q = Vector3.Cross(T, e1); //Calculate V parameter and test bound v = Vector3.Dot(ray.Direction, Q) * inv_det; //The intersection lies outside of the triangle if(v < 0f || u + v > 1f) return null; t = Vector3.Dot(e2, Q) * inv_det; if(t > Epsilon) //ray intersection { Intersection I = new Intersection(); I.Distance = t; I.Position = ray.Origin + ray.Direction * t; I.Ray = ray; I.Target = this; return I; } // No hit, no win return null; }
public List<Intersection> Intersect(Ray3 ray) { List<Intersection> Intersections = new List<Intersection>(); float ScaledSize = (float)Size * MainWindow.Options.PixelScale.X / 2f; if (Depiction == PointDepiction.Mesh && DepictionMesh != null) { ScaledSize = DepictionMesh.BoundingBoxCorners[7].X; ScaledSize = Math.Max(ScaledSize, DepictionMesh.BoundingBoxCorners[7].Y); ScaledSize = Math.Max(ScaledSize, DepictionMesh.BoundingBoxCorners[7].Z); } Parallel.ForEach(Points, p => { float Distance = p.DistanceFromRay(ray); if (Distance <= ScaledSize) lock (Intersections) Intersections.Add(new Intersection { Position = p.Position, Distance = Distance, Ray = ray, Target = p }); }); return Intersections; }
private void Viewport_MouseWheel(Ray3 ray, System.Windows.Forms.MouseEventArgs e) { if (SurfaceMesh == null) return; List<Intersection> Intersections = new List<Intersection>(); Intersections.AddRange(SurfaceMesh.Intersect(ray)); foreach (var group in PointGroups) if (group.IsVisible) Intersections.AddRange(group.Intersect(ray)); if (Intersections.Count > 0) { Intersections.Sort((i1, i2) => i1.Distance.CompareTo(i2.Distance)); MouseWheel?.Invoke(this, Intersections, e); } }
void Viewport_MouseMove(Ray3 ray, System.Windows.Forms.MouseEventArgs e) { if (SurfaceMesh == null) return; List<Intersection> Intersections = new List<Intersection>(); Intersections.AddRange(SurfaceMesh.Intersect(ray)); foreach (var group in PointGroups) if (group.IsVisible) Intersections.AddRange(group.Intersect(ray)); if (Intersections.Count == 0 && IsMouseOver) { IsMouseOver = false; MouseLeave?.Invoke(this, e); } else if (Intersections.Count > 0) { Intersections.Sort((i1, i2) => i1.Distance.CompareTo(i2.Distance)); if (!IsMouseOver) { IsMouseOver = true; MouseEnter?.Invoke(this, Intersections, e); } MouseMove?.Invoke(this, Intersections, e); } }
private void Viewport_MouseClick(Ray3 ray, System.Windows.Forms.MouseEventArgs e) { if (SurfaceMesh == null) return; List<Intersection> Intersections = new List<Intersection>(); Intersections.AddRange(SurfaceMesh.Intersect(ray)); if (Intersections.Count > 0) { Intersections.Sort((i1, i2) => i1.Distance.CompareTo(i2.Distance)); MouseClick?.Invoke(this, Intersections, e); } }
public float DistanceFromRay(Ray3 ray) { Vector3 ToPoint = (Position - ray.Origin); float DotP = Vector3.Dot(ray.Direction.Normalized(), ToPoint); if (DotP <= 0) return float.PositiveInfinity; Vector3 Closest = ray.Origin + ray.Direction.Normalized() * DotP; return (Closest - Position).Length; }