Olympe Engine 2.0
2D Game Engine with ECS Architecture
Loading...
Searching...
No Matches
TiledToOlympe.h
Go to the documentation of this file.
1/*
2 * TiledToOlympe.h - TMJ to Olympe Engine Level Converter
3 *
4 * Converts Tiled maps (.tmj) to Olympe Engine's internal level format:
5 * - Tile layers -> tileMap grid
6 * - Object layers -> entities (with prefab mapping)
7 * - Collision objects -> collisionMap
8 * - Polygon objects -> sectors
9 * - Polyline objects -> patrol paths
10 * - Image layers -> parallax layer metadata
11 * - Custom properties -> entity overrides
12 *
13 * ISOMETRIC COORDINATE CONVERSION:
14 * --------------------------------
15 * For isometric maps, TMJ stores object positions where BOTH X and Y are
16 * measured in tileHeight units. The conversion formula is:
17 * tileX = tmjPixelX / tileHeight
18 * tileY = tmjPixelY / tileHeight
19 * worldX = (tileX - tileY) * (tileWidth / 2)
20 * worldY = (tileX + tileY) * (tileHeight / 2)
21 *
22 * See TiledToOlympe.cpp and IsometricProjection.cpp for implementation.
23 */
24
25#pragma once
26
27#include "TiledStructures.h"
28#include "../../vector.h"
29#include <string>
30#include <map>
31#include <set>
32#include <memory>
33#include <functional>
34#include "../../third_party/nlohmann/json.hpp"
35
36// Forward declare Olympe::Editor types
37namespace Olympe {
38namespace Editor {
39 struct LevelDefinition;
40 struct EntityInstance;
41}
42}
43
44namespace Olympe {
45namespace Tiled {
46
47 // Configuration for conversion
49 {
50 // Map Tiled object types to Olympe prefab paths
51 std::map<std::string, std::string> typeToPrefabMap;
52
53 // Default prefab for objects without a type
54 std::string defaultPrefab;
55
56 // Layer name patterns for collision (e.g., "collision", "walls")
57 std::vector<std::string> collisionLayerPatterns;
58
59 // Layer name patterns for sectors (e.g., "sectors", "zones")
60 std::vector<std::string> sectorLayerPatterns;
61
62 // Whether to flip Y coordinates (Tiled uses top-left origin)
63 bool flipY;
64
65 // Base path for resolving relative image paths
66 std::string resourceBasePath;
67
68 // Map orientation ("orthogonal" or "isometric")
69 std::string mapOrientation;
70
71 // Tile dimensions for isometric projection
74
75 // Render order ("right-down", "right-up", "left-down", "left-up")
76 std::string renderOrder;
77
79 : defaultPrefab("Blueprints/DefaultEntity.json")
80 , flipY(true)
82 , mapOrientation("orthogonal")
83 , tileWidth(0)
84 , tileHeight(0)
85 , renderOrder("right-down")
86 {
87 // All members are now properly initialized in the initializer list
88 }
89 };
90
91
92
94 {
95 public:
98
99 // Set conversion configuration
100 void SetConfig(const ConversionConfig& config);
101
102 // Calculate actual map bounds for infinite maps
104 {
105 int minTileX = 0;
106 int minTileY = 0;
107 int maxTileX = 0;
108 int maxTileY = 0;
109 int widthInTiles = 0; // Actual width in tiles
110 int heightInTiles = 0; // Actual height in tiles
111 };
112
114
115 // Convert Tiled map to Olympe LevelDefinition
117
118 // Load prefab mapping from JSON file
119 bool LoadPrefabMapping(const std::string& jsonFilePath);
120
121 // Get last error message
122 const std::string& GetLastError() const { return lastError_; }
123
124 private:
125 // Conversion statistics
129 int patrolPaths = 0;
132 };
133
134 // New 6-phase pipeline methods
141 int& layerCount);
144 int& objectCount);
147 ConversionStats& stats);
150 int& linkCount);
153
154 // Helper methods
155 std::string ResolveImagePath(const std::string& imagePath);
159 int& zOrder,
160 int& layerCount);
161
162 // Convert layers (legacy methods kept for compatibility)
165 void ConvertImageLayer(const TiledLayer& layer);
167
168 // Convert objects (with layer offset support)
170 float layerOffsetX = 0.0f, float layerOffsetY = 0.0f);
173 float layerOffsetX = 0.0f, float layerOffsetY = 0.0f);
175 float layerOffsetX = 0.0f, float layerOffsetY = 0.0f);
177 float layerOffsetX = 0.0f, float layerOffsetY = 0.0f);
179 float layerOffsetX = 0.0f, float layerOffsetY = 0.0f);
180
181 // Parse entity descriptor from Tiled object (memory structure, NOT ECS entity)
182 std::unique_ptr<Olympe::Editor::EntityInstance> ParseEntityDescriptor(const TiledObject& obj,
183 float layerOffsetX = 0.0f,
184 float layerOffsetY = 0.0f);
185
186 // Convert properties to JSON overrides
187 void PropertiesToOverrides(const std::map<std::string, TiledProperty>& properties,
188 nlohmann::json& overrides);
189
190 // Get prefab path for object type
191 std::string GetPrefabPath(const std::string& objectType);
192
193 // Check if layer name matches pattern
194 bool MatchesPattern(const std::string& layerName, const std::vector<std::string>& patterns);
195
196 // Transform Y coordinate if needed
197 float TransformY(float y, float height);
198
199 // Transform object position - returns Vector directly (no conversion needed, TMJ coordinates are already in pixels)
200 // Added layer offsets for proper position adjustment
201 // For isometric: pass gid to apply tileset-based alignment and offsets
202 Vector TransformObjectPosition(float x, float y, float layerOffsetX = 0.0f, float layerOffsetY = 0.0f, uint32_t gid = 0);
203
204 // Helper to find tileset info for a given gid
205 const TiledTileset* FindTilesetForGid(uint32_t gid) const;
206
207 // Initialize collision map
209
210 // Merge tile layer into tilemap
211 void MergeTileLayer(const TiledLayer& layer,
212 std::vector<std::vector<int>>& tileMap,
213 int mapWidth, int mapHeight);
214
215 // Parse tint color from hex string to uint32_t
216 uint32_t ParseTintColor(const std::string& colorStr);
217
218 // Parse sector entity descriptor from polygon object (convenience wrapper)
219 std::unique_ptr<Olympe::Editor::EntityInstance> ParseSectorDescriptor(const TiledObject& obj,
220 float layerOffsetX = 0.0f,
221 float layerOffsetY = 0.0f);
222
223 // Parse patrol path entity descriptor from polyline object (convenience wrapper)
224 std::unique_ptr<Olympe::Editor::EntityInstance> ParsePatrolPathDescriptor(const TiledObject& obj,
225 float layerOffsetX = 0.0f,
226 float layerOffsetY = 0.0f);
227
228 // Parse collision polyline entity descriptor from polyline/polygon object
229 std::unique_ptr<Olympe::Editor::EntityInstance> ParseCollisionPolylineDescriptor(const TiledObject& obj,
230 float layerOffsetX = 0.0f,
231 float layerOffsetY = 0.0f);
232
234 std::string lastError_;
235
236 // ? MODIFIED: Actual map dimensions (calculated, not from TMJ)
237 int mapWidth_; // Actual width in tiles (from bounds calculation)
238 int mapHeight_; // Actual height in tiles (from bounds calculation)
239
240 // Declared TMJ dimensions (for origin alignment in infinite maps)
243
244 // ? NEW: Track if map is infinite. if true the map width/height are not reliable => we need to calculate bounds of the map while it loads
245 bool isInfiniteMap_ = false;
246
247 // Chunk coordinate system origin (for infinite maps)
250
251 // Actual tile coordinate bounds (for bounds-aware isometric origin calculation)
252 int minTileX_ = 0;
253 int minTileY_ = 0;
254 int maxTileX_ = 0;
255 int maxTileY_ = 0;
256
257 // Global offsets for entity position adjustment
258 // These offsets correct systematic positioning errors in isometric coordinate transformation
259 float globalOffsetX_ = 0.0f;
260 float globalOffsetY_ = 0.0f;
261
262 // Cached flags for performance optimization (updated during configuration)
263 bool hasOffsets_ = false; // true if any chunk origin or global offsets are non-zero
264 bool requiresYFlip_ = false; // true if render order requires Y-flip ("left-up" or "right-up")
265
266 // Store tilesets during conversion for gid lookup
267 const std::vector<TiledTileset>* tilesets_ = nullptr;
268 };
269
270} // namespace Tiled
271} // namespace Olympe
ComponentTypeID GetComponentTypeID_Static()
Definition ECS_Entity.h:56
bool Convert(const TiledMap &tiledMap, Olympe::Editor::LevelDefinition &outLevel)
const TiledTileset * FindTilesetForGid(uint32_t gid) const
void CategorizeGameObjects(const TiledMap &tiledMap, Olympe::Editor::LevelDefinition &outLevel, ConversionStats &stats)
const std::string & GetLastError() const
void ConvertSectorObject(const TiledObject &obj, Olympe::Editor::LevelDefinition &level, float layerOffsetX=0.0f, float layerOffsetY=0.0f)
std::string ResolveImagePath(const std::string &imagePath)
void PropertiesToOverrides(const std::map< std::string, TiledProperty > &properties, nlohmann::json &overrides)
std::unique_ptr< Olympe::Editor::EntityInstance > ParsePatrolPathDescriptor(const TiledObject &obj, float layerOffsetX=0.0f, float layerOffsetY=0.0f)
void ConvertObjectLayer(const TiledLayer &layer, Olympe::Editor::LevelDefinition &level)
void InitializeCollisionMap(Olympe::Editor::LevelDefinition &level, int width, int height)
nlohmann::json PropertyToJSON(const TiledProperty &prop)
void ConvertImageLayer(const TiledLayer &layer)
void ConvertCollisionObject(const TiledObject &obj, Olympe::Editor::LevelDefinition &level)
void MergeTileLayer(const TiledLayer &layer, std::vector< std::vector< int > > &tileMap, int mapWidth, int mapHeight)
void ConvertObject(const TiledObject &obj, Olympe::Editor::LevelDefinition &level, float layerOffsetX=0.0f, float layerOffsetY=0.0f)
float TransformY(float y, float height)
void ExtractSpatialStructures(const TiledMap &tiledMap, Olympe::Editor::LevelDefinition &outLevel, int &objectCount)
Vector TransformObjectPosition(float x, float y, float layerOffsetX=0.0f, float layerOffsetY=0.0f, uint32_t gid=0)
void ConvertTileLayer(const TiledLayer &layer, Olympe::Editor::LevelDefinition &level)
void SetConfig(const ConversionConfig &config)
std::unique_ptr< Olympe::Editor::EntityInstance > ParseSectorDescriptor(const TiledObject &obj, float layerOffsetX=0.0f, float layerOffsetY=0.0f)
void ExtractMapConfiguration(const TiledMap &tiledMap, Olympe::Editor::LevelDefinition &outLevel)
TiledToOlympe::MapBounds CalculateActualMapBounds(const TiledMap &tiledMap)
void BuildResourceCatalog(const TiledMap &tiledMap, Olympe::Editor::LevelDefinition &outLevel)
void ProcessGroupLayers(const TiledLayer &groupLayer, Olympe::Editor::LevelDefinition &outLevel, int &zOrder, int &layerCount)
bool MatchesPattern(const std::string &layerName, const std::vector< std::string > &patterns)
void ConvertCollisionObject(const TiledObject &obj, Olympe::Editor::LevelDefinition &level, float layerOffsetX=0.0f, float layerOffsetY=0.0f)
void ProcessVisualLayers(const TiledMap &tiledMap, Olympe::Editor::LevelDefinition &outLevel, int &layerCount)
void ConvertGroupLayer(const TiledLayer &layer, Olympe::Editor::LevelDefinition &level)
const std::vector< TiledTileset > * tilesets_
void ExtractObjectRelationships(const TiledMap &tiledMap, Olympe::Editor::LevelDefinition &outLevel, int &linkCount)
std::unique_ptr< Olympe::Editor::EntityInstance > ParseEntityDescriptor(const TiledObject &obj, float layerOffsetX=0.0f, float layerOffsetY=0.0f)
void ConvertPatrolPath(const TiledObject &obj, Olympe::Editor::LevelDefinition &level, float layerOffsetX=0.0f, float layerOffsetY=0.0f)
std::string GetPrefabPath(const std::string &objectType)
void ConvertPolygonCollision(const TiledObject &obj, Olympe::Editor::LevelDefinition &level, float layerOffsetX=0.0f, float layerOffsetY=0.0f)
bool LoadPrefabMapping(const std::string &jsonFilePath)
void ExtractMapMetadata(const TiledMap &tiledMap, Olympe::Editor::LevelDefinition &outLevel)
uint32_t ParseTintColor(const std::string &colorStr)
std::unique_ptr< Olympe::Editor::EntityInstance > ParseCollisionPolylineDescriptor(const TiledObject &obj, float layerOffsetX=0.0f, float layerOffsetY=0.0f)
nlohmann::json json
std::vector< std::string > collisionLayerPatterns
std::vector< std::string > sectorLayerPatterns
std::map< std::string, std::string > typeToPrefabMap