added tsm scene; smoothunion, more transforms, fix mat3 product; expose problem with lua api
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 2.1 MiB |
@@ -70,7 +70,7 @@ local function randomtorus()
|
|||||||
local thickness = util.randab(radius/4, radius)
|
local thickness = util.randab(radius/4, radius)
|
||||||
local orientation = randomorientation()
|
local orientation = randomorientation()
|
||||||
|
|
||||||
return obj.affinetransform(obj.torus(pos, radius, thickness), orientation, vec3.O)
|
return util.transform(obj.torus(pos, radius, thickness), orientation)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function randomcuboid()
|
local function randomcuboid()
|
||||||
@@ -86,13 +86,12 @@ local function randomcylinder()
|
|||||||
local height = util.randab(0, SCALE)
|
local height = util.randab(0, SCALE)
|
||||||
local orientation = randomorientation()
|
local orientation = randomorientation()
|
||||||
|
|
||||||
return obj.affinetransform(
|
return util.transform(
|
||||||
obj.intersection(
|
obj.intersection(
|
||||||
obj.cylinder(pos, radius),
|
obj.cylinder(pos, radius),
|
||||||
obj.cuboid(pos, vec3.new(radius, height, radius))
|
obj.cuboid(pos, vec3.new(radius, height, radius))
|
||||||
),
|
),
|
||||||
orientation,
|
orientation
|
||||||
vec3.O
|
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
+157
@@ -0,0 +1,157 @@
|
|||||||
|
-- Scene developed by TSM71
|
||||||
|
-- Also this took 30 hours to render
|
||||||
|
|
||||||
|
local COLOR_BLACK = colorvec.new(0, 0, 0, 0)
|
||||||
|
|
||||||
|
local GRAY = material.newfromdiagonal(
|
||||||
|
COLOR_BLACK,
|
||||||
|
colorvec.new(0.5, 0.5, 0.5, 0.5),
|
||||||
|
surfacetype.DIFFUSE
|
||||||
|
)
|
||||||
|
local CYAN = material.newfromdiagonal(
|
||||||
|
COLOR_BLACK,
|
||||||
|
colorvec.new(0, 1, 1, 0),
|
||||||
|
surfacetype.DIFFUSE
|
||||||
|
)
|
||||||
|
local PINK = material.newfromdiagonal(
|
||||||
|
COLOR_BLACK,
|
||||||
|
colorvec.new(1, .5, .5, 0),
|
||||||
|
surfacetype.DIFFUSE
|
||||||
|
)
|
||||||
|
local RED = material.newfromdiagonal(
|
||||||
|
COLOR_BLACK,
|
||||||
|
colorvec.new(1, 0, 0, 0),
|
||||||
|
surfacetype.DIFFUSE
|
||||||
|
)
|
||||||
|
local MAGENTA = material.newfromdiagonal(
|
||||||
|
COLOR_BLACK,
|
||||||
|
colorvec.new(1, 0, 1, 0),
|
||||||
|
surfacetype.DIFFUSE
|
||||||
|
)
|
||||||
|
local MIRROR = material.newfromdiagonal(
|
||||||
|
COLOR_BLACK,
|
||||||
|
colorvec.new(1, 1, 1, 1),
|
||||||
|
surfacetype.REFLECTIVE
|
||||||
|
)
|
||||||
|
local FLUORESCENT = material.new(
|
||||||
|
COLOR_BLACK,
|
||||||
|
colormat.new(
|
||||||
|
.25, 0, 0, .25,
|
||||||
|
0, .25, 0, .75,
|
||||||
|
0, 0, .25, 0,
|
||||||
|
0, 0, 0, 0
|
||||||
|
),
|
||||||
|
surfacetype.DIFFUSE
|
||||||
|
)
|
||||||
|
|
||||||
|
--[[
|
||||||
|
obj.transformaround = function(a, b, c)
|
||||||
|
return util.translate(
|
||||||
|
util.transform(
|
||||||
|
util.translate(
|
||||||
|
a,
|
||||||
|
-c
|
||||||
|
),
|
||||||
|
b
|
||||||
|
),
|
||||||
|
c
|
||||||
|
)
|
||||||
|
end
|
||||||
|
--]]
|
||||||
|
--obj.transformaround = function(a, _b, _c) return a end
|
||||||
|
--obj.affinetransform = function(a, _b, _c) return a end
|
||||||
|
--obj.smoothunion = function(a, b, _r) return obj.union(a, b) end
|
||||||
|
---[[
|
||||||
|
util.stacktransforms = function(list)
|
||||||
|
--do return list[1] end
|
||||||
|
--do return list[#list] end
|
||||||
|
local n = #list
|
||||||
|
local a = mat3.I
|
||||||
|
--for i=n, 1, -1 do
|
||||||
|
for i=1, n do
|
||||||
|
a = list[i] * a
|
||||||
|
--a = a * list[i]
|
||||||
|
end
|
||||||
|
return a
|
||||||
|
end
|
||||||
|
--]]
|
||||||
|
|
||||||
|
return obj.withlights(
|
||||||
|
obj.transformaround(
|
||||||
|
obj.withlights(
|
||||||
|
util.union({
|
||||||
|
util.intersection({
|
||||||
|
util.union({
|
||||||
|
obj.withmaterial(
|
||||||
|
obj.negation(
|
||||||
|
util.union({
|
||||||
|
obj.cuboid(vec3.new(0, 0, 0), vec3.new(.5, 1, 4)),
|
||||||
|
obj.cuboid(vec3.new(0, 0, 0), vec3.new(4, 1, .5))
|
||||||
|
})
|
||||||
|
),
|
||||||
|
GRAY
|
||||||
|
),
|
||||||
|
obj.withmaterial(
|
||||||
|
util.intersection({
|
||||||
|
util.union({
|
||||||
|
obj.cuboid(vec3.new(0, 1, 0), vec3.new(.4, .1, 3.9)),
|
||||||
|
obj.cuboid(vec3.new(0, 1, 0), vec3.new(3.9, .1, .4))
|
||||||
|
}),
|
||||||
|
obj.negation(
|
||||||
|
util.union({
|
||||||
|
obj.cuboid(vec3.new(0, 1, 0), vec3.new(.3, 1, 3.8)),
|
||||||
|
obj.cuboid(vec3.new(0, 1, 0), vec3.new(3.8, 1, .3))
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
FLUORESCENT
|
||||||
|
),
|
||||||
|
obj.smoothunion(
|
||||||
|
obj.withmaterial(
|
||||||
|
obj.sphere(vec3.new(0, .75, 0), .25),
|
||||||
|
CYAN
|
||||||
|
),
|
||||||
|
obj.withmaterial( -- withdynamicmaterial
|
||||||
|
obj.sphere(vec3.new(-.5, .5, 0), .25),
|
||||||
|
MAGENTA --dynamicmaterial.missingtexture(vec3.new(-.5, .5, 0))
|
||||||
|
),
|
||||||
|
.5
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
obj.withmaterial(
|
||||||
|
obj.negation(
|
||||||
|
obj.cuboid(vec3.new(0, 0, 0), vec3.new(2, .25, 2))
|
||||||
|
),
|
||||||
|
PINK
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
obj.withmaterial(
|
||||||
|
obj.cylinder(vec3.new(1, 0, 0), .375),
|
||||||
|
RED
|
||||||
|
),
|
||||||
|
util.transform(
|
||||||
|
obj.withmaterial(
|
||||||
|
obj.torus(vec3.new(0, 0, -1), .375, .125),
|
||||||
|
MIRROR
|
||||||
|
),
|
||||||
|
transform.SWAPYZ
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
light.new(vec3.new(.45, 1-.2, -.45), colorvec.new(0, 0, 0, .1)),
|
||||||
|
--light.new(vec3.new(.45, 1-.2, -.45), colorvec.new(0, 0, 0, 1)),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
util.stacktransforms({
|
||||||
|
transform.scalexyz(1, -1, 1),
|
||||||
|
transform.rotatez(10*math.pi/180),
|
||||||
|
}),
|
||||||
|
vec3.new(0, 0, -1.5)
|
||||||
|
),
|
||||||
|
{
|
||||||
|
light.new(vec3.new(0, .9375, 0), colorvec.new(.5, .25, 0, 0)),
|
||||||
|
light.new(vec3.new(0, .9375, -.625), colorvec.new(0, 0, 1, 0)),
|
||||||
|
--light.new(vec3.new(0, .9375, 0), colorvec.new(5, 2.5, 0, 0)),
|
||||||
|
--light.new(vec3.new(0, .9375, -.625), colorvec.new(0, 0, 10, 0)),
|
||||||
|
}
|
||||||
|
)
|
||||||
+8
-8
@@ -20,21 +20,21 @@ pub const ANGLE_POWER: f64 = 2.;
|
|||||||
//pub const IMG_WIDTH: usize = 480;
|
//pub const IMG_WIDTH: usize = 480;
|
||||||
//pub const IMG_WIDTH: usize = 1280;
|
//pub const IMG_WIDTH: usize = 1280;
|
||||||
//pub const IMG_WIDTH: usize = 1080;
|
//pub const IMG_WIDTH: usize = 1080;
|
||||||
//pub const IMG_WIDTH: usize = 1920;
|
pub const IMG_WIDTH: usize = 1920;
|
||||||
pub const IMG_WIDTH: usize = 4961;
|
//pub const IMG_WIDTH: usize = 4961;
|
||||||
//pub const IMG_HEIGHT: usize = 480;
|
//pub const IMG_HEIGHT: usize = 480;
|
||||||
//pub const IMG_HEIGHT: usize = 720;
|
//pub const IMG_HEIGHT: usize = 720;
|
||||||
//pub const IMG_HEIGHT: usize = 1080;
|
pub const IMG_HEIGHT: usize = 1080;
|
||||||
pub const IMG_HEIGHT: usize = 3508;
|
//pub const IMG_HEIGHT: usize = 3508;
|
||||||
pub const IMG_DIM: usize = if IMG_HEIGHT > IMG_WIDTH { IMG_HEIGHT } else { IMG_WIDTH };
|
pub const IMG_DIM: usize = if IMG_HEIGHT > IMG_WIDTH { IMG_HEIGHT } else { IMG_WIDTH };
|
||||||
pub const IMG_SIZE: usize = IMG_WIDTH * IMG_HEIGHT;
|
pub const IMG_SIZE: usize = IMG_WIDTH * IMG_HEIGHT;
|
||||||
pub const IMG_BYTE_SIZE: usize = IMG_SIZE * 3;
|
pub const IMG_BYTE_SIZE: usize = IMG_SIZE * 3;
|
||||||
|
|
||||||
pub const SUPERSAMPLING: usize = 1;
|
//pub const SUPERSAMPLING: usize = 1;
|
||||||
//pub const SUPERSAMPLING: usize = 2;
|
pub const SUPERSAMPLING: usize = 2;
|
||||||
pub const RAYS_PER_PIXEL: usize = 1;
|
//pub const RAYS_PER_PIXEL: usize = 1;
|
||||||
//pub const RAYS_PER_PIXEL: usize = 50;
|
//pub const RAYS_PER_PIXEL: usize = 50;
|
||||||
//pub const RAYS_PER_PIXEL: usize = 500;
|
pub const RAYS_PER_PIXEL: usize = 500;
|
||||||
//pub const MAX_BOUNCES: u32 = 1;
|
//pub const MAX_BOUNCES: u32 = 1;
|
||||||
//pub const MAX_BOUNCES: u32 = 4;
|
//pub const MAX_BOUNCES: u32 = 4;
|
||||||
//pub const MAX_BOUNCES: u32 = 8;
|
//pub const MAX_BOUNCES: u32 = 8;
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@ impl UserData for Mat3 {
|
|||||||
methods.add_meta_method(MetaMethod::Sub, |ctx, a: &Self, b: Self| Ok(*a-b));
|
methods.add_meta_method(MetaMethod::Sub, |ctx, a: &Self, b: Self| Ok(*a-b));
|
||||||
methods.add_meta_method(MetaMethod::Mul, |ctx, a: &Self, b: Self| Ok(*a*b));
|
methods.add_meta_method(MetaMethod::Mul, |ctx, a: &Self, b: Self| Ok(*a*b));
|
||||||
methods.add_meta_method(MetaMethod::Unm, |ctx, a: &Self, b: ()| Ok(-*a));
|
methods.add_meta_method(MetaMethod::Unm, |ctx, a: &Self, b: ()| Ok(-*a));
|
||||||
methods.add_meta_method(MetaMethod::Mul, |ctx, a: &Self, b: f64| Ok(*a*b));
|
//methods.add_meta_method(MetaMethod::Mul, |ctx, a: &Self, b: f64| Ok(*a*b)); //TODO find a way to make it cohabit
|
||||||
methods.add_meta_method(MetaMethod::Div, |ctx, a: &Self, b: f64| Ok(*a/b));
|
methods.add_meta_method(MetaMethod::Div, |ctx, a: &Self, b: f64| Ok(*a/b));
|
||||||
|
|
||||||
methods.add_method("a", |ctx, x, ()| Ok(x.a()));
|
methods.add_method("a", |ctx, x, ()| Ok(x.a()));
|
||||||
|
|||||||
@@ -54,6 +54,10 @@ pub fn obj<'lua>(ctx: Context<'lua>, _env: Table<'lua>) -> rlua::Result<Table<'l
|
|||||||
|ctx, (normal, offset): (Vec3, f64)| LuaObject::new(Plane::new(normal, offset))
|
|ctx, (normal, offset): (Vec3, f64)| LuaObject::new(Plane::new(normal, offset))
|
||||||
)?)?;
|
)?)?;
|
||||||
|
|
||||||
|
module.set("smoothunion", ctx.create_function(
|
||||||
|
|ctx, (a, b, r): (LuaObject, LuaObject, f64)| LuaObject::new(SmoothUnion::new(a.get(), b.get(), r))
|
||||||
|
)?)?;
|
||||||
|
|
||||||
module.set("sphere", ctx.create_function(
|
module.set("sphere", ctx.create_function(
|
||||||
|ctx, (pos, radius): (Vec3, f64)| LuaObject::new(Sphere::new(pos, radius))
|
|ctx, (pos, radius): (Vec3, f64)| LuaObject::new(Sphere::new(pos, radius))
|
||||||
)?)?;
|
)?)?;
|
||||||
@@ -66,6 +70,10 @@ pub fn obj<'lua>(ctx: Context<'lua>, _env: Table<'lua>) -> rlua::Result<Table<'l
|
|||||||
|ctx, (obj, trans, disp): (LuaObject, Mat3, Vec3)| LuaObject::new(AffineTransform::new(obj.get(), trans, disp))
|
|ctx, (obj, trans, disp): (LuaObject, Mat3, Vec3)| LuaObject::new(AffineTransform::new(obj.get(), trans, disp))
|
||||||
)?)?;
|
)?)?;
|
||||||
|
|
||||||
|
module.set("transformaround", ctx.create_function(
|
||||||
|
|ctx, (obj, trans, center): (LuaObject, Mat3, Vec3)| LuaObject::new(TransformAround::new(obj.get(), trans, center))
|
||||||
|
)?)?;
|
||||||
|
|
||||||
module.set("union", ctx.create_function(
|
module.set("union", ctx.create_function(
|
||||||
|ctx, (a, b): (LuaObject, LuaObject)| LuaObject::new(Union::new(a.get(), b.get()))
|
|ctx, (a, b): (LuaObject, LuaObject)| LuaObject::new(Union::new(a.get(), b.get()))
|
||||||
)?)?;
|
)?)?;
|
||||||
|
|||||||
+17
-3
@@ -1,5 +1,5 @@
|
|||||||
use rlua::{Context, Table, Error};
|
use rlua::{Context, Table};
|
||||||
use crate::object::{SWAP_XY, SWAP_YZ, SWAP_XZ, scale_xyz, scale, scale_x, scale_y, scale_z};
|
use crate::object::{SWAP_XY, SWAP_YZ, SWAP_XZ, scale_xyz, scale, scale_x, scale_y, scale_z, rotate_xyz, rotate_x, rotate_z, rotate_y};
|
||||||
use crate::structs::{Mat3, I3};
|
use crate::structs::{Mat3, I3};
|
||||||
|
|
||||||
pub fn transform<'lua>(ctx: Context<'lua>, _env: Table<'lua>) -> rlua::Result<Table<'lua>> {
|
pub fn transform<'lua>(ctx: Context<'lua>, _env: Table<'lua>) -> rlua::Result<Table<'lua>> {
|
||||||
@@ -26,11 +26,25 @@ pub fn transform<'lua>(ctx: Context<'lua>, _env: Table<'lua>) -> rlua::Result<Ta
|
|||||||
|ctx, k| Ok(scale_z(k))
|
|ctx, k| Ok(scale_z(k))
|
||||||
)?)?;
|
)?)?;
|
||||||
|
|
||||||
|
module.set("rotatexyz", ctx.create_function(
|
||||||
|
|ctx, (x, y, z)| Ok(rotate_xyz(x, y, z))
|
||||||
|
)?)?;
|
||||||
|
|
||||||
|
module.set("rotatex", ctx.create_function(
|
||||||
|
|ctx, a| Ok(rotate_x(a))
|
||||||
|
)?)?;
|
||||||
|
module.set("rotatey", ctx.create_function(
|
||||||
|
|ctx, a| Ok(rotate_y(a))
|
||||||
|
)?)?;
|
||||||
|
module.set("rotatez", ctx.create_function(
|
||||||
|
|ctx, a| Ok(rotate_z(a))
|
||||||
|
)?)?;
|
||||||
|
|
||||||
module.set("stack", ctx.create_function(
|
module.set("stack", ctx.create_function(
|
||||||
|ctx, transforms: Vec<Mat3>| {
|
|ctx, transforms: Vec<Mat3>| {
|
||||||
let mut acc = I3;
|
let mut acc = I3;
|
||||||
for trans in transforms.iter().rev().cloned() {
|
for trans in transforms.iter().rev().cloned() {
|
||||||
acc = trans * I3;
|
acc = acc * trans;
|
||||||
}
|
}
|
||||||
Ok(acc)
|
Ok(acc)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -65,7 +65,7 @@ function M.transform(object, mat)
|
|||||||
return obj.affinetransform(object, mat, vec3.O)
|
return obj.affinetransform(object, mat, vec3.O)
|
||||||
end
|
end
|
||||||
function M.translate(object, vec)
|
function M.translate(object, vec)
|
||||||
return obj.affinetransform(object, mat3.O, vec)
|
return obj.affinetransform(object, mat3.I, vec)
|
||||||
end
|
end
|
||||||
|
|
||||||
return M
|
return M
|
||||||
+3
-2
@@ -85,9 +85,10 @@ fn default_scene3() -> Scene {
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// get scene and camera
|
// get scene and camera
|
||||||
let scene = scene_from_file("scenes/randomspheres.lua".to_owned()).unwrap();
|
let scene = scene_from_file("scenes/tsm.lua".to_owned()).unwrap();
|
||||||
//let scene = default_scene3();
|
//let scene = default_scene3();
|
||||||
let cam = default_cam();
|
let cam = Cam::new(Z * -1.5, Z, f64::sqrt(2.));
|
||||||
|
//let cam = default_cam();
|
||||||
|
|
||||||
// get stats on the scene we're about to render
|
// get stats on the scene we're about to render
|
||||||
let total_rpp = (RAYS_PER_PIXEL * SUPERSAMPLING * SUPERSAMPLING) as u64;
|
let total_rpp = (RAYS_PER_PIXEL * SUPERSAMPLING * SUPERSAMPLING) as u64;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use std::vec::Vec;
|
|||||||
mod sphere;
|
mod sphere;
|
||||||
mod plane;
|
mod plane;
|
||||||
mod union;
|
mod union;
|
||||||
|
mod smoothunion;
|
||||||
mod intersection;
|
mod intersection;
|
||||||
mod exclusion;
|
mod exclusion;
|
||||||
mod negation;
|
mod negation;
|
||||||
@@ -64,6 +65,7 @@ impl<T: 'static + Obj + Clone> ObjClone for T {
|
|||||||
pub use sphere::Sphere;
|
pub use sphere::Sphere;
|
||||||
pub use plane::Plane;
|
pub use plane::Plane;
|
||||||
pub use union::Union;
|
pub use union::Union;
|
||||||
|
pub use smoothunion::SmoothUnion;
|
||||||
pub use intersection::Intersection;
|
pub use intersection::Intersection;
|
||||||
pub use exclusion::Exclusion;
|
pub use exclusion::Exclusion;
|
||||||
pub use negation::Negation;
|
pub use negation::Negation;
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
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 SmoothUnion<A: Obj, B: Obj> {
|
||||||
|
a: A,
|
||||||
|
b: B,
|
||||||
|
r: f64
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A: Obj, B: Obj> SmoothUnion<A, B> {
|
||||||
|
pub fn new(a: A, b: B, r: f64) -> SmoothUnion<A, B> {
|
||||||
|
SmoothUnion { a, b, r }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A: Obj, B: Obj> Obj for SmoothUnion<A, B> {
|
||||||
|
fn distance_to(&self, point: Vec3) -> f64 {
|
||||||
|
let d1 = self.a.distance_to(point);
|
||||||
|
let d2 = self.b.distance_to(point);
|
||||||
|
let h = f64::max(self.r - f64::abs(d1-d2),0.);
|
||||||
|
d1.min(d2) - h*h*0.25 / self.r
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
+79
-2
@@ -14,10 +14,10 @@ pub struct AffineTransform<T: Obj + Clone> {
|
|||||||
|
|
||||||
impl<T: Obj + Clone> AffineTransform<T> {
|
impl<T: Obj + Clone> AffineTransform<T> {
|
||||||
pub fn new(obj: T, transform: Mat3, translate: Vec3) -> AffineTransform<T> {
|
pub fn new(obj: T, transform: Mat3, translate: Vec3) -> AffineTransform<T> {
|
||||||
AffineTransform { obj, transform, transform_inv: transform.invert(), translate, scale: transform.det().cbrt() }
|
AffineTransform { obj, transform, transform_inv: transform.invert(), translate, scale: transform.det().abs().cbrt() }
|
||||||
}
|
}
|
||||||
pub fn new_linear(obj: T, transform: Mat3) -> AffineTransform<T> {
|
pub fn new_linear(obj: T, transform: Mat3) -> AffineTransform<T> {
|
||||||
AffineTransform { obj, transform, transform_inv: transform.invert(), translate: O, scale: transform.det().cbrt() }
|
AffineTransform { obj, transform, transform_inv: transform.invert(), translate: O, scale: transform.det().abs().cbrt() }
|
||||||
}
|
}
|
||||||
pub fn new_translate(obj: T, translate: Vec3) -> AffineTransform<T> {
|
pub fn new_translate(obj: T, translate: Vec3) -> AffineTransform<T> {
|
||||||
AffineTransform { obj, transform: I3, transform_inv: I3, translate, scale: 1. }
|
AffineTransform { obj, transform: I3, transform_inv: I3, translate, scale: 1. }
|
||||||
@@ -59,6 +59,37 @@ 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_y(k: f64) -> Mat3 { scale_xyz(1., k, 1.) }
|
||||||
pub const fn scale_z(k: f64) -> Mat3 { scale_xyz(1., 1., k) }
|
pub const fn scale_z(k: f64) -> Mat3 { scale_xyz(1., 1., k) }
|
||||||
|
|
||||||
|
pub fn rotate_x(a: f64) -> Mat3 {
|
||||||
|
let c = a.cos();
|
||||||
|
let s = a.sin();
|
||||||
|
Mat3::new(
|
||||||
|
1., 0., 0.,
|
||||||
|
0., c, -s,
|
||||||
|
0., s, c
|
||||||
|
)
|
||||||
|
}
|
||||||
|
pub fn rotate_y(a: f64) -> Mat3 {
|
||||||
|
let c = a.cos();
|
||||||
|
let s = a.sin();
|
||||||
|
Mat3::new(
|
||||||
|
c, 0., s,
|
||||||
|
0., 1., 0.,
|
||||||
|
-s, 0., c
|
||||||
|
)
|
||||||
|
}
|
||||||
|
pub fn rotate_z(a: f64) -> Mat3 {
|
||||||
|
let c = a.cos();
|
||||||
|
let s = a.sin();
|
||||||
|
Mat3::new(
|
||||||
|
c, -s, 0.,
|
||||||
|
s, c, 0.,
|
||||||
|
0., 0., 1.
|
||||||
|
)
|
||||||
|
}
|
||||||
|
pub fn rotate_xyz(x: f64, y: f64, z: f64) -> Mat3 {
|
||||||
|
rotate_z(z) * rotate_y(y) * rotate_x(x)
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: Obj + Clone> Obj for AffineTransform<T> {
|
impl<T: Obj + Clone> Obj for AffineTransform<T> {
|
||||||
fn distance_to(&self, point: Vec3) -> f64 {
|
fn distance_to(&self, point: Vec3) -> f64 {
|
||||||
self.obj.distance_to(self.apply_rev(point)) * self.scale
|
self.obj.distance_to(self.apply_rev(point)) * self.scale
|
||||||
@@ -82,3 +113,49 @@ impl<T: Obj + Clone> Obj for AffineTransform<T> {
|
|||||||
self.obj.node_count() + 1
|
self.obj.node_count() + 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||||
|
pub struct TransformAround<T: Obj + Clone> {
|
||||||
|
obj: T,
|
||||||
|
transform: Mat3,
|
||||||
|
transform_inv: Mat3,
|
||||||
|
center: Vec3,
|
||||||
|
scale: f64
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Obj + Clone> TransformAround<T> {
|
||||||
|
pub fn new(obj: T, transform: Mat3, center: Vec3) -> TransformAround<T> {
|
||||||
|
TransformAround { obj, transform, transform_inv: transform.invert(), center, scale: transform.det().abs().cbrt() }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apply_rev(&self, point: Vec3) -> Vec3 {
|
||||||
|
self.transform_inv * (point + self.center) - self.center
|
||||||
|
}
|
||||||
|
fn apply_fwd(&self, point: Vec3) -> Vec3 {
|
||||||
|
self.transform * (point - self.center) + self.center
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Obj + Clone> Obj for TransformAround<T> {
|
||||||
|
fn distance_to(&self, point: Vec3) -> f64 {
|
||||||
|
self.obj.distance_to(self.apply_rev(point)) * self.scale
|
||||||
|
}
|
||||||
|
fn normal_at(&self, point: Vec3) -> Vec3 {
|
||||||
|
self.apply_fwd(self.obj.normal_at(self.apply_rev(point))).unit()
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+1
-1
@@ -137,7 +137,7 @@ impl Mul<Mat3> for Mat3 {
|
|||||||
|
|
||||||
d: self.d*other.a + self.e*other.d + self.f*other.g,
|
d: self.d*other.a + self.e*other.d + self.f*other.g,
|
||||||
e: self.d*other.b + self.e*other.e + self.f*other.h,
|
e: self.d*other.b + self.e*other.e + self.f*other.h,
|
||||||
f: self.d*other.c + self.e*other.f + self.e*other.i,
|
f: self.d*other.c + self.e*other.f + self.f*other.i,
|
||||||
|
|
||||||
g: self.g*other.a + self.h*other.d + self.i*other.g,
|
g: self.g*other.a + self.h*other.d + self.i*other.g,
|
||||||
h: self.g*other.b + self.h*other.e + self.i*other.h,
|
h: self.g*other.b + self.h*other.e + self.i*other.h,
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
[ -z "$SEED" ] && export SEED=0
|
||||||
clear
|
clear
|
||||||
cargo build --release && \
|
cargo build --release && \
|
||||||
clear && \
|
clear && \
|
||||||
time SEED=0 target/release/rmarcher && \
|
time target/release/rmarcher && \
|
||||||
printf '\n' && \
|
printf '\n' && \
|
||||||
kitty +kitten icat --align=left a.png
|
kitty +kitten icat --align=left a.png
|
||||||
|
|||||||
Reference in New Issue
Block a user