mirror of
https://github.com/Mercantec-GHC/h5-projekt-mst.git
synced 2026-08-27 05:37:39 +02:00
fix camera translation
This commit is contained in:
parent
dad94f7e8c
commit
0a8019aded
@ -1,4 +1,3 @@
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
skate_slope::game::game_main()
|
||||
skate_slope::editor::editor_main()
|
||||
}
|
||||
|
||||
@ -1,34 +1,25 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use std::{
|
||||
collections::HashSet,
|
||||
f64::consts::PI,
|
||||
sync::{Arc, Mutex},
|
||||
time::Duration,
|
||||
};
|
||||
use std::{collections::HashSet, time::Duration};
|
||||
|
||||
use crate::{
|
||||
engine::{Color, Key, Renderer, Scene, Shape, V3},
|
||||
event_queue::EventQueue,
|
||||
vermiparous::Server,
|
||||
};
|
||||
use crate::engine::{Color, Key, Renderer, Scene, Shape, V3};
|
||||
|
||||
use crate::engine;
|
||||
|
||||
struct Game {
|
||||
struct Editor {
|
||||
objects: Vec<Object>,
|
||||
next_object_id: u32,
|
||||
event_queue: Arc<Mutex<EventQueue>>,
|
||||
keys_pressed: HashSet<Key>,
|
||||
camera_pos: V3,
|
||||
}
|
||||
|
||||
impl Game {
|
||||
fn new(event_queue: Arc<Mutex<EventQueue>>) -> Self {
|
||||
impl Editor {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
objects: Vec::new(),
|
||||
next_object_id: 0,
|
||||
event_queue,
|
||||
keys_pressed: HashSet::new(),
|
||||
camera_pos: V3(0.0, 0.0, -1.0),
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,34 +42,16 @@ impl Game {
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Renderer> engine::Game<R> for Game {
|
||||
impl<R: Renderer> engine::Game<R> for Editor {
|
||||
fn update(&mut self, delta_time: Duration) {
|
||||
for object in &mut self.objects {
|
||||
if self.keys_pressed.contains(&Key::Left) == self.keys_pressed.contains(&Key::Right) {
|
||||
if let ObjectKind::SkateBoard { pivot_deg, .. } = &mut object.kind {
|
||||
let decay_rate = 1.0 - (2.0 * delta_time.as_secs_f64());
|
||||
*pivot_deg *= decay_rate;
|
||||
}
|
||||
}
|
||||
if self.keys_pressed.contains(&Key::Left) {
|
||||
if let ObjectKind::SkateBoard { pivot_deg, .. } = &mut object.kind {
|
||||
*pivot_deg -= 18.0 * delta_time.as_secs_f64();
|
||||
if *pivot_deg < -12.5 {
|
||||
*pivot_deg = -12.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
if self.keys_pressed.contains(&Key::Right) {
|
||||
if let ObjectKind::SkateBoard { pivot_deg, .. } = &mut object.kind {
|
||||
*pivot_deg += 18.0 * delta_time.as_secs_f64();
|
||||
if *pivot_deg > 12.5 {
|
||||
*pivot_deg = 12.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object.update(delta_time);
|
||||
}
|
||||
if self.keys_pressed.contains(&Key::Left) {
|
||||
self.camera_pos.0 += delta_time.as_secs_f64() * 1.0;
|
||||
} else if self.keys_pressed.contains(&Key::Right) {
|
||||
self.camera_pos.0 -= delta_time.as_secs_f64() * 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
fn render(&mut self, r: &mut R) {
|
||||
@ -86,7 +59,7 @@ impl<R: Renderer> engine::Game<R> for Game {
|
||||
for object in &self.objects {
|
||||
object.render(&mut scene);
|
||||
}
|
||||
scene.render(r, V3(0.0, 0.0, -1.0));
|
||||
scene.render(r, self.camera_pos);
|
||||
}
|
||||
|
||||
fn event(&mut self, event: engine::Event) {
|
||||
@ -103,26 +76,7 @@ struct Object {
|
||||
}
|
||||
|
||||
enum ObjectKind {
|
||||
SkateBoard {
|
||||
pos: V3,
|
||||
vel: V3,
|
||||
rot: V3,
|
||||
nyoom_factor: f64,
|
||||
pivot_deg: f64,
|
||||
},
|
||||
Obstacle {
|
||||
pos: V3,
|
||||
vel: V3,
|
||||
},
|
||||
Ground {
|
||||
original_pos: V3,
|
||||
pos: V3,
|
||||
vel: V3,
|
||||
rot: V3,
|
||||
grid_item_size: f64,
|
||||
grid_width: i32,
|
||||
grid_depth: i32,
|
||||
},
|
||||
Box { pos: V3, vel: V3 },
|
||||
}
|
||||
|
||||
struct ShapeGroupShape {
|
||||
@ -169,232 +123,43 @@ impl ShapeGroup {
|
||||
impl Object {
|
||||
fn update(&mut self, delta_time: Duration) {
|
||||
match &mut self.kind {
|
||||
ObjectKind::SkateBoard {
|
||||
pos,
|
||||
vel,
|
||||
nyoom_factor,
|
||||
pivot_deg: pivot_factor,
|
||||
..
|
||||
} => {
|
||||
vel.0 = *pivot_factor * delta_time.as_secs_f64();
|
||||
*pos += *vel * delta_time.as_secs_f64();
|
||||
*nyoom_factor += 16.0 * delta_time.as_secs_f64();
|
||||
|
||||
// rot.0 += delta_time.as_secs_f64() * PI * 1.0;
|
||||
// rot.1 += delta_time.as_secs_f64() * PI * 0.2;
|
||||
// rot.2 += delta_time.as_secs_f64() * PI * 2.0;
|
||||
}
|
||||
ObjectKind::Obstacle { pos, vel } => {
|
||||
*pos += *vel * delta_time.as_secs_f64();
|
||||
}
|
||||
ObjectKind::Ground {
|
||||
pos,
|
||||
vel,
|
||||
grid_depth,
|
||||
grid_item_size,
|
||||
original_pos,
|
||||
..
|
||||
} => {
|
||||
*pos += *vel * delta_time.as_secs_f64();
|
||||
*vel += V3(vel.0, vel.1, vel.0 - 0.01 * delta_time.as_secs_f64());
|
||||
if pos.2 <= original_pos.2 - *grid_depth as f64 * *grid_item_size {
|
||||
pos.2 += *grid_depth as f64 * *grid_item_size
|
||||
}
|
||||
}
|
||||
ObjectKind::Box { pos, vel } => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn render(&self, scene: &mut Scene) {
|
||||
match self.kind {
|
||||
ObjectKind::SkateBoard {
|
||||
pos,
|
||||
rot,
|
||||
nyoom_factor,
|
||||
pivot_deg,
|
||||
..
|
||||
} => {
|
||||
let board_size = V3(0.175, 0.005, 0.05);
|
||||
let trucks = {
|
||||
let anchor_size = V3(0.005, 0.01, 0.005);
|
||||
let anchor_y = -anchor_size.1 - board_size.1 * 0.5;
|
||||
let pivot = vec![
|
||||
ShapeGroupShape {
|
||||
shape: Shape::new_cube(anchor_size),
|
||||
offset: V3(
|
||||
anchor_size.0 * -0.5 + board_size.0 * 0.4,
|
||||
anchor_y,
|
||||
anchor_size.2 * -0.5,
|
||||
),
|
||||
},
|
||||
ShapeGroupShape {
|
||||
shape: Shape::new_cube(anchor_size),
|
||||
offset: V3(
|
||||
anchor_size.0 * -0.5 - board_size.0 * 0.4,
|
||||
anchor_y,
|
||||
anchor_size.2 * -0.5,
|
||||
),
|
||||
},
|
||||
];
|
||||
let wheel_rail_size = V3(anchor_size.0, anchor_size.0, board_size.2 * 0.8);
|
||||
let wheel_rail_y = anchor_y - wheel_rail_size.1;
|
||||
let wheel_rail = vec![
|
||||
ShapeGroupShape {
|
||||
shape: Shape::new_cube(wheel_rail_size),
|
||||
offset: V3(
|
||||
wheel_rail_size.0 * -0.5 + board_size.0 * 0.4,
|
||||
wheel_rail_y,
|
||||
wheel_rail_size.2 * -0.5,
|
||||
),
|
||||
},
|
||||
ShapeGroupShape {
|
||||
shape: Shape::new_cube(wheel_rail_size),
|
||||
offset: V3(
|
||||
wheel_rail_size.0 * -0.5 - board_size.0 * 0.4,
|
||||
wheel_rail_y,
|
||||
wheel_rail_size.2 * -0.5,
|
||||
),
|
||||
},
|
||||
];
|
||||
let wheel_size = V3(0.01, 0.01, 0.0025);
|
||||
let wheel_y = wheel_rail_y - wheel_size.1 * 0.25;
|
||||
let wheel_rot = V3(0.0, 0.0, nyoom_factor);
|
||||
let wheel_rot_trans = V3(0.5, 0.5, 0.0);
|
||||
let wheel = vec![
|
||||
ShapeGroupShape {
|
||||
shape: Shape::new_cube(wheel_size)
|
||||
.translate(wheel_size * wheel_rot_trans * -1.0)
|
||||
.rotate(wheel_rot)
|
||||
.translate(wheel_size * wheel_rot_trans),
|
||||
offset: V3(
|
||||
wheel_size.0 * -0.5 + board_size.0 * 0.4,
|
||||
wheel_y,
|
||||
wheel_rail_size.2 * -0.5 - wheel_size.2,
|
||||
),
|
||||
},
|
||||
ShapeGroupShape {
|
||||
shape: Shape::new_cube(wheel_size)
|
||||
.translate(wheel_size * wheel_rot_trans * -1.0)
|
||||
.rotate(wheel_rot)
|
||||
.translate(wheel_size * wheel_rot_trans),
|
||||
|
||||
offset: V3(
|
||||
wheel_size.0 * -0.5 - board_size.0 * 0.4,
|
||||
wheel_y,
|
||||
wheel_rail_size.2 * -0.5 - wheel_size.2,
|
||||
),
|
||||
},
|
||||
ShapeGroupShape {
|
||||
shape: Shape::new_cube(wheel_size)
|
||||
.translate(wheel_size * wheel_rot_trans * -1.0)
|
||||
.rotate(wheel_rot)
|
||||
.translate(wheel_size * wheel_rot_trans),
|
||||
|
||||
offset: V3(
|
||||
wheel_size.0 * -0.5 + board_size.0 * 0.4,
|
||||
wheel_y,
|
||||
wheel_rail_size.2 * 0.5,
|
||||
),
|
||||
},
|
||||
ShapeGroupShape {
|
||||
shape: Shape::new_cube(wheel_size)
|
||||
.translate(wheel_size * wheel_rot_trans * -1.0)
|
||||
.rotate(wheel_rot)
|
||||
.translate(wheel_size * wheel_rot_trans),
|
||||
|
||||
offset: V3(
|
||||
wheel_size.0 * -0.5 - board_size.0 * 0.4,
|
||||
wheel_y,
|
||||
wheel_rail_size.2 * 0.5,
|
||||
),
|
||||
},
|
||||
];
|
||||
vec![pivot, wheel_rail, wheel].into_iter().flatten()
|
||||
};
|
||||
let board_pivot_trans = V3(0.0, 0.5, 0.5);
|
||||
let mut board = vec![ShapeGroupShape {
|
||||
shape: Shape::new_cube(board_size)
|
||||
.translate(board_size * board_pivot_trans * -1.0)
|
||||
.rotate(V3(pivot_deg * (PI / 180.0), 0.0, 0.0))
|
||||
.translate(board_size * board_pivot_trans),
|
||||
offset: board_size * -0.5,
|
||||
}];
|
||||
board.extend(trucks);
|
||||
let board = ShapeGroup::new(board).rotate(rot);
|
||||
board.draw(pos, scene, Color::Green, Color::Black);
|
||||
}
|
||||
ObjectKind::Obstacle { pos, .. } => {
|
||||
ObjectKind::Box { pos, .. } => {
|
||||
scene.draw_shape(
|
||||
pos,
|
||||
&Shape::new_cube(V3(0.2, 0.1, 0.2)),
|
||||
&Shape::new_cube(V3(1.0, 1.0, 1.0)),
|
||||
Color::Green,
|
||||
Color::Black,
|
||||
);
|
||||
scene.draw_shape(
|
||||
pos + V3(0.0, -0.5, 0.0),
|
||||
&Shape::new_cube(V3(0.5, 0.5, 0.5)),
|
||||
Color::Green,
|
||||
Color::Black,
|
||||
);
|
||||
}
|
||||
ObjectKind::Ground {
|
||||
pos,
|
||||
grid_depth,
|
||||
grid_item_size,
|
||||
grid_width,
|
||||
..
|
||||
} => {
|
||||
for grid in 0..5 {
|
||||
let mut shapes = Vec::new();
|
||||
for z in 0..grid_depth {
|
||||
for x in -grid_width / 2..grid_width / 2 {
|
||||
shapes.push(ShapeGroupShape {
|
||||
shape: Shape::new_plane(V3(grid_item_size, 0.0, grid_item_size)),
|
||||
offset: V3(
|
||||
x as f64 * grid_item_size,
|
||||
0.0,
|
||||
z as f64 * grid_item_size
|
||||
+ grid as f64 * grid_depth as f64 * grid_item_size,
|
||||
),
|
||||
});
|
||||
}
|
||||
}
|
||||
let ground = ShapeGroup::new(shapes);
|
||||
ground.draw(pos, scene, Color::Cyan, Color::Black);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn game_main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
pub fn editor_main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut sdl_io = engine::SdlIo::new()?;
|
||||
let event_queue = Arc::new(Mutex::new(EventQueue::new()));
|
||||
let mut game = Game::new(event_queue.clone());
|
||||
std::thread::spawn(move || {
|
||||
let server = Server::bind("10.133.51.127:5000");
|
||||
server.start(event_queue);
|
||||
});
|
||||
let objects: Vec<ObjectKind> = vec![
|
||||
ObjectKind::SkateBoard {
|
||||
pos: V3(0.0, -0.1, -0.7),
|
||||
vel: V3(0.0, 0.0, 0.0),
|
||||
rot: V3(0.0, PI * 0.5, 0.0),
|
||||
nyoom_factor: 0.0,
|
||||
pivot_deg: 0.0,
|
||||
},
|
||||
ObjectKind::Ground {
|
||||
original_pos: V3(0.0, -0.25, -0.6),
|
||||
pos: V3(0.0, -0.25, -0.6),
|
||||
vel: V3(0.0, 0.0, -0.1),
|
||||
rot: V3(0.0, 0.0, 0.0),
|
||||
grid_item_size: 0.1,
|
||||
grid_width: 10,
|
||||
grid_depth: 10,
|
||||
},
|
||||
ObjectKind::Obstacle {
|
||||
pos: V3(0.5, -0.2, 0.0),
|
||||
vel: V3(0.0, 0.0, -0.1),
|
||||
},
|
||||
];
|
||||
let mut editor = Editor::new();
|
||||
|
||||
let objects = [ObjectKind::Box {
|
||||
pos: V3(0.0, 0.0, 0.0),
|
||||
vel: V3(0.0, 0.0, 0.0),
|
||||
}];
|
||||
|
||||
for object in objects {
|
||||
game.spawn(object)
|
||||
editor.spawn(object)
|
||||
}
|
||||
|
||||
sdl_io.run(&mut game);
|
||||
sdl_io.run(&mut editor);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -7,9 +7,13 @@ pub struct V2(pub f64, pub f64);
|
||||
pub struct V3(pub f64, pub f64, pub f64);
|
||||
|
||||
impl V3 {
|
||||
pub fn project_2d(&self) -> V2 {
|
||||
pub fn filled(v: f64) -> Self {
|
||||
Self(v, v, v)
|
||||
}
|
||||
|
||||
pub fn project_2d(&self, camera_pos: V3) -> V2 {
|
||||
// V2(self.0 / self.2, self.1 / self.2)
|
||||
let c = V3(0.0, 0.0, -1.0);
|
||||
let c = camera_pos;
|
||||
let d = *self - c;
|
||||
let e = V3(0.0, 0.0, 0.0) - c;
|
||||
V2(e.2 / d.2 * d.0 + e.0, e.2 / d.2 * d.1 + e.1)
|
||||
@ -126,11 +130,11 @@ impl Triangle3 {
|
||||
Self(self.0 + offset, self.1 + offset, self.2 + offset)
|
||||
}
|
||||
|
||||
pub fn project_2d(&self) -> Triangle2 {
|
||||
pub fn project_2d(&self, camera_pos: V3) -> Triangle2 {
|
||||
Triangle2(
|
||||
self.0.project_2d(),
|
||||
self.1.project_2d(),
|
||||
self.2.project_2d(),
|
||||
self.0.project_2d(camera_pos),
|
||||
self.1.project_2d(camera_pos),
|
||||
self.2.project_2d(camera_pos),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -3,24 +3,30 @@ use crate::engine::{game::Renderer, Color, Shape, Triangle2, Triangle3, V2, V3};
|
||||
pub struct R3d<'r, R: Renderer> {
|
||||
r: &'r mut R,
|
||||
triangle_buffer: Vec<Triangle2>,
|
||||
camera_pos: V3,
|
||||
}
|
||||
|
||||
static CAMERA_POS: V3 = V3(0.0, 0.0, -1.0);
|
||||
|
||||
impl<'r, R: Renderer> R3d<'r, R> {
|
||||
pub fn new(r: &'r mut R) -> Self {
|
||||
pub fn new(r: &'r mut R, camera_pos: V3) -> Self {
|
||||
Self {
|
||||
r,
|
||||
triangle_buffer: Vec::new(),
|
||||
camera_pos,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn draw_line(&mut self, from: V3, to: V3, color: Color) {
|
||||
self.r.draw_line(from.project_2d(), to.project_2d(), color);
|
||||
self.r.draw_line(
|
||||
from.project_2d(self.camera_pos),
|
||||
to.project_2d(self.camera_pos),
|
||||
color,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn draw_triangle(&mut self, triangle: Triangle3, color: Color) {
|
||||
let triangle = triangle.translate(CAMERA_POS).project_2d();
|
||||
let triangle = triangle
|
||||
.translate(self.camera_pos)
|
||||
.project_2d(self.camera_pos);
|
||||
|
||||
self.r.draw_line(triangle.0, triangle.1, color);
|
||||
self.r.draw_line(triangle.1, triangle.2, color);
|
||||
@ -29,13 +35,16 @@ impl<'r, R: Renderer> R3d<'r, R> {
|
||||
|
||||
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.triangle_buffer.extend(
|
||||
shape
|
||||
.faces()
|
||||
.map(|tri| tri.translate(pos).project_2d(self.camera_pos)),
|
||||
);
|
||||
|
||||
self.r.draw_triangles(&self.triangle_buffer, fill_color);
|
||||
|
||||
for face in shape.faces() {
|
||||
if face.normal().dot(face.0 - CAMERA_POS + pos) >= 0.0 {
|
||||
if face.normal().dot(face.0 - self.camera_pos + pos) >= 0.0 {
|
||||
continue;
|
||||
}
|
||||
// let pxyz = face.middle() + face.normal();
|
||||
@ -58,13 +67,13 @@ impl<'r, R: Renderer> R3d<'r, R> {
|
||||
|
||||
// self.draw_triangle(face.translate(pos - CAMERA_POS), outline_color);
|
||||
self.r.draw_line(
|
||||
(face.0 + pos).project_2d(),
|
||||
(face.1 + pos).project_2d(),
|
||||
(face.0 + pos).project_2d(self.camera_pos),
|
||||
(face.1 + pos).project_2d(self.camera_pos),
|
||||
outline_color,
|
||||
);
|
||||
self.r.draw_line(
|
||||
(face.2 + pos).project_2d(),
|
||||
(face.0 + pos).project_2d(),
|
||||
(face.2 + pos).project_2d(self.camera_pos),
|
||||
(face.0 + pos).project_2d(self.camera_pos),
|
||||
outline_color,
|
||||
);
|
||||
}
|
||||
|
||||
@ -17,13 +17,13 @@ impl Scene {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render<R: Renderer>(&mut self, r: &mut R, camera: V3) {
|
||||
pub fn render<R: Renderer>(&mut self, r: &mut R, camera_pos: V3) {
|
||||
let mut indices_with_scores = self
|
||||
.objects
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, object)| {
|
||||
let mut point_scores = object.triangle.points().map(|p| p.distance(camera));
|
||||
let mut point_scores = object.triangle.points().map(|p| p.distance(camera_pos));
|
||||
point_scores.sort_by(|a, b| a.total_cmp(b));
|
||||
|
||||
(i, point_scores[0])
|
||||
@ -44,11 +44,11 @@ impl Scene {
|
||||
continue;
|
||||
}
|
||||
|
||||
if object.triangle.normal().dot(object.triangle.0 - camera) >= 0.0 {
|
||||
if object.triangle.normal().dot(object.triangle.0 - camera_pos) >= 0.0 {
|
||||
continue;
|
||||
}
|
||||
|
||||
let triangle = object.triangle.project_2d();
|
||||
let triangle = object.triangle.project_2d(camera_pos);
|
||||
|
||||
r.draw_triangle(triangle.clone(), object.fill_color);
|
||||
r.draw_line(triangle.0, triangle.1, object.outline_color);
|
||||
|
||||
@ -56,13 +56,13 @@ impl<R: Renderer> engine::Game<R> for Game {
|
||||
for object in &mut self.objects {
|
||||
if self.keys_pressed.contains(&Key::Left) == self.keys_pressed.contains(&Key::Right) {
|
||||
if let ObjectKind::SkateBoard { pivot_deg, .. } = &mut object.kind {
|
||||
let decay_rate = 1.0 - (2.0 * delta_time.as_secs_f64());
|
||||
let decay_rate = 1.0 - (4.0 * delta_time.as_secs_f64());
|
||||
*pivot_deg *= decay_rate;
|
||||
}
|
||||
}
|
||||
if self.keys_pressed.contains(&Key::Left) {
|
||||
if let ObjectKind::SkateBoard { pivot_deg, .. } = &mut object.kind {
|
||||
*pivot_deg -= 18.0 * delta_time.as_secs_f64();
|
||||
*pivot_deg -= 36.0 * delta_time.as_secs_f64();
|
||||
if *pivot_deg < -12.5 {
|
||||
*pivot_deg = -12.5;
|
||||
}
|
||||
@ -70,7 +70,7 @@ impl<R: Renderer> engine::Game<R> for Game {
|
||||
}
|
||||
if self.keys_pressed.contains(&Key::Right) {
|
||||
if let ObjectKind::SkateBoard { pivot_deg, .. } = &mut object.kind {
|
||||
*pivot_deg += 18.0 * delta_time.as_secs_f64();
|
||||
*pivot_deg += 36.0 * delta_time.as_secs_f64();
|
||||
if *pivot_deg > 12.5 {
|
||||
*pivot_deg = 12.5;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user