nefertiti/
nefertiti.rs

1use lumo::tracer::*;
2use lumo::*;
3
4// By CosmoWenmann (https://www.thingiverse.com/thing:3974391) licensed under CC BY-NC-SA 4.0
5const TEX_FILE: &str = "aem_aem21300_3dsl01_mo08-03_p_img.png";
6const NEFE_URL: &str = "https://cdn.thingiverse.com/assets/c7/e1/b6/f6/12/SPK_Nefertiti_Scan_FOIA_Response.zip";
7
8fn main() -> Result<(), Box<dyn std::error::Error>> {
9    let mut scene = Scene::default();
10
11    /* floor */
12    scene.add(Plane::new(
13        Vec3::NEG_Y,
14        Vec3::Y,
15        Material::diffuse(Texture::Solid(Color::BLACK))
16    ));
17
18    /* roof */
19    scene.add(Plane::new(
20        Vec3::Y,
21        Vec3::NEG_Y,
22        Material::diffuse(Texture::Solid(Color::BLACK))
23    ));
24
25    /* left wall */
26    scene.add(Plane::new(
27        Vec3::NEG_X,
28        Vec3::X,
29        Material::diffuse(Texture::Solid(Color::BLACK)),
30    ));
31
32    /* right wall */
33    scene.add(Plane::new(
34        Vec3::X,
35        Vec3::NEG_X,
36        Material::diffuse(Texture::Solid(Color::BLACK))
37    ));
38
39    /* front */
40    scene.add(Plane::new(
41        2.0 * Vec3::NEG_Z,
42        Vec3::Z,
43        Material::diffuse(Texture::Solid(Color::BLACK))
44    ));
45
46    /* back */
47    scene.add(Plane::new(
48        Vec3::Z,
49        Vec3::NEG_Z,
50        Material::diffuse(Texture::Solid(Color::BLACK))
51    ));
52
53    /* bust */
54    scene.add(
55        Cube::new(Material::metallic(
56            Texture::Solid(Color::new(61, 45, 36)),
57            0.0,
58        ))
59        .translate(-0.5, -0.5, -0.5)
60        .scale(0.45, 0.5, 0.45)
61        .translate(0.0, -0.75, -1.45),
62    );
63
64    /* statue */
65    if cfg!(debug_assertions) {
66	scene.add(
67            Cylinder::new(
68		0.6,
69		0.1,
70		Material::diffuse(Texture::Solid(Color::new(255, 0, 0))))
71		.translate(0.0, -0.5, -1.45)
72	);
73    } else {
74	scene.add(
75	    parser::mesh_from_url(
76                NEFE_URL,
77		Material::specular(
78                    Texture::Image(parser::texture_from_url(NEFE_URL, TEX_FILE)?),
79                    0.8
80                )
81            )?
82		.to_unit_size()
83		.to_origin()
84		.scale(0.5, 0.5, 0.5)
85		.rotate_x(-PI / 2.0)
86		.translate(0.0, -0.25, -1.45),
87	);
88    }
89
90    let xy_rect = Mat3::from_cols(
91        Vec3::ZERO,
92        Vec3::X,
93        Vec3::X + Vec3::Y,
94    );
95
96    let theta = PI / 4.0;
97
98    /* light */
99    let disk_towards = Vec3::new(-0.046, -0.192, -1.314);
100    let disk_dir = Vec3::new(-0.9132592442858147, 0.38194206881899756, -0.05342207528313975);
101
102    // left, w.r.t camera
103    scene.add_light(Disk::new(
104	disk_towards + 0.3 * disk_dir,
105	-disk_dir,
106	0.05,
107	Material::Light(Texture::Solid(30.0 * Color::WHITE))
108    ));
109
110    let right_disk_origin = Vec3::new(0.6, 0.15, -1.6);
111    scene.add_light(Disk::new(
112	right_disk_origin,
113	disk_towards + 0.28 * Vec3::X - right_disk_origin,
114	0.08,
115	Material::Light(Texture::Solid(20.0 * Color::WHITE))
116    ));
117
118    scene.add_light(Rectangle::new(
119        xy_rect,
120        Material::Light(Texture::Solid(2.0 * Color::WHITE)))
121                    .scale(0.4, 0.4, 1.0)
122                    .rotate_y(-theta)
123		    .rotate_axis(Vec3::new(theta.cos(), 0.0, theta.sin()), PI / 8.0)
124                    .translate(0.6, 0.2, -1.7)
125    );
126
127    // behind
128    scene.add_light(Rectangle::new(
129        xy_rect,
130        Material::Light(Texture::Solid(Color::WHITE)))
131                    .scale(0.3, 0.3, 1.0)
132                    .rotate_x(2.0 * PI - 2.0 * theta)
133                    .translate(-0.15, 0.5, -0.8)
134    );
135    scene.add_light(Rectangle::new(
136	xy_rect,
137	Material::Light(Texture::Solid(2.0 * Color::WHITE)))
138		    .scale(0.3, 0.3, 1.0)
139		    .rotate_x(PI)
140		    .translate(-0.1, 0.0, 0.0)
141    );
142
143    // above
144    scene.add_light(Rectangle::new(
145        xy_rect,
146        Material::Light(Texture::Solid(2.0 * Color::WHITE)))
147                    .scale(0.4, 0.4, 1.0)
148                    .rotate_x(PI / 2.0)
149                    .translate(-0.2, 0.5, -1.5)
150    );
151
152    let camera = if cfg!(debug_assertions) {
153	Camera::perspective(
154	    0.5 * Vec3::Z,
155	    Vec3::NEG_Z,
156	    Vec3::Y,
157	    90.0,
158            0.0,
159            0.0,
160	    1000,
161	    1000
162	)
163    } else {
164	Camera::orthographic(
165            Vec3::new(0.12, -0.23, -1.205),
166            Vec3::new(0.0, -0.26, -1.45),
167            Vec3::Y,
168            0.2,
169            0.0,
170            0.0,
171            641,
172            939,
173	)
174    };
175
176    let renderer = Renderer::new(scene, camera);
177    renderer.render().save("nefe.png")?;
178
179    Ok(())
180}