Ticket #516: smoothElevationTool.diff

File smoothElevationTool.diff, 10.5 KB (added by Digital Seraphim, 14 years ago)

Smooth Elevation Tool diff

  • source/tools/atlas/AtlasUI/ScenarioEditor/Tools/SmoothElevation.cpp

     
     1/* Copyright (C) 2009 Wildfire Games.
     2 * This file is part of 0 A.D.
     3 *
     4 * 0 A.D. is free software: you can redistribute it and/or modify
     5 * it under the terms of the GNU General Public License as published by
     6 * the Free Software Foundation, either version 2 of the License, or
     7 * (at your option) any later version.
     8 *
     9 * 0 A.D. is distributed in the hope that it will be useful,
     10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 * GNU General Public License for more details.
     13 *
     14 * You should have received a copy of the GNU General Public License
     15 * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
     16 */
     17
     18#include "precompiled.h"
     19
     20#include "ScenarioEditor/ScenarioEditor.h"
     21#include "Common/Tools.h"
     22#include "Common/Brushes.h"
     23#include "GameInterface/Messages.h"
     24
     25
     26using AtlasMessage::Position;
     27
     28class SmoothElevation : public StateDrivenTool<SmoothElevation>
     29{
     30    DECLARE_DYNAMIC_CLASS(SmoothElevation);
     31
     32    int m_Direction; // +1 = smoother, -1 = rougher
     33    Position m_Pos;
     34
     35public:
     36    SmoothElevation()
     37    {
     38        SetState(&Waiting);
     39    }
     40
     41
     42    void OnEnable()
     43    {
     44        g_Brush_Elevation.MakeActive();
     45    }
     46
     47    void OnDisable()
     48    {
     49        POST_MESSAGE(BrushPreview, (false, Position()));
     50    }
     51
     52
     53    struct sWaiting : public State
     54    {
     55        bool OnMouse(SmoothElevation* obj, wxMouseEvent& evt)
     56        {
     57            if (evt.LeftDown())
     58            {
     59                obj->m_Pos = Position(evt.GetPosition());
     60                SET_STATE(Smoothing);
     61                return true;
     62            }
     63            else if (evt.RightDown())
     64            {
     65                obj->m_Pos = Position(evt.GetPosition());
     66                SET_STATE(Roughing);
     67                return true;
     68            }
     69            else if (evt.Moving())
     70            {
     71                POST_MESSAGE(BrushPreview, (true, Position(evt.GetPosition())));
     72                return true;
     73            }
     74            else
     75            {
     76                return false;
     77            }
     78        }
     79    }
     80    Waiting;
     81
     82
     83    struct sSmoothing_common : public State
     84    {
     85        void OnEnter(SmoothElevation* obj)
     86        {
     87            POST_MESSAGE(BrushPreview, (true, obj->m_Pos));
     88        }
     89
     90        void OnLeave(SmoothElevation*)
     91        {
     92            ScenarioEditor::GetCommandProc().FinaliseLastCommand();
     93        }
     94
     95        bool OnMouse(SmoothElevation* obj, wxMouseEvent& evt)
     96        {
     97            if (IsMouseUp(evt))
     98            {
     99                SET_STATE(Waiting);
     100                return true;
     101            }
     102            else if (evt.Dragging())
     103            {
     104                wxPoint pos = evt.GetPosition();
     105                obj->m_Pos = Position(pos);
     106                POST_MESSAGE(BrushPreview, (true, obj->m_Pos));
     107                return true;
     108            }
     109            else
     110            {
     111                return false;
     112            }
     113        }
     114
     115        void OnTick(SmoothElevation* obj, float dt)
     116        {
     117            POST_COMMAND(SmoothElevation, (obj->m_Pos, dt*4096.f*GetDirection()*g_Brush_Elevation.GetStrength()));
     118            obj->m_Pos = Position::Unchanged();
     119        }
     120
     121        virtual bool IsMouseUp(wxMouseEvent& evt) = 0;
     122        virtual int GetDirection() = 0;
     123    };
     124
     125    struct sSmoothing : public sSmoothing_common
     126    {
     127        bool IsMouseUp(wxMouseEvent& evt) { return evt.LeftUp(); }
     128        int GetDirection() { return +1; }
     129    }
     130    Smoothing;
     131
     132    struct sRoughing : public sSmoothing_common
     133    {
     134        bool IsMouseUp(wxMouseEvent& evt) { return evt.RightUp(); }
     135        int GetDirection() { return -1; }
     136    }
     137    Roughing;
     138};
     139
     140IMPLEMENT_DYNAMIC_CLASS(SmoothElevation, StateDrivenTool<SmoothElevation>);
  • source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Terrain/Terrain.cpp

     
    5656    {
    5757        wxSizer* sizer = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Elevation tools"));
    5858        sizer->Add(new ToolButton(scenarioEditor.GetToolManager(), this, _("Modify"), _T("AlterElevation"), wxSize(50,20)));
     59        sizer->Add(new ToolButton(scenarioEditor.GetToolManager(), this, _("Smooth"), _T("SmoothElevation"), wxSize(50,20)));
    5960        sizer->Add(new ToolButton(scenarioEditor.GetToolManager(), this, _("Flatten"), _T("FlattenElevation"), wxSize(50,20)));
    6061//      sizer->Add(new ToolButton(scenarioEditor.GetToolManager(), this, _("Smooth"), _T(""), wxSize(50,20)));
    6162//      sizer->Add(new ToolButton(scenarioEditor.GetToolManager(), this, _("Sample"), _T(""), wxSize(50,20)));
  • source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp

     
    474474    toolbar->AddToolButton(_("Default"),       _("Default"),                   _T("default.png"),          _T(""),                 _T(""));
    475475    toolbar->AddToolButton(_("Move"),          _("Move/rotate object"),        _T("moveobject.png"),       _T("TransformObject"),  _T("")/*_T("ObjectSidebar")*/);
    476476    toolbar->AddToolButton(_("Elevation"),     _("Alter terrain elevation"),   _T("alterelevation.png"),   _T("AlterElevation"),   _T("")/*_T("TerrainSidebar")*/);
     477    toolbar->AddToolButton(_("Smooth"),        _("Smooth terrain elevation"),   _T("alterelevation.png"),   _T("SmoothElevation"),   _T("")/*_T("TerrainSidebar")*/);
    477478    toolbar->AddToolButton(_("Flatten"),       _("Flatten terrain elevation"), _T("flattenelevation.png"), _T("FlattenElevation"), _T("")/*_T("TerrainSidebar")*/);
    478479    toolbar->AddToolButton(_("Paint Terrain"), _("Paint terrain texture"),     _T("paintterrain.png"),     _T("PaintTerrain"),     _T("")/*_T("TerrainSidebar")*/);
    479480
  • source/tools/atlas/GameInterface/Messages.h

     
    372372        ((float, amount))
    373373        );
    374374
     375COMMAND(SmoothElevation, MERGE,
     376        ((Position, pos))
     377        ((float, amount))
     378        );
     379
    375380COMMAND(FlattenElevation, MERGE,
    376381        ((Position, pos))
    377382        ((float, amount))
  • source/tools/atlas/GameInterface/Handlers/ElevationHandlers.cpp

     
    178178END_COMMAND(AlterElevation)
    179179
    180180//////////////////////////////////////////////////////////////////////////
     181   
     182BEGIN_COMMAND(SmoothElevation)
     183{
     184    TerrainArray m_TerrainDelta;
     185    ssize_t m_i0, m_j0, m_i1, m_j1;
    181186
     187    cSmoothElevation()
     188    {
     189        m_TerrainDelta.Init();
     190    }
     191
     192    void MakeDirty()
     193    {
     194        g_Game->GetWorld()->GetTerrain()->MakeDirty(m_i0, m_j0, m_i1, m_j1, RENDERDATA_UPDATE_VERTICES);
     195        CmpPtr<ICmpTerrain> cmpTerrain(*g_Game->GetSimulation2(), SYSTEM_ENTITY);
     196        if (!cmpTerrain.null())
     197            cmpTerrain->MakeDirty(m_i0, m_j0, m_i1, m_j1);
     198    }
     199
     200    void Do()
     201    {
     202        int amount = (int)msg->amount;
     203
     204        printf("amount = %d\n", amount);
     205
     206        // If the framerate is very high, 'amount' is often very
     207        // small (even zero) so the integer truncation is significant
     208        static float roundingError = 0.0;
     209        roundingError += msg->amount - (float)amount;
     210        if (roundingError >= 1.f)
     211        {
     212            amount += (int)roundingError;
     213            roundingError -= (float)(int)roundingError;
     214        }
     215
     216        static CVector3D previousPosition;
     217        g_CurrentBrush.m_Centre = msg->pos->GetWorldSpace(previousPosition);
     218        previousPosition = g_CurrentBrush.m_Centre;
     219
     220        ssize_t x0, y0;
     221        g_CurrentBrush.GetBottomLeft(x0, y0);
     222
     223        if (g_CurrentBrush.m_H > 2)
     224        {
     225            int num = (g_CurrentBrush.m_H - 2) * (g_CurrentBrush.m_W-2);
     226            float *terrainDeltas = (float*)calloc(num, sizeof(float));
     227
     228            for (ssize_t dy = 0; dy < g_CurrentBrush.m_H; ++dy)
     229            {
     230                for (ssize_t dx = 0; dx < g_CurrentBrush.m_W; ++dx)
     231                {
     232                    //float b = g_CurrentBrush.Get(dx, dy) * m_TerrainDelta.GetVertex(x0+dx,y0+dy);
     233                    float b = m_TerrainDelta.GetVertex(x0+dx,y0+dy);
     234                   
     235                    if (b)
     236                    {
     237                        float delta = b / 9.0;
     238                        int x1_min = std::max(1, dx - 1);
     239                        int x1_max = std::min(dx + 1, g_CurrentBrush.m_W - 2);
     240                        int y1_min = std::max(1, dy - 1);
     241                        int y1_max = std::min(dy + 1, g_CurrentBrush.m_H - 2);
     242
     243
     244                        for(int yy = y1_min; yy <= y1_max; yy ++)
     245                        {
     246                            for(int xx = x1_min;xx <= x1_max; xx ++)
     247                            {
     248                                int index =(yy-1)*(g_CurrentBrush.m_W-2) + (xx-1);
     249                                terrainDeltas[index] += delta;
     250                            }
     251                        }
     252                    }
     253                }
     254            }
     255            for (ssize_t dy = 1; dy < g_CurrentBrush.m_H - 1; ++dy)
     256            {
     257                for (ssize_t dx = 1; dx < g_CurrentBrush.m_W - 1; ++dx)
     258                {
     259                    int index =(dy-1)*(g_CurrentBrush.m_W-2) + (dx-1);
     260                    float b = terrainDeltas[index];
     261                    if (b)
     262                        m_TerrainDelta.MoveVertexTowards(x0+dx, y0+dy, (int)b, (int)(amount*g_CurrentBrush.Get(dx,dy)));
     263                }
     264            }
     265
     266            free(terrainDeltas);
     267        }
     268
     269        m_i0 = x0;
     270        m_j0 = y0;
     271        m_i1 = x0 + g_CurrentBrush.m_W;
     272        m_j1 = y0 + g_CurrentBrush.m_H;
     273        MakeDirty();
     274    }
     275
     276    void Undo()
     277    {
     278        m_TerrainDelta.Undo();
     279        MakeDirty();
     280    }
     281
     282    void Redo()
     283    {
     284        m_TerrainDelta.Redo();
     285        MakeDirty();
     286    }
     287
     288    void MergeIntoPrevious(cSmoothElevation* prev)
     289    {
     290        prev->m_TerrainDelta.OverlayWith(m_TerrainDelta);
     291        prev->m_i0 = std::min(prev->m_i0, m_i0);
     292        prev->m_j0 = std::min(prev->m_j0, m_j0);
     293        prev->m_i1 = std::max(prev->m_i1, m_i1);
     294        prev->m_j1 = std::max(prev->m_j1, m_j1);
     295    }
     296};
     297END_COMMAND(SmoothElevation)
     298
     299//////////////////////////////////////////////////////////////////////////
     300
     301
    182302BEGIN_COMMAND(FlattenElevation)
    183303{
    184304    TerrainArray m_TerrainDelta;
  • source/lib/res/sound/ogg.cpp

     
    9292            NODEFAULT;
    9393        }
    9494
    95         adapter->offset = Clamp(origin+offset, off_t(0), adapter->size);
     95        adapter->offset = Clamp(off_t(origin+offset), off_t(0), adapter->size);
    9696        return 0;
    9797    }
    9898
  • binaries/data/tools/atlas/scripts/section/terrain.js

     
    129129       
    130130    var tools = [
    131131        { label: 'Modify', name: 'AlterElevation' },
     132        { label: 'Smooth', name: 'SmoothElevation' },
    132133        { label: 'Flatten', name: 'FlattenElevation' },
    133134        { label: 'Paint', name: 'PaintTerrain' },
    134135    ];