save and load player position

This commit is contained in:
2020-11-29 22:12:13 +01:00
parent 0edd6b6411
commit e054a76a3f
5 changed files with 73 additions and 30 deletions

View File

@@ -24,5 +24,24 @@
1.0 1.0
] ]
} }
] ],
"player": {
"mesh_index": null,
"position": [
1.170153,
-1.0,
-8.366567
],
"rotation": [
-0.023371277,
-0.0068558683,
0.95928043,
0.28140035
],
"scale": [
1.0,
1.0,
1.0
]
}
} }

View File

@@ -11,7 +11,7 @@ struct MeshJson {
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
struct ObjectJson { struct ObjectJson {
mesh_index: usize, mesh_index: Option<usize>,
position: [f32; 3], position: [f32; 3],
rotation: [f32; 4], rotation: [f32; 4],
scale: [f32; 3] scale: [f32; 3]
@@ -20,7 +20,8 @@ struct ObjectJson {
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
struct LevelJson { struct LevelJson {
meshes: Vec<MeshJson>, meshes: Vec<MeshJson>,
objects: Vec<ObjectJson> objects: Vec<ObjectJson>,
player: ObjectJson
} }
pub fn load_level(path: &str, game: &mut TestGame, renderer: &mut VulkanRenderer) -> Result<Vec<GameObjectHandle>, Box<dyn Error>> { pub fn load_level(path: &str, game: &mut TestGame, renderer: &mut VulkanRenderer) -> Result<Vec<GameObjectHandle>, Box<dyn Error>> {
@@ -32,37 +33,52 @@ pub fn load_level(path: &str, game: &mut TestGame, renderer: &mut VulkanRenderer
// TODO: Add empty parent GO instead of just loading the first mesh // TODO: Add empty parent GO instead of just loading the first mesh
mesh_handles[0].clone() mesh_handles[0].clone()
}).collect(); }).collect();
let objects: Vec<GameObjectHandle> = level_json.objects.iter().map(|json_obj| { let objects: Vec<GameObjectHandle> = level_json.objects.iter().filter_map(|json_obj| {
let mut handle = game.add_game_object(renderer, meshes[json_obj.mesh_index].clone()); // TODO: Parenting
let game_object = handle.get_game_object_mut(renderer).unwrap(); if let Some(mesh_index) = json_obj.mesh_index {
game_object.position = json_obj.position.into(); let mut handle = game.add_game_object(renderer, meshes[mesh_index].clone());
game_object.rotation = json_obj.rotation.into(); let game_object = handle.get_game_object_mut(renderer).unwrap();
game_object.scale = json_obj.scale.into(); game_object.position = json_obj.position.into();
handle game_object.rotation = json_obj.rotation.into();
game_object.scale = json_obj.scale.into();
Some(handle)
} else {
None
}
}).collect(); }).collect();
game.player.camera.position = level_json.player.position.into();
game.player.camera.rotation = level_json.player.rotation.into();
Ok(objects) Ok(objects)
} }
pub fn save_level(path: &str, game: &mut TestGame, renderer: &mut VulkanRenderer) -> Result<(), Box<dyn Error>> { pub fn save_level(path: &str, game: &mut TestGame, renderer: &mut VulkanRenderer) -> Result<(), Box<dyn Error>> {
let meshes = game.meshes.iter().map(|mesh_handle| { let meshes = renderer.game_data.meshes.iter().map(|mesh| {
MeshJson { MeshJson {
path: mesh_handle.original_path.to_string() path: mesh.original_path.to_string()
} }
}).collect(); }).collect();
let objects = game.game_objects.iter().map(|game_object_handle| { let objects = game.game_objects.iter().map(|game_object_handle| {
let game_object = game_object_handle.get_game_object(renderer).unwrap(); let game_object = game_object_handle.get_game_object(renderer).unwrap();
ObjectJson { ObjectJson {
mesh_index: game_object_handle.object_index, mesh_index: Some(game_object_handle.object_index),
position: game_object.position.into(), position: game_object.position.into(),
rotation: game_object.rotation.into(), rotation: game_object.rotation.into(),
scale: game_object.scale.into() scale: game_object.scale.into()
} }
}).collect(); }).collect();
let player = ObjectJson {
mesh_index: None,
position: game.player.camera.position.into(),
rotation: game.player.camera.rotation.into(),
scale: [1., 1., 1.]
};
let level_json = LevelJson { let level_json = LevelJson {
meshes, meshes,
objects objects,
player
}; };
let file = File::create(path)?; let file = File::create(path)?;

View File

@@ -23,7 +23,6 @@ mod level;
pub struct TestGame { pub struct TestGame {
input: InputState, input: InputState,
player: Player, player: Player,
meshes: Vec<MeshHandle>,
game_objects: Vec<GameObjectHandle>, game_objects: Vec<GameObjectHandle>,
log_config: LogConfig, log_config: LogConfig,
texture_index_counter: usize, texture_index_counter: usize,
@@ -36,7 +35,6 @@ impl TestGame {
TestGame { TestGame {
input: InputState::new(toml_path, log_config), input: InputState::new(toml_path, log_config),
player: Player::new(), player: Player::new(),
meshes: vec![],
game_objects: vec![], game_objects: vec![],
log_config, log_config,
texture_index_counter: 0, texture_index_counter: 0,
@@ -69,19 +67,19 @@ impl Game for TestGame {
renderer.game_data.shutdown = true; renderer.game_data.shutdown = true;
} }
if self.input.button_just_released("test") {
println!("Saving...");
save_level("levels/test.lvl", self, renderer).unwrap();
println!("Clearing level...");
self.clear_level(renderer);
println!("Loading...");
load_level("levels/test.lvl", self, renderer).unwrap();
}
if self.input.button_just_pressed("reload_shaders") { if self.input.button_just_pressed("reload_shaders") {
renderer.game_data.recreate_pipeline = true; renderer.game_data.recreate_pipeline = true;
} }
if self.input.button_just_pressed("quicksave") {
save_level("levels/test.lvl", self, renderer).unwrap();
}
if self.input.button_just_pressed("quickload") {
self.clear_level(renderer);
load_level("levels/test.lvl", self, renderer).unwrap();
}
if self.input.button_down("print_framerate") { if self.input.button_down("print_framerate") {
println!("{:.0} ms / {:.0} FPS", frame_time * 1000.0, 1.0 / frame_time); println!("{:.0} ms / {:.0} FPS", frame_time * 1000.0, 1.0 / frame_time);
} }
@@ -139,14 +137,13 @@ impl TestGame {
let normal_id = self.offset_texture_id(cpu_mesh.local_normal_map_index); let normal_id = self.offset_texture_id(cpu_mesh.local_normal_map_index);
// Upload mesh // Upload mesh
let mesh_id = renderer.upload_mesh(cpu_mesh); let mesh_id = renderer.upload_mesh(cpu_mesh, gltf_path.to_string());
let mesh_handle = MeshHandle { let mesh_handle = MeshHandle {
index: mesh_id, index: mesh_id,
diffuse_handle: diffuse_id, diffuse_handle: diffuse_id,
normal_handle: normal_id, normal_handle: normal_id,
original_path: gltf_path.to_string() original_path: gltf_path.to_string()
}; };
self.meshes.push(mesh_handle.clone());
mesh_handles.push(mesh_handle); mesh_handles.push(mesh_handle);
} }
@@ -166,7 +163,6 @@ impl TestGame {
fn clear_level(&mut self, renderer: &mut VulkanRenderer) { fn clear_level(&mut self, renderer: &mut VulkanRenderer) {
self.game_objects.clear(); self.game_objects.clear();
self.meshes.clear();
self.texture_index_counter = 0; self.texture_index_counter = 0;
renderer.clear_all(); renderer.clear_all();
} }

View File

@@ -1,3 +1,4 @@
use crate::MeshHandle;
use cgmath::{vec3, One, SquareMatrix, Deg, Rad, Quaternion, Vector3, Matrix4, Rotation, Rotation3, InnerSpace}; use cgmath::{vec3, One, SquareMatrix, Deg, Rad, Quaternion, Vector3, Matrix4, Rotation, Rotation3, InnerSpace};
use crate::{ use crate::{
VulkanRenderer, VulkanRenderer,
@@ -26,6 +27,7 @@ impl Camera {
} }
pub fn update(&mut self, renderer: &mut VulkanRenderer) { pub fn update(&mut self, renderer: &mut VulkanRenderer) {
// Camera stuff
self.view = Matrix4::from(self.rotation) * Matrix4::from_translation(self.position); self.view = Matrix4::from(self.rotation) * Matrix4::from_translation(self.position);
self.proj = cgmath::perspective( self.proj = cgmath::perspective(
@@ -57,6 +59,7 @@ pub struct Player {
pub movement_speed: f32, pub movement_speed: f32,
pub look_sensitivity: f32, pub look_sensitivity: f32,
pub height: f32, pub height: f32,
cube_mesh: Option<MeshHandle>
} }
impl Player { impl Player {
@@ -67,6 +70,7 @@ impl Player {
movement_speed: 3.0, movement_speed: 3.0,
look_sensitivity: 10.0, look_sensitivity: 10.0,
height: -1.0, height: -1.0,
cube_mesh: None
} }
} }
} }
@@ -96,6 +100,13 @@ impl Updatable for Player {
input.get_axis("move_forward") * self.movement_speed)) * delta_time; input.get_axis("move_forward") * self.movement_speed)) * delta_time;
} }
// Spawn cube
if input.button_just_released("test") {
if self.cube_mesh.is_none() {
// self.cube_mesh = Some()
}
}
// Update // Update
self.camera.update(renderer); self.camera.update(renderer);
} }

View File

@@ -65,6 +65,7 @@ pub trait Game {
pub struct Mesh { pub struct Mesh {
pub vertex_buffer: Arc<CpuAccessibleBuffer<[Vertex]>>, pub vertex_buffer: Arc<CpuAccessibleBuffer<[Vertex]>>,
pub index_buffer: Arc<CpuAccessibleBuffer<[u32]>>, pub index_buffer: Arc<CpuAccessibleBuffer<[u32]>>,
pub original_path: String,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@@ -433,10 +434,10 @@ impl VulkanRenderer {
}; };
} }
pub fn upload_mesh(self: &mut Self, mesh: CPUMesh) -> usize { pub fn upload_mesh(self: &mut Self, mesh: CPUMesh, original_path: String) -> usize {
let vertex_buffer = CpuAccessibleBuffer::from_iter(self.device.clone(), BufferUsage::vertex_buffer(), false, mesh.vertices.into_iter()).unwrap(); let vertex_buffer = CpuAccessibleBuffer::from_iter(self.device.clone(), BufferUsage::vertex_buffer(), false, mesh.vertices.into_iter()).unwrap();
let index_buffer = CpuAccessibleBuffer::from_iter(self.device.clone(), BufferUsage::index_buffer(), false, mesh.indices.into_iter()).unwrap(); let index_buffer = CpuAccessibleBuffer::from_iter(self.device.clone(), BufferUsage::index_buffer(), false, mesh.indices.into_iter()).unwrap();
self.game_data.meshes.push(Mesh { vertex_buffer, index_buffer }); self.game_data.meshes.push(Mesh { vertex_buffer, index_buffer, original_path });
self.game_data.meshes.len() - 1 self.game_data.meshes.len() - 1
} }