Implement acceleration tree
This commit is contained in:
parent
f44716e2c4
commit
636dc6450b
4 changed files with 66 additions and 76 deletions
|
@ -1,4 +1,4 @@
|
|||
use cgmath::{vec2, vec3, Vector2, Vector3, Zero};
|
||||
use cgmath::{vec3, Vector2, Vector3, Zero};
|
||||
|
||||
use std::f32::{MAX, MIN};
|
||||
|
||||
|
@ -38,10 +38,59 @@ impl<'a> AccelerationData<'a> {
|
|||
}
|
||||
|
||||
pub fn find_closest_hit(&self, ray: &Ray) -> Option<Intersection> {
|
||||
None
|
||||
let mut closest_index = -1;
|
||||
let mut closest_distance = MAX;
|
||||
let mut barycentric = Vector2::zero();
|
||||
|
||||
self.traverse_tree(|_, aabb| {
|
||||
if aabb.intersect(ray) {
|
||||
// check if node is a leaf
|
||||
if aabb.start_index != -1 {
|
||||
for i in aabb.start_index..aabb.end_index {
|
||||
let mut t = 0.0;
|
||||
let mut tmp_bary = Vector2::zero();
|
||||
|
||||
if self.triangles[i as usize].intersect_mt(ray, &mut t, &mut tmp_bary) {
|
||||
if t < closest_distance {
|
||||
closest_index = i as i32;
|
||||
closest_distance = t;
|
||||
barycentric = tmp_bary;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
});
|
||||
|
||||
if closest_index == -1 {
|
||||
None
|
||||
} else {
|
||||
Some(Intersection::new(
|
||||
closest_distance,
|
||||
self.triangles[closest_index as usize].clone(),
|
||||
barycentric,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print_tree(&self) {
|
||||
self.traverse_tree(|index, aabb| {
|
||||
print_aabb(index, aabb);
|
||||
true
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// private
|
||||
impl<'a> AccelerationData<'a> {
|
||||
fn traverse_tree<F>(&self, mut f: F)
|
||||
where
|
||||
F: FnMut(usize, &AABB) -> bool,
|
||||
{
|
||||
let mut discovered = vec![false; 1024];
|
||||
let mut stack = Vec::new();
|
||||
|
||||
|
@ -57,27 +106,24 @@ impl<'a> AccelerationData<'a> {
|
|||
|
||||
discovered[v] = true;
|
||||
|
||||
print_aabb(v, self.data[v]);
|
||||
|
||||
let left_child = self.data[v].left_child;
|
||||
if left_child != -1 {
|
||||
if !discovered[left_child as usize] {
|
||||
stack.push(left_child as usize);
|
||||
if (f)(v, &self.data[v]) {
|
||||
let left_child = self.data[v].left_child;
|
||||
if left_child != -1 {
|
||||
if !discovered[left_child as usize] {
|
||||
stack.push(left_child as usize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let right_child = self.data[v].right_child;
|
||||
if right_child != -1 {
|
||||
if !discovered[right_child as usize] {
|
||||
stack.push(right_child as usize);
|
||||
let right_child = self.data[v].right_child;
|
||||
if right_child != -1 {
|
||||
if !discovered[right_child as usize] {
|
||||
stack.push(right_child as usize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// private
|
||||
impl<'a> AccelerationData<'a> {
|
||||
fn create_leaf_nodes(input_data: &[Triangle], triangles_per_as: u32) -> Vec<AABB> {
|
||||
let mut acceleration_data = Vec::new();
|
||||
|
||||
|
@ -178,6 +224,6 @@ impl<'a> AccelerationData<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn print_aabb(index: usize, aabb: AABB) {
|
||||
fn print_aabb(index: usize, aabb: &AABB) {
|
||||
println!("({}):\t{:?}", index, aabb);
|
||||
}
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
use cgmath::{vec2, vec3, Vector2, Vector3, Zero};
|
||||
use cgmath::Vector2;
|
||||
|
||||
use crate::triangle::Triangle;
|
||||
|
||||
use std::f32::MAX;
|
||||
|
||||
pub struct Intersection {
|
||||
pub distance: f32,
|
||||
pub triangle: Triangle,
|
||||
|
@ -18,12 +16,4 @@ impl Intersection {
|
|||
barycentric,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn zero() -> Intersection {
|
||||
Intersection {
|
||||
distance: MAX,
|
||||
triangle: Triangle::zero(),
|
||||
barycentric: Vector2::zero(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
33
src/main.rs
33
src/main.rs
|
@ -49,7 +49,6 @@ fn generate_grid(width: u32, height: u32) -> Vec<Triangle> {
|
|||
fn main() {
|
||||
let input_data = generate_grid(5, 5);
|
||||
|
||||
/*
|
||||
let camera = Camera::new(
|
||||
vec3(0.0, -4.0, 4.0),
|
||||
vec3(0.0, 0.0, 0.0),
|
||||
|
@ -57,15 +56,6 @@ fn main() {
|
|||
45.0,
|
||||
1280.0 / 720.0,
|
||||
);
|
||||
*/
|
||||
|
||||
let camera = Camera::new(
|
||||
vec3(0.0, 0.0, 3.0),
|
||||
vec3(0.0, 0.0, 0.0),
|
||||
vec3(0.0, 1.0, 1.0),
|
||||
45.0,
|
||||
1280.0 / 720.0,
|
||||
);
|
||||
|
||||
debug_raytracer_camera(1280, 720, &camera, &input_data);
|
||||
}
|
||||
|
@ -95,29 +85,6 @@ fn debug_raytracer_camera(dim_x: u32, dim_y: u32, camera: &Camera, data: &[Trian
|
|||
fn pixel_color(ray: &Ray, acceleration_data: &AccelerationData) -> Vector3<f32> {
|
||||
let mut final_color = vec3(0.0, 1.0, 0.0);
|
||||
|
||||
/*
|
||||
let mut closest_value = MAX;
|
||||
let mut closest_index = -1;
|
||||
let mut barycentric = Vector2::zero();
|
||||
|
||||
for accel in acceleration_data.iter() {
|
||||
if accel.intersect(ray) {
|
||||
for i in accel.start_index..accel.end_index {
|
||||
let mut t = 0.0;
|
||||
let mut tmp_bary = Vector2::zero();
|
||||
|
||||
if data[i].intersect_mt(ray, &mut t, &mut tmp_bary) {
|
||||
if t < closest_value {
|
||||
closest_index = i as i32;
|
||||
closest_value = t;
|
||||
barycentric = tmp_bary;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
if let Some(intersection) = acceleration_data.find_closest_hit(ray) {
|
||||
let triangle = intersection.triangle;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use cgmath::{InnerSpace, Vector2, Vector3, Zero};
|
||||
use cgmath::{InnerSpace, Vector2, Vector3};
|
||||
|
||||
use super::ray::Ray;
|
||||
|
||||
|
@ -15,15 +15,9 @@ impl Vertex {
|
|||
texture_coordinate,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn zero() -> Vertex {
|
||||
Vertex {
|
||||
position: Vector3::zero(),
|
||||
texture_coordinate: Vector2::zero(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Triangle {
|
||||
pub vertices: [Vertex; 3],
|
||||
pub color: Vector3<f32>,
|
||||
|
@ -37,13 +31,6 @@ impl Triangle {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn zero() -> Triangle {
|
||||
Triangle {
|
||||
vertices: [Vertex::zero(); 3],
|
||||
color: Vector3::zero(),
|
||||
}
|
||||
}
|
||||
|
||||
// source: https://www.scratchapixel.com/lessons/3d-basic-rendering/ray-tracing-rendering-a-triangle/moller-trumbore-ray-triangle-intersection
|
||||
pub fn intersect_mt(&self, ray: &Ray, t: &mut f32, barycentric: &mut Vector2<f32>) -> bool {
|
||||
let v0v1 = self.vertices[1].position - self.vertices[0].position;
|
||||
|
|
Loading…
Reference in a new issue