Kelsidavis-WoWee/include/pipeline/wowee_building.hpp
Kelsi ca15da5e9b feat: WOT doodad/WMO placements, WOB materials, deduplicate loader
Architecture fixes for open format data fidelity:

- WOT now serializes full doodad/WMO placement arrays (positions,
  rotations, scale, flags, doodad sets) — was only storing counts,
  causing all placed objects to be lost on WOT round-trip
- WOT loader parses placements back into ADTTerrain for client rendering
- WOB Material struct added: preserves WMO material flags, shader type,
  and blend mode during WMO→WOB conversion (was geometry-only)
- WOB doodad rotation: quaternion→euler conversion instead of hardcoded
  zero (placed doodads inside buildings now retain their orientation)
- importOpen() deduplicated: delegates to pipeline::WoweeTerrainLoader
  instead of duplicating 100 lines of parsing code
2026-05-05 14:44:46 -07:00

73 lines
1.9 KiB
C++

#pragma once
#include <glm/glm.hpp>
#include <string>
#include <vector>
#include <cstdint>
namespace wowee {
namespace pipeline {
// Wowee Open Building format (.wob) — novel WMO replacement
// Buildings with multiple groups, portals, and doodad sets
struct WoweeBuilding {
struct Vertex {
glm::vec3 position;
glm::vec3 normal;
glm::vec2 texCoord;
glm::vec4 color; // vertex color/lighting
};
struct Material {
std::string texturePath;
uint32_t flags = 0;
uint32_t shader = 0;
uint32_t blendMode = 0;
};
struct Group {
std::string name;
std::vector<Vertex> vertices;
std::vector<uint32_t> indices;
std::vector<std::string> texturePaths;
std::vector<Material> materials;
glm::vec3 boundMin{0}, boundMax{0};
bool isOutdoor = false;
};
struct Portal {
int groupA = -1, groupB = -1;
std::vector<glm::vec3> vertices; // portal polygon
};
struct DoodadPlacement {
std::string modelPath; // .wom path
glm::vec3 position;
glm::vec3 rotation;
float scale = 1.0f;
};
std::string name;
std::vector<Group> groups;
std::vector<Portal> portals;
std::vector<DoodadPlacement> doodads;
float boundRadius = 1.0f;
bool isValid() const { return !groups.empty(); }
};
class WoweeBuildingLoader {
public:
static WoweeBuilding load(const std::string& basePath);
static bool save(const WoweeBuilding& building, const std::string& basePath);
static bool exists(const std::string& basePath);
// Convert WOB to WMOModel for the client's WMO renderer
static bool toWMOModel(const WoweeBuilding& building, class WMOModel& outModel);
// Convert WMOModel to WOB (for editor export)
static WoweeBuilding fromWMO(const class WMOModel& wmo, const std::string& name = "");
};
} // namespace pipeline
} // namespace wowee