use anyhow::Result; use nalgebra::{Isometry3, Vector3}; use rubullet::*; use std::time::Duration; fn get_ray_from_to( camera_info: DebugVisualizerCameraInfo, mouse_x: f32, mouse_y: f32, ) -> (Vector3, Vector3) { println!("{:?}", camera_info); let cam_pos: Vector3 = camera_info.target - camera_info.dist * camera_info.camera_forward; let far_plane = 10000.; let ray_forward: Vector3 = camera_info.target - cam_pos; let inv_len = far_plane / ray_forward.norm(); let ray_forward = ray_forward * inv_len; let ray_from = cam_pos; let one_over_width = 1. / camera_info.width as f32; let one_over_height = 1. / camera_info.height as f32; let d_hor = camera_info.horizontal * one_over_width; let d_ver = camera_info.vertical * one_over_height; let ray_to_center = ray_from + ray_forward; let ray_to: Vector3 = ray_to_center - 0.5 * camera_info.horizontal + 0.5 * camera_info.vertical + Vector3::new(mouse_x, mouse_x, mouse_x).component_mul(&d_hor) - Vector3::new(mouse_y, mouse_y, mouse_y).component_mul(&d_ver); ( Vector3::new(ray_from.x as f64, ray_from.y as f64, ray_from.z as f64), Vector3::new(ray_to.x as f64, ray_to.y as f64, ray_to.z as f64), ) } fn main() -> Result<()> { let mut physics_client = PhysicsClient::connect(Mode::Gui)?; physics_client.set_additional_search_path("../rubullet-sys/bullet3/libbullet3/data")?; physics_client.configure_debug_visualizer(DebugVisualizerFlag::CovEnableGui, false); physics_client.set_physics_engine_parameter(SetPhysicsEngineParameterOptions { num_solver_iterations: Some(10), ..Default::default() }); physics_client.set_time_step(Duration::from_secs_f64(1. / 120.)); let log_id = physics_client.start_state_logging( LoggingType::ProfileTimings, "visualShapeBench.json", None, )?; let plane = physics_client.load_urdf( "plane_transparent.urdf", UrdfOptions { use_maximal_coordinates: Some(true), ..Default::default() }, )?; physics_client.configure_debug_visualizer(DebugVisualizerFlag::CovEnableRendering, false); physics_client.configure_debug_visualizer(DebugVisualizerFlag::CovEnablePlanarReflection, true); physics_client.configure_debug_visualizer(DebugVisualizerFlag::CovEnableGui, false); physics_client.configure_debug_visualizer(DebugVisualizerFlag::CovEnableTinyRenderer, false); let shift = Isometry3::translation(0., -0.02, 0.); let mesh_scale = Vector3::new(0.1, 0.1, 0.1); let visual_shape_id = physics_client.create_visual_shape( GeometricVisualShape::MeshFile { filename: "duck.obj".into(), mesh_scaling: Some(mesh_scale), }, VisualShapeOptions { frame_offset: shift, rgba_colors: [1.; 4], specular_colors: [0.4, 0.4, 0.], flags: None, }, )?; let collision_shape_id = physics_client.create_collision_shape( GeometricCollisionShape::MeshFile { filename: "duck_vhacd.obj".into(), mesh_scaling: Some(mesh_scale), flags: None, }, shift, )?; let range_x = 3; let range_y = 3; for i in 0..range_x { for j in 0..range_y { physics_client.create_multi_body( collision_shape_id, visual_shape_id, MultiBodyOptions { base_mass: 1., base_pose: Isometry3::translation( ((-range_x as f64 / 2.) + i as f64) * mesh_scale.x * 2., ((-range_y as f64 / 2.) + j as f64) * mesh_scale.y * 2., 1., ), use_maximal_coordinates: true, ..Default::default() }, )?; } } physics_client.configure_debug_visualizer(DebugVisualizerFlag::CovEnableRendering, true); physics_client.stop_state_logging(log_id); physics_client.set_gravity([0., 0., -10.]); physics_client.set_real_time_simulation(true); let colors = [ [1., 0., 0., 1.], [0., 1., 0., 1.], [0., 0., 1., 1.], [1., 1., 1., 1.], ]; let mut current_color = 0; loop { let mouse_events = physics_client.get_mouse_events(); for event in mouse_events { match event { MouseEvent::Move { .. } => {} MouseEvent::Button { mouse_pos_x, mouse_pos_y, button_index, button_state, } => { if button_state.was_triggered() && button_index == 0 { let (ray_from, ray_to) = get_ray_from_to( physics_client.get_debug_visualizer_camera(), mouse_pos_x, mouse_pos_y, ); let ray_info = physics_client.ray_test(ray_from, ray_to, None)?; if let Some(ray) = ray_info { if ray.body_id != plane { physics_client.change_visual_shape( ray.body_id, ray.link_index, ChangeVisualShapeOptions { rgba_color: Some(colors[current_color]), ..Default::default() }, )?; current_color = (current_color + 1) % colors.len() } } } } } } } }