fix(animation): retain trailing PartArray poses
Port CPartArray::UpdateParts minimum-count behavior: preserve the prior visual and rigid transforms for setup parts absent from a short authored AnimFrame, including the initial hydrated rest pose. Co-Authored-By: OpenAI Codex <codex@openai.com>
This commit is contained in:
parent
f004ac5562
commit
a2fd61684a
6 changed files with 326 additions and 59 deletions
|
|
@ -73,6 +73,90 @@ public sealed class LiveEntityAnimationPresenterTests
|
|||
Assert.Empty(replacement.EffectPartPosesScratch);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ShortFirstFrame_RetainsDistinctVisualAndRigidRestPoses()
|
||||
{
|
||||
var fixture = Build(partCount: 2, scale: 2f);
|
||||
Matrix4x4 visualRest = Matrix4x4.CreateScale(7f)
|
||||
* Matrix4x4.CreateTranslation(8f, 9f, 10f);
|
||||
Matrix4x4 rigidRest = Matrix4x4.CreateTranslation(11f, 12f, 13f);
|
||||
fixture.Entity.MeshRefs =
|
||||
[
|
||||
new MeshRef(0x01000001u, Matrix4x4.Identity),
|
||||
new MeshRef(0x01000002u, visualRest),
|
||||
];
|
||||
fixture.Entity.SetIndexedPartPoses(
|
||||
[Matrix4x4.Identity, rigidRest],
|
||||
[true, true]);
|
||||
var presenter = Presenter(fixture.Live, new EntityEffectPoseRegistry(), new Context());
|
||||
|
||||
presenter.Present(Schedules(fixture,
|
||||
[new PartTransform(Vector3.UnitX, Quaternion.Identity)]));
|
||||
|
||||
Assert.Equal(visualRest, fixture.Entity.MeshRefs[1].PartTransform);
|
||||
Assert.Equal(rigidRest, fixture.Entity.IndexedPartTransforms[1]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LaterShortFrame_RetainsPreviouslyPresentedTrailingPart()
|
||||
{
|
||||
var fixture = Build(partCount: 2);
|
||||
var presenter = Presenter(fixture.Live, new EntityEffectPoseRegistry(), new Context());
|
||||
presenter.Present(Schedules(fixture,
|
||||
[
|
||||
new PartTransform(Vector3.UnitX, Quaternion.Identity),
|
||||
new PartTransform(new Vector3(4f, 5f, 6f), Quaternion.CreateFromAxisAngle(Vector3.UnitZ, 0.5f)),
|
||||
]));
|
||||
Matrix4x4 visual = fixture.Entity.MeshRefs[1].PartTransform;
|
||||
Matrix4x4 rigid = fixture.Entity.IndexedPartTransforms[1];
|
||||
|
||||
presenter.Present(Schedules(fixture,
|
||||
[new PartTransform(Vector3.UnitY, Quaternion.Identity)]));
|
||||
|
||||
Assert.Equal(visual, fixture.Entity.MeshRefs[1].PartTransform);
|
||||
Assert.Equal(rigid, fixture.Entity.IndexedPartTransforms[1]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AppearanceShrink_ClearsAllTrailingPresentationState()
|
||||
{
|
||||
var fixture = Build(partCount: 3);
|
||||
var poses = new EntityEffectPoseRegistry();
|
||||
var presenter = Presenter(fixture.Live, poses, new Context());
|
||||
presenter.Present(Schedules(fixture,
|
||||
[
|
||||
new PartTransform(Vector3.UnitX, Quaternion.Identity),
|
||||
new PartTransform(Vector3.UnitY, Quaternion.Identity),
|
||||
new PartTransform(Vector3.UnitZ, Quaternion.Identity),
|
||||
]));
|
||||
var replacementSetup = new Setup();
|
||||
replacementSetup.Parts.Add(0x01000009u);
|
||||
replacementSetup.DefaultScale.Add(Vector3.One);
|
||||
fixture.Entity.MeshRefs = [new MeshRef(0x01000009u, Matrix4x4.Identity)];
|
||||
fixture.Entity.SetIndexedPartPoses([Matrix4x4.Identity], [true]);
|
||||
GameWindow.RebindAnimatedEntityForAppearance(
|
||||
fixture.State,
|
||||
fixture.Entity,
|
||||
replacementSetup,
|
||||
1f,
|
||||
[new LiveAnimationPartTemplate(0x01000009u, null, true)],
|
||||
[true]);
|
||||
|
||||
presenter.Present(Schedules(fixture,
|
||||
[new PartTransform(new Vector3(9f, 0f, 0f), Quaternion.Identity)]));
|
||||
|
||||
Assert.Single(fixture.Entity.MeshRefs);
|
||||
Assert.Single(fixture.Entity.IndexedPartTransforms);
|
||||
Assert.Single(fixture.State.VisualPartPosesScratch);
|
||||
Assert.Single(fixture.State.EffectPartPosesScratch);
|
||||
Assert.True(poses.TryGetPartPoseSnapshot(
|
||||
fixture.Entity.Id,
|
||||
out IReadOnlyList<Matrix4x4> published,
|
||||
out IReadOnlyList<bool> available));
|
||||
Assert.Single(published);
|
||||
Assert.Single(available);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MotionDone_OldComponentCannotResolveReplacementByGuid()
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue