Пример #1
0
        public override void LoadWorldGeometry(string fileName)
        {
            var serializer = new XmlSerializer(typeof(TerrainOptions));

            this.options = (TerrainOptions)serializer.Deserialize(ResourceGroupManager.Instance.OpenResource(fileName));

            this.scale    = new Vector3(this.options.scalex, this.options.scaley, this.options.scalez);
            this.tileSize = this.options.size;
            // load the heightmap
            {
                Image image = Image.FromStream(ResourceGroupManager.Instance.OpenResource(this.options.Terrain),
                                               this.options.Terrain.Split('.')[1]);
                worldSize = this.options.worldSize = image.Width;
                var    dest = new Real[(int)worldSize * (int)worldSize];
                byte[] src  = image.Data;
                Real   invScale;

                //if ( image.Format != PixelFormat.L8 && image.Format != PixelFormat.L16 )
                //    throw new AxiomException( "Heightmap is not a grey scale image!" );

                bool is16bit = (image.Format == PixelFormat.L16);

                // Determine mapping from fixed to floating
                ulong rowSize;
                if (is16bit)
                {
                    invScale = 1.0f / 65535.0f;
                    rowSize  = (ulong)worldSize * 2;
                }
                else
                {
                    invScale = 1.0f;                     // / 255.0f;
                    rowSize  = (ulong)worldSize;
                }
                // Read the data
                int srcIndex = 0;
                int dstIndex = 0;
                for (ulong j = 0; j < (ulong)worldSize; ++j)
                {
                    for (ulong i = 0; i < (ulong)worldSize; ++i)
                    {
                        if (is16bit)
                        {
#if AXIOM_BIG_ENDIAN
                            ushort val = (ushort)(src[srcIndex++] << 8);
                            val += src[srcIndex++];
#else
                            ushort val = src[srcIndex++];
                            val += (ushort)(src[srcIndex++] << 8);
#endif
                            dest[dstIndex++] = new Real(val) * invScale;
                        }
                        else
                        {
                            dest[dstIndex++] = new Real(src[srcIndex++]);                                   // *invScale;
#if (XBOX || XBOX360)
                            srcIndex += 3;
#endif
                        }
                    }
                }

                // get the data from the heightmap
                this.options.data = dest;
            }

            float maxx = this.options.scalex * this.options.worldSize;
            float maxy = 255 * this.options.scaley;
            float maxz = this.options.scalez * this.options.worldSize;

            Resize(new AxisAlignedBox(Vector3.Zero, new Vector3(maxx, maxy, maxz)));

            this.terrainMaterial =
                (Material)
                (MaterialManager.Instance.CreateOrRetrieve(
                     !String.IsNullOrEmpty(this.options.MaterialName) ? this.options.MaterialName : "Terrain",
                     ResourceGroupManager.Instance.WorldResourceGroupName).First);

            if (this.options.WorldTexture != "")
            {
                this.terrainMaterial.GetTechnique(0).GetPass(0).CreateTextureUnitState(this.options.WorldTexture, 0);
            }

            if (this.options.DetailTexture != "")
            {
                this.terrainMaterial.GetTechnique(0).GetPass(0).CreateTextureUnitState(this.options.DetailTexture, 1);
            }

            this.terrainMaterial.Lighting = this.options.isLit;
            this.terrainMaterial.Load();

            this.terrainRoot = (SceneNode)RootSceneNode.CreateChild("TerrainRoot");

            this.numTiles = (this.options.worldSize - 1) / (this.options.size - 1);

            this.tiles = new TerrainRenderable[this.numTiles, this.numTiles];

            int p = 0, q = 0;

            for (int j = 0; j < this.options.worldSize - 1; j += (this.options.size - 1))
            {
                p = 0;

                for (int i = 0; i < this.options.worldSize - 1; i += (this.options.size - 1))
                {
                    this.options.startx = i;
                    this.options.startz = j;

                    string name = string.Format("Tile[{0},{1}]", p, q);

                    var node = (SceneNode)this.terrainRoot.CreateChild(name);
                    var tile = new TerrainRenderable();
                    tile.Name = name;

                    tile.RenderQueueGroup = WorldGeometryRenderQueueId;

                    tile.SetMaterial(this.terrainMaterial);
                    tile.Init(this.options);

                    this.tiles[p, q] = tile;

                    node.AttachObject(tile);

                    p++;
                }

                q++;
            }

            int size1 = this.tiles.GetLength(0);
            int size2 = this.tiles.GetLength(1);

            for (int j = 0; j < size1; j++)
            {
                for (int i = 0; i < size2; i++)
                {
                    if (j != size1 - 1)
                    {
                        this.tiles[i, j].SetNeighbor(Neighbor.South, this.tiles[i, j + 1]);
                        this.tiles[i, j + 1].SetNeighbor(Neighbor.North, this.tiles[i, j]);
                    }

                    if (i != size2 - 1)
                    {
                        this.tiles[i, j].SetNeighbor(Neighbor.East, this.tiles[i + 1, j]);
                        this.tiles[i + 1, j].SetNeighbor(Neighbor.West, this.tiles[i, j]);
                    }
                }
            }

            if (this.options.isLit)
            {
                for (int j = 0; j < size1; j++)
                {
                    for (int i = 0; i < size2; i++)
                    {
                        this.tiles[i, j].CalculateNormals();
                    }
                }
            }
        }
        public override void LoadWorldGeometry(string fileName)
        {
            TerrainOptions options = new TerrainOptions();

            DataSet optionData = new DataSet();

            optionData.ReadXml(fileName);
            DataTable table = optionData.Tables[0];
            DataRow   row   = table.Rows[0];

            string terrainFileName = "";
            string detailTexture   = "";
            string worldTexture    = "";

            if (table.Columns["Terrain"] != null)
            {
                terrainFileName = (string)row["Terrain"];
            }

            if (table.Columns["DetailTexture"] != null)
            {
                detailTexture = (string)row["DetailTexture"];
            }

            if (table.Columns["WorldTexture"] != null)
            {
                worldTexture = (string)row["WorldTexture"];
            }

            if (table.Columns["MaxMipMapLevel"] != null)
            {
                options.maxMipmap = Convert.ToInt32(row["MaxMipMapLevel"]);
            }

            if (table.Columns["DetailTile"] != null)
            {
                options.detailTile = Convert.ToInt32(row["DetailTile"]);
            }

            if (table.Columns["MaxPixelError"] != null)
            {
                options.maxPixelError = Convert.ToInt32(row["MaxPixelError"]);
            }

            if (table.Columns["TileSize"] != null)
            {
                options.size = Convert.ToInt32(row["TileSize"]);
            }

            if (table.Columns["ScaleX"] != null)
            {
                options.scalex = StringConverter.ParseFloat((string)row["ScaleX"]);
            }

            if (table.Columns["ScaleY"] != null)
            {
                options.scaley = StringConverter.ParseFloat((string)row["ScaleY"]);
            }

            if (table.Columns["ScaleZ"] != null)
            {
                options.scalez = StringConverter.ParseFloat((string)row["ScaleZ"]);
            }

            if (table.Columns["VertexNormals"] != null)
            {
                options.isLit = ((string)row["VertexNormals"]) == "yes" ? true : false;
            }

            scale    = new Vector3(options.scalex, options.scaley, options.scalez);
            tileSize = options.size;

            // load the heightmap
            Image image = Image.FromFile(terrainFileName);

            // TODO: Check terrain size for 2^n + 1

            // get the data from the heightmap
            options.data = image.Data;

            options.worldSize = image.Width;

            float maxx = options.scalex * options.worldSize;
            float maxy = 255 * options.scaley;
            float maxz = options.scalez * options.worldSize;

            Resize(new AxisAlignedBox(Vector3.Zero, new Vector3(maxx, maxy, maxz)));

            terrainMaterial = CreateMaterial("Terrain");

            if (worldTexture != "")
            {
                terrainMaterial.GetTechnique(0).GetPass(0).CreateTextureUnitState(worldTexture, 0);
            }

            if (detailTexture != "")
            {
                terrainMaterial.GetTechnique(0).GetPass(0).CreateTextureUnitState(detailTexture, 1);
            }

            terrainMaterial.Lighting = options.isLit;
            terrainMaterial.Load();

            terrainRoot = (SceneNode)RootSceneNode.CreateChild("TerrainRoot");

            numTiles = (options.worldSize - 1) / (options.size - 1);

            tiles = new TerrainRenderable[numTiles, numTiles];

            int p = 0, q = 0;

            for (int j = 0; j < options.worldSize - 1; j += (options.size - 1))
            {
                p = 0;

                for (int i = 0; i < options.worldSize - 1; i += (options.size - 1))
                {
                    options.startx = i;
                    options.startz = j;

                    string name = string.Format("Tile[{0},{1}]", p, q);

                    SceneNode         node = (SceneNode)terrainRoot.CreateChild(name);
                    TerrainRenderable tile = new TerrainRenderable();
                    tile.Name = name;

                    tile.SetMaterial(terrainMaterial);
                    tile.Init(options);

                    tiles[p, q] = tile;

                    node.AttachObject(tile);

                    p++;
                }

                q++;
            }

            int size1 = tiles.GetLength(0);
            int size2 = tiles.GetLength(1);

            for (int j = 0; j < size1; j++)
            {
                for (int i = 0; i < size2; i++)
                {
                    if (j != size1 - 1)
                    {
                        ((TerrainRenderable)tiles[i, j]).SetNeighbor(Neighbor.South, (TerrainRenderable)tiles[i, j + 1]);
                        ((TerrainRenderable)tiles[i, j + 1]).SetNeighbor(Neighbor.North, (TerrainRenderable)tiles[i, j]);
                    }

                    if (i != size2 - 1)
                    {
                        ((TerrainRenderable)tiles[i, j]).SetNeighbor(Neighbor.East, (TerrainRenderable)tiles[i + 1, j]);
                        ((TerrainRenderable)tiles[i + 1, j]).SetNeighbor(Neighbor.West, (TerrainRenderable)tiles[i, j]);
                    }
                }
            }

#if NOT_USED
            if (false)            // && options.isLit) //TODO: Fix
            {
                for (int j = 0; j < size1; j++)
                {
                    for (int i = 0; i < size2; i++)
                    {
                        ((TerrainRenderable)tiles[i, j]).CalculateNormals();
                    }
                }
            }
#endif
            this.terrainOptions = options;             //we need these later for GetHeightAt, so make them a member variable
        }