Fixed obb x ray oversight in test and failure in outputting normals accurately. refactoring. still need to fix ray x octtree
This commit is contained in:
parent
e0be55ddcc
commit
c316533fea
|
@ -1,7 +1,7 @@
|
|||
#![allow(dead_code)]
|
||||
|
||||
use bevy::{
|
||||
math::{Mat3, Quat, Vec3},
|
||||
math::{Mat3, Quat, Vec3, Vec3Swizzles},
|
||||
transform::{components::Transform, TransformPoint as _},
|
||||
};
|
||||
|
||||
|
@ -27,6 +27,20 @@ impl VectorPair {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct RayAABBIntersection {
|
||||
hitpoint: Vec3,
|
||||
normal: Vec3,
|
||||
}
|
||||
impl RayAABBIntersection {
|
||||
pub fn new(hitpoint: Vec3, normal: Vec3) -> RayAABBIntersection {
|
||||
RayAABBIntersection {
|
||||
hitpoint: hitpoint,
|
||||
normal: normal,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct OctTreeCollisionPoint {
|
||||
pos: VectorPair,
|
||||
|
@ -35,95 +49,9 @@ pub struct OctTreeCollisionPoint {
|
|||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct RayOctTreeIntersection {
|
||||
pub(crate) hitpoint_local: Vec3,
|
||||
pub(crate) hitpoint_global: Vec3,
|
||||
pub(crate) local_normal: Vec3,
|
||||
pub(crate) global_normal: Vec3,
|
||||
}
|
||||
|
||||
pub fn octtree_ray_overlap<T: Clone>(
|
||||
oct: &OctTree<T>,
|
||||
transform: &OBB,
|
||||
ray_origin: Vec3,
|
||||
ray_normal: Vec3,
|
||||
) -> Option<RayOctTreeIntersection> {
|
||||
let x = ray_octtree_visitor(
|
||||
&oct.root, transform, ray_origin, ray_normal, oct.center, oct.size,
|
||||
);
|
||||
if x.is_some() {
|
||||
let x = x.unwrap();
|
||||
let matrix = transform.as_transform().compute_matrix();
|
||||
let local_hitpoint = matrix.transform_point3(x.global);
|
||||
let global_normal = matrix.inverse().transform_vector3(x.local);
|
||||
let result = RayOctTreeIntersection {
|
||||
hitpoint_local: local_hitpoint,
|
||||
hitpoint_global: x.global,
|
||||
local_normal: x.local,
|
||||
global_normal,
|
||||
};
|
||||
return Some(result);
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
fn ray_octtree_visitor<T: Clone>(
|
||||
node: &TreeNode<T>,
|
||||
transform: &OBB,
|
||||
ray_origin: Vec3,
|
||||
ray_normal: Vec3,
|
||||
position: Vec3,
|
||||
size: usize,
|
||||
) -> Option<VectorPair> {
|
||||
if node.is_branch() {
|
||||
let children = node.branch_contents_reference();
|
||||
if children.is_none() {
|
||||
return None;
|
||||
}
|
||||
let children = children.unwrap();
|
||||
let mut elements: Vec<(Vec3, usize, &TreeNode<T>)> = Vec::new();
|
||||
for (index, element) in children.iter().enumerate() {
|
||||
if !element.is_empty() {
|
||||
let (sub_position, sub_size) = constants::sub_region(position, size, index as i32);
|
||||
elements.push((sub_position, sub_size, element));
|
||||
}
|
||||
}
|
||||
elements.sort_by(|f, s| {
|
||||
let first_transformed = transform
|
||||
.as_transform()
|
||||
.compute_matrix()
|
||||
.transform_point(f.0);
|
||||
let second_transformed = transform
|
||||
.as_transform()
|
||||
.compute_matrix()
|
||||
.transform_point(s.0);
|
||||
let fdist = first_transformed.distance(ray_origin);
|
||||
let sdist = second_transformed.distance(ray_origin);
|
||||
fdist.total_cmp(&sdist)
|
||||
});
|
||||
for element in elements {
|
||||
let x = ray_octtree_visitor(
|
||||
element.2, transform, ray_origin, ray_normal, element.0, element.1,
|
||||
);
|
||||
if x.is_some() {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
} else if node.is_leaf() {
|
||||
let mut node_bounds = transform.clone();
|
||||
let position = transform
|
||||
.as_transform()
|
||||
.compute_matrix()
|
||||
.transform_point(position);
|
||||
node_bounds.position = position;
|
||||
node_bounds.half_size = node_bounds.half_size * size as f32;
|
||||
|
||||
let x = ray_obb_intersection(ray_origin, ray_normal, &node_bounds);
|
||||
if x.is_some() {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
//v nothing could be found, failing out so other searches can continue
|
||||
None
|
||||
pub(crate) hit_data: RayOBBIntersection,
|
||||
pub(crate) path_to_hit: Path,
|
||||
pub(crate) voxel_index_location: Vec3,
|
||||
}
|
||||
|
||||
pub fn octtree_overlap<T: Clone>(
|
||||
|
@ -302,16 +230,6 @@ fn visitor_octtree_x_octtree<T: Clone>(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn collision_test<T: Clone>(
|
||||
_structure1: OctTree<T>,
|
||||
_context1: Transform,
|
||||
_structure2: OctTree<T>,
|
||||
_context2: Transform,
|
||||
) -> Option<Vec<Vec3>> {
|
||||
// TODO: actual function
|
||||
None
|
||||
}
|
||||
|
||||
pub fn aa_bounds_contains(center: Vec3, size: usize, subject: Vec3) -> bool {
|
||||
let fsize = size as f32;
|
||||
let min = center - Vec3::splat(fsize as f32 / 2.);
|
||||
|
@ -336,43 +254,59 @@ pub fn sphere_sphere_overlap(
|
|||
None
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct RayOBBIntersection {
|
||||
hitpoint: VectorPair,
|
||||
normal: VectorPair,
|
||||
}
|
||||
impl RayOBBIntersection {
|
||||
pub fn new(hitpoint: VectorPair, normal: VectorPair) -> RayOBBIntersection {
|
||||
RayOBBIntersection { hitpoint, normal }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ray_obb_intersection(
|
||||
ray_origin: Vec3,
|
||||
ray_direction_normalized: Vec3,
|
||||
bounds: &OBB,
|
||||
) -> Option<VectorPair> {
|
||||
) -> Option<RayOBBIntersection> {
|
||||
let transform: Transform = Transform::from_translation(bounds.position)
|
||||
.with_rotation(bounds.orientation)
|
||||
.with_scale(bounds.half_size * 2.);
|
||||
let matrix = transform.compute_matrix().inverse();
|
||||
let ro_trans: Vec3 = matrix.transform_point3(ray_origin);
|
||||
let rd_trans: Vec3 = matrix.transform_vector3(ray_direction_normalized); // normalizing?
|
||||
let rd_trans: Vec3 = matrix
|
||||
.transform_vector3(ray_direction_normalized)
|
||||
.normalize();
|
||||
let passthru =
|
||||
distance_to_ray_bounds_intersection(ro_trans, rd_trans, Vec3::ZERO, Vec3::splat(0.5));
|
||||
if passthru.is_some() {
|
||||
let hitpoint = ray_origin + (ray_direction_normalized * passthru.unwrap());
|
||||
let mut dist_array: [(Vec3, f32); 6] = Default::default();
|
||||
let mut min_dist: usize = 8;
|
||||
for (index, norm) in crate::vvlib::constants::cardinal_directions::ORDERED
|
||||
.iter()
|
||||
.enumerate()
|
||||
{
|
||||
let pos = norm.clone() * bounds.half_size * 2.;
|
||||
let pos = pos + bounds.position;
|
||||
let pos = matrix.transform_vector3(pos);
|
||||
let dist = pos.distance(hitpoint);
|
||||
dist_array[index] = (norm.clone(), dist);
|
||||
if index == 0 {
|
||||
min_dist = index;
|
||||
} else if dist_array[min_dist].1 > dist {
|
||||
min_dist = index;
|
||||
let pt = passthru.unwrap();
|
||||
let hitpoint = ray_origin + (ray_direction_normalized * pt.0 * (bounds.half_size * 2.)); // bounds.half_size scales back out of normalized unit-space
|
||||
let hitpoint_ro = ro_trans + (rd_trans * pt.0);
|
||||
let hit_vp = VectorPair::new(hitpoint, hitpoint_ro);
|
||||
/*
|
||||
let mut dist_array: [(Vec3, f32); 6] = Default::default();
|
||||
let mut min_dist: usize = 8;
|
||||
for (index, norm) in crate::vvlib::constants::cardinal_directions::ORDERED
|
||||
.iter()
|
||||
.enumerate()
|
||||
{
|
||||
let pos = norm.clone() * bounds.half_size * 2.;
|
||||
let pos = pos + bounds.position;
|
||||
let pos = matrix.transform_vector3(pos);
|
||||
let dist = pos.distance(hitpoint);
|
||||
dist_array[index] = (norm.clone(), dist);
|
||||
if index == 0 {
|
||||
min_dist = index;
|
||||
} else if dist_array[min_dist].1 < dist {
|
||||
min_dist = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
let normal = dist_array[min_dist].0;
|
||||
return Some(VectorPair {
|
||||
global: hitpoint,
|
||||
local: normal,
|
||||
});
|
||||
let normal = dist_array[min_dist].0;
|
||||
*/
|
||||
let normal_vp = VectorPair::new(matrix.transpose().transform_vector3(pt.1), pt.1);
|
||||
return Some(RayOBBIntersection::new(hit_vp, normal_vp));
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
|
@ -383,7 +317,7 @@ pub fn distance_to_ray_bounds_intersection(
|
|||
ray_direction_normalized: Vec3,
|
||||
bound_center: Vec3,
|
||||
bound_half_size: Vec3,
|
||||
) -> Option<f32> {
|
||||
) -> Option<(f32, Vec3)> {
|
||||
let bound_min: Vec3 = bound_center - bound_half_size;
|
||||
let bound_max: Vec3 = bound_center + bound_half_size;
|
||||
let tmin: Vec3 = (bound_min - ray_origin) / ray_direction_normalized;
|
||||
|
@ -396,30 +330,19 @@ pub fn distance_to_ray_bounds_intersection(
|
|||
if !(t0 <= t1 && t1 > 0.0) {
|
||||
return None;
|
||||
}
|
||||
return Some(t0);
|
||||
|
||||
let n =
|
||||
-ray_direction_normalized.signum() * step(sc.yzx(), sc.xyz()) * step(sc.zxy(), sc.xyz());
|
||||
let n = n.normalize();
|
||||
return Some((t0, n));
|
||||
}
|
||||
|
||||
pub fn ray_sphere_intersection(
|
||||
ray_origin: Vec3,
|
||||
ray_direction_normalized: Vec3,
|
||||
sphere_center: Vec3,
|
||||
sphere_radius: f32,
|
||||
) -> Option<Vec3> {
|
||||
let e = sphere_center - ray_origin;
|
||||
let rsq = sphere_radius * sphere_radius;
|
||||
let esq = e.length() * e.length();
|
||||
let a = e.dot(ray_direction_normalized);
|
||||
let bsq = esq - (a * a);
|
||||
let f = (((rsq) - bsq).abs()).sqrt();
|
||||
let mut t = a - f;
|
||||
|
||||
if rsq - (esq - a * a) < 0.0 {
|
||||
return None;
|
||||
} else if esq < rsq {
|
||||
t = a + f;
|
||||
pub fn step(l: Vec3, r: Vec3) -> Vec3 {
|
||||
let v = l.cmple(r);
|
||||
Vec3 {
|
||||
x: v.x as i32 as f32,
|
||||
y: v.y as i32 as f32,
|
||||
z: v.z as i32 as f32,
|
||||
}
|
||||
|
||||
return Some(ray_origin + (ray_direction_normalized * t));
|
||||
}
|
||||
|
||||
pub fn ray_aabb_intersection(
|
||||
|
@ -427,7 +350,7 @@ pub fn ray_aabb_intersection(
|
|||
ray_direction_normalized: Vec3,
|
||||
bound_center: Vec3,
|
||||
bound_half_size: Vec3,
|
||||
) -> Option<VectorPair> {
|
||||
) -> Option<RayAABBIntersection> {
|
||||
let passthru = distance_to_ray_bounds_intersection(
|
||||
ray_origin,
|
||||
ray_direction_normalized,
|
||||
|
@ -435,28 +358,27 @@ pub fn ray_aabb_intersection(
|
|||
bound_half_size,
|
||||
);
|
||||
if passthru.is_some() {
|
||||
let hitpoint = ray_origin + (ray_direction_normalized * passthru.unwrap());
|
||||
let mut dist_array: [(Vec3, f32); 6] = Default::default();
|
||||
let mut min_dist: usize = 8;
|
||||
for (index, norm) in crate::vvlib::constants::cardinal_directions::ORDERED
|
||||
.iter()
|
||||
.enumerate()
|
||||
{
|
||||
let pos = norm.clone() * bound_half_size * 2.;
|
||||
let pos = pos + bound_center;
|
||||
let dist = pos.distance(hitpoint);
|
||||
dist_array[index] = (norm.clone(), dist);
|
||||
if index == 0 {
|
||||
min_dist = index;
|
||||
} else if dist_array[min_dist].1 > dist {
|
||||
min_dist = index;
|
||||
}
|
||||
}
|
||||
let normal = dist_array[min_dist].0;
|
||||
return Some(VectorPair {
|
||||
global: hitpoint,
|
||||
local: normal,
|
||||
});
|
||||
let hitpoint = ray_origin + (ray_direction_normalized * passthru.unwrap().0);
|
||||
/*
|
||||
let mut dist_array: [(Vec3, f32); 6] = Default::default();
|
||||
let mut min_dist: usize = 8;
|
||||
for (index, norm) in crate::vvlib::constants::cardinal_directions::ORDERED
|
||||
.iter()
|
||||
.enumerate()
|
||||
{
|
||||
let pos = norm.clone() * bound_half_size * 2.;
|
||||
let pos = pos + bound_center;
|
||||
let dist = pos.distance(hitpoint);
|
||||
dist_array[index] = (norm.clone(), dist);
|
||||
if index == 0 {
|
||||
min_dist = index;
|
||||
} else if dist_array[min_dist].1 > dist {
|
||||
min_dist = index;
|
||||
}
|
||||
}
|
||||
let normal = dist_array[min_dist].0;
|
||||
*/
|
||||
return Some(RayAABBIntersection::new(hitpoint, passthru.unwrap().1));
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
|
@ -500,6 +422,29 @@ pub fn sphere_obb_intersection(
|
|||
None
|
||||
}
|
||||
|
||||
pub fn ray_sphere_intersection(
|
||||
ray_origin: Vec3,
|
||||
ray_direction_normalized: Vec3,
|
||||
sphere_center: Vec3,
|
||||
sphere_radius: f32,
|
||||
) -> Option<Vec3> {
|
||||
let e = sphere_center - ray_origin;
|
||||
let rsq = sphere_radius * sphere_radius;
|
||||
let esq = e.length() * e.length();
|
||||
let a = e.dot(ray_direction_normalized);
|
||||
let bsq = esq - (a * a);
|
||||
let f = (((rsq) - bsq).abs()).sqrt();
|
||||
let mut t = a - f;
|
||||
|
||||
if rsq - (esq - a * a) < 0.0 {
|
||||
return None;
|
||||
} else if esq < rsq {
|
||||
t = a + f;
|
||||
}
|
||||
|
||||
return Some(ray_origin + (ray_direction_normalized * t));
|
||||
}
|
||||
|
||||
pub fn obb_to_global_sphere(local_pos: Vec3, size: usize, trans: &OBB) -> (Vec3, f32) {
|
||||
//let local_pos = trans.orientation.mul_vec3(local_pos);
|
||||
let bound_radius = Vec3::splat(size as f32 / 2.).length() * trans.half_size.length();
|
||||
|
@ -557,29 +502,152 @@ fn get_seperating_plane_obb(r_pos: Vec3, plane: Vec3, first: &OBB, second: &OBB)
|
|||
+ (second.axis_z() * second.half_size.z).dot(plane).abs());
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_octtree() {
|
||||
let origin = Vec3::ZERO;
|
||||
let neighbor = Vec3::new(1., 1., 1.);
|
||||
let mut test_oct = OctTree::<i32>::new(origin, 1);
|
||||
test_oct.set_voxel_at_location(neighbor, 2);
|
||||
|
||||
let far_off_bullshit = Vec3::new(26., 26., 26.);
|
||||
test_oct.set_voxel_at_location(far_off_bullshit, 5);
|
||||
dbg!(&test_oct);
|
||||
assert_eq!(test_oct.voxel_at_location(neighbor).unwrap().0, 2);
|
||||
assert_eq!(test_oct.voxel_at_location(origin).unwrap().0, 1);
|
||||
assert_eq!(test_oct.voxel_at_location(far_off_bullshit).unwrap().0, 5);
|
||||
pub fn octtree_ray_overlap<T: Clone>(
|
||||
oct: &OctTree<T>,
|
||||
transform: &OBB,
|
||||
ray_origin: Vec3,
|
||||
ray_normal: Vec3,
|
||||
) -> Option<RayOctTreeIntersection> {
|
||||
let x = ray_octtree_visitor(
|
||||
&oct.root,
|
||||
transform,
|
||||
ray_origin,
|
||||
ray_normal,
|
||||
oct.center,
|
||||
oct.size,
|
||||
Default::default(),
|
||||
);
|
||||
if x.is_some() {
|
||||
let x = x.unwrap();
|
||||
let path = x.1;
|
||||
//let matrix = transform.as_transform().compute_matrix();
|
||||
let result = RayOctTreeIntersection {
|
||||
hit_data: x.0,
|
||||
path_to_hit: path.clone(),
|
||||
voxel_index_location: path.to_vec3(oct.center, oct.size),
|
||||
};
|
||||
return Some(result);
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
fn ray_octtree_visitor<T: Clone>(
|
||||
node: &TreeNode<T>,
|
||||
transform: &OBB,
|
||||
ray_origin: Vec3,
|
||||
ray_normal: Vec3,
|
||||
position: Vec3,
|
||||
size: usize,
|
||||
parent_path: Path,
|
||||
) -> Option<(RayOBBIntersection, Path)> {
|
||||
if node.is_branch() {
|
||||
let children = node.branch_contents_reference();
|
||||
if children.is_none() {
|
||||
return None;
|
||||
}
|
||||
let children = children.unwrap();
|
||||
let mut elements: Vec<(Vec3, usize, &TreeNode<T>, usize)> = Vec::new();
|
||||
for (index, element) in children.iter().enumerate() {
|
||||
if !element.is_empty() {
|
||||
let (sub_position, sub_size) = constants::sub_region(position, size, index as i32);
|
||||
elements.push((sub_position, sub_size, element, index));
|
||||
}
|
||||
}
|
||||
elements.sort_by(|f, s| {
|
||||
let first_transformed = transform
|
||||
.as_transform()
|
||||
.compute_matrix()
|
||||
.transform_point3(f.0);
|
||||
let second_transformed = transform
|
||||
.as_transform()
|
||||
.compute_matrix()
|
||||
.transform_point3(s.0);
|
||||
let fdist = first_transformed.distance(ray_origin);
|
||||
let sdist = second_transformed.distance(ray_origin);
|
||||
fdist.total_cmp(&sdist)
|
||||
});
|
||||
for element in elements {
|
||||
let mut child_path = parent_path.clone();
|
||||
child_path.append(element.3);
|
||||
let x = ray_octtree_visitor(
|
||||
element.2, transform, ray_origin, ray_normal, element.0, element.1, child_path,
|
||||
);
|
||||
if x.is_some() {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
} else if node.is_leaf() {
|
||||
let mut node_bounds = transform.clone();
|
||||
let position = transform
|
||||
.as_transform()
|
||||
.compute_matrix()
|
||||
.transform_point3(position);
|
||||
node_bounds.position = position;
|
||||
node_bounds.half_size = node_bounds.half_size; // * size as f32; size is 1 for leaves
|
||||
|
||||
let x = ray_obb_intersection(ray_origin, ray_normal, &node_bounds);
|
||||
if x.is_some() {
|
||||
dbg!(position);
|
||||
return Some((x.unwrap(), parent_path));
|
||||
}
|
||||
}
|
||||
//v nothing could be found, failing out so other searches can continue
|
||||
None
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_path() {
|
||||
let mut path_test: Path = Default::default();
|
||||
path_test.set_index(0, 6);
|
||||
path_test.set_index(7, 4);
|
||||
assert_eq!(path_test.get_index(7), 4);
|
||||
println!("{:#?}", dbg!(path_test.clone()));
|
||||
assert_eq!(path_test.get_index(0), 6);
|
||||
println!("{:#?}", dbg!(path_test.clone()));
|
||||
pub fn test_ray_x_octtree() {
|
||||
let mut oct = OctTree::new(Vec3::new(0., 1., 0.), 0);
|
||||
oct.set_voxel_at_location(Vec3::new(1., 0., 0.), 1);
|
||||
let obby = OBB::new(
|
||||
Vec3::splat(5.),
|
||||
Quat::from_rotation_y(f32::to_radians(25.))
|
||||
* Quat::from_rotation_z(f32::to_radians(25.))
|
||||
* Quat::from_rotation_x(f32::to_radians(25.)),
|
||||
Vec3::splat(1.),
|
||||
);
|
||||
let ray_origin = Vec3::ZERO;
|
||||
let ray_normal = Vec3::splat(5.).normalize();
|
||||
let collision = octtree_ray_overlap(&oct, &obby, ray_origin, ray_normal);
|
||||
let path_local = collision
|
||||
.clone()
|
||||
.unwrap()
|
||||
.path_to_hit
|
||||
.to_vec3(oct.center, oct.size);
|
||||
dbg!(path_local);
|
||||
if collision.is_some() {
|
||||
dbg!(collision.clone().unwrap());
|
||||
let col = collision.unwrap();
|
||||
let hitloc = col.hit_data.hitpoint.local.clone();
|
||||
let hitnorm = col.hit_data.normal.local.clone();
|
||||
let hitvox = hitloc - (hitnorm * 1.05);
|
||||
dbg!(hitvox.round());
|
||||
}
|
||||
|
||||
{
|
||||
let mut oct = OctTree::new(Vec3::new(0., 10., 0.), 10);
|
||||
oct.set_voxel_at_location(Vec3::ZERO, 0);
|
||||
let obby = OBB::new(Vec3::new(2., -10., 0.), Quat::IDENTITY, Vec3::splat(0.5));
|
||||
let ray_origin = Vec3::new(0., 0., 0.);
|
||||
let ray_normal = Vec3::X;
|
||||
let collision = octtree_ray_overlap(&oct, &obby, ray_origin, ray_normal);
|
||||
|
||||
if collision.is_some() {
|
||||
let path_local = collision
|
||||
.clone()
|
||||
.unwrap()
|
||||
.path_to_hit
|
||||
.to_vec3(oct.center, oct.size);
|
||||
dbg!(path_local);
|
||||
dbg!(collision.clone().unwrap());
|
||||
let col = collision.unwrap();
|
||||
let hitloc = col.hit_data.hitpoint.local.clone();
|
||||
let hitnorm = col.hit_data.normal.local.clone();
|
||||
let hitvox = hitloc - (hitnorm * 1.05);
|
||||
dbg!(hitvox.round());
|
||||
}
|
||||
}
|
||||
panic!();
|
||||
}
|
||||
#[test]
|
||||
pub fn test_sphere_collisions() {
|
||||
|
@ -620,26 +688,32 @@ pub fn test_obb_collisions() {
|
|||
pub fn test_ray_x_bounding_collisions() {
|
||||
let abounds: OBB = OBB::new(
|
||||
Vec3::new(10., 0., 0.),
|
||||
Quat::from_rotation_z(f32::to_radians(90.)),
|
||||
Quat::from_rotation_y(f32::to_radians(90.)),
|
||||
Vec3::splat(5.),
|
||||
);
|
||||
let aabb_test: Option<VectorPair> =
|
||||
ray_aabb_intersection(Vec3::ZERO, Vec3::X, abounds.position, abounds.half_size);
|
||||
let obb_test: Option<VectorPair> = ray_obb_intersection(Vec3::ZERO, Vec3::X, &abounds);
|
||||
let aabb_test = ray_aabb_intersection(Vec3::ZERO, Vec3::X, abounds.position, abounds.half_size);
|
||||
let obb_test = ray_obb_intersection(Vec3::ZERO, Vec3::X, &abounds);
|
||||
|
||||
assert_eq!(aabb_test.clone().unwrap().global, Vec3::new(5., 0., 0.));
|
||||
assert_eq!(aabb_test.unwrap().local, Vec3::new(-1., 0., 0.));
|
||||
assert_eq!(aabb_test.clone().unwrap().hitpoint, Vec3::new(5., 0., 0.));
|
||||
assert_eq!(aabb_test.unwrap().normal, Vec3::new(-1., 0., 0.));
|
||||
|
||||
assert_eq!(obb_test.unwrap().global.round(), Vec3::new(5., 0., 0.));
|
||||
assert_eq!(
|
||||
obb_test.unwrap().hitpoint.global.round(),
|
||||
Vec3::new(5., 0., 0.)
|
||||
);
|
||||
|
||||
let rotated_bounds: OBB = OBB::new(
|
||||
Vec3::new(20., 0., 0.),
|
||||
Quat::from_rotation_z(f32::to_radians(-50.0)),
|
||||
Quat::from_rotation_z(f32::to_radians(45.0)),
|
||||
Vec3::splat(5.),
|
||||
);
|
||||
let rotated_obb_test = ray_obb_intersection(Vec3::ZERO, Vec3::X, &rotated_bounds).unwrap();
|
||||
assert_eq!(rotated_obb_test.global.round().x, 13.);
|
||||
assert_eq!(rotated_obb_test.local, Vec3::new(0., -1., 0.));
|
||||
dbg!(rotated_obb_test.clone());
|
||||
assert_eq!(rotated_obb_test.hitpoint.global.round().x, 13.);
|
||||
assert_eq!(
|
||||
rotated_obb_test.normal.local.normalize(),
|
||||
Vec3::new(-0.7071068, 0.7071068, -0.0)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -759,21 +833,3 @@ pub fn test_oct_x_oct_collisions() {
|
|||
);
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
pub fn test_ray_x_octtree() {
|
||||
//A
|
||||
let mut oct = OctTree::new(Vec3::new(0., 0., 0.), 0);
|
||||
oct.set_voxel_at_location(Vec3::new(1., 1., 1.), 1);
|
||||
let obby = OBB::new(
|
||||
Vec3::splat(5.),
|
||||
Quat::from_rotation_x(f32::to_radians(30.)),
|
||||
Vec3::splat(1.),
|
||||
);
|
||||
let ray_origin = Vec3::ZERO;
|
||||
let ray_normal = Vec3::splat(5.).normalize();
|
||||
let collision = octtree_ray_overlap(&oct, &obby, ray_origin, ray_normal);
|
||||
if collision.is_some() {
|
||||
dbg!(collision.unwrap());
|
||||
}
|
||||
panic!();
|
||||
}
|
||||
|
|
|
@ -30,40 +30,6 @@ pub struct Path {
|
|||
pub(crate) packed: u64,
|
||||
pub(crate) length: usize,
|
||||
}
|
||||
|
||||
impl<T: Clone> TreeNode<T> {
|
||||
pub fn is_branch(&self) -> bool {
|
||||
match self {
|
||||
TreeNode::Branch(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
pub fn is_leaf(&self) -> bool {
|
||||
match self {
|
||||
TreeNode::Leaf(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
pub fn is_empty(&self) -> bool {
|
||||
match self {
|
||||
TreeNode::Empty => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
pub fn branch_contents_reference(&self) -> Option<&[TreeNode<T>; 8]> {
|
||||
match self {
|
||||
TreeNode::Branch(a) => Some(a.as_ref()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
pub fn branch_contents_mutable(&mut self) -> Option<&mut [TreeNode<T>; 8]> {
|
||||
match self {
|
||||
TreeNode::Branch(a) => Some(a.as_mut()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Path {
|
||||
pub fn pop(&mut self) -> usize {
|
||||
self.length -= 1;
|
||||
|
@ -97,6 +63,9 @@ impl Path {
|
|||
self.packed = self.packed & shift_mask;
|
||||
self.packed = self.packed | shifted_value;
|
||||
}
|
||||
pub fn append(&mut self, value: usize) {
|
||||
self.set_index(self.length, value);
|
||||
}
|
||||
|
||||
pub fn to_vec3(&self, center: Vec3, size: usize) -> Vec3 {
|
||||
let mut iter = (center, size);
|
||||
|
@ -111,6 +80,39 @@ impl Path {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: Clone> TreeNode<T> {
|
||||
pub fn is_branch(&self) -> bool {
|
||||
match self {
|
||||
TreeNode::Branch(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
pub fn is_leaf(&self) -> bool {
|
||||
match self {
|
||||
TreeNode::Leaf(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
pub fn is_empty(&self) -> bool {
|
||||
match self {
|
||||
TreeNode::Empty => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
pub fn branch_contents_reference(&self) -> Option<&[TreeNode<T>; 8]> {
|
||||
match self {
|
||||
TreeNode::Branch(a) => Some(a.as_ref()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
pub fn branch_contents_mutable(&mut self) -> Option<&mut [TreeNode<T>; 8]> {
|
||||
match self {
|
||||
TreeNode::Branch(a) => Some(a.as_mut()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone> OctTree<T> {
|
||||
pub fn new(npos: Vec3, value: T) -> Self {
|
||||
Self {
|
||||
|
@ -625,3 +627,28 @@ pub fn test_removal() {
|
|||
test_tree.remove_voxel(Vec3::ZERO);
|
||||
assert_eq!(test_tree.size, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_octtree() {
|
||||
let origin = Vec3::ZERO;
|
||||
let neighbor = Vec3::new(1., 1., 1.);
|
||||
let mut test_oct = OctTree::<i32>::new(origin, 1);
|
||||
test_oct.set_voxel_at_location(neighbor, 2);
|
||||
|
||||
let far_off_bullshit = Vec3::new(26., 26., 26.);
|
||||
test_oct.set_voxel_at_location(far_off_bullshit, 5);
|
||||
dbg!(&test_oct);
|
||||
assert_eq!(test_oct.voxel_at_location(neighbor).unwrap().0, 2);
|
||||
assert_eq!(test_oct.voxel_at_location(origin).unwrap().0, 1);
|
||||
assert_eq!(test_oct.voxel_at_location(far_off_bullshit).unwrap().0, 5);
|
||||
}
|
||||
#[test]
|
||||
pub fn test_path() {
|
||||
let mut path_test: Path = Default::default();
|
||||
path_test.set_index(0, 6);
|
||||
path_test.set_index(7, 4);
|
||||
assert_eq!(path_test.get_index(7), 4);
|
||||
println!("{:#?}", dbg!(path_test.clone()));
|
||||
assert_eq!(path_test.get_index(0), 6);
|
||||
println!("{:#?}", dbg!(path_test.clone()));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue