91 lines
3.0 KiB
Rust
91 lines
3.0 KiB
Rust
use std::{error::Error, io::{BufReader, BufWriter}};
|
|
use std::fs::File;
|
|
|
|
use serde_derive::{Deserialize, Serialize};
|
|
|
|
use crate::{vulkan::{MeshHandle, VulkanRenderer, gameobject::GameObjectHandle}};
|
|
use crate::game::TestGame;
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
struct MeshJson {
|
|
path: String
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
struct ObjectJson {
|
|
mesh_index: Option<usize>,
|
|
position: [f32; 3],
|
|
rotation: [f32; 4],
|
|
scale: [f32; 3]
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
struct LevelJson {
|
|
meshes: Vec<MeshJson>,
|
|
objects: Vec<ObjectJson>,
|
|
player: ObjectJson
|
|
}
|
|
|
|
pub fn load_level(path: &str, game: &mut TestGame, renderer: &mut VulkanRenderer) -> Result<Vec<GameObjectHandle>, Box<dyn Error>> {
|
|
let file = File::open(path)?;
|
|
let reader = BufReader::new(file);
|
|
let level_json: LevelJson = serde_json::from_reader(reader)?;
|
|
let meshes: Vec<MeshHandle> = level_json.meshes.iter().map(|json_mesh| {
|
|
let mesh_handles = game.load_gltf(renderer, &json_mesh.path);
|
|
// TODO: Add empty parent GO instead of just loading the first mesh
|
|
mesh_handles[0].clone()
|
|
}).collect();
|
|
let objects: Vec<GameObjectHandle> = level_json.objects.iter().filter_map(|json_obj| {
|
|
// TODO: Parenting
|
|
if let Some(mesh_index) = json_obj.mesh_index {
|
|
let mut handle = game.add_game_object(renderer, meshes[mesh_index].clone());
|
|
let game_object = handle.get_game_object_mut(renderer).unwrap();
|
|
game_object.position = json_obj.position.into();
|
|
game_object.rotation = json_obj.rotation.into();
|
|
game_object.scale = json_obj.scale.into();
|
|
Some(handle)
|
|
} else {
|
|
None
|
|
}
|
|
}).collect();
|
|
game.player.camera.position = level_json.player.position.into();
|
|
game.player.camera.rotation = level_json.player.rotation.into();
|
|
Ok(objects)
|
|
}
|
|
|
|
pub fn save_level(path: &str, game: &mut TestGame, renderer: &mut VulkanRenderer) -> Result<(), Box<dyn Error>> {
|
|
let meshes = renderer.game_data.meshes.iter().filter(|m| m.original_path.is_some()).map(|mesh| {
|
|
MeshJson {
|
|
path: mesh.original_path.clone().unwrap()
|
|
}
|
|
}).collect();
|
|
|
|
let objects = game.game_objects.iter().map(|game_object_handle| {
|
|
let game_object = game_object_handle.get_game_object(renderer).unwrap();
|
|
ObjectJson {
|
|
mesh_index: Some(game_object_handle.object_index),
|
|
position: game_object.position.into(),
|
|
rotation: game_object.rotation.into(),
|
|
scale: game_object.scale.into()
|
|
}
|
|
}).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 {
|
|
meshes,
|
|
objects,
|
|
player
|
|
};
|
|
|
|
let file = File::create(path)?;
|
|
let writer = BufWriter::new(file);
|
|
serde_json::to_writer_pretty(writer, &level_json)?;
|
|
|
|
Ok(())
|
|
} |