Searchlight beam: the btfx brighten material class + BT_SPOT_SELF rig
SPOT.BGF decoded: a 7-vert cone from the mount, ~50u forward and ~35deg DOWN
(a ground-pool lamp, not an air beam), verts tinted cyan-white, material
class 'brighten' smuggling its additive factor in DIFFUSE.r (0.25) with a
warm emissive on the night page. The loader had never met the class -- it
drew as an opaque dark-red blob. Now: brightenFactor parsed (name-gated to
brighten*), batch -> L4DRAWOP.brightenAlpha, drawn in the blend pass as an
additive veil (dest += vertexRGB x factor), unlit. [T3] tint compose
(vertex cyan vs night emissive warm) noted in the draw branch -- field
eyeball accepted the current look.
BT_SPOT_SELF=1 (bench-only): builds the cone on the own-cockpit tree so the
BT_CAM=face view can inspect it solo. KB: view toggle is BACKTICK ('V' is
the rear-view hold since #68 -- the toggle skips bound keys); stale V-toggle
claims swept.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
7d8f109241
commit
b75bb4a04c
@@ -350,6 +350,12 @@ struct MatInfo {
|
||||
// EMISSIVE (tag 0x26): pure-emissive materials (diffuse black) render as an
|
||||
// unlit glow -- tex x emissive (btpolar:pintBIceEmit_mtl, the polar ice).
|
||||
bool hasEmissive = false;
|
||||
// BTFX "brighten" class (SPOT.BGF searchlight beam cone): the material
|
||||
// smuggles its ADDITIVE factor in DIFFUSE.r (brighten.25 authors diffuse
|
||||
// {0.25,0,0}) and its glow colour in EMISSIVE ({0.9,0.4,0.2} on the night
|
||||
// page). 0 = not a brighten material; >0 = draw as an additive veil,
|
||||
// dest += emissive x factor (the 1995 DIV brighten semantics).
|
||||
float brightenFactor = 0.0f;
|
||||
float emissive[3] = {0,0,0};
|
||||
};
|
||||
|
||||
@@ -495,12 +501,14 @@ struct MaterialResolver {
|
||||
std::string name, texName, rampName;
|
||||
MatInfo info;
|
||||
bool haveColor = false;
|
||||
float rawDiffuseR = -1.0f; // brighten-class factor carrier
|
||||
for (const Chunk& ch : c.children) {
|
||||
if (ch.id == TAG_NAME) name = chunkStr(ch);
|
||||
else if (ch.id == TAG_MATERIAL_TEXTURE && ch.len > 1) texName = chunkStr(ch, 1);
|
||||
else if (ch.id == TAG_RAMP_REF) rampName = chunkStr(ch);
|
||||
else if (ch.id == TAG_DIFFUSE && ch.len >= 12) {
|
||||
info.color = packColor(rdF32(ch.data), rdF32(ch.data + 4), rdF32(ch.data + 8));
|
||||
rawDiffuseR = rdF32(ch.data);
|
||||
haveColor = true;
|
||||
info.hasDiffuse = true;
|
||||
} else if (ch.id == TAG_AMBIENT && ch.len >= 12 && !haveColor
|
||||
@@ -520,6 +528,12 @@ struct MaterialResolver {
|
||||
info.hasEmissive = (info.emissive[0] + info.emissive[1] + info.emissive[2]) > 0.001f;
|
||||
}
|
||||
}
|
||||
// BTFX brighten class: name-gated so ordinary materials keep
|
||||
// their diffuse semantics untouched (the factor rides only in
|
||||
// "brighten*" records -- brighten.25/.5/.75 in btfx.bmf).
|
||||
if (name.compare(0, 8, "brighten") == 0 && rawDiffuseR > 0.0f)
|
||||
info.brightenFactor = rawDiffuseR;
|
||||
|
||||
// Resolve the ramp reference to its low/high colours: this
|
||||
// file's own definitions first, then the cross-library
|
||||
// registry (mech skins reference 'softer' defined elsewhere).
|
||||
@@ -645,6 +659,7 @@ struct Builder {
|
||||
int currentCopRole = 0; // role of the pmesh being built (consumed by buildPmesh)
|
||||
bool currentHasEmissive = false;
|
||||
float currentEmissive[3] = {0,0,0};
|
||||
float currentBrighten = 0.0f; // btfx brighten-class additive factor
|
||||
|
||||
// per-vertex scratch (normals accumulated from forward triangles only)
|
||||
std::vector<float> px, py, pz, nx, ny, nz, uu, vv;
|
||||
@@ -926,6 +941,7 @@ struct Builder {
|
||||
batch.shadowMat = currentShadowMat;
|
||||
batch.hasEmissive = currentHasEmissive;
|
||||
for (int i = 0; i < 3; ++i) batch.emissive[i] = currentEmissive[i];
|
||||
batch.brightenFactor = currentBrighten; // btfx additive veil (spot cone)
|
||||
// SUBMISSION-ORDER DEPTH BIAS (additive objects): the content layers
|
||||
// EXACTLY-COPLANAR shells (AR02 LOD2: solid concrete + a coplanar
|
||||
// PUNCH-cutout overlay + an inner shell, plane separations
|
||||
@@ -1251,8 +1267,9 @@ struct Builder {
|
||||
for (int i = 0; i < 3; ++i) { currentRampLo[i] = info.rampLo[i]; currentRampHi[i] = info.rampHi[i]; }
|
||||
currentHasEmissive = info.hasEmissive;
|
||||
for (int i = 0; i < 3; ++i) currentEmissive[i] = info.emissive[i];
|
||||
currentBrighten = info.brightenFactor;
|
||||
}
|
||||
else { currentColor = colorForMaterial(full); currentTex.clear(); currentHasDiffuse = false; currentTexChannel = 0; currentTexScroll = false; currentTexScrollU = currentTexScrollV = 0.0f; }
|
||||
else { currentColor = colorForMaterial(full); currentTex.clear(); currentHasDiffuse = false; currentTexChannel = 0; currentTexScroll = false; currentTexScrollU = currentTexScrollV = 0.0f; currentBrighten = 0.0f; }
|
||||
// TRANSLOCATION WARP: override the material's coarse "sky" ramp with the
|
||||
// NARROW LAVENDER ramp that matched the original (capture.png). The swirl
|
||||
// is the bintA cloud coloured lo->hi by luminance; a wide sky ramp
|
||||
|
||||
Reference in New Issue
Block a user