Added gui controls for camera dbugging
This commit is contained in:
@@ -69,10 +69,10 @@ impl Camera {
|
|||||||
pub fn cast_rays(&self, width: u32, height: u32) -> Vec<Ray> {
|
pub fn cast_rays(&self, width: u32, height: u32) -> Vec<Ray> {
|
||||||
//All good
|
//All good
|
||||||
let aspect = width as f64 / height as f64;
|
let aspect = width as f64 / height as f64;
|
||||||
let fovy_radians = self.fovy as f64;
|
let fovy_radians = (self.fovy as f64).to_radians();
|
||||||
let fovh_radians = 2.0 * ((fovy_radians / 2.0).tan() * aspect).atan();
|
let fovh_radians = 2.0 * ((fovy_radians / 2.0).tan() * aspect).atan();
|
||||||
// All good
|
// All good
|
||||||
let view_direction = self.target - self.eye;
|
let view_direction = (self.target - self.eye).normalize();
|
||||||
//All good
|
//All good
|
||||||
let hor = view_direction.cross(&self.up).normalize(); // pointing right
|
let hor = view_direction.cross(&self.up).normalize(); // pointing right
|
||||||
let vert = view_direction.cross(&hor).normalize(); // pointing up
|
let vert = view_direction.cross(&hor).normalize(); // pointing up
|
||||||
@@ -123,4 +123,8 @@ impl Camera {
|
|||||||
|
|
||||||
Ray::new(self.eye, direction)
|
Ray::new(self.eye, direction)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_position(&mut self, eye: Point3<f32>) {
|
||||||
|
self.eye = eye;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
27
src/gui.rs
27
src/gui.rs
@@ -1,3 +1,4 @@
|
|||||||
|
use nalgebra::Point3;
|
||||||
use pixels::{wgpu, PixelsContext};
|
use pixels::{wgpu, PixelsContext};
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
@@ -5,10 +6,14 @@ const BUFFER_PROPORTION_INIT: f32 = 0.8;
|
|||||||
const BUFFER_PROPORTION_MIN: f32 = 0.5;
|
const BUFFER_PROPORTION_MIN: f32 = 0.5;
|
||||||
const BUFFER_PROPORTION_MAX: f32 = 0.9;
|
const BUFFER_PROPORTION_MAX: f32 = 0.9;
|
||||||
|
|
||||||
const RAYS_INIT: i32 = 100;
|
const RAYS_INIT: i32 = 9000;
|
||||||
const RAYS_MIN: i32 = 100;
|
const RAYS_MIN: i32 = 100;
|
||||||
const RAYS_MAX: i32 = 10000;
|
const RAYS_MAX: i32 = 10000;
|
||||||
|
|
||||||
|
const CAMERA_MIN: f32 = -10.0;
|
||||||
|
const CAMERA_MAX: f32 = 10.0;
|
||||||
|
const CAMERA_INIT: f32 = 5.0;
|
||||||
|
|
||||||
/// Manages all state required for rendering Dear ImGui over `Pixels`.
|
/// Manages all state required for rendering Dear ImGui over `Pixels`.
|
||||||
pub(crate) struct Gui {
|
pub(crate) struct Gui {
|
||||||
imgui: imgui::Context,
|
imgui: imgui::Context,
|
||||||
@@ -19,8 +24,12 @@ pub(crate) struct Gui {
|
|||||||
about_open: bool,
|
about_open: bool,
|
||||||
|
|
||||||
pub ray_num: i32,
|
pub ray_num: i32,
|
||||||
|
|
||||||
pub buffer_proportion: f32,
|
pub buffer_proportion: f32,
|
||||||
pub buffer_resize: bool,
|
pub buffer_resize: bool,
|
||||||
|
|
||||||
|
pub camera_eye: Point3<f32>,
|
||||||
|
pub camera_reposition: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Gui {
|
impl Gui {
|
||||||
@@ -73,6 +82,8 @@ impl Gui {
|
|||||||
ray_num: RAYS_INIT,
|
ray_num: RAYS_INIT,
|
||||||
buffer_proportion: BUFFER_PROPORTION_INIT,
|
buffer_proportion: BUFFER_PROPORTION_INIT,
|
||||||
buffer_resize: false,
|
buffer_resize: false,
|
||||||
|
camera_eye: Point3::new(CAMERA_INIT, CAMERA_INIT, CAMERA_INIT),
|
||||||
|
camera_reposition: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,6 +137,20 @@ impl Gui {
|
|||||||
};
|
};
|
||||||
self.buffer_resize = buffer_resize;
|
self.buffer_resize = buffer_resize;
|
||||||
|
|
||||||
|
let mut camera_reposition = false;
|
||||||
|
ui.text("Vector3 Input:");
|
||||||
|
// Create three input fields for x, y, and z components
|
||||||
|
ui.slider("X", CAMERA_MIN, CAMERA_MAX, &mut self.camera_eye.coords[0]);
|
||||||
|
ui.slider("Y", CAMERA_MIN, CAMERA_MAX, &mut self.camera_eye.coords[1]);
|
||||||
|
ui.slider("Z", CAMERA_MIN, CAMERA_MAX, &mut self.camera_eye.coords[2]);
|
||||||
|
// Check if any component of the Vector3 has changed
|
||||||
|
if ui.button("Apply") {
|
||||||
|
println!("Camera changed: {:?}", self.camera_eye);
|
||||||
|
self.camera_eye = Point3::from(self.camera_eye);
|
||||||
|
camera_reposition = true;
|
||||||
|
}
|
||||||
|
self.camera_reposition = camera_reposition;
|
||||||
|
|
||||||
// Render Dear ImGui with WGPU
|
// Render Dear ImGui with WGPU
|
||||||
let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||||
label: Some("imgui"),
|
label: Some("imgui"),
|
||||||
|
|||||||
32
src/main.rs
32
src/main.rs
@@ -80,7 +80,7 @@ impl State {
|
|||||||
|
|
||||||
/// Update the `World` internal state; bounce the box around the screen.
|
/// Update the `World` internal state; bounce the box around the screen.
|
||||||
fn update(&mut self) -> bool {
|
fn update(&mut self) -> bool {
|
||||||
if self.gui.buffer_resize {
|
if self.gui.buffer_resize || self.gui.camera_reposition {
|
||||||
let pixels = &self.pixels;
|
let pixels = &self.pixels;
|
||||||
let size = self.window.inner_size();
|
let size = self.window.inner_size();
|
||||||
let width_new = (size.width as f32 * self.gui.buffer_proportion) as u32;
|
let width_new = (size.width as f32 * self.gui.buffer_proportion) as u32;
|
||||||
@@ -92,6 +92,7 @@ impl State {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
self.index = 0;
|
self.index = 0;
|
||||||
|
self.camera.set_position(self.gui.camera_eye);
|
||||||
self.rays = Arc::new(self.camera.cast_rays(width_new, height_new));
|
self.rays = Arc::new(self.camera.cast_rays(width_new, height_new));
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
@@ -204,38 +205,33 @@ fn main() -> Result<(), Error> {
|
|||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new();
|
||||||
//SCENE
|
//SCENE
|
||||||
//Camera
|
//Camera
|
||||||
let eye = Point3::new(100.0, 100.0, 100.0);
|
let eye = Point3::new(10.0, 0.0, 10.0);
|
||||||
let target = Point3::new(0.0, 0.0, 0.0);
|
let target = Point3::new(0.0, 0.0, 0.0);
|
||||||
let up = Vector3::new(0.0, 1.0, 0.0);
|
let up = Vector3::new(0.0, 1.0, 0.0);
|
||||||
let camera = Camera::new(
|
let camera = Camera::new(
|
||||||
eye,
|
eye,
|
||||||
target,
|
target,
|
||||||
up,
|
up,
|
||||||
70.0,
|
90.0,
|
||||||
(START_WIDTH as f32 / START_HEIGHT as f32) as f32,
|
(START_WIDTH as f32 / START_HEIGHT as f32) as f32,
|
||||||
);
|
);
|
||||||
// SETUP PRIMITIVES
|
// SETUP MATERIALS
|
||||||
let magenta = Arc::new(Material::magenta());
|
let magenta = Arc::new(Material::magenta());
|
||||||
let blue = Arc::new(Material::blue());
|
let blue = Arc::new(Material::blue());
|
||||||
let turquoise = Arc::new(Material::turquoise());
|
let turquoise = Arc::new(Material::turquoise());
|
||||||
let red = Arc::new(Material::red());
|
let red = Arc::new(Material::red());
|
||||||
// let sphere = Arc::new(Sphere::unit(magenta.clone()));
|
// SETUP PRIMITIVES
|
||||||
// primitives.push(sphere.clone());
|
|
||||||
// let cone = Arc::new(Cone::new(0.25, 1.0, -0.5, turquoise.clone()));
|
|
||||||
// primitives.push(cone.clone());
|
|
||||||
let mut primitives: Vec<Box<dyn Primitive>> = Vec::new();
|
let mut primitives: Vec<Box<dyn Primitive>> = Vec::new();
|
||||||
let cube = Box::new(Cube::unit(turquoise.clone()));
|
//let cube = Box::new(Cube::unit(turquoise.clone()));
|
||||||
let sphere = Box::new(Sphere::new(Point3::new(0.0, 4.0, 0.0), 1.0, red.clone()));
|
// primitives.push(cube);
|
||||||
let cone = Box::new(Circle::new(
|
let sphere = Box::new(Sphere::new(Point3::new(0.0, -2.0, 0.0), 1.0, red.clone()));
|
||||||
Point3::new(0.0, -3.0, 0.0),
|
let sphere2 = Box::new(Sphere::new(Point3::new(0.0, 2.0, 0.0), 1.0, red.clone()));
|
||||||
2.0,
|
let cone = Box::new(Cone::new(1.0, 1.0, -1.0, magenta.clone()));
|
||||||
Vector3::new(0.0, 1.0, 0.0),
|
|
||||||
magenta.clone(),
|
|
||||||
));
|
|
||||||
primitives.push(cube);
|
|
||||||
primitives.push(sphere);
|
primitives.push(sphere);
|
||||||
|
primitives.push(sphere2);
|
||||||
primitives.push(cone);
|
primitives.push(cone);
|
||||||
//Lights
|
|
||||||
|
// SETUP LIGHTS
|
||||||
let light_pos = Point3::new(0.0, 12.0, 4.0);
|
let light_pos = Point3::new(0.0, 12.0, 4.0);
|
||||||
let light_colour = Vector3::new(0.4, 0.4, 0.6);
|
let light_colour = Vector3::new(0.4, 0.4, 0.6);
|
||||||
let light_falloff = [1.0, 0.00, 0.00];
|
let light_falloff = [1.0, 0.00, 0.00];
|
||||||
|
|||||||
@@ -244,7 +244,7 @@ impl Primitive for Circle {
|
|||||||
};
|
};
|
||||||
let intersect = ray.at_t(t);
|
let intersect = ray.at_t(t);
|
||||||
let distance = distance(&intersect, &self.position);
|
let distance = distance(&intersect, &self.position);
|
||||||
match distance > self.radius {
|
match distance >= self.radius {
|
||||||
true => return None,
|
true => return None,
|
||||||
false => {
|
false => {
|
||||||
return Some(Intersection {
|
return Some(Intersection {
|
||||||
@@ -297,14 +297,14 @@ impl Primitive for Cylinder {
|
|||||||
pub struct Cone {
|
pub struct Cone {
|
||||||
radius: f32,
|
radius: f32,
|
||||||
base: f32,
|
base: f32,
|
||||||
height: f32,
|
apex: f32,
|
||||||
circle: Circle,
|
circle: Circle,
|
||||||
material: Arc<Material>,
|
material: Arc<Material>,
|
||||||
bounding_box: BoundingBox,
|
bounding_box: BoundingBox,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Cone {
|
impl Cone {
|
||||||
pub fn new(radius: f32, height: f32, base: f32, material: Arc<Material>) -> Self {
|
pub fn new(radius: f32, apex: f32, base: f32, material: Arc<Material>) -> Self {
|
||||||
let circle = Circle::new(
|
let circle = Circle::new(
|
||||||
Point3::new(0.0, base, 0.0),
|
Point3::new(0.0, base, 0.0),
|
||||||
radius,
|
radius,
|
||||||
@@ -312,11 +312,11 @@ impl Cone {
|
|||||||
Arc::clone(&material),
|
Arc::clone(&material),
|
||||||
);
|
);
|
||||||
let bln = Point3::new(-radius, base, -radius);
|
let bln = Point3::new(-radius, base, -radius);
|
||||||
let trf = Point3::new(radius, base + height, radius);
|
let trf = Point3::new(radius, base + apex, radius);
|
||||||
Cone {
|
Cone {
|
||||||
radius,
|
radius: radius / 2.0,
|
||||||
base,
|
base,
|
||||||
height,
|
apex,
|
||||||
circle,
|
circle,
|
||||||
material,
|
material,
|
||||||
bounding_box: BoundingBox { bln, trf },
|
bounding_box: BoundingBox { bln, trf },
|
||||||
@@ -328,7 +328,7 @@ impl Cone {
|
|||||||
|
|
||||||
pub fn get_normal(&self, intersect: Point3<f32>) -> Vector3<f32> {
|
pub fn get_normal(&self, intersect: Point3<f32>) -> Vector3<f32> {
|
||||||
let r = self.radius;
|
let r = self.radius;
|
||||||
let h = self.height;
|
let h = self.apex;
|
||||||
let (x, y, z) = (intersect.x, intersect.y, intersect.z);
|
let (x, y, z) = (intersect.x, intersect.y, intersect.z);
|
||||||
let normal = Vector3::new(2.0 * x, 2.0 * r * r * (h - y), 2.0 * z).normalize();
|
let normal = Vector3::new(2.0 * x, 2.0 * r * r * (h - y), 2.0 * z).normalize();
|
||||||
normal
|
normal
|
||||||
@@ -339,7 +339,7 @@ impl Primitive for Cone {
|
|||||||
fn intersect_ray(&self, ray: &Ray) -> Option<Intersection> {
|
fn intersect_ray(&self, ray: &Ray) -> Option<Intersection> {
|
||||||
let point = &ray.a;
|
let point = &ray.a;
|
||||||
let dir = &ray.b;
|
let dir = &ray.b;
|
||||||
let (r, h) = (self.radius, self.height);
|
let (r, h) = (self.radius, self.apex);
|
||||||
let (a1, a2, a3) = (point.x, point.y, point.z);
|
let (a1, a2, a3) = (point.x, point.y, point.z);
|
||||||
let (b1, b2, b3) = (dir.x, dir.y, dir.z);
|
let (b1, b2, b3) = (dir.x, dir.y, dir.z);
|
||||||
let r2 = r * r;
|
let r2 = r * r;
|
||||||
@@ -368,7 +368,7 @@ impl Primitive for Cone {
|
|||||||
None => None,
|
None => None,
|
||||||
Some(t) => {
|
Some(t) => {
|
||||||
let intersect = ray.at_t(t);
|
let intersect = ray.at_t(t);
|
||||||
match intersect.y >= self.base && intersect.y <= self.height {
|
match intersect.y >= self.base && intersect.y <= self.apex {
|
||||||
true => Some(Intersection {
|
true => Some(Intersection {
|
||||||
point: intersect,
|
point: intersect,
|
||||||
normal: Unit::new_normalize(self.get_normal(intersect)),
|
normal: Unit::new_normalize(self.get_normal(intersect)),
|
||||||
|
|||||||
Reference in New Issue
Block a user