mirror of
https://github.com/Mercantec-GHC/h5-projekt-mst.git
synced 2026-08-26 21:27:38 +02:00
172 lines
4.5 KiB
Rust
172 lines
4.5 KiB
Rust
use std::f64::consts::PI;
|
|
|
|
use obj::Obj;
|
|
|
|
use crate::{
|
|
m3x3::M3x3,
|
|
quats::RadianQuat,
|
|
tri2::Tri2,
|
|
tri3::Tri3,
|
|
v3::V3,
|
|
window::{Color, Renderer},
|
|
};
|
|
|
|
pub struct Scene {
|
|
tris: Vec<(Tri3, V3, Color)>,
|
|
}
|
|
|
|
impl Scene {
|
|
pub fn new() -> Self {
|
|
Self { tris: Vec::new() }
|
|
}
|
|
|
|
pub fn render(
|
|
&self,
|
|
r: &mut impl Renderer,
|
|
camera_pos: V3,
|
|
camera_rot: M3x3,
|
|
screen_rel_pos: V3,
|
|
) {
|
|
let mut indices_with_scores = self
|
|
.tris
|
|
.iter()
|
|
.enumerate()
|
|
.map(|(i, (tri, ..))| {
|
|
let mut score = (camera_pos - tri.middle()).len();
|
|
(i, score)
|
|
})
|
|
.rev()
|
|
.collect::<Vec<_>>();
|
|
|
|
indices_with_scores.sort_by(|a, b| b.1.total_cmp(&a.1));
|
|
|
|
for (i, _) in indices_with_scores {
|
|
let (tri3, normal, color) = &self.tris[i];
|
|
|
|
// if !(tri3.0.2 >= -1.0 && tri3.1.2 >= -1.0 && tri3.2.2 >= -1.0) {
|
|
// continue;
|
|
// }
|
|
|
|
if normal.dot(camera_pos - tri3.0) < 0.0 {
|
|
continue;
|
|
}
|
|
|
|
let light = V3(1.0, 1.0, -1.0);
|
|
|
|
let exposure = 1.5 - normal.angle(light) / PI;
|
|
|
|
let (red, green, blue) = color.rgb();
|
|
|
|
let color = Color::RGB(
|
|
(red as f64 * exposure).clamp(0.0, 255.0) as _,
|
|
(green as f64 * exposure).clamp(0.0, 255.0) as _,
|
|
(blue as f64 * exposure).clamp(0.0, 255.0) as _,
|
|
);
|
|
|
|
let tri2 = tri3.project_2d(camera_pos, camera_rot, screen_rel_pos);
|
|
|
|
r.draw_triangles(&[tri2], color);
|
|
// r.draw_line(tri2.0, tri2.1, Color::BLACK);
|
|
// r.draw_line(tri2.1, tri2.2, Color::BLACK);
|
|
// r.draw_line(tri2.2, tri2.0, Color::BLACK);
|
|
}
|
|
}
|
|
|
|
pub fn draw_model(&mut self, model: Model) {
|
|
self.tris.extend(model.tris());
|
|
}
|
|
|
|
pub fn draw_triangle(&mut self, tri: Tri3, color: Color) {
|
|
self.tris.push((tri, tri.normal(), color));
|
|
}
|
|
}
|
|
|
|
pub struct Model {
|
|
tris: Vec<(Tri3, V3, Color)>,
|
|
}
|
|
|
|
impl Model {
|
|
pub fn new() -> Self {
|
|
Self { tris: Vec::new() }
|
|
}
|
|
|
|
pub fn tris(&self) -> impl Iterator<Item = (Tri3, V3, Color)> {
|
|
self.tris.iter().copied()
|
|
}
|
|
|
|
pub fn translate(&mut self, offset: V3) -> &mut Self {
|
|
for tri in &mut self.tris {
|
|
tri.0 = tri.0.translate(offset);
|
|
}
|
|
self
|
|
}
|
|
|
|
pub fn rotate_by_m3x3(&mut self, rot: M3x3) -> &mut Self {
|
|
for tri in &mut self.tris {
|
|
tri.0 = tri.0.rotate_by_m3x3(rot);
|
|
tri.1 = tri.1.rotate_by_m3x3(rot);
|
|
}
|
|
self
|
|
}
|
|
|
|
pub fn rotate_by_quat(&mut self, rot: RadianQuat) -> &mut Self {
|
|
for tri in &mut self.tris {
|
|
tri.0 = tri.0.rotate_by_quat(rot);
|
|
tri.1 = tri.1.rotate_by_quat(rot);
|
|
}
|
|
self
|
|
}
|
|
|
|
pub fn scale(&mut self, scale: V3) -> &mut Self {
|
|
for tri in &mut self.tris {
|
|
tri.0 = tri.0.scale(scale);
|
|
}
|
|
self
|
|
}
|
|
|
|
pub fn add_tri(&mut self, tri: Tri3, color: Color) -> &mut Self {
|
|
self.tris.push((tri, tri.normal(), color));
|
|
self
|
|
}
|
|
|
|
pub fn add_obj(&mut self, obj: &Obj, color: Color) -> &mut Self {
|
|
// if our triangle definition convention is [0, 1, 2]
|
|
// obj's is [2, 1, 0].
|
|
//
|
|
// likewise, if our coordinate system is [x, y, z],
|
|
// obj's is [x, z, y].
|
|
|
|
let count = obj.indices.len() / 3;
|
|
for i in 0..count {
|
|
let v2 = obj.vertices[obj.indices[i * 3] as usize];
|
|
let v1 = obj.vertices[obj.indices[i * 3 + 1] as usize];
|
|
let v0 = obj.vertices[obj.indices[i * 3 + 2] as usize];
|
|
|
|
let tri = Tri3(
|
|
V3(
|
|
v0.position[0] as _,
|
|
v0.position[2] as _,
|
|
v0.position[1] as _,
|
|
),
|
|
V3(
|
|
v1.position[0] as _,
|
|
v1.position[2] as _,
|
|
v1.position[1] as _,
|
|
),
|
|
V3(
|
|
v2.position[0] as _,
|
|
v2.position[2] as _,
|
|
v2.position[1] as _,
|
|
),
|
|
);
|
|
|
|
let normal = V3(v0.normal[0] as _, v0.normal[2] as _, v0.normal[1] as _)
|
|
+ V3(v1.normal[0] as _, v1.normal[2] as _, v1.normal[1] as _)
|
|
+ V3(v2.normal[0] as _, v2.normal[2] as _, v2.normal[1] as _);
|
|
|
|
self.tris.push((tri, normal, color));
|
|
}
|
|
self
|
|
}
|
|
}
|