Torque3D Documentation / _generateds / terrainEditor.h

terrainEditor.h

Engine/source/gui/worldEditor/terrainEditor.h

More...

Classes:

Detailed Description

  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2012 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24#ifndef _TERRAINEDITOR_H_
 25#define _TERRAINEDITOR_H_
 26
 27#ifndef _EDITTSCTRL_H_
 28#include "gui/worldEditor/editTSCtrl.h"
 29#endif
 30#ifndef _TERRDATA_H_
 31#include "terrain/terrData.h"
 32#endif
 33#ifndef _UNDO_H_
 34#include "util/undo.h"
 35#endif
 36
 37
 38
 39// Each 2D grid position must be associated with a terrainBlock
 40struct GridPoint
 41{
 42   Point2I        gridPos;
 43   TerrainBlock*  terrainBlock;
 44
 45   GridPoint() { gridPos.set(0, 0); terrainBlock = NULL; };
 46};
 47
 48class GridInfo
 49{
 50public:
 51
 52   GridPoint                  mGridPoint;
 53   U8                         mMaterial;
 54   F32                        mHeight;
 55   F32                        mWeight;
 56   F32                        mStartHeight;
 57
 58   bool                       mPrimarySelect;
 59   bool                       mMaterialChanged;
 60
 61   // hash table
 62   S32                        mNext;
 63   S32                        mPrev;
 64};
 65
 66
 67class Selection : public Vector<GridInfo>
 68{
 69private:
 70
 71   StringTableEntry     mName;
 72   BitSet32             mUndoFlags;
 73
 74   // hash table
 75   S32 lookup(const Point2I & pos);
 76   void insert(GridInfo info);
 77   U32 getHashIndex(const Point2I & pos);
 78   bool validate();
 79
 80   Vector<S32>          mHashLists;
 81   U32                  mHashListSize;
 82
 83public:
 84
 85   Selection();
 86   virtual ~Selection();
 87
 88   void reset();
 89
 90   /// add unique grid info into the selection - test uniqueness by grid position
 91   bool add(const GridInfo &info);
 92   bool getInfo(Point2I pos, GridInfo & info);
 93   bool setInfo(GridInfo & info);
 94   bool remove(const GridInfo &info);
 95   void setName(StringTableEntry name);
 96   StringTableEntry getName(){return(mName);}
 97   F32 getAvgHeight();
 98   F32 getMinHeight();
 99   F32 getMaxHeight();
100};
101
102
103class TerrainEditor;
104
105class Brush : public Selection
106{
107protected:
108
109   TerrainEditor *   mTerrainEditor;
110   Point2I           mSize;
111   GridPoint         mGridPoint;         
112   Vector<S32>       mRenderList;
113
114public:
115
116   enum { MaxBrushDim = 256 };
117
118   Brush(TerrainEditor * editor);
119   virtual ~Brush(){};
120
121   virtual const char *getType() const = 0;
122
123   // Brush appears to intentionally bypass Selection's hash table, so we
124   // override validate() here.
125   bool validate() { return true; }
126   void setPosition(const Point3F & pos);
127   void setPosition(const Point2I & pos);
128   const Point2I & getPosition();
129   const GridPoint & getGridPoint();
130   void setTerrain(TerrainBlock* terrain) { mGridPoint.terrainBlock = terrain; };
131   Point2I getSize() const {return(mSize);}
132   virtual void setSize(const Point2I & size){mSize = size;}
133
134   void update();
135   void render();            
136
137   virtual void rebuild() = 0;            
138   virtual void _renderOutline() = 0;      
139};
140
141class BoxBrush : public Brush
142{
143public:
144
145   BoxBrush(TerrainEditor * editor) : Brush(editor){}
146   
147   const char *getType() const { return "box"; }
148   void rebuild();
149
150protected:
151
152   void _renderOutline();
153};
154
155class EllipseBrush : public Brush
156{
157public:
158
159   EllipseBrush(TerrainEditor * editor) : Brush(editor){}
160   
161   const char *getType() const { return "ellipse"; }
162   void rebuild();
163
164protected:
165
166   void _renderOutline();
167};
168
169class SelectionBrush : public Brush
170{
171public:
172
173   SelectionBrush(TerrainEditor * editor);
174
175   const char *getType() const { return "selection"; }
176   void rebuild();
177   void render(Vector<GFXVertexPCT> & vertexBuffer, S32 & verts, S32 & elems, S32 & prims, const LinearColorF & inColorFull, const LinearColorF & inColorNone, const LinearColorF & outColorFull, const LinearColorF & outColorNone) const;
178   void setSize(const Point2I &){}
179
180protected:
181
182   void _renderOutline() {}
183};
184
185
186class TerrainAction;
187
188class TerrainEditor : public EditTSCtrl
189{
190   // XA: This methods where added to replace the friend consoleMethods.
191   public:
192      void attachTerrain(TerrainBlock *terrBlock);
193      void detachTerrain(TerrainBlock *terrBlock);
194      
195      S32 getTerrainBlockCount() {return mTerrainBlocks.size();}
196      TerrainBlock* getTerrainBlock(S32 index);
197      void getTerrainBlocksMaterialList(Vector<StringTableEntry>& list);   // Returns consolidated list of all materials used on all terrain blocks
198
199      void setBrushType(const char* type);
200      const char* getBrushType() const;
201
202      void setBrushSize(S32 w, S32 h);
203      const char* getBrushPos();
204      void setBrushPos(Point2I pos);
205      
206      void setAction(const char* action);
207      const char* getActionName(U32 index);
208      const char* getCurrentAction() const;
209      S32 getNumActions();
210      void processAction(const char* sAction);
211         
212      void resetSelWeights(bool clear);
213      void clearSelection();
214      
215      S32 getNumTextures();
216
217      void markEmptySquares();
218      
219      void mirrorTerrain(S32 mirrorIndex);
220      
221      TerrainBlock* getActiveTerrain() { return mActiveTerrain; };
222
223      void scheduleGridUpdate() { mNeedsGridUpdate = true; }
224      void scheduleMaterialUpdate() { mNeedsMaterialUpdate = true; }
225      void setGridUpdateMinMax() 
226      { 
227         mGridUpdateMax.set( S32_MAX, S32_MAX );
228         mGridUpdateMin.set( 0, 0 );
229      }
230      
231      void submitMaterialUndo( String actionName );
232      void onMaterialUndo( TerrainBlock *terr );
233
234      void autoMaterialLayer( F32 mMinHeight, F32 mMaxHeight, F32 mMinSlope, F32 mMaxSlope, F32 mCoverage );
235
236   private: 
237
238      typedef EditTSCtrl Parent;
239
240      TerrainBlock* mActiveTerrain;
241
242      // A list of all of the TerrainBlocks this editor can edit
243      VectorPtr<TerrainBlock*> mTerrainBlocks;
244      
245      Point2I  mGridUpdateMin;
246      Point2I  mGridUpdateMax;
247      U32 mMouseDownSeq;
248
249      /// If one of these flags when the terrainEditor goes to render
250      /// an appropriate update method will be called on the terrain.
251      /// This prevents unnecessary work from happening from directly
252      /// within an editor event's process method.
253      bool mNeedsGridUpdate;
254      bool mNeedsMaterialUpdate;
255
256      bool                       mMouseDown;
257      PlaneF                     mMousePlane;
258      Point3F                    mMousePos;
259      Brush *                    mMouseBrush;
260      bool                       mBrushChanged;
261      bool                       mRenderBrush;
262      F32                        mBrushPressure;
263      Point2I                    mBrushSize;
264      F32                        mBrushSoftness;
265      Vector<TerrainAction*>    mActions;
266      TerrainAction *            mCurrentAction;
267      bool                       mInAction;
268      Selection                  mDefaultSel;
269      bool                       mSelectionLocked;      
270      
271      S32                        mPaintIndex;
272
273      Selection *                mCurrentSel;
274
275      class TerrainEditorUndoAction : public UndoAction
276      {
277      public:
278
279         TerrainEditorUndoAction( const UTF8* actionName ) 
280            :  UndoAction( actionName ),
281               mTerrainEditor( NULL ),
282               mSel( NULL )
283         {
284         }
285
286         virtual ~TerrainEditorUndoAction()
287         {
288            delete mSel;
289         }
290
291         TerrainEditor *mTerrainEditor;
292
293         Selection *mSel;
294         
295         virtual void undo();
296         virtual void redo() { undo(); }
297      };
298
299      void submitUndo( Selection *sel );
300
301      Selection *mUndoSel;
302
303      class TerrainMaterialUndoAction : public UndoAction
304      {
305      public:
306
307         TerrainMaterialUndoAction( const UTF8 *actionName )
308            : UndoAction( actionName ),
309              mEditor( NULL ),
310              mTerrain( NULL )
311         {
312         }
313
314         TerrainEditor *mEditor;
315         TerrainBlock *mTerrain;
316         Vector<U8> mLayerMap;         
317         Vector<TerrainMaterial*> mMaterials;
318
319         virtual void undo();
320         virtual void redo();
321      };
322
323      bool mIsDirty; // dirty flag for writing terrain.
324      bool mIsMissionDirty; // dirty flag for writing mission.
325
326      GFXStateBlockRef mStateBlock;
327
328   public:
329
330      TerrainEditor();
331      ~TerrainEditor();
332
333      // conversion functions
334      // Returns true if the grid position is on the main tile
335      bool isMainTile(const GridPoint & gPoint) const;
336
337      // Takes a world point and find the "highest" terrain underneath it
338      // Returns true if the returned GridPoint includes a valid terrain and grid position
339      TerrainBlock* getTerrainUnderWorldPoint(const Point3F & wPos);
340
341      // Converts a GridPoint to a world position
342      bool gridToWorld(const GridPoint & gPoint, Point3F & wPos);
343      bool gridToWorld(const Point2I & gPos, Point3F & wPos, TerrainBlock* terrain);
344
345      // Converts a world position to a grid point
346      // If the grid point does not have a TerrainBlock already it will find the nearest
347      // terrian under the world position
348      bool worldToGrid(const Point3F & wPos, GridPoint & gPoint);
349      bool worldToGrid(const Point3F & wPos, Point2I & gPos, TerrainBlock* terrain = NULL);
350
351      // Converts any point that is off of the main tile to its equivalent on the main tile
352      // Returns true if the point was already on the main tile
353      bool gridToCenter(const Point2I & gPos, Point2I & cPos) const;
354
355      //bool getGridInfo(const Point3F & wPos, GridInfo & info);
356      // Gets the grid info for a point on a TerrainBlock's grid
357      bool getGridInfo(const GridPoint & gPoint, GridInfo & info);
358      bool getGridInfo(const Point2I & gPos, GridInfo & info, TerrainBlock* terrain);
359
360      // Returns a list of infos for all points on the terrain that are at that point in space
361      void getGridInfos(const GridPoint & gPoint, Vector<GridInfo>& infos);
362
363      void setGridInfo(const GridInfo & info, bool checkActive = false);
364      void setGridInfoHeight(const GridInfo & info);
365      void gridUpdateComplete( bool materialChanged = false );
366      void materialUpdateComplete();
367      void processActionTick(U32 sequence);
368
369      TerrainBlock* collide(const Gui3DMouseEvent & event, Point3F & pos);
370      void lockSelection(bool lock) { mSelectionLocked = lock; };
371
372      Selection * getUndoSel(){return(mUndoSel);}
373      Selection * getCurrentSel(){return(mCurrentSel);}
374      void setCurrentSel(Selection * sel) { mCurrentSel = sel; }
375      void resetCurrentSel() {mCurrentSel = &mDefaultSel; }
376
377      S32 getPaintMaterialIndex() const { return mPaintIndex; }
378
379      void setBrushPressure( F32 pressure );
380      F32 getBrushPressure() const { return mBrushPressure; }
381      
382      void setBrushSoftness( F32 softness );
383      F32 getBrushSoftness() const { return mBrushSoftness; }
384
385      Point2I getBrushSize() { return(mBrushSize); }
386      
387      TerrainBlock* getTerrainBlock() const { return mActiveTerrain; }
388      TerrainBlock* getClientTerrain( TerrainBlock *serverTerrain = NULL ) const;
389      bool terrainBlockValid() { return(mActiveTerrain ? true : false); }
390      void setDirty() { mIsDirty = true; }
391      void setMissionDirty()  { mIsMissionDirty = true; }
392
393      TerrainAction * lookupAction(const char * name);
394
395   private:
396
397
398      // terrain interface functions
399      // Returns the height at a grid point
400      F32 getGridHeight(const GridPoint & gPoint);
401      // Sets a height at a grid point
402      void setGridHeight(const GridPoint & gPoint, const F32 height);
403
404      ///
405      U8 getGridMaterial( const GridPoint &gPoint ) const;
406
407      ///
408      void setGridMaterial( const GridPoint & gPoint, U8 index );
409
410      // Gets the material group of a specific spot on a TerrainBlock's grid
411      U8 getGridMaterialGroup(const GridPoint & gPoint);
412
413      // Sets a material group for a spot on a TerrainBlock's grid
414      void setGridMaterialGroup(const GridPoint & gPoint, U8 group);
415
416      //
417      void updateBrush(Brush & brush, const Point2I & gPos);      
418
419      //
420      void renderSelection(const Selection & sel, const LinearColorF & inColorFull, const LinearColorF & inColorNone, const LinearColorF & outColorFull, const LinearColorF & outColorNone, bool renderFill, bool renderFrame);
421      void renderBrush(const Brush & brush, const LinearColorF & inColorFull, const LinearColorF & inColorNone, const LinearColorF & outColorFull, const LinearColorF & outColorNone, bool renderFill, bool renderFrame);
422      void renderBorder();
423
424   public:
425      
426      // persist field data - these are dynamic
427      bool                 mRenderBorder;
428      F32                  mBorderHeight;
429      ColorI               mBorderFillColor;
430      ColorI               mBorderFrameColor;
431      bool                 mBorderLineMode;
432      bool                 mSelectionHidden;
433      bool                 mRenderVertexSelection;
434      bool                 mRenderSolidBrush;
435      bool                 mProcessUsesBrush;
436
437      //
438      F32                  mAdjustHeightVal;
439      F32                  mSetHeightVal;
440      F32                  mScaleVal;
441      F32                  mSmoothFactor;
442      F32                  mNoiseFactor;
443      S32                  mMaterialGroup;
444      F32                  mSoftSelectRadius;
445      StringTableEntry     mSoftSelectFilter;
446      StringTableEntry     mSoftSelectDefaultFilter;
447      F32                  mAdjustHeightMouseScale;
448      Point2I              mMaxBrushSize;
449
450      F32 mSlopeMinAngle;
451      F32 mSlopeMaxAngle;
452
453   public:
454
455      // SimObject
456      bool onAdd();
457      void onDeleteNotify(SimObject * object);
458
459      static void initPersistFields();
460
461      // GuiControl
462      bool onWake();
463      void onSleep();      
464
465      // EditTSCtrl
466      bool onInputEvent( const InputEventInfo & evt );
467      void on3DMouseUp( const Gui3DMouseEvent & evt );
468      void on3DMouseDown( const Gui3DMouseEvent & evt );
469      void on3DMouseMove( const Gui3DMouseEvent & evt );
470      void on3DMouseDragged( const Gui3DMouseEvent & evt );
471      bool onMouseWheelUp( const GuiEvent & evt );
472      bool onMouseWheelDown( const GuiEvent & evt );            
473      void get3DCursor( GuiCursor *&cursor, bool &visible, const Gui3DMouseEvent &evt );   
474      void onPreRender();
475      void renderScene(const RectI & updateRect);
476      void renderGui( Point2I offset, const RectI &updateRect );
477      void updateGuiInfo();
478
479      // Determine if the given grid point is valid within a non-wrap
480      // around terrain.
481      bool isPointInTerrain( const GridPoint & gPoint);
482
483      /// Reorder material at the given index to the new position, changing the order in which it is rendered / blended
484      void reorderMaterial( S32 index, S32 orderPos );
485
486      //
487      Point3F getMousePos(){return(mMousePos);};
488
489      void renderPoints( const Vector<GFXVertexPCT> &pointList );
490
491
492      DECLARE_CONOBJECT(TerrainEditor);     
493};
494
495inline void TerrainEditor::setGridInfoHeight(const GridInfo & info)
496{
497   setGridHeight(info.mGridPoint, info.mHeight);
498}
499
500#endif
501