use bevy::prelude::*; use bevy_mod_raycast::prelude::*; use bevy_normal_material::material::NormalMaterial; use curvo::prelude::NurbsCurve3D; use nalgebra::Point3; use crate::{spawn_interp_curve, AppState, InterpolateCurve, LineMaterial}; pub fn enter_interpolate_curve(mut commands: Commands) { commands.spawn((InterpolateCurve::default(),)); } pub fn update_interpolate_curve( mut next_state: ResMut>, _commands: Commands, mouse_button_input: Res>, key_button_input: Res>, mut curve: Query<&mut InterpolateCurve>, cursor_ray: Res, _raycast: Raycast, mut gizmos: Gizmos, ) { if let Some(cursor_ray) = **cursor_ray { if let Some(d) = cursor_ray.intersect_plane(Vec3::ZERO, Plane3d::default()) { let p = cursor_ray.get_point(d); gizmos.circle(p, Direction3d::Y, 0.1, Color::WHITE); if mouse_button_input.just_pressed(MouseButton::Left) { let mut c = curve.single_mut(); c.points.push(p); } } } if let Ok(c) = curve.get_single() { gizmos.linestrip(c.points.clone(), Color::WHITE); let n = c.points.len(); if n >= 3 { let points: Vec<_> = c.points.iter().map(|p| Point3::from(*p)).collect(); let interpolated = NurbsCurve3D::try_interpolate(&points, (n - 1).min(3), None, None).unwrap(); let tess = interpolated.tessellate(None); gizmos.linestrip(tess.iter().map(|p| Vec3::from(*p)), Color::GRAY); } } if key_button_input.just_pressed(KeyCode::Enter) || key_button_input.just_pressed(KeyCode::Space) || key_button_input.just_pressed(KeyCode::Escape) { next_state.set(AppState::Idle); } } pub fn exit_interpolate_curve( mut commands: Commands, curve: Query<(Entity, &InterpolateCurve)>, mut meshes: ResMut>, mut line_materials: ResMut>, _normal_materials: ResMut<'_, Assets>, ) { curve.iter().for_each(|(e, c)| { commands.entity(e).despawn(); let points: Vec<_> = c.points.iter().map(|p| Point3::from(*p)).collect(); if points.len() > 3 { let degree = (points.len() - 1).min(3); spawn_interp_curve( &mut commands, &mut meshes, &mut line_materials, Color::ALICE_BLUE, &points, degree, ); } }); }