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); }
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; }
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; }
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; }
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; }
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); } }
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); }
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); }
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); }