lua scene support with one example, general improvements
This commit is contained in:
@@ -15,16 +15,19 @@ A ray marching renderer in rust
|
|||||||
- Spectral simulation (currently using 4 color components)
|
- Spectral simulation (currently using 4 color components)
|
||||||
- Global illumination (with diffuse and reflective surfaces)
|
- Global illumination (with diffuse and reflective surfaces)
|
||||||
- Punctual illumination
|
- Punctual illumination
|
||||||
|
- Defining scenes in lua
|
||||||
|
|
||||||
## What is planned
|
## What is planned
|
||||||
- Testing of more shapes
|
- Testing of more shapes
|
||||||
- Support for a lua-based scene representation DSL
|
- Support for a lua-based scene representation DSL
|
||||||
|
- Support for controlling the whole application from lua
|
||||||
- Support for linking against a `scene.so` exporting a scene
|
- Support for linking against a `scene.so` exporting a scene
|
||||||
- Support for using as a library
|
- Support for using as a library
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||

|

|
||||||

|

|
||||||
|

|
||||||
|
|
||||||
## License
|
## License
|
||||||
MIT
|
MIT
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 590 KiB |
@@ -0,0 +1,52 @@
|
|||||||
|
local unpack = table.unpack or _G.unpack
|
||||||
|
math.randomseed(os.time())
|
||||||
|
|
||||||
|
local function randab(a, b)
|
||||||
|
return math.random() * (b-a) + a
|
||||||
|
end
|
||||||
|
|
||||||
|
local function randtable(n, a, b)
|
||||||
|
local t = {}
|
||||||
|
for i=1, n do
|
||||||
|
t[i] = randab(a, b)
|
||||||
|
end
|
||||||
|
return t
|
||||||
|
end
|
||||||
|
|
||||||
|
local function choice(list)
|
||||||
|
return list[math.random(1, #list)]
|
||||||
|
end
|
||||||
|
|
||||||
|
local function randomsphere()
|
||||||
|
local pos = vec3.new(unpack(randtable(3, -2, 2)))
|
||||||
|
local radius = randab(0, 0.5)
|
||||||
|
local emission = colorvec.new(unpack(randtable(4, 0, 1)))
|
||||||
|
local reflection = colormat.new(unpack(randtable(16, 0, 1)))
|
||||||
|
local surfacetype = choice({surfacetype.DIFFUSE, surfacetype.REFLECTIVE, surfacetype.STOP})
|
||||||
|
|
||||||
|
return obj.withmaterial(
|
||||||
|
obj.sphere(pos, radius),
|
||||||
|
material.new(emission, reflection, surfacetype)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function union(objs)
|
||||||
|
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 obj.union(union(left), union(right))
|
||||||
|
end
|
||||||
|
|
||||||
|
local spheres = {}
|
||||||
|
for i=1, 100 do
|
||||||
|
spheres[i] = randomsphere()
|
||||||
|
end
|
||||||
|
return union(spheres)
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
use crate::structs::{ColorVec, ColorMat};
|
||||||
|
use rlua::{UserData, Context, Table};
|
||||||
|
|
||||||
|
impl UserData for ColorVec {}
|
||||||
|
impl UserData for ColorMat {}
|
||||||
|
|
||||||
|
pub fn color_vec(ctx: Context, _: ()) -> rlua::Result<Table> {
|
||||||
|
let module = ctx.create_table()?;
|
||||||
|
|
||||||
|
module.set("new", ctx.create_function(
|
||||||
|
|ctx, (r, g, b, u)| Ok(ColorVec::new([r, g, b, u]))
|
||||||
|
)?)?;
|
||||||
|
|
||||||
|
module.set("ZERO", ColorVec::new_zero())?;
|
||||||
|
|
||||||
|
Ok(module)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn color_mat(ctx: Context, _: ()) -> rlua::Result<Table> {
|
||||||
|
let module = ctx.create_table()?;
|
||||||
|
|
||||||
|
module.set("new", ctx.create_function(
|
||||||
|
|ctx, (
|
||||||
|
a, b, c, d,
|
||||||
|
e, f, g, h,
|
||||||
|
i, j, k, l,
|
||||||
|
m, n, o, p
|
||||||
|
)| Ok(ColorMat::new([
|
||||||
|
[a, b, c, d],
|
||||||
|
[e, f, g, h],
|
||||||
|
[i, j, k, l],
|
||||||
|
[m, n, o, p]
|
||||||
|
]))
|
||||||
|
)?)?;
|
||||||
|
|
||||||
|
module.set("newfromvec", ctx.create_function(
|
||||||
|
|ctx, vec: ColorVec| Ok(ColorMat::new_from_diagonal(vec))
|
||||||
|
)?)?;
|
||||||
|
|
||||||
|
module.set("newfromdiagonal", ctx.create_function(
|
||||||
|
|ctx, (r, g, b, u)| Ok(ColorMat::new_from_diagonal(ColorVec::new([r, g, b, u])))
|
||||||
|
)?)?;
|
||||||
|
|
||||||
|
module.set("ZERO", ColorMat::new_zero())?;
|
||||||
|
|
||||||
|
Ok(module)
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
use crate::light::Light;
|
||||||
|
use rlua::{UserData, Context, Table};
|
||||||
|
|
||||||
|
impl UserData for Light {}
|
||||||
|
|
||||||
|
pub fn light(ctx: Context, _: ()) -> rlua::Result<Table> {
|
||||||
|
let module = ctx.create_table()?;
|
||||||
|
|
||||||
|
module.set("new", ctx.create_function(
|
||||||
|
|ctx, (pos, color)| Ok(Light::new(pos, color))
|
||||||
|
)?)?;
|
||||||
|
|
||||||
|
Ok(module)
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
use crate::structs::{Mat3, I3, O3};
|
||||||
|
use rlua::{UserData, UserDataMethods, Context, MetaMethod, Table};
|
||||||
|
|
||||||
|
impl UserData for Mat3 {
|
||||||
|
fn add_methods<'lua, T: UserDataMethods<'lua, Self>>(methods: &mut T) {
|
||||||
|
methods.add_meta_method(MetaMethod::Add, |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::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::Div, |ctx, a: &Self, b: f64| Ok(*a/b));
|
||||||
|
|
||||||
|
methods.add_method("a", |ctx, x, ()| Ok(x.a()));
|
||||||
|
methods.add_method("b", |ctx, x, ()| Ok(x.b()));
|
||||||
|
methods.add_method("c", |ctx, x, ()| Ok(x.c()));
|
||||||
|
methods.add_method("d", |ctx, x, ()| Ok(x.d()));
|
||||||
|
methods.add_method("e", |ctx, x, ()| Ok(x.e()));
|
||||||
|
methods.add_method("f", |ctx, x, ()| Ok(x.f()));
|
||||||
|
methods.add_method("g", |ctx, x, ()| Ok(x.g()));
|
||||||
|
methods.add_method("h", |ctx, x, ()| Ok(x.h()));
|
||||||
|
methods.add_method("i", |ctx, x, ()| Ok(x.i()));
|
||||||
|
|
||||||
|
methods.add_method("det", |ctx, x, ()| Ok(x.det()));
|
||||||
|
methods.add_method("trans",|ctx, x, ()| Ok(x.trans()));
|
||||||
|
methods.add_method("minor", |ctx, x, ()| Ok(x.minor()));
|
||||||
|
methods.add_method("invert", |ctx, x, ()| Ok(x.invert()));
|
||||||
|
|
||||||
|
methods.add_method("membermul", |ctx, x, y| Ok(x.member_mul(y)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mat3(ctx: Context, _: ()) -> rlua::Result<Table> {
|
||||||
|
let module = ctx.create_table()?;
|
||||||
|
|
||||||
|
module.set("new", ctx.create_function(
|
||||||
|
|ctx, (a, b, c, d, e, f, g, h, i)| Ok(Mat3::new(a, b, c, d, e, f, g, h, i))
|
||||||
|
)?)?;
|
||||||
|
|
||||||
|
module.set("I", I3)?;
|
||||||
|
module.set("O", O3)?;
|
||||||
|
|
||||||
|
Ok(module)
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
use crate::material::{SurfaceType, Material};
|
||||||
|
use rlua::{UserData, Context, Table};
|
||||||
|
|
||||||
|
impl UserData for SurfaceType {}
|
||||||
|
impl UserData for Material {}
|
||||||
|
|
||||||
|
pub fn surface_type(ctx: Context, _: ()) -> rlua::Result<Table> {
|
||||||
|
let module = ctx.create_table()?;
|
||||||
|
|
||||||
|
module.set("DIFFUSE", SurfaceType::Diffuse)?;
|
||||||
|
module.set("REFLECTIVE", SurfaceType::Reflective)?;
|
||||||
|
module.set("STOP", SurfaceType::Stop)?;
|
||||||
|
|
||||||
|
Ok(module)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn material(ctx: Context, _: ()) -> rlua::Result<Table> {
|
||||||
|
let module = ctx.create_table()?;
|
||||||
|
|
||||||
|
module.set("new", ctx.create_function(
|
||||||
|
|ctx, (emission, reflection, surface)| Ok(Material::new(emission, reflection, surface))
|
||||||
|
)?)?;
|
||||||
|
|
||||||
|
module.set("newfromdiagonal", ctx.create_function(
|
||||||
|
|ctx, (emission, reflection, surface)| Ok(Material::new_from_diagonal(emission, reflection, surface))
|
||||||
|
)?)?;
|
||||||
|
|
||||||
|
Ok(module)
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
use rlua::{Context, Table, Lua, Function};
|
||||||
|
|
||||||
|
mod obj;
|
||||||
|
mod vec3;
|
||||||
|
mod mat3;
|
||||||
|
mod color;
|
||||||
|
mod material;
|
||||||
|
mod light;
|
||||||
|
|
||||||
|
pub use obj::{LuaObject, obj};
|
||||||
|
pub use vec3::vec3;
|
||||||
|
pub use mat3::mat3;
|
||||||
|
pub use color::{color_vec, color_mat};
|
||||||
|
pub use material::{surface_type, material};
|
||||||
|
pub use light::light;
|
||||||
|
|
||||||
|
pub fn env(ctx: Context, _: ()) -> rlua::Result<Table> {
|
||||||
|
let module = ctx.create_table()?;
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn scene_from_file(file: String) -> rlua::Result<LuaObject> {
|
||||||
|
Lua::new().context(|ctx| {
|
||||||
|
let env = env(ctx, ())?;
|
||||||
|
let meta = ctx.create_table()?;
|
||||||
|
meta.set("__index", ctx.globals())?;
|
||||||
|
env.set_metatable(Some(meta));
|
||||||
|
|
||||||
|
let loadfile: Function = ctx.globals().get("loadfile")?;
|
||||||
|
let chunk: Function = loadfile.call((file, "t", env))?;
|
||||||
|
ctx.unpack(chunk.call(())?)
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
use crate::object::*;
|
||||||
|
use crate::structs::{Vec3, Mat3};
|
||||||
|
use std::sync::Arc;
|
||||||
|
use crate::material::Material;
|
||||||
|
use crate::light::Light;
|
||||||
|
use rlua::{UserData, Context, Table};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct LuaObject(Arc<Scene>);
|
||||||
|
|
||||||
|
impl LuaObject {
|
||||||
|
fn new<T: 'static + Obj + Clone>(obj: T) -> rlua::Result<LuaObject> {
|
||||||
|
Ok(LuaObject(Arc::new(Scene::new(obj))))
|
||||||
|
}
|
||||||
|
fn get(self) -> Scene {
|
||||||
|
(*self.0).clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Obj for LuaObject {
|
||||||
|
fn distance_to(&self, point: Vec3) -> f64 { self.0.distance_to(point) }
|
||||||
|
fn normal_at(&self, point: Vec3) -> Vec3 { self.0.normal_at(point) }
|
||||||
|
fn material_at(&self, point: Vec3) -> Material { self.0.material_at(point) }
|
||||||
|
fn get_lights(&self) -> Vec<Light> { self.0.get_lights() }
|
||||||
|
fn node_count(&self) -> u32 { 1 + self.0.node_count() }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UserData for LuaObject {}
|
||||||
|
|
||||||
|
pub fn obj(ctx: Context, _: ()) -> rlua::Result<Table> {
|
||||||
|
let module = ctx.create_table()?;
|
||||||
|
|
||||||
|
module.set("cuboid", ctx.create_function(
|
||||||
|
|ctx, (pos, radius): (Vec3, Vec3)| LuaObject::new(Cuboid::new(pos, radius))
|
||||||
|
)?)?;
|
||||||
|
|
||||||
|
module.set("cylinder", ctx.create_function(
|
||||||
|
|ctx, (pos, radius): (Vec3, f64)| LuaObject::new(Cylinder::new(pos, radius))
|
||||||
|
)?)?;
|
||||||
|
|
||||||
|
module.set("exclusion", ctx.create_function(
|
||||||
|
|ctx, (a, b): (LuaObject, LuaObject)| LuaObject::new(Exclusion::new(a.get(), b.get()))
|
||||||
|
)?)?;
|
||||||
|
|
||||||
|
module.set("intersection", ctx.create_function(
|
||||||
|
|ctx, (a, b): (LuaObject, LuaObject)| LuaObject::new(Intersection::new(a.get(), b.get()))
|
||||||
|
)?)?;
|
||||||
|
|
||||||
|
module.set("plane", ctx.create_function(
|
||||||
|
|ctx, (normal, offset): (Vec3, f64)| LuaObject::new(Plane::new(normal, offset))
|
||||||
|
)?)?;
|
||||||
|
|
||||||
|
module.set("sphere", ctx.create_function(
|
||||||
|
|ctx, (pos, radius): (Vec3, f64)| LuaObject::new(Sphere::new(pos, radius))
|
||||||
|
)?)?;
|
||||||
|
|
||||||
|
module.set("torus", ctx.create_function(
|
||||||
|
|ctx, (center, radius, thickness): (Vec3, f64, f64)| LuaObject::new(Torus::new(center, radius, thickness))
|
||||||
|
)?)?;
|
||||||
|
|
||||||
|
module.set("affinetransform", ctx.create_function(
|
||||||
|
|ctx, (obj, trans, disp): (LuaObject, Mat3, Vec3)| LuaObject::new(AffineTransform::new(obj.get(), trans, disp))
|
||||||
|
)?)?;
|
||||||
|
|
||||||
|
module.set("union", ctx.create_function(
|
||||||
|
|ctx, (a, b): (LuaObject, LuaObject)| LuaObject::new(Union::new(a.get(), b.get()))
|
||||||
|
)?)?;
|
||||||
|
|
||||||
|
module.set("waves", ctx.create_function(
|
||||||
|
|ctx, ()| LuaObject::new(Waves::new())
|
||||||
|
)?)?;
|
||||||
|
|
||||||
|
module.set("withlights", ctx.create_function(
|
||||||
|
|ctx, (obj, light): (LuaObject, Light)| LuaObject::new(WithLights::new_one(obj.get(), light))
|
||||||
|
)?)?;
|
||||||
|
|
||||||
|
module.set("withmaterial", ctx.create_function(
|
||||||
|
|ctx, (obj, material): (LuaObject, Material)| LuaObject::new(WithMaterial::new(obj.get(), material))
|
||||||
|
)?)?;
|
||||||
|
|
||||||
|
//TODO add the rest of the objects
|
||||||
|
|
||||||
|
Ok(module)
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
use crate::structs::{Vec3, X, Y, Z, O};
|
||||||
|
use rlua::{UserData, UserDataMethods, MetaMethod, Context, Table};
|
||||||
|
|
||||||
|
impl UserData for Vec3 {
|
||||||
|
fn add_methods<'lua, T: UserDataMethods<'lua, Self>>(methods: &mut T) {
|
||||||
|
methods.add_meta_method(MetaMethod::Add, |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::Pow, |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::Mul, |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("x", |ctx, x, ()| Ok(x.x()));
|
||||||
|
methods.add_method("y", |ctx, x, ()| Ok(x.y()));
|
||||||
|
methods.add_method("z", |ctx, x, ()| Ok(x.z()));
|
||||||
|
|
||||||
|
methods.add_method("magnitude", |ctx, x, ()| Ok(x.magnitude()));
|
||||||
|
methods.add_method("unit", |ctx, x, ()| Ok(x.unit()));
|
||||||
|
|
||||||
|
methods.add_method("distanceto", |ctx, x, y| Ok(x.distance_to(y)));
|
||||||
|
methods.add_method("angleto", |ctx, x, y| Ok(x.angle_to(y)));
|
||||||
|
methods.add_method("membermul", |ctx, x, y| Ok(x.member_mul(y)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn vec3(ctx: Context, _: ()) -> rlua::Result<Table> {
|
||||||
|
let module = ctx.create_table()?;
|
||||||
|
|
||||||
|
module.set("new", ctx.create_function(
|
||||||
|
|ctx, (x, y, z)| Ok(Vec3::new(x, y, z))
|
||||||
|
)?)?;
|
||||||
|
|
||||||
|
module.set("X", X)?;
|
||||||
|
module.set("Y", Y)?;
|
||||||
|
module.set("Z", Z)?;
|
||||||
|
module.set("O", O)?;
|
||||||
|
|
||||||
|
Ok(module)
|
||||||
|
}
|
||||||
+3
-1
@@ -3,6 +3,7 @@ mod light;
|
|||||||
mod object;
|
mod object;
|
||||||
mod structs;
|
mod structs;
|
||||||
mod consts;
|
mod consts;
|
||||||
|
mod lua;
|
||||||
|
|
||||||
use object::*;
|
use object::*;
|
||||||
use crate::consts::*;
|
use crate::consts::*;
|
||||||
@@ -10,6 +11,7 @@ use crate::structs::*;
|
|||||||
use crate::material::*;
|
use crate::material::*;
|
||||||
use image::{ColorType, ImageFormat};
|
use image::{ColorType, ImageFormat};
|
||||||
use crate::light::Light;
|
use crate::light::Light;
|
||||||
|
use crate::lua::scene_from_file;
|
||||||
|
|
||||||
fn default_cam() -> Cam {
|
fn default_cam() -> Cam {
|
||||||
Cam::new_pointing(Y*3. - X*5., O, 0.5)
|
Cam::new_pointing(Y*3. - X*5., O, 0.5)
|
||||||
@@ -84,7 +86,7 @@ fn default_scene3() -> Scene {
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// get scene and camera
|
// get scene and camera
|
||||||
let scene = default_scene2();
|
let scene = scene_from_file("scenes/randomspheres.lua".to_owned()).unwrap();
|
||||||
let cam = default_cam();
|
let cam = default_cam();
|
||||||
|
|
||||||
// get stats on the scene we're about to render
|
// get stats on the scene we're about to render
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
use crate::consts::{EPSILON, MAX_DIST};
|
use crate::consts::{EPSILON, MAX_DIST};
|
||||||
use crate::structs::{Vec3, O, X, Y, Z};
|
use crate::structs::{Vec3, X, Y, Z};
|
||||||
use crate::material::Material;
|
use crate::material::Material;
|
||||||
use crate::material;
|
use crate::material;
|
||||||
use crate::light::Light;
|
use crate::light::Light;
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ impl<T: Obj> Obj for WithMaterial<T> {
|
|||||||
fn normal_at(&self, point: Vec3) -> Vec3 {
|
fn normal_at(&self, point: Vec3) -> Vec3 {
|
||||||
self.obj.normal_at(point)
|
self.obj.normal_at(point)
|
||||||
}
|
}
|
||||||
fn material_at(&self, point: Vec3) -> Material {
|
fn material_at(&self, _point: Vec3) -> Material {
|
||||||
self.material
|
self.material
|
||||||
}
|
}
|
||||||
fn get_lights(&self) -> Vec<Light> {
|
fn get_lights(&self) -> Vec<Light> {
|
||||||
|
|||||||
+9
-10
@@ -6,7 +6,6 @@ use crate::light::Light;
|
|||||||
use std::f64::consts::PI;
|
use std::f64::consts::PI;
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
use crossbeam_channel::unbounded;
|
use crossbeam_channel::unbounded;
|
||||||
use std::ops::{Mul, Add, Sub};
|
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||||
@@ -125,7 +124,7 @@ impl Cam {
|
|||||||
let mut stderr = std::io::stderr();
|
let mut stderr = std::io::stderr();
|
||||||
if REPORT_STATUS {
|
if REPORT_STATUS {
|
||||||
stderr.write_all(format!("Rendering... 0/{} rows (0.00%)", IMG_HEIGHT).as_bytes()).unwrap();
|
stderr.write_all(format!("Rendering... 0/{} rows (0.00%)", IMG_HEIGHT).as_bytes()).unwrap();
|
||||||
stderr.flush();
|
stderr.flush().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
let lights = scene.get_lights();
|
let lights = scene.get_lights();
|
||||||
@@ -137,14 +136,14 @@ impl Cam {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if REPORT_STATUS {
|
if REPORT_STATUS {
|
||||||
stderr.write_all(format!("\x1b[1K\x1b[GRendering... {}/{} rows ({:.2}%)", y+1, IMG_HEIGHT, (y+1) as f64/IMG_HEIGHT as f64).as_bytes());
|
stderr.write_all(format!("\x1b[1K\x1b[GRendering... {}/{} rows ({:.2}%)", y+1, IMG_HEIGHT, (y+1) as f64/IMG_HEIGHT as f64).as_bytes()).unwrap();
|
||||||
stderr.flush();
|
stderr.flush().unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if REPORT_STATUS {
|
if REPORT_STATUS {
|
||||||
stderr.write_all(format!("\x1b[1K\x1b[GRendering... Done\n").as_bytes());
|
stderr.write_all(format!("\x1b[1K\x1b[GRendering... Done\n").as_bytes()).unwrap();
|
||||||
stderr.flush();
|
stderr.flush().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pixels
|
pixels
|
||||||
@@ -216,7 +215,7 @@ impl Cam {
|
|||||||
let mut stderr = std::io::stderr();
|
let mut stderr = std::io::stderr();
|
||||||
if REPORT_STATUS {
|
if REPORT_STATUS {
|
||||||
stderr.write_all(format!("Rendering... 0/{} slices (0.00%), 0.00% pixels", total_slices).as_bytes()).unwrap();
|
stderr.write_all(format!("Rendering... 0/{} slices (0.00%), 0.00% pixels", total_slices).as_bytes()).unwrap();
|
||||||
stderr.flush();
|
stderr.flush().unwrap();
|
||||||
}
|
}
|
||||||
let mut rendered_slices = 0u32;
|
let mut rendered_slices = 0u32;
|
||||||
let mut rendered_pixels = 0u64;
|
let mut rendered_pixels = 0u64;
|
||||||
@@ -241,12 +240,12 @@ impl Cam {
|
|||||||
let pct_slices = rendered_slices as f64 / total_slices as f64 * 100.;
|
let pct_slices = rendered_slices as f64 / total_slices as f64 * 100.;
|
||||||
let pct_pixels = rendered_pixels as f64 / (IMG_WIDTH * IMG_HEIGHT) as f64 * 100.;
|
let pct_pixels = rendered_pixels as f64 / (IMG_WIDTH * IMG_HEIGHT) as f64 * 100.;
|
||||||
stderr.write_all(format!("\x1b[1K\x1b[GRendering... {}/{} slices ({:.02}%), {:.02}% pixels", rendered_slices, total_slices, pct_slices, pct_pixels).as_bytes()).unwrap();
|
stderr.write_all(format!("\x1b[1K\x1b[GRendering... {}/{} slices ({:.02}%), {:.02}% pixels", rendered_slices, total_slices, pct_slices, pct_pixels).as_bytes()).unwrap();
|
||||||
stderr.flush();
|
stderr.flush().unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if REPORT_STATUS {
|
if REPORT_STATUS {
|
||||||
stderr.write_all(format!("\x1b[1K\x1b[GRendering... Done\n").as_bytes());
|
stderr.write_all(format!("\x1b[1K\x1b[GRendering... Done\n").as_bytes()).unwrap();
|
||||||
stderr.flush();
|
stderr.flush().unwrap();
|
||||||
}
|
}
|
||||||
}).unwrap();
|
}).unwrap();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user