mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-13 00:03:45 +00:00
feat(dashboard): metal and glow looks in the UGC and zone 3D views
NifFile::ShaderLookFor knows Polished Metal (98), Brushed Steel (99) and LEGO-Emissive (53). The UGC mesh route sends each mesh's look (from its multishader tag), and the UGC 3D view draws metal as reflective and glow unlit. The zone views draw LEGO-Emissive objects going to their vertex color by its alpha, as the shader does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -492,6 +492,31 @@ TEST(NifFileTests, KnowsWhatEachShaderLeavesOut) {
|
||||
EXPECT_EQ(NifFile::ShaderLookFor(37), NifFile::NO_TEXTURE); // Basic VC NT
|
||||
EXPECT_EQ(NifFile::ShaderLookFor(70), NifFile::UNLIT); // ScrollingUV_NoLight_AnimAlpha
|
||||
EXPECT_EQ(NifFile::ShaderLookFor(32), NifFile::UNLIT | NifFile::NO_VERTEX_COLORS | NifFile::MATERIAL_COLOR); // Basic NL Material
|
||||
// The UGC server's metal and glow groups: Polished Metal, Brushed Steel, LEGO-Emissive
|
||||
EXPECT_EQ(NifFile::ShaderLookFor(98), NifFile::REFLECTIVE);
|
||||
EXPECT_EQ(NifFile::ShaderLookFor(99), NifFile::REFLECTIVE | NifFile::BRUSHED);
|
||||
EXPECT_EQ(NifFile::ShaderLookFor(53), NifFile::EMISSIVE);
|
||||
// Through a multishader tag's gameValue (S88 -> 98), as a player model's parts are drawn
|
||||
EXPECT_EQ(NifFile::ShaderLookFor(NifFile::MultishaderPart(98)), NifFile::REFLECTIVE);
|
||||
EXPECT_EQ(NifFile::ShaderLookFor(NifFile::MultishaderPart(std::nullopt)), 0);
|
||||
}
|
||||
|
||||
TEST(NifFileTests, EncodesEachMeshsLook) {
|
||||
NifFile::Model model;
|
||||
model.meshes.resize(2);
|
||||
for (auto& mesh : model.meshes) {
|
||||
mesh.positions = { 0, 0, 0, 1, 0, 0, 0, 1, 0 };
|
||||
mesh.indices = { 0, 1, 2 };
|
||||
}
|
||||
const auto header = [](const std::string& encoded) {
|
||||
uint32_t length = 0;
|
||||
std::memcpy(&length, encoded.data(), 4);
|
||||
return nlohmann::json::parse(encoded.substr(4, length));
|
||||
};
|
||||
const auto with = header(NifFile::Encode(model, { "", "" }, {}, { NifFile::REFLECTIVE, NifFile::EMISSIVE }));
|
||||
EXPECT_EQ(with["meshes"][0]["look"], NifFile::REFLECTIVE);
|
||||
EXPECT_EQ(with["meshes"][1]["look"], NifFile::EMISSIVE);
|
||||
EXPECT_FALSE(header(NifFile::Encode(model, { "", "" }))["meshes"][0].contains("look"));
|
||||
}
|
||||
|
||||
// The game client's own meshes, when a client is configured (DLU_CLIENT_RES, else client_location in the build's
|
||||
|
||||
@@ -33,13 +33,13 @@ same(S.textureAlphaMode(manifest, 1, { shaderTag: 1 }), 'decal', 'LEGO part text
|
||||
same(S.textureAlphaMode(manifest, 1, { shaderTag: 30 }), 'opacity', 'Basic VC part texture alpha');
|
||||
|
||||
// Lit, textured, vertex colors, no material colors: Basic VC
|
||||
same(S.gameLook(manifest, 1, { ...colored, shaderTag: 30 }), { lit: true, texture: true, vertexColors: true, material: false, layers: null }, 'Basic VC');
|
||||
same(S.gameLook(manifest, 1, { ...colored, shaderTag: 30 }), { lit: true, texture: true, vertexColors: true, material: false, layers: null, metal: null, emissive: false }, 'Basic VC');
|
||||
// Vertex colors are read even when NiVertexColorProperty ignores them, but only if the mesh has some
|
||||
same(S.gameLook(manifest, 0, { ...colored, vertexColors: 0 }).vertexColors, true, 'shader reads vertex colors');
|
||||
same(S.gameLook(manifest, 0, {}).vertexColors, false, 'mesh without vertex colors');
|
||||
same(S.gameLook(manifest, 3, colored), { lit: false, texture: false, vertexColors: true, material: false, layers: null }, 'Basic NL VC NT');
|
||||
same(S.gameLook(manifest, 3, colored), { lit: false, texture: false, vertexColors: true, material: false, layers: null, metal: null, emissive: false }, 'Basic NL VC NT');
|
||||
// Fixed function: NiVertexColorProperty and the material decide
|
||||
same(S.gameLook(manifest, 2, { ...colored, vertexColors: 0 }), { lit: true, texture: true, vertexColors: false, material: true, layers: null }, 'fixed function');
|
||||
same(S.gameLook(manifest, 2, { ...colored, vertexColors: 0 }), { lit: true, texture: true, vertexColors: false, material: true, layers: null, metal: null, emissive: false }, 'fixed function');
|
||||
// Without the zone's lighting the viewer lights scenery itself
|
||||
same(S.gameLook({ ...manifest, lighting: null }, 0, colored), null, 'no lighting');
|
||||
|
||||
@@ -63,6 +63,15 @@ same(S.gameLook(layered, 0, colored).layers, 'blended', 'two layers blended');
|
||||
same(S.gameLook(layered, 1, colored).layers, 'added', 'two layers added');
|
||||
same(S.gameLook(manifest, 0, colored).layers, null, 'one layer');
|
||||
|
||||
// A player model's metal and glow groups (UGC server shader settings): Polished Metal, Brushed Steel, LEGO-Emissive
|
||||
const shiny = { ...manifest, shaders: [9999], shaderTags: { 1: 5, 88: 98, 89: 99, 46: 53 },
|
||||
shaderLooks: { 98: S.SHADER_LOOK.REFLECTIVE, 99: S.SHADER_LOOK.REFLECTIVE | S.SHADER_LOOK.BRUSHED, 53: S.SHADER_LOOK.EMISSIVE } };
|
||||
same(S.gameLook(shiny, 0, { ...colored, shaderTag: 88 }).metal, 'polished', 'polished metal');
|
||||
same(S.gameLook(shiny, 0, { ...colored, shaderTag: 89 }).metal, 'brushed', 'brushed steel');
|
||||
same(S.gameLook(shiny, 0, { ...colored, shaderTag: 46 }).emissive, true, 'emissive');
|
||||
same(S.gameLook(shiny, 0, { ...colored, shaderTag: 1 }).metal, null, 'plastic');
|
||||
same([S.metalOf(0), S.metalOf(S.SHADER_LOOK.REFLECTIVE), S.metalOf(S.SHADER_LOOK.REFLECTIVE | S.SHADER_LOOK.BRUSHED)], [null, 'polished', 'brushed'], 'metal of look bits');
|
||||
|
||||
// The near plane grows with the distance, within limits
|
||||
same([S.nearPlaneFor(10), S.nearPlaneFor(2000), S.nearPlaneFor(100000)], [0.5, 5, 20], 'near plane');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user