From c9df9af38b10ce5a747849deb65f6061d86e6c9a Mon Sep 17 00:00:00 2001 From: Louis Capitanchik <contact@louiscap.co> Date: Sun, 22 Jan 2023 20:11:55 +0000 Subject: [PATCH] Include map to image generation --- Cargo.lock | 322 ++++++++++++++++++++++++++++++++++++----------- Cargo.toml | 1 + src/assets.rs | 6 +- src/lib.rs | 13 +- src/map_query.rs | 62 ++++++++- src/pregen.rs | 123 ++++++++++++++++++ src/types.rs | 114 ++++++++++++++++- 7 files changed, 551 insertions(+), 90 deletions(-) create mode 100644 src/pregen.rs diff --git a/Cargo.lock b/Cargo.lock index a0c9e2c..f13ccec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -310,8 +310,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7baf73c58d41c353c6fd08e6764a2e7420c9f19e8227b391c50981db6d0282a6" dependencies = [ "bevy_macro_utils", - "quote", - "syn", + "quote 1.0.23", + "syn 1.0.107", ] [[package]] @@ -355,9 +355,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c15bd45438eeb681ad74f2d205bb07a5699f98f9524462a30ec764afab2742ce" dependencies = [ "bevy_macro_utils", - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.49", + "quote 1.0.23", + "syn 1.0.107", ] [[package]] @@ -501,8 +501,8 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "022bb69196deeea691b6997414af85bbd7f2b34a8914c4aa7a7ff4dfa44f7677" dependencies = [ - "quote", - "syn", + "quote 1.0.23", + "syn 1.0.107", "toml", ] @@ -581,9 +581,9 @@ checksum = "a2bf4cb9cd5acb4193f890f36cb63679f1502e2de025e66a63b194b8b133d018" dependencies = [ "bevy_macro_utils", "bit-set", - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.49", + "quote 1.0.23", + "syn 1.0.107", "uuid", ] @@ -636,9 +636,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7acae697776ac05bea523e1725cf2660c91c53abe72c66782ea1e1b9eedb572" dependencies = [ "bevy_macro_utils", - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.49", + "quote 1.0.23", + "syn 1.0.107", ] [[package]] @@ -842,12 +842,12 @@ dependencies = [ "lazy_static", "lazycell", "peeking_take_while", - "proc-macro2", - "quote", + "proc-macro2 1.0.49", + "quote 1.0.23", "regex", "rustc-hash", "shlex", - "syn", + "syn 1.0.107", ] [[package]] @@ -898,9 +898,9 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5fe233b960f12f8007e3db2d136e3cb1c291bfd7396e384ee76025fc1a3932b4" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.49", + "quote 1.0.23", + "syn 1.0.107", ] [[package]] @@ -1189,14 +1189,38 @@ dependencies = [ "winapi", ] +[[package]] +name = "darling" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcfbcb0c5961907597a7d1148e3af036268f2b773886b8bb3eeb1e1281d3d3d6" +dependencies = [ + "darling_core 0.9.0", + "darling_macro 0.9.0", +] + [[package]] name = "darling" version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" dependencies = [ - "darling_core", - "darling_macro", + "darling_core 0.13.4", + "darling_macro 0.13.4", +] + +[[package]] +name = "darling_core" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6afc018370c3bff3eb51f89256a6bdb18b4fdcda72d577982a14954a7a0b402c" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2 0.4.30", + "quote 0.6.13", + "strsim 0.7.0", + "syn 0.15.44", ] [[package]] @@ -1207,10 +1231,21 @@ checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" dependencies = [ "fnv", "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn", + "proc-macro2 1.0.49", + "quote 1.0.23", + "strsim 0.10.0", + "syn 1.0.107", +] + +[[package]] +name = "darling_macro" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6d8dac1c6f1d29a41c4712b4400f878cb4fcc4c7628f298dd75038e024998d1" +dependencies = [ + "darling_core 0.9.0", + "quote 0.6.13", + "syn 0.15.44", ] [[package]] @@ -1219,9 +1254,34 @@ version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" dependencies = [ - "darling_core", - "quote", - "syn", + "darling_core 0.13.4", + "quote 1.0.23", + "syn 1.0.107", +] + +[[package]] +name = "derive_builder" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ac53fa6a3cda160df823a9346442525dcaf1e171999a1cf23e67067e4fd64d4" +dependencies = [ + "darling 0.9.0", + "derive_builder_core", + "proc-macro2 0.4.30", + "quote 0.6.13", + "syn 0.15.44", +] + +[[package]] +name = "derive_builder_core" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0288a23da9333c246bb18c143426074a6ae96747995c5819d2947b64cd942b37" +dependencies = [ + "darling 0.9.0", + "proc-macro2 0.4.30", + "quote 0.6.13", + "syn 0.15.44", ] [[package]] @@ -1269,9 +1329,9 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec27b639e942eb0297513b81cc6d87c50f6c77dc8c37af00a39ed5db3b9657ee" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.49", + "quote 1.0.23", + "syn 1.0.107", ] [[package]] @@ -1503,9 +1563,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bdd53d6e284bb2bf02a6926e4cc4984978c1990914d6cd9deae4e31cf37cd113" dependencies = [ "inflections", - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.49", + "quote 1.0.23", + "syn 1.0.107", ] [[package]] @@ -1595,9 +1655,9 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59d2aba832b60be25c1b169146b27c64115470981b128ed84c8db18c1b03c6ff" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.49", + "quote 1.0.23", + "syn 1.0.107", ] [[package]] @@ -1647,7 +1707,7 @@ dependencies = [ "bytemuck", "byteorder", "color_quant", - "num-rational", + "num-rational 0.4.1", "num-traits", "png", "scoped_threadpool", @@ -1922,13 +1982,14 @@ dependencies = [ [[package]] name = "micro_ldtk" -version = "0.1.0" +version = "0.2.0" dependencies = [ "anyhow", "bevy", "ldtk_rust", "log", "num-traits", + "quadtree_rs", "serde", "serde_json", ] @@ -1979,7 +2040,7 @@ dependencies = [ "spirv", "termcolor", "thiserror", - "unicode-xid", + "unicode-xid 0.2.4", ] [[package]] @@ -2038,11 +2099,11 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0df7ac00c4672f9d5aece54ee3347520b7e20f158656c7db2e6de01902eb7a6c" dependencies = [ - "darling", + "darling 0.13.4", "proc-macro-crate", - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.49", + "quote 1.0.23", + "syn 1.0.107", ] [[package]] @@ -2126,15 +2187,50 @@ dependencies = [ "winapi", ] +[[package]] +name = "num" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8536030f9fea7127f841b45bb6243b27255787fb4eb83958aa1ef9d2fdc0c36" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational 0.2.4", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95" +dependencies = [ + "autocfg", + "num-traits", +] + [[package]] name = "num-derive" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.49", + "quote 1.0.23", + "syn 1.0.107", ] [[package]] @@ -2147,6 +2243,29 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-iter" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" +dependencies = [ + "autocfg", + "num-bigint", + "num-integer", + "num-traits", +] + [[package]] name = "num-rational" version = "0.4.1" @@ -2183,9 +2302,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b0498641e53dd6ac1a4f22547548caa6864cc4933784319cd1775271c5a46ce" dependencies = [ "proc-macro-crate", - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.49", + "quote 1.0.23", + "syn 1.0.107", ] [[package]] @@ -2341,7 +2460,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb458bb7f6e250e6eb79d5026badc10a3ebb8f9a15d1fff0f13d17c71f4d6dee" dependencies = [ - "unicode-xid", + "unicode-xid 0.2.4", ] [[package]] @@ -2355,6 +2474,15 @@ dependencies = [ "toml", ] +[[package]] +name = "proc-macro2" +version = "0.4.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" +dependencies = [ + "unicode-xid 0.1.0", +] + [[package]] name = "proc-macro2" version = "1.0.49" @@ -2370,13 +2498,32 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74605f360ce573babfe43964cbe520294dcb081afbf8c108fc6e23036b4da2df" +[[package]] +name = "quadtree_rs" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ec1506903c0f5cff273bd34df6646c7040f2a7c5b0a92a9179d89551bed9ffd" +dependencies = [ + "derive_builder", + "num", +] + +[[package]] +name = "quote" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" +dependencies = [ + "proc-macro2 0.4.30", +] + [[package]] name = "quote" version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" dependencies = [ - "proc-macro2", + "proc-macro2 1.0.49", ] [[package]] @@ -2549,9 +2696,9 @@ version = "1.0.152" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.49", + "quote 1.0.23", + "syn 1.0.107", ] [[package]] @@ -2658,11 +2805,11 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" dependencies = [ - "proc-macro2", - "quote", + "proc-macro2 1.0.49", + "quote 1.0.23", "serde", "serde_derive", - "syn", + "syn 1.0.107", ] [[package]] @@ -2672,13 +2819,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" dependencies = [ "base-x", - "proc-macro2", - "quote", + "proc-macro2 1.0.49", + "quote 1.0.23", "serde", "serde_derive", "serde_json", "sha1", - "syn", + "syn 1.0.107", ] [[package]] @@ -2687,6 +2834,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" +[[package]] +name = "strsim" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" + [[package]] name = "strsim" version = "0.10.0" @@ -2699,14 +2852,25 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fb1df15f412ee2e9dfc1c504260fa695c1c3f10fe9f4a6ee2d2184d7d6450e2" +[[package]] +name = "syn" +version = "0.15.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" +dependencies = [ + "proc-macro2 0.4.30", + "quote 0.6.13", + "unicode-xid 0.1.0", +] + [[package]] name = "syn" version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" dependencies = [ - "proc-macro2", - "quote", + "proc-macro2 1.0.49", + "quote 1.0.23", "unicode-ident", ] @@ -2747,9 +2911,9 @@ version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.49", + "quote 1.0.23", + "syn 1.0.107", ] [[package]] @@ -2803,9 +2967,9 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.49", + "quote 1.0.23", + "syn 1.0.107", ] [[package]] @@ -2882,6 +3046,12 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +[[package]] +name = "unicode-xid" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" + [[package]] name = "unicode-xid" version = "0.2.4" @@ -2958,9 +3128,9 @@ dependencies = [ "bumpalo", "log", "once_cell", - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.49", + "quote 1.0.23", + "syn 1.0.107", "wasm-bindgen-shared", ] @@ -2982,7 +3152,7 @@ version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" dependencies = [ - "quote", + "quote 1.0.23", "wasm-bindgen-macro-support", ] @@ -2992,9 +3162,9 @@ version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2 1.0.49", + "quote 1.0.23", + "syn 1.0.107", "wasm-bindgen-backend", "wasm-bindgen-shared", ] diff --git a/Cargo.toml b/Cargo.toml index 155f24e..45d190d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,4 +17,5 @@ serde = "1.0.147" serde_json = "1.0.87" ldtk_rust = "0.6.0" num-traits = "0.2.15" +quadtree_rs = "0.1.2" diff --git a/src/assets.rs b/src/assets.rs index b9101ef..8e450e2 100644 --- a/src/assets.rs +++ b/src/assets.rs @@ -3,13 +3,13 @@ use std::ops::{Deref, DerefMut}; use anyhow::Error; use bevy::asset::{AssetEvent, AssetLoader, Assets, BoxedFuture, LoadContext, LoadedAsset}; -use bevy::prelude::{EventReader, Res, ResMut, Resource}; +use bevy::prelude::{EventReader, EventWriter, Res, ResMut, Resource}; use bevy::reflect::TypeUuid; use ldtk_rust::Project; use serde_json::Value; use crate::utils::SerdeClone; -use crate::LdtkLevel; +use crate::{LdtkLevel, LevelDataUpdated}; #[derive(TypeUuid)] #[uuid = "292a8918-9487-11ed-8dd2-43b6f36cb076"] @@ -87,6 +87,7 @@ pub fn handle_ldtk_project_events( assets: Res<Assets<LdtkProject>>, mut level_index: ResMut<LevelIndex>, mut tilset_index: ResMut<TilesetIndex>, + mut update_events: EventWriter<LevelDataUpdated>, ) { for event in events.iter() { match event { @@ -97,6 +98,7 @@ pub fn handle_ldtk_project_events( level.identifier.clone(), LdtkLevel::from(level.serde_clone()), ); + update_events.send(LevelDataUpdated(level.identifier.clone())); } for tileset in &project.defs.tilesets { diff --git a/src/lib.rs b/src/lib.rs index 53bb4f2..c280b1b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,6 +2,7 @@ mod assets; mod camera; mod locator; mod map_query; +mod pregen; mod types; pub(crate) mod utils; // mod spawning; @@ -28,10 +29,13 @@ mod __plugin { use bevy::asset::AddAsset; use bevy::ecs::query::ReadOnlyWorldQuery; + use crate::LevelDataUpdated; + pub struct MicroLDTKPlugin; impl Plugin for MicroLDTKPlugin { fn build(&self, app: &mut App) { - app.init_resource::<super::assets::TilesetIndex>() + app.add_event::<LevelDataUpdated>() + .init_resource::<super::assets::TilesetIndex>() .init_resource::<super::assets::LevelIndex>() .add_asset::<super::assets::LdtkProject>() .add_asset_loader(super::assets::LdtkLoader) @@ -75,5 +79,8 @@ pub use __plugin::{MicroLDTKCameraPlugin, MicroLDTKPlugin}; pub use assets::{LdtkLoader, LdtkProject, LevelIndex, TileMetadata, TilesetIndex}; pub use camera::CameraBounder; pub use map_query::{CameraBounds, MapQuery}; -pub use types::{LdtkLayer, LdtkLevel, SpatialIndex, TileFlip, TileRef}; -pub use utils::{entity_centre, grid_to_px, px_to_grid, ActiveLevel, WorldLinked}; +pub use pregen::{ + write_layer_to_texture, write_map_to_texture, Rasterise, SuppliesImage, SuppliesTextureAtlas, +}; +pub use types::{LdtkLayer, LdtkLevel, LevelDataUpdated, SpatialIndex, TileFlip, TileRef}; +pub use utils::{entity_centre, grid_to_px, px_to_grid, ActiveLevel, Indexer, WorldLinked}; diff --git a/src/map_query.rs b/src/map_query.rs index 29afdd8..43c6243 100644 --- a/src/map_query.rs +++ b/src/map_query.rs @@ -23,6 +23,19 @@ pub struct InstanceRef<'a> { } impl<'a> InstanceRef<'a> { + pub fn x(&self) -> i64 { + self.entity.px[0] + } + pub fn y(&self) -> i64 { + self.entity.px[1] + } + pub fn width(&self) -> i64 { + self.entity.width + } + pub fn height(&self) -> i64 { + self.entity.height + } + pub fn get_type(&self) -> &'a String { &self.entity.identifier } @@ -55,16 +68,16 @@ pub struct CameraBounds { impl CameraBounds { pub fn get_min_x(&self, camera_width: f32) -> f32 { - self.left + (camera_width / 2.0) - (get_ldtk_tile_scale() / 2.0) + self.left + (camera_width / 2.0) // - (get_ldtk_tile_scale() / 2.0) } pub fn get_max_x(&self, camera_width: f32) -> f32 { - self.right - (camera_width / 2.0) - (get_ldtk_tile_scale() / 2.0) + self.right - (camera_width / 2.0) // - (get_ldtk_tile_scale() / 2.0) } pub fn get_min_y(&self, camera_height: f32) -> f32 { - self.bottom + (camera_height / 2.0) - (get_ldtk_tile_scale() / 2.0) + self.bottom + (camera_height / 2.0) // - (get_ldtk_tile_scale() / 2.0) } pub fn get_max_y(&self, camera_height: f32) -> f32 { - self.top - (camera_height / 2.0) - (get_ldtk_tile_scale() / 2.0) + self.top - (camera_height / 2.0) // - (get_ldtk_tile_scale() / 2.0) } } @@ -79,6 +92,10 @@ impl<'w, 's> MapQuery<'w, 's> { } } + pub fn get_layers_of(level: &LdtkLevel) -> impl DoubleEndedIterator<Item = &LdtkLayer> { + level.layers() + } + pub fn get_entities_of(level: &LdtkLevel) -> Vec<&EntityInstance> { level .layers() @@ -111,6 +128,24 @@ impl<'w, 's> MapQuery<'w, 's> { .collect() } + pub fn get_filtered_instance_refs_of( + level: &LdtkLevel, + entity_type: impl ToString, + ) -> Vec<InstanceRef> { + let e_type = entity_type.to_string(); + level + .layers() + .flat_map(|layer| { + layer + .as_ref() + .entity_instances + .iter() + .map(|inst| InstanceRef { entity: inst }) + }) + .filter(|inst| inst.entity.identifier == e_type) + .collect() + } + pub fn get_owned_entities_of(level: &LdtkLevel) -> Vec<EntityInstance> { level .layers() @@ -134,10 +169,20 @@ impl<'w, 's> MapQuery<'w, 's> { } } - pub fn get_active_level(&self) -> Option<&LdtkLevel> { + pub fn active_level_is(&self, name: impl ToString) -> bool { self.active .as_ref() - .and_then(|index| self.index.get(&index.map)) + .map(|active_level| active_level.map == name.to_string()) + .unwrap_or(false) + } + + pub fn get_active_level_name(&self) -> Option<&String> { + self.active.as_ref().map(|m| &m.map) + } + + pub fn get_active_level(&self) -> Option<&LdtkLevel> { + self.get_active_level_name() + .and_then(|index| self.index.get(index)) } pub fn get_entities(&self) -> Vec<&EntityInstance> { @@ -145,6 +190,11 @@ impl<'w, 's> MapQuery<'w, 's> { .map(MapQuery::get_entities_of) .unwrap_or_default() } + pub fn get_instance_refs(&self) -> Vec<InstanceRef> { + self.get_active_level() + .map(MapQuery::get_instance_refs_of) + .unwrap_or_default() + } pub fn get_camera_bounds(&self) -> Option<CameraBounds> { self.get_active_level().map(MapQuery::get_camera_bounds_of) diff --git a/src/pregen.rs b/src/pregen.rs new file mode 100644 index 0000000..84cb9e4 --- /dev/null +++ b/src/pregen.rs @@ -0,0 +1,123 @@ +use bevy::prelude::{Handle, Image, TextureAtlas}; +use bevy::render::render_resource::TextureFormat; +use bevy::render::texture::TextureFormatPixelInfo; + +use crate::{get_ldtk_tile_scale, Indexer, LdtkLayer, LdtkLevel}; + +pub fn write_layer_to_texture( + layer: &LdtkLayer, + buffer: &mut Vec<u8>, + format: &TextureFormat, + image: &Image, + atlas: &TextureAtlas, +) { + if !layer.has_tiles() { + return; + } + + let tile_size = get_ldtk_tile_scale(); + let layer_indexer = Indexer::new( + layer.indexer().width() * tile_size as i64, + layer.indexer().height() * tile_size as i64, + ); + let texture_indexer = Indexer::new(image.size().x, image.size().y); + + layer.for_each_tile(|x, y, tile| { + let part = match atlas.textures.get(tile.tile.t as usize) { + Some(rect) => rect, + None => return, + }; + + let real_x = x * tile_size as i64; + let real_y = y * tile_size as i64; + + for relative_x in 0..part.width() as usize { + for relative_y in 0..part.height() as usize { + let tile_image_x = part.min.x as usize + relative_x; + let tile_image_y = part.min.y as usize + relative_y; + let tile_index = texture_indexer.index(tile_image_x, tile_image_y); + + let output_x = real_x as usize + relative_x; + let output_y = real_y as usize + relative_y; + let output_index = layer_indexer.index(output_x, output_y); + + if let Some(target_pixel) = + image.data.chunks_exact(format.pixel_size()).nth(tile_index) + { + if let Some(map_px) = buffer + .chunks_exact_mut(format.pixel_size()) + .nth(output_index) + { + if target_pixel.iter().any(|p| p != &0) { + map_px.copy_from_slice(target_pixel); + } + } + }; + } + } + }); +} + +pub fn write_map_to_texture( + level: &LdtkLevel, + buffer: &mut Vec<u8>, + format: &TextureFormat, + image: &Image, + atlas: &TextureAtlas, +) { + for layer in level.layers() { + write_layer_to_texture(layer, buffer, format, image, atlas); + } +} + +pub trait SuppliesTextureAtlas { + fn get_atlas_handle(&self, name: impl ToString) -> Option<&Handle<TextureAtlas>>; + fn get_atlas(&self, name: &Handle<TextureAtlas>) -> Option<&TextureAtlas>; +} +pub trait SuppliesImage { + fn get_image_handle(&self, name: impl ToString) -> Option<&Handle<Image>>; + fn get_image(&self, handle: &Handle<Image>) -> Option<&Image>; +} + +pub trait Rasterise { + fn write_to_texture( + &self, + buffer: &mut Vec<u8>, + format: &TextureFormat, + images: &impl SuppliesImage, + atlas: &impl SuppliesTextureAtlas, + ); +} + +impl Rasterise for LdtkLevel { + fn write_to_texture( + &self, + buffer: &mut Vec<u8>, + format: &TextureFormat, + images: &impl SuppliesImage, + atlas: &impl SuppliesTextureAtlas, + ) { + for layer in self.layers() { + layer.write_to_texture(buffer, format, images, atlas); + } + } +} +impl Rasterise for LdtkLayer { + fn write_to_texture( + &self, + buffer: &mut Vec<u8>, + format: &TextureFormat, + images: &impl SuppliesImage, + atlas: &impl SuppliesTextureAtlas, + ) { + if let Some(atlas) = self + .infer_tileset_name() + .and_then(|tn| atlas.get_atlas_handle(tn)) + .and_then(|hn| atlas.get_atlas(hn)) + { + if let Some(image) = images.get_image(&atlas.texture) { + write_layer_to_texture(self, buffer, format, image, atlas); + } + } + } +} diff --git a/src/types.rs b/src/types.rs index 7fa9a4b..676ad47 100644 --- a/src/types.rs +++ b/src/types.rs @@ -5,9 +5,16 @@ use bevy::math::{IVec2, UVec2}; use bevy::utils::HashMap; use ldtk_rust::{LayerInstance, Level, TileInstance}; use num_traits::AsPrimitive; +use quadtree_rs::area::{Area, AreaBuilder}; +use quadtree_rs::point::Point; +use quadtree_rs::Quadtree; +use serde_json::Value; use crate::utils::{Indexer, SerdeClone}; -use crate::{get_ldtk_tile_scale, px_to_grid}; +use crate::{get_ldtk_tile_scale, px_to_grid, MapQuery}; + +#[derive(Default, Clone, Debug, Ord, PartialOrd, PartialEq, Eq)] +pub struct LevelDataUpdated(pub String); pub struct TileRef<'a> { pub tile: &'a TileInstance, @@ -89,49 +96,146 @@ impl From<IVec2> for SpatialIndex { } } +pub type ColliderQuadtree = Quadtree<i64, LocatedEntity>; + pub struct LdtkLevel { level: Level, + properties: HashMap<String, Value>, processed_layers: Vec<LdtkLayer>, + colliders: ColliderQuadtree, } impl LdtkLevel { + pub fn width(&self) -> f32 { + self.level.px_wid as f32 + } + pub fn width_i(&self) -> i64 { + self.level.px_wid + } + pub fn height(&self) -> f32 { + self.level.px_hei as f32 + } + pub fn height_i(&self) -> i64 { + self.level.px_hei + } pub fn level_ref(&self) -> &Level { &self.level } pub fn level_ref_mut(&mut self) -> &mut Level { &mut self.level } + pub fn colliders_ref(&self) -> &ColliderQuadtree { + &self.colliders + } + pub fn colliders_ref_mut(&mut self) -> &mut ColliderQuadtree { + &mut self.colliders + } pub fn layers(&self) -> impl DoubleEndedIterator<Item = &LdtkLayer> { self.processed_layers.iter() } pub fn layers_mut(&mut self) -> impl DoubleEndedIterator<Item = &mut LdtkLayer> { self.processed_layers.iter_mut() } + pub fn properties_ref(&self) -> &HashMap<String, Value> { + &self.properties + } + pub fn properties_mut(&mut self) -> &mut HashMap<String, Value> { + &mut self.properties + } + pub fn property(&self, name: impl ToString) -> Option<&Value> { + self.properties.get(&name.to_string()) + } + pub fn property_or_null(&self, name: impl ToString) -> &Value { + self.property(name).unwrap_or_else(|| &Value::Null) + } pub fn get_indexer(&self) -> Indexer { Indexer::new(px_to_grid(self.level.px_wid), px_to_grid(self.level.px_hei)) } } +#[derive(Debug, Clone, Default)] +pub struct LocatedEntity { + pub position: IVec2, + pub size: IVec2, + pub properties: HashMap<String, Value>, + pub collides: bool, +} + impl From<Level> for LdtkLevel { fn from(mut value: Level) -> Self { let layers = value.layer_instances.take(); + let mut properties = HashMap::with_capacity(value.field_instances.len()); + let fields = std::mem::take(&mut value.field_instances); - Self { + for field in fields { + properties.insert(field.identifier, field.value.unwrap_or_else(|| Value::Null)); + } + + let level_width = value.px_wid; + let level_height = value.px_hei; + + let mut level = Self { + colliders: Quadtree::new(0), processed_layers: layers .unwrap_or_default() .into_iter() + .rev() .enumerate() .map(|(idx, inst)| LdtkLayer::new(idx, inst)) .collect(), level: value, + properties, + }; + + let mut collider_quads = Quadtree::<i64, LocatedEntity>::new(32); + for entity in MapQuery::get_entities_of(&level) { + if entity.tags.contains(&String::from("Collider")) { + let mut properties = HashMap::with_capacity(entity.field_instances.len()); + for field in entity.field_instances.iter() { + properties.insert( + field.identifier.clone(), + field.value.as_ref().unwrap_or_else(|| &Value::Null).clone(), + ); + } + + let width = entity.width; + let height = entity.height; + let left_x = entity.px[0]; + let bottom_y = level_height - (entity.px[1] + height); + + let size = IVec2::new(entity.width as i32, entity.height as i32); + let position = IVec2::new(level.level.px_wid as i32, level.level.px_hei as i32) + - (IVec2::new(entity.px[0] as i32, entity.px[1] as i32) + size); + + let entity = LocatedEntity { + position, + size, + properties, + collides: true, + }; + + match AreaBuilder::default() + .anchor(Point::from((position.x as i64, position.y as i64))) + .dimensions((size.x as i64, size.y as i64)) + .build() + { + Ok(point) => { + collider_quads.insert(point, entity); + } + Err(_) => {} + } + } } + + level.colliders = collider_quads; + level } } pub struct LdtkLayer { + pub level: usize, layer: LayerInstance, position_lookup: HashMap<SpatialIndex, TileInstance>, - level: usize, indexer: Indexer, } @@ -159,6 +263,10 @@ impl LdtkLayer { } } + pub fn name(&self) -> &String { + &self.layer.identifier + } + pub fn indexer(&self) -> Indexer { self.indexer } -- GitLab