initial commit
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
use crate::structs::Vec3;
|
||||
use crate::object::Obj;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct Cuboid {
|
||||
center: Vec3,
|
||||
radius: Vec3
|
||||
}
|
||||
|
||||
impl Cuboid {
|
||||
pub fn new(center: Vec3, radius: Vec3) -> Cuboid {
|
||||
Cuboid { center, radius }
|
||||
}
|
||||
pub fn new_xyz(cx: f64, cy: f64, cz: f64, rx: f64, ry: f64, rz: f64) -> Cuboid {
|
||||
let center = Vec3::new(cx, cy, cz);
|
||||
let radius = Vec3::new(rx, ry, rz);
|
||||
Cuboid { center, radius }
|
||||
}
|
||||
}
|
||||
|
||||
impl Obj for Cuboid {
|
||||
fn distance_to(&self, point: Vec3) -> f64 {
|
||||
let dx = point.x() - self.center.x();
|
||||
let dy = point.y() - self.center.y();
|
||||
let dz = point.z() - self.center.z();
|
||||
|
||||
if dx.abs()<self.radius.x() && dy.abs()<self.radius.y() && dz.abs()<self.radius.z() {
|
||||
-f64::min(
|
||||
f64::min(
|
||||
f64::min(
|
||||
f64::abs(dx-self.radius.x()),
|
||||
f64::abs(dx+self.radius.x())
|
||||
),
|
||||
f64::abs(dy-self.radius.y())
|
||||
),
|
||||
f64::min(
|
||||
f64::min(
|
||||
f64::abs(dy+self.radius.y()),
|
||||
f64::abs(dz-self.radius.z())
|
||||
),
|
||||
f64::abs(dz+self.radius.z())
|
||||
)
|
||||
)
|
||||
} else {
|
||||
let dx0 = f64::max(0., dx.abs()-self.radius.x());
|
||||
let dy0 = f64::max(0., dy.abs()-self.radius.y());
|
||||
let dz0 = f64::max(0., dz.abs()-self.radius.z());
|
||||
|
||||
f64::sqrt(dx0*dx0 + dy0*dy0 + dz0*dz0)
|
||||
}
|
||||
}
|
||||
|
||||
fn normal_at(&self, point: Vec3) -> Vec3 {
|
||||
let dx = (point.x()-self.center.y())/self.radius.x();
|
||||
let dy = (point.y()-self.center.y())/self.radius.y();
|
||||
let dz = (point.z()-self.center.z())/self.radius.z();
|
||||
let (adx, ady, adz) = (dx.abs(), dy.abs(), dz.abs());
|
||||
|
||||
Vec3::new(
|
||||
if adx>=ady && adx>adz { if dx>0. { 1. } else { -1. }} else { 0. },
|
||||
if ady>=adz && ady>adx { if dy>0. { 1. } else { -1. }} else { 0. },
|
||||
if adz>=adx && adz>ady { if dz>0. { 1. } else { -1. }} else { 0. },
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
use crate::structs::Vec3;
|
||||
use crate::object::Obj;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct Cylinder {
|
||||
center: Vec3,
|
||||
radius: f64
|
||||
}
|
||||
|
||||
impl Cylinder {
|
||||
pub const fn new(center: Vec3, radius: f64) -> Cylinder {
|
||||
Cylinder { center, radius }
|
||||
}
|
||||
}
|
||||
|
||||
impl Obj for Cylinder {
|
||||
fn distance_to(&self, point: Vec3) -> f64 {
|
||||
Vec3::new(self.center.x(), 0., self.center.z()).distance_to(point) - self.radius
|
||||
}
|
||||
fn normal_at(&self, point: Vec3) -> Vec3 {
|
||||
point - Vec3::new(self.center.x(), 0.,self.center.z())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
use crate::object::Obj;
|
||||
use crate::light::Light;
|
||||
use crate::structs::Vec3;
|
||||
use std::vec;
|
||||
use crate::material::Material;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct Intersection<A: Obj, B: Obj> {
|
||||
a: A,
|
||||
b: B
|
||||
}
|
||||
|
||||
impl<A: Obj, B: Obj> Intersection<A, B> {
|
||||
pub fn new(a: A, b: B) -> Intersection<A, B> {
|
||||
Intersection { a, b }
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Obj, B: Obj> Obj for Intersection<A, B> {
|
||||
fn distance_to(&self, point: Vec3) -> f64 {
|
||||
f64::max(self.a.distance_to(point), self.b.distance_to(point))
|
||||
}
|
||||
fn normal_at(&self, point: Vec3) -> Vec3 {
|
||||
if self.a.distance_to(point) > self.b.distance_to(point) {
|
||||
self.a.normal_at(point)
|
||||
} else {
|
||||
self.b.normal_at(point)
|
||||
}
|
||||
}
|
||||
fn material_at(&self, point: Vec3) -> Material {
|
||||
if self.a.distance_to(point) > self.b.distance_to(point) {
|
||||
self.a.material_at(point)
|
||||
} else {
|
||||
self.b.material_at(point)
|
||||
}
|
||||
}
|
||||
fn get_lights(&self) -> vec::Vec<Light> {
|
||||
let mut l = self.a.get_lights();
|
||||
l.extend(self.b.get_lights());
|
||||
l
|
||||
}
|
||||
fn node_count(&self) -> u32 {
|
||||
self.a.node_count() + self.b.node_count() + 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
use crate::consts::{EPSILON, MAX_DIST};
|
||||
use crate::structs::{Vec3, O, X, Y, Z};
|
||||
use crate::material::Material;
|
||||
use crate::material;
|
||||
use crate::light::Light;
|
||||
use std::vec::Vec;
|
||||
|
||||
mod sphere;
|
||||
mod plane;
|
||||
mod union;
|
||||
mod intersection;
|
||||
mod cuboid;
|
||||
mod cylinder;
|
||||
mod torus;
|
||||
mod waves;
|
||||
mod with_material;
|
||||
mod with_lights;
|
||||
mod transform;
|
||||
mod scene;
|
||||
|
||||
pub trait Obj: Send + Sync {
|
||||
fn distance_to(&self, _point: Vec3) -> f64 {
|
||||
MAX_DIST
|
||||
}
|
||||
fn normal_at(&self, point: Vec3) -> Vec3 {
|
||||
let v = self.distance_to(point);
|
||||
let x = self.distance_to(point + X*EPSILON) - v;
|
||||
let y = self.distance_to(point + Y*EPSILON) - v;
|
||||
let z = self.distance_to(point + Z*EPSILON) - v;
|
||||
|
||||
Vec3::new(x, y, z).unit()
|
||||
}
|
||||
fn material_at(&self, _point: Vec3) -> Material {
|
||||
material::WHITE
|
||||
}
|
||||
fn get_lights(&self) -> Vec<Light> {
|
||||
Vec::new()
|
||||
}
|
||||
fn node_count(&self) -> u32 { 1 }
|
||||
}
|
||||
|
||||
impl<T: Obj> Obj for &T {
|
||||
fn distance_to(&self, point: Vec3) -> f64 { (*self).distance_to(point) }
|
||||
fn normal_at(&self, point: Vec3) -> Vec3 { (*self).normal_at(point) }
|
||||
fn material_at(&self, point: Vec3) -> Material { (*self).material_at(point) }
|
||||
fn get_lights(&self) -> Vec<Light> { (*self).get_lights() }
|
||||
fn node_count(&self) -> u32 { (*self).node_count() }
|
||||
}
|
||||
|
||||
pub trait ObjClone: Obj {
|
||||
fn clone_obj(&self) -> Box<dyn ObjClone>;
|
||||
}
|
||||
|
||||
impl<T: 'static + Obj + Clone> ObjClone for T {
|
||||
fn clone_obj(&self) -> Box<dyn ObjClone> {
|
||||
Box::new(self.clone())
|
||||
}
|
||||
}
|
||||
|
||||
pub use sphere::Sphere;
|
||||
pub use plane::Plane;
|
||||
pub use union::Union;
|
||||
pub use intersection::Intersection;
|
||||
pub use cuboid::Cuboid;
|
||||
pub use cylinder::Cylinder;
|
||||
pub use torus::Torus;
|
||||
pub use waves::Waves;
|
||||
pub use with_material::{WithMaterial, WithDynamicMaterial};
|
||||
pub use with_lights::{WithLights, WithLight};
|
||||
pub use transform::AffineTransform;
|
||||
pub use scene::Scene;
|
||||
@@ -0,0 +1,31 @@
|
||||
use crate::structs::Vec3;
|
||||
use crate::object::Obj;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct Plane {
|
||||
normal: Vec3,
|
||||
offset: f64
|
||||
}
|
||||
|
||||
impl Plane {
|
||||
pub fn new(normal: Vec3, offset: f64) -> Plane {
|
||||
let l = normal.magnitude();
|
||||
Plane { normal: normal/l, offset: offset/l }
|
||||
}
|
||||
pub fn new_xyz(x: f64, y: f64, z: f64, offset: f64) -> Plane {
|
||||
let normal = Vec3::new(x, y, z);
|
||||
Plane::new(normal, offset)
|
||||
}
|
||||
pub const unsafe fn new_raw(normal: Vec3, offset: f64) -> Plane {
|
||||
Plane { normal, offset }
|
||||
}
|
||||
}
|
||||
|
||||
impl Obj for Plane {
|
||||
fn distance_to(&self, point: Vec3) -> f64 {
|
||||
point*self.normal + self.offset
|
||||
}
|
||||
fn normal_at(&self, _point: Vec3) -> Vec3 {
|
||||
self.normal
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
use crate::object::{Obj, ObjClone};
|
||||
use crate::structs::Vec3;
|
||||
use crate::material::Material;
|
||||
use crate::light::Light;
|
||||
|
||||
pub struct Scene {
|
||||
scene: Box<dyn ObjClone>
|
||||
}
|
||||
|
||||
impl Scene {
|
||||
pub fn new<T: 'static + ObjClone>(scene: T) -> Scene {
|
||||
Scene { scene: Box::new(scene) }
|
||||
}
|
||||
pub fn new_from_box(scene: Box<dyn ObjClone>) -> Scene {
|
||||
Scene { scene }
|
||||
}
|
||||
}
|
||||
|
||||
impl Obj for Scene {
|
||||
fn distance_to(&self, point: Vec3) -> f64 { self.scene.distance_to(point) }
|
||||
fn normal_at(&self, point: Vec3) -> Vec3 { self.scene.normal_at(point) }
|
||||
fn material_at(&self, point: Vec3) -> Material { self.scene.material_at(point) }
|
||||
fn get_lights(&self) -> Vec<Light> { self.scene.get_lights() }
|
||||
fn node_count(&self) -> u32 { self.scene.node_count() + 1 }
|
||||
}
|
||||
|
||||
impl Clone for Scene {
|
||||
fn clone(&self) -> Scene {
|
||||
Scene { scene: self.scene.clone_obj() }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
use crate::structs::Vec3;
|
||||
use crate::object::Obj;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct Sphere {
|
||||
pos: Vec3,
|
||||
radius: f64
|
||||
}
|
||||
|
||||
impl Sphere {
|
||||
pub const fn new(pos: Vec3, radius: f64) -> Sphere {
|
||||
Sphere { pos, radius }
|
||||
}
|
||||
pub const fn new_xyz(x: f64, y: f64, z: f64, radius: f64) -> Sphere {
|
||||
let pos = Vec3::new(x, y, z);
|
||||
Sphere { pos, radius }
|
||||
}
|
||||
}
|
||||
|
||||
impl Obj for Sphere {
|
||||
fn distance_to(&self, point: Vec3) -> f64 {
|
||||
self.pos.distance_to(point) - self.radius
|
||||
}
|
||||
fn normal_at(&self, point: Vec3) -> Vec3 {
|
||||
(point - self.pos).unit()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
use crate::structs::Vec3;
|
||||
use crate::object::Obj;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct Torus {
|
||||
center: Vec3,
|
||||
radius: f64,
|
||||
thickness: f64
|
||||
}
|
||||
|
||||
impl Torus {
|
||||
pub const fn new(center: Vec3, radius: f64, thickness: f64) -> Torus {
|
||||
Torus { center, radius, thickness }
|
||||
}
|
||||
pub const fn new_xyz(x: f64, y: f64, z: f64, radius: f64, thickness: f64) -> Torus {
|
||||
Torus::new(Vec3::new(x, y, z), radius, thickness)
|
||||
}
|
||||
}
|
||||
|
||||
impl Obj for Torus {
|
||||
fn distance_to(&self, point: Vec3) -> f64 {
|
||||
let (dx, dy) = (point.x()-self.center.x(), point.y()-self.center.y());
|
||||
let dh = f64::abs(f64::sqrt(dx*dx + dy*dy) - self.radius);
|
||||
let dz = point.z() - self.center.z();
|
||||
f64::sqrt(dh*dh + dz*dz) - self.thickness
|
||||
}
|
||||
|
||||
fn normal_at(&self, point: Vec3) -> Vec3 {
|
||||
let centered = point - self.center;
|
||||
let centered_no_z= Vec3::new(centered.x(), centered.y(), 0.);
|
||||
let closest = centered_no_z.unit() * self.radius;
|
||||
(centered - closest).unit()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
use crate::object::Obj;
|
||||
use crate::structs::{Mat3, Vec3, O, I3};
|
||||
use crate::material::Material;
|
||||
use crate::light::Light;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct AffineTransform<T: Obj + Clone> {
|
||||
obj: T,
|
||||
transform: Mat3,
|
||||
transform_inv: Mat3,
|
||||
translate: Vec3
|
||||
}
|
||||
|
||||
impl<T: Obj + Clone> AffineTransform<T> {
|
||||
pub fn new(obj: T, transform: Mat3, translate: Vec3) -> AffineTransform<T> {
|
||||
AffineTransform { obj, transform, transform_inv: transform.invert(), translate }
|
||||
}
|
||||
pub fn new_linear(obj: T, transform: Mat3) -> AffineTransform<T> {
|
||||
AffineTransform { obj, transform, transform_inv: transform.invert(), translate: O }
|
||||
}
|
||||
pub fn new_translate(obj: T, translate: Vec3) -> AffineTransform<T> {
|
||||
AffineTransform { obj, transform: I3, transform_inv: I3, translate }
|
||||
}
|
||||
|
||||
fn apply_rev(&self, point: Vec3) -> Vec3 {
|
||||
self.transform_inv*point - self.translate
|
||||
}
|
||||
fn apply_fwd(&self, point: Vec3) -> Vec3 {
|
||||
self.transform*point + self.translate
|
||||
}
|
||||
}
|
||||
|
||||
pub const SWAP_XY: Mat3 = Mat3::new(
|
||||
0., 1., 0.,
|
||||
1., 0., 0.,
|
||||
0., 0., 1.,
|
||||
);
|
||||
pub const SWAP_XZ: Mat3 = Mat3::new(
|
||||
0., 0., 1.,
|
||||
0., 1., 0.,
|
||||
1., 0., 0.,
|
||||
);
|
||||
pub const SWAP_YZ: Mat3 = Mat3::new(
|
||||
1., 0., 0.,
|
||||
0., 0., 1.,
|
||||
0., 1., 0.,
|
||||
);
|
||||
|
||||
pub const fn scale_xyz(x: f64, y: f64, z: f64) -> Mat3 {
|
||||
Mat3::new(
|
||||
x , 0., 0.,
|
||||
0., y , 0.,
|
||||
0., 0., z ,
|
||||
)
|
||||
}
|
||||
pub const fn scale(k: f64) -> Mat3 { scale_xyz(k, k, k) }
|
||||
pub const fn scale_x(k: f64) -> Mat3 { scale_xyz(k, 1., 1.) }
|
||||
pub const fn scale_y(k: f64) -> Mat3 { scale_xyz(1., k, 1.) }
|
||||
pub const fn scale_z(k: f64) -> Mat3 { scale_xyz(1., 1., k) }
|
||||
|
||||
impl<T: Obj + Clone> Obj for AffineTransform<T> {
|
||||
fn distance_to(&self, point: Vec3) -> f64 {
|
||||
self.obj.distance_to(self.apply_rev(point))
|
||||
}
|
||||
fn normal_at(&self, point: Vec3) -> Vec3 {
|
||||
self.apply_fwd(self.obj.normal_at(self.apply_rev(point)))
|
||||
}
|
||||
fn material_at(&self, point: Vec3) -> Material {
|
||||
self.obj.material_at(self.apply_rev(point))
|
||||
}
|
||||
fn get_lights(&self) -> Vec<Light> {
|
||||
self.obj
|
||||
.get_lights()
|
||||
.into_iter()
|
||||
.map(|light| {
|
||||
Light::new(self.apply_fwd(light.pos()), light.color())
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
fn node_count(&self) -> u32 {
|
||||
self.obj.node_count() + 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
use crate::object::Obj;
|
||||
use crate::light::Light;
|
||||
use crate::structs::Vec3;
|
||||
use std::vec;
|
||||
use crate::material::Material;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct Union<A: Obj, B: Obj> {
|
||||
a: A,
|
||||
b: B
|
||||
}
|
||||
|
||||
impl<A: Obj, B: Obj> Union<A, B> {
|
||||
pub fn new(a: A, b: B) -> Union<A, B> {
|
||||
Union { a, b }
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Obj, B: Obj> Obj for Union<A, B> {
|
||||
fn distance_to(&self, point: Vec3) -> f64 {
|
||||
f64::min(self.a.distance_to(point), self.b.distance_to(point))
|
||||
}
|
||||
fn normal_at(&self, point: Vec3) -> Vec3 {
|
||||
if self.a.distance_to(point) < self.b.distance_to(point) {
|
||||
self.a.normal_at(point)
|
||||
} else {
|
||||
self.b.normal_at(point)
|
||||
}
|
||||
}
|
||||
fn material_at(&self, point: Vec3) -> Material {
|
||||
if self.a.distance_to(point) < self.b.distance_to(point) {
|
||||
self.a.material_at(point)
|
||||
} else {
|
||||
self.b.material_at(point)
|
||||
}
|
||||
}
|
||||
fn get_lights(&self) -> vec::Vec<Light> {
|
||||
let mut l = self.a.get_lights();
|
||||
l.extend(self.b.get_lights());
|
||||
l
|
||||
}
|
||||
fn node_count(&self) -> u32 {
|
||||
self.a.node_count() + self.b.node_count() + 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
use crate::object::Obj;
|
||||
use crate::structs::Vec3;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct Waves {}
|
||||
|
||||
impl Waves {
|
||||
pub const fn new() -> Waves {
|
||||
Waves {}
|
||||
}
|
||||
}
|
||||
|
||||
impl Obj for Waves {
|
||||
fn distance_to(&self, point: Vec3) -> f64 {
|
||||
let dist = point.x().sin() + point.y().sin() + point.z();
|
||||
dist / f64::sqrt(3.)
|
||||
}
|
||||
|
||||
fn normal_at(&self, point: Vec3) -> Vec3 {
|
||||
Vec3::new(-point.x().cos(), -point.y().cos(), 1.).unit()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
use crate::light::Light;
|
||||
use crate::object::Obj;
|
||||
use crate::structs::Vec3;
|
||||
use crate::material::Material;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct WithLights<T: Obj, const N: usize> {
|
||||
obj: T,
|
||||
lights: [Light; N]
|
||||
}
|
||||
|
||||
impl<T: Obj, const N: usize> WithLights<T, N> {
|
||||
pub fn new(obj: T, lights: [Light; N]) -> WithLights<T, N> {
|
||||
WithLights { obj, lights }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Obj, const N: usize> Obj for WithLights<T, N> {
|
||||
fn distance_to(&self, point: Vec3) -> f64 {
|
||||
self.obj.distance_to(point)
|
||||
}
|
||||
fn normal_at(&self, point: Vec3) -> Vec3 {
|
||||
self.obj.normal_at(point)
|
||||
}
|
||||
fn material_at(&self, point: Vec3) -> Material {
|
||||
self.obj.material_at(point)
|
||||
}
|
||||
fn get_lights(&self) -> Vec<Light> {
|
||||
let mut l = self.obj.get_lights();
|
||||
l.extend(&self.lights);
|
||||
l
|
||||
}
|
||||
fn node_count(&self) -> u32 {
|
||||
self.obj.node_count() + 1
|
||||
}
|
||||
}
|
||||
|
||||
pub type WithLight<T> = WithLights<T, 1>;
|
||||
|
||||
impl<T: Obj> WithLight<T> {
|
||||
pub fn new_one(obj: T, light: Light) -> WithLight<T> {
|
||||
WithLight { obj, lights: [light; 1] }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
use crate::object::Obj;
|
||||
use crate::material::Material;
|
||||
use crate::structs::Vec3;
|
||||
use crate::light::Light;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct WithMaterial<T: Obj> {
|
||||
obj: T,
|
||||
material: Material
|
||||
}
|
||||
|
||||
impl<T: Obj> WithMaterial<T> {
|
||||
pub fn new(obj: T, material: Material) -> WithMaterial<T> {
|
||||
WithMaterial { obj, material }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Obj> Obj for WithMaterial<T> {
|
||||
fn distance_to(&self, point: Vec3) -> f64 {
|
||||
self.obj.distance_to(point)
|
||||
}
|
||||
fn normal_at(&self, point: Vec3) -> Vec3 {
|
||||
self.obj.normal_at(point)
|
||||
}
|
||||
fn material_at(&self, point: Vec3) -> Material {
|
||||
self.material
|
||||
}
|
||||
fn get_lights(&self) -> Vec<Light> {
|
||||
self.obj.get_lights()
|
||||
}
|
||||
fn node_count(&self) -> u32 {
|
||||
self.obj.node_count() + 1
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct WithDynamicMaterial<T: Obj, F: Clone + Send + Sync + Fn(Vec3) -> Material> {
|
||||
obj: T,
|
||||
fun: F
|
||||
}
|
||||
|
||||
impl<T: Obj, F: Clone + Send + Sync + Fn(Vec3) -> Material> WithDynamicMaterial<T, F> {
|
||||
pub fn new(obj: T, fun: F) -> WithDynamicMaterial<T, F> {
|
||||
WithDynamicMaterial { obj, fun }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Obj, F: Clone + Send + Sync + Fn(Vec3) -> Material> Obj for WithDynamicMaterial<T, F> {
|
||||
fn distance_to(&self, point: Vec3) -> f64 {
|
||||
self.obj.distance_to(point)
|
||||
}
|
||||
fn normal_at(&self, point: Vec3) -> Vec3 {
|
||||
self.obj.normal_at(point)
|
||||
}
|
||||
fn material_at(&self, point: Vec3) -> Material {
|
||||
(self.fun)(point)
|
||||
}
|
||||
fn get_lights(&self) -> Vec<Light> {
|
||||
self.obj.get_lights()
|
||||
}
|
||||
fn node_count(&self) -> u32 {
|
||||
self.obj.node_count() + 1
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user