rubullet 0.1.0-alpha-3

Rust interface to the Bullet Physics SDK simmilar to PyBullet
Documentation
//! An introduction to the usage of RuBullet.
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));
    }
}