Skip to content
This repository has been archived by the owner on Sep 26, 2023. It is now read-only.

Commit

Permalink
Basic packaged scene loading
Browse files Browse the repository at this point in the history
  • Loading branch information
konceptosociala committed Jun 6, 2023
1 parent 5ee6246 commit 389602a
Show file tree
Hide file tree
Showing 27 changed files with 293 additions and 84 deletions.
Binary file modified assets.pkg
Binary file not shown.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Binary file added assets/packages/my_scene.tar.lz4
Binary file not shown.
File renamed without changes.
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
20 changes: 20 additions & 0 deletions examples/packaged_scene.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use despero::prelude::*;

fn main() {
Despero::init(WindowBuilder::default())

.default_systems()
.add_setup_system(load_scene)
.run();
}

fn load_scene(
mut cmd: Write<CommandBuffer>,
mut asset_manager: Write<AssetManager>,
) -> DesperoResult<()> {
let scene = Scene::load_packaged("assets/packages/my_scene.tar.lz4")?;

cmd.spawn_scene(scene, &mut asset_manager);

Ok(())
}
6 changes: 3 additions & 3 deletions examples/pbr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ fn create_scene(
mut cmd: Write<CommandBuffer>,
mut asset_manager: Write<AssetManager>,
){
let diffuse = asset_manager.create_texture("assets/pbr_test/diffuse.jpg", Filter::Linear);
let diffuse = asset_manager.create_texture("assets/textures/pbr_test/diffuse.jpg", Filter::Linear);

cmd.spawn(
ModelBundle::builder()
Expand Down Expand Up @@ -72,11 +72,11 @@ fn create_scene(
},
));

let sky_tex = asset_manager.create_texture("assets/StandardCubeMap.png", Filter::Linear);
let sky_tex = asset_manager.create_texture("assets/textures/StandardCubeMap.png", Filter::Linear);

cmd.spawn(
ModelBundle::builder()
.mesh(Mesh::load_obj("assets/skybox.obj").swap_remove(0))
.mesh(Mesh::load_obj("assets/models/skybox.obj").swap_remove(0))
.material(
asset_manager.create_material(
DefaultMat::builder()
Expand Down
132 changes: 132 additions & 0 deletions scene.ron
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
Scene(
assets: AssetManager(
audio: AudioManager(
sounds: [],
cast_count: 128,
listener_count: 8,
),
textures: [
Texture(
load_type: Path("assets/textures/uv.jpg"),
filter: Linear,
),
],
materials: [
{
"material": "DefaultMat",
"color": (1.0, 1.0, 1.0),
"albedo": 0,
"metallic": 0.5,
"metallic_map": 0,
"roughness": 0.5,
"roughness_map": 0,
"normal": 1.0,
"normal_map": 0,
},
],
),
entities: [
Entity(
components: [
{
"component": "Mesh",
"vertexdata": [
Vertex(
position: (-1.0, 1.0, 0.0),
normal: (0.0, 0.0, -4.0),
texcoord: (0.0, 1.0),
),
Vertex(
position: (-1.0, -1.0, 0.0),
normal: (0.0, 0.0, -4.0),
texcoord: (0.0, 0.0),
),
Vertex(
position: (1.0, 1.0, 0.0),
normal: (0.0, 0.0, -4.0),
texcoord: (1.0, 1.0),
),
Vertex(
position: (1.0, -1.0, 0.0),
normal: (0.0, 0.0, -4.0),
texcoord: (1.0, 0.0),
),
],
"indexdata": [
0,
2,
1,
1,
2,
3,
],
},
{
"component": "AssetHandle",
"value": 0,
},
{
"component": "Transform",
"translation": [
0.0,
0.0,
0.0,
],
"rotation": [
0.0,
0.0,
0.0,
1.0,
],
"scale": 1.0,
},
],
),
Entity(
components: [
{
"component": "Camera",
"camera_type": FirstPerson,
"projectionmatrix": [
1.2990379,
0.0,
0.0,
0.0,
0.0,
1.7320507,
0.0,
0.0,
0.0,
0.0,
1.001001,
1.0,
0.0,
0.0,
-0.1001001,
0.0,
],
"fovy": 1.0471976,
"aspect": 1.3333334,
"near": 0.1,
"far": 100.0,
"is_active": true,
},
{
"component": "Transform",
"translation": [
0.0,
0.0,
5.0,
],
"rotation": [
0.0,
0.0,
0.0,
1.0,
],
"scale": 1.0,
},
],
),
],
)
4 changes: 3 additions & 1 deletion src/assets/asset_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ use parking_lot::{MappedMutexGuard, Mutex, MutexGuard};
#[cfg(feature = "render")]
use ash::vk;

use super::AssetHandle;
use crate::audio::AudioManager;

#[cfg(feature = "render")]
use super::AssetHandle;
#[cfg(feature = "render")]
use crate::render::*;

Expand Down
14 changes: 7 additions & 7 deletions src/assets/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,18 @@ pub use ser_component::*;
pub use settings::*;
pub use world_serializer::*;

use std::path::PathBuf;
use serde::{Serialize, Deserialize};

#[derive(Default, Clone, Debug, Serialize, Deserialize)]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum AssetLoadType {
#[default]
Resource,
Path(String),
Resource(String),
Path(PathBuf),
}

impl<T: ToString> From<T> for AssetLoadType {
fn from(value: T) -> Self {
AssetLoadType::Path(value.to_string())
impl Default for AssetLoadType {
fn default() -> Self {
AssetLoadType::Resource("".into())
}
}

Expand Down
118 changes: 83 additions & 35 deletions src/assets/scene.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
use std::path::Path;
use std::fs::read_to_string;
use std::sync::Arc;
use std::fs::File;
use std::io::{Read, Cursor};
use std::path::Path;
use std::fs::{File, read_to_string};

#[cfg(feature = "render")]
use image::ImageFormat;
use kira::sound::static_sound::{StaticSoundData, StaticSoundSettings};
use tar::EntryType;
use ron::ser::{Serializer, PrettyConfig};

Expand All @@ -10,13 +14,16 @@ use serde::{
Deserialize
};

use crate::audio::AudioError;
use crate::ecs::*;
use crate::error::*;
use crate::assets::{
asset_manager::*,
ser_component::*,
};

use super::AssetLoadType;

#[derive(Default, Serialize, Deserialize)]
#[serde(rename = "Entity")]
pub struct SerializableEntity {
Expand All @@ -40,8 +47,8 @@ impl Scene {
)?)
}

/// Load scene with assets from compressed `.lvl` package.
/// It is `.tar.lz4` package which can be created manually or with
/// Load scene with assets from compressed `.tar.lz4` package.
/// It is ordinary package which can be created manually or with
/// [Metio Editor](https://konceptosociala.eu.org/softvaro/metio).
///
/// It has the following structure:
Expand All @@ -56,40 +63,80 @@ impl Scene {
/// │ ├─ sound1.mp3
/// ```
pub fn load_packaged<P: AsRef<Path>>(path: P) -> DesperoResult<Self> {
// TODO: Packaged scene
//
let mut asset_manager = AssetManager::new();
let mut scene = Scene::new();

let package = File::open("assets.pkg")?;
let package = File::open(path)?;
let decoded = lz4::Decoder::new(package)?;
let mut archive = tar::Archive::new(decoded);

let mut entries = vec![]; // Vec<(Header, Vec<u8>)>

for file in archive.entries().unwrap() {
let file = file.unwrap();
let header = file.header();
match header.entry_type() {
EntryType::Regular => {
if header.path().unwrap() == Path::new("manager.ron") {
asset_manager = ron::de::from_reader(file)?;
let mut file = file.unwrap();
let header = file.header().clone();

let mut bytes = vec![];
file.read_to_end(&mut bytes)?;

entries.push((header, bytes));
}

for (header, file) in &mut entries {
let path = header.path().unwrap();
if path == Path::new("scene.ron") {
log::debug!("Deserializing scene `{}`...", path.display());
scene = ron::de::from_reader(&**file)?;
}
}

for (header, file) in entries {
let filepath = header.path().unwrap();

if header.entry_type() == EntryType::Regular {
let name = filepath
.file_stem()
.unwrap()
.to_os_string()
.into_string()
.unwrap();

#[cfg(feature = "render")]
let ext = filepath.extension().unwrap().to_owned();

if filepath.starts_with("textures") {
#[cfg(feature = "render")]
for texture in &mut scene.assets.textures {
if texture.load_type == AssetLoadType::Resource(name.clone()) {
let cursor = Cursor::new(file.clone());

let image = image::load(
cursor,
ImageFormat::from_extension(ext.clone()).expect("Wrong image extension!")
)
.map(|img| img.to_rgba8())
.expect("Unable to open image");

texture.image = Some(image);
}
}
},
EntryType::Directory => {
// if `sounds`:
//
//

// if `textures`:
// for texture in asset_manager.textures {
// let reader = BufReader::new(file);
// let image = image::load(reader, ImageFormat::from_path(path));
// texture.generate_from(image);
// }
//
},
_ => {},
} else if filepath.starts_with("audio") {
for sound in &mut scene.assets.audio.sounds {
if sound.load_type == AssetLoadType::Resource(name.clone()) {
let cursor = Cursor::new(file.clone());

let static_data = StaticSoundData::from_media_source(
cursor,
StaticSoundSettings::default(),
).map_err(|e| AudioError::from(e))?;

sound.static_data = Some(static_data);
}
}
}
}
}
Ok(Self::new())

Ok(scene)
}

pub fn save<P: AsRef<std::path::Path>>(&self, path: P) -> DesperoResult<()> {
Expand All @@ -111,9 +158,10 @@ pub trait SpawnSceneExt {

impl SpawnSceneExt for CommandBuffer {
fn spawn_scene(&mut self, scene: Scene, asset_manager: &mut AssetManager) {
self.write(|world| {
world.clear();
});
// self.write(|world| {
// world.clear();
// });
// TODO: Clear world

for entity in scene.entities {
let mut entity_builder = EntityBuilder::new();
Expand All @@ -131,7 +179,7 @@ impl SpawnSceneExt for CommandBuffer {

impl SpawnSceneExt for World {
fn spawn_scene(&mut self, scene: Scene, asset_manager: &mut AssetManager) {
self.clear();
// self.clear();

for entity in scene.entities {
let mut entity_builder = EntityBuilder::new();
Expand Down

0 comments on commit 389602a

Please sign in to comment.