mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-10 02:53:51 +00:00
feat(editor): add --gen-texture-corrugated metal-sheet ridges
50th procedural texture: smooth cosine ridges that lerp between bgHex (trough) and hiHex (crest) over a configurable period. Direction defaults to vertical ridges (wave varies along X) — the standard corrugated-sheet-metal-roof look — with optional horizontal mode for siding panels and pipe texturing. Useful for sheet-metal roofing, corrugated-iron walls, sci-fi paneling, and any "ridged plate" surface where the existing flat --gen-texture-metal would read as too uniform. Default 16px period at 256x256 reads cleanly with about 16 ridges across the tile.
This commit is contained in:
parent
4455a4eb6f
commit
a7989cc7ab
3 changed files with 77 additions and 1 deletions
|
|
@ -83,7 +83,7 @@ const char* const kArgRequired[] = {
|
||||||
"--gen-texture-cracked", "--gen-texture-runes",
|
"--gen-texture-cracked", "--gen-texture-runes",
|
||||||
"--gen-texture-leopard", "--gen-texture-zebra",
|
"--gen-texture-leopard", "--gen-texture-zebra",
|
||||||
"--gen-texture-knit", "--gen-texture-chainmail",
|
"--gen-texture-knit", "--gen-texture-chainmail",
|
||||||
"--gen-texture-planks",
|
"--gen-texture-planks", "--gen-texture-corrugated",
|
||||||
"--validate-glb", "--info-glb", "--info-glb-tree", "--info-glb-bytes",
|
"--validate-glb", "--info-glb", "--info-glb-tree", "--info-glb-bytes",
|
||||||
"--validate-jsondbc", "--check-glb-bounds", "--validate-stl",
|
"--validate-jsondbc", "--check-glb-bounds", "--validate-stl",
|
||||||
"--validate-png", "--validate-blp",
|
"--validate-png", "--validate-blp",
|
||||||
|
|
|
||||||
|
|
@ -4586,6 +4586,79 @@ int handleKnit(int& i, int argc, char** argv) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int handleCorrugated(int& i, int argc, char** argv) {
|
||||||
|
// Corrugated metal sheeting: smooth cosine ridges along one
|
||||||
|
// axis. Each pixel's brightness comes from cos((x or y) /
|
||||||
|
// period * 2π) mapped from [-1,1] to [0,1] and used to lerp
|
||||||
|
// between bgHex (the trough/shadow color) and hiHex (the
|
||||||
|
// crest/highlight color). Vertical orientation by default
|
||||||
|
// (ridges run top→bottom, wave varies along X) which is the
|
||||||
|
// standard sheet-metal-roof look.
|
||||||
|
std::string outPath = argv[++i];
|
||||||
|
std::string bgHex = argv[++i];
|
||||||
|
std::string hiHex = argv[++i];
|
||||||
|
int period = 16;
|
||||||
|
char dir = 'v'; // 'v' = vertical ridges, 'h' = horizontal
|
||||||
|
int W = 256, H = 256;
|
||||||
|
if (i + 1 < argc && argv[i + 1][0] != '-') {
|
||||||
|
try { period = std::stoi(argv[++i]); } catch (...) {}
|
||||||
|
}
|
||||||
|
if (i + 1 < argc && argv[i + 1][0] != '-') {
|
||||||
|
const char* a = argv[++i];
|
||||||
|
if (a[0] == 'h' || a[0] == 'H') dir = 'h';
|
||||||
|
else if (a[0] == 'v' || a[0] == 'V') dir = 'v';
|
||||||
|
}
|
||||||
|
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 ||
|
||||||
|
period < 2 || period > 1024) {
|
||||||
|
std::fprintf(stderr,
|
||||||
|
"gen-texture-corrugated: invalid dims (W/H 1..8192, "
|
||||||
|
"period 2..1024)\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
uint8_t br_, bg_, bb_, hr, hg, hb_;
|
||||||
|
if (!parseHex(bgHex, br_, bg_, bb_) ||
|
||||||
|
!parseHex(hiHex, hr, hg, hb_)) {
|
||||||
|
std::fprintf(stderr,
|
||||||
|
"gen-texture-corrugated: bg or highlight hex color is invalid\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
std::vector<uint8_t> pixels(static_cast<size_t>(W) * H * 3, 0);
|
||||||
|
const float twoPi = 6.28318530717958f;
|
||||||
|
for (int y = 0; y < H; ++y) {
|
||||||
|
for (int x = 0; x < W; ++x) {
|
||||||
|
int v = (dir == 'v') ? x : y;
|
||||||
|
float phase = (static_cast<float>(v) / period) * twoPi;
|
||||||
|
float t = (std::cos(phase) + 1.0f) * 0.5f;
|
||||||
|
uint8_t r = static_cast<uint8_t>(br_ + t * (hr - br_));
|
||||||
|
uint8_t g = static_cast<uint8_t>(bg_ + t * (hg - bg_));
|
||||||
|
uint8_t b = static_cast<uint8_t>(bb_ + t * (hb_ - bb_));
|
||||||
|
size_t idx = (static_cast<size_t>(y) * W + x) * 3;
|
||||||
|
pixels[idx + 0] = r;
|
||||||
|
pixels[idx + 1] = g;
|
||||||
|
pixels[idx + 2] = b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!stbi_write_png(outPath.c_str(), W, H, 3,
|
||||||
|
pixels.data(), W * 3)) {
|
||||||
|
std::fprintf(stderr,
|
||||||
|
"gen-texture-corrugated: 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(" bg/hi : %s / %s\n", bgHex.c_str(), hiHex.c_str());
|
||||||
|
std::printf(" ridges : period=%d (%s)\n", period,
|
||||||
|
dir == 'v' ? "vertical" : "horizontal");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int handlePlanks(int& i, int argc, char** argv) {
|
int handlePlanks(int& i, int argc, char** argv) {
|
||||||
// Plank floor: horizontal "boards" of randomized length and tint
|
// Plank floor: horizontal "boards" of randomized length and tint
|
||||||
// separated by thin dark seams. Each plank gets a hash-derived
|
// separated by thin dark seams. Each plank gets a hash-derived
|
||||||
|
|
@ -4854,6 +4927,7 @@ constexpr TextureEntry kTextureTable[] = {
|
||||||
{"--gen-texture-knit", 3, handleKnit},
|
{"--gen-texture-knit", 3, handleKnit},
|
||||||
{"--gen-texture-chainmail", 3, handleChainmail},
|
{"--gen-texture-chainmail", 3, handleChainmail},
|
||||||
{"--gen-texture-planks", 3, handlePlanks},
|
{"--gen-texture-planks", 3, handlePlanks},
|
||||||
|
{"--gen-texture-corrugated", 3, handleCorrugated},
|
||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -133,6 +133,8 @@ void printUsage(const char* argv0) {
|
||||||
std::printf(" Chainmail: brick-offset ring outlines for armor/mail textures (interlocking metal rings)\n");
|
std::printf(" Chainmail: brick-offset ring outlines for armor/mail textures (interlocking metal rings)\n");
|
||||||
std::printf(" --gen-texture-planks <out.png> <bgHex> <seamHex> [plankH] [grains/plank] [seed] [W H]\n");
|
std::printf(" --gen-texture-planks <out.png> <bgHex> <seamHex> [plankH] [grains/plank] [seed] [W H]\n");
|
||||||
std::printf(" Planks: horizontal floor boards with per-plank tint, grain streaks, and stagger seams\n");
|
std::printf(" Planks: horizontal floor boards with per-plank tint, grain streaks, and stagger seams\n");
|
||||||
|
std::printf(" --gen-texture-corrugated <out.png> <bgHex> <hiHex> [period] [v|h] [W H]\n");
|
||||||
|
std::printf(" Corrugated: smooth cosine ridges between bg and hi (sheet-metal roofing / siding)\n");
|
||||||
std::printf(" --add-texture-to-zone <zoneDir> <png-path> [renameTo]\n");
|
std::printf(" --add-texture-to-zone <zoneDir> <png-path> [renameTo]\n");
|
||||||
std::printf(" Copy an existing PNG into <zoneDir> (optionally renaming it on the way in)\n");
|
std::printf(" Copy an existing PNG into <zoneDir> (optionally renaming it on the way in)\n");
|
||||||
std::printf(" --gen-mesh <wom-base> <cube|plane|sphere|cylinder|torus|cone|ramp> [size]\n");
|
std::printf(" --gen-mesh <wom-base> <cube|plane|sphere|cylinder|torus|cone|ramp> [size]\n");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue