Fix WDB texture parsing for parts vs models

Parts and models have different texture info formats - models include a
skipTextures field that parts don't have. Add isModel parameter to
parseTextureInfo to handle this difference correctly. Also remove silent
catch blocks and overly defensive checks.
This commit is contained in:
Christian Semmler 2026-02-01 16:13:09 -08:00
parent 9c46c8cc6c
commit 22ca0d4d50

View File

@ -119,14 +119,8 @@ export class WdbParser {
parts.push({ name, lods }); parts.push({ name, lods });
} }
// Parse textures at textureInfoOffset
this.reader.seek(offset + textureInfoOffset); this.reader.seek(offset + textureInfoOffset);
let textures = []; const textures = this.parseTextureInfo();
try {
textures = this.parseTextureInfo();
} catch (e) {
// Continue without textures - wheel caps don't need textures for color display
}
return { parts, textures }; return { parts, textures };
} }
@ -153,9 +147,8 @@ export class WdbParser {
// Parse ROI hierarchy // Parse ROI hierarchy
const roi = this.parseRoi(); const roi = this.parseRoi();
// Parse textures at textureInfoOffset
this.reader.seek(offset + textureInfoOffset); this.reader.seek(offset + textureInfoOffset);
const textures = this.parseTextureInfo(); const textures = this.parseTextureInfo(true); // Models have skipTextures field
return { version, anim, roi, textures }; return { version, anim, roi, textures };
} }
@ -407,9 +400,19 @@ export class WdbParser {
return { color, alpha, shading, useAlias, textureName, materialName }; return { color, alpha, shading, useAlias, textureName, materialName };
} }
parseTextureInfo() { /**
* Parse texture info block
* @param {boolean} isModel - If true, read skipTextures field (models have it, parts don't)
*/
parseTextureInfo(isModel = false) {
const numTextures = this.reader.readU32(); const numTextures = this.reader.readU32();
const skipTextures = this.reader.readU32();
// Models have an extra skipTextures field that parts don't have
// See legomodelpresenter.cpp vs legopartpresenter.cpp in LEGO1 source
if (isModel) {
this.reader.readU32(); // skipTextures - skip over this field
}
const textures = []; const textures = [];
for (let i = 0; i < numTextures; i++) { for (let i = 0; i < numTextures; i++) {
@ -516,16 +519,10 @@ export function buildPartsMap(parser, worldParts) {
if (!worldParts || worldParts.length === 0) return partsMap; if (!worldParts || worldParts.length === 0) return partsMap;
for (const partRef of worldParts) { for (const partRef of worldParts) {
try {
const partData = parser.parsePartData(partRef.dataOffset); const partData = parser.parsePartData(partRef.dataOffset);
if (partData && partData.parts) {
for (const part of partData.parts) { for (const part of partData.parts) {
partsMap.set(part.name.toLowerCase(), part); partsMap.set(part.name.toLowerCase(), part);
} }
} }
} catch (e) {
// Continue with other parts
}
}
return partsMap; return partsMap;
} }