use anyhow::Result;
use nalgebra::{Isometry3, Vector3};
use rand::prelude::*;
use rubullet::DebugVisualizerFlag::CovEnableRendering;
use rubullet::*;
use std::time::Duration;
fn main() -> Result<()> {
let mut physics_client = PhysicsClient::connect(Mode::Gui)?;
physics_client.configure_debug_visualizer(CovEnableRendering, false);
let height_pertubation_range = 0.05;
let mut rng = thread_rng();
let num_heightfield_rows = 256;
let num_heightfield_columns = 256;
let mut heightfield_data = vec![0_f32; num_heightfield_rows * num_heightfield_columns];
for j in 0..num_heightfield_columns / 2 {
for i in 0..num_heightfield_rows / 2 {
let height: f32 = rng.gen_range((0.)..height_pertubation_range);
heightfield_data[2 * i + 2 * j * num_heightfield_rows] = height;
heightfield_data[2 * i + 1 + 2 * j * num_heightfield_rows] = height;
heightfield_data[2 * i + (2 * j + 1) * num_heightfield_rows] = height;
heightfield_data[2 * i + 1 + (2 * j + 1) * num_heightfield_rows] = height;
}
}
let terrain_shape = physics_client.create_collision_shape(
GeometricCollisionShape::Heightfield {
mesh_scaling: Some(Vector3::new(0.05, 0.05, 1.)),
texture_scaling: (num_heightfield_rows - 1) as f64 / 2.,
data: heightfield_data,
num_rows: num_heightfield_rows,
num_columns: num_heightfield_columns,
replace_heightfield: None,
},
None,
)?;
let terrain = physics_client.create_multi_body(terrain_shape, VisualId::NONE, None)?;
physics_client.change_visual_shape(
terrain,
None,
ChangeVisualShapeOptions {
rgba_color: Some([1.; 4]),
..Default::default()
},
)?;
let sphere_radius = 0.05;
let col_sphere_id = physics_client.create_collision_shape(
GeometricCollisionShape::Sphere {
radius: sphere_radius,
},
None,
)?;
let col_box_id = physics_client.create_collision_shape(
GeometricCollisionShape::Box {
half_extents: Vector3::from_element(sphere_radius),
},
None,
)?;
let mass = 1.;
let visual_shape_id = VisualId::NONE;
for i in 0..3 {
for j in 0..3 {
for k in 0..3 {
let base_pose = Isometry3::translation(
i as f64 * 5. * sphere_radius,
j as f64 * 5. * sphere_radius,
1. + k as f64 * 5. * sphere_radius + 1.,
);
let sphere_uid = {
if k & 2 != 0 {
physics_client.create_multi_body(
col_sphere_id,
visual_shape_id,
MultiBodyOptions {
base_mass: mass,
base_pose,
..Default::default()
},
)?
} else {
let link_masses = vec![1.];
let link_collision_shapes = vec![col_box_id];
let link_visual_shapes = vec![VisualId::NONE];
let link_poses = vec![Isometry3::translation(0., 0., 0.11)];
let link_inertial_frame_poses = vec![Isometry3::translation(0., 0., 0.)];
let indices = vec![0];
let joint_types = vec![JointType::Revolute];
let axis = vec![Vector3::new(0., 0., 1.)];
physics_client.create_multi_body(
col_box_id,
visual_shape_id,
MultiBodyOptions {
base_mass: mass,
base_pose,
link_masses,
link_collision_shapes,
link_visual_shapes,
link_poses,
link_inertial_frame_poses,
link_parent_indices: indices,
link_joint_types: joint_types,
link_joint_axis: axis,
..Default::default()
},
)?
}
};
for joint in 0..physics_client.get_num_joints(sphere_uid) {
physics_client.set_joint_motor_control(
sphere_uid,
joint,
ControlCommand::Velocity(1.),
Some(10.),
);
}
}
}
}
physics_client.configure_debug_visualizer(CovEnableRendering, true);
physics_client.set_gravity(Vector3::new(0.0, 0.0, -10.0));
physics_client.set_real_time_simulation(true);
loop {
std::thread::sleep(Duration::from_secs_f64(0.01));
}
}