mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-10 02:53:51 +00:00
feat(editor): add --gen-mesh-candle wax-pillar primitive
80th procedural mesh primitive. Wax pillar candle:
• saucer (optional) — wider shallow disc base, the drip
catcher that sits on the table
• wax — thin tall pillar standing on the saucer (or
directly on the ground if saucerR=0)
Uses the addClosedCylinderY helper for both pieces — same
two-cylinder pattern as --gen-mesh-bird-bath but with a
much skinnier upper cylinder. The 81-line handler is
mostly arg parsing + validation; geometry is just two
helper calls.
Useful for chapels / shrines, vigil scenes, witch-hut
ritual surfaces, alchemist labs, séance tables, festival-
of-lights ground decoration. Set saucerR=0 for a plain
candle without the saucer (e.g. for stack-them-on-a-cake
contexts).
Watertight under weld (verified — wax + saucer are two
independent closed cylinders).
Milestone: now at 80 procedural mesh primitives.
This commit is contained in:
parent
74b8795aa3
commit
b47649b078
3 changed files with 53 additions and 1 deletions
|
|
@ -60,7 +60,7 @@ const char* const kArgRequired[] = {
|
|||
"--gen-mesh-stone-bench", "--gen-mesh-mine-cart",
|
||||
"--gen-mesh-hitching-rail", "--gen-mesh-pillar-row",
|
||||
"--gen-mesh-statue-base", "--gen-mesh-bird-bath",
|
||||
"--gen-mesh-planter-box", "--gen-mesh-urn",
|
||||
"--gen-mesh-planter-box", "--gen-mesh-urn", "--gen-mesh-candle",
|
||||
"--gen-camp-pack", "--gen-blacksmith-pack", "--gen-village-pack",
|
||||
"--gen-temple-pack", "--gen-graveyard-pack",
|
||||
"--gen-garden-pack", "--gen-dock-pack", "--gen-tavern-pack",
|
||||
|
|
|
|||
|
|
@ -5161,6 +5161,55 @@ int handleTent(int& i, int argc, char** argv) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int handleCandle(int& i, int argc, char** argv) {
|
||||
// Wax pillar candle: thin tall wax cylinder optionally
|
||||
// standing on a wider shallow saucer base (the drip catcher).
|
||||
// Both pieces use addClosedCylinderY — same pattern as
|
||||
// --gen-mesh-bird-bath but with a much skinnier upper
|
||||
// cylinder. The 80th procedural mesh primitive.
|
||||
std::string womBase = argv[++i];
|
||||
float waxR = 0.04f;
|
||||
float waxH = 0.30f;
|
||||
float saucerR = 0.08f; // 0 → no saucer
|
||||
float saucerH = 0.015f;
|
||||
int sides = 14;
|
||||
parseOptFloat(i, argc, argv, waxR);
|
||||
parseOptFloat(i, argc, argv, waxH);
|
||||
parseOptFloat(i, argc, argv, saucerR);
|
||||
parseOptFloat(i, argc, argv, saucerH);
|
||||
parseOptInt(i, argc, argv, sides);
|
||||
if (waxR <= 0 || waxH <= 0 || saucerR < 0 ||
|
||||
(saucerR > 0 && saucerR <= waxR) ||
|
||||
(saucerR > 0 && saucerH <= 0) ||
|
||||
sides < 6 || sides > 64) {
|
||||
std::fprintf(stderr,
|
||||
"gen-mesh-candle: dims > 0; saucerR > waxR (or 0); sides 6..64\n");
|
||||
return 1;
|
||||
}
|
||||
stripExt(womBase, ".wom");
|
||||
wowee::pipeline::WoweeModel wom;
|
||||
initWomDefaults(wom, womBase);
|
||||
float yBase = 0.0f;
|
||||
if (saucerR > 0.0f) {
|
||||
addClosedCylinderY(wom, saucerR, 0.0f, saucerH, sides);
|
||||
yBase = saucerH;
|
||||
}
|
||||
addClosedCylinderY(wom, waxR, yBase, yBase + waxH, sides);
|
||||
finalizeAsSingleBatch(wom);
|
||||
float maxR = std::max(waxR, saucerR);
|
||||
setCenteredBoundsXZ(wom, maxR, maxR, yBase + waxH);
|
||||
if (!saveWomOrError(wom, womBase, "gen-mesh-candle")) return 1;
|
||||
printWomWrote(womBase);
|
||||
std::printf(" wax : R=%.3f x %.3f tall\n", waxR, waxH);
|
||||
if (saucerR > 0.0f)
|
||||
std::printf(" saucer : R=%.3f x %.3f thick\n", saucerR, saucerH);
|
||||
else
|
||||
std::printf(" saucer : (none)\n");
|
||||
std::printf(" sides : %d\n", sides);
|
||||
printWomMeshStats(wom);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int handleUrn(int& i, int argc, char** argv) {
|
||||
// Multi-tier vertical urn: foot (wide short cylinder) →
|
||||
// body (tall main cylinder) → neck (narrow constriction) →
|
||||
|
|
@ -7264,6 +7313,7 @@ constexpr MeshEntry kMeshTable[] = {
|
|||
{"--gen-mesh-bird-bath", 1, handleBirdBath},
|
||||
{"--gen-mesh-planter-box", 1, handlePlanterBox},
|
||||
{"--gen-mesh-urn", 1, handleUrn},
|
||||
{"--gen-mesh-candle", 1, handleCandle},
|
||||
{"--gen-camp-pack", 1, handleGenCampPack},
|
||||
{"--gen-blacksmith-pack", 1, handleGenBlacksmithPack},
|
||||
{"--gen-village-pack", 1, handleGenVillagePack},
|
||||
|
|
|
|||
|
|
@ -308,6 +308,8 @@ void printUsage(const char* argv0) {
|
|||
std::printf(" Planter box: long open-top wood basin + visible soil-fill block (window sills / kitchen / balcony)\n");
|
||||
std::printf(" --gen-mesh-urn <wom-base> [bodyR] [bodyH] [footR] [footH] [neckR] [neckH] [lipR] [lipH] [sides]\n");
|
||||
std::printf(" Urn: 4-tier vertical pottery vessel (foot + body + neck + lip) — temple / mausoleum / kitchen storage\n");
|
||||
std::printf(" --gen-mesh-candle <wom-base> [waxR] [waxH] [saucerR] [saucerH] [sides]\n");
|
||||
std::printf(" Candle: thin wax pillar on optional saucer base (set saucerR=0 to skip) — chapels / vigil scenes\n");
|
||||
std::printf(" --gen-camp-pack <outDir>\n");
|
||||
std::printf(" Convenience: emit tent + firepit + bedroll + canopy + woodpile + haystack into outDir as 6 .wom files\n");
|
||||
std::printf(" --gen-blacksmith-pack <outDir>\n");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue