///|
/// Raycast demo: casts rays from the origin in several directions and reports
/// the first hit against a small scene of shapes. Run with `moon run cmd/raycast`.
fn main {
// A box, a circle, and a triangle (polygon), arranged in a row.
let box = @mooncollider.Shape::from_aabb(
@mooncollider.AABB::from_min_max(
@mooncollider.Vec2::new(2.0, 0.0),
@mooncollider.Vec2::new(3.0, 1.0),
),
)
let circle = @mooncollider.Shape::from_circle(
@mooncollider.Circle::new(@mooncollider.Vec2::new(6.0, 0.5), 0.8),
)
let triangle = @mooncollider.Shape::from_polygon(
@mooncollider.Polygon::convex_hull([
@mooncollider.Vec2::new(9.0, 0.0),
@mooncollider.Vec2::new(10.0, 0.0),
@mooncollider.Vec2::new(9.5, 1.5),
]),
)
let shapes = [box, circle, triangle]
// Cast 5 rays from the origin at different upward angles.
let angles = [0.0, 0.1, 0.2, 0.3, 0.5]
println("MoonCollider raycast demo")
println("ray_angle, hit_shape, t, point_x, point_y, normal_x, normal_y")
for i = 0; i < angles.length(); i = i + 1 {
let a = angles[i]
let dir = @mooncollider.Vec2::new(@math.cos(a), @math.sin(a))
let ray = @mooncollider.Ray::new(@mooncollider.Vec2::zero(), dir)
let mut best_t = 1.0e30
let mut best_idx = -1
let mut best_hit = @mooncollider.RaycastHit::new(
-1.0,
@mooncollider.Vec2::zero(),
@mooncollider.Vec2::zero(),
)
for j = 0; j < shapes.length(); j = j + 1 {
let h = @mooncollider.raycast(ray, shapes[j])
if h.hit() && h.t < best_t {
best_t = h.t
best_idx = j
best_hit = h
}
}
if best_idx >= 0 {
let name = match best_idx {
0 => "box"
1 => "circle"
_ => "triangle"
}
println(
"\{a}, \{name}, \{best_hit.t}, \{best_hit.point.x}, \{best_hit.point.y}, \{best_hit.normal.x}, \{best_hit.normal.y}",
)
} else {
println("\{a}, miss, -, -, -, -, -")
}
}
println("done")
}