chunk dragger files

This commit is contained in:
Skarn
2022-02-10 01:27:39 +03:00
parent 1576186a35
commit fec7f23ce5
4 changed files with 340 additions and 0 deletions

View File

@@ -0,0 +1,170 @@
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
#include "ChunkClipboard.hpp"
#include <noggit/World.h>
#include <cassert>
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<unsigned>(chunk->px), static_cast<unsigned>(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<unsigned>(chunk->px), static_cast<unsigned>(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<unsigned>(chunk->px), static_cast<unsigned>(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<unsigned>(chunk->px), static_cast<unsigned>(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<unsigned>(x), static_cast<unsigned>(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<unsigned>(flags) & static_cast<unsigned>(ChunkCopyFlags::TERRAIN))
{
chunk_cache.terrain_height = std::array<char, 145 * 3 * sizeof(float)>{};
std::memcpy(chunk_cache.terrain_height->data(), &chunk->mVertices, 145 * 3 * sizeof(float));
}
if (static_cast<unsigned>(flags) & static_cast<unsigned>(ChunkCopyFlags::VERTEX_COLORS))
{
chunk_cache.vertex_colors = std::array<char, 145 * 3 * sizeof(float)>{};
std::memcpy(chunk_cache.vertex_colors->data(), &chunk->mccv, 145 * 3 * sizeof(float));
}
if (static_cast<unsigned>(flags) & static_cast<unsigned>(ChunkCopyFlags::SHADOWS))
{
chunk_cache.shadows = std::array<std::uint8_t, 64 * 64>{};
std::memcpy(chunk_cache.shadows->data(), &chunk->_shadow_map, 64 * 64 * sizeof(std::uint8_t));
}
if (static_cast<unsigned>(flags) & static_cast<unsigned>(ChunkCopyFlags::LIQUID))
{
chunk_cache.liquid_layers = *chunk->liquid_chunk()->getLayers();
}
if (static_cast<unsigned>(flags) & static_cast<unsigned>(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)
{
}

View File

@@ -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 <QObject>
#include <glm/glm.hpp>
#include <set>
#include <array>
#include <vector>
#include <cstdint>
#include <optional>
#include <noggit/TileIndex.hpp>
#include <noggit/Alphamap.hpp>
#include <noggit/texture_set.hpp>
#include <noggit/MapHeaders.h>
#include <noggit/liquid_layer.hpp>
#include <ClientData.hpp>
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<std::string> textures;
std::array<std::optional<Alphamap>, 3> alphamaps;
std::optional<tmp_edit_alpha_values> 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<std::array<char, 145 * 3 * sizeof(float)>> terrain_height;
std::optional<std::array<char, 145 * 3 * sizeof(float)>> vertex_colors;
std::optional<std::array<std::uint8_t, 64 * 64>> shadows;
std::optional<std::vector<liquid_layer>> liquid_layers;
std::optional<ChunkTextureCache> textures;
std::optional<std::vector<ChunkObjectCacheEntry>> 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<SelectedChunkIndex> const& selectedChunks() const { return _selected_chunks; };
signals:
void selectionChanged(std::set<SelectedChunkIndex> const& selected_chunks);
void selectionCleared();
void pasted();
private:
std::set<SelectedChunkIndex> _selected_chunks;
std::vector<std::pair<SelectedChunkIndex, ChunkCache>> _cached_chunks;
World* _world;
ChunkCopyFlags _copy_flags;
};
}
#endif //NOGGIT_CHUNKCLIPBOARD_HPP

View File

@@ -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)
{
}

View File

@@ -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 <QWidget>
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