public static ScreenCaptureSnapshot Deserialize(byte[] input)
        {
            if (input == null)
                return null;

            ScreenCaptureSnapshot result = new ScreenCaptureSnapshot();
            ComposedByteStream stream = ComposedByteStream.FromByteArray(input);
            if (stream != null)
            {
                ComposedPrimitives prims = ComposedPrimitives.FromByteArray(stream.ReadNextStream<byte>());
                result.screenWidth = prims.ReadNextValue<int>();
                result.screenHeight = prims.ReadNextValue<int>();

                int camNamesCount = prims.ReadNextValue<int>();
                int camRendersCount = prims.ReadNextValue<int>();
                int camRectCount = prims.ReadNextValue<int>();

                result.mainCamLocalRotation = new SVector3(prims.ReadNextValue<float>(), prims.ReadNextValue<float>(), prims.ReadNextValue<float>());
                result.mainCamWorldRotation = new SVector3(prims.ReadNextValue<float>(), prims.ReadNextValue<float>(), prims.ReadNextValue<float>());
                result.inputAcceleration = new SVector3(prims.ReadNextValue<float>(), prims.ReadNextValue<float>(), prims.ReadNextValue<float>());

                result.camNames = new string[camNamesCount];
                for (int i = 0; i < camNamesCount; i++)
                    result.camNames[i] = stream.ReadNextStream();

                result.camRenders = new byte[camRendersCount][];
                for (int i = 0; i < camRendersCount; i++)
                    result.camRenders[i] = stream.ReadNextStream<byte>();

                result.camRects = new Rect[camRectCount];
                for (int i = 0; i < camRectCount; i++)
                {
                    float[] rectFloats = stream.ReadNextStream<float>();
                    if (rectFloats != null && rectFloats.Length == 4)
                        result.camRects[i] = new Rect(rectFloats[0], rectFloats[1], rectFloats[2], rectFloats[3]);
                }
            }
            return result;
        }
        public static byte[] Serialize(ScreenCaptureSnapshot input)
        {
            ComposedByteStream stream = ComposedByteStream.FetchStream();

            //--------------- Primitives --------------------
            ComposedPrimitives prims = new ComposedPrimitives();
            prims.AddValue(input.screenWidth);
            prims.AddValue(input.screenHeight);

            prims.AddValue(input.camNames != null ? input.camNames.Length : 0);
            prims.AddValue(input.camRenders != null ? input.camRenders.Length : 0);
            prims.AddValue(input.camRects != null ? input.camRects.Length : 0);

            prims.AddValue(input.mainCamLocalRotation.x);
            prims.AddValue(input.mainCamLocalRotation.y);
            prims.AddValue(input.mainCamLocalRotation.z);
            prims.AddValue(input.mainCamWorldRotation.x);
            prims.AddValue(input.mainCamWorldRotation.y);
            prims.AddValue(input.mainCamWorldRotation.z);
            prims.AddValue(input.inputAcceleration.x);
            prims.AddValue(input.inputAcceleration.y);
            prims.AddValue(input.inputAcceleration.z);

            stream.AddStream(prims.Compose());
            //--------------- Primitives --------------------

            if(input.camNames != null || input.camNames.Length != 0) {
                foreach(string name in input.camNames)
                    stream.AddStream(name);
            }

            if (input.camRenders != null && input.camRenders.Length != 0) {
                foreach (byte[] render in input.camRenders)
                    stream.AddStream(render);
            }

            if (input.camRects != null && input.camRects.Length != 0) {
                foreach (Rect rect in input.camRects)
                    stream.AddStream(new float[] { rect.x, rect.y, rect.width, rect.height });
            }
            return stream.Compose();
        }
        //Todo:Add material data and make all dispose calls recursive.
        public override void Dispose()
        {
            base.Dispose();

            if (header != null) header.Dispose();
            if (systemInfo != null) systemInfo.Dispose();
            if (debugLogs != null) debugLogs.Dispose();
            if (humanInput != null) humanInput.Dispose();
            if (meshData != null) meshData.Dispose();
            if (particleData != null) particleData.Dispose();
            if (materialData != null) materialData.Dispose();
            if (gameObjectsSnapshot != null) gameObjectsSnapshot.Dispose();

            header = null;
            systemInfo = null;
            debugLogs = null;
            humanInput = null;
            meshData = null;
            particleData = null;
            materialData = null;
            gameObjectsSnapshot = null;
            screenCapture = null;
        }