mod app;
use app::*;
use monstertruck_gpu::*;
use monstertruck_meshing::prelude::*;
use monstertruck_modeling::*;
use monstertruck_render::*;
use std::f64::consts::PI;
use std::sync::Arc;
const N: usize = 5;
const BACKGROUND: [f64; 4] = [45.0 / 255.0, 36.0 / 255.0, 42.0 / 255.0, 1.0];
const BOXCOLOR: [f64; 4] = [208.0 / 255.0, 176.0 / 255.0, 107.0 / 255.0, 1.0];
struct MyApp {
scene: WindowScene,
instances: Vec<PolygonInstance>,
matrices: Vec<Matrix4>,
}
#[async_trait(?Send)]
impl App for MyApp {
async fn init(window: Arc<winit::window::Window>) -> MyApp {
let side_length = (N + 1) as f64 * 1.5;
let camera_dist = side_length / 2.0 / (PI / 8.0).tan();
let a = side_length / 2.0;
let b = camera_dist / 2.0;
let sample_count = 4;
let scene_desc = WindowSceneDescriptor {
studio: StudioConfig {
camera: Camera {
matrix: Matrix4::from_translation(camera_dist * Vector3::unit_z()),
method: ProjectionMethod::perspective(Rad(PI / 4.0)),
near_clip: 0.1,
far_clip: 100.0,
},
lights: vec![
Light {
position: Point3::new(-a, -a, b),
color: Vector3::new(0.5, 0.5, 0.5),
light_type: LightType::Point,
},
Light {
position: Point3::new(-a, a, b),
color: Vector3::new(0.5, 0.5, 0.5),
light_type: LightType::Point,
},
Light {
position: Point3::new(a, -a, b),
color: Vector3::new(0.5, 0.5, 0.5),
light_type: LightType::Point,
},
Light {
position: Point3::new(a, a, b),
color: Vector3::new(0.5, 0.5, 0.5),
light_type: LightType::Point,
},
],
background: wgpu::Color {
r: BACKGROUND[0],
g: BACKGROUND[1],
b: BACKGROUND[2],
a: BACKGROUND[3],
},
},
backend_buffer: BackendBufferConfig {
sample_count,
..Default::default()
},
};
let mut scene = WindowScene::from_window(window, &scene_desc).await;
let v = builder::vertex(Point3::new(-0.5, -0.5, -0.5));
let e = builder::extrude(&v, Vector3::unit_x());
let f = builder::extrude(&e, Vector3::unit_y());
let cube: Solid = builder::extrude(&f, Vector3::unit_z());
let mesh = cube.triangulation(0.01).to_polygon();
let instance: PolygonInstance = scene
.instance_creator()
.create_instance(&mesh, &Default::default());
let mut matrices = Vec::new();
let instances: Vec<_> = (0..N)
.flat_map(move |i| (0..N).map(move |j| (i, j)))
.map(|(i, j)| {
let mut instance = instance.clone_instance();
let (s, t) = (i as f64 / (N - 1) as f64, j as f64 / (N - 1) as f64);
let matrix = Matrix4::from_translation(Vector3::new(
1.5 * (i + 1) as f64 - side_length / 2.0,
1.5 * (j + 1) as f64 - side_length / 2.0,
0.0,
));
matrices.push(matrix);
*instance.instance_state_mut() = PolygonState {
matrix,
material: Material {
albedo: Vector4::from(BOXCOLOR),
reflectance: s,
roughness: t,
ambient_ratio: 0.02,
background_ratio: 0.0,
alpha_blend: false,
},
..Default::default()
};
instance
})
.collect();
instances.iter().for_each(|shape| {
scene.add_object(shape);
});
MyApp {
scene,
instances,
matrices,
}
}
fn render(&mut self) {
let time = self.scene.elapsed().as_secs_f64();
for (i, shape) in self.instances.iter_mut().enumerate() {
let axis = if i % 2 == 0 {
(-1.0_f64).powi(i as i32 / 2) * Vector3::unit_y()
} else {
-(-1.0_f64).powi(i as i32 / 2) * Vector3::unit_x()
};
shape.instance_state_mut().matrix =
self.matrices[i] * Matrix4::from_axis_angle(axis, Rad(time * PI / 2.0));
self.scene.update_bind_group(shape);
}
self.scene.render_frame();
}
}
fn main() { MyApp::run() }