Audio Phase 4d (AUDIO_FIDELITY F5): footStep is the authored CONTACT LEVEL
The binary's per-frame perf (disasm @0x4a9e80-0x4a9eb6 leg / @0x4aba86- 0x4abab9 body) computes footStep@0x394 = (jointlocal.y <= *footStepThreshold) with the threshold pointer = SequenceController+0x20 = &ANI hdr[2] -- the header word the engine's own AnimationInstance captures (JMOVER.cpp:1415) and our SelectSequence skipped. States 0/1 retain the value. Port: SelectSequence captures hdr[2]; PerformAndWatch evaluates the contact level per frame from the cached jointlocal root joint (leg channel drives the pose); the 150 ms clip-transition pulse + decay are RETIRED (steps fired at clip boundaries with a fixed width; clips whose root crosses twice or never counted wrong). Live verification (30s walk): the authored threshold decodes real (-0.232 root height); rootY oscillates across it per stride (-0.26 contact / -0.19 swing) with clean 0->1->0 transitions per leg state (5/6/7); 34 footfall deliveries at stride rate with per-stride varying gains. Also closes F23(2): the 17 authored AnimationState trigger states fire empirically -- the EngineShiftFwd/Rev heard during the gait dead-band hunt WERE states 10/11/14/15; the runtime clip numbering is correct. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
9dcb4752de
commit
0e2401fb52
@@ -5274,18 +5274,32 @@ void
|
||||
// (AudioLogicalTrigger FootStep, AudioMotionScale/Trigger LocalVelocity, ...)
|
||||
// never executed -- only the PUSHED StateIndicator watchers fired. That's
|
||||
// why footsteps/motion-scaled sounds were silent while state sounds worked. [T0]
|
||||
// FootStep pulse decay (see SetBodyAnimation): clear the contact flag ~150ms
|
||||
// after the plant so the FootStep matcher (fires on the CHANGE to 1) sees a 0
|
||||
// before the next stride re-pulses. Lives HERE (not IntegrateMotion, which the
|
||||
// current gait path never calls) so it provably ticks every mech frame, right
|
||||
// before the watcher poll below reads it. Time-based -- tick-rate immune.
|
||||
if (footStepDecay > 0)
|
||||
// (AUDIO_FIDELITY F5) footStep is the authored CONTACT LEVEL (binary
|
||||
// disasm @0x4a9e80-0x4a9eb6): while the leg channel's gait state is not
|
||||
// Standing(0)/1, footStep = (jointlocal.y <= *clip threshold); states
|
||||
// 0/1 RETAIN the previous value. The FootStep matcher fires on the
|
||||
// CHANGE to 1 -- one clean rising edge per actual foot plant, timed by
|
||||
// the clip's authored root-height crossing (replaces the 150 ms
|
||||
// transition pulse, which fired at clip boundaries with a fixed width).
|
||||
if (legAnimationState != 0 && legAnimationState != 1)
|
||||
{
|
||||
footStepDecay -= (int)(dt * 1000.0f);
|
||||
if (footStepDecay <= 0)
|
||||
if (!footStepRootResolved)
|
||||
{
|
||||
footStepDecay = 0;
|
||||
footStep = 0;
|
||||
footStepRootResolved = 1;
|
||||
footStepRootJoint = ResolveJoint("jointlocal");
|
||||
}
|
||||
Scalar *fs_thresh = legAnimation.footStepThreshold;
|
||||
if (footStepRootJoint != 0 && fs_thresh != 0)
|
||||
{
|
||||
int contact =
|
||||
(footStepRootJoint->GetTranslation().y <= *fs_thresh) ? 1 : 0;
|
||||
if (getenv("BT_AUDIO_LOG")) { static int s_fc=0;
|
||||
if (contact != footStep && s_fc++ < 40)
|
||||
DEBUG_STREAM << "[audio] footstep contact " << footStep << "->" << contact
|
||||
<< " rootY=" << footStepRootJoint->GetTranslation().y
|
||||
<< " thresh=" << *fs_thresh << " legState=" << legAnimationState
|
||||
<< "\n" << std::flush; }
|
||||
footStep = contact;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user