more lua support, fixed scene 3

This commit is contained in:
Codinget
2021-04-30 23:29:40 +02:00
parent 9529f56a01
commit 5db2ecb4fe
19 changed files with 211 additions and 95 deletions
+2 -2
View File
@@ -4,7 +4,7 @@ use rlua::{UserData, Context, Table};
impl UserData for ColorVec {}
impl UserData for ColorMat {}
pub fn color_vec(ctx: Context, _: ()) -> rlua::Result<Table> {
pub fn color_vec<'lua>(ctx: Context<'lua>, _env: Table<'lua>) -> rlua::Result<Table<'lua>> {
let module = ctx.create_table()?;
module.set("new", ctx.create_function(
@@ -16,7 +16,7 @@ pub fn color_vec(ctx: Context, _: ()) -> rlua::Result<Table> {
Ok(module)
}
pub fn color_mat(ctx: Context, _: ()) -> rlua::Result<Table> {
pub fn color_mat<'lua>(ctx: Context<'lua>, _env: Table<'lua>) -> rlua::Result<Table<'lua>> {
let module = ctx.create_table()?;
module.set("new", ctx.create_function(
+1 -1
View File
@@ -3,7 +3,7 @@ use rlua::{UserData, Context, Table};
impl UserData for Light {}
pub fn light(ctx: Context, _: ()) -> rlua::Result<Table> {
pub fn light<'lua>(ctx: Context<'lua>, _env: Table<'lua>) -> rlua::Result<Table<'lua>> {
let module = ctx.create_table()?;
module.set("new", ctx.create_function(
+1 -1
View File
@@ -29,7 +29,7 @@ impl UserData for Mat3 {
}
}
pub fn mat3(ctx: Context, _: ()) -> rlua::Result<Table> {
pub fn mat3<'lua>(ctx: Context<'lua>, _env: Table<'lua>) -> rlua::Result<Table<'lua>> {
let module = ctx.create_table()?;
module.set("new", ctx.create_function(
+2 -2
View File
@@ -4,7 +4,7 @@ use rlua::{UserData, Context, Table};
impl UserData for SurfaceType {}
impl UserData for Material {}
pub fn surface_type(ctx: Context, _: ()) -> rlua::Result<Table> {
pub fn surface_type<'lua>(ctx: Context<'lua>, _env: Table<'lua>) -> rlua::Result<Table<'lua>> {
let module = ctx.create_table()?;
module.set("DIFFUSE", SurfaceType::Diffuse)?;
@@ -14,7 +14,7 @@ pub fn surface_type(ctx: Context, _: ()) -> rlua::Result<Table> {
Ok(module)
}
pub fn material(ctx: Context, _: ()) -> rlua::Result<Table> {
pub fn material<'lua>(ctx: Context<'lua>, _env: Table<'lua>) -> rlua::Result<Table<'lua>> {
let module = ctx.create_table()?;
module.set("new", ctx.create_function(
+18 -13
View File
@@ -6,6 +6,8 @@ mod mat3;
mod color;
mod material;
mod light;
mod transform;
mod util;
pub use obj::{LuaObject, obj};
pub use vec3::vec3;
@@ -13,25 +15,28 @@ pub use mat3::mat3;
pub use color::{color_vec, color_mat};
pub use material::{surface_type, material};
pub use light::light;
pub use transform::transform;
pub use util::util;
pub fn env(ctx: Context, _: ()) -> rlua::Result<Table> {
let module = ctx.create_table()?;
pub fn add_scene_env<'lua>(ctx: Context<'lua>, env: Table<'lua>) -> rlua::Result<Table<'lua>> {
env.set("obj", obj(ctx, env.clone())?)?;
env.set("vec3", vec3(ctx, env.clone())?)?;
env.set("mat3", mat3(ctx, env.clone())?)?;
env.set("colorvec", color_vec(ctx, env.clone())?)?;
env.set("colormat", color_mat(ctx, env.clone())?)?;
env.set("surfacetype", surface_type(ctx, env.clone())?)?;
env.set("material", material(ctx, env.clone())?)?;
env.set("light", light(ctx, env.clone())?)?;
env.set("transform", transform(ctx, env.clone())?)?;
env.set("util", util(ctx, env.clone())?)?;
module.set("obj", obj(ctx, ())?)?;
module.set("vec3", vec3(ctx, ())?)?;
module.set("mat3", mat3(ctx, ())?)?;
module.set("colorvec", color_vec(ctx, ())?)?;
module.set("colormat", color_mat(ctx, ())?)?;
module.set("surfacetype", surface_type(ctx, ())?)?;
module.set("material", material(ctx, ())?)?;
module.set("light", light(ctx, ())?)?;
Ok(module)
Ok(env)
}
pub fn scene_from_file(file: String) -> rlua::Result<LuaObject> {
Lua::new().context(|ctx| {
let env = env(ctx, ())?;
let env = ctx.create_table()?;
add_scene_env(ctx, env.clone())?;
let meta = ctx.create_table()?;
meta.set("__index", ctx.globals())?;
env.set_metatable(Some(meta));
+6 -2
View File
@@ -27,7 +27,7 @@ impl Obj for LuaObject {
impl UserData for LuaObject {}
pub fn obj(ctx: Context, _: ()) -> rlua::Result<Table> {
pub fn obj<'lua>(ctx: Context<'lua>, _env: Table<'lua>) -> rlua::Result<Table<'lua>> {
let module = ctx.create_table()?;
module.set("cuboid", ctx.create_function(
@@ -70,10 +70,14 @@ pub fn obj(ctx: Context, _: ()) -> rlua::Result<Table> {
|ctx, ()| LuaObject::new(Waves::new())
)?)?;
module.set("withlights", ctx.create_function(
module.set("withlight", ctx.create_function(
|ctx, (obj, light): (LuaObject, Light)| LuaObject::new(WithLights::new_one(obj.get(), light))
)?)?;
module.set("withlights", ctx.create_function(
|ctx, (obj, lights): (LuaObject, Vec<Light>)| LuaObject::new(WithAnyLights::new(obj.get(), lights))
)?)?;
module.set("withmaterial", ctx.create_function(
|ctx, (obj, material): (LuaObject, Material)| LuaObject::new(WithMaterial::new(obj.get(), material))
)?)?;
+40
View File
@@ -0,0 +1,40 @@
use rlua::{Context, Table, Error};
use crate::object::{SWAP_XY, SWAP_YZ, SWAP_XZ, scale_xyz, scale, scale_x, scale_y, scale_z};
use crate::structs::{Mat3, I3};
pub fn transform<'lua>(ctx: Context<'lua>, _env: Table<'lua>) -> rlua::Result<Table<'lua>> {
let module = ctx.create_table()?;
module.set("SWAPXY", SWAP_XY)?;
module.set("SWAPXZ", SWAP_XZ)?;
module.set("SWAPYZ", SWAP_YZ)?;
module.set("scalexyz", ctx.create_function(
|ctx, (x, y, z)| Ok(scale_xyz(x, y, z))
)?)?;
module.set("scale", ctx.create_function(
|ctx, k| Ok(scale(k))
)?)?;
module.set("scalex", ctx.create_function(
|ctx, k| Ok(scale_x(k))
)?)?;
module.set("scaley", ctx.create_function(
|ctx, k| Ok(scale_y(k))
)?)?;
module.set("scalez", ctx.create_function(
|ctx, k| Ok(scale_z(k))
)?)?;
module.set("stack", ctx.create_function(
|ctx, transforms: Vec<Mat3>| {
let mut acc = I3;
for trans in transforms.iter().rev().cloned() {
acc = trans * I3;
}
Ok(acc)
}
)?)?;
Ok(module)
}
+71
View File
@@ -0,0 +1,71 @@
local env = ...
local obj = env.obj
local vec3 = env.vec3
local mat3 = env.mat3
local transform = env.transform
local M = {}
-- technically a binary fold
local function binstack(objs, fn)
local n = #objs
if n == 1 then return objs[1] end
local mid = n//2
local left, right = {}, {}
for i=1, mid do
left[i] = objs[i]
end
for i=mid+1, n do
right[i-mid] = objs[i]
end
return fn(binstack(left, fn), binstack(right, fn))
end
-- technically a fold
local function linstack(objs, fn)
local head = objs[1]
for i=2, #objs do
head = fn(head, objs[i])
end
return head
end
-- random functions
local SEED = os.getenv "SEED" or os.time()
function M.seed()
math.randomseed(SEED)
end
function M.randab(a, b)
return math.random() * (b-a) + a
end
function M.choice(list)
return list[math.random(1, #list)]
end
-- multiple object composition
function M.union(objs)
return binstack(objs, obj.union)
end
function M.intersection(objs)
return binstack(objs, obj.intersection)
end
function M.smoothunion(objs, k)
return linstack(objs, function(a, b) return obj.smoothunion(a, b, k) end)
end
function M.smoothintersection(objs, k)
return linstack(objs, function(a, b) return obj.smoothintersection(a, b, k) end)
end
-- simpler transformations
function M.scale(object, k)
return obj.affinetransform(object, transform.scale(k), vec3.O)
end
function M.transform(object, mat)
return obj.affinetransform(object, mat, vec3.O)
end
function M.translate(object, vec)
return obj.affinetransform(object, mat3.O, vec)
end
return M
+5
View File
@@ -0,0 +1,5 @@
use rlua::{Context, Table};
pub fn util<'lua>(ctx: Context<'lua>, env: Table<'lua>) -> rlua::Result<Table<'lua>> {
ctx.load(include_str!("util.lua")).call(env)
}
+1 -1
View File
@@ -24,7 +24,7 @@ impl UserData for Vec3 {
}
}
pub fn vec3(ctx: Context, _: ()) -> rlua::Result<Table> {
pub fn vec3<'lua>(ctx: Context<'lua>, _env: Table<'lua>) -> rlua::Result<Table<'lua>> {
let module = ctx.create_table()?;
module.set("new", ctx.create_function(
+3 -3
View File
@@ -68,8 +68,7 @@ fn default_scene2() -> Scene {
}
fn default_scene3() -> Scene {
//TODO fix this scene
let s1 = WithMaterial::new(Sphere::new_xyz(4., 0., 0., 1.), WHITE);
let s1 = WithMaterial::new(Sphere::new_xyz(4., 0., 0., 1.), MIRROR);
let s2 = WithMaterial::new(Sphere::new_xyz(3., 1., 1., 0.5), GREEN);
let navion = WithMaterial::new(Plane::new_xyz(0., 1., -1., 3.), BLUE);
let backwall = WithMaterial::new(Plane::new_xyz(-1., -1., -0.5, 8.), RED);
@@ -86,7 +85,8 @@ fn default_scene3() -> Scene {
fn main() {
// get scene and camera
let scene = scene_from_file("scenes/smolgalaxy.lua".to_owned()).unwrap();
//let scene = scene_from_file("scenes/randomspheres.lua".to_owned()).unwrap();
let scene = default_scene3();
let cam = default_cam();
// get stats on the scene we're about to render
+1 -1
View File
@@ -70,6 +70,6 @@ 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 with_lights::{WithLights, WithLight, WithAnyLights};
pub use transform::*;
pub use scene::Scene;
+6 -5
View File
@@ -8,18 +8,19 @@ pub struct AffineTransform<T: Obj + Clone> {
obj: T,
transform: Mat3,
transform_inv: Mat3,
translate: Vec3
translate: Vec3,
scale: f64
}
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 }
AffineTransform { obj, transform, transform_inv: transform.invert(), translate, scale: transform.det().cbrt() }
}
pub fn new_linear(obj: T, transform: Mat3) -> AffineTransform<T> {
AffineTransform { obj, transform, transform_inv: transform.invert(), translate: O }
AffineTransform { obj, transform, transform_inv: transform.invert(), translate: O, scale: transform.det().cbrt() }
}
pub fn new_translate(obj: T, translate: Vec3) -> AffineTransform<T> {
AffineTransform { obj, transform: I3, transform_inv: I3, translate }
AffineTransform { obj, transform: I3, transform_inv: I3, translate, scale: 1. }
}
fn apply_rev(&self, point: Vec3) -> Vec3 {
@@ -60,7 +61,7 @@ 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))
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()
+36
View File
@@ -41,4 +41,40 @@ impl<T: Obj> WithLight<T> {
pub fn new_one(obj: T, light: Light) -> WithLight<T> {
WithLight { obj, lights: [light; 1] }
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct WithAnyLights<T: Obj> {
obj: T,
lights: Vec<Light>
}
impl<T: Obj> WithAnyLights<T> {
pub fn new(obj: T, lights: Vec<Light>) -> WithAnyLights<T> {
WithAnyLights { obj, lights }
}
pub fn add_light(&mut self, light: Light) {
self.lights.push(light)
}
}
impl<T: Obj> Obj for WithAnyLights<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.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
}
}