From 855f3c6d78220cfd0ba37c4a0d5a89f58dc8cd32 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 11 Dec 2024 20:18:13 +0300 Subject: [PATCH 01/44] add libluajit --- dev/AppImageBuilder.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/dev/AppImageBuilder.yml b/dev/AppImageBuilder.yml index 0231e1df..69e687e4 100644 --- a/dev/AppImageBuilder.yml +++ b/dev/AppImageBuilder.yml @@ -30,6 +30,7 @@ AppDir: - libogg0 - libvorbis0a - libvorbisfile3 + - libluajit-5.1-2 exclude: - hicolor-icon-theme - sound-theme-freedesktop From 26613b8741dd3fa94e8ed45bc244bacc264f998c Mon Sep 17 00:00:00 2001 From: Onran <100285264+Onran0@users.noreply.github.com> Date: Sun, 15 Dec 2024 01:35:12 +0900 Subject: [PATCH 02/44] Update libentities.md --- doc/ru/scripting/builtins/libentities.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/ru/scripting/builtins/libentities.md b/doc/ru/scripting/builtins/libentities.md index 1e0cc6c0..ad0e5b2a 100644 --- a/doc/ru/scripting/builtins/libentities.md +++ b/doc/ru/scripting/builtins/libentities.md @@ -15,7 +15,8 @@ entities.get(uid: int) -> table -- префикс - id пака -- имя - название компонента -- префикс и имя компонента разделяются двумя подчеркиваниями -entities.spawn(name: str, pos: vec3, [optional] args: table) +-- Возвращает обьект сущности +entities.spawn(name: str, pos: vec3, [optional] args: table) -> table -- Проверяет наличие сущности по уникальному идентификатору. entities.exists(uid: int) -> bool From 8caa536a6abb34a454a95618986473f10ecb655f Mon Sep 17 00:00:00 2001 From: Onran <100285264+Onran0@users.noreply.github.com> Date: Sun, 15 Dec 2024 01:35:49 +0900 Subject: [PATCH 03/44] Update libentities.md --- doc/en/scripting/builtins/libentities.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/en/scripting/builtins/libentities.md b/doc/en/scripting/builtins/libentities.md index cb46a3a5..9108fbdf 100644 --- a/doc/en/scripting/builtins/libentities.md +++ b/doc/en/scripting/builtins/libentities.md @@ -15,7 +15,8 @@ entities.get(uid: int) -> table -- prefix - component pack id -- name - component name -- component prefix and name are separated with two underscores -entities.spawn(name: str, pos: vec3, [optional] args: table) +-- Returns an entity object +entities.spawn(name: str, pos: vec3, [optional] args: table) -> table -- Checks the existence of an entity by a unique identifier. entities.exists(uid: int) -> bool From 33c76e7d704c047d259e924d4b45f99c42ca9ce3 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 18 Dec 2024 19:54:47 +0300 Subject: [PATCH 04/44] add 'heightmap-inputs' to world-generator docs --- doc/en/world-generator.md | 1 + doc/ru/world-generator.md | 1 + 2 files changed, 2 insertions(+) diff --git a/doc/en/world-generator.md b/doc/en/world-generator.md index 2112bce2..b0ab265c 100644 --- a/doc/en/world-generator.md +++ b/doc/en/world-generator.md @@ -52,6 +52,7 @@ The main properties described in the configuration file: - **biomes-bpd** - number of blocks per point of the biome selection parameter map. Default: 4. - **heights-bpd** - number of blocks per point of the height map. Default: 4. - **wide-structs-chunks-radius** - maximum radius for placing 'wide' structures, measured in chunks. +- **heightmap-inputs** - an array of parameter map numbers that will be passed by the inputs table to the height map generation function. ## Global variables diff --git a/doc/ru/world-generator.md b/doc/ru/world-generator.md index 1523f94a..5c1c6e6e 100644 --- a/doc/ru/world-generator.md +++ b/doc/ru/world-generator.md @@ -52,6 +52,7 @@ - **biomes-bpd** - количество блоков на точку карты параметра выбора биомов. По-умолчанию: 4. - **heights-bpd** - количество блоков на точку карты высот. По-умолчанию: 4. - **wide-structs-chunks-radius** - масимальный радиус размещения 'широких' структур, измеряемый в чанках. +- **heightmap-inputs** - массив номеров карт параметров, которые будут переданы таблицей inputs в функцию генерации карты высот. ## Глобальные переменные From babb6a6d8da270e42155dfd63451399046e11ea2 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 18 Dec 2024 23:49:39 +0300 Subject: [PATCH 05/44] update doc/*/audio.md --- doc/en/audio.md | 6 +++--- doc/ru/audio.md | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/en/audio.md b/doc/en/audio.md index 9322583f..cacd7107 100644 --- a/doc/en/audio.md +++ b/doc/en/audio.md @@ -60,7 +60,7 @@ Library **audio** contains available Audio API in Lua scripts. ```lua audio.play_stream( - -- audio file location + -- audio file location (without entry point, but with extension included) name: string, -- audio source world position x: number, y: number, z: number, @@ -79,7 +79,7 @@ Plays streaming audio from the specified file at the specified world position. R ```lua audio.play_stream_2d( - -- audio file location + -- audio file location (without entry point, but with extension included) name: string, -- audio gain (0.0 - 1.0) volume: number @@ -202,4 +202,4 @@ audio.count_speakers() -> integer -- get current number of playing streams audio.count_streams() -> integer -``` \ No newline at end of file +``` diff --git a/doc/ru/audio.md b/doc/ru/audio.md index b560b739..1fce6c35 100644 --- a/doc/ru/audio.md +++ b/doc/ru/audio.md @@ -61,7 +61,7 @@ ```lua audio.play_stream( - -- путь к аудио-файлу + -- путь к аудио-файлу (без точки входа, но с указанием расширения) name: string, -- позиция источника аудио в мире x: number, y: number, z: number, @@ -80,7 +80,7 @@ audio.play_stream( ```lua audio.play_stream_2d( - -- путь к аудио-файлу + -- путь к аудио-файлу (без точки входа, но с указанием расширения) name: string, -- громкость аудио (от 0.0 до 1.0) volume: number From 61741a5cc898272627491b4cd8d5404048169df1 Mon Sep 17 00:00:00 2001 From: Richard Try Date: Thu, 19 Dec 2024 01:37:34 +0300 Subject: [PATCH 06/44] Copy metatable in table.deepcopy Copy metatable as well during deep copying --- res/scripts/stdmin.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/scripts/stdmin.lua b/res/scripts/stdmin.lua index 13934e06..76df31e2 100644 --- a/res/scripts/stdmin.lua +++ b/res/scripts/stdmin.lua @@ -74,7 +74,7 @@ function table.deep_copy(t) end end - return copied + return setmetatable(copied, getmetatable(t)) end function table.count_pairs(t) From 2787f2fc5495004f6029644ed5221f3abfc0c68f Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 19 Dec 2024 22:44:54 +0300 Subject: [PATCH 07/44] fix: grabbed item is deleted on inventory close --- src/frontend/hud.cpp | 28 ++++++++++++++++++++++++++++ src/frontend/hud.hpp | 3 +++ 2 files changed, 31 insertions(+) diff --git a/src/frontend/hud.cpp b/src/frontend/hud.cpp index 21111e18..01252c4c 100644 --- a/src/frontend/hud.cpp +++ b/src/frontend/hud.cpp @@ -47,6 +47,7 @@ #include "window/Window.hpp" #include "world/Level.hpp" #include "world/World.hpp" +#include "debug/Logger.hpp" #include #include @@ -56,6 +57,8 @@ using namespace gui; +static debug::Logger logger("hud"); + bool Hud::showGeneratorMinimap = false; // implemented in debug_panel.cpp @@ -485,7 +488,32 @@ void Hud::openPermanent(UiDocument* doc) { add(HudElement(hud_element_mode::permanent, doc, doc->getRoot(), false)); } +void Hud::dropExchangeSlot() { + auto slotView = std::dynamic_pointer_cast( + gui->get(SlotView::EXCHANGE_SLOT_NAME) + ); + if (slotView == nullptr) { + return; + } + ItemStack& stack = slotView->getStack(); + + auto indices = frontend.getLevel().content->getIndices(); + if (auto invView = std::dynamic_pointer_cast(blockUI)) { + invView->getInventory()->move(stack, indices); + } + if (stack.isEmpty()) { + return; + } + player->getInventory()->move(stack, indices); + if (!stack.isEmpty()) { + logger.warning() << "discard item [" << stack.getItemId() << ":" + << stack.getCount(); + stack.clear(); + } +} + void Hud::closeInventory() { + dropExchangeSlot(); gui->remove(SlotView::EXCHANGE_SLOT_NAME); exchangeSlot = nullptr; exchangeSlotInv = nullptr; diff --git a/src/frontend/hud.hpp b/src/frontend/hud.hpp index 5594664a..ad834955 100644 --- a/src/frontend/hud.hpp +++ b/src/frontend/hud.hpp @@ -128,6 +128,9 @@ class Hud : public util::ObjectsKeeper { void updateHotbarControl(); void cleanup(); + /// @brief Perform exchange slot removal when it's not empty. + void dropExchangeSlot(); + void showExchangeSlot(); void updateWorldGenDebugVisualization(); public: From cda34e3975a42696ea31a1b0018731e746cd13bb Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 19 Dec 2024 22:54:54 +0300 Subject: [PATCH 08/44] fix block overriding --- src/content/ContentLoader.cpp | 8 +++----- src/voxels/Block.hpp | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/content/ContentLoader.cpp b/src/content/ContentLoader.cpp index 1e954a55..fee559e4 100644 --- a/src/content/ContentLoader.cpp +++ b/src/content/ContentLoader.cpp @@ -220,11 +220,11 @@ void ContentLoader::loadBlock( } // block model - std::string modelTypeName; + std::string modelTypeName = to_string(def.model); root.at("model").get(modelTypeName); root.at("model-name").get(def.modelName); if (auto model = BlockModel_from(modelTypeName)) { - if (*model == BlockModel::custom) { + if (*model == BlockModel::custom && def.customModelRaw == nullptr) { if (root.has("model-primitives")) { def.customModelRaw = root["model-primitives"]; } else if (def.modelName.empty()) { @@ -246,7 +246,7 @@ void ContentLoader::loadBlock( root.at("material").get(def.material); // rotation profile - std::string profile = "none"; + std::string profile = def.rotations.name; root.at("rotation").get(profile); def.rotatable = profile != "none"; @@ -285,8 +285,6 @@ void ContentLoader::loadBlock( ); aabb.b += aabb.a; def.hitboxes = {aabb}; - } else { - def.hitboxes = {AABB()}; } // block light emission [r, g, b] where r,g,b in range [0..15] diff --git a/src/voxels/Block.hpp b/src/voxels/Block.hpp index e7fb182c..557bf04c 100644 --- a/src/voxels/Block.hpp +++ b/src/voxels/Block.hpp @@ -181,7 +181,7 @@ public: bool translucent = false; /// @brief Set of block physical hitboxes - std::vector hitboxes; + std::vector hitboxes {AABB()}; /// @brief Set of available block rotations (coord-systems) BlockRotProfile rotations = BlockRotProfile::NONE; From 958a7065468cf7df2b4a0755eac926e3b3f0134a Mon Sep 17 00:00:00 2001 From: Xertis <118364459+Xertis@users.noreply.github.com> Date: Fri, 20 Dec 2024 22:59:53 +0300 Subject: [PATCH 09/44] add new extensions.lua --- res/scripts/stdmin.lua | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/res/scripts/stdmin.lua b/res/scripts/stdmin.lua index 76df31e2..56b11639 100644 --- a/res/scripts/stdmin.lua +++ b/res/scripts/stdmin.lua @@ -51,6 +51,19 @@ function math.rand(low, high) return low + (high - low) * math.random() end +function math.normalize(num, conf) + conf = conf or 10 + + return (num / conf) % 1 +end + +function math.round(num, places) + places = places or 0 + + local mult = 10 ^ places + return math.floor(num * mult + 0.5) / mult +end + ---------------------------------------------- function table.copy(t) @@ -91,6 +104,15 @@ function table.random(t) return t[math.random(1, #t)] end +function table.shuffle(t) + for i = #t, 2, -1 do + local j = math.random(i) + t[i], t[j] = t[j], t[i] + end + + return t +end + ---------------------------------------------- local pattern_escape_replacements = { From 31a2c69c485064c407cd039f779c520e98c64417 Mon Sep 17 00:00:00 2001 From: Xertis <118364459+Xertis@users.noreply.github.com> Date: Fri, 20 Dec 2024 23:11:00 +0300 Subject: [PATCH 10/44] Update extensions.md --- doc/ru/scripting/extensions.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/doc/ru/scripting/extensions.md b/doc/ru/scripting/extensions.md index d0ddd365..d0780af3 100644 --- a/doc/ru/scripting/extensions.md +++ b/doc/ru/scripting/extensions.md @@ -46,6 +46,13 @@ table.remove_value(t: table, x: object) Удаляет элемент **x** из **t**. +```lua +table.shuffle(t: table) -> table +``` + +Перемешивает значения в таблице. + + ```lua table.tostring(t: table) -> string ``` @@ -146,6 +153,18 @@ math.rand(low, high) Возвращает случайное дробное число в диапазоне от **low** до **high**. +```lua +math.normalize(num: number, [опционально] conf: num) -> number +``` + +Возвращает нормализованное значение num относительно conf. + +```lua +math.round(num: number, [опционально] places: num) -> number +``` + +Возвращает округлённое число до указанного количества знаков после запятой places. + ## Дополнительные глобальные функции В этом же скрипте также определены и другие глобальные функции которые доступны для использования. Ниже их список From c4a40d6b804414edf314413197c17df47f9b344d Mon Sep 17 00:00:00 2001 From: Xertis <118364459+Xertis@users.noreply.github.com> Date: Fri, 20 Dec 2024 23:16:25 +0300 Subject: [PATCH 11/44] Update extensions.md --- doc/ru/scripting/extensions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/ru/scripting/extensions.md b/doc/ru/scripting/extensions.md index d0780af3..ca165b0c 100644 --- a/doc/ru/scripting/extensions.md +++ b/doc/ru/scripting/extensions.md @@ -163,7 +163,7 @@ math.normalize(num: number, [опционально] conf: num) -> number math.round(num: number, [опционально] places: num) -> number ``` -Возвращает округлённое число до указанного количества знаков после запятой places. +Возвращает округлённое значение num до указанного количества знаков после запятой places. ## Дополнительные глобальные функции From 6018db9c286b6993a0bc1a5e944df7a66d5864dd Mon Sep 17 00:00:00 2001 From: Xertis <118364459+Xertis@users.noreply.github.com> Date: Fri, 20 Dec 2024 23:26:59 +0300 Subject: [PATCH 12/44] refact math.normalize --- res/scripts/stdmin.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/scripts/stdmin.lua b/res/scripts/stdmin.lua index 56b11639..72383dce 100644 --- a/res/scripts/stdmin.lua +++ b/res/scripts/stdmin.lua @@ -52,7 +52,7 @@ function math.rand(low, high) end function math.normalize(num, conf) - conf = conf or 10 + conf = conf or 1 return (num / conf) % 1 end From f4ac84daa2ed68d79ef20463affee06bf372bec6 Mon Sep 17 00:00:00 2001 From: Xertis Date: Fri, 20 Dec 2024 23:55:10 +0300 Subject: [PATCH 13/44] fix --- res/scripts/stdmin.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/scripts/stdmin.lua b/res/scripts/stdmin.lua index 72383dce..56b11639 100644 --- a/res/scripts/stdmin.lua +++ b/res/scripts/stdmin.lua @@ -52,7 +52,7 @@ function math.rand(low, high) end function math.normalize(num, conf) - conf = conf or 1 + conf = conf or 10 return (num / conf) % 1 end From f43e378bc02f37ff4d3b9bed0fc5fe5cfa8be1df Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 21 Dec 2024 02:01:52 +0300 Subject: [PATCH 14/44] update leaves --- res/content/base/blocks/leaves.json | 4 +++- res/content/base/textures/blocks/leaves.png | Bin 6541 -> 753 bytes .../base/textures/blocks/leaves_culled.png | Bin 0 -> 6541 bytes 3 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 res/content/base/textures/blocks/leaves_culled.png diff --git a/res/content/base/blocks/leaves.json b/res/content/base/blocks/leaves.json index cdf9f014..91182bc8 100644 --- a/res/content/base/blocks/leaves.json +++ b/res/content/base/blocks/leaves.json @@ -1,5 +1,7 @@ { "texture": "leaves", "material": "base:grass", - "base:durability": 0.7 + "base:durability": 0.7, + "culling": "optional", + "model": "aabb" } diff --git a/res/content/base/textures/blocks/leaves.png b/res/content/base/textures/blocks/leaves.png index 3beaf7ab9ad7c6304fc4ac43642e7103c425cfa3..9ea91852924b13e86424d2d03df46a5db0f463ea 100644 GIT binary patch delta 730 zcmV<00ww*8Gw}tGBYy(8Nkl+UY>)&Qd@$AX^C%2#BD@AVhue z%{MhB{wv=whF4zH2V$Z^N(2Hz1O=pp7?!e>j$LO;x8wAV9U)fzVCi>zwa`* z3{$idF}y!8o3uW#z)zR!Qy}33g@`?0@QU0}cu_{d(^LxTT&T zVzZOYCPHZ;82E!GL2N6H`pfH?HwV~!*G(pQMKJ@=oxcU_>>@-DDvL51_@%DX<(r(4b)(QOKs@4)6!HN zN9$~)Y6X+vcz@#z)eI4e0;ED2KARy1)h!~iWa|Im!IDArZ9WDdNTo5}AAaehuWt|e zn!7_HW%CS=kFpTkE+A`bk|2bPl#Mtx-FDONyn?zk^YH8)4%+{b1piPatO7;8N4$mnpig86*ONR%Ea{XMX^GPRCJhsW1-JGE`8)!wtZ5f=qHU|#{lGs$$Ul2#Gb{^NFN#A>dibi2K8}ZZgavj5@;UQYp#c=m+%ymxA7Zt~=UI$2lz7b4t3c!U&AmH+?% M07*qoM6N<$f)nLj761SM literal 6541 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 diff --git a/res/content/base/textures/blocks/leaves_culled.png b/res/content/base/textures/blocks/leaves_culled.png new file mode 100644 index 0000000000000000000000000000000000000000..3beaf7ab9ad7c6304fc4ac43642e7103c425cfa3 GIT binary patch literal 6541 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 literal 0 HcmV?d00001 From d021b443dd98b52a24215678b87882917795b0be Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 21 Dec 2024 05:38:30 +0300 Subject: [PATCH 15/44] update leaves texture --- res/content/base/textures/blocks/leaves.png | Bin 753 -> 896 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/res/content/base/textures/blocks/leaves.png b/res/content/base/textures/blocks/leaves.png index 9ea91852924b13e86424d2d03df46a5db0f463ea..a9cd60e3e88fcc465db4b9933f6daf962ae574b8 100644 GIT binary patch delta 874 zcmV-w1C{*o1%L;TBYy)&Nkl>1D4<40mAXJqU)Y+!>B3-~RtV%LJivI`a{PzY5;XrWCT@*paW6E%)aY{%H1u{~pZJaf1n zDdBAHc|X2$uK4a}GqkdzV}9NbB@)E;mX7*{!A5g3_1i8Is(*;stb+CLYD`H-DB`!E z+d*7f3}SQ3f_Ur8f@j#9oJQwH1k|cM z3}q3V-nkma{-KF{-oau{#>QF$qvJ9T*6J+25GB_QU@7CruX_L!1yoN45a43@<0)x#KOo$ddBNI^hLs?duj#QklHcO~J{Wes<4{^PZkyAq{@VPa$5K$0gl@_@eEWJ}AVbkcC} z_f{L}iy?GvK0>A3M^qZXWenFo8mHSg%Ixlq0)LBURC4(?^J@k>9V0O-!-j>zA8mFR z^pi8-YwYZ`Sce-+J0%au;mI-#kXumE?K-%h@0{V_bZktXld#44@wU!LRC-~af1GCwJ5PH2mIXw)E*uSD=c)7m7Gytx_{FWS=%hgmKObE1foL|&%|5lA@&xdJjLO>+qgE(w?nBY17St>;bb+UY>)&Qd@$AX^C%2#BD@AVhue z%{MhB{wv=whF4zH2V$Z^N(2Hz1O=pp7?!e>j$LO;x8wAV9U)fzVCi>zwa`* z3{$idF}y!8o3uW#z)zR!Qy}33g@`?0@QU0}cu_{d(^LxTT&T zVzZOYCPHZ;82E!GL2N6H`pfH?HwV~!*G(pQMKJ@=oxcU_>>@-DDvL51_@%DX<(r(4b)(QOKs@4)6!HN zN9$~)Y6X+vcz@#z)eI4e0;ED2KARy1)h!~iWa|Im!IDArZ9WDdNTo5}AAaehuWt|e zn!7_HW%CS=kFpTkE+A`bk|2bPl#Mtx-FDONyn?zk^YH8)4%+{b1piPatO7;8N4$mnpig86*ONR%Ea{XMX^GPRCJhsW1-JGE`8)!wtZ5f=qHU|#{lGs$$Ul2#Gb{^NFN#A>dibi2K8}ZZgavj5@;UQYp#c=m+%ymxA7Zt~=UI$2lz7b4t3c!U&AmH+?% M07*qoM6N<$f^m3T-2eap From 954724c8378da525fc7349c018e9351c5bdfdf8f Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 21 Dec 2024 06:41:03 +0300 Subject: [PATCH 16/44] add 'culling' property & optimize generated chunk meshes & fix faces culling when 'light-passing' is false --- res/content/base/blocks/leaves.json | 4 +-- .../{leaves_culled.png => leaves_opaque.png} | Bin src/content/ContentLoader.cpp | 10 +++++++- src/graphics/render/BlocksRenderer.cpp | 24 +++++++++--------- src/graphics/render/BlocksRenderer.hpp | 8 ++++-- src/voxels/Block.cpp | 24 ++++++++++++++++++ src/voxels/Block.hpp | 12 +++++++++ 7 files changed, 65 insertions(+), 17 deletions(-) rename res/content/base/textures/blocks/{leaves_culled.png => leaves_opaque.png} (100%) diff --git a/res/content/base/blocks/leaves.json b/res/content/base/blocks/leaves.json index 91182bc8..e3ddae22 100644 --- a/res/content/base/blocks/leaves.json +++ b/res/content/base/blocks/leaves.json @@ -1,7 +1,7 @@ { "texture": "leaves", "material": "base:grass", - "base:durability": 0.7, + "draw-group": 5, "culling": "optional", - "model": "aabb" + "base:durability": 0.7 } diff --git a/res/content/base/textures/blocks/leaves_culled.png b/res/content/base/textures/blocks/leaves_opaque.png similarity index 100% rename from res/content/base/textures/blocks/leaves_culled.png rename to res/content/base/textures/blocks/leaves_opaque.png diff --git a/src/content/ContentLoader.cpp b/src/content/ContentLoader.cpp index fee559e4..1dc676ea 100644 --- a/src/content/ContentLoader.cpp +++ b/src/content/ContentLoader.cpp @@ -239,10 +239,18 @@ void ContentLoader::loadBlock( } def.model = *model; } else if (!modelTypeName.empty()) { - logger.error() << "unknown model " << modelTypeName; + logger.error() << "unknown model: " << modelTypeName; def.model = BlockModel::none; } + std::string cullingModeName = to_string(def.culling); + root.at("culling").get(cullingModeName); + if (auto mode = CullingMode_from(cullingModeName)) { + def.culling = *mode; + } else { + logger.error() << "unknown culling mode: " << cullingModeName; + } + root.at("material").get(def.material); // rotation profile diff --git a/src/graphics/render/BlocksRenderer.cpp b/src/graphics/render/BlocksRenderer.cpp index cb590bcb..f1e8001f 100644 --- a/src/graphics/render/BlocksRenderer.cpp +++ b/src/graphics/render/BlocksRenderer.cpp @@ -342,41 +342,41 @@ void BlocksRenderer::blockCube( } if (ao) { - if (isOpen(coord + Z, group)) { + if (isOpen(coord + Z, block)) { faceAO(coord, X, Y, Z, texfaces[5], lights); } - if (isOpen(coord - Z, group)) { + if (isOpen(coord - Z, block)) { faceAO(coord, -X, Y, -Z, texfaces[4], lights); } - if (isOpen(coord + Y, group)) { + if (isOpen(coord + Y, block)) { faceAO(coord, X, -Z, Y, texfaces[3], lights); } - if (isOpen(coord - Y, group)) { + if (isOpen(coord - Y, block)) { faceAO(coord, X, Z, -Y, texfaces[2], lights); } - if (isOpen(coord + X, group)) { + if (isOpen(coord + X, block)) { faceAO(coord, -Z, Y, X, texfaces[1], lights); } - if (isOpen(coord - X, group)) { + if (isOpen(coord - X, block)) { faceAO(coord, Z, Y, -X, texfaces[0], lights); } } else { - if (isOpen(coord + Z, group)) { + if (isOpen(coord + Z, block)) { face(coord, X, Y, Z, texfaces[5], pickLight(coord + Z), lights); } - if (isOpen(coord - Z, group)) { + if (isOpen(coord - Z, block)) { face(coord, -X, Y, -Z, texfaces[4], pickLight(coord - Z), lights); } - if (isOpen(coord + Y, group)) { + if (isOpen(coord + Y, block)) { face(coord, X, -Z, Y, texfaces[3], pickLight(coord + Y), lights); } - if (isOpen(coord - Y, group)) { + if (isOpen(coord - Y, block)) { face(coord, X, Z, -Y, texfaces[2], pickLight(coord - Y), lights); } - if (isOpen(coord + X, group)) { + if (isOpen(coord + X, block)) { face(coord, -Z, Y, X, texfaces[1], pickLight(coord + X), lights); } - if (isOpen(coord - X, group)) { + if (isOpen(coord - X, block)) { face(coord, Z, Y, -X, texfaces[0], pickLight(coord - X), lights); } } diff --git a/src/graphics/render/BlocksRenderer.hpp b/src/graphics/render/BlocksRenderer.hpp index c0e0086e..d27f681b 100644 --- a/src/graphics/render/BlocksRenderer.hpp +++ b/src/graphics/render/BlocksRenderer.hpp @@ -118,7 +118,7 @@ class BlocksRenderer { bool isOpenForLight(int x, int y, int z) const; // Does block allow to see other blocks sides (is it transparent) - inline bool isOpen(const glm::ivec3& pos, ubyte group) const { + inline bool isOpen(const glm::ivec3& pos, const Block& def) const { auto id = voxelsBuffer->pickBlockId( chunk->x * CHUNK_W + pos.x, pos.y, chunk->z * CHUNK_D + pos.z ); @@ -126,7 +126,11 @@ class BlocksRenderer { return false; } const auto& block = *blockDefsCache[id]; - if ((block.drawGroup != group && block.lightPassing) || !block.rt.solid) { + if (((block.drawGroup != def.drawGroup) && block.drawGroup) || !block.rt.solid) { + return true; + } + if (def.culling == CullingMode::DISABLED || + (def.culling == CullingMode::OPTIONAL && id == def.rt.id)) { return true; } return !id; diff --git a/src/voxels/Block.cpp b/src/voxels/Block.cpp index 520f9f99..96bca245 100644 --- a/src/voxels/Block.cpp +++ b/src/voxels/Block.cpp @@ -49,6 +49,30 @@ std::optional BlockModel_from(std::string_view str) { return std::nullopt; } +std::string to_string(CullingMode mode) { + switch (mode) { + case CullingMode::DEFAULT: + return "default"; + case CullingMode::OPTIONAL: + return "optional"; + case CullingMode::DISABLED: + return "disabled"; + default: + return "unknown"; + } +} + +std::optional CullingMode_from(std::string_view str) { + if (str == "default") { + return CullingMode::DEFAULT; + } else if (str == "optional") { + return CullingMode::OPTIONAL; + } else if (str == "disabled") { + return CullingMode::DISABLED; + } + return std::nullopt; +} + CoordSystem::CoordSystem(glm::ivec3 axisX, glm::ivec3 axisY, glm::ivec3 axisZ) : axisX(axisX), axisY(axisY), axisZ(axisZ) { fix = glm::ivec3(0); diff --git a/src/voxels/Block.hpp b/src/voxels/Block.hpp index 557bf04c..eb232e8d 100644 --- a/src/voxels/Block.hpp +++ b/src/voxels/Block.hpp @@ -97,6 +97,15 @@ enum class BlockModel { std::string to_string(BlockModel model); std::optional BlockModel_from(std::string_view str); +enum class CullingMode { + DEFAULT, + OPTIONAL, + DISABLED, +}; + +std::string to_string(CullingMode mode); +std::optional CullingMode_from(std::string_view str); + using BoxModel = AABB; /// @brief Common kit of block properties applied to groups of blocks @@ -142,6 +151,9 @@ public: std::string modelName = ""; + /// @brief Culling mode + CullingMode culling = CullingMode::DEFAULT; + /// @brief Does the block passing lights into itself bool lightPassing = false; From dc8f5e7873de10b966a43e172b070af753f998b8 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 21 Dec 2024 08:13:05 +0300 Subject: [PATCH 17/44] add 'graphics.dense-render' setting --- res/layouts/pages/settings_graphics.xml.lua | 1 + res/texts/en_US.txt | 1 + res/texts/ru_RU.txt | 2 + src/files/settings_io.cpp | 1 + src/frontend/ContentGfxCache.cpp | 80 +++++++++++++-------- src/frontend/ContentGfxCache.hpp | 18 ++++- src/frontend/LevelFrontend.cpp | 21 ++++-- src/frontend/LevelFrontend.hpp | 9 ++- src/frontend/screens/LevelScreen.cpp | 8 ++- src/graphics/render/BlocksRenderer.cpp | 3 - src/graphics/render/BlocksRenderer.hpp | 8 ++- src/settings.hpp | 6 ++ 12 files changed, 111 insertions(+), 47 deletions(-) diff --git a/res/layouts/pages/settings_graphics.xml.lua b/res/layouts/pages/settings_graphics.xml.lua index 8a479a1c..c4503e52 100644 --- a/res/layouts/pages/settings_graphics.xml.lua +++ b/res/layouts/pages/settings_graphics.xml.lua @@ -41,4 +41,5 @@ function on_open() create_setting("graphics.fog-curve", "Fog Curve", 0.1) create_setting("graphics.gamma", "Gamma", 0.05, "", "graphics.gamma.tooltip") create_checkbox("graphics.backlight", "Backlight", "graphics.backlight.tooltip") + create_checkbox("graphics.dense-render", "Dense blocks render", "graphics.dense-render.tooltip") end diff --git a/res/texts/en_US.txt b/res/texts/en_US.txt index c19fe00a..e9b23897 100644 --- a/res/texts/en_US.txt +++ b/res/texts/en_US.txt @@ -16,6 +16,7 @@ devtools.traceback=Traceback (most recent call first) # Tooltips graphics.gamma.tooltip=Lighting brightness curve graphics.backlight.tooltip=Backlight to prevent total darkness +graphics.dense-render.tooltip=Enables transparency in blocks like leaves # settings settings.Controls Search Mode=Search by attached button name diff --git a/res/texts/ru_RU.txt b/res/texts/ru_RU.txt index ae591042..e78b5f72 100644 --- a/res/texts/ru_RU.txt +++ b/res/texts/ru_RU.txt @@ -28,6 +28,7 @@ pack.remove-confirm=Удалить весь поставляемый паком/ # Подсказки graphics.gamma.tooltip=Кривая яркости освещения graphics.backlight.tooltip=Подсветка, предотвращающая полную темноту +graphics.dense-render.tooltip=Включает прозрачность блоков, таких как листья. # Меню menu.Apply=Применить @@ -67,6 +68,7 @@ world.delete-confirm=Удалить мир безвозвратно? # Настройки settings.Ambient=Фон settings.Backlight=Подсветка +settings.Dense blocks render=Плотный рендер блоков settings.Camera Shaking=Тряска Камеры settings.Camera Inertia=Инерция Камеры settings.Camera FOV Effects=Эффекты поля зрения diff --git a/src/files/settings_io.cpp b/src/files/settings_io.cpp index d2a85f6a..fe251a11 100644 --- a/src/files/settings_io.cpp +++ b/src/files/settings_io.cpp @@ -68,6 +68,7 @@ SettingsHandler::SettingsHandler(EngineSettings& settings) { builder.section("graphics"); builder.add("fog-curve", &settings.graphics.fogCurve); builder.add("backlight", &settings.graphics.backlight); + builder.add("dense-render", &settings.graphics.denseRender); builder.add("gamma", &settings.graphics.gamma); builder.add("frustum-culling", &settings.graphics.frustumCulling); builder.add("skybox-resolution", &settings.graphics.skyboxResolution); diff --git a/src/frontend/ContentGfxCache.cpp b/src/frontend/ContentGfxCache.cpp index c6ba4e1c..844fd4e6 100644 --- a/src/frontend/ContentGfxCache.cpp +++ b/src/frontend/ContentGfxCache.cpp @@ -6,53 +6,71 @@ #include "assets/Assets.hpp" #include "content/Content.hpp" #include "content/ContentPack.hpp" -#include "core_defs.hpp" #include "graphics/core/Atlas.hpp" #include "maths/UVRegion.hpp" #include "voxels/Block.hpp" +#include "core_defs.hpp" +#include "settings.hpp" -ContentGfxCache::ContentGfxCache(const Content* content, const Assets& assets) - : content(content) { - auto indices = content->getIndices(); + +ContentGfxCache::ContentGfxCache( + const Content& content, + const Assets& assets, + const GraphicsSettings& settings +) + : content(content), assets(assets), settings(settings) { + refresh(); +} + +void ContentGfxCache::refresh(const Block& def, const Atlas& atlas) { + for (uint side = 0; side < 6; side++) { + std::string tex = def.textureFaces[side]; + if (def.culling == CullingMode::OPTIONAL && + !settings.denseRender.get() && atlas.has(tex + "_opaque")) { + tex = tex + "_opaque"; + } + if (atlas.has(tex)) { + sideregions[def.rt.id * 6 + side] = atlas.get(tex); + } else if (atlas.has(TEXTURE_NOTFOUND)) { + sideregions[def.rt.id * 6 + side] = atlas.get(TEXTURE_NOTFOUND); + } + } + if (def.model == BlockModel::custom) { + auto model = assets.require(def.modelName); + // temporary dirty fix tbh + if (def.modelName.find(':') == std::string::npos) { + for (auto& mesh : model.meshes) { + size_t pos = mesh.texture.find(':'); + if (pos == std::string::npos) { + continue; + } + if (auto region = atlas.getIf(mesh.texture.substr(pos+1))) { + for (auto& vertex : mesh.vertices) { + vertex.uv = region->apply(vertex.uv); + } + } + } + } + models[def.rt.id] = std::move(model); + } +} + +void ContentGfxCache::refresh() { + auto indices = content.getIndices(); sideregions = std::make_unique(indices->blocks.count() * 6); const auto& atlas = assets.require("blocks"); const auto& blocks = indices->blocks.getIterable(); for (blockid_t i = 0; i < blocks.size(); i++) { auto def = blocks[i]; - for (uint side = 0; side < 6; side++) { - const std::string& tex = def->textureFaces[side]; - if (atlas.has(tex)) { - sideregions[i * 6 + side] = atlas.get(tex); - } else if (atlas.has(TEXTURE_NOTFOUND)) { - sideregions[i * 6 + side] = atlas.get(TEXTURE_NOTFOUND); - } - } - if (def->model == BlockModel::custom) { - auto model = assets.require(def->modelName); - // temporary dirty fix tbh - if (def->modelName.find(':') == std::string::npos) { - for (auto& mesh : model.meshes) { - size_t pos = mesh.texture.find(':'); - if (pos == std::string::npos) { - continue; - } - if (auto region = atlas.getIf(mesh.texture.substr(pos+1))) { - for (auto& vertex : mesh.vertices) { - vertex.uv = region->apply(vertex.uv); - } - } - } - } - models[def->rt.id] = std::move(model); - } + refresh(*def, atlas); } } ContentGfxCache::~ContentGfxCache() = default; const Content* ContentGfxCache::getContent() const { - return content; + return &content; } const model::Model& ContentGfxCache::getModel(blockid_t id) const { diff --git a/src/frontend/ContentGfxCache.hpp b/src/frontend/ContentGfxCache.hpp index 96d46ea5..739d6c1d 100644 --- a/src/frontend/ContentGfxCache.hpp +++ b/src/frontend/ContentGfxCache.hpp @@ -10,19 +10,29 @@ class Content; class Assets; +class Atlas; +struct Block; struct UVRegion; +struct GraphicsSettings; namespace model { struct Model; } class ContentGfxCache { - const Content* content; + const Content& content; + const Assets& assets; + const GraphicsSettings& settings; + // array of block sides uv regions (6 per block) std::unique_ptr sideregions; std::unordered_map models; public: - ContentGfxCache(const Content* content, const Assets& assets); + ContentGfxCache( + const Content& content, + const Assets& assets, + const GraphicsSettings& settings + ); ~ContentGfxCache(); inline const UVRegion& getRegion(blockid_t id, int side) const { @@ -32,4 +42,8 @@ public: const model::Model& getModel(blockid_t id) const; const Content* getContent() const; + + void refresh(const Block& block, const Atlas& atlas); + + void refresh(); }; diff --git a/src/frontend/LevelFrontend.cpp b/src/frontend/LevelFrontend.cpp index 79784375..d3cbb9e8 100644 --- a/src/frontend/LevelFrontend.cpp +++ b/src/frontend/LevelFrontend.cpp @@ -14,12 +14,17 @@ #include "world/Level.hpp" LevelFrontend::LevelFrontend( - Player* currentPlayer, LevelController* controller, Assets& assets -) : level(*controller->getLevel()), - controller(controller), - assets(assets), - contentCache(std::make_unique(level.content, assets)) -{ + Player* currentPlayer, + LevelController* controller, + Assets& assets, + const EngineSettings& settings +) + : level(*controller->getLevel()), + controller(controller), + assets(assets), + contentCache(std::make_unique( + *level.content, assets, settings.graphics + )) { assets.store( BlocksPreview::build( *contentCache, assets, *level.content->getIndices() @@ -98,6 +103,10 @@ const Assets& LevelFrontend::getAssets() const { return assets; } +ContentGfxCache& LevelFrontend::getContentGfxCache() { + return *contentCache; +} + const ContentGfxCache& LevelFrontend::getContentGfxCache() const { return *contentCache; } diff --git a/src/frontend/LevelFrontend.hpp b/src/frontend/LevelFrontend.hpp index 163fc678..b53d267a 100644 --- a/src/frontend/LevelFrontend.hpp +++ b/src/frontend/LevelFrontend.hpp @@ -7,6 +7,7 @@ class Assets; class Player; class ContentGfxCache; class LevelController; +struct EngineSettings; class LevelFrontend { Level& level; @@ -14,12 +15,18 @@ class LevelFrontend { const Assets& assets; std::unique_ptr contentCache; public: - LevelFrontend(Player* currentPlayer, LevelController* controller, Assets& assets); + LevelFrontend( + Player* currentPlayer, + LevelController* controller, + Assets& assets, + const EngineSettings& settings + ); ~LevelFrontend(); Level& getLevel(); const Level& getLevel() const; const Assets& getAssets() const; const ContentGfxCache& getContentGfxCache() const; + ContentGfxCache& getContentGfxCache(); LevelController* getController() const; }; diff --git a/src/frontend/screens/LevelScreen.cpp b/src/frontend/screens/LevelScreen.cpp index 34d1db67..e38b3bec 100644 --- a/src/frontend/screens/LevelScreen.cpp +++ b/src/frontend/screens/LevelScreen.cpp @@ -17,6 +17,7 @@ #include "graphics/render/Decorator.hpp" #include "graphics/ui/elements/Menu.hpp" #include "graphics/ui/GUI.hpp" +#include "frontend/ContentGfxCache.hpp" #include "logic/LevelController.hpp" #include "logic/scripting/scripting_hud.hpp" #include "util/stringutil.hpp" @@ -42,7 +43,7 @@ LevelScreen::LevelScreen(Engine* engine, std::unique_ptr levelPtr) controller = std::make_unique(engine, std::move(levelPtr)); frontend = std::make_unique( - controller->getPlayer(), controller.get(), assets + controller->getPlayer(), controller.get(), assets, settings ); worldRenderer = std::make_unique( engine, *frontend, controller->getPlayer() @@ -57,6 +58,11 @@ LevelScreen::LevelScreen(Engine* engine, std::unique_ptr levelPtr) controller->getLevel()->chunks->saveAndClear(); worldRenderer->clear(); })); + keepAlive(settings.graphics.denseRender.observe([=](bool) { + controller->getLevel()->chunks->saveAndClear(); + worldRenderer->clear(); + frontend->getContentGfxCache().refresh(); + })); keepAlive(settings.camera.fov.observe([=](double value) { controller->getPlayer()->fpCamera->setFov(glm::radians(value)); })); diff --git a/src/graphics/render/BlocksRenderer.cpp b/src/graphics/render/BlocksRenderer.cpp index f1e8001f..56f1c4e2 100644 --- a/src/graphics/render/BlocksRenderer.cpp +++ b/src/graphics/render/BlocksRenderer.cpp @@ -8,9 +8,6 @@ #include "voxels/Chunks.hpp" #include "lighting/Lightmap.hpp" #include "frontend/ContentGfxCache.hpp" -#include "settings.hpp" - -#include const glm::vec3 BlocksRenderer::SUN_VECTOR (0.411934f, 0.863868f, -0.279161f); diff --git a/src/graphics/render/BlocksRenderer.hpp b/src/graphics/render/BlocksRenderer.hpp index d27f681b..c652b6a0 100644 --- a/src/graphics/render/BlocksRenderer.hpp +++ b/src/graphics/render/BlocksRenderer.hpp @@ -13,6 +13,7 @@ #include "graphics/core/MeshData.hpp" #include "maths/util.hpp" #include "commons.hpp" +#include "settings.hpp" class Content; class Mesh; @@ -22,7 +23,6 @@ class Chunks; class VoxelsVolume; class Chunks; class ContentGfxCache; -struct EngineSettings; struct UVRegion; class BlocksRenderer { @@ -129,8 +129,10 @@ class BlocksRenderer { if (((block.drawGroup != def.drawGroup) && block.drawGroup) || !block.rt.solid) { return true; } - if (def.culling == CullingMode::DISABLED || - (def.culling == CullingMode::OPTIONAL && id == def.rt.id)) { + if ((def.culling == CullingMode::DISABLED || + (def.culling == CullingMode::OPTIONAL && + settings.graphics.denseRender.get())) && + id == def.rt.id) { return true; } return !id; diff --git a/src/settings.hpp b/src/settings.hpp index b0eee035..48d72b27 100644 --- a/src/settings.hpp +++ b/src/settings.hpp @@ -63,16 +63,22 @@ struct GraphicsSettings { NumberSetting gamma {1.0f, 0.4f, 1.0f}; /// @brief Enable blocks backlight to prevent complete darkness FlagSetting backlight {true}; + /// @brief Disable culling with 'optional' mode + FlagSetting denseRender {true}; /// @brief Enable chunks frustum culling FlagSetting frustumCulling {true}; + /// @brief Skybox texture face resolution IntegerSetting skyboxResolution {64 + 32, 64, 128}; + /// @brief Chunk renderer vertices buffer capacity IntegerSetting chunkMaxVertices {200'000, 0, 4'000'000}; + /// @brief Limit of chunk renderers count IntegerSetting chunkMaxRenderers {6, -4, 32}; }; struct DebugSettings { /// @brief Turns off chunks saving/loading FlagSetting generatorTestMode {false}; + /// @brief Write lights cache FlagSetting doWriteLights {true}; }; From a5a72af796d6bb842538ab6b7ab47c4b8ce9e705 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 21 Dec 2024 08:31:58 +0300 Subject: [PATCH 18/44] fix msvc build --- src/frontend/ContentGfxCache.hpp | 2 +- src/graphics/render/Decorator.hpp | 2 +- src/graphics/render/ModelsGenerator.hpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/frontend/ContentGfxCache.hpp b/src/frontend/ContentGfxCache.hpp index 739d6c1d..cb5e2ad7 100644 --- a/src/frontend/ContentGfxCache.hpp +++ b/src/frontend/ContentGfxCache.hpp @@ -11,7 +11,7 @@ class Content; class Assets; class Atlas; -struct Block; +class Block; struct UVRegion; struct GraphicsSettings; diff --git a/src/graphics/render/Decorator.hpp b/src/graphics/render/Decorator.hpp index fbc196aa..422f6f77 100644 --- a/src/graphics/render/Decorator.hpp +++ b/src/graphics/render/Decorator.hpp @@ -14,7 +14,7 @@ class Chunks; class Camera; class Assets; class Player; -struct Block; +class Block; class Engine; class LevelController; class WorldRenderer; diff --git a/src/graphics/render/ModelsGenerator.hpp b/src/graphics/render/ModelsGenerator.hpp index 52bc56d0..c4665118 100644 --- a/src/graphics/render/ModelsGenerator.hpp +++ b/src/graphics/render/ModelsGenerator.hpp @@ -7,7 +7,7 @@ struct ItemDef; class Assets; class Content; -struct Block; +class Block; class ModelsGenerator { public: From 6f6421df53caf4a5a87329806f8af22fbf1f7022 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 21 Dec 2024 08:45:30 +0300 Subject: [PATCH 19/44] update doc/*/block-properties.md --- doc/en/block-properties.md | 7 +++++++ doc/ru/block-properties.md | 8 +++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/doc/en/block-properties.md b/doc/en/block-properties.md index fb874e0c..6400c910 100644 --- a/doc/en/block-properties.md +++ b/doc/en/block-properties.md @@ -81,6 +81,13 @@ Turns off block model shading Determines the presence of the vertex AO effect. Turned-on by default. +### *culling* + +Face culling mode: +- **default** - normal face culling +- **optional** - face culling among blocks of the same rendering group can be disabled via the `graphics.dense-render` setting. +- **disabled** - face culling among blocks of the same rendering group disabled. + ## Physics ### *obstacle* diff --git a/doc/ru/block-properties.md b/doc/ru/block-properties.md index 1862e659..366cf0fb 100644 --- a/doc/ru/block-properties.md +++ b/doc/ru/block-properties.md @@ -82,7 +82,6 @@ При значении `true` блок не препятствует прохождению вертикального луча солнечного света. - ### Без освещения - *shadeless* Выключает освещение на модели блока. @@ -91,6 +90,13 @@ Определяет наличие эффекта вершинного AO. Включен по-умолчанию. +### Отсечение - *culling* + +Режим отсечения граней: +- **default** - обычное отсечение граней +- **optional** - отсечение граней среди блоков одной группы отрисовки можно отключить через настройку `graphics.dense-render` (Плотный рендер блоков). +- **disabled** - отсечение граней среди блоков одной группы отрисовки отключено. + ## Физика ### Препятствие - *obstacle* From 2d7f448d88edcf2e765319506b7d74fb0614de99 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 21 Dec 2024 09:58:49 +0300 Subject: [PATCH 20/44] update leaves texture --- res/content/base/textures/blocks/leaves.png | Bin 896 -> 911 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/res/content/base/textures/blocks/leaves.png b/res/content/base/textures/blocks/leaves.png index a9cd60e3e88fcc465db4b9933f6daf962ae574b8..60b1fe36d2a663765a0b67ba6d17493685c93dbd 100644 GIT binary patch delta 888 zcmV-;1Bd*82agAkB!5;(L_t(|oIO)pZyQAv{${SMBS#1uzxBdIHO?erxH_Q0SdTH z)Os?`FU#28F(KagCgWVB_DzH$HegzK^OFf;k^nPrKo5x6eo)51$4J$fme6Q?NIiYE`D-Zdqoqp$z6)~X zHYP`1P!&S`agEja>FU)8`9c!V1rCo}Fb}%UJMlT<%G)~r{H?-wf}`-iPkI=x&6p2 zXACZC!|M~_l>sfHqLwuv9_*T&l^5qPYPfU##G#c~)hS#zkld;x!h>G8G)}jEIAJSm z!*o`$@ZU}ov2#AOd;AN9d>6X651TQ(_vt9zynmKwcdlia9#_fc*-UTN8J~!*Y80N4 z(1VH0-%WNTyUFTX5L>ARYjM=vUd|D6P_hhtB$iaP+ZOJnTaE^UKy$M)O^kc7!|i;s z!d|-)q8B2nF+a8Y0v4hI6kUNJxzVe25u8`)l||k-PZ{*<>2)XCyB`dtg?w{M8xL9I)*;xp3bzKM(0KZ)T%uU zWf7d-xf;g)p^1Fn!D3Fv###fT<1!A`>MXtxCD#pLDdWeldjJy!R8IyF;9~jXDe@Bh zxY~k9Hq5-qet+jq*FT@7@4q-?LtA~j$;L7g8KyfFas05!F1#8eO<`ESQ-wJFqDDru zi&Q3#M|sn8>gogUO}{Zh90K&n!NGnTT1uwLX$6Tf36-h?<~k5tZ3n6rM7d&N`I8y? z;j02$y;)+>Y=k<7jgIKU`HMk>lQOItp>)(lKmsad7k}B;k`U)+B;=1A1XYIJKifE^ zc-)8SIRzW{S}5+cP4g=&Ykgv4@kA zgVM2uOn+8`Ju6XUOosUOr&F}~OBs*uG;x7fJ>t7hjwq$;fB@f8q$ubO(TTs#MI=G+joZ;YfY)qb$u*LcEMuWY4Jx*sJs_8Iw z2LiGw0ZLSXAp2qKeZ=NedSRY_oM#L>PkQ{81w^?n91URSsq_C9WIuuU#jUUC?CJ+e zdSd*bgCGaX)l?o#2()#aU(|5_R*h-ThiPm=KqTUWIBa>C;5q(TDn$o%&aZx3Wm-Bw zax8=pM}8(1#?N2(*-LN9p6_BdfMM<3XI=aUmJ)WPdMoBE00000NkvXXu0mjfw7RXR From b372286a691f62cbfa36390aac8ac634abb8471c Mon Sep 17 00:00:00 2001 From: Xertis <118364459+Xertis@users.noreply.github.com> Date: Sat, 21 Dec 2024 10:44:25 +0300 Subject: [PATCH 21/44] changing the standard conf to 1 --- res/scripts/stdmin.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/scripts/stdmin.lua b/res/scripts/stdmin.lua index 56b11639..72383dce 100644 --- a/res/scripts/stdmin.lua +++ b/res/scripts/stdmin.lua @@ -52,7 +52,7 @@ function math.rand(low, high) end function math.normalize(num, conf) - conf = conf or 10 + conf = conf or 1 return (num / conf) % 1 end From 2b64128581708c03f34c40d90ff56a4fd6114faa Mon Sep 17 00:00:00 2001 From: Onran <100285264+Onran0@users.noreply.github.com> Date: Sun, 22 Dec 2024 01:54:55 +0900 Subject: [PATCH 22/44] Update stdmin.lua --- res/scripts/stdmin.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/scripts/stdmin.lua b/res/scripts/stdmin.lua index 72383dce..5b93fa2f 100644 --- a/res/scripts/stdmin.lua +++ b/res/scripts/stdmin.lua @@ -1,6 +1,6 @@ -- Check if given table is an array function is_array(x) - if #t > 0 then + if #x > 0 then return true end for k, v in pairs(x) do From 4ce2f3edcaf0cbe5eca144288e5664cf685203e8 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 22 Dec 2024 02:14:04 +0300 Subject: [PATCH 23/44] add new Bytearray:append overloads --- src/logic/scripting/lua/libs/libfile.cpp | 27 +++---------------- src/logic/scripting/lua/lua_util.hpp | 22 +++++++++++++++ .../lua/usertypes/lua_type_bytearray.cpp | 13 +++++++-- 3 files changed, 36 insertions(+), 26 deletions(-) diff --git a/src/logic/scripting/lua/libs/libfile.cpp b/src/logic/scripting/lua/libs/libfile.cpp index a27ac949..a38081c9 100644 --- a/src/logic/scripting/lua/libs/libfile.cpp +++ b/src/logic/scripting/lua/libs/libfile.cpp @@ -149,27 +149,6 @@ static int l_read_bytes(lua::State* L) { ); } -static void read_bytes_from_table( - lua::State* L, int tableIndex, std::vector& bytes -) { - if (!lua::istable(L, tableIndex)) { - throw std::runtime_error("table expected"); - } else { - size_t size = lua::objlen(L, tableIndex); - for (size_t i = 0; i < size; i++) { - lua::rawgeti(L, i + 1, tableIndex); - const int byte = lua::tointeger(L, -1); - lua::pop(L); - if (byte < 0 || byte > 255) { - throw std::runtime_error( - "invalid byte '" + std::to_string(byte) + "'" - ); - } - bytes.push_back(byte); - } - } -} - static int l_write_bytes(lua::State* L) { fs::path path = get_writeable_path(L); @@ -181,7 +160,7 @@ static int l_write_bytes(lua::State* L) { } std::vector bytes; - read_bytes_from_table(L, 2, bytes); + lua::read_bytes_from_table(L, 2, bytes); return lua::pushboolean( L, files::write_bytes(path, bytes.data(), bytes.size()) ); @@ -223,7 +202,7 @@ static int l_list(lua::State* L) { static int l_gzip_compress(lua::State* L) { std::vector bytes; - read_bytes_from_table(L, 1, bytes); + lua::read_bytes_from_table(L, 1, bytes); auto compressed_bytes = gzip::compress(bytes.data(), bytes.size()); int newTable = lua::gettop(L); @@ -237,7 +216,7 @@ static int l_gzip_compress(lua::State* L) { static int l_gzip_decompress(lua::State* L) { std::vector bytes; - read_bytes_from_table(L, 1, bytes); + lua::read_bytes_from_table(L, 1, bytes); auto decompressed_bytes = gzip::decompress(bytes.data(), bytes.size()); int newTable = lua::gettop(L); diff --git a/src/logic/scripting/lua/lua_util.hpp b/src/logic/scripting/lua/lua_util.hpp index 983abb39..f9da3b21 100644 --- a/src/logic/scripting/lua/lua_util.hpp +++ b/src/logic/scripting/lua/lua_util.hpp @@ -2,6 +2,7 @@ #include #include +#include #include #include "data/dv.hpp" @@ -698,4 +699,25 @@ namespace lua { } return def; } + + inline void read_bytes_from_table( + lua::State* L, int tableIndex, std::vector& bytes + ) { + if (!lua::istable(L, tableIndex)) { + throw std::runtime_error("table expected"); + } else { + size_t size = lua::objlen(L, tableIndex); + for (size_t i = 0; i < size; i++) { + lua::rawgeti(L, i + 1, tableIndex); + const int byte = lua::tointeger(L, -1); + lua::pop(L); + if (byte < 0 || byte > 255) { + throw std::runtime_error( + "invalid byte '" + std::to_string(byte) + "'" + ); + } + bytes.push_back(byte); + } + } + } } diff --git a/src/logic/scripting/lua/usertypes/lua_type_bytearray.cpp b/src/logic/scripting/lua/usertypes/lua_type_bytearray.cpp index 0493995b..c982d2d8 100644 --- a/src/logic/scripting/lua/usertypes/lua_type_bytearray.cpp +++ b/src/logic/scripting/lua/usertypes/lua_type_bytearray.cpp @@ -2,6 +2,7 @@ #include +#include "util/listutil.hpp" #include "../lua_util.hpp" using namespace lua; @@ -18,8 +19,16 @@ LuaBytearray::~LuaBytearray() { static int l_append(lua::State* L) { if (auto buffer = touserdata(L, 1)) { - auto value = tointeger(L, 2); - buffer->data().push_back(static_cast(value)); + if (lua::isnumber(L, 2)) { + auto value = tointeger(L, 2); + buffer->data().push_back(static_cast(value)); + } else if (lua::istable(L, 2)) { + lua::read_bytes_from_table(L, 2, buffer->data()); + } else if (auto extension = lua::touserdata(L, 2)) { + util::concat(buffer->data(), extension->data()); + } else { + throw std::runtime_error("integer/table/Bytearray expected"); + } } return 0; } From 212cc486d4f2e7aa970cc40c727fb417d192e737 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 22 Dec 2024 02:22:00 +0300 Subject: [PATCH 24/44] optimize data_buffer:put_bytes for Bytearray --- res/modules/data_buffer.lua | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/res/modules/data_buffer.lua b/res/modules/data_buffer.lua index e3d207ff..67214835 100644 --- a/res/modules/data_buffer.lua +++ b/res/modules/data_buffer.lua @@ -72,9 +72,14 @@ function data_buffer:put_byte(byte) end function data_buffer:put_bytes(bytes) - for i = 1, #bytes do - self:put_byte(bytes[i]) - end + if type(self.bytes) == 'table' then + for i = 1, #bytes do + self:put_byte(bytes[i]) + end + else + self.bytes:append(bytes) + self.pos = self.pos + #bytes + end end function data_buffer:put_single(single) @@ -308,4 +313,4 @@ end setmetatable(data_buffer, data_buffer) -return data_buffer \ No newline at end of file +return data_buffer From d6ccdf98717a9152311f580f128d5e3dbb8710de Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 22 Dec 2024 02:27:00 +0300 Subject: [PATCH 25/44] add new Bytearray:insert overloads --- .../lua/usertypes/lua_type_bytearray.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/logic/scripting/lua/usertypes/lua_type_bytearray.cpp b/src/logic/scripting/lua/usertypes/lua_type_bytearray.cpp index c982d2d8..fc7ecf6f 100644 --- a/src/logic/scripting/lua/usertypes/lua_type_bytearray.cpp +++ b/src/logic/scripting/lua/usertypes/lua_type_bytearray.cpp @@ -43,8 +43,19 @@ static int l_insert(lua::State* L) { if (static_cast(index) > data.size()) { return 0; } - auto value = tointeger(L, 3); - data.insert(data.begin() + index, static_cast(value)); + if (lua::isnumber(L, 3)) { + auto value = tointeger(L, 3); + data.insert(data.begin() + index, static_cast(value)); + } else if (lua::istable(L, 3)) { + std::vector temp; + lua::read_bytes_from_table(L, 3, temp); + data.insert(data.begin() + index, temp.begin(), temp.end()); + } else if (auto extension = lua::touserdata(L, 3)) { + const std::vector& src = extension->data(); + data.insert(data.begin() + index, src.begin(), src.end()); + } else { + throw std::runtime_error("integer/table/Bytearray expected"); + } return 0; } From c9b69fdfb2b04b66d54ebea2efc57accda512cca Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 22 Dec 2024 02:32:00 +0300 Subject: [PATCH 26/44] fix data_buffer:put_bytes --- res/modules/data_buffer.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/modules/data_buffer.lua b/res/modules/data_buffer.lua index 67214835..91dce29c 100644 --- a/res/modules/data_buffer.lua +++ b/res/modules/data_buffer.lua @@ -77,7 +77,7 @@ function data_buffer:put_bytes(bytes) self:put_byte(bytes[i]) end else - self.bytes:append(bytes) + self.bytes:insert(self.pos, bytes) self.pos = self.pos + #bytes end end From 240470f69b2d459cd71a1f6aea080598e2632095 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 22 Dec 2024 02:49:10 +0300 Subject: [PATCH 27/44] add new ore creation to the world-generator docs --- doc/en/world-generator.md | 22 ++++++++++++++++++++++ doc/ru/world-generator.md | 21 +++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/doc/en/world-generator.md b/doc/en/world-generator.md index b0ab265c..40fd1b37 100644 --- a/doc/en/world-generator.md +++ b/doc/en/world-generator.md @@ -27,6 +27,7 @@ * [Small structures placement](#small-structures-placement) * [Wide structures placement](#wide-structures-placement) - [Structural air](#structural-air) +- [Generator 'Demo' (base:demo)](#generator-demo-basedemo) ## Basic concepts @@ -473,3 +474,24 @@ function place_structures_wide( `core:struct_air` - a block that should be used in chunks to mark empty space that should not be filled with blocks when generated in the world. + +# Generator 'Demo' (base:demo) + +## Adding new ore + +To add a new ore in your pack: +1. In the `generators` folder, create a `demo.files` folder (you don't need to create demo.toml). + +2. In the created folder, create a fragments folder and place the ore fragment file in it. +3. In `demo.files`, create a structures.toml file: +```toml +fragment_name = {} +``` +4. Also in `demo.files`, create an ores.json file: +```json +[ + {"struct": "fragment_name", "rarity": rarity} +] +``` +The higher the rarity value, the less ore generation chance. +You can rely on the rarity of coal ore: 4400. diff --git a/doc/ru/world-generator.md b/doc/ru/world-generator.md index 5c1c6e6e..7f7be5c4 100644 --- a/doc/ru/world-generator.md +++ b/doc/ru/world-generator.md @@ -27,6 +27,7 @@ * [Расстановка малых структур](#расстановка-малых-структур) * [Расстановка 'широких' структур](#расстановка-широких-структур) - [Структурный воздух](#структурный-воздух) +- [Генератор 'Demo' (base:demo)](#генератор-demo-basedemo) ## Основные понятия @@ -478,3 +479,23 @@ function place_structures_wide( `core:struct_air` - блок, которые следует использовать в фрагментах для обозначения пустого пространства, которое не должно заполняться блоками при генерации в мире. + +# Генератор 'Demo' (base:demo) + +## Добавление новой руды + +Чтобы добавить новую руду из своего пака: +1. В папке `generators` создайте папку `demo.files` (demo.toml создавать не нужно). +2. В созданной папке создайте папку fragments и поместите в неё файл фрагмента руды. +3. В `demo.files` создайте файл structures.toml: +```toml +имя_фрагмента = {} +``` +4. Также в `demo.files` создайте файл ores.json: +```json +[ + {"struct": "имя_фрагмента", "rarity": редкость} +] +``` +Чем выше значение редкости, тем меньше вероятность генерации руды. +Опираться можно на редкость угольной руды: 4400. From 90b1f63406d7d9d2488e6b8c86cdff1fcb939411 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 23 Dec 2024 14:13:45 +0300 Subject: [PATCH 28/44] update leaves texture & update mip-mapping settings --- res/content/base/textures/blocks/leaves.png | Bin 911 -> 899 bytes src/graphics/core/GLTexture.cpp | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/res/content/base/textures/blocks/leaves.png b/res/content/base/textures/blocks/leaves.png index 60b1fe36d2a663765a0b67ba6d17493685c93dbd..46b38d224dd95be5feab37d8e7156006c69a4f68 100644 GIT binary patch delta 876 zcmV-y1C#uZ2ZINYB!5atL_t(|oJCVjZyQwM z6hxb<3y=^CgoI#&5F36A8^o@Fija^Hut1=Oq^htAZ9`2yl&ZB;+O$q=*Ky*>`1|AX zJfZ26uI9a&bMHI%o--1}Qb+wfG2w*jSFpNLL?K~PPfX@~qJK)yzMyjVh>E43^MwCb z2mkz}g5{M8q$e+v>lGNGHc)Bd)ei^w>Q`x+c{{+mU&8Xuf}K=O7O5|$aVAlue4oQU z+XXtC@Ogt%sTL+3xA)D@GqY~uqhW-_oz4GX0zP3aoacd=-BCQ)>OjMl^mp@X^qXj8p07j z{!W!`P_@{!pQEn@*dwl}aSQi0ENEew2ZmGxd)>(9TF58sB<))*cr*o>Yz1?l4D)Ya zZqkD2Uyu5^WHwNex^Q${fiEPZl4qnJ?!n~-?kpDQrGF3lSsEL5BlWNa#Y0&C$9mEc z45JG}V=5BY_VH+KADg!dVjkjlFNslkly@ske3%TnE&Dt9Z0%Q;Zqvt@-+L*WwrFauhrODMtzrYC<6f9% z9a1(^hwg5oO@y-__3`D48M=CLlk|v(+d|D$+q_F1>icc)%ce48Up z7)9>(V(ev&hr=%X{&k&BzAkeII~jE${^JgH+WikEx_?p!ZDj2L0000SMBS#1uzxBdIHO?erxH_Q0SdTH z)Os?`FU#28F(KagCgWVB_DzH$HegzK^OFf;k^nPrKo5x6eo)51$4J$fme6Q?NIiYE`D-Zdqoqp$z6)~X zHYP`1P!&S`agEja>FU)8`9c!V1rCo}Fb}%UJMlT<%G)~r{H?-wf}`-iPkI=x&6p2 zXACZC!|M~_l>sfHqLwuv9_*T&l^5qPYPfU##G#c~)hS#zkld;x!h>G8G)}jEIAJSm z!*o`$@ZU}ov2#AOd;AN9d>6X651TQ(_vt9zynmKwcdlia9#_fc*-UTN8J~!*Y80N4 z(1VH0-%WNTyUFTX5L>ARYjM=vUd|D6P_hhtB$iaP+ZOJnTaE^UKy$M)O^kc7!|i;s z!d|-)q8B2nF+a8Y0v4hI6kUNJxzVe25u8`)l||k-PZ{ Date: Mon, 23 Dec 2024 16:04:48 +0300 Subject: [PATCH 29/44] add 'angle_spread' property --- src/graphics/render/Emitter.cpp | 7 ++++++- src/graphics/render/Emitter.hpp | 4 +++- src/graphics/render/ParticlesRenderer.cpp | 17 +++++++++++++++-- src/presets/ParticlesPreset.cpp | 2 ++ src/presets/ParticlesPreset.hpp | 2 ++ 5 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/graphics/render/Emitter.cpp b/src/graphics/render/Emitter.cpp index 82848a63..09e1ddc8 100644 --- a/src/graphics/render/Emitter.cpp +++ b/src/graphics/render/Emitter.cpp @@ -23,8 +23,9 @@ Emitter::Emitter( texture(texture), count(count), preset(std::move(preset)) { + random.setSeed(rand()); this->prototype.emitter = this; - timer = preset.spawnInterval; + timer = preset.spawnInterval * random.randFloat(); } const Texture* Emitter::getTexture() const { @@ -83,6 +84,10 @@ void Emitter::update( Particle particle = prototype; particle.emitter = this; particle.random = random.rand32(); + if (glm::abs(preset.angleSpread) >= 0.005f) { + particle.angle = + random.randFloat() * preset.angleSpread * glm::pi() * 2; + } glm::vec3 spawnOffset = generate_coord(preset.spawnShape); spawnOffset *= preset.spawnSpread; diff --git a/src/graphics/render/Emitter.hpp b/src/graphics/render/Emitter.hpp index c1d6c168..0ad34053 100644 --- a/src/graphics/render/Emitter.hpp +++ b/src/graphics/render/Emitter.hpp @@ -27,6 +27,8 @@ struct Particle { float lifetime; /// @brief UV region UVRegion region; + /// @brief Current rotation angle + float angle; }; class Texture; @@ -39,7 +41,7 @@ class Emitter { EmitterOrigin origin; /// @brief Particle prototype Particle prototype; - /// @brief Particle + /// @brief Particle texture const Texture* texture; /// @brief Number of particles should be spawned before emitter deactivation. /// -1 is infinite. diff --git a/src/graphics/render/ParticlesRenderer.cpp b/src/graphics/render/ParticlesRenderer.cpp index 0e2292a5..71ec24c5 100644 --- a/src/graphics/render/ParticlesRenderer.cpp +++ b/src/graphics/render/ParticlesRenderer.cpp @@ -91,10 +91,23 @@ void ParticlesRenderer::renderParticles(const Camera& camera, float delta) { } float scale = 1.0f + ((particle.random ^ 2628172) % 1000) * 0.001f * preset.sizeSpread; + + glm::vec3 localRight = right; + glm::vec3 localUp = preset.globalUpVector ? glm::vec3(0, 1, 0) : up; + float angle = particle.angle; + if (glm::abs(angle) >= 0.005f) { + glm::vec3 rotatedRight(glm::cos(angle), -glm::sin(angle), 0.0f); + glm::vec3 rotatedUp(glm::sin(angle), glm::cos(angle), 0.0f); + + localRight = right * rotatedRight.x + localUp * rotatedRight.y + + camera.front * rotatedRight.z; + localUp = right * rotatedUp.x + localUp * rotatedUp.y + + camera.front * rotatedUp.z; + } batch->quad( particle.position, - right, - preset.globalUpVector ? glm::vec3(0, 1, 0) : up, + localRight, + localUp, preset.size * scale, light, glm::vec3(1.0f), diff --git a/src/presets/ParticlesPreset.cpp b/src/presets/ParticlesPreset.cpp index 181dbeb5..27274442 100644 --- a/src/presets/ParticlesPreset.cpp +++ b/src/presets/ParticlesPreset.cpp @@ -43,6 +43,7 @@ dv::value ParticlesPreset::serialize() const { root["explosion"] = dv::to_value(explosion); root["size"] = dv::to_value(size); root["size_spread"] = sizeSpread; + root["angle_spread"] = angleSpread; root["spawn_spread"] = dv::to_value(size); root["spawn_shape"] = to_string(spawnShape); root["random_sub_uv"] = randomSubUV; @@ -58,6 +59,7 @@ void ParticlesPreset::deserialize(const dv::value& src) { src.at("spawn_interval").get(spawnInterval); src.at("lifetime").get(lifetime); src.at("lifetime_spread").get(lifetimeSpread); + src.at("angle_spread").get(angleSpread); src.at("random_sub_uv").get(randomSubUV); if (src.has("velocity")) { dv::get_vec(src["velocity"], velocity); diff --git a/src/presets/ParticlesPreset.hpp b/src/presets/ParticlesPreset.hpp index f8d5f2b4..67c6c91b 100644 --- a/src/presets/ParticlesPreset.hpp +++ b/src/presets/ParticlesPreset.hpp @@ -44,6 +44,8 @@ struct ParticlesPreset : public Serializable { glm::vec3 size {0.1f}; /// @brief Particles size spread float sizeSpread = 0.2f; + /// @brief Random initial angle spread + float angleSpread = 0.0f; /// @brief Spawn spread shape ParticleSpawnShape spawnShape = BALL; /// @brief Spawn spread From 6be640458d6b4ae46866b342ca0f26e561ead125 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 23 Dec 2024 16:26:45 +0300 Subject: [PATCH 30/44] fix particles lighting --- src/graphics/render/ParticlesRenderer.cpp | 25 ++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/graphics/render/ParticlesRenderer.cpp b/src/graphics/render/ParticlesRenderer.cpp index 71ec24c5..a68f56e2 100644 --- a/src/graphics/render/ParticlesRenderer.cpp +++ b/src/graphics/render/ParticlesRenderer.cpp @@ -82,15 +82,34 @@ void ParticlesRenderer::renderParticles(const Camera& camera, float delta) { } update_particle(particle, delta, chunks); + float scale = 1.0f + ((particle.random ^ 2628172) % 1000) * + 0.001f * preset.sizeSpread; + glm::vec4 light(1, 1, 1, 0); if (preset.lighting) { light = MainBatch::sampleLight( - particle.position, chunks, backlight + particle.position, + chunks, + backlight ); + for (int x = -1; x <= 1; x++) { + for (int y = -1; y <= 1; y++) { + for (int z = -1; z <= 1; z++) { + light = glm::max( + light, + MainBatch::sampleLight( + particle.position - preset.size * scale * + glm::vec3(x, y, z), + chunks, + backlight + ) + ); + } + } + } light *= 0.9f + (particle.random % 100) * 0.001f; } - float scale = 1.0f + ((particle.random ^ 2628172) % 1000) * - 0.001f * preset.sizeSpread; + glm::vec3 localRight = right; glm::vec3 localUp = preset.globalUpVector ? glm::vec3(0, 1, 0) : up; From 6ac088f7b9599dc0950dc4b3d208a13e8b5ae234 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 23 Dec 2024 16:34:08 +0300 Subject: [PATCH 31/44] set default particles render distance to 32 --- src/graphics/render/ParticlesRenderer.cpp | 5 +++-- src/presets/ParticlesPreset.hpp | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/graphics/render/ParticlesRenderer.cpp b/src/graphics/render/ParticlesRenderer.cpp index a68f56e2..6c3ed73c 100644 --- a/src/graphics/render/ParticlesRenderer.cpp +++ b/src/graphics/render/ParticlesRenderer.cpp @@ -92,14 +92,15 @@ void ParticlesRenderer::renderParticles(const Camera& camera, float delta) { chunks, backlight ); + auto size = glm::max(glm::vec3(0.5f), preset.size * scale); for (int x = -1; x <= 1; x++) { for (int y = -1; y <= 1; y++) { for (int z = -1; z <= 1; z++) { light = glm::max( light, MainBatch::sampleLight( - particle.position - preset.size * scale * - glm::vec3(x, y, z), + particle.position - + size * glm::vec3(x, y, z), chunks, backlight ) diff --git a/src/presets/ParticlesPreset.hpp b/src/presets/ParticlesPreset.hpp index 67c6c91b..10b9f088 100644 --- a/src/presets/ParticlesPreset.hpp +++ b/src/presets/ParticlesPreset.hpp @@ -27,7 +27,7 @@ struct ParticlesPreset : public Serializable { /// @brief Use global up vector instead of camera-dependent one bool globalUpVector = false; /// @brief Max distance of actually spawning particles. - float maxDistance = 16.0f; + float maxDistance = 32.0f; /// @brief Particles spawn interval float spawnInterval = 0.1f; /// @brief Particle life time From 7f95306c6525b91765c55ce8b1ada46d5dc77e2b Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 23 Dec 2024 16:48:07 +0300 Subject: [PATCH 32/44] add 'min_angular_vel', 'max_angular_vel' properties --- src/graphics/render/Emitter.cpp | 5 +++++ src/graphics/render/Emitter.hpp | 2 ++ src/graphics/render/ParticlesRenderer.cpp | 2 ++ src/presets/ParticlesPreset.cpp | 4 ++++ src/presets/ParticlesPreset.hpp | 4 ++++ 5 files changed, 17 insertions(+) diff --git a/src/graphics/render/Emitter.cpp b/src/graphics/render/Emitter.cpp index 09e1ddc8..76b2f018 100644 --- a/src/graphics/render/Emitter.cpp +++ b/src/graphics/render/Emitter.cpp @@ -88,6 +88,11 @@ void Emitter::update( particle.angle = random.randFloat() * preset.angleSpread * glm::pi() * 2; } + particle.angularVelocity = + (preset.minAngularVelocity + + random.randFloat() * + (preset.maxAngularVelocity - preset.minAngularVelocity)) * + ((random.rand() % 2) * 2 - 1); glm::vec3 spawnOffset = generate_coord(preset.spawnShape); spawnOffset *= preset.spawnSpread; diff --git a/src/graphics/render/Emitter.hpp b/src/graphics/render/Emitter.hpp index 0ad34053..b2a371ad 100644 --- a/src/graphics/render/Emitter.hpp +++ b/src/graphics/render/Emitter.hpp @@ -29,6 +29,8 @@ struct Particle { UVRegion region; /// @brief Current rotation angle float angle; + /// @brief Angular velocity + float angularVelocity; }; class Texture; diff --git a/src/graphics/render/ParticlesRenderer.cpp b/src/graphics/render/ParticlesRenderer.cpp index 6c3ed73c..f3a30cdd 100644 --- a/src/graphics/render/ParticlesRenderer.cpp +++ b/src/graphics/render/ParticlesRenderer.cpp @@ -31,12 +31,14 @@ static inline void update_particle( const auto& preset = particle.emitter->preset; auto& pos = particle.position; auto& vel = particle.velocity; + auto& angle = particle.angle; vel += delta * preset.acceleration; if (preset.collision && chunks.isObstacleAt(pos + vel * delta)) { vel *= 0.0f; } pos += vel * delta; + angle += particle.angularVelocity * delta; particle.lifetime -= delta; } diff --git a/src/presets/ParticlesPreset.cpp b/src/presets/ParticlesPreset.cpp index 27274442..8a007076 100644 --- a/src/presets/ParticlesPreset.cpp +++ b/src/presets/ParticlesPreset.cpp @@ -44,6 +44,8 @@ dv::value ParticlesPreset::serialize() const { root["size"] = dv::to_value(size); root["size_spread"] = sizeSpread; root["angle_spread"] = angleSpread; + root["min_angular_vel"] = minAngularVelocity; + root["max_angular_vel"] = maxAngularVelocity; root["spawn_spread"] = dv::to_value(size); root["spawn_shape"] = to_string(spawnShape); root["random_sub_uv"] = randomSubUV; @@ -60,6 +62,8 @@ void ParticlesPreset::deserialize(const dv::value& src) { src.at("lifetime").get(lifetime); src.at("lifetime_spread").get(lifetimeSpread); src.at("angle_spread").get(angleSpread); + src.at("min_angular_vel").get(minAngularVelocity); + src.at("max_angular_vel").get(maxAngularVelocity); src.at("random_sub_uv").get(randomSubUV); if (src.has("velocity")) { dv::get_vec(src["velocity"], velocity); diff --git a/src/presets/ParticlesPreset.hpp b/src/presets/ParticlesPreset.hpp index 10b9f088..2b955d13 100644 --- a/src/presets/ParticlesPreset.hpp +++ b/src/presets/ParticlesPreset.hpp @@ -46,6 +46,10 @@ struct ParticlesPreset : public Serializable { float sizeSpread = 0.2f; /// @brief Random initial angle spread float angleSpread = 0.0f; + /// @brief Minimum angular velocity + float minAngularVelocity = 0.0f; + /// @brief Maximum angular velocity + float maxAngularVelocity = 0.0f; /// @brief Spawn spread shape ParticleSpawnShape spawnShape = BALL; /// @brief Spawn spread From e899575a7ab9a6c9c3ffab020307eedaf4dee434 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 23 Dec 2024 16:54:25 +0300 Subject: [PATCH 33/44] update Emitter randomizer --- src/graphics/render/Emitter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/render/Emitter.cpp b/src/graphics/render/Emitter.cpp index 76b2f018..ff8413d5 100644 --- a/src/graphics/render/Emitter.cpp +++ b/src/graphics/render/Emitter.cpp @@ -23,7 +23,7 @@ Emitter::Emitter( texture(texture), count(count), preset(std::move(preset)) { - random.setSeed(rand()); + random.setSeed(reinterpret_cast(this)); this->prototype.emitter = this; timer = preset.spawnInterval * random.randFloat(); } From 78761a445afc14b4839682a2333cd3b2a4dd02f3 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 23 Dec 2024 16:54:39 +0300 Subject: [PATCH 34/44] add leaf texture --- res/content/base/textures/particles/leaf_0.png | Bin 0 -> 5263 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 res/content/base/textures/particles/leaf_0.png diff --git a/res/content/base/textures/particles/leaf_0.png b/res/content/base/textures/particles/leaf_0.png new file mode 100644 index 0000000000000000000000000000000000000000..282fff809871a6043875be914ac134b734754131 GIT binary patch literal 5263 zcmeHLX;>5I77k#cA}AEOxA%QN)QkO5m3YyF_}z4kSt^&fr0{B6$B9q z6e%uP6s3TzTgA0h1?$4%f+z*6pyCP$RxO}+5)kp;{_#H7e@>oBX3lrc`RBATg&FXUet=Obv=k`sL^e>&u%4@k9LG5s|9Jdkv zYhwFLxqa2L2@5Cpm zM_*h|SzgKG-vS-iojkq$ZXiHGd%K16)QD$H#x36sKBB8yfrpbHD z&I{K4=0WLKqO3?w>oWmPq4u}(C08ew(!P{dg@-FgRUYZ7sC;z9ZC81P@s5&Hywgd$ z$JhDY@lACeH_(4LyyR@^XR{8J1;^H@`7y9`-_;AzX%{Y5<$j)$ai^=TxxaVJ@yx}F z+6QMQDy%K{8KF*$t%}ve3V9GVKB2YlT77QOc8ffp4USe{E?!T3a&k*jNxg+na`@xh zf@UL6>!2~eGS?dOEW>Z5?9XyS%!m_>F;5?pg~`SNYivEU#bfK|Ns6mOcYI&rxJI%% zE?UH!%T%nPr^2V7F8gWaj?l6q7nfz66wX4wY!fqk$2C@`nru|<9o(ELf^^&93+Emz zqDF>XEoLngL>FYwP4f$$&vFpYYfqPpneAWgR&;wW7(IOwxTihsPHHx0xz&$DDR{x)mr(B{HkN9>)Smo~dyy}?}jAS7CI3%E)-vKRg}a#zrp5@cRMP313T zEHhSo%(A&N+**EK=n+=$mY8|==>zo8gmVSg(-tQN#NKGk3rzU~e#m?ou%eN$?s{)l zLtWd>#6vQ#>e$WCGBP&@96Sh3FE@Q%5Pe19i z;mqpJ&DH0=_h`M}eB08zIf}X}qH*n4nVaMZ>2^mi385qE^XjwkwON-gXQ!%q*XH{C z*x6WHQLv8Yv}aeddreAl{KFVyXd980oFAA~n0m3qw>I={u%mYU%Jg&Z*)wjXMA z`%AU?q4e|f^2XxLV?u?`T;c|Hy);QZF3mcuY>Xg(8@fSP$rWaonO2>IZ)ys5HH&hh zCNVgFJ>OlK57`H)Ak?GyuAn-B!);&0sEtq^t;{=-_O!Rf9DKC5t>cWD`00%w2Bf#r zO*D3VhodhY6w5E#C+`o;s=KxPT)#ClVihN0)IALCi%@i37Wa?qBl&ln;>GcFIs(CH zjl|1~=jY}1rjg+7qcAax?R$!6^G#r|zqj*PQ=6Exye%&4)0j~c(|AQ!%*&DdW4+@F zsE#vTH>Rwps@is@boGY)6=N$>fEOmWAN^U}L7d+Doz2qIFaCV$QTz2h#m&T|`rYJ< z4{Xh-E%eK&hjT8L&%YJQA$v|II>P7k{dZ<}g-1O9v}?e%dVhcCKxO>ZV`q|*IPT{y zF3)HMwzeLytnE8Zob|hNH>*3}&vN{1Wq9|C3{?Y`EKU>6U;-CGuxe4XQ4)mA~%K4eqrCgwR};2VOKUW2I#%bw0H2-O^$4|yVutgQ}8d(uBnGF zHNT27$$#m1ytQ$MkLOLgBBrG=hyAD0Y)S$}7#zD3$mKZ^I>o(Q*7nzvI>LJHHX=3m zO*R#UO_wLF_F8_x_xeMR&L>X_n@?(&_VgJ!?Np{R#_bEi8~%U$1? z0?bt>Rp5=EKyaU}Q}EFhm>LjZVu_4R>^yps2uOr%VknJE<|@3fNQrN}5(|zG2tngl zpe!MAwuia94#5GWn3@mhq|q`JqGJ;cxCnl&H&NF=RR>#Buap^eaHI^cY`zT#pNO# zIjYg8=f`0a_46Y_IVuq%hD(f0r!io%2oy2tRFI0%L?DwwW`P(>NEI@e5QNgO5m0_I zm6|U@F+CIx?kd4?SVD-;A`2l<#KQCtFa|PdEE*^xGx;zqpfV_A;RuL8r39}^e)Pz! z^iV<^iou5|7{+9QGzx@*R7gkz1t=8;aSQ>5LP8;iG7L~c6qzSiO8NM5N~C--MpDSc zh5^0c$Q+&@n@DjbzqRn9`Dzg!z$Pw`$TYgQ10fPA7Odv$)r1%@l|`ddVTcCPS!DRF z(_&1i!Yfga36WjlL0tW^AUGLZSiZhaaR5UE&IR#OVtln+86uZQvx)kY0DYvPyaD&Y zMe&uWaE~~B#ShhdFcvd-H~0udOAJE*U?^LJj}A_v;>Tixa^i7=Lue#lCdTmRd#Iq^ z*d_n8Sado>XF_}skWOU^Mfeg6XzwQdKU0J#AO#MAXb6Rj!2dzfouqGEZx+>^^k2(9=rE$w z;nED+@D7SMWYTa)9?}dK`9mH<<@O<`0DzB^yqCTo<@zYsdnxc<&L6Amqg?N$zB#=4ft-)RN(K!A-vYVwjVF~7PpL6_=c$ngfSEJrxBr` za0+fTQ~Pnf%{nY5TiDp=%*igpO^6?7PROU%(E1*mzxN6qdbb&w=eM4CRr4!;Y{z~d z*p`eR4IXnIyxv=Pa>}w3{WXB|Z>9^^mVH79>$LKp@x^2OPecO2&pUuqF?V^&zX1YR B Date: Mon, 23 Dec 2024 17:26:22 +0300 Subject: [PATCH 35/44] upgrade emitters garbage collection --- src/graphics/render/Emitter.cpp | 7 ++++++- src/graphics/render/Emitter.hpp | 6 ++++++ src/graphics/render/ParticlesRenderer.cpp | 20 +++++++++----------- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/graphics/render/Emitter.cpp b/src/graphics/render/Emitter.cpp index ff8413d5..88951588 100644 --- a/src/graphics/render/Emitter.cpp +++ b/src/graphics/render/Emitter.cpp @@ -19,7 +19,7 @@ Emitter::Emitter( ) : level(level), origin(std::move(origin)), - prototype({this, 0, glm::vec3(), preset.velocity, preset.lifetime, region}), + prototype({this, 0, {}, preset.velocity, preset.lifetime, region}), texture(texture), count(count), preset(std::move(preset)) { @@ -113,6 +113,7 @@ void Emitter::update( if (count > 0) { count--; } + refCount++; } } @@ -124,6 +125,10 @@ bool Emitter::isDead() const { return count == 0; } +bool Emitter::isReferred() const { + return refCount > 0; +} + const EmitterOrigin& Emitter::getOrigin() const { return origin; } diff --git a/src/graphics/render/Emitter.hpp b/src/graphics/render/Emitter.hpp index b2a371ad..ce1ec8f4 100644 --- a/src/graphics/render/Emitter.hpp +++ b/src/graphics/render/Emitter.hpp @@ -54,6 +54,9 @@ class Emitter { util::PseudoRandom random; public: + /// @brief Number of references (alive particles) + int refCount = 0; + /// @brief Particle settings ParticlesPreset preset; Emitter( @@ -86,6 +89,9 @@ public: /// @return true if the emitter has spawned all particles bool isDead() const; + /// @return true if there is at least one alive referring particle left + bool isReferred() const; + const EmitterOrigin& getOrigin() const; void setOrigin(const EmitterOrigin& origin); diff --git a/src/graphics/render/ParticlesRenderer.cpp b/src/graphics/render/ParticlesRenderer.cpp index f3a30cdd..e96eb615 100644 --- a/src/graphics/render/ParticlesRenderer.cpp +++ b/src/graphics/render/ParticlesRenderer.cpp @@ -63,7 +63,8 @@ void ParticlesRenderer::renderParticles(const Camera& camera, float delta) { auto iter = vec.begin(); while (iter != vec.end()) { auto& particle = *iter; - auto& preset = particle.emitter->preset; + auto& emitter = *particle.emitter; + auto& preset = emitter.preset; if (!preset.frames.empty()) { float time = preset.lifetime - particle.lifetime; @@ -137,6 +138,7 @@ void ParticlesRenderer::renderParticles(const Camera& camera, float delta) { ); if (particle.lifetime <= 0.0f) { iter = vec.erase(iter); + emitter.refCount--; } else { iter++; } @@ -159,19 +161,15 @@ void ParticlesRenderer::render(const Camera& camera, float delta) { auto iter = emitters.begin(); while (iter != emitters.end()) { auto& emitter = *iter->second; + if (emitter.isDead() && !emitter.isReferred()) { + // destruct Emitter only when there is no particles spawned by it + iter = emitters.erase(iter); + continue; + } auto texture = emitter.getTexture(); const auto& found = particles.find(texture); std::vector* vec; - if (found == particles.end()) { - if (emitter.isDead()) { - // destruct Emitter only when there is no particles spawned by it - iter = emitters.erase(iter); - continue; - } - vec = &particles[texture]; - } else { - vec = &found->second; - } + vec = &particles[texture]; emitter.update(delta, camera.position, *vec); iter++; } From 40ac604e58612b76025f7b87d4d6ef46bf9bf6b8 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 24 Dec 2024 05:00:17 +0300 Subject: [PATCH 36/44] many emitters test --- res/content/base/blocks/leaves.json | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/res/content/base/blocks/leaves.json b/res/content/base/blocks/leaves.json index e3ddae22..4ea4832f 100644 --- a/res/content/base/blocks/leaves.json +++ b/res/content/base/blocks/leaves.json @@ -3,5 +3,24 @@ "material": "base:grass", "draw-group": 5, "culling": "optional", + "particles": { + "lifetime": 4.0, + "spawn_interval": 1000.0, + "acceleration": [0, -0.1, 0], + "velocity": [0.2, -2.5, 0.3], + "explosion": [0, 0, 0], + "collision": false, + "size": [0.3, 0.3, 0.3], + "size_spread": 0.2, + "spawn_shape": "box", + "spawn_spread": [0.2, 0.2, 0.2], + "angle_spread": 1.0, + "min_angular_vel": 0.5, + "max_angular_vel": 2.0, + "lighting": true, + "frames": [ + "particles:leaf_0" + ] + }, "base:durability": 0.7 } From 344df27f611a3090dd1b555fd55c12089522212c Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 24 Dec 2024 05:14:51 +0300 Subject: [PATCH 37/44] minor refactor --- src/graphics/render/Decorator.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/graphics/render/Decorator.cpp b/src/graphics/render/Decorator.cpp index b7bd4218..95ccbcc2 100644 --- a/src/graphics/render/Decorator.cpp +++ b/src/graphics/render/Decorator.cpp @@ -99,9 +99,8 @@ void Decorator::update( void Decorator::update(float delta, const Camera& camera) { glm::ivec3 pos = camera.position; - pos -= glm::ivec3(UPDATE_AREA_DIAMETER / 2); for (int i = 0; i < ITERATIONS; i++) { - update(delta, pos, camera.position); + update(delta, pos - glm::ivec3(UPDATE_AREA_DIAMETER / 2), pos); } const auto& chunks = *level.chunks; const auto& indices = *level.content->getIndices(); From faf4cfa735cc60263c71db2ed675c1f8bf2e447b Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 24 Dec 2024 05:25:40 +0300 Subject: [PATCH 38/44] update doc/*/particles.md --- doc/en/particles.md | 4 ++++ doc/ru/particles.md | 3 +++ 2 files changed, 7 insertions(+) diff --git a/doc/en/particles.md b/doc/en/particles.md index 8b7a37e7..47ab8ac3 100644 --- a/doc/en/particles.md +++ b/doc/en/particles.md @@ -16,6 +16,10 @@ Particles are a table, all fields of which are optional. | acceleration | Particles acceleration. | {0, -16, 0} | | explosion | Force of particles explosion on spawn. | {2, 2, 2} | | size | Size of particles. | {0.1, 0.1, 0.1} | +| size_spread | Maximum particle size spread over time. | 0.2 | +| angle_spread | Maximum initial rotation angle spread (0 to 1) | 0.0 | +| min_angular_vel | Minimum angular velocity (radians per sec). Non-negative. | 0.0 | +| max_angular_vel | Maximum angular velocity (radians per sec). Non-negative. | 0.0 | | spawn_shape | Shape of particle spawn area. (ball/sphere/box) | ball | | spawn_spread | Size of particle spawn area. | {0, 0, 0} | | random_sub_uv | Size of random texture subregion (1 - entire texture will be used). | 1.0 | diff --git a/doc/ru/particles.md b/doc/ru/particles.md index 167337f8..90af27f1 100644 --- a/doc/ru/particles.md +++ b/doc/ru/particles.md @@ -18,6 +18,9 @@ | explosion | Сила разлёта частиц при спавне. | {2, 2, 2} | | size | Размер частиц. | {0.1, 0.1, 0.1} | | size_spread | Максимальное отклонение времени размера частиц. | 0.2 | +| angle_spread | Максимальное отклонение начального угла поворота (от 0 до 1) | 0.0 | +| min_angular_vel | Минимальная угловая скорость (радианы в сек.). Неотрицательное. | 0.0 | +| max_angular_vel | Максимальная угловая скорость (радианы в сек.). Неотрицательное. | 0.0 | | spawn_shape | Форма области спавна частиц. (ball/sphere/box) | ball | | spawn_spread | Размер области спавна частиц. | {0, 0, 0} | | random_sub_uv | Размер случайного подрегиона текстуры (1 - будет использована вся текстура). | 1.0 | From f1c7317c5ab2a148e5188e091cd1aa3490dc8b4d Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 24 Dec 2024 05:35:02 +0300 Subject: [PATCH 39/44] fix non-skipping particles --- src/graphics/render/Emitter.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/graphics/render/Emitter.cpp b/src/graphics/render/Emitter.cpp index 88951588..e908ece8 100644 --- a/src/graphics/render/Emitter.cpp +++ b/src/graphics/render/Emitter.cpp @@ -77,6 +77,10 @@ void Emitter::update( count = std::max(0, count - skipped); timer -= skipped * spawnInterval; } + if (count < 0) { + int skipped = timer / spawnInterval; + timer -= skipped * spawnInterval; + } return; } while (count && timer > spawnInterval) { From 10491fbb6156695af5a17e7a562b09af736b5747 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 24 Dec 2024 08:49:20 +0300 Subject: [PATCH 40/44] add UVFace --- src/maths/UVFace.hpp | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 src/maths/UVFace.hpp diff --git a/src/maths/UVFace.hpp b/src/maths/UVFace.hpp new file mode 100644 index 00000000..538ae210 --- /dev/null +++ b/src/maths/UVFace.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include +#include + +#include "UVRegion.hpp" + +struct UVFace { + std::array points; + + UVFace(const UVRegion& region) { + points[0] = {region.u1, region.v1}; + points[1] = {region.u2, region.v1}; + points[2] = {region.u2, region.v2}; + points[3] = {region.u1, region.v2}; + } + + template + inline void rotate(int times) { + int times = n % 4; + if (times < 0) { + times += 4; + } + std::array temp = points; + points[0] = temp[times]; + points[1] = temp[(times + 1) % 4]; + points[2] = temp[(times + 2) % 4]; + points[3] = temp[(times + 3) % 4]; + } +}; From 65b88356984ce549dc69179a17393c716790bc33 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 24 Dec 2024 15:53:26 +0300 Subject: [PATCH 41/44] update doc/*/block-properties.md (model-name) --- doc/en/block-properties.md | 10 ++++++++++ doc/ru/block-properties.md | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/doc/en/block-properties.md b/doc/en/block-properties.md index 6400c910..87df173b 100644 --- a/doc/en/block-properties.md +++ b/doc/en/block-properties.md @@ -35,6 +35,16 @@ Block model type from list: - "X" - grass model (two crossed sprites) - "aabb" - model based of block hitbox (complex hitbox will be combined into one). Examples: pipes, bulbs, panels. +### *model-name* + +In addition to built-in model types, you can use your own, loaded from file. + +The property specifies the model name without `entry_point:models/` nor extension. + +> [!WARNING] +> Textures (materials) used in the model must be in the `blocks` atlas and specified in the *atlas-texture* format: +> `blocks:texture_name` + ### *draw-group* Integer specifying number of block draw group (render order). Used for semi-transparent blocks. diff --git a/doc/ru/block-properties.md b/doc/ru/block-properties.md index 366cf0fb..2f958e88 100644 --- a/doc/ru/block-properties.md +++ b/doc/ru/block-properties.md @@ -35,6 +35,16 @@ - "X" - модель травы (крест из двух спрайтов) - "aabb" - модель, соответствующая хитбоксу блока (составной хитбокс будет объединен в один). Примеры: трубы, лампочки, панели. +### Имя модели - *model-name* + +Кроме встроенных типов моделей, можно использовать собственные, загружаемые из файлов. + +В свойстве указывается имя модели без `точка_входа:models/` и расширения. + +> [!WARNING] +> Текстуры (материалы), использующиеся в модели, должны находиться в атласе `blocks` и указываться в соответствующем формате: +> `blocks:имя_текстуры` + ### Группа отрисовки - *draw-group* Целое число определяющее номер группы отрисовки данного блока. From 560288b5c337f100781a2cb1d557e6200a8a50df Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 24 Dec 2024 20:00:49 +0300 Subject: [PATCH 42/44] update util::PseudoRandom.setSeed --- src/maths/util.hpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/maths/util.hpp b/src/maths/util.hpp index ec128917..df39cf41 100644 --- a/src/maths/util.hpp +++ b/src/maths/util.hpp @@ -9,6 +9,12 @@ #include namespace util { + inline uint64_t shuffle_bits_step(uint64_t x, uint64_t m, unsigned shift) { + uint64_t t = ((x >> shift) ^ x) & m; + x = (x ^ t) ^ (t << shift); + return x; + } + constexpr inline float EPSILON = 1e-6f; class PseudoRandom { @@ -57,17 +63,20 @@ namespace util { return randU64() / static_cast(UINT64_MAX); } - void setSeed(int number) { - seed = (static_cast(number * 23729) ^ - static_cast(number + 16786)); - rand(); - } void setSeed(int number1, int number2) { seed = ((static_cast(number1 * 23729) | static_cast(number2 % 16786)) ^ static_cast(number2 * number1)); rand(); } + + void setSeed(long number) { + number = shuffle_bits_step(number, 0x2222222222222222ull, 1); + number = shuffle_bits_step(number, 0x0c0c0c0c0c0c0c0cull, 2); + number = shuffle_bits_step(number, 0x00f000f000f000f0ull, 4); + seed = number; + rand(); + } }; template From bb038653d6eafb51b660bd50bfb91c4fae5a7f24 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 25 Dec 2024 10:28:31 +0300 Subject: [PATCH 43/44] fix UVFace.rotate --- src/maths/UVFace.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/maths/UVFace.hpp b/src/maths/UVFace.hpp index 538ae210..8a0815bb 100644 --- a/src/maths/UVFace.hpp +++ b/src/maths/UVFace.hpp @@ -16,7 +16,7 @@ struct UVFace { } template - inline void rotate(int times) { + inline void rotate() { int times = n % 4; if (times < 0) { times += 4; From dff2f014f28f32724e2e149f48849c363e5afbe9 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 27 Dec 2024 08:34:29 +0300 Subject: [PATCH 44/44] update night lighting --- res/shaders/lib/commons.glsl | 2 +- res/shaders/lib/constants.glsl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/res/shaders/lib/commons.glsl b/res/shaders/lib/commons.glsl index 0a9561b3..a3bdbbc7 100644 --- a/res/shaders/lib/commons.glsl +++ b/res/shaders/lib/commons.glsl @@ -17,7 +17,7 @@ vec3 pick_sky_color(samplerCube cubemap) { vec3 skyLightColor = texture(cubemap, vec3(0.4f, 0.0f, 0.4f)).rgb; skyLightColor *= SKY_LIGHT_TINT; skyLightColor = min(vec3(1.0), skyLightColor*SKY_LIGHT_MUL); - skyLightColor = max(MAX_SKY_LIGHT, skyLightColor); + skyLightColor = max(MIN_SKY_LIGHT, skyLightColor); return skyLightColor; } diff --git a/res/shaders/lib/constants.glsl b/res/shaders/lib/constants.glsl index ad119914..c7020584 100644 --- a/res/shaders/lib/constants.glsl +++ b/res/shaders/lib/constants.glsl @@ -10,7 +10,7 @@ // lighting #define SKY_LIGHT_MUL 2.9 #define SKY_LIGHT_TINT vec3(0.9, 0.8, 1.0) -#define MAX_SKY_LIGHT vec3(0.1, 0.11, 0.14) +#define MIN_SKY_LIGHT vec3(0.2, 0.25, 0.33) // fog #define FOG_POS_SCALE vec3(1.0, 0.2, 1.0)