diff --git a/tools/editor/cli_arg_required.cpp b/tools/editor/cli_arg_required.cpp index 20122304..a455ad27 100644 --- a/tools/editor/cli_arg_required.cpp +++ b/tools/editor/cli_arg_required.cpp @@ -68,6 +68,7 @@ const char* const kArgRequired[] = { "--gen-mesh-planter-box", "--gen-mesh-urn", "--gen-mesh-candle", "--gen-mesh-lantern", "--gen-mesh-chalice", "--gen-mesh-standing-torch", "--gen-mesh-scroll-case", + "--gen-mesh-stove", "--gen-camp-pack", "--gen-blacksmith-pack", "--gen-village-pack", "--gen-temple-pack", "--gen-graveyard-pack", "--gen-garden-pack", "--gen-dock-pack", "--gen-tavern-pack", diff --git a/tools/editor/cli_gen_mesh.cpp b/tools/editor/cli_gen_mesh.cpp index 14f98033..356600f9 100644 --- a/tools/editor/cli_gen_mesh.cpp +++ b/tools/editor/cli_gen_mesh.cpp @@ -5161,6 +5161,46 @@ int handleTent(int& i, int argc, char** argv) { return 0; } +int handleStove(int& i, int argc, char** argv) { + // Pot-bellied wood stove: wide cylindrical body + thin + // tall chimney column rising from the top of the body. + // Distinct from --gen-mesh-forge (square stone hearth + + // hood + chimney) — stove is the round-cylinder home/ + // workshop variant. The 85th procedural mesh primitive. + std::string womBase = argv[++i]; + float bodyR = 0.30f; + float bodyH = 0.65f; + float chimneyR = 0.07f; + float chimneyH = 1.10f; + int sides = 16; + parseOptFloat(i, argc, argv, bodyR); + parseOptFloat(i, argc, argv, bodyH); + parseOptFloat(i, argc, argv, chimneyR); + parseOptFloat(i, argc, argv, chimneyH); + parseOptInt(i, argc, argv, sides); + if (bodyR <= 0 || bodyH <= 0 || chimneyR <= 0 || chimneyH <= 0 || + sides < 6 || sides > 64 || chimneyR >= bodyR) { + std::fprintf(stderr, + "gen-mesh-stove: dims > 0; sides 6..64; " + "chimneyR < bodyR\n"); + return 1; + } + stripExt(womBase, ".wom"); + wowee::pipeline::WoweeModel wom; + initWomDefaults(wom, womBase); + addClosedCylinderY(wom, bodyR, 0.0f, bodyH, sides); + addClosedCylinderY(wom, chimneyR, bodyH, bodyH + chimneyH, sides); + finalizeAsSingleBatch(wom); + setCenteredBoundsXZ(wom, bodyR, bodyR, bodyH + chimneyH); + if (!saveWomOrError(wom, womBase, "gen-mesh-stove")) return 1; + printWomWrote(womBase); + std::printf(" body : R=%.3f x %.3f tall\n", bodyR, bodyH); + std::printf(" chimney : R=%.3f x %.3f tall (%d sides)\n", + chimneyR, chimneyH, sides); + printWomMeshStats(wom); + return 0; +} + int handleScrollCase(int& i, int argc, char** argv) { // Cylindrical scroll case / map tube: thin tall cylindrical // body with an optional shorter wider cap on top. Distinct @@ -7445,6 +7485,7 @@ constexpr MeshEntry kMeshTable[] = { {"--gen-mesh-chalice", 1, handleChalice}, {"--gen-mesh-standing-torch", 1, handleStandingTorch}, {"--gen-mesh-scroll-case", 1, handleScrollCase}, + {"--gen-mesh-stove", 1, handleStove}, {"--gen-camp-pack", 1, handleGenCampPack}, {"--gen-blacksmith-pack", 1, handleGenBlacksmithPack}, {"--gen-village-pack", 1, handleGenVillagePack}, diff --git a/tools/editor/cli_help.cpp b/tools/editor/cli_help.cpp index 7784cf1e..f5dcc394 100644 --- a/tools/editor/cli_help.cpp +++ b/tools/editor/cli_help.cpp @@ -330,6 +330,8 @@ void printUsage(const char* argv0) { std::printf(" Standing torch: tall thin post + wider fire-bowl on top (hall lining / dungeon entry / ceremony path)\n"); std::printf(" --gen-mesh-scroll-case [bodyR] [bodyH] [capR] [capH] [sides]\n"); std::printf(" Scroll case: thin tall cylinder + optional wider cap (set capR=0 to skip) — libraries / mage scenes\n"); + std::printf(" --gen-mesh-stove [bodyR] [bodyH] [chimneyR] [chimneyH] [sides]\n"); + std::printf(" Pot-bellied stove: round cylindrical body + thin chimney column on top (cottage / workshop heating)\n"); std::printf(" --gen-camp-pack \n"); std::printf(" Convenience: emit tent + firepit + bedroll + canopy + woodpile + haystack into outDir as 6 .wom files\n"); std::printf(" --gen-blacksmith-pack \n");