Add existing files
This commit is contained in:
commit
9d188ed692
298
Cargo.lock
generated
Normal file
298
Cargo.lock
generated
Normal file
|
@ -0,0 +1,298 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
[[package]]
|
||||||
|
name = "alga"
|
||||||
|
version = "0.9.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4f823d037a7ec6ea2197046bafd4ae150e6bc36f9ca347404f46a46823fa84f2"
|
||||||
|
dependencies = [
|
||||||
|
"approx",
|
||||||
|
"num-complex",
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "approx"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3"
|
||||||
|
dependencies = [
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
|
||||||
|
|
||||||
|
[[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 = "cloudabi"
|
||||||
|
version = "0.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fuchsia-cprng"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "generic-array"
|
||||||
|
version = "0.12.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
|
||||||
|
dependencies = [
|
||||||
|
"typenum",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.80"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libm"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "matrixmultiply"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d4f7ec66360130972f34830bfad9ef05c6610a43938a467bcc9ab9369ab3478f"
|
||||||
|
dependencies = [
|
||||||
|
"rawpointer",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nalgebra"
|
||||||
|
version = "0.18.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "aaa9fddbc34c8c35dd2108515587b8ce0cab396f17977b8c738568e4edb521a2"
|
||||||
|
dependencies = [
|
||||||
|
"alga",
|
||||||
|
"approx",
|
||||||
|
"generic-array",
|
||||||
|
"matrixmultiply",
|
||||||
|
"num-complex",
|
||||||
|
"num-rational",
|
||||||
|
"num-traits",
|
||||||
|
"rand",
|
||||||
|
"typenum",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-complex"
|
||||||
|
version = "0.2.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg 1.0.1",
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-integer"
|
||||||
|
version = "0.1.44"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg 1.0.1",
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-rational"
|
||||||
|
version = "0.2.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg 1.0.1",
|
||||||
|
"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 1.0.1",
|
||||||
|
"libm",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.6.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg 0.1.7",
|
||||||
|
"libc",
|
||||||
|
"rand_chacha",
|
||||||
|
"rand_core 0.4.2",
|
||||||
|
"rand_hc",
|
||||||
|
"rand_isaac",
|
||||||
|
"rand_jitter",
|
||||||
|
"rand_os",
|
||||||
|
"rand_pcg",
|
||||||
|
"rand_xorshift",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_chacha"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg 0.1.7",
|
||||||
|
"rand_core 0.3.1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core 0.4.2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_hc"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core 0.3.1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_isaac"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core 0.3.1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_jitter"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"rand_core 0.4.2",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_os"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
|
||||||
|
dependencies = [
|
||||||
|
"cloudabi",
|
||||||
|
"fuchsia-cprng",
|
||||||
|
"libc",
|
||||||
|
"rand_core 0.4.2",
|
||||||
|
"rdrand",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_pcg"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg 0.1.7",
|
||||||
|
"rand_core 0.4.2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_xorshift"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core 0.3.1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rawpointer"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rdrand"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core 0.3.1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "render"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"nalgebra",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typenum"
|
||||||
|
version = "1.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi"
|
||||||
|
version = "0.3.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-i686-pc-windows-gnu",
|
||||||
|
"winapi-x86_64-pc-windows-gnu",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-i686-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
10
Cargo.toml
Normal file
10
Cargo.toml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
[package]
|
||||||
|
name = "render"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Bijan Sheibani"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
nalgebra = "0.18"
|
127
src/camera.rs
Normal file
127
src/camera.rs
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
|
||||||
|
extern crate nalgebra as na;
|
||||||
|
use na::*;
|
||||||
|
use na::geometry::{Point2, Point3};
|
||||||
|
|
||||||
|
use crate::types::Ray;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Camera {
|
||||||
|
matrix: Isometry3<f32>, // The transformation that stores the
|
||||||
|
// position and orientation of the camera. (Not actually a matrix, but w/e)
|
||||||
|
|
||||||
|
focal_length: f32, // The distance from the camera origin to the canvas.
|
||||||
|
canvas_size: Vector2<f32>, // The size of the canvas within the world space.
|
||||||
|
|
||||||
|
pub image_size: Vector2<u32> // The size of the final image in pixels.
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Camera {
|
||||||
|
// Constructs a new camera from a position and viewing direction
|
||||||
|
// (assuming the camera is oriented upright).
|
||||||
|
pub fn new(pos: Point3<f32>, dir: Vector3<f32>, focal_length: f32,
|
||||||
|
canvas_x: f32, canvas_y: f32, image_x: u32, image_y: u32) -> Self {
|
||||||
|
let iso = Isometry3::face_towards(&pos, &(pos + dir), &Vector3::y());
|
||||||
|
Camera {
|
||||||
|
matrix: iso,
|
||||||
|
focal_length: focal_length,
|
||||||
|
canvas_size: Vector2::new(canvas_x, canvas_y),
|
||||||
|
image_size: Vector2::new(image_x, image_y)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pos(&self) -> Point3<f32> { Point3::from(self.matrix.translation.vector) }
|
||||||
|
|
||||||
|
// Takes a 2D point in the image space and
|
||||||
|
// maps it to the 3D point on the canvas.
|
||||||
|
fn project(&self, x: u32, y: u32) -> Point3<f32> {
|
||||||
|
// convert point from raster coordinates to center-based coordinates
|
||||||
|
let pixelndc = Point2::new(x as f32 + 0.5 - self.image_size.x as f32 * 0.5, -(y as f32 + 0.5) + self.image_size.y as f32 * 0.5);
|
||||||
|
|
||||||
|
let point: Point3<f32> = Point::from(pixelndc.coords.component_div(&self.image_size.map(|x| x as f32))
|
||||||
|
.component_mul(&self.canvas_size)
|
||||||
|
.fixed_resize(self.focal_length));
|
||||||
|
self.matrix * point
|
||||||
|
}
|
||||||
|
|
||||||
|
// Takes a 2D point in the image space and
|
||||||
|
// returns a ray in the world space, for use in raytracing.
|
||||||
|
pub fn raycast(&self, x: u32, y: u32) -> Ray {
|
||||||
|
Ray::from_points(self.pos(), self.project(x, y))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
fn round(point: Point3<f32>) -> Point3<f32> {
|
||||||
|
Point::from(point.coords.map(|x| x.round()))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn camera_pos() {
|
||||||
|
let camera: Camera = Camera::new(Point3::new(-5.0, 0.0, 0.0),
|
||||||
|
Vector3::new(1.0, 0.0, 0.0),
|
||||||
|
1.0,
|
||||||
|
2.0, 2.0,
|
||||||
|
800, 800);
|
||||||
|
|
||||||
|
assert_eq!(camera.pos(), Point3::new(-5.0, 0.0, 0.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn camera_matrix1() {
|
||||||
|
let camera: Camera = Camera::new(Point3::new(-5.0, 0.0, 0.0),
|
||||||
|
Vector3::new(1.0, 0.0, 0.0),
|
||||||
|
1.0,
|
||||||
|
2.0, 2.0,
|
||||||
|
800, 800);
|
||||||
|
|
||||||
|
let point = Point3::new(0.0, 0.0, 4.0);
|
||||||
|
let point = camera.matrix * point;
|
||||||
|
let point = round(point); // round to avoid errors
|
||||||
|
assert_eq!(point, Point3::new(-1.0, 0.0, 0.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn camera_matrix2() {
|
||||||
|
let camera: Camera = Camera::new(Point3::new(-5.0, 0.0, 0.0),
|
||||||
|
Vector3::new(1.0, 0.0, 0.0),
|
||||||
|
1.0,
|
||||||
|
2.0, 2.0,
|
||||||
|
800, 800);
|
||||||
|
|
||||||
|
let point = Point3::new(4.0, 0.0, 0.0);
|
||||||
|
let point = camera.matrix * point;
|
||||||
|
let point = round(point); // round to avoid errors
|
||||||
|
assert_eq!(point, Point3::new(-5.0, 0.0, -4.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn camera_project1() {
|
||||||
|
let camera: Camera = Camera::new(Point3::new(-5.0, 0.0, 0.0),
|
||||||
|
Vector3::new(1.0, 0.0, 0.0),
|
||||||
|
1.0,
|
||||||
|
2.0, 2.0,
|
||||||
|
800, 800);
|
||||||
|
|
||||||
|
let point = camera.project(400, 400);
|
||||||
|
let point = round(point); // round to avoid errors
|
||||||
|
assert_eq!(point, Point3::new(-4.0, 0.0, 0.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn camera_project2() {
|
||||||
|
let camera: Camera = Camera::new(Point3::new(-5.0, 0.0, 0.0),
|
||||||
|
Vector3::new(1.0, 0.0, 0.0),
|
||||||
|
1.0,
|
||||||
|
2.0, 2.0,
|
||||||
|
800, 800);
|
||||||
|
|
||||||
|
let point = camera.project(0, 0);
|
||||||
|
let point = round(point); // round to avoid errors
|
||||||
|
assert_eq!(point, Point3::new(-4.0, 1.0, 1.0));
|
||||||
|
}
|
||||||
|
}
|
62
src/main.rs
Normal file
62
src/main.rs
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
extern crate nalgebra as na;
|
||||||
|
|
||||||
|
use std::cmp::Ordering;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
|
use na::*;
|
||||||
|
use na::geometry::Point3;
|
||||||
|
|
||||||
|
mod camera; use camera::*;
|
||||||
|
mod types; use types::*;
|
||||||
|
mod object; use object::*;
|
||||||
|
|
||||||
|
fn cast_ray(ray: Ray, scene: &Scene) -> Color {
|
||||||
|
//Color::new(0.0, -ray.direction.x, ray.direction.y)
|
||||||
|
|
||||||
|
let closest = scene.iter()
|
||||||
|
.filter_map(|obj| obj.intersect(ray)
|
||||||
|
.map(|x| (obj, x)))
|
||||||
|
.min_by(|a, b| a.1.partial_cmp(&b.1).unwrap_or(Ordering::Equal));
|
||||||
|
|
||||||
|
if closest.is_some() {
|
||||||
|
Color::new(1.0, 1.0, 1.0)
|
||||||
|
} else {
|
||||||
|
Color::new(0.0, 0.0, 0.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(camera: &Camera, scene: &Scene, filename: &str) -> std::io::Result<()> {
|
||||||
|
let width = camera.image_size.x;
|
||||||
|
let height = camera.image_size.y;
|
||||||
|
|
||||||
|
let mut buffer: Vec<Color> = Vec::with_capacity((width * height) as usize);
|
||||||
|
|
||||||
|
for j in 0..height {
|
||||||
|
for i in 0..width {
|
||||||
|
let ray = camera.raycast(i, j);
|
||||||
|
buffer.push(cast_ray(ray, &scene));
|
||||||
|
}
|
||||||
|
// println!("Rendered row {}", j);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut file = File::create(filename)?;
|
||||||
|
file.set_len(0)?;
|
||||||
|
file.write_all(format!("P6\n{} {}\n255\n", width, height).as_bytes())?;
|
||||||
|
for color in buffer.into_iter() {
|
||||||
|
file.write_all(&color.to_byte_array())?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> std::io::Result<()> {
|
||||||
|
|
||||||
|
let camera = Camera::new(Point3::new(0.0,0.0,0.0), Vector3::new(0.0,0.0,-1.0), 1.0, 2.0, 2.0, 400, 400);
|
||||||
|
|
||||||
|
let scene = vec![
|
||||||
|
Object::Sphere(Sphere::new(0.0,0.0,-5.0,2.0)),
|
||||||
|
Object::Sphere(Sphere::new(-3.0,0.0,-8.0,2.5))
|
||||||
|
];
|
||||||
|
|
||||||
|
render(&camera, &scene, "out.ppm")
|
||||||
|
}
|
27
src/object.rs
Normal file
27
src/object.rs
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
|
||||||
|
mod sphere; pub use sphere::*;
|
||||||
|
mod triangle; pub use triangle::*;
|
||||||
|
|
||||||
|
use na::*;
|
||||||
|
|
||||||
|
use crate::types::Ray;
|
||||||
|
|
||||||
|
pub enum Object {
|
||||||
|
Sphere(Sphere)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Object {
|
||||||
|
pub fn intersect(&self, ray: Ray) -> Option<f32> {
|
||||||
|
match *self {
|
||||||
|
Object::Sphere(ref sphere) => sphere.intersect(ray)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn normal(&self, ray: Ray) -> Unit<Vector3<f32>> {
|
||||||
|
match *self {
|
||||||
|
Object::Sphere(ref sphere) => sphere.normal(ray)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Scene = Vec<Object>;
|
52
src/object/sphere.rs
Normal file
52
src/object/sphere.rs
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
extern crate nalgebra as na;
|
||||||
|
|
||||||
|
use na::*;
|
||||||
|
use na::geometry::Point3;
|
||||||
|
|
||||||
|
use crate::types::*;
|
||||||
|
|
||||||
|
pub struct Sphere {
|
||||||
|
pub center: Point3<f32>,
|
||||||
|
pub radius: f32
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Sphere {
|
||||||
|
pub fn new(x: f32, y: f32, z: f32, radius: f32) -> Self {
|
||||||
|
Sphere {
|
||||||
|
center: Point3::new(x, y, z),
|
||||||
|
radius: radius
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn intersect(&self, ray: Ray) -> Option<f32> {
|
||||||
|
fn solve_quadratic(a: f32, b: f32, c: f32) -> Option<(f32, f32)> {
|
||||||
|
let discr = b * b - 4.0 * a * c;
|
||||||
|
|
||||||
|
if discr < 0.0 { None }
|
||||||
|
else if discr == 0.0 {
|
||||||
|
let x = -0.5 * b / a;
|
||||||
|
Some((x, x))
|
||||||
|
} else {
|
||||||
|
let q = if b > 0.0 { -0.5 * (b + discr.sqrt()) } else { -0.5 * (b - discr.sqrt()) };
|
||||||
|
Some((q / a, c / q))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let l = ray.origin - self.center;
|
||||||
|
let a = ray.direction.dot(&ray.direction);
|
||||||
|
let b = 2.0 * ray.direction.dot(&l);
|
||||||
|
let c = l.dot(&l) - self.radius * self.radius;
|
||||||
|
|
||||||
|
let (mut t0, mut t1) = solve_quadratic(a, b, c)?;
|
||||||
|
|
||||||
|
if t0 > t1 { std::mem::swap(&mut t0, &mut t1); }
|
||||||
|
|
||||||
|
if t0 > 0.0 { Some(t0) }
|
||||||
|
else if t1 > 0.0 { Some(t1) }
|
||||||
|
else { None }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn normal(&self, ray: Ray) -> Unit<Vector3<f32>> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
}
|
0
src/object/triangle.rs
Normal file
0
src/object/triangle.rs
Normal file
50
src/types.rs
Normal file
50
src/types.rs
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
extern crate nalgebra as na;
|
||||||
|
use na::*;
|
||||||
|
use na::geometry::Point3;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub struct Ray {
|
||||||
|
pub origin: Point3<f32>,
|
||||||
|
pub direction: Unit<Vector3<f32>>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ray {
|
||||||
|
pub fn from_parts(origin: Point3<f32>, direction: Unit<Vector3<f32>>) -> Self {
|
||||||
|
Ray {
|
||||||
|
origin: origin,
|
||||||
|
direction: direction
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn new(origin: Point3<f32>, direction: Vector3<f32>) -> Self { Ray::from_parts(origin, Unit::new_normalize(direction)) }
|
||||||
|
pub fn from_points(a: Point3<f32>, b: Point3<f32>) -> Self { Ray::new(a, b - a) }
|
||||||
|
|
||||||
|
pub fn project(&self, t: f32) -> Point3<f32> { self.origin + t * self.direction.into_inner() }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub struct Color {
|
||||||
|
pub red: f32,
|
||||||
|
pub green: f32,
|
||||||
|
pub blue: f32,
|
||||||
|
|
||||||
|
_private: () // Private field prevents direct construction
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Color {
|
||||||
|
pub fn new(red: f32, green: f32, blue: f32) -> Self {
|
||||||
|
Color {
|
||||||
|
red: clamp(red, 0.0, 1.0),
|
||||||
|
green: clamp(green, 0.0, 1.0),
|
||||||
|
blue: clamp(blue, 0.0, 1.0),
|
||||||
|
|
||||||
|
_private: ()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_byte_array(&self) -> [u8; 3] {
|
||||||
|
let red = (255.0 * self.red) as u8;
|
||||||
|
let green = (255.0 * self.green) as u8;
|
||||||
|
let blue = (255.0 * self.blue) as u8;
|
||||||
|
[red, green, blue]
|
||||||
|
}
|
||||||
|
}
|
1
target/.rustc_info.json
Normal file
1
target/.rustc_info.json
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"rustc_fingerprint":12061330666014814200,"outputs":{"2452144974977565071":["___.exe\nlib___.rlib\n___.dll\n___.dll\n___.lib\n___.dll\nC:\\Users\\bijan\\.rustup\\toolchains\\stable-i686-pc-windows-msvc\ndebug_assertions\nproc_macro\ntarget_arch=\"x86\"\ntarget_endian=\"little\"\ntarget_env=\"msvc\"\ntarget_family=\"windows\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_os=\"windows\"\ntarget_pointer_width=\"32\"\ntarget_vendor=\"pc\"\nwindows\n",""],"16538190320964532705":["rustc 1.41.0 (5e1a79984 2020-01-27)\nbinary: rustc\ncommit-hash: 5e1a799842ba6ed4a57e91f7ab9435947482f7d8\ncommit-date: 2020-01-27\nhost: i686-pc-windows-msvc\nrelease: 1.41.0\nLLVM version: 9.0\n",""]},"successes":{}}
|
0
target/debug/.cargo-lock
Normal file
0
target/debug/.cargo-lock
Normal file
|
@ -0,0 +1 @@
|
||||||
|
This file has an mtime of when this was started.
|
|
@ -0,0 +1 @@
|
||||||
|
ebb920bd55452a45
|
|
@ -0,0 +1 @@
|
||||||
|
{"rustc":12207601712932690048,"features":"[\"default\", \"std\"]","target":16522217680686957364,"profile":14672114853574311971,"path":7633858312084395291,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug\\.fingerprint\\ab_glyph_rasterizer-8248956ca8415db8\\dep-lib-ab_glyph_rasterizer-8248956ca8415db8"}}],"rustflags":[],"metadata":11806270875101347079}
|
|
@ -0,0 +1 @@
|
||||||
|
This file has an mtime of when this was started.
|
|
@ -0,0 +1 @@
|
||||||
|
78b0e4fb2bd7af09
|
|
@ -0,0 +1 @@
|
||||||
|
{"rustc":12207601712932690048,"features":"[\"default\", \"std\"]","target":16522217680686957364,"profile":9935990280773120926,"path":7633858312084395291,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug\\.fingerprint\\ab_glyph_rasterizer-b3ccb2f68aa7e7a2\\dep-lib-ab_glyph_rasterizer-b3ccb2f68aa7e7a2"}}],"rustflags":[],"metadata":11806270875101347079}
|
|
@ -0,0 +1 @@
|
||||||
|
This file has an mtime of when this was started.
|
|
@ -0,0 +1 @@
|
||||||
|
db3dad47842a2080
|
|
@ -0,0 +1 @@
|
||||||
|
{"rustc":12207601712932690048,"features":"[]","target":8966022420021965095,"profile":9935990280773120926,"path":17379837534419019086,"deps":[[15809339616147270539,"gimli",false,15446023932270068924]],"local":[{"CheckDepInfo":{"dep_info":"debug\\.fingerprint\\addr2line-60e194fa809e51c8\\dep-lib-addr2line-60e194fa809e51c8"}}],"rustflags":[],"metadata":11692742975522428388}
|
|
@ -0,0 +1 @@
|
||||||
|
This file has an mtime of when this was started.
|
|
@ -0,0 +1 @@
|
||||||
|
7be24b45c7c4343d
|
|
@ -0,0 +1 @@
|
||||||
|
{"rustc":12207601712932690048,"features":"[]","target":8966022420021965095,"profile":14672114853574311971,"path":17379837534419019086,"deps":[[15809339616147270539,"gimli",false,18389161117168374087]],"local":[{"CheckDepInfo":{"dep_info":"debug\\.fingerprint\\addr2line-9010bc19d78d40d6\\dep-lib-addr2line-9010bc19d78d40d6"}}],"rustflags":[],"metadata":11692742975522428388}
|
|
@ -0,0 +1 @@
|
||||||
|
This file has an mtime of when this was started.
|
|
@ -0,0 +1 @@
|
||||||
|
13cbcb6705b82a14
|
|
@ -0,0 +1 @@
|
||||||
|
{"rustc":12207601712932690048,"features":"[]","target":10237188548688945853,"profile":9935990280773120926,"path":15236005339190915527,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug\\.fingerprint\\adler-146082f41e05b62d\\dep-lib-adler-146082f41e05b62d"}}],"rustflags":[],"metadata":10288524725990234452}
|
|
@ -0,0 +1 @@
|
||||||
|
This file has an mtime of when this was started.
|
|
@ -0,0 +1 @@
|
||||||
|
bec5ddd1d675a935
|
|
@ -0,0 +1 @@
|
||||||
|
{"rustc":12207601712932690048,"features":"[]","target":10237188548688945853,"profile":14672114853574311971,"path":15236005339190915527,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug\\.fingerprint\\adler-7cb418e6e5ca6be1\\dep-lib-adler-7cb418e6e5ca6be1"}}],"rustflags":[],"metadata":10288524725990234452}
|
|
@ -0,0 +1 @@
|
||||||
|
This file has an mtime of when this was started.
|
|
@ -0,0 +1 @@
|
||||||
|
92618fd38e7ef558
|
|
@ -0,0 +1 @@
|
||||||
|
{"rustc":12207601712932690048,"features":"[\"default\", \"std\"]","target":5280682417758014802,"profile":14672114853574311971,"path":15697693938898355822,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug\\.fingerprint\\adler32-8c3a6ff4cbd004b5\\dep-lib-adler32-8c3a6ff4cbd004b5"}}],"rustflags":[],"metadata":14811084762281514323}
|
|
@ -0,0 +1 @@
|
||||||
|
This file has an mtime of when this was started.
|
|
@ -0,0 +1 @@
|
||||||
|
86ba3e4e97637661
|
|
@ -0,0 +1 @@
|
||||||
|
{"rustc":12207601712932690048,"features":"[\"default\", \"std\"]","target":5280682417758014802,"profile":9935990280773120926,"path":15697693938898355822,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug\\.fingerprint\\adler32-cf0bd9a0c3898796\\dep-lib-adler32-cf0bd9a0c3898796"}}],"rustflags":[],"metadata":14811084762281514323}
|
|
@ -0,0 +1 @@
|
||||||
|
This file has an mtime of when this was started.
|
|
@ -0,0 +1 @@
|
||||||
|
c95bdfaef2c5e4e7
|
|
@ -0,0 +1 @@
|
||||||
|
{"rustc":12207601712932690048,"features":"[\"std\"]","target":9258705378109553973,"profile":14672114853574311971,"path":16073260490560416965,"deps":[[1951668677046445136,"approx",false,6577572985522262062],[7216377681729432009,"num_traits",false,7980548084844201855],[15845988608448177198,"num_complex",false,7177604756755841878]],"local":[{"CheckDepInfo":{"dep_info":"debug\\.fingerprint\\alga-7df3a7e31a8b6a1f\\dep-lib-alga-7df3a7e31a8b6a1f"}}],"rustflags":[],"metadata":16934162586732421168}
|
|
@ -0,0 +1 @@
|
||||||
|
This file has an mtime of when this was started.
|
|
@ -0,0 +1 @@
|
||||||
|
a1c3b7cb7d86f29b
|
|
@ -0,0 +1 @@
|
||||||
|
{"rustc":12207601712932690048,"features":"[\"std\"]","target":9258705378109553973,"profile":9935990280773120926,"path":16073260490560416965,"deps":[[1951668677046445136,"approx",false,18023259525201585783],[7216377681729432009,"num_traits",false,3818044152068798506],[15845988608448177198,"num_complex",false,7908486078001762746]],"local":[{"CheckDepInfo":{"dep_info":"debug\\.fingerprint\\alga-92b511306c3ba896\\dep-lib-alga-92b511306c3ba896"}}],"rustflags":[],"metadata":16934162586732421168}
|
|
@ -0,0 +1 @@
|
||||||
|
This file has an mtime of when this was started.
|
|
@ -0,0 +1 @@
|
||||||
|
1fd069d262a16d8a
|
|
@ -0,0 +1 @@
|
||||||
|
{"rustc":12207601712932690048,"features":"[\"std\"]","target":9258705378109553973,"profile":9935990280773120926,"path":16073260490560416965,"deps":[[1951668677046445136,"approx",false,6430038081729786697],[7216377681729432009,"num_traits",false,11520591089723022789],[15845988608448177198,"num_complex",false,120132229748337530]],"local":[{"CheckDepInfo":{"dep_info":"debug\\.fingerprint\\alga-b794fda61d9c9f30\\dep-lib-alga-b794fda61d9c9f30"}}],"rustflags":[],"metadata":16934162586732421168}
|
|
@ -0,0 +1 @@
|
||||||
|
This file has an mtime of when this was started.
|
|
@ -0,0 +1 @@
|
||||||
|
6ecb114cd91c6e9a
|
|
@ -0,0 +1 @@
|
||||||
|
{"rustc":12207601712932690048,"features":"[\"std\"]","target":9258705378109553973,"profile":14672114853574311971,"path":16073260490560416965,"deps":[[1951668677046445136,"approx",false,15152171042854381304],[7216377681729432009,"num_traits",false,17834334400922953852],[15845988608448177198,"num_complex",false,9536299976409066134]],"local":[{"CheckDepInfo":{"dep_info":"debug\\.fingerprint\\alga-cf984dc39e604cff\\dep-lib-alga-cf984dc39e604cff"}}],"rustflags":[],"metadata":16934162586732421168}
|
|
@ -0,0 +1 @@
|
||||||
|
This file has an mtime of when this was started.
|
|
@ -0,0 +1 @@
|
||||||
|
2e9042e6c73b485b
|
|
@ -0,0 +1 @@
|
||||||
|
{"rustc":12207601712932690048,"features":"[]","target":7928831156482473482,"profile":14672114853574311971,"path":11208681304070709304,"deps":[[7216377681729432009,"num_traits",false,7980548084844201855]],"local":[{"CheckDepInfo":{"dep_info":"debug\\.fingerprint\\approx-3305c48ec0a3008d\\dep-lib-approx-3305c48ec0a3008d"}}],"rustflags":[],"metadata":16854554930049447738}
|
|
@ -0,0 +1 @@
|
||||||
|
This file has an mtime of when this was started.
|
|
@ -0,0 +1 @@
|
||||||
|
49f3bc4991153c59
|
|
@ -0,0 +1 @@
|
||||||
|
{"rustc":12207601712932690048,"features":"[]","target":7928831156482473482,"profile":9935990280773120926,"path":11208681304070709304,"deps":[[7216377681729432009,"num_traits",false,11520591089723022789]],"local":[{"CheckDepInfo":{"dep_info":"debug\\.fingerprint\\approx-76c0a19ca1f8b2bb\\dep-lib-approx-76c0a19ca1f8b2bb"}}],"rustflags":[],"metadata":16854554930049447738}
|
|
@ -0,0 +1 @@
|
||||||
|
This file has an mtime of when this was started.
|
|
@ -0,0 +1 @@
|
||||||
|
f8a64ba9485347d2
|
|
@ -0,0 +1 @@
|
||||||
|
{"rustc":12207601712932690048,"features":"[]","target":7928831156482473482,"profile":14672114853574311971,"path":11208681304070709304,"deps":[[7216377681729432009,"num_traits",false,17834334400922953852]],"local":[{"CheckDepInfo":{"dep_info":"debug\\.fingerprint\\approx-b146f740cf2751b5\\dep-lib-approx-b146f740cf2751b5"}}],"rustflags":[],"metadata":16854554930049447738}
|
|
@ -0,0 +1 @@
|
||||||
|
This file has an mtime of when this was started.
|
|
@ -0,0 +1 @@
|
||||||
|
77e650fe0b7b1ffa
|
|
@ -0,0 +1 @@
|
||||||
|
{"rustc":12207601712932690048,"features":"[]","target":7928831156482473482,"profile":9935990280773120926,"path":11208681304070709304,"deps":[[7216377681729432009,"num_traits",false,3818044152068798506]],"local":[{"CheckDepInfo":{"dep_info":"debug\\.fingerprint\\approx-ecdda099ed410c28\\dep-lib-approx-ecdda099ed410c28"}}],"rustflags":[],"metadata":16854554930049447738}
|
|
@ -0,0 +1 @@
|
||||||
|
This file has an mtime of when this was started.
|
|
@ -0,0 +1 @@
|
||||||
|
3053ba62fa82055f
|
|
@ -0,0 +1 @@
|
||||||
|
{"rustc":12207601712932690048,"features":"[]","target":5569561587987676018,"profile":9935990280773120926,"path":11024953172022924607,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug\\.fingerprint\\autocfg-4d3f61728aad50c0\\dep-lib-autocfg-4d3f61728aad50c0"}}],"rustflags":[],"metadata":18213289899592611528}
|
|
@ -0,0 +1 @@
|
||||||
|
This file has an mtime of when this was started.
|
|
@ -0,0 +1 @@
|
||||||
|
c74e84aa1051d320
|
|
@ -0,0 +1 @@
|
||||||
|
{"rustc":12207601712932690048,"features":"[]","target":5569561587987676018,"profile":9935990280773120926,"path":13475262468176122485,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug\\.fingerprint\\autocfg-7a8241ec2aaa37e0\\dep-lib-autocfg-7a8241ec2aaa37e0"}}],"rustflags":[],"metadata":18213289899592611528}
|
|
@ -0,0 +1 @@
|
||||||
|
This file has an mtime of when this was started.
|
|
@ -0,0 +1 @@
|
||||||
|
5bffb0d813c687ad
|
|
@ -0,0 +1 @@
|
||||||
|
{"rustc":12207601712932690048,"features":"[\"addr2line\", \"default\", \"gimli-symbolize\", \"miniz_oxide\", \"object\", \"std\"]","target":16712715360960966281,"profile":9935990280773120926,"path":15285438630436746122,"deps":[[6824117138527718822,"libc",false,52686853109561366],[9202982497086577583,"miniz_oxide",false,6706537442428666616],[10687924014058982666,"rustc_demangle",false,974523111465493955],[13353560740643010665,"cfg_if",false,17501794342123126626],[13474011796623780910,"object",false,2848864681485534101],[15030762764533320563,"addr2line",false,9232425983736102363]],"local":[{"CheckDepInfo":{"dep_info":"debug\\.fingerprint\\backtrace-2731cc83ed8cceb4\\dep-lib-backtrace-2731cc83ed8cceb4"}}],"rustflags":[],"metadata":12597549411253744391}
|
|
@ -0,0 +1 @@
|
||||||
|
This file has an mtime of when this was started.
|
|
@ -0,0 +1 @@
|
||||||
|
2b9e222dfb271e54
|
|
@ -0,0 +1 @@
|
||||||
|
{"rustc":12207601712932690048,"features":"[\"addr2line\", \"default\", \"gimli-symbolize\", \"miniz_oxide\", \"object\", \"std\"]","target":16712715360960966281,"profile":14672114853574311971,"path":15285438630436746122,"deps":[[6824117138527718822,"libc",false,5415395039475141299],[9202982497086577583,"miniz_oxide",false,14560653146167183749],[10687924014058982666,"rustc_demangle",false,10031205660284960560],[13353560740643010665,"cfg_if",false,9738745122429390245],[13474011796623780910,"object",false,12996341115640085343],[15030762764533320563,"addr2line",false,4410366295242695291]],"local":[{"CheckDepInfo":{"dep_info":"debug\\.fingerprint\\backtrace-adcaf657db9e02d3\\dep-lib-backtrace-adcaf657db9e02d3"}}],"rustflags":[],"metadata":12597549411253744391}
|
|
@ -0,0 +1 @@
|
||||||
|
This file has an mtime of when this was started.
|
|
@ -0,0 +1 @@
|
||||||
|
bed5559b154f96ab
|
|
@ -0,0 +1 @@
|
||||||
|
{"rustc":12207601712932690048,"features":"[\"default\"]","target":13526883075859089328,"profile":9935990280773120926,"path":1930079083076275365,"deps":[[15150800114095447224,"build_script_build",false,7817873588385516288]],"local":[{"CheckDepInfo":{"dep_info":"debug\\.fingerprint\\bitflags-175d81486c4c23b9\\dep-lib-bitflags-175d81486c4c23b9"}}],"rustflags":[],"metadata":13051731519915299023}
|
|
@ -0,0 +1 @@
|
||||||
|
5e35e0ec9108ce29
|
|
@ -0,0 +1 @@
|
||||||
|
{"rustc":12207601712932690048,"features":"[\"default\"]","target":10088282520713642473,"profile":9935990280773120926,"path":3614827716476440570,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug\\.fingerprint\\bitflags-2085827d2ccfc591\\dep-build-script-build_script_build-2085827d2ccfc591"}}],"rustflags":[],"metadata":13051731519915299023}
|
|
@ -0,0 +1 @@
|
||||||
|
This file has an mtime of when this was started.
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue