载入中...
搜索中...
未找到
TileSystem.cpp
浏览该文件的文档.
1#include "map/TileSystem.h"
2#include "map/TileLayer.h"
3#include "map/TileConfig.h"
5#include "graphics/Graphics.h"
7#include "graphics/Canvas.h"
9#include "common/Module.h"
10
11#include <vector>
12
13namespace eve::map {
14namespace {
15
16struct ViewCam {
17 float x = 0.f;
18 float y = 0.f;
19 float zoom = 1.f;
20 bool valid = false;
21};
22
23ViewCam fromEntity(graphics::Camera2D *ent) {
24 ViewCam v;
25 if (!ent) return v;
26 auto d = ent->data();
27 v.valid = true;
28 v.x = d->x;
29 v.y = d->y;
30 v.zoom = d->zoom;
31 return v;
32}
33
35Color solidForGid(uint32_t gid, const Color &tint) {
36 const uint32_t h = gid * 2654435761u;
37 const float r = ((h >> 0) & 255u) / 255.f;
38 const float g = ((h >> 8) & 255u) / 255.f;
39 const float b = ((h >> 16) & 255u) / 255.f;
40 return Color{r * tint.r, g * tint.g, b * tint.b, tint.a};
41}
42
43bool atlasUV(const TileLayer::Tileset &ts, uint32_t gid, float &u0, float &v0, float &u1,
44 float &v1) {
45 if (!ts.texture || ts.columns <= 0 || ts.tileW <= 0 || ts.tileH <= 0) return false;
46 if (gid < uint32_t(ts.firstGid)) return false;
47 const int local = int(gid) - ts.firstGid;
48 const int col = local % ts.columns;
49 const int row = local / ts.columns;
50 const float iw = float(ts.texture->getWidth());
51 const float ih = float(ts.texture->getHeight());
52 if (iw <= 0.f || ih <= 0.f) return false;
53
54 const float px = float(ts.margin + col * (ts.tileW + ts.spacing));
55 const float py = float(ts.margin + row * (ts.tileH + ts.spacing));
56 u0 = px / iw;
57 v0 = py / ih;
58 u1 = (px + float(ts.tileW)) / iw;
59 v1 = (py + float(ts.tileH)) / ih;
60 return true;
61}
62
63int64_t fileModtime(const std::string &path) {
64 auto *fs = eve::ModuleManager::getInstance<eve::filesystem::Filesystem>("Filesystem");
65 if (!fs) fs = eve::filesystem::Filesystem::create();
67 if (!fs->getInfo(path, info)) return -1;
68 return info.modtime;
69}
70
71} // namespace
72
73void TileRenderSystem::collect(std::vector<graphics::DrawItem2D> &out) {
74 if (ecs::current()->getManager<TileLayer>() == nullptr) return;
75
78 for (auto it = view.begin(); it != view.end(); ++it) {
79 auto [cfg, tiles, ts, draw] = *it;
80 if (!draw->visible || cfg->mapW <= 0 || cfg->mapH <= 0) continue;
81 if (tiles->gids.size() < size_t(cfg->mapW * cfg->mapH)) continue;
82
83 const Color &tint = draw->tint;
84 const ViewCam cam = fromEntity(draw->camera);
85
86 for (int ty = 0; ty < cfg->mapH; ++ty) {
87 for (int tx = 0; tx < cfg->mapW; ++tx) {
88 const uint32_t raw = tiles->gids[size_t(ty * cfg->mapW + tx)];
89 const uint32_t gid = tileGid(raw);
90 if (gid == 0) continue;
91
93 tileToWorld(*cfg, tx, ty, item.x, item.y);
94 item.w = cfg->tileW;
95 item.h = cfg->tileH;
96 item.depthY = tileToDepthY(*cfg, tx, ty);
97 item.layer = draw->layer;
98 item.canvas = draw->canvas;
99 item.camera = draw->camera;
100 item.camValid = cam.valid;
101 item.camX = cam.x;
102 item.camY = cam.y;
103 item.camZoom = cam.zoom;
104 item.receiveLight = false;
105 item.litPath = false;
106
107 float u0, v0, u1, v1;
108 if (atlasUV(*ts, gid, u0, v0, u1, v1)) {
109 item.texture = ts->texture;
110 item.hasUV = true;
111 item.u0 = u0;
112 item.v0 = v0;
113 item.u1 = u1;
114 item.v1 = v1;
115 item.color = tint;
116 } else {
117 item.texture = nullptr;
118 item.color = solidForGid(gid, tint);
119 }
120 out.push_back(item);
121 }
122 }
123 }
124}
125
127 if (!gfx) return;
128 std::vector<graphics::DrawItem2D> items;
129 collect(items);
130 graphics::RenderSystem::drawItems(*gfx, items, false);
131}
132
134 if (ecs::current()->getManager<TileLayer>() == nullptr) return 0;
135
136 int reloaded = 0;
137 auto view = ecs::View<TileLayer, TileLayer::Config, TileLayer::Resource>();
138 for (auto it = view.begin(); it != view.end(); ++it) {
139 auto [cfg, res] = *it;
140 if (!res->autoReload || res->path.empty() || !cfg->entity) continue;
141
142 const int64_t mt = fileModtime(res->path);
143 if (mt < 0 || mt == res->modtime) continue;
144 if (reloadConfigFile(cfg->entity, nullptr)) ++reloaded;
145 }
146 return reloaded;
147}
148
149} // namespace eve::map
int y
Definition Grass.cpp:135
int x
Definition Grass.cpp:135
int h
std::vector< Colorf > px
uint32_t b
glm::mat4 view
float zoom
bool valid
int d
int v
std::vector< WfcTile > tiles
Definition WfcSimple.cpp:22
static void drawItems(Graphics &gfx, std::vector< DrawItem2D > &items, bool present)
Sort and draw items. If present=true, calls gfx.present() at the end. Map::render uses present=false ...
ECS tile layer entity. Script mutates tile GIDs / tileset / draw; TileRenderSystem batch-draws atlas ...
Definition TileLayer.h:30
static void collect(std::vector< graphics::DrawItem2D > &out)
Append non-empty visible tiles into a shared 2D draw queue.
static void render(graphics::Graphics *gfx)
Collect + draw tiles only (no present). Null gfx is a no-op.
glm::vec4 Color
RGBA color used by every graphics draw call. Lives inside eve::graphics so including a graphics heade...
Definition Color.h:13
放置世界:格子占用(多通道)+ 地形语义 + 已放置建筑实例。 行为由 PlacementSystem 提供;本类暴露便于脚本绑定的薄封装方法。 坐标换算统一走 eve::grid(支持 rectang...
void tileToWorld(const TileLayer::Config &cfg, int tx, int ty, float &wx, float &wy)
Converts a tile index to world pixels using the layer's projection.
bool reloadConfigFile(TileLayer *layer, std::string *error)
uint32_t tileGid(uint32_t raw)
Strip Tiled flip / rotate flags; keep low 28 bits.
Definition TileLayer.h:161
float tileToDepthY(const TileLayer::Config &cfg, int tx, int ty)
Painter's-algorithm depth for the tile under the layer's projection.
WidgetDesc row(std::vector< WidgetDesc > children, std::string id)
Horizontal elastic layout row.
Definition Widget.cpp:431
Shared 2D draw queue item (sprites + tiles).
Definition DrawItem2D.h:18
float camX
Screen-space camera already resolved; if cameraEntity set, RenderSystem resolves.
Definition DrawItem2D.h:47