Flat shading of spheres finished
This commit is contained in:
BIN
img.bmp
BIN
img.bmp
Binary file not shown.
|
Before Width: | Height: | Size: 192 KiB After Width: | Height: | Size: 192 KiB |
72
src/main.rs
72
src/main.rs
@@ -4,36 +4,35 @@ use std::mem;
|
|||||||
extern crate bmp;
|
extern crate bmp;
|
||||||
extern crate nalgebra;
|
extern crate nalgebra;
|
||||||
|
|
||||||
use nalgebra::Pnt3;
|
use nalgebra::*;
|
||||||
use nalgebra::Vec3;
|
|
||||||
use bmp::Image;
|
use bmp::Image;
|
||||||
use bmp::Pixel;
|
use bmp::Pixel;
|
||||||
|
|
||||||
struct Ray {
|
struct Ray {
|
||||||
pos: nalgebra::Pnt3<f64>,
|
pos: Vec3<f64>,
|
||||||
dir: nalgebra::Vec3<f64>
|
dir: Vec3<f64>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ray {
|
impl Ray {
|
||||||
fn new(pos: nalgebra::Pnt3<f64>, dir: nalgebra::Vec3<f64>) -> Ray {
|
fn new(pos: Vec3<f64>, dir: Vec3<f64>) -> Ray {
|
||||||
Ray {
|
Ray {
|
||||||
pos: pos,
|
pos: pos,
|
||||||
dir: dir
|
dir: dir
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn at(&self, t: f64) -> Pnt3<f64> {
|
fn at(&self, t: f64) -> Vec3<f64> {
|
||||||
self.pos + t * self.dir
|
self.pos + t * self.dir
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct OrthoCamera {
|
struct OrthoCamera {
|
||||||
pos: nalgebra::Pnt3<f64>,
|
pos: Vec3<f64>,
|
||||||
plane: bmp::Image
|
plane: bmp::Image
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OrthoCamera {
|
impl OrthoCamera {
|
||||||
fn new(pos: nalgebra::Pnt3<f64>) -> OrthoCamera {
|
fn new(pos: Vec3<f64>) -> OrthoCamera {
|
||||||
OrthoCamera {
|
OrthoCamera {
|
||||||
pos: pos,
|
pos: pos,
|
||||||
plane: Image::new(256,256)
|
plane: Image::new(256,256)
|
||||||
@@ -42,59 +41,66 @@ impl OrthoCamera {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct Sphere {
|
struct Sphere {
|
||||||
pos: nalgebra::Pnt3<f64>,
|
pos: Vec3<f64>,
|
||||||
radius: f64
|
radius: f64
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Sphere {
|
impl Sphere {
|
||||||
fn new(pos: nalgebra::Pnt3<f64>, radius: f64) -> Sphere {
|
fn new(pos: Vec3<f64>, radius: f64) -> Sphere {
|
||||||
Sphere {
|
Sphere {
|
||||||
pos: pos,
|
pos: pos,
|
||||||
radius: radius
|
radius: radius
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn intersection(primary_ray: Ray) -> Vec3<f64> {
|
// Implemented from
|
||||||
let t0: f64;
|
// http://kylehalladay.com/blog/tutorial/math/2013/12/24/Ray-Sphere-Intersection.html
|
||||||
let t1: f64;
|
fn intersection(&self, primary_ray: Ray, t1: &mut f64, t2: &mut f64) -> bool {
|
||||||
|
let l = self.pos - primary_ray.pos;
|
||||||
|
let tc = dot(&l, &primary_ray.dir);
|
||||||
|
|
||||||
let center = Vec3::new(pos);
|
if tc < 0.0 {
|
||||||
|
|
||||||
return center;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn solve_quadratic(a: f64, b: f64, c: f64, x0: &mut f64, x1: &mut f64) -> bool {
|
|
||||||
let discr: f64 = b * b - 4.0 * a * c;
|
|
||||||
if discr < 0.0 {
|
|
||||||
return false;
|
return false;
|
||||||
} else if discr == 0.0 {
|
|
||||||
*x0 = - 0.5 * b / a;
|
|
||||||
*x1 = - 0.5 * b / a;
|
|
||||||
} else {
|
|
||||||
let q: f64 = if b > 0.0 { -0.5 * (b + f64::sqrt(discr)) } else { -0.5 * (b - f64::sqrt(discr)) };
|
|
||||||
*x0 = q / a;
|
|
||||||
*x1 = c / q;
|
|
||||||
}
|
}
|
||||||
if x0 > x1 { mem::swap(x0, x1); }
|
|
||||||
|
let d = f64::sqrt((l.norm() * l.norm()) as f64 - (tc*tc));
|
||||||
|
|
||||||
|
if d > self.radius { return false };
|
||||||
|
|
||||||
|
let t1c = f64::sqrt(f64::powf(self.radius, 2.0) - f64::powf(d, 2.0));
|
||||||
|
*t1 = tc - t1c;
|
||||||
|
*t2 = tc + t1c;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut camera = OrthoCamera::new(Pnt3::new(0.0, 0.0, 0.0));
|
let mut camera = OrthoCamera::new(Vec3::new(0.0, 0.0, 0.0));
|
||||||
let mut spheres = Vec::new();
|
let mut spheres = Vec::new();
|
||||||
|
|
||||||
spheres.push(Sphere::new(Pnt3::new(0.0, 0.0, 20.0), 5.0));
|
spheres.push(Sphere::new(Vec3::new(100.0, 100.0, 50.0), 25.0));
|
||||||
|
|
||||||
for (x, y) in camera.plane.coordinates() {
|
for (x, y) in camera.plane.coordinates() {
|
||||||
camera.plane.set_pixel(x, y, px!(x, y, 200));
|
println!("Camera coords: {}. {}", x, y);
|
||||||
|
for sphere in &spheres {
|
||||||
|
let ray = Ray::new(Vec3::new(x as f64, y as f64, camera.pos.z as f64), Vec3::new(0.0, 0.0, 1.0));
|
||||||
|
let mut t1 = 0.0;
|
||||||
|
let mut t2 = 0.0;
|
||||||
|
let result = sphere.intersection(ray, &mut t1, &mut t2);
|
||||||
|
if result == true {
|
||||||
|
camera.plane.set_pixel(x, y, px!(255, 255, 255));
|
||||||
|
} else {
|
||||||
|
camera.plane.set_pixel(x, y, px!(0, 0, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = camera.plane.save("img.bmp");
|
let _ = camera.plane.save("img.bmp");
|
||||||
|
|
||||||
|
|
||||||
// Testing rays
|
// Testing rays
|
||||||
let ray = Ray::new(Pnt3::new(0.0, 0.0, 0.0), Vec3::new(0.0, 0.25, 0.8));
|
let ray = Ray::new(Vec3::new(0.0, 0.0, 0.0), Vec3::new(0.0, 0.25, 0.8));
|
||||||
|
|
||||||
let result = ray.at(5.0);
|
let result = ray.at(5.0);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user