Tools rewrite
This commit is contained in:
@@ -544,7 +544,7 @@ void Noggit::Action::finish()
|
||||
}
|
||||
|
||||
if (_post)
|
||||
(_map_view->*_post)();
|
||||
_post();
|
||||
}
|
||||
|
||||
float* Noggit::Action::getChunkTerrainOriginalData(MapChunk* chunk)
|
||||
@@ -578,9 +578,9 @@ bool Noggit::Action::getBlockCursor() const
|
||||
|
||||
}
|
||||
|
||||
void Noggit::Action::setPostCallback(auto(MapView::*method)()->void)
|
||||
void Noggit::Action::setPostCallback(std::function<void()> function)
|
||||
{
|
||||
_post = method;
|
||||
_post = function;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
#include <QObject>
|
||||
#include <ClientData.hpp>
|
||||
|
||||
#include <functional>
|
||||
|
||||
class MapView;
|
||||
class MapChunk;
|
||||
|
||||
@@ -115,7 +117,7 @@ namespace Noggit
|
||||
float getDelta() const;
|
||||
void setBlockCursor(bool state);
|
||||
bool getBlockCursor() const;
|
||||
void setPostCallback(auto(MapView::*method)()->void);
|
||||
void setPostCallback(std::function<void()> function);
|
||||
bool getTag() { return _tag; };
|
||||
void setTag(bool tag) { _tag = tag; };
|
||||
|
||||
@@ -184,7 +186,7 @@ namespace Noggit
|
||||
|
||||
tsl::robin_map<unsigned, std::vector<unsigned>> _object_operations;
|
||||
|
||||
auto(MapView::*_post)()->void = nullptr;
|
||||
std::function<void()> _post;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
9
src/noggit/Input.hpp
Normal file
9
src/noggit/Input.hpp
Normal file
@@ -0,0 +1,9 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
constexpr float XSENS = 15.0f;
|
||||
constexpr float YSENS = 15.0f;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,22 +5,17 @@
|
||||
#include <math/ray.hpp>
|
||||
#include <noggit/Misc.h>
|
||||
#include <noggit/Selection.h>
|
||||
#include <noggit/BoolToggleProperty.hpp>
|
||||
#include <noggit/Camera.hpp>
|
||||
#include <noggit/tool_enums.hpp>
|
||||
#include <noggit/ui/ObjectEditor.h>
|
||||
#include <noggit/ui/MinimapCreator.hpp>
|
||||
#include <noggit/ui/UidFixWindow.hpp>
|
||||
#include <noggit/unsigned_int_property.hpp>
|
||||
#include <noggit/ui/tools/AssetBrowser/Ui/AssetBrowser.hpp>
|
||||
#include <noggit/ui/tools/ViewportGizmo/ViewportGizmo.hpp>
|
||||
#include <noggit/ui/tools/ViewportManager/ViewportManager.hpp>
|
||||
#include <noggit/ui/tools/ToolPanel/ToolPanel.hpp>
|
||||
#include <noggit/TabletManager.hpp>
|
||||
#include <external/qtimgui/QtImGui.h>
|
||||
#include <opengl/texture.hpp>
|
||||
#include <opengl/scoped.hpp>
|
||||
#include <optional>
|
||||
#include <noggit/Tool.hpp>
|
||||
|
||||
#include <QtCore/QElapsedTimer>
|
||||
#include <QtCore/QSettings>
|
||||
@@ -51,6 +46,7 @@ namespace Noggit::Ui::Windows
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
class Tool;
|
||||
|
||||
namespace Ui::Tools::ViewToolbar::Ui
|
||||
{
|
||||
@@ -59,18 +55,7 @@ namespace Noggit
|
||||
|
||||
namespace Ui::Tools
|
||||
{
|
||||
class BrushStack;
|
||||
class LightEditor;
|
||||
|
||||
namespace ChunkManipulator
|
||||
{
|
||||
class ChunkManipulatorPanel;
|
||||
}
|
||||
}
|
||||
|
||||
namespace Scripting
|
||||
{
|
||||
class scripting_tool;
|
||||
class ToolPanel;
|
||||
}
|
||||
|
||||
class Camera;
|
||||
@@ -79,21 +64,9 @@ namespace Noggit
|
||||
namespace Ui
|
||||
{
|
||||
class detail_infos;
|
||||
class flatten_blur_tool;
|
||||
class help;
|
||||
class minimap_widget;
|
||||
class ShaderTool;
|
||||
class TerrainTool;
|
||||
class texture_picker;
|
||||
class texturing_tool;
|
||||
class toolbar;
|
||||
class water;
|
||||
class zone_id_browser;
|
||||
class texture_palette_small;
|
||||
class hole_tool;
|
||||
struct tileset_chooser;
|
||||
class ObjectPalette;
|
||||
class GroundEffectsTool;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,12 +144,6 @@ public:
|
||||
Noggit::BoolToggleProperty _show_minimap_window = { false };
|
||||
private:
|
||||
|
||||
int _selected_area_id = -1;
|
||||
|
||||
[[nodiscard]]
|
||||
math::ray intersect_ray() const;
|
||||
selection_result intersect_result(bool terrain_only);
|
||||
void doSelection(bool selectTerrainOnly, bool mouseMove = false);
|
||||
void update_cursor_pos();
|
||||
|
||||
display_mode _display_mode;
|
||||
@@ -196,26 +163,13 @@ private:
|
||||
float mTimespeed;
|
||||
|
||||
void ResetSelectedObjectRotation();
|
||||
void snap_selected_models_to_the_ground();
|
||||
void DeleteSelectedObjects();
|
||||
void changeZoneIDValue (int set);
|
||||
|
||||
QPointF _last_mouse_pos;
|
||||
float mh, mv, rh, rv; // mh = left click x, rv = right click y
|
||||
|
||||
float keyx = 0, keyy = 0, keyz = 0, keyr = 0, keys = 0;
|
||||
|
||||
bool MoveObj;
|
||||
float numpad_moveratio = 0.001f;
|
||||
|
||||
glm::vec3 objMove;
|
||||
|
||||
std::vector<selection_type> lastSelected;
|
||||
|
||||
bool _rotation_editor_need_update = false;
|
||||
bool _texture_picker_need_update = false;
|
||||
bool _area_picker_need_update = false;
|
||||
|
||||
// Vars for the ground editing toggle mode store the status of some
|
||||
// view settings when the ground editing mode is switched on to
|
||||
// restore them if switch back again
|
||||
@@ -243,8 +197,6 @@ private:
|
||||
uid_fix_mode _uid_fix;
|
||||
bool _from_bookmark;
|
||||
|
||||
bool saving_minimap = false;
|
||||
|
||||
Noggit::Ui::toolbar* _toolbar;
|
||||
Noggit::Ui::Tools::ViewToolbar::Ui::ViewToolbar* _view_toolbar;
|
||||
Noggit::Ui::Tools::ViewToolbar::Ui::ViewToolbar* _secondary_toolbar;
|
||||
@@ -261,7 +213,10 @@ signals:
|
||||
void resized();
|
||||
void saved();
|
||||
void updateProgress(int value);
|
||||
void selectionUpdated();
|
||||
void selectionUpdated(std::vector<selection_type>& selection);
|
||||
void menuToggleChanged(bool value);
|
||||
void rotationChanged();
|
||||
void trySetBrushTexture(QImage* image, QWidget* sender);
|
||||
public slots:
|
||||
void on_exit_prompt();
|
||||
void ShowContextMenu(QPoint pos);
|
||||
@@ -284,16 +239,9 @@ public:
|
||||
void tick (float dt);
|
||||
void change_selected_wmo_nameset(int set);
|
||||
void change_selected_wmo_doodadset(int set);
|
||||
void saveMinimap(MinimapRenderSettings* settings);
|
||||
void initMinimapSave() { saving_minimap = true; };
|
||||
auto setBrushTexture(QImage const* img) -> void;
|
||||
Noggit::Camera* getCamera() { return &_camera; };
|
||||
void randomizeTerrainRotation();
|
||||
void randomizeTexturingRotation();
|
||||
void randomizeShaderRotation();
|
||||
void randomizeStampRotation();
|
||||
void onSettingsSave();
|
||||
void updateRotationEditor() { _rotation_editor_need_update = true; };
|
||||
void setCameraDirty() { _camera_moved_since_last_draw = true; };
|
||||
|
||||
[[nodiscard]]
|
||||
@@ -308,15 +256,6 @@ public:
|
||||
[[nodiscard]]
|
||||
QWidget *getLeftSecondaryToolbar();
|
||||
|
||||
[[nodiscard]]
|
||||
QWidget* getActiveStampModeItem();
|
||||
|
||||
[[nodiscard]]
|
||||
Noggit::Ui::flatten_blur_tool* getFlattenTool() { return flattenTool; };
|
||||
|
||||
[[nodiscard]]
|
||||
Noggit::Ui::GroundEffectsTool* getGroundEffectsTool();
|
||||
|
||||
[[nodiscard]]
|
||||
Noggit::NoggitRenderContext getRenderContext() { return _context; };
|
||||
|
||||
@@ -329,14 +268,8 @@ public:
|
||||
[[nodiscard]]
|
||||
Noggit::Ui::Tools::AssetBrowser::Ui::AssetBrowserWidget* getAssetBrowserWidget() { return _asset_browser; };
|
||||
|
||||
[[nodiscard]]
|
||||
Noggit::Ui::object_editor* getObjectEditor() { return objectEditor; };
|
||||
|
||||
[[nodiscard]]
|
||||
QDockWidget* getObjectPalette() { return _object_palette_dock; };
|
||||
|
||||
[[nodiscard]]
|
||||
QDockWidget* getTexturePalette() { return _texture_palette_dock; };
|
||||
glm::vec3 cursorPosition() const;
|
||||
void cursorPosition(glm::vec3 position);
|
||||
|
||||
private:
|
||||
enum Modifier
|
||||
@@ -353,15 +286,17 @@ private:
|
||||
{
|
||||
Qt::Key key;
|
||||
size_t modifiers;
|
||||
std::function<void()> function;
|
||||
std::function<void()> onPress;
|
||||
std::function<void()> onRelease;
|
||||
std::function<bool()> condition;
|
||||
HotKey (Qt::Key k, size_t m, std::function<void()> f, std::function<bool()> c)
|
||||
: key (k), modifiers (m), function (f), condition (c) {}
|
||||
HotKey (Qt::Key k, size_t m, std::function<void()> f, std::function<bool()> c, std::function<void()> r = []{})
|
||||
: key (k), modifiers (m), onPress(f), onRelease{r}, condition (c) {}
|
||||
};
|
||||
|
||||
std::forward_list<HotKey> hotkeys;
|
||||
|
||||
void addHotkey(Qt::Key key, size_t modifiers, std::function<void()> function, std::function<bool()> condition = [] { return true; });
|
||||
void addHotkey(Qt::Key key, size_t modifiers, StringHash hotkeyName);
|
||||
|
||||
QElapsedTimer _startup_time;
|
||||
qreal _last_update = 0.f;
|
||||
@@ -389,7 +324,6 @@ private:
|
||||
Noggit::Ui::Windows::NoggitWindow* _main_window;
|
||||
|
||||
glm::vec4 normalized_device_coords (int x, int y) const;
|
||||
float aspect_ratio() const;
|
||||
|
||||
Noggit::TabletManager* _tablet_manager;
|
||||
|
||||
@@ -402,31 +336,17 @@ private:
|
||||
QLabel* _status_database;
|
||||
|
||||
Noggit::BoolToggleProperty _locked_cursor_mode = {false};
|
||||
Noggit::BoolToggleProperty _move_model_to_cursor_position = {true};
|
||||
Noggit::BoolToggleProperty _move_model_snap_to_objects = { true };
|
||||
Noggit::BoolToggleProperty _snap_multi_selection_to_ground = {false};
|
||||
Noggit::BoolToggleProperty _rotate_along_ground = {true };
|
||||
Noggit::BoolToggleProperty _rotate_doodads_along_doodads = { false };
|
||||
Noggit::BoolToggleProperty _rotate_doodads_along_wmos = { false };
|
||||
Noggit::BoolToggleProperty _rotate_along_ground_smooth = {true };
|
||||
Noggit::BoolToggleProperty _rotate_along_ground_random = {false };
|
||||
Noggit::BoolToggleProperty _use_median_pivot_point = {true};
|
||||
Noggit::BoolToggleProperty _display_all_water_layers = {true};
|
||||
Noggit::unsigned_int_property _displayed_water_layer = {0};
|
||||
Noggit::object_paste_params _object_paste_params;
|
||||
|
||||
Noggit::BoolToggleProperty _show_node_editor = {false};
|
||||
Noggit::BoolToggleProperty _show_minimap_borders = {true};
|
||||
Noggit::BoolToggleProperty _show_minimap_skies = {false};
|
||||
Noggit::BoolToggleProperty _show_keybindings_window = {false};
|
||||
Noggit::BoolToggleProperty _show_texture_palette_window = {false};
|
||||
Noggit::BoolToggleProperty _show_texture_palette_small_window = {false};
|
||||
Noggit::BoolToggleProperty _showStampPalette{false};
|
||||
|
||||
Noggit::Ui::minimap_widget* _minimap;
|
||||
QDockWidget* _minimap_dock;
|
||||
QDockWidget* _texture_palette_dock;
|
||||
QDockWidget* _object_palette_dock;
|
||||
|
||||
void move_camera_with_auto_height (glm::vec3 const&);
|
||||
|
||||
@@ -435,33 +355,14 @@ private:
|
||||
void unloadOpenglData() override;
|
||||
|
||||
Noggit::Ui::help* _keybindings;
|
||||
Noggit::Ui::tileset_chooser* TexturePalette;
|
||||
Noggit::Ui::detail_infos* guidetailInfos;
|
||||
Noggit::Ui::zone_id_browser* ZoneIDBrowser;
|
||||
Noggit::Ui::texture_palette_small* _texture_palette_small;
|
||||
Noggit::Ui::ObjectPalette* _object_palette;
|
||||
Noggit::Ui::texture_picker* TexturePicker;
|
||||
Noggit::Ui::water* guiWater;
|
||||
Noggit::Ui::object_editor* objectEditor;
|
||||
Noggit::Ui::flatten_blur_tool* flattenTool;
|
||||
Noggit::Ui::TerrainTool* terrainTool;
|
||||
Noggit::Ui::ShaderTool* shaderTool;
|
||||
Noggit::Ui::texturing_tool* texturingTool;
|
||||
Noggit::Ui::hole_tool* holeTool;
|
||||
Noggit::Ui::MinimapCreator* minimapTool;
|
||||
Noggit::Ui::Tools::BrushStack* stampTool;
|
||||
Noggit::Ui::Tools::LightEditor* lightEditor;
|
||||
Noggit::Ui::Tools::ChunkManipulator::ChunkManipulatorPanel* _chunk_manipulator;
|
||||
Noggit::Scripting::scripting_tool* scriptingTool;
|
||||
|
||||
OpenGL::texture* const _texBrush;
|
||||
|
||||
Noggit::Ui::Tools::AssetBrowser::Ui::AssetBrowserWidget* _asset_browser;
|
||||
Noggit::Ui::Tools::AssetBrowser::Ui::AssetBrowserWidget* _asset_browser = nullptr;
|
||||
|
||||
QDockWidget* _asset_browser_dock;
|
||||
QDockWidget* _node_editor_dock;
|
||||
QDockWidget* _texture_browser_dock;
|
||||
QDockWidget* _texture_picker_dock;
|
||||
QDockWidget* _detail_infos_dock;
|
||||
|
||||
Noggit::Ui::Tools::ToolPanel* _tool_panel_dock;
|
||||
@@ -479,33 +380,14 @@ private:
|
||||
bool _needs_redraw = false;
|
||||
bool _unload_tiles = true;
|
||||
|
||||
unsigned _mmap_async_index = 0;
|
||||
unsigned _mmap_render_index = 0;
|
||||
std::optional<QImage> _mmap_combined_image;
|
||||
|
||||
OpenGL::Scoped::deferred_upload_buffers<2> _buffers;
|
||||
|
||||
QRubberBand* _area_selection;
|
||||
|
||||
public:
|
||||
|
||||
private:
|
||||
|
||||
void setupViewportOverlay();
|
||||
void setupRaiseLowerUi();
|
||||
void setupFlattenBlurUi();
|
||||
void setupTexturePainterUi();
|
||||
void setupHoleCutterUi();
|
||||
void setupAreaDesignatorUi();
|
||||
void setupFlagUi();
|
||||
void setupWaterEditorUi();
|
||||
void setupVertexPainterUi();
|
||||
void setupObjectEditorUi();
|
||||
void setupMinimapEditorUi();
|
||||
void setupStampUi();
|
||||
void setupLightEditorUi();
|
||||
void setupScriptingUi();
|
||||
void setupChunkManipulatorUi();
|
||||
void setupNodeEditor();
|
||||
void setupAssetBrowser();
|
||||
void setupDetailInfos();
|
||||
@@ -517,10 +399,60 @@ private:
|
||||
void setupEditMenu();
|
||||
void setupAssistMenu();
|
||||
void setupViewMenu();
|
||||
void setupToolsMenu();
|
||||
void setupHelpMenu();
|
||||
void setupHotkeys();
|
||||
void setupClientMenu();
|
||||
void setupMainToolbar();
|
||||
|
||||
QWidget* _overlay_widget;
|
||||
|
||||
std::vector<std::unique_ptr<Noggit::Tool>> _tools;
|
||||
size_t _activeToolIndex = 0;
|
||||
|
||||
std::unique_ptr<Noggit::Tool>& activeTool();
|
||||
void activeTool(editing_mode newTool);
|
||||
|
||||
public:
|
||||
[[nodiscard]]
|
||||
Noggit::Ui::Tools::ViewToolbar::Ui::ViewToolbar* getLeftSecondaryViewToolbar();
|
||||
|
||||
[[nodiscard]]
|
||||
QSettings* settings();
|
||||
|
||||
[[nodiscard]]
|
||||
Noggit::Ui::Windows::NoggitWindow* mainWindow();
|
||||
|
||||
[[nodiscard]]
|
||||
bool isUiHidden() const;
|
||||
|
||||
[[nodiscard]]
|
||||
bool drawAdtGrid() const;
|
||||
[[nodiscard]]
|
||||
bool drawHoleGrid() const;
|
||||
|
||||
void invalidate();
|
||||
|
||||
void selectObjects(std::array<glm::vec2, 2> selection_box, float depth);
|
||||
void doSelection(bool selectTerrainOnly, bool mouseMove = false);
|
||||
void DeleteSelectedObjects();
|
||||
void snap_selected_models_to_the_ground();
|
||||
|
||||
[[nodiscard]]
|
||||
bool isRotatingCamera() const;
|
||||
|
||||
[[nodiscard]]
|
||||
float aspect_ratio() const;
|
||||
|
||||
[[nodiscard]]
|
||||
math::ray intersect_ray() const;
|
||||
|
||||
[[nodiscard]]
|
||||
selection_result intersect_result(bool terrain_only);
|
||||
|
||||
[[nodiscard]]
|
||||
std::shared_ptr<Noggit::Project::NoggitProject>& project();
|
||||
|
||||
[[nodiscard]]
|
||||
float timeSpeed() const;
|
||||
};
|
||||
|
||||
53
src/noggit/MinimapRenderSettings.hpp
Normal file
53
src/noggit/MinimapRenderSettings.hpp
Normal file
@@ -0,0 +1,53 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
#pragma once
|
||||
|
||||
class QListWidget;
|
||||
|
||||
#include <glm/vec3.hpp>
|
||||
#include <glm/vec4.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
enum MinimapGenMode
|
||||
{
|
||||
CURRENT_ADT,
|
||||
SELECTED_ADTS,
|
||||
MAP
|
||||
};
|
||||
|
||||
struct MinimapRenderSettings
|
||||
{
|
||||
MinimapGenMode export_mode = CURRENT_ADT;
|
||||
std::string file_format = ".blp";
|
||||
|
||||
// Render settings
|
||||
int resolution = 512;
|
||||
bool draw_m2 = false;
|
||||
bool draw_wmo = true;
|
||||
bool draw_water = true;
|
||||
bool draw_adt_grid = false;
|
||||
bool draw_elevation = false;
|
||||
bool draw_shadows = false;
|
||||
bool use_filters = false;
|
||||
bool combined_minimap = false;
|
||||
|
||||
// Selection
|
||||
// std::array<bool, 4096> selected_tiles = {false};
|
||||
|
||||
std::vector<char> selected_tiles = std::vector<char>( size_t{4096}, false, {} );
|
||||
|
||||
// Filtering
|
||||
QListWidget* m2_model_filter_include = nullptr;
|
||||
QListWidget* m2_instance_filter_include = nullptr;
|
||||
QListWidget* wmo_model_filter_exclude = nullptr;
|
||||
QListWidget* wmo_instance_filter_exclude = nullptr;
|
||||
|
||||
// Lighting. Based on default eastern kingdom global light settings (lightparams 12)
|
||||
glm::vec3 diffuse_color = {1.0, 0.532352924, 0.0};
|
||||
glm::vec3 ambient_color = {0.407770514, 0.508424163, 0.602650642};
|
||||
glm::vec4 ocean_color_light = {0.0693173409, 0.294008732, 0.348329663, 0.75};
|
||||
glm::vec4 ocean_color_dark = {0.000762581825, 0.113907099, 0.161220074, 1.0};
|
||||
glm::vec4 river_color_light = {0.308351517, 0.363725543, 0.0798838138, 0.5};
|
||||
glm::vec4 river_color_dark = {0.19945538, 0.320697188, 0.332425594, 1.0};
|
||||
};
|
||||
40
src/noggit/StringHash.hpp
Normal file
40
src/noggit/StringHash.hpp
Normal file
@@ -0,0 +1,40 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
struct StringHash
|
||||
{
|
||||
uint64_t hash;
|
||||
|
||||
consteval explicit StringHash(uint64_t value)
|
||||
: hash{ value }
|
||||
{
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr operator uint64_t()
|
||||
{
|
||||
return hash;
|
||||
}
|
||||
};
|
||||
|
||||
consteval auto operator""_hash(char const* str, size_t len)
|
||||
{
|
||||
// djb2 hash
|
||||
|
||||
uint64_t hash = 5381;
|
||||
|
||||
for (size_t i = 0; i < len; ++i)
|
||||
{
|
||||
hash = ((hash << 5) + hash) + static_cast<int>(str[i]);
|
||||
}
|
||||
|
||||
return StringHash{ hash };
|
||||
}
|
||||
|
||||
consteval bool operator==(StringHash a, StringHash b)
|
||||
{
|
||||
return a.hash == b.hash;
|
||||
}
|
||||
247
src/noggit/Tool.cpp
Normal file
247
src/noggit/Tool.cpp
Normal file
@@ -0,0 +1,247 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#include "Tool.hpp"
|
||||
#include <noggit/MapView.h>
|
||||
#include <noggit/BoolToggleProperty.hpp>
|
||||
#include <noggit/ActionManager.hpp>
|
||||
#include <noggit/MinimapRenderSettings.hpp>
|
||||
|
||||
#include <QAction>
|
||||
#include <QObject>
|
||||
#include <QMenu>
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
Tool::Tool(MapView* mapView)
|
||||
: _mapView{ mapView }
|
||||
{
|
||||
}
|
||||
|
||||
MapView* const Tool::mapView()
|
||||
{
|
||||
return _mapView;
|
||||
}
|
||||
|
||||
void Tool::onHotkeyPress(StringHash name)
|
||||
{
|
||||
if (auto&& itr = _hotkeys.find(name); itr != _hotkeys.end())
|
||||
{
|
||||
itr->second.onPress();
|
||||
}
|
||||
}
|
||||
|
||||
void Tool::onHotkeyRelease(StringHash name)
|
||||
{
|
||||
if (auto&& itr = _hotkeys.find(name); itr != _hotkeys.end())
|
||||
{
|
||||
itr->second.onRelease();
|
||||
}
|
||||
}
|
||||
|
||||
bool Tool::hotkeyCondition(StringHash name)
|
||||
{
|
||||
if (auto&& itr = _hotkeys.find(name); itr != _hotkeys.end())
|
||||
{
|
||||
return itr->second.condition();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int Tool::actionModality() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Tool::setupUi(Ui::Tools::ToolPanel* toolPanel)
|
||||
{
|
||||
}
|
||||
|
||||
void Tool::postUiSetup()
|
||||
{
|
||||
}
|
||||
|
||||
ToolDrawParameters Tool::drawParameters() const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
float Tool::brushRadius() const
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
bool Tool::useMultiselectionPivot() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Tool::useMedianPivotPoint() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void Tool::onSelected()
|
||||
{
|
||||
}
|
||||
|
||||
void Tool::onDeselected()
|
||||
{
|
||||
}
|
||||
|
||||
void Tool::onTick(float deltaTime, TickParameters const& params)
|
||||
{
|
||||
}
|
||||
|
||||
bool Tool::preRender()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void Tool::postRender()
|
||||
{
|
||||
}
|
||||
|
||||
void Tool::onMousePress(MousePressParameters const& params)
|
||||
{
|
||||
}
|
||||
|
||||
void Tool::onMouseRelease(MouseReleaseParameters const& params)
|
||||
{
|
||||
}
|
||||
|
||||
void Tool::onMouseMove(MouseMoveParameters const& params)
|
||||
{
|
||||
}
|
||||
|
||||
void Tool::onMouseWheel(MouseWheelParameters const& params)
|
||||
{
|
||||
}
|
||||
|
||||
void Tool::hidePopups()
|
||||
{
|
||||
}
|
||||
|
||||
void Tool::onFocusLost()
|
||||
{
|
||||
}
|
||||
|
||||
void Tool::saveSettings()
|
||||
{
|
||||
}
|
||||
|
||||
void Tool::registerMenuItems(QMenu* menu)
|
||||
{
|
||||
}
|
||||
|
||||
void Tool::registerContextMenuItems(QMenu* menu)
|
||||
{
|
||||
}
|
||||
|
||||
void Tool::addHotkey(StringHash name, Hotkey hotkey)
|
||||
{
|
||||
if (auto&& itr = _hotkeys.find(name); itr != _hotkeys.end())
|
||||
{
|
||||
// If you get here and you're sure the name you're using isn't already used by this tool,
|
||||
// then you may have run into a hash collision and we need to re-evaluate the hashing algorithm.
|
||||
// Or, just change the name and move on...
|
||||
throw std::exception{ "There's already a hotkey with this name!" };
|
||||
}
|
||||
|
||||
_hotkeys[name] = hotkey;
|
||||
}
|
||||
|
||||
void Tool::addMenuTitle(QMenu* menu, char const* title)
|
||||
{
|
||||
menu->addSeparator();
|
||||
|
||||
auto* pLabel = new QLabel(title);
|
||||
pLabel->setAlignment(Qt::AlignCenter);
|
||||
auto* separator = new QWidgetAction(_mapView);
|
||||
separator->setDefaultWidget(pLabel);
|
||||
menu->addAction(separator);
|
||||
|
||||
menu->addSeparator();
|
||||
}
|
||||
|
||||
void Tool::addMenuItem(QMenu* menu, char const* title, QKeySequence shortcut, BoolToggleProperty& property)
|
||||
{
|
||||
QAction* action(new QAction(title, _mapView));
|
||||
action->setShortcut(shortcut);
|
||||
action->setCheckable(true);
|
||||
action->setChecked(property.get());
|
||||
menu->addAction(action);
|
||||
QObject::connect(action, &QAction::toggled
|
||||
, &property, &Noggit::BoolToggleProperty::set
|
||||
);
|
||||
QObject::connect(&property, &Noggit::BoolToggleProperty::changed
|
||||
, action, &QAction::setChecked
|
||||
);
|
||||
}
|
||||
|
||||
void Tool::addMenuItem(QMenu* menu, char const* title, BoolToggleProperty& property)
|
||||
{
|
||||
QAction* action(new QAction(title, _mapView));
|
||||
action->setCheckable(true);
|
||||
action->setChecked(property.get());
|
||||
menu->addAction(action);
|
||||
QObject::connect(action, &QAction::toggled
|
||||
, &property, &Noggit::BoolToggleProperty::set
|
||||
);
|
||||
QObject::connect(&property, &Noggit::BoolToggleProperty::changed
|
||||
, action, &QAction::setChecked
|
||||
);
|
||||
}
|
||||
|
||||
void Tool::addMenuItem(QMenu* menu, char const* title, QKeySequence shortcut, std::function<void()> onAction)
|
||||
{
|
||||
auto action(menu->addAction(title));
|
||||
action->setShortcut(shortcut);
|
||||
auto callback = onAction;
|
||||
QObject::connect(action, &QAction::triggered, [this, callback]()
|
||||
{
|
||||
if (NOGGIT_CUR_ACTION) \
|
||||
return;
|
||||
callback();
|
||||
});
|
||||
}
|
||||
|
||||
void Tool::addMenuItem(QMenu* menu, char const* title, QKeySequence shortcut, bool enabled, std::function<void()> onAction)
|
||||
{
|
||||
auto action(menu->addAction(title));
|
||||
action->setShortcut(shortcut);
|
||||
action->setEnabled(enabled);
|
||||
auto callback = onAction;
|
||||
QObject::connect(action, &QAction::triggered, [this, callback]()
|
||||
{
|
||||
if (NOGGIT_CUR_ACTION) \
|
||||
return;
|
||||
callback();
|
||||
});
|
||||
}
|
||||
|
||||
void Tool::addMenuItem(QMenu* menu, char const* title, char const* tooltip, bool enabled, std::function<void()> onAction)
|
||||
{
|
||||
auto action(menu->addAction(title));
|
||||
action->setToolTip(tooltip);
|
||||
action->setEnabled(enabled);
|
||||
auto callback = onAction;
|
||||
QObject::connect(action, &QAction::triggered, [this, callback]()
|
||||
{
|
||||
if (NOGGIT_CUR_ACTION) \
|
||||
return;
|
||||
callback();
|
||||
});
|
||||
}
|
||||
|
||||
void Tool::addMenuItem(QMenu* menu, char const* title, std::function<void()> onAction)
|
||||
{
|
||||
auto action(menu->addAction(title));
|
||||
QObject::connect(action, &QAction::triggered, onAction);
|
||||
}
|
||||
|
||||
void Tool::addMenuSeperator(QMenu* menu)
|
||||
{
|
||||
menu->addSeparator();
|
||||
}
|
||||
}
|
||||
208
src/noggit/Tool.hpp
Normal file
208
src/noggit/Tool.hpp
Normal file
@@ -0,0 +1,208 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "tool_enums.hpp"
|
||||
#include "ToolDrawParameters.hpp"
|
||||
#include "StringHash.hpp"
|
||||
|
||||
#include <noggit/ui/FontNoggit.hpp>
|
||||
|
||||
#include <glm/vec3.hpp>
|
||||
|
||||
#include <QLineF>
|
||||
#include <QPoint>
|
||||
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <unordered_map>
|
||||
|
||||
class MapView;
|
||||
|
||||
class QWheelEvent;
|
||||
class QMenu;
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
struct BoolToggleProperty;
|
||||
|
||||
namespace Ui::Tools
|
||||
{
|
||||
class ToolPanel;
|
||||
}
|
||||
|
||||
struct TickParameters
|
||||
{
|
||||
display_mode displayMode = display_mode::in_3D;
|
||||
bool underMap = false;
|
||||
|
||||
bool left_mouse = false;
|
||||
bool right_mouse = false;
|
||||
bool mod_shift_down = false;
|
||||
bool mod_ctrl_down = false;
|
||||
bool mod_alt_down = false;
|
||||
bool mod_num_down = false;
|
||||
|
||||
glm::vec3 dir = { 1.0f, 0.0f, 0.0f };
|
||||
glm::vec3 dirUp = { 1.0f, 0.0f, 0.0f };
|
||||
glm::vec3 dirRight = { 0.0f, 0.0f, 1.0f };
|
||||
};
|
||||
|
||||
struct MousePressParameters
|
||||
{
|
||||
Qt::MouseButton button = Qt::MouseButton::NoButton;
|
||||
QPoint mouse_position;
|
||||
bool mod_ctrl_down = false;
|
||||
};
|
||||
|
||||
struct MouseReleaseParameters
|
||||
{
|
||||
Qt::MouseButton button = Qt::MouseButton::NoButton;
|
||||
QPoint mouse_position;
|
||||
bool mod_ctrl_down = false;
|
||||
};
|
||||
|
||||
struct MouseMoveParameters
|
||||
{
|
||||
display_mode displayMode = display_mode::in_3D;
|
||||
bool left_mouse = false;
|
||||
bool right_mouse = false;
|
||||
bool mod_shift_down = false;
|
||||
bool mod_ctrl_down = false;
|
||||
bool mod_alt_down = false;
|
||||
bool mod_num_down = false;
|
||||
bool mod_space_down = false;
|
||||
QLineF relative_movement;
|
||||
QPoint mouse_position;
|
||||
};
|
||||
|
||||
struct MouseWheelParameters
|
||||
{
|
||||
QWheelEvent& event;
|
||||
bool mod_shift_down = false;
|
||||
bool mod_ctrl_down = false;
|
||||
bool mod_alt_down = false;
|
||||
bool mod_num_down = false;
|
||||
bool mod_space_down = false;
|
||||
};
|
||||
|
||||
class Tool
|
||||
{
|
||||
protected:
|
||||
struct Hotkey
|
||||
{
|
||||
std::function<void()> onPress;
|
||||
std::function<void()> onRelease = [] {};
|
||||
std::function<bool()> condition;
|
||||
};
|
||||
|
||||
public:
|
||||
explicit Tool(MapView* mapView);
|
||||
virtual ~Tool() = default;
|
||||
|
||||
[[nodiscard]]
|
||||
MapView* const mapView();
|
||||
|
||||
// will be called whenever a user presses a hotkey
|
||||
void onHotkeyPress(StringHash name);
|
||||
|
||||
// will be called after a user pressed a hotkey
|
||||
void onHotkeyRelease(StringHash name);
|
||||
|
||||
// will be called before onHotkeyPress to see if it needs to be called
|
||||
[[nodiscard]]
|
||||
bool hotkeyCondition(StringHash name);
|
||||
|
||||
// Returns the current action modality to cancel the current action on mismatch
|
||||
[[nodiscard]]
|
||||
virtual unsigned int actionModality() const;
|
||||
|
||||
// The name displayed in the toolbar
|
||||
[[nodiscard]]
|
||||
virtual char const* name() const = 0;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual editing_mode editingMode() const = 0;
|
||||
|
||||
// The icon displayed in the toolbar
|
||||
[[nodiscard]]
|
||||
virtual Ui::FontNoggit::Icons icon() const = 0;
|
||||
|
||||
// UI setup code goes here
|
||||
virtual void setupUi(Ui::Tools::ToolPanel* toolPanel);
|
||||
|
||||
// UI setup code that relies on other UI elements being initialized goes here
|
||||
virtual void postUiSetup();
|
||||
|
||||
// If you need menu items, register them here
|
||||
virtual void registerMenuItems(QMenu* menu);
|
||||
|
||||
// If you need context menu items, register them here
|
||||
virtual void registerContextMenuItems(QMenu* menu);
|
||||
|
||||
// Returns the ToolDrawParameters required by the renderer to draw tool specific objects (like the brush for texturing mode)
|
||||
[[nodiscard]]
|
||||
virtual ToolDrawParameters drawParameters() const;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual float brushRadius() const;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual bool useMultiselectionPivot() const;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual bool useMedianPivotPoint() const;
|
||||
|
||||
// will be called whenever this tool gets selected by the user
|
||||
virtual void onSelected();
|
||||
|
||||
// will be called whenever the user selects a different tool
|
||||
virtual void onDeselected();
|
||||
|
||||
// will be called every tick
|
||||
virtual void onTick(float deltaTime, TickParameters const& params);
|
||||
|
||||
// will be called before the map gets drawn. May return false to skip rendering the map
|
||||
virtual bool preRender();
|
||||
|
||||
// will be called after the map got drawn
|
||||
virtual void postRender();
|
||||
|
||||
// will be called whenever a mouse button is pressed
|
||||
virtual void onMousePress(MousePressParameters const& params);
|
||||
|
||||
virtual void onMouseRelease(MouseReleaseParameters const& params);
|
||||
|
||||
// will be called whenever the mouse moves
|
||||
virtual void onMouseMove(MouseMoveParameters const& params);
|
||||
|
||||
// will be called when the user scrolls the mouse wheel
|
||||
virtual void onMouseWheel(MouseWheelParameters const& params);
|
||||
|
||||
// Hide your tools' popups!
|
||||
virtual void hidePopups();
|
||||
|
||||
// The main window's focus was lost
|
||||
virtual void onFocusLost();
|
||||
|
||||
// Save tool-specific settings to disk
|
||||
virtual void saveSettings();
|
||||
|
||||
protected:
|
||||
void addHotkey(StringHash name, Hotkey hotkey);
|
||||
|
||||
void addMenuTitle(QMenu* menu, char const* title);
|
||||
void addMenuItem(QMenu* menu, char const* title, QKeySequence shortcut, BoolToggleProperty& property);
|
||||
void addMenuItem(QMenu* menu, char const* title, BoolToggleProperty& property);
|
||||
void addMenuItem(QMenu* menu, char const* title, QKeySequence shortcut, std::function<void()> onAction);
|
||||
void addMenuItem(QMenu* menu, char const* title, QKeySequence shortcut, bool enabled, std::function<void()> onAction);
|
||||
void addMenuItem(QMenu* menu, char const* title, char const* tooltip, bool enabled, std::function<void()> onAction);
|
||||
void addMenuItem(QMenu* menu, char const* title, std::function<void()> onAction);
|
||||
|
||||
void addMenuSeperator(QMenu* menu);
|
||||
|
||||
private:
|
||||
MapView* _mapView = nullptr;
|
||||
std::unordered_map<decltype(StringHash::hash), Hotkey> _hotkeys;
|
||||
};
|
||||
}
|
||||
31
src/noggit/ToolDrawParameters.hpp
Normal file
31
src/noggit/ToolDrawParameters.hpp
Normal file
@@ -0,0 +1,31 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "tool_enums.hpp"
|
||||
#include "MinimapRenderSettings.hpp"
|
||||
|
||||
#include <glm/vec3.hpp>
|
||||
#include <glm/vec4.hpp>
|
||||
|
||||
struct MinimapRenderSettings;
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
struct ToolDrawParameters
|
||||
{
|
||||
float radius = 0.0f;
|
||||
float inner_radius = 0.0f;
|
||||
float angle = 0.0f;
|
||||
float orientation = 0.0f;
|
||||
glm::vec3 ref_pos;
|
||||
bool angled_mode = false;
|
||||
bool use_ref_pos = false;
|
||||
bool show_unpaintable_chunks = false;
|
||||
CursorType cursor_type = CursorType::CIRCLE;
|
||||
eTerrainType terrain_type = eTerrainType::eTerrainType_Flat;
|
||||
int displayed_water_layer = -1;
|
||||
glm::vec4 cursor_color = { 1.f, 1.f, 1.f, 1.f };
|
||||
MinimapRenderSettings minimapRenderSettings;
|
||||
};
|
||||
}
|
||||
17
src/noggit/object_paste_params.hpp
Normal file
17
src/noggit/object_paste_params.hpp
Normal file
@@ -0,0 +1,17 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
struct object_paste_params
|
||||
{
|
||||
float minRotation = -180.f;
|
||||
float maxRotation = 180.f;
|
||||
float minTilt = -5.f;
|
||||
float maxTilt = 5.f;
|
||||
float minScale = 0.9f;
|
||||
float maxScale = 1.1f;
|
||||
bool rotate_on_terrain = true;
|
||||
};
|
||||
}
|
||||
122
src/noggit/tools/AreaTool.cpp
Normal file
122
src/noggit/tools/AreaTool.cpp
Normal file
@@ -0,0 +1,122 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#include "AreaTool.hpp"
|
||||
|
||||
#include <noggit/ActionManager.hpp>
|
||||
#include <noggit/MapView.h>
|
||||
#include <noggit/Input.hpp>
|
||||
#include <noggit/ui/ZoneIDBrowser.h>
|
||||
#include <noggit/ui/tools/ToolPanel/ToolPanel.hpp>
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
AreaTool::AreaTool(MapView* mapView)
|
||||
: Tool{ mapView }
|
||||
{
|
||||
addHotkey("setAreaId"_hash, {
|
||||
.onPress = [=] {
|
||||
if (_selectedAreaId != -1)
|
||||
{
|
||||
NOGGIT_ACTION_MGR->beginAction(mapView, Noggit::ActionFlags::eCHUNKS_AREAID);
|
||||
mapView->getWorld()->setAreaID(mapView->getCamera()->position, _selectedAreaId, true);
|
||||
NOGGIT_ACTION_MGR->endAction();
|
||||
}},
|
||||
.condition = [=] { return mapView->get_editing_mode() == editing_mode::areaid && !NOGGIT_CUR_ACTION; }
|
||||
});
|
||||
}
|
||||
|
||||
AreaTool::~AreaTool()
|
||||
{
|
||||
}
|
||||
|
||||
char const* AreaTool::name() const
|
||||
{
|
||||
return "Area Designator";
|
||||
}
|
||||
|
||||
editing_mode AreaTool::editingMode() const
|
||||
{
|
||||
return editing_mode::areaid;
|
||||
}
|
||||
|
||||
Ui::FontNoggit::Icons AreaTool::icon() const
|
||||
{
|
||||
return Ui::FontNoggit::TOOL_AREA_DESIGNATOR;
|
||||
}
|
||||
|
||||
void AreaTool::setupUi(Ui::Tools::ToolPanel* toolPanel)
|
||||
{
|
||||
_areaTool = new Noggit::Ui::zone_id_browser(mapView());
|
||||
toolPanel->registerTool(name(), _areaTool);
|
||||
|
||||
_areaTool->setMapID(mapView()->getWorld()->getMapID());
|
||||
QObject::connect(_areaTool, &Noggit::Ui::zone_id_browser::selected
|
||||
, [this](int area_id) { _selectedAreaId = area_id; }
|
||||
);
|
||||
}
|
||||
|
||||
ToolDrawParameters AreaTool::drawParameters() const
|
||||
{
|
||||
return ToolDrawParameters();
|
||||
}
|
||||
|
||||
void AreaTool::registerMenuItems(QMenu* menu)
|
||||
{
|
||||
addMenuTitle(menu, "Area Designator");
|
||||
addMenuItem(menu, "Set Area ID", [=] {
|
||||
if (_selectedAreaId == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NOGGIT_ACTION_MGR->beginAction(mapView(), Noggit::ActionFlags::eCHUNKS_AREAID);
|
||||
mapView()->getWorld()->setAreaID(mapView()->getCamera()->position, _selectedAreaId, true);
|
||||
NOGGIT_ACTION_MGR->endAction();
|
||||
});
|
||||
}
|
||||
|
||||
void AreaTool::onSelected()
|
||||
{
|
||||
mapView()->getWorld()->renderer()->getTerrainParamsUniformBlock()->draw_areaid_overlay = true;
|
||||
}
|
||||
|
||||
void AreaTool::onDeselected()
|
||||
{
|
||||
mapView()->getWorld()->renderer()->getTerrainParamsUniformBlock()->draw_areaid_overlay = false;
|
||||
}
|
||||
|
||||
void AreaTool::onTick(float deltaTime, TickParameters const& params)
|
||||
{
|
||||
if (!mapView()->getWorld()->has_selection() || params.underMap || !params.left_mouse)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (params.mod_shift_down)
|
||||
{
|
||||
NOGGIT_ACTION_MGR->beginAction(mapView(), Noggit::ActionFlags::eCHUNKS_AREAID,
|
||||
Noggit::ActionModalityControllers::eSHIFT
|
||||
| Noggit::ActionModalityControllers::eLMB);
|
||||
// draw the selected AreaId on current selected chunk
|
||||
mapView()->getWorld()->setAreaID(mapView()->cursorPosition(), _selectedAreaId, false, _areaTool->brushRadius());
|
||||
}
|
||||
else if (params.mod_ctrl_down)
|
||||
{
|
||||
for (auto&& selection : mapView()->getWorld()->current_selection())
|
||||
{
|
||||
MapChunk* chnk(std::get<selected_chunk_type>(selection).chunk);
|
||||
int newID = chnk->getAreaID();
|
||||
_selectedAreaId = newID;
|
||||
_areaTool->setZoneID(newID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AreaTool::onMouseMove(MouseMoveParameters const& params)
|
||||
{
|
||||
if (params.left_mouse && params.mod_alt_down && !params.mod_shift_down && !params.mod_ctrl_down)
|
||||
{
|
||||
_areaTool->changeRadius(params.relative_movement.dx() / XSENS);
|
||||
}
|
||||
}
|
||||
}
|
||||
48
src/noggit/tools/AreaTool.hpp
Normal file
48
src/noggit/tools/AreaTool.hpp
Normal file
@@ -0,0 +1,48 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <noggit/Tool.hpp>
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
namespace Ui
|
||||
{
|
||||
class zone_id_browser;
|
||||
}
|
||||
|
||||
class AreaTool final : public Tool
|
||||
{
|
||||
public:
|
||||
AreaTool(MapView* mapView);
|
||||
~AreaTool();
|
||||
|
||||
[[nodiscard]]
|
||||
virtual char const* name() const override;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual editing_mode editingMode() const override;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual Ui::FontNoggit::Icons icon() const override;
|
||||
|
||||
void setupUi(Ui::Tools::ToolPanel* toolPanel) override;
|
||||
|
||||
[[nodiscard]]
|
||||
ToolDrawParameters drawParameters() const override;
|
||||
|
||||
void registerMenuItems(QMenu* menu) override;
|
||||
|
||||
virtual void onSelected();
|
||||
|
||||
virtual void onDeselected();
|
||||
|
||||
void onTick(float deltaTime, TickParameters const& params) override;
|
||||
|
||||
void onMouseMove(MouseMoveParameters const& params) override;
|
||||
|
||||
private:
|
||||
Ui::zone_id_browser* _areaTool = nullptr;
|
||||
int _selectedAreaId = -1;
|
||||
};
|
||||
}
|
||||
43
src/noggit/tools/ChunkTool.cpp
Normal file
43
src/noggit/tools/ChunkTool.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#include "ChunkTool.hpp"
|
||||
|
||||
#include <noggit/ActionManager.hpp>
|
||||
#include <noggit/MapView.h>
|
||||
#include <noggit/Input.hpp>
|
||||
#include <noggit/ui/tools/ChunkManipulator/ChunkManipulatorPanel.hpp>
|
||||
#include <noggit/ui/tools/ToolPanel/ToolPanel.hpp>
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
ChunkTool::ChunkTool(MapView* mapView)
|
||||
: Tool{ mapView }
|
||||
{
|
||||
}
|
||||
|
||||
ChunkTool::~ChunkTool()
|
||||
{
|
||||
delete _chunkManipulator;
|
||||
}
|
||||
|
||||
char const* ChunkTool::name() const
|
||||
{
|
||||
return "Chunk Manipulator";
|
||||
}
|
||||
|
||||
editing_mode ChunkTool::editingMode() const
|
||||
{
|
||||
return editing_mode::chunk;
|
||||
}
|
||||
|
||||
Ui::FontNoggit::Icons ChunkTool::icon() const
|
||||
{
|
||||
return Ui::FontNoggit::INFO;
|
||||
}
|
||||
|
||||
void ChunkTool::setupUi(Ui::Tools::ToolPanel* toolPanel)
|
||||
{
|
||||
_chunkManipulator = new Noggit::Ui::Tools::ChunkManipulator::ChunkManipulatorPanel(mapView(), mapView());
|
||||
toolPanel->registerTool(name(), _chunkManipulator);
|
||||
}
|
||||
}
|
||||
34
src/noggit/tools/ChunkTool.hpp
Normal file
34
src/noggit/tools/ChunkTool.hpp
Normal file
@@ -0,0 +1,34 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <noggit/Tool.hpp>
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
namespace Ui::Tools::ChunkManipulator
|
||||
{
|
||||
class ChunkManipulatorPanel;
|
||||
}
|
||||
|
||||
class ChunkTool final : public Tool
|
||||
{
|
||||
public:
|
||||
ChunkTool(MapView* mapView);
|
||||
~ChunkTool();
|
||||
|
||||
[[nodiscard]]
|
||||
virtual char const* name() const override;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual editing_mode editingMode() const override;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual Ui::FontNoggit::Icons icon() const override;
|
||||
|
||||
void setupUi(Ui::Tools::ToolPanel* toolPanel) override;
|
||||
|
||||
private:
|
||||
Ui::Tools::ChunkManipulator::ChunkManipulatorPanel* _chunkManipulator = nullptr;
|
||||
};
|
||||
}
|
||||
187
src/noggit/tools/FlattenBlurTool.cpp
Normal file
187
src/noggit/tools/FlattenBlurTool.cpp
Normal file
@@ -0,0 +1,187 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#include "FlattenBlurTool.hpp"
|
||||
|
||||
#include <noggit/ActionManager.hpp>
|
||||
#include <noggit/Input.hpp>
|
||||
#include <noggit/MapView.h>
|
||||
#include <noggit/ui/FlattenTool.hpp>
|
||||
#include <noggit/ui/tools/ToolPanel/ToolPanel.hpp>
|
||||
#include <noggit/ui/tools/ViewToolbar/Ui/ViewToolbar.hpp>
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
FlattenBlurTool::FlattenBlurTool(MapView* mapView)
|
||||
: Tool{ mapView }
|
||||
{
|
||||
addHotkey("nextType"_hash, Hotkey{
|
||||
.onPress = [this] { _flattenTool->nextFlattenType(); },
|
||||
.condition = [mapView] { return mapView->get_editing_mode() == editing_mode::flatten_blur && !NOGGIT_CUR_ACTION; },
|
||||
});
|
||||
|
||||
addHotkey("toggleAngle"_hash, Hotkey{
|
||||
.onPress = [this] { _flattenTool->toggleFlattenAngle(); },
|
||||
.condition = [mapView] { return mapView->get_editing_mode() == editing_mode::flatten_blur && !NOGGIT_CUR_ACTION; },
|
||||
});
|
||||
|
||||
addHotkey("nextMode"_hash, Hotkey{
|
||||
.onPress = [this, mv = mapView]
|
||||
{
|
||||
mv->getLeftSecondaryViewToolbar()->nextFlattenMode();
|
||||
_flattenTool->nextFlattenMode();
|
||||
},
|
||||
.condition = [mapView] { return mapView->get_editing_mode() == editing_mode::flatten_blur && !NOGGIT_CUR_ACTION; },
|
||||
});
|
||||
|
||||
addHotkey("toggleLock"_hash, Hotkey{
|
||||
.onPress = [this] { _flattenTool->toggleFlattenLock(); },
|
||||
.condition = [mapView] { return mapView->get_editing_mode() == editing_mode::flatten_blur && !NOGGIT_CUR_ACTION; },
|
||||
});
|
||||
|
||||
addHotkey("lockCursor"_hash, Hotkey{
|
||||
.onPress = [this, mv = mapView] { _flattenTool->lockPos(mv->cursorPosition()); },
|
||||
.condition = [mapView] { return mapView->get_editing_mode() == editing_mode::flatten_blur && !NOGGIT_CUR_ACTION; },
|
||||
});
|
||||
|
||||
addHotkey("increaseRadius"_hash, Hotkey{
|
||||
.onPress = [this] { _flattenTool->changeRadius(0.01f); },
|
||||
.condition = [mapView] { return mapView->get_editing_mode() == editing_mode::flatten_blur && !NOGGIT_CUR_ACTION; },
|
||||
});
|
||||
|
||||
addHotkey("decreaseRadius"_hash, Hotkey{
|
||||
.onPress = [this] { _flattenTool->changeRadius(-0.01f); },
|
||||
.condition = [mapView] { return mapView->get_editing_mode() == editing_mode::flatten_blur && !NOGGIT_CUR_ACTION; },
|
||||
});
|
||||
}
|
||||
|
||||
FlattenBlurTool::~FlattenBlurTool()
|
||||
{
|
||||
delete _flattenTool;
|
||||
}
|
||||
|
||||
char const* FlattenBlurTool::name() const
|
||||
{
|
||||
return "Flatten | Blur";
|
||||
}
|
||||
|
||||
editing_mode FlattenBlurTool::editingMode() const
|
||||
{
|
||||
return editing_mode::flatten_blur;
|
||||
}
|
||||
|
||||
Ui::FontNoggit::Icons FlattenBlurTool::icon() const
|
||||
{
|
||||
return Ui::FontNoggit::TOOL_FLATTEN_BLUR;
|
||||
}
|
||||
|
||||
void FlattenBlurTool::setupUi(Ui::Tools::ToolPanel* toolPanel)
|
||||
{
|
||||
_flattenTool = new Noggit::Ui::flatten_blur_tool(mapView());
|
||||
toolPanel->registerTool(name(), _flattenTool);
|
||||
}
|
||||
|
||||
void FlattenBlurTool::postUiSetup()
|
||||
{
|
||||
QObject::connect(mapView()->getLeftSecondaryViewToolbar()
|
||||
, &Ui::Tools::ViewToolbar::Ui::ViewToolbar::updateStateRaise
|
||||
, [this](bool newState)
|
||||
{
|
||||
_flattenTool->_flatten_mode.raise = newState;
|
||||
}
|
||||
);
|
||||
|
||||
QObject::connect(mapView()->getLeftSecondaryViewToolbar()
|
||||
, &Ui::Tools::ViewToolbar::Ui::ViewToolbar::updateStateLower
|
||||
, [this](bool newState)
|
||||
{
|
||||
_flattenTool->_flatten_mode.lower = newState;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void FlattenBlurTool::onTick(float deltaTime, TickParameters const& params)
|
||||
{
|
||||
if (!mapView()->getWorld()->has_selection() || !params.left_mouse)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (params.displayMode == display_mode::in_3D && !params.underMap)
|
||||
{
|
||||
if (params.mod_shift_down)
|
||||
{
|
||||
NOGGIT_ACTION_MGR->beginAction(mapView(), Noggit::ActionFlags::eCHUNKS_TERRAIN,
|
||||
Noggit::ActionModalityControllers::eSHIFT
|
||||
| Noggit::ActionModalityControllers::eLMB);
|
||||
_flattenTool->flatten(mapView()->getWorld(), mapView()->cursorPosition(), deltaTime);
|
||||
}
|
||||
else if (params.mod_ctrl_down)
|
||||
{
|
||||
|
||||
NOGGIT_ACTION_MGR->beginAction(mapView(), Noggit::ActionFlags::eCHUNKS_TERRAIN,
|
||||
Noggit::ActionModalityControllers::eCTRL
|
||||
| Noggit::ActionModalityControllers::eLMB);
|
||||
_flattenTool->blur(mapView()->getWorld(), mapView()->cursorPosition(), deltaTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ToolDrawParameters FlattenBlurTool::drawParameters() const
|
||||
{
|
||||
return
|
||||
{
|
||||
.radius = _flattenTool->brushRadius(),
|
||||
.angle = _flattenTool->angle(),
|
||||
.orientation = _flattenTool->orientation(),
|
||||
.ref_pos = _flattenTool->ref_pos(),
|
||||
.angled_mode = _flattenTool->angled_mode(),
|
||||
.use_ref_pos = _flattenTool->use_ref_pos(),
|
||||
};
|
||||
}
|
||||
|
||||
void FlattenBlurTool::onMouseMove(MouseMoveParameters const& params)
|
||||
{
|
||||
if (params.left_mouse)
|
||||
{
|
||||
if (params.mod_alt_down && !params.mod_shift_down && !params.mod_ctrl_down)
|
||||
{
|
||||
_flattenTool->changeRadius(params.relative_movement.dx() / XSENS);
|
||||
}
|
||||
|
||||
if (params.mod_space_down)
|
||||
{
|
||||
_flattenTool->changeSpeed(params.relative_movement.dx() / 30.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FlattenBlurTool::onMouseWheel(MouseWheelParameters const& params)
|
||||
{
|
||||
auto&& delta_for_range
|
||||
([&](float range)
|
||||
{
|
||||
//! \note / 8.f for degrees, / 40.f for smoothness
|
||||
return (params.mod_ctrl_down ? 0.01f : 0.1f)
|
||||
* range
|
||||
// alt = horizontal delta
|
||||
* (params.mod_alt_down ? params.event.angleDelta().x() : params.event.angleDelta().y())
|
||||
/ 320.f
|
||||
;
|
||||
}
|
||||
);
|
||||
|
||||
if (params.mod_alt_down)
|
||||
{
|
||||
_flattenTool->changeOrientation(delta_for_range(360.f));
|
||||
}
|
||||
else if (params.mod_shift_down)
|
||||
{
|
||||
_flattenTool->changeAngle(delta_for_range(89.f));
|
||||
}
|
||||
else if (params.mod_space_down)
|
||||
{
|
||||
//! \note not actual range
|
||||
_flattenTool->changeHeight(delta_for_range(40.f));
|
||||
}
|
||||
}
|
||||
}
|
||||
45
src/noggit/tools/FlattenBlurTool.hpp
Normal file
45
src/noggit/tools/FlattenBlurTool.hpp
Normal file
@@ -0,0 +1,45 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <noggit/Tool.hpp>
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
namespace Ui
|
||||
{
|
||||
class flatten_blur_tool;
|
||||
}
|
||||
|
||||
class FlattenBlurTool final : public Tool
|
||||
{
|
||||
public:
|
||||
FlattenBlurTool(MapView* mapView);
|
||||
~FlattenBlurTool();
|
||||
|
||||
[[nodiscard]]
|
||||
char const* name() const override;
|
||||
|
||||
[[nodiscard]]
|
||||
editing_mode editingMode() const override;
|
||||
|
||||
[[nodiscard]]
|
||||
Ui::FontNoggit::Icons icon() const override;
|
||||
|
||||
void setupUi(Ui::Tools::ToolPanel* toolPanel) override;
|
||||
|
||||
void postUiSetup() override;
|
||||
|
||||
void onTick(float deltaTime, TickParameters const& params) override;
|
||||
|
||||
[[nodiscard]]
|
||||
ToolDrawParameters drawParameters() const override;
|
||||
|
||||
void onMouseMove(MouseMoveParameters const& params) override;
|
||||
|
||||
void onMouseWheel(MouseWheelParameters const& params) override;
|
||||
|
||||
private:
|
||||
Ui::flatten_blur_tool* _flattenTool = nullptr;
|
||||
};
|
||||
}
|
||||
113
src/noggit/tools/HoleTool.cpp
Normal file
113
src/noggit/tools/HoleTool.cpp
Normal file
@@ -0,0 +1,113 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#include "HoleTool.hpp"
|
||||
|
||||
#include <noggit/ActionManager.hpp>
|
||||
#include <noggit/MapView.h>
|
||||
#include <noggit/Input.hpp>
|
||||
#include <noggit/ui/hole_tool.hpp>
|
||||
#include <noggit/ui/tools/ToolPanel/ToolPanel.hpp>
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
HoleTool::HoleTool(MapView* mapView)
|
||||
: Tool{ mapView }
|
||||
{
|
||||
addHotkey("unsetAdtHole"_hash, Hotkey{
|
||||
.onPress = [=] {
|
||||
NOGGIT_ACTION_MGR->beginAction(mapView, Noggit::ActionFlags::eCHUNKS_HOLES);
|
||||
mapView->getWorld()->setHoleADT(mapView->getCamera()->position, false);
|
||||
NOGGIT_ACTION_MGR->endAction();
|
||||
},
|
||||
.condition = [=] { return mapView->get_editing_mode() == editing_mode::holes && !NOGGIT_CUR_ACTION; },
|
||||
});
|
||||
|
||||
addHotkey("setAdtHole"_hash, Hotkey{
|
||||
.onPress = [=] {
|
||||
NOGGIT_ACTION_MGR->beginAction(mapView, Noggit::ActionFlags::eCHUNKS_HOLES);
|
||||
mapView->getWorld()->setHoleADT(mapView->getCamera()->position, true);
|
||||
NOGGIT_ACTION_MGR->endAction();
|
||||
},
|
||||
.condition = [=] { return mapView->get_editing_mode() == editing_mode::holes && !NOGGIT_CUR_ACTION; },
|
||||
});
|
||||
}
|
||||
|
||||
HoleTool::~HoleTool()
|
||||
{
|
||||
delete _holeTool;
|
||||
}
|
||||
|
||||
char const* HoleTool::name() const
|
||||
{
|
||||
return "Hole Cutter";
|
||||
}
|
||||
|
||||
editing_mode HoleTool::editingMode() const
|
||||
{
|
||||
return editing_mode::holes;
|
||||
}
|
||||
|
||||
Ui::FontNoggit::Icons HoleTool::icon() const
|
||||
{
|
||||
return Ui::FontNoggit::TOOL_HOLE_CUTTER;
|
||||
}
|
||||
|
||||
void HoleTool::setupUi(Ui::Tools::ToolPanel* toolPanel)
|
||||
{
|
||||
_holeTool = new Noggit::Ui::hole_tool(mapView());
|
||||
toolPanel->registerTool(name(), _holeTool);
|
||||
}
|
||||
|
||||
ToolDrawParameters HoleTool::drawParameters() const
|
||||
{
|
||||
return
|
||||
{
|
||||
.radius = _holeTool->brushRadius(),
|
||||
};
|
||||
}
|
||||
|
||||
void HoleTool::onSelected()
|
||||
{
|
||||
mapView()->getWorld()->renderer()->getTerrainParamsUniformBlock()->draw_lines = true;
|
||||
mapView()->getWorld()->renderer()->getTerrainParamsUniformBlock()->draw_hole_lines = true;
|
||||
}
|
||||
|
||||
void HoleTool::onDeselected()
|
||||
{
|
||||
mapView()->getWorld()->renderer()->getTerrainParamsUniformBlock()->draw_lines = mapView()->drawAdtGrid();
|
||||
mapView()->getWorld()->renderer()->getTerrainParamsUniformBlock()->draw_hole_lines = mapView()->drawHoleGrid();
|
||||
}
|
||||
|
||||
void HoleTool::onTick(float deltaTime, TickParameters const& params)
|
||||
{
|
||||
if (!mapView()->getWorld()->has_selection() || !params.left_mouse)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto mv = mapView();
|
||||
// no undermap check here, else it's impossible to remove holes
|
||||
if (params.mod_shift_down)
|
||||
{
|
||||
NOGGIT_ACTION_MGR->beginAction(mv, Noggit::ActionFlags::eCHUNKS_HOLES,
|
||||
Noggit::ActionModalityControllers::eSHIFT
|
||||
| Noggit::ActionModalityControllers::eLMB);
|
||||
mv->getWorld()->setHole(mv->cursorPosition(), _holeTool->brushRadius(), params.mod_alt_down, false);
|
||||
}
|
||||
else if (params.mod_ctrl_down && !params.underMap)
|
||||
{
|
||||
NOGGIT_ACTION_MGR->beginAction(mv, Noggit::ActionFlags::eCHUNKS_HOLES,
|
||||
Noggit::ActionModalityControllers::eCTRL
|
||||
| Noggit::ActionModalityControllers::eLMB);
|
||||
mv->getWorld()->setHole(mv->cursorPosition(), _holeTool->brushRadius(), params.mod_alt_down, true);
|
||||
}
|
||||
}
|
||||
|
||||
void HoleTool::onMouseMove(MouseMoveParameters const& params)
|
||||
{
|
||||
if (params.left_mouse && params.mod_alt_down && !params.mod_shift_down && !params.mod_ctrl_down)
|
||||
{
|
||||
_holeTool->changeRadius(params.relative_movement.dx() / XSENS);
|
||||
}
|
||||
}
|
||||
}
|
||||
45
src/noggit/tools/HoleTool.hpp
Normal file
45
src/noggit/tools/HoleTool.hpp
Normal file
@@ -0,0 +1,45 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <noggit/Tool.hpp>
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
namespace Ui
|
||||
{
|
||||
class hole_tool;
|
||||
}
|
||||
|
||||
class HoleTool final : public Tool
|
||||
{
|
||||
public:
|
||||
HoleTool(MapView* mapView);
|
||||
~HoleTool();
|
||||
|
||||
[[nodiscard]]
|
||||
virtual char const* name() const override;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual editing_mode editingMode() const override;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual Ui::FontNoggit::Icons icon() const override;
|
||||
|
||||
void setupUi(Ui::Tools::ToolPanel* toolPanel) override;
|
||||
|
||||
[[nodiscard]]
|
||||
ToolDrawParameters drawParameters() const override;
|
||||
|
||||
void onSelected() override;
|
||||
|
||||
void onDeselected() override;
|
||||
|
||||
void onTick(float deltaTime, TickParameters const& params) override;
|
||||
|
||||
void onMouseMove(MouseMoveParameters const& params) override;
|
||||
|
||||
private:
|
||||
Ui::hole_tool* _holeTool = nullptr;
|
||||
};
|
||||
}
|
||||
71
src/noggit/tools/ImpassTool.cpp
Normal file
71
src/noggit/tools/ImpassTool.cpp
Normal file
@@ -0,0 +1,71 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#include "ImpassTool.hpp"
|
||||
|
||||
#include <noggit/ActionManager.hpp>
|
||||
#include <noggit/MapView.h>
|
||||
#include <noggit/Input.hpp>
|
||||
#include <noggit/ui/tools/ToolPanel/ToolPanel.hpp>
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
ImpassTool::ImpassTool(MapView* mapView)
|
||||
: Tool{ mapView }
|
||||
{
|
||||
}
|
||||
|
||||
char const* ImpassTool::name() const
|
||||
{
|
||||
return "Impass Designator";
|
||||
}
|
||||
|
||||
editing_mode ImpassTool::editingMode() const
|
||||
{
|
||||
return editing_mode::impass;
|
||||
}
|
||||
|
||||
Ui::FontNoggit::Icons ImpassTool::icon() const
|
||||
{
|
||||
return Ui::FontNoggit::TOOL_IMPASS_DESIGNATOR;
|
||||
}
|
||||
|
||||
void ImpassTool::setupUi(Ui::Tools::ToolPanel* toolPanel)
|
||||
{
|
||||
// Dummy, because the toolbar requires a widget for every tool
|
||||
toolPanel->registerTool(name(), new QWidget{mapView()});
|
||||
}
|
||||
|
||||
void ImpassTool::onSelected()
|
||||
{
|
||||
mapView()->getWorld()->renderer()->getTerrainParamsUniformBlock()->draw_impass_overlay = true;
|
||||
}
|
||||
|
||||
void ImpassTool::onDeselected()
|
||||
{
|
||||
mapView()->getWorld()->renderer()->getTerrainParamsUniformBlock()->draw_impass_overlay = false;
|
||||
}
|
||||
|
||||
void ImpassTool::onTick(float deltaTime, TickParameters const& params)
|
||||
{
|
||||
if (!mapView()->getWorld()->has_selection() || params.underMap || !params.left_mouse)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// todo: replace this -- why and with what?
|
||||
if (params.mod_shift_down)
|
||||
{
|
||||
NOGGIT_ACTION_MGR->beginAction(mapView(), Noggit::ActionFlags::eCHUNKS_FLAGS,
|
||||
Noggit::ActionModalityControllers::eSHIFT
|
||||
| Noggit::ActionModalityControllers::eLMB);
|
||||
mapView()->getWorld()->mapIndex.setFlag(true, mapView()->cursorPosition(), 0x2);
|
||||
}
|
||||
else if (params.mod_ctrl_down)
|
||||
{
|
||||
NOGGIT_ACTION_MGR->beginAction(mapView(), Noggit::ActionFlags::eCHUNKS_FLAGS,
|
||||
Noggit::ActionModalityControllers::eCTRL
|
||||
| Noggit::ActionModalityControllers::eLMB);
|
||||
mapView()->getWorld()->mapIndex.setFlag(false, mapView()->cursorPosition(), 0x2);
|
||||
}
|
||||
}
|
||||
}
|
||||
32
src/noggit/tools/ImpassTool.hpp
Normal file
32
src/noggit/tools/ImpassTool.hpp
Normal file
@@ -0,0 +1,32 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <noggit/Tool.hpp>
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
class ImpassTool final : public Tool
|
||||
{
|
||||
public:
|
||||
ImpassTool(MapView* mapView);
|
||||
~ImpassTool() = default;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual char const* name() const override;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual editing_mode editingMode() const override;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual Ui::FontNoggit::Icons icon() const override;
|
||||
|
||||
virtual void setupUi(Ui::Tools::ToolPanel* toolPanel) override;
|
||||
|
||||
void onSelected() override;
|
||||
|
||||
void onDeselected() override;
|
||||
|
||||
void onTick(float deltaTime, TickParameters const& params) override;
|
||||
};
|
||||
}
|
||||
49
src/noggit/tools/LightTool.cpp
Normal file
49
src/noggit/tools/LightTool.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#include "LightTool.hpp"
|
||||
|
||||
#include <noggit/ActionManager.hpp>
|
||||
#include <noggit/MapView.h>
|
||||
#include <noggit/Input.hpp>
|
||||
#include <noggit/ui/tools/LightEditor/LightEditor.hpp>
|
||||
#include <noggit/ui/tools/ToolPanel/ToolPanel.hpp>
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
LightTool::LightTool(MapView* mapView)
|
||||
: Tool{ mapView }
|
||||
{
|
||||
}
|
||||
|
||||
LightTool::~LightTool()
|
||||
{
|
||||
delete _lightEditor;
|
||||
}
|
||||
|
||||
char const* LightTool::name() const
|
||||
{
|
||||
return "Light Editor";
|
||||
}
|
||||
|
||||
editing_mode LightTool::editingMode() const
|
||||
{
|
||||
return editing_mode::light;
|
||||
}
|
||||
|
||||
Ui::FontNoggit::Icons LightTool::icon() const
|
||||
{
|
||||
return Ui::FontNoggit::TOOL_LIGHT;
|
||||
}
|
||||
|
||||
void LightTool::setupUi(Ui::Tools::ToolPanel* toolPanel)
|
||||
{
|
||||
_lightEditor = new Noggit::Ui::Tools::LightEditor(mapView(), mapView());
|
||||
toolPanel->registerTool(name(), _lightEditor);
|
||||
}
|
||||
|
||||
void LightTool::onTick(float deltaTime, TickParameters const& params)
|
||||
{
|
||||
if (mapView()->timeSpeed() > 0.0f)
|
||||
_lightEditor->UpdateWorldTime();
|
||||
}
|
||||
}
|
||||
36
src/noggit/tools/LightTool.hpp
Normal file
36
src/noggit/tools/LightTool.hpp
Normal file
@@ -0,0 +1,36 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <noggit/Tool.hpp>
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
namespace Ui::Tools
|
||||
{
|
||||
class LightEditor;
|
||||
}
|
||||
|
||||
class LightTool final : public Tool
|
||||
{
|
||||
public:
|
||||
LightTool(MapView* mapView);
|
||||
~LightTool();
|
||||
|
||||
[[nodiscard]]
|
||||
virtual char const* name() const override;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual editing_mode editingMode() const override;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual Ui::FontNoggit::Icons icon() const override;
|
||||
|
||||
void setupUi(Ui::Tools::ToolPanel* toolPanel) override;
|
||||
|
||||
void onTick(float deltaTime, TickParameters const& params) override;
|
||||
|
||||
private:
|
||||
Ui::Tools::LightEditor* _lightEditor = nullptr;
|
||||
};
|
||||
}
|
||||
299
src/noggit/tools/MinimapTool.cpp
Normal file
299
src/noggit/tools/MinimapTool.cpp
Normal file
@@ -0,0 +1,299 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#include "MinimapTool.hpp"
|
||||
|
||||
#include <noggit/ActionManager.hpp>
|
||||
#include <noggit/MapView.h>
|
||||
#include <noggit/Input.hpp>
|
||||
#include <noggit/project/CurrentProject.hpp>
|
||||
#include <noggit/ui/MinimapCreator.hpp>
|
||||
#include <noggit/ui/tools/ToolPanel/ToolPanel.hpp>
|
||||
#include <noggit/ui/windows/noggitWindow/NoggitWindow.hpp>
|
||||
|
||||
#include <QDir>
|
||||
#include <QStatusBar>
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
MinimapTool::MinimapTool(MapView* mapView)
|
||||
: Tool{ mapView }
|
||||
{
|
||||
}
|
||||
|
||||
MinimapTool::~MinimapTool()
|
||||
{
|
||||
delete _minimapTool;
|
||||
}
|
||||
|
||||
char const* MinimapTool::name() const
|
||||
{
|
||||
return "Minimap Editor";
|
||||
}
|
||||
|
||||
editing_mode MinimapTool::editingMode() const
|
||||
{
|
||||
return editing_mode::minimap;
|
||||
}
|
||||
|
||||
Ui::FontNoggit::Icons MinimapTool::icon() const
|
||||
{
|
||||
return Ui::FontNoggit::TOOL_MINIMAP_EDITOR;
|
||||
}
|
||||
|
||||
void MinimapTool::setupUi(Ui::Tools::ToolPanel* toolPanel)
|
||||
{
|
||||
auto mv = mapView();
|
||||
_minimapTool = new Noggit::Ui::MinimapCreator(mv, mv->getWorld(), mv);
|
||||
toolPanel->registerTool(name(), _minimapTool);
|
||||
|
||||
QObject::connect(_minimapTool, &Ui::MinimapCreator::onSave, [=] {
|
||||
saving_minimap = true;
|
||||
});
|
||||
}
|
||||
|
||||
ToolDrawParameters MinimapTool::drawParameters() const
|
||||
{
|
||||
return
|
||||
{
|
||||
.radius = _minimapTool->brushRadius(),
|
||||
.minimapRenderSettings = *_minimapTool->getMinimapRenderSettings(),
|
||||
};
|
||||
}
|
||||
|
||||
void MinimapTool::onSelected()
|
||||
{
|
||||
mapView()->getWorld()->renderer()->getTerrainParamsUniformBlock()->draw_selection_overlay = true;
|
||||
mapView()->getMinimapWidget()->use_selection(_minimapTool->getSelectedTiles());
|
||||
}
|
||||
|
||||
void MinimapTool::onTick(float deltaTime, TickParameters const& params)
|
||||
{
|
||||
if (!mapView()->getWorld()->has_selection() || !params.left_mouse)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool MinimapTool::preRender()
|
||||
{
|
||||
if (!saving_minimap)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
auto mv = mapView();
|
||||
auto world = mv->getWorld();
|
||||
auto settings = _minimapTool->getMinimapRenderSettings();
|
||||
|
||||
mv->setCameraDirty();
|
||||
|
||||
OpenGL::context::scoped_setter const _(::gl, mv->context());
|
||||
mv->makeCurrent();
|
||||
|
||||
bool mmap_render_success = false;
|
||||
|
||||
static QProgressBar* progress;
|
||||
static QPushButton* cancel_btn;
|
||||
|
||||
auto init = [=](int max) {
|
||||
progress = new QProgressBar(nullptr);
|
||||
progress->setMinimum(0);
|
||||
progress->setMaximum(max);
|
||||
mv->mainWindow()->statusBar()->addPermanentWidget(progress);
|
||||
|
||||
cancel_btn = new QPushButton(nullptr);
|
||||
cancel_btn->setText("Cancel");
|
||||
|
||||
QObject::connect(cancel_btn, &QPushButton::clicked,
|
||||
[=]
|
||||
{
|
||||
_mmap_async_index = 0;
|
||||
_mmap_render_index = 0;
|
||||
saving_minimap = false;
|
||||
progress->deleteLater();
|
||||
cancel_btn->deleteLater();
|
||||
_mmap_combined_image.reset();
|
||||
});
|
||||
|
||||
mv->mainWindow()->statusBar()->addPermanentWidget(cancel_btn);
|
||||
|
||||
QObject::connect(mv, &MapView::updateProgress,
|
||||
[=](int value)
|
||||
{
|
||||
// This weirdness is required due to a bug on Linux when QT repaint crashes due to too many events
|
||||
// being passed through. TODO: this potentially only masks the issue, which may reappear on faster
|
||||
// hardware.
|
||||
if (progress->value() != value)
|
||||
progress->setValue(value);
|
||||
});
|
||||
|
||||
// setup combined image if necessary
|
||||
if (settings->combined_minimap)
|
||||
{
|
||||
_mmap_combined_image.emplace(8192, 8192, QImage::Format_RGBA8888);
|
||||
_mmap_combined_image->fill(Qt::black);
|
||||
}
|
||||
};
|
||||
|
||||
auto save = [=, &mmap_render_success]()
|
||||
{
|
||||
while (!world->mapIndex.hasTile({ _mmap_async_index / 64, _mmap_async_index % 64 }))
|
||||
{
|
||||
++_mmap_async_index;
|
||||
}
|
||||
|
||||
TileIndex tile = TileIndex(_mmap_async_index / 64, _mmap_async_index % 64);
|
||||
|
||||
if (world->mapIndex.hasTile(tile))
|
||||
{
|
||||
OpenGL::context::scoped_setter const _(::gl, mv->context());
|
||||
mv->makeCurrent();
|
||||
mmap_render_success = world->renderer()->saveMinimap(tile, settings, _mmap_combined_image);
|
||||
|
||||
_mmap_render_index++;
|
||||
emit mv->updateProgress(_mmap_render_index);
|
||||
|
||||
if (!mmap_render_success)
|
||||
{
|
||||
LogError << "Minimap rendered incorrectly for tile: " << tile.x << "_" << tile.z << std::endl;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
switch (settings->export_mode)
|
||||
{
|
||||
case MinimapGenMode::CURRENT_ADT:
|
||||
{
|
||||
TileIndex tile = TileIndex(mv->getCamera()->position);
|
||||
|
||||
if (world->mapIndex.hasTile(tile))
|
||||
{
|
||||
mmap_render_success = world->renderer()->saveMinimap(tile, settings, _mmap_combined_image);
|
||||
}
|
||||
|
||||
if (mmap_render_success)
|
||||
{
|
||||
world->mapIndex.saveMinimapMD5translate();
|
||||
}
|
||||
|
||||
saving_minimap = false;
|
||||
|
||||
break;
|
||||
}
|
||||
case MinimapGenMode::MAP:
|
||||
{
|
||||
// init progress
|
||||
if (!_mmap_async_index)
|
||||
{
|
||||
init(world->mapIndex.getNumExistingTiles());
|
||||
}
|
||||
|
||||
if (!saving_minimap)
|
||||
return false;
|
||||
|
||||
if (_mmap_async_index < 4096 && static_cast<int>(_mmap_render_index) < progress->maximum())
|
||||
{
|
||||
save();
|
||||
_mmap_async_index++;
|
||||
}
|
||||
else
|
||||
{
|
||||
finishSaving(progress, cancel_btn, world, settings);
|
||||
}
|
||||
|
||||
//_main_window->statusBar()->showMessage("Minimap rendering done.", 2000);
|
||||
break;
|
||||
}
|
||||
case MinimapGenMode::SELECTED_ADTS:
|
||||
{
|
||||
auto selected_tiles = _minimapTool->getSelectedTiles();
|
||||
|
||||
// init progress
|
||||
if (!_mmap_async_index)
|
||||
{
|
||||
int n_selected_tiles = 0;
|
||||
|
||||
for (int i = 0; i < 4096; ++i)
|
||||
{
|
||||
if (selected_tiles->at(i))
|
||||
n_selected_tiles++;
|
||||
}
|
||||
|
||||
init(n_selected_tiles);
|
||||
}
|
||||
|
||||
if (!saving_minimap)
|
||||
return false;
|
||||
|
||||
if (_mmap_async_index < 4096 && static_cast<int>(_mmap_render_index) < progress->maximum())
|
||||
{
|
||||
if (selected_tiles->at(_mmap_async_index))
|
||||
{
|
||||
save();
|
||||
}
|
||||
_mmap_async_index++;
|
||||
}
|
||||
else
|
||||
{
|
||||
finishSaving(progress, cancel_btn, world, settings);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//minimapTool->progressUpdate(0);
|
||||
return !saving_minimap;
|
||||
}
|
||||
|
||||
void MinimapTool::onMouseMove(MouseMoveParameters const& params)
|
||||
{
|
||||
if (params.left_mouse)
|
||||
{
|
||||
if (params.mod_alt_down && !params.mod_shift_down && !params.mod_ctrl_down)
|
||||
{
|
||||
_minimapTool->changeRadius(params.relative_movement.dx() / XSENS);
|
||||
}
|
||||
|
||||
if (params.mod_shift_down || params.mod_ctrl_down)
|
||||
{
|
||||
mapView()->doSelection(false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MinimapTool::finishSaving(QProgressBar* progress, QPushButton* cancel_btn, World* world, MinimapRenderSettings* settings)
|
||||
{
|
||||
_mmap_async_index = 0;
|
||||
_mmap_render_index = 0;
|
||||
saving_minimap = false;
|
||||
progress->deleteLater();
|
||||
cancel_btn->deleteLater();
|
||||
world->mapIndex.saveMinimapMD5translate();
|
||||
|
||||
// save combined minimap
|
||||
if (settings->combined_minimap)
|
||||
{
|
||||
QString image_path = QString(std::string(world->basename + "_combined_minimap.png").c_str());
|
||||
QString str = QString(Noggit::Project::CurrentProject::get()->ProjectPath.c_str());
|
||||
if (!(str.endsWith('\\') || str.endsWith('/')))
|
||||
{
|
||||
str += "/";
|
||||
}
|
||||
|
||||
QDir dir(str + "/textures/minimap/");
|
||||
if (!dir.exists())
|
||||
dir.mkpath(".");
|
||||
|
||||
_mmap_combined_image->save(dir.filePath(image_path));
|
||||
_mmap_combined_image.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void MinimapTool::saveSettings()
|
||||
{
|
||||
// Save minimap creator model filters
|
||||
_minimapTool->saveFiltersToJSON();
|
||||
}
|
||||
}
|
||||
60
src/noggit/tools/MinimapTool.hpp
Normal file
60
src/noggit/tools/MinimapTool.hpp
Normal file
@@ -0,0 +1,60 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <noggit/Tool.hpp>
|
||||
|
||||
class QProgressBar;
|
||||
class QPushButton;
|
||||
class World;
|
||||
struct MinimapRenderSettings;
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
namespace Ui
|
||||
{
|
||||
class MinimapCreator;
|
||||
}
|
||||
|
||||
class MinimapTool final : public Tool
|
||||
{
|
||||
public:
|
||||
MinimapTool(MapView* mapView);
|
||||
~MinimapTool();
|
||||
|
||||
[[nodiscard]]
|
||||
virtual char const* name() const override;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual editing_mode editingMode() const override;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual Ui::FontNoggit::Icons icon() const override;
|
||||
|
||||
void setupUi(Ui::Tools::ToolPanel* toolPanel) override;
|
||||
|
||||
[[nodiscard]]
|
||||
ToolDrawParameters drawParameters() const override;
|
||||
|
||||
void onSelected() override;
|
||||
|
||||
void onTick(float deltaTime, TickParameters const& params) override;
|
||||
|
||||
bool preRender() override;
|
||||
|
||||
void onMouseMove(MouseMoveParameters const& params) override;
|
||||
|
||||
void saveSettings() override;
|
||||
|
||||
private:
|
||||
Ui::MinimapCreator* _minimapTool = nullptr;
|
||||
|
||||
unsigned _mmap_async_index = 0;
|
||||
unsigned _mmap_render_index = 0;
|
||||
std::optional<QImage> _mmap_combined_image;
|
||||
|
||||
bool saving_minimap = false;
|
||||
|
||||
void finishSaving(QProgressBar* progress, QPushButton* cancel_btn, World* world, MinimapRenderSettings* settings);
|
||||
};
|
||||
}
|
||||
968
src/noggit/tools/ObjectTool.cpp
Normal file
968
src/noggit/tools/ObjectTool.cpp
Normal file
@@ -0,0 +1,968 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#include "ObjectTool.hpp"
|
||||
|
||||
#include <noggit/ActionManager.hpp>
|
||||
#include <noggit/MapView.h>
|
||||
#include <noggit/Input.hpp>
|
||||
#include <noggit/ui/ObjectEditor.h>
|
||||
#include <noggit/ui/tools/AssetBrowser/Ui/AssetBrowser.hpp>
|
||||
#include <noggit/ui/ModelImport.h>
|
||||
#include <noggit/ui/RotationEditor.h>
|
||||
#include <noggit/ui/HelperModels.h>
|
||||
#include <noggit/ui/tools/ToolPanel/ToolPanel.hpp>
|
||||
#include <noggit/ui/object_palette.hpp>
|
||||
#include <noggit/ui/windows/noggitWindow/NoggitWindow.hpp>
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
ObjectTool::ObjectTool(MapView* mapView)
|
||||
: Tool{ mapView }
|
||||
{
|
||||
setupHotkeys();
|
||||
}
|
||||
|
||||
ObjectTool::~ObjectTool()
|
||||
{
|
||||
delete _objectEditor;
|
||||
}
|
||||
|
||||
unsigned int ObjectTool::actionModality() const
|
||||
{
|
||||
unsigned int actionModality = 0;
|
||||
if (_moveObject)
|
||||
actionModality |= Noggit::ActionModalityControllers::eMMB;
|
||||
if (_keys)
|
||||
actionModality |= Noggit::ActionModalityControllers::eSCALE;
|
||||
if (_keyr)
|
||||
actionModality |= Noggit::ActionModalityControllers::eROTATE;
|
||||
|
||||
return actionModality;
|
||||
}
|
||||
|
||||
char const* ObjectTool::name() const
|
||||
{
|
||||
return "Object Editor";
|
||||
}
|
||||
|
||||
editing_mode ObjectTool::editingMode() const
|
||||
{
|
||||
return editing_mode::object;
|
||||
}
|
||||
|
||||
Ui::FontNoggit::Icons ObjectTool::icon() const
|
||||
{
|
||||
return Ui::FontNoggit::TOOL_OBJECT_EDITOR;
|
||||
}
|
||||
|
||||
void ObjectTool::setupUi(Ui::Tools::ToolPanel* toolPanel)
|
||||
{
|
||||
auto mv = mapView();
|
||||
|
||||
// initialize some saved defaults
|
||||
_object_paste_params.rotate_on_terrain = mv->settings()->value("paste_params/rotate_on_terrain", true).toBool();
|
||||
|
||||
/* Tool */
|
||||
_objectEditor = new Noggit::Ui::object_editor(mv
|
||||
, mv->getWorld()
|
||||
, &_move_model_to_cursor_position
|
||||
, &_snap_multi_selection_to_ground
|
||||
, &_use_median_pivot_point
|
||||
, &_object_paste_params
|
||||
, &_rotate_along_ground
|
||||
, &_rotate_along_ground_smooth
|
||||
, &_rotate_along_ground_random
|
||||
, &_move_model_snap_to_objects
|
||||
, mv
|
||||
);
|
||||
toolPanel->registerTool(name(), _objectEditor);
|
||||
|
||||
/* Additional tools */
|
||||
|
||||
/* Area selection */
|
||||
_area_selection = new QRubberBand(QRubberBand::Rectangle, mv);
|
||||
|
||||
/* Object Palette */
|
||||
_object_palette = new Noggit::Ui::ObjectPalette(mv, mv->project(), mv);
|
||||
_object_palette->hide();
|
||||
|
||||
// Dock
|
||||
_object_palette_dock = new QDockWidget("Object Palette", mv);
|
||||
_object_palette_dock->setFeatures(QDockWidget::DockWidgetMovable
|
||||
| QDockWidget::DockWidgetFloatable
|
||||
| QDockWidget::DockWidgetClosable
|
||||
);
|
||||
|
||||
_object_palette_dock->setWidget(_object_palette);
|
||||
_object_palette_dock->setAllowedAreas(Qt::BottomDockWidgetArea | Qt::TopDockWidgetArea);
|
||||
mv->mainWindow()->addDockWidget(Qt::BottomDockWidgetArea, _object_palette_dock);
|
||||
_object_palette_dock->hide();
|
||||
// End Dock
|
||||
|
||||
QObject::connect(_object_palette_dock, &QDockWidget::visibilityChanged,
|
||||
[=](bool visible)
|
||||
{
|
||||
if (mv->isUiHidden())
|
||||
return;
|
||||
|
||||
mv->settings()->setValue("map_view/object_palette", visible);
|
||||
mv->settings()->sync();
|
||||
});
|
||||
|
||||
QObject::connect(mapView(), &MapView::rotationChanged, [=] {
|
||||
updateRotationEditor();
|
||||
});
|
||||
|
||||
QObject::connect(_objectEditor, &Ui::object_editor::objectPaletteBtnPressed, [=] {
|
||||
_object_palette_dock->setVisible(_object_palette_dock->isHidden());
|
||||
});
|
||||
|
||||
QObject::connect(mapView(), &MapView::selectionUpdated, [=](auto) {
|
||||
_objectEditor->update_selection_ui(mapView()->getWorld());
|
||||
});
|
||||
|
||||
using AssetBrowser = Noggit::Ui::Tools::AssetBrowser::Ui::AssetBrowserWidget;
|
||||
QObject::connect(mapView()->getAssetBrowserWidget(), &AssetBrowser::selectionChanged, [=](std::string const& path) {
|
||||
if (_objectEditor->isVisible()) _objectEditor->copy(path);
|
||||
});
|
||||
|
||||
QObject::connect(_object_palette, &Ui::ObjectPalette::selected, [=](std::string str) {
|
||||
_objectEditor->copy(str);
|
||||
});
|
||||
}
|
||||
|
||||
ToolDrawParameters ObjectTool::drawParameters() const
|
||||
{
|
||||
return
|
||||
{
|
||||
.radius = _objectEditor->brushRadius(),
|
||||
};
|
||||
}
|
||||
|
||||
float ObjectTool::brushRadius() const
|
||||
{
|
||||
return _objectEditor->brushRadius();
|
||||
}
|
||||
|
||||
bool ObjectTool::useMultiselectionPivot() const
|
||||
{
|
||||
return _use_median_pivot_point.get();
|
||||
}
|
||||
|
||||
bool ObjectTool::useMedianPivotPoint() const
|
||||
{
|
||||
return _use_median_pivot_point.get();
|
||||
}
|
||||
|
||||
void ObjectTool::registerMenuItems(QMenu* menu)
|
||||
{
|
||||
addMenuTitle(menu, name());
|
||||
|
||||
addMenuItem(menu, "Last M2 from WMV", QKeySequence{ "Shift+V" }, [this] { _objectEditor->import_last_model_from_wmv(eMODEL); });
|
||||
addMenuItem(menu, "Last WMO from WMV", QKeySequence{ "Alt+V" }, [this] { _objectEditor->import_last_model_from_wmv(eWMO); });
|
||||
addMenuItem(menu, "Helper models", [this] {_objectEditor->helper_models_widget->show(); });
|
||||
}
|
||||
|
||||
void ObjectTool::registerContextMenuItems(QMenu* menu)
|
||||
{
|
||||
auto world = mapView()->getWorld();
|
||||
addMenuTitle(menu, name());
|
||||
|
||||
bool has_selected_objects = world->get_selected_model_count();
|
||||
bool has_copied_objects = _objectEditor->clipboardSize();
|
||||
|
||||
addMenuItem(menu, "Copy Object(s)", QKeySequence::Copy, has_selected_objects, [=] { _objectEditor->copy_current_selection(world); });
|
||||
addMenuItem(menu, "Paste Object(s)", QKeySequence::Paste, has_copied_objects, [=] {
|
||||
auto mv = mapView();
|
||||
NOGGIT_ACTION_MGR->beginAction(mv, Noggit::ActionFlags::eOBJECTS_ADDED);
|
||||
_objectEditor->pasteObject(mv->cursorPosition(), mv->getCamera()->position, world, &_object_paste_params);
|
||||
NOGGIT_ACTION_MGR->endAction();
|
||||
});
|
||||
|
||||
addMenuItem(menu, "Delete Object(s)", QKeySequence::Delete, has_selected_objects, [=] {
|
||||
auto mv = mapView();
|
||||
NOGGIT_ACTION_MGR->beginAction(mv, Noggit::ActionFlags::eOBJECTS_REMOVED);
|
||||
mv->DeleteSelectedObjects();
|
||||
NOGGIT_ACTION_MGR->endAction();
|
||||
});
|
||||
|
||||
addMenuItem(menu, "Duplicate Object(s)", { "CTRL+B" }, has_copied_objects, [=] {
|
||||
auto mv = mapView();
|
||||
NOGGIT_ACTION_MGR->beginAction(mv, Noggit::ActionFlags::eOBJECTS_ADDED);
|
||||
_objectEditor->copy_current_selection(world);
|
||||
_objectEditor->pasteObject(mv->cursorPosition(), mv->getCamera()->position, world, &_object_paste_params);
|
||||
NOGGIT_ACTION_MGR->endAction();
|
||||
});
|
||||
|
||||
addMenuSeperator(menu);
|
||||
|
||||
addMenuItem(menu, "Select all Like Selected", "Warning : Doing actions on models overlapping unloaded tiles can cause crash",
|
||||
world->get_selected_model_count() == 1, [=] {
|
||||
auto world = mapView()->getWorld();
|
||||
|
||||
auto last_entry = world->get_last_selected_model();
|
||||
if (last_entry)
|
||||
{
|
||||
if (!last_entry.value().index() == eEntry_Object)
|
||||
return;
|
||||
|
||||
auto obj = std::get<selected_object_type>(last_entry.value());
|
||||
auto model_name = obj->instance_model()->file_key().filepath();
|
||||
// auto models = world->get_models_by_filename()[model_name];
|
||||
|
||||
// if changing this, make sure to check for duplicate instead // if (!world->is_selected(instance))
|
||||
world->reset_selection();
|
||||
|
||||
if (obj->which() == eMODEL)
|
||||
{
|
||||
world->getModelInstanceStorage().for_each_m2_instance([&](ModelInstance& model_instance)
|
||||
{
|
||||
if (model_instance.instance_model()->file_key().filepath() == model_name)
|
||||
{
|
||||
world->add_to_selection(&model_instance);
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (obj->which() == eWMO)
|
||||
world->getModelInstanceStorage().for_each_wmo_instance([&](WMOInstance& wmo_instance)
|
||||
{
|
||||
if (wmo_instance.instance_model()->file_key().filepath() == model_name)
|
||||
{
|
||||
// objects_to_select.push_back(wmo_instance.uid);
|
||||
world->add_to_selection(&wmo_instance);
|
||||
}
|
||||
});
|
||||
|
||||
// for (auto uid_it = objects_to_select.begin(); uid_it != objects_to_select.end(); uid_it++)
|
||||
// {
|
||||
// auto instance = world->getObjectInstance(*uid_it);
|
||||
// // if (!world->is_selected(instance))
|
||||
// world->add_to_selection(instance);
|
||||
// }
|
||||
}
|
||||
});
|
||||
|
||||
addMenuItem(menu, "Hide Selected Objects", Qt::Key_H, has_selected_objects, [=] {
|
||||
if (world->has_selection())
|
||||
{
|
||||
for (auto& obj : world->get_selected_objects())
|
||||
{
|
||||
if (obj->which() == eMODEL)
|
||||
static_cast<ModelInstance*>(obj)->model->hide();
|
||||
else if (obj->which() == eWMO)
|
||||
static_cast<WMOInstance*>(obj)->wmo->hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
addMenuItem(menu, "Hide Unselected Objects (NOT IMPLEMENTED)", [] {});
|
||||
|
||||
// QAction action_2("Show Hidden", this);
|
||||
|
||||
addMenuItem(menu, "Add Object To Palette", QKeySequence::UnknownKey, world->get_selected_model_count(),
|
||||
[=] {
|
||||
auto last_entry = world->get_last_selected_model();
|
||||
if (last_entry)
|
||||
{
|
||||
if (!last_entry.value().index() == eEntry_Object)
|
||||
return;
|
||||
|
||||
_object_palette_dock->setVisible(true);
|
||||
auto obj = std::get<selected_object_type>(last_entry.value());
|
||||
auto model_name = obj->instance_model()->file_key().filepath();
|
||||
_object_palette->addObjectByFilename(model_name.c_str());
|
||||
}
|
||||
});
|
||||
|
||||
addMenuSeperator(menu);
|
||||
|
||||
// allow replacing all selected?
|
||||
addMenuItem(menu, "Replace Models (By Clipboard)", "Replace the currently selected objects by the object in the clipboard (There must only be one!). M2s can only be replaced by m2s",
|
||||
has_selected_objects && _objectEditor->clipboardSize() == 1, [=] {
|
||||
auto mv = mapView();
|
||||
|
||||
mv->makeCurrent();
|
||||
OpenGL::context::scoped_setter const _(::gl, mv->context());
|
||||
|
||||
if (mv->get_editing_mode() != editing_mode::object && NOGGIT_CUR_ACTION)
|
||||
return;
|
||||
|
||||
if (!_objectEditor->clipboardSize())
|
||||
return;
|
||||
|
||||
// verify this
|
||||
NOGGIT_ACTION_MGR->beginAction(mv, Noggit::ActionFlags::eOBJECTS_ADDED | Noggit::ActionFlags::eOBJECTS_REMOVED);
|
||||
|
||||
// get the model to replace by
|
||||
auto replace_select = _objectEditor->getClipboard().front();
|
||||
auto replacement_obj = std::get<selected_object_type>(replace_select);
|
||||
auto& replace_path = replacement_obj->instance_model()->file_key().filepath();
|
||||
|
||||
std::vector<SceneObject*> objects_to_delete;
|
||||
|
||||
// iterate selection (objects to replace)
|
||||
std::vector<selected_object_type> selected_objects = world->get_selected_objects();
|
||||
for (SceneObject* old_obj : selected_objects)
|
||||
{
|
||||
if (old_obj->instance_model()->file_key().filepath() == replace_path)
|
||||
continue;
|
||||
|
||||
math::degrees::vec3 source_rot(math::degrees(0)._, math::degrees(0)._, math::degrees(0)._);
|
||||
source_rot = old_obj->dir;
|
||||
float source_scale = old_obj->scale;
|
||||
glm::vec3 source_pos = old_obj->pos;
|
||||
|
||||
// world->deleteInstance(old_obj->uid);
|
||||
objects_to_delete.emplace_back(old_obj);
|
||||
|
||||
if (replacement_obj->which() == eWMO)
|
||||
{
|
||||
// auto replace_wmo = static_cast<WMOInstance*>(replacement_obj);
|
||||
// auto source_wmo = static_cast<WMOInstance*>(old_obj);
|
||||
|
||||
auto new_obj = world->addWMOAndGetInstance(replace_path, source_pos, source_rot, true);
|
||||
new_obj->wmo->wait_until_loaded();
|
||||
new_obj->wmo->waitForChildrenLoaded();
|
||||
new_obj->recalcExtents();
|
||||
}
|
||||
else if (replacement_obj->which() == eMODEL)
|
||||
{
|
||||
// auto replace_m2 = static_cast<ModelInstance*>(replacement_obj);
|
||||
// auto source_m2 = static_cast<ModelInstance*>(source_obj);
|
||||
|
||||
// Just swapping model
|
||||
// Issue : doesn't work with actions
|
||||
// world->updateTilesEntry(entry, model_update::remove);
|
||||
// source_m2->model = scoped_model_reference(replace_path, _context);
|
||||
// source_m2->recalcExtents();
|
||||
// world->updateTilesEntry(entry, model_update::add);
|
||||
|
||||
auto new_obj = world->addM2AndGetInstance(replace_path
|
||||
, source_pos
|
||||
, source_scale
|
||||
, source_rot
|
||||
, &_object_paste_params
|
||||
, true
|
||||
, true
|
||||
);
|
||||
new_obj->model->wait_until_loaded();
|
||||
new_obj->model->waitForChildrenLoaded();
|
||||
new_obj->recalcExtents();
|
||||
}
|
||||
}
|
||||
// this would also delete models that got skipped
|
||||
// world->delete_selected_models();
|
||||
|
||||
world->deleteObjects(objects_to_delete, true);
|
||||
world->reset_selection();
|
||||
|
||||
NOGGIT_ACTION_MGR->endAction();
|
||||
});
|
||||
|
||||
addMenuItem(menu, "Snap Selected To Ground", Qt::Key_PageDown, has_selected_objects, [=] {
|
||||
NOGGIT_ACTION_MGR->beginAction(mapView(), Noggit::ActionFlags::eOBJECTS_TRANSFORMED);
|
||||
mapView()->snap_selected_models_to_the_ground();
|
||||
NOGGIT_ACTION_MGR->endAction();
|
||||
});
|
||||
|
||||
addMenuItem(menu, "Save objects coords(to file)", QKeySequence::UnknownKey, has_selected_objects, [=] {
|
||||
if (world->has_selection() && world->get_selected_model_count())
|
||||
{
|
||||
std::stringstream obj_data;
|
||||
for (auto& obj : world->get_selected_objects())
|
||||
{
|
||||
obj_data << "\"Object : " << obj->instance_model()->file_key().filepath() << "(UID :" << obj->uid << ")\"," << std::endl;
|
||||
obj_data << "\"Scale : " << obj->scale << "\"," << std::endl;
|
||||
// coords string in ts-wow format
|
||||
obj_data << "\"Coords(server): {map:" << world->getMapID() << ",x:" << (ZEROPOINT - obj->pos.z) << ",y:" << (ZEROPOINT - obj->pos.x)
|
||||
<< ",z:" << obj->pos.y << ",o:";
|
||||
|
||||
float server_rot = 2 * glm::pi<float>() - glm::pi<float>() / 180.0 * (float(obj->dir.y) < 0 ? fabs(float(obj->dir.y)) + 180.0 : fabs(float(obj->dir.y) - 180.0));
|
||||
// float server_rot = glm::radians(obj->dir.y) + glm::radians(180.f);
|
||||
|
||||
obj_data << server_rot << "}\"," << std::endl;
|
||||
|
||||
/// converting db gobject rotation to noggit. Keep commented for later usage
|
||||
/*
|
||||
glm::quat test_db_quat = glm::quat(1.0, 1.0, 1.0, 1.0);
|
||||
test_db_quat.x = 0.607692, test_db_quat.y = -0.361538, test_db_quat.z = 0.607693, test_db_quat.w = 0.361539;
|
||||
glm::vec3 rot_euler = glm::eulerAngles(test_db_quat);
|
||||
glm::vec3 rot_degrees = glm::degrees(rot_euler);
|
||||
rot_degrees = glm::vec3(rot_degrees.y, rot_degrees.z - 180.f, rot_degrees.x); // final noggit coords
|
||||
*/
|
||||
|
||||
glm::quat rot_quat = glm::quat(glm::vec3(glm::radians(obj->dir.z), glm::radians(obj->dir.x), server_rot));
|
||||
auto normalized_quat = glm::normalize(rot_quat);
|
||||
|
||||
obj_data << "\"Rotation (server quaternion): {x:" << normalized_quat.x << ",y:" << normalized_quat.y << ",z:" << normalized_quat.z
|
||||
<< ",w:" << normalized_quat.w << "}\"," << std::endl << "\n";
|
||||
}
|
||||
|
||||
std::ofstream f("saved_objects_data.txt", std::ios_base::app);
|
||||
f << "\"Saved " << world->get_selected_model_count() << " objects at : " << QDateTime::currentDateTime().toString("dd MMMM yyyy hh:mm:ss").toStdString() << "\"" << std::endl;
|
||||
f << obj_data.str();
|
||||
f.close();
|
||||
}});
|
||||
|
||||
addMenuSeperator(menu);
|
||||
|
||||
bool groupable = false;
|
||||
if (world->has_multiple_model_selected())
|
||||
{
|
||||
// if there's no existing groups, that means it's always groupable
|
||||
if (!world->_selection_groups.size())
|
||||
groupable = true;
|
||||
|
||||
if (!groupable)
|
||||
{
|
||||
// check if there's any ungrouped object
|
||||
for (auto obj : world->get_selected_objects())
|
||||
{
|
||||
bool obj_ungrouped = true;
|
||||
for (auto& group : world->_selection_groups)
|
||||
{
|
||||
if (group.contains_object(obj))
|
||||
obj_ungrouped = false;
|
||||
}
|
||||
if (obj_ungrouped)
|
||||
{
|
||||
groupable = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO
|
||||
addMenuItem(menu, "Group Selected Objects", QKeySequence::UnknownKey, groupable, [=] {
|
||||
// remove all groups the objects are already in and create a new one
|
||||
// for (auto obj : _world->get_selected_objects())
|
||||
// {
|
||||
// for (auto& group : _world->_selection_groups)
|
||||
// {
|
||||
// if (group.contains_object(obj))
|
||||
// {
|
||||
// group.remove_group();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
for (auto& group : world->_selection_groups)
|
||||
{
|
||||
if (group.isSelected())
|
||||
{
|
||||
group.remove_group();
|
||||
}
|
||||
}
|
||||
|
||||
world->add_object_group_from_selection();
|
||||
});
|
||||
|
||||
bool group_selected = false;
|
||||
for (auto& group : world->_selection_groups)
|
||||
{
|
||||
if (group.isSelected())
|
||||
{
|
||||
group_selected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
addMenuItem(menu, "Ungroup Selected Objects", QKeySequence::UnknownKey, group_selected, [=] {
|
||||
world->clear_selection_groups();
|
||||
});
|
||||
}
|
||||
|
||||
void ObjectTool::onSelected()
|
||||
{
|
||||
_object_palette_dock->setVisible(!mapView()->isUiHidden() && mapView()->settings()->value("map_view/object_palette", false).toBool());
|
||||
}
|
||||
|
||||
void ObjectTool::onDeselected()
|
||||
{
|
||||
_objectEditor->modelImport->hide();
|
||||
_objectEditor->rotationEditor->hide();
|
||||
_object_palette->hide();
|
||||
_object_palette_dock->hide();
|
||||
_moveObject = false;
|
||||
}
|
||||
|
||||
void ObjectTool::onTick(float deltaTime, TickParameters const& params)
|
||||
{
|
||||
unsigned action_modality = 0;
|
||||
|
||||
float numpad_moveratio = 0.001f;
|
||||
|
||||
if (mapView()->getWorld()->has_selection())
|
||||
{
|
||||
auto mv = mapView();
|
||||
auto world = mv->getWorld();
|
||||
|
||||
// reset numpad_moveratio when no numpad key is pressed
|
||||
if (!(_keyx != 0 || _keyy != 0 || _keyz != 0 || _keyr != 0 || _keys != 0))
|
||||
{
|
||||
numpad_moveratio = 0.5f;
|
||||
}
|
||||
else // Set move scale and rotate for numpad keys
|
||||
{
|
||||
if (params.mod_ctrl_down && params.mod_shift_down)
|
||||
{
|
||||
numpad_moveratio += 0.5f;
|
||||
}
|
||||
else if (params.mod_shift_down)
|
||||
{
|
||||
numpad_moveratio += 0.05f;
|
||||
}
|
||||
else if (params.mod_ctrl_down)
|
||||
{
|
||||
numpad_moveratio += 0.005f;
|
||||
}
|
||||
}
|
||||
|
||||
if (_keys != 0.f)
|
||||
{
|
||||
NOGGIT_ACTION_MGR->beginAction(mv, Noggit::ActionFlags::eOBJECTS_TRANSFORMED,
|
||||
Noggit::ActionModalityControllers::eSCALE);
|
||||
world->scale_selected_models(_keys * numpad_moveratio / 50.f, World::m2_scaling_type::add);
|
||||
updateRotationEditor();
|
||||
}
|
||||
if (_keyr != 0.f)
|
||||
{
|
||||
NOGGIT_ACTION_MGR->beginAction(mv, Noggit::ActionFlags::eOBJECTS_TRANSFORMED,
|
||||
Noggit::ActionModalityControllers::eROTATE);
|
||||
world->rotate_selected_models(math::degrees(0.f)
|
||||
, math::degrees(_keyr * numpad_moveratio * 5.f)
|
||||
, math::degrees(0.f)
|
||||
, _use_median_pivot_point.get()
|
||||
);
|
||||
updateRotationEditor();
|
||||
}
|
||||
|
||||
if (_moveObject)
|
||||
{
|
||||
if (params.mod_alt_down)
|
||||
{
|
||||
NOGGIT_ACTION_MGR->beginAction(mv, Noggit::ActionFlags::eOBJECTS_TRANSFORMED,
|
||||
Noggit::ActionModalityControllers::eALT
|
||||
| Noggit::ActionModalityControllers::eMMB);
|
||||
world->scale_selected_models(std::pow(2.f, _mv * 4.f), World::m2_scaling_type::mult);
|
||||
}
|
||||
else if (params.mod_shift_down)
|
||||
{
|
||||
NOGGIT_ACTION_MGR->beginAction(mv, Noggit::ActionFlags::eOBJECTS_TRANSFORMED,
|
||||
Noggit::ActionModalityControllers::eSHIFT
|
||||
| Noggit::ActionModalityControllers::eMMB);
|
||||
world->move_selected_models(0.f, _mv * 80.f, 0.f);
|
||||
}
|
||||
else if (params.mod_ctrl_down)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
else
|
||||
{
|
||||
bool snapped = false;
|
||||
bool snapped_to_object = false;
|
||||
if (world->has_multiple_model_selected())
|
||||
{
|
||||
NOGGIT_ACTION_MGR->beginAction(mv, Noggit::ActionFlags::eOBJECTS_TRANSFORMED,
|
||||
Noggit::ActionModalityControllers::eMMB);
|
||||
world->set_selected_models_pos(mv->cursorPosition(), false);
|
||||
|
||||
if (_snap_multi_selection_to_ground.get())
|
||||
{
|
||||
mv->snap_selected_models_to_the_ground();
|
||||
snapped = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_move_model_to_cursor_position.get())
|
||||
{
|
||||
NOGGIT_ACTION_MGR->beginAction(mv, Noggit::ActionFlags::eOBJECTS_TRANSFORMED,
|
||||
Noggit::ActionModalityControllers::eMMB);
|
||||
|
||||
if ((_mh <= 0.01f && _mh >= -0.01f) && (_mv <= 0.01f && _mv >= -0.01f))
|
||||
{
|
||||
glm::vec3 _vec = (_mh * params.dirUp + _mv * params.dirRight);
|
||||
world->move_selected_models(_vec * 500.f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NOGGIT_ACTION_MGR->beginAction(mv, Noggit::ActionFlags::eOBJECTS_TRANSFORMED,
|
||||
Noggit::ActionModalityControllers::eMMB);
|
||||
|
||||
if (_move_model_to_cursor_position.get() || _move_model_snap_to_objects.get())
|
||||
{
|
||||
selection_result results(mv->intersect_result(false));
|
||||
|
||||
if (!results.empty())
|
||||
{
|
||||
for (auto result = results.begin(); result != results.end(); result++)
|
||||
{
|
||||
auto const& hit(result->second);
|
||||
bool is_selected_model = false;
|
||||
|
||||
// if a terrain is found first use that (terrain cursor pos position updated on move already)
|
||||
if (hit.index() == eEntry_MapChunk && _move_model_to_cursor_position.get())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (hit.index() == eEntry_Object && _move_model_snap_to_objects.get())
|
||||
{
|
||||
auto obj_hit = std::get<selected_object_type>(hit);
|
||||
auto obj_hit_type = obj_hit->which();
|
||||
|
||||
// don't snap to animated models
|
||||
if (obj_hit_type == eMODEL)
|
||||
{
|
||||
auto m2_model_hit = static_cast<ModelInstance*>(obj_hit);
|
||||
if (m2_model_hit->model->animated_mesh())
|
||||
continue;
|
||||
}
|
||||
|
||||
// find and ignore current object/selected models or it will keep snaping to itself
|
||||
for (auto& entry : world->current_selection())
|
||||
{
|
||||
auto type = entry.index();
|
||||
if (type == eEntry_Object)
|
||||
{
|
||||
auto& selection_obj = std::get<selected_object_type>(entry);
|
||||
if (selection_obj->uid == obj_hit->uid)
|
||||
{
|
||||
is_selected_model = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (is_selected_model)
|
||||
continue;
|
||||
auto hit_pos = mv->intersect_ray().position(result->first);
|
||||
mv->cursorPosition(hit_pos);
|
||||
snapped_to_object = true;
|
||||
// TODO : rotate objects to objects normal
|
||||
// if (_rotate_doodads_along_doodads.get())
|
||||
// world->rotate_selected_models_to_object_normal(_rotate_along_ground_smooth.get(), obj_hit, hit_pos, glm::transpose(model_view()), _rotate_doodads_along_wmos.get());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
world->set_selected_models_pos(mv->cursorPosition(), false);
|
||||
snapped = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (snapped && _rotate_along_ground.get())
|
||||
{
|
||||
if (!snapped_to_object)
|
||||
world->rotate_selected_models_to_ground_normal(_rotate_along_ground_smooth.get());
|
||||
|
||||
if (_rotate_along_ground_random.get())
|
||||
{
|
||||
float minX = 0, maxX = 0, minY = 0, maxY = 0, minZ = 0, maxZ = 0;
|
||||
|
||||
if (mv->settings()->value("model/random_rotation", false).toBool())
|
||||
{
|
||||
minY = _object_paste_params.minRotation;
|
||||
maxY = _object_paste_params.maxRotation;
|
||||
}
|
||||
|
||||
if (mv->settings()->value("model/random_tilt", false).toBool())
|
||||
{
|
||||
minX = _object_paste_params.minTilt;
|
||||
maxX = _object_paste_params.maxTilt;
|
||||
minZ = minX;
|
||||
maxZ = maxX;
|
||||
}
|
||||
|
||||
world->rotate_selected_models_randomly(
|
||||
minX,
|
||||
maxX,
|
||||
minY,
|
||||
maxY,
|
||||
minZ,
|
||||
maxZ);
|
||||
|
||||
if (mv->settings()->value("model/random_size", false).toBool())
|
||||
{
|
||||
float min = _object_paste_params.minScale;
|
||||
float max = _object_paste_params.maxScale;
|
||||
|
||||
world->scale_selected_models(misc::randfloat(min, max), World::m2_scaling_type::set);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateRotationEditor();
|
||||
}
|
||||
|
||||
/* TODO: Numpad for action system
|
||||
if (_keyx != 0.f || _keyy != 0.f || _keyz != 0.f)
|
||||
{
|
||||
world->move_selected_models(_keyx * numpad_moveratio, _keyy * numpad_moveratio, _keyz * numpad_moveratio);
|
||||
updateRotationEditor();
|
||||
}
|
||||
*/
|
||||
|
||||
if (mv->isRotatingCamera())
|
||||
{
|
||||
if (params.mod_ctrl_down) // X
|
||||
{
|
||||
NOGGIT_ACTION_MGR->beginAction(mv, Noggit::ActionFlags::eOBJECTS_TRANSFORMED,
|
||||
Noggit::ActionModalityControllers::eCTRL
|
||||
| Noggit::ActionModalityControllers::eRMB);
|
||||
world->rotate_selected_models(math::degrees(_rh + _rv)
|
||||
, math::degrees(0.f)
|
||||
, math::degrees(0.f)
|
||||
, _use_median_pivot_point.get()
|
||||
);
|
||||
}
|
||||
if (params.mod_shift_down) // Y
|
||||
{
|
||||
NOGGIT_ACTION_MGR->beginAction(mv, Noggit::ActionFlags::eOBJECTS_TRANSFORMED,
|
||||
Noggit::ActionModalityControllers::eSHIFT
|
||||
| Noggit::ActionModalityControllers::eRMB);
|
||||
world->rotate_selected_models(math::degrees(0.f)
|
||||
, math::degrees(_rh + _rv)
|
||||
, math::degrees(0.f)
|
||||
, _use_median_pivot_point.get()
|
||||
);
|
||||
}
|
||||
if (params.mod_alt_down) // Z
|
||||
{
|
||||
NOGGIT_ACTION_MGR->beginAction(mv, Noggit::ActionFlags::eOBJECTS_TRANSFORMED,
|
||||
Noggit::ActionModalityControllers::eALT
|
||||
| Noggit::ActionModalityControllers::eRMB);
|
||||
world->rotate_selected_models(math::degrees(0.f)
|
||||
, math::degrees(0.f)
|
||||
, math::degrees(_rh + _rv)
|
||||
, _use_median_pivot_point.get()
|
||||
);
|
||||
}
|
||||
|
||||
updateRotationEditor();
|
||||
}
|
||||
}
|
||||
|
||||
_mh = 0;
|
||||
_mv = 0;
|
||||
_rh = 0;
|
||||
_rv = 0;
|
||||
}
|
||||
|
||||
void ObjectTool::onMousePress(MousePressParameters const& params)
|
||||
{
|
||||
if (params.button == Qt::MouseButton::LeftButton && !params.mod_ctrl_down)
|
||||
{
|
||||
_area_selection->setGeometry(QRect(_drag_start_pos, QSize()));
|
||||
_area_selection->show();
|
||||
_drag_start_pos = params.mouse_position;
|
||||
mapView()->invalidate();
|
||||
}
|
||||
|
||||
if (params.button == Qt::MouseButton::MiddleButton)
|
||||
{
|
||||
_moveObject = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectTool::onMouseRelease(MouseReleaseParameters const& params)
|
||||
{
|
||||
if (params.button == Qt::MouseButton::MiddleButton)
|
||||
{
|
||||
_moveObject = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (params.button != Qt::MouseButton::LeftButton || params.mod_ctrl_down)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto drag_end_pos = params.mouse_position;
|
||||
|
||||
if (_drag_start_pos != drag_end_pos && !ImGuizmo::IsUsing())
|
||||
{
|
||||
const std::array<glm::vec2, 2> selection_box
|
||||
{
|
||||
glm::vec2(std::min(_drag_start_pos.x(), drag_end_pos.x()), std::min(_drag_start_pos.y(), drag_end_pos.y())),
|
||||
glm::vec2(std::max(_drag_start_pos.x(), drag_end_pos.x()), std::max(_drag_start_pos.y(), drag_end_pos.y()))
|
||||
};
|
||||
// _world->select_objects_in_area(selection_box, !_mod_shift_down, model_view(), projection(), width(), height(), objectEditor->drag_selection_depth(), _camera.position);
|
||||
mapView()->selectObjects(selection_box, 3000.0f);
|
||||
}
|
||||
else // Do normal selection when we just clicked
|
||||
{
|
||||
mapView()->doSelection(false);
|
||||
}
|
||||
|
||||
_area_selection->hide();
|
||||
}
|
||||
|
||||
void ObjectTool::onMouseMove(MouseMoveParameters const& params)
|
||||
{
|
||||
auto mapView = this->mapView();
|
||||
if (_moveObject)
|
||||
{
|
||||
_mh = -mapView->aspect_ratio() * params.relative_movement.dx() / static_cast<float>(mapView->width());
|
||||
_mv = -params.relative_movement.dy() / static_cast<float>(mapView->height());
|
||||
}
|
||||
else
|
||||
{
|
||||
_mh = 0.0f;
|
||||
_mv = 0.0f;
|
||||
}
|
||||
|
||||
if (params.mod_shift_down || params.mod_ctrl_down || params.mod_alt_down || params.mod_space_down)
|
||||
{
|
||||
_rh = params.relative_movement.dx() / XSENS * 5.0f;
|
||||
_rv = params.relative_movement.dy() / YSENS * 5.0f;
|
||||
}
|
||||
|
||||
if (params.left_mouse)
|
||||
{
|
||||
if (params.mod_alt_down && !params.mod_shift_down && !params.mod_ctrl_down)
|
||||
{
|
||||
_objectEditor->changeRadius(params.relative_movement.dx() / XSENS);
|
||||
}
|
||||
|
||||
if (!params.mod_alt_down && params.displayMode == display_mode::in_3D && !ImGuizmo::IsUsing())
|
||||
{
|
||||
_area_selection->setGeometry(QRect(_drag_start_pos, params.mouse_position).normalized());
|
||||
mapView->invalidate();
|
||||
}
|
||||
|
||||
if (params.mod_shift_down || params.mod_ctrl_down)
|
||||
{
|
||||
mapView->doSelection(false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectTool::hidePopups()
|
||||
{
|
||||
_objectEditor->modelImport->hide();
|
||||
_objectEditor->rotationEditor->hide();
|
||||
_objectEditor->helper_models_widget->hide();
|
||||
_object_palette_dock->hide();
|
||||
}
|
||||
|
||||
void ObjectTool::onFocusLost()
|
||||
{
|
||||
_keyx = 0;
|
||||
_keyz = 0;
|
||||
_keyy = 0;
|
||||
_keyr = 0;
|
||||
_keys = 0;
|
||||
_moveObject = false;
|
||||
}
|
||||
|
||||
void ObjectTool::setupHotkeys()
|
||||
{
|
||||
auto mapView = this->mapView();
|
||||
|
||||
addHotkey("copySelection"_hash, Hotkey{
|
||||
.onPress = [=] { _objectEditor->copy_current_selection(mapView->getWorld()); },
|
||||
.condition = [=] { return mapView->get_editing_mode() == editing_mode::object && !NOGGIT_CUR_ACTION; },
|
||||
});
|
||||
|
||||
addHotkey("paste"_hash, Hotkey{
|
||||
.onPress = [=] {
|
||||
NOGGIT_ACTION_MGR->beginAction(mapView, Noggit::ActionFlags::eOBJECTS_ADDED);
|
||||
_objectEditor->pasteObject(mapView->cursorPosition(), mapView->getCamera()->position, mapView->getWorld(), &_object_paste_params);
|
||||
NOGGIT_ACTION_MGR->endAction();
|
||||
},
|
||||
.condition = [=] { return mapView->get_editing_mode() == editing_mode::object && !NOGGIT_CUR_ACTION; },
|
||||
});
|
||||
|
||||
addHotkey("importM2FromWmv"_hash, Hotkey{
|
||||
.onPress = [=] { _objectEditor->import_last_model_from_wmv(eMODEL); },
|
||||
.condition = [=] { return mapView->get_editing_mode() == editing_mode::object && !NOGGIT_CUR_ACTION; },
|
||||
});
|
||||
|
||||
addHotkey("importWmoFromWmv"_hash, Hotkey{
|
||||
.onPress = [=] { _objectEditor->import_last_model_from_wmv(eWMO); },
|
||||
.condition = [=] { return mapView->get_editing_mode() == editing_mode::object && !NOGGIT_CUR_ACTION; },
|
||||
});
|
||||
|
||||
addHotkey("duplacteSelection"_hash, Hotkey{
|
||||
.onPress = [=] {
|
||||
NOGGIT_ACTION_MGR->beginAction(mapView, Noggit::ActionFlags::eOBJECTS_ADDED);
|
||||
_objectEditor->copy_current_selection(mapView->getWorld());
|
||||
_objectEditor->pasteObject(mapView->cursorPosition(), mapView->getCamera()->position, mapView->getWorld(), &_object_paste_params);
|
||||
NOGGIT_ACTION_MGR->endAction();
|
||||
},
|
||||
.condition = [=] { return mapView->get_editing_mode() == editing_mode::object && !NOGGIT_CUR_ACTION; },
|
||||
});
|
||||
|
||||
addHotkey("togglePasteMode"_hash, Hotkey{
|
||||
.onPress = [=] { _objectEditor->togglePasteMode(); },
|
||||
.condition = [=] { return mapView->get_editing_mode() == editing_mode::object; },
|
||||
});
|
||||
|
||||
addHotkey("moveSelectedDown"_hash, Hotkey{
|
||||
.onPress = [=] { _keyx = 1; },
|
||||
.onRelease = [=] { _keyx = 0; },
|
||||
.condition = [=] { return mapView->get_editing_mode() == editing_mode::object; },
|
||||
});
|
||||
|
||||
addHotkey("moveSelectedUp"_hash, Hotkey{
|
||||
.onPress = [=] { _keyx = -1; },
|
||||
.onRelease = [=] { _keyx = 0; },
|
||||
.condition = [=] { return mapView->get_editing_mode() == editing_mode::object; },
|
||||
});
|
||||
|
||||
addHotkey("moveSelectedLeft"_hash, Hotkey{
|
||||
.onPress = [=] { _keyz = 1; },
|
||||
.onRelease = [=] { _keyz = 0; },
|
||||
.condition = [=] { return mapView->get_editing_mode() == editing_mode::object; },
|
||||
});
|
||||
|
||||
addHotkey("moveSelectedRight"_hash, Hotkey{
|
||||
.onPress = [=] { _keyz = -1; },
|
||||
.onRelease = [=] { _keyz = 0; },
|
||||
.condition = [=] { return mapView->get_editing_mode() == editing_mode::object; },
|
||||
});
|
||||
|
||||
addHotkey("rotateSelectedPitchCcw"_hash, Hotkey{
|
||||
.onPress = [=] { _keyy = 1; },
|
||||
.onRelease = [=] { _keyy = 0; },
|
||||
.condition = [=] { return mapView->get_editing_mode() == editing_mode::object; },
|
||||
});
|
||||
|
||||
addHotkey("rotateSelectedPitchCw"_hash, Hotkey{
|
||||
.onPress = [=] { _keyy = -1; },
|
||||
.onRelease = [=] { _keyy = 0; },
|
||||
.condition = [=] { return mapView->get_editing_mode() == editing_mode::object; },
|
||||
});
|
||||
|
||||
addHotkey("rotateSelectedYawCcw"_hash, Hotkey{
|
||||
.onPress = [=] { _keyr = 1; },
|
||||
.onRelease = [=] {_keyr = 0; },
|
||||
.condition = [=] { return mapView->get_editing_mode() == editing_mode::object; },
|
||||
});
|
||||
|
||||
addHotkey("rotateSelectedYawCw"_hash, Hotkey{
|
||||
.onPress = [=] {_keyr = -1; },
|
||||
.onRelease = [=] {_keyr = 0; },
|
||||
.condition = [=] { return mapView->get_editing_mode() == editing_mode::object; },
|
||||
});
|
||||
|
||||
addHotkey("increaseSelectedScale"_hash, Hotkey{
|
||||
.onPress = [=] { _keys = 1; },
|
||||
.onRelease = [=] { _keys = 0; },
|
||||
.condition = [=] { return mapView->get_editing_mode() == editing_mode::object; },
|
||||
});
|
||||
|
||||
addHotkey("decreaseSelectedScale"_hash, Hotkey{
|
||||
.onPress = [=] { _keys = -1; },
|
||||
.onRelease = [=] { _keys = 0; },
|
||||
.condition = [=] { return mapView->get_editing_mode() == editing_mode::object; },
|
||||
});
|
||||
}
|
||||
|
||||
void ObjectTool::updateRotationEditor()
|
||||
{
|
||||
_objectEditor->rotationEditor->updateValues(mapView()->getWorld());
|
||||
}
|
||||
}
|
||||
93
src/noggit/tools/ObjectTool.hpp
Normal file
93
src/noggit/tools/ObjectTool.hpp
Normal file
@@ -0,0 +1,93 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <noggit/Tool.hpp>
|
||||
#include <noggit/object_paste_params.hpp>
|
||||
#include <noggit/BoolToggleProperty.hpp>
|
||||
|
||||
class QRubberBand;
|
||||
class QDockWidget;
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
namespace Ui
|
||||
{
|
||||
class object_editor;
|
||||
class ObjectPalette;
|
||||
}
|
||||
|
||||
class ObjectTool final : public Tool
|
||||
{
|
||||
public:
|
||||
ObjectTool(MapView* mapView);
|
||||
~ObjectTool();
|
||||
|
||||
[[nodiscard]]
|
||||
unsigned int actionModality() const override;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual char const* name() const override;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual editing_mode editingMode() const override;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual Ui::FontNoggit::Icons icon() const override;
|
||||
|
||||
void setupUi(Ui::Tools::ToolPanel* toolPanel) override;
|
||||
|
||||
[[nodiscard]]
|
||||
ToolDrawParameters drawParameters() const override;
|
||||
|
||||
[[nodiscard]]
|
||||
float brushRadius() const override;
|
||||
|
||||
[[nodiscard]]
|
||||
bool useMultiselectionPivot() const override;
|
||||
|
||||
[[nodiscard]]
|
||||
bool useMedianPivotPoint() const override;
|
||||
|
||||
void registerMenuItems(QMenu* menu) override;
|
||||
|
||||
void registerContextMenuItems(QMenu* menu) override;
|
||||
|
||||
void onSelected() override;
|
||||
|
||||
void onDeselected() override;
|
||||
|
||||
void onTick(float deltaTime, TickParameters const& params) override;
|
||||
|
||||
void onMousePress(MousePressParameters const& params) override;
|
||||
|
||||
void onMouseRelease(MouseReleaseParameters const& params) override;
|
||||
|
||||
void onMouseMove(MouseMoveParameters const& params) override;
|
||||
|
||||
void hidePopups() override;
|
||||
|
||||
void onFocusLost() override;
|
||||
|
||||
private:
|
||||
Ui::object_editor* _objectEditor = nullptr;
|
||||
QRubberBand* _area_selection = nullptr;
|
||||
Ui::ObjectPalette* _object_palette = nullptr;
|
||||
QDockWidget* _object_palette_dock = nullptr;
|
||||
object_paste_params _object_paste_params;
|
||||
BoolToggleProperty _move_model_to_cursor_position = { true };
|
||||
BoolToggleProperty _snap_multi_selection_to_ground = { false };
|
||||
BoolToggleProperty _use_median_pivot_point = { true };
|
||||
BoolToggleProperty _rotate_along_ground = { true };
|
||||
BoolToggleProperty _rotate_along_ground_smooth = { true };
|
||||
BoolToggleProperty _rotate_along_ground_random = { false };
|
||||
BoolToggleProperty _move_model_snap_to_objects = { true };
|
||||
QPoint _drag_start_pos;
|
||||
float _keyx = 0, _keyy = 0, _keyz = 0, _keyr = 0, _keys = 0;
|
||||
float _mh = 0, _mv = 0, _rh = 0, _rv = 0; // mh = left click x, rv = right click y
|
||||
bool _moveObject = false;
|
||||
|
||||
void setupHotkeys();
|
||||
void updateRotationEditor();
|
||||
};
|
||||
}
|
||||
254
src/noggit/tools/RaiseLowerTool.cpp
Normal file
254
src/noggit/tools/RaiseLowerTool.cpp
Normal file
@@ -0,0 +1,254 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#include "RaiseLowerTool.hpp"
|
||||
|
||||
#include <noggit/ActionManager.hpp>
|
||||
#include <noggit/Input.hpp>
|
||||
#include <noggit/MapView.h>
|
||||
#include <noggit/ui/TerrainTool.hpp>
|
||||
#include <noggit/ui/tools/ToolPanel/ToolPanel.hpp>
|
||||
|
||||
#include <random>
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
RaiseLowerTool::RaiseLowerTool(MapView* mapView)
|
||||
: Tool{ mapView }
|
||||
{
|
||||
addHotkey("nextType"_hash, Hotkey{
|
||||
.onPress = [this] { _terrainTool->nextType(); },
|
||||
.condition = [mapView] { return mapView->get_editing_mode() == editing_mode::ground && !NOGGIT_CUR_ACTION; },
|
||||
});
|
||||
|
||||
addHotkey("flatten"_hash, Hotkey{
|
||||
.onPress = [this] {
|
||||
NOGGIT_ACTION_MGR->beginAction(this->mapView(), Noggit::ActionFlags::eCHUNKS_TERRAIN);
|
||||
_terrainTool->flattenVertices(this->mapView()->getWorld());
|
||||
NOGGIT_ACTION_MGR->endAction();
|
||||
},
|
||||
.condition = [mapView] { return mapView->get_editing_mode() == editing_mode::ground && !NOGGIT_CUR_ACTION; },
|
||||
});
|
||||
|
||||
addHotkey("increaseRadius"_hash, Hotkey{
|
||||
.onPress = [this] { _terrainTool->changeRadius(0.01f); },
|
||||
.condition = [mapView] { return mapView->get_editing_mode() == editing_mode::ground && !NOGGIT_CUR_ACTION; },
|
||||
});
|
||||
|
||||
addHotkey("decreaseRadius"_hash, Hotkey{
|
||||
.onPress = [this] { _terrainTool->changeRadius(-0.01f); },
|
||||
.condition = [mapView] { return mapView->get_editing_mode() == editing_mode::ground && !NOGGIT_CUR_ACTION; },
|
||||
});
|
||||
|
||||
addHotkey("clearVertexSelection"_hash, Hotkey{
|
||||
.onPress = [=] {
|
||||
NOGGIT_ACTION_MGR->beginAction(mapView, Noggit::ActionFlags::eVERTEX_SELECTION);
|
||||
mapView->getWorld()->clearVertexSelection();
|
||||
NOGGIT_ACTION_MGR->endAction();
|
||||
},
|
||||
.condition = [mapView] { return mapView->get_editing_mode() == editing_mode::ground && !NOGGIT_CUR_ACTION; },
|
||||
});
|
||||
}
|
||||
|
||||
RaiseLowerTool::~RaiseLowerTool()
|
||||
{
|
||||
delete _terrainTool;
|
||||
}
|
||||
|
||||
char const* RaiseLowerTool::name() const
|
||||
{
|
||||
return "Raise / Lower";
|
||||
}
|
||||
|
||||
editing_mode RaiseLowerTool::editingMode() const
|
||||
{
|
||||
return editing_mode::ground;
|
||||
}
|
||||
|
||||
Ui::FontNoggit::Icons RaiseLowerTool::icon() const
|
||||
{
|
||||
return Ui::FontNoggit::TOOL_RAISE_LOWER;
|
||||
}
|
||||
|
||||
void RaiseLowerTool::setupUi(Ui::Tools::ToolPanel* toolPanel)
|
||||
{
|
||||
_terrainTool = new Noggit::Ui::TerrainTool{ mapView(), mapView() };
|
||||
toolPanel->registerTool(name(), _terrainTool);
|
||||
|
||||
QObject::connect(_terrainTool
|
||||
, &Noggit::Ui::TerrainTool::updateVertices
|
||||
, [mapView = mapView()](int vertex_mode, math::degrees const& angle, math::degrees const& orientation)
|
||||
{
|
||||
mapView->makeCurrent();
|
||||
OpenGL::context::scoped_setter const _(::gl, mapView->context());
|
||||
|
||||
mapView->getWorld()->orientVertices(vertex_mode == eVertexMode_Mouse
|
||||
? mapView->cursorPosition()
|
||||
: mapView->getWorld()->vertexCenter()
|
||||
, angle
|
||||
, orientation
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
ToolDrawParameters RaiseLowerTool::drawParameters() const
|
||||
{
|
||||
CursorType cursorType = CursorType::CIRCLE;
|
||||
if ((_terrainTool->_edit_type != eTerrainType_Vertex && _terrainTool->_edit_type != eTerrainType_Script) && _terrainTool->getImageMaskSelector()->isEnabled())
|
||||
cursorType = CursorType::STAMP;
|
||||
|
||||
return ToolDrawParameters
|
||||
{
|
||||
.radius = _terrainTool->brushRadius(),
|
||||
.inner_radius = _terrainTool->innerRadius(),
|
||||
.cursor_type = cursorType,
|
||||
.terrain_type = _terrainTool->_edit_type,
|
||||
};
|
||||
}
|
||||
|
||||
void RaiseLowerTool::onSelected()
|
||||
{
|
||||
if (_terrainTool->_edit_type != eTerrainType_Vertex
|
||||
|| (_terrainTool->_edit_type != eTerrainType_Script && _terrainTool->getImageMaskSelector()->isEnabled()))
|
||||
{
|
||||
_terrainTool->updateMaskImage();
|
||||
}
|
||||
}
|
||||
|
||||
void RaiseLowerTool::onTick(float deltaTime, TickParameters const& params)
|
||||
{
|
||||
if (!params.left_mouse)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (params.displayMode == display_mode::in_3D && !params.underMap)
|
||||
{
|
||||
auto mask_selector = _terrainTool->getImageMaskSelector();
|
||||
auto mv = mapView();
|
||||
|
||||
if (params.mod_shift_down && (!mask_selector->isEnabled() || mask_selector->getBrushMode()))
|
||||
{
|
||||
auto action = NOGGIT_ACTION_MGR->beginAction(mv, Noggit::ActionFlags::eCHUNKS_TERRAIN,
|
||||
Noggit::ActionModalityControllers::eSHIFT
|
||||
| Noggit::ActionModalityControllers::eLMB);
|
||||
|
||||
action->setPostCallback([this] { randomizeTerrainRotation(); });
|
||||
|
||||
_terrainTool->changeTerrain(mv->getWorld(), mv->cursorPosition(), 7.5f * deltaTime);
|
||||
}
|
||||
else if (params.mod_ctrl_down && (!mask_selector->isEnabled() || mask_selector->getBrushMode()))
|
||||
{
|
||||
auto action = NOGGIT_ACTION_MGR->beginAction(mv, Noggit::ActionFlags::eCHUNKS_TERRAIN,
|
||||
Noggit::ActionModalityControllers::eCTRL
|
||||
| Noggit::ActionModalityControllers::eLMB);
|
||||
|
||||
action->setPostCallback([this] { randomizeTerrainRotation(); });
|
||||
|
||||
_terrainTool->changeTerrain(mv->getWorld(), mv->cursorPosition(), -7.5f * deltaTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RaiseLowerTool::onMouseMove(MouseMoveParameters const& params)
|
||||
{
|
||||
if (params.right_mouse)
|
||||
{
|
||||
if (params.mod_alt_down && !params.mod_shift_down && !params.mod_ctrl_down)
|
||||
{
|
||||
if (_terrainTool->_edit_type == eTerrainType_Vertex)
|
||||
{
|
||||
NOGGIT_ACTION_MGR->beginAction(mapView(), Noggit::ActionFlags::eCHUNKS_TERRAIN,
|
||||
Noggit::ActionModalityControllers::eALT | Noggit::ActionModalityControllers::eRMB);
|
||||
_terrainTool->changeOrientation(-params.relative_movement.dx() / XSENS * 4.5f);
|
||||
}
|
||||
else
|
||||
{
|
||||
_terrainTool->changeInnerRadius(params.relative_movement.dx() / 100.0f);
|
||||
}
|
||||
}
|
||||
|
||||
if (!params.mod_alt_down && params.mod_shift_down && !params.mod_ctrl_down)
|
||||
{
|
||||
if (_terrainTool->_edit_type == eTerrainType_Vertex)
|
||||
{
|
||||
NOGGIT_ACTION_MGR->beginAction(mapView(), Noggit::ActionFlags::eCHUNKS_TERRAIN,
|
||||
Noggit::ActionModalityControllers::eSHIFT | Noggit::ActionModalityControllers::eRMB);
|
||||
_terrainTool->moveVertices(mapView()->getWorld(), -params.relative_movement.dy() / YSENS);
|
||||
}
|
||||
}
|
||||
|
||||
if (!params.mod_alt_down && !params.mod_shift_down && params.mod_ctrl_down)
|
||||
{
|
||||
if (_terrainTool->_edit_type == eTerrainType_Vertex)
|
||||
{
|
||||
NOGGIT_ACTION_MGR->beginAction(mapView(), Noggit::ActionFlags::eCHUNKS_TERRAIN,
|
||||
Noggit::ActionModalityControllers::eCTRL |
|
||||
Noggit::ActionModalityControllers::eRMB);
|
||||
_terrainTool->changeAngle(-params.relative_movement.dy() / YSENS * 4.f);
|
||||
}
|
||||
}
|
||||
|
||||
if (params.mod_space_down)
|
||||
{
|
||||
if (_terrainTool->_edit_type == eTerrainType_Vertex)
|
||||
{
|
||||
NOGGIT_ACTION_MGR->beginAction(mapView(), Noggit::ActionFlags::eCHUNKS_TERRAIN,
|
||||
Noggit::ActionModalityControllers::eRMB
|
||||
| Noggit::ActionModalityControllers::eSPACE);
|
||||
_terrainTool->setOrientRelativeTo(mapView()->getWorld(), mapView()->cursorPosition());
|
||||
}
|
||||
else if (_terrainTool->getImageMaskSelector()->isEnabled())
|
||||
{
|
||||
auto action = NOGGIT_ACTION_MGR->beginAction(mapView(), Noggit::ActionFlags::eDO_NOT_WRITE_HISTORY,
|
||||
Noggit::ActionModalityControllers::eRMB
|
||||
| Noggit::ActionModalityControllers::eSPACE);
|
||||
_terrainTool->getImageMaskSelector()->setRotation(-params.relative_movement.dx() / XSENS * 10.f);
|
||||
action->setBlockCursor(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (params.left_mouse)
|
||||
{
|
||||
if (params.mod_alt_down && !params.mod_shift_down && !params.mod_ctrl_down)
|
||||
{
|
||||
_terrainTool->changeRadius(params.relative_movement.dx() / XSENS);
|
||||
}
|
||||
|
||||
if (params.mod_space_down)
|
||||
{
|
||||
_terrainTool->changeSpeed(params.relative_movement.dx() / 30.0f);
|
||||
}
|
||||
|
||||
if (params.mod_shift_down && params.displayMode == display_mode::in_3D)
|
||||
{
|
||||
auto image_mask_selector = _terrainTool->getImageMaskSelector();
|
||||
if (_terrainTool->_edit_type != eTerrainType_Vertex && _terrainTool->_edit_type != eTerrainType_Script &&
|
||||
image_mask_selector->isEnabled() && !image_mask_selector->getBrushMode())
|
||||
{
|
||||
auto action = NOGGIT_ACTION_MGR->beginAction(mapView(), Noggit::ActionFlags::eCHUNKS_TERRAIN,
|
||||
Noggit::ActionModalityControllers::eSHIFT
|
||||
| Noggit::ActionModalityControllers::eLMB);
|
||||
|
||||
action->setPostCallback([this] { randomizeTerrainRotation(); });
|
||||
|
||||
_terrainTool->changeTerrain(mapView()->getWorld(), mapView()->cursorPosition(), params.relative_movement.dx() / 30.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RaiseLowerTool::randomizeTerrainRotation()
|
||||
{
|
||||
auto image_mask_selector = _terrainTool->getImageMaskSelector();
|
||||
if (!image_mask_selector->getRandomizeRotation())
|
||||
return;
|
||||
|
||||
unsigned int ms = static_cast<unsigned>(QDateTime::currentMSecsSinceEpoch());
|
||||
std::mt19937 gen(ms);
|
||||
std::uniform_int_distribution<> uid(0, 360);
|
||||
|
||||
image_mask_selector->setRotation(uid(gen));
|
||||
}
|
||||
}
|
||||
45
src/noggit/tools/RaiseLowerTool.hpp
Normal file
45
src/noggit/tools/RaiseLowerTool.hpp
Normal file
@@ -0,0 +1,45 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <noggit/Tool.hpp>
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
namespace Ui
|
||||
{
|
||||
class TerrainTool;
|
||||
}
|
||||
|
||||
class RaiseLowerTool final : public Tool
|
||||
{
|
||||
public:
|
||||
RaiseLowerTool(MapView* mapView);
|
||||
~RaiseLowerTool();
|
||||
|
||||
[[nodiscard]]
|
||||
virtual char const* name() const override;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual editing_mode editingMode() const override;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual Ui::FontNoggit::Icons icon() const override;
|
||||
|
||||
void setupUi(Ui::Tools::ToolPanel* toolPanel) override;
|
||||
|
||||
[[nodiscard]]
|
||||
ToolDrawParameters drawParameters() const override;
|
||||
|
||||
void onSelected() override;
|
||||
|
||||
void onTick(float deltaTime, TickParameters const& params) override;
|
||||
|
||||
void onMouseMove(MouseMoveParameters const& params) override;
|
||||
|
||||
private:
|
||||
Ui::TerrainTool* _terrainTool = nullptr;
|
||||
|
||||
void randomizeTerrainRotation();
|
||||
};
|
||||
}
|
||||
70
src/noggit/tools/ScriptingTool.cpp
Normal file
70
src/noggit/tools/ScriptingTool.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#include "ScriptingTool.hpp"
|
||||
|
||||
#include <noggit/ActionManager.hpp>
|
||||
#include <noggit/MapView.h>
|
||||
#include <noggit/Input.hpp>
|
||||
#include <noggit/scripting/scripting_tool.hpp>
|
||||
#include <noggit/scripting/script_settings.hpp>
|
||||
#include <noggit/ui/tools/ToolPanel/ToolPanel.hpp>
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
ScriptingTool::ScriptingTool(MapView* mapView)
|
||||
: Tool{ mapView }
|
||||
{
|
||||
}
|
||||
|
||||
ScriptingTool::~ScriptingTool()
|
||||
{
|
||||
delete _scriptingTool;
|
||||
}
|
||||
|
||||
char const* ScriptingTool::name() const
|
||||
{
|
||||
return "Scripting";
|
||||
}
|
||||
|
||||
editing_mode ScriptingTool::editingMode() const
|
||||
{
|
||||
return editing_mode::scripting;
|
||||
}
|
||||
|
||||
Ui::FontNoggit::Icons ScriptingTool::icon() const
|
||||
{
|
||||
return Ui::FontNoggit::INFO;
|
||||
}
|
||||
|
||||
void ScriptingTool::setupUi(Ui::Tools::ToolPanel* toolPanel)
|
||||
{
|
||||
_scriptingTool = new Noggit::Scripting::scripting_tool(mapView(), mapView(), mapView()->settings());
|
||||
toolPanel->registerTool(name(), _scriptingTool);
|
||||
}
|
||||
|
||||
ToolDrawParameters ScriptingTool::drawParameters() const
|
||||
{
|
||||
return
|
||||
{
|
||||
.radius = _scriptingTool->get_settings()->brushRadius(),
|
||||
.inner_radius = _scriptingTool->get_settings()->innerRadius(),
|
||||
};
|
||||
}
|
||||
|
||||
void ScriptingTool::onTick(float deltaTime, TickParameters const& params)
|
||||
{
|
||||
auto world = mapView()->getWorld();
|
||||
|
||||
auto currentSelection = world->current_selection();
|
||||
if (world->has_selection())
|
||||
{
|
||||
for (auto& selection : currentSelection)
|
||||
{
|
||||
if (selection.index() == eEntry_MapChunk)
|
||||
{
|
||||
_scriptingTool->sendBrushEvent(mapView()->cursorPosition(), 7.5f * deltaTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
39
src/noggit/tools/ScriptingTool.hpp
Normal file
39
src/noggit/tools/ScriptingTool.hpp
Normal file
@@ -0,0 +1,39 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <noggit/Tool.hpp>
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
namespace Scripting
|
||||
{
|
||||
class scripting_tool;
|
||||
}
|
||||
|
||||
class ScriptingTool final : public Tool
|
||||
{
|
||||
public:
|
||||
ScriptingTool(MapView* mapView);
|
||||
~ScriptingTool();
|
||||
|
||||
[[nodiscard]]
|
||||
virtual char const* name() const override;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual editing_mode editingMode() const override;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual Ui::FontNoggit::Icons icon() const override;
|
||||
|
||||
void setupUi(Ui::Tools::ToolPanel* toolPanel) override;
|
||||
|
||||
[[nodiscard]]
|
||||
ToolDrawParameters drawParameters() const override;
|
||||
|
||||
void onTick(float deltaTime, TickParameters const& params) override;
|
||||
|
||||
private:
|
||||
Scripting::scripting_tool* _scriptingTool = nullptr;
|
||||
};
|
||||
}
|
||||
177
src/noggit/tools/StampTool.cpp
Normal file
177
src/noggit/tools/StampTool.cpp
Normal file
@@ -0,0 +1,177 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#include "StampTool.hpp"
|
||||
|
||||
#include <noggit/ActionManager.hpp>
|
||||
#include <noggit/MapView.h>
|
||||
#include <noggit/Input.hpp>
|
||||
#include <noggit/ui/tools/BrushStack/BrushStack.hpp>
|
||||
#include <noggit/ui/tools/ToolPanel/ToolPanel.hpp>
|
||||
|
||||
#include <random>
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
StampTool::StampTool(MapView* mapView)
|
||||
: Tool{ mapView }
|
||||
{
|
||||
}
|
||||
|
||||
StampTool::~StampTool()
|
||||
{
|
||||
delete _stampTool;
|
||||
}
|
||||
|
||||
char const* StampTool::name() const
|
||||
{
|
||||
return "Stamp Mode";
|
||||
}
|
||||
|
||||
editing_mode StampTool::editingMode() const
|
||||
{
|
||||
return editing_mode::stamp;
|
||||
}
|
||||
|
||||
Ui::FontNoggit::Icons StampTool::icon() const
|
||||
{
|
||||
return Ui::FontNoggit::TOOL_STAMP;
|
||||
}
|
||||
|
||||
void StampTool::setupUi(Ui::Tools::ToolPanel* toolPanel)
|
||||
{
|
||||
_stampTool = new Noggit::Ui::Tools::BrushStack(mapView(), mapView());
|
||||
toolPanel->registerTool(name(), _stampTool);
|
||||
|
||||
QObject::connect(mapView(), &MapView::trySetBrushTexture, [=](QImage* brush, QWidget* sender) {
|
||||
auto mv = mapView();
|
||||
auto item = _stampTool->getActiveBrushItem();
|
||||
|
||||
if (mv->get_editing_mode() != editing_mode::stamp || (item && item->getTool() == sender))
|
||||
{
|
||||
mv->setBrushTexture(brush);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ToolDrawParameters StampTool::drawParameters() const
|
||||
{
|
||||
return
|
||||
{
|
||||
.radius = _stampTool->getRadius(),
|
||||
.inner_radius = _stampTool->getInnerRadius(),
|
||||
.cursor_type = (_stampTool->getActiveBrushItem() && _stampTool->getActiveBrushItem()->isMaskEnabled()) ? CursorType::STAMP : CursorType::CIRCLE,
|
||||
};
|
||||
}
|
||||
|
||||
void StampTool::onSelected()
|
||||
{
|
||||
if (_stampTool->getActiveBrushItem() && _stampTool->getActiveBrushItem()->isEnabled())
|
||||
{
|
||||
_stampTool->getActiveBrushItem()->updateMask();
|
||||
}
|
||||
}
|
||||
|
||||
void StampTool::onTick(float deltaTime, TickParameters const& params)
|
||||
{
|
||||
if (!mapView()->getWorld()->has_selection() || !params.left_mouse)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto mv = mapView();
|
||||
auto world = mv->getWorld();
|
||||
|
||||
for (auto& selection : world->current_selection())
|
||||
{
|
||||
if (selection.index() != eEntry_MapChunk
|
||||
|| params.displayMode != display_mode::in_3D
|
||||
|| !(params.mod_shift_down || params.mod_ctrl_down || params.mod_alt_down)
|
||||
|| !_stampTool->getBrushMode())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
auto action = NOGGIT_ACTION_MGR->beginAction(mv, Noggit::ActionFlags::eNO_FLAG,
|
||||
Noggit::ActionModalityControllers::eSHIFT
|
||||
| Noggit::ActionModalityControllers::eLMB);
|
||||
|
||||
if (!_stampTool->getBrushMode())
|
||||
action->setBlockCursor(true);
|
||||
|
||||
_stampTool->execute(mv->cursorPosition(),
|
||||
world, deltaTime,
|
||||
params.mod_shift_down,
|
||||
params.mod_alt_down,
|
||||
params.mod_ctrl_down,
|
||||
world->isUnderMap(mv->cursorPosition()));
|
||||
}
|
||||
}
|
||||
|
||||
void StampTool::onMouseMove(MouseMoveParameters const& params)
|
||||
{
|
||||
auto mv = mapView();
|
||||
if (params.right_mouse)
|
||||
{
|
||||
if (params.mod_alt_down && !params.mod_shift_down && !params.mod_ctrl_down)
|
||||
{
|
||||
_stampTool->changeInnerRadius(params.relative_movement.dx() / 300.0f);
|
||||
}
|
||||
|
||||
if (params.mod_space_down)
|
||||
{
|
||||
auto action = NOGGIT_ACTION_MGR->beginAction(mv, Noggit::ActionFlags::eDO_NOT_WRITE_HISTORY,
|
||||
Noggit::ActionModalityControllers::eRMB
|
||||
| Noggit::ActionModalityControllers::eSPACE);
|
||||
|
||||
_stampTool->changeRotation(-params.relative_movement.dx() / XSENS * 10.f);
|
||||
action->setBlockCursor(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (params.left_mouse)
|
||||
{
|
||||
if (params.mod_alt_down && !params.mod_shift_down && !params.mod_ctrl_down)
|
||||
{
|
||||
_stampTool->changeRadius(params.relative_movement.dx() / XSENS);
|
||||
}
|
||||
|
||||
if (params.mod_space_down)
|
||||
{
|
||||
_stampTool->changeSpeed(params.relative_movement.dx() / XSENS);
|
||||
}
|
||||
|
||||
if (params.mod_shift_down)
|
||||
{
|
||||
if(params.displayMode == display_mode::in_3D && !_stampTool->getBrushMode())
|
||||
{
|
||||
auto action = NOGGIT_ACTION_MGR->beginAction(mv, Noggit::ActionFlags::eNO_FLAG,
|
||||
Noggit::ActionModalityControllers::eSHIFT
|
||||
| Noggit::ActionModalityControllers::eLMB);
|
||||
|
||||
action->setPostCallback([this] { randomizeStampRotation(); });
|
||||
action->setBlockCursor(true);
|
||||
|
||||
_stampTool->execute(mv->cursorPosition()
|
||||
, mv->getWorld()
|
||||
, params.relative_movement.dx() / 30.0f
|
||||
, params.mod_shift_down
|
||||
, params.mod_alt_down
|
||||
, params.mod_ctrl_down
|
||||
, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StampTool::randomizeStampRotation()
|
||||
{
|
||||
if (!_stampTool->getRandomizeRotation())
|
||||
return;
|
||||
|
||||
unsigned int ms = static_cast<unsigned>(QDateTime::currentMSecsSinceEpoch());
|
||||
std::mt19937 gen(ms);
|
||||
std::uniform_int_distribution<> uid(0, 360);
|
||||
|
||||
_stampTool->changeRotation(uid(gen));
|
||||
}
|
||||
}
|
||||
44
src/noggit/tools/StampTool.hpp
Normal file
44
src/noggit/tools/StampTool.hpp
Normal file
@@ -0,0 +1,44 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <noggit/Tool.hpp>
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
namespace Ui::Tools
|
||||
{
|
||||
class BrushStack;
|
||||
}
|
||||
|
||||
class StampTool final : public Tool
|
||||
{
|
||||
public:
|
||||
StampTool(MapView* mapView);
|
||||
~StampTool();
|
||||
|
||||
[[nodiscard]]
|
||||
virtual char const* name() const override;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual editing_mode editingMode() const override;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual Ui::FontNoggit::Icons icon() const override;
|
||||
|
||||
void setupUi(Ui::Tools::ToolPanel* toolPanel) override;
|
||||
|
||||
[[nodiscard]]
|
||||
ToolDrawParameters drawParameters() const override;
|
||||
|
||||
void onSelected() override;
|
||||
|
||||
void onTick(float deltaTime, TickParameters const& params) override;
|
||||
|
||||
void onMouseMove(MouseMoveParameters const& params) override;
|
||||
|
||||
private:
|
||||
Ui::Tools::BrushStack* _stampTool = nullptr;
|
||||
void randomizeStampRotation();
|
||||
};
|
||||
}
|
||||
584
src/noggit/tools/TexturingTool.cpp
Normal file
584
src/noggit/tools/TexturingTool.cpp
Normal file
@@ -0,0 +1,584 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#include "FlattenBlurTool.hpp"
|
||||
|
||||
#include <noggit/ActionManager.hpp>
|
||||
#include <noggit/Input.hpp>
|
||||
#include <noggit/MapView.h>
|
||||
#include <noggit/Selection.h>
|
||||
#include <noggit/ui/texturing_tool.hpp>
|
||||
#include <noggit/ui/texture_swapper.hpp>
|
||||
#include <noggit/ui/texture_swapper.hpp>
|
||||
#include <noggit/ui/TexturePicker.h>
|
||||
#include <noggit/ui/texture_palette_small.hpp>
|
||||
#include <noggit/ui/CurrentTexture.h>
|
||||
#include <noggit/ui/TexturingGUI.h>
|
||||
#include <noggit/ui/tools/ToolPanel/ToolPanel.hpp>
|
||||
#include <noggit/ui/tools/AssetBrowser/Ui/AssetBrowser.hpp>
|
||||
#include <noggit/ui/windows/noggitWindow/NoggitWindow.hpp>
|
||||
#include "TexturingTool.hpp"
|
||||
#include <noggit/ui/tools/ViewToolbar/Ui/ViewToolbar.hpp>
|
||||
|
||||
#include <QDockWidget>
|
||||
#include <QMenu>
|
||||
|
||||
#include <random>
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
TexturingTool::TexturingTool(MapView* mapView)
|
||||
: Tool{ mapView }
|
||||
{
|
||||
addHotkey("toggleTool"_hash, Hotkey{
|
||||
.onPress = [=] { _texturingTool->toggle_tool(); },
|
||||
.condition = [=] { return mapView->get_editing_mode() == editing_mode::paint && !NOGGIT_CUR_ACTION; },
|
||||
});
|
||||
|
||||
addHotkey("setBrushLevelMinMax"_hash, Hotkey{
|
||||
.onPress = [=] { _texturingTool->toggle_brush_level_min_max(); },
|
||||
.condition = [=] { return mapView->get_editing_mode() == editing_mode::paint && !NOGGIT_CUR_ACTION; },
|
||||
});
|
||||
|
||||
addHotkey("increaseRadius"_hash, Hotkey{
|
||||
.onPress = [=] { _texturingTool->change_radius(0.1f); },
|
||||
.condition = [=] { return mapView->get_editing_mode() == editing_mode::paint && !NOGGIT_CUR_ACTION; },
|
||||
});
|
||||
|
||||
addHotkey("decreaseRadius"_hash, Hotkey{
|
||||
.onPress = [=] { _texturingTool->change_radius(-0.1f); },
|
||||
.condition = [=] { return mapView->get_editing_mode() == editing_mode::paint && !NOGGIT_CUR_ACTION; },
|
||||
});
|
||||
|
||||
addHotkey("setBrushLevel0Pct"_hash, Hotkey{
|
||||
.onPress = [=] { _texturingTool->set_brush_level(0.0f); },
|
||||
.condition = [=] { return mapView->get_editing_mode() == editing_mode::paint && !NOGGIT_CUR_ACTION; },
|
||||
});
|
||||
|
||||
addHotkey("setBrushLevel25Pct"_hash, Hotkey{
|
||||
.onPress = [=] { _texturingTool->set_brush_level(255.0f * 0.25f); },
|
||||
.condition = [=] { return mapView->get_editing_mode() == editing_mode::paint && !NOGGIT_CUR_ACTION; },
|
||||
});
|
||||
|
||||
addHotkey("setBrushLevel50Pct"_hash, Hotkey{
|
||||
.onPress = [=] { _texturingTool->set_brush_level(255.0f * 0.5f); },
|
||||
.condition = [=] { return mapView->get_editing_mode() == editing_mode::paint && !NOGGIT_CUR_ACTION; },
|
||||
});
|
||||
|
||||
addHotkey("setBrushLevel75Pct"_hash, Hotkey{
|
||||
.onPress = [=] { _texturingTool->set_brush_level(255.0f * 0.75f); },
|
||||
.condition = [=] { return mapView->get_editing_mode() == editing_mode::paint && !NOGGIT_CUR_ACTION; },
|
||||
});
|
||||
|
||||
addHotkey("setBrushLevel100Pct"_hash, Hotkey{
|
||||
.onPress = [=] { _texturingTool->set_brush_level(255.0f); },
|
||||
.condition = [=] { return mapView->get_editing_mode() == editing_mode::paint && !NOGGIT_CUR_ACTION; },
|
||||
});
|
||||
|
||||
addHotkey("toggleTexturePalette"_hash, Hotkey{
|
||||
.onPress = [=] { _show_texture_palette_small_window.toggle(); },
|
||||
.condition = [=] { return mapView->get_editing_mode() == editing_mode::paint && !NOGGIT_CUR_ACTION; },
|
||||
});
|
||||
|
||||
QObject::connect(mapView
|
||||
, &MapView::selectionUpdated
|
||||
, [=](std::vector<selection_type>& selection)
|
||||
{
|
||||
if (_texturePickerNeedUpdate)
|
||||
{
|
||||
_texturePickerDock->setVisible(true);
|
||||
_texturePicker->setMainTexture(_texturingTool->_current_texture);
|
||||
_texturePicker->getTextures(*selection.begin());
|
||||
|
||||
_texturePickerNeedUpdate = false;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
TexturingTool::~TexturingTool()
|
||||
{
|
||||
delete _texturePickerDock;
|
||||
delete _texturePaletteDock;
|
||||
delete _textureBrowserDock;
|
||||
delete _texturingTool;
|
||||
}
|
||||
|
||||
char const* TexturingTool::name() const
|
||||
{
|
||||
return "Texture Painter";
|
||||
}
|
||||
|
||||
editing_mode TexturingTool::editingMode() const
|
||||
{
|
||||
return editing_mode::paint;
|
||||
}
|
||||
|
||||
Ui::FontNoggit::Icons TexturingTool::icon() const
|
||||
{
|
||||
return Ui::FontNoggit::TOOL_TEXTURE_PAINT;
|
||||
}
|
||||
|
||||
void TexturingTool::setupUi(Ui::Tools::ToolPanel* toolPanel)
|
||||
{
|
||||
auto mv = mapView();
|
||||
/* Tool */
|
||||
_texturingTool = new Ui::texturing_tool(&mv->getCamera()->position, mv, &_show_texture_palette_small_window, mv);
|
||||
toolPanel->registerTool(name(), _texturingTool);
|
||||
|
||||
// Connects
|
||||
QObject::connect(_texturingTool->texture_swap_tool()->texture_display()
|
||||
, &Noggit::Ui::current_texture::texture_dropped
|
||||
, [=](std::string const& filename)
|
||||
{
|
||||
mv->makeCurrent();
|
||||
OpenGL::context::scoped_setter const _(::gl, mv->context());
|
||||
|
||||
_texturingTool->texture_swap_tool()->set_texture(filename);
|
||||
}
|
||||
);
|
||||
|
||||
QObject::connect(_texturingTool->_current_texture
|
||||
, &Noggit::Ui::current_texture::texture_dropped
|
||||
, [=](std::string const& filename)
|
||||
{
|
||||
mv->makeCurrent();
|
||||
OpenGL::context::scoped_setter const _(::gl, mv->context());
|
||||
|
||||
Noggit::Ui::selected_texture::set({ filename, mv->getRenderContext() });
|
||||
}
|
||||
);
|
||||
|
||||
QObject::connect(_texturingTool->_current_texture, &Noggit::Ui::current_texture::clicked
|
||||
, [=]
|
||||
{
|
||||
_textureBrowserDock->setVisible(!_textureBrowserDock->isVisible());
|
||||
}
|
||||
);
|
||||
|
||||
QObject::connect(_texturingTool, &Ui::texturing_tool::texturePaletteToggled,
|
||||
[=]()
|
||||
{
|
||||
_show_texture_palette_small_window.set(!_show_texture_palette_small_window.get());
|
||||
});
|
||||
|
||||
/* Additional tools */
|
||||
|
||||
/* Texture Browser */
|
||||
|
||||
// Dock
|
||||
_textureBrowserDock = new QDockWidget("Texture Browser", mv);
|
||||
_textureBrowserDock->setFeatures(QDockWidget::DockWidgetMovable
|
||||
| QDockWidget::DockWidgetFloatable
|
||||
| QDockWidget::DockWidgetClosable);
|
||||
_textureBrowserDock->setAllowedAreas(Qt::BottomDockWidgetArea | Qt::TopDockWidgetArea | Qt::LeftDockWidgetArea);
|
||||
mv->mainWindow()->addDockWidget(Qt::BottomDockWidgetArea, _textureBrowserDock);
|
||||
_textureBrowserDock->hide();
|
||||
|
||||
QObject::connect(_textureBrowserDock, &QDockWidget::visibilityChanged,
|
||||
[=](bool visible)
|
||||
{
|
||||
if (mv->isUiHidden())
|
||||
return;
|
||||
|
||||
mv->settings()->setValue("map_view/texture_browser", visible);
|
||||
mv->settings()->sync();
|
||||
});
|
||||
|
||||
QObject::connect(mv, &QObject::destroyed, _textureBrowserDock, &QObject::deleteLater);
|
||||
// End Dock
|
||||
|
||||
_texturePalette = new Noggit::Ui::tileset_chooser(mv);
|
||||
_textureBrowserDock->setWidget(_texturePalette);
|
||||
QObject::connect(mv, &QObject::destroyed, _texturePalette, &QObject::deleteLater);
|
||||
|
||||
QObject::connect(_texturePalette, &Noggit::Ui::tileset_chooser::selected
|
||||
, [=](std::string const& filename)
|
||||
{
|
||||
mv->makeCurrent();
|
||||
OpenGL::context::scoped_setter const _(::gl, mv->context());
|
||||
|
||||
Noggit::Ui::selected_texture::set({ filename, mv->getRenderContext() });
|
||||
_texturingTool->_current_texture->set_texture(filename);
|
||||
_texturePicker->setMainTexture(_texturingTool->_current_texture);
|
||||
_texturePicker->updateSelection();
|
||||
}
|
||||
);
|
||||
|
||||
QObject::connect(_texturePalette, &Noggit::Ui::widget::visibilityChanged
|
||||
, &_show_texture_palette_window, &Noggit::BoolToggleProperty::set
|
||||
);
|
||||
|
||||
QObject::connect(&_show_texture_palette_window, &Noggit::BoolToggleProperty::changed
|
||||
, [this, mv]
|
||||
{
|
||||
if ((mv->get_editing_mode() == editing_mode::paint || mv->get_editing_mode() == editing_mode::stamp)
|
||||
&& !mv->isUiHidden())
|
||||
{
|
||||
_textureBrowserDock->setVisible(_show_texture_palette_window.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
QSignalBlocker const _(_show_texture_palette_window);
|
||||
_show_texture_palette_window.set(false);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
/* Texture Palette Small */
|
||||
_texturePaletteSmall = new Noggit::Ui::texture_palette_small(mv->project(), mv->getWorld()->getMapID(), mv);
|
||||
|
||||
// Dock
|
||||
_texturePaletteDock = new QDockWidget("Texture Palette", mv);
|
||||
_texturePaletteDock->setFeatures(QDockWidget::DockWidgetMovable
|
||||
| QDockWidget::DockWidgetFloatable
|
||||
| QDockWidget::DockWidgetClosable
|
||||
);
|
||||
|
||||
_texturePaletteDock->setWidget(_texturePaletteSmall);
|
||||
_texturePaletteDock->setAllowedAreas(Qt::BottomDockWidgetArea | Qt::TopDockWidgetArea);
|
||||
_texturePaletteDock->hide();
|
||||
|
||||
QObject::connect(mv, &QObject::destroyed, _texturePaletteDock, &QObject::deleteLater);
|
||||
|
||||
mv->mainWindow()->addDockWidget(Qt::BottomDockWidgetArea, _texturePaletteDock);
|
||||
// End Dock
|
||||
|
||||
QObject::connect(_texturePaletteDock, &QDockWidget::visibilityChanged,
|
||||
[=](bool visible)
|
||||
{
|
||||
if (mv->isUiHidden())
|
||||
return;
|
||||
|
||||
mv->settings()->setValue("map_view/texture_palette", visible);
|
||||
mv->settings()->sync();
|
||||
});
|
||||
|
||||
QObject::connect(_texturePaletteSmall, &Noggit::Ui::texture_palette_small::selected
|
||||
, [=](std::string const& filename)
|
||||
{
|
||||
mv->makeCurrent();
|
||||
OpenGL::context::scoped_setter const _(::gl, mv->context());
|
||||
|
||||
Noggit::Ui::selected_texture::set({ filename, mv->getRenderContext() });
|
||||
_texturingTool->_current_texture->set_texture(filename);
|
||||
}
|
||||
);
|
||||
QObject::connect(mv, &QObject::destroyed, _texturePaletteSmall, &QObject::deleteLater);
|
||||
|
||||
QObject::connect(&_show_texture_palette_small_window, &Noggit::BoolToggleProperty::changed
|
||||
, _texturePaletteDock, [=]
|
||||
{
|
||||
QSignalBlocker const blocker(_show_texture_palette_small_window);
|
||||
if (mv->get_editing_mode() == editing_mode::paint && !mv->isUiHidden())
|
||||
{
|
||||
_texturePaletteDock->setVisible(_show_texture_palette_small_window.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
_show_texture_palette_small_window.set(false);
|
||||
}
|
||||
}
|
||||
);
|
||||
QObject::connect(_texturePaletteDock, &QDockWidget::visibilityChanged
|
||||
, &_show_texture_palette_small_window, &Noggit::BoolToggleProperty::set
|
||||
);
|
||||
|
||||
QObject::connect(_texturingTool->_current_texture, &Noggit::Ui::current_texture::texture_updated
|
||||
, [=]()
|
||||
{
|
||||
mv->getWorld()->notifyTileRendererOnSelectedTextureChange();
|
||||
_texturingTool->getGroundEffectsTool()->TextureChanged();
|
||||
}
|
||||
);
|
||||
|
||||
/* Texture Picker */
|
||||
|
||||
// Dock
|
||||
_texturePickerDock = new QDockWidget("Texture picker", mv);
|
||||
_texturePickerDock->setFeatures(QDockWidget::DockWidgetMovable
|
||||
| QDockWidget::DockWidgetFloatable
|
||||
| QDockWidget::DockWidgetClosable);
|
||||
mv->mainWindow()->addDockWidget(Qt::BottomDockWidgetArea, _texturePickerDock);
|
||||
_texturePickerDock->setAllowedAreas(Qt::BottomDockWidgetArea | Qt::TopDockWidgetArea);
|
||||
_texturePickerDock->setFloating(true);
|
||||
_texturePickerDock->hide();
|
||||
QObject::connect(mv, &QObject::destroyed, _texturePickerDock, &QObject::deleteLater);
|
||||
// End Dock
|
||||
|
||||
_texturePicker = new Noggit::Ui::texture_picker(_texturingTool->_current_texture, mv);
|
||||
_texturePickerDock->setWidget(_texturePicker);
|
||||
QObject::connect(mv, &QObject::destroyed, _texturePicker, &QObject::deleteLater);
|
||||
|
||||
QObject::connect(_texturePicker
|
||||
, &Noggit::Ui::texture_picker::set_texture
|
||||
, [=](scoped_blp_texture_reference texture)
|
||||
{
|
||||
mv->makeCurrent();
|
||||
OpenGL::context::scoped_setter const _(::gl, mv->context());
|
||||
Noggit::Ui::selected_texture::set(std::move(texture));
|
||||
}
|
||||
);
|
||||
QObject::connect(_texturePicker, &Noggit::Ui::texture_picker::shift_left
|
||||
, [=]
|
||||
{
|
||||
mv->makeCurrent();
|
||||
OpenGL::context::scoped_setter const _(::gl, mv->context());
|
||||
_texturePicker->shiftSelectedTextureLeft();
|
||||
}
|
||||
);
|
||||
QObject::connect(_texturePicker, &Noggit::Ui::texture_picker::shift_right
|
||||
, [=]
|
||||
{
|
||||
mv->makeCurrent();
|
||||
OpenGL::context::scoped_setter const _(::gl, mv->context());
|
||||
_texturePicker->shiftSelectedTextureRight();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void TexturingTool::registerMenuItems(QMenu* menu)
|
||||
{
|
||||
addMenuTitle(menu, "Texture Painter");
|
||||
addMenuItem(menu, "Texture Browser", Qt::Key_X, _show_texture_palette_window);
|
||||
addMenuItem(menu, "Texture palette", _show_texture_palette_small_window);
|
||||
}
|
||||
|
||||
ToolDrawParameters TexturingTool::drawParameters() const
|
||||
{
|
||||
auto cursorType = CursorType::CIRCLE;
|
||||
if (_texturingTool->getTexturingMode() == Noggit::Ui::texturing_mode::paint && _texturingTool->getImageMaskSelector()->isEnabled())
|
||||
cursorType = CursorType::STAMP;
|
||||
|
||||
return
|
||||
{
|
||||
.radius = _texturingTool->brush_radius(),
|
||||
.inner_radius = _texturingTool->hardness(),
|
||||
.show_unpaintable_chunks = _texturingTool->show_unpaintable_chunks(),
|
||||
.cursor_type = cursorType,
|
||||
};
|
||||
}
|
||||
|
||||
void TexturingTool::onSelected()
|
||||
{
|
||||
auto mv = mapView();
|
||||
if (_texturingTool->getTexturingMode() == Noggit::Ui::texturing_mode::paint && _texturingTool->getImageMaskSelector()->isEnabled())
|
||||
{
|
||||
_texturingTool->updateMaskImage();
|
||||
}
|
||||
else if (_texturingTool->getTexturingMode() == Noggit::Ui::texturing_mode::ground_effect)
|
||||
{
|
||||
_texturingTool->getGroundEffectsTool()->updateTerrainUniformParams();
|
||||
}
|
||||
|
||||
bool use_classic_ui = mv->settings()->value("classicUI", false).toBool();
|
||||
if (use_classic_ui)
|
||||
{
|
||||
if (_texturingTool->show_unpaintable_chunks())
|
||||
{
|
||||
mv->getWorld()->renderer()->getTerrainParamsUniformBlock()->draw_paintability_overlay = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mv->getLeftSecondaryViewToolbar()->showUnpaintableChunk())
|
||||
{
|
||||
mv->getWorld()->renderer()->getTerrainParamsUniformBlock()->draw_paintability_overlay = true;
|
||||
}
|
||||
}
|
||||
|
||||
_textureBrowserDock->setVisible(!mv->isUiHidden() && mv->settings()->value("map_view/texture_browser", false).toBool());
|
||||
_texturePaletteDock->setVisible(!mv->isUiHidden() && mv->settings()->value("map_view/texture_palette", false).toBool());
|
||||
}
|
||||
|
||||
void TexturingTool::onDeselected()
|
||||
{
|
||||
_texturingTool->getGroundEffectsTool()->hide();
|
||||
_textureBrowserDock->setVisible(false);
|
||||
_texturePaletteDock->setVisible(false);
|
||||
}
|
||||
|
||||
void TexturingTool::onTick(float deltaTime, TickParameters const& params)
|
||||
{
|
||||
if (!params.left_mouse)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto mv = mapView();
|
||||
|
||||
if (_texturingTool->getTexturingMode() == Noggit::Ui::texturing_mode::ground_effect)
|
||||
{
|
||||
if (params.mod_shift_down)
|
||||
{
|
||||
if (_texturingTool->getGroundEffectsTool()->brush_mode() == Noggit::Ui::ground_effect_brush_mode::exclusion)
|
||||
{
|
||||
NOGGIT_ACTION_MGR->beginAction(mv, Noggit::ActionFlags::eCHUNK_DOODADS_EXCLUSION,
|
||||
Noggit::ActionModalityControllers::eSHIFT
|
||||
| Noggit::ActionModalityControllers::eLMB);
|
||||
mv->getWorld()->paintGroundEffectExclusion(mv->cursorPosition(), _texturingTool->getGroundEffectsTool()->radius(), true);
|
||||
// mv->getWorld()->setHole(mv->cursorPosition(), holeTool->brushRadius(), _mod_alt_down, false);
|
||||
}
|
||||
else if (_texturingTool->getGroundEffectsTool()->brush_mode() == Noggit::Ui::ground_effect_brush_mode::effect)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else if (params.mod_ctrl_down && !params.underMap)
|
||||
{
|
||||
NOGGIT_ACTION_MGR->beginAction(mv, Noggit::ActionFlags::eCHUNK_DOODADS_EXCLUSION,
|
||||
Noggit::ActionModalityControllers::eCTRL
|
||||
| Noggit::ActionModalityControllers::eLMB);
|
||||
mv->getWorld()->paintGroundEffectExclusion(mv->cursorPosition(), _texturingTool->getGroundEffectsTool()->radius(), false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (params.mod_shift_down && params.mod_ctrl_down && params.mod_alt_down)
|
||||
{
|
||||
// clear chunk texture
|
||||
if (!params.underMap)
|
||||
{
|
||||
NOGGIT_ACTION_MGR->beginAction(mv, Noggit::ActionFlags::eCHUNKS_TEXTURE,
|
||||
Noggit::ActionModalityControllers::eSHIFT
|
||||
| Noggit::ActionModalityControllers::eCTRL
|
||||
| Noggit::ActionModalityControllers::eALT
|
||||
| Noggit::ActionModalityControllers::eLMB);
|
||||
|
||||
mv->getWorld()->eraseTextures(mv->cursorPosition());
|
||||
}
|
||||
}
|
||||
else if (params.mod_ctrl_down && !mv->isUiHidden())
|
||||
{
|
||||
_texturePickerNeedUpdate = true;
|
||||
// Pick texture
|
||||
// _texturePickerDock->setVisible(true);
|
||||
// _texturePicker->setMainTexture(_texturingTool->_current_texture);
|
||||
// _texturePicker->getTextures(selection);
|
||||
}
|
||||
else if (params.mod_shift_down && !!Noggit::Ui::selected_texture::get())
|
||||
{
|
||||
if ((params.displayMode == display_mode::in_3D && !params.underMap) || params.displayMode == display_mode::in_2D)
|
||||
{
|
||||
auto image_mask_selector = _texturingTool->getImageMaskSelector();
|
||||
|
||||
if (NOGGIT_CUR_ACTION
|
||||
&& _texturingTool->getTexturingMode() == Noggit::Ui::texturing_mode::paint
|
||||
&& image_mask_selector->isEnabled()
|
||||
&& !image_mask_selector->getBrushMode())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto action = NOGGIT_ACTION_MGR->beginAction(mv, Noggit::ActionFlags::eCHUNKS_TEXTURE,
|
||||
Noggit::ActionModalityControllers::eSHIFT
|
||||
| Noggit::ActionModalityControllers::eLMB);
|
||||
|
||||
action->setPostCallback([this] { randomizeTexturingRotation(); });
|
||||
|
||||
if (_texturingTool->getTexturingMode() == Noggit::Ui::texturing_mode::paint
|
||||
&& image_mask_selector->isEnabled()
|
||||
&& !image_mask_selector->getBrushMode())
|
||||
action->setBlockCursor(true);
|
||||
|
||||
_texturingTool->paint(mv->getWorld(), mv->cursorPosition(), deltaTime, *Noggit::Ui::selected_texture::get());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TexturingTool::onMousePress(MousePressParameters const& params)
|
||||
{
|
||||
if (params.button != Qt::MouseButton::LeftButton || !params.mod_ctrl_down)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mapView()->doSelection(false, false);
|
||||
}
|
||||
|
||||
void TexturingTool::onMouseMove(MouseMoveParameters const& params)
|
||||
{
|
||||
if (params.right_mouse)
|
||||
{
|
||||
if (params.mod_alt_down && !params.mod_shift_down && !params.mod_ctrl_down)
|
||||
{
|
||||
_texturingTool->change_hardness(params.relative_movement.dx() / 300.0f);
|
||||
}
|
||||
|
||||
if (params.mod_space_down)
|
||||
{
|
||||
if (_texturingTool->getImageMaskSelector()->isEnabled())
|
||||
{
|
||||
auto action = NOGGIT_ACTION_MGR->beginAction(mapView(), Noggit::ActionFlags::eDO_NOT_WRITE_HISTORY,
|
||||
Noggit::ActionModalityControllers::eRMB
|
||||
| Noggit::ActionModalityControllers::eSPACE);
|
||||
_texturingTool->getImageMaskSelector()->setRotation(-params.relative_movement.dx() / XSENS * 10.f);
|
||||
action->setBlockCursor(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (params.left_mouse)
|
||||
{
|
||||
if (params.mod_alt_down && !params.mod_shift_down && !params.mod_ctrl_down)
|
||||
{
|
||||
_texturingTool->change_radius(params.relative_movement.dx() / XSENS);
|
||||
}
|
||||
|
||||
if (params.mod_space_down)
|
||||
{
|
||||
_texturingTool->change_pressure(params.relative_movement.dx() / 300.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TexturingTool::onMouseWheel(MouseWheelParameters const& params)
|
||||
{
|
||||
auto&& delta_for_range
|
||||
([&](float range)
|
||||
{
|
||||
//! \note / 8.f for degrees, / 40.f for smoothness
|
||||
return (params.mod_ctrl_down ? 0.01f : 0.1f)
|
||||
* range
|
||||
// alt = horizontal delta
|
||||
* (params.mod_alt_down ? params.event.angleDelta().x() : params.event.angleDelta().y())
|
||||
/ 320.f
|
||||
;
|
||||
}
|
||||
);
|
||||
|
||||
if (params.mod_space_down)
|
||||
{
|
||||
_texturingTool->change_brush_level(delta_for_range(255.f));
|
||||
}
|
||||
else if (params.mod_alt_down)
|
||||
{
|
||||
_texturingTool->change_spray_size(delta_for_range(39.f));
|
||||
}
|
||||
else if (params.mod_shift_down)
|
||||
{
|
||||
_texturingTool->change_spray_pressure(delta_for_range(10.f));
|
||||
}
|
||||
}
|
||||
|
||||
void TexturingTool::hidePopups()
|
||||
{
|
||||
_texturePaletteSmall->hide();
|
||||
_texturePickerDock->hide();
|
||||
_textureBrowserDock->hide();
|
||||
}
|
||||
|
||||
void TexturingTool::randomizeTexturingRotation()
|
||||
{
|
||||
auto image_mask_selector = _texturingTool->getImageMaskSelector();
|
||||
if (!image_mask_selector->getRandomizeRotation())
|
||||
return;
|
||||
|
||||
unsigned int ms = static_cast<unsigned>(QDateTime::currentMSecsSinceEpoch());
|
||||
std::mt19937 gen(ms);
|
||||
std::uniform_int_distribution<> uid(0, 360);
|
||||
|
||||
image_mask_selector->setRotation(uid(gen));
|
||||
}
|
||||
}
|
||||
70
src/noggit/tools/TexturingTool.hpp
Normal file
70
src/noggit/tools/TexturingTool.hpp
Normal file
@@ -0,0 +1,70 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <noggit/Tool.hpp>
|
||||
#include <noggit/BoolToggleProperty.hpp>
|
||||
|
||||
class QDockWidget;
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
namespace Ui
|
||||
{
|
||||
class texturing_tool;
|
||||
struct tileset_chooser;
|
||||
class texture_picker;
|
||||
class texture_palette_small;
|
||||
}
|
||||
|
||||
class TexturingTool final : public Tool
|
||||
{
|
||||
public:
|
||||
TexturingTool(MapView* mapView);
|
||||
~TexturingTool();
|
||||
|
||||
[[nodiscard]]
|
||||
char const* name() const override;
|
||||
|
||||
[[nodiscard]]
|
||||
editing_mode editingMode() const override;
|
||||
|
||||
[[nodiscard]]
|
||||
Ui::FontNoggit::Icons icon() const override;
|
||||
|
||||
void setupUi(Ui::Tools::ToolPanel* toolPanel) override;
|
||||
|
||||
void registerMenuItems(QMenu* menu) override;
|
||||
|
||||
[[nodiscard]]
|
||||
ToolDrawParameters drawParameters() const override;
|
||||
|
||||
void onSelected() override;
|
||||
|
||||
void onDeselected() override;
|
||||
|
||||
void onTick(float deltaTime, TickParameters const& params) override;
|
||||
|
||||
void onMousePress(MousePressParameters const& params) override;
|
||||
|
||||
void onMouseMove(MouseMoveParameters const& params) override;
|
||||
|
||||
void onMouseWheel(MouseWheelParameters const& params) override;
|
||||
|
||||
void hidePopups() override;
|
||||
|
||||
private:
|
||||
Ui::texturing_tool* _texturingTool = nullptr;
|
||||
QDockWidget* _textureBrowserDock = nullptr;
|
||||
Ui::tileset_chooser* _texturePalette = nullptr;
|
||||
Ui::texture_picker* _texturePicker = nullptr;
|
||||
Ui::texture_palette_small* _texturePaletteSmall = nullptr;
|
||||
QDockWidget* _texturePaletteDock = nullptr;
|
||||
QDockWidget* _texturePickerDock = nullptr;
|
||||
bool _texturePickerNeedUpdate = false;
|
||||
Noggit::BoolToggleProperty _show_texture_palette_window = { false };
|
||||
Noggit::BoolToggleProperty _show_texture_palette_small_window = { false };
|
||||
|
||||
void randomizeTexturingRotation();
|
||||
};
|
||||
}
|
||||
162
src/noggit/tools/VertexPainterTool.cpp
Normal file
162
src/noggit/tools/VertexPainterTool.cpp
Normal file
@@ -0,0 +1,162 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#include "VertexPainterTool.hpp"
|
||||
|
||||
#include <noggit/ActionManager.hpp>
|
||||
#include <noggit/MapView.h>
|
||||
#include <noggit/Input.hpp>
|
||||
#include <noggit/ui/ShaderTool.hpp>
|
||||
#include <noggit/ui/tools/ToolPanel/ToolPanel.hpp>
|
||||
|
||||
#include <random>
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
VertexPainterTool::VertexPainterTool(MapView* mapView)
|
||||
: Tool{ mapView }
|
||||
{
|
||||
addHotkey("addColor"_hash, Hotkey{
|
||||
.onPress = [=] { _shaderTool->addColorToPalette(); },
|
||||
.condition = [=] { return mapView->get_editing_mode() == editing_mode::mccv && !NOGGIT_CUR_ACTION; },
|
||||
});
|
||||
}
|
||||
|
||||
VertexPainterTool::~VertexPainterTool()
|
||||
{
|
||||
delete _shaderTool;
|
||||
}
|
||||
|
||||
char const* VertexPainterTool::name() const
|
||||
{
|
||||
return "Vertex Painter";
|
||||
}
|
||||
|
||||
editing_mode VertexPainterTool::editingMode() const
|
||||
{
|
||||
return editing_mode::mccv;
|
||||
}
|
||||
|
||||
Ui::FontNoggit::Icons VertexPainterTool::icon() const
|
||||
{
|
||||
return Ui::FontNoggit::TOOL_VERTEX_PAINT;
|
||||
}
|
||||
|
||||
void VertexPainterTool::setupUi(Ui::Tools::ToolPanel* toolPanel)
|
||||
{
|
||||
_shaderTool = new Noggit::Ui::ShaderTool(mapView(), mapView());
|
||||
toolPanel->registerTool(name(), _shaderTool);
|
||||
}
|
||||
|
||||
ToolDrawParameters VertexPainterTool::drawParameters() const
|
||||
{
|
||||
return
|
||||
{
|
||||
.radius = _shaderTool->brushRadius(),
|
||||
.cursor_type = (_shaderTool->getImageMaskSelector()->isEnabled()) ? CursorType::STAMP : CursorType::CIRCLE,
|
||||
.cursor_color = _shaderTool->shaderColor(),
|
||||
};
|
||||
}
|
||||
|
||||
void VertexPainterTool::onSelected()
|
||||
{
|
||||
if (_shaderTool->getImageMaskSelector()->isEnabled())
|
||||
{
|
||||
_shaderTool->updateMaskImage();
|
||||
}
|
||||
}
|
||||
|
||||
void VertexPainterTool::randomizeShaderRotation()
|
||||
{
|
||||
auto image_mask_selector = _shaderTool->getImageMaskSelector();
|
||||
if (!image_mask_selector->getRandomizeRotation())
|
||||
return;
|
||||
|
||||
unsigned int ms = static_cast<unsigned>(QDateTime::currentMSecsSinceEpoch());
|
||||
std::mt19937 gen(ms);
|
||||
std::uniform_int_distribution<> uid(0, 360);
|
||||
|
||||
image_mask_selector->setRotation(uid(gen));
|
||||
}
|
||||
|
||||
void VertexPainterTool::onTick(float deltaTime, TickParameters const& params)
|
||||
{
|
||||
if (params.underMap || !params.left_mouse)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& selection : mapView()->getWorld()->current_selection())
|
||||
{
|
||||
if (selection.index() != eEntry_MapChunk)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((params.mod_shift_down ^ params.mod_ctrl_down) == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
auto mv = mapView();
|
||||
bool add = params.mod_shift_down && !params.mod_ctrl_down;
|
||||
auto flags = add ? Noggit::ActionModalityControllers::eSHIFT : Noggit::ActionModalityControllers::eCTRL;
|
||||
|
||||
auto image_mask_selector = _shaderTool->getImageMaskSelector();
|
||||
|
||||
if (NOGGIT_CUR_ACTION
|
||||
&& image_mask_selector->isEnabled()
|
||||
&& !image_mask_selector->getBrushMode())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
auto action = NOGGIT_ACTION_MGR->beginAction(mv, Noggit::ActionFlags::eCHUNKS_VERTEX_COLOR,
|
||||
flags | Noggit::ActionModalityControllers::eLMB);
|
||||
|
||||
action->setPostCallback([this] { randomizeShaderRotation(); });
|
||||
|
||||
if (image_mask_selector->isEnabled() && !image_mask_selector->getBrushMode())
|
||||
action->setBlockCursor(true);
|
||||
|
||||
_shaderTool->changeShader(mv->getWorld(), mv->cursorPosition(), deltaTime, add);
|
||||
}
|
||||
}
|
||||
|
||||
void VertexPainterTool::onMousePress(MousePressParameters const& params)
|
||||
{
|
||||
if (params.button != Qt::MouseButton::MiddleButton)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_shaderTool->pickColor(mapView()->getWorld(), mapView()->cursorPosition());
|
||||
}
|
||||
|
||||
void VertexPainterTool::onMouseMove(MouseMoveParameters const& params)
|
||||
{
|
||||
if (params.right_mouse)
|
||||
{
|
||||
if (params.mod_space_down && _shaderTool->getImageMaskSelector()->isEnabled())
|
||||
{
|
||||
auto action = NOGGIT_ACTION_MGR->beginAction(mapView(), Noggit::ActionFlags::eDO_NOT_WRITE_HISTORY,
|
||||
Noggit::ActionModalityControllers::eRMB
|
||||
| Noggit::ActionModalityControllers::eSPACE);
|
||||
_shaderTool->getImageMaskSelector()->setRotation(-params.relative_movement.dx() / XSENS * 10.f);
|
||||
action->setBlockCursor(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (params.left_mouse)
|
||||
{
|
||||
if (params.mod_alt_down && !params.mod_shift_down && !params.mod_ctrl_down)
|
||||
{
|
||||
_shaderTool->changeRadius(params.relative_movement.dx() / XSENS);
|
||||
}
|
||||
|
||||
if (params.mod_space_down)
|
||||
{
|
||||
_shaderTool->changeSpeed(params.relative_movement.dx() / XSENS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
47
src/noggit/tools/VertexPainterTool.hpp
Normal file
47
src/noggit/tools/VertexPainterTool.hpp
Normal file
@@ -0,0 +1,47 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <noggit/Tool.hpp>
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
namespace Ui
|
||||
{
|
||||
class ShaderTool;
|
||||
}
|
||||
|
||||
class VertexPainterTool final : public Tool
|
||||
{
|
||||
public:
|
||||
VertexPainterTool(MapView* mapView);
|
||||
~VertexPainterTool();
|
||||
|
||||
[[nodiscard]]
|
||||
virtual char const* name() const override;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual editing_mode editingMode() const override;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual Ui::FontNoggit::Icons icon() const override;
|
||||
|
||||
virtual void setupUi(Ui::Tools::ToolPanel* toolPanel) override;
|
||||
|
||||
[[nodiscard]]
|
||||
ToolDrawParameters drawParameters() const override;
|
||||
|
||||
void onSelected() override;
|
||||
|
||||
void onTick(float deltaTime, TickParameters const& params) override;
|
||||
|
||||
void onMousePress(MousePressParameters const& params) override;
|
||||
|
||||
void onMouseMove(MouseMoveParameters const& params) override;
|
||||
|
||||
private:
|
||||
Noggit::Ui::ShaderTool* _shaderTool = nullptr;
|
||||
|
||||
void randomizeShaderRotation();
|
||||
};
|
||||
}
|
||||
165
src/noggit/tools/WaterTool.cpp
Normal file
165
src/noggit/tools/WaterTool.cpp
Normal file
@@ -0,0 +1,165 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#include "WaterTool.hpp"
|
||||
|
||||
#include <noggit/ActionManager.hpp>
|
||||
#include <noggit/MapView.h>
|
||||
#include <noggit/Input.hpp>
|
||||
#include <noggit/ui/Water.h>
|
||||
#include <noggit/ui/tools/ToolPanel/ToolPanel.hpp>
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
WaterTool::WaterTool(MapView* mapView)
|
||||
: Tool{ mapView }
|
||||
{
|
||||
addHotkey("toggleAngled"_hash, Hotkey{
|
||||
.onPress = [=] { _guiWater->toggle_angled_mode(); },
|
||||
.condition = [=] { return mapView->get_editing_mode() == editing_mode::water && !NOGGIT_CUR_ACTION; },
|
||||
});
|
||||
|
||||
addHotkey("toggleLock"_hash, Hotkey{
|
||||
.onPress = [=] { _guiWater->toggle_lock(); },
|
||||
.condition = [=] { return mapView->get_editing_mode() == editing_mode::water && !NOGGIT_CUR_ACTION; },
|
||||
});
|
||||
|
||||
addHotkey("lockCursor"_hash, Hotkey{
|
||||
.onPress = [=] { _guiWater->lockPos(mapView->cursorPosition()); },
|
||||
.condition = [=] { return mapView->get_editing_mode() == editing_mode::water && !NOGGIT_CUR_ACTION; },
|
||||
});
|
||||
}
|
||||
|
||||
WaterTool::~WaterTool()
|
||||
{
|
||||
delete _guiWater;
|
||||
}
|
||||
|
||||
char const* WaterTool::name() const
|
||||
{
|
||||
return "Water Editor";
|
||||
}
|
||||
|
||||
editing_mode WaterTool::editingMode() const
|
||||
{
|
||||
return editing_mode::water;
|
||||
}
|
||||
|
||||
Ui::FontNoggit::Icons WaterTool::icon() const
|
||||
{
|
||||
return Ui::FontNoggit::TOOL_WATER_EDITOR;
|
||||
}
|
||||
|
||||
void WaterTool::setupUi(Ui::Tools::ToolPanel* toolPanel)
|
||||
{
|
||||
_guiWater = new Noggit::Ui::water(&_displayedWaterLayer, &_displayAllWaterLayers, mapView());
|
||||
toolPanel->registerTool(name(), _guiWater);
|
||||
|
||||
auto mv = mapView();
|
||||
|
||||
QObject::connect(_guiWater, &Noggit::Ui::water::regenerate_water_opacity
|
||||
, [=](float factor)
|
||||
{
|
||||
mv->makeCurrent();
|
||||
OpenGL::context::scoped_setter const _(::gl, mv->context());
|
||||
NOGGIT_ACTION_MGR->beginAction(mv, Noggit::ActionFlags::eCHUNKS_WATER);
|
||||
mv->getWorld()->autoGenWaterTrans(mv->getCamera()->position, factor);
|
||||
NOGGIT_ACTION_MGR->endAction();
|
||||
}
|
||||
);
|
||||
|
||||
QObject::connect(_guiWater, &Noggit::Ui::water::crop_water
|
||||
, [=]
|
||||
{
|
||||
mv->makeCurrent();
|
||||
OpenGL::context::scoped_setter const _(::gl, mv->context());
|
||||
NOGGIT_ACTION_MGR->beginAction(mv, Noggit::ActionFlags::eCHUNKS_WATER);
|
||||
mv->getWorld()->CropWaterADT(mv->getCamera()->position);
|
||||
NOGGIT_ACTION_MGR->endAction();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
ToolDrawParameters WaterTool::drawParameters() const
|
||||
{
|
||||
return
|
||||
{
|
||||
.radius = _guiWater->brushRadius(),
|
||||
.angle = _guiWater->angle(),
|
||||
.orientation = _guiWater->orientation(),
|
||||
.ref_pos = _guiWater->ref_pos(),
|
||||
.angled_mode = _guiWater->angled_mode(),
|
||||
.use_ref_pos = _guiWater->use_ref_pos(),
|
||||
.displayed_water_layer = _displayAllWaterLayers.get() ? -1 : static_cast<int>(_displayedWaterLayer.get()),
|
||||
};
|
||||
}
|
||||
|
||||
void WaterTool::onTick(float deltaTime, TickParameters const& params)
|
||||
{
|
||||
if (params.underMap || !params.left_mouse)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto mv = mapView();
|
||||
if (params.displayMode == display_mode::in_3D && !params.underMap)
|
||||
{
|
||||
if (params.mod_shift_down)
|
||||
{
|
||||
NOGGIT_ACTION_MGR->beginAction(mv, Noggit::ActionFlags::eCHUNKS_WATER,
|
||||
Noggit::ActionModalityControllers::eSHIFT
|
||||
| Noggit::ActionModalityControllers::eLMB);
|
||||
_guiWater->paintLiquid(mv->getWorld(), mv->cursorPosition(), true);
|
||||
}
|
||||
else if (params.mod_ctrl_down)
|
||||
{
|
||||
NOGGIT_ACTION_MGR->beginAction(mv, Noggit::ActionFlags::eCHUNKS_WATER,
|
||||
Noggit::ActionModalityControllers::eCTRL
|
||||
| Noggit::ActionModalityControllers::eLMB);
|
||||
_guiWater->paintLiquid(mv->getWorld(), mv->cursorPosition(), false);
|
||||
}
|
||||
}
|
||||
|
||||
// HINT: this was originally at the very end of MapView::Tick. Do we need a new postTick method?
|
||||
// While testing I can't find any issues with the tools.
|
||||
// Using the camera's position from last frame doesn't seem to matter but it's technically incorrect for one frame!
|
||||
_guiWater->updatePos(mv->getCamera()->position);
|
||||
}
|
||||
|
||||
void WaterTool::onMouseMove(MouseMoveParameters const& params)
|
||||
{
|
||||
if (params.left_mouse && params.mod_alt_down && !params.mod_shift_down && !params.mod_ctrl_down)
|
||||
{
|
||||
_guiWater->changeRadius(params.relative_movement.dx() / XSENS);
|
||||
}
|
||||
}
|
||||
|
||||
void WaterTool::onMouseWheel(MouseWheelParameters const& params)
|
||||
{
|
||||
auto&& delta_for_range
|
||||
([&](float range)
|
||||
{
|
||||
//! \note / 8.f for degrees, / 40.f for smoothness
|
||||
return (params.mod_ctrl_down ? 0.01f : 0.1f)
|
||||
* range
|
||||
// alt = horizontal delta
|
||||
* (params.mod_alt_down ? params.event.angleDelta().x() : params.event.angleDelta().y())
|
||||
/ 320.f
|
||||
;
|
||||
}
|
||||
);
|
||||
|
||||
if (params.mod_alt_down)
|
||||
{
|
||||
_guiWater->changeOrientation(delta_for_range(360.f));
|
||||
}
|
||||
else if (params.mod_shift_down)
|
||||
{
|
||||
_guiWater->changeAngle(delta_for_range(89.f));
|
||||
}
|
||||
else if (params.mod_space_down)
|
||||
{
|
||||
//! \note not actual range
|
||||
_guiWater->change_height(delta_for_range(40.f));
|
||||
}
|
||||
}
|
||||
}
|
||||
47
src/noggit/tools/WaterTool.hpp
Normal file
47
src/noggit/tools/WaterTool.hpp
Normal file
@@ -0,0 +1,47 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <noggit/Tool.hpp>
|
||||
#include <noggit/unsigned_int_property.hpp>
|
||||
#include <noggit/BoolToggleProperty.hpp>
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
namespace Ui
|
||||
{
|
||||
class water;
|
||||
}
|
||||
|
||||
class WaterTool final : public Tool
|
||||
{
|
||||
public:
|
||||
WaterTool(MapView* mapView);
|
||||
~WaterTool();
|
||||
|
||||
[[nodiscard]]
|
||||
virtual char const* name() const override;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual editing_mode editingMode() const override;
|
||||
|
||||
[[nodiscard]]
|
||||
virtual Ui::FontNoggit::Icons icon() const override;
|
||||
|
||||
virtual void setupUi(Ui::Tools::ToolPanel* toolPanel) override;
|
||||
|
||||
[[nodiscard]]
|
||||
ToolDrawParameters drawParameters() const override;
|
||||
|
||||
void onTick(float deltaTime, TickParameters const& params) override;
|
||||
|
||||
void onMouseMove(MouseMoveParameters const& params) override;
|
||||
|
||||
void onMouseWheel(MouseWheelParameters const& params) override;
|
||||
|
||||
private:
|
||||
Noggit::Ui::water* _guiWater = nullptr;
|
||||
Noggit::unsigned_int_property _displayedWaterLayer = { 0 };
|
||||
Noggit::BoolToggleProperty _displayAllWaterLayers = { true };
|
||||
};
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <QtGui/QIcon>
|
||||
#include <QtGui/QIconEngine>
|
||||
|
||||
|
||||
@@ -383,6 +383,10 @@ namespace Noggit
|
||||
}
|
||||
);
|
||||
|
||||
using AssetBrowser = Noggit::Ui::Tools::AssetBrowser::Ui::AssetBrowserWidget;
|
||||
connect(map_view->getAssetBrowserWidget(), &AssetBrowser::selectionChanged, this, [=](std::string const& path) {
|
||||
if (isVisible()) setDoodadSlotFromBrowser(path.c_str());
|
||||
});
|
||||
}
|
||||
|
||||
void GroundEffectsTool::updateTerrainUniformParams()
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include <QtWidgets/QListWidget>
|
||||
|
||||
class World;
|
||||
class texturing_tool;
|
||||
class MapView;
|
||||
class DBCFile::Record;
|
||||
|
||||
@@ -22,6 +21,8 @@ namespace Noggit
|
||||
{
|
||||
namespace Ui
|
||||
{
|
||||
class texturing_tool;
|
||||
|
||||
struct ground_effect_doodad
|
||||
{
|
||||
unsigned int ID = 0;
|
||||
|
||||
@@ -1,354 +1,354 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#include <noggit/ui/Help.h>
|
||||
#include <noggit/ui/FontNoggit.hpp>
|
||||
|
||||
#include <QtWidgets/QFormLayout>
|
||||
#include <QtWidgets/QHBoxLayout>
|
||||
#include <QtWidgets/QLabel>
|
||||
#include <QtWidgets/QScrollArea>
|
||||
#include <QtWidgets/QTabWidget>
|
||||
|
||||
#include <initializer_list>
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
namespace Ui
|
||||
{
|
||||
|
||||
help::help(QWidget* parent)
|
||||
: widget (parent, Qt::Window)
|
||||
{
|
||||
setWindowTitle ("Help");
|
||||
setWindowIcon (QIcon (":/icon"));
|
||||
setWindowFlags(Qt::Window | Qt::WindowStaysOnTopHint);
|
||||
|
||||
QString header_style =
|
||||
"QLabel { \n "
|
||||
" font-weight: bold; \n "
|
||||
" margin-top: 8px; \n "
|
||||
" margin-bottom: 4px; \n "
|
||||
" margin-left: 150px; \n "
|
||||
"} \n ";
|
||||
|
||||
|
||||
auto layout (new QFormLayout (this));
|
||||
layout->setSizeConstraint(QLayout::SetFixedSize);
|
||||
|
||||
auto tabs (new QTabWidget (this));
|
||||
|
||||
auto base_widget (new QWidget (this));
|
||||
auto base_layout(new QGridLayout (base_widget));
|
||||
|
||||
|
||||
auto basic_controls_layout (new QFormLayout (this));
|
||||
base_layout->addLayout(basic_controls_layout, 0, 0);
|
||||
|
||||
base_widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
|
||||
auto label = new QLabel("Basic controls:");
|
||||
label->setStyleSheet(header_style);
|
||||
basic_controls_layout->addRow(label);
|
||||
|
||||
generate_hotkey_row({FontNoggit::rmb_drag}, "\aRotate camera", basic_controls_layout);
|
||||
generate_hotkey_row({FontNoggit::lmb}, "\aSelect chunk or object", basic_controls_layout);
|
||||
generate_hotkey_row({FontNoggit::i}, "\aInvert mouse up and down", basic_controls_layout);
|
||||
generate_hotkey_row({FontNoggit::q, FontNoggit::e}, "\a,\aMove up and down", basic_controls_layout);
|
||||
generate_hotkey_row({FontNoggit::w, FontNoggit::a , FontNoggit::s , FontNoggit::d}, "\a\a\a\aMove left, right, forward, backwards", basic_controls_layout);
|
||||
generate_hotkey_row({FontNoggit::home}, "\aMove position to the cursor", basic_controls_layout);
|
||||
generate_hotkey_row({FontNoggit::m}, "\aShow map", basic_controls_layout);
|
||||
generate_hotkey_row({FontNoggit::u}, "\a2D texture editor", basic_controls_layout);
|
||||
generate_hotkey_row({FontNoggit::ctrl, FontNoggit::f1}, "\a+\aThis help", basic_controls_layout);
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::j}, "\a+\aReload an adt under the camera", basic_controls_layout);
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::r}, "\a+\aTurn camera 180 degrees", basic_controls_layout);
|
||||
generate_hotkey_row({FontNoggit::shift}, "\a+ 1, 2, 3 or 4 Set a predefined camera speed", basic_controls_layout);
|
||||
generate_hotkey_row({FontNoggit::alt, FontNoggit::f4}, "\a+\aExit to main menu", basic_controls_layout);
|
||||
generate_hotkey_row({FontNoggit::l}, "\aToggle top view (hint: it's faster to use with graphic tablet stylus buttons)", basic_controls_layout);
|
||||
generate_hotkey_row({}, "", basic_controls_layout); // padding
|
||||
|
||||
auto toggles_layout(new QFormLayout(this));
|
||||
base_layout->addLayout(toggles_layout, 0, 1);
|
||||
|
||||
auto label_toggle = new QLabel("Toggles:");
|
||||
label_toggle->setStyleSheet(header_style);
|
||||
toggles_layout->addRow(label_toggle);
|
||||
|
||||
generate_hotkey_row({FontNoggit::f1}, "\aToggle M2s", toggles_layout);
|
||||
generate_hotkey_row({FontNoggit::f2}, "\aToggle WMO doodads set", toggles_layout);
|
||||
generate_hotkey_row({FontNoggit::f3}, "\aToggle ground", toggles_layout);
|
||||
generate_hotkey_row({FontNoggit::f4}, "\aToggle water", toggles_layout);
|
||||
generate_hotkey_row({FontNoggit::f6}, "\aToggle WMOs", toggles_layout);
|
||||
generate_hotkey_row({FontNoggit::f7}, "\aToggle chunk (red) and ADT (green) lines", toggles_layout);
|
||||
generate_hotkey_row({FontNoggit::f8}, "\aToggle detailed window", toggles_layout);
|
||||
generate_hotkey_row({FontNoggit::f9}, "\aToggle map contour", toggles_layout);
|
||||
generate_hotkey_row({FontNoggit::f10}, "\aToggle wireframe", toggles_layout);
|
||||
generate_hotkey_row({FontNoggit::f11}, "\aToggle model animations", toggles_layout);
|
||||
generate_hotkey_row({FontNoggit::f12}, "\aToggle fog", toggles_layout);
|
||||
generate_hotkey_row({}, "1 - 9 Select the editing modes", toggles_layout);
|
||||
|
||||
auto files_layout(new QFormLayout(this));
|
||||
base_layout->addLayout(files_layout, 1, 0);
|
||||
|
||||
auto label_files = new QLabel("Files:");
|
||||
label_files->setStyleSheet(header_style);
|
||||
files_layout->addRow(label_files);
|
||||
|
||||
generate_hotkey_row({FontNoggit::f5}, "\aSave bookmark", files_layout);
|
||||
generate_hotkey_row({FontNoggit::ctrl, FontNoggit::s}, "\a+\a Save all changed ADT tiles", files_layout);
|
||||
generate_hotkey_row({FontNoggit::ctrl, FontNoggit::shift, FontNoggit::s}, "\a+\a+\aSave ADT tile at camera position", files_layout);
|
||||
generate_hotkey_row({FontNoggit::ctrl, FontNoggit::shift, FontNoggit::a}, "\a+\a+\aSave all loaded ADT tiles", files_layout);
|
||||
generate_hotkey_row({FontNoggit::g}, "\aSave port commands to ports.txt", files_layout);
|
||||
|
||||
auto adjust_layout(new QFormLayout(this));
|
||||
base_layout->addLayout(adjust_layout, 1, 1);
|
||||
|
||||
auto label_adjust = new QLabel("Adjust:");
|
||||
label_adjust->setStyleSheet(header_style);
|
||||
adjust_layout->addRow(label_adjust);
|
||||
|
||||
generate_hotkey_row({FontNoggit::o, FontNoggit::p}, "\aor\aSlower / Faster movement", adjust_layout);
|
||||
generate_hotkey_row({FontNoggit::b, FontNoggit::n}, "\aor\aSlower / Faster time", adjust_layout);
|
||||
generate_hotkey_row({FontNoggit::j}, "\aPause time", adjust_layout);
|
||||
// NYI
|
||||
// generate_hotkey_row({FontNoggit::shift, FontNoggit::plus, FontNoggit::minus}, "\a+\aor\aFog distance when no model is selected", adjust_layout);
|
||||
|
||||
auto flag_widget (new QWidget (this));
|
||||
auto flag_layout (new QFormLayout (flag_widget));
|
||||
|
||||
auto holes_label = new QLabel("Holes:");
|
||||
holes_label->setStyleSheet(header_style);
|
||||
flag_layout->addRow(holes_label);
|
||||
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::lmb}, "\a+\aClear hole", flag_layout);
|
||||
generate_hotkey_row({FontNoggit::ctrl, FontNoggit::lmb}, "\a+\aAdd hole", flag_layout);
|
||||
generate_hotkey_row({FontNoggit::t}, "\aRemove all holes on ADT", flag_layout);
|
||||
generate_hotkey_row({FontNoggit::alt, FontNoggit::t}, "\a+\aRemove all ground on ADT", flag_layout);
|
||||
|
||||
auto impass_flags_label = new QLabel("Impassible Flags:");
|
||||
impass_flags_label->setStyleSheet(header_style);
|
||||
flag_layout->addRow(impass_flags_label);
|
||||
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::lmb }, "\a+\aPaint flag", flag_layout);
|
||||
generate_hotkey_row({FontNoggit::ctrl, FontNoggit::lmb }, "\a+\aClear flag", flag_layout);
|
||||
|
||||
auto areaid_label = new QLabel("AreaID Flags:");
|
||||
areaid_label->setStyleSheet(header_style);
|
||||
flag_layout->addRow(areaid_label);
|
||||
|
||||
generate_hotkey_row({FontNoggit::ctrl, FontNoggit::lmb }, "\a+\aPick existing AreaID", flag_layout);
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::lmb }, "\a+\aPaint selected AreaID", flag_layout);
|
||||
generate_hotkey_row({ FontNoggit::f }, "\a - Fill current ADT with selected AreaID", flag_layout);
|
||||
|
||||
|
||||
auto ground_widget (new QWidget (this));
|
||||
auto ground_layout (new QGridLayout (ground_widget));
|
||||
|
||||
auto ground_column1_layout(new QFormLayout(this));
|
||||
ground_layout->addLayout(ground_column1_layout, 0, 0);
|
||||
|
||||
auto ground_label = new QLabel("Edit ground:");
|
||||
ground_label->setStyleSheet(header_style);
|
||||
ground_column1_layout->addRow(ground_label);
|
||||
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::f1 }, "\a+\aToggle ground edit mode", ground_column1_layout);
|
||||
generate_hotkey_row({FontNoggit::alt, FontNoggit::lmb_drag }, "\a+\aChange brush size", ground_column1_layout);
|
||||
generate_hotkey_row({FontNoggit::space, FontNoggit::lmb_drag }, "\a+\aChange speed", ground_column1_layout);
|
||||
|
||||
auto raise_label = new QLabel("Raise / Lower tool:");
|
||||
raise_label->setStyleSheet(header_style);
|
||||
ground_column1_layout->addRow(raise_label);
|
||||
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::lmb }, "\a+\aRaise terrain", ground_column1_layout);
|
||||
generate_hotkey_row({FontNoggit::ctrl, FontNoggit::lmb }, "\a+\aLower terrain", ground_column1_layout);
|
||||
generate_hotkey_row({FontNoggit::y }, "\aSwitch to next type", ground_column1_layout);
|
||||
generate_hotkey_row({FontNoggit::alt, FontNoggit::rmb_drag }, "\a+\aChange inner radius", ground_column1_layout);
|
||||
|
||||
auto raise_label_vm = new QLabel("Raise / Lower tool (vertex mode):");
|
||||
raise_label_vm->setStyleSheet(header_style);
|
||||
ground_column1_layout->addRow(raise_label_vm);
|
||||
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::lmb }, "\a+\aSelect vertices", ground_column1_layout);
|
||||
generate_hotkey_row({FontNoggit::ctrl, FontNoggit::lmb }, "\a+\aDeselect vertices", ground_column1_layout);
|
||||
generate_hotkey_row({FontNoggit::c }, "\aClear selection", ground_column1_layout);
|
||||
generate_hotkey_row({FontNoggit::space, FontNoggit::f }, "\a+\aFlatten vertices", ground_column1_layout);
|
||||
generate_hotkey_row({FontNoggit::space, FontNoggit::rmb_drag }, "\a+\aOrient vertices toward the mouse cursor", ground_column1_layout);
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::rmb_drag }, "\a+\aChange vertices height", ground_column1_layout);
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::mmb }, "\a+\aChange angle", ground_column1_layout);
|
||||
generate_hotkey_row({FontNoggit::alt, FontNoggit::mmb }, "\a+\aChange orientation", ground_column1_layout);
|
||||
|
||||
auto ground_column2_layout(new QFormLayout(this));
|
||||
ground_layout->addLayout(ground_column2_layout, 0, 1);
|
||||
|
||||
auto flatten_label = new QLabel("Flatten / Blur tool:");
|
||||
flatten_label->setStyleSheet(header_style);
|
||||
ground_column2_layout->addRow(flatten_label);
|
||||
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::lmb }, "\a+\aFlatten terrain", ground_column2_layout);
|
||||
generate_hotkey_row({FontNoggit::ctrl, FontNoggit::lmb }, "\a+\aBlur terrain", ground_column2_layout);
|
||||
generate_hotkey_row({FontNoggit::t }, "\aToggle flatten angle", ground_column2_layout);
|
||||
generate_hotkey_row({FontNoggit::space, FontNoggit::t }, "\a+\aToggle flatten type", ground_column2_layout);
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::mmb }, "\a+\aChange angle", ground_column2_layout);
|
||||
generate_hotkey_row({FontNoggit::alt, FontNoggit::mmb }, "\a+\aChange orientation", ground_column2_layout);
|
||||
generate_hotkey_row({FontNoggit::y }, "\aSwitch to next type", ground_column2_layout);
|
||||
generate_hotkey_row({FontNoggit::f }, "\aSet relative point", ground_column2_layout);
|
||||
generate_hotkey_row({FontNoggit::space, FontNoggit::f }, "\a+\aToggle flatten relative mode", ground_column2_layout);
|
||||
generate_hotkey_row({FontNoggit::space, FontNoggit::mmb }, "\a+\aChange height", ground_column2_layout);
|
||||
|
||||
|
||||
auto texture_widget (new QWidget (this));
|
||||
auto texture_layout (new QFormLayout (texture_widget));
|
||||
|
||||
auto common_controls_label = new QLabel("Common controls:");
|
||||
common_controls_label->setStyleSheet(header_style);
|
||||
texture_layout->addRow(common_controls_label);
|
||||
|
||||
generate_hotkey_row({FontNoggit::ctrl, FontNoggit::lmb }, "\a+\aOpen texture picker for the chunk", texture_layout);
|
||||
|
||||
auto paint_label = new QLabel("Paint:");
|
||||
paint_label->setStyleSheet(header_style);
|
||||
texture_layout->addRow(paint_label);
|
||||
|
||||
generate_hotkey_row({FontNoggit::ctrl, FontNoggit::shift, FontNoggit::alt, FontNoggit::lmb }, "\a+\a+\a+\aErase textures", texture_layout);
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::lmb }, "\a+\aDraw texture or fills if chunk is empty", texture_layout);
|
||||
generate_hotkey_row({FontNoggit::alt, FontNoggit::lmb_drag }, "\a+\aChange radius", texture_layout);
|
||||
generate_hotkey_row({FontNoggit::alt, FontNoggit::rmb_drag }, "\a+\aChange hardness (falloff)", texture_layout);
|
||||
generate_hotkey_row({FontNoggit::space, FontNoggit::lmb_drag }, "\a+\aChange pressure (strength)", texture_layout);
|
||||
generate_hotkey_row({FontNoggit::space, FontNoggit::mmb }, "\a+\aChange opacity (gradient)", texture_layout);
|
||||
generate_hotkey_row({FontNoggit::space, FontNoggit::r }, "\a+\aToggle min and max oapcity (gradient)", texture_layout);
|
||||
generate_hotkey_row({FontNoggit::t }, "\aToggle spray brush", texture_layout);
|
||||
generate_hotkey_row({FontNoggit::alt, FontNoggit::mmb }, "\a+\aChange spray radius", texture_layout);
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::mmb }, "\a+\aChange spray pressure", texture_layout);
|
||||
|
||||
auto swapper_label = new QLabel("Swap:");
|
||||
swapper_label->setStyleSheet(header_style);
|
||||
texture_layout->addRow(swapper_label);
|
||||
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::lmb }, "\a+\aSwap texture", texture_layout);
|
||||
generate_hotkey_row({FontNoggit::alt, FontNoggit::lmb_drag }, "\a+\aChange radius", texture_layout);
|
||||
generate_hotkey_row({FontNoggit::t }, "\aToggle brush swapper", texture_layout);
|
||||
|
||||
auto anim_label = new QLabel("Anim:");
|
||||
anim_label->setStyleSheet(header_style);
|
||||
texture_layout->addRow(anim_label);
|
||||
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::lmb }, "\a+\aUpdate animation", texture_layout);
|
||||
generate_hotkey_row({FontNoggit::t }, "\aSwitch between add/remove animation mode", texture_layout);
|
||||
|
||||
|
||||
auto water_widget (new QWidget (this));
|
||||
auto water_layout (new QFormLayout (water_widget));
|
||||
|
||||
auto water_label = new QLabel("Water:");
|
||||
water_label->setStyleSheet(header_style);
|
||||
water_layout->addRow(water_label);
|
||||
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::lmb }, "\a+\aAdd liquid", water_layout);
|
||||
generate_hotkey_row({FontNoggit::ctrl, FontNoggit::lmb }, "\a+\aRemove liquid", water_layout);
|
||||
generate_hotkey_row({FontNoggit::alt, FontNoggit::lmb_drag }, "\a+\aChange brush size", water_layout);
|
||||
generate_hotkey_row({FontNoggit::t }, "\aToggle angled mode", water_layout);
|
||||
generate_hotkey_row({FontNoggit::alt, FontNoggit::mmb }, "\a+\aChange orientation", water_layout);
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::mmb }, "\a+\aChange angle", water_layout);
|
||||
generate_hotkey_row({FontNoggit::f }, "\aSet lock position to cursor position", water_layout);
|
||||
generate_hotkey_row({FontNoggit::space, FontNoggit::f }, "\a+\aToggle lock mode", water_layout);
|
||||
generate_hotkey_row({FontNoggit::space, FontNoggit::mmb }, "\a+\aChange height", water_layout);
|
||||
|
||||
|
||||
auto object_widget (new QWidget (this));
|
||||
auto object_layout (new QFormLayout (object_widget));
|
||||
|
||||
auto object_label = new QLabel("Edit objects if a model is selected with left click (in object editor):");
|
||||
object_label->setStyleSheet(header_style);
|
||||
object_layout->addRow(object_label);
|
||||
|
||||
generate_hotkey_row({FontNoggit::mmb }, "\aMove object", object_layout);
|
||||
generate_hotkey_row({FontNoggit::alt, FontNoggit::mmb }, "\a+\aScale M2", object_layout);
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::ctrl, FontNoggit::alt, FontNoggit::lmb }, "\aor\aor\a+\aRotate object", object_layout);
|
||||
generate_hotkey_row({FontNoggit::ctrl }, "\a+ 0 - 9 Change doodadset of selected WMO", object_layout);
|
||||
generate_hotkey_row({FontNoggit::ctrl, FontNoggit::r }, "\a+\aReset rotation", object_layout);
|
||||
generate_hotkey_row({FontNoggit::h }, "\aToggle selected model/wmo visibility", object_layout);
|
||||
generate_hotkey_row({FontNoggit::space, FontNoggit::h }, "\a+\a - Hide/Show hidden model/wmo", object_layout);
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::h }, "\a+\a - Clear hidden model/wmo list", object_layout);
|
||||
generate_hotkey_row({FontNoggit::page_down }, "\aSet object to ground level", object_layout);
|
||||
generate_hotkey_row({FontNoggit::ctrl, FontNoggit::c }, "\a+\aCopy object to clipboard", object_layout);
|
||||
generate_hotkey_row({FontNoggit::ctrl, FontNoggit::v }, "\a+\aPaste object on mouse position", object_layout);
|
||||
generate_hotkey_row({FontNoggit::ctrl, FontNoggit::b }, "\a+\aDuplicate selected object to mouse position", object_layout);
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::v }, "\a+\aImport last M2 from WMV", object_layout);
|
||||
generate_hotkey_row({FontNoggit::alt, FontNoggit::v }, "\a+\aImport last WMO from WMV", object_layout);
|
||||
generate_hotkey_row({FontNoggit::t }, "\aSwitch between paste modes", object_layout);
|
||||
generate_hotkey_row({FontNoggit::f }, "\aMove selection to cursor position", object_layout);
|
||||
generate_hotkey_row({FontNoggit::minus, FontNoggit::plus }, "\aor\aScale M2", object_layout);
|
||||
generate_hotkey_row({FontNoggit::num }, "\a 7 or 9 Rotate object", object_layout);
|
||||
generate_hotkey_row({FontNoggit::num }, "\a 4 or 8 or 6 or 2 Vertical position", object_layout);
|
||||
generate_hotkey_row({FontNoggit::num }, "\a 1 or 3 Move up/down", object_layout);
|
||||
generate_hotkey_row({FontNoggit::shift }, "Holding \a 1 / 3 Double speed", object_layout);
|
||||
generate_hotkey_row({FontNoggit::ctrl }, "Holding \a 1 / 3 Triple speed", object_layout);
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::ctrl }, "Holding \a and \a Half speed", object_layout);
|
||||
|
||||
auto shader_widget (new QWidget (this));
|
||||
auto shader_layout (new QFormLayout (shader_widget));
|
||||
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::lmb }, "\a+\aAdd shader", shader_layout);
|
||||
generate_hotkey_row({FontNoggit::ctrl, FontNoggit::lmb }, "\a+\aRemove shader", shader_layout);
|
||||
generate_hotkey_row({FontNoggit::alt, FontNoggit::lmb_drag }, "\a+\aChange brush size", shader_layout);
|
||||
generate_hotkey_row({FontNoggit::space, FontNoggit::lmb_drag }, "\a+\aChange speed", shader_layout);
|
||||
generate_hotkey_row({FontNoggit::mmb }, "\aPick shader color from the ground", shader_layout);
|
||||
generate_hotkey_row({FontNoggit::plus }, "\aAdd current color to palette", shader_layout);
|
||||
|
||||
layout->addWidget(tabs);
|
||||
tabs->addTab(base_widget, "Basic");
|
||||
tabs->addTab(ground_widget, "Terrain Editors");
|
||||
tabs->addTab(texture_widget, "Texture Painter");
|
||||
tabs->addTab(water_widget, "Water Editor");
|
||||
tabs->addTab(object_widget, "Object Editor");
|
||||
tabs->addTab(shader_widget, "Vertex Painter");
|
||||
tabs->addTab(flag_widget, "Impass Flag / Hole Cutter / Area ID");
|
||||
}
|
||||
|
||||
|
||||
void help::generate_hotkey_row(std::initializer_list<FontNoggit::Icons>&& hotkeys, const char* description, QFormLayout* layout)
|
||||
{
|
||||
auto row_layout = new QHBoxLayout(this);
|
||||
|
||||
const char* from = nullptr;
|
||||
auto icon = hotkeys.begin();
|
||||
|
||||
while (*description)
|
||||
{
|
||||
if (*description == '\a')
|
||||
{
|
||||
if (from)
|
||||
{
|
||||
auto label = new QLabel(::std::string(from, description - from).c_str());
|
||||
row_layout->addWidget(label);
|
||||
}
|
||||
|
||||
auto label = new QLabel(this);
|
||||
QIcon hotkey_icon = FontNoggitIcon(*icon++);
|
||||
label->setPixmap(hotkey_icon.pixmap(22, 22));
|
||||
row_layout->addWidget(label);
|
||||
|
||||
from = ++description;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!from)
|
||||
{
|
||||
from = description;
|
||||
}
|
||||
++description;
|
||||
}
|
||||
}
|
||||
|
||||
if (from && *from)
|
||||
{
|
||||
auto label = new QLabel(from);
|
||||
row_layout->addWidget(label);
|
||||
}
|
||||
|
||||
row_layout->setAlignment(Qt::AlignLeft);
|
||||
layout->addRow(row_layout);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#include <noggit/ui/Help.h>
|
||||
#include <noggit/ui/FontNoggit.hpp>
|
||||
|
||||
#include <QtWidgets/QFormLayout>
|
||||
#include <QtWidgets/QHBoxLayout>
|
||||
#include <QtWidgets/QLabel>
|
||||
#include <QtWidgets/QScrollArea>
|
||||
#include <QtWidgets/QTabWidget>
|
||||
|
||||
#include <initializer_list>
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
namespace Ui
|
||||
{
|
||||
|
||||
help::help(QWidget* parent)
|
||||
: widget (parent, Qt::Window)
|
||||
{
|
||||
setWindowTitle ("Help");
|
||||
setWindowIcon (QIcon (":/icon"));
|
||||
setWindowFlags(Qt::Window | Qt::WindowStaysOnTopHint);
|
||||
|
||||
QString header_style =
|
||||
"QLabel { \n "
|
||||
" font-weight: bold; \n "
|
||||
" margin-top: 8px; \n "
|
||||
" margin-bottom: 4px; \n "
|
||||
" margin-left: 150px; \n "
|
||||
"} \n ";
|
||||
|
||||
|
||||
auto layout (new QFormLayout (this));
|
||||
layout->setSizeConstraint(QLayout::SetFixedSize);
|
||||
|
||||
auto tabs (new QTabWidget (this));
|
||||
|
||||
auto base_widget (new QWidget (this));
|
||||
auto base_layout(new QGridLayout (base_widget));
|
||||
|
||||
|
||||
auto basic_controls_layout (new QFormLayout (this));
|
||||
base_layout->addLayout(basic_controls_layout, 0, 0);
|
||||
|
||||
base_widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
|
||||
auto label = new QLabel("Basic controls:");
|
||||
label->setStyleSheet(header_style);
|
||||
basic_controls_layout->addRow(label);
|
||||
|
||||
generate_hotkey_row({FontNoggit::rmb_drag}, "\aRotate camera", basic_controls_layout);
|
||||
generate_hotkey_row({FontNoggit::lmb}, "\aSelect chunk or object", basic_controls_layout);
|
||||
generate_hotkey_row({FontNoggit::i}, "\aInvert mouse up and down", basic_controls_layout);
|
||||
generate_hotkey_row({FontNoggit::q, FontNoggit::e}, "\a,\aMove up and down", basic_controls_layout);
|
||||
generate_hotkey_row({FontNoggit::w, FontNoggit::a , FontNoggit::s , FontNoggit::d}, "\a\a\a\aMove left, right, forward, backwards", basic_controls_layout);
|
||||
generate_hotkey_row({FontNoggit::home}, "\aMove position to the cursor", basic_controls_layout);
|
||||
generate_hotkey_row({FontNoggit::m}, "\aShow map", basic_controls_layout);
|
||||
generate_hotkey_row({FontNoggit::u}, "\a2D texture editor", basic_controls_layout);
|
||||
generate_hotkey_row({FontNoggit::ctrl, FontNoggit::f1}, "\a+\aThis help", basic_controls_layout);
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::j}, "\a+\aReload an adt under the camera", basic_controls_layout);
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::r}, "\a+\aTurn camera 180 degrees", basic_controls_layout);
|
||||
generate_hotkey_row({FontNoggit::shift}, "\a+ 1, 2, 3 or 4 Set a predefined camera speed", basic_controls_layout);
|
||||
generate_hotkey_row({FontNoggit::alt, FontNoggit::f4}, "\a+\aExit to main menu", basic_controls_layout);
|
||||
generate_hotkey_row({FontNoggit::l}, "\aToggle top view (hint: it's faster to use with graphic tablet stylus buttons)", basic_controls_layout);
|
||||
generate_hotkey_row({}, "", basic_controls_layout); // padding
|
||||
|
||||
auto toggles_layout(new QFormLayout(this));
|
||||
base_layout->addLayout(toggles_layout, 0, 1);
|
||||
|
||||
auto label_toggle = new QLabel("Toggles:");
|
||||
label_toggle->setStyleSheet(header_style);
|
||||
toggles_layout->addRow(label_toggle);
|
||||
|
||||
generate_hotkey_row({FontNoggit::f1}, "\aToggle M2s", toggles_layout);
|
||||
generate_hotkey_row({FontNoggit::f2}, "\aToggle WMO doodads set", toggles_layout);
|
||||
generate_hotkey_row({FontNoggit::f3}, "\aToggle ground", toggles_layout);
|
||||
generate_hotkey_row({FontNoggit::f4}, "\aToggle water", toggles_layout);
|
||||
generate_hotkey_row({FontNoggit::f6}, "\aToggle WMOs", toggles_layout);
|
||||
generate_hotkey_row({FontNoggit::f7}, "\aToggle chunk (red) and ADT (green) lines", toggles_layout);
|
||||
generate_hotkey_row({FontNoggit::f8}, "\aToggle detailed window", toggles_layout);
|
||||
generate_hotkey_row({FontNoggit::f9}, "\aToggle map contour", toggles_layout);
|
||||
generate_hotkey_row({FontNoggit::f10}, "\aToggle wireframe", toggles_layout);
|
||||
generate_hotkey_row({FontNoggit::f11}, "\aToggle model animations", toggles_layout);
|
||||
generate_hotkey_row({FontNoggit::f12}, "\aToggle fog", toggles_layout);
|
||||
generate_hotkey_row({}, "1 - 9 Select the editing modes", toggles_layout);
|
||||
|
||||
auto files_layout(new QFormLayout(this));
|
||||
base_layout->addLayout(files_layout, 1, 0);
|
||||
|
||||
auto label_files = new QLabel("Files:");
|
||||
label_files->setStyleSheet(header_style);
|
||||
files_layout->addRow(label_files);
|
||||
|
||||
generate_hotkey_row({FontNoggit::f5}, "\aSave bookmark", files_layout);
|
||||
generate_hotkey_row({FontNoggit::ctrl, FontNoggit::s}, "\a+\a Save all changed ADT tiles", files_layout);
|
||||
generate_hotkey_row({FontNoggit::ctrl, FontNoggit::shift, FontNoggit::s}, "\a+\a+\aSave ADT tile at camera position", files_layout);
|
||||
generate_hotkey_row({FontNoggit::ctrl, FontNoggit::shift, FontNoggit::a}, "\a+\a+\aSave all loaded ADT tiles", files_layout);
|
||||
generate_hotkey_row({FontNoggit::g}, "\aSave port commands to ports.txt", files_layout);
|
||||
|
||||
auto adjust_layout(new QFormLayout(this));
|
||||
base_layout->addLayout(adjust_layout, 1, 1);
|
||||
|
||||
auto label_adjust = new QLabel("Adjust:");
|
||||
label_adjust->setStyleSheet(header_style);
|
||||
adjust_layout->addRow(label_adjust);
|
||||
|
||||
generate_hotkey_row({FontNoggit::o, FontNoggit::p}, "\aor\aSlower / Faster movement", adjust_layout);
|
||||
generate_hotkey_row({FontNoggit::b, FontNoggit::n}, "\aor\aSlower / Faster time", adjust_layout);
|
||||
generate_hotkey_row({FontNoggit::j}, "\aPause time", adjust_layout);
|
||||
// NYI
|
||||
// generate_hotkey_row({FontNoggit::shift, FontNoggit::plus, FontNoggit::minus}, "\a+\aor\aFog distance when no model is selected", adjust_layout);
|
||||
|
||||
auto flag_widget (new QWidget (this));
|
||||
auto flag_layout (new QFormLayout (flag_widget));
|
||||
|
||||
auto holes_label = new QLabel("Holes:");
|
||||
holes_label->setStyleSheet(header_style);
|
||||
flag_layout->addRow(holes_label);
|
||||
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::lmb}, "\a+\aClear hole", flag_layout);
|
||||
generate_hotkey_row({FontNoggit::ctrl, FontNoggit::lmb}, "\a+\aAdd hole", flag_layout);
|
||||
generate_hotkey_row({FontNoggit::t}, "\aRemove all holes on ADT", flag_layout);
|
||||
generate_hotkey_row({FontNoggit::alt, FontNoggit::t}, "\a+\aRemove all ground on ADT", flag_layout);
|
||||
|
||||
auto impass_flags_label = new QLabel("Impassible Flags:");
|
||||
impass_flags_label->setStyleSheet(header_style);
|
||||
flag_layout->addRow(impass_flags_label);
|
||||
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::lmb }, "\a+\aPaint flag", flag_layout);
|
||||
generate_hotkey_row({FontNoggit::ctrl, FontNoggit::lmb }, "\a+\aClear flag", flag_layout);
|
||||
|
||||
auto areaid_label = new QLabel("AreaID Flags:");
|
||||
areaid_label->setStyleSheet(header_style);
|
||||
flag_layout->addRow(areaid_label);
|
||||
|
||||
generate_hotkey_row({FontNoggit::ctrl, FontNoggit::lmb }, "\a+\aPick existing AreaID", flag_layout);
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::lmb }, "\a+\aPaint selected AreaID", flag_layout);
|
||||
generate_hotkey_row({ FontNoggit::f }, "\a - Fill current ADT with selected AreaID", flag_layout);
|
||||
|
||||
|
||||
auto ground_widget (new QWidget (this));
|
||||
auto ground_layout (new QGridLayout (ground_widget));
|
||||
|
||||
auto ground_column1_layout(new QFormLayout(this));
|
||||
ground_layout->addLayout(ground_column1_layout, 0, 0);
|
||||
|
||||
auto ground_label = new QLabel("Edit ground:");
|
||||
ground_label->setStyleSheet(header_style);
|
||||
ground_column1_layout->addRow(ground_label);
|
||||
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::f1 }, "\a+\aToggle ground edit mode", ground_column1_layout);
|
||||
generate_hotkey_row({FontNoggit::alt, FontNoggit::lmb_drag }, "\a+\aChange brush size", ground_column1_layout);
|
||||
generate_hotkey_row({FontNoggit::space, FontNoggit::lmb_drag }, "\a+\aChange speed", ground_column1_layout);
|
||||
|
||||
auto raise_label = new QLabel("Raise / Lower tool:");
|
||||
raise_label->setStyleSheet(header_style);
|
||||
ground_column1_layout->addRow(raise_label);
|
||||
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::lmb }, "\a+\aRaise terrain", ground_column1_layout);
|
||||
generate_hotkey_row({FontNoggit::ctrl, FontNoggit::lmb }, "\a+\aLower terrain", ground_column1_layout);
|
||||
generate_hotkey_row({FontNoggit::y }, "\aSwitch to next type", ground_column1_layout);
|
||||
generate_hotkey_row({FontNoggit::alt, FontNoggit::rmb_drag }, "\a+\aChange inner radius", ground_column1_layout);
|
||||
|
||||
auto raise_label_vm = new QLabel("Raise / Lower tool (vertex mode):");
|
||||
raise_label_vm->setStyleSheet(header_style);
|
||||
ground_column1_layout->addRow(raise_label_vm);
|
||||
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::lmb }, "\a+\aSelect vertices", ground_column1_layout);
|
||||
generate_hotkey_row({FontNoggit::ctrl, FontNoggit::lmb }, "\a+\aDeselect vertices", ground_column1_layout);
|
||||
generate_hotkey_row({FontNoggit::c }, "\aClear selection", ground_column1_layout);
|
||||
generate_hotkey_row({FontNoggit::space, FontNoggit::f }, "\a+\aFlatten vertices", ground_column1_layout);
|
||||
generate_hotkey_row({FontNoggit::space, FontNoggit::rmb_drag }, "\a+\aOrient vertices toward the mouse cursor", ground_column1_layout);
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::rmb_drag }, "\a+\aChange vertices height", ground_column1_layout);
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::mmb }, "\a+\aChange angle", ground_column1_layout);
|
||||
generate_hotkey_row({FontNoggit::alt, FontNoggit::mmb }, "\a+\aChange orientation", ground_column1_layout);
|
||||
|
||||
auto ground_column2_layout(new QFormLayout(this));
|
||||
ground_layout->addLayout(ground_column2_layout, 0, 1);
|
||||
|
||||
auto flatten_label = new QLabel("Flatten / Blur tool:");
|
||||
flatten_label->setStyleSheet(header_style);
|
||||
ground_column2_layout->addRow(flatten_label);
|
||||
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::lmb }, "\a+\aFlatten terrain", ground_column2_layout);
|
||||
generate_hotkey_row({FontNoggit::ctrl, FontNoggit::lmb }, "\a+\aBlur terrain", ground_column2_layout);
|
||||
generate_hotkey_row({FontNoggit::t }, "\aToggle flatten angle", ground_column2_layout);
|
||||
generate_hotkey_row({FontNoggit::space, FontNoggit::t }, "\a+\aToggle flatten type", ground_column2_layout);
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::mmb }, "\a+\aChange angle", ground_column2_layout);
|
||||
generate_hotkey_row({FontNoggit::alt, FontNoggit::mmb }, "\a+\aChange orientation", ground_column2_layout);
|
||||
generate_hotkey_row({FontNoggit::y }, "\aSwitch to next type", ground_column2_layout);
|
||||
generate_hotkey_row({FontNoggit::f }, "\aSet relative point", ground_column2_layout);
|
||||
generate_hotkey_row({FontNoggit::space, FontNoggit::f }, "\a+\aToggle flatten relative mode", ground_column2_layout);
|
||||
generate_hotkey_row({FontNoggit::space, FontNoggit::mmb }, "\a+\aChange height", ground_column2_layout);
|
||||
|
||||
|
||||
auto texture_widget (new QWidget (this));
|
||||
auto texture_layout (new QFormLayout (texture_widget));
|
||||
|
||||
auto common_controls_label = new QLabel("Common controls:");
|
||||
common_controls_label->setStyleSheet(header_style);
|
||||
texture_layout->addRow(common_controls_label);
|
||||
|
||||
generate_hotkey_row({FontNoggit::ctrl, FontNoggit::lmb }, "\a+\aOpen texture picker for the chunk", texture_layout);
|
||||
|
||||
auto paint_label = new QLabel("Paint:");
|
||||
paint_label->setStyleSheet(header_style);
|
||||
texture_layout->addRow(paint_label);
|
||||
|
||||
generate_hotkey_row({FontNoggit::ctrl, FontNoggit::shift, FontNoggit::alt, FontNoggit::lmb }, "\a+\a+\a+\aErase textures", texture_layout);
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::lmb }, "\a+\aDraw texture or fills if chunk is empty", texture_layout);
|
||||
generate_hotkey_row({FontNoggit::alt, FontNoggit::lmb_drag }, "\a+\aChange radius", texture_layout);
|
||||
generate_hotkey_row({FontNoggit::alt, FontNoggit::rmb_drag }, "\a+\aChange hardness (falloff)", texture_layout);
|
||||
generate_hotkey_row({FontNoggit::space, FontNoggit::lmb_drag }, "\a+\aChange pressure (strength)", texture_layout);
|
||||
generate_hotkey_row({FontNoggit::space, FontNoggit::mmb }, "\a+\aChange opacity (gradient)", texture_layout);
|
||||
generate_hotkey_row({FontNoggit::space, FontNoggit::r }, "\a+\aToggle min and max oapcity (gradient)", texture_layout);
|
||||
generate_hotkey_row({FontNoggit::t }, "\aToggle spray brush", texture_layout);
|
||||
generate_hotkey_row({FontNoggit::alt, FontNoggit::mmb }, "\a+\aChange spray radius", texture_layout);
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::mmb }, "\a+\aChange spray pressure", texture_layout);
|
||||
|
||||
auto swapper_label = new QLabel("Swap:");
|
||||
swapper_label->setStyleSheet(header_style);
|
||||
texture_layout->addRow(swapper_label);
|
||||
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::lmb }, "\a+\aSwap texture", texture_layout);
|
||||
generate_hotkey_row({FontNoggit::alt, FontNoggit::lmb_drag }, "\a+\aChange radius", texture_layout);
|
||||
generate_hotkey_row({FontNoggit::t }, "\aToggle brush swapper", texture_layout);
|
||||
|
||||
auto anim_label = new QLabel("Anim:");
|
||||
anim_label->setStyleSheet(header_style);
|
||||
texture_layout->addRow(anim_label);
|
||||
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::lmb }, "\a+\aUpdate animation", texture_layout);
|
||||
generate_hotkey_row({FontNoggit::t }, "\aSwitch between add/remove animation mode", texture_layout);
|
||||
|
||||
|
||||
auto water_widget (new QWidget (this));
|
||||
auto water_layout (new QFormLayout (water_widget));
|
||||
|
||||
auto water_label = new QLabel("Water:");
|
||||
water_label->setStyleSheet(header_style);
|
||||
water_layout->addRow(water_label);
|
||||
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::lmb }, "\a+\aAdd liquid", water_layout);
|
||||
generate_hotkey_row({FontNoggit::ctrl, FontNoggit::lmb }, "\a+\aRemove liquid", water_layout);
|
||||
generate_hotkey_row({FontNoggit::alt, FontNoggit::lmb_drag }, "\a+\aChange brush size", water_layout);
|
||||
generate_hotkey_row({FontNoggit::t }, "\aToggle angled mode", water_layout);
|
||||
generate_hotkey_row({FontNoggit::alt, FontNoggit::mmb }, "\a+\aChange orientation", water_layout);
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::mmb }, "\a+\aChange angle", water_layout);
|
||||
generate_hotkey_row({FontNoggit::f }, "\aSet lock position to cursor position", water_layout);
|
||||
generate_hotkey_row({FontNoggit::space, FontNoggit::f }, "\a+\aToggle lock mode", water_layout);
|
||||
generate_hotkey_row({FontNoggit::space, FontNoggit::mmb }, "\a+\aChange height", water_layout);
|
||||
|
||||
|
||||
auto object_widget (new QWidget (this));
|
||||
auto object_layout (new QFormLayout (object_widget));
|
||||
|
||||
auto object_label = new QLabel("Edit objects if a model is selected with left click (in object editor):");
|
||||
object_label->setStyleSheet(header_style);
|
||||
object_layout->addRow(object_label);
|
||||
|
||||
generate_hotkey_row({FontNoggit::mmb }, "\aMove object", object_layout);
|
||||
generate_hotkey_row({FontNoggit::alt, FontNoggit::mmb }, "\a+\aScale M2", object_layout);
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::ctrl, FontNoggit::alt, FontNoggit::lmb }, "\aor\aor\a+\aRotate object", object_layout);
|
||||
generate_hotkey_row({FontNoggit::ctrl }, "\a+ 0 - 9 Change doodadset of selected WMO", object_layout);
|
||||
generate_hotkey_row({FontNoggit::ctrl, FontNoggit::r }, "\a+\aReset rotation", object_layout);
|
||||
generate_hotkey_row({FontNoggit::h }, "\aToggle selected model/wmo visibility", object_layout);
|
||||
generate_hotkey_row({FontNoggit::space, FontNoggit::h }, "\a+\a - Hide/Show hidden model/wmo", object_layout);
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::h }, "\a+\a - Clear hidden model/wmo list", object_layout);
|
||||
generate_hotkey_row({FontNoggit::page_down }, "\aSet object to ground level", object_layout);
|
||||
generate_hotkey_row({FontNoggit::ctrl, FontNoggit::c }, "\a+\aCopy object to clipboard", object_layout);
|
||||
generate_hotkey_row({FontNoggit::ctrl, FontNoggit::v }, "\a+\aPaste object on mouse position", object_layout);
|
||||
generate_hotkey_row({FontNoggit::ctrl, FontNoggit::b }, "\a+\aDuplicate selected object to mouse position", object_layout);
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::v }, "\a+\aImport last M2 from WMV", object_layout);
|
||||
generate_hotkey_row({FontNoggit::alt, FontNoggit::v }, "\a+\aImport last WMO from WMV", object_layout);
|
||||
generate_hotkey_row({FontNoggit::t }, "\aSwitch between paste modes", object_layout);
|
||||
generate_hotkey_row({FontNoggit::f }, "\aMove selection to cursor position", object_layout);
|
||||
generate_hotkey_row({FontNoggit::minus, FontNoggit::plus }, "\aor\aScale M2", object_layout);
|
||||
generate_hotkey_row({FontNoggit::num }, "\a 7 or 9 Rotate object", object_layout);
|
||||
generate_hotkey_row({FontNoggit::num }, "\a 4 or 8 or 6 or 2 Vertical position", object_layout);
|
||||
generate_hotkey_row({FontNoggit::num }, "\a 1 or 3 Move up/down", object_layout);
|
||||
generate_hotkey_row({FontNoggit::shift }, "Holding \a 1 / 3 Double speed", object_layout);
|
||||
generate_hotkey_row({FontNoggit::ctrl }, "Holding \a 1 / 3 Triple speed", object_layout);
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::ctrl }, "Holding \a and \a Half speed", object_layout);
|
||||
|
||||
auto shader_widget (new QWidget (this));
|
||||
auto shader_layout (new QFormLayout (shader_widget));
|
||||
|
||||
generate_hotkey_row({FontNoggit::shift, FontNoggit::lmb }, "\a+\aAdd shader", shader_layout);
|
||||
generate_hotkey_row({FontNoggit::ctrl, FontNoggit::lmb }, "\a+\aRemove shader", shader_layout);
|
||||
generate_hotkey_row({FontNoggit::alt, FontNoggit::lmb_drag }, "\a+\aChange brush size", shader_layout);
|
||||
generate_hotkey_row({FontNoggit::space, FontNoggit::lmb_drag }, "\a+\aChange speed", shader_layout);
|
||||
generate_hotkey_row({FontNoggit::mmb }, "\aPick shader color from the ground", shader_layout);
|
||||
generate_hotkey_row({FontNoggit::plus }, "\aAdd current color to palette", shader_layout);
|
||||
|
||||
layout->addWidget(tabs);
|
||||
tabs->addTab(base_widget, "Basic");
|
||||
tabs->addTab(ground_widget, "Terrain Editors");
|
||||
tabs->addTab(texture_widget, "Texture Painter");
|
||||
tabs->addTab(water_widget, "Water Editor");
|
||||
tabs->addTab(object_widget, "Object Editor");
|
||||
tabs->addTab(shader_widget, "Vertex Painter");
|
||||
tabs->addTab(flag_widget, "Impass Flag / Hole Cutter / Area ID");
|
||||
}
|
||||
|
||||
|
||||
void help::generate_hotkey_row(std::initializer_list<FontNoggit::Icons>&& hotkeys, const char* description, QFormLayout* layout)
|
||||
{
|
||||
auto row_layout = new QHBoxLayout(this);
|
||||
|
||||
const char* from = nullptr;
|
||||
auto icon = hotkeys.begin();
|
||||
|
||||
while (*description)
|
||||
{
|
||||
if (*description == '\a')
|
||||
{
|
||||
if (from)
|
||||
{
|
||||
auto label = new QLabel(::std::string(from, description - from).c_str());
|
||||
row_layout->addWidget(label);
|
||||
}
|
||||
|
||||
auto label = new QLabel(this);
|
||||
QIcon hotkey_icon = FontNoggitIcon(*icon++);
|
||||
label->setPixmap(hotkey_icon.pixmap(22, 22));
|
||||
row_layout->addWidget(label);
|
||||
|
||||
from = ++description;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!from)
|
||||
{
|
||||
from = description;
|
||||
}
|
||||
++description;
|
||||
}
|
||||
}
|
||||
|
||||
if (from && *from)
|
||||
{
|
||||
auto label = new QLabel(from);
|
||||
row_layout->addWidget(label);
|
||||
}
|
||||
|
||||
row_layout->setAlignment(Qt::AlignLeft);
|
||||
layout->addRow(row_layout);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -827,17 +827,17 @@ namespace Noggit
|
||||
// Buttons
|
||||
connect(cur_adt_btn, &QPushButton::clicked, [=]() {
|
||||
_render_settings.export_mode = MinimapGenMode::CURRENT_ADT;
|
||||
mapView->initMinimapSave();
|
||||
emit onSave();
|
||||
});
|
||||
|
||||
connect(sel_adts_btn, &QPushButton::clicked, [=]() {
|
||||
_render_settings.export_mode = MinimapGenMode::SELECTED_ADTS;
|
||||
mapView->initMinimapSave();
|
||||
emit onSave();
|
||||
});
|
||||
|
||||
connect(all_adts_btn, &QPushButton::clicked, [=]() {
|
||||
_render_settings.export_mode = MinimapGenMode::MAP;
|
||||
mapView->initMinimapSave();
|
||||
emit onSave();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@@ -15,53 +15,13 @@
|
||||
#include <array>
|
||||
#include <glm/vec4.hpp>
|
||||
|
||||
#include <noggit/MinimapRenderSettings.hpp>
|
||||
#include <noggit/ui/minimap_widget.hpp>
|
||||
|
||||
|
||||
class MapView;
|
||||
class World;
|
||||
|
||||
enum MinimapGenMode
|
||||
{
|
||||
CURRENT_ADT,
|
||||
SELECTED_ADTS,
|
||||
MAP
|
||||
};
|
||||
|
||||
struct MinimapRenderSettings
|
||||
{
|
||||
MinimapGenMode export_mode;
|
||||
std::string file_format = ".blp";
|
||||
|
||||
// Render settings
|
||||
int resolution = 512;
|
||||
bool draw_m2 = false;
|
||||
bool draw_wmo = true;
|
||||
bool draw_water = true;
|
||||
bool draw_adt_grid = false;
|
||||
bool draw_elevation = false;
|
||||
bool draw_shadows = false;
|
||||
bool use_filters = false;
|
||||
bool combined_minimap = false;
|
||||
|
||||
// Selection
|
||||
std::array<bool, 4096> selected_tiles = {false};
|
||||
|
||||
// Filtering
|
||||
QListWidget* m2_model_filter_include;
|
||||
QListWidget* m2_instance_filter_include;
|
||||
QListWidget* wmo_model_filter_exclude;
|
||||
QListWidget* wmo_instance_filter_exclude;
|
||||
|
||||
// Lighting. Based on default eastern kingdom global light settings (lightparams 12)
|
||||
glm::vec3 diffuse_color = {1.0, 0.532352924, 0.0};
|
||||
glm::vec3 ambient_color = {0.407770514, 0.508424163, 0.602650642};
|
||||
glm::vec4 ocean_color_light = {0.0693173409, 0.294008732, 0.348329663, 0.75};
|
||||
glm::vec4 ocean_color_dark = {0.000762581825, 0.113907099, 0.161220074, 1.0};
|
||||
glm::vec4 river_color_light = {0.308351517, 0.363725543, 0.0798838138, 0.5};
|
||||
glm::vec4 river_color_dark = {0.19945538, 0.320697188, 0.332425594, 1.0};
|
||||
|
||||
};
|
||||
|
||||
|
||||
namespace Noggit
|
||||
@@ -72,6 +32,7 @@ namespace Noggit
|
||||
|
||||
class MinimapCreator : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MinimapCreator(MapView* mapView, World* world, QWidget* parent = nullptr);
|
||||
|
||||
@@ -79,7 +40,8 @@ namespace Noggit
|
||||
|
||||
float brushRadius() const { return _radius; }
|
||||
|
||||
std::array<bool, 4096>* getSelectedTiles() { return &_render_settings.selected_tiles; };
|
||||
//std::array<bool, 4096>* getSelectedTiles() { return &_render_settings.selected_tiles; };
|
||||
std::vector<char>* getSelectedTiles() { return &_render_settings.selected_tiles; };
|
||||
|
||||
MinimapRenderSettings* getMinimapRenderSettings() { return &_render_settings; };
|
||||
|
||||
@@ -98,6 +60,9 @@ namespace Noggit
|
||||
void loadFiltersFromJSON();
|
||||
void saveFiltersToJSON();
|
||||
|
||||
signals:
|
||||
void onSave();
|
||||
|
||||
private:
|
||||
float _radius = 0.01f;
|
||||
MinimapRenderSettings _render_settings;
|
||||
|
||||
@@ -544,7 +544,9 @@ namespace Noggit
|
||||
|
||||
connect( object_palette_btn
|
||||
, &QPushButton::clicked
|
||||
, [=]() { mapView->getObjectPalette()->setVisible(mapView->getObjectPalette()->isHidden()); }
|
||||
, [=]() {
|
||||
emit objectPaletteBtnPressed();
|
||||
}
|
||||
);
|
||||
|
||||
connect(_doodadSetSelector
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#pragma once
|
||||
#include <noggit/Selection.h>
|
||||
#include <noggit/BoolToggleProperty.hpp>
|
||||
#include <noggit/object_paste_params.hpp>
|
||||
|
||||
#include <QLabel>
|
||||
#include <QWidget>
|
||||
@@ -36,21 +37,11 @@ enum ModelPasteMode
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
struct object_paste_params
|
||||
{
|
||||
float minRotation = -180.f;
|
||||
float maxRotation = 180.f;
|
||||
float minTilt = -5.f;
|
||||
float maxTilt = 5.f;
|
||||
float minScale = 0.9f;
|
||||
float maxScale = 1.1f;
|
||||
bool rotate_on_terrain = true;
|
||||
};
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class object_editor : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
object_editor ( MapView*
|
||||
, World*
|
||||
@@ -94,6 +85,9 @@ namespace Noggit
|
||||
|
||||
void update_selection_ui(World* world);
|
||||
|
||||
signals:
|
||||
void objectPaletteBtnPressed();
|
||||
|
||||
private:
|
||||
float _radius = 0.01f;
|
||||
float _drag_selection_depth = 100.0f;
|
||||
|
||||
@@ -273,9 +273,7 @@ namespace Noggit
|
||||
matrix.rotateRadians(_image_mask_group->getRotation() / 360.0f * 2.0f * M_PI);
|
||||
_mask_image = pixmap->toImage().transformed(matrix, Qt::SmoothTransformation);
|
||||
|
||||
if (_map_view->get_editing_mode() != editing_mode::stamp
|
||||
|| (_map_view->getActiveStampModeItem() && _map_view->getActiveStampModeItem() == this))
|
||||
_map_view->setBrushTexture(&_mask_image);
|
||||
emit _map_view->trySetBrushTexture(&_mask_image, this);
|
||||
}
|
||||
|
||||
QJsonObject ShaderTool::toJSON()
|
||||
|
||||
@@ -241,9 +241,7 @@ namespace Noggit
|
||||
matrix.rotateRadians(_image_mask_group->getRotation() / 360.0f * 2.0f * M_PI);
|
||||
_mask_image = pixmap->toImage().transformed(matrix, Qt::SmoothTransformation);
|
||||
|
||||
if (_map_view->get_editing_mode() != editing_mode::stamp
|
||||
|| (_map_view->getActiveStampModeItem() && _map_view->getActiveStampModeItem() == this))
|
||||
_map_view->setBrushTexture(&_mask_image);
|
||||
emit _map_view->trySetBrushTexture(&_mask_image, this);
|
||||
}
|
||||
|
||||
void TerrainTool::changeTerrain
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#include <noggit/Tool.hpp>
|
||||
#include <noggit/ui/Toolbar.h>
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
namespace Ui
|
||||
{
|
||||
toolbar::toolbar(std::function<void (editing_mode)> set_editing_mode)
|
||||
toolbar::toolbar(std::vector<std::unique_ptr<Noggit::Tool>> const& tools, std::function<void (editing_mode)> set_editing_mode)
|
||||
: _set_editing_mode (set_editing_mode)
|
||||
, _tool_group(this)
|
||||
{
|
||||
@@ -14,20 +15,10 @@ namespace Noggit
|
||||
setAllowedAreas(Qt::LeftToolBarArea);
|
||||
setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
|
||||
|
||||
add_tool_icon(editing_mode::ground, tr("Raise / Lower"), FontNoggit::TOOL_RAISE_LOWER);
|
||||
add_tool_icon(editing_mode::flatten_blur, tr("Flatten / Blur"), FontNoggit::TOOL_FLATTEN_BLUR);
|
||||
add_tool_icon(editing_mode::paint, tr("Texture Painter"), FontNoggit::TOOL_TEXTURE_PAINT);
|
||||
add_tool_icon(editing_mode::holes, tr("Hole Cutter"), FontNoggit::TOOL_HOLE_CUTTER);
|
||||
add_tool_icon(editing_mode::areaid, tr("Area Designator"), FontNoggit::TOOL_AREA_DESIGNATOR);
|
||||
add_tool_icon(editing_mode::impass, tr("Impass Designator"), FontNoggit::TOOL_IMPASS_DESIGNATOR);
|
||||
add_tool_icon(editing_mode::water, tr("Water Editor"), FontNoggit::TOOL_WATER_EDITOR);
|
||||
add_tool_icon(editing_mode::mccv, tr("Vertex Painter"), FontNoggit::TOOL_VERTEX_PAINT);
|
||||
add_tool_icon(editing_mode::object, tr("Object Editor"), FontNoggit::TOOL_OBJECT_EDITOR);
|
||||
add_tool_icon(editing_mode::minimap, tr("Minimap Editor"), FontNoggit::TOOL_MINIMAP_EDITOR);
|
||||
add_tool_icon(editing_mode::stamp, tr("Stamp Mode"), FontNoggit::TOOL_STAMP);
|
||||
add_tool_icon(editing_mode::light, tr("Light Editor"), FontNoggit::TOOL_LIGHT);
|
||||
add_tool_icon(editing_mode::scripting, tr("Scripting"), FontNoggit::INFO);
|
||||
add_tool_icon(editing_mode::chunk, tr("Chunk Manipulator"), FontNoggit::INFO);
|
||||
for (auto&& tool : tools)
|
||||
{
|
||||
add_tool_icon(tool->editingMode(), tr(tool->name()), tool->icon());
|
||||
}
|
||||
}
|
||||
|
||||
void toolbar::add_tool_icon(editing_mode mode, const QString& name, const FontNoggit::Icons& icon)
|
||||
|
||||
@@ -12,12 +12,14 @@
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
class Tool;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class toolbar: public QToolBar
|
||||
{
|
||||
public:
|
||||
toolbar(std::function<void (editing_mode)> set_editing_mode);
|
||||
toolbar(std::vector<std::unique_ptr<Noggit::Tool>> const& tools, std::function<void (editing_mode)> set_editing_mode);
|
||||
|
||||
void check_tool(editing_mode);
|
||||
|
||||
|
||||
@@ -1,396 +1,396 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#include <noggit/DBC.h>
|
||||
#include <noggit/Log.h>
|
||||
#include <noggit/Misc.h>
|
||||
#include <noggit/World.h>
|
||||
#include <noggit/ui/pushbutton.hpp>
|
||||
#include <noggit/ui/Water.h>
|
||||
#include <noggit/MapHeaders.h>
|
||||
#include <util/qt/overload.hpp>
|
||||
|
||||
#include <QtWidgets/QButtonGroup>
|
||||
#include <QtWidgets/QCheckBox>
|
||||
#include <QtWidgets/QDoubleSpinBox>
|
||||
#include <QtWidgets/QFormLayout>
|
||||
#include <QtWidgets/QGroupBox>
|
||||
#include <QtWidgets/QComboBox>
|
||||
#include <QtWidgets/QLabel>
|
||||
#include <QtWidgets/QListWidget>
|
||||
#include <QtWidgets/QRadioButton>
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
namespace Ui
|
||||
{
|
||||
water::water ( unsigned_int_property* current_layer
|
||||
, BoolToggleProperty* display_all_layers
|
||||
, QWidget* parent
|
||||
)
|
||||
: QWidget (parent)
|
||||
, _liquid_id(5)
|
||||
, _liquid_type(liquid_basic_types_water)
|
||||
, _radius(10.0f)
|
||||
, _angle(10.0f)
|
||||
, _orientation(0.0f)
|
||||
, _locked(false)
|
||||
, _angled_mode(false)
|
||||
, _override_liquid_id(true)
|
||||
, _override_height(true)
|
||||
, _opacity_mode(auto_opacity)
|
||||
, _custom_opacity_factor(RIVER_OPACITY_VALUE)
|
||||
, _lock_pos(glm::vec3(0.0f, 0.0f, 0.0f))
|
||||
, tile(0, 0)
|
||||
{
|
||||
setMinimumWidth(250);
|
||||
setMaximumWidth(250);
|
||||
|
||||
auto layout (new QFormLayout (this));
|
||||
|
||||
auto brush_group(new QGroupBox("Brush", this));
|
||||
auto brush_layout (new QFormLayout (brush_group));
|
||||
|
||||
_radius_spin = new QDoubleSpinBox (this);
|
||||
_radius_spin->setRange (0.f, 1000.f);
|
||||
connect ( _radius_spin, qOverload<double> (&QDoubleSpinBox::valueChanged)
|
||||
, [&] (float f) { _radius = f; }
|
||||
);
|
||||
_radius_spin->setValue(_radius);
|
||||
brush_layout->addRow ("Radius", _radius_spin);
|
||||
|
||||
waterType = new QComboBox(this);
|
||||
|
||||
for (DBCFile::Iterator i = gLiquidTypeDB.begin(); i != gLiquidTypeDB.end(); ++i)
|
||||
{
|
||||
int liquid_id = i->getInt(LiquidTypeDB::ID);
|
||||
|
||||
// filter WMO liquids
|
||||
if (liquid_id == LIQUID_WMO_Water || liquid_id == LIQUID_WMO_Ocean || liquid_id == LIQUID_WMO_Water_Interior
|
||||
|| liquid_id == LIQUID_WMO_Magma || liquid_id == LIQUID_WMO_Slime)
|
||||
continue;
|
||||
|
||||
std::stringstream ss;
|
||||
ss << liquid_id << "-" << LiquidTypeDB::getLiquidName(liquid_id);
|
||||
waterType->addItem (QString::fromUtf8(ss.str().c_str()), QVariant (liquid_id));
|
||||
|
||||
}
|
||||
|
||||
connect (waterType, qOverload<int> (&QComboBox::currentIndexChanged)
|
||||
, [&]
|
||||
{
|
||||
changeWaterType(waterType->currentData().toInt());
|
||||
|
||||
// change auto opacity based on liquid type
|
||||
if (_opacity_mode == custom_opacity || _opacity_mode == auto_opacity)
|
||||
return;
|
||||
|
||||
// other liquid types shouldn't use opacity(depth)
|
||||
int liquid_type = LiquidTypeDB::getLiquidType(_liquid_id);
|
||||
if (liquid_type == liquid_basic_types_ocean) // ocean
|
||||
{
|
||||
ocean_button->setChecked(true);
|
||||
_opacity_mode = ocean_opacity;
|
||||
}
|
||||
else // water. opacity doesn't matter for lava/slim
|
||||
{
|
||||
river_button->setChecked(true);
|
||||
_opacity_mode = river_opacity;
|
||||
}
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
brush_layout->addRow (waterType);
|
||||
|
||||
layout->addRow (brush_group);
|
||||
|
||||
auto angle_group (new QGroupBox ("Angled mode", this));
|
||||
angle_group->setCheckable (true);
|
||||
angle_group->setChecked (_angled_mode.get());
|
||||
|
||||
|
||||
connect ( &_angled_mode, &BoolToggleProperty::changed
|
||||
, angle_group, &QGroupBox::setChecked
|
||||
);
|
||||
connect ( angle_group, &QGroupBox::toggled
|
||||
, &_angled_mode, &BoolToggleProperty::set
|
||||
);
|
||||
auto angle_layout (new QFormLayout (angle_group));
|
||||
|
||||
_angle_spin = new QDoubleSpinBox (this);
|
||||
_angle_spin->setRange (0.00001f, 89.f);
|
||||
_angle_spin->setSingleStep (2.0f);
|
||||
connect ( _angle_spin, qOverload<double> (&QDoubleSpinBox::valueChanged)
|
||||
, [&] (float f) { _angle = f; }
|
||||
);
|
||||
_angle_spin->setValue(_angle);
|
||||
angle_layout->addRow ("Angle", _angle_spin);
|
||||
|
||||
_orientation_spin = new QDoubleSpinBox (this);
|
||||
_orientation_spin->setRange (0.f, 360.f);
|
||||
_orientation_spin->setWrapping (true);
|
||||
_orientation_spin->setValue(_orientation);
|
||||
_orientation_spin->setSingleStep (5.0f);
|
||||
connect ( _orientation_spin, qOverload<double> (&QDoubleSpinBox::valueChanged)
|
||||
, [&] (float f) { _orientation = f; }
|
||||
);
|
||||
|
||||
angle_layout->addRow ("Orienation", _orientation_spin);
|
||||
|
||||
layout->addRow (angle_group);
|
||||
|
||||
auto lock_group (new QGroupBox ("Lock", this));
|
||||
lock_group->setCheckable (true);
|
||||
lock_group->setChecked (_locked.get());
|
||||
auto lock_layout (new QFormLayout (lock_group));
|
||||
|
||||
lock_layout->addRow("X:", _x_spin = new QDoubleSpinBox (this));
|
||||
lock_layout->addRow("Z:", _z_spin = new QDoubleSpinBox (this));
|
||||
lock_layout->addRow("H:", _h_spin = new QDoubleSpinBox (this));
|
||||
|
||||
_x_spin->setRange (std::numeric_limits<float>::lowest(), std::numeric_limits<float>::max());
|
||||
_z_spin->setRange (std::numeric_limits<float>::lowest(), std::numeric_limits<float>::max());
|
||||
_h_spin->setRange (std::numeric_limits<float>::lowest(), std::numeric_limits<float>::max());
|
||||
_x_spin->setDecimals (2);
|
||||
_z_spin->setDecimals (2);
|
||||
_h_spin->setDecimals (2);
|
||||
|
||||
connect ( _x_spin, qOverload<double> (&QDoubleSpinBox::valueChanged)
|
||||
, [&] (float f) { _lock_pos.x = f; }
|
||||
);
|
||||
connect ( _z_spin, qOverload<double> (&QDoubleSpinBox::valueChanged)
|
||||
, [&] (float f) { _lock_pos.z = f; }
|
||||
);
|
||||
connect ( _h_spin, qOverload<double> (&QDoubleSpinBox::valueChanged)
|
||||
, [&] (float f) { _lock_pos.y = f; }
|
||||
);
|
||||
|
||||
connect ( &_locked, &BoolToggleProperty::changed
|
||||
, lock_group, &QGroupBox::setChecked
|
||||
);
|
||||
connect ( lock_group, &QGroupBox::toggled
|
||||
, &_locked, &BoolToggleProperty::set
|
||||
);
|
||||
|
||||
layout->addRow(lock_group);
|
||||
|
||||
auto override_group (new QGroupBox ("Override", this));
|
||||
auto override_layout (new QFormLayout (override_group));
|
||||
|
||||
override_layout->addWidget (new CheckBox ("Liquid ID", &_override_liquid_id, this));
|
||||
override_layout->addWidget (new CheckBox ("Height", &_override_height, this));
|
||||
|
||||
layout->addRow(override_group);
|
||||
|
||||
auto opacity_group (new QGroupBox ("Auto opacity", this));
|
||||
auto opacity_layout (new QFormLayout (opacity_group));
|
||||
|
||||
auto auto_button(new QRadioButton("Auto", this));
|
||||
auto_button->setToolTip("Automatically uses river or ocean opacity based on liquid type.");
|
||||
river_button = new QRadioButton ("River", this);
|
||||
river_button->setToolTip(std::to_string(RIVER_OPACITY_VALUE).c_str());
|
||||
ocean_button = new QRadioButton ("Ocean", this);
|
||||
ocean_button->setToolTip(std::to_string(OCEAN_OPACITY_VALUE).c_str());
|
||||
custom_button = new QRadioButton ("Custom factor:", this);
|
||||
|
||||
transparency_toggle = new QButtonGroup (this);
|
||||
transparency_toggle->addButton(auto_button, auto_opacity);
|
||||
transparency_toggle->addButton (river_button, river_opacity);
|
||||
transparency_toggle->addButton (ocean_button, ocean_opacity);
|
||||
transparency_toggle->addButton (custom_button, custom_opacity);
|
||||
|
||||
connect ( transparency_toggle, qOverload<int> (&QButtonGroup::idClicked)
|
||||
, [&] (int id) { _opacity_mode = id; }
|
||||
);
|
||||
|
||||
opacity_layout->addRow(auto_button);
|
||||
opacity_layout->addRow (river_button);
|
||||
opacity_layout->addRow (ocean_button);
|
||||
opacity_layout->addRow (custom_button);
|
||||
|
||||
transparency_toggle->button (_opacity_mode)->setChecked (true);
|
||||
|
||||
QDoubleSpinBox *opacity_spin = new QDoubleSpinBox (this);
|
||||
opacity_spin->setRange (0.f, 1.f);
|
||||
opacity_spin->setDecimals (4);
|
||||
opacity_spin->setSingleStep (0.02f);
|
||||
opacity_spin->setValue(_custom_opacity_factor);
|
||||
connect ( opacity_spin, qOverload<double> (&QDoubleSpinBox::valueChanged)
|
||||
, [&] (float f) { _custom_opacity_factor = f; }
|
||||
);
|
||||
opacity_layout->addRow (opacity_spin);
|
||||
|
||||
layout->addRow (opacity_group);
|
||||
|
||||
layout->addRow ( new pushbutton
|
||||
( "Regen ADT opacity"
|
||||
, [this]
|
||||
{
|
||||
emit regenerate_water_opacity
|
||||
(get_opacity_factor());
|
||||
}
|
||||
)
|
||||
);
|
||||
layout->addRow ( new pushbutton
|
||||
( "Crop water"
|
||||
, [this]
|
||||
{
|
||||
emit crop_water();
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
auto layer_group (new QGroupBox ("Layers", this));
|
||||
auto layer_layout (new QFormLayout (layer_group));
|
||||
|
||||
layer_layout->addRow (new CheckBox("Show all layers", display_all_layers));
|
||||
layer_layout->addRow (new QLabel("Current layer:", this));
|
||||
|
||||
waterLayer = new QSpinBox (this);
|
||||
waterLayer->setValue (current_layer->get());
|
||||
waterLayer->setRange (0, 100);
|
||||
layer_layout->addRow (waterLayer);
|
||||
|
||||
layout->addRow (layer_group);
|
||||
|
||||
connect ( waterLayer, qOverload<int> (&QSpinBox::valueChanged)
|
||||
, current_layer, &unsigned_int_property::set
|
||||
);
|
||||
connect ( current_layer, &unsigned_int_property::changed
|
||||
, waterLayer, &QSpinBox::setValue
|
||||
);
|
||||
|
||||
updateData();
|
||||
|
||||
}
|
||||
|
||||
void water::updatePos(TileIndex const& newTile)
|
||||
{
|
||||
if (newTile == tile) return;
|
||||
|
||||
tile = newTile;
|
||||
|
||||
updateData();
|
||||
}
|
||||
|
||||
void water::updateData()
|
||||
{
|
||||
std::stringstream mt;
|
||||
mt << _liquid_id << " - " << LiquidTypeDB::getLiquidName(_liquid_id);
|
||||
waterType->setCurrentText (QString::fromStdString (mt.str()));
|
||||
_liquid_type = static_cast<liquid_basic_types>(LiquidTypeDB::getLiquidType(_liquid_id));
|
||||
}
|
||||
|
||||
void water::changeWaterType(int waterint)
|
||||
{
|
||||
_liquid_id = waterint;
|
||||
|
||||
updateData();
|
||||
}
|
||||
|
||||
void water::changeRadius(float change)
|
||||
{
|
||||
_radius_spin->setValue(_radius + change);
|
||||
}
|
||||
|
||||
void water::setRadius(float radius)
|
||||
{
|
||||
_radius_spin->setValue(radius);
|
||||
}
|
||||
|
||||
void water::changeOrientation(float change)
|
||||
{
|
||||
_orientation += change;
|
||||
|
||||
while (_orientation >= 360.0f)
|
||||
{
|
||||
_orientation -= 360.0f;
|
||||
}
|
||||
while (_orientation < 0.0f)
|
||||
{
|
||||
_orientation += 360.0f;
|
||||
}
|
||||
|
||||
_orientation_spin->setValue(_orientation);
|
||||
}
|
||||
|
||||
void water::changeAngle(float change)
|
||||
{
|
||||
_angle_spin->setValue(_angle + change);
|
||||
}
|
||||
|
||||
void water::change_height(float change)
|
||||
{
|
||||
_h_spin->setValue(_lock_pos.y + change);
|
||||
}
|
||||
|
||||
void water::paintLiquid (World* world, glm::vec3 const& pos, bool add)
|
||||
{
|
||||
world->paintLiquid ( pos
|
||||
, _radius
|
||||
, _liquid_id
|
||||
, add
|
||||
, math::degrees (_angled_mode.get() ? _angle : 0.0f)
|
||||
, math::degrees (_angled_mode.get() ? _orientation : 0.0f)
|
||||
, _locked.get()
|
||||
, _lock_pos
|
||||
, _override_height.get()
|
||||
, _override_liquid_id.get()
|
||||
, get_opacity_factor()
|
||||
);
|
||||
}
|
||||
|
||||
void water::lockPos(glm::vec3 const& cursor_pos)
|
||||
{
|
||||
QSignalBlocker const blocker_x(_x_spin);
|
||||
QSignalBlocker const blocker_z(_z_spin);
|
||||
QSignalBlocker const blocker_h(_h_spin);
|
||||
_lock_pos = cursor_pos;
|
||||
|
||||
_x_spin->setValue(_lock_pos.x);
|
||||
_z_spin->setValue(_lock_pos.z);
|
||||
_h_spin->setValue(_lock_pos.y);
|
||||
|
||||
if (!_locked.get())
|
||||
{
|
||||
toggle_lock();
|
||||
}
|
||||
}
|
||||
|
||||
void water::toggle_lock()
|
||||
{
|
||||
_locked.toggle();
|
||||
}
|
||||
|
||||
void water::toggle_angled_mode()
|
||||
{
|
||||
_angled_mode.toggle();
|
||||
}
|
||||
|
||||
float water::get_opacity_factor() const
|
||||
{
|
||||
switch (_opacity_mode)
|
||||
{
|
||||
default: // values found by experimenting
|
||||
case river_opacity: return RIVER_OPACITY_VALUE;
|
||||
case ocean_opacity: return OCEAN_OPACITY_VALUE;
|
||||
case custom_opacity: return _custom_opacity_factor;
|
||||
case auto_opacity:
|
||||
{
|
||||
switch (_liquid_type)
|
||||
{
|
||||
case 0: return RIVER_OPACITY_VALUE;
|
||||
case 1: return OCEAN_OPACITY_VALUE;
|
||||
default: return RIVER_OPACITY_VALUE; // lava and slime, opacity isn't used
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
QSize water::sizeHint() const
|
||||
{
|
||||
return QSize(250, height());
|
||||
}
|
||||
}
|
||||
}
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#include <noggit/DBC.h>
|
||||
#include <noggit/Log.h>
|
||||
#include <noggit/Misc.h>
|
||||
#include <noggit/World.h>
|
||||
#include <noggit/ui/pushbutton.hpp>
|
||||
#include <noggit/ui/Water.h>
|
||||
#include <noggit/MapHeaders.h>
|
||||
#include <util/qt/overload.hpp>
|
||||
|
||||
#include <QtWidgets/QButtonGroup>
|
||||
#include <QtWidgets/QCheckBox>
|
||||
#include <QtWidgets/QDoubleSpinBox>
|
||||
#include <QtWidgets/QFormLayout>
|
||||
#include <QtWidgets/QGroupBox>
|
||||
#include <QtWidgets/QComboBox>
|
||||
#include <QtWidgets/QLabel>
|
||||
#include <QtWidgets/QListWidget>
|
||||
#include <QtWidgets/QRadioButton>
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
namespace Ui
|
||||
{
|
||||
water::water ( unsigned_int_property* current_layer
|
||||
, BoolToggleProperty* display_all_layers
|
||||
, QWidget* parent
|
||||
)
|
||||
: QWidget (parent)
|
||||
, _liquid_id(5)
|
||||
, _liquid_type(liquid_basic_types_water)
|
||||
, _radius(10.0f)
|
||||
, _angle(10.0f)
|
||||
, _orientation(0.0f)
|
||||
, _locked(false)
|
||||
, _angled_mode(false)
|
||||
, _override_liquid_id(true)
|
||||
, _override_height(true)
|
||||
, _opacity_mode(auto_opacity)
|
||||
, _custom_opacity_factor(RIVER_OPACITY_VALUE)
|
||||
, _lock_pos(glm::vec3(0.0f, 0.0f, 0.0f))
|
||||
, tile(0, 0)
|
||||
{
|
||||
setMinimumWidth(250);
|
||||
setMaximumWidth(250);
|
||||
|
||||
auto layout (new QFormLayout (this));
|
||||
|
||||
auto brush_group(new QGroupBox("Brush", this));
|
||||
auto brush_layout (new QFormLayout (brush_group));
|
||||
|
||||
_radius_spin = new QDoubleSpinBox (this);
|
||||
_radius_spin->setRange (0.f, 1000.f);
|
||||
connect ( _radius_spin, qOverload<double> (&QDoubleSpinBox::valueChanged)
|
||||
, [&] (float f) { _radius = f; }
|
||||
);
|
||||
_radius_spin->setValue(_radius);
|
||||
brush_layout->addRow ("Radius", _radius_spin);
|
||||
|
||||
waterType = new QComboBox(this);
|
||||
|
||||
for (DBCFile::Iterator i = gLiquidTypeDB.begin(); i != gLiquidTypeDB.end(); ++i)
|
||||
{
|
||||
int liquid_id = i->getInt(LiquidTypeDB::ID);
|
||||
|
||||
// filter WMO liquids
|
||||
if (liquid_id == LIQUID_WMO_Water || liquid_id == LIQUID_WMO_Ocean || liquid_id == LIQUID_WMO_Water_Interior
|
||||
|| liquid_id == LIQUID_WMO_Magma || liquid_id == LIQUID_WMO_Slime)
|
||||
continue;
|
||||
|
||||
std::stringstream ss;
|
||||
ss << liquid_id << "-" << LiquidTypeDB::getLiquidName(liquid_id);
|
||||
waterType->addItem (QString::fromUtf8(ss.str().c_str()), QVariant (liquid_id));
|
||||
|
||||
}
|
||||
|
||||
connect (waterType, qOverload<int> (&QComboBox::currentIndexChanged)
|
||||
, [&]
|
||||
{
|
||||
changeWaterType(waterType->currentData().toInt());
|
||||
|
||||
// change auto opacity based on liquid type
|
||||
if (_opacity_mode == custom_opacity || _opacity_mode == auto_opacity)
|
||||
return;
|
||||
|
||||
// other liquid types shouldn't use opacity(depth)
|
||||
int liquid_type = LiquidTypeDB::getLiquidType(_liquid_id);
|
||||
if (liquid_type == liquid_basic_types_ocean) // ocean
|
||||
{
|
||||
ocean_button->setChecked(true);
|
||||
_opacity_mode = ocean_opacity;
|
||||
}
|
||||
else // water. opacity doesn't matter for lava/slim
|
||||
{
|
||||
river_button->setChecked(true);
|
||||
_opacity_mode = river_opacity;
|
||||
}
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
brush_layout->addRow (waterType);
|
||||
|
||||
layout->addRow (brush_group);
|
||||
|
||||
auto angle_group (new QGroupBox ("Angled mode", this));
|
||||
angle_group->setCheckable (true);
|
||||
angle_group->setChecked (_angled_mode.get());
|
||||
|
||||
|
||||
connect ( &_angled_mode, &BoolToggleProperty::changed
|
||||
, angle_group, &QGroupBox::setChecked
|
||||
);
|
||||
connect ( angle_group, &QGroupBox::toggled
|
||||
, &_angled_mode, &BoolToggleProperty::set
|
||||
);
|
||||
auto angle_layout (new QFormLayout (angle_group));
|
||||
|
||||
_angle_spin = new QDoubleSpinBox (this);
|
||||
_angle_spin->setRange (0.00001f, 89.f);
|
||||
_angle_spin->setSingleStep (2.0f);
|
||||
connect ( _angle_spin, qOverload<double> (&QDoubleSpinBox::valueChanged)
|
||||
, [&] (float f) { _angle = f; }
|
||||
);
|
||||
_angle_spin->setValue(_angle);
|
||||
angle_layout->addRow ("Angle", _angle_spin);
|
||||
|
||||
_orientation_spin = new QDoubleSpinBox (this);
|
||||
_orientation_spin->setRange (0.f, 360.f);
|
||||
_orientation_spin->setWrapping (true);
|
||||
_orientation_spin->setValue(_orientation);
|
||||
_orientation_spin->setSingleStep (5.0f);
|
||||
connect ( _orientation_spin, qOverload<double> (&QDoubleSpinBox::valueChanged)
|
||||
, [&] (float f) { _orientation = f; }
|
||||
);
|
||||
|
||||
angle_layout->addRow ("Orienation", _orientation_spin);
|
||||
|
||||
layout->addRow (angle_group);
|
||||
|
||||
auto lock_group (new QGroupBox ("Lock", this));
|
||||
lock_group->setCheckable (true);
|
||||
lock_group->setChecked (_locked.get());
|
||||
auto lock_layout (new QFormLayout (lock_group));
|
||||
|
||||
lock_layout->addRow("X:", _x_spin = new QDoubleSpinBox (this));
|
||||
lock_layout->addRow("Z:", _z_spin = new QDoubleSpinBox (this));
|
||||
lock_layout->addRow("H:", _h_spin = new QDoubleSpinBox (this));
|
||||
|
||||
_x_spin->setRange (std::numeric_limits<float>::lowest(), std::numeric_limits<float>::max());
|
||||
_z_spin->setRange (std::numeric_limits<float>::lowest(), std::numeric_limits<float>::max());
|
||||
_h_spin->setRange (std::numeric_limits<float>::lowest(), std::numeric_limits<float>::max());
|
||||
_x_spin->setDecimals (2);
|
||||
_z_spin->setDecimals (2);
|
||||
_h_spin->setDecimals (2);
|
||||
|
||||
connect ( _x_spin, qOverload<double> (&QDoubleSpinBox::valueChanged)
|
||||
, [&] (float f) { _lock_pos.x = f; }
|
||||
);
|
||||
connect ( _z_spin, qOverload<double> (&QDoubleSpinBox::valueChanged)
|
||||
, [&] (float f) { _lock_pos.z = f; }
|
||||
);
|
||||
connect ( _h_spin, qOverload<double> (&QDoubleSpinBox::valueChanged)
|
||||
, [&] (float f) { _lock_pos.y = f; }
|
||||
);
|
||||
|
||||
connect ( &_locked, &BoolToggleProperty::changed
|
||||
, lock_group, &QGroupBox::setChecked
|
||||
);
|
||||
connect ( lock_group, &QGroupBox::toggled
|
||||
, &_locked, &BoolToggleProperty::set
|
||||
);
|
||||
|
||||
layout->addRow(lock_group);
|
||||
|
||||
auto override_group (new QGroupBox ("Override", this));
|
||||
auto override_layout (new QFormLayout (override_group));
|
||||
|
||||
override_layout->addWidget (new CheckBox ("Liquid ID", &_override_liquid_id, this));
|
||||
override_layout->addWidget (new CheckBox ("Height", &_override_height, this));
|
||||
|
||||
layout->addRow(override_group);
|
||||
|
||||
auto opacity_group (new QGroupBox ("Auto opacity", this));
|
||||
auto opacity_layout (new QFormLayout (opacity_group));
|
||||
|
||||
auto auto_button(new QRadioButton("Auto", this));
|
||||
auto_button->setToolTip("Automatically uses river or ocean opacity based on liquid type.");
|
||||
river_button = new QRadioButton ("River", this);
|
||||
river_button->setToolTip(std::to_string(RIVER_OPACITY_VALUE).c_str());
|
||||
ocean_button = new QRadioButton ("Ocean", this);
|
||||
ocean_button->setToolTip(std::to_string(OCEAN_OPACITY_VALUE).c_str());
|
||||
custom_button = new QRadioButton ("Custom factor:", this);
|
||||
|
||||
transparency_toggle = new QButtonGroup (this);
|
||||
transparency_toggle->addButton(auto_button, auto_opacity);
|
||||
transparency_toggle->addButton (river_button, river_opacity);
|
||||
transparency_toggle->addButton (ocean_button, ocean_opacity);
|
||||
transparency_toggle->addButton (custom_button, custom_opacity);
|
||||
|
||||
connect ( transparency_toggle, qOverload<int> (&QButtonGroup::idClicked)
|
||||
, [&] (int id) { _opacity_mode = id; }
|
||||
);
|
||||
|
||||
opacity_layout->addRow(auto_button);
|
||||
opacity_layout->addRow (river_button);
|
||||
opacity_layout->addRow (ocean_button);
|
||||
opacity_layout->addRow (custom_button);
|
||||
|
||||
transparency_toggle->button (_opacity_mode)->setChecked (true);
|
||||
|
||||
QDoubleSpinBox *opacity_spin = new QDoubleSpinBox (this);
|
||||
opacity_spin->setRange (0.f, 1.f);
|
||||
opacity_spin->setDecimals (4);
|
||||
opacity_spin->setSingleStep (0.02f);
|
||||
opacity_spin->setValue(_custom_opacity_factor);
|
||||
connect ( opacity_spin, qOverload<double> (&QDoubleSpinBox::valueChanged)
|
||||
, [&] (float f) { _custom_opacity_factor = f; }
|
||||
);
|
||||
opacity_layout->addRow (opacity_spin);
|
||||
|
||||
layout->addRow (opacity_group);
|
||||
|
||||
layout->addRow ( new pushbutton
|
||||
( "Regen ADT opacity"
|
||||
, [this]
|
||||
{
|
||||
emit regenerate_water_opacity
|
||||
(get_opacity_factor());
|
||||
}
|
||||
)
|
||||
);
|
||||
layout->addRow ( new pushbutton
|
||||
( "Crop water"
|
||||
, [this]
|
||||
{
|
||||
emit crop_water();
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
auto layer_group (new QGroupBox ("Layers", this));
|
||||
auto layer_layout (new QFormLayout (layer_group));
|
||||
|
||||
layer_layout->addRow (new CheckBox("Show all layers", display_all_layers));
|
||||
layer_layout->addRow (new QLabel("Current layer:", this));
|
||||
|
||||
waterLayer = new QSpinBox (this);
|
||||
waterLayer->setValue (current_layer->get());
|
||||
waterLayer->setRange (0, 100);
|
||||
layer_layout->addRow (waterLayer);
|
||||
|
||||
layout->addRow (layer_group);
|
||||
|
||||
connect ( waterLayer, qOverload<int> (&QSpinBox::valueChanged)
|
||||
, current_layer, &unsigned_int_property::set
|
||||
);
|
||||
connect ( current_layer, &unsigned_int_property::changed
|
||||
, waterLayer, &QSpinBox::setValue
|
||||
);
|
||||
|
||||
updateData();
|
||||
|
||||
}
|
||||
|
||||
void water::updatePos(TileIndex const& newTile)
|
||||
{
|
||||
if (newTile == tile) return;
|
||||
|
||||
tile = newTile;
|
||||
|
||||
updateData();
|
||||
}
|
||||
|
||||
void water::updateData()
|
||||
{
|
||||
std::stringstream mt;
|
||||
mt << _liquid_id << " - " << LiquidTypeDB::getLiquidName(_liquid_id);
|
||||
waterType->setCurrentText (QString::fromStdString (mt.str()));
|
||||
_liquid_type = static_cast<liquid_basic_types>(LiquidTypeDB::getLiquidType(_liquid_id));
|
||||
}
|
||||
|
||||
void water::changeWaterType(int waterint)
|
||||
{
|
||||
_liquid_id = waterint;
|
||||
|
||||
updateData();
|
||||
}
|
||||
|
||||
void water::changeRadius(float change)
|
||||
{
|
||||
_radius_spin->setValue(_radius + change);
|
||||
}
|
||||
|
||||
void water::setRadius(float radius)
|
||||
{
|
||||
_radius_spin->setValue(radius);
|
||||
}
|
||||
|
||||
void water::changeOrientation(float change)
|
||||
{
|
||||
_orientation += change;
|
||||
|
||||
while (_orientation >= 360.0f)
|
||||
{
|
||||
_orientation -= 360.0f;
|
||||
}
|
||||
while (_orientation < 0.0f)
|
||||
{
|
||||
_orientation += 360.0f;
|
||||
}
|
||||
|
||||
_orientation_spin->setValue(_orientation);
|
||||
}
|
||||
|
||||
void water::changeAngle(float change)
|
||||
{
|
||||
_angle_spin->setValue(_angle + change);
|
||||
}
|
||||
|
||||
void water::change_height(float change)
|
||||
{
|
||||
_h_spin->setValue(_lock_pos.y + change);
|
||||
}
|
||||
|
||||
void water::paintLiquid (World* world, glm::vec3 const& pos, bool add)
|
||||
{
|
||||
world->paintLiquid ( pos
|
||||
, _radius
|
||||
, _liquid_id
|
||||
, add
|
||||
, math::degrees (_angled_mode.get() ? _angle : 0.0f)
|
||||
, math::degrees (_angled_mode.get() ? _orientation : 0.0f)
|
||||
, _locked.get()
|
||||
, _lock_pos
|
||||
, _override_height.get()
|
||||
, _override_liquid_id.get()
|
||||
, get_opacity_factor()
|
||||
);
|
||||
}
|
||||
|
||||
void water::lockPos(glm::vec3 const& cursor_pos)
|
||||
{
|
||||
QSignalBlocker const blocker_x(_x_spin);
|
||||
QSignalBlocker const blocker_z(_z_spin);
|
||||
QSignalBlocker const blocker_h(_h_spin);
|
||||
_lock_pos = cursor_pos;
|
||||
|
||||
_x_spin->setValue(_lock_pos.x);
|
||||
_z_spin->setValue(_lock_pos.z);
|
||||
_h_spin->setValue(_lock_pos.y);
|
||||
|
||||
if (!_locked.get())
|
||||
{
|
||||
toggle_lock();
|
||||
}
|
||||
}
|
||||
|
||||
void water::toggle_lock()
|
||||
{
|
||||
_locked.toggle();
|
||||
}
|
||||
|
||||
void water::toggle_angled_mode()
|
||||
{
|
||||
_angled_mode.toggle();
|
||||
}
|
||||
|
||||
float water::get_opacity_factor() const
|
||||
{
|
||||
switch (_opacity_mode)
|
||||
{
|
||||
default: // values found by experimenting
|
||||
case river_opacity: return RIVER_OPACITY_VALUE;
|
||||
case ocean_opacity: return OCEAN_OPACITY_VALUE;
|
||||
case custom_opacity: return _custom_opacity_factor;
|
||||
case auto_opacity:
|
||||
{
|
||||
switch (_liquid_type)
|
||||
{
|
||||
case 0: return RIVER_OPACITY_VALUE;
|
||||
case 1: return OCEAN_OPACITY_VALUE;
|
||||
default: return RIVER_OPACITY_VALUE; // lava and slime, opacity isn't used
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
QSize water::sizeHint() const
|
||||
{
|
||||
return QSize(250, height());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace Noggit
|
||||
if (!_selected_tiles)
|
||||
return;
|
||||
|
||||
_selected_tiles->fill(false);
|
||||
std::memset(_selected_tiles->data(), false, _selected_tiles->size());
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -41,9 +41,9 @@ namespace Noggit
|
||||
{ _draw_boundaries = draw_boundaries_; update(); return _draw_boundaries; }
|
||||
inline const bool& draw_boundaries() const { return _draw_boundaries; }
|
||||
|
||||
inline const std::array<bool, 4096>* use_selection (std::array<bool, 4096>* selection_)
|
||||
inline const std::vector<char>* use_selection (std::vector<char>* selection_)
|
||||
{ _use_selection = selection_; _selected_tiles = selection_; update(); return _selected_tiles; }
|
||||
inline const std::array<bool, 4096>* selection() const { return _selected_tiles; }
|
||||
inline const std::vector<char>* selection() const { return _selected_tiles; }
|
||||
|
||||
inline void camera (Noggit::Camera* camera) { _camera = camera; }
|
||||
void set_resizeable(bool state) { _resizeable = state; };
|
||||
@@ -66,7 +66,7 @@ namespace Noggit
|
||||
private:
|
||||
World* _world;
|
||||
Noggit::Camera* _camera;
|
||||
std::array<bool, 4096>* _selected_tiles;
|
||||
std::vector<char>* _selected_tiles;
|
||||
|
||||
bool _draw_skies;
|
||||
bool _draw_camera;
|
||||
|
||||
@@ -102,7 +102,7 @@ namespace Noggit
|
||||
|
||||
connect(_object_list, &QListWidget::itemClicked, this, [=](QListWidgetItem* item)
|
||||
{
|
||||
_map_view->getObjectEditor()->copy(item->toolTip().toStdString());
|
||||
emit selected(item->toolTip().toStdString());
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -347,7 +347,7 @@ namespace Noggit
|
||||
connect ( quick_palette_btn, &QPushButton::clicked
|
||||
, [=] ()
|
||||
{
|
||||
_map_view->getTexturePalette()->setVisible(_map_view->getTexturePalette()->isHidden());
|
||||
emit texturePaletteToggled();
|
||||
}
|
||||
);
|
||||
|
||||
@@ -402,9 +402,7 @@ namespace Noggit
|
||||
matrix.rotateRadians(_image_mask_group->getRotation() * M_PI / 180.f);
|
||||
_mask_image = pixmap->toImage().transformed(matrix, Qt::SmoothTransformation);
|
||||
|
||||
if (_map_view->get_editing_mode() != editing_mode::stamp
|
||||
|| (_map_view->getActiveStampModeItem() && _map_view->getActiveStampModeItem() == this))
|
||||
_map_view->setBrushTexture(&_mask_image);
|
||||
emit _map_view->trySetBrushTexture(&_mask_image, this);
|
||||
}
|
||||
|
||||
void texturing_tool::update_brush_hardness()
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <QtWidgets/QWidget>
|
||||
#include <QtWidgets/QListWidget>
|
||||
#include <QJsonObject>
|
||||
#include <QPainter>
|
||||
|
||||
class World;
|
||||
class MapView;
|
||||
@@ -127,6 +128,7 @@ namespace Noggit
|
||||
|
||||
class texturing_tool : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
texturing_tool ( const glm::vec3* camera_pos
|
||||
, MapView* map_view
|
||||
@@ -197,6 +199,9 @@ namespace Noggit
|
||||
QJsonObject toJSON();
|
||||
void fromJSON(QJsonObject const& json);
|
||||
|
||||
signals:
|
||||
void texturePaletteToggled();
|
||||
|
||||
private:
|
||||
void change_tex_flag(World* world, glm::vec3 const& pos, bool add, scoped_blp_texture_reference texture);
|
||||
|
||||
|
||||
@@ -135,14 +135,7 @@ AssetBrowserWidget::AssetBrowserWidget(MapView* map_view, QWidget *parent)
|
||||
ui->viewport->setModel(str_path);
|
||||
_selected_path = str_path;
|
||||
|
||||
if (_browse_mode == asset_browse_mode::detail_doodads && _map_view->get_editing_mode() == editing_mode::paint)
|
||||
{
|
||||
_map_view->getGroundEffectsTool()->setDoodadSlotFromBrowser(str_path.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
_map_view->getObjectEditor()->copy(str_path);
|
||||
}
|
||||
emit selectionChanged(str_path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -91,6 +91,7 @@ namespace Noggit
|
||||
asset_browse_mode _browse_mode = asset_browse_mode::world;
|
||||
signals:
|
||||
void gl_data_unloaded();
|
||||
void selectionChanged(std::string const& path);
|
||||
|
||||
private:
|
||||
::Ui::AssetBrowser* ui;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#include <noggit/MapView.h>
|
||||
#include <noggit/BoolToggleProperty.hpp>
|
||||
#include <noggit/ui/tools/ViewToolbar/Ui/ViewToolbar.hpp>
|
||||
#include <noggit/ui/tools/ActionHistoryNavigator/ActionHistoryNavigator.hpp>
|
||||
#include <noggit/ui/FontAwesome.hpp>
|
||||
@@ -213,15 +215,15 @@ ViewToolbar::ViewToolbar(MapView* mapView, editing_mode mode)
|
||||
IconAction* _icon = new IconAction(FontNoggitIcon{ FontNoggit::TOOL_FLATTEN_BLUR });
|
||||
|
||||
CheckBoxAction* _raise = new CheckBoxAction(tr("Raise"), true);
|
||||
connect(_raise->checkbox(), &QCheckBox::stateChanged, [mapView](int state)
|
||||
connect(_raise->checkbox(), &QCheckBox::stateChanged, [this, mapView](int state)
|
||||
{
|
||||
mapView->getFlattenTool()->_flatten_mode.raise = state;
|
||||
emit updateStateRaise(state != 0);
|
||||
});
|
||||
|
||||
CheckBoxAction* _lower = new CheckBoxAction(tr("Lower"), true);
|
||||
connect(_lower->checkbox(), &QCheckBox::stateChanged, [mapView](int state)
|
||||
connect(_lower->checkbox(), &QCheckBox::stateChanged, [this, mapView](int state)
|
||||
{
|
||||
mapView->getFlattenTool()->_flatten_mode.lower = state;
|
||||
emit updateStateLower(state != 0);
|
||||
});
|
||||
|
||||
|
||||
@@ -434,10 +436,8 @@ bool ViewToolbar::showUnpaintableChunk()
|
||||
return static_cast<SubToolBarAction*>(_texture_secondary_tool[0])->GET<CheckBoxAction*>(unpaintable_chunk_index)->checkbox()->isChecked() && current_mode == editing_mode::paint;
|
||||
}
|
||||
|
||||
void ViewToolbar::nextFlattenMode(MapView* mapView)
|
||||
void ViewToolbar::nextFlattenMode()
|
||||
{
|
||||
mapView->getFlattenTool()->_flatten_mode.next();
|
||||
|
||||
CheckBoxAction* _raise_option = static_cast<SubToolBarAction*>(_flatten_secondary_tool[0])->GET<CheckBoxAction*>(raise_index);
|
||||
CheckBoxAction* _lower_option = static_cast<SubToolBarAction*>(_flatten_secondary_tool[0])->GET<CheckBoxAction*>(lower_index);
|
||||
|
||||
|
||||
@@ -8,17 +8,20 @@
|
||||
#include <QtWidgets/QActionGroup>
|
||||
#include <QtWidgets/QToolBar>
|
||||
|
||||
#include <noggit/MapView.h>
|
||||
#include <noggit/ui/FontNoggit.hpp>
|
||||
#include <noggit/BoolToggleProperty.hpp>
|
||||
#include <noggit/ui/FlattenTool.hpp>
|
||||
|
||||
class MapView;
|
||||
|
||||
namespace Noggit
|
||||
{
|
||||
struct BoolToggleProperty;
|
||||
|
||||
namespace Ui::Tools::ViewToolbar::Ui
|
||||
{
|
||||
class ViewToolbar: public QToolBar
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ViewToolbar(MapView* mapView);
|
||||
ViewToolbar(MapView* mapView, ViewToolbar* tb);
|
||||
@@ -34,7 +37,7 @@ namespace Noggit
|
||||
|
||||
/*secondary left tool*/
|
||||
QVector<QWidgetAction*> _flatten_secondary_tool;
|
||||
void nextFlattenMode(MapView* mapView);
|
||||
void nextFlattenMode();
|
||||
|
||||
QVector<QWidgetAction*> _texture_secondary_tool;
|
||||
bool showUnpaintableChunk();
|
||||
@@ -46,6 +49,10 @@ namespace Noggit
|
||||
bool drawWireframeSphereLight();
|
||||
float getAlphaSphereLight();
|
||||
|
||||
signals:
|
||||
void updateStateRaise(bool newState);
|
||||
void updateStateLower(bool newState);
|
||||
|
||||
private:
|
||||
QActionGroup _tool_group;
|
||||
editing_mode current_mode;
|
||||
|
||||
@@ -289,7 +289,7 @@ void ViewportGizmo::handleTransformGizmo(MapView* map_view
|
||||
|
||||
if (map_view)
|
||||
{
|
||||
map_view->updateRotationEditor();
|
||||
emit map_view->rotationChanged();
|
||||
}
|
||||
|
||||
if (_world)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "LightViewWidget.h"
|
||||
#include <QPainter>
|
||||
|
||||
LightViewWidget::LightViewWidget(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <QStandardPaths>
|
||||
#include <QDir>
|
||||
#include <QIcon>
|
||||
#include <QScrollArea>
|
||||
|
||||
#include <sstream>
|
||||
#include <chrono>
|
||||
|
||||
Reference in New Issue
Block a user