♻️ refactor: move stuff out of main.rs
parent
74251fcf37
commit
8872a45d50
|
@ -167,11 +167,11 @@ impl Graphics {
|
||||||
|
|
||||||
pub fn draw (
|
pub fn draw (
|
||||||
&self,
|
&self,
|
||||||
static_level: &crate::StaticLevel,
|
phys_tris: &[opengl_rust::physics::Triangle],
|
||||||
logic: &crate::LogicState,
|
logic: &crate::LogicState,
|
||||||
gl_state: &mut GlState,
|
gl_state: &mut GlState,
|
||||||
level: &crate::LoadedLevel,
|
level: &crate::LoadedLevel,
|
||||||
camera: &crate::Camera,
|
camera: &crate::level_loader::Camera,
|
||||||
) {
|
) {
|
||||||
// use serde::Deserialize;
|
// use serde::Deserialize;
|
||||||
use uniforms as u;
|
use uniforms as u;
|
||||||
|
@ -334,7 +334,7 @@ impl Graphics {
|
||||||
if true {
|
if true {
|
||||||
// Raycast for player shadow
|
// Raycast for player shadow
|
||||||
let coll = opengl_rust::physics::get_candidate (
|
let coll = opengl_rust::physics::get_candidate (
|
||||||
&static_level.tris, &[],
|
&phys_tris, &[],
|
||||||
logic.player.pos,
|
logic.player.pos,
|
||||||
logic.player.pos + Vec3::new (0.0, 0.0, -100.0),
|
logic.player.pos + Vec3::new (0.0, 0.0, -100.0),
|
||||||
0.0
|
0.0
|
||||||
|
|
|
@ -2,10 +2,13 @@ use anyhow::Result;
|
||||||
|
|
||||||
use opengl_rust::{
|
use opengl_rust::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
|
physics::Triangle,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct LoadedLevel {
|
pub struct LoadedLevel {
|
||||||
pub player_spawn: Vec3,
|
pub player_spawn: Vec3,
|
||||||
|
pub camera: Camera,
|
||||||
|
pub phys_tris: Vec <Triangle>,
|
||||||
pub buffer: Vec <u8>,
|
pub buffer: Vec <u8>,
|
||||||
pub level: gltf::Document,
|
pub level: gltf::Document,
|
||||||
}
|
}
|
||||||
|
@ -28,8 +31,16 @@ impl LoadedLevel {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut player_spawn = None;
|
let mut player_spawn = None;
|
||||||
|
let mut camera = None;
|
||||||
|
let mut phys_tris: Vec <opengl_rust::physics::Triangle> = Vec::new ();
|
||||||
|
|
||||||
for node in scene.nodes () {
|
for node in scene.nodes () {
|
||||||
|
if node.camera ().is_some () {
|
||||||
|
camera = Some (Camera {
|
||||||
|
transform: node.transform ().clone (),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if node.name () == Some ("Player Spawn") {
|
if node.name () == Some ("Player Spawn") {
|
||||||
let (translation, _, _) = node.transform ().decomposed ();
|
let (translation, _, _) = node.transform ().decomposed ();
|
||||||
player_spawn = Some (Vec3::from (translation));
|
player_spawn = Some (Vec3::from (translation));
|
||||||
|
@ -38,7 +49,9 @@ impl LoadedLevel {
|
||||||
|
|
||||||
}
|
}
|
||||||
else if let Some (mesh) = node.mesh () {
|
else if let Some (mesh) = node.mesh () {
|
||||||
for (_i, prim) in mesh.primitives ().enumerate () {
|
let m = gltf_node_get_mat4 (&node);
|
||||||
|
|
||||||
|
for (_, prim) in mesh.primitives ().enumerate () {
|
||||||
let positions = match prim.get (&Semantic::Positions) {
|
let positions = match prim.get (&Semantic::Positions) {
|
||||||
None => continue,
|
None => continue,
|
||||||
Some (x) => x,
|
Some (x) => x,
|
||||||
|
@ -51,7 +64,7 @@ impl LoadedLevel {
|
||||||
None => continue,
|
None => continue,
|
||||||
Some (x) => x,
|
Some (x) => x,
|
||||||
};
|
};
|
||||||
let _pos_view = match positions.view () {
|
let pos_view = match positions.view () {
|
||||||
None => continue,
|
None => continue,
|
||||||
Some (x) => x,
|
Some (x) => x,
|
||||||
};
|
};
|
||||||
|
@ -59,10 +72,53 @@ impl LoadedLevel {
|
||||||
None => continue,
|
None => continue,
|
||||||
Some (x) => x,
|
Some (x) => x,
|
||||||
};
|
};
|
||||||
let _indices_view = match indices.view () {
|
let indices_view = match indices.view () {
|
||||||
None => continue,
|
None => continue,
|
||||||
Some (x) => x,
|
Some (x) => x,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let idx_start = indices.offset () + indices_view.offset ();
|
||||||
|
let idx_slice = &buffer [idx_start..idx_start + indices.count () * 2];
|
||||||
|
let vert_start = positions.offset () + pos_view.offset ();
|
||||||
|
let vert_slice = &buffer [vert_start..vert_start + positions.count () * 4 * 3];
|
||||||
|
|
||||||
|
for chunk in idx_slice.chunks_exact (2 * 3) {
|
||||||
|
let read_idx = |i: usize| u16::from_le_bytes ([chunk [i * 2 + 0], chunk [i * 2 + 1]]);
|
||||||
|
|
||||||
|
let idxs = [
|
||||||
|
read_idx (0),
|
||||||
|
read_idx (1),
|
||||||
|
read_idx (2),
|
||||||
|
];
|
||||||
|
|
||||||
|
let read_pos_coord = |i| f32::from_le_bytes ([
|
||||||
|
vert_slice [i * 4 + 0],
|
||||||
|
vert_slice [i * 4 + 1],
|
||||||
|
vert_slice [i * 4 + 2],
|
||||||
|
vert_slice [i * 4 + 3],
|
||||||
|
]);
|
||||||
|
|
||||||
|
let read_pos = move |i| {
|
||||||
|
let i = usize::try_from (i).unwrap ();
|
||||||
|
m.transform_point3 (Vec3::new (
|
||||||
|
read_pos_coord (i * 3 + 0),
|
||||||
|
read_pos_coord (i * 3 + 1),
|
||||||
|
read_pos_coord (i * 3 + 2),
|
||||||
|
))
|
||||||
|
};
|
||||||
|
|
||||||
|
// glTF triangle winding is backwards from what I expected
|
||||||
|
// no biggie
|
||||||
|
let verts = [
|
||||||
|
read_pos (idxs [0]),
|
||||||
|
read_pos (idxs [2]),
|
||||||
|
read_pos (idxs [1]),
|
||||||
|
];
|
||||||
|
|
||||||
|
phys_tris.push (opengl_rust::physics::Triangle {
|
||||||
|
verts,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,10 +128,25 @@ impl LoadedLevel {
|
||||||
Some (x) => x,
|
Some (x) => x,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let camera = match camera {
|
||||||
|
None => bail! ("Couldn't find camera node in glTF file"),
|
||||||
|
Some (x) => x,
|
||||||
|
};
|
||||||
|
|
||||||
Ok (Self {
|
Ok (Self {
|
||||||
buffer,
|
buffer,
|
||||||
|
camera,
|
||||||
level,
|
level,
|
||||||
|
phys_tris,
|
||||||
player_spawn,
|
player_spawn,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct Camera {
|
||||||
|
pub transform: gltf::scene::Transform,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn gltf_node_get_mat4 (node: &gltf::Node) -> Mat4 {
|
||||||
|
Mat4::from_cols_array_2d (&node.transform ().matrix ())
|
||||||
|
}
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
use opengl_rust::{
|
use opengl_rust::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
physics::PhysicsBody,
|
physics::{
|
||||||
|
PhysicsBody,
|
||||||
|
Triangle,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
LoadedLevel,
|
LoadedLevel,
|
||||||
StaticLevel,
|
|
||||||
VirtualGamepad,
|
VirtualGamepad,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -26,7 +28,7 @@ impl LogicState {
|
||||||
self.player.pos = level.player_spawn;
|
self.player.pos = level.player_spawn;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn step (&mut self, static_level: &StaticLevel, phys_params: &opengl_rust::physics::Params, p_gp: VirtualGamepad) -> LogicStepOutput
|
pub fn step (&mut self, phys_tris: &[Triangle], phys_params: &opengl_rust::physics::Params, p_gp: VirtualGamepad) -> LogicStepOutput
|
||||||
{
|
{
|
||||||
let player_acc = 1.0;
|
let player_acc = 1.0;
|
||||||
let player_acc_air = 0.125;
|
let player_acc_air = 0.125;
|
||||||
|
@ -107,7 +109,7 @@ impl LogicState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let phys_result = opengl_rust::physics::step (&phys_params, &static_level.tris, &[], 0.5, &self.player);
|
let phys_result = opengl_rust::physics::step (&phys_params, phys_tris, &[], 0.5, &self.player);
|
||||||
|
|
||||||
self.player = phys_result.body;
|
self.player = phys_result.body;
|
||||||
if self.player.pos.z < kill_z {
|
if self.player.pos.z < kill_z {
|
||||||
|
|
|
@ -20,11 +20,6 @@ use virtual_gamepad::VirtualGamepad;
|
||||||
|
|
||||||
pub struct GameState {
|
pub struct GameState {
|
||||||
logic: LogicState,
|
logic: LogicState,
|
||||||
static_level: StaticLevel,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct StaticLevel {
|
|
||||||
tris: Vec <opengl_rust::physics::Triangle>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
|
@ -59,103 +54,12 @@ async fn main () -> Result <()> {
|
||||||
let mut time_step = TimeStep::new (60, 1000);
|
let mut time_step = TimeStep::new (60, 1000);
|
||||||
|
|
||||||
let level = LoadedLevel::from_path ("gltf/level-00.glb")?;
|
let level = LoadedLevel::from_path ("gltf/level-00.glb")?;
|
||||||
let scene = level.level.scenes ().next ().unwrap ();
|
|
||||||
|
|
||||||
let mut camera = None;
|
|
||||||
let mut phys_tris: Vec <opengl_rust::physics::Triangle> = Vec::new ();
|
|
||||||
|
|
||||||
for node in scene.nodes () {
|
|
||||||
if node.camera ().is_some () {
|
|
||||||
camera = Some (Camera {
|
|
||||||
transform: node.transform ().clone (),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let mesh = match node.mesh () {
|
|
||||||
None => continue,
|
|
||||||
Some (x) => x,
|
|
||||||
};
|
|
||||||
|
|
||||||
let m = gltf_node_get_mat4 (&node);
|
|
||||||
|
|
||||||
for prim in mesh.primitives () {
|
|
||||||
use gltf::Semantic;
|
|
||||||
|
|
||||||
let positions = match prim.get (&Semantic::Positions) {
|
|
||||||
None => continue,
|
|
||||||
Some (x) => x,
|
|
||||||
};
|
|
||||||
let pos_view = match positions.view () {
|
|
||||||
None => continue,
|
|
||||||
Some (x) => x,
|
|
||||||
};
|
|
||||||
let indices = match prim.indices () {
|
|
||||||
None => continue,
|
|
||||||
Some (x) => x,
|
|
||||||
};
|
|
||||||
let indices_view = match indices.view () {
|
|
||||||
None => continue,
|
|
||||||
Some (x) => x,
|
|
||||||
};
|
|
||||||
|
|
||||||
let idx_start = indices.offset () + indices_view.offset ();
|
|
||||||
let idx_slice = &level.buffer [idx_start..idx_start + indices.count () * 2];
|
|
||||||
let vert_start = positions.offset () + pos_view.offset ();
|
|
||||||
let vert_slice = &level.buffer [vert_start..vert_start + positions.count () * 4 * 3];
|
|
||||||
|
|
||||||
for chunk in idx_slice.chunks_exact (2 * 3) {
|
|
||||||
let read_idx = |i: usize| u16::from_le_bytes ([chunk [i * 2 + 0], chunk [i * 2 + 1]]);
|
|
||||||
|
|
||||||
let idxs = [
|
|
||||||
read_idx (0),
|
|
||||||
read_idx (1),
|
|
||||||
read_idx (2),
|
|
||||||
];
|
|
||||||
|
|
||||||
let read_pos_coord = |i| f32::from_le_bytes ([
|
|
||||||
vert_slice [i * 4 + 0],
|
|
||||||
vert_slice [i * 4 + 1],
|
|
||||||
vert_slice [i * 4 + 2],
|
|
||||||
vert_slice [i * 4 + 3],
|
|
||||||
]);
|
|
||||||
|
|
||||||
let read_pos = move |i| {
|
|
||||||
let i = usize::try_from (i).unwrap ();
|
|
||||||
m.transform_point3 (Vec3::new (
|
|
||||||
read_pos_coord (i * 3 + 0),
|
|
||||||
read_pos_coord (i * 3 + 1),
|
|
||||||
read_pos_coord (i * 3 + 2),
|
|
||||||
))
|
|
||||||
};
|
|
||||||
|
|
||||||
// glTF triangle winding is backwards from what I expected
|
|
||||||
// no biggie
|
|
||||||
let verts = [
|
|
||||||
read_pos (idxs [0]),
|
|
||||||
read_pos (idxs [2]),
|
|
||||||
read_pos (idxs [1]),
|
|
||||||
];
|
|
||||||
|
|
||||||
phys_tris.push (opengl_rust::physics::Triangle {
|
|
||||||
verts,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let camera = match camera {
|
|
||||||
None => bail! ("Couldn't find camera node in glTF file"),
|
|
||||||
Some (x) => x,
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut graphics = Graphics::new ();
|
let mut graphics = Graphics::new ();
|
||||||
|
|
||||||
let mut gl_state = Default::default ();
|
let mut gl_state = Default::default ();
|
||||||
let mut game_state = GameState {
|
let mut game_state = GameState {
|
||||||
logic: Default::default (),
|
logic: Default::default (),
|
||||||
static_level: StaticLevel {
|
|
||||||
tris: phys_tris,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
let phys_params = opengl_rust::physics::Params {
|
let phys_params = opengl_rust::physics::Params {
|
||||||
dt: 1.0 / 60.0,
|
dt: 1.0 / 60.0,
|
||||||
|
@ -235,7 +139,7 @@ async fn main () -> Result <()> {
|
||||||
|
|
||||||
let p_gp = player_gamepad;
|
let p_gp = player_gamepad;
|
||||||
|
|
||||||
let logic_step_output = game_state.logic.step (&game_state.static_level, &phys_params, p_gp);
|
let logic_step_output = game_state.logic.step (&level.phys_tris, &phys_params, p_gp);
|
||||||
if logic_step_output.reset_level {
|
if logic_step_output.reset_level {
|
||||||
game_state.logic.reset_level (&level);
|
game_state.logic.reset_level (&level);
|
||||||
}
|
}
|
||||||
|
@ -247,10 +151,10 @@ async fn main () -> Result <()> {
|
||||||
let prediction_frames = 4;
|
let prediction_frames = 4;
|
||||||
let mut predicted_logic = game_state.logic.clone ();
|
let mut predicted_logic = game_state.logic.clone ();
|
||||||
for _ in 0..prediction_frames {
|
for _ in 0..prediction_frames {
|
||||||
predicted_logic.step (&game_state.static_level, &phys_params, p_gp);
|
predicted_logic.step (&level.phys_tris, &phys_params, p_gp);
|
||||||
}
|
}
|
||||||
|
|
||||||
graphics.draw (&game_state.static_level, &predicted_logic, &mut gl_state, &level, &camera);
|
graphics.draw (&level.phys_tris, &predicted_logic, &mut gl_state, &level, &level.camera);
|
||||||
graphics.frames += 1;
|
graphics.frames += 1;
|
||||||
|
|
||||||
if graphics.frames == next_upf_print {
|
if graphics.frames == next_upf_print {
|
||||||
|
@ -281,10 +185,3 @@ struct TriangleStream {
|
||||||
pub indices: gpu_buffers::IndexBuffer,
|
pub indices: gpu_buffers::IndexBuffer,
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
pub struct Camera {
|
|
||||||
transform: gltf::scene::Transform,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn gltf_node_get_mat4 (node: &gltf::Node) -> Mat4 {
|
|
||||||
Mat4::from_cols_array_2d (&node.transform ().matrix ())
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue