mun_runtime 0.3.0

A runtime for hot reloading and invoking Mun from Rust
Documentation
extern fn log_f32(value: f32);

struct SimContext {
    sphere: Sphere,
    water: Water,
    gravity: f32,
}

struct Sphere {
    radius: f32,
    mass: f32,      // density: f32,
    height: f32,
    velocity: f32,
}

struct Water {
    density: f32,
}

pub fn new_sim() -> SimContext {
    SimContext {
        sphere: new_sphere(),
        water: new_water(),
        gravity: 9.81,
    }
}

fn new_sphere() -> Sphere {
    let radius = 1.0;
    let density = 250.0;

    let volume = calc_sphere_volume(radius);
    let mass = density * volume;

    Sphere {
        radius,
        mass,
        height: 1.0,
        velocity: 0.0,
    }
}

fn new_water() -> Water {
    Water {
        density: 1000.0,
    }
}

fn calc_submerged_ratio(s: Sphere) -> f32 {
    let bottom = s.height - s.radius;
    let diameter = 2.0 * s.radius;
    if bottom >= 0.0 {
        0.0
    } else if bottom <= -diameter {
        1.0
    } else {
        -bottom / diameter
    }
}

fn calc_sphere_volume(radius: f32) -> f32 {
    let pi = 3.1415926535897;
    let r = radius;

    3.0/4.0 * pi * r * r * r
}

fn calc_buoyancy_force(s: Sphere, w: Water, gravity: f32, submerged_ratio: f32) -> f32 {
    let volume = calc_sphere_volume(s.radius);
    volume * submerged_ratio * w.density * gravity
}

pub fn sim_update(ctx: SimContext, elapsed_secs: f32) {
    let submerged_ratio = calc_submerged_ratio(ctx.sphere);
    if submerged_ratio > 0.0 {
        let buoyancy_force = calc_buoyancy_force(
            ctx.sphere,
            ctx.water,
            ctx.gravity,
            submerged_ratio
        );
        let buoyancy_acc = buoyancy_force / ctx.sphere.mass;
        ctx.sphere.velocity += buoyancy_acc * elapsed_secs;
    }

    ctx.sphere.velocity -= ctx.gravity * elapsed_secs;

    ctx.sphere.height += ctx.sphere.velocity * elapsed_secs;

    log_f32(ctx.sphere.height);
}