save and load player position
This commit is contained in:
@@ -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
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
42
src/level.rs
42
src/level.rs
@@ -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)?;
|
||||||
|
|||||||
24
src/main.rs
24
src/main.rs
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user