parent
78222ad55a
commit
85b79a86ed
Binary file not shown.
@ -0,0 +1,60 @@
|
||||
use bevy::prelude::{Component, Reflect, Resource};
|
||||
use fj_core::objects::{Sketch, Solid};
|
||||
use fj_math::{Point, Vector};
|
||||
use fj_interop::mesh::Mesh as FjMesh;
|
||||
use fj_core::storage::Handle as FjHandle;
|
||||
|
||||
#[derive(Component)]
|
||||
struct FjSolidWrapper {
|
||||
handle: fj_core::storage::Handle<Solid>,
|
||||
}
|
||||
|
||||
#[derive(Component, Debug)]
|
||||
pub struct FjMeshWrapper {
|
||||
pub mesh: FjMesh<Point<3>>,
|
||||
pub handle: FjHandle<Solid>,
|
||||
pub sketch: Sketch,
|
||||
}
|
||||
|
||||
pub(crate) trait ToPoint3 {
|
||||
fn to_point3(&self) -> Point<3>;
|
||||
}
|
||||
|
||||
|
||||
impl ToPoint3 for bevy::prelude::Vec3 {
|
||||
fn to_point3(&self) -> fj_math::Point<3> {
|
||||
fj_math::Point { coords: Vector { components: [fj_math::Scalar::from_u64(0),fj_math::Scalar::from_u64(0),fj_math::Scalar::from_u64(0)] } }
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) 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())
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) trait ToVec2 {
|
||||
fn to_vec2(&self) -> bevy::prelude::Vec2;
|
||||
}
|
||||
|
||||
impl crate::interop::ToVec2 for fj_math::Point<2> {
|
||||
fn to_vec2(&self) -> bevy::prelude::Vec2 {
|
||||
bevy::prelude::Vec2::new(self.u.into_f32(), self.v.into_f32())
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::interop::ToVec2 for fj_math::Vector<2> {
|
||||
fn to_vec2(&self) -> bevy::prelude::Vec2 {
|
||||
bevy::prelude::Vec2::new(self.u.into_f32(), self.v.into_f32())
|
||||
}
|
||||
}
|
@ -0,0 +1,162 @@
|
||||
use bevy::math::Vec3;
|
||||
use bevy::prelude::Mesh;
|
||||
use bevy::render::mesh::{Indices, PrimitiveTopology};
|
||||
use fj_math::Point;
|
||||
use fj_interop::mesh::Mesh as FjMesh;
|
||||
use fj_core::storage::Handle as FjHandle;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct LineList {
|
||||
pub lines: Vec<(Vec3, Vec3)>,
|
||||
}
|
||||
|
||||
impl From<LineList> for Mesh {
|
||||
fn from(line: LineList) -> Self {
|
||||
let vertices: Vec<_> = line.lines.into_iter().flat_map(|(a, b)| [a, b]).collect();
|
||||
|
||||
// This tells wgpu that the positions are list of lines
|
||||
// where every pair is a start and end point
|
||||
Mesh::new(PrimitiveTopology::LineList)
|
||||
// Add the vertices positions as an attribute
|
||||
.with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, vertices)
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_uv_mapping(fj_mesh: &FjMesh<Point<3>>) -> Vec<[f32; 2]> {
|
||||
let mut uvs = Vec::new();
|
||||
|
||||
for vertex in fj_mesh.vertices() {
|
||||
let x = vertex.coords.x.into_f32();
|
||||
let y = vertex.coords.y.into_f32();
|
||||
// Here we're using x and y coordinates as u and v
|
||||
uvs.push([x, y]);
|
||||
uvs.push([x, y]);
|
||||
uvs.push([x, y]);
|
||||
uvs.push([x, y]);
|
||||
uvs.push([x, y]);
|
||||
uvs.push([x, y]);
|
||||
}
|
||||
uvs
|
||||
}
|
||||
|
||||
fn generate_normals(fj_mesh: &FjMesh<Point<3>>) -> Vec<[f32; 3]> {
|
||||
let mut normals = Vec::new();
|
||||
for triangle in fj_mesh.triangles() {
|
||||
let normal = triangle.inner.normal();
|
||||
normals.push([normal.x.into_f32(), normal.y.into_f32(), normal.z.into_f32()]);
|
||||
normals.push([normal.x.into_f32(), normal.y.into_f32(), normal.z.into_f32()]);
|
||||
normals.push([normal.x.into_f32(), normal.y.into_f32(), normal.z.into_f32()]);
|
||||
}
|
||||
normals
|
||||
}
|
||||
|
||||
fn generate_positions(fj_mesh: &FjMesh<Point<3>>) -> Vec<[f32; 3]> {
|
||||
let mut positions = Vec::new();
|
||||
|
||||
// Iterate through each triangle
|
||||
for triangle in fj_mesh.triangles() {
|
||||
// For each vertex index in the triangle
|
||||
for vertex_index in triangle.inner.points() {
|
||||
positions.push([vertex_index.x.into_f32(), vertex_index.y.into_f32(), vertex_index.z.into_f32()]);
|
||||
}
|
||||
}
|
||||
|
||||
positions
|
||||
}
|
||||
|
||||
fn generate_indices(fj_mesh: &FjMesh<Point<3>>) -> Vec<u32> {
|
||||
let mut num_positions = 0;
|
||||
|
||||
// Count the total number of positions (3 per triangle)
|
||||
for triangle in fj_mesh.triangles() {
|
||||
num_positions += 3;
|
||||
}
|
||||
|
||||
// Generate the indices [0, 1, 2, ..., num_positions-1]
|
||||
(0..num_positions as u32).collect()
|
||||
}
|
||||
|
||||
// Need to take a solid, and return all the data needed to create a Bevy Mesh from scratch
|
||||
pub fn convert_mesh(fj_mesh: &FjMesh<Point<3>>) -> Mesh {
|
||||
let mut mesh = Mesh::new(PrimitiveTopology::TriangleList);
|
||||
mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, generate_positions(&fj_mesh));
|
||||
mesh.insert_attribute(Mesh::ATTRIBUTE_NORMAL, generate_normals(&fj_mesh));
|
||||
// mesh.insert_attribute(Mesh::ATTRIBUTE_UV_0, generate_uv_mapping(&fj_mesh));
|
||||
mesh.set_indices(Some(Indices::U32(generate_indices(&fj_mesh))));
|
||||
mesh
|
||||
}
|
||||
|
||||
pub fn create_rectangle_mesh(p1: Vec3, p2: Vec3, width: f32, height: f32) -> Mesh {
|
||||
// Calculate direction vector from p1 to p2
|
||||
let direction = (p2 - p1).normalize();
|
||||
// Create arbitrary up vector
|
||||
let up = Vec3::Y;
|
||||
// Right vector for the rectangle width
|
||||
let right = direction.cross(up).normalize() * width * 0.5;
|
||||
// Up vector for rectangle height, ensuring it's perpendicular
|
||||
let up_perpendicular = direction.cross(right).normalize() * height * 0.5;
|
||||
|
||||
let vertices = [
|
||||
p1 - right - up_perpendicular, // Bottom-left of p1 face
|
||||
p1 + right - up_perpendicular, // Bottom-right of p1 face
|
||||
p1 + right + up_perpendicular, // Top-right of p1 face
|
||||
p1 - right + up_perpendicular, // Top-left of p1 face
|
||||
p2 - right - up_perpendicular, // Bottom-left of p2 face
|
||||
p2 + right - up_perpendicular, // Bottom-right of p2 face
|
||||
p2 + right + up_perpendicular, // Top-right of p2 face
|
||||
p2 - right + up_perpendicular, // Top-left of p2 face
|
||||
];
|
||||
|
||||
// Calculate face normals
|
||||
let front_normal = (vertices[1] - vertices[0]).cross(vertices[3] - vertices[0]).normalize();
|
||||
let back_normal = (vertices[5] - vertices[4]).cross(vertices[7] - vertices[4]).normalize();
|
||||
let right_normal = (vertices[5] - vertices[1]).cross(vertices[2] - vertices[1]).normalize();
|
||||
let left_normal = (vertices[0] - vertices[4]).cross(vertices[7] - vertices[4]).normalize();
|
||||
let top_normal = (vertices[2] - vertices[3]).cross(vertices[7] - vertices[3]).normalize();
|
||||
let bottom_normal = (vertices[1] - vertices[0]).cross(vertices[4] - vertices[0]).normalize();
|
||||
|
||||
let normals = vec![
|
||||
bottom_normal, bottom_normal, top_normal, top_normal, // Bottom and top for first quad
|
||||
bottom_normal, bottom_normal, top_normal, top_normal, // Bottom and top for second quad
|
||||
front_normal, front_normal, front_normal, front_normal, // Front face normals
|
||||
back_normal, back_normal, back_normal, back_normal, // Back face normals
|
||||
right_normal, right_normal, right_normal, right_normal, // Right face normals
|
||||
left_normal, left_normal, left_normal, left_normal, // Left face normals
|
||||
];
|
||||
|
||||
|
||||
// Convert positions and normals to the format expected by Bevy
|
||||
|
||||
// Creating a mesh
|
||||
let mut mesh = Mesh::new(PrimitiveTopology::TriangleList);
|
||||
|
||||
// Insert positions
|
||||
let positions: Vec<[f32; 3]> = vertices.iter().map(|v| [v.x, v.y, v.z]).collect();
|
||||
mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, positions);
|
||||
|
||||
// Insert normals (optional here, assuming all outwards for simplicity)
|
||||
let normals: Vec<[f32; 3]> = normals.iter().map(|n| [n.x, n.y, n.z]).collect();
|
||||
mesh.insert_attribute(Mesh::ATTRIBUTE_NORMAL, normals);
|
||||
|
||||
// Define two triangles for each face of the rectangle mesh
|
||||
|
||||
let indices = Indices::U32(vec![
|
||||
// Front face
|
||||
0, 2, 1, 0, 3, 2,
|
||||
// Back face
|
||||
4, 6, 5, 4, 7, 6,
|
||||
// Top face
|
||||
2, 3, 6, 6, 3, 7,
|
||||
// Bottom face
|
||||
0, 1, 5, 0, 5, 4,
|
||||
// Right face
|
||||
1, 2, 6, 1, 6, 5,
|
||||
// Left face
|
||||
0, 4, 7, 0, 7, 3,
|
||||
]);
|
||||
|
||||
|
||||
mesh.set_indices(Some(indices));
|
||||
|
||||
mesh
|
||||
}
|
Loading…
Reference in new issue