Skip to content

Commit

Permalink
Expose barycentric coord and triangle index (#103)
Browse files Browse the repository at this point in the history
  • Loading branch information
ottah authored Feb 18, 2024
1 parent 586ac48 commit e850210
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 5 deletions.
27 changes: 26 additions & 1 deletion src/primitives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ pub enum Primitive3d {
pub struct IntersectionData {
position: Vec3,
normal: Vec3,
barycentric_coord: Vec3,
distance: f32,
triangle: Option<Triangle>,
triangle_index: Option<usize>,
}

impl From<rays::PrimitiveIntersection> for IntersectionData {
Expand All @@ -22,18 +24,29 @@ impl From<rays::PrimitiveIntersection> for IntersectionData {
position: data.position(),
normal: data.normal(),
distance: data.distance(),
barycentric_coord: Vec3::ZERO,
triangle: None,
triangle_index: None,
}
}
}

impl IntersectionData {
pub fn new(position: Vec3, normal: Vec3, distance: f32, triangle: Option<Triangle>) -> Self {
pub fn new(
position: Vec3,
normal: Vec3,
barycentric: Vec3,
distance: f32,
triangle: Option<Triangle>,
triangle_index: Option<usize>,
) -> Self {
Self {
position,
normal,
barycentric_coord: barycentric,
distance,
triangle,
triangle_index,
}
}

Expand All @@ -49,6 +62,12 @@ impl IntersectionData {
self.normal
}

/// Get the intersection data's barycentric coord.
#[must_use]
pub fn barycentric_coord(&self) -> Vec3 {
self.barycentric_coord
}

/// Get the intersection data's distance.
#[must_use]
pub fn distance(&self) -> f32 {
Expand All @@ -60,6 +79,12 @@ impl IntersectionData {
pub fn triangle(&self) -> Option<Triangle> {
self.triangle
}

/// Get the intersection data's triangle index.
#[must_use]
pub fn triangle_index(&self) -> Option<usize> {
self.triangle_index
}
}

/// Encapsulates Ray3D, preventing use of struct literal syntax. This allows us to guarantee that
Expand Down
17 changes: 13 additions & 4 deletions src/raycast.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::f32::EPSILON;

use bevy_math::{Mat4, Vec3A};
use bevy_math::{Mat4, Vec3, Vec3A};
use bevy_render::{
mesh::{Indices, Mesh, VertexAttributeValues},
render_resource::PrimitiveTopology,
Expand Down Expand Up @@ -117,6 +117,7 @@ pub fn ray_mesh_intersection(
// positions for each triangle, so we'll take indices in chunks of three, where each
// chunk of three indices are references to the three vertices of a triangle.
for index in indices.chunks(3) {
let triangle_index = Some(index[0].into_usize());
let tri_vertex_positions = [
Vec3A::from(vertex_positions[index[0].into_usize()]),
Vec3A::from(vertex_positions[index[1].into_usize()]),
Expand All @@ -140,6 +141,7 @@ pub fn ray_mesh_intersection(
pick_intersection = Some(IntersectionData::new(
mesh_transform.transform_point3(i.position()),
mesh_transform.transform_vector3(i.normal()),
i.barycentric_coord(),
mesh_transform
.transform_vector3(mesh_space_ray.direction() * i.distance())
.length(),
Expand All @@ -150,12 +152,14 @@ pub fn ray_mesh_intersection(
mesh_transform.transform_point3a(tri.v2),
])
}),
triangle_index,
));
min_pick_distance = i.distance();
}
}
} else {
for i in (0..vertex_positions.len()).step_by(3) {
let triangle_index = Some(i);
let tri_vertex_positions = [
Vec3A::from(vertex_positions[i]),
Vec3A::from(vertex_positions[i + 1]),
Expand All @@ -179,6 +183,7 @@ pub fn ray_mesh_intersection(
pick_intersection = Some(IntersectionData::new(
mesh_transform.transform_point3(i.position()),
mesh_transform.transform_vector3(i.normal()),
i.barycentric_coord(),
mesh_transform
.transform_vector3(mesh_space_ray.direction() * i.distance())
.length(),
Expand All @@ -189,6 +194,7 @@ pub fn ray_mesh_intersection(
mesh_transform.transform_point3a(tri.v2),
])
}),
triangle_index,
));
min_pick_distance = i.distance();
}
Expand All @@ -213,10 +219,11 @@ fn triangle_intersection(
let distance = *ray_hit.distance();
if distance > 0.0 && distance < max_distance {
let position = ray.position(distance);
let u = ray_hit.uv_coords().0;
let v = ray_hit.uv_coords().1;
let w = 1.0 - u - v;
let barycentric = Vec3::new(u, v, w);
let normal = if let Some(normals) = tri_normals {
let u = ray_hit.uv_coords().0;
let v = ray_hit.uv_coords().1;
let w = 1.0 - u - v;
normals[1] * u + normals[2] * v + normals[0] * w
} else {
(tri_vertices.v1() - tri_vertices.v0())
Expand All @@ -226,8 +233,10 @@ fn triangle_intersection(
let intersection = IntersectionData::new(
position,
normal.into(),
barycentric,
distance,
Some(tri_vertices.to_triangle()),
None,
);
return Some(intersection);
}
Expand Down

0 comments on commit e850210

Please sign in to comment.