use std::{env, time::Duration};
use nalgebra::{Vector3, Rotation3};
use clay::{
prelude::*,
shape::*,
material::*,
object::*,
scene::{ListScene, GradientBackground as GradBg},
view::ProjectionView,
process::{create_renderer, create_default_postproc},
};
use clay_viewer::{Window, Motion};
use clay_utils::{args, FrameCounter};
type MyObject = Covered<Sphere, Colored<Diffuse>>;
type MyScene = ListScene<MyObject, GradBg>;
type MyView = ProjectionView;
fn main() -> clay::Result<()> {
let context = args::parse(env::args())?;
let dims = (1280, 800);
let mut scene = ListScene::new(GradBg::new(
Vector3::new(1.0, 1.0, 1.0), Vector3::new(0.0, 0.0, 0.0),
Vector3::new(0.0, 0.0, 1.0),
));
scene.add(
Sphere::new(0.75, Vector3::new(-0.75, 0.0, 0.0))
.cover(Diffuse {}.color_with(Vector3::new(0.4, 1.0, 0.4)))
);
scene.add(
Sphere::new(1.0, Vector3::new(1.0, 0.0, 0.0))
.cover(Diffuse {}.color_with(Vector3::new(0.4, 0.4, 1.0)))
);
let view = ProjectionView::new(
Vector3::new(0.25, -3.0, 0.0),
Rotation3::face_towards(&-Vector3::new(0.0, 1.0, 0.0), &Vector3::z_axis()),
);
let mut renderer = create_renderer::<MyScene, MyView>().build(dims, scene, view)?;
let (mut worker, _) = renderer.create_worker(&context)?;
let (mut postproc, _) = create_default_postproc().collect()?
.build_default(&context, dims)?;
let mut window = Window::new(dims)?;
window.set_capture_mode(true);
let mut motion = Motion::new(renderer.view.pos, renderer.view.ori.clone());
let mut fcnt = FrameCounter::new_with_log(Duration::from_secs(2));
while !window.poll_with_handler(&mut motion)? {
let n = worker.run_for(Duration::from_millis(20))?;
postproc.process_one(&worker.data().buffer())?;
postproc.make_image()?;
window.draw(&postproc.image())?;
let dt = window.step_frame();
if motion.was_updated() {
worker.data_mut().buffer_mut().clear()?;
motion.step(dt);
renderer.view.update(motion.pos(), motion.ori());
renderer.view.fov = motion.fov;
renderer.update_data(&context, worker.data_mut())?;
}
fcnt.step_frame(dt, n);
}
Ok(())
}