1use rusterix::prelude::*;
2use std::path::Path;
3use std::time::Instant;
4use theframework::*;
5use vek::{Mat4, Vec2, Vec3, Vec4};
6
7fn main() {
8 let demo = ObjDemo::new();
9 let app = TheApp::new();
10
11 () = app.run(Box::new(demo));
12}
13
14pub struct ObjDemo {
17 camera: D3OrbitCamera,
18 scene: Scene,
19 assets: Assets,
20 start_time: Instant,
21}
22
23impl TheTrait for ObjDemo {
24 fn new() -> Self
25 where
26 Self: Sized,
27 {
28 let scene = Scene::from_static(
29 vec![Batch2D::from_rectangle(0.0, 0.0, 200.0, 200.0)],
30 vec![
31 Batch3D::from_obj(Path::new("examples/teapot.obj"))
32 .source(PixelSource::StaticTileIndex(0))
33 .repeat_mode(RepeatMode::RepeatXY)
34 .transform(Mat4::scaling_3d(Vec3::new(0.35, -0.35, 0.35)))
35 .with_computed_normals(),
36 ],
37 )
38 .lights(vec![
39 Light::new(LightType::Point)
40 .with_intensity(1.0)
41 .with_color([1.0, 1.0, 0.95])
42 .compile(),
43 ])
44 .background(Box::new(VGrayGradientShader::new()));
45
46 let assets = Assets::default().textures(vec![Tile::from_texture(Texture::from_image(
47 Path::new("images/logo.png"),
48 ))]);
49
50 let mut camera = D3OrbitCamera::new();
51 camera.set_parameter_f32("distance", 1.5);
52
53 Self {
54 camera,
55 scene,
56 start_time: Instant::now(),
57 assets,
58 }
59 }
60
61 fn draw(&mut self, pixels: &mut [u8], ctx: &mut TheContext) {
62 let _start = get_time();
63
64 let elapsed = self.start_time.elapsed().as_secs_f32() * 1.5;
66 self.scene.lights[0].position = Vec3::new(2.0 * elapsed.cos(), 0.8, 2.0 * elapsed.sin());
67
68 Rasterizer::setup(
70 None,
71 self.camera.view_matrix(),
72 self.camera
73 .projection_matrix(ctx.width as f32, ctx.height as f32),
74 )
75 .ambient(Vec4::broadcast(0.8))
76 .rasterize(
77 &mut self.scene,
78 pixels, ctx.width, ctx.height, 60, &self.assets,
83 );
84
85 let _stop = get_time();
86 }
88
89 fn hover(&mut self, x: f32, y: f32, ctx: &mut TheContext) -> bool {
91 self.camera.set_parameter_vec2(
92 "from_normalized",
93 Vec2::new(x / ctx.width as f32, y / ctx.height as f32),
94 );
95 true
96 }
97
98 fn update(&mut self, _ctx: &mut TheContext) -> bool {
100 true
101 }
102
103 fn window_title(&self) -> String {
104 "Rusterix OBJ Demo".to_string()
105 }
106}
107
108fn get_time() -> u128 {
109 #[cfg(target_arch = "wasm32")]
110 {
111 web_sys::window().unwrap().performance().unwrap().now() as u128
112 }
113 #[cfg(not(target_arch = "wasm32"))]
114 {
115 let stop = std::time::SystemTime::now()
116 .duration_since(std::time::UNIX_EPOCH)
117 .expect("Time went backwards");
118 stop.as_millis()
119 }
120}