Cafu Engine
ToolTerrainEdit.hpp
1 /*
2 Cafu Engine, http://www.cafu.de/
3 Copyright (c) Carsten Fuchs and other contributors.
4 This project is licensed under the terms of the MIT license.
5 */
6 
7 #ifndef CAFU_TOOL_TERRAIN_EDIT_HPP_INCLUDED
8 #define CAFU_TOOL_TERRAIN_EDIT_HPP_INCLUDED
9 
10 #include "Tool.hpp"
11 #include "MapTerrain.hpp"
12 #include "ObserverPattern.hpp"
13 
14 #include "Templates/Array.hpp"
15 
16 #include "wx/bitmap.h"
17 #include "wx/menu.h"
18 
19 
20 class MapTerrainT;
21 class MapDocumentT;
22 class MapElementT;
25 
26 
27 class ToolTerrainEditorT : public ToolT, public ObserverT
28 {
29  public:
30 
31  enum ToolModeE
32  {
33  TOOLMODE_INACTIVE,
34  TOOLMODE_ACTIVE,
35  TOOLMODE_EYEDROPPER
36  };
37 
38  enum ExportFileTypeE
39  {
40  BMP,
41  PNG,
42  JPG,
43  PGM_ASCII,
44  PGM_BINARY,
45  TER
46  };
47 
48  ToolTerrainEditorT(MapDocumentT& MapDoc, ToolManagerT& ToolMan, wxWindow* ParentOptionsBar);
50 
51  /// Sets the dialog that is asociated with this tool.
52  /// Without a dialog certain tool parameters can't be read (like radius etc.) and the tool
53  /// is not functional. This method should be called as soon as possible after the tool has
54  /// been created.
55  /// @param TerrainEditorDialog The dialog of this tool.
56  void SetToolDialog(TerrainEditorDialogT* TerrainEditorDialog);
57 
58  /// Checks if the tool has a terrain selected.
59  /// @return Whether a terrain is selected by the tool.
60  bool IsTerrainSelected() { return (m_TerrainCopy!=NULL); }
61 
62  /// Updates the resolution of the terrain currently attached to the tool.
63  /// If no terrain is attached to the tool nothing is done.
64  void SetResolution(unsigned long Resolution);
65 
66  /// Gets the resolution of the terrain currently attached to the tool.
67  /// @return Resolution of the currently attached terrain.
68  unsigned long GetResolution() { return m_TerrainCopy->GetResolution(); }
69 
70  /// Generates the terrains height data using Perlin noise with the given parameters.
71  void GenerateTerrain(int Octaves, double Frequency, double Persistence, double Lacunarity, int Seed);
72 
73  /// Imports the height data in the passed file into the terrain currently attached to the tool.
74  /// If no terrain is attached to the tool nothing is done.
75  void ImportHeightMap(const wxString& FileName);
76 
77  /// Exports the height data to a file in the specified file format.
78  /// @param FileName The full path to the filename in which the height data should be stored.
79  /// @param ExportFileType The file format used to store the height data.
80  void ExportHeightMap(wxString FileName, ExportFileTypeE ExportFileType);
81 
82  /// Updates the modification matrix using the passed radius and hardness.
83  void UpdateModifyWeights();
84 
85  /// Updates the noise weights according to the passed radius.
86  void UpdateNoiseWeights();
87 
88  /// Updates the gauss kernel according to the passed tool effect.
89  void UpdateGaussWeights();
90 
91  // Implementations/overrides of ToolT methods.
92  int GetWxEventID() const { return ChildFrameT::ID_MENU_TOOLS_TOOL_TERRAINEDITOR; }
93  wxWindow* GetOptionsBar();
94  void OnActivate(ToolT* OldTool);
95  void OnDeactivate(ToolT* NewTool);
96 
97  bool OnKeyDown2D (ViewWindow2DT& ViewWindow, wxKeyEvent& KE);
98  bool OnKeyUp2D (ViewWindow2DT& ViewWindow, wxKeyEvent& KE);
99  bool OnLMouseDown2D (ViewWindow2DT& ViewWindow, wxMouseEvent& ME);
100  bool OnLMouseUp2D (ViewWindow2DT& ViewWindow, wxMouseEvent& ME);
101  bool OnMMouseUp2D (ViewWindow2DT& ViewWindow, wxMouseEvent& ME);
102  bool OnMouseMove2D (ViewWindow2DT& ViewWindow, wxMouseEvent& ME);
103  int OnContextMenu2D(ViewWindow2DT& ViewWindow, wxContextMenuEvent& CE, wxMenu& Menu);
104 
105  bool OnKeyDown3D (ViewWindow3DT& ViewWindow, wxKeyEvent& KE);
106  bool OnKeyUp3D (ViewWindow3DT& ViewWindow, wxKeyEvent& KE);
107  bool OnLMouseDown3D (ViewWindow3DT& ViewWindow, wxMouseEvent& ME);
108  bool OnLMouseUp3D (ViewWindow3DT& ViewWindow, wxMouseEvent& ME);
109  bool OnMMouseUp3D (ViewWindow3DT& ViewWindow, wxMouseEvent& ME);
110  bool OnMouseMove3D (ViewWindow3DT& ViewWindow, wxMouseEvent& ME);
111 
112  bool IsHiddenByTool(const MapElementT* Elem) const;
113  void RenderTool2D(Renderer2DT& Renderer) const;
114  void RenderTool3D(Renderer3DT& Renderer) const;
115 
116  // ObserverT implementation.
117  void NotifySubjectChanged_Deleted(SubjectT* Subject, const ArrayT<MapPrimitiveT*>& Primitives);
118  void NotifySubjectChanged_Modified(SubjectT* Subject, const ArrayT<MapElementT*>& MapElements, MapElemModDetailE Detail);
119  void NotifySubjectChanged_Modified(SubjectT* Subject, const ArrayT<MapElementT*>& MapElements, MapElemModDetailE Detail, const ArrayT<BoundingBox3fT>& OldBounds);
120  void NotifySubjectDies(SubjectT* dyingSubject);
121 
122  // The TypeSys related declarations for this class.
123  virtual const cf::TypeSys::TypeInfoT* GetType() const { return &TypeInfo; }
124  static void* CreateInstance(const cf::TypeSys::CreateParamsT& Params);
125  static const cf::TypeSys::TypeInfoT TypeInfo;
126 
127 
128  private:
129 
130  TerrainEditorDialogT* m_TerrainEditorDialog; ///< The terrain editor dialog that is associated with this tool.
131  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.
132  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.
133  bool m_IsRecSelfNotify; ///< Whether a modification of the terrain has been caused by ourselves.
134 
135  mutable bool m_RenderUpdateBitmap; ///< Whether the terrain has changed and its render bitmap needs to be updated.
136  mutable bool m_RenderUpdateTool; ///< Whether the tool position/radius has changed and its render position/radius needs to be updated.
137  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.
138 
139  // Render attributes. These are values that are calculated when the terrain was is rendered in the top down 2D view.
140  // 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.
141  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.
142  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.
143  mutable wxPoint m_PointTLToolOff; ///< Used when rendering the terrain in the 2D view.
144  mutable int m_SizeXTool; ///< Used for tool calculations.
145  mutable int m_SizeYTool; ///< Used for tool calculations.
146  mutable wxPoint m_ToolRenderPosition; ///< Used to render the tool in the 2D view.
147  mutable int m_ToolRadiusX; ///< Used to render the tool in the 2D view.
148  mutable int m_ToolRadiusY; ///< Used to render the tool in the 2D view.
149 
150  wxPoint m_HeightDataPos; ///< The current position of the tool cursor in the terrain, in heightmap coordinates. Independent from the current m_ToolMode value.
151  ToolModeE m_ToolMode; ///< Indicates the current state of the tool, i.e. whether it is inactive or active with one of the mouse buttons.
152 
153  // 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.
154  // When the tool is or becomes inactive, their contents has no meaning.
155  wxRect m_EditBounds; ///< Bounds of the terrain modification operations since the activation of the tool.
156  wxPoint m_EditHeigthMapPos; ///< Last tool cursor position (in heightmap coordinates) at which the last terrain modification occured.
157  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.)
158 
159  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.
160 
161  unsigned short m_ReferenceHeight; ///< A reference height value used for by various tools (e.g. the flatten tool), set with a RMB click.
162  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.
163  ArrayT<float> m_NoiseWeights; ///< A matrix containing all weights needed to add bumps/holes when using the noise tool.
164  int m_NoiseWeightsRes; ///< Resoution of the noise weight array.
165  ArrayT<float> m_GaussWeights; ///< A matrix containing the wheight used for gaussian operations (e.g. gaussian blur).
166  int m_GaussWeightsRes; ///< Resoution of the gauss kernel.
167 
168  enum ColorGradientE
169  {
170  GREY=0,
171  RAINBOW,
172  DEBUG_COLOR
173  };
174 
175  ColorGradientE m_CurrentColorGradient;
176 
177  OptionsBar_EditFacePropsToolT* m_OptionsBar; ///< The options bar for this tool.
178 
179 
180  /// Sets the terrain editing mode and calls DoEdit() for initial terrain edit.
181  /// Further terrain modifications with this edit mode are done using the DoEdit() method directly.
182  /// @param EditMode The edit mode that is used to edit the terrain.
183  void SetEditMode(ToolModeE ToolMode);
184 
185  /// Modifies the terrain according to current tool state and edit mode.
186  /// The terrain is only modified if the tools position has changed since the last call to DoEdit().
187  /// @param Force Forces terrain modification ignoring tool position.
188  void DoEdit(bool Force=false);
189 
190  /// Sets the terrain that is currently affected by the editor.
191  /// @param NewTerrain Pointer to the terrain object that is to be edited.
192  void SetTerrain(MapTerrainT* NewTerrain, bool UpdateObs_VisChanged=true);
193 
194  /// Creates a map command from all changes made up to this point and modifies the original terrain.
195  void CommitChanges();
196 
197  /// Sets the tools new position inside the height data, after validating it (must be inside height data boundaries).
198  /// If the new position is not valid the position is set to (-1, -1, -1).
199  void SetHeightDataPos(const wxPoint& HeightDataPos);
200 
201  /// Returns the terrain height at the current tool position, in world coordinates.
202  float GetToolHeight_World() const;
203 
204  /// Returns a scaled bitmap of the terrains height data according to parameters.
205  /// This is needed to render a scaled portion of the height data in a 2D view.
206  /// @param x The x pos from which height data is read.
207  /// @param y The y pos from which height data is read.
208  /// @param width The amount of height data to read in x direction.
209  /// @param height The amount of height data to read in y direction.
210  /// @param NewSizeX The size to scale the original heigth data to in x direction.
211  /// @param NewSizeY The size to scale the original heigth data to in y direction.
212  /// @return The scaled height data bitmap.
213  wxBitmap GetScaledBitmap(float x, float y, float width, float height, unsigned int NewSizeX, unsigned int NewSizeY) const;
214 
215  /// Helper method to pick the height value at the tools current position and store it as reference heigth value.
216  void PickReHeightValue();
217 
218  /// Gets the current radius from the attached dialog and translates it in height data units.
219  /// This is necessary since terrains have different size and resolution and makes sure, that a radius with a given
220  /// value has the same size on all terrains.
221  int GetRadius() const;
222 
223  /// Updates the tool information shown in the status bar.
224  void UpdateToolInformation();
225 };
226 
227 #endif
This class provides auxiliary means for rendering a 3D view.
Definition: Renderer3D.hpp:30
This class implements the rendering into a 2D view.
Definition: Renderer2D.hpp:22
MapElemModDetailE
Definition: ObserverPattern.hpp:37
This class represents a CaWE "map" document.
Definition: MapDocument.hpp:45
void UpdateGaussWeights()
Updates the gauss kernel according to the passed tool effect.
Definition: ToolTerrainEdit.cpp:523
void SetToolDialog(TerrainEditorDialogT *TerrainEditorDialog)
Sets the dialog that is asociated with this tool.
Definition: ToolTerrainEdit.cpp:164
wxWindow * GetOptionsBar()
Returns the options bar window associated with this tool. NULL if no options bar has been assigned...
Definition: ToolTerrainEdit.cpp:549
void NotifySubjectChanged_Deleted(SubjectT *Subject, const ArrayT< MapPrimitiveT * > &Primitives)
Notifies the observer that one or more map primitives have been deleted.
Definition: ToolTerrainEdit.cpp:1262
Definition: DialogTerrainEdit.hpp:19
bool OnLMouseDown2D(ViewWindow2DT &ViewWindow, wxMouseEvent &ME)
Also used for LMB "double-click" events (use ME.ButtonDClick() for distinction).
Definition: ToolTerrainEdit.cpp:662
void ExportHeightMap(wxString FileName, ExportFileTypeE ExportFileType)
Exports the height data to a file in the specified file format.
Definition: ToolTerrainEdit.cpp:297
Definition: ObserverPattern.hpp:64
void GenerateTerrain(int Octaves, double Frequency, double Persistence, double Lacunarity, int Seed)
Generates the terrains height data using Perlin noise with the given parameters.
Definition: ToolTerrainEdit.cpp:216
void NotifySubjectDies(SubjectT *dyingSubject)
This method is called whenever a subject is about the be destroyed (and become unavailable).
Definition: ToolTerrainEdit.cpp:1304
Definition: ToolTerrainEdit.hpp:27
bool IsHiddenByTool(const MapElementT *Elem) const
The caller calls this method in order to learn whether it should exempt the given map element Elem fr...
Definition: ToolTerrainEdit.cpp:1102
The TerrainT class represents a terrain in a map.
Definition: MapTerrain.hpp:22
Definition: ObserverPattern.hpp:158
unsigned long GetResolution() const
Gets the terrains heigth data resolution side length.
Definition: MapTerrain.hpp:57
void UpdateNoiseWeights()
Updates the noise weights according to the passed radius.
Definition: ToolTerrainEdit.cpp:487
void SetResolution(unsigned long Resolution)
Updates the resolution of the terrain currently attached to the tool.
Definition: ToolTerrainEdit.cpp:189
int GetWxEventID() const
Returns the ID of the wxWidgets event (menu selection or toolbar button click) that is associated wit...
Definition: ToolTerrainEdit.hpp:92
The options bar for the Edit Face Properties tool.
Definition: ToolOptionsBars.hpp:195
Definition: ChildFrameViewWin2D.hpp:24
Definition: ChildFrameViewWin3D.hpp:21
void NotifySubjectChanged_Modified(SubjectT *Subject, const ArrayT< MapElementT * > &MapElements, MapElemModDetailE Detail)
Definition: ToolTerrainEdit.cpp:1278
bool OnLMouseDown3D(ViewWindow3DT &ViewWindow, wxMouseEvent &ME)
Also used for LMB "double-click" events (use ME.ButtonDClick() for distinction).
Definition: ToolTerrainEdit.cpp:1016
void ImportHeightMap(const wxString &FileName)
Imports the height data in the passed file into the terrain currently attached to the tool...
Definition: ToolTerrainEdit.cpp:251
Definition: ToolManager.hpp:20
unsigned long GetResolution()
Gets the resolution of the terrain currently attached to the tool.
Definition: ToolTerrainEdit.hpp:68
This is the base class for all tools in the map editor.
Definition: Tool.hpp:34
This file provides the classes for the Observer pattern as described in the book by the GoF...
Definition: TypeSys.hpp:52
This class keeps type information (about an entity class that occurs in the game).
Definition: TypeSys.hpp:79
This is the base class for all elements ("objects") that can exist in a map.
Definition: MapElement.hpp:57
bool IsTerrainSelected()
Checks if the tool has a terrain selected.
Definition: ToolTerrainEdit.hpp:60
void UpdateModifyWeights()
Updates the modification matrix using the passed radius and hardness.
Definition: ToolTerrainEdit.cpp:441