ft (wip): deserialization
This commit is contained in:
61
src/scenes/raw_camera.rs
Normal file
61
src/scenes/raw_camera.rs
Normal file
@@ -0,0 +1,61 @@
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::{camera::Camera, vec3::Vec3};
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct RawCamera {
|
||||
// output
|
||||
image_width: u32, // TODO: test these are now explicitly required (and that default impl does
|
||||
// not make these optional)
|
||||
image_height: u32,
|
||||
|
||||
// raytracing
|
||||
#[serde(default)]
|
||||
anti_alias_rate: u32,
|
||||
#[serde(default)]
|
||||
max_depth: u32,
|
||||
|
||||
// camera
|
||||
#[serde(default)]
|
||||
fov: f32,
|
||||
#[serde(default)]
|
||||
look_from: Vec3,
|
||||
#[serde(default)]
|
||||
look_at: Vec3,
|
||||
#[serde(default)]
|
||||
vup: Vec3,
|
||||
}
|
||||
|
||||
impl Default for RawCamera {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
image_width: 400,
|
||||
image_height: 300,
|
||||
anti_alias_rate: 1,
|
||||
max_depth: 10,
|
||||
fov: 70.,
|
||||
look_from: Vec3::new(0., 0., 0.),
|
||||
look_at: Vec3::new(0., 0., -1.),
|
||||
vup: Vec3::new(0., 1., 0.),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<RawCamera> for Camera {
|
||||
type Error = String;
|
||||
|
||||
fn try_from(raw: RawCamera) -> Result<Self, Self::Error> {
|
||||
let c = Camera::new_full(
|
||||
raw.image_width,
|
||||
raw.image_height,
|
||||
raw.anti_alias_rate,
|
||||
raw.max_depth,
|
||||
raw.fov,
|
||||
raw.look_from,
|
||||
raw.look_at,
|
||||
raw.vup,
|
||||
);
|
||||
|
||||
Ok(c)
|
||||
}
|
||||
}
|
||||
107
src/scenes/scene.rs
Normal file
107
src/scenes/scene.rs
Normal file
@@ -0,0 +1,107 @@
|
||||
use std::{
|
||||
fmt::{self, Debug},
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::{
|
||||
camera::Camera,
|
||||
objects::{
|
||||
materials::{
|
||||
dielectric::Dielectric,
|
||||
lambertian::{Lambertian, Metal},
|
||||
traits::Material,
|
||||
},
|
||||
sphere::Sphere,
|
||||
traits::Hittable,
|
||||
},
|
||||
scenes::raw_camera::RawCamera,
|
||||
vec3::Vec3,
|
||||
};
|
||||
|
||||
pub struct Scene {
|
||||
pub camera: Camera,
|
||||
pub materials: Vec<Arc<dyn Material>>,
|
||||
pub objects: Vec<Arc<dyn Hittable>>,
|
||||
}
|
||||
|
||||
impl Scene {
|
||||
pub fn render(&mut self) {
|
||||
self.camera.render(&self.objects);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct SceneDef {
|
||||
pub camera: RawCamera,
|
||||
pub materials: Vec<MaterialDef>,
|
||||
pub objects: Vec<HittableDef>,
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for Scene {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
let conc = SceneDef::deserialize(deserializer)?;
|
||||
let mats: Vec<Arc<dyn Material>> = conc
|
||||
.materials
|
||||
.into_iter()
|
||||
.map(MaterialDef::into_arc)
|
||||
.collect();
|
||||
let objs: Vec<Arc<dyn Hittable>> = conc
|
||||
.objects
|
||||
.into_iter()
|
||||
.map(|h| h.into_arc(&mats))
|
||||
.collect();
|
||||
Ok(Self {
|
||||
camera: Camera::try_from(conc.camera).unwrap(),
|
||||
materials: mats,
|
||||
objects: objs,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct RawSphere {
|
||||
pub center: Vec3,
|
||||
pub radius: f32,
|
||||
pub material: u32,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(tag = "type", rename_all = "lowercase")]
|
||||
enum HittableDef {
|
||||
Sphere(RawSphere),
|
||||
}
|
||||
|
||||
impl HittableDef {
|
||||
fn into_arc(self, materials: &Vec<Arc<dyn Material>>) -> Arc<dyn Hittable> {
|
||||
match self {
|
||||
HittableDef::Sphere(s) => Arc::new(Sphere::new(
|
||||
s.center,
|
||||
s.radius,
|
||||
materials.get(s.material as usize).unwrap().clone(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(tag = "type", rename_all = "lowercase")]
|
||||
enum MaterialDef {
|
||||
Lambertian(Lambertian),
|
||||
Metal(Metal),
|
||||
Dielectric(Dielectric),
|
||||
}
|
||||
|
||||
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),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user