feat(vfx): bind effects to live animated poses
This commit is contained in:
parent
96ddfdf175
commit
542dcfc384
41 changed files with 3246 additions and 741 deletions
|
|
@ -148,6 +148,7 @@ public sealed class LiveEntityRuntime
|
|||
private readonly Dictionary<uint, uint> _guidByLocalId = new();
|
||||
private readonly Dictionary<uint, ILiveEntityAnimationRuntime> _animationsByLocalId = new();
|
||||
private readonly Dictionary<uint, ILiveEntityRemoteMotionRuntime> _remoteMotionByGuid = new();
|
||||
private uint _rebucketingGuid;
|
||||
private uint _nextLocalEntityId;
|
||||
|
||||
public LiveEntityRuntime(
|
||||
|
|
@ -191,6 +192,12 @@ public sealed class LiveEntityRuntime
|
|||
public IReadOnlyDictionary<uint, ILiveEntityRemoteMotionRuntime> RemoteMotionRuntimes => _remoteMotionByGuid;
|
||||
public ParentAttachmentState ParentAttachments { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Raised after a materialized projection enters or leaves the currently
|
||||
/// loaded spatial view. Logical resources remain owned by the record.
|
||||
/// </summary>
|
||||
public event Action<LiveEntityRecord, bool>? ProjectionVisibilityChanged;
|
||||
|
||||
public LiveEntityRegistrationResult RegisterLiveEntity(WorldSession.EntitySpawn incoming)
|
||||
{
|
||||
InboundCreateResult result = _inbound.AcceptCreate(incoming);
|
||||
|
|
@ -311,7 +318,21 @@ public sealed class LiveEntityRuntime
|
|||
|| record.WorldEntity is not { } entity)
|
||||
return false;
|
||||
|
||||
_spatial.RebucketLiveEntity(entity, spatialCellOrLandblockId);
|
||||
bool wasProjected = record.IsSpatiallyProjected;
|
||||
bool wasVisible = record.IsSpatiallyVisible;
|
||||
// GpuWorldState reports an intermediate false/true pair while moving
|
||||
// between two loaded buckets. Suppress those implementation details
|
||||
// and publish only the final logical visibility edge.
|
||||
record.IsSpatiallyProjected = true;
|
||||
_rebucketingGuid = serverGuid;
|
||||
try
|
||||
{
|
||||
_spatial.RebucketLiveEntity(entity, spatialCellOrLandblockId);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_rebucketingGuid = 0;
|
||||
}
|
||||
bool visible = _spatial.IsLiveEntityVisible(serverGuid);
|
||||
record.IsSpatiallyVisible = visible;
|
||||
if (record.ProjectionKind is LiveEntityProjectionKind.World)
|
||||
|
|
@ -327,7 +348,8 @@ public sealed class LiveEntityRuntime
|
|||
record.CanonicalLandblockId = spatialCellOrLandblockId == 0
|
||||
? 0u
|
||||
: (spatialCellOrLandblockId & 0xFFFF0000u) | 0xFFFFu;
|
||||
record.IsSpatiallyProjected = true;
|
||||
if (!wasProjected || wasVisible != visible)
|
||||
ProjectionVisibilityChanged?.Invoke(record, visible);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -708,6 +730,8 @@ public sealed class LiveEntityRuntime
|
|||
_visibleWorldEntitiesByGuid[serverGuid] = entity;
|
||||
else
|
||||
_visibleWorldEntitiesByGuid.Remove(serverGuid);
|
||||
if (_rebucketingGuid != serverGuid)
|
||||
ProjectionVisibilityChanged?.Invoke(record, visible);
|
||||
}
|
||||
|
||||
private void TearDownRecord(LiveEntityRecord record)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue