feat(ugc): brushed_colors, LEGO color ids drawn as brushed steel

The client's Materials.xml has no brushedSteel or matteSteel colors, so the
Brushed Steel shader (mapShaders 89) was never used. brushed_colors names
color ids to draw with it whatever their type (e.g. the drum lacquered
298, 300, 1002, 1004); a named color wins over the metal and glow colors.
Empty by default. The docs note that the client registers the brushed
reflection and noise textures itself (0x00453730), so the .nif needs none.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Aaron Kimbrell
2026-09-28 10:18:07 -05:00
parent 6c45d4abdb
commit f3922b3bcb
7 changed files with 24 additions and 2 deletions

View File

@@ -191,6 +191,7 @@ namespace UgcModel {
}
eLook LookOf(uint32_t id, const UgcBricks::Material& material, const LookRules& rules) {
if (const auto color = rules.colors.find(id); color != rules.colors.end()) return color->second;
if (rules.paletteGlow && UgcPalette::Glow(id)) return eLook::GLOW;
if (rules.paletteMetallic && UgcPalette::IsMetallic(id)) return eLook::METAL;
const auto type = rules.materialTypes.find(material.type);

View File

@@ -75,9 +75,11 @@ namespace UgcModel {
/**
* Which colors have which look, from the client's data: a Materials.xml MaterialType (brickdb.zip) and LU Toolbox's
* metallic and glow colors (UgcPalette). Glow wins over metal; transparent bricks are always plastic.
* metallic and glow colors (UgcPalette), and colors named in the settings. A named color wins, then glow over metal;
* transparent bricks are always plastic.
*/
struct LookRules {
std::map<uint32_t, eLook> colors; // LEGO color ids given a look by the settings (brushed_colors)
std::map<std::string, eLook> materialTypes{ { "shinySteel", eLook::METAL }, { "brushedSteel", eLook::BRUSHED }, { "matteSteel", eLook::BRUSHED } };
bool paletteMetallic{ true }; // LU Toolbox's Metallic colors (UgcPalette::IsMetallic) are METAL
bool paletteGlow{ true }; // its glow colors (UgcPalette::Glow) are GLOW

View File

@@ -106,6 +106,15 @@ namespace {
if (!type.empty() && type != "none") settings.build.looks.materialTypes[type] = look;
}
}
// LEGO color ids drawn as brushed steel whatever their Materials.xml type
{
std::stringstream stream(Game::config->GetValue("brushed_colors"));
std::string id;
while (std::getline(stream, id, ',')) {
std::erase_if(id, [](unsigned char c) { return std::isspace(c); });
if (const auto color = GeneralUtils::TryParse<uint32_t>(id)) settings.build.looks.colors[*color] = UgcModel::eLook::BRUSHED;
}
}
settings.optimize.removeHidden = Setting<int32_t>("remove_hidden_faces", 1) != 0;
settings.optimize.groundPlane = Setting<int32_t>("hsr_ground_plane", 0) != 0;
settings.optimize.resolution = Setting<int32_t>("optimize_resolution", 1024);