From 3ef8f4d918406eec6bdc29e0ebd883fabfac9b2e Mon Sep 17 00:00:00 2001
From: Julian T <julian@jtle.dk>
Date: Thu, 5 Aug 2021 15:44:40 +0200
Subject: Add picture for c5505ab84820248c6dba35fc06aef9e0ced183de

---
 Cargo.lock                    | 436 ------------------------------------------
 Cargo.toml                    |  13 --
 generated.png                 | Bin 227454 -> 125962 bytes
 readme.md                     |  25 ---
 src/camera/camera.rs          | 135 -------------
 src/camera/film.rs            | 145 --------------
 src/camera/filter/mod.rs      |  32 ----
 src/camera/mod.rs             |  13 --
 src/core/bound2.rs            | 127 ------------
 src/core/bound3.rs            | 113 -----------
 src/core/mod.rs               |  34 ----
 src/core/ray.rs               |  35 ----
 src/core/spectrum.rs          |  88 ---------
 src/core/vector2.rs           | 167 ----------------
 src/core/vector3.rs           | 185 ------------------
 src/lib.rs                    |  41 ----
 src/main.rs                   |  63 ------
 src/material/dielectric.rs    |  56 ------
 src/material/diffuse_light.rs |  27 ---
 src/material/lambertian.rs    |  38 ----
 src/material/mod.rs           |  25 ---
 src/material/reflectant.rs    |  40 ----
 src/material/sky_light.rs     |  19 --
 src/render/coordinator.rs     | 126 ------------
 src/render/mod.rs             |   5 -
 src/render/task.rs            |  49 -----
 src/sample/mod.rs             |  46 -----
 src/sample/uniform.rs         |  39 ----
 src/trace/mod.rs              |  41 ----
 src/trace/pathtrace.rs        |  60 ------
 src/world/container/list.rs   |  56 ------
 src/world/container/mod.rs    |   3 -
 src/world/hittable.rs         |  41 ----
 src/world/mod.rs              |  42 ----
 src/world/scene.rs            |  43 -----
 src/world/shapes/mod.rs       |  30 ---
 src/world/shapes/sphere.rs    |  98 ----------
 37 files changed, 2536 deletions(-)
 delete mode 100644 Cargo.lock
 delete mode 100644 Cargo.toml
 delete mode 100644 readme.md
 delete mode 100644 src/camera/camera.rs
 delete mode 100644 src/camera/film.rs
 delete mode 100644 src/camera/filter/mod.rs
 delete mode 100644 src/camera/mod.rs
 delete mode 100644 src/core/bound2.rs
 delete mode 100644 src/core/bound3.rs
 delete mode 100644 src/core/mod.rs
 delete mode 100644 src/core/ray.rs
 delete mode 100644 src/core/spectrum.rs
 delete mode 100644 src/core/vector2.rs
 delete mode 100644 src/core/vector3.rs
 delete mode 100644 src/lib.rs
 delete mode 100644 src/main.rs
 delete mode 100644 src/material/dielectric.rs
 delete mode 100644 src/material/diffuse_light.rs
 delete mode 100644 src/material/lambertian.rs
 delete mode 100644 src/material/mod.rs
 delete mode 100644 src/material/reflectant.rs
 delete mode 100644 src/material/sky_light.rs
 delete mode 100644 src/render/coordinator.rs
 delete mode 100644 src/render/mod.rs
 delete mode 100644 src/render/task.rs
 delete mode 100644 src/sample/mod.rs
 delete mode 100644 src/sample/uniform.rs
 delete mode 100644 src/trace/mod.rs
 delete mode 100644 src/trace/pathtrace.rs
 delete mode 100644 src/world/container/list.rs
 delete mode 100644 src/world/container/mod.rs
 delete mode 100644 src/world/hittable.rs
 delete mode 100644 src/world/mod.rs
 delete mode 100644 src/world/scene.rs
 delete mode 100644 src/world/shapes/mod.rs
 delete mode 100644 src/world/shapes/sphere.rs

diff --git a/Cargo.lock b/Cargo.lock
deleted file mode 100644
index 370504f..0000000
--- a/Cargo.lock
+++ /dev/null
@@ -1,436 +0,0 @@
-# This file is automatically @generated by Cargo.
-# It is not intended for manual editing.
-[[package]]
-name = "adler"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
-
-[[package]]
-name = "adler32"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
-
-[[package]]
-name = "autocfg"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
-
-[[package]]
-name = "bitflags"
-version = "1.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
-
-[[package]]
-name = "bytemuck"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a4bad0c5981acc24bc09e532f35160f952e35422603f0563cd7a73c2c2e65a0"
-
-[[package]]
-name = "byteorder"
-version = "1.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b"
-
-[[package]]
-name = "cfg-if"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
-
-[[package]]
-name = "color_quant"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
-
-[[package]]
-name = "const_fn"
-version = "0.4.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28b9d6de7f49e22cf97ad17fc4036ece69300032f45f78f30b4a4482cdc3f4a6"
-
-[[package]]
-name = "crc32fast"
-version = "1.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
-dependencies = [
- "cfg-if",
-]
-
-[[package]]
-name = "crossbeam"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd01a6eb3daaafa260f6fc94c3a6c36390abc2080e38e3e34ced87393fb77d80"
-dependencies = [
- "cfg-if",
- "crossbeam-channel",
- "crossbeam-deque",
- "crossbeam-epoch",
- "crossbeam-queue",
- "crossbeam-utils",
-]
-
-[[package]]
-name = "crossbeam-channel"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775"
-dependencies = [
- "cfg-if",
- "crossbeam-utils",
-]
-
-[[package]]
-name = "crossbeam-deque"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9"
-dependencies = [
- "cfg-if",
- "crossbeam-epoch",
- "crossbeam-utils",
-]
-
-[[package]]
-name = "crossbeam-epoch"
-version = "0.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1aaa739f95311c2c7887a76863f500026092fb1dce0161dab577e559ef3569d"
-dependencies = [
- "cfg-if",
- "const_fn",
- "crossbeam-utils",
- "lazy_static",
- "memoffset",
- "scopeguard",
-]
-
-[[package]]
-name = "crossbeam-queue"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0f6cb3c7f5b8e51bc3ebb73a2327ad4abdbd119dc13223f14f961d2f38486756"
-dependencies = [
- "cfg-if",
- "crossbeam-utils",
-]
-
-[[package]]
-name = "crossbeam-utils"
-version = "0.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d"
-dependencies = [
- "autocfg",
- "cfg-if",
- "lazy_static",
-]
-
-[[package]]
-name = "deflate"
-version = "0.8.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174"
-dependencies = [
- "adler32",
- "byteorder",
-]
-
-[[package]]
-name = "either"
-version = "1.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
-
-[[package]]
-name = "getrandom"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8"
-dependencies = [
- "cfg-if",
- "libc",
- "wasi",
-]
-
-[[package]]
-name = "gif"
-version = "0.11.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02efba560f227847cb41463a7395c514d127d4f74fff12ef0137fff1b84b96c4"
-dependencies = [
- "color_quant",
- "weezl",
-]
-
-[[package]]
-name = "hermit-abi"
-version = "0.1.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "image"
-version = "0.23.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ce04077ead78e39ae8610ad26216aed811996b043d47beed5090db674f9e9b5"
-dependencies = [
- "bytemuck",
- "byteorder",
- "color_quant",
- "gif",
- "jpeg-decoder",
- "num-iter",
- "num-rational",
- "num-traits",
- "png",
- "scoped_threadpool",
- "tiff",
-]
-
-[[package]]
-name = "jpeg-decoder"
-version = "0.1.22"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "229d53d58899083193af11e15917b5640cd40b29ff475a1fe4ef725deb02d0f2"
-dependencies = [
- "rayon",
-]
-
-[[package]]
-name = "lazy_static"
-version = "1.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
-
-[[package]]
-name = "libc"
-version = "0.2.85"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ccac4b00700875e6a07c6cde370d44d32fa01c5a65cdd2fca6858c479d28bb3"
-
-[[package]]
-name = "memoffset"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87"
-dependencies = [
- "autocfg",
-]
-
-[[package]]
-name = "miniz_oxide"
-version = "0.3.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435"
-dependencies = [
- "adler32",
-]
-
-[[package]]
-name = "miniz_oxide"
-version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d"
-dependencies = [
- "adler",
- "autocfg",
-]
-
-[[package]]
-name = "num-integer"
-version = "0.1.44"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
-dependencies = [
- "autocfg",
- "num-traits",
-]
-
-[[package]]
-name = "num-iter"
-version = "0.1.42"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59"
-dependencies = [
- "autocfg",
- "num-integer",
- "num-traits",
-]
-
-[[package]]
-name = "num-rational"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07"
-dependencies = [
- "autocfg",
- "num-integer",
- "num-traits",
-]
-
-[[package]]
-name = "num-traits"
-version = "0.2.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
-dependencies = [
- "autocfg",
-]
-
-[[package]]
-name = "num_cpus"
-version = "1.13.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
-dependencies = [
- "hermit-abi",
- "libc",
-]
-
-[[package]]
-name = "png"
-version = "0.16.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c3287920cb847dee3de33d301c463fba14dda99db24214ddf93f83d3021f4c6"
-dependencies = [
- "bitflags",
- "crc32fast",
- "deflate",
- "miniz_oxide 0.3.7",
-]
-
-[[package]]
-name = "ppv-lite86"
-version = "0.2.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
-
-[[package]]
-name = "rand"
-version = "0.8.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e"
-dependencies = [
- "libc",
- "rand_chacha",
- "rand_core",
- "rand_hc",
-]
-
-[[package]]
-name = "rand_chacha"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d"
-dependencies = [
- "ppv-lite86",
- "rand_core",
-]
-
-[[package]]
-name = "rand_core"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c026d7df8b298d90ccbbc5190bd04d85e159eaf5576caeacf8741da93ccbd2e5"
-dependencies = [
- "getrandom",
-]
-
-[[package]]
-name = "rand_hc"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73"
-dependencies = [
- "rand_core",
-]
-
-[[package]]
-name = "rand_pcg"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7de198537002b913568a3847e53535ace266f93526caf5c360ec41d72c5787f0"
-dependencies = [
- "rand_core",
-]
-
-[[package]]
-name = "rayon"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674"
-dependencies = [
- "autocfg",
- "crossbeam-deque",
- "either",
- "rayon-core",
-]
-
-[[package]]
-name = "rayon-core"
-version = "1.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a"
-dependencies = [
- "crossbeam-channel",
- "crossbeam-deque",
- "crossbeam-utils",
- "lazy_static",
- "num_cpus",
-]
-
-[[package]]
-name = "rendering"
-version = "0.1.0"
-dependencies = [
- "crossbeam",
- "image",
- "rand",
- "rand_pcg",
-]
-
-[[package]]
-name = "scoped_threadpool"
-version = "0.1.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8"
-
-[[package]]
-name = "scopeguard"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
-
-[[package]]
-name = "tiff"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a53f4706d65497df0c4349241deddf35f84cee19c87ed86ea8ca590f4464437"
-dependencies = [
- "jpeg-decoder",
- "miniz_oxide 0.4.3",
- "weezl",
-]
-
-[[package]]
-name = "wasi"
-version = "0.10.2+wasi-snapshot-preview1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
-
-[[package]]
-name = "weezl"
-version = "0.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4a32b378380f4e9869b22f0b5177c68a5519f03b3454fde0b291455ddbae266c"
diff --git a/Cargo.toml b/Cargo.toml
deleted file mode 100644
index 629e22f..0000000
--- a/Cargo.toml
+++ /dev/null
@@ -1,13 +0,0 @@
-[package]
-name = "rendering"
-version = "0.1.0"
-authors = ["Julian T <julian@jtle.dk>"]
-edition = "2018"
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
-image = "0.23.12"
-rand = "0.8.3"
-rand_pcg = "0.3.0"
-crossbeam = "0.8.0"
diff --git a/generated.png b/generated.png
index 946d096..8e36d3b 100644
Binary files a/generated.png and b/generated.png differ
diff --git a/readme.md b/readme.md
deleted file mode 100644
index b4691be..0000000
--- a/readme.md
+++ /dev/null
@@ -1,25 +0,0 @@
-# Rendering in rust
-
-This is a (not finished) ray tracer written in rust.
-It is based on the book serie [Ray Tracing In One Weekend](https://raytracing.github.io/) and [Physics Based Rendering](http://www.pbr-book.org/).
-
-This rust version is my third implementation, the previous being:
-
-
-- [Raytracing in c](https://git.jtle.dk/raytrace/about/)
-    This is the one which gives the best results,
-    however as my ambitions for the project grew as did my requirement for more language features.
-- [Pathtracing in c++](https://github.com/jbjjbjjbj/rendering/tree/old_master)
-I never really finished it before changing to rust.
-    However it had a really cool qt gui, updating as samples were added.
-
-## Rendered image
-
-![render](https://raw.githubusercontent.com/jbjjbjjbj/rendering/rendered/generated.png)
-
-## Goals
-
-- [X] Render collection of circles outside, with blurry background
-- [ ] Render [Cornell box](https://en.wikipedia.org/wiki/Cornell_box)
-- [ ] Render [Utah teapot](https://en.wikipedia.org/wiki/Utah_teapot)
-- [ ] Render [Stanford dragon](https://en.wikipedia.org/wiki/Stanford_dragon)
diff --git a/src/camera/camera.rs b/src/camera/camera.rs
deleted file mode 100644
index 7f9e79d..0000000
--- a/src/camera/camera.rs
+++ /dev/null
@@ -1,135 +0,0 @@
-//! Generates rays from screen coordinates
-//!
-//! Generates rays in world space from screen coordinates.
-//! Future versions should also simulate depth of field.
-//!
-//! # Examples
-//!
-//! ```
-//! use rendering::camera::{CameraSettings, Camera};
-//! use rendering::core::{Vector3f, Vector2f, Vector2i};
-//! use rendering::sample::UniformSampler;
-//!
-//! let set = CameraSettings {
-//!     origin: Vector3f::new(10.0),
-//!     target: Vector3f::new(0.0),
-//!     up: Vector3f::new_xyz(0.0, 1.0, 0.0),
-//!     fov: 90.0, 
-//!     filmsize: Vector2i::new(10),
-//!     focus: None,
-//!     aperture: None,
-//! };
-//!
-//! let cam = Camera::new(&set);
-//! let mut sampler = UniformSampler::new();
-//!
-//! let (r, _) = cam.generate_ray(&Vector2f::new(5.0), &mut sampler);
-//! let dir = r.direction;
-//!
-//! assert!(
-//!     dir.x == -0.6031558065478413 &&
-//!     dir.y == -0.6599739684616743 &&
-//!     dir.z == -0.4479257014065748
-//!     );
-//!
-//! ```
-use crate::Float;
-use crate::core::{Vector3f, Vector2f, Vector2i, Ray};
-use crate::sample::Sampler;
-
-/// A simple perspective camera
-pub struct Camera {
-    /// The camera origin in the screen
-    origin: Vector3f,
-    /// Vector from camera origin to the screen lower left corner of the film plane
-    screen_origin: Vector3f,
-    /// Scaling vectors from screen_origin
-    qx: Vector3f,
-    qy: Vector3f,
-
-    /// Value for depth of view
-    lens_radius: Option<Float>,
-}
-
-/// Settings for initializing camera
-pub struct CameraSettings {
-    /// Where rays originate from
-    pub origin: Vector3f,
-    /// Point where center of image is pointed at
-    pub target: Vector3f,
-    /// Vector that will be up in the resulting image
-    pub up: Vector3f,
-    /// The vertical field of view in degrees.
-    /// Currently must be between [0; 180[.
-    pub fov: Float,
-    /// The film aspect ratio, height / width
-    pub filmsize: Vector2i,
-    /// The lens aperture
-    ///
-    /// Depth of view is disabled if None
-    pub aperture: Option<Float>,
-    /// The distance to the focus plane
-    ///
-    /// if None it will be set to the distance between origin and target
-    pub focus: Option<Float>,
-}
-
-impl Camera {
-    /// Create a new camera look at a target
-    pub fn new(set: &CameraSettings) -> Camera {
-        let filmsize = Vector2f::from(set.filmsize);
-        // Calculate translation vectors
-        let mut forward = set.target - set.origin;
-
-        let focus = set.focus.unwrap_or_else(|| forward.length());
-
-        forward.norm_in();
-
-        let right = set.up.cross(&forward).norm();
-        let newup = forward.cross(&right).norm();
-
-        let aspect = (filmsize.y) / (filmsize.x);
-        // Calculate screen size from fov and focus distance
-        let width = 2.0 * focus * (set.fov / 2.0).to_radians().tan();
-        let height = aspect * width;
-
-        // Calculate screen scaling vectors
-        let qx = right * (width / (filmsize.x - 1.0));
-        let qy = newup * (height / (filmsize.y - 1.0));
-
-        let screen_origin = forward * focus - (right * (width/2.0)) + (newup * (height/2.0));
-
-        Camera {
-            origin: set.origin,
-            screen_origin,
-            qx,
-            qy,
-            lens_radius: set.aperture.map(|a| a / 2.0),
-        }
-    }
-
-    /// Generates a ray a screen space point
-    ///
-    /// The point coordinates should be between [0,1) with (0, 0) being the upper left corner
-    ///
-    /// Will return a ray and a weight
-    ///
-    /// The direction of the returned way is normalized
-    pub fn generate_ray(&self, point: &Vector2f, sampler: &mut dyn Sampler) -> (Ray, Float) {
-        // Depth of view origin offset
-        let ooffset = match self.lens_radius {
-            Some(r) => {
-                let rand_dir = sampler.get_in_circle() * r;
-                self.qx * rand_dir.x + self.qy * rand_dir.y
-            },
-            None => Vector3f::ZERO,
-        };
-
-        let dir = self.screen_origin + (self.qx * point.x) - (self.qy * point.y) - ooffset;
-
-        (
-            Ray { origin: self.origin + ooffset, direction: dir.norm() },
-            1.0
-            )
-    }
-}
diff --git a/src/camera/film.rs b/src/camera/film.rs
deleted file mode 100644
index 852ae9e..0000000
--- a/src/camera/film.rs
+++ /dev/null
@@ -1,145 +0,0 @@
-use crate::core::*;
-use crate::Float;
-use image::{RgbImage, Rgb};
-
-/// Contains the necesary values when doing calculations
-///
-/// This is not the final RGB value
-#[derive(Clone)]
-pub struct Pixel {
-    /// The sum of the collected samples
-    rgb: Spectrum,
-    /// The amount of samples collected
-    samples: u32,
-}
-
-pub struct Film {
-    pub size: Vector2i,
-    pub frame: Bound2i,
-
-    pixels: Vec<Pixel>,
-}
-
-/// FilmTile is a small version of the Film used when rendering
-///
-/// This means that multiple threads can work on the same area and commit their changed when they
-/// are done.
-pub struct FilmTile {
-    pub bounds: Bound2i,
-    pub size: Vector2i,
-
-    pixels: Vec<Pixel>,
-}
-
-impl Pixel {
-    fn new() -> Pixel {
-        Pixel {
-            rgb: Default::default(),
-            samples: 0,
-        }
-    }
-
-    fn add(&mut self, c: &Spectrum, weight: Float) {
-        self.rgb += &(*c * weight);
-        self.samples += 1;
-    }
-
-    fn finalize_rgb(&self) -> [u8; 3] {
-        let spc = (self.rgb / (self.samples as Float)).gamma_correct();
-        let (r, g, b) = spc.to_rgb(255.0);
-        [
-            r as u8,
-            g as u8,
-            b as u8,
-        ]
-    }
-}
-
-impl std::ops::AddAssign<&Self> for Pixel {
-    fn add_assign(&mut self, op: &Self) {
-        self.rgb += &op.rgb;
-        self.samples += op.samples;
-    }
-}
-
-impl Film {
-    pub fn new(size: Vector2i) -> Film {
-        let area = size.x * size.y;
-        Film {
-            size,
-            frame: Bound2i::new(&Vector2i::new(0), &size),
-            pixels: vec![Pixel::new(); area as usize],
-        }
-    }
-
-    /// Creates a new FilmTile from the specified bounds
-    ///
-    /// This tile can later be commited with the commit_tile function
-    pub fn get_tile(&self, bound: &Bound2i) -> FilmTile {
-        FilmTile::new(
-            bound,
-        )
-
-    }
-
-    /// Commit a tile back on the film
-    ///
-    /// This will lock the Film while the changes from the Tile is written
-    pub fn commit_tile(&mut self, tile: &FilmTile) {
-        let offset = tile.bounds.min;
-
-        for y in 0 .. tile.size.y {
-            let rowindex = (offset.y + y) * self.size.x;
-            let prowindex = y * tile.size.x;
-
-            for x in 0 .. tile.size.x {
-                let index = offset.x + x + rowindex;
-                let pindex: i32 = x + prowindex;
-
-                self.pixels[index as usize] += &tile.pixels[pindex as usize];
-            }
-        }
-    }
-
-    pub fn finalize_image(&self) -> RgbImage {
-        let mut img = RgbImage::new(self.size.x as u32, self.size.y as u32);
-
-        for y in 0..self.size.y {
-            let index = y * self.size.x;
-            for x in 0..self.size.x {
-                img.put_pixel(
-                    x as u32, 
-                    y as u32, 
-                    Rgb(self.pixels[(index + x) as usize].finalize_rgb()),
-                    );
-            }
-        }
-
-        img
-    }
-}
-
-impl FilmTile {
-    fn new(bounds: &Bound2i) -> FilmTile {
-        FilmTile {
-            bounds: bounds.clone(),
-            pixels: vec![Pixel::new(); bounds.area() as usize],
-            size: bounds.diagonal(),
-        }
-    }
-
-    /// Add a single sample sampled from the scene
-    pub fn add_sample(&mut self, inp: &Vector2f, c: Spectrum) {
-        let point = Vector2i::from(inp.floor());
-        // Subtract the offset
-        let point = (point - self.bounds.min).cap(self.size.x-1, self.size.y-1);
-
-        let index = point.x + point.y * self.size.x;
-
-        if let Some(pixel) = self.pixels.get_mut(index as usize) {
-            pixel.add(&c, 1.0);
-        } else {
-            println!("Could not get pixel {} inp: {}, index: {}", point, inp, index);
-        }
-    }
-}
diff --git a/src/camera/filter/mod.rs b/src/camera/filter/mod.rs
deleted file mode 100644
index 01d094c..0000000
--- a/src/camera/filter/mod.rs
+++ /dev/null
@@ -1,32 +0,0 @@
-use crate::vector::Vector2f;
-use crate::Float;
-
-trait Eval {
-    fn eval(&self, point: &Vector2f) -> Float;
-}
-
-pub struct Filter {
-    eval: Box<dyn Eval>,
-    pub radius: Vector2f,
-}
-
-struct BoxFilter {}
-
-// The same a no filter, and can give aliasing in final image
-impl Eval for BoxFilter {
-    fn eval(&self, _: &Vector2f) -> Float {
-        1.0
-    }
-}
-
-impl Eval for Filter {
-    fn eval(&self, point: &Vector2f) -> Float {
-        self.eval.eval(point)
-    }
-}
-
-impl Filter {
-    pub fn new_box(radius: Vector2f) -> Filter {
-        Filter { radius: radius, eval: Box::new(BoxFilter {}) }
-    }
-}
diff --git a/src/camera/mod.rs b/src/camera/mod.rs
deleted file mode 100644
index 999b5b5..0000000
--- a/src/camera/mod.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-//! Implements how light is captured on film and how rays are generated
-//!
-//! The Film module specifies how calculated spectrum values contribute to the final image.
-//!
-//! The Camera class generated rays that can be cast into the scene.
-//! This requires converting the film coordinates into real coordinates
-
-pub mod film;
-//pub mod filter;
-mod camera;
-
-pub use camera::{Camera, CameraSettings};
-pub use film::Film;
diff --git a/src/core/bound2.rs b/src/core/bound2.rs
deleted file mode 100644
index bc0e7cd..0000000
--- a/src/core/bound2.rs
+++ /dev/null
@@ -1,127 +0,0 @@
-//! Implements a 2d axis aligned bounding box
-use crate::{Number, Float};
-use super::vector2::Vector2;
-use crate::core;
-use crate::core::{min, max};
-
-/// Implements a region between min and max
-#[derive(Clone)]
-pub struct Bound2<T: Number> {
-    pub min: Vector2<T>,
-    pub max: Vector2<T>
-}
-
-pub type Bound2i = Bound2<i32>;
-pub type Bound2f = Bound2<Float>;
-
-impl<T: Number> Bound2<T> {
-    /// Creates a new bound from two points
-    ///
-    /// p0 does not have to be smaller than p1
-    pub fn new(p0: &Vector2<T>, p1: &Vector2<T>) -> Self {
-        let min = Vector2::new_xy(min(p0.x, p1.x), min(p0.y, p1.y));
-        let max = Vector2::new_xy(max(p0.x, p1.x), max(p0.y, p1.y));
-
-        Self { min, max }
-    }
-
-    pub fn new_xyxy(x1: T, y1: T, x2: T, y2: T) -> Self {
-        Self::new(
-            &Vector2::new_xy(x1, y1),
-            &Vector2::new_xy(x2, y2),
-            )
-    }
-
-    /// Finds the intersected area between two bounds
-    pub fn intersect(&self, b: &Bound2<T>) -> Bound2<T> {
-        Bound2::new(
-            &Vector2::new_xy(max(self.min.x, b.min.x), max(self.min.y, b.min.y)),
-            &Vector2::new_xy(min(self.max.x, b.max.x), min(self.max.y, b.max.y)),
-            )
-    }
-
-
-    /// Calculates the diagonal vector
-    ///
-    /// Can be used to calculate the size of the bound
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use rendering::core::Bound2i;
-    /// let b = Bound2i::new_xyxy(2, 2, 6, 7);
-    /// let diag = b.diagonal();
-    ///
-    /// assert!(diag.x == 4 && diag.y == 5);
-    /// ```
-    pub fn diagonal(&self) -> Vector2<T> {
-        self.max - self.min
-    }
-
-    /// Calculates the area of of the bounded region
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use rendering::core::Bound2i;
-    /// let b = Bound2i::new_xyxy(10, 10, 20, 20);
-    /// 
-    /// assert!(b.area() == 100);
-    /// ```
-    pub fn area(&self) -> T {
-        let diag = self.diagonal();
-        diag.x * diag.y
-    }
-}
-
-impl From<&Bound2i> for Bound2f {
-    fn from(b: &Bound2i) -> Self {
-        Self {
-            min: core::Vector2f::from(b.min),
-            max: core::Vector2f::from(b.max),
-        }
-    }
-}
-
-impl From<&Bound2f> for Bound2i {
-    fn from(b: &Bound2f) -> Self {
-        Self {
-            min: core::Vector2i::from(b.min),
-            max: core::Vector2i::from(b.max),
-        }
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    fn create_test() -> Bound2<i32> {
-        Bound2::new(
-            &Vector2::new_xy(1, 2),
-            &Vector2::new_xy(10, 3)
-            )
-    }
-
-    #[test]
-    fn area() {
-        let b = create_test();
-
-        assert!(b.area() == 9);
-    }
-
-    #[test]
-    fn intersect_test() {
-        let b1 = Bound2i::new_xyxy(10, 10, 20, 20);
-        let b2 = Bound2i::new_xyxy(2, 11, 22, 17);
-
-        let b = b1.intersect(&b2);
-
-        assert!(
-            b.min.x == 10 &&
-            b.min.y == 11 &&
-            b.max.x == 20 &&
-            b.max.y == 17
-            )
-    }
-}
diff --git a/src/core/bound3.rs b/src/core/bound3.rs
deleted file mode 100644
index ce6bb09..0000000
--- a/src/core/bound3.rs
+++ /dev/null
@@ -1,113 +0,0 @@
-//! Implements 3d axis aligned bounding box
-use crate::{Number, Float};
-use super::vector3::{Vector3, Vector3f};
-use crate::core::{min, max};
-use crate::core::Ray;
-
-#[derive(Clone)]
-pub struct Bound3<T: Number> {
-    pub min: Vector3<T>,
-    pub max: Vector3<T>
-}
-
-pub type Bound3f = Bound3<Float>;
-
-impl<T: Number> Bound3<T> {
-    /// Creates a bound from two points
-    pub fn new(p0: Vector3<T>, p1: Vector3<T>) -> Self {
-        // Elliminate some code duplication here
-        let min = Vector3::new_xyz(
-            min(p0.x, p1.x),
-            min(p0.y, p1.y),
-            min(p0.z, p1.z)
-            );
-        let max = Vector3::new_xyz(
-            max(p0.x, p1.x),
-            max(p0.y, p1.y),
-            max(p0.z, p1.z)
-            );
-
-        Self {min, max}
-    }
-
-    pub fn combine(&self, op: &Self) -> Self {
-        let min = Vector3::new_xyz(
-            min(self.min.x, op.min.x),
-            min(self.min.y, op.min.y),
-            min(self.min.z, op.min.z)
-            );
-        let max = Vector3::new_xyz(
-            max(self.max.x, op.max.x),
-            max(self.max.y, op.max.y),
-            max(self.max.z, op.max.z)
-            );
-
-        Self {min, max}
-    }
-
-    pub fn and(&self, op: &Self) -> Self {
-        let min_b = Vector3::new_xyz(
-            max(self.min.x, op.min.x),
-            max(self.min.y, op.min.y),
-            max(self.min.z, op.min.z)
-            );
-        let max_b = Vector3::new_xyz(
-            min(self.max.x, op.max.x),
-            min(self.max.y, op.max.y),
-            min(self.max.z, op.max.z)
-            );
-
-        Self {min: min_b, max: max_b}
-    }
-
-    pub fn area(&self) -> T {
-        let diag = self.max - self.min;
-        diag.x * diag.y * diag.z
-    }
-}
-
-impl Bound3f {
-    pub const EMPTY: Bound3f = Bound3f{min: Vector3f::ZERO, max: Vector3f::ZERO};
-
-    /// Calculate whether there is a intersect between a bounding box and a ray
-    ///
-    /// # Examples:
-    ///
-    /// ```
-    /// use rendering::core::{Bound3f, Vector3f, Ray};
-    /// use rendering::INFTY;
-    /// let b = Bound3f::new(Vector3f::new(7.0), Vector3f::new(10.0));
-    /// let r1 = Ray::new_to(Vector3f::new(0.0), Vector3f::new(5.0));
-    /// let r2 = Ray::new_to(Vector3f::new(-0.0), Vector3f::new(-5.0));
-    /// let r3 = Ray::new(Vector3f::new_xyz(-1.0, 0.0, 0.0), Vector3f::new_xyz(1.0, 0.0, 0.0));
-    ///
-    /// assert!(b.intersect(&r1, 0.0, INFTY));
-    /// assert!(!b.intersect(&r2, 0.0, INFTY));
-    /// assert!(!b.intersect(&r3, 0.0, INFTY));
-    /// ```
-    pub fn intersect(&self, ray: &Ray, t_min: Float, t_max: Float) -> bool {
-        println!("BIN: {} -> {}", self.min, self.max);
-        // Method stolen from Ray tracing the next week.
-        // They mention its from pixar
-        for i in 0..3 {
-            let inv = 1.0 / ray.direction[i];
-            let mut t0 = (self.min[i] - ray.origin[i]) * inv;
-            let mut t1 = (self.max[i] - ray.origin[i]) * inv;
-
-            if inv < 0.0 {
-                let tmp = t0;
-                t0 = t1;
-                t1 = tmp;
-            }
-
-            let t_min = max(t0, t_min);
-            let t_max = min(t1, t_max);
-
-            if t_max <= t_min {
-                return false;
-            }
-        }
-
-        return true;
-    }
-}
diff --git a/src/core/mod.rs b/src/core/mod.rs
deleted file mode 100644
index 95d450c..0000000
--- a/src/core/mod.rs
+++ /dev/null
@@ -1,34 +0,0 @@
-//! Contains a collection of core modules used by other modules
-//!
-//! Also creates a shortcut for some common types
-
-mod vector2;
-mod vector3;
-mod bound2;
-mod bound3;
-mod spectrum;
-mod ray;
-
-pub use vector2::{Vector2i, Vector2f};
-pub use vector3::Vector3f;
-pub use bound2::{Bound2i, Bound2f};
-pub use bound3::Bound3f;
-pub use spectrum::Spectrum;
-pub use ray::Ray;
-
-use crate::Number;
-
-pub fn min<T: Number> (a: T, b: T) -> T {
-    if b < a {
-        return b;
-    }
-    a
-}
-
-pub fn max<T: Number> (a: T, b: T) -> T {
-    if b > a {
-        return b;
-    }
-    a
-}
-
diff --git a/src/core/ray.rs b/src/core/ray.rs
deleted file mode 100644
index 19d3cf1..0000000
--- a/src/core/ray.rs
+++ /dev/null
@@ -1,35 +0,0 @@
-//! The ray class used when probing the 3d scene
-use crate::core::Vector3f;
-use crate::Float;
-
-/// A ray that is sent into the world.
-/// This is the main type used for testing intersections.
-pub struct Ray {
-    /// Origin of the ray
-    pub origin: Vector3f,
-    /// Direction is assumed to be a unit vector.
-    pub direction: Vector3f,
-}
-
-impl Ray {
-    pub fn new(origin: Vector3f, direction: Vector3f) -> Ray {
-        Ray {
-            origin,
-            direction,
-        }
-    }
-
-    pub fn new_to(origin: Vector3f, target: Vector3f) -> Ray {
-        let dir = (target - origin).norm();
-        Ray {
-            origin,
-            direction: dir
-        }
-    }
-
-    /// Resolve a point on the ray at time t
-    pub fn at(&self, t: Float) -> Vector3f {
-        self.origin + self.direction * t
-    }
-}
-
diff --git a/src/core/spectrum.rs b/src/core/spectrum.rs
deleted file mode 100644
index ed3505b..0000000
--- a/src/core/spectrum.rs
+++ /dev/null
@@ -1,88 +0,0 @@
-//! Used to represent color
-//!
-//! Currently only implements RGB colors
-use crate::Float;
-
-// TODO implement SampledSpectrum instead for nicer images
-
-#[derive(Clone, Copy, Default)]
-pub struct Spectrum {
-    c: [Float; 3],
-}
-
-impl Spectrum {
-    pub const ZERO: Self = Spectrum { c: [0.0; 3] };
-    pub const WHITE: Self = Spectrum { c: [1.0; 3] };
-
-    pub fn new_rgb(r: Float, g: Float, b: Float) -> Spectrum {
-        Spectrum { c: [r, g, b] }
-    }
-
-    pub fn to_rgb(&self, scale: Float) -> (Float, Float, Float) {
-        (self.c[0] * scale, self.c[1] * scale, self.c[2] * scale)
-    }
-
-    pub fn gamma_correct(&self) -> Self {
-        Self::new_rgb(
-            self.c[0].sqrt(),
-            self.c[1].sqrt(),
-            self.c[2].sqrt(),
-            )
-    }
-}
-
-impl std::ops::Mul<Float> for Spectrum {
-    type Output = Spectrum;
-
-    fn mul(self, op: Float) -> Self::Output {
-        Self::Output::new_rgb(
-            self.c[0] * op,
-            self.c[1] * op,
-            self.c[2] * op,
-            )
-    }
-}
-
-impl std::ops::Mul for Spectrum {
-    type Output = Spectrum;
-
-    fn mul(self, op: Self) -> Self::Output {
-        Self::Output::new_rgb(
-            self.c[0] * op.c[0],
-            self.c[1] * op.c[1],
-            self.c[2] * op.c[2],
-            )
-    }
-}
-
-impl std::ops::Div<Float> for Spectrum {
-    type Output = Spectrum;
-
-    fn div(self, op: Float) -> Self::Output {
-        Self::Output::new_rgb(
-            self.c[0] / op,
-            self.c[1] / op,
-            self.c[2] / op,
-            )
-    }
-}
-
-impl std::ops::Add for Spectrum {
-    type Output = Spectrum;
-
-    fn add(self, op: Self) -> Self::Output {
-        Self::Output::new_rgb(
-            self.c[0] + op.c[0],
-            self.c[1] + op.c[1],
-            self.c[2] + op.c[2],
-            )
-    }
-}
-
-impl std::ops::AddAssign<&Self> for Spectrum {
-    fn add_assign(&mut self, op: &Self) {
-        self.c[0] += op.c[0];
-        self.c[1] += op.c[1];
-        self.c[2] += op.c[2];
-    }
-}
diff --git a/src/core/vector2.rs b/src/core/vector2.rs
deleted file mode 100644
index 405b12a..0000000
--- a/src/core/vector2.rs
+++ /dev/null
@@ -1,167 +0,0 @@
-//! Implements 2d vectors
-//!
-//! This is implemented generictly with types that fit in the Number trait
-use crate::{Float, Number};
-use std::ops::{Sub, Add, Mul, Div};
-use std::fmt;
-use std::cmp::min;
-
-#[derive(Clone, Copy)]
-pub struct Vector2<T: Number> {
-    pub x: T,
-    pub y: T,
-}
-
-pub type Vector2f = Vector2<Float>;
-pub type Vector2i = Vector2<i32>;
-
-
-impl<T: Number> Vector2<T> {
-    pub fn new(initial: T) -> Vector2<T> {
-        Vector2 { x: initial, y: initial }
-    }
-
-    pub fn new_xy(x: T, y: T) -> Vector2<T> {
-        Vector2 { x, y }
-    }
-}
-
-impl<T: Number> Sub for Vector2<T> {
-    type Output = Self;
-    fn sub(self, op: Self) -> Self::Output {
-        Self::new_xy(
-            self.x - op.x,
-            self.y - op.y,
-        )
-    }
-}
-
-impl<T: Number> Add for Vector2<T> {
-    type Output = Self;
-    fn add(self, op: Self) -> Self::Output {
-        Self::new_xy(
-            self.x + op.x,
-            self.y + op.y,
-        )
-    }
-}
-
-impl<T: Number> Mul for Vector2<T> {
-    type Output = Self;
-    fn mul(self, op: Self) -> Self::Output {
-        Self::new_xy(
-            self.x * op.x,
-            self.y * op.y,
-        )
-    }
-}
-
-impl<T: Number> Mul<T> for Vector2<T> {
-    type Output = Self;
-    fn mul(self, op: T) -> Self::Output {
-        Self::new_xy(
-            self.x * op,
-            self.y * op,
-        )
-    }
-}
-
-impl<T: Number> Div for Vector2<T> {
-    type Output = Self;
-    fn div(self, op: Self) -> Self::Output {
-        Self::new_xy(
-            self.x / op.x,
-            self.y / op.y,
-        )
-    }
-}
-
-impl<T: Number> fmt::Display for Vector2<T> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.write_fmt(format_args!("[{}, {}]", self.x, self.y))
-    }
-}
-
-impl From<Vector2i> for Vector2f {
-    fn from(v: Vector2i) -> Self {
-        Self {
-            x: v.x as Float,
-            y: v.y as Float,
-        }
-    }
-}
-
-impl From<Vector2f> for Vector2i {
-    fn from(v: Vector2f) -> Self {
-        Self {
-            x: v.x as i32,
-            y: v.y as i32,
-        }
-    }
-}
-
-impl Vector2i {
-    pub const ZERO: Self = Vector2i {x: 0, y: 0};
-
-    pub fn cap(&self, x: i32, y: i32) -> Self {
-        Self::new_xy(
-            min(self.x, x),
-            min(self.y, y),
-            )
-    }
-}
-
-impl Vector2f {
-    pub fn length(&self) -> Float {
-        (self.x*self.x + self.y*self.y).sqrt()
-    }
-
-    pub fn ceil(&self) -> Self {
-        Self::new_xy(
-            self.x.ceil(),
-            self.y.ceil()
-            )
-    }
-
-    pub fn floor(&self) -> Self {
-        Self::new_xy(
-            self.x.floor(),
-            self.y.floor()
-            )
-    }
-}
-
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    #[test]
-    fn new_vec2() {
-        let v = Vector2::new_xy(2.0, 10.0);
-
-        assert!(v.x == 2.0 && v.y == 10.0);
-
-        let v = Vector2::new(3);
-
-        assert!(v.x == 3 && v.y == 3);
-    }
-
-    #[test]
-    fn sub_vec2() {
-        let v1 = Vector2::new_xy(10, 11);
-        let v2 = Vector2::new_xy(2, 3);
-
-        let v3 = v1-v2;
-        assert!(v3.x == 8 && v3.y == 8);
-    }
-
-    #[test]
-    fn add_vec2() {
-        let v1 = Vector2::new_xy(10, 11);
-        let v2 = Vector2::new_xy(2, 3);
-
-        let v3 = v1+v2;
-        assert!(v3.x == 12 && v3.y == 14);
-    }
-}
diff --git a/src/core/vector3.rs b/src/core/vector3.rs
deleted file mode 100644
index 1cc6f60..0000000
--- a/src/core/vector3.rs
+++ /dev/null
@@ -1,185 +0,0 @@
-//! Implements 3d vectors
-//!
-//! Also add more 3d math things needed for shading and 3d calculations.
-use crate::{Float, Number, NEAR_ZERO};
-use std::ops::{Mul, Sub, Add, DivAssign, Neg, AddAssign, Index};
-use std::fmt;
-
-#[derive(Clone, Copy)]
-pub struct Vector3<T: Number> {
-    pub x: T,
-    pub y: T,
-    pub z: T,
-}
-
-pub type Vector3f = Vector3<Float>;
-
-impl<T: Number> Vector3<T> {
-    pub fn new(initial: T) -> Vector3<T> {
-        Vector3 { 
-            x: initial,
-            y: initial,
-            z: initial,
-        }
-    }
-
-    pub fn new_xyz(x: T, y: T, z: T) -> Vector3<T> {
-        Vector3 { x, y, z}
-    }
-}
-
-impl<T: Number> Sub for Vector3<T> {
-    type Output = Self;
-    fn sub(self, op: Self) -> Self::Output {
-        Self::new_xyz(
-            self.x - op.x,
-            self.y - op.y,
-            self.z - op.z,
-        )
-    }
-}
-
-impl<T: Number> Add for Vector3<T> {
-    type Output = Self;
-    fn add(self, op: Self) -> Self::Output {
-        Self::new_xyz(
-            self.x + op.x,
-            self.y + op.y,
-            self.z + op.z,
-        )
-    }
-}
-
-impl<T: Number> Add<T> for Vector3<T> {
-    type Output = Self;
-
-    fn add(self, op: T) -> Self::Output {
-        Self::new_xyz(
-            self.x + op,
-            self.y + op,
-            self.z + op,
-        )
-    }
-}
-
-impl<T: Number> Mul<T> for Vector3<T> {
-    type Output = Self;
-    fn mul(self, op: T) -> Self::Output {
-        Self::Output::new_xyz(
-            self.x * op,
-            self.y * op,
-            self.z * op,
-            )
-    }
-}
-
-impl<T: Number> Neg for Vector3<T> {
-    type Output = Self;
-
-    fn neg(self) -> Self::Output {
-        Self::Output::new_xyz(
-            -self.x,
-            -self.y,
-            -self.z,
-            )
-    }
-}
-
-impl<T: Number> AddAssign<&Self> for Vector3<T> {
-    fn add_assign(&mut self, op: &Self) {
-        self.x += op.x;
-        self.y += op.y;
-        self.z += op.z;
-    }
-}
-
-impl<T: Number> DivAssign<T> for Vector3<T> {
-    fn div_assign(&mut self, op: T) {
-        self.x /= op;
-        self.y /= op;
-        self.z /= op;
-    }
-}
-
-impl<T: Number> fmt::Display for Vector3<T> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.write_fmt(format_args!("[{}, {}, {}]", self.x, self.y, self.z))
-    }
-}
-
-// Ohh god
-impl<T: Number> Index<u32> for Vector3<T> {
-    type Output = T;
-
-    fn index(&self, i: u32) -> &Self::Output {
-        match i {
-            0 => &self.x,
-            1 => &self.y,
-            2 => &self.z,
-            _ => panic!("index out of bounds: index {} is not possible with 3d vector", i)
-        }
-    }
-}
-
-impl Vector3f {
-    pub const ZERO: Self = Vector3f {x: 0.0, y: 0.0, z: 0.0};
-
-    /// Calculates the length times itself
-    ///
-    /// This is faster than using len * len as the square is ommited
-    pub fn len_squared(&self) -> Float {
-        self.x * self.x + self.y * self.y + self.z * self.z
-    }
-
-    pub fn length(&self) -> Float {
-        self.len_squared().sqrt()
-    }
-
-    pub fn dot(&self, op: &Self) -> Float {
-        self.x * op.x + self.y * op.y + self.z * op.z
-    }
-
-    /// Inplace normal instead of creating a new vector
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use rendering::core::Vector3f;
-    /// let mut v = Vector3f::new_xyz(10.0, 0.0, 0.0);
-    /// v.norm_in();
-    /// assert!(v.x == 1.0);
-    /// ```
-    pub fn norm_in(&mut self) {
-        // TODO Experiment with checking for normality with len_squared
-        let len = self.length();
-        if len == 0.0 {
-            *self = Self::new(0.0);
-        }
-
-        *self /= len;
-    }
-
-    pub fn norm(&self) -> Self {
-        let mut new = *self;
-        new.norm_in();
-        new
-    }
-
-    pub fn cross(&self, op: &Self) -> Self {
-        Self::new_xyz(
-            self.y * op.z - self.z * op.y,
-            self.z * op.x - self.x * op.z,
-            self.x * op.y - self.y * op.x,
-            )
-
-    }
-
-    /// Check if vector is close to [0, 0, 0]
-    ///
-    /// This is based on the NEAR_ZERO constant
-    pub fn near_zero(&self) -> bool {
-        (self.x.abs() < NEAR_ZERO) &&
-            (self.y.abs() < NEAR_ZERO) &&
-            (self.z.abs() < NEAR_ZERO)
-    }
-}
diff --git a/src/lib.rs b/src/lib.rs
deleted file mode 100644
index 0e6674d..0000000
--- a/src/lib.rs
+++ /dev/null
@@ -1,41 +0,0 @@
-pub mod core;
-pub mod camera;
-pub mod render;
-pub mod world;
-pub mod trace;
-pub mod sample;
-pub mod material;
-
-use std::ops::{Add, Sub, Mul, DivAssign, AddAssign, Neg, Div};
-use std::cmp;
-use std::fmt;
-use std::f64::consts::PI;
-
-/// Trait used to implement generics
-///
-/// This is used in Bound and Vectors
-pub trait Number:
-    Copy +
-    cmp::PartialOrd +
-    Sub<Output = Self> +
-    Add<Output = Self> +
-    Mul<Output = Self> +
-    Neg<Output = Self> + 
-    Div<Output = Self> +
-    DivAssign +
-    AddAssign +
-    fmt::Display
-{}
-
-impl Number for i32 {}
-impl Number for f32 {}
-impl Number for f64 {}
-
-/// Used for representing floating point values throughout the program
-/// 
-/// A higher precision type will require more ram
-pub type Float = f64;
-
-pub const M_PI: Float = PI;
-pub const NEAR_ZERO: Float = 1e-8;
-pub const INFTY: Float = f64::INFINITY;
diff --git a/src/main.rs b/src/main.rs
deleted file mode 100644
index dd67fdc..0000000
--- a/src/main.rs
+++ /dev/null
@@ -1,63 +0,0 @@
-use rendering::camera::{Camera, Film, CameraSettings};
-use rendering::world::{Scene, Object, shapes::Sphere};
-use rendering::trace::DefaultTracer;
-use rendering::core::{Vector2i, Vector3f, Spectrum};
-use rendering::render::{RenderContext, RenderCoord};
-use rendering::sample::UniformSampler;
-use rendering::material::*;
-
-use std::sync::Arc;
-
-fn main() {
-    let res = Vector2i::new_xy(500, 500);
-
-    let cam = Camera::new(&CameraSettings {
-        target: Vector3f::new_xyz(0.0, 0.0, -1.0),
-        origin: Vector3f::new_xyz(0.0, 0.0, 1.0),
-        up: Vector3f::new_xyz(0.0, 1.0, 0.0),
-        fov: 45.0, 
-        filmsize: res,
-        focus: None,
-        aperture: Some(10.0),
-        //aperture: None,
-    });
-
-    let brown = Arc::new(Lambertian::new(Spectrum::new_rgb(0.5, 0.3, 0.0)));
-    let blue = Arc::new(Lambertian::new(Spectrum::new_rgb(0.0, 0.3, 0.7)));
-    let green = Arc::new(Lambertian::new(Spectrum::new_rgb(0.0, 0.7, 0.3)));
-    let metal = Arc::new(Reflectant::new(Spectrum::new_rgb(0.8, 0.8, 0.9), Some(1.0)));
-    let glass = Arc::new(Dielectric::new(1.5));
-    let sun = Arc::new(DiffuseLight::new_white(50.0));
-
-    let mut scn = Scene::new();
-    scn.add_objects(vec![
-        Object::new(glass, Sphere::new(0.2, Vector3f::new_xyz(0.0, 0.0, -1.0))),
-        Object::new(blue, Sphere::new(0.5, Vector3f::new_xyz(1.0, 0.0, -1.5))),
-        Object::new(green, Sphere::new(0.3, Vector3f::new_xyz(0.5, 0.0, -2.5))),
-        Object::new(brown, Sphere::new(100.0, Vector3f::new_xyz(0.0, -100.5, -1.0))),
-        Object::new(metal, Sphere::new(0.2, Vector3f::new_xyz(-0.5, 0.0, -1.0))),
-        Object::new(sun, Sphere::new(0.4, Vector3f::new_xyz(-1.0, 3.0, 0.0))),
-    ]);
-
-    let tracer = DefaultTracer::new(&scn, Some(50), 
-                                    //Some(Box::new(SkyLight::new()))
-                                    None
-                                    );
-
-    let mut sampler = UniformSampler::new();
-
-    let ctx = RenderContext { cam: &cam, trc: &tracer };
-
-    let mut film = Film::new(res);
-    {
-        let coord = RenderCoord::new(&mut film, Vector2i::new_xy(50, 50), 16000);
-
-        coord.run_threaded(&ctx, &mut sampler, 8);
-    }
-
-    let image = film.finalize_image();
-    if let Err(e) = image.save("test.png") {
-        println!("Failed to save {}", e);
-    }
-
-}
diff --git a/src/material/dielectric.rs b/src/material/dielectric.rs
deleted file mode 100644
index c8dc279..0000000
--- a/src/material/dielectric.rs
+++ /dev/null
@@ -1,56 +0,0 @@
-use super::Material;
-use crate::core::{min, Vector3f, Spectrum, Ray};
-use crate::world::Intersection;
-use crate::sample::Sampler;
-use crate::Float;
-use crate::material::reflectant::reflect;
-
-pub struct Dielectric {
-    ratio: Float,
-}
-
-// Implementation from RTIOW
-fn refract(v: Vector3f, n: Vector3f, r_ratio: Float, cos_theta: Float) -> Vector3f {
-    let r_perp = (v + n * cos_theta) * r_ratio;
-    let r_parallel = n * (-(1.0 - r_perp.len_squared()).abs().sqrt());
-
-    r_perp + r_parallel
-}
-
-// Schlick Approximation, explained in RTIOW
-fn fresnel(cos: Float, ratio: Float) -> Float {
-    let mut r0 = (1.0-ratio) / (1.0+ratio);
-    r0 = r0 * r0;
-
-    r0 + (1.0-r0)*(1.0-cos).powi(5)
-}
-
-impl Dielectric {
-    pub fn new(ratio: Float) -> Self {
-        Self { ratio }
-    }
-}
-
-impl Material for Dielectric {
-    // Implementation from RTIOW
-    fn scatter(&self, ray: &Ray, i: &Intersection, sampler: &mut dyn Sampler) -> Option<(Spectrum, Ray)> {
-        let ratio = if i.front {1.0/self.ratio} else {self.ratio};
-
-        let ray_dir = ray.direction.norm();
-        let cos_theta = min((-ray_dir).dot(&i.n), 1.0);
-        let sin_theta = (1.0 - cos_theta*cos_theta).sqrt();
-
-        // Test if it is possible for the ray the retract or if it must reflect.
-        let cannot_refract = (ratio * sin_theta) > 1.0;
-        let direction = if cannot_refract || (fresnel(cos_theta, ratio) > sampler.get_sample()) {
-            reflect(ray_dir, i.n)
-        } else {
-            refract(ray_dir, i.n, ratio, cos_theta)
-        };
-
-        Some((
-                Spectrum::WHITE,
-                Ray::new(i.p, direction),
-             ))
-    }
-}
diff --git a/src/material/diffuse_light.rs b/src/material/diffuse_light.rs
deleted file mode 100644
index fe462a8..0000000
--- a/src/material/diffuse_light.rs
+++ /dev/null
@@ -1,27 +0,0 @@
-use super::Material;
-use crate::core::{Ray, Spectrum};
-use crate::Float;
-
-pub struct DiffuseLight {
-    color: Spectrum,
-}
-
-impl DiffuseLight {
-    pub fn new(c: Spectrum) -> Self {
-        Self {
-            color: c,
-        }
-    }
-
-    pub fn new_white(s: Float) -> Self {
-        Self {
-            color: Spectrum::new_rgb(s, s, s),
-        }
-    }
-}
-
-impl Material for DiffuseLight {
-    fn emitted(&self, _: &Ray) -> Option<Spectrum> {
-        Some(self.color)
-    }
-}
diff --git a/src/material/lambertian.rs b/src/material/lambertian.rs
deleted file mode 100644
index 3df6522..0000000
--- a/src/material/lambertian.rs
+++ /dev/null
@@ -1,38 +0,0 @@
-use super::Material;
-use crate::core::{Ray, Spectrum};
-use crate::world::Intersection;
-use crate::sample::Sampler;
-
-use std::rc::Rc;
-
-pub struct Lambertian {
-    color: Spectrum,
-}
-
-impl Lambertian {
-    pub fn new(c: Spectrum) -> Lambertian {
-        Lambertian {
-            color: c,
-        }
-    }
-
-    pub fn new_rc(c: Spectrum) -> Rc<dyn Material> {
-        Rc::new(Self::new(c))
-    }
-}
-
-impl Material for Lambertian {
-    fn scatter(&self, _: &Ray, i: &Intersection, sampler: &mut dyn Sampler) -> Option<(Spectrum, Ray)> {
-        let mut newray = Ray {
-            origin: i.p,
-            direction: i.n + sampler.get_unit_vector(),
-        };
-
-        // Make sure that the resulting direction is not (0, 0, 0)
-        if newray.direction.near_zero() {
-            newray.direction = i.n;
-        }
-
-        Some((self.color, newray))
-    }
-}
diff --git a/src/material/mod.rs b/src/material/mod.rs
deleted file mode 100644
index 6732598..0000000
--- a/src/material/mod.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-use crate::core::{Ray, Spectrum};
-use crate::world::Intersection;
-use crate::sample::Sampler;
-
-mod lambertian;
-mod diffuse_light;
-mod sky_light;
-mod dielectric;
-pub mod reflectant;
-
-pub use lambertian::Lambertian;
-pub use diffuse_light::DiffuseLight;
-pub use sky_light::SkyLight;
-pub use dielectric::Dielectric;
-pub use reflectant::Reflectant;
-
-pub trait Material: Sync + Send {
-    fn scatter(&self, _: &Ray, _: &Intersection, _: &mut dyn Sampler) -> Option<(Spectrum, Ray)> {
-        None
-    }
-
-    fn emitted(&self, _: &Ray) -> Option<Spectrum> {
-        None
-    }
-}
diff --git a/src/material/reflectant.rs b/src/material/reflectant.rs
deleted file mode 100644
index b5ec0ae..0000000
--- a/src/material/reflectant.rs
+++ /dev/null
@@ -1,40 +0,0 @@
-use crate::Float;
-use crate::core::{Ray, Spectrum, Vector3f};
-use crate::world::Intersection;
-use super::Material;
-use crate::sample::Sampler;
-
-pub struct Reflectant {
-    color: Spectrum,
-    fuzz: Option<Float>,
-}
-
-impl Reflectant {
-    pub fn new(c: Spectrum, fuzz: Option<Float>) -> Reflectant {
-        Reflectant {
-            color: c,
-            fuzz,
-        }
-    }
-}
-
-pub fn reflect(v: Vector3f, n: Vector3f) -> Vector3f {
-    v - n * (2.0 * v.dot(&n))
-}
-
-impl Material for Reflectant {
-    fn scatter(&self, ray: &Ray, i: &Intersection, sampler: &mut dyn Sampler) -> Option<(Spectrum, Ray)> {
-        // Find reflectance vector
-        let mut reflected = reflect(ray.direction, i.n);
-        if let Some(fuzz) = self.fuzz {
-            reflected += &(sampler.get_unit_vector() * fuzz);
-        }
-
-        Some((
-                self.color,
-                Ray::new(i.p, reflected.norm()),
-                ))
-    }
-}
-
-
diff --git a/src/material/sky_light.rs b/src/material/sky_light.rs
deleted file mode 100644
index e499b6e..0000000
--- a/src/material/sky_light.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-use super::Material;
-use crate::core::{Ray, Spectrum};
-
-pub struct SkyLight {
-}
-
-impl SkyLight {
-    pub fn new() -> Self {
-        Self {}
-    }
-}
-
-impl Material for SkyLight {
-    fn emitted(&self, ray: &Ray) -> Option<Spectrum> {
-        let t = (ray.direction.norm().y + 1.0) * 0.5;
-
-        Some(Spectrum::new_rgb(1.0, 1.0, 1.0) * (1.0-t) + Spectrum::new_rgb(0.5, 0.7, 1.0) * t)
-    }
-}
diff --git a/src/render/coordinator.rs b/src/render/coordinator.rs
deleted file mode 100644
index e2f825b..0000000
--- a/src/render/coordinator.rs
+++ /dev/null
@@ -1,126 +0,0 @@
-//! Split a image into small tiles
-//!
-//! This enables multithreaded rendering.
-
-use super::{RenderTask, RenderContext};
-use crate::camera::Film;
-use crate::core::{Bound2i, Vector2i};
-use crate::sample::Sampler;
-
-use std::sync::{Mutex};
-
-struct Tiler {
-    tilesize: Vector2i,
-
-    fullbound: Bound2i,
-    tilemap_size: Vector2i,
-    tilemap_area: i32,
-
-    next_tile: i32,
-    tiles_done: i32,
-}
-
-pub struct RenderCoord<'a> {
-    film: Mutex<&'a mut Film>,
-    samples: u32,
-    tiler: Mutex<Tiler>,
-}
-
-impl Tiler {
-    pub fn new(fullsize: Vector2i, tilesize: Vector2i) -> Tiler {
-        assert!(tilesize.x != 0 && tilesize.y != 0);
-
-        let tilemap_size = fullsize / tilesize;
-
-        Self {
-            tilesize,
-
-            fullbound: Bound2i::new(&Vector2i::ZERO, &fullsize),
-            tilemap_size,
-            tilemap_area: (tilemap_size.x * tilemap_size.y),
-
-            next_tile: 0,
-            tiles_done: 0,
-        }
-
-    }
-
-    pub fn next_tile(&mut self) -> Option<(Bound2i, i32)> {
-        // Check if we are outside
-        if self.next_tile >= self.tilemap_area {
-            return None;
-        }
-
-        // Convert the tile to xy in tilemap
-        let tile = Vector2i::new_xy(self.next_tile / self.tilemap_size.x, self.next_tile % self.tilemap_size.x);
-        let tile_index = self.next_tile;
-
-        self.next_tile += 1;
-
-        // Create a bound from the tilecoordinate
-        let tile_start = tile * self.tilesize;
-        // We need to make sure the resulting tile is inside the image bound
-        Some((
-                Bound2i::new(&tile_start, &(tile_start + self.tilesize)).intersect(&self.fullbound),
-                tile_index,
-                ))
-    }
-
-    /// Mark a index as done and return the overall process
-    pub fn mark_done(&mut self, _index: i32) -> f32 {
-        self.tiles_done += 1;
-
-        println!("Progress: {}/{}", self.tiles_done, self.tilemap_area);
-        self.tiles_done as f32 / self.tilemap_area as f32
-    }
-}
-
-impl<'a> RenderCoord<'a> {
-    pub fn new(film: &'a mut Film, tilesize: Vector2i, samples: u32) -> Self {
-        let size = film.size;
-
-        Self {
-            film: Mutex::new(film),
-            samples,
-            tiler: Mutex::new(Tiler::new(size, tilesize)),
-        }
-    }
-
-    pub fn next_task(&self) -> Option<RenderTask> {
-        let (tile_bound, index) = self.tiler.lock().unwrap().next_tile()?;
-
-        let film_tile = {
-            let film = self.film.lock().unwrap();
-            Box::new(film.get_tile(&tile_bound))
-        };
-
-        Some(RenderTask::new(film_tile, self.samples, index))
-    }
-
-    pub fn finish_task(&self, task: &RenderTask) {
-        {
-            let mut film = self.film.lock().unwrap();
-            film.commit_tile(task.tile.as_ref());
-        }
-
-        self.tiler.lock().unwrap().mark_done(task.tile_index);
-    }
-
-    pub fn work(&self, ctx: &RenderContext, sampler: &mut dyn Sampler) {
-        while let Some(mut task) = self.next_task() {
-            task.render(ctx, sampler);
-            self.finish_task(&task);
-        }
-    }
-
-    pub fn run_threaded(&self, ctx: &RenderContext, sampler: &mut (dyn Sampler + Send), threads: u32) {
-        crossbeam::scope(|scope| {
-            for _ in 0..threads {
-                let mut sampler = sampler.clone_and_seed();
-                scope.spawn(move |_| {
-                    self.work(ctx, sampler.as_mut());
-                });
-            }
-        }).unwrap();
-    }
-}
diff --git a/src/render/mod.rs b/src/render/mod.rs
deleted file mode 100644
index b81aaf5..0000000
--- a/src/render/mod.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-mod task;
-mod coordinator;
-
-pub use task::{RenderContext, RenderTask};
-pub use coordinator::RenderCoord;
diff --git a/src/render/task.rs b/src/render/task.rs
deleted file mode 100644
index 017fe24..0000000
--- a/src/render/task.rs
+++ /dev/null
@@ -1,49 +0,0 @@
-//! Implements the main render loop
-//!
-//! This is not a final design
-use crate::camera::film::FilmTile;
-use crate::camera::Camera;
-use crate::trace::{DefaultTracer, Tracer};
-use crate::sample::Sampler;
-
-use crate::core::{Vector2f};
-use crate::Float;
-
-pub struct RenderTask {
-    pub tile: Box<FilmTile>,
-    samples: u32,
-    pub tile_index: i32,
-}
-
-pub struct RenderContext<'a> {
-    pub cam: &'a Camera,
-    pub trc: &'a DefaultTracer<'a>,
-}
-
-impl RenderTask {
-    pub fn new(tile: Box<FilmTile>, samples: u32, tile_index: i32) -> Self {
-        Self { tile, samples, tile_index }
-    }
-
-    fn render_at(&mut self, ctx: &RenderContext, x: i32, y: i32, sampler: &mut dyn Sampler) {
-        let corner = Vector2f::new_xy(x as Float, y as Float);
-
-        for _ in 0..self.samples {
-            let p = corner + sampler.get_sample_2d();
-
-            // Create a ray
-            let (r, _) = ctx.cam.generate_ray(&p, sampler);
-
-            self.tile.add_sample(&p, ctx.trc.trace(sampler, &r));
-        }
-    }
-
-    pub fn render(&mut self, ctx: &RenderContext, sampler: &mut dyn Sampler) {
-        let b = self.tile.bounds.clone();
-        for y in b.min.y .. b.max.y {
-            for x in b.min.x .. b.max.x {
-                self.render_at(ctx, x, y, sampler);
-            }
-        }
-    }
-}
diff --git a/src/sample/mod.rs b/src/sample/mod.rs
deleted file mode 100644
index 1a53921..0000000
--- a/src/sample/mod.rs
+++ /dev/null
@@ -1,46 +0,0 @@
-use crate::{M_PI, Float};
-use crate::core::{Vector3f, Vector2f};
-
-mod uniform;
-
-pub use uniform::UniformSampler;
-
-fn distribute_between(x: Float, a: Float, b: Float) -> Float {
-    x * (b - a) + a
-}
-
-pub trait Sampler {
-    fn get_sample(&mut self) -> Float;
-
-    fn get_sample_2d(&mut self) -> Vector2f {
-        Vector2f::new_xy(self.get_sample(), self.get_sample())
-    }
-
-    fn clone_and_seed(&mut self) -> Box<dyn Sampler + Send>;
-
-    fn get_unit_vector(&mut self) -> Vector3f {
-        let s2d = self.get_sample_2d();
-
-        let lambda = distribute_between(s2d.x, -M_PI, M_PI);
-        let costheta = 2.0 * s2d.y - 1.0;
-        let sintheta = costheta.acos().sin();
-
-        Vector3f::new_xyz(
-            lambda.cos() * sintheta,
-            lambda.sin() * sintheta,
-            costheta,
-            )
-    }
-
-    fn get_in_circle(&mut self) -> Vector2f {
-        let s2d = self.get_sample_2d();
-
-        let d = s2d.x.sqrt();
-        let theta = s2d.y * 2.0 * M_PI;
-
-        Vector2f::new_xy(
-            d * theta.cos(),
-            d * theta.sin(),
-            )
-    }
-}
diff --git a/src/sample/uniform.rs b/src/sample/uniform.rs
deleted file mode 100644
index c144f27..0000000
--- a/src/sample/uniform.rs
+++ /dev/null
@@ -1,39 +0,0 @@
-use crate::Float;
-use super::Sampler;
-
-use rand::prelude::*;
-use rand::distributions::Uniform;
-use rand_pcg::Pcg32;
-
-#[derive(Clone)]
-pub struct UniformSampler {
-    r: Pcg32,
-    d: Uniform<Float>,
-}
-
-impl UniformSampler {
-    pub fn new() -> Self {
-        Self::default()
-    }
-}
-
-impl Default for UniformSampler {
-    fn default() -> Self {
-        Self {
-            r: Pcg32::seed_from_u64(1),
-            d: Uniform::new(0.0, 1.0),
-        }
-    }
-}
-
-impl Sampler for UniformSampler {
-    fn get_sample(&mut self) -> Float {
-        self.d.sample(&mut self.r)
-    }
-
-    fn clone_and_seed(&mut self) -> Box<dyn Sampler + Send> {
-        let mut n = self.clone();
-        n.r = Pcg32::seed_from_u64(self.r.next_u64());
-        Box::new(n)
-    }
-}
diff --git a/src/trace/mod.rs b/src/trace/mod.rs
deleted file mode 100644
index d45fb23..0000000
--- a/src/trace/mod.rs
+++ /dev/null
@@ -1,41 +0,0 @@
-use crate::world::{Hittable, Scene};
-use crate::core::{Spectrum, Ray, Vector3f};
-use crate::sample::Sampler;
-
-mod pathtrace;
-pub use pathtrace::PathTracer;
-
-/// Simple surface normal tracer
-///
-/// This ray tracer bases color values on the hit surface normals
-pub struct NormTracer<'a> {
-    scn: &'a Scene,
-}
-
-/// Alias for chosen trace implementation.
-///
-/// This is swiched at compile time to save alot of time.
-pub type DefaultTracer<'a> = PathTracer<'a>;
-
-pub trait Tracer {
-    fn trace(&self, sampler: &mut dyn Sampler, ray: &Ray) -> Spectrum;
-}
-
-impl NormTracer<'_> {
-    pub fn new(scn: &Scene) -> NormTracer {
-        NormTracer {scn}
-    }
-}
-
-impl Tracer for NormTracer<'_> {
-    fn trace(&self, _: &mut dyn Sampler, ray: &Ray) -> Spectrum {
-        // Trace ray, we dont care about material
-        if let Some(i) = self.scn.intersect(ray) {
-            let norm = i.n * 0.5 + Vector3f::new(0.5);
-
-            return Spectrum::new_rgb(norm.x, norm.y, norm.z);
-        }
-
-        Spectrum::new_rgb(0.0, 0.0, 0.0)
-    }
-}
diff --git a/src/trace/pathtrace.rs b/src/trace/pathtrace.rs
deleted file mode 100644
index f53e433..0000000
--- a/src/trace/pathtrace.rs
+++ /dev/null
@@ -1,60 +0,0 @@
-use crate::world::{Hittable, Scene};
-use crate::core::{Ray, Spectrum};
-use crate::material::Material;
-use crate::sample::Sampler;
-use super::Tracer;
-
-pub struct PathTracer<'a> {
-    depth: i32,
-    scn: &'a Scene,
-    background: Option<Box<dyn Material>>,
-}
-
-impl PathTracer<'_> {
-    pub fn new(scn: &Scene, depth: Option<i32>, background: Option<Box<dyn Material>>) -> PathTracer {
-        let depth = depth.unwrap_or(-1);
-
-        PathTracer {
-            depth,
-            scn,
-            background,
-        }
-    }
-
-    pub fn trace_recur(&self, sampler: &mut dyn Sampler, ray: &Ray, depth: i32) -> Spectrum {
-
-        if depth == 0 {
-            return Spectrum::ZERO;
-        }
-
-        if let Some(i) = self.scn.intersect(ray) {
-            // Extract material or default
-            if let Some(mat) = i.m {
-                let mut col = Spectrum::ZERO;
-
-                if let Some((scalar, nray)) = mat.scatter(ray, &i, sampler) {
-                    col += &(self.trace_recur(sampler, &nray, depth-1) * scalar);
-                }
-
-                if let Some(c) = mat.emitted(ray) {
-                    col += &c;
-                }
-
-                return col;
-            }
-        }
-
-        // If no color return background
-        if let Some(back) = &self.background {
-            back.emitted(ray).unwrap_or(Spectrum::ZERO)
-        } else {
-            Spectrum::ZERO
-        }
-    }
-}
-
-impl Tracer for PathTracer<'_> {
-    fn trace(&self, sampler: &mut dyn Sampler, ray: &Ray) -> Spectrum {
-        self.trace_recur(sampler, ray, self.depth)
-    }
-}
diff --git a/src/world/container/list.rs b/src/world/container/list.rs
deleted file mode 100644
index 22b6d88..0000000
--- a/src/world/container/list.rs
+++ /dev/null
@@ -1,56 +0,0 @@
-use crate::world::{Object, Hittable, Intersection};
-use crate::core::{Bound3f, Ray};
-
-
-pub struct HittableList {
-    elems: Vec<Object>,
-}
-
-impl HittableList {
-    pub fn new() -> Self {
-        Self::default()
-    }
-
-    pub fn add(&mut self, h: Object) {
-        self.elems.push(h);
-    }
-}
-
-impl Hittable for HittableList {
-    fn intersect(&self, ray: &Ray) -> Option<Intersection> {
-        let mut min: Option<Intersection> = None;
-
-        for e in self.elems.iter() {
-            if let Some(i) = e.intersect(&ray) {
-                match min {
-                    // Do nothing if distance is bigger than min
-                    Some(ref min_i) if min_i.t < i.t => {},
-                    // If no existing min or closer than
-                    _ => min = Some(i),
-                }
-            }
-        }
-
-        min
-    }
-
-    fn bounding_box(&self) -> Bound3f {
-        let mut bound: Bound3f = Bound3f::EMPTY;
-
-        for e in self.elems.iter() {
-            let eb = e.bounding_box();
-            bound = bound.combine(&eb);
-        }
-
-        bound
-    }
-}
-
-impl Default for HittableList {
-    fn default() -> Self {
-        Self {
-            elems: Vec::new(),
-        }
-    }
-}
-
diff --git a/src/world/container/mod.rs b/src/world/container/mod.rs
deleted file mode 100644
index 35d4693..0000000
--- a/src/world/container/mod.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-mod list;
-
-pub use list::HittableList;
diff --git a/src/world/hittable.rs b/src/world/hittable.rs
deleted file mode 100644
index e11a3bc..0000000
--- a/src/world/hittable.rs
+++ /dev/null
@@ -1,41 +0,0 @@
-use crate::core::{Vector3f, Bound3f, Ray};
-use crate::Float;
-use crate::material::Material;
-
-/// Returns the context of a intersection
-pub struct Intersection<'a> {
-    /// Normal vector at intersection
-    pub n: Vector3f,
-    pub p: Vector3f,
-    pub front: bool,
-    pub t: Float,
-    pub m: Option<&'a dyn Material>,
-}
-
-impl<'a> Intersection<'a> {
-    pub fn new(out_normal: Vector3f, point: Vector3f, ray: &Ray, t: Float) -> Self {
-        let front = ray.direction.dot(&out_normal) < 0.0;
-        Intersection {
-            n: { if front { out_normal } else { -out_normal } },
-            front,
-            p: point,
-            m: None,
-            t,
-        }
-    }
-
-    pub fn add_material_if_none(&mut self, mat: &'a dyn Material) {
-        if let None = self.m {
-            self.m = Some(mat);
-        }
-    }
-}
-
-/// Defines a common trait for objects in the scene
-pub trait Hittable: Sync + Send {
-    /// Returns the intersection with ray
-    fn intersect(&self, ray: &Ray) -> Option<Intersection>;
-
-    /// Returns the axis alligned bounding box containing self
-    fn bounding_box(&self) -> Bound3f;
-}
diff --git a/src/world/mod.rs b/src/world/mod.rs
deleted file mode 100644
index cba6ddc..0000000
--- a/src/world/mod.rs
+++ /dev/null
@@ -1,42 +0,0 @@
-//! Manages world objects, and implements intersection
-pub mod shapes;
-
-mod scene;
-pub mod container;
-mod hittable;
-pub use scene::*;
-pub use hittable::{Intersection, Hittable};
-pub use shapes::Shape;
-
-use std::sync::Arc;
-use crate::material::Material;
-use crate::core::{Bound3f, Ray};
-
-pub struct Object {
-    pub shape: Shape,
-    pub mat: Arc<dyn Material>,
-}
-
-impl Object {
-    pub fn new<T: Into<Shape>>(mat: Arc<dyn Material>, shape: T) -> Self {
-        Object {
-            mat,
-            shape: shape.into(),
-        }
-    }
-}
-
-impl Hittable for Object {
-    fn intersect(&self, ray: &Ray) -> Option<Intersection> {
-        if let Some(mut inter) = self.shape.intersect(ray) {
-            inter.add_material_if_none(self.mat.as_ref());
-            Some(inter)
-        } else {
-            None
-        }
-    }
-
-    fn bounding_box(&self) -> Bound3f {
-        self.shape.bounding_box()
-    }
-}
diff --git a/src/world/scene.rs b/src/world/scene.rs
deleted file mode 100644
index 87bec1f..0000000
--- a/src/world/scene.rs
+++ /dev/null
@@ -1,43 +0,0 @@
-use crate::core::{Bound3f, Ray};
-
-use super::{Object, container, Hittable, Intersection};
-
-type Container = container::HittableList;
-
-pub struct Scene {
-    content: Container,
-}
-
-impl Scene {
-    pub fn new() -> Self {
-        Self::default()
-    }
-
-    pub fn add_object(&mut self, obj: Object) {
-        self.content.add(obj);
-    }
-
-    pub fn add_objects(&mut self, objs: Vec<Object>) {
-        for obj in objs {
-            self.add_object(obj);
-        }
-    }
-}
-
-impl Hittable for Scene {
-    fn intersect(&self, ray: &Ray) -> Option<Intersection> {
-        self.content.intersect(ray)
-    }
-
-    fn bounding_box(&self) -> Bound3f {
-        self.content.bounding_box()
-    }
-}
-
-impl Default for Scene {
-    fn default() -> Self {
-        Self {
-            content: Container::new(),
-        }
-    }
-}
diff --git a/src/world/shapes/mod.rs b/src/world/shapes/mod.rs
deleted file mode 100644
index a11df5d..0000000
--- a/src/world/shapes/mod.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-mod sphere;
-
-pub use sphere::Sphere;
-
-use crate::world::{Hittable, Intersection};
-use crate::core::{Bound3f, Ray};
-
-pub enum Shape {
-    Sphere(Sphere),
-}
-
-impl Hittable for Shape {
-    fn intersect(&self, ray: &Ray) -> Option<Intersection> {
-        match self {
-            Self::Sphere(sph) => sph.intersect(ray)
-        }
-    }
-
-    fn bounding_box(&self) -> Bound3f {
-        match self {
-            Self::Sphere(sph) => sph.bounding_box()
-        }
-    }
-}
-
-impl From<Sphere> for Shape {
-    fn from(s: Sphere) -> Self {
-        Self::Sphere(s)
-    }
-}
diff --git a/src/world/shapes/sphere.rs b/src/world/shapes/sphere.rs
deleted file mode 100644
index 1df9c35..0000000
--- a/src/world/shapes/sphere.rs
+++ /dev/null
@@ -1,98 +0,0 @@
-//! Implements sphere
-//!
-//! Spheres are relatively easy to calculate intersections between
-use crate::{Float, NEAR_ZERO};
-use crate::core::{Ray, Vector3f, Bound3f};
-use crate::world::{Hittable, Intersection};
-
-pub struct Sphere {
-    radius: Float,
-    center: Vector3f,
-}
-
-impl Sphere {
-    pub fn new(radius: Float, center: Vector3f) -> Sphere {
-        Sphere {
-            radius,
-            center,
-        }
-    }
-
-    fn norm_at(&self, point: &Vector3f) -> Vector3f {
-        let mut v = *point - self.center;
-        v /= self.radius;
-        v
-    }
-}
-
-impl Hittable for Sphere {
-    // Implementation from ray tracing in a weekend
-    fn intersect(&self, ray: &Ray) -> Option<Intersection> {
-        let oc = ray.origin - self.center;
-        let a = ray.direction.len_squared();
-        let half_b = oc.dot(&ray.direction);
-        let c = oc.len_squared() - self.radius * self.radius;
-        let disc = half_b*half_b - a*c;
-
-        if disc < 0.0 {
-            None
-        } else {
-            let disc_sqrt = disc.sqrt();
-
-            let mut distance = -half_b - disc_sqrt;
-            if distance <= NEAR_ZERO {
-                distance = -half_b + disc_sqrt;
-            }
-            if distance <= NEAR_ZERO {
-                return None;
-            }
-
-            distance /= a;
-            let w = ray.at(distance);
-            Some(Intersection::new(
-                    self.norm_at(&w),
-                    w,
-                    ray,
-                    distance,
-                    ))
-        }
-
-    }
-
-    /// Box containing the circle
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use rendering::core::Vector3f;
-    /// use rendering::world::{Hittable, shapes::Sphere};
-    ///
-    /// let sph = Sphere::new(1.0, Vector3f::new(0.0));
-    /// let b = sph.bounding_box();
-    ///
-    /// assert!(b.min.x == -1.0 && b.min.y == -1.0 && b.min.z == -1.0);
-    /// assert!(b.max.x == 1.0 && b.max.y == 1.0 && b.max.z == 1.0);
-    fn bounding_box(&self) -> Bound3f {
-        let offset = Vector3f::new(self.radius);
-
-        Bound3f::new(self.center - offset, self.center + offset)
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    #[test]
-    fn sphere_intersect() {
-        let sph = Sphere::new(2.0, Vector3f::new_xyz(2.0, 3.0, 4.0));
-
-        let ray = Ray {
-            origin: Vector3f::new_xyz(1.0, 0.0, 0.0),
-            direction: Vector3f::new_xyz(0.0, 1.0, 1.5).norm(),
-        };
-
-        let dist = sph.intersect(&ray).unwrap();
-        assert!((dist.t - 3.28).abs() < 0.01);
-    }
-}
-- 
cgit v1.2.3