Polyphase Game Engine
Loading...
Searching...
No Matches
TileMap.h
Go to the documentation of this file.
1#pragma once
2
3#include <string>
4#include <vector>
5#include <unordered_map>
6#include <unordered_set>
7#include "glm/glm.hpp"
8#include "Asset.h"
9#include "AssetRef.h"
10
11class TileSet;
12
13// Tiles within a layer are stored in fixed-size chunks. Empty chunks are not
14// allocated, so painting outward (including in negative coordinates) only
15// costs memory for the cells that have actually been touched.
16static constexpr int32_t kTileChunkSize = 32;
17
18enum class TileMapLayerType : uint8_t
19{
20 Visual = 0,
22 Decal,
24
25 Count
26};
27
28// Single placed cell in a layer. mTileIndex of -1 means "no tile".
30{
31 int32_t mTileIndex = -1;
32 uint8_t mFlags = 0; // bit 0 = flipX, bit 1 = flipY, bit 2 = rot90, bit 3 = hidden
33 uint8_t mPadding = 0;
34 int16_t mVariant = 0; // for animated/variant tiles
35};
36
37// A fixed-size grid of cells. Allocated lazily when the first cell is painted.
39{
40 TileCell mCells[kTileChunkSize * kTileChunkSize] = {};
41};
42
44{
45 std::string mName = "Layer";
46 bool mVisible = true;
47 bool mLocked = false;
48 float mOpacity = 1.0f;
50 int32_t mZOrder = 0;
51
52 // Sparse chunk storage. Key packs (chunkX, chunkY) into one int64_t so
53 // negative coordinates work natively.
54 std::unordered_map<int64_t, TileChunk> mChunks;
55};
56
58{
59public:
60
62
63 TileMap();
64 virtual ~TileMap();
65
66 virtual void LoadStream(Stream& stream, Platform platform) override;
67 virtual void SaveStream(Stream& stream, Platform platform) override;
68 virtual void Create() override;
69 virtual void Destroy() override;
70 virtual void GatherProperties(std::vector<Property>& outProps) override;
71 virtual glm::vec4 GetTypeColor() override;
72 virtual const char* GetTypeName() override;
73
74 TileSet* GetTileSet() const;
75 void SetTileSet(TileSet* tileSet);
76
77 glm::ivec2 GetTileSize() const { return mTileSize; }
78 void SetTileSize(glm::ivec2 size) { mTileSize = size; }
79
80 glm::vec2 GetOrigin() const { return mOrigin; }
81 void SetOrigin(glm::vec2 origin) { mOrigin = origin; }
82
83 int32_t GetNumLayers() const { return int32_t(mLayers.size()); }
84 TileMapLayer* GetLayer(int32_t layerIndex);
85 const TileMapLayer* GetLayer(int32_t layerIndex) const;
86
87 // Cell APIs. Layer index is clamped to [0, numLayers). Out-of-range layers
88 // become no-ops on writes / return -1 on reads.
89 TileCell GetCell(int32_t cellX, int32_t cellY, int32_t layerIndex = 0) const;
90 void SetCell(int32_t cellX, int32_t cellY, const TileCell& cell, int32_t layerIndex = 0);
91 void ClearCell(int32_t cellX, int32_t cellY, int32_t layerIndex = 0);
92 bool IsCellOccupied(int32_t cellX, int32_t cellY, int32_t layerIndex = 0) const;
93
94 // Convenience for the simple "tile index" path used by paint tools and Lua.
95 int32_t GetTile(int32_t cellX, int32_t cellY, int32_t layerIndex = 0) const;
96 void SetTile(int32_t cellX, int32_t cellY, int32_t tileIndex, int32_t layerIndex = 0);
97
98 // Bulk replace helpers (Phase 3). Returns the number of cells modified.
99 // ReplaceTile swaps every cell whose mTileIndex equals oldIndex.
100 // ReplaceTilesWithTag uses the bound TileSet to match cells whose tile carries the tag.
101 int32_t ReplaceTile(int32_t oldIndex, int32_t newIndex, int32_t layerIndex = 0);
102 int32_t ReplaceTilesWithTag(const std::string& tag, int32_t newIndex, int32_t layerIndex = 0);
103 int32_t CountTileUses(int32_t tileIndex, int32_t layerIndex = 0) const;
104
105 // Used-area bookkeeping. Updated by SetCell so the renderer can build a
106 // tight AABB without scanning every chunk.
107 glm::ivec2 GetMinUsed() const { return mMinUsed; }
108 glm::ivec2 GetMaxUsed() const { return mMaxUsed; }
109 bool HasContent() const { return mHasContent; }
110
111 // Dirty-chunk tracking. The node calls TakeDirtyChunks() each tick to
112 // figure out which chunks need a vertex rebuild + GPU upload.
113 const std::unordered_set<int64_t>& GetDirtyChunks() const { return mDirtyChunks; }
114 void ClearDirtyChunks() { mDirtyChunks.clear(); }
115 void MarkAllDirty();
116
117 // Chunk key helpers — exposed because the node and the paint manager need them.
118 static int64_t PackChunkKey(int32_t chunkX, int32_t chunkY);
119 static void UnpackChunkKey(int64_t key, int32_t& outChunkX, int32_t& outChunkY);
120 static int32_t FloorDivChunk(int32_t cell);
121 static int32_t FloorModChunk(int32_t cell);
122
123 static bool HandlePropChange(class Datum* datum, uint32_t index, const void* newValue);
124
125protected:
126
127 void EnsureLayer(int32_t layerIndex);
128 void RecomputeUsedBounds();
129
131 // Default to 1 world unit per cell — matches standard 2D engine conventions
132 // and keeps freshly-spawned TileMap2D nodes visible without scaling. Override
133 // in the inspector if you want pixel-perfect or larger physics units.
134 glm::ivec2 mTileSize = { 1, 1 };
135 glm::vec2 mOrigin = { 0.0f, 0.0f };
136 bool mAllowNegativeCoords = true;
137
138 std::vector<TileMapLayer> mLayers;
139
140 glm::ivec2 mMinUsed = { 0, 0 };
141 glm::ivec2 mMaxUsed = { 0, 0 };
142 bool mHasContent = false;
143
144 std::unordered_set<int64_t> mDirtyChunks;
145};
Platform
Definition EngineTypes.h:31
#define POLYPHASE_API
Definition PolyphaseAPI.h:31
TileMapLayerType
Definition TileMap.h:19
Definition AssetRef.h:18
Definition Asset.h:113
virtual void Create()
Definition Asset.cpp:77
virtual void SaveStream(Stream &stream, Platform platform)
Definition Asset.cpp:236
virtual glm::vec4 GetTypeColor()
Definition Asset.cpp:254
virtual const char * GetTypeName()
Definition Asset.cpp:259
virtual void GatherProperties(std::vector< Property > &outProps) override
Definition Asset.cpp:249
virtual void LoadStream(Stream &stream, Platform platform)
Definition Asset.cpp:222
virtual void Destroy()
Definition Asset.cpp:87
Definition Datum.h:164
Definition Stream.h:21
Definition TileMap.h:58
void SetOrigin(glm::vec2 origin)
Definition TileMap.h:81
void SetTileSize(glm::ivec2 size)
Definition TileMap.h:78
void ClearDirtyChunks()
Definition TileMap.h:114
int32_t GetNumLayers() const
Definition TileMap.h:83
glm::ivec2 GetTileSize() const
Definition TileMap.h:77
glm::ivec2 GetMinUsed() const
Definition TileMap.h:107
glm::ivec2 GetMaxUsed() const
Definition TileMap.h:108
AssetRef mTileSet
Definition TileMap.h:130
glm::vec2 GetOrigin() const
Definition TileMap.h:80
std::unordered_set< int64_t > mDirtyChunks
Definition TileMap.h:144
DECLARE_ASSET(TileMap, Asset)
const std::unordered_set< int64_t > & GetDirtyChunks() const
Definition TileMap.h:113
std::vector< TileMapLayer > mLayers
Definition TileMap.h:138
bool HasContent() const
Definition TileMap.h:109
Definition TileSet.h:102
Definition TileMap.h:30
int32_t mTileIndex
Definition TileMap.h:31
uint8_t mPadding
Definition TileMap.h:33
uint8_t mFlags
Definition TileMap.h:32
int16_t mVariant
Definition TileMap.h:34
Definition TileMap.h:39
TileCell mCells[kTileChunkSize *kTileChunkSize]
Definition TileMap.h:40
Definition TileMap.h:44
std::string mName
Definition TileMap.h:45
std::unordered_map< int64_t, TileChunk > mChunks
Definition TileMap.h:54
float mOpacity
Definition TileMap.h:48
TileMapLayerType mType
Definition TileMap.h:49
bool mLocked
Definition TileMap.h:47
int32_t mZOrder
Definition TileMap.h:50
bool mVisible
Definition TileMap.h:46