rafx_plugins/assets/ldtk/
assets.rs

1use crate::shaders::tile_layer::tile_layer_frag;
2use fnv::FnvHashMap;
3use glam::Vec3;
4use hydrate_base::handle::Handle;
5use hydrate_base::LoadHandle;
6use rafx::api::RafxResult;
7use rafx::assets::{
8    AssetManager, BufferAsset, DefaultAssetTypeHandler, DefaultAssetTypeLoadHandler, ImageAsset,
9    MaterialInstanceAsset,
10};
11use rafx::framework::{BufferResource, DescriptorSetArc, ResourceArc};
12use serde::{Deserialize, Serialize};
13use std::sync::Arc;
14use type_uuid::*;
15
16pub type LevelUid = i64;
17pub type TileSetUid = i64;
18
19#[derive(Serialize, Deserialize, Clone, Debug)]
20pub struct LdtkLayerDrawCallData {
21    pub vertex_data_offset_in_bytes: u32,
22    pub index_data_offset_in_bytes: u32,
23    pub index_count: u32,
24    pub z_pos: f32,
25}
26
27#[derive(Serialize, Deserialize, Clone, Debug)]
28pub struct LdtkLayerData {
29    pub material_instance: Handle<MaterialInstanceAsset>,
30    pub draw_call_data: Vec<LdtkLayerDrawCallData>,
31    pub z_pos: f32,
32    pub world_x_pos: i64,
33    pub world_y_pos: i64,
34    pub grid_width: i64,
35    pub grid_height: i64,
36    pub grid_size: i64,
37}
38
39#[derive(Serialize, Deserialize, Clone, Debug)]
40pub struct LdtkLevelData {
41    pub layer_data: Vec<LdtkLayerData>,
42    pub vertex_data: Option<Handle<BufferAsset>>,
43    pub index_data: Option<Handle<BufferAsset>>,
44}
45
46#[derive(Serialize, Deserialize, Clone, Debug)]
47pub struct LdtkTileSet {
48    pub image: Handle<ImageAsset>,
49    pub material_instance: Handle<MaterialInstanceAsset>,
50    pub image_width: u32,
51    pub image_height: u32,
52}
53
54#[derive(TypeUuid, Serialize, Deserialize, Clone, Debug)]
55#[uuid = "1eb04266-4a32-473a-a54a-70b4d1172877"]
56pub struct LdtkAssetData {
57    pub tilesets: FnvHashMap<TileSetUid, LdtkTileSet>,
58    pub levels: FnvHashMap<LevelUid, LdtkLevelData>,
59}
60
61#[derive(Clone, Debug)]
62pub struct LdtkLayer {
63    pub per_layer_descriptor_set: DescriptorSetArc,
64    pub width: i64,
65    pub height: i64,
66    pub center: Vec3,
67}
68
69#[derive(Clone, Debug)]
70pub struct LdtkLevel {
71    pub layers: Vec<LdtkLayer>,
72    pub vertex_buffer: Option<ResourceArc<BufferResource>>,
73    pub index_buffer: Option<ResourceArc<BufferResource>>,
74}
75
76#[derive(Debug)]
77pub struct LdtkProjectAssetInner {
78    pub data: LdtkAssetData,
79    pub levels: FnvHashMap<LevelUid, LdtkLevel>,
80}
81
82#[derive(TypeUuid, Clone, Debug)]
83#[uuid = "231e4fd5-add2-4024-a479-d8181b3e52a3"]
84pub struct LdtkProjectAsset {
85    pub inner: Arc<LdtkProjectAssetInner>,
86}
87
88pub struct LdtkLoadHandler;
89
90impl DefaultAssetTypeLoadHandler<LdtkAssetData, LdtkProjectAsset> for LdtkLoadHandler {
91    #[profiling::function]
92    fn load(
93        asset_manager: &mut AssetManager,
94        ldtk_asset: LdtkAssetData,
95        _load_handle: LoadHandle,
96    ) -> RafxResult<LdtkProjectAsset> {
97        let mut levels = FnvHashMap::<LevelUid, LdtkLevel>::default();
98        for (&level_uid, level_data) in &ldtk_asset.levels {
99            let mut layers = Vec::default();
100            for layer_data in &level_data.layer_data {
101                let material_instance = asset_manager
102                    .latest_asset(&layer_data.material_instance)
103                    .unwrap();
104                let _material_pass = material_instance
105                    .material
106                    .get_single_material_pass()
107                    .expect("tileset material must have a single pass for opaque phase");
108                let material_pass_index = 0;
109                let tileset_image_set_index = tile_layer_frag::TEX_DESCRIPTOR_SET_INDEX;
110                let descriptor_set = material_instance.material_descriptor_sets
111                    [material_pass_index][tileset_image_set_index]
112                    .clone()
113                    .unwrap();
114
115                let width = layer_data.grid_width * layer_data.grid_size;
116                let height = layer_data.grid_height * layer_data.grid_size;
117                layers.push(LdtkLayer {
118                    per_layer_descriptor_set: descriptor_set,
119                    center: Vec3::new(
120                        (layer_data.world_x_pos + (width / 2)) as f32,
121                        (layer_data.world_y_pos + (height / 2)) as f32,
122                        layer_data.z_pos,
123                    ),
124                    width,
125                    height,
126                });
127            }
128
129            let mut vertex_buffer = None;
130            let mut index_buffer = None;
131
132            if let (Some(vertex_data_handle), Some(index_data_handle)) =
133                (&level_data.vertex_data, &level_data.index_data)
134            {
135                vertex_buffer = Some(
136                    asset_manager
137                        .latest_asset(&vertex_data_handle)
138                        .unwrap()
139                        .buffer
140                        .clone(),
141                );
142                index_buffer = Some(
143                    asset_manager
144                        .latest_asset(&index_data_handle)
145                        .unwrap()
146                        .buffer
147                        .clone(),
148                );
149            }
150
151            levels.insert(
152                level_uid,
153                LdtkLevel {
154                    layers,
155                    vertex_buffer,
156                    index_buffer,
157                },
158            );
159        }
160
161        let inner = LdtkProjectAssetInner {
162            data: ldtk_asset,
163            levels,
164        };
165
166        Ok(LdtkProjectAsset {
167            inner: Arc::new(inner),
168        })
169    }
170}
171
172pub type LdtkAssetType = DefaultAssetTypeHandler<LdtkAssetData, LdtkProjectAsset, LdtkLoadHandler>;