fix(physics): port retail slope landing stop
This commit is contained in:
parent
1d8371dbe5
commit
5a0f9868a6
13 changed files with 870 additions and 103 deletions
|
|
@ -0,0 +1,164 @@
|
|||
using System.Numerics;
|
||||
using System.Text.Json;
|
||||
using AcDream.Core.Physics;
|
||||
using AcDream.Runtime.Gameplay;
|
||||
|
||||
namespace AcDream.Runtime.Tests.Gameplay;
|
||||
|
||||
[Collection(PlayerPhysicsQuantumCaptureCollection.Name)]
|
||||
public sealed class PlayerPhysicsQuantumCaptureTests : IDisposable
|
||||
{
|
||||
private readonly string _path = Path.Combine(
|
||||
Path.GetTempPath(),
|
||||
$"acdream-player-physics-{Guid.NewGuid():N}.jsonl");
|
||||
|
||||
public PlayerPhysicsQuantumCaptureTests() =>
|
||||
PlayerPhysicsQuantumCapture.ResetForTest();
|
||||
|
||||
[Fact]
|
||||
public void DisabledCapture_DoesNotCreateAFile()
|
||||
{
|
||||
PhysicsBody body = CreateBody();
|
||||
|
||||
Assert.False(PlayerPhysicsQuantumCapture.IsEnabled);
|
||||
_ = PlayerPhysicsQuantumCapture.Snapshot(body);
|
||||
Assert.False(File.Exists(_path));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EnabledCapture_WritesCompleteOrderedQuantum()
|
||||
{
|
||||
PhysicsBody body = CreateBody();
|
||||
PlayerPhysicsQuantumCapture.CapturePath = _path;
|
||||
|
||||
PlayerPhysicsBodyTraceSnapshot start =
|
||||
PlayerPhysicsQuantumCapture.Snapshot(body);
|
||||
body.Velocity = new Vector3(2f, 3f, -4f);
|
||||
PlayerPhysicsBodyTraceSnapshot pre =
|
||||
PlayerPhysicsQuantumCapture.Snapshot(body);
|
||||
body.UpdatePhysicsInternal(0.05f);
|
||||
PlayerPhysicsBodyTraceSnapshot post =
|
||||
PlayerPhysicsQuantumCapture.Snapshot(body);
|
||||
body.Velocity = new Vector3(1f, 1.5f, 0.2f);
|
||||
PlayerPhysicsBodyTraceSnapshot committed =
|
||||
PlayerPhysicsQuantumCapture.Snapshot(body);
|
||||
|
||||
PlayerPhysicsQuantumCapture.Log(
|
||||
dt: 0.05f,
|
||||
cellBefore: 0xAAB40011,
|
||||
cellAfter: 0xAAB40012,
|
||||
input: new MovementInput(Forward: true, Run: true),
|
||||
rootAndManagerDelta: new Vector3(0.1f, 0.2f, 0.3f),
|
||||
candidateMoved: true,
|
||||
quantumStart: start,
|
||||
preIntegration: pre,
|
||||
postIntegration: post,
|
||||
resolve: new PlayerPhysicsResolveTraceSnapshot(
|
||||
new Vector3(4f, 5f, 6f),
|
||||
0xAAB40012,
|
||||
Ok: true,
|
||||
IsOnGround: true,
|
||||
InContact: true,
|
||||
OnWalkable: true,
|
||||
CollisionNormalValid: true,
|
||||
CollisionNormal: Vector3.UnitZ),
|
||||
postCommit: committed);
|
||||
PlayerPhysicsQuantumCapture.Close();
|
||||
|
||||
string[] lines = File.ReadAllLines(_path);
|
||||
Assert.Single(lines);
|
||||
|
||||
using JsonDocument json = JsonDocument.Parse(lines[0]);
|
||||
JsonElement root = json.RootElement;
|
||||
Assert.Equal(0, root.GetProperty("sequence").GetInt64());
|
||||
Assert.Equal(0.05f, root.GetProperty("dt").GetSingle());
|
||||
Assert.Equal(0xAAB40011u, root.GetProperty("cellBefore").GetUInt32());
|
||||
Assert.Equal(0xAAB40012u, root.GetProperty("cellAfter").GetUInt32());
|
||||
Assert.True(root.GetProperty("input").GetProperty("forward").GetBoolean());
|
||||
Assert.True(root.GetProperty("input").GetProperty("run").GetBoolean());
|
||||
Assert.Equal(2f,
|
||||
root.GetProperty("preIntegration")
|
||||
.GetProperty("velocity")
|
||||
.GetProperty("x")
|
||||
.GetSingle());
|
||||
Assert.True(root.GetProperty("resolve").GetProperty("onWalkable").GetBoolean());
|
||||
Assert.Equal(0.2f,
|
||||
root.GetProperty("postCommit")
|
||||
.GetProperty("velocity")
|
||||
.GetProperty("z")
|
||||
.GetSingle());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResetForTest_ClosesWriterAndRestartsSequence()
|
||||
{
|
||||
PhysicsBody body = CreateBody();
|
||||
PlayerPhysicsQuantumCapture.CapturePath = _path;
|
||||
PlayerPhysicsBodyTraceSnapshot snapshot =
|
||||
PlayerPhysicsQuantumCapture.Snapshot(body);
|
||||
|
||||
WriteMinimal(snapshot);
|
||||
PlayerPhysicsQuantumCapture.ResetForTest();
|
||||
PlayerPhysicsQuantumCapture.CapturePath = _path;
|
||||
WriteMinimal(snapshot);
|
||||
PlayerPhysicsQuantumCapture.Close();
|
||||
|
||||
string[] lines = File.ReadAllLines(_path);
|
||||
Assert.Equal(2, lines.Length);
|
||||
Assert.All(lines, line =>
|
||||
{
|
||||
using JsonDocument json = JsonDocument.Parse(line);
|
||||
Assert.Equal(0, json.RootElement.GetProperty("sequence").GetInt64());
|
||||
});
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
PlayerPhysicsQuantumCapture.ResetForTest();
|
||||
if (File.Exists(_path))
|
||||
File.Delete(_path);
|
||||
}
|
||||
|
||||
private void WriteMinimal(PlayerPhysicsBodyTraceSnapshot snapshot) =>
|
||||
PlayerPhysicsQuantumCapture.Log(
|
||||
0.04f,
|
||||
1,
|
||||
1,
|
||||
default,
|
||||
Vector3.Zero,
|
||||
false,
|
||||
snapshot,
|
||||
snapshot,
|
||||
snapshot,
|
||||
new PlayerPhysicsResolveTraceSnapshot(
|
||||
snapshot.Position,
|
||||
1,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
Vector3.Zero),
|
||||
snapshot);
|
||||
|
||||
private static PhysicsBody CreateBody() => new()
|
||||
{
|
||||
Position = new Vector3(1f, 2f, 3f),
|
||||
Velocity = new Vector3(4f, 5f, 6f),
|
||||
Acceleration = new Vector3(0f, 0f, -9.8f),
|
||||
GroundNormal = Vector3.UnitZ,
|
||||
ContactPlaneValid = true,
|
||||
ContactPlane = new Plane(Vector3.UnitZ, -3f),
|
||||
Friction = 0.95f,
|
||||
Elasticity = 0.05f,
|
||||
State = PhysicsStateFlags.Gravity,
|
||||
TransientState =
|
||||
TransientStateFlags.Contact | TransientStateFlags.OnWalkable,
|
||||
};
|
||||
}
|
||||
|
||||
[CollectionDefinition(Name, DisableParallelization = true)]
|
||||
public sealed class PlayerPhysicsQuantumCaptureCollection
|
||||
{
|
||||
public const string Name = "Player physics quantum capture";
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue