mirror of
https://github.com/Mercantec-GHC/h5-projekt-mst.git
synced 2026-08-27 05:37:39 +02:00
get rotated idiot
This commit is contained in:
parent
59bcd540fe
commit
57f201ca40
@ -1,4 +1,7 @@
|
|||||||
use crate::engine::math::{V2, V3};
|
use crate::engine::{
|
||||||
|
math::{V2, V3},
|
||||||
|
Triangle2,
|
||||||
|
};
|
||||||
use std::{marker::PhantomData, time::Duration};
|
use std::{marker::PhantomData, time::Duration};
|
||||||
|
|
||||||
use super::error::Error;
|
use super::error::Error;
|
||||||
@ -16,15 +19,17 @@ pub trait Renderer {
|
|||||||
fn draw_rect(&mut self, pos: V2, size: V2, color: Color);
|
fn draw_rect(&mut self, pos: V2, size: V2, color: Color);
|
||||||
fn draw_point(&mut self, pos: V2, color: Color);
|
fn draw_point(&mut self, pos: V2, color: Color);
|
||||||
fn draw_line(&mut self, from: V2, to: V2, color: Color);
|
fn draw_line(&mut self, from: V2, to: V2, color: Color);
|
||||||
|
fn draw_triangles(&mut self, triangles: &[Triangle2], color: Color);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub enum Color {
|
pub enum Color {
|
||||||
HEX(u32),
|
Hex(u32),
|
||||||
WHITE,
|
White,
|
||||||
GREEN,
|
Green,
|
||||||
RED,
|
Red,
|
||||||
CYAN,
|
Cyan,
|
||||||
|
Black,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Event {
|
pub enum Event {
|
||||||
|
|||||||
@ -38,6 +38,11 @@ impl V3 {
|
|||||||
pub fn map<F: Fn(f64) -> f64>(&self, func: F) -> Self {
|
pub fn map<F: Fn(f64) -> f64>(&self, func: F) -> Self {
|
||||||
V3(func(self.0), func(self.1), func(self.2))
|
V3(func(self.0), func(self.1), func(self.2))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn rotate(&self, rot: V3) -> Self {
|
||||||
|
M3x3::new_rotate_z(rot.2)
|
||||||
|
* (M3x3::new_rotate_y(rot.1) * (M3x3::new_rotate_x(rot.0) * *self))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Add for V3 {
|
impl Add for V3 {
|
||||||
@ -94,6 +99,79 @@ impl MulAssign<f64> for V3 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
|
pub struct Triangle2(pub V2, pub V2, pub V2);
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
|
pub struct Triangle3(pub V3, pub V3, pub V3);
|
||||||
|
|
||||||
|
impl Triangle3 {
|
||||||
|
pub fn normal(&self) -> V3 {
|
||||||
|
(self.1 - self.0).cross(self.2 - self.1)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn translate(&self, offset: V3) -> Self {
|
||||||
|
Self(self.0 + offset, self.1 + offset, self.2 + offset)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn project_2d(&self) -> Triangle2 {
|
||||||
|
Triangle2(
|
||||||
|
self.0.project_2d(),
|
||||||
|
self.1.project_2d(),
|
||||||
|
self.2.project_2d(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn middle(&self) -> V3 {
|
||||||
|
(self.0 + self.1 + self.2).map(|v| v / 3.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct M3x3([f64; 9]);
|
||||||
|
|
||||||
|
impl M3x3 {
|
||||||
|
#[rustfmt::skip]
|
||||||
|
pub fn new_rotate_x(angle: f64) -> Self {
|
||||||
|
Self([
|
||||||
|
1.0, 0.0, 0.0,
|
||||||
|
0.0, f64::cos(angle), -f64::sin(angle),
|
||||||
|
0.0, f64::sin(angle), f64::cos(angle),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
pub fn new_rotate_y(angle: f64) -> Self {
|
||||||
|
Self([
|
||||||
|
f64::cos(angle), 0.0, f64::sin(angle),
|
||||||
|
0.0, 1.0, 0.0,
|
||||||
|
-f64::sin(angle), 0.0, f64::cos(angle),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
pub fn new_rotate_z(angle: f64) -> Self {
|
||||||
|
Self([
|
||||||
|
f64::cos(angle), -f64::sin(angle), 0.0,
|
||||||
|
f64::sin(angle), f64::cos(angle), 0.0,
|
||||||
|
0.0, 0.0, 1.0,
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Mul<V3> for M3x3 {
|
||||||
|
type Output = V3;
|
||||||
|
|
||||||
|
fn mul(self, rhs: V3) -> Self::Output {
|
||||||
|
let V3(x, y, z) = rhs;
|
||||||
|
let [xx, xy, xz, yx, yy, yz, zx, zy, zz] = self.0;
|
||||||
|
V3(
|
||||||
|
x * xx + y * xy + z * xz,
|
||||||
|
x * yx + y * yy + z * yz,
|
||||||
|
x * zx + y * zy + z * zz,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
@ -1,43 +1,18 @@
|
|||||||
use crate::engine::{game::Renderer, Color, Shape, V2, V3};
|
use crate::engine::{game::Renderer, Color, Shape, Triangle2, Triangle3, V2, V3};
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
|
||||||
pub struct Triangle2(pub V2, pub V2, pub V2);
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
|
||||||
pub struct Triangle3(pub V3, pub V3, pub V3);
|
|
||||||
|
|
||||||
impl Triangle3 {
|
|
||||||
pub fn normal_vector(&self) -> V3 {
|
|
||||||
(self.1 - self.0).cross(self.2 - self.1)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn translate(&self, offset: V3) -> Self {
|
|
||||||
Self(self.0 + offset, self.1 + offset, self.2 + offset)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn project_2d(&self) -> Triangle2 {
|
|
||||||
Triangle2(
|
|
||||||
self.0.project_2d(),
|
|
||||||
self.1.project_2d(),
|
|
||||||
self.2.project_2d(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn middle(&self) -> V3 {
|
|
||||||
let m1 = self.0 + (self.1 - self.0).map(|v| v / 2.0);
|
|
||||||
m1 + (self.2 - m1).map(|v| v / 2.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct R3d<'r, R: Renderer> {
|
pub struct R3d<'r, R: Renderer> {
|
||||||
r: &'r mut R,
|
r: &'r mut R,
|
||||||
|
triangle_buffer: Vec<Triangle2>,
|
||||||
}
|
}
|
||||||
|
|
||||||
static CAMERA_POS: V3 = V3(0.0, 0.0, -1.0);
|
static CAMERA_POS: V3 = V3(0.0, 0.0, -1.0);
|
||||||
|
|
||||||
impl<'r, R: Renderer> R3d<'r, R> {
|
impl<'r, R: Renderer> R3d<'r, R> {
|
||||||
pub fn new(r: &'r mut R) -> Self {
|
pub fn new(r: &'r mut R) -> Self {
|
||||||
Self { r }
|
Self {
|
||||||
|
r,
|
||||||
|
triangle_buffer: Vec::new(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_line(&mut self, from: V3, to: V3, color: Color) {
|
pub fn draw_line(&mut self, from: V3, to: V3, color: Color) {
|
||||||
@ -53,25 +28,45 @@ impl<'r, R: Renderer> R3d<'r, R> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_shape(&mut self, pos: V3, shape: &Shape, outline_color: Color, fill_color: Color) {
|
pub fn draw_shape(&mut self, pos: V3, shape: &Shape, outline_color: Color, fill_color: Color) {
|
||||||
|
self.triangle_buffer.clear();
|
||||||
|
self.triangle_buffer
|
||||||
|
.extend(shape.faces().map(|tri| tri.translate(pos).project_2d()));
|
||||||
|
|
||||||
|
self.r.draw_triangles(&self.triangle_buffer, fill_color);
|
||||||
|
|
||||||
for face in shape.faces() {
|
for face in shape.faces() {
|
||||||
let normal_vector = face.normal_vector();
|
if face.normal().dot(face.0 - CAMERA_POS + pos) >= 0.0 {
|
||||||
let pxyz = face.middle() + normal_vector;
|
continue;
|
||||||
self.draw_line(face.middle() + pos, pxyz + pos, Color::RED);
|
}
|
||||||
|
// let pxyz = face.middle() + face.normal();
|
||||||
// self.draw_line(
|
// self.draw_line(
|
||||||
// face.middle() + pos,
|
// face.middle() + pos,
|
||||||
// face.middle() + face.0.unit() * 0.1 + pos,
|
// face.middle() + (face.1 - face.0).unit() * 0.02 + pos,
|
||||||
// Color::HEX(0x33dd33),
|
// Color::HEX(0xffaa00),
|
||||||
// );
|
// );
|
||||||
|
// self.draw_line(
|
||||||
|
// face.middle() + pos,
|
||||||
|
// face.middle() + (face.2 - face.1).unit() * 0.02 + pos,
|
||||||
|
// Color::HEX(0x00ffaa),
|
||||||
|
// );
|
||||||
|
// self.draw_line(
|
||||||
|
// face.middle() + pos,
|
||||||
|
// face.middle() + (face.0 - face.2).unit() * 0.02 + pos,
|
||||||
|
// Color::HEX(0xaa00ff),
|
||||||
|
// );
|
||||||
|
// self.draw_line(face.middle() + pos, pxyz + pos, Color::HEX(0xffffff));
|
||||||
|
|
||||||
let bingbongvector = face.0 - CAMERA_POS + pos;
|
// self.draw_triangle(face.translate(pos - CAMERA_POS), outline_color);
|
||||||
if normal_vector.dot(bingbongvector) < 0.0 {
|
self.r.draw_line(
|
||||||
self.draw_triangle(face.translate(pos - CAMERA_POS), outline_color);
|
(face.0 + pos).project_2d(),
|
||||||
|
(face.1 + pos).project_2d(),
|
||||||
|
outline_color,
|
||||||
|
);
|
||||||
|
self.r.draw_line(
|
||||||
|
(face.2 + pos).project_2d(),
|
||||||
|
(face.0 + pos).project_2d(),
|
||||||
|
outline_color,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// for vertex in shape.vertices() {
|
|
||||||
// self.r
|
|
||||||
// .draw_point((vertex + pos).project_2d(), outline_color);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,9 +3,9 @@ use std::time::{Duration, Instant};
|
|||||||
use sdl3::{
|
use sdl3::{
|
||||||
event::Event,
|
event::Event,
|
||||||
keyboard::Keycode,
|
keyboard::Keycode,
|
||||||
pixels::{Color as SdlColor, PixelFormat},
|
pixels::{Color as SdlColor, FColor, PixelFormat},
|
||||||
rect::Point,
|
rect::Point,
|
||||||
render::{Canvas, FPoint, FRect},
|
render::{Canvas, FPoint, FRect, Vertex, VertexIndices},
|
||||||
video::Window,
|
video::Window,
|
||||||
Sdl, VideoSubsystem,
|
Sdl, VideoSubsystem,
|
||||||
};
|
};
|
||||||
@ -14,7 +14,7 @@ use crate::engine::{
|
|||||||
error::Error,
|
error::Error,
|
||||||
game,
|
game,
|
||||||
math::{V2, V3},
|
math::{V2, V3},
|
||||||
Color, Renderer,
|
Color, Renderer, Triangle2,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub static WIDTH: f64 = 1280.0;
|
pub static WIDTH: f64 = 1280.0;
|
||||||
@ -137,6 +137,23 @@ impl Renderer for SdlIo {
|
|||||||
.draw_line(self.point_w2s(from), self.point_w2s(to))
|
.draw_line(self.point_w2s(from), self.point_w2s(to))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn draw_triangles(&mut self, triangles: &[Triangle2], color: Color) {
|
||||||
|
let vertices = triangles
|
||||||
|
.iter()
|
||||||
|
.flat_map(|t| [t.0, t.1, t.2])
|
||||||
|
.map(|p| self.point_w2s(p))
|
||||||
|
.map(|p| Vertex {
|
||||||
|
position: p.into(),
|
||||||
|
color: color.into(),
|
||||||
|
tex_coord: FPoint::new(0.0, 0.0),
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
self.canvas
|
||||||
|
.render_geometry(&vertices, None, VertexIndices::Sequential)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<V2> for FPoint {
|
impl From<V2> for FPoint {
|
||||||
@ -148,11 +165,22 @@ impl From<V2> for FPoint {
|
|||||||
impl From<Color> for SdlColor {
|
impl From<Color> for SdlColor {
|
||||||
fn from(value: Color) -> Self {
|
fn from(value: Color) -> Self {
|
||||||
match value {
|
match value {
|
||||||
Color::HEX(v) => SdlColor::from_u32(&PixelFormat::BGR24, v),
|
Color::Hex(v) => SdlColor::RGB(
|
||||||
Color::WHITE => SdlColor::WHITE,
|
((v >> 16) & 0xff) as u8,
|
||||||
Color::GREEN => SdlColor::GREEN,
|
((v >> 8) & 0xff) as u8,
|
||||||
Color::RED => SdlColor::RED,
|
(v & 0xff) as u8,
|
||||||
Color::CYAN => SdlColor::CYAN,
|
),
|
||||||
|
Color::White => SdlColor::WHITE,
|
||||||
|
Color::Green => SdlColor::GREEN,
|
||||||
|
Color::Red => SdlColor::RED,
|
||||||
|
Color::Cyan => SdlColor::CYAN,
|
||||||
|
Color::Black => SdlColor::BLACK,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<Color> for FColor {
|
||||||
|
fn from(value: Color) -> Self {
|
||||||
|
FColor::from(<Color as Into<SdlColor>>::into(value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -54,10 +54,9 @@ static PLANE_VERTICES: [(i8, i8, i8); 4] = [
|
|||||||
(1, 0, 0),
|
(1, 0, 0),
|
||||||
(1, 0, 1),
|
(1, 0, 1),
|
||||||
];
|
];
|
||||||
static PLANE_EDGES: [(usize, usize); 5] = [
|
static PLANE_EDGES: [(usize, usize); 4] = [
|
||||||
//
|
//
|
||||||
(0, 1),
|
(0, 1),
|
||||||
(1, 2),
|
|
||||||
(2, 3),
|
(2, 3),
|
||||||
(0, 2),
|
(0, 2),
|
||||||
(1, 3),
|
(1, 3),
|
||||||
@ -101,12 +100,33 @@ impl Shape {
|
|||||||
self.vertices.iter().cloned()
|
self.vertices.iter().cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn edges<'a>(&'a self) -> impl Iterator<Item = (V3, V3)> + 'a {
|
||||||
|
let verts: &[V3] = &self.vertices;
|
||||||
|
self.edges.iter().map(|(a, b)| (verts[*a], verts[*b]))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn faces<'a>(&'a self) -> impl Iterator<Item = Triangle3> + 'a {
|
pub fn faces<'a>(&'a self) -> impl Iterator<Item = Triangle3> + 'a {
|
||||||
let verts: &[V3] = &self.vertices;
|
let verts: &[V3] = &self.vertices;
|
||||||
self.faces
|
self.faces
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(a, b, c)| Triangle3(verts[*a], verts[*b], verts[*c]))
|
.map(|(a, b, c)| Triangle3(verts[*a], verts[*b], verts[*c]))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn rotate(&self, rot: V3) -> Self {
|
||||||
|
Self {
|
||||||
|
vertices: self.vertices.iter().map(|v| v.rotate(rot)).collect(),
|
||||||
|
edges: self.edges.clone(),
|
||||||
|
faces: self.faces.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn translate(&self, trans: V3) -> Self {
|
||||||
|
Self {
|
||||||
|
vertices: self.vertices.iter().map(|v| *v + trans).collect(),
|
||||||
|
edges: self.edges.clone(),
|
||||||
|
faces: self.faces.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn scale_i8_vertex(p: (i8, i8, i8), s: &V3) -> V3 {
|
fn scale_i8_vertex(p: (i8, i8, i8), s: &V3) -> V3 {
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use std::time::Duration;
|
use std::{f64, time::Duration};
|
||||||
|
|
||||||
use crate::engine::{Color, R3d, Shape, Triangle3, V3};
|
use crate::engine::{Color, R3d, Shape, V3};
|
||||||
|
|
||||||
mod engine;
|
mod engine;
|
||||||
|
|
||||||
@ -15,8 +15,8 @@ impl<R: engine::Renderer> engine::Object<R> for MyObject {
|
|||||||
match self {
|
match self {
|
||||||
MyObject::Player { pos, vel } => {
|
MyObject::Player { pos, vel } => {
|
||||||
*pos += *vel * delta_time.as_secs_f64();
|
*pos += *vel * delta_time.as_secs_f64();
|
||||||
if pos.0 >= 1.0 {
|
if pos.0 >= 2.1 {
|
||||||
pos.0 = -1.0;
|
pos.0 = -2.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -32,8 +32,8 @@ impl<R: engine::Renderer> engine::Object<R> for MyObject {
|
|||||||
r3d.draw_shape(
|
r3d.draw_shape(
|
||||||
V3(x as f64 * 0.1, -0.5, z as f64 * 0.1),
|
V3(x as f64 * 0.1, -0.5, z as f64 * 0.1),
|
||||||
&Shape::new_plane(V3(0.1, 0.0, 0.1)),
|
&Shape::new_plane(V3(0.1, 0.0, 0.1)),
|
||||||
Color::CYAN,
|
Color::Cyan,
|
||||||
Color::WHITE,
|
Color::Black,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -41,14 +41,16 @@ impl<R: engine::Renderer> engine::Object<R> for MyObject {
|
|||||||
r3d.draw_shape(
|
r3d.draw_shape(
|
||||||
*pos + V3(0.0, 0.2, 0.0),
|
*pos + V3(0.0, 0.2, 0.0),
|
||||||
&Shape::new_cube(V3(0.2, 0.1, 0.2)),
|
&Shape::new_cube(V3(0.2, 0.1, 0.2)),
|
||||||
Color::GREEN,
|
Color::Green,
|
||||||
Color::WHITE,
|
Color::Black,
|
||||||
);
|
);
|
||||||
r3d.draw_shape(
|
r3d.draw_shape(
|
||||||
*pos + V3(-0.4, -0.2, 0.0),
|
*pos + V3(-0.8, -0.2, 0.0),
|
||||||
&Shape::new_cube(V3(0.2, 0.2, 0.2)),
|
&Shape::new_cube(V3(0.2, 0.2, 0.2))
|
||||||
Color::GREEN,
|
.translate(V3(-0.1, -0.1, -0.1))
|
||||||
Color::WHITE,
|
.rotate(V3(pos.0 * 5.0, pos.0 * 5.0, pos.0 * 5.0)),
|
||||||
|
Color::Green,
|
||||||
|
Color::Black,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -60,7 +62,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
let mut game = engine::Game::<engine::SdlIo, MyObject>::new()?;
|
let mut game = engine::Game::<engine::SdlIo, MyObject>::new()?;
|
||||||
|
|
||||||
let player = MyObject::Player {
|
let player = MyObject::Player {
|
||||||
pos: V3(0.0, -0.1, 0.0),
|
pos: V3(-1.0, -0.1, 0.0),
|
||||||
vel: V3(0.4, 0.0, 0.0),
|
vel: V3(0.4, 0.0, 0.0),
|
||||||
};
|
};
|
||||||
game.spawn(player);
|
game.spawn(player);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user