|
|
|
|
@ -1,5 +1,41 @@
|
|
|
|
|
///
|
|
|
|
|
/// General levevel structure is this:
|
|
|
|
|
/// Level: Vec<Epoch>
|
|
|
|
|
/// Epoch: Id, Handle<DynamicScene>
|
|
|
|
|
///
|
|
|
|
|
/// You can index a Level by it's Epoch like
|
|
|
|
|
/// `/path/to/level.file#epoch-id`
|
|
|
|
|
///
|
|
|
|
|
/// !!!TODO!!!
|
|
|
|
|
/// * read .trees.level files, loading Levels
|
|
|
|
|
/// * Similar to GLTFs, this contains nested assets
|
|
|
|
|
/// * Handle<Level> -> Vec<Handle<Epochs>> => Handle<DynamicScene>
|
|
|
|
|
/// * Review how GLTF loading works for this, very similar goal.
|
|
|
|
|
///
|
|
|
|
|
/// Ex:
|
|
|
|
|
/// foo.trees.level:
|
|
|
|
|
/// [
|
|
|
|
|
/// Epoch {
|
|
|
|
|
/// id: 1,
|
|
|
|
|
/// scene: [
|
|
|
|
|
/// entities: [...]
|
|
|
|
|
/// resources: [...]
|
|
|
|
|
/// ],
|
|
|
|
|
/// },
|
|
|
|
|
/// Epoch {
|
|
|
|
|
/// id: 2,
|
|
|
|
|
/// scene: [...]
|
|
|
|
|
/// }, etc
|
|
|
|
|
/// ]
|
|
|
|
|
///
|
|
|
|
|
use crate::editor::prelude::*;
|
|
|
|
|
use bevy::tasks::IoTaskPool;
|
|
|
|
|
use bevy::{
|
|
|
|
|
asset::{AssetLoader, LoadContext, LoadedAsset},
|
|
|
|
|
reflect::{TypePath, TypeUuid},
|
|
|
|
|
scene::SceneLoader,
|
|
|
|
|
tasks::IoTaskPool,
|
|
|
|
|
utils::BoxedFuture,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Default)]
|
|
|
|
|
pub struct EditorLevelPlugin;
|
|
|
|
|
@ -7,8 +43,10 @@ pub struct EditorLevelPlugin;
|
|
|
|
|
impl Plugin for EditorLevelPlugin {
|
|
|
|
|
fn build(&self, app: &mut App) {
|
|
|
|
|
app.register_type::<LevelRoot>()
|
|
|
|
|
.add_asset::<Level>()
|
|
|
|
|
.init_asset_loader::<LevelAssetLoader>()
|
|
|
|
|
.add_systems(Update, level_ui)
|
|
|
|
|
.add_systems(Update, load_level)
|
|
|
|
|
.add_systems(Update, set_level)
|
|
|
|
|
.add_systems(Update, export_level.run_if(ui::activated::<ExportLevel>))
|
|
|
|
|
.add_systems(Update, rehydrate_level::<Visibility, ComputedVisibility>)
|
|
|
|
|
.add_systems(
|
|
|
|
|
@ -24,7 +62,16 @@ impl Plugin for EditorLevelPlugin {
|
|
|
|
|
#[reflect(Component)]
|
|
|
|
|
pub struct LevelRoot;
|
|
|
|
|
|
|
|
|
|
pub type Level = DynamicScene;
|
|
|
|
|
#[derive(Debug, TypeUuid, TypePath, Default, Deserialize)]
|
|
|
|
|
#[uuid = "eb5c5f73-076e-4476-83f2-d97cf077ec90"]
|
|
|
|
|
struct Level {
|
|
|
|
|
epochs: Vec<Epoch>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Reflect)]
|
|
|
|
|
struct RawLevel {
|
|
|
|
|
epochs: Vec<Epoch>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Component, Default)]
|
|
|
|
|
pub struct LevelWidget;
|
|
|
|
|
@ -84,7 +131,7 @@ fn level_ui(
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn load_level(
|
|
|
|
|
fn set_level(
|
|
|
|
|
events: Query<
|
|
|
|
|
&ui::TargetAsset<DynamicScene>,
|
|
|
|
|
(Added<ui::Active>, With<ui::TargetAsset<DynamicScene>>),
|
|
|
|
|
@ -224,3 +271,40 @@ fn clear_level(
|
|
|
|
|
});
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Default)]
|
|
|
|
|
pub struct LevelAssetLoader;
|
|
|
|
|
|
|
|
|
|
impl AssetLoader for LevelAssetLoader {
|
|
|
|
|
fn load<'a>(
|
|
|
|
|
&'a self,
|
|
|
|
|
bytes: &'a [u8],
|
|
|
|
|
load_context: &'a mut LoadContext,
|
|
|
|
|
) -> BoxedFuture<'a, Result<(), bevy::asset::Error>> {
|
|
|
|
|
Box::pin(async move { Ok(load_level(bytes, load_context).await?) })
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn extensions(&self) -> &[&str] {
|
|
|
|
|
&["trees.level"]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ref: https://github.com/bevyengine/bevy/blob/12c6fa7e591545afe8c7101b0f021121eea7272f/crates/bevy_gltf/src/loader.rs#L92
|
|
|
|
|
pub async fn load_level<'a, 'b>(
|
|
|
|
|
bytes: &'a [u8],
|
|
|
|
|
load_context: &'a mut LoadContext<'b>,
|
|
|
|
|
) -> Handle<Level> {
|
|
|
|
|
let level: Level = ron::de::from_bytes(bytes).expect("Deserialize level");
|
|
|
|
|
info!("Level: {:?}", level);
|
|
|
|
|
let scene = SceneLoader::from_world(&mut World::new())
|
|
|
|
|
.load(bytes, load_context)
|
|
|
|
|
.await;
|
|
|
|
|
info!("Scene result: {:?}", scene);
|
|
|
|
|
let epochs: Vec<Epoch> = {
|
|
|
|
|
todo!("Load epochs");
|
|
|
|
|
let id = todo!("get epoch ID");
|
|
|
|
|
let scene = todo!("get dynamic scene");
|
|
|
|
|
vec![]
|
|
|
|
|
};
|
|
|
|
|
load_context.set_default_asset(LoadedAsset::new(Level { epochs }));
|
|
|
|
|
}
|
|
|
|
|
|