diff --git a/tools/editor/cli_arg_required.cpp b/tools/editor/cli_arg_required.cpp index 8d3585c8..0d3ba065 100644 --- a/tools/editor/cli_arg_required.cpp +++ b/tools/editor/cli_arg_required.cpp @@ -55,6 +55,7 @@ const char* const kArgRequired[] = { "--gen-mesh-workbench", "--gen-mesh-crate-stack", "--gen-mesh-watchpost", "--gen-mesh-water-trough", "--gen-mesh-training-dummy", "--gen-mesh-hitching-post", + "--gen-mesh-outhouse", "--gen-camp-pack", "--gen-mesh-table", "--gen-mesh-lamppost", "--gen-mesh-bed", "--gen-mesh-ladder", "--gen-mesh-well", "--gen-mesh-signpost", diff --git a/tools/editor/cli_gen_mesh.cpp b/tools/editor/cli_gen_mesh.cpp index da7d106c..cce37f51 100644 --- a/tools/editor/cli_gen_mesh.cpp +++ b/tools/editor/cli_gen_mesh.cpp @@ -5193,6 +5193,70 @@ int handleTent(int& i, int argc, char** argv) { return 0; } +int handleOuthouse(int& i, int argc, char** argv) { + // Small wooden shed / outhouse: solid body box with an + // inset door slab on the +Z face and a slightly-larger flat + // roof slab overhanging the body. Distinct from + // --gen-mesh-house (multi-walled, peaked-roof dwelling) — an + // outhouse is the single-room privy / tool-shed variant. + // The 68th procedural mesh primitive. + std::string womBase = argv[++i]; + float width = 0.9f; + float depth = 1.0f; + float height = 1.8f; + float doorH = 1.4f; + float doorW = 0.5f; + float roofOverhang = 0.10f; + float roofT = 0.06f; + parseOptFloat(i, argc, argv, width); + parseOptFloat(i, argc, argv, depth); + parseOptFloat(i, argc, argv, height); + parseOptFloat(i, argc, argv, doorH); + parseOptFloat(i, argc, argv, doorW); + parseOptFloat(i, argc, argv, roofOverhang); + parseOptFloat(i, argc, argv, roofT); + if (width <= 0 || depth <= 0 || height <= 0 || + doorH <= 0 || doorH >= height || + doorW <= 0 || doorW >= width || + roofOverhang < 0 || roofT <= 0 || roofT >= height) { + std::fprintf(stderr, + "gen-mesh-outhouse: dims > 0; doorH < height; doorW < width\n"); + return 1; + } + stripExt(womBase, ".wom"); + wowee::pipeline::WoweeModel wom; + initWomDefaults(wom, womBase); + const float W2 = width * 0.5f; + const float D2 = depth * 0.5f; + const float bodyH = height - roofT; + // Body: solid rectangular box. + addFlatBox(wom, 0.0f, bodyH * 0.5f, 0.0f, + W2, bodyH * 0.5f, D2); + // Door slab on the +Z face: thin box pushed slightly outward + // so it visually sits on the wall (gives doorframe-like depth). + const float doorT = 0.03f; + addFlatBox(wom, 0.0f, doorH * 0.5f, +D2 + doorT * 0.5f, + doorW * 0.5f, doorH * 0.5f, doorT * 0.5f); + // Roof slab: slightly larger than the body footprint and + // sitting on top of the body. + const float rofW2 = W2 + roofOverhang; + const float rofD2 = D2 + roofOverhang; + addFlatBox(wom, 0.0f, bodyH + roofT * 0.5f, 0.0f, + rofW2, roofT * 0.5f, rofD2); + finalizeAsSingleBatch(wom); + setCenteredBoundsXZ(wom, std::max(W2, rofW2), + std::max(D2 + doorT, rofD2), height); + if (!saveWomOrError(wom, womBase, "gen-mesh-outhouse")) return 1; + std::printf("Wrote %s.wom\n", womBase.c_str()); + std::printf(" body : %.3f x %.3f x %.3f\n", width, depth, bodyH); + std::printf(" door : %.3f x %.3f on +Z face\n", doorW, doorH); + std::printf(" roof : %.3f thick, %.3f overhang\n", + roofT, roofOverhang); + std::printf(" vertices : %zu\n", wom.vertices.size()); + std::printf(" triangles : %zu\n", wom.indices.size() / 3); + return 0; +} + int handleHitchingPost(int& i, int argc, char** argv) { // Hitching post: two vertical posts joined by a horizontal // cross-bar at upper height. Standard town/stable fixture @@ -6439,6 +6503,7 @@ constexpr MeshEntry kMeshTable[] = { {"--gen-mesh-water-trough", 1, handleWaterTrough}, {"--gen-mesh-training-dummy", 1, handleTrainingDummy}, {"--gen-mesh-hitching-post", 1, handleHitchingPost}, + {"--gen-mesh-outhouse", 1, handleOuthouse}, {"--gen-camp-pack", 1, handleGenCampPack}, {"--gen-mesh-table", 1, handleTable}, {"--gen-mesh-lamppost", 1, handleLamppost}, diff --git a/tools/editor/cli_help.cpp b/tools/editor/cli_help.cpp index c245ddae..92ae57f7 100644 --- a/tools/editor/cli_help.cpp +++ b/tools/editor/cli_help.cpp @@ -260,6 +260,8 @@ void printUsage(const char* argv0) { std::printf(" Training dummy: post + cubic torso + cross-bar arms + optional head (sparring / drill yard)\n"); std::printf(" --gen-mesh-hitching-post [span] [height] [postW] [barT] [capH]\n"); std::printf(" Hitching post: 2 vertical posts + horizontal cross-bar + optional decorative caps (stable / town square)\n"); + std::printf(" --gen-mesh-outhouse [width] [depth] [height] [doorH] [doorW] [roofOverhang] [roofT]\n"); + std::printf(" Outhouse: solid body + inset door slab on +Z + overhanging roof slab (privy / tool shed)\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-mesh-table [width] [depth] [height] [legThick] [topThick]\n");