Ticket #2059: pikes.diff

File pikes.diff, 7.2 KB (added by sanderd17, 11 years ago)
  • source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Terrain/Terrain.cpp

     
    178178        /////////////////////////////////////////////////////////////////////////
    179179        // Terrain elevation
    180180        wxSizer* sizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Elevation tools"));
    181         wxSizer* gridSizer = new wxGridSizer(3);
     181        wxSizer* gridSizer = new wxGridSizer(4);
    182182        gridSizer->Add(Tooltipped(new ToolButton(scenarioEditor.GetToolManager(), this, _("Modify"), _T("AlterElevation")),
    183183            _("Brush with left mouse buttons to raise terrain,\nright mouse button to lower it")), wxSizerFlags().Expand());
     184        gridSizer->Add(Tooltipped(new ToolButton(scenarioEditor.GetToolManager(), this, _("Pike"), _T("PikeElevation")),
     185            _("Brush with left mouse buttons to raise terrain,\nright mouse button to lower it")), wxSizerFlags().Expand());
    184186        gridSizer->Add(Tooltipped(new ToolButton(scenarioEditor.GetToolManager(), this, _("Smooth"), _T("SmoothElevation")),
    185187            _("Brush with left mouse button to smooth terrain,\nright mouse button to roughen it")), wxSizerFlags().Expand());
    186188        gridSizer->Add(Tooltipped(new ToolButton(scenarioEditor.GetToolManager(), this, _("Flatten"), _T("FlattenElevation")),
  • source/tools/atlas/AtlasUI/ScenarioEditor/Tools/PikeElevation.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
     25using AtlasMessage::Position;
     26
     27class PikeElevation : public StateDrivenTool<PikeElevation>
     28{
     29    DECLARE_DYNAMIC_CLASS(PikeElevation);
     30
     31    Position m_Pos;
     32
     33public:
     34    PikeElevation()
     35    {
     36        SetState(&Waiting);
     37    }
     38
     39
     40    void OnEnable()
     41    {
     42        g_Brush_Elevation.MakeActive();
     43    }
     44
     45    void OnDisable()
     46    {
     47        POST_MESSAGE(BrushPreview, (false, Position()));
     48    }
     49
     50
     51    struct sWaiting : public State
     52    {
     53        bool OnMouse(PikeElevation* obj, wxMouseEvent& evt)
     54        {
     55            if (evt.LeftDown())
     56            {
     57                obj->m_Pos = Position(evt.GetPosition());
     58                SET_STATE(Piking);
     59                return true;
     60            }
     61            else if (evt.Moving())
     62            {
     63                POST_MESSAGE(BrushPreview, (true, Position(evt.GetPosition())));
     64                return true;
     65            }
     66            else
     67            {
     68                return false;
     69            }
     70        }
     71    }
     72    Waiting;
     73
     74
     75    struct sPiking : public State
     76    {
     77        void OnEnter(PikeElevation* obj)
     78        {
     79            POST_MESSAGE(BrushPreview, (true, obj->m_Pos));
     80        }
     81
     82        void OnLeave(PikeElevation*)
     83        {
     84            ScenarioEditor::GetCommandProc().FinaliseLastCommand();
     85        }
     86
     87        bool OnMouse(PikeElevation* obj, wxMouseEvent& evt)
     88        {
     89            if (evt.LeftUp())
     90            {
     91                SET_STATE(Waiting);
     92                return true;
     93            }
     94            else if (evt.Dragging())
     95            {
     96                wxPoint pos = evt.GetPosition();
     97                obj->m_Pos = Position(pos);
     98                POST_MESSAGE(BrushPreview, (true, obj->m_Pos));
     99                return true;
     100            }
     101            else
     102            {
     103                return false;
     104            }
     105        }
     106
     107        void OnTick(PikeElevation* obj, float dt)
     108        {
     109            POST_COMMAND(PikeElevation, (obj->m_Pos, dt*4096.f*g_Brush_Elevation.GetStrength()));
     110            obj->m_Pos = Position::Unchanged();
     111        }
     112    }
     113    Piking;
     114};
     115
     116IMPLEMENT_DYNAMIC_CLASS(PikeElevation, StateDrivenTool<PikeElevation>);
  • source/tools/atlas/GameInterface/Handlers/ElevationHandlers.cpp

     
    365365};
    366366END_COMMAND(FlattenElevation)
    367367
     368
     369BEGIN_COMMAND(PikeElevation)
     370{
     371    TerrainArray m_TerrainDelta;
     372    ssize_t m_i0, m_j0, m_i1, m_j1; // dirtied tiles (inclusive lower bound, exclusive upper)
     373
     374    cPikeElevation()
     375    {
     376        m_TerrainDelta.Init();
     377    }
     378
     379    void MakeDirty()
     380    {
     381        g_Game->GetWorld()->GetTerrain()->MakeDirty(m_i0, m_j0, m_i1, m_j1, RENDERDATA_UPDATE_VERTICES);
     382        CmpPtr<ICmpTerrain> cmpTerrain(*g_Game->GetSimulation2(), SYSTEM_ENTITY);
     383        if (cmpTerrain)
     384            cmpTerrain->MakeDirty(m_i0, m_j0, m_i1, m_j1);
     385    }
     386
     387    void Do()
     388    {
     389        int amount = (int)msg->amount;
     390
     391        // If the framerate is very high, 'amount' is often very
     392        // small (even zero) so the integer truncation is significant
     393        static float roundingError = 0.0;
     394        roundingError += msg->amount - (float)amount;
     395        if (roundingError >= 1.f)
     396        {
     397            amount += (int)roundingError;
     398            roundingError -= (float)(int)roundingError;
     399        }
     400
     401        static CVector3D previousPosition;
     402        g_CurrentBrush.m_Centre = msg->pos->GetWorldSpace(previousPosition);
     403        previousPosition = g_CurrentBrush.m_Centre;
     404
     405        ssize_t x0, y0;
     406        g_CurrentBrush.GetBottomLeft(x0, y0);
     407        float h = ((float) g_CurrentBrush.m_H-1)/2.f;
     408
     409        for (ssize_t dy = 0; dy < g_CurrentBrush.m_H; ++dy)
     410        {
     411            for (ssize_t dx = 0; dx < g_CurrentBrush.m_W; ++dx)
     412            {
     413                float b = g_CurrentBrush.Get(dx, dy);
     414                if (b)
     415                {
     416                    float x = (float) dx - ((float)g_CurrentBrush.m_H-1)/2.f;
     417                    float y = (float) dy - ((float)g_CurrentBrush.m_W-1)/2.f;
     418                    float distance = clamp(1 - (float) sqrt(x*x + y*y)/h,0.f,1.f);
     419                    m_TerrainDelta.RaiseVertex(x0+dx, y0+dy, (int)(amount*distance));
     420                }
     421            }
     422        }
     423        m_i0 = x0 - 1;
     424        m_j0 = y0 - 1;
     425        m_i1 = x0 + g_CurrentBrush.m_W;
     426        m_j1 = y0 + g_CurrentBrush.m_H;
     427        MakeDirty();
     428    }
     429
     430    void Undo()
     431    {
     432        m_TerrainDelta.Undo();
     433        MakeDirty();
     434    }
     435
     436    void Redo()
     437    {
     438        m_TerrainDelta.Redo();
     439        MakeDirty();
     440    }
     441
     442    void MergeIntoPrevious(cPikeElevation* prev)
     443    {
     444        prev->m_TerrainDelta.OverlayWith(m_TerrainDelta);
     445        prev->m_i0 = std::min(prev->m_i0, m_i0);
     446        prev->m_j0 = std::min(prev->m_j0, m_j0);
     447        prev->m_i1 = std::max(prev->m_i1, m_i1);
     448        prev->m_j1 = std::max(prev->m_j1, m_j1);
     449    }
     450};
     451END_COMMAND(PikeElevation)
     452
    368453}
  • source/tools/atlas/GameInterface/Messages.h

     
    496496        ((float, amount))
    497497        );
    498498
     499COMMAND(PikeElevation, MERGE,
     500        ((Position, pos))
     501        ((float, amount))
     502        );
     503
    499504struct ePaintTerrainPriority { enum { HIGH, LOW }; };
    500505COMMAND(PaintTerrain, MERGE,
    501506        ((Position, pos))