예제 #1
0
파일: TerrainHelper.cs 프로젝트: GDxU/pb
    public static float getHeight(float heightSeed, MapVertex mapVertex, float hexSize, Texture2D elevatedHeightmap, Texture2D mountainHeightmap)
    {
        Vector3 vertex = mapVertex.toVector3();
        Hex     hex    = mapVertex.hex;

        return(getHeight(heightSeed, vertex, hex, hexSize, elevatedHeightmap, mountainHeightmap));
    }
예제 #2
0
        // Use Prim's algorithm to generate a MST of edges.
        private IEnumerable <Edge> TrimEdges(ICollection <int>[] adjacency, IList <Room> rooms)
        {
            // Comparator for MapVertex is defined to give negated, so this is actually a minheap
            var pq = new MaxHeap <MapVertex>(rooms.Count);

            (int firstX, int firstY) = rooms[0].Center;
            pq.Add(new MapVertex(0, firstX, firstY, 0));

            bool[]   inMst  = new bool[rooms.Count];
            double[] weight = new double[rooms.Count];
            int[]    parent = new int[rooms.Count];

            for (int i = 0; i < rooms.Count; i++)
            {
                weight[i] = double.MaxValue;
                parent[i] = -1;
            }

            while (pq.Count > 0)
            {
                MapVertex min = pq.PopMax();
                inMst[min.ID] = true;

                foreach (int neighborID in adjacency[min.ID])
                {
                    if (inMst[neighborID])
                    {
                        continue;
                    }

                    (int neighborX, int neighborY) = rooms[neighborID].Center;
                    double newWeight = Distance.EuclideanSquared(min.X, min.Y,
                                                                 neighborX, neighborY);

                    if (weight[neighborID] > newWeight)
                    {
                        weight[neighborID] = newWeight;
                        pq.Add(new MapVertex(neighborID, neighborX, neighborY, newWeight));
                        parent[neighborID] = min.ID;
                    }
                }
            }

            ICollection <Edge> graph = new HashSet <Edge>();

            for (int i = 0; i < rooms.Count; i++)
            {
                if (parent[i] != -1)
                {
                    graph.Add(new Edge(i, parent[i]));
                }
            }

            return(graph);
        }
예제 #3
0
        private static void ReadVerticesOrThrow(MapData map, MapComponents components)
        {
            ByteReader reader = ByteReader.From(ByteOrder.Little, components.Vertices.Value.Data);

            int count = reader.Length / BytesPerVertex;

            for (int index = 0; index < count; index++)
            {
                MapVertex vertex = new MapVertex(index, reader.Short(), reader.Short());
                map.Vertices.Add(vertex);
            }
        }
예제 #4
0
        private List <BspSegment> ReadLinesFrom(MapData map)
        {
            List <BspSegment> segments = new List <BspSegment>();

            foreach (MapLinedef line in map.Linedefs)
            {
                MapVertex startMapVertex = map.Vertices[line.StartVertex];
                MapVertex endMapVertex   = map.Vertices[line.EndVertex];

                BspVertex start = VertexAllocator[startMapVertex.Struct()];
                BspVertex end   = VertexAllocator[endMapVertex.Struct()];

                BspSegment segment = SegmentAllocator.GetOrCreate(start, end, line);
                segments.Add(segment);
            }

            return(segments);
        }
예제 #5
0
        static List <MapVertex> g_vPosition = new List <MapVertex>();                   // TODO: currently there's a bug where the last cordinate/index wont get added.


        //-----------------------------------------------------------------------------
        // loadMapFromFile
        //-----------------------------------------------------------------------------
        // start cordinate index from grid mid to allow for subtraction. ie (iLenght * 0,5).
        public static void loadMapFromFile(MapVertex mapVertex)
        {
            string sContent = File.ReadAllText("Map.bsp");;

            char[] cContent = sContent.ToCharArray();
            int    iOffset  = 0;
            //int iPath;

            int i = 0;                  // mapVertex.m_iX / 2;   // 5, start at mid
            int j = mapVertex.m_iY / 2; // 5, start at mid

            //int i = 5;   // 5, start at mid
            //int j = 5;   // 5, start at mid

            for (int x = 0; x != sContent.Length; x++)
            {
                switch (cContent[x])
                {
                case 'D':
                    //iPath = direction.down;

                    for (int g = 0; g != iOffset; g++)
                    {
                        MapVertex vertex = new MapVertex(i, j);
                        g_vPosition.Add(vertex);
                        i++;
                    }
                    break;

                case 'U':
                    for (int g = 0; g != iOffset; g++)
                    {
                        MapVertex vertex = new MapVertex(i, j);
                        g_vPosition.Add(vertex);
                        i--;
                    }
                    break;

                case 'L':
                    //iPath = direction.left;
                    for (int g = 0; g != iOffset; g++)
                    {
                        MapVertex vertex = new MapVertex(i, j);
                        g_vPosition.Add(vertex);
                        j--;
                    }
                    break;

                case 'R':
                    for (int g = 0; g != iOffset; g++)
                    {
                        MapVertex vertex = new MapVertex(i, j);
                        g_vPosition.Add(vertex);
                        j++;
                    }
                    break;

                default:                                     // content was a number, ignore that and restart main while loop to check next char.
                    iOffset = (int)Char.GetNumericValue(cContent[x]);

                    //(Convert char to int)
                    continue;
                    //-----------------------------------------------------------------------------
                }
            }
        }
예제 #6
0
 //-----------------------------------------------------------------------------
 // setPixelMap
 //-----------------------------------------------------------------------------
 public void setPixelMap(MapVertex mapVertex, char cSymbol)
 {
     m_cmGrid[mapVertex.m_iX, mapVertex.m_iY] = cSymbol;
 }
예제 #7
0
            //-----------------------------------------------------------------------------
            // getSizeAsObject
            //-----------------------------------------------------------------------------
            public MapVertex getSizeAsObject()
            {
                MapVertex mapVertex = new MapVertex(m_iSizeX, m_iSizeY);

                return(mapVertex);
            }
예제 #8
0
파일: MeshGenerator.cs 프로젝트: GDxU/pb
    public MapMesh generateTerrain(Map map, List <List <Vector2> > riverPoints, TriangleNet.Mesh mapTriangulation)
    {
        MapMesh terrain = new MapMesh();

        List <Vector3> landVertices       = new List <Vector3>();
        List <Vector3> oceanVertices      = new List <Vector3>();
        List <Vector3> innerWaterVertices = new List <Vector3>();
        Dictionary <Vector2, float> mapVerticesHeights = new Dictionary <Vector2, float>();

        foreach (Triangle triangle in mapTriangulation.Triangles)
        {
            List <MapVertex> mapVertices = triangle.vertices
                                           .Select(vertex => vertex is MapVertex ? (MapVertex)vertex : convertToMapVertex(vertex))
                                           .Reverse()
                                           .ToList();

            List <Vector3> underWaterShifts = new List <Vector3>(new Vector3[3]);

            List <bool> needsShoreAdjustments = new List <bool>(new bool[3]);

            if (mapVertices.Any(mapVertice => mapVertice.hex == null))
            {
                for (int i = 0; i < mapVertices.Count; i++)
                {
                    if (mapVertices[i].hex != null)
                    {
                        needsShoreAdjustments[i] = true;
                    }
                }
            }

            MapVertex shoreMapVertex = mapVertices.FirstOrDefault(mapVertex => mapVertex.hex != null && (mapVertex.hex.biome == null || mapVertex.hex.biome.name != "Fresh lake"));
            if (shoreMapVertex != null)
            {
                Vector2 shoreCenter = HexMathHelper.hexToWorldCoords(new Vector2(shoreMapVertex.hex.x, shoreMapVertex.hex.y), this.hexSize);
                //if shore triangle push it underwater to create shore slope
                for (int i = 0; i < mapVertices.Count; i++)
                {
                    if (mapVertices[i].hex == null)
                    {
                        underWaterShifts[i]  = (new Vector2((float)mapVertices[i].x, (float)mapVertices[i].y) - shoreCenter).normalized * 0.3f;
                        underWaterShifts[i] += new Vector3(0, 0, 0.03f);
                    }
                }
            }

            List <Vector3> triangleVertices = new List <Vector3>();
            for (int i = 0; i < mapVertices.Count; i++)
            {
                float   height    = TerrainHelper.getHeight(heightSeed, mapVertices[i], this.hexSize, elevatedHeightmap, mountainHeightmap);
                Vector3 newVertex = mapVertices[i].toVector3() + underWaterShifts[i] + new Vector3(0, 0, height);

                if (!mapVerticesHeights.ContainsKey(newVertex) && needsShoreAdjustments[i])
                {
                    newVertex.z = Random.Range(0.08f, 0.13f);
                    mapVerticesHeights[newVertex] = newVertex.z;
                }

                if (mapVertices[i].isRiver && (mapVertices[i].hex == null || !mapVertices[i].hex.hasTag(RiverHelper.FRESH_LAKE_TAG)))
                {
                    newVertex += TerrainHelper.getRiverHeightAdjustment(newVertex);
                }

                triangleVertices.Add(newVertex);
            }

            if (mapVertices.All(mapVertex => mapVertex.hex == null))
            {
                oceanVertices.AddRange(triangleVertices);
            }
            else if (mapVertices.All(mapVertex => mapVertex.isRiver))
            {
                innerWaterVertices.AddRange(triangleVertices);
            }
            else if (mapVertices.All(mapVertex => mapVertex.hex != null && mapVertex.hex.hasTag(RiverHelper.FRESH_LAKE_TAG)))
            {
                innerWaterVertices.AddRange(triangleVertices);
            }
            else
            {
                landVertices.AddRange(triangleVertices);
            }
        }

        //smooth shore
        for (int i = 0; i < landVertices.Count; i++)
        {
            Vector3 vertex = landVertices[i];
            if (mapVerticesHeights.ContainsKey(vertex))
            {
                vertex.z        = mapVerticesHeights[landVertices[i]];
                landVertices[i] = vertex;
            }
        }

        terrain.landMesh       = this.createMesh("Land", landVertices);
        terrain.oceanMesh      = this.createMesh("Ocean", oceanVertices);
        terrain.innerWaterMesh = this.createMesh("Lakes and Rivers", innerWaterVertices);

        return(terrain);
    }