terrainEditor.h 15 KB

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