Created
November 21, 2018 19:29
-
-
Save XavilPergis/9d72da818ea307fbb1a1acd57a7770c4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use collision::Ray3; | |
fn int_bound(ray: Ray3<f64>, axis: usize) -> f64 { | |
if ray.direction[axis] < 0.0 { | |
let mut new = ray; | |
new.origin[axis] *= -1.0; | |
new.direction[axis] *= -1.0; | |
int_bound(new, axis) | |
} else { | |
(1.0 - ::util::modulo(ray.origin[axis], 1.0)) / ray.direction[axis] | |
} | |
} | |
fn sign(n: f64) -> f64 { | |
if n > 0.0 { | |
1.0 | |
} else if n < 0.0 { | |
-1.0 | |
} else { | |
0.0 | |
} | |
} | |
fn trace_ray<F>(ray: Ray3<f64>, radius: f64, mut func: F) -> bool | |
where | |
F: FnMut(BlockPos, Option<Vector3<i32>>) -> bool, | |
{ | |
// init phase | |
let origin: BlockPos = WorldPos(ray.origin).into(); | |
let mut current = origin.0; | |
let step_x = sign(ray.direction.x); | |
let step_y = sign(ray.direction.y); | |
let step_z = sign(ray.direction.z); | |
let mut t_max_x = int_bound(ray, 0); | |
let mut t_max_y = int_bound(ray, 1); | |
let mut t_max_z = int_bound(ray, 2); | |
let t_delta_x = step_x / ray.direction.x; | |
let t_delta_y = step_y / ray.direction.y; | |
let t_delta_z = step_z / ray.direction.z; | |
let step_x = step_x as i32; | |
let step_y = step_y as i32; | |
let step_z = step_z as i32; | |
let mut normal = None; | |
// incremental pahse | |
loop { | |
if func(BlockPos(current), normal) { | |
return true; | |
} | |
if t_max_x < t_max_y { | |
if t_max_x < t_max_z { | |
if t_max_x > radius { | |
break; | |
} | |
current.x += step_x; | |
t_max_x += t_delta_x; | |
normal = Some(Vector3::new(-step_x, 0, 0)); | |
} else { | |
if t_max_z > radius { | |
break; | |
} | |
current.z += step_z; | |
t_max_z += t_delta_z; | |
normal = Some(Vector3::new(0, 0, -step_z)); | |
} | |
} else { | |
if t_max_y < t_max_z { | |
if t_max_y > radius { | |
break; | |
} | |
current.y += step_y; | |
t_max_y += t_delta_y; | |
normal = Some(Vector3::new(0, -step_y, 0)); | |
} else { | |
if t_max_z > radius { | |
break; | |
} | |
current.z += step_z; | |
t_max_z += t_delta_z; | |
normal = Some(Vector3::new(0, 0, -step_z)); | |
} | |
} | |
} | |
false | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment