protected void ParseElement(XmlTextReader r)
        {
            bool readEnd = true;
            // set the field in this object based on the element we just read
            switch (r.Name)
            {
                case "name":
                    // read the value
                    r.Read();
                    if (r.NodeType != XmlNodeType.Text)
                    {
                        return;
                    }
                    name = string.Format("{0} - unique boundary - {1}", r.Value, uniqueNum);
                    uniqueNum++;

                    break;

                case "points":
                    ParsePoints(r);
                    readEnd = false;
                    break;
                case "boundarySemantic":
                    BoundarySemanticType type = BoundarySemanticType.None;

                    for (int i = 0; i < r.AttributeCount; i++)
                    {    
                        r.MoveToAttribute(i);

                        // set the field in this object based on the element we just read
                        switch (r.Name)
                        {
                            case "type":
                                switch (r.Value)
                                {
                                    case "SpeedTreeForest":
                                        type = BoundarySemanticType.SpeedTreeForest;
                                        break;
                                    case "WaterPlane":
                                        type = BoundarySemanticType.WaterPlane;
                                        break;
								    case "Vegetation":
										type = BoundarySemanticType.Vegetation;
										break;
								}
                                break;
                        }
                    }
                    r.MoveToElement(); //Moves the reader back to the element node.

                    switch ( type ) 
                    {
                        case BoundarySemanticType.SpeedTreeForest:
                            Forest forest = new Forest(sceneNode, r);
                            this.AddSemantic(forest);
                            break;
                        case BoundarySemanticType.WaterPlane:
                            WaterPlane water = new WaterPlane(sceneNode, r);
                            this.AddSemantic(water);
                            break;
                        case BoundarySemanticType.Vegetation:
                            VegetationSemantic vegetationBoundary = new VegetationSemantic(r);
                            this.AddSemantic(vegetationBoundary);
                            break;
						default:
                            break;
                    }
                    readEnd = false;
                    break;
            }

            if (readEnd)
            {
                // error out if we dont see an end element here
                r.Read();
                if (r.NodeType != XmlNodeType.EndElement)
                {
                    return;
                }
            }
        }
        protected void ParseElement(XmlTextReader r)
        {
            bool readEnd = true;

            // set the field in this object based on the element we just read
            switch (r.Name)
            {
            case "name":
                // read the value
                r.Read();
                if (r.NodeType != XmlNodeType.Text)
                {
                    return;
                }
                name = string.Format("{0} - unique boundary - {1}", r.Value, uniqueNum);
                uniqueNum++;

                break;

            case "points":
                ParsePoints(r);
                readEnd = false;
                break;

            case "boundarySemantic":
                BoundarySemanticType type = BoundarySemanticType.None;

                for (int i = 0; i < r.AttributeCount; i++)
                {
                    r.MoveToAttribute(i);

                    // set the field in this object based on the element we just read
                    switch (r.Name)
                    {
                    case "type":
                        switch (r.Value)
                        {
                        case "SpeedTreeForest":
                            type = BoundarySemanticType.SpeedTreeForest;
                            break;

                        case "WaterPlane":
                            type = BoundarySemanticType.WaterPlane;
                            break;

                        case "Vegetation":
                            type = BoundarySemanticType.Vegetation;
                            break;
                        }
                        break;
                    }
                }
                r.MoveToElement();     //Moves the reader back to the element node.

                switch (type)
                {
                case BoundarySemanticType.SpeedTreeForest:
                    Forest forest = new Forest(sceneNode, r);
                    this.AddSemantic(forest);
                    break;

                case BoundarySemanticType.WaterPlane:
                    WaterPlane water = new WaterPlane(sceneNode, r);
                    this.AddSemantic(water);
                    break;

                case BoundarySemanticType.Vegetation:
                    VegetationSemantic vegetationBoundary = new VegetationSemantic(r);
                    this.AddSemantic(vegetationBoundary);
                    break;

                default:
                    break;
                }
                readEnd = false;
                break;
            }

            if (readEnd)
            {
                // error out if we dont see an end element here
                r.Read();
                if (r.NodeType != XmlNodeType.EndElement)
                {
                    return;
                }
            }
        }
        private void AddContent(bool drawForest1, bool drawForest2, bool lakes, bool ocean, bool buildings, bool roads)
        {
            if (drawForest1 || drawForest2)
            {
                treeSceneNode = scene.RootSceneNode.CreateChildSceneNode("Trees");
            }

            bool betaWorldForest = false;

            if (betaWorldForest)
            {
                boundary1 = new Boundary("boundary1");
                boundary1.AddPoint(new Vector3(441 * oneMeter, 0, 4269 * oneMeter));
                boundary1.AddPoint(new Vector3(105 * oneMeter, 0, 4278 * oneMeter));
                boundary1.AddPoint(new Vector3(66 * oneMeter, 0, 4162 * oneMeter));
                boundary1.AddPoint(new Vector3(-132 * oneMeter, 0, 4102 * oneMeter));
                boundary1.AddPoint(new Vector3(-540 * oneMeter, 0, 3658 * oneMeter));
                boundary1.AddPoint(new Vector3(-639 * oneMeter, 0, 3570 * oneMeter));
                boundary1.AddPoint(new Vector3(182 * oneMeter, 0, 3510 * oneMeter));
                boundary1.AddPoint(new Vector3(236 * oneMeter, 0, 3845 * oneMeter));
                boundary1.AddPoint(new Vector3(382 * oneMeter, 0, 3966 * oneMeter));
                boundary1.Close();

                //boundary1.Hilight = true;

                mvScene.AddBoundary(boundary1);

                forest = new Forest(1234, "Forest1", treeSceneNode);
                boundary1.AddSemantic(forest);

                forest.WindFilename = "demoWind.ini";

                forest.WindDirection = Vector3.UnitX;
                forest.WindStrength = 0.0f;

                forest.AddTreeType("CedarOfLebanon_RT.spt", 55 * 300, 0, 4);
                forest.AddTreeType("WeepingWillow_RT.spt", 50 * 300, 0, 5);
                forest.AddTreeType("DatePalm_RT.spt", 40 * 300, 0, 16);

                Boundary boundary4 = new Boundary("boundary4");
                boundary4.AddPoint(new Vector3(441 * oneMeter, 0, 4269 * oneMeter));
                boundary4.AddPoint(new Vector3(105 * oneMeter, 0, 4278 * oneMeter));
                boundary4.AddPoint(new Vector3(66 * oneMeter, 0, 4162 * oneMeter));
                boundary4.AddPoint(new Vector3(-132 * oneMeter, 0, 4102 * oneMeter));
                boundary4.AddPoint(new Vector3(-540 * oneMeter, 0, 3658 * oneMeter));
                boundary4.AddPoint(new Vector3(-639 * oneMeter, 0, 3570 * oneMeter));
                boundary4.AddPoint(new Vector3(182 * oneMeter, 0, 3510 * oneMeter));
                boundary4.AddPoint(new Vector3(236 * oneMeter, 0, 3845 * oneMeter));
                boundary4.AddPoint(new Vector3(382 * oneMeter, 0, 3966 * oneMeter));
                boundary4.Close();

                //boundary1.Hilight = true;

                mvScene.AddBoundary(boundary4);

                Forest forest4 = new Forest(1234, "Forest4", treeSceneNode);
                boundary4.AddSemantic(forest);

                forest4.WindFilename = "demoWind.ini";

                forest4.WindDirection = Vector3.UnitX;
                forest4.WindStrength = 1.0f;

                forest4.AddTreeType("DatePalm_RT.spt", 40 * 300, 0, 14);
                forest4.AddTreeType("CoconutPalm_RT.spt", 55 * 300, 0, 23);
                forest4.AddTreeType("CinnamonFern_RT.spt", 70 * 300, 0, 14);

                boundary2 = new Boundary("boundary2");
                boundary2.AddPoint(new Vector3(285 * oneMeter, 0, 3462 * oneMeter));
                boundary2.AddPoint(new Vector3(-679 * oneMeter, 0, 3560 * oneMeter));
                boundary2.AddPoint(new Vector3(-647 * oneMeter, 0, 3381 * oneMeter));
                boundary2.AddPoint(new Vector3(-512 * oneMeter, 0, 3230 * oneMeter));
                boundary2.AddPoint(new Vector3(402 * oneMeter, 0, 3116 * oneMeter));
                boundary2.AddPoint(new Vector3(402 * oneMeter, 0, 3339 * oneMeter));
                boundary2.AddPoint(new Vector3(305 * oneMeter, 0, 3363 * oneMeter));
                boundary2.Close();

                mvScene.AddBoundary(boundary2);

                Forest forest2 = new Forest(1234, "Forest2", treeSceneNode);

                boundary2.AddSemantic(forest2);

                forest2.WindFilename = "demoWind.ini";

                forest2.WindDirection = Vector3.UnitX;
                forest2.WindStrength = 1.0f;

                forest2.AddTreeType("SpiderTree_RT_Dead.spt", 80 * 300, 0, 23);
                forest2.AddTreeType("CinnamonFern_RT.spt", 70 * 300, 0, 12);
                forest2.AddTreeType("CoconutPalm_RT.spt", 55 * 300, 0, 12);

                Boundary boundary3 = new Boundary("boundary3");
                boundary3.AddPoint(new Vector3(285 * oneMeter, 0, 3462 * oneMeter));
                boundary3.AddPoint(new Vector3(-679 * oneMeter, 0, 3560 * oneMeter));
                boundary3.AddPoint(new Vector3(-647 * oneMeter, 0, 3381 * oneMeter));
                boundary3.AddPoint(new Vector3(-512 * oneMeter, 0, 3230 * oneMeter));
                boundary3.AddPoint(new Vector3(402 * oneMeter, 0, 3116 * oneMeter));
                boundary3.AddPoint(new Vector3(402 * oneMeter, 0, 3339 * oneMeter));
                boundary3.AddPoint(new Vector3(305 * oneMeter, 0, 3363 * oneMeter));
                boundary3.Close();

                mvScene.AddBoundary(boundary3);

                Forest forest3 = new Forest(1234, "Forest3", treeSceneNode);

                boundary3.AddSemantic(forest3);

                forest3.WindFilename = "demoWind.ini";

                forest3.WindDirection = Vector3.UnitX;
                forest3.WindStrength = 1.0f;

                forest3.AddTreeType("DatePalm_RT.spt", 40 * 300, 0, 14);
                forest3.AddTreeType("AmericanHolly_RT.spt", 40 * 300, 0, 24);
                forest3.AddTreeType("CoconutPalm_RT.spt", 55 * 300, 0, 23);
                forest3.AddTreeType("SpiderTree_RT_Dead.spt", 80 * 300, 0, 9);
            }

            if (drawForest1)
            {
                boundary1 = new Boundary("boundary1");
                boundary1.AddPoint(new Vector3(441 * oneMeter, 0, 4269 * oneMeter));
                boundary1.AddPoint(new Vector3(105 * oneMeter, 0, 4278 * oneMeter));
                boundary1.AddPoint(new Vector3(66 * oneMeter, 0, 4162 * oneMeter));
                boundary1.AddPoint(new Vector3(-132 * oneMeter, 0, 4102 * oneMeter));
                boundary1.AddPoint(new Vector3(-540 * oneMeter, 0, 3658 * oneMeter));
                boundary1.AddPoint(new Vector3(-639 * oneMeter, 0, 3570 * oneMeter));
                boundary1.AddPoint(new Vector3(182 * oneMeter, 0, 3510 * oneMeter));
                boundary1.AddPoint(new Vector3(236 * oneMeter, 0, 3845 * oneMeter));
                boundary1.AddPoint(new Vector3(382 * oneMeter, 0, 3966 * oneMeter));
                boundary1.Close();

                //boundary1.Hilight = true;

                mvScene.AddBoundary(boundary1);

                forest = new Forest(1234, "Forest1", treeSceneNode);
                boundary1.AddSemantic(forest);

                forest.WindFilename = "demoWind.ini";

                forest.WindDirection = Vector3.UnitX;
                forest.WindStrength = 1.0f;

                //forest.AddTreeType("EnglishOak_RT.spt", 55 * 300, 0, 100);
                //forest.AddTreeType("AmericanHolly_RT.spt", 40 * 300, 0, 100);
                //forest.AddTreeType("ChristmasScotchPine_RT.spt", 70 * 300, 0, 100);

                //forest.AddTreeType("CedarOfLebanon_RT.spt", 55 * 300, 0, 4);
                //forest.AddTreeType("WeepingWillow_RT.spt", 50 * 300, 0, 5);
                //forest.AddTreeType("DatePalm_RT.spt", 40 * 300, 0, 16);
                //forest.AddTreeType("DatePalm_RT.spt", 40 * 300, 0, 14);
                //forest.AddTreeType("CoconutPalm_RT.spt", 55 * 300, 0, 23);
                //forest.AddTreeType("CinnamonFern_RT.spt", 70 * 300, 0, 14);
                //forest.AddTreeType("SpiderTree_RT_Dead.spt", 80 * 300, 0, 23);
                //forest.AddTreeType("CinnamonFern_RT.spt", 70 * 300, 0, 12);
                //forest.AddTreeType("CoconutPalm_RT.spt", 55 * 300, 0, 12);
                //forest.AddTreeType("DatePalm_RT.spt", 40 * 300, 0, 14);
                //forest.AddTreeType("AmericanHolly_RT.spt", 40 * 300, 0, 24);
                //forest.AddTreeType("CoconutPalm_RT.spt", 55 * 300, 0, 23);
                //forest.AddTreeType("SpiderTree_RT_Dead.spt", 80 * 300, 0, 9);

                uint numinstances = 50;

                //forest.AddTreeType("Azalea_RT.spt", 55 * 300, 0, numinstances);
                //forest.AddTreeType("Azalea_RT_Pink.spt", 55 * 300, 0, numinstances);
                //forest.AddTreeType("AzaleaPatch_RT.spt", 55 * 300, 0, numinstances);
                //forest.AddTreeType("AzaleaPatch_RT_Pink.spt", 55 * 300, 0, numinstances);

                //forest.AddTreeType("CurlyPalm_RT.spt", 55 * 300, 0, numinstances);
                //forest.AddTreeType("CurlyPalmCluster_RT.spt", 55 * 300, 0, numinstances);

                //forest.AddTreeType("FraserFir_RT.spt", 55 * 300, 0, numinstances);
                //forest.AddTreeType("FraserFir_RT_Snow.spt", 55 * 300, 0, numinstances);
                //forest.AddTreeType("FraserFirCluster_RT.spt", 55 * 300, 0, numinstances);
                //forest.AddTreeType("FraserFirCluster_RT_Snow.spt", 55 * 300, 0, numinstances);

                forest.AddTreeType("RDApple_RT.spt", 55 * 300, 0, numinstances);
                //forest.AddTreeType("RDApple_RT_Apples.spt", 55 * 300, 0, numinstances);
                //forest.AddTreeType("RDApple_RT_Spring.spt", 55 * 300, 0, numinstances);
                //forest.AddTreeType("RDApple_RT_Winter.spt", 55 * 300, 0, numinstances);

                forest.AddTreeType("UmbrellaThorn_RT.spt", 55 * 300, 0, numinstances);
                //forest.AddTreeType("UmbrellaThorn_RT_Dead.spt", 55 * 300, 0, numinstances);
                //forest.AddTreeType("UmbrellaThorn_RT_Flowers.spt", 55 * 300, 0, numinstances);

                //forest.AddTreeType("WeepingWillow_RT.spt", 55 * 300, 0, numinstances);
                //forest.AddTreeType("WeepingWillow_RT_Fall.spt", 55 * 300, 0, numinstances);
                //forest.AddTreeType("WeepingWillow_RT_Winter.spt", 55 * 300, 0, numinstances);

                //forest.AddTreeType("AmericanBoxwood_RT.spt", 55 * 300, 0, numinstances);
                //forest.AddTreeType("AmericanBoxwoodCluster_RT.spt", 55 * 300, 0, numinstances);

                //forest.AddTreeType("Beech_RT.spt", 55 * 300, 0, numinstances);
                //forest.AddTreeType("Beech_RT_Fall.spt", 55 * 300, 0, numinstances);
                //forest.AddTreeType("Beech_RT_Winter.spt", 55 * 300, 0, numinstances);

                forest.AddTreeType("SugarPine_RT.spt", 55 * 300, 0, numinstances);
                //forest.AddTreeType("SugarPine_RT_Winter.spt", 55 * 300, 0, numinstances);

                //forest.AddTreeType("VenusTree_RT.spt", 55 * 300, 0, numinstances);

                //forest.AddTreeType("CherryTree_RT.spt", 55 * 300, 0, numinstances);
                //forest.AddTreeType("CherryTree_RT_Spring.spt", 55 * 300, 0, numinstances);
                //forest.AddTreeType("CherryTree_RT_Fall.spt", 55 * 300, 0, numinstances);
                //forest.AddTreeType("CherryTree_RT_Winter.spt", 55 * 300, 0, numinstances);

                //forest.AddTreeType("SpiderTree_RT.spt", 55 * 300, 0, numinstances);
                //forest.AddTreeType("SpiderTree_RT_Dead.spt", 55 * 300, 0, numinstances);

                //forest.AddTreeType("JungleBrush_RT.spt", 55 * 300, 0, numinstances);

                forest.AddTreeType("QueenPalm_RT.spt", 55 * 300, 0, numinstances);
                //forest.AddTreeType("QueenPalm_RT_Flowers.spt", 55 * 300, 0, numinstances);
                //forest.AddTreeType("QueenPalmCluster_RT.spt", 55 * 300, 0, numinstances);

                if (false)
                {
                    //uint numinstances = 30;
                    forest.AddTreeType("CurlyPalm_RT.spt", 55 * 300, 0, numinstances);
                    forest.AddTreeType("DatePalm_RT.spt", 40 * 300, 0, numinstances);
                    forest.AddTreeType("JungleBrush_RT.spt", 70 * 300, 0, numinstances);
                    forest.AddTreeType("Cercropia_RT.spt", 55 * 300, 0, numinstances);
                    forest.AddTreeType("CommonOlive_RT_Summer.spt", 40 * 300, 0, numinstances);
                    forest.AddTreeType("ColvilleaRacemosa_RT_Flower.spt", 70 * 300, 0, numinstances);
                    forest.AddTreeType("JapaneseAngelica_RT_Summer.spt", 55 * 300, 0, numinstances);
                    forest.AddTreeType("NorthIslandRata_RT_Spring.spt", 40 * 300, 0, numinstances);
                    forest.AddTreeType("SpiderTree_RT.spt", 70 * 300, 0, numinstances);
                    forest.AddTreeType("Stump_RT.spt", 150 * 300, 0, numinstances);
                    forest.AddTreeType("UmbrellaThorn_RT_Flowers.spt", 70 * 300, 0, numinstances);

                    forest.AddTreeType("AmurCork_RT_LateSummer.spt", 55 * 300, 0, numinstances);
                    forest.AddTreeType("ArizonaBush_RT_Flowers.spt", 40 * 300, 0, numinstances);
                    forest.AddTreeType("BananaTree_RT.spt", 70 * 300, 0, numinstances);
                    forest.AddTreeType("Baobab_RT.spt", 55 * 300, 0, numinstances);
                    forest.AddTreeType("CaliforniaBuckeye_RT_Nuts.spt", 120 * 300, 0, numinstances);

                    forest.AddTreeType("CedarOfLebanon_RT.spt", 55 * 300, 0, numinstances);
                    forest.AddTreeType("CherryTree_RT_Spring.spt", 40 * 300, 0, numinstances);
                    forest.AddTreeType("CinnamonFern_RT.spt", 70 * 300, 0, numinstances);
                    forest.AddTreeType("CoconutPalm_RT.spt", 55 * 300, 0, numinstances);
                    forest.AddTreeType("Crepe Myrtle_RT_Flowers.spt", 120 * 300, 0, numinstances);
                }
                //forest.AddTreeType("CedarOfLebanon_RT.spt", 100 * 300, 0, 30);
                //forest.AddTreeType("CherryTree_RT_Spring.spt", 40 * 300, 0, 30);
                //forest.AddTreeType("CinnamonFern_RT.spt", 70 * 300, 0, 30);
                //forest.AddTreeType("CoconutPalm_RT.spt", 55 * 300, 0, 30);
                //forest.AddTreeType("Crepe Myrtle_RT_Flowers.spt", 120 * 300, 0, 30);

                if (false)
                {
                    forest.AddTreeType("Crepe Myrtle_RT_Winter.spt", 100 * 300, 0, 30);
                    forest.AddTreeType("FanPalm_RT.spt", 40 * 300, 0, 30);
                    forest.AddTreeType("ItalianCypress_RT.spt", 70 * 300, 0, 30);
                    forest.AddTreeType("JapaneseMaple_RT_Summer.spt", 55 * 300, 0, 30);
                    forest.AddTreeType("JoshuaTree_RT.spt", 120 * 300, 0, 30);

                    forest.AddTreeType("KoreanStewartia_RT.spt", 100 * 300, 0, 30);
                    forest.AddTreeType("ManchurianAngelicaTree_RT_Small.spt", 100 * 300, 0, 30);
                    forest.AddTreeType("MimosaTree_RT.spt", 100 * 300, 0, 30);
                    forest.AddTreeType("MimosaTree_RT_Flower.spt", 100 * 300, 0, 30);
                    forest.AddTreeType("Mulga_RT_Flowers.spt", 50 * 300, 0, 30);

                    forest.AddTreeType("OmenTree_RT.spt", 80 * 300, 0, 30);
                    forest.AddTreeType("OrientalSpruce_RT.spt", 50 * 300, 0, 30);
                    forest.AddTreeType("PonytailPalm_RT.spt", 140 * 300, 0, 30);
                    forest.AddTreeType("QueenPalm_RT.spt", 55 * 300, 0, 30);
                    forest.AddTreeType("ColvilleaRacemosa_RT.spt", 50 * 300, 0, 30);

                    forest.AddTreeType("SpiderTree_RT_Dead.spt", 80 * 300, 0, 30);
                    forest.AddTreeType("Tamarind_RT_Spring.spt", 50 * 300, 0, 30);
                    forest.AddTreeType("WeepingWillow_RT.spt", 50 * 300, 0, 30);
                }
            }

            if ( drawForest2 ) {
                boundary2 = new Boundary("boundary2");
                boundary2.AddPoint(new Vector3(285 * oneMeter, 0, 3462 * oneMeter));
                boundary2.AddPoint(new Vector3(-679 * oneMeter, 0, 3560 * oneMeter));
                boundary2.AddPoint(new Vector3(-647 * oneMeter, 0, 3381 * oneMeter));
                boundary2.AddPoint(new Vector3(-512 * oneMeter, 0, 3230 * oneMeter));
                boundary2.AddPoint(new Vector3(402 * oneMeter, 0, 3116 * oneMeter));
                boundary2.AddPoint(new Vector3(402 * oneMeter, 0, 3339 * oneMeter));
                boundary2.AddPoint(new Vector3(305 * oneMeter, 0, 3363 * oneMeter));
                boundary2.Close();

                mvScene.AddBoundary(boundary2);

                Forest forest2 = new Forest(1234, "Forest2", treeSceneNode);

                boundary2.AddSemantic(forest2);

                forest2.WindFilename = "demoWind.ini";

                forest2.AddTreeType("EnglishOak_RT.spt", 55 * 300, 0, 150);
                forest2.AddTreeType("AmericanHolly_RT.spt", 40 * 300, 0, 150);
                forest2.AddTreeType("ChristmasScotchPine_RT.spt", 70 * 300, 0, 150);

                forest2.WindDirection = Vector3.UnitX;
                forest2.WindStrength = 0f;
            }

            if (lakes)
            {
                boundary3 = new Boundary("boundary3");
                boundary3.AddPoint(new Vector3(-540 * oneMeter, 0, 3151 * oneMeter));
                boundary3.AddPoint(new Vector3(-656 * oneMeter, 0, 3058 * oneMeter));
                boundary3.AddPoint(new Vector3(-631 * oneMeter, 0, 2878 * oneMeter));
                boundary3.AddPoint(new Vector3(-335 * oneMeter, 0, 2882 * oneMeter));
                boundary3.AddPoint(new Vector3(-336 * oneMeter, 0, 3098 * oneMeter));
                boundary3.AddPoint(new Vector3(-478 * oneMeter, 0, 3166 * oneMeter));
                boundary3.Close();

                //boundary3.Hilight = true;

                mvScene.AddBoundary(boundary3);

                WaterPlane waterSemantic = new WaterPlane(42 * WorldManager.oneMeter, "lake1", treeSceneNode);

                boundary3.AddSemantic(waterSemantic);

            }

            if (buildings)
            {
                Entity entity = scene.CreateEntity("tree", "demotree4.mesh");

                SceneNode node = scene.RootSceneNode.CreateChildSceneNode();
                node.AttachObject(entity);
                node.Position = new Vector3(332383, 71536, 4247994);

                entity = scene.CreateEntity("house", "human_house_stilt.mesh");

                node = scene.RootSceneNode.CreateChildSceneNode();
                node.AttachObject(entity);
                node.Position = new Vector3(0, 130.0f * oneMeter, 3900 * oneMeter);

            }

            if (ocean)
            {
                Entity waterEntity = scene.CreateEntity("Water", "WaterPlane");

                Debug.Assert(waterEntity != null);
                waterEntity.MaterialName = "MVSMOcean";

                SceneNode waterNode = scene.RootSceneNode.CreateChildSceneNode("WaterNode");
                Debug.Assert(waterNode != null);
                waterNode.AttachObject(waterEntity);
                waterNode.Translate(new Vector3(0, 0, 0));
            }

            if (roads)
            {
                road1 = mvScene.CreateRoad("Via Appia");
                road1.HalfWidth = 2;

                List<Vector3> roadPoints = new List<Vector3>();
                roadPoints.Add(new Vector3(97000, 0, 4156000));
                roadPoints.Add(new Vector3(205000, 0, 4031000));
                roadPoints.Add(new Vector3(254000, 0, 3954000));
                roadPoints.Add(new Vector3(234000, 0, 3500000));
                roadPoints.Add(new Vector3(256000, 0, 3337000));
                roadPoints.Add(new Vector3(98000, 0, 3242000));

                road1.AddPoints(roadPoints);

            }
        }
        public TreeGroup(String filename, float size, float sizeVariance, SpeedWindWrapper speedWind, Forest forest, List<Vector3> locations)
        {
            if (!initialized)
            {
                Initialize();
            }

            name = String.Format("Forest: {0} File: {1} Instances: {2}", forest.Name, filename, locations.Count);
            this.forest = forest;

            this.speedWind = speedWind;

            speedTree = new SpeedTreeWrapper();

            speedTree.TextureFlip = true;
            LoadTree(filename);
            speedTree.BranchWindMethod = WindMethod.WindGPU;
            speedTree.FrondWindMethod = WindMethod.WindGPU;
            speedTree.LeafWindMethod = WindMethod.WindGPU;

            float originalSize = 0f;
            float variance = 0f;
            speedTree.GetTreeSize(ref originalSize, ref variance);
            speedTree.OriginalSize = originalSize;
            speedTree.SetTreeSize(size, sizeVariance);

            treeTextures = speedTree.Textures;

            // make sure the tree doesn't have too many leaf texture groups
            Debug.Assert(treeTextures.LeafTextureFilenames.Length <= 3);

            // for trees with 3 leaf textures, reduce the number of rocking groups to 2
            // (from the default of 3), so that we don't overflow the number of available shader
            // param registers
            if (treeTextures.LeafTextureFilenames.Length == 3)
            {
                speedTree.NumLeafRockingGroups = 2;
            }

            speedTree.Compute(SpeedTreeUtil.ToSpeedTree(Matrix4.Identity), 1, true);

            speedTree.TreePosition = SpeedTreeUtil.ToSpeedTree(Vector3.Zero);

            // set lod limits
            speedTree.SetLodLimits(nearLOD, farLOD);

            // create the geometry object
            geometry = new TreeGeometry();

            //
            // Setup branches
            //

            // create the render operation
            branchRenderOp = new RenderOperation();
            branchRenderOp.operationType = OperationType.TriangleStrip;
            branchRenderOp.useIndices = true;

            // set up the material.
            branchMaterial = SetupTreeMaterial("SpeedTree/Branch", treeTextures.BranchTextureFilename, treeTextures.SelfShadowFilename, GenerateNormalMapTextureName(treeTextures.BranchTextureFilename), speedTree.BranchMaterial, !normalMapped, branchTechnique);

            // get number of branch LODs
            uint nBranchLODs = speedTree.NumBranchLodLevels;

            // allocate branch buffers
            branchVertexBuffers = new VertexData[nBranchLODs];
            branchIndexBuffers = new IndexData[nBranchLODs];

            for (short i = 0; i < nBranchLODs; i++)
            {
                // set up the vertex and index buffers for the branch geometry
                speedTree.GetGeometry(geometry, SpeedTreeWrapper.GeometryFlags.BranchGeometry, i, -1, -1);
                BuildIndexedBuffer(geometry.Branches, true, out branchVertexBuffers[i], out branchIndexBuffers[i]);
            }
            //
            // Setup fronds
            //

            // create the render operation
            frondRenderOp = new RenderOperation();
            frondRenderOp.operationType = OperationType.TriangleStrip;
            frondRenderOp.useIndices = true;

            // set up the material
            frondMaterial = SetupTreeMaterial("SpeedTree/Frond", treeTextures.CompositeFilename, treeTextures.SelfShadowFilename, null, speedTree.FrondMaterial, true, 0);

            uint nFrondLODs = speedTree.NumFrondLodLevels;

            // allocate frond buffer arrays
            frondVertexBuffers = new VertexData[nFrondLODs];
            frondIndexBuffers = new IndexData[nFrondLODs];

            for ( short i = 0; i < nFrondLODs; i++ )
            {
                // build the frond geometry for each LOD
                speedTree.GetGeometry(geometry, SpeedTreeWrapper.GeometryFlags.FrondGeometry, -1, i, -1);
                BuildIndexedBuffer(geometry.Fronds, false, out frondVertexBuffers[i], out frondIndexBuffers[i]);
            }

            //
            // Setup Leaves
            //

            TreeCamera saveCam = SpeedTreeWrapper.Camera;

            TreeCamera treeCamera = new TreeCamera();
            treeCamera.position = SpeedTreeUtil.ToSpeedTree(Vector3.Zero);
            treeCamera.direction = SpeedTreeUtil.ToSpeedTree(new Vector3(1,0,0));
            SpeedTreeWrapper.Camera = treeCamera;

            // set up render ops
            leaf0RenderOp = new RenderOperation();
            leaf0RenderOp.operationType = OperationType.TriangleList;
            leaf0RenderOp.useIndices = true;

            leaf1RenderOp = new RenderOperation();
            leaf1RenderOp.operationType = OperationType.TriangleList;
            leaf1RenderOp.useIndices = true;

            // set up the material
            leafMaterial = SetupTreeMaterial("SpeedTree/Leaf", treeTextures.CompositeFilename, null, null, speedTree.LeafMaterial, true, 0);

            uint nLeafLODs = speedTree.NumLeafLodLevels;

            // allocate leaf buffer arrays
            leafVertexBuffers = new VertexData[nLeafLODs];
            leafIndexBuffers = new IndexData[nLeafLODs];

            float [] lodLeafAdjust = speedTree.LeafLodSizeAdjustments;

            for ( short i = 0; i < nLeafLODs; i++ )
            {
                // build the leaf geometry for each LOD
                speedTree.GetGeometry(geometry, SpeedTreeWrapper.GeometryFlags.LeafGeometry, -1, -1, i);
                BuildLeafBuffer(geometry.Leaves0, lodLeafAdjust[i], out leafVertexBuffers[i], out leafIndexBuffers[i]);
            }

            // restore the camera afte getting leaf buffers
            SpeedTreeWrapper.Camera = saveCam;

            bounds = new AxisAlignedBox();

            // build all the trees and accumulate bounds
            foreach (Vector3 loc in locations)
            {
                SpeedTreeWrapper treeInstance = speedTree.MakeInstance();
                treeInstance.OriginalSize = originalSize;
                Tree t = new Tree(this, treeInstance, loc);

                bounds.Merge(t.Bounds);

                trees.Add(t);
            }

            boundingRadius = (bounds.Maximum - bounds.Minimum).Length / 2;

            // create the buckets
            branchBuckets = new Dictionary<int, List<Tree>>[nBranchLODs];
            frondBuckets = new Dictionary<int, List<Tree>>[nFrondLODs];
            leafBuckets = new Dictionary<int, List<Tree>>[nLeafLODs];
            billboardBucket = new Dictionary<int, List<Tree>>[1];

            // initialize the bucket dictionaries
            for (int i = 0; i < nBranchLODs; i++)
            {
                branchBuckets[i] = new Dictionary<int, List<Tree>>();
            }
            for (int i = 0; i < nFrondLODs; i++)
            {
                frondBuckets[i] = new Dictionary<int, List<Tree>>();
            }
            for (int i = 0; i < nLeafLODs; i++)
            {
                leafBuckets[i] = new Dictionary<int, List<Tree>>();
            }
            billboardBucket[0] = new Dictionary<int, List<Tree>>();
            allGroups.Add(this);
        }