| 675 | } |
| 676 | |
| 677 | fn intersect_triangle(ray: &Ray, tri: &Triangle, max_t: f32) -> Option<(f32, Vec2)> { |
| 678 | const EPS: f32 = 1.0e-6; |
| 679 | let edge1 = tri.v1 - tri.v0; |
| 680 | let edge2 = tri.v2 - tri.v0; |
| 681 | let h = ray.direction.cross(edge2); |
| 682 | let a = edge1.dot(h); |
| 683 | if a.abs() < EPS { |
| 684 | return None; |
| 685 | } |
| 686 | let f = 1.0 / a; |
| 687 | let s = ray.origin - tri.v0; |
| 688 | let u = f * s.dot(h); |
| 689 | if u < 0.0 || u > 1.0 { |
| 690 | return None; |
| 691 | } |
| 692 | let q = s.cross(edge1); |
| 693 | let v = f * ray.direction.dot(q); |
| 694 | if v < 0.0 || u + v > 1.0 { |
| 695 | return None; |
| 696 | } |
| 697 | let t = f * edge2.dot(q); |
| 698 | if t > EPS && t < max_t { |
| 699 | Some((t, Vec2::new(u, v))) |
| 700 | } else { |
| 701 | None |
| 702 | } |
| 703 | } |
| 704 | |
| 705 | /// Slab-based ray vs AABB. Returns `Some((t_near, t_far))` when the ray |
| 706 | /// intersects the box in front of the origin; used by the BVH walk to |