#pragma once #include "pipeline/wowee_model.hpp" #include #include #include #include #include namespace wowee { namespace editor { namespace cli { // Initialize a fresh WoweeModel with the canonical procedural- // primitive defaults: name derived from the base path's stem and // version 3 (current). 64 handlers in cli_gen_mesh.cpp open-coded // this 3-line block before extraction. inline void initWomDefaults(wowee::pipeline::WoweeModel& wom, const std::string& base) { wom.name = std::filesystem::path(base).stem().string(); wom.version = 3; } // Set the WoweeModel's bound box for a primitive whose footprint // is symmetric around the origin in X+Z and rises from y=0 to // y=maxY. 21+ procedural mesh handlers use this exact pattern; // extracting collapses two-line stanzas to one call. inline void setCenteredBoundsXZ(wowee::pipeline::WoweeModel& wom, float halfX, float halfZ, float maxY) { wom.boundMin = glm::vec3(-halfX, 0.0f, -halfZ); wom.boundMax = glm::vec3( halfX, maxY, halfZ); } // Print the canonical "Wrote .wom" success line shown at // the start of every --gen-mesh-* handler's stat report. 72 sites // each ran the same printf — hoisting collapses each to one call. inline void printWomWrote(const std::string& base) { std::printf("Wrote %s.wom\n", base.c_str()); } // Print the standard final two stat lines shown at the end of // every --gen-mesh-* handler's report: // vertices : N // triangles : T // 49+ handlers used this exact pair before extraction. inline void printWomMeshStats(const wowee::pipeline::WoweeModel& wom) { std::printf(" vertices : %zu\n", wom.vertices.size()); std::printf(" triangles : %zu\n", wom.indices.size() / 3); } // Save a WoweeModel and report a stderr message on failure. // Returns true on success so the caller can do // `if (!saveWomOrError(...)) return 1;`. The cmdName is included // in the error message for context. inline bool saveWomOrError(const wowee::pipeline::WoweeModel& wom, const std::string& base, const char* cmdName) { if (wowee::pipeline::WoweeModelLoader::save(wom, base)) return true; std::fprintf(stderr, "%s: failed to save %s.wom\n", cmdName, base.c_str()); return false; } // Strip a file-extension suffix from a base path if present. Used // pervasively by --gen-mesh-* / --bake-* / --info-* handlers that // accept either `path/foo` or `path/foo.ext` as input — the loader // expects the bare base, so the trailing ".wom" / ".wob" / ".woc" // must be removed if the user typed it. // // Pattern was open-coded as a 4-line if-block in 64+ sites // across cli_gen_mesh.cpp; hoisted here for one-line callers. inline void stripExt(std::string& base, const char* ext) { std::size_t extLen = 0; while (ext[extLen]) ++extLen; if (base.size() >= extLen && base.compare(base.size() - extLen, extLen, ext) == 0) { base.resize(base.size() - extLen); } } // Append a single batch covering ALL of wom.indices to wom.batches. // Called at the end of every gen-mesh primitive (the procedural // builders emit just one batch per primitive). The same 4-line // "construct + populate + push" boilerplate was repeated in 53 // handlers before extraction. inline void finalizeAsSingleBatch(wowee::pipeline::WoweeModel& wom) { wowee::pipeline::WoweeModel::Batch batch; batch.indexStart = 0; batch.indexCount = static_cast(wom.indices.size()); batch.textureIndex = 0; wom.batches.push_back(batch); } // Append one vertex (position, normal, UV) to a WoweeModel and // return its newly-assigned index. Inline because the procedural // mesh primitives call this thousands of times per build and the // abstraction shouldn't cost a function-call frame each time. // Pre-extraction this was the same 5-line lambda copy-pasted into // 21 different handlers. inline uint32_t addVertex(wowee::pipeline::WoweeModel& wom, glm::vec3 p, glm::vec3 n, glm::vec2 uv) { wowee::pipeline::WoweeModel::Vertex vtx; vtx.position = p; vtx.normal = n; vtx.texCoord = uv; wom.vertices.push_back(vtx); return static_cast(wom.vertices.size() - 1); } // Per-float overload used by handlers that compute pos/normal/uv // components inline rather than building intermediate glm vectors // (--gen-mesh-stairs, --gen-mesh-tube, --gen-mesh-capsule, // --gen-mesh-arch). Same semantics as the vec3/vec2 form. inline uint32_t addVertex(wowee::pipeline::WoweeModel& wom, float px, float py, float pz, float nx, float ny, float nz, float u, float v) { return addVertex(wom, glm::vec3(px, py, pz), glm::vec3(nx, ny, nz), glm::vec2(u, v)); } // Append a flat-shaded axis-aligned box to a WoweeModel. The box // is centered at (cx, cy, cz) with half-extents (hx, hy, hz). Each // of the 6 faces emits its own 4 vertices with the face's outward // normal, so adjacent faces don't share normals — exactly what // flat shading needs. UVs are 0..1 across each face. // // Used pervasively by --gen-mesh-* primitives that build meshes // from axis-aligned box primitives (firepit stones, dock pilings, // canopy posts, woodpile logs, tent walls before the door cutout // added one-off triangles, etc.). Hoisted out of cli_gen_mesh.cpp // where 36 identical lambdas duplicated this implementation. void addFlatBox(wowee::pipeline::WoweeModel& wom, float cx, float cy, float cz, float hx, float hy, float hz); // Overload taking lower/upper corner positions (lo, hi). Some // callers (--gen-mesh-archway, --gen-mesh-fence) compute corners // directly rather than center+halfsize. void addFlatBox(wowee::pipeline::WoweeModel& wom, glm::vec3 lo, glm::vec3 hi); } // namespace cli } // namespace editor } // namespace wowee