mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-06 09:03:52 +00:00
refactor(wom): extract WOM->M2 conversion to shared helper
Adds WoweeModelLoader::toM2() and tryLoadByGamePath() to deduplicate the identical conversion code that lived in editor_viewport for both objects and NPCs. Cuts ~70 lines of duplicated logic and makes WOM->M2 reusable across the codebase.
This commit is contained in:
parent
eb8f5a09b1
commit
03a863abe1
3 changed files with 80 additions and 81 deletions
|
|
@ -134,46 +134,11 @@ void EditorViewport::rebuildObjects(const std::vector<PlacedObject>& objects,
|
|||
pipeline::M2Model model;
|
||||
bool loaded = false;
|
||||
|
||||
// Try WOM open format first
|
||||
{
|
||||
std::string womBase = obj.path;
|
||||
auto womDot = womBase.rfind('.');
|
||||
if (womDot != std::string::npos) womBase = womBase.substr(0, womDot);
|
||||
std::replace(womBase.begin(), womBase.end(), '\\', '/');
|
||||
for (const char* prefix : {"custom_zones/models/", "output/models/"}) {
|
||||
if (pipeline::WoweeModelLoader::exists(std::string(prefix) + womBase)) {
|
||||
auto wom = pipeline::WoweeModelLoader::load(std::string(prefix) + womBase);
|
||||
if (wom.isValid()) {
|
||||
model.name = wom.name;
|
||||
model.boundRadius = wom.boundRadius;
|
||||
for (const auto& v : wom.vertices) {
|
||||
pipeline::M2Vertex mv;
|
||||
mv.position = v.position;
|
||||
mv.normal = v.normal;
|
||||
mv.texCoords[0] = v.texCoord;
|
||||
std::memcpy(mv.boneWeights, v.boneWeights, 4);
|
||||
std::memcpy(mv.boneIndices, v.boneIndices, 4);
|
||||
model.vertices.push_back(mv);
|
||||
}
|
||||
for (uint32_t idx : wom.indices)
|
||||
model.indices.push_back(static_cast<uint16_t>(idx));
|
||||
for (const auto& tp : wom.texturePaths) {
|
||||
pipeline::M2Texture tex; tex.type = 0; tex.flags = 0; tex.filename = tp;
|
||||
model.textures.push_back(tex);
|
||||
}
|
||||
model.textureLookup = {0};
|
||||
pipeline::M2Batch batch{};
|
||||
batch.textureCount = std::min(1u, static_cast<uint32_t>(wom.texturePaths.size()));
|
||||
batch.indexCount = static_cast<uint32_t>(model.indices.size());
|
||||
batch.vertexCount = static_cast<uint32_t>(model.vertices.size());
|
||||
model.batches.push_back(batch);
|
||||
pipeline::M2Material mat; mat.flags = 0; mat.blendMode = 0;
|
||||
model.materials.push_back(mat);
|
||||
loaded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Try WOM open format first (replaces proprietary M2 when available)
|
||||
if (auto wom = pipeline::WoweeModelLoader::tryLoadByGamePath(obj.path);
|
||||
wom.isValid()) {
|
||||
model = pipeline::WoweeModelLoader::toM2(wom);
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
// Fall back to M2 from game data
|
||||
|
|
@ -277,49 +242,13 @@ void EditorViewport::rebuildObjects(const std::vector<PlacedObject>& objects,
|
|||
if (it != m2ModelIds.end()) {
|
||||
modelId = it->second;
|
||||
} else {
|
||||
// Try WOM open format first
|
||||
// Try WOM open format first (replaces proprietary M2 when available)
|
||||
pipeline::M2Model model;
|
||||
bool loaded = false;
|
||||
{
|
||||
std::string womBase = npc.modelPath;
|
||||
auto womDot = womBase.rfind('.');
|
||||
if (womDot != std::string::npos) womBase = womBase.substr(0, womDot);
|
||||
std::replace(womBase.begin(), womBase.end(), '\\', '/');
|
||||
for (const char* prefix : {"custom_zones/models/", "output/models/"}) {
|
||||
if (pipeline::WoweeModelLoader::exists(std::string(prefix) + womBase)) {
|
||||
auto wom = pipeline::WoweeModelLoader::load(std::string(prefix) + womBase);
|
||||
if (wom.isValid()) {
|
||||
model.name = wom.name;
|
||||
model.boundRadius = wom.boundRadius;
|
||||
for (const auto& v : wom.vertices) {
|
||||
pipeline::M2Vertex mv;
|
||||
mv.position = v.position;
|
||||
mv.normal = v.normal;
|
||||
mv.texCoords[0] = v.texCoord;
|
||||
std::memcpy(mv.boneWeights, v.boneWeights, 4);
|
||||
std::memcpy(mv.boneIndices, v.boneIndices, 4);
|
||||
model.vertices.push_back(mv);
|
||||
}
|
||||
for (uint32_t idx : wom.indices)
|
||||
model.indices.push_back(static_cast<uint16_t>(idx));
|
||||
for (const auto& tp : wom.texturePaths) {
|
||||
pipeline::M2Texture tex; tex.type = 0; tex.flags = 0; tex.filename = tp;
|
||||
model.textures.push_back(tex);
|
||||
}
|
||||
model.textureLookup = {0};
|
||||
pipeline::M2Batch batch{};
|
||||
batch.textureCount = std::min(1u, static_cast<uint32_t>(wom.texturePaths.size()));
|
||||
batch.indexCount = static_cast<uint32_t>(model.indices.size());
|
||||
batch.vertexCount = static_cast<uint32_t>(model.vertices.size());
|
||||
model.batches.push_back(batch);
|
||||
pipeline::M2Material mat; mat.flags = 0; mat.blendMode = 0;
|
||||
model.materials.push_back(mat);
|
||||
loaded = true;
|
||||
LOG_DEBUG("NPC loaded from WOM: ", prefix, womBase);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (auto wom = pipeline::WoweeModelLoader::tryLoadByGamePath(npc.modelPath);
|
||||
wom.isValid()) {
|
||||
model = pipeline::WoweeModelLoader::toM2(wom);
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
// Fall back to M2 from game data
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue