fix(physics): validate retail cell containment roots
This commit is contained in:
parent
7716c2ee89
commit
3e0f3b6206
23 changed files with 429 additions and 197 deletions
|
|
@ -7,9 +7,9 @@ namespace AcDream.Core.World.Cells;
|
|||
|
||||
/// <summary>
|
||||
/// The unified cell graph: the active, authoritative id->cell resolver and registry.
|
||||
/// Populated unconditionally from
|
||||
/// <see cref="AcDream.Core.Physics.PhysicsDataCache.CacheCellStruct"/> (including
|
||||
/// authored cells with null physics or containment roots) and consumed across
|
||||
/// Populated from validated
|
||||
/// <see cref="AcDream.Core.Physics.PhysicsDataCache.CacheCellStruct"/> payloads
|
||||
/// (a physics root is optional; a containment root is required) and consumed across
|
||||
/// the engine: <see cref="GetVisible"/> resolves any cell id, <see cref="CurrCell"/> is
|
||||
/// the player render/lighting root, <see cref="FindVisibleChildCell"/> resolves the
|
||||
/// 3rd-person camera cell, and <see cref="TryGetTerrainOrigin"/> supplies the block-local
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@ namespace AcDream.Core.World.Cells;
|
|||
public sealed class EnvCell : ObjCell
|
||||
{
|
||||
/// <summary>
|
||||
/// Cell-containment BSP (retail CellStruct.CellBSP). A present tree with a
|
||||
/// null root is universally inside; an absent test/tooling payload uses the
|
||||
/// legacy AABB fallback.
|
||||
/// Cell-containment BSP (retail CellStruct.CellBSP). Production publication
|
||||
/// requires a non-null root; prepared production uses
|
||||
/// <see cref="FlatContainmentBsp"/> instead.
|
||||
/// </summary>
|
||||
public CellBSPTree? ContainmentBsp { get; }
|
||||
|
||||
|
|
@ -38,14 +38,18 @@ public sealed class EnvCell : ObjCell
|
|||
|
||||
public override bool PointInCell(Vector3 worldPoint)
|
||||
{
|
||||
// Retail CEnvCell::point_in_cell @ 0x0052C300 returns false before
|
||||
// touching the CellStruct when this->portals is null. Installed data
|
||||
// contains real zero-portal cells, so this guard is behavior-bearing.
|
||||
if (Portals.Count == 0)
|
||||
return false;
|
||||
|
||||
var local = Vector3.Transform(worldPoint, InverseWorldTransform);
|
||||
if (FlatContainmentBsp is not null)
|
||||
if (FlatContainmentBsp is { RootIndex: >= 0 })
|
||||
return FlatBspQuery.PointInsideCellBsp(FlatContainmentBsp, local);
|
||||
if (ContainmentBsp is not null)
|
||||
if (ContainmentBsp?.Root is not null)
|
||||
return BSPQuery.PointInsideCellBsp(ContainmentBsp.Root, local); // BSPQuery.cs:1034
|
||||
return local.X >= LocalBoundsMin.X && local.X <= LocalBoundsMax.X
|
||||
&& local.Y >= LocalBoundsMin.Y && local.Y <= LocalBoundsMax.Y
|
||||
&& local.Z >= LocalBoundsMin.Z && local.Z <= LocalBoundsMax.Z;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue