Created crate for BVH node traversal order calculations.
Might move this into the main source base at some point, but I'm not totally sure about the correctness of the table yet, so would like to generate it for now.
This commit is contained in:
parent
554f73eacb
commit
a4a73713d2
5
Cargo.lock
generated
5
Cargo.lock
generated
|
@ -30,6 +30,10 @@ name = "bitflags"
|
|||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "bvh_order"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.0.0"
|
||||
|
@ -158,6 +162,7 @@ name = "psychopath"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bvh_order 0.1.0",
|
||||
"clap 2.24.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"color 0.1.0",
|
||||
"crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
[workspace]
|
||||
members = [
|
||||
"sub_crates/bvh_order",
|
||||
"sub_crates/color",
|
||||
"sub_crates/float4",
|
||||
"sub_crates/halton",
|
||||
|
@ -36,6 +37,9 @@ scoped_threadpool = "0.1"
|
|||
time = "0.1"
|
||||
|
||||
# Local crate dependencies
|
||||
[dependencies.bvh_order]
|
||||
path = "sub_crates/bvh_order"
|
||||
|
||||
[dependencies.color]
|
||||
path = "sub_crates/color"
|
||||
|
||||
|
|
10
sub_crates/bvh_order/Cargo.toml
Normal file
10
sub_crates/bvh_order/Cargo.toml
Normal file
|
@ -0,0 +1,10 @@
|
|||
[package]
|
||||
name = "bvh_order"
|
||||
version = "0.1.0"
|
||||
authors = ["Nathan Vegdahl <cessen@cessen.com>"]
|
||||
license = "MIT"
|
||||
build = "build.rs"
|
||||
|
||||
[lib]
|
||||
name = "bvh_order"
|
||||
path = "src/lib.rs"
|
105
sub_crates/bvh_order/build.rs
Normal file
105
sub_crates/bvh_order/build.rs
Normal file
|
@ -0,0 +1,105 @@
|
|||
// Generate table for traversal order of quad BVHs.
|
||||
|
||||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
|
||||
fn main() {
|
||||
// Build the traversal table.
|
||||
let mut traversal_table = [
|
||||
Vec::new(),
|
||||
Vec::new(),
|
||||
Vec::new(),
|
||||
Vec::new(),
|
||||
Vec::new(),
|
||||
Vec::new(),
|
||||
Vec::new(),
|
||||
Vec::new(),
|
||||
];
|
||||
for raydir in 0..8 {
|
||||
let ray = [raydir & 1, (raydir >> 1) & 1, (raydir >> 2) & 1];
|
||||
|
||||
for s2 in 0..3 {
|
||||
for s1 in 0..3 {
|
||||
for s0 in 0..3 {
|
||||
let mut perm = [0, 1, 2, 3];
|
||||
if ray[s1] == 1 {
|
||||
perm.swap(0, 1);
|
||||
}
|
||||
if ray[s2] == 1 {
|
||||
perm.swap(2, 3);
|
||||
}
|
||||
if ray[s0] == 1 {
|
||||
perm.swap(0, 2);
|
||||
perm.swap(1, 3);
|
||||
}
|
||||
traversal_table[raydir].push(
|
||||
perm[0] + (perm[1] << 2) + (perm[2] << 4) +
|
||||
(perm[3] << 6),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for s1 in 0..3 {
|
||||
for s0 in 0..3 {
|
||||
let mut perm = [0, 1, 2];
|
||||
if ray[s1] == 1 {
|
||||
perm.swap(0, 1);
|
||||
}
|
||||
if ray[s0] == 1 {
|
||||
perm.swap(0, 1);
|
||||
perm.swap(0, 2);
|
||||
}
|
||||
traversal_table[raydir].push(perm[0] + (perm[1] << 2) + (perm[2] << 4));
|
||||
}
|
||||
}
|
||||
|
||||
for s1 in 0..3 {
|
||||
for s0 in 0..3 {
|
||||
let mut perm = [0, 1, 2];
|
||||
if ray[s1] == 1 {
|
||||
perm.swap(1, 2);
|
||||
}
|
||||
if ray[s0] == 1 {
|
||||
perm.swap(0, 2);
|
||||
perm.swap(0, 1);
|
||||
}
|
||||
traversal_table[raydir].push(perm[0] + (perm[1] << 2) + (perm[2] << 4));
|
||||
}
|
||||
}
|
||||
|
||||
for s0 in 0..3 {
|
||||
let mut perm = [0, 1];
|
||||
if ray[s0] == 1 {
|
||||
perm.swap(0, 1);
|
||||
}
|
||||
traversal_table[raydir].push(perm[0] + (perm[1] << 2));
|
||||
}
|
||||
}
|
||||
|
||||
// Write traversal table to Rust file
|
||||
let out_dir = env::var("OUT_DIR").unwrap();
|
||||
let dest_path = Path::new(&out_dir).join("table_inc.rs");
|
||||
let mut f = File::create(&dest_path).unwrap();
|
||||
|
||||
f.write_all("pub static TRAVERSAL_TABLE: [[u8; 48]; 8] = [".as_bytes())
|
||||
.unwrap();
|
||||
|
||||
for sub_table in traversal_table.iter() {
|
||||
f.write_all("\n [".as_bytes()).unwrap();
|
||||
for (i, n) in sub_table.iter().enumerate() {
|
||||
if i == 27 || i == 36 || i == 45 {
|
||||
f.write_all("\n ".as_bytes()).unwrap();
|
||||
}
|
||||
f.write_all(format!("{}", n).as_bytes()).unwrap();
|
||||
if i != 47 {
|
||||
f.write_all(", ".as_bytes()).unwrap();
|
||||
}
|
||||
}
|
||||
f.write_all("],".as_bytes()).unwrap();
|
||||
}
|
||||
|
||||
f.write_all("\n];".as_bytes()).unwrap();
|
||||
}
|
34
sub_crates/bvh_order/src/lib.rs
Normal file
34
sub_crates/bvh_order/src/lib.rs
Normal file
|
@ -0,0 +1,34 @@
|
|||
#![allow(dead_code)]
|
||||
|
||||
// Include the file generated by the build.rs script
|
||||
include!(concat!(env!("OUT_DIR"), "/table_inc.rs"));
|
||||
|
||||
/// Represents the split axes of the BVH2 node(s) that a BVH4 node was created
|
||||
/// from.
|
||||
///
|
||||
/// * `Full` means four nodes from three splits: top, left, and right.
|
||||
/// * `Left` is three nodes from two splits: top and left.
|
||||
/// * `Right` is three nodes from two splits: top and right.
|
||||
/// * `TopOnly` is two nodes from one split (in other words, the BVH4 node is
|
||||
/// identical to the single BVH2 node that it was created from).
|
||||
///
|
||||
/// Left in this case means the node whose coordinate on the top split-axis is
|
||||
/// lower. For example, if the top split is on the x axis, then `left.x <= right.x`.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum SplitAxes {
|
||||
Full((u8, u8, u8)), // top, left, right
|
||||
Left((u8, u8)), // top, left
|
||||
Right((u8, u8)), // top, right
|
||||
TopOnly(u8), // top
|
||||
}
|
||||
|
||||
/// Calculates the traversal code for a BVH4 node based on the splits and
|
||||
/// topology of its children.
|
||||
pub fn calc_traversal_code(split: SplitAxes) -> u8 {
|
||||
match split {
|
||||
SplitAxes::Full((top, left, right)) => top + (left * 3) + (right * 9),
|
||||
SplitAxes::Left((top, left)) => top + (left * 3) + 27,
|
||||
SplitAxes::Right((top, right)) => top + (right * 3) + (27 + 9),
|
||||
SplitAxes::TopOnly(top) => top + (27 + 9 + 9),
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user