diff --git a/Cargo.toml b/Cargo.toml index 32e8a5f..50f3a52 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,3 +16,4 @@ fj-math = "0.47.0" fj-interop = "0.47.0" fj-core = "0.47.0" fj-export = "0.47.0" +rand = "0.8.5" diff --git a/src/lib.rs b/src/lib.rs index ef5549a..8864572 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,7 +6,7 @@ use bevy::ecs::query::Without; use bevy::ecs::system::ResMut; // Importing Bevy assets and rendering related components -use bevy::prelude::Mesh; +use bevy::prelude::{Mesh, shape}; use bevy::render::mesh::{Indices, PrimitiveTopology}; use bevy::asset::Assets; use bevy::pbr::{PbrBundle, StandardMaterial}; @@ -33,6 +33,25 @@ use fj_interop::mesh::Mesh as FjMesh; // Importing Fj-math and other standard functionalities use fj_math::{Aabb, Point, Scalar, Vector}; use std::ops::Deref; +use bevy::math::Vec3; +use fj_core::geometry::curve::GlobalPath; +use rand::Rng; + +trait ToVec3 { + fn to_vec3(&self) -> bevy::prelude::Vec3; +} + +impl ToVec3 for fj_math::Point<3> { + fn to_vec3(&self) -> bevy::prelude::Vec3 { + bevy::prelude::Vec3::new(self.x.into_f32(), self.y.into_f32(), self.z.into_f32()) + } +} + +impl ToVec3 for fj_math::Vector<3> { + fn to_vec3(&self) -> bevy::prelude::Vec3 { + bevy::prelude::Vec3::new(self.x.into_f32(), self.y.into_f32(), self.z.into_f32()) + } +} #[derive(Component)] struct FjSolidWrapper{ @@ -52,8 +71,7 @@ pub struct FjRenderPlugin; impl Plugin for FjRenderPlugin { fn build(&self, app: &mut App) { - app - .add_systems(Update, update_fj_model_system); + app.add_systems(Update, update_fj_model_system); } } @@ -72,7 +90,6 @@ fn generate_uv_mapping(fj_mesh: &FjMesh>) -> Vec<[f32; 2]> { uvs.push([x, y]); uvs.push([x, y]); } - uvs } @@ -142,9 +159,112 @@ fn update_fj_model_system( FjConvertedFlag )); + add_debug_info_to_entity(&mut commands, solid, &mut meshes, &mut materials); } } +fn add_debug_info_to_entity(mut commands: &mut Commands, + fj_model: &FjMeshWrapper, + mut meshes: &mut ResMut>, + mut materials: &mut ResMut> +) { + + for shell in fj_model.handle.shells() { + println!("{:?}. shell", shell); + for face in shell.faces() { + println!("{:?}. face", face); + let surface = face.surface(); + let geom = surface.geometry(); + let geom_sweep_vector = geom.v; + match geom.u { + GlobalPath::Circle(x) => { + x.aabb(); + } + GlobalPath::Line(x) => { + let origin = x.origin(); + let direction = x.direction(); + let opposite_corner = Vec3::new( + origin.x.into_f32() + direction.x.into_f32() + 0.01, + origin.y.into_f32() + direction.y.into_f32() + 0.01, + origin.z.into_f32() + direction.z.into_f32() + 0.01, + ); + let mut rng = rand::thread_rng(); + let red: f32 = rng.gen_range(0.0..1.0); + let green: f32 = rng.gen_range(0.0..1.0); + let blue: f32 = rng.gen_range(0.0..1.0); + commands.spawn(( // line on base of sweep + PbrBundle { + mesh: meshes.add(Mesh::from(shape::Box::from_corners(opposite_corner.into(), origin.to_vec3()))), + material: materials.add(Color::rgb(red, green, blue).into()), + transform: Transform::from_xyz(0.0, 0.0, 0.0), + ..default() + }, + // RaycastPickTarget::default(), // <- Needed for the raycast backend. + // PickableBundle::default() // <- This one too + )); + commands.spawn(( // line on top of sweep, just offset by the sweep vector + PbrBundle { + mesh: meshes.add(Mesh::from(shape::Box::from_corners(opposite_corner.into(), origin.to_vec3()))), + material: materials.add(Color::rgb(red, green, blue).into()), + transform: Transform::from_xyz(geom_sweep_vector.x.into_f32(), geom_sweep_vector.y.into_f32(), geom_sweep_vector.z.into_f32()), + ..default() + }, + // RaycastPickTarget::default(), // <- Needed for the raycast backend. + // PickableBundle::default() // <- This one too + )); + commands.spawn(( // line following the sweep + PbrBundle { + mesh: meshes.add(Mesh::from(shape::Box::from_corners(origin.to_vec3() + geom_sweep_vector.to_vec3(), origin.to_vec3() + 0.01))), + material: materials.add(Color::rgb(red, green, blue).into()), + transform: Transform::from_xyz(0.0, 0.0, 0.0), + ..default() + }, + // RaycastPickTarget::default(), // <- Needed for the raycast backend. + // PickableBundle::default() // <- This one too + )); + commands.spawn(( // vertex + PbrBundle { + mesh: meshes.add(Mesh::from(shape::Cube { size: 0.025 })), + material: materials.add(Color::rgb(1.0, 1.0, 1.0).into()), + transform: Transform::from_xyz(origin.to_xyz().x.into_f32(), origin.to_xyz().y.into_f32(), origin.to_xyz().z.into_f32()), + ..default() + }, + // RaycastPickTarget::default(), // <- Needed for the raycast backend. + // PickableBundle::default() // <- This one too + )); + commands.spawn(( // swept vertex + PbrBundle { + mesh: meshes.add(Mesh::from(shape::Cube { size: 0.025 })), + material: materials.add(Color::rgb(1.0, 1.0, 1.0).into()), + transform: Transform::from_xyz( + origin.to_xyz().x.into_f32() + geom_sweep_vector.to_vec3().x, + origin.to_xyz().y.into_f32() + geom_sweep_vector.to_vec3().y, + origin.to_xyz().z.into_f32() + geom_sweep_vector.to_vec3().z, + ), + // transform: Transform::from_scale(origin.to_vec3() + geom_sweep_vector.to_vec3()), + ..default() + }, + // RaycastPickTarget::default(), // <- Needed for the raycast backend. + // PickableBundle::default(), // <- This one too + // I want to insert a component when dragging starts, that contains + // data about the exact ray hit location. + // On::>::run(run), + // On::>::target_insert(DragCaster::default()), + // On::>::target_component_mut::(|drag, mut caster| { + // caster.hit_location = drag.hit.position.unwrap(); + // + // // (*transform).translation = transform.translation + Vec3::new(-drag.delta.x / 100.0, 0.0, drag.delta.y / 100.0); + // }), + // On::>::target_component_mut::(|drag, mut caster| { + // drag.distance + // // (*transform).translation = transform.translation + Vec3::new(-drag.delta.x / 100.0, 0.0, drag.delta.y / 100.0); + // }), + )); + } + } + } + } +}