diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..8bb49b95 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +ply/**/*.ply binary linguist-generated + diff --git a/README.md b/README.md index 3fee4a73..4ebb2f5c 100644 --- a/README.md +++ b/README.md @@ -25,13 +25,11 @@ If you make a PR to this repository, please acknowledge that you are giving all ### Model files -This repository has some example model files for demonstrating triangle-based object imports in addition to the declarative object primitives. +This repository has some example model files for demonstrating triangle-based object imports in addition to the declarative object primitives. Check the following directories: -- Utah Teapot model `teapot.stl` CC0 1.0 Universal Public Domain [Wikipedia]() -- Stanford Bunny model `bunny.stl` CC Attribution 3.0 Unported [Wikipedia](https://commons.wikimedia.org/wiki/File:Stanford_Bunny.stl) -- Stanford Dragon model `dragon.stl` (stl converted version) CC Attribution [Thingiverse](https://www.thingiverse.com/thing:27666) -- Rubber Duck model `duck.stl` CC0 1.0 Universal Public Domain [Thingiverse](https://www.thingiverse.com/thing:139894) -- Triangular Prism model `prism.stl` Public Domain [Wikipedia](https://commons.wikimedia.org/wiki/File:Triangular_prism.stl) +- `stl/` +- `ply/` +- `gltf/` ## Useful references diff --git a/clovers-cli/Cargo.toml b/clovers-cli/Cargo.toml index 3eb35d12..2eadaea9 100644 --- a/clovers-cli/Cargo.toml +++ b/clovers-cli/Cargo.toml @@ -19,6 +19,7 @@ clovers = { path = "../clovers", features = [ "stl", "traces", "gl_tf", + "ply", ], default-features = false } # External diff --git a/clovers-cli/src/scenefile.rs b/clovers-cli/src/scenefile.rs index aaaf3d38..46a6dd9f 100644 --- a/clovers-cli/src/scenefile.rs +++ b/clovers-cli/src/scenefile.rs @@ -70,6 +70,7 @@ impl SceneFile { Object::RotateY(i) => i.priority, Object::Sphere(i) => i.priority, Object::STL(i) => i.priority, + Object::PLY(i) => i.priority, Object::GLTF(i) => i.priority, Object::Translate(i) => i.priority, Object::Triangle(i) => i.priority, diff --git a/clovers/Cargo.toml b/clovers/Cargo.toml index 5e88c681..b5230aa3 100644 --- a/clovers/Cargo.toml +++ b/clovers/Cargo.toml @@ -11,6 +11,7 @@ path = "src/lib.rs" crate-type = ["lib"] [features] +ply = ["ply-rs"] serde-derive = ["serde/derive", "nalgebra/serde-serialize"] stl = ["stl_io", "std"] gl_tf = ["gltf"] @@ -22,6 +23,7 @@ enum_dispatch = "0.3.13" gltf = { version = "1.4.1", optional = true } nalgebra = { version = "0.33.0" } palette = { version = "0.7.6", features = ["serializing"] } +ply-rs = { version = "0.1.3", optional = true } rand = { version = "0.8.5", features = ["small_rng"], default-features = false } rand_distr = { version = "0.4.3", features = ["std_math"] } serde = { version = "1.0.204", features = [ diff --git a/clovers/src/objects.rs b/clovers/src/objects.rs index c051c856..64ee218b 100644 --- a/clovers/src/objects.rs +++ b/clovers/src/objects.rs @@ -11,6 +11,8 @@ pub mod constant_medium; #[cfg(feature = "gl_tf")] pub mod gltf; pub mod moving_sphere; +#[cfg(feature = "ply")] +pub mod ply; pub mod quad; pub mod rotate; pub mod sphere; @@ -25,6 +27,8 @@ use alloc::vec::Vec; pub use boxy::*; // avoid keyword pub use constant_medium::*; pub use moving_sphere::*; +#[cfg(feature = "ply")] +pub use ply::*; pub use quad::*; pub use rotate::*; pub use sphere::*; @@ -70,6 +74,9 @@ pub enum Object { #[cfg(feature = "stl")] /// STL object initializer STL(STLInit), + #[cfg(feature = "ply")] + /// PLY object initializer + PLY(PLYInit), #[cfg(feature = "gl_tf")] /// GLTF object initializer GLTF(GLTFInit), @@ -127,6 +134,11 @@ pub fn object_to_hitable(obj: Object, materials: &[SharedMaterial]) -> Hitable<' let stl = initialize_stl(stl_init, materials); Hitable::HitableList(HitableList::new(stl.hitables)) } + #[cfg(feature = "ply")] + Object::PLY(ply_init) => { + let ply = initialize_ply(ply_init, materials); + Hitable::HitableList(HitableList::new(ply.hitables)) + } #[cfg(feature = "gl_tf")] Object::GLTF(x) => { let gltf = GLTF::new(x); diff --git a/clovers/src/objects/ply.rs b/clovers/src/objects/ply.rs new file mode 100644 index 00000000..124a7c14 --- /dev/null +++ b/clovers/src/objects/ply.rs @@ -0,0 +1,166 @@ +//! PLY utilities + +use alloc::string::String; +use nalgebra::Rotation3; +use ply_rs::{ + parser::Parser, + ply::{self, Property}, +}; + +use crate::{ + aabb::AABB, + bvh::build::utils::vec_bounding_box, + hitable::Hitable, + materials::{Material, MaterialInit, SharedMaterial}, + objects::Triangle, + Float, Position, Vec3, +}; + +/// Internal PLY object representation after initialization. Contains the material for all triangles in it to avoid having n copies. +#[derive(Debug, Clone)] +pub struct PLY<'scene> { + /// Primitives of the `PLY` object, a list of `Triangle`s. + pub hitables: Vec>, + /// Material for the object + pub material: &'scene Material, + /// Axis-aligned bounding box of the object + pub aabb: AABB, +} + +/// PLY structure. This gets converted into an internal representation using [Triangles](crate::objects::Triangle) +#[derive(Clone, Debug)] +#[cfg_attr(feature = "serde-derive", derive(serde::Serialize, serde::Deserialize))] +pub struct PLYInit { + /// Used for multiple importance sampling + #[cfg_attr(feature = "serde-derive", serde(default))] + pub priority: bool, + /// Path of the .ply file + pub path: String, + /// Material to use for the .ply object + #[cfg_attr(feature = "serde-derive", serde(default))] + pub material: MaterialInit, + /// Scaling factor for the object + pub scale: Float, + /// Location of the object in the rendered scene + pub center: Position, + /// Rotation of the object. Described as three angles, `roll`, `pitch`, `yaw`, applied in that order. + pub rotation: Vec3, +} + +#[must_use] +/// Initializes a PLY +pub fn initialize_ply<'scene>( + ply_init: PLYInit, + materials: &'scene [SharedMaterial], +) -> PLY<'scene> { + let material: &Material = match ply_init.material { + MaterialInit::Shared(name) => &materials.iter().find(|m| m.name == name).unwrap().material, + MaterialInit::Owned(m) => { + // TODO: do not leak memory + let material: &'scene Material = Box::leak(Box::new(m)); + material + } + }; + let mut hitables = Vec::new(); + + // TODO: error handling! + let mut f = std::fs::File::open(ply_init.path).unwrap(); + let parser = Parser::::new(); + let ply = parser.read_ply(&mut f); + let ply = ply.unwrap(); + + let mut vertices = Vec::new(); + for vertex in &ply.payload["vertex"] { + let x = property_to_float(&vertex["x"]); + let y = property_to_float(&vertex["y"]); + let z = property_to_float(&vertex["z"]); + vertices.push(Vec3::new(x, y, z)); + } + + for face in &ply.payload["face"] { + let indices = property_to_vec_u32(&face["vertex_indices"]); + + let a = vertices[indices[0]]; + let b = vertices[indices[1]]; + let c = vertices[indices[2]]; + + let a: Vec3 = Vec3::new(a[0], a[1], a[2]); + let b: Vec3 = Vec3::new(b[0], b[1], b[2]); + let c: Vec3 = Vec3::new(c[0], c[1], c[2]); + // Handle rotation + let rotation = Rotation3::from_euler_angles( + ply_init.rotation[0].to_radians(), + ply_init.rotation[1].to_radians(), + ply_init.rotation[2].to_radians(), + ); + let a: Vec3 = rotation * a; + let b: Vec3 = rotation * b; + let c: Vec3 = rotation * c; + // Handle scaling and offset + let a: Vec3 = a * ply_init.scale + ply_init.center; + let b: Vec3 = b * ply_init.scale + ply_init.center; + let c: Vec3 = c * ply_init.scale + ply_init.center; + + let triangle = Triangle::from_coordinates(a, b, c, material); + hitables.push(Hitable::Triangle(triangle)); + } + // TODO: remove unwrap + let aabb = vec_bounding_box(&hitables).unwrap(); + + PLY { + hitables, + material, + aabb, + } +} + +// TODO: better ergonomics? +#[allow(trivial_numeric_casts)] +#[allow(clippy::cast_precision_loss)] +#[allow(clippy::cast_possible_truncation)] +fn property_to_float(p: &Property) -> Float { + match *p { + Property::Int(i) => i as Float, + Property::UInt(u) => u as Float, + Property::Float(f) => f as Float, + Property::Double(f) => f as Float, + // Unsupported + Property::Char(_) + | Property::UChar(_) + | Property::Short(_) + | Property::UShort(_) + | Property::ListChar(_) + | Property::ListUChar(_) + | Property::ListShort(_) + | Property::ListUShort(_) + | Property::ListInt(_) + | Property::ListUInt(_) + | Property::ListFloat(_) + | Property::ListDouble(_) => unimplemented!("PLY: unsupported property format {p:?}"), + } +} + +// TODO: better ergonomics? +#[allow(trivial_numeric_casts)] +fn property_to_vec_u32(p: &Property) -> Vec { + match p { + Property::Char(_) + | Property::UChar(_) + | Property::Short(_) + | Property::UShort(_) + | Property::Int(_) + | Property::UInt(_) + | Property::Float(_) + | Property::Double(_) + | Property::ListChar(_) + | Property::ListFloat(_) + | Property::ListDouble(_) => unimplemented!("PLY: unsupported property format {p:?}"), + // + Property::ListUChar(vec_u) => vec_u.iter().map(|&u| u.into()).collect(), + Property::ListUShort(vec_u) => vec_u.iter().map(|&u| u.into()).collect(), + Property::ListUInt(vec_u) => vec_u.iter().map(|&u| u as usize).collect(), + // + Property::ListShort(vec_i) => vec_i.iter().map(|&i| i.unsigned_abs().into()).collect(), + Property::ListInt(vec_i) => vec_i.iter().map(|&i| i.unsigned_abs() as usize).collect(), + } +} diff --git a/gltf/README.md b/gltf/README.md index 7ee35ef9..bfa44408 100644 --- a/gltf/README.md +++ b/gltf/README.md @@ -1,3 +1,3 @@ -# gltf +# glTF models Models borrowed from [glTF Sample Models](https://github.com/KhronosGroup/glTF-Sample-Models) diff --git a/ply/README.md b/ply/README.md new file mode 100644 index 00000000..c2bd952e --- /dev/null +++ b/ply/README.md @@ -0,0 +1,24 @@ +# PLY models + +These famous objects are from the [Large Geometric Models Archive at Georgia Tech](https://sites.cc.gatech.edu/projects/large_models/index.html). + +| Model | Faces | Vertices | +| --------------- | --------- | -------- | +| Stanford Bunny | 69,451 | 35,947 | +| Stanford Dragon | 871,414 | 437,645 | +| Happy Buddha | 1,087,716 | 543,652 | + +The files were converted from the ASCII ply format to the binary ply format using the `ply2binary` program, built from the sources available [here](https://sites.cc.gatech.edu/projects/large_models/ply.html). To quote from the README of that repository: + +> These geometry filters have been developed on a Silicon Graphics +> workstation using the native C compiler. The code may very well run +> unmodified on other platforms but this has not yet been verified. + +Indeed, the code assumes a different endianness from the running operating system. As a workaround, after running `./ply2binary < ~/example.ascii.ply > ~/example.binary.ply`, you need to edit the header in the binary file: + +```diff +- format binary_big_endian 1.0 ++ format binary_little_endian 1.0 +``` + +After this change, the binary file can be read correctly by compliant parsers. diff --git a/ply/bunny.binary.ply b/ply/bunny.binary.ply new file mode 100644 index 00000000..e756fd8c Binary files /dev/null and b/ply/bunny.binary.ply differ diff --git a/ply/dragon.binary.ply b/ply/dragon.binary.ply new file mode 100644 index 00000000..d9d36357 Binary files /dev/null and b/ply/dragon.binary.ply differ diff --git a/ply/happy.binary.ply b/ply/happy.binary.ply new file mode 100644 index 00000000..86093bcc Binary files /dev/null and b/ply/happy.binary.ply differ diff --git a/scenes/bunny.json b/scenes/bunny.json new file mode 100644 index 00000000..80963450 --- /dev/null +++ b/scenes/bunny.json @@ -0,0 +1,84 @@ +{ + "time_0": 0, + "time_1": 1, + "background_color": [0.025, 0.025, 0.025], + "camera": { + "look_from": [0, 200, -800], + "look_at": [0, 200, 0], + "up": [0, 1, 0], + "vertical_fov": 40, + "aperture": 30, + "focus_distance": 650 + }, + "objects": [ + { + "kind": "PLY", + "comment": "bunny", + "path": "ply/bunny.binary.ply", + "scale": 2500, + "center": [-45, -85, 0], + "rotation": [0, 200, 0], + "material": "white lambertian" + }, + { + "kind": "Quad", + "comment": "floor", + "q": [-2000, 0.01, -500], + "u": [4000, 0, 0], + "v": [0, 0, 1000], + "material": "checkerboard" + }, + { + "kind": "Quad", + "comment": "back wall", + "q": [-2000, 0, 500], + "u": [4000, 0, 0], + "v": [0, 1000, 0], + "material": "checkerboard" + }, + { + "kind": "Sphere", + "center": [0, 800, -300], + "radius": 300, + "material": "lamp", + "comment": "big ceiling light", + "priority": true + } + ], + "materials": [ + { + "name": "dark lambertian", + "kind": "Lambertian", + "albedo": { + "kind": "SolidColor", + "color": [0.3, 0.3, 0.3] + } + }, + { + "name": "white lambertian", + "kind": "Lambertian", + "albedo": { + "kind": "SolidColor", + "color": [0.8, 0.8, 0.8] + } + }, + { + "name": "checkerboard", + "kind": "Lambertian", + "albedo": { + "kind": "SpatialChecker", + "even": [0.8, 0.8, 0.8], + "odd": [0.3, 0.3, 0.3], + "density": 0.01 + } + }, + { + "name": "lamp", + "kind": "DiffuseLight", + "emit": { + "kind": "SolidColor", + "color": [5, 5, 5] + } + } + ] +} diff --git a/scenes/dragon.json b/scenes/dragon.json index a22fbd55..3cf0a4b8 100644 --- a/scenes/dragon.json +++ b/scenes/dragon.json @@ -1,78 +1,93 @@ { "time_0": 0, "time_1": 1, - "background_color": [0, 0, 0], + "background_color": [0.025, 0.025, 0.025], "camera": { - "look_from": [0, 250, -800], - "look_at": [0, 250, 0], + "look_from": [0, 200, -800], + "look_at": [0, 200, 0], "up": [0, 1, 0], "vertical_fov": 40, - "aperture": 10, - "focus_distance": 800 + "aperture": 30, + "focus_distance": 650 }, "objects": [ { - "kind": "Quad", - "comment": "back wall", - "q": [-2000, 0, 800], - "u": [4000, 0, 0], - "v": [0, 1000, 0], - "material": { - "kind": "Lambertian", - "albedo": { "kind": "SolidColor", "color": [1, 1, 1] } - } - }, - { - "kind": "STL", + "kind": "PLY", "comment": "dragon", - "path": "stl/dragon.stl", - "scale": 12, - "center": [0, 240, 250], - "rotation": [-90, -40, 0], - "material": { - "name": "Dense flint glass SF10", - "kind": "Dispersive", - "cauchy_a": 1.728, - "cauchy_b": 0.01342 - } + "path": "ply/dragon.binary.ply", + "scale": 2500, + "center": [-45, -135, -100], + "rotation": [0, 200, 0], + "material": "white lambertian" }, { "kind": "Quad", - "q": [-2000, 0, -200], + "comment": "floor", + "q": [-2000, 0.01, -500], "u": [4000, 0, 0], "v": [0, 0, 1000], - "comment": "floor", - "priority": false, - "material": { - "kind": "Lambertian", - "albedo": { "kind": "SolidColor", "color": [1, 1, 1] } - } + "material": "checkerboard" }, { "kind": "Quad", - "q": [-200, 800, 100], - "u": [400, 0, 0], - "v": [0, 0, 400], - "material": { - "kind": "DiffuseLight", - "emit": { "kind": "SolidColor", "color": [7, 7, 7] } - }, + "comment": "back wall", + "q": [-2000, 0, 500], + "u": [4000, 0, 0], + "v": [0, 1000, 0], + "material": "checkerboard" + }, + { + "kind": "Sphere", + "center": [0, 800, -300], + "radius": 300, + "material": "lamp", "comment": "big ceiling light", "priority": true } ], - "priority_objects": [ + "materials": [ { - "kind": "Quad", - "q": [-200, 800, 100], - "u": [400, 0, 0], - "v": [0, 0, 400], - "material": { - "kind": "DiffuseLight", - "emit": { "kind": "SolidColor", "color": [7, 7, 7] } + "name": "dark lambertian", + "kind": "Lambertian", + "albedo": { + "kind": "SolidColor", + "color": [0.3, 0.3, 0.3] + } + }, + { + "name": "white lambertian", + "kind": "Lambertian", + "albedo": { + "kind": "SolidColor", + "color": [0.8, 0.8, 0.8] + } + }, + { + "name": "checkerboard", + "kind": "Lambertian", + "albedo": { + "kind": "SpatialChecker", + "even": [0.8, 0.8, 0.8], + "odd": [0.3, 0.3, 0.3], + "density": 0.01 + } + }, + { + "name": "lamp", + "kind": "DiffuseLight", + "emit": { + "kind": "SolidColor", + "color": [5, 5, 5] + } + }, + { + "name": "copper", + "kind": "Metal", + "albedo": { + "kind": "SolidColor", + "color": { "hex": "#b87333" } }, - "comment": "big ceiling light", - "priority": true + "fuzz": 0.35 } ] } diff --git a/scenes/happy_buddha.json b/scenes/happy_buddha.json new file mode 100644 index 00000000..3740d279 --- /dev/null +++ b/scenes/happy_buddha.json @@ -0,0 +1,84 @@ +{ + "time_0": 0, + "time_1": 1, + "background_color": [0.025, 0.025, 0.025], + "camera": { + "look_from": [0, 200, -800], + "look_at": [0, 200, 0], + "up": [0, 1, 0], + "vertical_fov": 40, + "aperture": 30, + "focus_distance": 650 + }, + "objects": [ + { + "kind": "PLY", + "comment": "happy buddha", + "path": "ply/happy.binary.ply", + "scale": 2200, + "center": [-18.5, -112, -130], + "rotation": [0, 200, 0], + "material": "white lambertian" + }, + { + "kind": "Quad", + "comment": "floor", + "q": [-2000, 0.01, -500], + "u": [4000, 0, 0], + "v": [0, 0, 1000], + "material": "checkerboard" + }, + { + "kind": "Quad", + "comment": "back wall", + "q": [-2000, 0, 500], + "u": [4000, 0, 0], + "v": [0, 1000, 0], + "material": "checkerboard" + }, + { + "kind": "Sphere", + "center": [0, 800, -300], + "radius": 300, + "material": "lamp", + "comment": "big ceiling light", + "priority": true + } + ], + "materials": [ + { + "name": "dark lambertian", + "kind": "Lambertian", + "albedo": { + "kind": "SolidColor", + "color": [0.3, 0.3, 0.3] + } + }, + { + "name": "white lambertian", + "kind": "Lambertian", + "albedo": { + "kind": "SolidColor", + "color": [0.8, 0.8, 0.8] + } + }, + { + "name": "checkerboard", + "kind": "Lambertian", + "albedo": { + "kind": "SpatialChecker", + "even": [0.8, 0.8, 0.8], + "odd": [0.3, 0.3, 0.3], + "density": 0.01 + } + }, + { + "name": "lamp", + "kind": "DiffuseLight", + "emit": { + "kind": "SolidColor", + "color": [5, 5, 5] + } + } + ] +} diff --git a/scenes/scene.json b/scenes/scene.json deleted file mode 100644 index 2122a32f..00000000 --- a/scenes/scene.json +++ /dev/null @@ -1,165 +0,0 @@ -{ - "time_0": 0, - "time_1": 1, - "background_color": [0, 0, 0], - "camera": { - "look_from": [300, 250, -800], - "look_at": [300, 250, 0], - "up": [0, 1, 0], - "vertical_fov": 40, - "aperture": 0, - "focus_distance": 10 - }, - "objects": [ - { - "kind": "STL", - "comment": "dragon", - "path": "stl/dragon.stl", - "rotation": [-90, 180, 0], - "center": [270, 300, 600], - "scale": 15, - "material": "gold" - }, - { - "kind": "STL", - "path": "stl/teapot.stl", - "comment": "teapot", - "rotation": [-90, 180, 0], - "center": [650, 0, 100], - "material": "teal", - "scale": 20 - }, - { - "kind": "STL", - "comment": "bunny", - "path": "stl/bunny.stl", - "scale": 3, - "center": [-80, -15, 300], - "rotation": [-90, 180, 0], - "material": "pink" - }, - { - "kind": "Translate", - "comment": "tall box", - "offset": [750, 0, 600], - "object": { - "kind": "RotateY", - "angle": 35, - "object": { - "kind": "ConstantMedium", - "density": 0.01, - "boundary": { - "kind": "Boxy", - "corner_0": [0, 0, 0], - "corner_1": [200, 400, 200], - "material": "fog" - } - }, - "texture": { - "kind": "SolidColor", - "color": [0.9, 0.9, 0.9] - } - } - }, - { - "kind": "Sphere", - "comment": "metal sphere", - "radius": 90, - "center": [400, 90, 300], - "material": "metal sphere" - }, - { - "kind": "Quad", - "q": [-5000, 0, -500], - "u": [10000, 0, 0], - "v": [0, 0, 10000], - "comment": "floor", - "material": "metal floor" - }, - { - "kind": "Quad", - "priority": true, - "q": [0, 700, -100], - "u": [600, 0, 0], - "v": [0, 0, 300], - "material": "lamp", - "comment": "big ceiling light" - }, - { - "kind": "Sphere", - "priority": true, - "center": [190, 120, 190], - "radius": 90, - "material": "glass", - "comment": "glass sphere" - } - ], - "materials": [ - { - "name": "gold", - "kind": "Metal", - "albedo": { - "kind": "SolidColor", - "color": [0.9, 0.6, 0.3] - } - }, - { - "name": "teal", - "kind": "Lambertian", - "albedo": { - "kind": "SolidColor", - "color": [0.5, 0.9, 0.7] - } - }, - { - "name": "pink", - "kind": "Lambertian", - "albedo": { - "kind": "SolidColor", - "color": [0.7, 0.3, 0.5] - } - }, - { - "name": "fog", - "kind": "Isotropic", - "albedo": { - "kind": "SolidColor", - "color": [0.9, 0.9, 0.9] - } - }, - { - "name": "metal sphere", - "kind": "Metal", - "fuzz": 0.05, - "albedo": { - "kind": "SolidColor", - "color": [0.7, 0.7, 0.7] - } - }, - { - "name": "metal floor", - "kind": "Metal", - "albedo": { - "kind": "SurfaceChecker", - "even": [0.9, 0.9, 0.9], - "odd": [0.1, 0.1, 0.1], - "density": 100 - }, - "fuzz": 0.015 - }, - { - "name": "lamp", - "kind": "DiffuseLight", - "emit": { - "kind": "SolidColor", - "color": [7, 7, 7] - } - }, - { - "name": "glass", - "kind": "Dielectric", - "refractive_index": 1.5, - "color": [1, 1, 1] - } - ] -} diff --git a/scenes/teapot.json b/scenes/teapot.json new file mode 100644 index 00000000..c52f5278 --- /dev/null +++ b/scenes/teapot.json @@ -0,0 +1,84 @@ +{ + "time_0": 0, + "time_1": 1, + "background_color": [0.025, 0.025, 0.025], + "camera": { + "look_from": [0, 200, -800], + "look_at": [0, 200, 0], + "up": [0, 1, 0], + "vertical_fov": 40, + "aperture": 30, + "focus_distance": 650 + }, + "objects": [ + { + "kind": "STL", + "comment": "teapot", + "path": "stl/teapot.stl", + "scale": 25, + "center": [0, 10, -90], + "rotation": [-90, 0, 0], + "material": "white lambertian" + }, + { + "kind": "Quad", + "comment": "floor", + "q": [-2000, 0.01, -500], + "u": [4000, 0, 0], + "v": [0, 0, 1000], + "material": "checkerboard" + }, + { + "kind": "Quad", + "comment": "back wall", + "q": [-2000, 0, 500], + "u": [4000, 0, 0], + "v": [0, 1000, 0], + "material": "checkerboard" + }, + { + "kind": "Sphere", + "center": [0, 800, -300], + "radius": 300, + "material": "lamp", + "comment": "big ceiling light", + "priority": true + } + ], + "materials": [ + { + "name": "dark lambertian", + "kind": "Lambertian", + "albedo": { + "kind": "SolidColor", + "color": [0.3, 0.3, 0.3] + } + }, + { + "name": "white lambertian", + "kind": "Lambertian", + "albedo": { + "kind": "SolidColor", + "color": [0.8, 0.8, 0.8] + } + }, + { + "name": "checkerboard", + "kind": "Lambertian", + "albedo": { + "kind": "SpatialChecker", + "even": [0.8, 0.8, 0.8], + "odd": [0.3, 0.3, 0.3], + "density": 0.01 + } + }, + { + "name": "lamp", + "kind": "DiffuseLight", + "emit": { + "kind": "SolidColor", + "color": [5, 5, 5] + } + } + ] +} diff --git a/stl/README.md b/stl/README.md new file mode 100644 index 00000000..bfb6e376 --- /dev/null +++ b/stl/README.md @@ -0,0 +1,4 @@ +# STL models + +- Utah Teapot model `teapot.stl` CC0 1.0 Universal Public Domain [Wikipedia]() +- Triangular Prism model `prism.stl` Public Domain [Wikipedia](https://commons.wikimedia.org/wiki/File:Triangular_prism.stl) diff --git a/stl/bunny.stl b/stl/bunny.stl deleted file mode 100644 index bec02fcb..00000000 Binary files a/stl/bunny.stl and /dev/null differ diff --git a/stl/dragon.stl b/stl/dragon.stl deleted file mode 100644 index 3efa0456..00000000 Binary files a/stl/dragon.stl and /dev/null differ diff --git a/stl/duck.stl b/stl/duck.stl deleted file mode 100644 index 8f4b986f..00000000 Binary files a/stl/duck.stl and /dev/null differ