- Timestamp:
- 08/18/11 01:44:52 (13 years ago)
- Location:
- ps/trunk/source/tools/atlas
- Files:
-
- 3 edited
-
AtlasUI/ScenarioEditor/Sections/Terrain/Terrain.cpp (modified) (2 diffs)
-
GameInterface/Handlers/TerrainHandlers.cpp (modified) (3 diffs)
-
GameInterface/Messages.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
ps/trunk/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Terrain/Terrain.cpp
r9797 r10029 76 76 gridSizer->Add(new ToolButton(scenarioEditor.GetToolManager(), this, _("Paint"), _T("PaintTerrain")), wxSizerFlags().Expand()); 77 77 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()); 78 79 sizer->Add(gridSizer, wxSizerFlags().Expand()); 79 80 m_MainSizer->Add(sizer, wxSizerFlags().Expand().Border(wxTOP, 10)); … … 295 296 // when they selected a terrain; unless already explicitly in Replace mode, because 296 297 // 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")) 298 299 m_ScenarioEditor.GetToolManager().SetCurrentTool(_T("PaintTerrain")); 299 300 } -
ps/trunk/source/tools/atlas/GameInterface/Handlers/TerrainHandlers.cpp
r9566 r10029 33 33 #include "simulation2/components/ICmpPathfinder.h" 34 34 #include "simulation2/components/ICmpTerrain.h" 35 #include "simulation2/helpers/Grid.h" 35 36 36 37 #include "../Brushes.h" … … 345 346 346 347 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 } 347 354 348 355 ssize_t tiles = m_TerrainDelta.GetTilesPerSide(); … … 380 387 END_COMMAND(ReplaceTerrain) 381 388 389 ////////////////////////////////////////////////////////////////////////// 390 391 BEGIN_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 }; 501 END_COMMAND(FillTerrain) 382 502 383 503 } -
ps/trunk/source/tools/atlas/GameInterface/Messages.h
r9617 r10029 460 460 ); 461 461 462 COMMAND(FillTerrain, NOMERGE, 463 ((Position, pos)) 464 ((std::wstring, texture)) 465 ); 466 462 467 ////////////////////////////////////////////////////////////////////////// 463 468
Note:
See TracChangeset
for help on using the changeset viewer.
