triangle and fix cube normals
This commit is contained in:
@@ -506,17 +506,17 @@ impl Primitive for Cube {
|
||||
|
||||
//Get normal of intersection point
|
||||
let normal = if tmin == t1.x {
|
||||
Vector3::new(-1.0, 0.0, 0.0)
|
||||
Vector3::new(1.0, 0.0, 0.0)
|
||||
} else if tmin == t1.y {
|
||||
Vector3::new(0.0, -1.0, 0.0)
|
||||
} else if tmin == t1.z {
|
||||
Vector3::new(0.0, 0.0, -1.0)
|
||||
Vector3::new(0.0, 0.0, 1.0)
|
||||
} else if tmin == t2.x {
|
||||
Vector3::new(1.0, 0.0, 0.0)
|
||||
Vector3::new(-1.0, 0.0, 0.0)
|
||||
} else if tmin == t2.y {
|
||||
Vector3::new(0.0, 1.0, 0.0)
|
||||
} else {
|
||||
Vector3::new(0.0, 0.0, 1.0)
|
||||
Vector3::new(0.0, 0.0, -1.0)
|
||||
};
|
||||
|
||||
Some(Intersection {
|
||||
@@ -535,6 +535,8 @@ impl Primitive for Cube {
|
||||
}
|
||||
|
||||
// TRIANGLE -----------------------------------------------------------------
|
||||
// Points u,v,w will be pointing outward from uw x uv
|
||||
// Using the right hand rule
|
||||
#[derive(Clone)]
|
||||
#[allow(dead_code)]
|
||||
pub struct Triangle {
|
||||
@@ -549,7 +551,7 @@ impl Triangle {
|
||||
pub fn new(u: Point3<f64>, v: Point3<f64>, w: Point3<f64>) -> Rc<dyn Primitive> {
|
||||
let uv = v - u;
|
||||
let uw = w - u;
|
||||
let normal = uv.cross(&uw).normalize();
|
||||
let normal = uw.cross(&uv).normalize();
|
||||
let bln = u.inf(&v).inf(&w);
|
||||
let trf = u.sup(&v).sup(&w);
|
||||
let bounding_box = BoundingBox { bln, trf };
|
||||
@@ -572,40 +574,43 @@ impl Triangle {
|
||||
|
||||
impl Primitive for Triangle {
|
||||
fn intersect_ray(&self, ray: &Ray) -> Option<Intersection> {
|
||||
let constant = self.u.coords.dot(&self.normal);
|
||||
let denominator = ray.b.dot(&self.normal);
|
||||
let t = (constant - ray.a.coords.dot(&self.normal)) / denominator;
|
||||
let (u, v, w) = (self.u, self.v, self.w);
|
||||
let e1 = v - u;
|
||||
let e2 = w - u;
|
||||
let b_cross_e2 = ray.b.cross(&e2);
|
||||
let det = e1.dot(&b_cross_e2);
|
||||
|
||||
if t > INFINITY {
|
||||
if det > -EPSILON && det < EPSILON {
|
||||
return None;
|
||||
}
|
||||
|
||||
let intersect = ray.at_t(t);
|
||||
let inv_det = 1.0 / det;
|
||||
let s = ray.a - u;
|
||||
let p = inv_det * s.dot(&b_cross_e2);
|
||||
|
||||
let uv = self.v - self.u;
|
||||
let vw = self.w - self.v;
|
||||
let wu = self.u - self.w;
|
||||
|
||||
let ui = intersect - self.u;
|
||||
let vi = intersect - self.v;
|
||||
let wi = intersect - self.w;
|
||||
|
||||
let u_cross = uv.cross(&ui);
|
||||
let v_cross = vw.cross(&vi);
|
||||
let w_cross = wu.cross(&wi);
|
||||
|
||||
let normal = self.normal;
|
||||
|
||||
if u_cross.dot(&normal) >= 0.0 && v_cross.dot(&normal) >= 0.0 && w_cross.dot(&normal) >= 0.0
|
||||
{
|
||||
Some(Intersection {
|
||||
point: intersect,
|
||||
normal: normal,
|
||||
distance: t,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
if p < 0.0 || p > 1.0 {
|
||||
return None;
|
||||
}
|
||||
|
||||
let s_cross_e1 = s.cross(&e1);
|
||||
let v = inv_det * ray.b.dot(&s_cross_e1);
|
||||
|
||||
if v < 0.0 || p + v > 1.0 {
|
||||
return None;
|
||||
}
|
||||
let t = inv_det * e2.dot(&s_cross_e1);
|
||||
|
||||
if t > EPSILON
|
||||
// ray intersection
|
||||
{
|
||||
let intersect = ray.at_t(t);
|
||||
return Some(Intersection {
|
||||
point: intersect,
|
||||
normal: self.normal,
|
||||
distance: t,
|
||||
});
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn intersect_bounding_box(&self, ray: &Ray) -> bool {
|
||||
|
||||
15
src/state.rs
15
src/state.rs
@@ -20,8 +20,8 @@ use winit::window::{Window, WindowBuilder};
|
||||
|
||||
const START_WIDTH: i32 = 1200;
|
||||
const START_HEIGHT: i32 = 700;
|
||||
const COLOUR_CLEAR: [u8; 4] = [0x22, 0x00, 0x11, 0xff];
|
||||
const PIXEL_CLEAR: [u8; 4] = [0x55, 0x00, 0x22, 0xff];
|
||||
const COLOUR_CLEAR: [u8; 4] = [0x22, 0x00, 0x11, 0x00];
|
||||
const PIXEL_CLEAR: [u8; 4] = [0x55, 0x00, 0x22, 0x00];
|
||||
|
||||
pub const INIT_FILE: &str = "rhai/scene.rhai";
|
||||
pub const SAVE_FILE: &str = "img.png";
|
||||
@@ -153,9 +153,13 @@ impl State {
|
||||
None => break,
|
||||
};
|
||||
//Shade colour for selected ray
|
||||
let colour = &self.rays[index].shade_ray(&self.scene);
|
||||
//Assign colour to pixel in frame
|
||||
let rgba = colour.map_or(PIXEL_CLEAR, |colour| [colour.x, colour.y, colour.z, 255]);
|
||||
let rgba = match &self.rays[index].shade_ray(&self.scene, 0) {
|
||||
Some(mut colour) => {
|
||||
colour = colour * 255.0;
|
||||
[colour.x as u8, colour.y as u8, colour.z as u8, 0xff]
|
||||
}
|
||||
None => PIXEL_CLEAR,
|
||||
};
|
||||
frame[index * 4..(index + 1) * 4].copy_from_slice(&rgba);
|
||||
}
|
||||
Ok(())
|
||||
@@ -248,6 +252,7 @@ fn create_window(event_loop: &EventLoop<()>) -> Window {
|
||||
.with_title("Hello Pixels + Dear ImGui")
|
||||
.with_inner_size(size)
|
||||
.with_min_inner_size(size)
|
||||
.with_transparent(true)
|
||||
.build(event_loop)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user