linear-sim 0.7.0

Minimal linear 3D simulation library
Documentation
#![warn(unused_extern_crates)]

use linear_sim::*;
use geometry::shape;

macro_rules! show {
  ($e:expr) => { println!("{}: {:?}", stringify!($e), $e); }
}

#[expect(unused_macros)]
macro_rules! pretty {
  ($e:expr) => { println!("{}: {:#?}", stringify!($e), $e); }
}

const OBJECT_KEY_STATIC_MYBLOCK   : object::Key = object::Key::from_raw (0);
const OBJECT_KEY_DYNAMIC_MYSPHERE : object::Key = object::Key::from_raw (0);

fn main() {
  println!("linear-sim example...");

  // print some diagnostics
  shape::report_sizes();
  object::report_sizes();
  system::report_sizes();

  // test proximity query
  let a = object::Static {
    position:   component::Position ([0.0, 0.0, 0.0].into()),
    bound:      component::Bound::from (shape::Capsule::noisy (2.0, 3.0)),
    material:   component::MATERIAL_STONE,
    collidable: true
  };
  let b = object::Static {
    position:   component::Position ([0.0, 0.0, 0.0].into()),
    bound:      component::Bound::from (shape::Capsule::noisy (1.0, 2.0)),
    material:   component::MATERIAL_STONE,
    collidable: true
  };
  show!(a);
  show!(b);
  let proximity = collision::Proximity::query (&a, &b);
  show!(proximity);

  // test resolve inter-penetration (intersection)
  let (resolved_a, resolved_b) = constraint::Penetration { object_a: &a, object_b: &b }
    .resolve_position().unwrap();
  show!(resolved_a);
  show!(resolved_b);
  let proximity = collision::Proximity::query (&resolved_a, &resolved_b);
  show!(proximity);

  // create system with semi-implicit euler integrator
  let mut system = System::<integrator::SemiImplicitEuler>::default();

  // create static object: axis-aligned block (cuboid)
  let myblock = {
    let position   = component::Position ([0.0, 4.0, 3.0].into());
    let bound      = component::Bound::from (shape::Cuboid::noisy ([2.0, 3.5, 0.2]));
    let material   = component::MATERIAL_STONE;
    let collidable = true;
    object::Static { position, bound, material, collidable }.into()
  };
  let result = system.handle_event (event::Input::CreateObject (
    myblock, Some (OBJECT_KEY_STATIC_MYBLOCK)
  ));
  assert_eq!(result.len(), 1);
  assert!(matches!(result[0], event::Output::CreateObjectResult (
    event::CreateObjectResult::Created (_)
  )));

  // create dynamic object: sphere
  let radius = 0.5;
  let mysphere = {
    let position    = component::Position ([0.0, 4.0, 5.0].into());
    let mass        = component::Mass::new (20.0);
    let derivatives = component::Derivatives::zero();
    let drag        = component::Drag::zero();
    let bound       = component::Bound::from (shape::Sphere::noisy (radius));
    let material    = component::MATERIAL_STONE;
    let collidable  = true;
    object::Dynamic {
      position, mass, derivatives, drag, bound, material, collidable
    }.into()
  };
  let result = system.handle_event (event::Input::CreateObject (
    mysphere, Some (OBJECT_KEY_DYNAMIC_MYSPHERE)
  ));
  assert_eq!(result.len(), 1);
  assert!(matches!(result[0], event::Output::CreateObjectResult (
    event::CreateObjectResult::Created (_)
  )));

  // create gravity force
  let gravity = {
    let acceleration = [0.0, 0.0, -0.04].into();
    force::Gravity { acceleration }
  };
  assert!(system.handle_event (event::Input::SetGravity (gravity)).is_empty());

  // print initialized system
  //pretty!(system);

  // take step
  assert!(system.handle_event (event::Input::Step).is_empty());

  println!("...linear-sim example");
}