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