예제 #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);
        }