public void Update()
    {
        if (_owner.bypassPrediction)
        {
            leftProjection = rightProjection = Rect.MinMaxRect(-1, -1, 1, 1);
            return;
        }

        if (_zmqPredictedMotion == null)
        {
            return;
        }

        _prevExternalInputActualPress     = externalInputActualPress;
        _prevExternalInputPredictivePress = externalInputPredictivePress;

        while (_zmqPredictedMotion.TryReceive(ref _msgRecv, TimeSpan.Zero))
        {
            if (_msgRecv.Size <= 0)
            {
                continue;
            }

            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(_msgRecv.Data, 0, 8);
                for (int i = 0; i < 49; i++)
                {
                    Array.Reverse(_msgRecv.Data, 8 + i * 4, 4);
                }
            }

            int pos = 0;
            timestamp      = getLong(_msgRecv.Data, ref pos);
            predictionTime = getFloat(_msgRecv.Data, ref pos);

            var inputLeftEyePosition  = getPosition(_msgRecv.Data, ref pos);
            var inputRightEyePosition = getPosition(_msgRecv.Data, ref pos);
            var inputHeadOrientation  = getRotation(_msgRecv.Data, ref pos);
            var inputProjection       = getProjection(_msgRecv.Data, ref pos);
            var inputRightHandPose    = new Pose(getPosition(_msgRecv.Data, ref pos), getRotation(_msgRecv.Data, ref pos));

            var leftEyePosition  = getPosition(_msgRecv.Data, ref pos);
            var rightEyePosition = getPosition(_msgRecv.Data, ref pos);
            var headOrientation  = getRotation(_msgRecv.Data, ref pos);

            leftEye  = new Pose(leftEyePosition, headOrientation);
            rightEye = new Pose(rightEyePosition, headOrientation);

            leftProjection  = getProjection(_msgRecv.Data, ref pos);
            rightProjection = getProjection(_msgRecv.Data, ref pos);

            foveationInnerRadius  = getFloat(_msgRecv.Data, ref pos);
            foveationMiddleRadius = getFloat(_msgRecv.Data, ref pos);

            rightHand = new Pose(getPosition(_msgRecv.Data, ref pos), getRotation(_msgRecv.Data, ref pos));

            externalInputId = getUshort(_msgRecv.Data, ref pos);

            var actualPress    = getBool(_msgRecv.Data, ref pos);
            var predictedPress = getBool(_msgRecv.Data, ref pos);

            if (_prevExternalInputActualPress != actualPress)
            {
                externalInputActualPress = actualPress;
            }
            if (_prevExternalInputPredictivePress != predictedPress)
            {
                externalInputPredictivePress = predictedPress;
            }

            _motionDataProvider.Put(timestamp, predictionTime,
                                    new Pose(inputLeftEyePosition, inputHeadOrientation), new Pose(inputRightEyePosition, inputHeadOrientation),
                                    MPPProjection.FromRect(inputProjection), inputRightHandPose,
                                    leftEye, rightEye,
                                    MPPProjection.FromRect(leftProjection), MPPProjection.FromRect(rightProjection),
                                    foveationInnerRadius, foveationMiddleRadius, rightHand);
        }
    }