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
|
|
@ -3,20 +3,22 @@ using System.Numerics;
|
|||
namespace AcDream.Core.Physics;
|
||||
|
||||
/// <summary>
|
||||
/// Per-frame combiner for remote-entity motion: animation root motion
|
||||
/// + InterpolationManager catch-up correction. Pure function — no
|
||||
/// side effects, no hidden state.
|
||||
/// Per-frame combiner for remote-entity motion: the root-motion delta emitted
|
||||
/// by <c>CSequence::update</c> + InterpolationManager catch-up correction.
|
||||
/// Pure function — no side effects or hidden state.
|
||||
///
|
||||
/// Mirrors retail CPhysicsObj::UpdateObjectInternal (acclient @ 0x00513730):
|
||||
/// rootOffset = CPartArray::Update(dt) // animation
|
||||
/// PositionManager::adjust_offset(rootOffset) // adds correction
|
||||
/// frame.origin += rootOffset
|
||||
///
|
||||
/// In acdream the animation root motion is sourced from
|
||||
/// AnimationSequencer.CurrentVelocity (body-local velocity from the
|
||||
/// active locomotion cycle). We rotate that by the body's orientation
|
||||
/// to get a world-space delta, then add the InterpolationManager's
|
||||
/// world-space correction.
|
||||
/// The animation root motion is the complete body-local <c>Frame.Origin</c>
|
||||
/// accumulated by <c>CPartArray::Update</c>: authored PosFrames plus the
|
||||
/// literal sequence velocity. We rotate that delta by the body's orientation
|
||||
/// to get world space. It must not be reconstructed from the interpreted
|
||||
/// command; the retail Humanoid table carries zero sequence velocity for Walk
|
||||
/// and Run, and retail moves observed characters through the interpolation
|
||||
/// queue instead.
|
||||
///
|
||||
/// <para><b>Renamed R5</b> (was <c>PositionManager</c>): this class is only the
|
||||
/// InterpolationManager-composition portion of retail's
|
||||
|
|
@ -33,13 +35,12 @@ public sealed class RemoteMotionCombiner
|
|||
/// </summary>
|
||||
/// <param name="dt">Per-frame delta time, seconds.</param>
|
||||
/// <param name="currentBodyPosition">Body's current world-space position.</param>
|
||||
/// <param name="seqVel">
|
||||
/// Body-local velocity from the active animation cycle
|
||||
/// (from <c>AnimationSequencer.CurrentVelocity</c>); pass
|
||||
/// <c>Vector3.Zero</c> if the entity has no sequencer or is on a
|
||||
/// non-locomotion cycle.
|
||||
/// <param name="rootMotionLocalDelta">
|
||||
/// Complete body-local displacement accumulated by this frame's
|
||||
/// <c>CSequence::update</c>. This is already a delta for the current
|
||||
/// quantum, not a velocity to multiply by <paramref name="dt"/>.
|
||||
/// </param>
|
||||
/// <param name="ori">Body orientation; used to rotate seqVel from body-local to world.</param>
|
||||
/// <param name="ori">Body orientation; used to rotate root motion from body-local to world.</param>
|
||||
/// <param name="interp">The remote's InterpolationManager (for AdjustOffset call).</param>
|
||||
/// <param name="maxSpeed">From <c>MotionInterpreter.GetMaxSpeed()</c> — passed to AdjustOffset for the catch-up clamp.</param>
|
||||
/// <param name="terrainNormal">
|
||||
|
|
@ -59,7 +60,7 @@ public sealed class RemoteMotionCombiner
|
|||
public Vector3 ComputeOffset(
|
||||
double dt,
|
||||
Vector3 currentBodyPosition,
|
||||
Vector3 seqVel,
|
||||
Vector3 rootMotionLocalDelta,
|
||||
Quaternion ori,
|
||||
InterpolationManager interp,
|
||||
float maxSpeed,
|
||||
|
|
@ -93,8 +94,7 @@ public sealed class RemoteMotionCombiner
|
|||
if (correction.LengthSquared() > 0f)
|
||||
return correction;
|
||||
|
||||
Vector3 rootMotionLocal = seqVel * (float)dt;
|
||||
Vector3 rootMotionWorld = Vector3.Transform(rootMotionLocal, ori);
|
||||
Vector3 rootMotionWorld = Vector3.Transform(rootMotionLocalDelta, ori);
|
||||
|
||||
// Slope projection (queue-empty fallback only). Locomotion cycles
|
||||
// bake Z=0 in body-local, so without projection the body's Z stays
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue