fix(runtime): align portal and movement presentation
Port retail portal viewport projection and reveal behavior, preserve outbound combat style, drive remote and local grounded movement from authored CSequence root frames, and reuse the local prepared pose so animation hooks advance once. User-verified portal, observer movement, combat stance, and short-tap locomotion gates. Release build passed with 5,767 tests and five intentional skips. Co-authored-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
parent
e95f55f25b
commit
124e046976
30 changed files with 1362 additions and 348 deletions
|
|
@ -1220,6 +1220,29 @@ public sealed class AnimationSequencerTests
|
|||
Assert.Equal(new Vector3(0f, 4f, 0f), seq.CurrentVelocity);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CurrentVelocity_ZeroLocomotionMotionData_IsNotSynthesizedFromCommand()
|
||||
{
|
||||
// Retail add_motion @ 0x005224B0 writes MotionData.Velocity * speed
|
||||
// unconditionally. It never substitutes CMotionInterp's body-speed
|
||||
// constants into CSequence. The installed Humanoid table uses this
|
||||
// zero-velocity shape for both Walk and Run.
|
||||
const uint Style = 0x8000003Du;
|
||||
const uint Motion = 0x40000007u;
|
||||
const uint AnimId = 0x03000406u;
|
||||
|
||||
var anim = Fixtures.MakeAnim(4, 1, Vector3.Zero, Quaternion.Identity);
|
||||
var setup = Fixtures.MakeSetup(1);
|
||||
var mt = Fixtures.MakeMtable(Style, Motion, AnimId, framerate: 10f);
|
||||
var loader = new FakeLoader();
|
||||
loader.Register(AnimId, anim);
|
||||
|
||||
var seq = new AnimationSequencer(setup, mt, loader);
|
||||
seq.SetCycle(Style, Motion, speedMod: 2f);
|
||||
|
||||
Assert.Equal(Vector3.Zero, seq.CurrentVelocity);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CurrentVelocity_ScaledBySpeedMod()
|
||||
{
|
||||
|
|
@ -1454,8 +1477,9 @@ public sealed class AnimationSequencerTests
|
|||
{
|
||||
// A RunForward motion with MotionData.Velocity = (0,4,0) should
|
||||
// surface as (0,4,0) at speedMod=1.0, (0,6,0) at 1.5×, (0,2,0) at
|
||||
// 0.5×. The dead-reckoning integrator in TickAnimations reads
|
||||
// CurrentVelocity each tick, so this has to be accurate.
|
||||
// 0.5×.
|
||||
// CSequence stores that literal DAT velocity for retail
|
||||
// get_state_velocity consumers, so scaling must remain exact.
|
||||
// R2-Q4: retail-mandatory StyleDefaults + the 0x40000000 cycle-class
|
||||
// bit on Motion (see CurrentVelocity_ExposedFromMotionData_WhenHasVelocity).
|
||||
const uint Style = 0x8000003Du;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue