Skip to content

Commit 91d1d27

Browse files
committed
more nan protection
1 parent ba38536 commit 91d1d27

2 files changed

Lines changed: 25 additions & 2 deletions

File tree

Basis/Packages/com.basis.framework/Drivers/Remote/BasisRemoteAvatarDriver.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,12 @@ public void RemoteCalibration(BasisRemotePlayer RemotePlayer)
209209
tposeHipsLocalPos = float3.zero;
210210
tposeHipsLocalRot = quaternion.identity;
211211
}
212+
// Initialize this player's interpolation slot before registering it with the bone
213+
// job system. The bone Schedule reads _filtered*[playerId] earlier in LateUpdate than
214+
// BeginWrite's lazy init runs (LateUpdate tail), so a cached/fallback avatar that
215+
// calibrates within a frame of joining would otherwise be read from uninitialized
216+
// memory and pose as NaN.
217+
BasisRemoteNetworkDriver.EnsureSlotInitialized(receiver.playerId);
212218
RemoteBoneJobSystem.AddRemotePlayer(
213219
key: receiver.playerId,
214220
remotePlayerRoot: animatorRoot,

Basis/Packages/com.basis.framework/Networking/Recievers/BasisRemoteNetworkDriver.cs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
using Basis.Network.Core.Compression;
22
using Basis.Scripts.Networking;
33
using System;
4-
using System.Collections.Generic;
54
using System.Runtime.CompilerServices;
65
using Unity.Burst;
76
using Unity.Collections;
87
using Unity.Collections.LowLevel.Unsafe;
98
using Unity.Jobs;
109
using Unity.Mathematics;
11-
using UnityEngine;
1210

1311
/// <summary>
1412
/// Remote network driver that:
@@ -237,6 +235,25 @@ public static unsafe void BeginWrite()
237235
_ptrPoseFilterSeeded = (IntPtr)_poseFilterSeeded.GetUnsafePtr();
238236
}
239237

238+
/// <summary>
239+
/// Grows the lazily-initialized region to include <paramref name="playerId"/> on the
240+
/// main thread. BeginWrite only covers [0, LargestNetworkReceiverID+1), and that
241+
/// high-water is recomputed at the tail of LateUpdate — AFTER RemoteBoneJobSystem.Schedule()
242+
/// reads these slots earlier in the same LateUpdate. A remote whose avatar calibrates within
243+
/// a frame of joining (cached/fallback avatars) registers a key the driver hasn't covered
244+
/// yet, so the bone-copy jobs read uninitialized NativeArray memory and emit a NaN pose.
245+
/// Call this at calibration, before the player is registered with RemoteBoneJobSystem.
246+
/// Completes any in-flight oneEuroJob first (same reason as SeedScaleState): EnsureInitialized
247+
/// writes arrays the job touches.
248+
/// </summary>
249+
public static void EnsureSlotInitialized(int playerId)
250+
{
251+
if (!_initialized) return;
252+
if ((uint)playerId >= FixedCapacity) return;
253+
oneEuroJob.Complete();
254+
EnsureInitialized(playerId + 1);
255+
}
256+
240257
[MethodImpl(MethodImplOptions.AggressiveInlining)]
241258
public static unsafe void ResetPoseFilter(int index)
242259
{

0 commit comments

Comments
 (0)