diag(render): flap re-diagnosed as portal-flood re-clip DRIFT; physics + camera REFUTED
The 2026-06-08 AM "physics rest micro-jitter" diagnosis is refuted with primary
evidence (door-recheck 216K standstill records: 0 position re-snaps; player
byte-stable during the flap). Two adversarial verification sub-agents confirmed:
- Retail roots the render at the camera viewer_cell (swept from the player via
SmartBox::update_viewer 0x453ce0; DrawInside(viewer_cell) 0x453aa0) and toggles
DrawInside / LScape::draw -- so acdream's eye-cell rooting + inside/outside
toggle are RETAIL-FAITHFUL. The locked-design "root at player cell" is wrong.
- The flap is render membership instability, eye-motion-driven: the visible-cell
set oscillates (8<->3) as the eye sweeps monotonically. Root = the
re-enqueue-on-growth DRIFT (PortalVisibilityBuilder.cs:322, MaxReprocessPerCell
=16) re-clipping each grown cell every round -> sub-cm eye jitter flips membership.
Fix (spec, not yet implemented): verbatim port of retail's enqueue-once flood
(ConstructView + AddViewToPortals): enqueue once on first discovery, clip each
cell's portals once, union late growth in place (AddToCell) + draw-reorder
(FixCellList), never re-enqueue. Kills the drift; rooting/camera/seal untouched.
This commit lands VERIFIED GROUNDWORK + design only:
- spec: docs/superpowers/specs/2026-06-08-portal-flood-enqueue-once-port-design.md
- findings: docs/research/2026-06-08-flap-physics-diagnosis-REFUTED-its-render-membership.md
- [pv-input] probe gains rawPlayer + yaw (disambiguates the varying input)
- 4 GREEN physics rest-stability tests (prove rest is bit-stable -> flap not physics)
- apparatus: launch-flap-capture.ps1, analyze_flap_live.py, find_burst.py
- captured fixtures: tests/.../Fixtures/flap-doorway/0xA9B4017{0..5}.json
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
d6aa526dd3
commit
6c3a96b26e
14 changed files with 8231 additions and 1 deletions
413
tests/AcDream.Core.Tests/Fixtures/flap-doorway/0xA9B40170.json
Normal file
413
tests/AcDream.Core.Tests/Fixtures/flap-doorway/0xA9B40170.json
Normal file
|
|
@ -0,0 +1,413 @@
|
|||
{
|
||||
"CellId": 2847146352,
|
||||
"WorldTransform": {
|
||||
"M11": -1,
|
||||
"M12": 8.74228E-08,
|
||||
"M13": 0,
|
||||
"M14": 0,
|
||||
"M21": -8.74228E-08,
|
||||
"M22": -1,
|
||||
"M23": 0,
|
||||
"M24": 0,
|
||||
"M31": 0,
|
||||
"M32": 0,
|
||||
"M33": 1,
|
||||
"M34": 0,
|
||||
"M41": 161.929,
|
||||
"M42": 7.50315,
|
||||
"M43": 94,
|
||||
"M44": 1
|
||||
},
|
||||
"InverseWorldTransform": {
|
||||
"M11": -1,
|
||||
"M12": -8.74228E-08,
|
||||
"M13": 0,
|
||||
"M14": -0,
|
||||
"M21": 8.74228E-08,
|
||||
"M22": -1,
|
||||
"M23": 0,
|
||||
"M24": 0,
|
||||
"M31": 0,
|
||||
"M32": 0,
|
||||
"M33": 1,
|
||||
"M34": -0,
|
||||
"M41": 161.929,
|
||||
"M42": 7.5031643,
|
||||
"M43": -94,
|
||||
"M44": 1
|
||||
},
|
||||
"ResolvedPolygons": [
|
||||
{
|
||||
"Id": 0,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": -1,
|
||||
"Y": 0,
|
||||
"Z": 0
|
||||
},
|
||||
"D": 7.45189
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 7.45189,
|
||||
"Y": -8.609,
|
||||
"Z": 0
|
||||
},
|
||||
{
|
||||
"X": 7.45189,
|
||||
"Y": -8.34616,
|
||||
"Z": 2.5
|
||||
},
|
||||
{
|
||||
"X": 7.45189,
|
||||
"Y": -7.65,
|
||||
"Z": 2.5
|
||||
},
|
||||
{
|
||||
"X": 7.45189,
|
||||
"Y": -7.65,
|
||||
"Z": -1.19209E-08
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 1,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": 0,
|
||||
"Y": 1.2430552E-08,
|
||||
"Z": 1
|
||||
},
|
||||
"D": 1.0701463E-07
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 5.54731,
|
||||
"Y": -7.65,
|
||||
"Z": -1.19209E-08
|
||||
},
|
||||
{
|
||||
"X": 5.54731,
|
||||
"Y": -8.609,
|
||||
"Z": 0
|
||||
},
|
||||
{
|
||||
"X": 7.45189,
|
||||
"Y": -8.609,
|
||||
"Z": 0
|
||||
},
|
||||
{
|
||||
"X": 7.45189,
|
||||
"Y": -7.65,
|
||||
"Z": -1.19209E-08
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 2,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": 1,
|
||||
"Y": 0,
|
||||
"Z": 0
|
||||
},
|
||||
"D": -5.54731
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 5.54731,
|
||||
"Y": -7.65,
|
||||
"Z": 2.5
|
||||
},
|
||||
{
|
||||
"X": 5.54731,
|
||||
"Y": -8.34616,
|
||||
"Z": 2.5
|
||||
},
|
||||
{
|
||||
"X": 5.54731,
|
||||
"Y": -8.609,
|
||||
"Z": 0
|
||||
},
|
||||
{
|
||||
"X": 5.54731,
|
||||
"Y": -7.65,
|
||||
"Z": -1.19209E-08
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 3,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": 0,
|
||||
"Y": 0,
|
||||
"Z": -1
|
||||
},
|
||||
"D": 2.5
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 7.45189,
|
||||
"Y": -7.65,
|
||||
"Z": 2.5
|
||||
},
|
||||
{
|
||||
"X": 7.45189,
|
||||
"Y": -8.34616,
|
||||
"Z": 2.5
|
||||
},
|
||||
{
|
||||
"X": 5.54731,
|
||||
"Y": -8.34616,
|
||||
"Z": 2.5
|
||||
},
|
||||
{
|
||||
"X": 5.54731,
|
||||
"Y": -7.65,
|
||||
"Z": 2.5
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"PortalPolygons": [
|
||||
{
|
||||
"Id": 0,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": 0,
|
||||
"Y": 0,
|
||||
"Z": -1
|
||||
},
|
||||
"D": 2.5
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 7.45189,
|
||||
"Y": -7.65,
|
||||
"Z": 2.5
|
||||
},
|
||||
{
|
||||
"X": 7.45189,
|
||||
"Y": -8.34616,
|
||||
"Z": 2.5
|
||||
},
|
||||
{
|
||||
"X": 5.54731,
|
||||
"Y": -8.34616,
|
||||
"Z": 2.5
|
||||
},
|
||||
{
|
||||
"X": 5.54731,
|
||||
"Y": -7.65,
|
||||
"Z": 2.5
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 1,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": -1,
|
||||
"Y": 0,
|
||||
"Z": 0
|
||||
},
|
||||
"D": 7.45189
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 7.45189,
|
||||
"Y": -8.609,
|
||||
"Z": 0
|
||||
},
|
||||
{
|
||||
"X": 7.45189,
|
||||
"Y": -8.34616,
|
||||
"Z": 2.5
|
||||
},
|
||||
{
|
||||
"X": 7.45189,
|
||||
"Y": -7.65,
|
||||
"Z": 2.5
|
||||
},
|
||||
{
|
||||
"X": 7.45189,
|
||||
"Y": -7.65,
|
||||
"Z": -1.19209E-08
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 2,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": 0,
|
||||
"Y": 1.2430552E-08,
|
||||
"Z": 1
|
||||
},
|
||||
"D": 1.0701463E-07
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 5.54731,
|
||||
"Y": -7.65,
|
||||
"Z": -1.19209E-08
|
||||
},
|
||||
{
|
||||
"X": 5.54731,
|
||||
"Y": -8.609,
|
||||
"Z": 0
|
||||
},
|
||||
{
|
||||
"X": 7.45189,
|
||||
"Y": -8.609,
|
||||
"Z": 0
|
||||
},
|
||||
{
|
||||
"X": 7.45189,
|
||||
"Y": -7.65,
|
||||
"Z": -1.19209E-08
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 3,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": 1,
|
||||
"Y": 0,
|
||||
"Z": 0
|
||||
},
|
||||
"D": -5.54731
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 5.54731,
|
||||
"Y": -7.65,
|
||||
"Z": 2.5
|
||||
},
|
||||
{
|
||||
"X": 5.54731,
|
||||
"Y": -8.34616,
|
||||
"Z": 2.5
|
||||
},
|
||||
{
|
||||
"X": 5.54731,
|
||||
"Y": -8.609,
|
||||
"Z": 0
|
||||
},
|
||||
{
|
||||
"X": 5.54731,
|
||||
"Y": -7.65,
|
||||
"Z": -1.19209E-08
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 4,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": 0,
|
||||
"Y": -0.99451864,
|
||||
"Z": 0.10455982
|
||||
},
|
||||
"D": -8.5618105
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 5.54731,
|
||||
"Y": -8.609,
|
||||
"Z": 0
|
||||
},
|
||||
{
|
||||
"X": 7.45189,
|
||||
"Y": -8.609,
|
||||
"Z": 0
|
||||
},
|
||||
{
|
||||
"X": 7.45189,
|
||||
"Y": -8.34616,
|
||||
"Z": 2.5
|
||||
},
|
||||
{
|
||||
"X": 5.54731,
|
||||
"Y": -8.34616,
|
||||
"Z": 2.5
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 5,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": 0,
|
||||
"Y": -1,
|
||||
"Z": 0
|
||||
},
|
||||
"D": -7.65
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 7.45189,
|
||||
"Y": -7.65,
|
||||
"Z": -1.19209E-08
|
||||
},
|
||||
{
|
||||
"X": 7.45189,
|
||||
"Y": -7.65,
|
||||
"Z": 2.5
|
||||
},
|
||||
{
|
||||
"X": 5.54731,
|
||||
"Y": -7.65,
|
||||
"Z": 2.5
|
||||
},
|
||||
{
|
||||
"X": 5.54731,
|
||||
"Y": -7.65,
|
||||
"Z": -1.19209E-08
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Portals": [
|
||||
{
|
||||
"OtherCellId": 65535,
|
||||
"PolygonId": 4,
|
||||
"Flags": 5
|
||||
},
|
||||
{
|
||||
"OtherCellId": 369,
|
||||
"PolygonId": 5,
|
||||
"Flags": 3
|
||||
}
|
||||
],
|
||||
"VisibleCellIds": [
|
||||
2847146351,
|
||||
2847146353,
|
||||
2847146354,
|
||||
2847146355,
|
||||
2847146356,
|
||||
2847146357
|
||||
]
|
||||
}
|
||||
3773
tests/AcDream.Core.Tests/Fixtures/flap-doorway/0xA9B40171.json
Normal file
3773
tests/AcDream.Core.Tests/Fixtures/flap-doorway/0xA9B40171.json
Normal file
File diff suppressed because it is too large
Load diff
1963
tests/AcDream.Core.Tests/Fixtures/flap-doorway/0xA9B40172.json
Normal file
1963
tests/AcDream.Core.Tests/Fixtures/flap-doorway/0xA9B40172.json
Normal file
File diff suppressed because it is too large
Load diff
413
tests/AcDream.Core.Tests/Fixtures/flap-doorway/0xA9B40173.json
Normal file
413
tests/AcDream.Core.Tests/Fixtures/flap-doorway/0xA9B40173.json
Normal file
|
|
@ -0,0 +1,413 @@
|
|||
{
|
||||
"CellId": 2847146355,
|
||||
"WorldTransform": {
|
||||
"M11": -1,
|
||||
"M12": 8.74228E-08,
|
||||
"M13": 0,
|
||||
"M14": 0,
|
||||
"M21": -8.74228E-08,
|
||||
"M22": -1,
|
||||
"M23": 0,
|
||||
"M24": 0,
|
||||
"M31": 0,
|
||||
"M32": 0,
|
||||
"M33": 1,
|
||||
"M34": 0,
|
||||
"M41": 161.929,
|
||||
"M42": 7.50315,
|
||||
"M43": 94,
|
||||
"M44": 1
|
||||
},
|
||||
"InverseWorldTransform": {
|
||||
"M11": -1,
|
||||
"M12": -8.74228E-08,
|
||||
"M13": 0,
|
||||
"M14": -0,
|
||||
"M21": 8.74228E-08,
|
||||
"M22": -1,
|
||||
"M23": 0,
|
||||
"M24": 0,
|
||||
"M31": 0,
|
||||
"M32": 0,
|
||||
"M33": 1,
|
||||
"M34": -0,
|
||||
"M41": 161.929,
|
||||
"M42": 7.5031643,
|
||||
"M43": -94,
|
||||
"M44": 1
|
||||
},
|
||||
"ResolvedPolygons": [
|
||||
{
|
||||
"Id": 0,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": 5.9604556E-08,
|
||||
"Y": 0,
|
||||
"Z": 1
|
||||
},
|
||||
"D": -2.3245777E-07
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 3.9,
|
||||
"Y": 0.0526863,
|
||||
"Z": 0
|
||||
},
|
||||
{
|
||||
"X": 3.9,
|
||||
"Y": -1.85189,
|
||||
"Z": 0
|
||||
},
|
||||
{
|
||||
"X": 4.1,
|
||||
"Y": -1.85189,
|
||||
"Z": -1.19209E-08
|
||||
},
|
||||
{
|
||||
"X": 4.1,
|
||||
"Y": 0.0526863,
|
||||
"Z": -1.19209E-08
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 1,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": -7.54372E-07,
|
||||
"Y": -1,
|
||||
"Z": -6.0349706E-08
|
||||
},
|
||||
"D": 0.052689318
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 4.1,
|
||||
"Y": 0.052686,
|
||||
"Z": 2.5
|
||||
},
|
||||
{
|
||||
"X": 3.9,
|
||||
"Y": 0.0526863,
|
||||
"Z": 2.5
|
||||
},
|
||||
{
|
||||
"X": 3.9,
|
||||
"Y": 0.0526863,
|
||||
"Z": 0
|
||||
},
|
||||
{
|
||||
"X": 4.1,
|
||||
"Y": 0.0526863,
|
||||
"Z": -1.19209E-08
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 2,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": 0,
|
||||
"Y": 0,
|
||||
"Z": -1
|
||||
},
|
||||
"D": 2.5
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 4.1,
|
||||
"Y": -1.85189,
|
||||
"Z": 2.5
|
||||
},
|
||||
{
|
||||
"X": 3.9,
|
||||
"Y": -1.8519,
|
||||
"Z": 2.5
|
||||
},
|
||||
{
|
||||
"X": 3.9,
|
||||
"Y": 0.0526863,
|
||||
"Z": 2.5
|
||||
},
|
||||
{
|
||||
"X": 4.1,
|
||||
"Y": 0.052686,
|
||||
"Z": 2.5
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 3,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": -2.5033974E-05,
|
||||
"Y": 1,
|
||||
"Z": 2.002716E-06
|
||||
},
|
||||
"D": 1.8519901
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 3.9,
|
||||
"Y": -1.85189,
|
||||
"Z": 0
|
||||
},
|
||||
{
|
||||
"X": 3.9,
|
||||
"Y": -1.8519,
|
||||
"Z": 2.5
|
||||
},
|
||||
{
|
||||
"X": 4.1,
|
||||
"Y": -1.85189,
|
||||
"Z": 2.5
|
||||
},
|
||||
{
|
||||
"X": 4.1,
|
||||
"Y": -1.85189,
|
||||
"Z": -1.19209E-08
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"PortalPolygons": [
|
||||
{
|
||||
"Id": 0,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": 0,
|
||||
"Y": 0,
|
||||
"Z": -1
|
||||
},
|
||||
"D": 2.5
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 4.1,
|
||||
"Y": -1.85189,
|
||||
"Z": 2.5
|
||||
},
|
||||
{
|
||||
"X": 3.9,
|
||||
"Y": -1.8519,
|
||||
"Z": 2.5
|
||||
},
|
||||
{
|
||||
"X": 3.9,
|
||||
"Y": 0.0526863,
|
||||
"Z": 2.5
|
||||
},
|
||||
{
|
||||
"X": 4.1,
|
||||
"Y": 0.052686,
|
||||
"Z": 2.5
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 1,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": -2.5033974E-05,
|
||||
"Y": 1,
|
||||
"Z": 2.002716E-06
|
||||
},
|
||||
"D": 1.8519901
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 3.9,
|
||||
"Y": -1.85189,
|
||||
"Z": 0
|
||||
},
|
||||
{
|
||||
"X": 3.9,
|
||||
"Y": -1.8519,
|
||||
"Z": 2.5
|
||||
},
|
||||
{
|
||||
"X": 4.1,
|
||||
"Y": -1.85189,
|
||||
"Z": 2.5
|
||||
},
|
||||
{
|
||||
"X": 4.1,
|
||||
"Y": -1.85189,
|
||||
"Z": -1.19209E-08
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 2,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": 5.9604556E-08,
|
||||
"Y": 0,
|
||||
"Z": 1
|
||||
},
|
||||
"D": -2.3245777E-07
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 3.9,
|
||||
"Y": 0.0526863,
|
||||
"Z": 0
|
||||
},
|
||||
{
|
||||
"X": 3.9,
|
||||
"Y": -1.85189,
|
||||
"Z": 0
|
||||
},
|
||||
{
|
||||
"X": 4.1,
|
||||
"Y": -1.85189,
|
||||
"Z": -1.19209E-08
|
||||
},
|
||||
{
|
||||
"X": 4.1,
|
||||
"Y": 0.0526863,
|
||||
"Z": -1.19209E-08
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 3,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": -7.54372E-07,
|
||||
"Y": -1,
|
||||
"Z": -6.0349706E-08
|
||||
},
|
||||
"D": 0.052689318
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 4.1,
|
||||
"Y": 0.052686,
|
||||
"Z": 2.5
|
||||
},
|
||||
{
|
||||
"X": 3.9,
|
||||
"Y": 0.0526863,
|
||||
"Z": 2.5
|
||||
},
|
||||
{
|
||||
"X": 3.9,
|
||||
"Y": 0.0526863,
|
||||
"Z": 0
|
||||
},
|
||||
{
|
||||
"X": 4.1,
|
||||
"Y": 0.0526863,
|
||||
"Z": -1.19209E-08
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 4,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": -1,
|
||||
"Y": 0,
|
||||
"Z": 0
|
||||
},
|
||||
"D": 4.1
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 4.1,
|
||||
"Y": 0.052686,
|
||||
"Z": 2.5
|
||||
},
|
||||
{
|
||||
"X": 4.1,
|
||||
"Y": 0.0526863,
|
||||
"Z": -1.19209E-08
|
||||
},
|
||||
{
|
||||
"X": 4.1,
|
||||
"Y": -1.85189,
|
||||
"Z": -1.19209E-08
|
||||
},
|
||||
{
|
||||
"X": 4.1,
|
||||
"Y": -1.85189,
|
||||
"Z": 2.5
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 5,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": 1,
|
||||
"Y": 0,
|
||||
"Z": 0
|
||||
},
|
||||
"D": -3.9
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 3.9,
|
||||
"Y": -1.8519,
|
||||
"Z": 2.5
|
||||
},
|
||||
{
|
||||
"X": 3.9,
|
||||
"Y": -1.85189,
|
||||
"Z": 0
|
||||
},
|
||||
{
|
||||
"X": 3.9,
|
||||
"Y": 0.0526863,
|
||||
"Z": 0
|
||||
},
|
||||
{
|
||||
"X": 3.9,
|
||||
"Y": 0.0526863,
|
||||
"Z": 2.5
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Portals": [
|
||||
{
|
||||
"OtherCellId": 369,
|
||||
"PolygonId": 4,
|
||||
"Flags": 3
|
||||
},
|
||||
{
|
||||
"OtherCellId": 370,
|
||||
"PolygonId": 5,
|
||||
"Flags": 3
|
||||
}
|
||||
],
|
||||
"VisibleCellIds": [
|
||||
2847146351,
|
||||
2847146352,
|
||||
2847146353,
|
||||
2847146354,
|
||||
2847146356,
|
||||
2847146357
|
||||
]
|
||||
}
|
||||
583
tests/AcDream.Core.Tests/Fixtures/flap-doorway/0xA9B40174.json
Normal file
583
tests/AcDream.Core.Tests/Fixtures/flap-doorway/0xA9B40174.json
Normal file
|
|
@ -0,0 +1,583 @@
|
|||
{
|
||||
"CellId": 2847146356,
|
||||
"WorldTransform": {
|
||||
"M11": -1,
|
||||
"M12": 8.74228E-08,
|
||||
"M13": 0,
|
||||
"M14": 0,
|
||||
"M21": -8.74228E-08,
|
||||
"M22": -1,
|
||||
"M23": 0,
|
||||
"M24": 0,
|
||||
"M31": 0,
|
||||
"M32": 0,
|
||||
"M33": 1,
|
||||
"M34": 0,
|
||||
"M41": 161.929,
|
||||
"M42": 7.50315,
|
||||
"M43": 94,
|
||||
"M44": 1
|
||||
},
|
||||
"InverseWorldTransform": {
|
||||
"M11": -1,
|
||||
"M12": -8.74228E-08,
|
||||
"M13": 0,
|
||||
"M14": -0,
|
||||
"M21": 8.74228E-08,
|
||||
"M22": -1,
|
||||
"M23": 0,
|
||||
"M24": 0,
|
||||
"M31": 0,
|
||||
"M32": 0,
|
||||
"M33": 1,
|
||||
"M34": -0,
|
||||
"M41": 161.929,
|
||||
"M42": 7.5031643,
|
||||
"M43": -94,
|
||||
"M44": 1
|
||||
},
|
||||
"ResolvedPolygons": [
|
||||
{
|
||||
"Id": 0,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": 0,
|
||||
"Y": 0,
|
||||
"Z": 1
|
||||
},
|
||||
"D": 3.999
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 9,
|
||||
"Y": -2.85,
|
||||
"Z": -3.999
|
||||
},
|
||||
{
|
||||
"X": 9,
|
||||
"Y": 2.98,
|
||||
"Z": -3.999
|
||||
},
|
||||
{
|
||||
"X": -2.664,
|
||||
"Y": 2.98,
|
||||
"Z": -3.999
|
||||
},
|
||||
{
|
||||
"X": -2.664,
|
||||
"Y": -2.85,
|
||||
"Z": -3.999
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 1,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": -1,
|
||||
"Y": 0,
|
||||
"Z": 0
|
||||
},
|
||||
"D": 9
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 9,
|
||||
"Y": -2.85,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": 9,
|
||||
"Y": 2.98,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": 9,
|
||||
"Y": 2.98,
|
||||
"Z": -3.999
|
||||
},
|
||||
{
|
||||
"X": 9,
|
||||
"Y": -2.85,
|
||||
"Z": -3.999
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 2,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": 0,
|
||||
"Y": 0,
|
||||
"Z": -1
|
||||
},
|
||||
"D": -0.364
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 9,
|
||||
"Y": 2.98,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": 9,
|
||||
"Y": 1.15,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": 7,
|
||||
"Y": 1.15,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": -2.664,
|
||||
"Y": 2.98,
|
||||
"Z": -0.364
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 3,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": 0,
|
||||
"Y": -1,
|
||||
"Z": 0
|
||||
},
|
||||
"D": 2.98
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 9,
|
||||
"Y": 2.98,
|
||||
"Z": -3.999
|
||||
},
|
||||
{
|
||||
"X": 9,
|
||||
"Y": 2.98,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": -2.664,
|
||||
"Y": 2.98,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": -2.664,
|
||||
"Y": 2.98,
|
||||
"Z": -3.999
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 4,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": 0,
|
||||
"Y": 0,
|
||||
"Z": -1
|
||||
},
|
||||
"D": -0.364
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 7,
|
||||
"Y": 1.15,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": 7,
|
||||
"Y": -2.85,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": -2.664,
|
||||
"Y": -2.85,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": -2.664,
|
||||
"Y": 2.98,
|
||||
"Z": -0.364
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 5,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": 0,
|
||||
"Y": 1,
|
||||
"Z": 0
|
||||
},
|
||||
"D": 2.85
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": -2.664,
|
||||
"Y": -2.85,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": 9,
|
||||
"Y": -2.85,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": 9,
|
||||
"Y": -2.85,
|
||||
"Z": -3.999
|
||||
},
|
||||
{
|
||||
"X": -2.664,
|
||||
"Y": -2.85,
|
||||
"Z": -3.999
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 6,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": 1,
|
||||
"Y": 0,
|
||||
"Z": 0
|
||||
},
|
||||
"D": 2.664
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": -2.664,
|
||||
"Y": 2.98,
|
||||
"Z": -3.999
|
||||
},
|
||||
{
|
||||
"X": -2.664,
|
||||
"Y": 2.98,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": -2.664,
|
||||
"Y": -2.85,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": -2.664,
|
||||
"Y": -2.85,
|
||||
"Z": -3.999
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"PortalPolygons": [
|
||||
{
|
||||
"Id": 0,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": 0,
|
||||
"Y": 0,
|
||||
"Z": 1
|
||||
},
|
||||
"D": 3.999
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 9,
|
||||
"Y": -2.85,
|
||||
"Z": -3.999
|
||||
},
|
||||
{
|
||||
"X": 9,
|
||||
"Y": 2.98,
|
||||
"Z": -3.999
|
||||
},
|
||||
{
|
||||
"X": -2.664,
|
||||
"Y": 2.98,
|
||||
"Z": -3.999
|
||||
},
|
||||
{
|
||||
"X": -2.664,
|
||||
"Y": -2.85,
|
||||
"Z": -3.999
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 1,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": 0,
|
||||
"Y": 1,
|
||||
"Z": 0
|
||||
},
|
||||
"D": 2.85
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": -2.664,
|
||||
"Y": -2.85,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": 9,
|
||||
"Y": -2.85,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": 9,
|
||||
"Y": -2.85,
|
||||
"Z": -3.999
|
||||
},
|
||||
{
|
||||
"X": -2.664,
|
||||
"Y": -2.85,
|
||||
"Z": -3.999
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 2,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": -1,
|
||||
"Y": 0,
|
||||
"Z": 0
|
||||
},
|
||||
"D": 9
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 9,
|
||||
"Y": -2.85,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": 9,
|
||||
"Y": 2.98,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": 9,
|
||||
"Y": 2.98,
|
||||
"Z": -3.999
|
||||
},
|
||||
{
|
||||
"X": 9,
|
||||
"Y": -2.85,
|
||||
"Z": -3.999
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 3,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": 0,
|
||||
"Y": -1,
|
||||
"Z": 0
|
||||
},
|
||||
"D": 2.98
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 9,
|
||||
"Y": 2.98,
|
||||
"Z": -3.999
|
||||
},
|
||||
{
|
||||
"X": 9,
|
||||
"Y": 2.98,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": -2.664,
|
||||
"Y": 2.98,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": -2.664,
|
||||
"Y": 2.98,
|
||||
"Z": -3.999
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 4,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": 1,
|
||||
"Y": 0,
|
||||
"Z": 0
|
||||
},
|
||||
"D": 2.664
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": -2.664,
|
||||
"Y": 2.98,
|
||||
"Z": -3.999
|
||||
},
|
||||
{
|
||||
"X": -2.664,
|
||||
"Y": 2.98,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": -2.664,
|
||||
"Y": -2.85,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": -2.664,
|
||||
"Y": -2.85,
|
||||
"Z": -3.999
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 5,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": 0,
|
||||
"Y": 0,
|
||||
"Z": -1
|
||||
},
|
||||
"D": -0.364
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 9,
|
||||
"Y": 2.98,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": 9,
|
||||
"Y": 1.15,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": 7,
|
||||
"Y": 1.15,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": -2.664,
|
||||
"Y": 2.98,
|
||||
"Z": -0.364
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 6,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": 0,
|
||||
"Y": 0,
|
||||
"Z": -1
|
||||
},
|
||||
"D": -0.364
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 7,
|
||||
"Y": 1.15,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": 7,
|
||||
"Y": -2.85,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": -2.664,
|
||||
"Y": -2.85,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": -2.664,
|
||||
"Y": 2.98,
|
||||
"Z": -0.364
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 7,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": 0,
|
||||
"Y": 0,
|
||||
"Z": 1
|
||||
},
|
||||
"D": 0.364
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 7,
|
||||
"Y": 1.15,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": 7,
|
||||
"Y": -2.85,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": 9,
|
||||
"Y": -2.85,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": 9,
|
||||
"Y": 1.15,
|
||||
"Z": -0.364
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Portals": [
|
||||
{
|
||||
"OtherCellId": 373,
|
||||
"PolygonId": 7,
|
||||
"Flags": 1
|
||||
}
|
||||
],
|
||||
"VisibleCellIds": [
|
||||
2847146351,
|
||||
2847146352,
|
||||
2847146353,
|
||||
2847146354,
|
||||
2847146355,
|
||||
2847146357
|
||||
]
|
||||
}
|
||||
413
tests/AcDream.Core.Tests/Fixtures/flap-doorway/0xA9B40175.json
Normal file
413
tests/AcDream.Core.Tests/Fixtures/flap-doorway/0xA9B40175.json
Normal file
|
|
@ -0,0 +1,413 @@
|
|||
{
|
||||
"CellId": 2847146357,
|
||||
"WorldTransform": {
|
||||
"M11": -1,
|
||||
"M12": 8.74228E-08,
|
||||
"M13": 0,
|
||||
"M14": 0,
|
||||
"M21": -8.74228E-08,
|
||||
"M22": -1,
|
||||
"M23": 0,
|
||||
"M24": 0,
|
||||
"M31": 0,
|
||||
"M32": 0,
|
||||
"M33": 1,
|
||||
"M34": 0,
|
||||
"M41": 161.929,
|
||||
"M42": 7.50315,
|
||||
"M43": 94,
|
||||
"M44": 1
|
||||
},
|
||||
"InverseWorldTransform": {
|
||||
"M11": -1,
|
||||
"M12": -8.74228E-08,
|
||||
"M13": 0,
|
||||
"M14": -0,
|
||||
"M21": 8.74228E-08,
|
||||
"M22": -1,
|
||||
"M23": 0,
|
||||
"M24": 0,
|
||||
"M31": 0,
|
||||
"M32": 0,
|
||||
"M33": 1,
|
||||
"M34": -0,
|
||||
"M41": 161.929,
|
||||
"M42": 7.5031643,
|
||||
"M43": -94,
|
||||
"M44": 1
|
||||
},
|
||||
"ResolvedPolygons": [
|
||||
{
|
||||
"Id": 0,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": 0,
|
||||
"Y": -1,
|
||||
"Z": 0
|
||||
},
|
||||
"D": 1.15
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 9,
|
||||
"Y": 1.15,
|
||||
"Z": 0
|
||||
},
|
||||
{
|
||||
"X": 7,
|
||||
"Y": 1.15,
|
||||
"Z": -1.19209E-08
|
||||
},
|
||||
{
|
||||
"X": 7,
|
||||
"Y": 1.15,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": 9,
|
||||
"Y": 1.15,
|
||||
"Z": -0.364
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 1,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": 0,
|
||||
"Y": 1,
|
||||
"Z": 0
|
||||
},
|
||||
"D": 2.85
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 7,
|
||||
"Y": -2.85,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": 7,
|
||||
"Y": -2.85,
|
||||
"Z": -1.19209E-08
|
||||
},
|
||||
{
|
||||
"X": 9,
|
||||
"Y": -2.85,
|
||||
"Z": 1.11022E-16
|
||||
},
|
||||
{
|
||||
"X": 9,
|
||||
"Y": -2.85,
|
||||
"Z": -0.364
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 2,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": 1,
|
||||
"Y": 0,
|
||||
"Z": 0
|
||||
},
|
||||
"D": -7
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 7,
|
||||
"Y": 1.15,
|
||||
"Z": -1.19209E-08
|
||||
},
|
||||
{
|
||||
"X": 7,
|
||||
"Y": -2.85,
|
||||
"Z": -1.19209E-08
|
||||
},
|
||||
{
|
||||
"X": 7,
|
||||
"Y": -2.85,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": 7,
|
||||
"Y": 1.15,
|
||||
"Z": -0.364
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 3,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": -1,
|
||||
"Y": 0,
|
||||
"Z": 0
|
||||
},
|
||||
"D": 9
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 9,
|
||||
"Y": -2.85,
|
||||
"Z": 1.11022E-16
|
||||
},
|
||||
{
|
||||
"X": 9,
|
||||
"Y": 1.15,
|
||||
"Z": 0
|
||||
},
|
||||
{
|
||||
"X": 9,
|
||||
"Y": 1.15,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": 9,
|
||||
"Y": -2.85,
|
||||
"Z": -0.364
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"PortalPolygons": [
|
||||
{
|
||||
"Id": 0,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": 0,
|
||||
"Y": -1,
|
||||
"Z": 0
|
||||
},
|
||||
"D": 1.15
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 9,
|
||||
"Y": 1.15,
|
||||
"Z": 0
|
||||
},
|
||||
{
|
||||
"X": 7,
|
||||
"Y": 1.15,
|
||||
"Z": -1.19209E-08
|
||||
},
|
||||
{
|
||||
"X": 7,
|
||||
"Y": 1.15,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": 9,
|
||||
"Y": 1.15,
|
||||
"Z": -0.364
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 1,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": 1,
|
||||
"Y": 0,
|
||||
"Z": 0
|
||||
},
|
||||
"D": -7
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 7,
|
||||
"Y": 1.15,
|
||||
"Z": -1.19209E-08
|
||||
},
|
||||
{
|
||||
"X": 7,
|
||||
"Y": -2.85,
|
||||
"Z": -1.19209E-08
|
||||
},
|
||||
{
|
||||
"X": 7,
|
||||
"Y": -2.85,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": 7,
|
||||
"Y": 1.15,
|
||||
"Z": -0.364
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 2,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": 0,
|
||||
"Y": 1,
|
||||
"Z": 0
|
||||
},
|
||||
"D": 2.85
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 7,
|
||||
"Y": -2.85,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": 7,
|
||||
"Y": -2.85,
|
||||
"Z": -1.19209E-08
|
||||
},
|
||||
{
|
||||
"X": 9,
|
||||
"Y": -2.85,
|
||||
"Z": 1.11022E-16
|
||||
},
|
||||
{
|
||||
"X": 9,
|
||||
"Y": -2.85,
|
||||
"Z": -0.364
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 3,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": -1,
|
||||
"Y": 0,
|
||||
"Z": 0
|
||||
},
|
||||
"D": 9
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 9,
|
||||
"Y": -2.85,
|
||||
"Z": 1.11022E-16
|
||||
},
|
||||
{
|
||||
"X": 9,
|
||||
"Y": 1.15,
|
||||
"Z": 0
|
||||
},
|
||||
{
|
||||
"X": 9,
|
||||
"Y": 1.15,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": 9,
|
||||
"Y": -2.85,
|
||||
"Z": -0.364
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 4,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": 5.96045E-09,
|
||||
"Y": -1.387775E-17,
|
||||
"Z": -1
|
||||
},
|
||||
"D": -5.364405E-08
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 9,
|
||||
"Y": -2.85,
|
||||
"Z": 1.11022E-16
|
||||
},
|
||||
{
|
||||
"X": 7,
|
||||
"Y": -2.85,
|
||||
"Z": -1.19209E-08
|
||||
},
|
||||
{
|
||||
"X": 7,
|
||||
"Y": 1.15,
|
||||
"Z": -1.19209E-08
|
||||
},
|
||||
{
|
||||
"X": 9,
|
||||
"Y": 1.15,
|
||||
"Z": 0
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Id": 5,
|
||||
"NumPoints": 4,
|
||||
"SidesType": 0,
|
||||
"Plane": {
|
||||
"Normal": {
|
||||
"X": 0,
|
||||
"Y": 0,
|
||||
"Z": 1
|
||||
},
|
||||
"D": 0.364
|
||||
},
|
||||
"Vertices": [
|
||||
{
|
||||
"X": 7,
|
||||
"Y": 1.15,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": 7,
|
||||
"Y": -2.85,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": 9,
|
||||
"Y": -2.85,
|
||||
"Z": -0.364
|
||||
},
|
||||
{
|
||||
"X": 9,
|
||||
"Y": 1.15,
|
||||
"Z": -0.364
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Portals": [
|
||||
{
|
||||
"OtherCellId": 369,
|
||||
"PolygonId": 4,
|
||||
"Flags": 3
|
||||
},
|
||||
{
|
||||
"OtherCellId": 372,
|
||||
"PolygonId": 5,
|
||||
"Flags": 3
|
||||
}
|
||||
],
|
||||
"VisibleCellIds": [
|
||||
2847146351,
|
||||
2847146352,
|
||||
2847146353,
|
||||
2847146354,
|
||||
2847146355,
|
||||
2847146356
|
||||
]
|
||||
}
|
||||
|
|
@ -34,6 +34,97 @@ public class PlayerMovementControllerTests
|
|||
Assert.Equal(96f, result.Position.Y, precision: 1);
|
||||
}
|
||||
|
||||
// ── Indoor-flap root cause: resting-body bit-stability ────────────────────
|
||||
//
|
||||
// The indoor render "flap" (textures battling at the cottage doorway) is
|
||||
// portal-flood membership instability. PortalVisibilityBuilder.Build is a
|
||||
// proven-deterministic pure function, so the membership can only flip if its
|
||||
// INPUT (the camera eye, derived from the player RenderPosition) varies.
|
||||
// Live 6-dp capture (pvinput.log:54) shows the player RenderPosition carries
|
||||
// a perpetual ~1-ULP flicker at rest (Z 94.000000 <-> 93.999992 — exactly one
|
||||
// float mantissa step). ComputeRenderPosition is Vector3.Lerp(_prevPhysicsPos,
|
||||
// _currPhysicsPos, alpha), and Lerp(a, a, t) == a exactly, so a jittering
|
||||
// RenderPosition at rest means the physics body's resting Position is NOT
|
||||
// bit-stable between ticks. Retail's authoritative local position is bit-stable
|
||||
// at rest (validate_transition -> kill_velocity on every grounded contact), so
|
||||
// retail never flaps.
|
||||
//
|
||||
// This test pins the physics-side invariant: a grounded body with no input
|
||||
// must hold a byte-identical position across many frames. It PASSES — which
|
||||
// is itself the evidence: the physics resting position is bit-stable, so the
|
||||
// doorway flap is NOT a physics-rest jitter. See
|
||||
// docs/research/2026-06-08-flap-physics-diagnosis-REFUTED-its-render-membership.md
|
||||
// (the flap is render-side portal-flood membership instability at the grazing
|
||||
// doorway portal under a sweeping camera eye). Kept as a regression guard.
|
||||
[Fact]
|
||||
public void Update_AtRestNoInput_RenderPositionBitStableAcrossManyFrames()
|
||||
{
|
||||
var engine = MakeFlatEngine();
|
||||
var controller = new PlayerMovementController(engine);
|
||||
var rest = new Vector3(96f, 96f, 50f);
|
||||
controller.SetPosition(rest, 0x0001);
|
||||
|
||||
// Settle one frame so the resolver establishes its rest state, then
|
||||
// capture the baseline the body must hold.
|
||||
var settled = controller.Update(1f / 60f, new MovementInput());
|
||||
Vector3 baselineRender = settled.RenderPosition;
|
||||
Vector3 baselinePhysics = settled.Position;
|
||||
|
||||
// Hold still for ~10 s of 60 Hz frames (crosses MinQuantum every ~2
|
||||
// frames, so the 30 Hz physics tick fires throughout — same cadence as
|
||||
// live). Any deviation, even one ULP, is the flap's root cause.
|
||||
float maxRenderDev = 0f;
|
||||
float maxPhysicsDev = 0f;
|
||||
for (int i = 0; i < 600; i++)
|
||||
{
|
||||
var r = controller.Update(1f / 60f, new MovementInput());
|
||||
maxRenderDev = MathF.Max(maxRenderDev, (r.RenderPosition - baselineRender).Length());
|
||||
maxPhysicsDev = MathF.Max(maxPhysicsDev, (r.Position - baselinePhysics).Length());
|
||||
}
|
||||
|
||||
Assert.True(
|
||||
maxRenderDev == 0f && maxPhysicsDev == 0f,
|
||||
$"resting body drifted: render={maxRenderDev * 1e6f:F3} µm, " +
|
||||
$"physics={maxPhysicsDev * 1e6f:F3} µm; expected byte-identical rest");
|
||||
}
|
||||
|
||||
// After walking then releasing input, the body must SETTLE to a
|
||||
// byte-identical resting position — not keep blipping a residual velocity.
|
||||
// This models the live flap: the player walks to the cottage doorway and
|
||||
// stops, and the eye then carries a ~1-ULP jitter that flips portal-flood
|
||||
// membership. Flat-terrain variant: if even this drifts, the residual-after-
|
||||
// motion path is the root and it is not indoor-specific.
|
||||
[Fact]
|
||||
public void Update_WalkThenStop_SettlesToBitStableRest()
|
||||
{
|
||||
var engine = MakeFlatEngine();
|
||||
var controller = new PlayerMovementController(engine);
|
||||
controller.SetPosition(new Vector3(96f, 96f, 50f), 0x0001);
|
||||
controller.Yaw = 0f;
|
||||
|
||||
// Walk forward ~0.5 s, then release.
|
||||
for (int i = 0; i < 30; i++)
|
||||
controller.Update(1f / 60f, new MovementInput(Forward: true));
|
||||
// Let velocity decay / state settle.
|
||||
for (int i = 0; i < 30; i++)
|
||||
controller.Update(1f / 60f, new MovementInput());
|
||||
|
||||
var settled = controller.Update(1f / 60f, new MovementInput());
|
||||
Vector3 basePos = settled.Position;
|
||||
Vector3 baseRender = settled.RenderPosition;
|
||||
|
||||
float maxPos = 0f, maxRender = 0f;
|
||||
for (int i = 0; i < 600; i++)
|
||||
{
|
||||
var r = controller.Update(1f / 60f, new MovementInput());
|
||||
maxPos = MathF.Max(maxPos, (r.Position - basePos).Length());
|
||||
maxRender = MathF.Max(maxRender, (r.RenderPosition - baseRender).Length());
|
||||
}
|
||||
|
||||
Assert.True(maxPos == 0f && maxRender == 0f,
|
||||
$"post-walk rest drifted: pos={maxPos * 1e6f:F3} µm, render={maxRender * 1e6f:F3} µm");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Update_ForwardInput_MovesInFacingDirection()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using AcDream.App.Input;
|
||||
using AcDream.Core.Physics;
|
||||
using DatReaderWriter.Enums;
|
||||
using DatReaderWriter.Types;
|
||||
|
|
@ -136,6 +137,137 @@ public class CellarUpTrajectoryReplayTests : IDisposable
|
|||
// Tests
|
||||
// ───────────────────────────────────────────────────────────────
|
||||
|
||||
/// <summary>
|
||||
/// Indoor-flap root cause (2026-06-08). A body resting on the cellar
|
||||
/// floor with ZERO requested motion must hold a byte-identical position
|
||||
/// across many ticks — retail's authoritative local position is bit-stable
|
||||
/// at rest (validate_transition → kill_velocity + SetWalkable on every
|
||||
/// grounded contact, decomp :272567/:274467).
|
||||
///
|
||||
/// <para>
|
||||
/// The indoor render "flap" (textures battling at the cottage doorway) is
|
||||
/// portal-flood membership instability. PortalVisibilityBuilder.Build is a
|
||||
/// proven-deterministic pure function, so the membership can only flip if its
|
||||
/// INPUT (the camera eye, from the player RenderPosition) varies.
|
||||
/// RenderPosition = Lerp(_prevPhysicsPos, _currPhysicsPos), and Lerp(a,a,t)==a,
|
||||
/// so a jittering eye at rest means the physics body's resting Position is not
|
||||
/// bit-stable. Flat LandCell terrain rest IS bit-stable
|
||||
/// (<see cref="AcDream.Core.Tests.Input.PlayerMovementControllerTests"/>.
|
||||
/// Update_AtRestNoInput_RenderPositionBitStableAcrossManyFrames passes); the
|
||||
/// instability is the INDOOR path — the floor-touch is classified
|
||||
/// walkable=False (no walkable-polygon anchor), so each tick re-fires a
|
||||
/// step-down probe whose re-found Z is not bit-stable.
|
||||
/// </para>
|
||||
///
|
||||
/// PASSES — the indoor resting body is bit-stable even with the
|
||||
/// grounded/cp=none contradictory state present. This is evidence (with the
|
||||
/// flat-terrain variant) that the doorway flap is NOT a physics-rest jitter;
|
||||
/// it is render-side portal-flood membership instability under a sweeping eye.
|
||||
/// See docs/research/2026-06-08-flap-physics-diagnosis-REFUTED-its-render-membership.md.
|
||||
/// The diagnostic log (on any future regression) names the failing per-tick
|
||||
/// condition. Kept as a regression guard.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void IndoorCellarFloor_AtRestZeroOffset_BodyPositionBitStable()
|
||||
{
|
||||
var (engine, _) = BuildEngineWithCellarFixtures();
|
||||
|
||||
// Body seeded exactly at its natural resting pose on the cellar floor,
|
||||
// WITH the walkable-polygon + contact-plane anchor (BuildInitialBody) —
|
||||
// i.e. the most-favourable starting state. If even this drifts, the rest
|
||||
// path fails to PERSIST the anchor.
|
||||
var body = BuildInitialBody();
|
||||
var rest = body.Position;
|
||||
uint cell = CellarId;
|
||||
bool grounded = true;
|
||||
|
||||
var log = new List<string>();
|
||||
float maxDrift = 0f;
|
||||
for (int tick = 1; tick <= 200; tick++)
|
||||
{
|
||||
// ZERO requested motion: currentPos == targetPos == rest pose.
|
||||
var result = engine.ResolveWithTransition(
|
||||
currentPos: body.Position,
|
||||
targetPos: body.Position,
|
||||
cellId: cell,
|
||||
sphereRadius: SphereRadius,
|
||||
sphereHeight: SphereHeight,
|
||||
stepUpHeight: StepUpHeight,
|
||||
stepDownHeight: StepDownHeight,
|
||||
isOnGround: grounded,
|
||||
body: body,
|
||||
moverFlags: ObjectInfoState.IsPlayer | ObjectInfoState.EdgeSlide,
|
||||
movingEntityId: 0);
|
||||
|
||||
body.Position = result.Position;
|
||||
cell = result.CellId;
|
||||
grounded = result.IsOnGround;
|
||||
|
||||
float drift = (body.Position - rest).Length();
|
||||
maxDrift = MathF.Max(maxDrift, drift);
|
||||
|
||||
if (tick <= 6 || drift > 0f)
|
||||
{
|
||||
log.Add(string.Format(System.Globalization.CultureInfo.InvariantCulture,
|
||||
"tick{0,3}: pos=({1:F7},{2:F7},{3:F7}) drift={4:F3}µm grounded={5} " +
|
||||
"walkable={6} cpV={7} ts=0x{8:X}",
|
||||
tick, body.Position.X, body.Position.Y, body.Position.Z,
|
||||
drift * 1e6f, grounded, body.WalkablePolygonValid,
|
||||
body.ContactPlaneValid, (uint)body.TransientState));
|
||||
}
|
||||
}
|
||||
|
||||
Assert.True(maxDrift == 0f,
|
||||
$"cellar-floor rest drifted {maxDrift * 1e6f:F3} µm (expected byte-identical):\n "
|
||||
+ string.Join("\n ", log.Take(24)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indoor-flap investigation (2026-06-08) — the FULL production loop. Drives
|
||||
/// <see cref="PlayerMovementController"/> (integration + flag logic + velocity,
|
||||
/// not just the resolver) on the indoor cellar engine with NO input. PASSES —
|
||||
/// the RenderPosition the camera reads is byte-identical at rest, confirming
|
||||
/// the flap is not produced by the indoor controller rest loop. Kept as a
|
||||
/// regression guard. See
|
||||
/// docs/research/2026-06-08-flap-physics-diagnosis-REFUTED-its-render-membership.md.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void IndoorCell_FullController_AtRestNoInput_RenderPositionBitStable()
|
||||
{
|
||||
var (engine, _) = BuildEngineWithCellarFixtures();
|
||||
var controller = new PlayerMovementController(engine);
|
||||
controller.SetPosition(InitialSphereWorld, CellarId);
|
||||
|
||||
var settled = controller.Update(1f / 60f, new MovementInput());
|
||||
var basePos = settled.Position;
|
||||
var baseRender = settled.RenderPosition;
|
||||
|
||||
var log = new List<string>();
|
||||
float maxPos = 0f, maxRender = 0f;
|
||||
for (int i = 1; i <= 600; i++)
|
||||
{
|
||||
var r = controller.Update(1f / 60f, new MovementInput());
|
||||
float dp = (r.Position - basePos).Length();
|
||||
float dr = (r.RenderPosition - baseRender).Length();
|
||||
maxPos = MathF.Max(maxPos, dp);
|
||||
maxRender = MathF.Max(maxRender, dr);
|
||||
if (i <= 4 || dp > 0f || dr > 0f)
|
||||
{
|
||||
log.Add(string.Format(System.Globalization.CultureInfo.InvariantCulture,
|
||||
"f{0,3}: pos=({1:F7},{2:F7},{3:F7}) render=({4:F7},{5:F7},{6:F7}) " +
|
||||
"grounded={7} cell=0x{8:X8}",
|
||||
i, r.Position.X, r.Position.Y, r.Position.Z,
|
||||
r.RenderPosition.X, r.RenderPosition.Y, r.RenderPosition.Z,
|
||||
r.IsOnGround, r.CellId));
|
||||
}
|
||||
}
|
||||
|
||||
Assert.True(maxPos == 0f && maxRender == 0f,
|
||||
$"indoor controller rest drifted: pos={maxPos * 1e6f:F3} µm, "
|
||||
+ $"render={maxRender * 1e6f:F3} µm (expected byte-identical):\n "
|
||||
+ string.Join("\n ", log.Take(24)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Confirms the harness compiles, the engine runs the simulation,
|
||||
/// and a trajectory comes back with the expected number of points.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue