diff --git a/tools/editor/cli_arg_required.cpp b/tools/editor/cli_arg_required.cpp index 991955b5..2e66ba2b 100644 --- a/tools/editor/cli_arg_required.cpp +++ b/tools/editor/cli_arg_required.cpp @@ -113,6 +113,7 @@ const char* const kArgRequired[] = { "--gen-texture-ironbark", "--gen-texture-mold", "--gen-texture-embroidery", "--gen-texture-lightbeam", "--gen-texture-dewdrops", "--gen-texture-pinwheel", + "--gen-texture-scratched-metal", "--validate-glb", "--info-glb", "--info-glb-tree", "--info-glb-bytes", "--validate-jsondbc", "--check-glb-bounds", "--validate-stl", "--validate-png", "--validate-blp", diff --git a/tools/editor/cli_gen_texture.cpp b/tools/editor/cli_gen_texture.cpp index e266f2ab..06fb6e86 100644 --- a/tools/editor/cli_gen_texture.cpp +++ b/tools/editor/cli_gen_texture.cpp @@ -3500,6 +3500,78 @@ int handleKnit(int& i, int argc, char** argv) { return 0; } +int handleScratchedMetal(int& i, int argc, char** argv) { + // Scratched / worn metal: base metal color overlaid with N + // short angled line segments brightened against the base. + // Each scratch is a hash-derived (cx, cy, length, angle) + // segment drawn via Bresenham-style stepping. Useful for + // weathered armor, worn weapon blades, well-used metal + // tools, salvaged hull plating, ancient relic surfaces. + std::string outPath = argv[++i]; + std::string baseHex = argv[++i]; + std::string scratchHex = argv[++i]; + int scratchCount = 100; + int maxLen = 24; + uint32_t seed = 1; + int W = 256, H = 256; + parseOptInt(i, argc, argv, scratchCount); + parseOptInt(i, argc, argv, maxLen); + parseOptUint(i, argc, argv, seed); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); + if (W < 1 || H < 1 || W > 8192 || H > 8192 || + scratchCount < 0 || scratchCount > 16384 || + maxLen < 2 || maxLen > 1024) { + std::fprintf(stderr, + "gen-texture-scratched-metal: invalid dims (W/H 1..8192, " + "scratchCount 0..16384, maxLen 2..1024)\n"); + return 1; + } + uint8_t br_, bg_, bb_, sr, sg, sb_; + if (!parseHexOrError(baseHex, br_, bg_, bb_, + "gen-texture-scratched-metal")) return 1; + if (!parseHexOrError(scratchHex, sr, sg, sb_, + "gen-texture-scratched-metal")) return 1; + auto hash32 = [](uint32_t x) -> uint32_t { + x ^= x >> 16; x *= 0x7feb352d; + x ^= x >> 15; x *= 0x846ca68b; + x ^= x >> 16; return x; + }; + // Init pixels to base. + std::vector pixels(static_cast(W) * H * 3, 0); + for (int y = 0; y < H; ++y) { + for (int x = 0; x < W; ++x) { + setPixelRGB(pixels, W, x, y, br_, bg_, bb_); + } + } + // Draw each scratch as a stepped line. + const float twoPi = 6.28318530717958f; + for (int k = 0; k < scratchCount; ++k) { + uint32_t h = hash32(static_cast(k) + seed); + int cx = static_cast(h % W); + int cy = static_cast((h >> 8) % H); + int len = 4 + static_cast((h >> 16) % maxLen); + float angle = static_cast((h >> 4) % 1000) / 1000.0f * twoPi; + float dx = std::cos(angle); + float dy = std::sin(angle); + // Step from -len/2 to +len/2 along the angle. + for (int t = -len / 2; t <= len / 2; ++t) { + int px = static_cast(cx + dx * t + 0.5f); + int py = static_cast(cy + dy * t + 0.5f); + if (px < 0 || px >= W || py < 0 || py >= H) continue; + setPixelRGB(pixels, W, px, py, sr, sg, sb_); + } + } + if (!savePngOrError(outPath, W, H, pixels, + "gen-texture-scratched-metal")) return 1; + printPngWrote(outPath, W, H); + std::printf(" base/scratch : %s / %s\n", + baseHex.c_str(), scratchHex.c_str()); + std::printf(" scratches : %d (max len %d, seed %u)\n", + scratchCount, maxLen, seed); + return 0; +} + int handlePinwheel(int& i, int argc, char** argv) { // N-sector pinwheel: alternating colored triangular wedges // radiating from the texture center, each subtending 2π/N @@ -5596,6 +5668,7 @@ constexpr TextureEntry kTextureTable[] = { {"--gen-texture-lightbeam", 3, handleLightbeam}, {"--gen-texture-dewdrops", 3, handleDewdrops}, {"--gen-texture-pinwheel", 3, handlePinwheel}, + {"--gen-texture-scratched-metal",3, handleScratchedMetal}, }; } // namespace diff --git a/tools/editor/cli_help.cpp b/tools/editor/cli_help.cpp index faaf327f..9b7a66aa 100644 --- a/tools/editor/cli_help.cpp +++ b/tools/editor/cli_help.cpp @@ -187,6 +187,8 @@ void printUsage(const char* argv0) { std::printf(" Dewdrops: scattered translucent water drops with radial brightness (grass / glass / leaf surfaces)\n"); std::printf(" --gen-texture-pinwheel [sectors] [W H]\n"); std::printf(" Pinwheel: alternating colored triangular wedges radiating from center (mandala / wind-rose / wheel inlay)\n"); + std::printf(" --gen-texture-scratched-metal [scratchCount] [maxLen] [seed] [W H]\n"); + std::printf(" Scratched metal: base color overlaid with N angled hash-derived line segments (worn armor / blades)\n"); std::printf(" --add-texture-to-zone [renameTo]\n"); std::printf(" Copy an existing PNG into (optionally renaming it on the way in)\n"); std::printf(" --gen-mesh [size]\n");