Ejemplo n.º 1
0
        public TerrainPrimitive(Viewer viewer, TileManager tileManager, Tile tile, int x, int z)
        {
            Viewer = viewer;
            TileX  = tile.TileX;
            TileZ  = tile.TileZ;
            Size   = tile.Size;

            PatchX    = x;
            PatchZ    = z;
            PatchSize = tile.Size * 2048 / tile.PatchCount;

            TileManager = tileManager;
            Tile        = tile;
            Patch       = Tile.GetPatch(x, z);

            var cx = Patch.CenterX - 1024;
            var cz = Patch.CenterZ - 1024 + 2048 * tile.Size;

            PatchLocation     = new Vector3(cx, Tile.Floor, cz);
            PatchVertexBuffer = GetVertexBuffer(out AverageElevation);
            PatchIndexBuffer  = GetIndexBuffer(out PatchPrimitiveCount);

            var terrainMaterial = tile.Size > 2 ? "TerrainSharedDistantMountain" : PatchIndexBuffer == null ? "TerrainShared" : "Terrain";
            var ts = Tile.Shaders[Patch.ShaderIndex].terrain_texslots;
            var uv = Tile.Shaders[Patch.ShaderIndex].terrain_uvcalcs;

            if (ts.Length > 1)
            {
                PatchMaterial = viewer.MaterialManager.Load(terrainMaterial, Helpers.GetTerrainTextureFile(viewer.Simulator, ts[0].Filename) + "\0" + Helpers.GetTerrainTextureFile(viewer.Simulator, ts[1].Filename) +
                                                            (uv[1].D != 0 && uv[1].D != 32 ? "\0" + uv[1].D.ToString(): ""));
            }
            else
            {
                PatchMaterial = viewer.MaterialManager.Load(terrainMaterial, Helpers.GetTerrainTextureFile(viewer.Simulator, ts[0].Filename) + "\0" + Helpers.GetTerrainTextureFile(viewer.Simulator, "microtex.ace"));
            }

            if (SharedPatchIndexBuffer == null)
            {
                SetupSharedData(Viewer.GraphicsDevice);
            }

            Tile  = null;
            Patch = null;

            VertexBufferBindings = new[] { new VertexBufferBinding(PatchVertexBuffer), new VertexBufferBinding(GetDummyVertexBuffer(viewer.GraphicsDevice)) };
        }
Ejemplo n.º 2
0
        private List <VertexPositionNormalTexture> CalculateTrees(TileManager tiles, ForestObj forest, WorldPosition position, out float objectRadius)
        {
            // To get consistent tree placement between sessions, derive the seed from the location.
            var random = new Random((int)(1000.0 * (position.Location.X + position.Location.Z + position.Location.Y)));
            List <TrVectorSection> sections = new List <TrVectorSection>();

            objectRadius = (float)Math.Sqrt(forest.forestArea.X * forest.forestArea.X + forest.forestArea.Z * forest.forestArea.Z) / 2;

            if (MaximumCenterlineOffset > 0)
            {
                Matrix InvForestXNAMatrix = Matrix.Invert(position.XNAMatrix);
                var    addList            = FindTracksAndRoadsClose(position.TileX, position.TileZ);
                FindTracksAndRoadsMoreClose(ref sections, addList, forest, position, InvForestXNAMatrix);


                // Check for cross-tile forests

                List <Vector3> forestVertices = new List <Vector3>();
                var            forestVertex   = new Vector3(-forest.forestArea.X / 2, 0, -forest.forestArea.Z / 2);
                Vector3.Transform(ref forestVertex, ref position.XNAMatrix, out forestVertex);
                forestVertices.Add(forestVertex);
                forestVertex = new Vector3(forest.forestArea.X / 2, 0, -forest.forestArea.Z / 2);
                Vector3.Transform(ref forestVertex, ref position.XNAMatrix, out forestVertex);
                forestVertices.Add(forestVertex);
                forestVertex = new Vector3(-forest.forestArea.X / 2, 0, forest.forestArea.Z / 2);
                Vector3.Transform(ref forestVertex, ref position.XNAMatrix, out forestVertex);
                forestVertices.Add(forestVertex);
                forestVertex = new Vector3(forest.forestArea.X / 2, 0, forest.forestArea.Z / 2);
                Vector3.Transform(ref forestVertex, ref position.XNAMatrix, out forestVertex);
                forestVertices.Add(forestVertex);
                bool[] considerTile = new bool [4] {
                    false, false, false, false
                };
                foreach (var fVertex in forestVertices)
                {
                    if (fVertex.X > 1024)
                    {
                        considerTile[0] = true;
                    }
                    if (fVertex.X < -1024)
                    {
                        considerTile[1] = true;
                    }
                    if (fVertex.Z > 1024)
                    {
                        considerTile[3] = true;
                    }
                    if (fVertex.Z < -1024)
                    {
                        considerTile[2] = true;
                    }
                }

                // add sections in nearby tiles for cross-tile forests
                if (considerTile[0])
                {
                    addList = FindTracksAndRoadsClose(position.TileX + 1, position.TileZ);
                    FindTracksAndRoadsMoreClose(ref sections, addList, forest, position, InvForestXNAMatrix);
                }
                if (considerTile[1])
                {
                    addList = FindTracksAndRoadsClose(position.TileX - 1, position.TileZ);
                    FindTracksAndRoadsMoreClose(ref sections, addList, forest, position, InvForestXNAMatrix);
                }
                if (considerTile[2])
                {
                    addList = FindTracksAndRoadsClose(position.TileX, position.TileZ + 1);
                    FindTracksAndRoadsMoreClose(ref sections, addList, forest, position, InvForestXNAMatrix);
                }
                if (considerTile[3])
                {
                    addList = FindTracksAndRoadsClose(position.TileX, position.TileZ - 1);
                    FindTracksAndRoadsMoreClose(ref sections, addList, forest, position, InvForestXNAMatrix);
                }
                if (considerTile[0] && considerTile[2])
                {
                    addList = FindTracksAndRoadsClose(position.TileX + 1, position.TileZ + 1);
                    FindTracksAndRoadsMoreClose(ref sections, addList, forest, position, InvForestXNAMatrix);
                }
                if (considerTile[0] && considerTile[3])
                {
                    addList = FindTracksAndRoadsClose(position.TileX + 1, position.TileZ - 1);
                    FindTracksAndRoadsMoreClose(ref sections, addList, forest, position, InvForestXNAMatrix);
                }
                if (considerTile[1] && considerTile[2])
                {
                    addList = FindTracksAndRoadsClose(position.TileX - 1, position.TileZ + 1);
                    FindTracksAndRoadsMoreClose(ref sections, addList, forest, position, InvForestXNAMatrix);
                }
                if (considerTile[1] && considerTile[3])
                {
                    addList = FindTracksAndRoadsClose(position.TileX - 1, position.TileZ - 1);
                    FindTracksAndRoadsMoreClose(ref sections, addList, forest, position, InvForestXNAMatrix);
                }
            }


            var trees = new List <VertexPositionNormalTexture>(forest.Population * 6);

            for (var i = 0; i < forest.Population; i++)
            {
                var xnaTreePosition = new Vector3((0.5f - (float)random.NextDouble()) * forest.forestArea.X, 0, (0.5f - (float)random.NextDouble()) * forest.forestArea.Z);
                Vector3.Transform(ref xnaTreePosition, ref position.XNAMatrix, out xnaTreePosition);

                bool onTrack        = false;
                var  scale          = MathHelper.Lerp(forest.scaleRange.Minimum, forest.scaleRange.Maximum, (float)random.NextDouble());
                var  treeSize       = new Vector3(forest.treeSize.Width * scale, forest.treeSize.Height * scale, 1);
                var  heightComputed = false;
                if (MaximumCenterlineOffset > 0 && sections != null && sections.Count > 0)
                {
                    foreach (var section in sections)
                    {
                        onTrack = InitTrackSection(section, xnaTreePosition, position.TileX, position.TileZ, treeSize.X / 2);
                        if (onTrack)
                        {
                            try
                            {
                                var trackShape = Viewer.Simulator.TSectionDat.TrackShapes.Get((uint)section.ShapeIndex);
                                if (trackShape != null && trackShape.TunnelShape)
                                {
                                    xnaTreePosition.Y = tiles.LoadAndGetElevation(position.TileX, position.TileZ, xnaTreePosition.X, -xnaTreePosition.Z, false);
                                    heightComputed    = true;
                                    if (xnaTreePosition.Y > section.Y + 10)
                                    {
                                        onTrack = false;
                                        continue;
                                    }
                                }
                            }
                            catch
                            {
                            }
                            break;
                        }
                    }
                }
                if (!onTrack)
                {
                    if (!heightComputed)
                    {
                        xnaTreePosition.Y = tiles.LoadAndGetElevation(position.TileX, position.TileZ, xnaTreePosition.X, -xnaTreePosition.Z, false);
                    }
                    xnaTreePosition -= position.XNAMatrix.Translation;

                    trees.Add(new VertexPositionNormalTexture(xnaTreePosition, treeSize, new Vector2(1, 1)));
                    trees.Add(new VertexPositionNormalTexture(xnaTreePosition, treeSize, new Vector2(0, 0)));
                    trees.Add(new VertexPositionNormalTexture(xnaTreePosition, treeSize, new Vector2(1, 0)));
                    trees.Add(new VertexPositionNormalTexture(xnaTreePosition, treeSize, new Vector2(1, 1)));
                    trees.Add(new VertexPositionNormalTexture(xnaTreePosition, treeSize, new Vector2(0, 1)));
                    trees.Add(new VertexPositionNormalTexture(xnaTreePosition, treeSize, new Vector2(0, 0)));
                }
            }
            return(trees);
        }