2D game physics and collision detection library for MoonBit
moon add uiwcvb/mooncollider///|
fn main {
let world = @mooncollider.World::new()
// A dynamic circle (the ball).
let _ = world.add_body(
@mooncollider.BodyDef::dynamic(
@mooncollider.Vec2::new(0.0, 10.0),
@mooncollider.Shape::from_circle(
@mooncollider.Circle::new(@mooncollider.Vec2::zero(), 0.5),
),
1.0, // mass
0.8, // restitution (bounciness)
),
)
// A static floor.
let _ = world.add_body(
@mooncollider.BodyDef::static_(
@mooncollider.Vec2::new(0.0, 0.0),
@mooncollider.Shape::from_aabb(
@mooncollider.AABB::from_min_max(
@mooncollider.Vec2::new(-10.0, -1.0),
@mooncollider.Vec2::new(10.0, 0.0),
),
),
),
)
// Step the simulation.
for i = 0; i < 200; i = i + 1 {
world.step(0.016)
}
}let a = @mooncollider.Shape::from_aabb(
@mooncollider.AABB::from_min_max(
@mooncollider.Vec2::new(0.0, 0.0),
@mooncollider.Vec2::new(2.0, 2.0),
),
)
let b = @mooncollider.Shape::from_circle(
@mooncollider.Circle::new(@mooncollider.Vec2::new(3.0, 1.0), 1.5),
)
let m = @mooncollider.collide(a, b)
if m.colliding() {
// m.normal points from a to b; m.depth is the penetration.
}let ray = @mooncollider.Ray::from_to(
@mooncollider.Vec2::new(-5.0, 0.0),
@mooncollider.Vec2::new(5.0, 0.0),
)
let hit = @mooncollider.raycast(
ray,
@mooncollider.Shape::from_circle(
@mooncollider.Circle::new(@mooncollider.Vec2::zero(), 1.0),
),
)
if hit.hit() {
// hit.point, hit.normal, hit.t
}let grid = @mooncollider.GridHash::new(2.0)
grid.insert(0, aabb_a)
grid.insert(1, aabb_b)
let pairs = grid.pairs() // Array[(Int, Int)], each (a, b) with a < bmoon run cmd/main # bouncing ball under gravity
moon run cmd/stacking # column of boxes settling into a stack
moon run cmd/raycast # rays cast at a scene of shapes
moon run cmd/pendulum # distance-joint pendulum
moon run cmd/ccd_stress # CCD tunneling comparison
moon run cmd/perf # performance benchmarks
moon run examples/pairs # batch collision queries without a worldmoon testmoon check
moon test
moon info && git diff --exit-codemoon fmt && git diff --exit-codemooncollider/
moon.mod / moon.pkg module + package config
vec2.mbt 2D vector math
shape.mbt AABB, Circle, Polygon, Shape
narrowphase.mbt collision detection + Manifold
gjk.mbt GJK + EPA generic convex collision
raycast.mbt ray vs shape
broadphase.mbt GridHash + QuadTree
broadphase_sap.mbt SweepAndPrune + AABBTree
body.mbt RigidBody + BodyDef
world.mbt World::step + collision resolution
joints.mbt Distance / Revolute / Weld joints
ccd.mbt continuous collision detection
mooncollider_test.mbt blackbox tests (public API)
mooncollider_wbtest.mbt whitebox tests (internal helpers)
mooncollider_fuzz_wbtest.mbt adversarial fuzz testing
cmd/main/ bounce demo
cmd/stacking/ stacking demo
cmd/raycast/ raycast demo
cmd/pendulum/ pendulum demo
cmd/ccd_stress/ CCD tunneling comparison
cmd/perf/ performance benchmarks
cmd/web/ JS bindings for the website sandbox
examples/pairs/ batch collision query example
docs/ website + design notespub enum BodyType {
Static
Dynamic
}fn DistanceJoint::from_world(world : World, a : Int, b : Int, world_anchor_a : Vec2, world_anchor_b : Vec2, length? : Double) -> DistanceJointpub(all) struct RigidBody {
id : Int
body_type : BodyType
position : Vec2
angle : Double
velocity : Vec2
angular_velocity : Double
force : Vec2
torque : Double
mass : Double
inv_mass : Double
inertia : Double
inv_inertia : Double
restitution : Double
friction : Double
linear_damping : Double
angular_damping : Double
shape : Shape
aabb : AABB
gravity_scale : Double
alive : Bool
}pub(all) struct TreeNode {
box : AABB
parent : Int
left : Int
right : Int
body_id : Int
height : Int
}2D game physics and collision detection library for MoonBit