Integrate the TilesetHashTable inside the same Tileset

This commit is contained in:
David Capello 2020-02-12 16:58:13 -03:00
parent 736e119440
commit d0f9429d03
4 changed files with 91 additions and 67 deletions

View File

@ -67,7 +67,7 @@
#include "doc/rgbmap.h"
#include "doc/sort_palette.h"
#include "doc/sprite.h"
#include "doc/tileset_hash_table.h"
#include "doc/tileset.h"
#include "os/surface.h"
#include "ui/alert.h"
#include "ui/graphics.h"
@ -777,21 +777,12 @@ void ColorBar::onRemapTilesButtonClick()
auto tileset = m_tilesView.tileset();
doc::TilesetHashTable hash;
{
doc::tile_index i = 0;
for (const auto& image : *tileset) {
ASSERT(image);
hash[image] = i++;
}
}
// Remap all tiles in the same order as in newTileset
Remap remap(tileset->size());
for (tile_index ti=0; ti<remap.size(); ++ti) {
auto img = m_oldTileset->get(ti);
if (img && hash.find(img) != hash.end()) {
auto destTi = hash[img];
tile_index destTi = tileset->findTileIndex(img);
if (img && destTi != doc::tile_i_notile) {
COLOR_BAR_TRACE(" - Remap tile %d -> %d\n", ti, destTi);
remap.map(ti, destTi);
}

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2019 Igara Studio S.A.
// Copyright (C) 2019-2020 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
@ -35,7 +35,6 @@
#include "doc/primitives.h"
#include "doc/sprite.h"
#include "doc/tileset.h"
#include "doc/tileset_hash_table.h"
#include "doc/tilesets.h"
#include "gfx/region.h"
#include "render/dithering.h"
@ -304,14 +303,6 @@ void draw_image_into_new_tilemap_cel(
doc::Grid grid = tileset->grid();
grid.origin(grid.origin() + originOffset);
doc::TilesetHashTable hashImages; // TODO the hashImages should be inside the Tileset
{
// Add existent tiles in the hash table
int i = 0;
for (auto& image : *tileset)
hashImages[image] = i++;
}
gfx::Size tileSize = grid.tileSize();
const gfx::Rect tilemapBounds = grid.canvasToTile(canvasBounds);
@ -337,23 +328,18 @@ void draw_image_into_new_tilemap_cel(
if (grid.hasMask())
mask_image(tileImage.get(), grid.mask().get());
doc::tile_index tileIndex = 0;
auto it = hashImages.find(tileImage);
if (it != hashImages.end()) {
tileIndex = it->second; // TODO
}
else {
doc::tile_index tileIndex =
tileset->findTileIndex(tileImage);
if (tileIndex == tile_i_notile) {
auto addTile = new cmd::AddTile(tileset, tileImage);
cmds->executeAndAdd(addTile);
tileIndex = addTile->tileIndex();
hashImages[tileImage] = tileIndex;
}
newTilemap->putPixel(
tilePt.x-tilemapBounds.x,
tilePt.y-tilemapBounds.y, doc::tile(tileIndex, 0));
tilePt.y-tilemapBounds.y, tileIndex);
}
static_cast<Doc*>(dstLayer->sprite()->document())
@ -409,14 +395,6 @@ void modify_tilemap_cel_region(
// Autogenerate tiles
if (tilesetMode == TilesetMode::Auto ||
tilesetMode == TilesetMode::Stack) {
doc::TilesetHashTable hashImages; // TODO the hashImages should be inside the Tileset
{
// Add existent tiles in the hash table
int i = 0;
for (auto& image : *tileset)
hashImages[image] = i++;
}
// TODO create a smaller image
doc::ImageRef newTilemap(
doc::Image::create(IMAGE_TILEMAP,
@ -460,12 +438,9 @@ void modify_tilemap_cel_region(
if (grid.hasMask())
mask_image(tileImage.get(), grid.mask().get());
tile_index tileIndex = 0;
auto it = hashImages.find(tileImage);
if (it != hashImages.end()) {
tileIndex = it->second; // TODO
tile_index tileIndex =
tileset->findTileIndex(tileImage);
if (tileIndex != tile_i_notile) {
if (tilesetMode == TilesetMode::Auto) {
if (tileIndex >= 0 && tileIndex < modifiedTileIndexes.size())
modifiedTileIndexes[tileIndex] = false;
@ -476,7 +451,6 @@ void modify_tilemap_cel_region(
cmds->executeAndAdd(addTile);
tileIndex = addTile->tileIndex();
hashImages[tileImage] = tileIndex;
}
OPS_TRACE(" - tile %d -> %d\n", ti, tileIndex);

View File

@ -1,5 +1,5 @@
// Aseprite Document Library
// Copyright (c) 2019 Igara Studio S.A.
// Copyright (c) 2019-2020 Igara Studio S.A.
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -26,8 +26,10 @@ Tileset::Tileset(Sprite* sprite,
, m_tiles(ntiles)
{
ASSERT(sprite);
for (tile_index ti=0; ti<ntiles; ++ti)
for (tile_index ti=0; ti<ntiles; ++ti) {
m_tiles[ti] = makeEmptyTile();
m_hash[m_tiles[ti]] = ti;
}
}
// static
@ -100,6 +102,46 @@ void Tileset::remap(const Remap& remap)
}
}
void Tileset::set(const tile_index ti,
const ImageRef& image)
{
removeFromHash(ti);
m_tiles[ti] = image;
m_hash[image] = ti;
}
tile_index Tileset::add(const ImageRef& image)
{
m_tiles.push_back(image);
const tile_index newIndex = tile_index(m_tiles.size()-1);
m_hash[image] = newIndex;
return newIndex;
}
void Tileset::insert(const tile_index ti,
const ImageRef& image)
{
ASSERT(ti <= size());
m_tiles.insert(m_tiles.begin()+ti, image);
// Fix all indexes in the hash that are greater than "ti"
for (auto& it : m_hash)
if (it.second >= ti)
++it.second;
// And now we can add the new image with the "ti" index
m_hash[image] = ti;
}
void Tileset::erase(const tile_index ti)
{
ASSERT(ti >= 0 && ti < size());
removeFromHash(ti);
m_tiles.erase(m_tiles.begin()+ti);
}
ImageRef Tileset::makeEmptyTile()
{
ImageSpec spec = m_sprite->spec();
@ -114,4 +156,26 @@ void Tileset::setExternal(const std::string& filename,
m_external.tileset = tsi;
}
tile_index Tileset::findTileIndex(const ImageRef& tileImage)
{
auto it = m_hash.find(tileImage);
if (it != m_hash.end())
return it->second;
else
return tile_i_notile;
}
void Tileset::removeFromHash(const tile_index ti)
{
for (auto it=m_hash.begin(); it!=m_hash.end(); ) {
if (it->second == ti)
it = m_hash.erase(it);
else {
if (it->second > ti)
--it->second;
++it;
}
}
}
} // namespace doc

View File

@ -1,5 +1,5 @@
// Aseprite Document Library
// Copyright (c) 2019 Igara Studio S.A.
// Copyright (c) 2019-2020 Igara Studio S.A.
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -12,6 +12,7 @@
#include "doc/image_ref.h"
#include "doc/object.h"
#include "doc/tile.h"
#include "doc/tileset_hash_table.h"
#include <string>
#include <vector>
@ -57,27 +58,13 @@ namespace doc {
else
return ImageRef(nullptr);
}
void set(const tile_index ti,
const ImageRef& image) {
m_tiles[ti] = image;
}
tile_index add(const ImageRef& image) {
m_tiles.push_back(image);
return tile_t(m_tiles.size()-1);
}
const ImageRef& image);
tile_index add(const ImageRef& image);
void insert(const tile_index ti,
const ImageRef& image) {
ASSERT(ti <= size());
m_tiles.insert(m_tiles.begin()+ti, image);
}
void erase(const tile_index ti) {
ASSERT(ti >= 0 && ti < size());
m_tiles.erase(m_tiles.begin()+ti);
}
const ImageRef& image);
void erase(const tile_index ti);
// Linked with an external file
void setExternal(const std::string& filename,
@ -99,10 +86,18 @@ namespace doc {
// Returns a new empty tile with the tileset specs.
ImageRef makeEmptyTile();
// If there is a tile in the set that matches the pixels of the
// given "tileImage", this function returns the index of that
// tile. Returns tile_i_notile if the image is not in the tileset.
tile_index findTileIndex(const ImageRef& tileImage);
private:
void removeFromHash(const tile_index ti);
Sprite* m_sprite;
Grid m_grid;
Tiles m_tiles;
TilesetHashTable m_hash;
std::string m_name;
struct External {
std::string filename;