refactor: scene deserialization organisation
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
"camera": {
|
"camera": {
|
||||||
"image_width": 1920,
|
"image_width": 1920,
|
||||||
"image_height": 1080,
|
"image_height": 1080,
|
||||||
"anti_alias_rate": 23,
|
"anti_alias_rate": 2,
|
||||||
"max_depth": 50,
|
"max_depth": 50,
|
||||||
"fov": 90.0,
|
"fov": 90.0,
|
||||||
"look_from": [15, 4, 15],
|
"look_from": [15, 4, 15],
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ fn main() {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// random spheres code; thought: make this available as cli flag?
|
// random spheres code; thought: make this available as cli flag?
|
||||||
let ground = Lambertian::rgb(0.5, 0.5, 0.5, 1.);
|
let ground = Lambertian::rgb(-2.5, 0.5, 0.5, 1.);
|
||||||
let mut world: Vec<Arc<dyn Hittable>> = vec![Arc::new(Sphere::xyz(
|
let mut world: Vec<Arc<dyn Hittable>> = vec![Arc::new(Sphere::xyz(
|
||||||
0.,
|
0.,
|
||||||
-1000.,
|
-1000.,
|
||||||
@@ -112,6 +112,7 @@ fn main() {
|
|||||||
c.set_fov(20.);
|
c.set_fov(20.);
|
||||||
c.set_anti_alias_rate(23);
|
c.set_anti_alias_rate(23);
|
||||||
c.set_max_depth(50);
|
c.set_max_depth(50);
|
||||||
|
c.set_vup(Vec3::new(0., 1., 0.));
|
||||||
c.set_look_from(Vec3::new(13., 2., 3.));
|
c.set_look_from(Vec3::new(13., 2., 3.));
|
||||||
c.set_look_at(Vec3::new(0., 0., 0.));
|
c.set_look_at(Vec3::new(0., 0., 0.));
|
||||||
c.add_defocus_blur(0.6, 10.);
|
c.add_defocus_blur(0.6, 10.);
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ use super::hit::Hit;
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Cube {
|
pub struct Cube {
|
||||||
faces: Vec<Arc<dyn Hittable>>,
|
faces: Vec<Arc<dyn Hittable>>,
|
||||||
material: Arc<dyn Material>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Cube {
|
impl Cube {
|
||||||
@@ -34,7 +33,7 @@ impl Cube {
|
|||||||
Arc::new(Quad::new(p5, p6, p7, p8, material.clone())),
|
Arc::new(Quad::new(p5, p6, p7, p8, material.clone())),
|
||||||
Arc::new(Quad::new(p4, p3, p7, p8, material.clone())),
|
Arc::new(Quad::new(p4, p3, p7, p8, material.clone())),
|
||||||
];
|
];
|
||||||
Self { faces, material }
|
Self { faces }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
use crate::objects::hit::Hit;
|
use crate::objects::hit::Hit;
|
||||||
use crate::objects::sphere::Sphere;
|
|
||||||
use crate::objects::traits::Hittable;
|
use crate::objects::traits::Hittable;
|
||||||
use crate::objects::triangle::Triangle;
|
use crate::objects::triangle::Triangle;
|
||||||
use crate::ray::Ray;
|
use crate::ray::Ray;
|
||||||
@@ -27,14 +26,6 @@ impl Quad {
|
|||||||
normal: (p2 - p1).cross(&(p4 - p1)).get_unit(),
|
normal: (p2 - p1).cross(&(p4 - p1)).get_unit(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn corner_spheres(&self) -> Vec<Sphere> {
|
|
||||||
vec![
|
|
||||||
Sphere::new(self.p1, 1., self.material.clone()),
|
|
||||||
Sphere::new(self.p2, 1., self.material.clone()),
|
|
||||||
Sphere::new(self.p3, 1., self.material.clone()),
|
|
||||||
Sphere::new(self.p4, 1., self.material.clone()),
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn hit(
|
pub fn hit(
|
||||||
p1: Vec3,
|
p1: Vec3,
|
||||||
|
|||||||
@@ -1,2 +1,4 @@
|
|||||||
pub mod raw_camera;
|
pub mod raw_camera;
|
||||||
|
pub mod material_def;
|
||||||
|
pub mod hittable_def;
|
||||||
pub mod scene;
|
pub mod scene;
|
||||||
|
|||||||
122
src/scenes/hittable_def.rs
Normal file
122
src/scenes/hittable_def.rs
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use log::warn;
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
objects::{
|
||||||
|
cube::Cube, materials::traits::Material, quad::Quad, sphere::Sphere, traits::Hittable,
|
||||||
|
triangle::Triangle,
|
||||||
|
},
|
||||||
|
scenes::material_def::MaterialDef,
|
||||||
|
vec3::Vec3,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(tag = "type", rename_all = "lowercase")]
|
||||||
|
pub(crate) enum HittableDef {
|
||||||
|
Sphere(RawSphere),
|
||||||
|
Triangle(RawTriangle),
|
||||||
|
Quad(RawQuad),
|
||||||
|
Cube(RawCube),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HittableDef {
|
||||||
|
pub(crate) fn into_arc(self, materials: &Vec<Arc<dyn Material>>) -> Option<Arc<dyn Hittable>> {
|
||||||
|
// THOUGHT: i think this can be done better; in the map/filter call in scnene.deserialize?
|
||||||
|
match self {
|
||||||
|
HittableDef::Sphere(s) => {
|
||||||
|
let material = s.material.into_arc(materials);
|
||||||
|
match material {
|
||||||
|
Some(m) => Some(Arc::new(Sphere::new(s.center, s.radius, m))),
|
||||||
|
None => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
HittableDef::Triangle(t) => {
|
||||||
|
let material = t.material.into_arc(materials);
|
||||||
|
match material {
|
||||||
|
Some(m) => Some(Arc::new(Triangle::new(t.p1, t.p2, t.p3, m))),
|
||||||
|
None => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
HittableDef::Quad(q) => {
|
||||||
|
let material = q.material.into_arc(materials);
|
||||||
|
match material {
|
||||||
|
Some(m) => Some(Arc::new(Quad::new(q.p1, q.p2, q.p3, q.p4, m))),
|
||||||
|
None => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
HittableDef::Cube(c) => {
|
||||||
|
let material = c.material.into_arc(materials);
|
||||||
|
match material {
|
||||||
|
Some(m) => Some(Arc::new(Cube::new(
|
||||||
|
c.p1, c.p2, c.p3, c.p4, c.p5, c.p6, c.p7, c.p8, m,
|
||||||
|
))),
|
||||||
|
None => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub(crate) struct RawSphere {
|
||||||
|
pub center: Vec3,
|
||||||
|
pub radius: f32,
|
||||||
|
pub material: RawMaterial,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub(crate) struct RawTriangle {
|
||||||
|
pub p1: Vec3,
|
||||||
|
pub p2: Vec3,
|
||||||
|
pub p3: Vec3,
|
||||||
|
pub material: RawMaterial,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub(crate) struct RawQuad {
|
||||||
|
pub p1: Vec3,
|
||||||
|
pub p2: Vec3,
|
||||||
|
pub p3: Vec3,
|
||||||
|
pub p4: Vec3,
|
||||||
|
pub material: RawMaterial,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub(crate) struct RawCube {
|
||||||
|
pub p1: Vec3,
|
||||||
|
pub p2: Vec3,
|
||||||
|
pub p3: Vec3,
|
||||||
|
pub p4: Vec3,
|
||||||
|
pub p5: Vec3,
|
||||||
|
pub p6: Vec3,
|
||||||
|
pub p7: Vec3,
|
||||||
|
pub p8: Vec3,
|
||||||
|
pub material: RawMaterial,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub(crate) enum RawMaterial {
|
||||||
|
Ref(u32),
|
||||||
|
Direct(MaterialDef),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RawMaterial {
|
||||||
|
pub fn into_arc(self, materials: &Vec<Arc<dyn Material>>) -> Option<Arc<dyn Material>> {
|
||||||
|
match self {
|
||||||
|
RawMaterial::Ref(r) => {
|
||||||
|
if r as usize >= materials.len() {
|
||||||
|
warn!(
|
||||||
|
"Hittable specified nonexistent material index {}; skipping...",
|
||||||
|
r
|
||||||
|
);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
Some(materials.get(r as usize).unwrap().clone())
|
||||||
|
}
|
||||||
|
RawMaterial::Direct(m) => Some(m.into_arc()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
27
src/scenes/material_def.rs
Normal file
27
src/scenes/material_def.rs
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
use crate::objects::materials::{dielectric::Dielectric, lambertian::{Lambertian, Metal}, normal::Normal, traits::Material};
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(tag = "type", rename_all = "lowercase")]
|
||||||
|
pub(crate) enum MaterialDef {
|
||||||
|
Lambertian(Lambertian),
|
||||||
|
Metal(Metal),
|
||||||
|
Dielectric(Dielectric),
|
||||||
|
Normal(Normal),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MaterialDef {
|
||||||
|
pub(crate) fn into_arc(self) -> Arc<dyn Material> {
|
||||||
|
match self {
|
||||||
|
MaterialDef::Lambertian(l) => Arc::new(l),
|
||||||
|
MaterialDef::Metal(m) => Arc::new(m),
|
||||||
|
MaterialDef::Dielectric(d) => Arc::new(d),
|
||||||
|
MaterialDef::Normal(n) => Arc::new(n),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,44 +1,20 @@
|
|||||||
use std::fmt::Debug;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use log::warn;
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
camera::Camera,
|
camera::Camera,
|
||||||
objects::{
|
objects::{materials::traits::Material, traits::Hittable},
|
||||||
cube::Cube,
|
scenes::{hittable_def::HittableDef, material_def::MaterialDef, raw_camera::RawCamera},
|
||||||
materials::{
|
|
||||||
dielectric::Dielectric,
|
|
||||||
lambertian::{Lambertian, Metal},
|
|
||||||
normal::Normal,
|
|
||||||
traits::Material,
|
|
||||||
},
|
|
||||||
quad::Quad,
|
|
||||||
sphere::Sphere,
|
|
||||||
traits::Hittable,
|
|
||||||
triangle::Triangle,
|
|
||||||
},
|
|
||||||
scenes::raw_camera::RawCamera,
|
|
||||||
vec3::Vec3,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct Scene {
|
pub struct Scene {
|
||||||
pub camera: Camera,
|
pub camera: Camera,
|
||||||
pub materials: Vec<Arc<dyn Material>>,
|
pub _materials: Vec<Arc<dyn Material>>,
|
||||||
pub objects: Vec<Arc<dyn Hittable>>,
|
pub objects: Vec<Arc<dyn Hittable>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for Scene {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
f.debug_struct("Scene")
|
|
||||||
.field("camera", &self.camera)
|
|
||||||
.field("materials", &self.materials)
|
|
||||||
.field("objects", &self.objects)
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Scene {
|
impl Scene {
|
||||||
pub fn render(&mut self) {
|
pub fn render(&mut self) {
|
||||||
self.camera.render(&self.objects);
|
self.camera.render(&self.objects);
|
||||||
@@ -70,138 +46,8 @@ impl<'de> Deserialize<'de> for Scene {
|
|||||||
.collect();
|
.collect();
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
camera: Camera::from(conc.camera),
|
camera: Camera::from(conc.camera),
|
||||||
materials: mats,
|
_materials: mats,
|
||||||
objects: objs,
|
objects: objs,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
#[serde(untagged)]
|
|
||||||
enum RawMaterial {
|
|
||||||
Ref(u32),
|
|
||||||
Direct(MaterialDef),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RawMaterial {
|
|
||||||
pub fn into_arc(self, materials: &Vec<Arc<dyn Material>>) -> Option<Arc<dyn Material>> {
|
|
||||||
match self {
|
|
||||||
RawMaterial::Ref(r) => {
|
|
||||||
if r as usize >= materials.len() {
|
|
||||||
warn!("Sphere specified nonexistent material {}; skipping...", r);
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
Some(materials.get(r as usize).unwrap().clone())
|
|
||||||
}
|
|
||||||
RawMaterial::Direct(m) => Some(m.into_arc()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
struct RawSphere {
|
|
||||||
pub center: Vec3,
|
|
||||||
pub radius: f32,
|
|
||||||
pub material: RawMaterial,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
struct RawTriangle {
|
|
||||||
pub p1: Vec3,
|
|
||||||
pub p2: Vec3,
|
|
||||||
pub p3: Vec3,
|
|
||||||
pub material: RawMaterial,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
struct RawQuad {
|
|
||||||
pub p1: Vec3,
|
|
||||||
pub p2: Vec3,
|
|
||||||
pub p3: Vec3,
|
|
||||||
pub p4: Vec3,
|
|
||||||
pub material: RawMaterial,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
struct RawCube {
|
|
||||||
pub p1: Vec3,
|
|
||||||
pub p2: Vec3,
|
|
||||||
pub p3: Vec3,
|
|
||||||
pub p4: Vec3,
|
|
||||||
pub p5: Vec3,
|
|
||||||
pub p6: Vec3,
|
|
||||||
pub p7: Vec3,
|
|
||||||
pub p8: Vec3,
|
|
||||||
pub material: RawMaterial,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
#[serde(tag = "type", rename_all = "lowercase")]
|
|
||||||
enum HittableDef {
|
|
||||||
Sphere(RawSphere),
|
|
||||||
Triangle(RawTriangle),
|
|
||||||
Quad(RawQuad),
|
|
||||||
Cube(RawCube),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl HittableDef {
|
|
||||||
fn into_arc(self, materials: &Vec<Arc<dyn Material>>) -> Option<Arc<dyn Hittable>> {
|
|
||||||
// THOUGHT: i think this can be done better; in the map/filter call up there?
|
|
||||||
match self {
|
|
||||||
HittableDef::Sphere(s) => {
|
|
||||||
let material = s.material.into_arc(materials);
|
|
||||||
if let Some(m) = material {
|
|
||||||
Some(Arc::new(Sphere::new(s.center, s.radius, m)))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
HittableDef::Triangle(t) => {
|
|
||||||
let material = t.material.into_arc(materials);
|
|
||||||
if let Some(m) = material {
|
|
||||||
Some(Arc::new(Triangle::new(t.p1, t.p2, t.p3, m)))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
HittableDef::Quad(q) => {
|
|
||||||
let material = q.material.into_arc(materials);
|
|
||||||
if let Some(m) = material {
|
|
||||||
Some(Arc::new(Quad::new(q.p1, q.p2, q.p3, q.p4, m)))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
HittableDef::Cube(c) => {
|
|
||||||
let material = c.material.into_arc(materials);
|
|
||||||
if let Some(m) = material {
|
|
||||||
Some(Arc::new(Cube::new(
|
|
||||||
c.p1, c.p2, c.p3, c.p4, c.p5, c.p6, c.p7, c.p8, m,
|
|
||||||
)))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
#[serde(tag = "type", rename_all = "lowercase")]
|
|
||||||
enum MaterialDef {
|
|
||||||
Lambertian(Lambertian),
|
|
||||||
Metal(Metal),
|
|
||||||
Dielectric(Dielectric),
|
|
||||||
Normal(Normal),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MaterialDef {
|
|
||||||
fn into_arc(self) -> Arc<dyn Material> {
|
|
||||||
match self {
|
|
||||||
MaterialDef::Lambertian(l) => Arc::new(l),
|
|
||||||
MaterialDef::Metal(m) => Arc::new(m),
|
|
||||||
MaterialDef::Dielectric(d) => Arc::new(d),
|
|
||||||
MaterialDef::Normal(n) => Arc::new(n),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user