Cultural rubble RENDERS: additional objects were drawing at the world origin (issue #3)
The playtest falsified the first revival: the truck vanished with no wreck. Cause: the rubble (and any additional cultural object) was built as a DPLStaticChildRenderable / DCSInstanceRenderable added at TOP LEVEL of mRenderables -- those classes read the bare matrix stack (identity at top level), so the rubble drew at the WORLD ORIGIN, not at the icon (and before the consolidation exclusion it was consolidated there permanently). Fix: every cultural video object (intact AND rubble) is a RootRenderable (Static) -- placed from myEntity->localToWorld, registered into the frame pass lists by the same per-frame Execute path the intact model draws through. The revived state switch then genuinely swaps them. PIXEL-VERIFIED via BT_SHOT screenshot timeline (full-speed BT_GOTO ram, ARENA1 MECHMOVR truck): intact truck visible -> ram/death -> the MECHMD wreck debris renders scattered at the truck's exact spot, intact model gone, mech walks the footprint. ARENA1 census: 57 rubble-typed objects across the 124 icons (MECHMD/bpip1d/ab07d_FR...). NOT yet closed (open on #3): (a) the wreck's scorch base quad draws as an opaque BLACK rectangle (13 plain ops on MECHMD -- material/ramp resolve, not a blend flag); (b) the death explosion (psfx 1008) still not visibly confirmed; (c) the authored burning-fire state visual unreconstructed. Diag added: [cultobj] census (BT_CULT_LOG) -- per-object file/type/op flags. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
28b01e3529
commit
5e7b4e8232
+42
-34
@@ -7139,6 +7139,15 @@ void
|
||||
continue; // next object
|
||||
}
|
||||
|
||||
// BT_CULT_LOG (issue #3): per-object census -- name/type + draw-op
|
||||
// flags (hunting the opaque-black scorch quad on rubble models).
|
||||
if (getenv("BT_CULT_LOG"))
|
||||
{
|
||||
DEBUG_STREAM << "[cultobj] entity=" << (long)entity->GetEntityID()
|
||||
<< " file=" << object_filename
|
||||
<< " type=" << (int)resource_type << std::flush;
|
||||
}
|
||||
|
||||
SET_VIDEO_LOAD_OBJECT();
|
||||
// HACK !!! load the object as uncached so entity identification will work right
|
||||
// this_object = dpl_LoadObject(object_filename, dpl_load_normal);
|
||||
@@ -7153,6 +7162,21 @@ void
|
||||
continue; // next object
|
||||
}
|
||||
}
|
||||
else if (getenv("BT_CULT_LOG"))
|
||||
{
|
||||
// [cultobj] tail: the loaded object's per-op flags
|
||||
DEBUG_STREAM << " ops=" << this_object->GetDrawOpCount();
|
||||
for (int opn = 0; opn < this_object->GetDrawOpCount(); opn++)
|
||||
{
|
||||
const L4DRAWOP *op = this_object->GetDrawOp(opn);
|
||||
DEBUG_STREAM << " [" << opn
|
||||
<< " aT=" << (int)op->alphaTest
|
||||
<< " dcl=" << (int)op->drawAsDecal
|
||||
<< " sky=" << (int)op->drawAsSky << "]";
|
||||
}
|
||||
DEBUG_STREAM << " shadow=" << (int)this_object->GetIsShadow()
|
||||
<< "\n" << std::flush;
|
||||
}
|
||||
if (first_object)
|
||||
{
|
||||
first_object = False;
|
||||
@@ -7177,40 +7201,24 @@ void
|
||||
}
|
||||
else
|
||||
{
|
||||
if (renderer_modes | L4VideoObject::BillboardObject)
|
||||
{
|
||||
//------------------------------------------
|
||||
// attach additional object to separate DCS
|
||||
// because it is billboarded
|
||||
//------------------------------------------
|
||||
component = new DPLStaticChildRenderable(
|
||||
entity,
|
||||
false,
|
||||
this_object,
|
||||
intersect_mode,
|
||||
intersect_mask,
|
||||
offset_matrix,
|
||||
NULL);
|
||||
// this_DCS = this_child->GetDCS();
|
||||
// this_instance = this_child->GetInstance();
|
||||
}
|
||||
else
|
||||
{
|
||||
//----------------------------------------
|
||||
// attach additional objects to root_DCS
|
||||
// (HACK) temporary implementation (HACK)
|
||||
//----------------------------------------
|
||||
component = new DCSInstanceRenderable(
|
||||
entity, // Entity to attach the renderable to
|
||||
DCSInstanceRenderable::Static, // How/when to execute the renderable
|
||||
this_object, // object to connect to the instance
|
||||
NULL, // the DCS to add the instance to
|
||||
intersect_mode, // type of intersections to do on this object
|
||||
intersect_mask, // intersection mask for the object
|
||||
True); // initial visibility setting
|
||||
//this_DCS = NULL;
|
||||
// this_instance = another_instance->GetInstance();
|
||||
}
|
||||
//------------------------------------------------------------
|
||||
// Issue #3 (cultural destruction): additional cultural objects
|
||||
// (the RUBBLE model above all) used to go to
|
||||
// DPLStaticChildRenderable / DCSInstanceRenderable -- but as
|
||||
// TOP-LEVEL mRenderables entries those classes read the bare
|
||||
// matrix stack (identity), so the rubble drew at the WORLD
|
||||
// ORIGIN, not at the icon (and pre-revival it consolidated
|
||||
// there permanently). RootRenderable places from
|
||||
// myEntity->localToWorld -- the same path the intact (first)
|
||||
// object draws through -- so every cultural object is one.
|
||||
//------------------------------------------------------------
|
||||
component = new RootRenderable(
|
||||
entity, // Entity to attach the renderable to
|
||||
RootRenderable::Static, // How/when to execute the renderable
|
||||
this_object, // the additional object (rubble etc.)
|
||||
false, // DPL Zone (for culling)
|
||||
intersect_mode, // type of intersections to do on this object
|
||||
intersect_mask); // intersection mask for the object
|
||||
}
|
||||
// add the new object to our renderables list. Keep the draw
|
||||
// component in hand -- the revived state switch (issue #3)
|
||||
|
||||
Reference in New Issue
Block a user