terrainEditor.h
Engine/source/gui/worldEditor/terrainEditor.h
Classes:
class
class
class
class
class
class
class
class
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