public bool Load(Stream stream)
        {
            BinaryReader br = new BinaryReader(stream);

            string header = ((char)br.ReadByte()).ToString() + ((char)br.ReadByte()) + ((char)br.ReadByte()) + ((char)br.ReadByte());

            if (header != "GRSM")
                return false;

            majorVersion = br.ReadByte();
            minorVersion = br.ReadByte();

            _animationLength = br.ReadInt32();
            _shade = (ShadeType)br.ReadInt32();

            if (majorVersion > 1 || (majorVersion == 1 && minorVersion >= 4))
                _alpha = br.ReadByte();
            else
                _alpha = 255;

            br.ReadBytes(16);

            _textures = new Texture2D[br.ReadInt32()];
            for (int i = 0; i < _textures.Length; i++)
            {
                _textures[i] = SharedInformation.ContentManager.Load<Texture2D>(@"data\texture\" + br.ReadCString(40));
            }

            _mainNodeName = br.ReadCString(40);

            _meshes = new GravityModelMesh[br.ReadInt32()];
            for (int i = 0; i < _meshes.Length; i++)
            {
                GravityModelMesh mesh = new GravityModelMesh();

                mesh.Load(this, br, majorVersion, minorVersion);

                _meshes[i] = mesh;
            }

            _rootMesh = FindMesh(_mainNodeName);
            _rootMesh.CreateChildren(_meshes);

            bbmin = new Vector3(999999, 999999, 999999);
            bbmax = new Vector3(-999999, -999999, -999999);

            _rootMesh.SetBoundingBox(ref bbmin, ref bbmax);
            bbrange = (bbmin + bbmax) / 2.0F;

            Matrix mat = Matrix.CreateScale(1, -1, 1);
            realbbmin = new Vector3(999999, 999999, 999999);
            realbbmax = new Vector3(-999999, -999999, -999999);
            _rootMesh.SetBoundingBox2(mat, ref realbbmin, ref realbbmax);
            realbbrange = (realbbmax + realbbmin) / 2.0F;
            //maxrange = Math.Max(Math.Max(Math.Max(realbbmax.X, -realbbmin.X), Math.Max(realbbmax.Y, -realbbmin.Y)), Math.Max(realbbmax.Z, -realbbmin.Z))));

            return true;
        }
        private UBitmap Generate(
            Shema shema,
            AlgorithmType algorithmType,
            CancellationToken token,
            int x,
            int y,
            int w,
            int h,
            int width,
            int height,
            List<double> seeds,
            ProjectionType projection,
            double seaLevel = 0,
            double lng = 0,
            double lat = 0
            )
        {
            __AlgorithmType = algorithmType;

            UColor[,] resultBitmap = null;

            shema.SortByLevel();

            __LayersCount = shema.Layers.Count(l => l.IsEnable);
            __CurrentLayerIndex = 0;

            if (token.IsCancellationRequested)
                return null;

            for (int index = 0; index < shema.Layers.Count; index++)
            {
                if (token.IsCancellationRequested)
                    return null;

                var layer = shema.Layers[index];
                if (!layer.IsEnable)
                    continue;

                double seed = 0;

                if (__CurrentLayerIndex < seeds.Count)
                    seed = seeds[__CurrentLayerIndex];
                else
                {
                    seed = seeds[seeds.Count - 1];

                    for (int i = seeds.Count; i <= __CurrentLayerIndex; i++)
                        seed = rand2(seed, seed);
                }

                __ShadeType = layer.Shade;
                __PlanetAlgorithm = GetAlgorithm(__AlgorithmType, seed, __ShadeType);
                var range = __PlanetAlgorithm.GetAltRange();
                __ColorContainer = new ColorContainer(layer, range);

                var layerBmp = MainGen(token, x, y, w, h, width, height, seed, projection, seaLevel, lng, lat);

                if (token.IsCancellationRequested)
                    return null;

                if (resultBitmap == null)
                    resultBitmap = layerBmp;
                else
                {
                    for (int _x = 0; _x < w; _x++)
                    {
                        for (int _y = 0; _y < h; _y++)
                        {
                            var nc = layerBmp[_x, _y];
                            resultBitmap[_x, _y] = UColor.Merge(resultBitmap[_x, _y], nc, 255 - nc.A, nc.A, UColorFlags.R | UColorFlags.G | UColorFlags.B);
                        }
                    }
                }

                __CurrentLayerIndex++;
            }

            return new UBitmap(resultBitmap);
        }
        private IPlanetAlgorithm GetAlgorithm(AlgorithmType type, double seed, ShadeType shadeType)
        {
            IPlanetAlgorithm planetAlgorithm = null;
            switch (type)
            {
                case AlgorithmType.Classic:
                    planetAlgorithm = new GClassic();
                    planetAlgorithm.Initialize(seed, shadeType);
                    break;
                default:
                    throw new NotSupportedException(__AlgorithmType.ToString());
            }

            return planetAlgorithm;
        }
        public bool Load(Stream stream)
        {
            BinaryReader br = new BinaryReader(stream);

            string header = ((char)br.ReadByte()).ToString() + ((char)br.ReadByte()) + ((char)br.ReadByte()) + ((char)br.ReadByte());

            if (header != "GRSM")
            {
                return(false);
            }

            majorVersion = br.ReadByte();
            minorVersion = br.ReadByte();

            _animationLength = br.ReadInt32();
            _shade           = (ShadeType)br.ReadInt32();

            if (majorVersion > 1 || (majorVersion == 1 && minorVersion >= 4))
            {
                _alpha = br.ReadByte();
            }
            else
            {
                _alpha = 255;
            }

            br.ReadBytes(16);

            _textures = new Texture2D[br.ReadInt32()];
            for (int i = 0; i < _textures.Length; i++)
            {
                _textures[i] = SharedInformation.ContentManager.Load <Texture2D>(@"data\texture\" + br.ReadCString(40));
            }

            _mainNodeName = br.ReadCString(40);

            _meshes = new GravityModelMesh[br.ReadInt32()];
            for (int i = 0; i < _meshes.Length; i++)
            {
                GravityModelMesh mesh = new GravityModelMesh();

                mesh.Load(this, br, majorVersion, minorVersion);

                _meshes[i] = mesh;
            }

            _rootMesh = FindMesh(_mainNodeName);
            _rootMesh.CreateChildren(_meshes);

            bbmin = new Vector3(999999, 999999, 999999);
            bbmax = new Vector3(-999999, -999999, -999999);

            _rootMesh.SetBoundingBox(ref bbmin, ref bbmax);
            bbrange = (bbmin + bbmax) / 2.0F;

            Matrix mat = Matrix.CreateScale(1, -1, 1);

            realbbmin = new Vector3(999999, 999999, 999999);
            realbbmax = new Vector3(-999999, -999999, -999999);
            _rootMesh.SetBoundingBox2(mat, ref realbbmin, ref realbbmax);
            realbbrange = (realbbmax + realbbmin) / 2.0F;
            //maxrange = Math.Max(Math.Max(Math.Max(realbbmax.X, -realbbmin.X), Math.Max(realbbmax.Y, -realbbmin.Y)), Math.Max(realbbmax.Z, -realbbmin.Z))));

            return(true);
        }