From f7a3a56a0a58ada8d1a4c3ace49920c9ec0b70c4 Mon Sep 17 00:00:00 2001 From: Amatsugu Date: Sun, 4 Aug 2024 21:45:23 -0400 Subject: [PATCH] Added generation of images based on the map Tweaks to consistency with DIRECTIONS and HEX_CORNERS Misc debug visualizations --- Cargo.lock | 426 +++++++++++++++++- engine/world_generation/Cargo.toml | 1 + .../src/generators/chunk_colliders.rs | 6 +- engine/world_generation/src/heightmap.rs | 61 ++- engine/world_generation/src/hex_utils.rs | 8 +- engine/world_generation/src/map/biome_map.rs | 1 + engine/world_generation/src/map/chunk.rs | 4 + engine/world_generation/src/map/map.rs | 50 +- engine/world_generation/src/map/map_utils.rs | 115 +++++ engine/world_generation/src/map/mesh_chunk.rs | 2 +- engine/world_generation/src/map/mod.rs | 3 +- game/main/src/map_rendering/map_init.rs | 6 + game/main/src/utlis/debug_plugin.rs | 9 + 13 files changed, 671 insertions(+), 21 deletions(-) create mode 100644 engine/world_generation/src/map/map_utils.rs diff --git a/Cargo.lock b/Cargo.lock index 15925f1..caf296d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -102,6 +102,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "aligned-vec" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4aa90d7ce82d4be67b64039a3d588d38dbcc6736577de4a847025ce5b0c468d1" + [[package]] name = "allocator-api2" version = "0.2.18" @@ -186,6 +192,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "arbitrary" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" + [[package]] name = "arboard" version = "3.4.0" @@ -194,7 +206,7 @@ checksum = "9fb4009533e8ff8f1450a5bcbc30f4242a1d34442221f72314bea1f5dc9c7f89" dependencies = [ "clipboard-win", "core-graphics", - "image 0.25.1", + "image 0.25.2", "log", "objc2", "objc2-app-kit", @@ -204,6 +216,17 @@ dependencies = [ "x11rb", ] +[[package]] +name = "arg_enum_proc_macro" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.70", +] + [[package]] name = "arrayref" version = "0.3.7" @@ -316,6 +339,29 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +[[package]] +name = "av1-grain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6678909d8c5d46a42abcf571271e15fdbc0a225e3646cf23762cd415046c78bf" +dependencies = [ + "anyhow", + "arrayvec", + "log", + "nom", + "num-rational", + "v_frame", +] + +[[package]] +name = "avif-serialize" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876c75a42f6364451a033496a14c44bffe41f5f4a8236f697391f11024e596d2" +dependencies = [ + "arrayvec", +] + [[package]] name = "base64" version = "0.21.7" @@ -1001,7 +1047,7 @@ dependencies = [ "encase", "futures-lite", "hexasphere", - "image 0.25.1", + "image 0.25.2", "js-sys", "ktx2", "naga", @@ -1301,6 +1347,12 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" +[[package]] +name = "bit_field" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" + [[package]] name = "bitflags" version = "1.3.2" @@ -1316,6 +1368,12 @@ dependencies = [ "serde", ] +[[package]] +name = "bitstream-io" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dcde5f311c85b8ca30c2e4198d4326bc342c76541590106f5fa4a50946ea499" + [[package]] name = "blake3" version = "1.5.1" @@ -1372,6 +1430,12 @@ dependencies = [ "world_generation", ] +[[package]] +name = "built" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "236e6289eda5a812bc6b53c3b024039382a2895fbbeef2d748b2931546d392c4" + [[package]] name = "bumpalo" version = "3.16.0" @@ -1404,6 +1468,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + [[package]] name = "bytes" version = "1.6.0" @@ -1462,6 +1532,16 @@ dependencies = [ "nom", ] +[[package]] +name = "cfg-expr" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" +dependencies = [ + "smallvec", + "target-lexicon", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -1767,6 +1847,12 @@ version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + [[package]] name = "cursor-icon" version = "1.1.0" @@ -1984,6 +2070,22 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "exr" +version = "1.72.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "887d93f60543e9a9362ef8a21beedd0a833c5d9610e18c67abe15a5963dcb1a4" +dependencies = [ + "bit_field", + "flume", + "half", + "lebe", + "miniz_oxide", + "rayon-core", + "smallvec", + "zune-inflate", +] + [[package]] name = "fastrand" version = "2.1.0" @@ -2021,6 +2123,15 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "flume" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +dependencies = [ + "spin", +] + [[package]] name = "fnv" version = "1.0.7" @@ -2145,6 +2256,16 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "gif" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2" +dependencies = [ + "color_quant", + "weezl", +] + [[package]] name = "gilrs" version = "0.10.8" @@ -2343,6 +2464,16 @@ dependencies = [ "svg_fmt", ] +[[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] + [[package]] name = "hashbrown" version = "0.14.5" @@ -2369,6 +2500,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.4.0" @@ -2424,17 +2561,43 @@ dependencies = [ [[package]] name = "image" -version = "0.25.1" +version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd54d660e773627692c524beaad361aca785a4f9f5730ce91f42aabe5bce3d11" +checksum = "99314c8a2152b8ddb211f924cdae532d8c5e4c8bb54728e12fff1b0cd5963a10" dependencies = [ "bytemuck", - "byteorder", + "byteorder-lite", + "color_quant", + "exr", + "gif", + "image-webp", "num-traits", "png", + "qoi", + "ravif", + "rayon", + "rgb", "tiff", + "zune-core", + "zune-jpeg", ] +[[package]] +name = "image-webp" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f79afb8cbee2ef20f59ccd477a218c12a93943d075b492015ecb1bb81f8ee904" +dependencies = [ + "byteorder-lite", + "quick-error", +] + +[[package]] +name = "imgref" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44feda355f4159a7c757171a77de25daf6411e217b4cabd03bd6650690468126" + [[package]] name = "immutable-chunkmap" version = "2.0.5" @@ -2480,6 +2643,17 @@ dependencies = [ "libc", ] +[[package]] +name = "interpolate_name" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.70", +] + [[package]] name = "io-kit-sys" version = "0.4.1" @@ -2599,6 +2773,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" +[[package]] +name = "lebe" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" + [[package]] name = "lewton" version = "0.10.2" @@ -2616,6 +2796,17 @@ version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +[[package]] +name = "libfuzzer-sys" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a96cfd5557eb82f2b83fed4955246c988d331975a002961b07c81584d107e7f7" +dependencies = [ + "arbitrary", + "cc", + "once_cell", +] + [[package]] name = "libloading" version = "0.7.4" @@ -2704,6 +2895,15 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "loop9" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062" +dependencies = [ + "imgref", +] + [[package]] name = "mach2" version = "0.4.2" @@ -2741,6 +2941,15 @@ dependencies = [ "rawpointer", ] +[[package]] +name = "maybe-rayon" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" +dependencies = [ + "cfg-if", +] + [[package]] name = "memchr" version = "2.7.4" @@ -2910,6 +3119,12 @@ dependencies = [ "jni-sys", ] +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + [[package]] name = "nix" version = "0.29.0" @@ -2966,6 +3181,12 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "610a5acd306ec67f907abe5567859a3c693fb9886eb1f012ab8f2a47bef3db51" +[[package]] +name = "noop_proc_macro" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" + [[package]] name = "ntapi" version = "0.4.1" @@ -3585,6 +3806,21 @@ dependencies = [ "syn 2.0.70", ] +[[package]] +name = "qoi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + [[package]] name = "quick-xml" version = "0.34.0" @@ -3617,7 +3853,7 @@ checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ "getrandom 0.1.16", "libc", - "rand_chacha", + "rand_chacha 0.2.2", "rand_core 0.5.1", "rand_hc", ] @@ -3628,6 +3864,8 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ + "libc", + "rand_chacha 0.3.1", "rand_core 0.6.4", ] @@ -3641,6 +3879,16 @@ dependencies = [ "rand_core 0.5.1", ] +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + [[package]] name = "rand_core" version = "0.5.1" @@ -3655,6 +3903,9 @@ name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.15", +] [[package]] name = "rand_hc" @@ -3714,6 +3965,55 @@ dependencies = [ "vec_map", ] +[[package]] +name = "rav1e" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd87ce80a7665b1cce111f8a16c1f3929f6547ce91ade6addf4ec86a8dda5ce9" +dependencies = [ + "arbitrary", + "arg_enum_proc_macro", + "arrayvec", + "av1-grain", + "bitstream-io", + "built", + "cfg-if", + "interpolate_name", + "itertools", + "libc", + "libfuzzer-sys", + "log", + "maybe-rayon", + "new_debug_unreachable", + "noop_proc_macro", + "num-derive", + "num-traits", + "once_cell", + "paste", + "profiling", + "rand 0.8.5", + "rand_chacha 0.3.1", + "simd_helpers", + "system-deps", + "thiserror", + "v_frame", + "wasm-bindgen", +] + +[[package]] +name = "ravif" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5797d09f9bd33604689e87e8380df4951d4912f01b63f71205e2abd4ae25e6b6" +dependencies = [ + "avif-serialize", + "imgref", + "loop9", + "quick-error", + "rav1e", + "rgb", +] + [[package]] name = "raw-window-handle" version = "0.6.2" @@ -3820,6 +4120,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" +[[package]] +name = "rgb" +version = "0.8.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e12bc8d2f72df26a5d3178022df33720fbede0d31d82c7291662eff89836994d" +dependencies = [ + "bytemuck", +] + [[package]] name = "robust" version = "1.1.0" @@ -3976,6 +4285,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" +dependencies = [ + "serde", +] + [[package]] name = "sharded-slab" version = "0.1.7" @@ -4019,6 +4337,15 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" +[[package]] +name = "simd_helpers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6" +dependencies = [ + "quote", +] + [[package]] name = "slab" version = "0.4.9" @@ -4089,6 +4416,15 @@ dependencies = [ "smallvec", ] +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + [[package]] name = "spirv" version = "0.3.0+sdk-1.3.268.0" @@ -4152,6 +4488,19 @@ dependencies = [ "windows 0.52.0", ] +[[package]] +name = "system-deps" +version = "6.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" +dependencies = [ + "cfg-expr", + "heck", + "pkg-config", + "toml", + "version-compare", +] + [[package]] name = "taffy" version = "0.5.2" @@ -4165,6 +4514,12 @@ dependencies = [ "slotmap", ] +[[package]] +name = "target-lexicon" +version = "0.12.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" + [[package]] name = "termcolor" version = "1.4.1" @@ -4255,11 +4610,26 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "toml" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.22.15", +] + [[package]] name = "toml_datetime" version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" +dependencies = [ + "serde", +] [[package]] name = "toml_edit" @@ -4279,6 +4649,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d59a3a72298453f564e2b111fa896f8d07fabb36f51f06d7e875fc5e0b5a3ef1" dependencies = [ "indexmap", + "serde", + "serde_spanned", "toml_datetime", "winnow 0.6.13", ] @@ -4484,6 +4856,17 @@ dependencies = [ "serde", ] +[[package]] +name = "v_frame" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f32aaa24bacd11e488aa9ba66369c7cd514885742c9fe08cfe85884db3e92b" +dependencies = [ + "aligned-vec", + "num-traits", + "wasm-bindgen", +] + [[package]] name = "valuable" version = "0.1.0" @@ -4496,6 +4879,12 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" +[[package]] +name = "version-compare" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" + [[package]] name = "version_check" version = "0.9.4" @@ -5318,6 +5707,7 @@ dependencies = [ "bevy", "bevy-inspector-egui", "bevy_asset_loader", + "image 0.25.2", "noise 0.9.0", "rayon", "ron", @@ -5413,3 +5803,27 @@ dependencies = [ "quote", "syn 2.0.70", ] + +[[package]] +name = "zune-core" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" + +[[package]] +name = "zune-inflate" +version = "0.2.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "zune-jpeg" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16099418600b4d8f028622f73ff6e3deaabdff330fb9a2a131dea781ee8b0768" +dependencies = [ + "zune-core", +] diff --git a/engine/world_generation/Cargo.toml b/engine/world_generation/Cargo.toml index 5232c4c..4bc9dbc 100644 --- a/engine/world_generation/Cargo.toml +++ b/engine/world_generation/Cargo.toml @@ -18,6 +18,7 @@ bevy_asset_loader = { version = "0.21.0", features = [ "3d", ] } ron = "0.8.1" +image = "0.25.2" [features] tracing = ["bevy/trace_tracy"] diff --git a/engine/world_generation/src/generators/chunk_colliders.rs b/engine/world_generation/src/generators/chunk_colliders.rs index 6d72be7..78a4baf 100644 --- a/engine/world_generation/src/generators/chunk_colliders.rs +++ b/engine/world_generation/src/generators/chunk_colliders.rs @@ -31,7 +31,7 @@ fn create_tile_collider(pos: Vec3, verts: &mut Vec, indices: &mut Vec<[u32 verts.push(p); } - //Top Surfave + //Top Surface indices.push([idx, idx + 1, idx + 5]); indices.push([idx + 1, idx + 2, idx + 5]); indices.push([idx + 2, idx + 4, idx + 5]); @@ -43,7 +43,7 @@ fn create_tile_collider(pos: Vec3, verts: &mut Vec, indices: &mut Vec<[u32 create_tile_wall_collider( idx, Vec3::new(pos.x, n_height.min(pos.y - OUTER_RADIUS / 2.), pos.z), - i, + (i + 1) % 6, verts, indices, ); @@ -54,7 +54,7 @@ fn create_tile_collider(pos: Vec3, verts: &mut Vec, indices: &mut Vec<[u32 fn create_tile_wall_collider(idx: u32, pos: Vec3, dir: usize, verts: &mut Vec, indices: &mut Vec<[u32; 3]>) { let idx2 = verts.len() as u32; - verts.push(pos + HEX_CORNERS[dir]); + verts.push(pos + HEX_CORNERS[(dir) % 6]); verts.push(pos + HEX_CORNERS[(dir + 1) % 6]); let off = dir as u32; diff --git a/engine/world_generation/src/heightmap.rs b/engine/world_generation/src/heightmap.rs index de0e2b9..49e9458 100644 --- a/engine/world_generation/src/heightmap.rs +++ b/engine/world_generation/src/heightmap.rs @@ -1,5 +1,8 @@ +use core::f32; + use bevy::math::{IVec2, UVec2}; use bevy::prelude::{FloatExt, Vec2}; +use bevy::render::render_resource::encase::internal::BufferMut; use bevy::utils::default; use noise::{NoiseFn, SuperSimplex}; use rayon::iter::{IntoParallelIterator, ParallelIterator}; @@ -11,7 +14,7 @@ use crate::prelude::*; pub fn generate_heightmap(cfg: &GenerationConfig, seed: u32, painter: &BiomePainter) -> Map { let biomes = &generate_biomes(cfg, seed, painter); // let mut chunks: Vec = Vec::with_capacity(cfg.size.length_squared() as usize); - let chunks = (0..cfg.size.y) + let chunks: Vec = (0..cfg.size.y) .into_par_iter() .flat_map(|z| { (0..cfg.size.x).into_par_iter().map(move |x| { @@ -20,11 +23,24 @@ pub fn generate_heightmap(cfg: &GenerationConfig, seed: u32, painter: &BiomePain }) }) .collect(); + let mut min = f32::MAX; + let mut max = f32::MIN; + for chunk in &chunks { + if chunk.min_level < min { + min = chunk.min_level; + } + if chunk.max_level > max { + max = chunk.max_level; + } + } + return Map { chunks, height: cfg.size.y as usize, width: cfg.size.x as usize, sea_level: cfg.sea_level as f32, + min_level: min, + max_level: max, }; } @@ -66,7 +82,7 @@ pub fn generate_biome_chunk( &cfg.moisture_noise, &noise_m, cfg.size.as_vec2(), - cfg.border_size, + 0.0, ); let temperature = sample_point( x as f64 + chunk_x as f64 * Chunk::SIZE as f64, @@ -74,7 +90,7 @@ pub fn generate_biome_chunk( &cfg.temperature_noise, &noise_t, cfg.size.as_vec2(), - cfg.border_size, + 0.0, ); let continentality = sample_point( x as f64 + chunk_x as f64 * Chunk::SIZE as f64, @@ -82,7 +98,7 @@ pub fn generate_biome_chunk( &cfg.continent_noise, &noise_c, cfg.size.as_vec2(), - cfg.border_size, + 0.0, ); let data = BiomeData { moisture: moisture.clamp(0., 100.), @@ -100,6 +116,29 @@ pub fn generate_biome_chunk( return chunk; } +pub fn generate_noise_map(size: UVec2, seed: u32, cfg: &NoiseConfig, border_size: f32) -> Vec { + let noise = SuperSimplex::new(seed); + + let data: Vec<_> = (0..(size.y as usize * Chunk::SIZE)) + .into_par_iter() + .flat_map(|y| { + let mut row = Vec::with_capacity(size.x as usize * Chunk::SIZE); + for x in 0..row.capacity() { + row.push(sample_point( + x as f64, + y as f64, + cfg, + &noise, + size.as_vec2(), + border_size, + )); + } + return row; + }) + .collect(); + return data; +} + pub fn generate_chunk( chunk_x: u32, chunk_z: u32, @@ -112,6 +151,8 @@ pub fn generate_chunk( let mut data = [BiomeData::default(); Chunk::AREA]; let mut biome_ids = [0; Chunk::AREA]; let noise = SuperSimplex::new(seed); + let mut min = f32::MAX; + let mut max = f32::MIN; for z in 0..Chunk::SIZE { for x in 0..Chunk::SIZE { let biome_data = biome_chunk.get_biome_data(x, z); @@ -135,6 +176,12 @@ pub fn generate_chunk( let idx = x + z * Chunk::SIZE; biome_ids[idx] = biome_chunk.get_biome_id_dithered(x, z, &noise, cfg.biome_dither); result[idx] = sample; + if sample > max { + max = sample; + } + if sample < min { + min = sample; + } data[idx] = biome_data.clone(); } } @@ -143,6 +190,8 @@ pub fn generate_chunk( biome_data: data, biome_id: biome_ids, chunk_offset: IVec2::new(chunk_x as i32, chunk_z as i32), + max_level: max, + min_level: min, ..default() }; } @@ -171,6 +220,10 @@ fn sample_point(x: f64, z: f64, cfg: &NoiseConfig, noise: &impl NoiseFn, } } + if border_size == 0.0 { + return elevation as f32; + } + let outer = size * Chunk::SIZE as f32; let p = Vec2::new(x as f32, z as f32); diff --git a/engine/world_generation/src/hex_utils.rs b/engine/world_generation/src/hex_utils.rs index ba20e2c..5cacc23 100644 --- a/engine/world_generation/src/hex_utils.rs +++ b/engine/world_generation/src/hex_utils.rs @@ -72,12 +72,12 @@ impl Display for HexCoord { impl HexCoord { pub const DIRECTIONS: [IVec3; 6] = [ - IVec3::new(0, 1, -1), - IVec3::new(1, 0, -1), IVec3::new(1, -1, 0), - IVec3::new(0, -1, 1), - IVec3::new(-1, 0, 1), + IVec3::new(1, 0, -1), + IVec3::new(0, 1, -1), IVec3::new(-1, 1, 0), + IVec3::new(-1, 0, 1), + IVec3::new(0, -1, 1), ]; pub const ZERO: HexCoord = HexCoord { hex: IVec3::ZERO }; diff --git a/engine/world_generation/src/map/biome_map.rs b/engine/world_generation/src/map/biome_map.rs index 91fc3c7..213ba55 100644 --- a/engine/world_generation/src/map/biome_map.rs +++ b/engine/world_generation/src/map/biome_map.rs @@ -4,6 +4,7 @@ use rayon::iter::{IntoParallelIterator, ParallelIterator}; use super::chunk::Chunk; +#[derive(Clone)] pub struct BiomeMap { pub height: usize, pub width: usize, diff --git a/engine/world_generation/src/map/chunk.rs b/engine/world_generation/src/map/chunk.rs index d59282e..ef37799 100644 --- a/engine/world_generation/src/map/chunk.rs +++ b/engine/world_generation/src/map/chunk.rs @@ -10,6 +10,8 @@ pub struct Chunk { pub biome_data: [BiomeData; Chunk::AREA], pub biome_id: [usize; Chunk::AREA], pub chunk_offset: IVec2, + pub min_level: f32, + pub max_level: f32, } impl Default for Chunk { @@ -20,6 +22,8 @@ impl Default for Chunk { biome_data: [BiomeData::default(); Chunk::AREA], biome_id: [0; Chunk::AREA], chunk_offset: Default::default(), + min_level: 0.0, + max_level: 0.0, } } } diff --git a/engine/world_generation/src/map/map.rs b/engine/world_generation/src/map/map.rs index 1a9ce59..b344ee5 100644 --- a/engine/world_generation/src/map/map.rs +++ b/engine/world_generation/src/map/map.rs @@ -2,7 +2,11 @@ use bevy::prelude::*; use crate::hex_utils::*; -use super::{chunk::Chunk, mesh_chunk::MeshChunkData}; +use super::{ + biome_map::{BiomeData, BiomeMap}, + chunk::Chunk, + mesh_chunk::MeshChunkData, +}; #[derive(Resource, Clone)] pub struct Map { @@ -10,6 +14,8 @@ pub struct Map { pub height: usize, pub width: usize, pub sea_level: f32, + pub min_level: f32, + pub max_level: f32, } impl Map { @@ -43,11 +49,21 @@ impl Map { } pub fn sample_height(&self, pos: &HexCoord) -> f32 { + assert!( + self.is_in_bounds(pos), + "The provided coordinate is not within the map bounds" + ); + let chunk = &self.chunks[pos.to_chunk_index(self.width)]; return chunk.heights[pos.to_chunk_local_index()]; } pub fn sample_height_mut(&mut self, pos: &HexCoord) -> &mut f32 { + assert!( + self.is_in_bounds(pos), + "The provided coordinate is not within the map bounds" + ); + let chunk = &mut self.chunks[pos.to_chunk_index(self.width)]; return &mut chunk.heights[pos.to_chunk_local_index()]; } @@ -56,16 +72,46 @@ impl Map { return pos.is_in_bounds(self.height * Chunk::SIZE, self.width * Chunk::SIZE); } + pub fn get_biome(&self, pos: &HexCoord) -> &BiomeData { + assert!( + self.is_in_bounds(pos), + "The provided coordinate is not within the map bounds" + ); + + let chunk = &self.chunks[pos.to_chunk_index(self.width)]; + return &chunk.biome_data[pos.to_chunk_local_index()]; + } + pub fn get_moisture(&self, pos: &HexCoord) -> f32 { + assert!( + self.is_in_bounds(pos), + "The provided coordinate is not within the map bounds" + ); + let chunk = &self.chunks[pos.to_chunk_index(self.width)]; return chunk.biome_data[pos.to_chunk_local_index()].moisture; } pub fn get_tempurature(&self, pos: &HexCoord) -> f32 { + assert!( + self.is_in_bounds(pos), + "The provided coordinate is not within the map bounds" + ); + let chunk = &self.chunks[pos.to_chunk_index(self.width)]; return chunk.biome_data[pos.to_chunk_local_index()].temperature; } + pub fn get_continentality(&self, pos: &HexCoord) -> f32 { + assert!( + self.is_in_bounds(pos), + "The provided coordinate is not within the map bounds" + ); + + let chunk = &self.chunks[pos.to_chunk_index(self.width)]; + return chunk.biome_data[pos.to_chunk_local_index()].continentality; + } + pub fn get_center(&self) -> Vec3 { let w = self.get_world_width(); let h = self.get_world_height(); @@ -96,7 +142,7 @@ impl Map { let h2 = cur - depth; *h = h2.lerp(cur, d * d).max(0.); - return (*p, *h); + return (*p, *h); }); return tiles; diff --git a/engine/world_generation/src/map/map_utils.rs b/engine/world_generation/src/map/map_utils.rs new file mode 100644 index 0000000..6e6ebb6 --- /dev/null +++ b/engine/world_generation/src/map/map_utils.rs @@ -0,0 +1,115 @@ +use bevy::{math::VectorSpace, prelude::*}; +use image::ImageBuffer; +use rayon::prelude::*; + +use crate::hex_utils::HexCoord; + +use super::{biome_map::BiomeMap, chunk::Chunk, map::Map}; + +pub fn render_image( + size: UVec2, + data: &Vec, + color1: LinearRgba, + color2: LinearRgba, +) -> ImageBuffer, Vec> { + let mut image = ImageBuffer::new(size.x * Chunk::SIZE as u32, size.y * Chunk::SIZE as u32); + update_image(size, data, color1, color2, &mut image); + + return image; +} + +pub fn update_image( + size: UVec2, + data: &Vec, + color1: LinearRgba, + color2: LinearRgba, + image: &mut ImageBuffer, Vec>, +) { + let min = *data.iter().min_by(|a, b| a.partial_cmp(b).unwrap()).unwrap_or(&0.0); + let max = *data.iter().min_by(|a, b| a.partial_cmp(b).unwrap()).unwrap_or(&1.0); + + let w = size.x * Chunk::SIZE as u32; + + image.par_enumerate_pixels_mut().for_each(|(x, y, pixel)| { + let idx = (y * w + x) as usize; + let v = data[idx]; + let t = v.remap(min, max, 0.0, 1.0); + let col = LinearRgba::lerp(&color1, color2, t); + *pixel = to_pixel(&col); + }); +} + +fn to_pixel(col: &LinearRgba) -> image::Rgb { + return image::Rgb([ + (col.red * 255.0) as u8, + (col.green * 255.0) as u8, + (col.blue * 255.0) as u8, + ]); +} +pub fn render_map(map: &Map, smooth: f32) -> ImageBuffer, Vec> { + let mut image = ImageBuffer::new( + map.width as u32 * Chunk::SIZE as u32, + map.height as u32 * Chunk::SIZE as u32, + ); + update_map(map, smooth, &mut image); + return image; +} +pub fn update_map(map: &Map, smooth: f32, image: &mut ImageBuffer, Vec>) { + image.par_enumerate_pixels_mut().for_each(|(x, y, pixel)| { + let coord = HexCoord::from_grid_pos(x as usize, y as usize); + let right = coord.get_neighbor(1); + let height = map.sample_height(&coord); + let mut color = Hsla::hsl(138.0, 1.0, 0.4); + if height < map.sea_level { + color.hue = 217.0; + } + if map.is_in_bounds(&right) { + let h2 = map.sample_height(&right); + let mut d = h2 - height; + + if smooth == 0.0 || d.abs() > smooth { + if d > 0.0 { + color.lightness += 0.1; + } else if d < 0.0 { + color.lightness -= 0.1; + } + } else { + if d.abs() <= smooth { + d /= smooth; + if d > 0.0 { + let c2: LinearRgba = color.with_lightness(color.lightness + 0.1).into(); + color = LinearRgba::lerp(&color.into(), c2, d).into(); + } else { + let c2: LinearRgba = color.with_lightness(color.lightness - 0.1).into(); + color = LinearRgba::lerp(&color.into(), c2, d.abs()).into(); + } + } + } + } + + *pixel = to_pixel(&color.into()); + }); +} + +pub fn render_biome_map(map: &Map) -> ImageBuffer, Vec> { + let mut image = ImageBuffer::new( + map.width as u32 * Chunk::SIZE as u32, + map.height as u32 * Chunk::SIZE as u32, + ); + update_biome_map(map, &mut image); + return image; +} + +pub fn update_biome_map(map: &Map, image: &mut ImageBuffer, Vec>) { + image.par_enumerate_pixels_mut().for_each(|(x, y, pixel)| { + let coord = HexCoord::from_grid_pos(x as usize, y as usize); + let tile = map.get_biome(&coord); + + let color = LinearRgba::rgb( + tile.temperature / 100.0, + tile.continentality / 100.0, + tile.moisture / 100.0, + ); + *pixel = to_pixel(&color); + }); +} diff --git a/engine/world_generation/src/map/mesh_chunk.rs b/engine/world_generation/src/map/mesh_chunk.rs index 3a09423..be87f78 100644 --- a/engine/world_generation/src/map/mesh_chunk.rs +++ b/engine/world_generation/src/map/mesh_chunk.rs @@ -11,7 +11,7 @@ impl MeshChunkData { pub fn get_neighbors(&self, coord: &HexCoord) -> [f32; 6] { let mut data = [0.; 6]; let n_tiles = coord.get_neighbors(); - for i in 0..6 { + for i in 6..0 { let n = n_tiles[i]; if !n.is_in_bounds(Chunk::SIZE, Chunk::SIZE) { continue; diff --git a/engine/world_generation/src/map/mod.rs b/engine/world_generation/src/map/mod.rs index dc19c18..fad9755 100644 --- a/engine/world_generation/src/map/mod.rs +++ b/engine/world_generation/src/map/mod.rs @@ -2,4 +2,5 @@ pub mod chunk; pub mod mesh_chunk; pub mod config; pub mod map; -pub mod biome_map; \ No newline at end of file +pub mod biome_map; +pub mod map_utils; \ No newline at end of file diff --git a/game/main/src/map_rendering/map_init.rs b/game/main/src/map_rendering/map_init.rs index 1a67cb5..b6b7429 100644 --- a/game/main/src/map_rendering/map_init.rs +++ b/game/main/src/map_rendering/map_init.rs @@ -14,6 +14,7 @@ use world_generation::{ biome_painter::*, heightmap::generate_heightmap, hex_utils::{offset_to_index, SHORT_DIAGONAL}, + map::map_utils::{render_biome_map, render_map}, prelude::*, tile_manager::*, tile_mapper::*, @@ -212,6 +213,11 @@ fn create_heightmap( }; let heightmap = generate_heightmap(&config, 42069, &biome_painter); + let game_map = render_map(&heightmap, 1.5); + let biome_map = render_biome_map(&heightmap); + _ = biome_map.save("Biomes.png"); + _ = game_map.save("Test.png"); + let (mut cam_t, cam_entity) = cam.single_mut(); cam_t.translation = heightmap.get_center(); diff --git a/game/main/src/utlis/debug_plugin.rs b/game/main/src/utlis/debug_plugin.rs index ca1ecd0..1558b1e 100644 --- a/game/main/src/utlis/debug_plugin.rs +++ b/game/main/src/utlis/debug_plugin.rs @@ -90,6 +90,15 @@ fn show_tile_heights( Color::WHITE, ); } + let nbors = map.get_neighbors(&contact_coord); + for i in 0..6 { + if let Some(s) = nbors[i] { + let coord = contact_coord.get_neighbor(i); + let p = coord.to_world(s); + gizmos.arrow(p, p + Vec3::Y * (i as f32 + 1.0), Color::WHITE); + } + } + gizmos.sphere(contact_point, Quat::IDENTITY, 0.1, Srgba::rgb(1., 0., 0.5)); } }