feat(streaming): shadow-publish flat collision assets
Carry one immutable prepared collision closure with each accepted near-tier generation and install graph plus flat views through the same retained publication receipt. Apply the same strict package-only rule to live entities, add exact sampled graph-authoritative comparison artifacts and lifecycle counters, and prove cancellation, demotion, rehydrate, revisit, teardown, reconnect, and the nine-stop route with 14,064 zero-mismatch samples. Co-authored-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
parent
f7ff9f4eea
commit
d9446030e6
32 changed files with 2777 additions and 92 deletions
|
|
@ -23,49 +23,172 @@ internal static class CollisionTraversal
|
|||
PhysicsDataCache cache,
|
||||
CellPhysics cell)
|
||||
{
|
||||
if (cache.CollisionTraversalMode == CollisionTraversalMode.Flat)
|
||||
if (UseFlat(cache))
|
||||
{
|
||||
FlatCellContainmentBsp flat = cell.FlatContainmentBsp ??
|
||||
throw MissingFlat("cell containment");
|
||||
return flat.RootIndex >= 0;
|
||||
}
|
||||
|
||||
return cell.CellBSP?.Root is not null;
|
||||
CollisionShadowVerifier? shadow = cache.CollisionShadow;
|
||||
if (shadow is null || !shadow.TrySample(out long sample))
|
||||
return cell.CellBSP?.Root is not null;
|
||||
|
||||
bool flatResult = false;
|
||||
Exception? flatFault = null;
|
||||
shadow.BeginFlatPass();
|
||||
try
|
||||
{
|
||||
flatResult = (cell.FlatContainmentBsp ??
|
||||
throw MissingFlat("cell containment")).RootIndex >= 0;
|
||||
}
|
||||
catch (Exception fault)
|
||||
{
|
||||
flatFault = fault;
|
||||
}
|
||||
finally
|
||||
{
|
||||
shadow.EndFlatPass();
|
||||
}
|
||||
|
||||
bool graphResult = cell.CellBSP?.Root is not null;
|
||||
if (flatFault is null)
|
||||
{
|
||||
shadow.RecordBoolean(
|
||||
sample,
|
||||
"HasCellContainment",
|
||||
cell.SourceId,
|
||||
graphResult,
|
||||
flatResult,
|
||||
string.Empty);
|
||||
}
|
||||
else
|
||||
{
|
||||
shadow.RecordFault(
|
||||
sample,
|
||||
"HasCellContainment",
|
||||
cell.SourceId,
|
||||
flatFault,
|
||||
string.Empty);
|
||||
}
|
||||
return graphResult;
|
||||
}
|
||||
|
||||
internal static bool HasPhysics(
|
||||
PhysicsDataCache cache,
|
||||
CellPhysics cell)
|
||||
{
|
||||
if (cache.CollisionTraversalMode == CollisionTraversalMode.Flat)
|
||||
if (UseFlat(cache))
|
||||
{
|
||||
FlatPhysicsBsp flat = cell.FlatPhysicsBsp ??
|
||||
throw MissingFlat("cell physics");
|
||||
return flat.RootIndex >= 0;
|
||||
}
|
||||
|
||||
return cell.BSP?.Root is not null;
|
||||
CollisionShadowVerifier? shadow = cache.CollisionShadow;
|
||||
if (shadow is null || !shadow.TrySample(out long sample))
|
||||
return cell.BSP?.Root is not null;
|
||||
|
||||
bool flatResult = false;
|
||||
Exception? flatFault = null;
|
||||
shadow.BeginFlatPass();
|
||||
try
|
||||
{
|
||||
flatResult = (cell.FlatPhysicsBsp ??
|
||||
throw MissingFlat("cell physics")).RootIndex >= 0;
|
||||
}
|
||||
catch (Exception fault)
|
||||
{
|
||||
flatFault = fault;
|
||||
}
|
||||
finally
|
||||
{
|
||||
shadow.EndFlatPass();
|
||||
}
|
||||
|
||||
bool graphResult = cell.BSP?.Root is not null;
|
||||
if (flatFault is null)
|
||||
{
|
||||
shadow.RecordBoolean(
|
||||
sample,
|
||||
"HasCellPhysics",
|
||||
cell.SourceId,
|
||||
graphResult,
|
||||
flatResult,
|
||||
string.Empty);
|
||||
}
|
||||
else
|
||||
{
|
||||
shadow.RecordFault(
|
||||
sample,
|
||||
"HasCellPhysics",
|
||||
cell.SourceId,
|
||||
flatFault,
|
||||
string.Empty);
|
||||
}
|
||||
return graphResult;
|
||||
}
|
||||
|
||||
internal static bool HasPhysics(
|
||||
PhysicsDataCache cache,
|
||||
GfxObjPhysics gfxObject)
|
||||
{
|
||||
if (cache.CollisionTraversalMode == CollisionTraversalMode.Flat)
|
||||
if (UseFlat(cache))
|
||||
{
|
||||
FlatPhysicsBsp flat = gfxObject.FlatPhysicsBsp ??
|
||||
throw MissingFlat("GfxObj physics");
|
||||
return flat.RootIndex >= 0;
|
||||
}
|
||||
|
||||
return gfxObject.BSP.Root is not null;
|
||||
CollisionShadowVerifier? shadow = cache.CollisionShadow;
|
||||
if (shadow is null || !shadow.TrySample(out long sample))
|
||||
return gfxObject.BSP.Root is not null;
|
||||
|
||||
bool flatResult = false;
|
||||
Exception? flatFault = null;
|
||||
shadow.BeginFlatPass();
|
||||
try
|
||||
{
|
||||
flatResult = (gfxObject.FlatPhysicsBsp ??
|
||||
throw MissingFlat("GfxObj physics")).RootIndex >= 0;
|
||||
}
|
||||
catch (Exception fault)
|
||||
{
|
||||
flatFault = fault;
|
||||
}
|
||||
finally
|
||||
{
|
||||
shadow.EndFlatPass();
|
||||
}
|
||||
|
||||
bool graphResult = gfxObject.BSP.Root is not null;
|
||||
if (flatFault is null)
|
||||
{
|
||||
shadow.RecordBoolean(
|
||||
sample,
|
||||
"HasGfxObjPhysics",
|
||||
gfxObject.SourceId,
|
||||
graphResult,
|
||||
flatResult,
|
||||
string.Empty);
|
||||
}
|
||||
else
|
||||
{
|
||||
shadow.RecordFault(
|
||||
sample,
|
||||
"HasGfxObjPhysics",
|
||||
gfxObject.SourceId,
|
||||
flatFault,
|
||||
string.Empty);
|
||||
}
|
||||
return graphResult;
|
||||
}
|
||||
|
||||
internal static FlatCollisionSphere RootBoundingSphere(
|
||||
PhysicsDataCache cache,
|
||||
CellPhysics cell)
|
||||
{
|
||||
if (cache.CollisionTraversalMode == CollisionTraversalMode.Flat)
|
||||
if (UseFlat(cache))
|
||||
{
|
||||
FlatPhysicsBsp flat = cell.FlatPhysicsBsp ??
|
||||
throw MissingFlat("cell physics");
|
||||
|
|
@ -73,7 +196,39 @@ internal static class CollisionTraversal
|
|||
}
|
||||
|
||||
DatReaderWriter.Types.Sphere sphere = cell.BSP!.Root!.BoundingSphere;
|
||||
return new FlatCollisionSphere(sphere.Origin, sphere.Radius);
|
||||
var graphResult =
|
||||
new FlatCollisionSphere(sphere.Origin, sphere.Radius);
|
||||
CollisionShadowVerifier? shadow = cache.CollisionShadow;
|
||||
if (shadow is null || !shadow.TrySample(out long sample))
|
||||
return graphResult;
|
||||
|
||||
try
|
||||
{
|
||||
shadow.BeginFlatPass();
|
||||
FlatPhysicsBsp flat = cell.FlatPhysicsBsp ??
|
||||
throw MissingFlat("cell physics");
|
||||
FlatCollisionSphere flatResult =
|
||||
flat.Nodes[flat.RootIndex].BoundingSphere;
|
||||
shadow.EndFlatPass();
|
||||
shadow.RecordSphere(
|
||||
sample,
|
||||
"RootBoundingSphere",
|
||||
cell.SourceId,
|
||||
graphResult,
|
||||
flatResult);
|
||||
}
|
||||
catch (Exception fault)
|
||||
{
|
||||
if (shadow.IsFlatPass)
|
||||
shadow.EndFlatPass();
|
||||
shadow.RecordFault(
|
||||
sample,
|
||||
"RootBoundingSphere",
|
||||
cell.SourceId,
|
||||
fault,
|
||||
string.Empty);
|
||||
}
|
||||
return graphResult;
|
||||
}
|
||||
|
||||
internal static bool PointInsideCell(
|
||||
|
|
@ -81,14 +236,63 @@ internal static class CollisionTraversal
|
|||
CellPhysics cell,
|
||||
Vector3 localPoint)
|
||||
{
|
||||
if (cache.CollisionTraversalMode == CollisionTraversalMode.Flat)
|
||||
if (UseFlat(cache))
|
||||
{
|
||||
FlatCellContainmentBsp flat = cell.FlatContainmentBsp ??
|
||||
throw MissingFlat("cell containment");
|
||||
return FlatBspQuery.PointInsideCellBsp(flat, localPoint);
|
||||
}
|
||||
|
||||
return BSPQuery.PointInsideCellBsp(cell.CellBSP?.Root, localPoint);
|
||||
CollisionShadowVerifier? shadow = cache.CollisionShadow;
|
||||
if (shadow is null || !shadow.TrySample(out long sample))
|
||||
return BSPQuery.PointInsideCellBsp(
|
||||
cell.CellBSP?.Root,
|
||||
localPoint);
|
||||
|
||||
bool flatResult = false;
|
||||
Exception? flatFault = null;
|
||||
shadow.BeginFlatPass();
|
||||
try
|
||||
{
|
||||
flatResult = FlatBspQuery.PointInsideCellBsp(
|
||||
cell.FlatContainmentBsp ??
|
||||
throw MissingFlat("cell containment"),
|
||||
localPoint);
|
||||
}
|
||||
catch (Exception fault)
|
||||
{
|
||||
flatFault = fault;
|
||||
}
|
||||
finally
|
||||
{
|
||||
shadow.EndFlatPass();
|
||||
}
|
||||
bool graphResult = BSPQuery.PointInsideCellBsp(
|
||||
cell.CellBSP?.Root,
|
||||
localPoint);
|
||||
string input = CollisionShadowVerifier.FormatInput(
|
||||
localPoint,
|
||||
0f);
|
||||
if (flatFault is null)
|
||||
{
|
||||
shadow.RecordBoolean(
|
||||
sample,
|
||||
"PointInsideCell",
|
||||
cell.SourceId,
|
||||
graphResult,
|
||||
flatResult,
|
||||
input);
|
||||
}
|
||||
else
|
||||
{
|
||||
shadow.RecordFault(
|
||||
sample,
|
||||
"PointInsideCell",
|
||||
cell.SourceId,
|
||||
flatFault,
|
||||
input);
|
||||
}
|
||||
return graphResult;
|
||||
}
|
||||
|
||||
internal static bool SphereIntersectsCell(
|
||||
|
|
@ -97,7 +301,7 @@ internal static class CollisionTraversal
|
|||
Vector3 localCenter,
|
||||
float radius)
|
||||
{
|
||||
if (cache.CollisionTraversalMode == CollisionTraversalMode.Flat)
|
||||
if (UseFlat(cache))
|
||||
{
|
||||
FlatCellContainmentBsp flat = cell.FlatContainmentBsp ??
|
||||
throw MissingFlat("cell containment");
|
||||
|
|
@ -107,10 +311,61 @@ internal static class CollisionTraversal
|
|||
radius);
|
||||
}
|
||||
|
||||
return BSPQuery.SphereIntersectsCellBsp(
|
||||
CollisionShadowVerifier? shadow = cache.CollisionShadow;
|
||||
if (shadow is null || !shadow.TrySample(out long sample))
|
||||
{
|
||||
return BSPQuery.SphereIntersectsCellBsp(
|
||||
cell.CellBSP?.Root,
|
||||
localCenter,
|
||||
radius);
|
||||
}
|
||||
|
||||
bool flatResult = false;
|
||||
Exception? flatFault = null;
|
||||
shadow.BeginFlatPass();
|
||||
try
|
||||
{
|
||||
flatResult = FlatBspQuery.SphereIntersectsCellBsp(
|
||||
cell.FlatContainmentBsp ??
|
||||
throw MissingFlat("cell containment"),
|
||||
localCenter,
|
||||
radius);
|
||||
}
|
||||
catch (Exception fault)
|
||||
{
|
||||
flatFault = fault;
|
||||
}
|
||||
finally
|
||||
{
|
||||
shadow.EndFlatPass();
|
||||
}
|
||||
bool graphResult = BSPQuery.SphereIntersectsCellBsp(
|
||||
cell.CellBSP?.Root,
|
||||
localCenter,
|
||||
radius);
|
||||
string input = CollisionShadowVerifier.FormatInput(
|
||||
localCenter,
|
||||
radius);
|
||||
if (flatFault is null)
|
||||
{
|
||||
shadow.RecordBoolean(
|
||||
sample,
|
||||
"SphereIntersectsCell",
|
||||
cell.SourceId,
|
||||
graphResult,
|
||||
flatResult,
|
||||
input);
|
||||
}
|
||||
else
|
||||
{
|
||||
shadow.RecordFault(
|
||||
sample,
|
||||
"SphereIntersectsCell",
|
||||
cell.SourceId,
|
||||
flatFault,
|
||||
input);
|
||||
}
|
||||
return graphResult;
|
||||
}
|
||||
|
||||
internal static TransitionState FindCollisions(
|
||||
|
|
@ -129,7 +384,7 @@ internal static class CollisionTraversal
|
|||
PhysicsEngine? engine,
|
||||
Vector3 worldOrigin)
|
||||
{
|
||||
if (cache.CollisionTraversalMode == CollisionTraversalMode.Flat)
|
||||
if (UseFlat(cache))
|
||||
{
|
||||
FlatPhysicsBsp flat = cell.FlatPhysicsBsp ??
|
||||
throw MissingFlat("cell physics");
|
||||
|
|
@ -149,7 +404,58 @@ internal static class CollisionTraversal
|
|||
worldOrigin);
|
||||
}
|
||||
|
||||
return BSPQuery.FindCollisions(
|
||||
CollisionShadowVerifier? shadow = cache.CollisionShadow;
|
||||
if (shadow is null || !shadow.TrySample(out long sample))
|
||||
{
|
||||
return BSPQuery.FindCollisions(
|
||||
cell.BSP?.Root,
|
||||
cell.Resolved,
|
||||
transition,
|
||||
localSphereCenter,
|
||||
localSphereRadius,
|
||||
hasLocalSphere1,
|
||||
localSphere1Center,
|
||||
localSphere1Radius,
|
||||
localCurrentCenter,
|
||||
localSpaceZ,
|
||||
scale,
|
||||
localToWorld,
|
||||
engine,
|
||||
worldOrigin);
|
||||
}
|
||||
|
||||
Transition flatTransition = shadow.PrepareShadow(transition);
|
||||
TransitionState flatState = TransitionState.Invalid;
|
||||
Exception? flatFault = null;
|
||||
shadow.BeginFlatPass();
|
||||
try
|
||||
{
|
||||
flatState = FlatBspQuery.FindCollisions(
|
||||
cell.FlatPhysicsBsp ??
|
||||
throw MissingFlat("cell physics"),
|
||||
flatTransition,
|
||||
localSphereCenter,
|
||||
localSphereRadius,
|
||||
hasLocalSphere1,
|
||||
localSphere1Center,
|
||||
localSphere1Radius,
|
||||
localCurrentCenter,
|
||||
localSpaceZ,
|
||||
scale,
|
||||
localToWorld,
|
||||
engine,
|
||||
worldOrigin);
|
||||
}
|
||||
catch (Exception fault)
|
||||
{
|
||||
flatFault = fault;
|
||||
}
|
||||
finally
|
||||
{
|
||||
shadow.EndFlatPass();
|
||||
}
|
||||
|
||||
TransitionState graphState = BSPQuery.FindCollisions(
|
||||
cell.BSP?.Root,
|
||||
cell.Resolved,
|
||||
transition,
|
||||
|
|
@ -164,6 +470,39 @@ internal static class CollisionTraversal
|
|||
localToWorld,
|
||||
engine,
|
||||
worldOrigin);
|
||||
string input = CollisionShadowVerifier.FormatInput(
|
||||
localSphereCenter,
|
||||
localSphereRadius,
|
||||
hasLocalSphere1,
|
||||
localSphere1Center,
|
||||
localSphere1Radius,
|
||||
localCurrentCenter,
|
||||
localSpaceZ,
|
||||
scale,
|
||||
localToWorld,
|
||||
worldOrigin);
|
||||
if (flatFault is null)
|
||||
{
|
||||
shadow.RecordTransition(
|
||||
sample,
|
||||
"FindCellCollisions",
|
||||
cell.SourceId,
|
||||
graphState,
|
||||
flatState,
|
||||
transition,
|
||||
flatTransition,
|
||||
input);
|
||||
}
|
||||
else
|
||||
{
|
||||
shadow.RecordFault(
|
||||
sample,
|
||||
"FindCellCollisions",
|
||||
cell.SourceId,
|
||||
flatFault,
|
||||
input);
|
||||
}
|
||||
return graphState;
|
||||
}
|
||||
|
||||
internal static TransitionState FindCollisions(
|
||||
|
|
@ -182,7 +521,7 @@ internal static class CollisionTraversal
|
|||
PhysicsEngine? engine,
|
||||
Vector3 worldOrigin)
|
||||
{
|
||||
if (cache.CollisionTraversalMode == CollisionTraversalMode.Flat)
|
||||
if (UseFlat(cache))
|
||||
{
|
||||
FlatPhysicsBsp flat = gfxObject.FlatPhysicsBsp ??
|
||||
throw MissingFlat("GfxObj physics");
|
||||
|
|
@ -202,7 +541,58 @@ internal static class CollisionTraversal
|
|||
worldOrigin);
|
||||
}
|
||||
|
||||
return BSPQuery.FindCollisions(
|
||||
CollisionShadowVerifier? shadow = cache.CollisionShadow;
|
||||
if (shadow is null || !shadow.TrySample(out long sample))
|
||||
{
|
||||
return BSPQuery.FindCollisions(
|
||||
gfxObject.BSP.Root,
|
||||
gfxObject.Resolved,
|
||||
transition,
|
||||
localSphereCenter,
|
||||
localSphereRadius,
|
||||
hasLocalSphere1,
|
||||
localSphere1Center,
|
||||
localSphere1Radius,
|
||||
localCurrentCenter,
|
||||
localSpaceZ,
|
||||
scale,
|
||||
localToWorld,
|
||||
engine,
|
||||
worldOrigin);
|
||||
}
|
||||
|
||||
Transition flatTransition = shadow.PrepareShadow(transition);
|
||||
TransitionState flatState = TransitionState.Invalid;
|
||||
Exception? flatFault = null;
|
||||
shadow.BeginFlatPass();
|
||||
try
|
||||
{
|
||||
flatState = FlatBspQuery.FindCollisions(
|
||||
gfxObject.FlatPhysicsBsp ??
|
||||
throw MissingFlat("GfxObj physics"),
|
||||
flatTransition,
|
||||
localSphereCenter,
|
||||
localSphereRadius,
|
||||
hasLocalSphere1,
|
||||
localSphere1Center,
|
||||
localSphere1Radius,
|
||||
localCurrentCenter,
|
||||
localSpaceZ,
|
||||
scale,
|
||||
localToWorld,
|
||||
engine,
|
||||
worldOrigin);
|
||||
}
|
||||
catch (Exception fault)
|
||||
{
|
||||
flatFault = fault;
|
||||
}
|
||||
finally
|
||||
{
|
||||
shadow.EndFlatPass();
|
||||
}
|
||||
|
||||
TransitionState graphState = BSPQuery.FindCollisions(
|
||||
gfxObject.BSP.Root,
|
||||
gfxObject.Resolved,
|
||||
transition,
|
||||
|
|
@ -217,8 +607,45 @@ internal static class CollisionTraversal
|
|||
localToWorld,
|
||||
engine,
|
||||
worldOrigin);
|
||||
string input = CollisionShadowVerifier.FormatInput(
|
||||
localSphereCenter,
|
||||
localSphereRadius,
|
||||
hasLocalSphere1,
|
||||
localSphere1Center,
|
||||
localSphere1Radius,
|
||||
localCurrentCenter,
|
||||
localSpaceZ,
|
||||
scale,
|
||||
localToWorld,
|
||||
worldOrigin);
|
||||
if (flatFault is null)
|
||||
{
|
||||
shadow.RecordTransition(
|
||||
sample,
|
||||
"FindGfxObjCollisions",
|
||||
gfxObject.SourceId,
|
||||
graphState,
|
||||
flatState,
|
||||
transition,
|
||||
flatTransition,
|
||||
input);
|
||||
}
|
||||
else
|
||||
{
|
||||
shadow.RecordFault(
|
||||
sample,
|
||||
"FindGfxObjCollisions",
|
||||
gfxObject.SourceId,
|
||||
flatFault,
|
||||
input);
|
||||
}
|
||||
return graphState;
|
||||
}
|
||||
|
||||
private static bool UseFlat(PhysicsDataCache cache) =>
|
||||
cache.CollisionTraversalMode == CollisionTraversalMode.Flat ||
|
||||
cache.CollisionShadow?.IsFlatPass == true;
|
||||
|
||||
private static InvalidOperationException MissingFlat(string kind) =>
|
||||
new(
|
||||
$"Flat collision traversal requires a prepared {kind} asset. " +
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue