use bevy::{ color::palettes::css::{RED, WHITE}, prelude::*, }; use bevy_verlet::prelude::*; fn main() { App::new() .add_plugins(DefaultPlugins.set(WindowPlugin { primary_window: Some(Window { title: "3D line".to_string(), resolution: (1000., 800.).into(), ..default() }), ..default() })) .add_plugins(VerletPlugin::default()) .add_systems(Startup, (setup_camera, setup_free_line, setup_fixed_line)) .insert_resource(VerletConfig { sticks_computation_depth: 5, ..Default::default() }) .run(); } fn setup_camera(mut commands: Commands) { commands.spawn(Camera3dBundle { transform: Transform::from_xyz(-30., 4., -80.).looking_at(Vec3::ZERO, Vec3::Y), ..Default::default() }); } fn setup_free_line( mut commands: Commands, mut materials: ResMut>, mut meshes: ResMut>, ) { let material = materials.add(Color::from(WHITE)); let fixed_material = materials.add(Color::from(RED)); let mesh = meshes.add(Cuboid::new(1., 1., 1.)); let stick_length: f32 = 2.; let points_count = 10; let mut previous_entity = None; for i in 0..=points_count { let mut cmd = commands.spawn(( pbr_bundle( material.clone(), mesh.clone(), Vec3::new((i * 2) as f32, 20., 0.), ), VerletPoint::default(), Name::new(format!("Point {}", i)), )); if previous_entity.is_none() { cmd.insert((VerletLocked, fixed_material.clone())); } let entity = cmd.id(); if let Some(e) = previous_entity { commands.spawn(( VerletStick { point_a_entity: e, point_b_entity: entity, length: stick_length, }, Name::new(format!("Stick {}", i)), )); } previous_entity = Some(entity); } } fn setup_fixed_line( mut commands: Commands, mut materials: ResMut>, mut meshes: ResMut>, ) { let material = materials.add(Color::from(WHITE)); let fixed_material = materials.add(Color::from(RED)); let mesh = meshes.add(Cuboid::new(1., 1., 1.)); let stick_length: f32 = 2.; let points_count = 20; let start_pos = -10.; let mut previous_entity = None; for i in 0..=points_count { let mut cmd = commands.spawn(( pbr_bundle( material.clone(), mesh.clone(), Vec3::new(start_pos + (i * 2) as f32, 0., 0.), ), VerletPoint::default(), Name::new(format!("Point {}", i)), )); if previous_entity.is_none() || i == points_count { cmd.insert((VerletLocked, fixed_material.clone())); } let entity = cmd.id(); if let Some(e) = previous_entity { commands.spawn(( VerletStick { point_a_entity: e, point_b_entity: entity, length: stick_length, }, Name::new(format!("Stick {}", i)), )); } previous_entity = Some(entity); } } fn pbr_bundle(material: Handle, mesh: Handle, pos: Vec3) -> PbrBundle { PbrBundle { mesh, material, transform: Transform::from_translation(pos), ..Default::default() } }