Exemplo n.º 1
0
        /// <summary>
        /// This is a hot path. Runs at the completion interpolation, and attempts to find/reconstruct the next suitable frame for interpolation.
        /// </summary>
        public Frame DetermineAndPrepareNextFrame(bool svrWaitingForTeleportConfirm)
        {
            // buffer is empty, no point looking for any frames - we need to extrapolate the next frame
            if (validFrameMask == 0)
            {
                ExtrapolateNextFrame(svrWaitingForTeleportConfirm);

                XDebug.Log(!XDebug.logInfo ? null :
                           //Debug.Log(
                           (Time.time + " NST:" + nst.NstId + " <b> Empty buffer</b>, (likely packetloss) copying current frame to " + NextFrame.frameid + " " + nst.name +
                            "\nCurrentFrame: " + currentFrame.frameid + " scn:" + currentFrame.sceneIndex + " " + currentFrame.compPos + " " + currentFrame.rootPos +
                            "\nNextFrame: " + NextFrame.frameid + " scn:" + NextFrame.sceneIndex + " " + NextFrame.compPos + " " + NextFrame.rootPos));

                return(NextFrame);
            }

            extrapolationCount = 0;

            // First see if there is a future frame ready - ignoring late arrivles that may have backfilled behind the current frame
            Frame nextValid = GetFirstFutureValidFrame();

            // if not see if there is an older frame that arrived late, if so we will jump back to that as current
            if (nextValid == null)
            {
                nextValid = GetOldestPastValidFrame() ?? GetOldestValidFrame();

                // The only valid frames are only in the past, we need to jump back to the oldest to get our current frame in a better ballpark
                if (nextValid != null)
                {
                    nextValid.CompletePosition(currentFrame);
                    //Debug.Log(
                    XDebug.Log(!XDebug.logInfo ? null :
                               (Time.time + " NST:" + nst.NstId + " <b> Skipping back </b>(likely packetloss) to frame " + nextValid.frameid +
                                " from current frame " + CurrentIndex + " " + nst.name +
                                "\nOnly frames in buffer were in the past, so seems that we are getting ahead of the buffer. Should see these rarely." +
                                "\nCurrentFrame: " + currentFrame.frameid + " scn:" + currentFrame.sceneIndex + " " + currentFrame.compPos + " " + currentFrame.rootPos +
                                "\nNextValid: " + nextValid.frameid + " scn:" + nextValid.sceneIndex + " " + nextValid.compPos + " " + nextValid.rootPos));

                    return(nextValid);
                }
            }

            // Find out how far in the future the next valid frame is, need to know this for the reconstruction lerp.
            int stepsFromLast = CountFrames(CurrentIndex, nextValid.frameid);

            // The next frame is the next valid... not much thinking required... just use it.
            if (stepsFromLast == 1)
            {
                InvalidateOldFrames(NextFrame);                 // LIKELY UNEEDED
                NextFrame.CompletePosition(currentFrame);

                //Debug.Log(
                //XDebug.Log(!XDebug.logInfo ? null :
                //	(Time.time + " NST:" + nst.NstId + " <b>Normal Next</b> from " + CurrentIndex + " to " + NextFrame.frameid + "  (likely packetloss) from expected frame. " + nst.name +
                //	"\nCurrentFrame: " + currentFrame.frameid + " scn:" + currentFrame.sceneIndex + " " + currentFrame.compPos + " " + currentFrame.rootPos +
                //	"\nNextFrame: " + NextFrame.frameid + " scn:" + NextFrame.sceneIndex + " " + NextFrame.compPos + " " + NextFrame.rootPos));

                return(NextFrame);
            }

            // if next frame on the buffer is a couple ahead of current, jump forward
            if (stepsFromLast > jumpForwardThreshold)
            {
                //Debug.Log(
                XDebug.Log(!XDebug.logInfo ? null :
                           (Time.time + " NST:" + nst.NstId + " <b>Jumping forward</b> from " + CurrentIndex + " to " + nextValid.frameid + "  (likely packetloss) from expected frame. " + nst.name +
                            "\nCurrentFrame: " + currentFrame.frameid + " " + currentFrame.compPos + " " + currentFrame.rootPos +
                            "\nNextValidFrame: " + nextValid.frameid + " " + nextValid.compPos + " " + nextValid.rootPos));

                InvalidateOldFrames(nextValid);
                nextValid.CompletePosition(currentFrame);
                return(nextValid);
            }

            //All other cases we Reconstruct missing next frame using the current frame and a future frame

            NextFrame.state = currentFrame.state;

            float t = 1f / stepsFromLast;

            nextValid.CompletePosition(currentFrame);


            Vector3 lerpedPos = Vector3.Lerp(currentFrame.rootPos, nextValid.rootPos, t);

            float lerpedStartTime = Mathf.Lerp(currentFrame.packetArriveTime, nextValid.packetArriveTime, t);

            NextFrame.ModifyFrame(currentFrame.updateType, currentFrame.rootBitCullLevel, lerpedPos, GenericX.NULL, lerpedStartTime);

            //Debug.Log(
            XDebug.Log(!XDebug.logInfo ? null :
                       (Time.time + " NST:" + nst.NstId + " <b>Reconstructing frame " + NextFrame.frameid + "</b> (likely packetloss) from current frame and future frame "
                        + NextFrame.compPos + " <b>" + NextFrame.rootPos + "</b> " + nst.name +
                        "\nCurrentFrame: " + currentFrame.frameid + " scn:" + currentFrame.sceneIndex + " " + currentFrame.compPos + " " + currentFrame.rootPos +
                        "\nNextValidFrame: " + nextValid.frameid + " scn:" + nextValid.sceneIndex + " " + nextValid.compPos + " " + nextValid.rootPos) + " " + nextValid.rootBitCullLevel);


            //XDebug.Log(!XDebug.logInfo ? null :
            //	(Time.time + "fid" + NextFrame.frameid + " <color=red><b> RECONSTRUCT ELEMENTS </b></color> " + NextFrame.RootRot + " " + currentFrame.RootRot + " " + nextValid.RootRot));

            // Notify all interested components that they need to reconstruct a missing frame (elements and such)
            foreach (INstOnReconstructMissing callbacks in nst.iNstOnReconstructMissing)
            {
                callbacks.OnReconstructMissing(NextFrame, currentFrame, nextValid, t, svrWaitingForTeleportConfirm);
            }

            return(NextFrame);
        }
Exemplo n.º 2
0
        /// <summary>
        /// This is a hot path. Runs at the completion interpolation, and attempts to find/reconstruct the next suitable frame for interpolation.
        /// </summary>
        public Frame DetermineAndPrepareNextFrame(bool svrWaitingForTeleportConfirm)
        {
            // buffer is empty, no point looking for any frames - we need to extrapolate the next frame
            if (validFrameMask <= 1)
            {
                DebugX.Log(!DebugX.logInfo ? "" :
                           //Debug.Log(
                           (Time.time + " NST " + nst.NstId + " " + nst.name + " <color=red><b> empty buffer, copying current frame to </b></color>" + NextFrame.frameid + " \n curr: " + currentFrame));

                ExtrapolateNextFrame(svrWaitingForTeleportConfirm);

                return(NextFrame);
            }

            extrapolationCount = 0;

            // First see if there is a future frame ready - ignoring late arrivles that may have backfilled behind the current frame
            Frame nextValid = GetFirstFutureValidFrame();

            // if not see if there is an older frame that arrived late, if so we will jump back to that as current
            if (nextValid == null)
            {
                nextValid = GetOldestPastValidFrame() ?? GetOldestValidFrame();

                // The only valid frames are only in the past, we need to jump back to the oldest to get our current frame in a better ballpark
                if (nextValid != null)
                {
                    DebugX.Log(!DebugX.logInfo ? "" :
                               //Debug.Log(
                               (Time.time + " NST " + nst.NstId + " " + nst.name + " <color=red><b> Skipping back to frame </b></color> " + nextValid.frameid + " from current frame " + CurrentIndex));

                    nextValid.CompletePosition(currentFrame);
                    return(nextValid);
                }
            }
            // Find out how far in the future the next valid frame is, need to know this for the reconstruction lerp.
            int stepsFromLast = CountFrames(CurrentIndex, nextValid.frameid);

            // The next frame is the next valid... not much thinking required... just use it.
            if (stepsFromLast == 1)
            {
                InvalidateOldFrames(NextFrame);                 // LIKELY UNEEDED
                NextFrame.CompletePosition(currentFrame);

                return(NextFrame);
            }

            // if next frame on the buffer is a couple ahead of current, jump forward
            if (stepsFromLast > jumpForwardThreshold)
            {
                //Debug.Log(
                DebugX.Log(!DebugX.logInfo ? "" :
                           ("<color=red><b>Jumping forward frame(s) </b></color>"));

                InvalidateOldFrames(nextValid);
                nextValid.CompletePosition(currentFrame);
                return(nextValid);
            }

            //All other cases we Reconstruct missing next frame using the current frame and a future frame
            Frame next = NextFrame;

            //Debug.Log(
            DebugX.Log(!DebugX.logInfo ? "" :
                       (Time.time + " NST:" + nst.NstId + " <color=black><b>Reconstructing missing packet " + next.frameid + " </b></color> \n" + currentFrame.compPos + "\n" + nextValid.compPos));

            next.state = currentFrame.state;

            float t = 1f / stepsFromLast;

            nextValid.CompletePosition(currentFrame);

            Vector3 lerpedPos = Vector3.Lerp(currentFrame.rootPos, nextValid.rootPos, t);

            float lerpedStartTime = Mathf.Lerp(currentFrame.packetArriveTime, nextValid.packetArriveTime, t);

            next.ModifyFrame(currentFrame.updateType, currentFrame.rootSendType, lerpedPos, GenericX.NULL, lerpedStartTime);

            DebugX.Log(!DebugX.logInfo ? "" :
                       (Time.time + "fid" + next.frameid + " <color=red><b> RECONSTRUCT ELEMENTS </b></color> " + next.RootRot + " " + currentFrame.RootRot + " " + nextValid.RootRot));

            // Notify all interested components that they need to reconstruct a missing frame (elements and such)
            foreach (INstOnReconstructMissing callbacks in nst.iNstOnReconstructMissing)
            {
                callbacks.OnReconstructMissing(next, currentFrame, nextValid, t, svrWaitingForTeleportConfirm);
            }

            return(next);
        }
Exemplo n.º 3
0
        public Frame DetermineNextFrame()
        {
            // buffer is empty, no point looking for any frames
            if (validFrameMask <= 1)
            {
                DebugX.Log(Time.time + " NST " + nst.NstId + " " + nst.name + " <color=red><b> empty buffer, copying current frame </b></color>" + NextFrame.packetid);
                ExtrapolateNextFrame();
                return(NextFrame);
            }

            // First see if there is a future frame ready
            Frame nextValid = GetFirstFutureValidFrame();

            // if not see if there is an older frame that arrived late, if so we will jump back to that as current
            if (nextValid == null)
            {
                nextValid = GetOldestPastValidFrame();

                // Valid frames are only in the past, we need to jump back to that packetindex
                if (nextValid != null)
                {
                    DebugX.Log(Time.time + " NST " + nst.NstId + " " + nst.name + " <color=red><b> Skipping back to older frame </b></color> " + nextValid.packetid);
                    nextValid.CompletePosition(currentFrame);
                    return(nextValid);
                }
                // No future or past frames found - Look everywhere as a last ditch check in case we are way out of sync

                nextValid = GetOldestValidFrame();
                if (nextValid != null)
                {
                    DebugX.Log(Time.time + " NST " + nst.NstId + " " + nst.name + " <color=red><b> Skipping to out of sequence frame </b></color> " + nextValid.packetid);
                    nextValid.CompletePosition(currentFrame);                     // of questionable value for a frame this out of sequence, but better than 0 position.
                    return(nextValid);
                }
            }

            // Find out how far in the future the next valid frame is, need to know this for the reconstruction lerp.
            int stepsFromLast = CountFrames(CurrentIndex, nextValid.packetid);

            // The next frame is the next valid... not much thinking required... just use it.
            if (stepsFromLast == 1)
            {
                InvalidateOldFrames(NextFrame);
                NextFrame.CompletePosition(currentFrame);
                return(NextFrame);
            }

            if (stepsFromLast > 2)             // arbitrary number... should refine this
            {
                InvalidateOldFrames(nextValid);
                nextValid.CompletePosition(currentFrame);
                return(nextValid);
            }

            //All other cases we Reconstruct missing next frame
            Frame next = NextFrame;

            DebugX.Log(Time.time + " NST:" + nst.NstId + " <color=black><b>Reconstructing missing packet " + next.packetid + " </b></color>");

            float t = 1f / stepsFromLast;

            nextValid.CompletePosition(currentFrame);
            CompressedElement lerpedCompPos = Vector3.Lerp(currentFrame.pos, nextValid.pos, t).CompressPos();             // TODO: should this be v3 lerps instead to avoid the rounding error?
            // TEST
            //CompressedPos lerpedCompPos = nextValid.compPos; // TODO: should this be v3 lerps instead to avoid the rounding error?

            float lerpedStartTime = Mathf.Lerp(currentFrame.packetArriveTime, nextValid.packetArriveTime, t);

            next.ModifyFrame(currentFrame.msgType, lerpedCompPos, lerpedCompPos.Decompress(), lerpedStartTime);

            // Reconstruct missing Position Element
            for (int i = 0; i < next.positions.Count; i++)
            {
                GenericX currentTargetX = nst.positionElements[i].target;

                if (BitTools.GetBitInMask(nextValid.positionsMask, i))
                {
                    next.positions[i] = (Vector3.Lerp(currentTargetX, nextValid.positions[i], t));
                    i.SetBitInMask(ref next.positionsMask, true);
                }
                else
                {
                    next.positions[i] = currentTargetX;
                    i.SetBitInMask(ref next.rotationsMask, false);
                }
            }

            // Reconstruct missing Rotation Element
            for (int i = 0; i < next.rotations.Count; i++)
            {
                GenericX currentTargetX = nst.rotationElements[i].target;

                if (BitTools.GetBitInMask(nextValid.rotationsMask, i))
                {
                    if (currentTargetX.type == XType.NULL)
                    {
                        Debug.LogError(nst.name + "  Cloning NULL GenX element " + i + "  " + currentTargetX + " - which should never happen, this would be a bug.");
                    }

                    next.rotations[i] = (Quaternion.Slerp(currentTargetX, nextValid.rotations[i], t));

                    //TEST
                    next.rotations[i] = currentTargetX;
                    i.SetBitInMask(ref next.rotationsMask, true);
                }
                else
                {
                    next.rotations[i] = nst.rotationElements[i].target;                     // maybe unneeded
                    i.SetBitInMask(ref next.rotationsMask, false);
                }
            }

            return(next);
        }