//----------------------------------------------------------------------------- // Torque Game Engine // Copyright (C) GarageGames.com, Inc. //----------------------------------------------------------------------------- #ifndef _TERRAINEDITOR_H_ #define _TERRAINEDITOR_H_ #ifndef _EDITTSCTRL_H_ #include "editor/editTSCtrl.h" #endif #ifndef _TERRDATA_H_ #include "terrain/terrData.h" #endif //------------------------------------------------------------------------------ class GridInfo { public: Point2I mGridPos; TerrainBlock::Material mMaterial; U8 mMaterialAlpha[TerrainBlock::MaterialGroups]; F32 mHeight; U8 mMaterialGroup; F32 mWeight; F32 mStartHeight; bool mPrimarySelect; bool mMaterialChanged; // hash table S32 mNext; S32 mPrev; }; //------------------------------------------------------------------------------ class Selection : public Vector { private: StringTableEntry mName; BitSet32 mUndoFlags; // hash table S32 lookup(const Point2I & pos); void insert(GridInfo & info); U32 getHashIndex(const Point2I & pos); Vector mHashLists; U32 mHashListSize; public: Selection(); virtual ~Selection(); void reset(); bool add(GridInfo & info); bool getInfo(Point2I pos, GridInfo & info); bool setInfo(GridInfo & info); bool remove(const GridInfo & info); void setName(StringTableEntry name); StringTableEntry getName(){return(mName);} F32 getAvgHeight(); }; //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ class TerrainEditor; class Brush : public Selection { protected: TerrainEditor * mTerrainEditor; Point2I mSize; Point2I mGridPos; public: enum { MaxBrushDim = 40 }; Brush(TerrainEditor * editor); virtual ~Brush(){}; // void setPosition(const Point3F & pos); void setPosition(const Point2I & pos); const Point2I & getPosition(); void update(); virtual void rebuild() = 0; Point2I getSize(){return(mSize);} virtual void setSize(const Point2I & size){mSize = size;} }; class BoxBrush : public Brush { public: BoxBrush(TerrainEditor * editor) : Brush(editor){} void rebuild(); }; class EllipseBrush : public Brush { public: EllipseBrush(TerrainEditor * editor) : Brush(editor){} void rebuild(); }; class SelectionBrush : public Brush { public: SelectionBrush(TerrainEditor * editor); void rebuild(); void setSize(const Point2I &){} }; //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ struct BaseMaterialInfo { StringTableEntry mMaterialNames[TerrainBlock::MaterialGroups]; U8 mBaseMaterials[TerrainBlock::BlockSize * TerrainBlock::BlockSize]; }; class TerrainAction; class TerrainEditor : public EditTSCtrl { public: void attachTerrain(TerrainBlock *terrBlock); void setBrushType(const char* type); void setBrushSize(S32 w, S32 h); const char* getBrushPos(); void setBrushPos(Point2I pos); void setAction(const char* action); const char* getActionName(U32 index); const char* getCurrentAction(); S32 getNumActions(); void processAction(const char* sAction); void undo(); void redo(); void resetSelWeights(bool clear); void clearSelection(); void buildMaterialMap(); S32 getNumTextures(); const char* getTextureName(S32 index); void markEmptySquares(); void clearModifiedFlags(); void mirrorTerrain(S32 mirrorIndex); void pushBaseMaterialInfo(); void popBaseMaterialInfo(); void setLoneBaseMaterial(const char* materialListBaseName); private: typedef EditTSCtrl Parent; TerrainBlock * mTerrainBlock; Point2I mGridUpdateMin; Point2I mGridUpdateMax; U32 mMouseDownSeq; Point3F mMousePos; Brush * mMouseBrush; bool mRenderBrush; Point2I mBrushSize; Vector mActions; TerrainAction * mCurrentAction; bool mInAction; Selection mDefaultSel; bool mSelectionLocked; GuiCursor * mDefaultCursor; GuiCursor * mCurrentCursor; bool mCursorVisible; StringTableEntry mPaintMaterial; Selection * mCurrentSel; // bool mRebuildEmpty; bool mRebuildTextures; void rebuild(); void addUndo(Vector & list, Selection * sel); bool processUndo(Vector & src, Vector & dest); void clearUndo(Vector & list); U32 mUndoLimit; Selection * mUndoSel; Vector mUndoList; Vector mRedoList; Vector mBaseMaterialInfos; bool mIsDirty; // dirty flag for writing terrain. bool mIsMissionDirty; // dirty flag for writing mission. public: TerrainEditor(); ~TerrainEditor(); // conversion functions bool gridToWorld(const Point2I & gPos, Point3F & wPos); bool worldToGrid(const Point3F & wPos, Point2I & gPos); bool gridToCenter(const Point2I & gPos, Point2I & cPos); bool getGridInfo(const Point3F & wPos, GridInfo & info); bool getGridInfo(const Point2I & gPos, GridInfo & info); void setGridInfo(const GridInfo & info); void setGridInfoHeight(const GridInfo & info); void gridUpdateComplete(); void materialUpdateComplete(); void processActionTick(U32 sequence); bool collide(const Gui3DMouseEvent & event, Point3F & pos); void lockSelection(bool lock) { mSelectionLocked = lock; }; Selection * getUndoSel(){return(mUndoSel);} Selection * getCurrentSel(){return(mCurrentSel);} void setCurrentSel(Selection * sel) { mCurrentSel = sel; } void resetCurrentSel() {mCurrentSel = &mDefaultSel; } S32 getPaintMaterial(); Point2I getBrushSize() { return(mBrushSize); } TerrainBlock * getTerrainBlock() { AssertFatal(mTerrainBlock!=NULL, "No terrain block"); return(mTerrainBlock); } TerrainBlock * getClientTerrain(); bool terrainBlockValid() { return(mTerrainBlock ? true : false); } void setCursor(GuiCursor * cursor); void getCursor(GuiCursor *&cursor, bool &showCursor, const GuiEvent &lastGuiEvent); void setDirty() { mIsDirty = true; } void setMissionDirty() { mIsMissionDirty = true; } TerrainAction * lookupAction(const char * name); private: // terrain interface functions F32 getGridHeight(const Point2I & gPos); void setGridHeight(const Point2I & gPos, const F32 height); TerrainBlock::Material getGridMaterial(const Point2I & gPos); void setGridMaterial(const Point2I & gPos, const TerrainBlock::Material & material); U8 getGridMaterialGroup(const Point2I & gPos); void setGridMaterialGroup(const Point2I & gPos, U8 group); // void updateBrush(Brush & brush, const Point2I & gPos); // Point3F getMousePos(){return(mMousePos);}; // void renderSelection(const Selection & sel, const ColorF & inColorFull, const ColorF & inColorNone, const ColorF & outColorFull, const ColorF & outColorNone, bool renderFill, bool renderFrame); void renderBorder(); public: // persist field data - these are dynamic bool mRenderBorder; F32 mBorderHeight; ColorI mBorderFillColor; ColorI mBorderFrameColor; bool mBorderLineMode; bool mSelectionHidden; bool mEnableSoftBrushes; bool mRenderVertexSelection; bool mProcessUsesBrush; // F32 mAdjustHeightVal; F32 mSetHeightVal; F32 mScaleVal; F32 mSmoothFactor; S32 mMaterialGroup; F32 mSoftSelectRadius; StringTableEntry mSoftSelectFilter; StringTableEntry mSoftSelectDefaultFilter; F32 mAdjustHeightMouseScale; public: // SimObject bool onAdd(); void onDeleteNotify(SimObject * object); static void initPersistFields(); // EditTSCtrl void on3DMouseUp(const Gui3DMouseEvent & event); void on3DMouseDown(const Gui3DMouseEvent & event); void on3DMouseMove(const Gui3DMouseEvent & event); void on3DMouseDragged(const Gui3DMouseEvent & event); void updateGuiInfo(); void renderScene(const RectI & updateRect); DECLARE_CONOBJECT(TerrainEditor); }; inline void TerrainEditor::setGridInfoHeight(const GridInfo & info) { setGridHeight(info.mGridPos, info.mHeight); } #endif