From fec7f23ce550e81bd4c45f9229d78089dd562de9 Mon Sep 17 00:00:00 2001 From: Skarn Date: Thu, 10 Feb 2022 01:27:39 +0300 Subject: [PATCH] chunk dragger files --- .../tools/ChunkManipulator/ChunkClipboard.cpp | 170 ++++++++++++++++++ .../tools/ChunkManipulator/ChunkClipboard.hpp | 133 ++++++++++++++ .../ChunkManipulator/ChunkManipulator.cpp | 12 ++ .../ChunkManipulator/ChunkManipulator.hpp | 25 +++ 4 files changed, 340 insertions(+) create mode 100644 src/noggit/ui/tools/ChunkManipulator/ChunkClipboard.cpp create mode 100644 src/noggit/ui/tools/ChunkManipulator/ChunkClipboard.hpp create mode 100644 src/noggit/ui/tools/ChunkManipulator/ChunkManipulator.cpp create mode 100644 src/noggit/ui/tools/ChunkManipulator/ChunkManipulator.hpp diff --git a/src/noggit/ui/tools/ChunkManipulator/ChunkClipboard.cpp b/src/noggit/ui/tools/ChunkManipulator/ChunkClipboard.cpp new file mode 100644 index 00000000..2e9f7a8f --- /dev/null +++ b/src/noggit/ui/tools/ChunkManipulator/ChunkClipboard.cpp @@ -0,0 +1,170 @@ + +// This file is part of Noggit3, licensed under GNU General Public License (version 3). + + +#include "ChunkClipboard.hpp" +#include + +#include + +using namespace Noggit::Ui::Tools::ChunkManipulator; + +ChunkClipboard::ChunkClipboard(World* world, QObject* parent) +: QObject(parent) +, _world(world) +{ + +} + +void ChunkClipboard::selectRange(glm::vec3 const& cursor_pos, float radius, ChunkSelectionMode mode) +{ + + switch (mode) + { + case ChunkSelectionMode::SELECT: + { + _world->for_all_chunks_in_range(cursor_pos, radius, [this](MapChunk* chunk) + { + _selected_chunks.emplace(SelectedChunkIndex{TileIndex{glm::vec3{chunk->xbase, 0.f, chunk->zbase}}, + static_cast(chunk->px), static_cast(chunk->py)}); + }); + break; + } + case ChunkSelectionMode::DESELECT: + { + _world->for_all_chunks_in_range(cursor_pos, radius, [this](MapChunk* chunk) + { + _selected_chunks.erase(SelectedChunkIndex{TileIndex{glm::vec3{chunk->xbase, 0.f, chunk->zbase}}, + static_cast(chunk->px), static_cast(chunk->py)}); + }); + break; + } + default: + assert(false); + } + + emit selectionChanged(_selected_chunks); +} + +void ChunkClipboard::selectChunk(glm::vec3 const& pos, ChunkSelectionMode mode) +{ + switch(mode) + { + case ChunkSelectionMode::SELECT: + { + _world->for_chunk_at(pos, [this](MapChunk* chunk) + { + _selected_chunks.emplace(SelectedChunkIndex{TileIndex{glm::vec3{chunk->xbase, 0.f, chunk->zbase}}, + static_cast(chunk->px), static_cast(chunk->py)}); + }); + break; + } + case ChunkSelectionMode::DESELECT: + { + _world->for_chunk_at(pos, [this](MapChunk* chunk) + { + _selected_chunks.erase(SelectedChunkIndex{TileIndex{glm::vec3{chunk->xbase, 0.f, chunk->zbase}}, + static_cast(chunk->px), static_cast(chunk->py)}); + }); + break; + } + default: + assert(false); + } + + emit selectionChanged(_selected_chunks); +} + +void ChunkClipboard::selectChunk(TileIndex const& tile_index, unsigned x, unsigned z, ChunkSelectionMode mode) +{ + SelectedChunkIndex index {tile_index,static_cast(x), static_cast(z)}; + assert(index.tile_index.is_valid()); + + if (!_world->mapIndex.hasTile(index.tile_index)) + return; + + switch (mode) + { + case ChunkSelectionMode::SELECT: + { + _selected_chunks.emplace(index); + break; + } + case ChunkSelectionMode::DESELECT: + { + _selected_chunks.erase(index); + break; + } + default: + assert(false); + } + + emit selectionChanged(_selected_chunks); +} + +void ChunkClipboard::copySelected(ChunkCopyFlags flags) +{ + _cached_chunks.clear(); + + for (auto const& index : _selected_chunks) + { + ChunkCache chunk_cache; + MapTile* tile = _world->mapIndex.loadTile(index.tile_index); + assert(tile); + tile->wait_until_loaded(); + MapChunk* chunk = tile->getChunk(index.x, index.z); + + if (static_cast(flags) & static_cast(ChunkCopyFlags::TERRAIN)) + { + chunk_cache.terrain_height = std::array{}; + std::memcpy(chunk_cache.terrain_height->data(), &chunk->mVertices, 145 * 3 * sizeof(float)); + } + + if (static_cast(flags) & static_cast(ChunkCopyFlags::VERTEX_COLORS)) + { + chunk_cache.vertex_colors = std::array{}; + std::memcpy(chunk_cache.vertex_colors->data(), &chunk->mccv, 145 * 3 * sizeof(float)); + } + + if (static_cast(flags) & static_cast(ChunkCopyFlags::SHADOWS)) + { + chunk_cache.shadows = std::array{}; + std::memcpy(chunk_cache.shadows->data(), &chunk->_shadow_map, 64 * 64 * sizeof(std::uint8_t)); + } + + if (static_cast(flags) & static_cast(ChunkCopyFlags::LIQUID)) + { + chunk_cache.liquid_layers = *chunk->liquid_chunk()->getLayers(); + } + + if (static_cast(flags) & static_cast(ChunkCopyFlags::TEXTURES)) + { + ChunkTextureCache cache; + auto texture_set = chunk->getTextureSet(); + + cache.n_textures = texture_set->num(); + cache.alphamaps = *texture_set->getAlphamaps(); + cache.tmp_edit_values = *texture_set->getTempAlphamaps(); + std::memcpy(&cache.layers_info, texture_set->getMCLYEntries(), sizeof(ENTRY_MCLY) * 4); + + for (int i = 0; i < cache.n_textures; ++i) + { + cache.textures.push_back(texture_set->filename(i)); + } + + chunk_cache.textures = cache; + } + + + } +} + +void ChunkClipboard::clearSelection() +{ + _selected_chunks.clear(); +} + +void ChunkClipboard::pasteSelection(glm::vec3 const& pos, ChunkPasteFlags flags) +{ + +} diff --git a/src/noggit/ui/tools/ChunkManipulator/ChunkClipboard.hpp b/src/noggit/ui/tools/ChunkManipulator/ChunkClipboard.hpp new file mode 100644 index 00000000..a32e41a4 --- /dev/null +++ b/src/noggit/ui/tools/ChunkManipulator/ChunkClipboard.hpp @@ -0,0 +1,133 @@ +// This file is part of Noggit3, licensed under GNU General Public License (version 3). + +#ifndef NOGGIT_CHUNKCLIPBOARD_HPP +#define NOGGIT_CHUNKCLIPBOARD_HPP + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + + +class World; + +namespace Noggit::Ui::Tools::ChunkManipulator +{ + + enum class ChunkCopyFlags + { + TERRAIN = 0x1, + LIQUID = 0x2, + WMOs = 0x4, + MODELS = 0x8, + SHADOWS = 0x10, + TEXTURES = 0x20, + VERTEX_COLORS = 0x40, + HOLES = 0x80, + FLAGS = 0x100, + AREA_ID = 0x200 + }; + + enum class ChunkPasteFlags + { + REPLACE = 0x1 + }; + + enum class ChunkSelectionMode + { + SELECT, + DESELECT + }; + + struct ChunkTextureCache + { + size_t n_textures; + std::vector textures; + std::array, 3> alphamaps; + std::optional tmp_edit_values; + ENTRY_MCLY layers_info[4]; + }; + + enum class ChunkManipulatorObjectTypes + { + WMO, + M2 + }; + + struct ChunkObjectCacheEntry + { + BlizzardArchive::Listfile::FileKey file_key; + ChunkManipulatorObjectTypes type; + glm::vec3 pos; + glm::vec3 dir; + float scale; + }; + + + struct SelectedChunkIndex + { + TileIndex tile_index; + unsigned x; + unsigned z; + + SelectedChunkIndex(TileIndex tile_index_, unsigned x_, unsigned z_) : tile_index(tile_index_), x(x_), z(z_) {} + }; + + struct ChunkCache + { + std::optional> terrain_height; + std::optional> vertex_colors; + std::optional> shadows; + std::optional> liquid_layers; + std::optional textures; + std::optional> objects; + int holes; + mcnk_flags flags; + }; + + class ChunkClipboard : public QObject + { + Q_OBJECT + public: + explicit ChunkClipboard(World* world, QObject* parent = nullptr); + + void selectRange(glm::vec3 const& cursor_pos, float radius, ChunkSelectionMode mode); + void selectChunk(glm::vec3 const& pos, ChunkSelectionMode mode); + void selectChunk(TileIndex const& tile_index, unsigned x, unsigned z, ChunkSelectionMode mode); + void copySelected(ChunkCopyFlags flags); + void clearSelection(); + void pasteSelection(glm::vec3 const& pos, ChunkPasteFlags flags); + + [[nodiscard]] + ChunkCopyFlags copyParams() const { return _copy_flags; }; + void setCopyParams(ChunkCopyFlags flags) { _copy_flags = flags; }; + + [[nodiscard]] + std::set const& selectedChunks() const { return _selected_chunks; }; + + signals: + void selectionChanged(std::set const& selected_chunks); + void selectionCleared(); + void pasted(); + + private: + std::set _selected_chunks; + std::vector> _cached_chunks; + World* _world; + ChunkCopyFlags _copy_flags; + + }; +} + +#endif //NOGGIT_CHUNKCLIPBOARD_HPP diff --git a/src/noggit/ui/tools/ChunkManipulator/ChunkManipulator.cpp b/src/noggit/ui/tools/ChunkManipulator/ChunkManipulator.cpp new file mode 100644 index 00000000..19180a94 --- /dev/null +++ b/src/noggit/ui/tools/ChunkManipulator/ChunkManipulator.cpp @@ -0,0 +1,12 @@ + +// This file is part of Noggit3, licensed under GNU General Public License (version 3). + +#include "ChunkManipulator.hpp" + +using namespace Noggit::Ui::Tools; + +ChunkManipulator::ChunkManipulator(MapView* map_view, QWidget* parent) +: QWidget(parent) +, _map_view(map_view) +{ +} diff --git a/src/noggit/ui/tools/ChunkManipulator/ChunkManipulator.hpp b/src/noggit/ui/tools/ChunkManipulator/ChunkManipulator.hpp new file mode 100644 index 00000000..ef27fc0d --- /dev/null +++ b/src/noggit/ui/tools/ChunkManipulator/ChunkManipulator.hpp @@ -0,0 +1,25 @@ +// This file is part of Noggit3, licensed under GNU General Public License (version 3). + + +#ifndef NOGGIT_CHUNKMANIPULATOR_HPP +#define NOGGIT_CHUNKMANIPULATOR_HPP + +#include + +class MapView; + +namespace Noggit::Ui::Tools +{ + class ChunkManipulator : public QWidget + { + public: + ChunkManipulator(MapView* map_view, QWidget* parent = nullptr); + + private: + MapView* _map_view; + + }; + +} + +#endif //NOGGIT_CHUNKMANIPULATOR_HPP