From a0895fabdf707c21580b8bdd46622a5e770f5f23 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Wed, 6 May 2026 07:27:33 -0700 Subject: [PATCH] fix(wom): drop invalid batches at save time Symmetric with the load-side validation. A WOM3 batch whose indexStart+indexCount exceeds the index buffer, or whose texture index points past the texture array, would otherwise emit an invalid file that the load-time guard then has to drop. Filter at save instead so the on-disk file stays compact and self-consistent. --- src/pipeline/wowee_model.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/pipeline/wowee_model.cpp b/src/pipeline/wowee_model.cpp index 54ed330e..2805de50 100644 --- a/src/pipeline/wowee_model.cpp +++ b/src/pipeline/wowee_model.cpp @@ -362,11 +362,24 @@ bool WoweeModelLoader::save(const WoweeModel& model, const std::string& basePath } } - // WOM3: write batches + // WOM3: write batches. Drop batches that reference invalid index ranges + // or texture slots — load would do the same drop and log a warning, but + // skipping at save time keeps the file small and deterministic. if (hasBatches) { - uint32_t batchCount = static_cast(model.batches.size()); - f.write(reinterpret_cast(&batchCount), 4); + const uint32_t totalIdx = static_cast(model.indices.size()); + const uint32_t totalTex = static_cast(model.texturePaths.size()); + std::vector validBatches; + validBatches.reserve(model.batches.size()); for (const auto& b : model.batches) { + if (b.indexCount == 0) continue; + if (b.indexStart > totalIdx) continue; + if (b.indexStart + b.indexCount > totalIdx) continue; + if (totalTex > 0 && b.textureIndex >= totalTex) continue; + validBatches.push_back(b); + } + uint32_t batchCount = static_cast(validBatches.size()); + f.write(reinterpret_cast(&batchCount), 4); + for (const auto& b : validBatches) { f.write(reinterpret_cast(&b.indexStart), 4); f.write(reinterpret_cast(&b.indexCount), 4); f.write(reinterpret_cast(&b.textureIndex), 4);