Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
DotWith committed Aug 18, 2024
2 parents 4b76df0 + e3a59f3 commit 6227164
Show file tree
Hide file tree
Showing 2 changed files with 178 additions and 33 deletions.
5 changes: 4 additions & 1 deletion bevy_rmesh/examples/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ fn setup(
// cube
commands.spawn(PbrBundle {
mesh: asset_server.load("cube.rmesh#Mesh0"),
material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()),
material: materials.add(StandardMaterial {
base_color: Color::rgb(0.8, 0.7, 0.6),
..default()
}),
transform: Transform::from_xyz(0.0, 0.5, 0.0),
..default()
});
Expand Down
206 changes: 174 additions & 32 deletions rmesh/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,180 @@ pub struct TriggerBox {
pub name: FixedLengthString,
}

impl ExtMesh for SimpleMesh {
fn bounding_box(&self) -> Bounds {
let mut min_x = f32::INFINITY;
let mut min_y = f32::INFINITY;
let mut min_z = f32::INFINITY;
let mut max_x = f32::NEG_INFINITY;
let mut max_y = f32::NEG_INFINITY;
let mut max_z = f32::NEG_INFINITY;

for vertex in &self.vertices {
let [x, y, z] = *vertex;

// Update min values
min_x = min_x.min(x);
min_y = min_y.min(y);
min_z = min_z.min(z);

// Update max values
max_x = max_x.max(x);
max_y = max_y.max(y);
max_z = max_z.max(z);
}

let min_point = [min_x, min_y, min_z];
let max_point = [max_x, max_y, max_z];
Bounds::new(min_point, max_point)
}

fn calculate_normals(&self) -> Vec<[f32; 3]> {
// Initialize vertex normals with zero vectors
let mut vertex_normals = vec![[0.0, 0.0, 0.0]; self.vertices.len()];

// Calculate face normals and accumulate them to vertex normals
for triangle in &self.triangles {
let vertex0 = self.vertices[triangle[0] as usize];
let vertex1 = self.vertices[triangle[1] as usize];
let vertex2 = self.vertices[triangle[2] as usize];

let edge1 = [
vertex1[0] - vertex0[0],
vertex1[1] - vertex0[1],
vertex1[2] - vertex0[2],
];
let edge2 = [
vertex2[0] - vertex0[0],
vertex2[1] - vertex0[1],
vertex2[2] - vertex0[2],
];

let normal = [
edge1[1] * edge2[2] - edge1[2] * edge2[1],
edge1[2] * edge2[0] - edge1[0] * edge2[2],
edge1[0] * edge2[1] - edge1[1] * edge2[0],
];

// Accumulate face normal to the vertices of the triangle
for i in 0..3 {
let vertex_index = triangle[i] as usize;
vertex_normals[vertex_index][0] += normal[0];
vertex_normals[vertex_index][1] += normal[1];
vertex_normals[vertex_index][2] += normal[2];
}
}

// Normalize vertex normals
for normal in &mut vertex_normals {
let length = (normal[0].powi(2) + normal[1].powi(2) + normal[2].powi(2)).sqrt();
if length != 0.0 {
normal[0] /= length;
normal[1] /= length;
normal[2] /= length;
}
}

vertex_normals
}
}

impl ExtMesh for ComplexMesh {
fn bounding_box(&self) -> Bounds {
let mut min_x = f32::INFINITY;
let mut min_y = f32::INFINITY;
let mut min_z = f32::INFINITY;
let mut max_x = f32::NEG_INFINITY;
let mut max_y = f32::NEG_INFINITY;
let mut max_z = f32::NEG_INFINITY;

for vertex in &self.vertices {
let [x, y, z] = vertex.position;

// Update min values
min_x = min_x.min(x);
min_y = min_y.min(y);
min_z = min_z.min(z);

// Update max values
max_x = max_x.max(x);
max_y = max_y.max(y);
max_z = max_z.max(z);
}

let min_point = [min_x, min_y, min_z];
let max_point = [max_x, max_y, max_z];
Bounds::new(min_point, max_point)
}

fn calculate_normals(&self) -> Vec<[f32; 3]> {
// Initialize vertex normals with zero vectors
let mut vertex_normals = vec![[0.0, 0.0, 0.0]; self.vertices.len()];

// Calculate face normals and accumulate them to vertex normals
for triangle in &self.triangles {
let vertex0 = self.vertices[triangle[0] as usize].position;
let vertex1 = self.vertices[triangle[1] as usize].position;
let vertex2 = self.vertices[triangle[2] as usize].position;

let edge1 = [
vertex1[0] - vertex0[0],
vertex1[1] - vertex0[1],
vertex1[2] - vertex0[2],
];
let edge2 = [
vertex2[0] - vertex0[0],
vertex2[1] - vertex0[1],
vertex2[2] - vertex0[2],
];

let normal = [
edge1[1] * edge2[2] - edge1[2] * edge2[1],
edge1[2] * edge2[0] - edge1[0] * edge2[2],
edge1[0] * edge2[1] - edge1[1] * edge2[0],
];

// Accumulate face normal to the vertices of the triangle
for i in 0..3 {
let vertex_index = triangle[i] as usize;
vertex_normals[vertex_index][0] += normal[0];
vertex_normals[vertex_index][1] += normal[1];
vertex_normals[vertex_index][2] += normal[2];
}
}

// Normalize vertex normals
for normal in &mut vertex_normals {
let length = (normal[0].powi(2) + normal[1].powi(2) + normal[2].powi(2)).sqrt();
if length != 0.0 {
normal[0] /= length;
normal[1] /= length;
normal[2] /= length;
}
}

vertex_normals
}
}

pub trait ExtMesh {
/// Used for aabb calc
fn bounding_box(&self) -> Bounds;
/// Calculate normals for the vertices based on the triangle faces.
fn calculate_normals(&self) -> Vec<[f32; 3]>;
}

pub struct Bounds {
pub min: [f32; 3],
pub max: [f32; 3],
}

impl Bounds {
pub fn new(min: [f32; 3], max: [f32; 3]) -> Self {
Self { min, max }
}
}

#[binrw]
#[derive(Debug)]
pub struct EntityData {
Expand Down Expand Up @@ -173,35 +347,3 @@ pub fn write_rmesh(header: &Header) -> Result<Vec<u8>, RMeshError> {

Ok(bytes)
}

/// Used for aabb calc
pub fn calculate_bounds(vertices: &Vec<Vertex>) -> Option<([f32; 3], [f32; 3])> {
if vertices.is_empty() {
return None;
}

let mut min_x = f32::INFINITY;
let mut min_y = f32::INFINITY;
let mut min_z = f32::INFINITY;
let mut max_x = f32::NEG_INFINITY;
let mut max_y = f32::NEG_INFINITY;
let mut max_z = f32::NEG_INFINITY;

for vertex in vertices {
let [x, y, z] = vertex.position;

// Update min values
min_x = min_x.min(x);
min_y = min_y.min(y);
min_z = min_z.min(z);

// Update max values
max_x = max_x.max(x);
max_y = max_y.max(y);
max_z = max_z.max(z);
}

let min_point = [min_x, min_y, min_z];
let max_point = [max_x, max_y, max_z];
Some((min_point, max_point))
}

0 comments on commit 6227164

Please sign in to comment.