mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-10 02:53:51 +00:00
feat(editor): add --gen-texture-mosaic 3-color tile pattern
Per-cell hash picks one of 3 colors for each square tile, with 1-pixel black grout on the top + left edges of every cell so tiles read as physically separated. Exit log breaks down how many tiles got each color so callers can verify the seed distribution. Defaults: tilePx=16, seed=1. Useful for cathedral floors, stained-glass set dressing, ornate plaza paving. Brings the procedural texture pattern set to 28.
This commit is contained in:
parent
f283ab2ce7
commit
6b1b901bc5
3 changed files with 98 additions and 0 deletions
|
|
@ -2278,6 +2278,98 @@ int handleVines(int& i, int argc, char** argv) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int handleMosaic(int& i, int argc, char** argv) {
|
||||
// 3-color mosaic: small square tiles randomly assigned one
|
||||
// of 3 colors, with 1-px black grout lines between them.
|
||||
// Per-tile color picked from a stable hash so the same seed
|
||||
// always yields the same mosaic.
|
||||
std::string outPath = argv[++i];
|
||||
std::string aHex = argv[++i];
|
||||
std::string bHex = argv[++i];
|
||||
std::string cHex = argv[++i];
|
||||
int tilePx = 16;
|
||||
uint32_t seed = 1;
|
||||
int W = 256, H = 256;
|
||||
if (i + 1 < argc && argv[i + 1][0] != '-') {
|
||||
try { tilePx = std::stoi(argv[++i]); } catch (...) {}
|
||||
}
|
||||
if (i + 1 < argc && argv[i + 1][0] != '-') {
|
||||
try { seed = static_cast<uint32_t>(std::stoul(argv[++i])); } catch (...) {}
|
||||
}
|
||||
if (i + 1 < argc && argv[i + 1][0] != '-') {
|
||||
try { W = std::stoi(argv[++i]); } catch (...) {}
|
||||
}
|
||||
if (i + 1 < argc && argv[i + 1][0] != '-') {
|
||||
try { H = std::stoi(argv[++i]); } catch (...) {}
|
||||
}
|
||||
if (W < 1 || H < 1 || W > 8192 || H > 8192 ||
|
||||
tilePx < 4 || tilePx > 256) {
|
||||
std::fprintf(stderr,
|
||||
"gen-texture-mosaic: invalid dims (W/H 1..8192, tilePx 4..256)\n");
|
||||
return 1;
|
||||
}
|
||||
uint8_t ar, ag, ab, br, bg, bb_, cr, cg, cb;
|
||||
if (!parseHex(aHex, ar, ag, ab) ||
|
||||
!parseHex(bHex, br, bg, bb_) ||
|
||||
!parseHex(cHex, cr, cg, cb)) {
|
||||
std::fprintf(stderr,
|
||||
"gen-texture-mosaic: one of the hex colors is invalid\n");
|
||||
return 1;
|
||||
}
|
||||
auto cellPick = [seed](int cx, int cy) -> int {
|
||||
uint32_t h = static_cast<uint32_t>(cx) * 374761393u +
|
||||
static_cast<uint32_t>(cy) * 668265263u +
|
||||
seed * 2147483647u;
|
||||
h = (h ^ (h >> 13)) * 1274126177u;
|
||||
h = h ^ (h >> 16);
|
||||
return h % 3;
|
||||
};
|
||||
std::vector<uint8_t> pixels(static_cast<size_t>(W) * H * 3, 0);
|
||||
int counts[3] = {0, 0, 0};
|
||||
for (int y = 0; y < H; ++y) {
|
||||
int cy = y / tilePx;
|
||||
int yInCell = y % tilePx;
|
||||
for (int x = 0; x < W; ++x) {
|
||||
int cx = x / tilePx;
|
||||
int xInCell = x % tilePx;
|
||||
// 1-px grout on the top and left edge of every cell.
|
||||
bool grout = (xInCell == 0) || (yInCell == 0);
|
||||
size_t i2 = (static_cast<size_t>(y) * W + x) * 3;
|
||||
if (grout) {
|
||||
pixels[i2 + 0] = 0;
|
||||
pixels[i2 + 1] = 0;
|
||||
pixels[i2 + 2] = 0;
|
||||
} else {
|
||||
int pick = cellPick(cx, cy);
|
||||
if (yInCell == 1 && xInCell == 1) ++counts[pick];
|
||||
if (pick == 0) {
|
||||
pixels[i2 + 0] = ar; pixels[i2 + 1] = ag; pixels[i2 + 2] = ab;
|
||||
} else if (pick == 1) {
|
||||
pixels[i2 + 0] = br; pixels[i2 + 1] = bg; pixels[i2 + 2] = bb_;
|
||||
} else {
|
||||
pixels[i2 + 0] = cr; pixels[i2 + 1] = cg; pixels[i2 + 2] = cb;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!stbi_write_png(outPath.c_str(), W, H, 3,
|
||||
pixels.data(), W * 3)) {
|
||||
std::fprintf(stderr,
|
||||
"gen-texture-mosaic: stbi_write_png failed for %s\n",
|
||||
outPath.c_str());
|
||||
return 1;
|
||||
}
|
||||
std::printf("Wrote %s\n", outPath.c_str());
|
||||
std::printf(" size : %dx%d\n", W, H);
|
||||
std::printf(" colors : %s / %s / %s\n",
|
||||
aHex.c_str(), bHex.c_str(), cHex.c_str());
|
||||
std::printf(" tile px : %d\n", tilePx);
|
||||
std::printf(" tile counts: A=%d B=%d C=%d\n",
|
||||
counts[0], counts[1], counts[2]);
|
||||
std::printf(" seed : %u\n", seed);
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool handleGenTexture(int& i, int argc, char** argv, int& outRc) {
|
||||
|
|
@ -2355,6 +2447,9 @@ bool handleGenTexture(int& i, int argc, char** argv, int& outRc) {
|
|||
if (std::strcmp(argv[i], "--gen-texture-vines") == 0 && i + 3 < argc) {
|
||||
outRc = handleVines(i, argc, argv); return true;
|
||||
}
|
||||
if (std::strcmp(argv[i], "--gen-texture-mosaic") == 0 && i + 4 < argc) {
|
||||
outRc = handleMosaic(i, argc, argv); return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue