| 1 | /* |
|---|
| 2 | ================================================================================= |
|---|
| 3 | This file is part of Cafu, the open-source game engine and graphics engine |
|---|
| 4 | for multiplayer, cross-platform, real-time 3D action. |
|---|
| 5 | Copyright (C) 2002-2012 Carsten Fuchs Software. |
|---|
| 6 | |
|---|
| 7 | Cafu is free software: you can redistribute it and/or modify it under the terms |
|---|
| 8 | of the GNU General Public License as published by the Free Software Foundation, |
|---|
| 9 | either version 3 of the License, or (at your option) any later version. |
|---|
| 10 | |
|---|
| 11 | Cafu is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
|---|
| 12 | without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
|---|
| 13 | PURPOSE. See the GNU General Public License for more details. |
|---|
| 14 | |
|---|
| 15 | You should have received a copy of the GNU General Public License |
|---|
| 16 | along with Cafu. If not, see <http://www.gnu.org/licenses/>. |
|---|
| 17 | |
|---|
| 18 | For support and more information about Cafu, visit us at <http://www.cafu.de>. |
|---|
| 19 | ================================================================================= |
|---|
| 20 | */ |
|---|
| 21 | |
|---|
| 22 | #ifndef CAFU_TOOL_TERRAIN_EDIT_HPP_INCLUDED |
|---|
| 23 | #define CAFU_TOOL_TERRAIN_EDIT_HPP_INCLUDED |
|---|
| 24 | |
|---|
| 25 | #include "Tool.hpp" |
|---|
| 26 | #include "MapTerrain.hpp" |
|---|
| 27 | #include "ObserverPattern.hpp" |
|---|
| 28 | |
|---|
| 29 | #include "Templates/Array.hpp" |
|---|
| 30 | |
|---|
| 31 | #include "wx/bitmap.h" |
|---|
| 32 | #include "wx/menu.h" |
|---|
| 33 | |
|---|
| 34 | |
|---|
| 35 | class MapTerrainT; |
|---|
| 36 | class MapDocumentT; |
|---|
| 37 | class MapElementT; |
|---|
| 38 | class OptionsBar_EditFacePropsToolT; |
|---|
| 39 | class TerrainEditorDialogT; |
|---|
| 40 | |
|---|
| 41 | |
|---|
| 42 | class ToolTerrainEditorT : public ToolT, public ObserverT |
|---|
| 43 | { |
|---|
| 44 | public: |
|---|
| 45 | |
|---|
| 46 | enum ToolModeE |
|---|
| 47 | { |
|---|
| 48 | TOOLMODE_INACTIVE, |
|---|
| 49 | TOOLMODE_ACTIVE, |
|---|
| 50 | TOOLMODE_EYEDROPPER |
|---|
| 51 | }; |
|---|
| 52 | |
|---|
| 53 | enum ExportFileTypeE |
|---|
| 54 | { |
|---|
| 55 | BMP, |
|---|
| 56 | PNG, |
|---|
| 57 | JPG, |
|---|
| 58 | PGM_ASCII, |
|---|
| 59 | PGM_BINARY, |
|---|
| 60 | TER |
|---|
| 61 | }; |
|---|
| 62 | |
|---|
| 63 | ToolTerrainEditorT(MapDocumentT& MapDoc, ToolManagerT& ToolMan, wxWindow* ParentOptionsBar); |
|---|
| 64 | ~ToolTerrainEditorT(); |
|---|
| 65 | |
|---|
| 66 | /// Sets the dialog that is asociated with this tool. |
|---|
| 67 | /// Without a dialog certain tool parameters can't be read (like radius etc.) and the tool |
|---|
| 68 | /// is not functional. This method should be called as soon as possible after the tool has |
|---|
| 69 | /// been created. |
|---|
| 70 | /// @param TerrainEditorDialog The dialog of this tool. |
|---|
| 71 | void SetToolDialog(TerrainEditorDialogT* TerrainEditorDialog); |
|---|
| 72 | |
|---|
| 73 | /// Checks if the tool has a terrain selected. |
|---|
| 74 | /// @return Whether a terrain is selected by the tool. |
|---|
| 75 | bool IsTerrainSelected() { return (m_TerrainCopy!=NULL); } |
|---|
| 76 | |
|---|
| 77 | /// Updates the resolution of the terrain currently attached to the tool. |
|---|
| 78 | /// If no terrain is attached to the tool nothing is done. |
|---|
| 79 | void SetResolution(unsigned long Resolution); |
|---|
| 80 | |
|---|
| 81 | /// Gets the resolution of the terrain currently attached to the tool. |
|---|
| 82 | /// @return Resolution of the currently attached terrain. |
|---|
| 83 | unsigned long GetResolution() { return m_TerrainCopy->GetResolution(); } |
|---|
| 84 | |
|---|
| 85 | /// Generates the terrains height data using Perlin noise with the given parameters. |
|---|
| 86 | void GenerateTerrain(int Octaves, double Frequency, double Persistence, double Lacunarity, int Seed); |
|---|
| 87 | |
|---|
| 88 | /// Imports the height data in the passed file into the terrain currently attached to the tool. |
|---|
| 89 | /// If no terrain is attached to the tool nothing is done. |
|---|
| 90 | void ImportHeightMap(const wxString& FileName); |
|---|
| 91 | |
|---|
| 92 | /// Exports the height data to a file in the specified file format. |
|---|
| 93 | /// @param FileName The full path to the filename in which the height data should be stored. |
|---|
| 94 | /// @param ExportFileType The file format used to store the height data. |
|---|
| 95 | void ExportHeightMap(wxString FileName, ExportFileTypeE ExportFileType); |
|---|
| 96 | |
|---|
| 97 | /// Updates the modification matrix using the passed radius and hardness. |
|---|
| 98 | void UpdateModifyWeights(); |
|---|
| 99 | |
|---|
| 100 | /// Updates the noise weights according to the passed radius. |
|---|
| 101 | void UpdateNoiseWeights(); |
|---|
| 102 | |
|---|
| 103 | /// Updates the gauss kernel according to the passed tool effect. |
|---|
| 104 | void UpdateGaussWeights(); |
|---|
| 105 | |
|---|
| 106 | // Implementations/overrides of ToolT methods. |
|---|
| 107 | int GetWxEventID() const { return ChildFrameT::ID_MENU_TOOLS_TOOL_TERRAINEDITOR; } |
|---|
| 108 | wxWindow* GetOptionsBar(); |
|---|
| 109 | void OnActivate(ToolT* OldTool); |
|---|
| 110 | void OnDeactivate(ToolT* NewTool); |
|---|
| 111 | |
|---|
| 112 | bool OnKeyDown2D (ViewWindow2DT& ViewWindow, wxKeyEvent& KE); |
|---|
| 113 | bool OnKeyUp2D (ViewWindow2DT& ViewWindow, wxKeyEvent& KE); |
|---|
| 114 | bool OnLMouseDown2D (ViewWindow2DT& ViewWindow, wxMouseEvent& ME); |
|---|
| 115 | bool OnLMouseUp2D (ViewWindow2DT& ViewWindow, wxMouseEvent& ME); |
|---|
| 116 | bool OnMMouseUp2D (ViewWindow2DT& ViewWindow, wxMouseEvent& ME); |
|---|
| 117 | bool OnMouseMove2D (ViewWindow2DT& ViewWindow, wxMouseEvent& ME); |
|---|
| 118 | int OnContextMenu2D(ViewWindow2DT& ViewWindow, wxContextMenuEvent& CE, wxMenu& Menu); |
|---|
| 119 | |
|---|
| 120 | bool OnKeyDown3D (ViewWindow3DT& ViewWindow, wxKeyEvent& KE); |
|---|
| 121 | bool OnKeyUp3D (ViewWindow3DT& ViewWindow, wxKeyEvent& KE); |
|---|
| 122 | bool OnLMouseDown3D (ViewWindow3DT& ViewWindow, wxMouseEvent& ME); |
|---|
| 123 | bool OnLMouseUp3D (ViewWindow3DT& ViewWindow, wxMouseEvent& ME); |
|---|
| 124 | bool OnMMouseUp3D (ViewWindow3DT& ViewWindow, wxMouseEvent& ME); |
|---|
| 125 | bool OnMouseMove3D (ViewWindow3DT& ViewWindow, wxMouseEvent& ME); |
|---|
| 126 | |
|---|
| 127 | bool IsHiddenByTool(const MapElementT* Elem) const; |
|---|
| 128 | void RenderTool2D(Renderer2DT& Renderer) const; |
|---|
| 129 | void RenderTool3D(Renderer3DT& Renderer) const; |
|---|
| 130 | |
|---|
| 131 | // ObserverT implementation. |
|---|
| 132 | void NotifySubjectChanged_Deleted(SubjectT* Subject, const ArrayT<MapElementT*>& MapElements); |
|---|
| 133 | void NotifySubjectChanged_Modified(SubjectT* Subject, const ArrayT<MapElementT*>& MapElements, MapElemModDetailE Detail); |
|---|
| 134 | void NotifySubjectChanged_Modified(SubjectT* Subject, const ArrayT<MapElementT*>& MapElements, MapElemModDetailE Detail, const ArrayT<BoundingBox3fT>& OldBounds); |
|---|
| 135 | void NotifySubjectDies(SubjectT* dyingSubject); |
|---|
| 136 | |
|---|
| 137 | // The TypeSys related declarations for this class. |
|---|
| 138 | virtual const cf::TypeSys::TypeInfoT* GetType() const { return &TypeInfo; } |
|---|
| 139 | static void* CreateInstance(const cf::TypeSys::CreateParamsT& Params); |
|---|
| 140 | static const cf::TypeSys::TypeInfoT TypeInfo; |
|---|
| 141 | |
|---|
| 142 | |
|---|
| 143 | private: |
|---|
| 144 | |
|---|
| 145 | TerrainEditorDialogT* m_TerrainEditorDialog; ///< The terrain editor dialog that is associated with this tool. |
|---|
| 146 | MapTerrainT* m_TerrainOrig; ///< The terrain in the map that is currently being edited by this tool. Note that this terrain is never modified directly, but only via the Command-Pattern by commands that apply changes that were previously made to the local m_TerrainCopy instance: The m_TerrainOrig is hidden in the map and not rendered while the dialog is active. |
|---|
| 147 | MapTerrainT* m_TerrainCopy; ///< The "working copy" of the terrain. Always identical to the m_TerrainOrig except during the periods while one of the mouse buttons is being held down (i.e. the tool is active). That is, while a mouse button is being pressed, all changes are only made to this instance (which therefore temporarily diverges from the m_TerrainOrig). When the mouse button is released (i.e. tool becomes inactive) again, a command is submitted that updates the m_TerrainOrig member to the same contents, which in turn makes the m_TerrainOrig and m_TerrainCopy identical again. |
|---|
| 148 | bool m_IsRecSelfNotify; ///< Whether a modification of the terrain has been caused by ourselves. |
|---|
| 149 | |
|---|
| 150 | mutable bool m_RenderUpdateBitmap; ///< Whether the terrain has changed and its render bitmap needs to be updated. |
|---|
| 151 | mutable bool m_RenderUpdateTool; ///< Whether the tool position/radius has changed and its render position/radius needs to be updated. |
|---|
| 152 | mutable wxBitmap m_RenderBitmap; ///< The bitmap to render in the top down 2D view. This bitmap is updated when the height data changes or the zoom factor/scrollposition of the 2D view changes. |
|---|
| 153 | |
|---|
| 154 | // Render attributes. These are values that are calculated when the terrain was is rendered in the top down 2D view. |
|---|
| 155 | // To prevent recalculation of the values each time 2D view is rendered (even if the terrains position in the view hasn't changed) they are stored here. |
|---|
| 156 | mutable wxPoint m_LastRenderPosBL; ///< Bottom left position of the terrain in client space on last render. This value is needed to determine if the terrain position inside the 2D view has changed and the terrain bitmap needs to be recaclutated. |
|---|
| 157 | mutable wxPoint m_LastRenderPosTR; ///< Top right position of the terrain in client space on last render. This value is needed to determine if the terrain position inside the 2D view has changed and the terrain bitmap needs to be recaclutated. |
|---|
| 158 | mutable wxPoint m_PointTLToolOff; ///< Used when rendering the terrain in the 2D view. |
|---|
| 159 | mutable int m_SizeXTool; ///< Used for tool calculations. |
|---|
| 160 | mutable int m_SizeYTool; ///< Used for tool calculations. |
|---|
| 161 | mutable wxPoint m_ToolRenderPosition; ///< Used to render the tool in the 2D view. |
|---|
| 162 | mutable int m_ToolRadiusX; ///< Used to render the tool in the 2D view. |
|---|
| 163 | mutable int m_ToolRadiusY; ///< Used to render the tool in the 2D view. |
|---|
| 164 | |
|---|
| 165 | wxPoint m_HeightDataPos; ///< The current position of the tool cursor in the terrain, in heightmap coordinates. Independent from the current m_ToolMode value. |
|---|
| 166 | ToolModeE m_ToolMode; ///< Indicates the current state of the tool, i.e. whether it is inactive or active with one of the mouse buttons. |
|---|
| 167 | |
|---|
| 168 | // These members are reset each time the tool is newly activated. They are only valid and kept up-to-date while the tool is active. |
|---|
| 169 | // When the tool is or becomes inactive, their contents has no meaning. |
|---|
| 170 | wxRect m_EditBounds; ///< Bounds of the terrain modification operations since the activation of the tool. |
|---|
| 171 | wxPoint m_EditHeigthMapPos; ///< Last tool cursor position (in heightmap coordinates) at which the last terrain modification occured. |
|---|
| 172 | Plane3fT m_EditPlane; ///< When the tool is active in a 3D view, the mouse cursor position is mapped to heightmap coordinates using this plane. (When the tool is *inactive* in a 3D view, a true ray intersection test is performed in order to determine the heightmap coordinates from the current mouse cursor position.) |
|---|
| 173 | |
|---|
| 174 | ArrayT<wxRect> m_EditRoadParts; ///< Array filled when the road tool is active. The road is constructed with these parts, each defining an individual area of the road. |
|---|
| 175 | |
|---|
| 176 | unsigned short m_ReferenceHeight; ///< A reference height value used for by various tools (e.g. the flatten tool), set with a RMB click. |
|---|
| 177 | ArrayT<float> m_ModifyWeights; ///< A matrix containing all relevant weights calculated by the modify function for the current tool options. The modify weights are computed each time the radius or hardness changes. |
|---|
| 178 | ArrayT<float> m_NoiseWeights; ///< A matrix containing all weights needed to add bumps/holes when using the noise tool. |
|---|
| 179 | int m_NoiseWeightsRes; ///< Resoution of the noise weight array. |
|---|
| 180 | ArrayT<float> m_GaussWeights; ///< A matrix containing the wheight used for gaussian operations (e.g. gaussian blur). |
|---|
| 181 | int m_GaussWeightsRes; ///< Resoution of the gauss kernel. |
|---|
| 182 | |
|---|
| 183 | enum ColorGradientE |
|---|
| 184 | { |
|---|
| 185 | GREY=0, |
|---|
| 186 | RAINBOW, |
|---|
| 187 | DEBUG_COLOR |
|---|
| 188 | }; |
|---|
| 189 | |
|---|
| 190 | ColorGradientE m_CurrentColorGradient; |
|---|
| 191 | |
|---|
| 192 | OptionsBar_EditFacePropsToolT* m_OptionsBar; ///< The options bar for this tool. |
|---|
| 193 | |
|---|
| 194 | |
|---|
| 195 | /// Sets the terrain editing mode and calls DoEdit() for initial terrain edit. |
|---|
| 196 | /// Further terrain modifications with this edit mode are done using the DoEdit() method directly. |
|---|
| 197 | /// @param EditMode The edit mode that is used to edit the terrain. |
|---|
| 198 | void SetEditMode(ToolModeE ToolMode); |
|---|
| 199 | |
|---|
| 200 | /// Modifies the terrain according to current tool state and edit mode. |
|---|
| 201 | /// The terrain is only modified if the tools position has changed since the last call to DoEdit(). |
|---|
| 202 | /// @param Force Forces terrain modification ignoring tool position. |
|---|
| 203 | void DoEdit(bool Force=false); |
|---|
| 204 | |
|---|
| 205 | /// Sets the terrain that is currently affected by the editor. |
|---|
| 206 | /// @param NewTerrain Pointer to the terrain object that is to be edited. |
|---|
| 207 | void SetTerrain(MapTerrainT* NewTerrain, bool UpdateObs_VisChanged=true); |
|---|
| 208 | |
|---|
| 209 | /// Creates a map command from all changes made up to this point and modifies the original terrain. |
|---|
| 210 | void CommitChanges(); |
|---|
| 211 | |
|---|
| 212 | /// Sets the tools new position inside the height data, after validating it (must be inside height data boundaries). |
|---|
| 213 | /// If the new position is not valid the position is set to (-1, -1, -1). |
|---|
| 214 | void SetHeightDataPos(const wxPoint& HeightDataPos); |
|---|
| 215 | |
|---|
| 216 | /// Returns the terrain height at the current tool position, in world coordinates. |
|---|
| 217 | float GetToolHeight_World() const; |
|---|
| 218 | |
|---|
| 219 | /// Returns a scaled bitmap of the terrains height data according to parameters. |
|---|
| 220 | /// This is needed to render a scaled portion of the height data in a 2D view. |
|---|
| 221 | /// @param x The x pos from which height data is read. |
|---|
| 222 | /// @param y The y pos from which height data is read. |
|---|
| 223 | /// @param width The amount of height data to read in x direction. |
|---|
| 224 | /// @param height The amount of height data to read in y direction. |
|---|
| 225 | /// @param NewSizeX The size to scale the original heigth data to in x direction. |
|---|
| 226 | /// @param NewSizeY The size to scale the original heigth data to in y direction. |
|---|
| 227 | /// @return The scaled height data bitmap. |
|---|
| 228 | wxBitmap GetScaledBitmap(float x, float y, float width, float height, unsigned int NewSizeX, unsigned int NewSizeY) const; |
|---|
| 229 | |
|---|
| 230 | /// Helper method to pick the height value at the tools current position and store it as reference heigth value. |
|---|
| 231 | void PickReHeightValue(); |
|---|
| 232 | |
|---|
| 233 | /// Gets the current radius from the attached dialog and translates it in height data units. |
|---|
| 234 | /// This is necessary since terrains have different size and resolution and makes sure, that a radius with a given |
|---|
| 235 | /// value has the same size on all terrains. |
|---|
| 236 | int GetRadius() const; |
|---|
| 237 | |
|---|
| 238 | /// Updates the tool information shown in the status bar. |
|---|
| 239 | void UpdateToolInformation(); |
|---|
| 240 | }; |
|---|
| 241 | |
|---|
| 242 | #endif |
|---|