예제 #1
0
        public bool Read(ref UdpBitStream bitstream, Frame frame, Frame currentFrame)
        {
            ElementFrame e = frames[frame.frameid];

            bool forcedUpdate   = IsUpdateForced(frame);
            bool applyToGhost   = ShouldApplyToGhost(frame);
            bool isCurrentFrame = frame == currentFrame;

            // Only read for the sent bit if not forced, there is no check bit for forced updates (since all clients and server know it is forced)
            bool hasChanged = forcedUpdate || bitstream.ReadBool();

            if (!hasChanged)
            {
                // Leave the transform as is if this is the current frame and hasn't changed - it has already been extrapolated and is mid-lerp
                // So leave it alone. Otherwise sete it to GenericX.NULL just to make debugging easier. Eventually can remove this.
                if (!isCurrentFrame)
                {
                    e.xform     = GenericX.NULL;
                    e.compXform = CompressedElement.Empty;
                }
                return(false);
            }

            e.compXform = crusher.Read(bitstream.Data, ref bitstream.ptr);

            e.xform = Decompress(e.compXform);

            if (applyToGhost)
            {
                Apply(e.xform, ghostGO);
            }

            return(true);
        }
예제 #2
0
        public void Initialize(NetworkSyncTransform _nst)
        {
            nst = _nst;
            na  = nst.na ? nst.na : (nst.na = nst.GetComponent <NSTNetAdapter>());

            frameCount = 60 / nst.sendEveryXTick;

            cache_axisEnabled = new bool[3];
            for (int i = 0; i < 3; ++i)
            {
                cache_axisEnabled[i] = crusher[i].Enabled;
            }

            frames = new ElementFrame[frameCount + 1];
            for (int i = 0; i < frames.Length; i++)
            {
                frames[i] = new ElementFrame(Localized, Compress(), false, this);
            }

            history = new GenericX[frameCount + 1];
            for (int i = 0; i < history.Length; i++)
            {
                history[i] = new GenericX();
            }

            lastSentCompressed = Compress();
            lastSentTransform  = Localized;
        }
예제 #3
0
        public void Snapshot(Frame newTargetFrame, bool lateUpdate = false, bool midTeleport = false)
        {
            ElementFrame nte = frames[newTargetFrame.frameid];
            ElementFrame te  = frames[targetFrameId];

            bool isNull = nte.xform.type == XType.NULL;

            // If the element carried no information for this frame, use the last updates value.
            if (isNull)
            {
                bool oldTargetIsNull = te == null || te.xform.type == XType.NULL;

                nte.xform     = oldTargetIsNull ? Localized : te.xform;
                nte.compXform = oldTargetIsNull ? Compress(nte.xform) : te.compXform;
            }

            // First run set both target and snapshot to the incoming.
            if (hasReceivedInitial == false)
            {
                targetFrameId      = newTargetFrame.frameid;
                hasReceivedInitial = true;
            }
            snapshotFrameId = targetFrameId;             // LocalizedRot;
            targetFrameId   = newTargetFrame.frameid;
        }
        public void Snapshot(Frame newTargetFrame, bool lateUpdate = false, bool midTeleport = false)
        {
            ElementFrame newte = frames[newTargetFrame.frameid];
            ElementFrame oldte = frames[targetFrameId];

            bool isNull = newte.xform.type == XType.NULL;

            // If the element carried no useful information for this frame, use the last updates value.
            if (isNull || (HeaderSettings.single.includeSceneIndex && (newTargetFrame.sceneIndex != NSTSceneManager.CurrentSceneIndex)))
            {
                bool oldTargetIsNull = oldte == null || oldte.xform.type == XType.NULL;

                newte.xform = oldTargetIsNull ? Localized : oldte.xform;

                if (oldTargetIsNull)
                {
                    Compress(newte.compXform, newte.xform);
                }
                else
                {
                    newte.compXform.CopyFrom(oldte.compXform);
                }
            }

            // First run set both target and snapshot to the incoming.
            if (hasReceivedInitial == false)
            {
                targetFrameId      = newTargetFrame.frameid;
                hasReceivedInitial = true;
            }
            snapshotFrameId = targetFrameId;             // LocalizedRot;
            targetFrameId   = newTargetFrame.frameid;
        }
예제 #5
0
        public bool Write(ref UdpBitStream bitstream, Frame frame)
        {
            ElementFrame e = frames[frame.frameid];

            e.compXform = Compress();
            e.xform     = Localized;

            CompressedElement newComp = e.compXform;

            bool forceUpdate = IsUpdateForced(frame);

            // For frames between forced updates, we need to first send a flag bit for if this element is being sent
            if (!forceUpdate)
            {
                bool hasChanged = !CompressedElement.Compare(newComp, lastSentCompressed) && sendCullMask.OnChanges();
                bitstream.WriteBool(hasChanged);

                // if no changes have occured we are done.
                if (!hasChanged)
                {
                    return(false);
                }
            }

            crusher.Write(e.compXform, bitstream.Data, ref bitstream.ptr);

            lastSentCompressed = newComp;
            lastSentTransform  = e.xform;

            return(true);
        }
        public void Initialize(NetworkSyncTransform _nst, INSTTransformElement _nstElement)
        {
            nst        = _nst;
            nstElement = _nstElement;

            na = nst.na ? nst.na : (nst.na = nst.GetComponent <NSTNetAdapter>());

            frameCount = NSTMaster.FRAME_COUNT / nst.sendEveryXTick;

            //// TODO: Would rather not have to do this here - but the automation for this isn't firing in time
            //crusher.CacheValues();

            frames = new ElementFrame[frameCount + 1];
            for (int i = 0; i < frames.Length; i++)
            {
                var ce = new CompressedElement();
                Compress(ce);
                frames[i] = new ElementFrame(Localized, ce, false, this);
            }

            history = new GenericX[frameCount + 1];
            for (int i = 0; i < history.Length; i++)
            {
                history[i] = new GenericX();
            }

            Compress(lastSentCompressed);
            lastSentTransform = Localized;
        }
예제 #7
0
        public override void MirrorToClients(ref UdpBitStream outstream, Frame frame, bool hasChanged)
        {
            // Write the used flag (if this is not a forced update) and determine if an update needs to be written.
            if (WriteUpdateFlag(ref outstream, frame, hasChanged) == false)
            {
                return;
            }

            ElementFrame e = frames[frame.frameid];

            if (rotationType == RotationType.Quaternion)
            {
                outstream.WriteULong(e.compXform, totalBitsForQuat);
            }
            else
            {
                for (int i = 0; i < 3; i++)
                {
                    if (includedAxes.IsXYZ(i))
                    {
                        outstream.WriteUInt(e.compXform[i], axes[i].bits);
                    }
                }
            }

            lastSentCompressed = e.compXform;
        }
예제 #8
0
        public override bool Write(ref UdpBitStream bitstream, Frame frame)
        {
            // Base class does some forceUpdate checking, keep it around.
            bool         forceUpdate = IsUpdateForced(frame);
            ElementFrame e           = frames[frame.frameid];

            e.compXform = Compress();
            e.xform     = Localized;
            CompressedElement newComp = e.compXform;

            if (rotationType == RotationType.Quaternion)
            {
                // For frames between forced updates, we need to first send a flag bit for if this element is being sent
                if (!forceUpdate)
                {
                    bool hasChanged = newComp.quat != lastSentCompressed.quat && sendCullMask.OnChanges();
                    bitstream.WriteBool(hasChanged);

                    // if no changes have occured we are done.
                    if (!hasChanged)
                    {
                        return(false);
                    }
                }

                bitstream.WriteULong(newComp.quat, totalBitsForQuat);

                lastSentCompressed.quat = newComp.quat;
                lastSentTransform       = e.xform;

                return(true);
            }

            else
            {
                // For frames between forced updates, we need to first send a flag bit for if this element is being sent
                if (!forceUpdate)
                {
                    bool hasChanged = !CompressedElement.Compare(newComp, lastSentCompressed) && sendCullMask.OnChanges();
                    bitstream.WriteBool(hasChanged);

                    // if no changes have occured we are done.
                    if (!hasChanged)
                    {
                        return(false);
                    }
                }

                for (int axis = 0; axis < 3; axis++)
                {
                    if (includedAxes.IsXYZ(axis))
                    {
                        bitstream.WriteUInt(newComp[axis], axes[axis].bits);
                        lastSentCompressed[axis] = newComp[axis];
                    }
                }

                return(true);
            }
        }
예제 #9
0
        public void MirrorToClients(ref UdpBitStream outstream, Frame frame, bool hasChanged)
        {
            // Write the used flag (if this is not a forced update) and determine if an update needs to be written.
            if (WriteUpdateFlag(ref outstream, frame, hasChanged) == false)
            {
                return;
            }

            ElementFrame e = frames[frame.frameid];

            crusher.Write(e.compXform, outstream.Data, ref outstream.ptr);
        }
예제 #10
0
        public override bool Read(ref UdpBitStream bitstream, Frame frame, Frame currentFrame)
        {
            ElementFrame e = frames[frame.frameid];

            bool forcedUpdate   = IsUpdateForced(frame);
            bool applyToGhost   = ShouldApplyToGhost(frame);
            bool isCurrentFrame = frame == currentFrame;

            // Only read for the sent bit if not forced, there is no check bit for forced updates (since all clients and server know it is required)
            bool hasChanged = forcedUpdate || bitstream.ReadBool();

            if (!hasChanged)
            {
                // Leave the transform as is if this is the current friend and hasn't changed - it has already been extrapolated and is mid-lerp
                // So leave it alone. Otherwise set it to GenericX.NULL just to make debugging easier. Eventually can remove this.
                if (!isCurrentFrame)
                {
                    e.xform     = GenericX.NULL;
                    e.compXform = CompressedElement.zero;
                }
                return(false);
            }

            if (rotationType == RotationType.Quaternion)
            {
                e.compXform = bitstream.ReadULong(totalBitsForQuat);
                e.xform     = e.compXform.quat.DecompressToQuat(totalBitsForQuat);
            }
            else
            {
                for (int axisId = 0; axisId < 3; axisId++)
                {
                    bool useAxis = includedAxes.IsXYZ(axisId);
                    cvals[axisId] = (useAxis) ? bitstream.ReadUInt(axes[axisId].bits) : 0;
                    vals[axisId]  = (useAxis) ? cvals[axisId] * axes[axisId].unmult + axes[axisId].min : 0;
                }

                e.xform     = new GenericX(vals[0], vals[1], vals[2], (XType)includedAxes);
                e.compXform = new CompressedElement(cvals[0], cvals[1], cvals[2]);
            }

            if (applyToGhost)
            {
                Apply(e.xform, rewindGO);                 // e.transform.ApplyRotation(rewindGO.transform, useLocal);
            }
            return(hasChanged);
        }
        public bool Write(ref UdpBitStream bitstream, Frame frame)
        {
            ElementFrame      e         = frames[frame.frameid];
            CompressedElement compXform = e.compXform;

            Compress(compXform);
            e.xform = Decompress(compXform);             // Localized;

            /// Experimental - Apply the outgoing lossy values to the GhostGO so owner/authority of object can use it to replicate lossy events like weapon fire.
            if (ghostGO)
            {
                Apply(e.xform, ghostGO);
            }

            if (!nstElement.Enabled)
            {
                bitstream.WriteBool(false);
                return(false);
            }

            bool forceUpdate = IsUpdateForced(frame);

            // For frames between forced updates, we need to first send a flag bit for if this element is being sent
            if (!forceUpdate)
            {
                bool hasChanged = !compXform.Equals(lastSentCompressed) && sendCullMask.OnChanges();
                bitstream.WriteBool(hasChanged);

                // if no changes have occured we are done.
                if (!hasChanged)
                {
                    return(false);
                }
            }
            else
            {
                bitstream.WriteBool(true);
            }

            crusher.Write(compXform, bitstream.Data, ref bitstream.ptr);

            lastSentCompressed.CopyFrom(compXform);
            lastSentTransform = e.xform;

            return(true);
        }
예제 #12
0
        public virtual void Initialize(NetworkSyncTransform _nst)
        {
            nst        = _nst;
            na         = _nst.na;
            frameCount = nst.frameCount;

            frames = new ElementFrame[frameCount + 1];
            for (int i = 0; i < frames.Length; i++)
            {
                frames[i] = new ElementFrame(Localized, Compress(), false, this);
            }

            history = new GenericX[frameCount + 1];
            for (int i = 0; i < history.Length; i++)
            {
                history[i] = new GenericX();
            }
        }
        public bool Read(ref UdpBitStream bitstream, Frame frame, Frame currentFrame)
        {
            ElementFrame e = frames[frame.frameid];

            //bool forcedUpdate = IsUpdateForced(frame);
            bool applyToGhost   = ShouldApplyToGhost(frame);
            bool isCurrentFrame = frame == currentFrame;

            // Only read for the sent bit if not forced, there is no check bit for forced updates (since all clients and server know it is forced)
            bool hasChanged = /*forcedUpdate || */ bitstream.ReadBool();

            /// If no info was included, or if we have a scene mismatch, indicate this transform update as invalid.
            if (!hasChanged /* || frame.sceneIndex != NSTSceneManager.CurrentSceneIndex*/)
            {
                // Leave the transform as is if this is the current frame and hasn't changed - it has already been extrapolated and is mid-lerp
                // So leave it alone. Otherwise sete it to GenericX.NULL just to make debugging easier. Eventually can remove this.
                if (!isCurrentFrame)
                {
                    //Debug.LogError(name + " NotCurrentFrame!");
                    e.xform = GenericX.NULL;
                    e.compXform.Clear();                     // = CompressedElement.Empty;
                }
                return(false);
            }

            crusher.Read(e.compXform, bitstream.Data, ref bitstream.ptr);

            e.xform = Decompress(e.compXform);

            if (applyToGhost)
            {
                Apply(e.xform, ghostGO);
            }

            return(true);
        }