#[cfg(test)]
mod test {
#[cfg(feature = "dim2")]
use na;
#[cfg(feature = "dim2")]
use na::{Vector1, Vector2, Isometry2};
#[cfg(feature = "dim2")]
use ncollide::shape::Cuboid;
#[cfg(feature = "dim2")]
use crate::object::{ActivationState, RigidBody};
#[cfg(feature = "dim2")]
use crate::world::World;
#[cfg(feature = "dim2")]
#[test]
fn gravity2() {
let mut world = World::new();
let geom = Cuboid::new(Vector2::new(1.0, 1.0));
let rb = RigidBody::new_dynamic(geom, 1.0, 0.3, 0.6);
let rb_handle = world.add_rigid_body(rb.clone());
let expected = &Isometry2::new(na::zero(), na::zero());
assert!(na::approx_eq(rb_handle.borrow().position(), expected),
format!("Initial position should be at zero. Actual: {:?}, Expected: {:?}",
rb_handle.borrow().position(), expected));
let gravity = Vector2::new(0.0, 20.0);
world.set_gravity(gravity);
let expected = &Isometry2::new(Vector2::new(0.0, 20.0), na::zero());
world.step(1.0);
assert!(na::approx_eq(rb_handle.borrow().position(), expected),
format!("Gravity did not pull object correctly (large time step). Actual: {:?}, Expected: {:?}",
rb_handle.borrow().position(), expected));
rb_handle.borrow_mut().set_lin_vel(Vector2::new(0.0, 0.0));
rb_handle.borrow_mut().set_transformation(Isometry2::new(na::zero(), na::zero()));
let expected = &Isometry2::new(Vector2::new(0.0, 10.01), na::zero());
for _ in 0 .. 1000 {
world.step(0.001);
}
assert!(na::approx_eq_eps(rb_handle.borrow().position(), expected, &0.01),
format!("Gravity did not pull object correctly (small time steps). Actual: {:?}, Expected: {:?}",
rb_handle.borrow().position(), expected));
rb_handle.borrow_mut().set_lin_vel(Vector2::new(0.0, 20.0));
rb_handle.borrow_mut().set_transformation(Isometry2::new(na::zero(), na::zero()));
let expected = &Isometry2::new(Vector2::new(0.0, 20.0), na::zero());
world.set_gravity(na::zero());
for _ in 0 .. 1000 {
world.step(0.001);
}
assert!(na::approx_eq_eps(rb_handle.borrow().position(), expected, &0.001),
format!("Gravity did not correctly switch off (global). Actual: {:?}, Expected: {:?}",
rb_handle.borrow().position(), expected));
rb_handle.borrow_mut().set_lin_vel(Vector2::new(0.0, 0.0));
rb_handle.borrow_mut().set_transformation(Isometry2::new(na::zero(), na::zero()));
for _ in 0 .. 1000 {
world.step(0.001);
}
assert!(*rb_handle.borrow().activation_state() == ActivationState::Inactive,
format!("Body should be inactive by now, but is {:?}", rb_handle.borrow().activation_state()));
rb_handle.borrow_mut().activate(1.0);
assert!(*rb_handle.borrow().activation_state() != ActivationState::Inactive,
format!("Body should be active by now, but is {:?}", rb_handle.borrow().activation_state()));
let expected = &Isometry2::new(Vector2::new(0.0, 10.0), na::zero());
world.set_gravity(Vector2::new(0.0, 20.0));
for _ in 0 .. 1000 {
world.step(0.001);
}
world.set_gravity(Vector2::new(0.0, -20.0));
for _ in 0 .. 2000 {
world.step(0.001);
}
assert!(na::approx_eq_eps(rb_handle.borrow().position(), expected, &0.02),
format!("Gravity did not change correctly. Actual: {:?}, Expected: {:?}",
rb_handle.borrow().position(), expected));
}
#[cfg(feature = "dim2")]
#[test]
fn forces2() {
let mut world = World::new();
let geom = Cuboid::new(Vector2::new(1.0, 1.0));
let rb = RigidBody::new_dynamic(geom.clone(), 1.0, 0.3, 0.6);
let rb_handle = world.add_rigid_body(rb.clone());
let mut rb2 = RigidBody::new_dynamic(geom.clone(), 2.0, 0.3, 0.6);
rb2.append_translation(&Vector2::new(5.0, 0.0));
let rb_handle2 = world.add_rigid_body(rb2);
world.set_gravity(Vector2::new(0.0, 0.0));
rb_handle.borrow_mut().append_lin_force(Vector2::new(0.0, 10.0));
rb_handle2.borrow_mut().append_lin_force(Vector2::new(0.0, 10.0));
rb_handle.borrow_mut().set_deactivation_threshold(None);
rb_handle2.borrow_mut().set_deactivation_threshold(None);
for _ in 0 .. 2000 {
world.step(0.001);
}
let expected = &Isometry2::new(Vector2::new(0.0, 5.0), na::zero());
assert!(na::approx_eq_eps(rb_handle.borrow().position(), expected, &0.01),
format!("Force did not properly pull first body. Actual: {:?}, Expected: {:?}",
rb_handle.borrow().position(), expected));
let expected = &Isometry2::new(Vector2::new(5.0, 2.5), na::zero());
assert!(na::approx_eq_eps(rb_handle2.borrow().position(), expected, &0.01),
format!("Force did not properly pull second body. Actual: {:?}, Expected: {:?}",
rb_handle2.borrow().position(), expected));
rb_handle.borrow_mut().set_transformation(Isometry2::new(na::zero(), na::zero()));
rb_handle.borrow_mut().set_lin_vel(Vector2::new(0.0, 0.0));
rb_handle2.borrow_mut().deactivate();
rb_handle.borrow_mut().clear_linear_force();
for _ in 0 .. 1000 {
world.step(0.001);
}
let expected = &Isometry2::new(Vector2::new(0.0, 0.0), na::zero());
assert!(na::approx_eq_eps(rb_handle.borrow().position(), expected, &0.01),
format!("Force should have been cleared. Actual: {:?}, Expected: {:?}",
rb_handle.borrow().position(), expected));
rb_handle.borrow_mut().append_lin_force(Vector2::new(0.0, 5.0));
rb_handle.borrow_mut().append_lin_force(Vector2::new(-10.0, 5.0));
for _ in 0 .. 2000 {
world.step(0.001);
}
let expected = &Isometry2::new(Vector2::new(-5.0, 5.0), na::zero());
assert!(na::approx_eq_eps(rb_handle.borrow().position(), expected, &0.01),
format!("Forces did not properly add up. Actual: {:?}, Expected: {:?}",
rb_handle.borrow().position(), expected));
rb_handle.borrow_mut().set_transformation(Isometry2::new(na::zero(), na::zero()));
rb_handle.borrow_mut().set_lin_vel(Vector2::new(0.0, 0.0));
rb_handle.borrow_mut().clear_forces();
rb_handle2.borrow_mut().set_transformation(Isometry2::new(Vector2::new(5.0, 0.0), na::zero()));
rb_handle2.borrow_mut().set_lin_vel(Vector2::new(0.0, 0.0));
rb_handle2.borrow_mut().activate(1.0);
rb_handle2.borrow_mut().clear_forces();
rb_handle.borrow_mut().append_ang_force(Vector1::new(10.0));
rb_handle2.borrow_mut().append_ang_force(Vector1::new(10.0));
for _ in 0 .. 1000 {
world.step(0.001);
}
let expected = &Isometry2::new(na::zero(), Vector1::new(1.875));
assert!(na::approx_eq_eps(rb_handle.borrow().position(), expected, &0.01),
format!("Rotation did not properly work. Actual: {:?}, Expected: {:?}",
rb_handle.borrow().position(), expected));
let expected = &Isometry2::new(Vector2::new(5.0, 0.0), Vector1::new(0.9375));
assert!(na::approx_eq_eps(rb_handle2.borrow().position(), expected, &0.01),
format!("Rotation2 did not properly work. Actual: {:?}, Expected: {:?}",
rb_handle2.borrow().position(), expected));
rb_handle.borrow_mut().set_transformation(Isometry2::new(na::zero(), na::zero()));
rb_handle.borrow_mut().set_ang_vel(Vector1::new(0.0));
rb_handle2.borrow_mut().set_transformation(Isometry2::new(Vector2::new(5.0, 0.0), na::zero()));
rb_handle2.borrow_mut().set_ang_vel(Vector1::new(0.0));
rb_handle.borrow_mut().clear_angular_force();
rb_handle2.borrow_mut().clear_angular_force();
for _ in 0 .. 1000 {
world.step(0.001);
}
let expected = &Isometry2::new(na::zero(), Vector1::new(0.0));
assert!(na::approx_eq_eps(rb_handle.borrow().position(), expected, &0.01),
format!("Rotation did not properly stop. Actual: {:?}, Expected: {:?}",
rb_handle.borrow().position(), expected));
let expected = &Isometry2::new(Vector2::new(5.0, 0.0), Vector1::new(0.0));
assert!(na::approx_eq_eps(rb_handle2.borrow().position(), expected, &0.01),
format!("Rotation2 did not properly stop. Actual: {:?}, Expected: {:?}",
rb_handle2.borrow().position(), expected));
rb_handle.borrow_mut().set_transformation(Isometry2::new(na::zero(), na::zero()));
rb_handle.borrow_mut().set_ang_vel(Vector1::new(0.0));
rb_handle.borrow_mut().clear_angular_force();
rb_handle2.borrow_mut().deactivate();
rb_handle.borrow_mut().append_ang_force(Vector1::new(10.0));
rb_handle.borrow_mut().append_ang_force(Vector1::new(-20.0));
for _ in 0 .. 1000 {
world.step(0.001);
}
let expected = &Isometry2::new(na::zero(), Vector1::new(-1.875));
assert!(na::approx_eq_eps(rb_handle.borrow().position(), expected, &0.01),
format!("Combined forces rotation did not properly work. Actual: {:?}, Expected: {:?}",
rb_handle.borrow().position(), expected));
rb_handle.borrow_mut().set_transformation(Isometry2::new(na::zero(), na::zero()));
rb_handle.borrow_mut().set_ang_vel(Vector1::new(0.0));
rb_handle.borrow_mut().clear_angular_force();
rb_handle.borrow_mut().append_lin_force(Vector2::new(0.0, 10.0));
rb_handle.borrow_mut().append_ang_force(Vector1::new(10.0));
rb_handle.borrow_mut().clear_forces();
for _ in 0 .. 1000 {
world.step(0.001);
}
let expected = &Isometry2::new(na::zero(), na::zero());
assert!(na::approx_eq_eps(rb_handle.borrow().position(), expected, &0.01),
format!("Cleared forces shouldn't work anymore. Actual: {:?}, Expected: {:?}",
rb_handle.borrow().position(), expected));
rb_handle.borrow_mut().set_transformation(Isometry2::new(na::zero(), na::zero()));
rb_handle.borrow_mut().set_ang_vel(Vector1::new(0.0));
rb_handle.borrow_mut().clear_angular_force();
rb_handle.borrow_mut().append_lin_force(Vector2::new(0.0, 10.0));
rb_handle.borrow_mut().append_ang_force(Vector1::new(10.0));
rb_handle.borrow_mut().clear_angular_force();
for _ in 0 .. 2000 {
world.step(0.001);
}
let expected = &Isometry2::new(Vector2::new(0.0, 5.0), na::zero());
assert!(na::approx_eq_eps(rb_handle.borrow().position(), expected, &0.01),
format!("Only linear movement is expected. Actual: {:?}, Expected: {:?}",
rb_handle.borrow().position(), expected));
rb_handle.borrow_mut().set_transformation(Isometry2::new(na::zero(), na::zero()));
rb_handle.borrow_mut().set_lin_vel(na::zero());
rb_handle.borrow_mut().set_ang_vel(na::zero());
rb_handle.borrow_mut().clear_forces();
rb_handle.borrow_mut().append_lin_force(Vector2::new(0.0, 10.0));
rb_handle.borrow_mut().append_ang_force(Vector1::new(10.0));
rb_handle.borrow_mut().clear_linear_force();
for _ in 0 .. 1000 {
world.step(0.001);
}
let expected = &Isometry2::new(na::zero(), Vector1::new(1.875));
assert!(na::approx_eq_eps(rb_handle.borrow().position(), expected, &0.01),
format!("Only rotation is expected. Actual: {:?}, Expected: {:?}",
rb_handle.borrow().position(), expected));
rb_handle.borrow_mut().set_transformation(Isometry2::new(na::zero(), na::zero()));
rb_handle.borrow_mut().set_lin_vel(na::zero());
rb_handle.borrow_mut().set_ang_vel(na::zero());
rb_handle.borrow_mut().clear_forces();
rb_handle.borrow_mut().activate(1.0);
rb_handle2.borrow_mut().set_transformation(Isometry2::new(Vector2::new(5.0, 0.0), na::zero()));
rb_handle2.borrow_mut().set_lin_vel(na::zero());
rb_handle2.borrow_mut().set_ang_vel(na::zero());
rb_handle2.borrow_mut().clear_forces();
rb_handle2.borrow_mut().activate(1.0);
rb_handle.borrow_mut().append_force_wrt_point(Vector2::new(0.0, 10.0), Vector2::new(1.0, 1.0));
rb_handle2.borrow_mut().append_force_wrt_point(Vector2::new(0.0, 10.0), Vector2::new(1.0, 1.0));
for _ in 0 .. 1000 {
world.step(0.001);
}
let expected = &Isometry2::new(Vector2::new(0.0, 1.25), Vector1::new(1.875));
assert!(na::approx_eq_eps(rb_handle.borrow().position(), expected, &0.01),
format!("Only rotation is expected on body 1. Actual: {:?}, Expected: {:?}",
rb_handle.borrow().position(), expected));
let expected = &Isometry2::new(Vector2::new(5.0, 0.625), Vector1::new(0.9375));
assert!(na::approx_eq_eps(rb_handle2.borrow().position(), expected, &0.01),
format!("Only rotation is expected on body 2. Actual: {:?}, Expected: {:?}",
rb_handle2.borrow().position(), expected));
}
#[cfg(feature = "dim2")]
#[test]
fn impulse2() {
let mut world = World::new();
let geom = Cuboid::new(Vector2::new(1.0, 1.0));
let rb = RigidBody::new_dynamic(geom.clone(), 1.0, 0.3, 0.6);
let rb_handle = world.add_rigid_body(rb.clone());
let mut rb2 = RigidBody::new_dynamic(geom.clone(), 2.0, 0.3, 0.6);
rb2.append_translation(&Vector2::new(5.0, 0.0));
let rb_handle2 = world.add_rigid_body(rb2);
world.set_gravity(Vector2::new(0.0, 0.0));
rb_handle.borrow_mut().apply_central_impulse(Vector2::new(0.0, 10.0));
rb_handle2.borrow_mut().apply_central_impulse(Vector2::new(0.0, 10.0));
for _ in 0 .. 1000 {
world.step(0.001);
}
let expected = &Isometry2::new(Vector2::new(0.0, 2.5), na::zero());
assert!(na::approx_eq_eps(rb_handle.borrow().position(), expected, &0.01),
format!("Different impulse result is expected on body 1. Actual: {:?}, Expected: {:?}",
rb_handle.borrow().position(), expected));
let expected = &Isometry2::new(Vector2::new(5.0, 1.25), na::zero());
assert!(na::approx_eq_eps(rb_handle2.borrow().position(), expected, &0.01),
format!("Different impulse result is expected on body 2. Actual: {:?}, Expected: {:?}",
rb_handle2.borrow().position(), expected));
rb_handle.borrow_mut().set_transformation(Isometry2::new(na::zero(), na::zero()));
rb_handle.borrow_mut().set_lin_vel(na::zero());
rb_handle.borrow_mut().set_ang_vel(na::zero());
rb_handle.borrow_mut().clear_forces();
rb_handle.borrow_mut().activate(1.0);
rb_handle2.borrow_mut().set_transformation(Isometry2::new(Vector2::new(5.0, 0.0), na::zero()));
rb_handle2.borrow_mut().set_lin_vel(na::zero());
rb_handle2.borrow_mut().set_ang_vel(na::zero());
rb_handle2.borrow_mut().clear_forces();
rb_handle2.borrow_mut().activate(1.0);
rb_handle.borrow_mut().apply_angular_momentum(Vector1::new(10.0));
rb_handle2.borrow_mut().apply_angular_momentum(Vector1::new(10.0));
for _ in 0 .. 1000 {
world.step(0.001);
}
let expected = &Isometry2::new(Vector2::new(0.0, 0.0), Vector1::new(3.75));
assert!(na::approx_eq_eps(rb_handle.borrow().position(), expected, &0.01),
format!("Different torque result is expected on body 1. Actual: {:?}, Expected: {:?}",
rb_handle.borrow().position(), expected));
let expected = &Isometry2::new(Vector2::new(5.0, 0.0), Vector1::new(1.875));
assert!(na::approx_eq_eps(rb_handle2.borrow().position(), expected, &0.01),
format!("Different torque result is expected on body 2. Actual: {:?}, Expected: {:?}",
rb_handle2.borrow().position(), expected));
rb_handle.borrow_mut().set_transformation(Isometry2::new(na::zero(), na::zero()));
rb_handle.borrow_mut().set_lin_vel(na::zero());
rb_handle.borrow_mut().set_ang_vel(na::zero());
rb_handle.borrow_mut().clear_forces();
rb_handle.borrow_mut().activate(1.0);
rb_handle2.borrow_mut().set_transformation(Isometry2::new(Vector2::new(5.0, 0.0), na::zero()));
rb_handle2.borrow_mut().set_lin_vel(na::zero());
rb_handle2.borrow_mut().set_ang_vel(na::zero());
rb_handle2.borrow_mut().clear_forces();
rb_handle2.borrow_mut().activate(1.0);
rb_handle.borrow_mut().apply_impulse_wrt_point(Vector2::new(0.0, 10.0), Vector2::new(1.0, 1.0));
rb_handle2.borrow_mut().apply_impulse_wrt_point(Vector2::new(0.0, 10.0), Vector2::new(1.0, 1.0));
for _ in 0 .. 1000 {
world.step(0.001);
}
let expected = &Isometry2::new(Vector2::new(0.0, 2.5), Vector1::new(3.75));
assert!(na::approx_eq_eps(rb_handle.borrow().position(), expected, &0.01),
format!("Different torque result is expected on body 1. Actual: {:?}, Expected: {:?}",
rb_handle.borrow().position(), expected));
let expected = &Isometry2::new(Vector2::new(5.0, 1.25), Vector1::new(1.875));
assert!(na::approx_eq_eps(rb_handle2.borrow().position(), expected, &0.01),
format!("Different torque result is expected on body 2. Actual: {:?}, Expected: {:?}",
rb_handle2.borrow().position(), expected));
}
}