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, position: [f32; 3], rotation: [f32; 4], scale: [f32; 3] } #[derive(Debug, Serialize, Deserialize)] struct LevelJson { meshes: Vec, objects: Vec, player: ObjectJson } pub fn load_level(path: &str, game: &mut TestGame, renderer: &mut VulkanRenderer) -> Result, Box> { let file = File::open(path)?; let reader = BufReader::new(file); let level_json: LevelJson = serde_json::from_reader(reader)?; let meshes: Vec = 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 = 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> { 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(()) }