linear-sim 0.9.0

Minimal linear 3D simulation library
Documentation
use rand_xorshift::XorShiftRng;
use vec_map::VecMap;

use gl_utils::*;
use math_utils::*;

use crate::program;

const POSITION_MIN        : [f64; 3] = [-5.0, -5.0,  2.0];
const POSITION_MAX        : [f64; 3] = [ 5.0,  5.0, 10.0];

const OBB_HALF_EXTENT_MIN : f64      =     0.01;   // 1cm
const OBB_HALF_EXTENT_MAX : f64      =     4.0;    // 4m

static EXAMPLE_ID : std::sync::atomic::AtomicU64 =
  std::sync::atomic::AtomicU64::new (0);

////////////////////////////////////////////////////////////////////////////////////////
//  obb
////////////////////////////////////////////////////////////////////////////////////////

pub fn init_obb (
  render_context : &mut Render <render::resource::Default>,
  rng            : &mut XorShiftRng
) {
  use rand::SeedableRng;
  use render::resource::draw3d;
  program::reset_render_context (render_context);
  program::print_testbed_modes_prompt();
  // reset initial seeded rng state
  const HALF_GRID_DIMS : f32 = 0.5 * draw3d::MESH_GRID_DIMS as f32;
  render_context.camera3d_position_set ([0.0, -2.0*HALF_GRID_DIMS, 4.0].into());
  *rng = XorShiftRng::seed_from_u64 (0);
  EXAMPLE_ID.store (0, std::sync::atomic::Ordering::SeqCst);
  // generate initial obb data
  let obb_vertices = next_obb_vertices (rng);
  // generate default debug grid vertex data
  let grid_vertex_data = render::resource::Default::debug_grid_vertices();
  let meshes = {
    let mut v = VecMap::with_capacity (2);
    assert!(v.insert (draw3d::MeshId::Grid as usize, &grid_vertex_data[..]).is_none());
    assert!(v.insert (draw3d::MeshId::Cube as usize, &obb_vertices[..]).is_none());
    v
  };
  // set per-instance data
  render_context.resource.draw3d.instance_vertices_set (
    &render_context.glium_display,
    draw3d::InstancesInit {
      billboards: VecMap::default(), meshes, .. Default::default()
    }
  );
  println!("linear-sim bounding volume oriented bounding box test");
  println!("  press 'Tab' to generate test cases");
}

pub fn next_obb (
  render_context : &mut Render <render::resource::Default>,
  rng            : &mut XorShiftRng
) {
  let _example_n = EXAMPLE_ID.fetch_add (1, std::sync::atomic::Ordering::SeqCst);
  let obb_vertices = next_obb_vertices (rng);
  render_context.resource.draw3d.instance_vertices_mesh_write (
    render::resource::draw3d::MeshId::Cube as usize, &obb_vertices[..]);
}

pub fn draw_obb (
  render_context : &Render <render::resource::Default>,
  glium_frame    : &mut glium::Frame
) {
  // default 3D draw pass
  render::Resource::draw_3d (render_context, glium_frame);
}

fn next_obb_vertices (rng : &mut XorShiftRng)
  -> [vertex::Vert3dOrientationScaleColor; 2]
{
  use rand::RngExt;
  use std::f64::consts::PI;
  let obb = {
    let initial_aabb  = geometry::Aabb3::<f64>::with_minmax (
      POSITION_MIN.into(), POSITION_MAX.into()).unwrap();
    let center      = initial_aabb.rand_point (rng);
    let orientation = Angles3::wrap (
      rng.random_range (0.0..2.0 * PI).into(),
      rng.random_range (0.0..2.0 * PI).into(),
      rng.random_range (0.0..2.0 * PI).into());
    let mut gen_extent = ||
      Positive::noisy (rng.random_range (OBB_HALF_EXTENT_MIN..OBB_HALF_EXTENT_MAX));
    let extents = [gen_extent(), gen_extent(), gen_extent()].into();
    geometry::Obb3 { center, extents, orientation }
  };
  let computed = geometry::Obb3::containing_points_approx (obb.corners().as_slice())
    .unwrap();
  [ obb_to_vertex (&computed, color::CYAN),
    obb_to_vertex (&obb, color::MAGENTA)
  ]
}

fn obb_to_vertex (obb : &geometry::Obb3 <f64>, color : [u8; 4])
  -> vertex::Vert3dOrientationScaleColor
{
  vertex::Vert3dOrientationScaleColor {
    color: color::rgba_u8_to_rgba_f32 (color),
    .. util::obb_to_vertex (obb.numcast().unwrap())
  }
}