rafx_plugins/assets/ldtk/
assets.rs1use 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>;