refactor(world): extract live projection mechanics
Move appearance rebinding, collision construction, default-pose resolution, local shadow ownership, and exact leave-world presentation into focused owners. Preserve retail parent ordering with staged validation, committed recovery, recursive attached-subtree withdrawal, and retryable exact teardown across parent, pickup, position, unwield, and pose-loss edges. Co-Authored-By: OpenAI Codex <codex@openai.com>
This commit is contained in:
parent
c87bac31a0
commit
69a2ca0c6d
26 changed files with 4172 additions and 430 deletions
59
src/AcDream.App/Physics/LiveEntityDefaultPoseResolver.cs
Normal file
59
src/AcDream.App/Physics/LiveEntityDefaultPoseResolver.cs
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
using AcDream.Core.Physics;
|
||||
using AcDream.Core.Physics.Motion;
|
||||
using DatReaderWriter.DBObjs;
|
||||
using DatReaderWriter.Types;
|
||||
|
||||
namespace AcDream.App.Physics;
|
||||
|
||||
/// <summary>
|
||||
/// Resolves the motion table's authored default-state part pose used by a
|
||||
/// live object's collision PartArray. Retail keeps the collision parts in the
|
||||
/// same current pose as the visual PartArray; an unresolved table falls back
|
||||
/// to Setup placement frames in <see cref="ShadowShapeBuilder"/>.
|
||||
/// The retained default-pose snapshot approximation is tracked as AP-84 in
|
||||
/// the retail divergence register until live per-frame collision poses land.
|
||||
/// </summary>
|
||||
internal sealed class LiveEntityDefaultPoseResolver
|
||||
{
|
||||
private readonly Func<uint, MotionTable?> _loadMotionTable;
|
||||
private readonly IAnimationLoader _animationLoader;
|
||||
private readonly bool _dumpMotion;
|
||||
|
||||
public LiveEntityDefaultPoseResolver(
|
||||
Func<uint, MotionTable?> loadMotionTable,
|
||||
IAnimationLoader animationLoader,
|
||||
bool dumpMotion)
|
||||
{
|
||||
_loadMotionTable = loadMotionTable
|
||||
?? throw new ArgumentNullException(nameof(loadMotionTable));
|
||||
_animationLoader = animationLoader
|
||||
?? throw new ArgumentNullException(nameof(animationLoader));
|
||||
_dumpMotion = dumpMotion;
|
||||
}
|
||||
|
||||
public IReadOnlyList<Frame>? Resolve(uint motionTableId, int partCount)
|
||||
{
|
||||
if (motionTableId == 0u || partCount == 0)
|
||||
return null;
|
||||
|
||||
MotionTable? motionTable = _loadMotionTable(motionTableId);
|
||||
if (motionTable is null)
|
||||
return null;
|
||||
|
||||
IReadOnlyList<Frame>? pose = MotionTablePose.DefaultStatePartFrames(
|
||||
motionTable,
|
||||
_animationLoader.LoadAnimation);
|
||||
|
||||
if (_dumpMotion)
|
||||
{
|
||||
string description = pose is null
|
||||
? "null->placement-fallback"
|
||||
: FormattableString.Invariant(
|
||||
$"part0=({pose[0].Origin.X:F2},{pose[0].Origin.Y:F2},{pose[0].Origin.Z:F2})");
|
||||
Console.WriteLine(FormattableString.Invariant(
|
||||
$"[shape-pose] mt=0x{motionTableId:X8} parts={partCount} {description}"));
|
||||
}
|
||||
|
||||
return pose;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue