This Trac instance is not used for development anymore!

We migrated our development workflow to git and Gitea.
To test the future redirection, replace trac by ariadne in the page URL.

Changeset 10029 for ps


Ignore:
Timestamp:
08/18/11 01:44:52 (13 years ago)
Author:
ben
Message:

Adds terrain fill (bucket) tool to Atlas.

Location:
ps/trunk/source/tools/atlas
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • ps/trunk/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Terrain/Terrain.cpp

    r9797 r10029  
    7676        gridSizer->Add(new ToolButton(scenarioEditor.GetToolManager(), this, _("Paint"), _T("PaintTerrain")), wxSizerFlags().Expand());
    7777        gridSizer->Add(new ToolButton(scenarioEditor.GetToolManager(), this, _("Replace"), _T("ReplaceTerrain")), wxSizerFlags().Expand());
     78        gridSizer->Add(new ToolButton(scenarioEditor.GetToolManager(), this, _("Fill"), _T("FillTerrain")), wxSizerFlags().Expand());
    7879        sizer->Add(gridSizer, wxSizerFlags().Expand());
    7980        m_MainSizer->Add(sizer, wxSizerFlags().Expand().Border(wxTOP, 10));
     
    295296        // when they selected a terrain; unless already explicitly in Replace mode, because
    296297        // then the user probably wanted that instead
    297         if (m_ScenarioEditor.GetToolManager().GetCurrentToolName() != _T("ReplaceTerrain"))
     298        if (m_ScenarioEditor.GetToolManager().GetCurrentToolName() != _T("ReplaceTerrain") && m_ScenarioEditor.GetToolManager().GetCurrentToolName() != _T("FillTerrain"))
    298299            m_ScenarioEditor.GetToolManager().SetCurrentTool(_T("PaintTerrain"));
    299300    }
  • ps/trunk/source/tools/atlas/GameInterface/Handlers/TerrainHandlers.cpp

    r9566 r10029  
    3333#include "simulation2/components/ICmpPathfinder.h"
    3434#include "simulation2/components/ICmpTerrain.h"
     35#include "simulation2/helpers/Grid.h"
    3536
    3637#include "../Brushes.h"
     
    345346
    346347        CTerrainTextureEntry* replacedTex = m_TerrainDelta.GetTexEntry(x0, y0);
     348
     349        // Don't bother if we're not making a change
     350        if (texentry == replacedTex)
     351        {
     352            return;
     353        }
    347354
    348355        ssize_t tiles = m_TerrainDelta.GetTilesPerSide();
     
    380387END_COMMAND(ReplaceTerrain)
    381388
     389//////////////////////////////////////////////////////////////////////////
     390
     391BEGIN_COMMAND(FillTerrain)
     392{
     393    TerrainArray m_TerrainDelta;
     394    ssize_t m_i0, m_j0, m_i1, m_j1;
     395
     396    cFillTerrain()
     397    {
     398        m_TerrainDelta.Init();
     399    }
     400
     401    void MakeDirty()
     402    {
     403        g_Game->GetWorld()->GetTerrain()->MakeDirty(m_i0, m_j0, m_i1, m_j1, RENDERDATA_UPDATE_INDICES);
     404        CmpPtr<ICmpTerrain> cmpTerrain(*g_Game->GetSimulation2(), SYSTEM_ENTITY);
     405        if (!cmpTerrain.null())
     406            cmpTerrain->MakeDirty(m_i0, m_j0, m_i1, m_j1);
     407    }
     408
     409    void Do()
     410    {
     411        g_CurrentBrush.m_Centre = msg->pos->GetWorldSpace();
     412
     413        ssize_t x0, y0;
     414        g_CurrentBrush.GetBottomLeft(x0, y0);
     415
     416        m_i0 = m_i1 = x0;
     417        m_j0 = m_j1 = y0;
     418
     419        CTerrainTextureEntry* texentry = g_TexMan.FindTexture(CStrW(*msg->texture).ToUTF8());
     420        if (! texentry)
     421        {
     422            debug_warn(L"Can't find texentry"); // TODO: nicer error handling
     423            return;
     424        }
     425
     426        CTerrainTextureEntry* replacedTex = m_TerrainDelta.GetTexEntry(x0, y0);
     427
     428        // Don't bother if we're not making a change
     429        if (texentry == replacedTex)
     430        {
     431            return;
     432        }
     433
     434        ssize_t tiles = m_TerrainDelta.GetTilesPerSide();
     435
     436        // Simple 4-way flood fill algorithm using queue and a grid to keep track of visited tiles,
     437        //  almost as fast as loop for filling whole map, much faster for small patches
     438        SparseGrid<bool> visited(tiles, tiles);
     439        std::queue<std::pair<u16, u16>> queue;
     440
     441        // Initial tile
     442        queue.push(std::make_pair((u16)x0, (u16)y0));
     443        visited.set(x0, y0, true);
     444
     445        while(!queue.empty())
     446        {
     447            // Check front of queue
     448            std::pair<u16, u16> t = queue.front();
     449            queue.pop();
     450            u16 i = t.first;
     451            u16 j = t.second;
     452
     453            if (m_TerrainDelta.GetTexEntry(i, j) == replacedTex)
     454            {
     455                // Found a tile to replace: adjust bounds and paint it
     456                m_i0 = std::min(m_i0, (ssize_t)i);
     457                m_j0 = std::min(m_j0, (ssize_t)j);
     458                m_i1 = std::max(m_i1, (ssize_t)i+1);
     459                m_j1 = std::max(m_j1, (ssize_t)j+1);
     460                m_TerrainDelta.PaintTile(i, j, texentry, m_TerrainDelta.GetPriority(i, j));
     461
     462                // Visit 4 adjacent tiles (could visit 8 if we want to count diagonal adjacency)
     463                if (i > 0 && !visited.get(i-1, j))
     464                {
     465                    visited.set(i-1, j, true);
     466                    queue.push(std::make_pair(i-1, j));
     467                }
     468                if (i < (tiles-1) && !visited.get(i+1, j))
     469                {
     470                    visited.set(i+1, j, true);
     471                    queue.push(std::make_pair(i+1, j));
     472                }
     473                if (j > 0 && !visited.get(i, j-1))
     474                {
     475                    visited.set(i, j-1, true);
     476                    queue.push(std::make_pair(i, j-1));
     477                }
     478                if (j < (tiles-1) && !visited.get(i, j+1))
     479                {
     480                    visited.set(i, j+1, true);
     481                    queue.push(std::make_pair(i, j+1));
     482                }
     483            }
     484        }
     485
     486        MakeDirty();
     487    }
     488
     489    void Undo()
     490    {
     491        m_TerrainDelta.Undo();
     492        MakeDirty();
     493    }
     494
     495    void Redo()
     496    {
     497        m_TerrainDelta.Redo();
     498        MakeDirty();
     499    }
     500};
     501END_COMMAND(FillTerrain)
    382502
    383503}
  • ps/trunk/source/tools/atlas/GameInterface/Messages.h

    r9617 r10029  
    460460        );
    461461
     462COMMAND(FillTerrain, NOMERGE,
     463        ((Position, pos))
     464        ((std::wstring, texture))
     465        );
     466
    462467//////////////////////////////////////////////////////////////////////////
    463468
Note: See TracChangeset for help on using the changeset viewer.