public static TriangleHit?Raycast(Ray ray, int level, BoundsMap bounds, Func <Cell, float> heightAt, Transform gridTransform = null) { if (gridTransform != null) { ray = new Ray(gridTransform.InverseTransformPoint(ray.origin), gridTransform.InverseTransformDirection(ray.direction)); } var closest = (ray.origin - Vector3.Dot(ray.origin, ray.direction) * ray.direction).magnitude; var candidates = new List <Triangle>(Triangle.AtLevel(0)); for (int i = 0; i < level; i++) { var triangles = candidates; candidates = new List <Triangle>(); foreach (var triangle in triangles) { var max = bounds.GetMax(triangle, i); if (max < closest) { continue; } if (intersectsCell(ray, triangle, i, bounds.GetMin(triangle, i), max)) { candidates.AddRange(triangle.GetChildren(i + 1)); } } } return(candidates.Select(t => t.Raycast(ray, level, heightAt)).Where(h => h.HasValue).MinByOrDefault(t => t.Value.Distance)); }
public static Cell?Raycast(Ray ray, int level, BoundsMap bounds, Func <Cell, float> heightAt, Transform gridTransform = null) { var hit = Triangle.Raycast(ray, level, bounds, heightAt, gridTransform); if (!hit.HasValue) { return(null); } var barycentric = hit.Value.BarycentricCoordinate; var triangle = hit.Value.Triangle; if ((barycentric.x >= barycentric.y) && (barycentric.x >= barycentric.z)) { return(triangle.GetVertices(level).ElementAt(0)); } else if ((barycentric.y >= barycentric.x) && (barycentric.y >= barycentric.z)) { return(triangle.GetVertices(level).ElementAt(1)); } else { return(triangle.GetVertices(level).ElementAt(2)); } }