コード例 #1
0
ファイル: Forest.cs プロジェクト: xiaomailong/OpenRails
 public ForestViewer(Viewer viewer, ForestObj forest, WorldPosition position)
 {
     Viewer   = viewer;
     Position = position;
     MaximumCenterlineOffset = Viewer.Simulator.TRK.Tr_RouteFile.ForestClearDistance;
     Material  = viewer.MaterialManager.Load("Forest", Helpers.GetForestTextureFile(viewer.Simulator, forest.TreeTexture));
     Primitive = new ForestPrimitive(Viewer, forest, position, MaximumCenterlineOffset);
 }
コード例 #2
0
        public ForestPrimitive(Viewer viewer, ForestObj forest, WorldPosition position, float maximumCenterlineOffset, bool checkRoadsToo)
        {
            Viewer = viewer;
            MaximumCenterlineOffset = maximumCenterlineOffset;
            CheckRoadsToo           = checkRoadsToo;

            var trees = CalculateTrees(viewer.Tiles, forest, position, out ObjectRadius);

            if (trees.Count > 0)
            {
                VertexBuffer = new VertexBuffer(viewer.GraphicsDevice, typeof(VertexPositionNormalTexture), trees.Count, BufferUsage.WriteOnly);
                VertexBuffer.SetData(trees.ToArray());
            }

            PrimitiveCount = trees.Count / 3;
        }
コード例 #3
0
ファイル: Forest.cs プロジェクト: xiaomailong/OpenRails
        public ForestPrimitive(Viewer viewer, ForestObj forest, WorldPosition position, float maximumCenterlineOffset)
        {
            Viewer = viewer;
            MaximumCenterlineOffset = maximumCenterlineOffset;

            var trees = CalculateTrees(viewer.Tiles, forest, position, out ObjectRadius);

            VertexDeclaration = new VertexDeclaration(viewer.GraphicsDevice, VertexPositionNormalTexture.VertexElements);
            if (trees.Count > 0)
            {
                VertexStride = VertexDeclaration.GetVertexStrideSize(0);
                VertexBuffer = new VertexBuffer(viewer.GraphicsDevice, typeof(VertexPositionNormalTexture), trees.Count, BufferUsage.WriteOnly);
                VertexBuffer.SetData(trees.ToArray());
            }

            PrimitiveCount = trees.Count / 3;
        }
コード例 #4
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);
        }
コード例 #5
0
 // don't consider track sections outside the forest boundaries
 public void FindTracksAndRoadsMoreClose(ref List <TrVectorSection> sections, List <TrVectorSection> allSections, ForestObj forest, WorldPosition position, Matrix invForestXNAMatrix)
 {
     if (allSections != null && allSections.Count > 0)
     {
         var toAddX = MaximumCenterlineOffset + forest.forestArea.X / 2 + forest.scaleRange.Maximum * forest.treeSize.Width;
         var toAddZ = MaximumCenterlineOffset + forest.forestArea.Z / 2 + forest.scaleRange.Maximum * forest.treeSize.Width;
         foreach (TrVectorSection section in allSections)
         {
             Vector3 sectPosition;
             Vector3 sectPosToForest;
             sectPosition.X    = section.X;
             sectPosition.Z    = section.Z;
             sectPosition.Y    = section.Y;
             sectPosition.X   += (section.TileX - position.TileX) * 2048;
             sectPosition.Z   += (section.TileZ - position.TileZ) * 2048;
             sectPosition.Z    = -sectPosition.Z;
             sectPosToForest   = Vector3.Transform(sectPosition, invForestXNAMatrix);
             sectPosToForest.Z = -sectPosToForest.Z;
             trackSection      = Viewer.Simulator.TSectionDat.TrackSections.Get(section.SectionIndex);
             if (trackSection == null)
             {
                 continue;
             }
             var trackSectionLength = GetLength(trackSection);
             if (Math.Abs(sectPosToForest.X) > trackSectionLength + toAddX)
             {
                 continue;
             }
             if (Math.Abs(sectPosToForest.Z) > trackSectionLength + toAddZ)
             {
                 continue;
             }
             sections.Add(section);
         }
     }
     return;
 }