Ejemplo n.º 1
0
    private TerrainTriangulationData TriangulateTerrainAdjacentToRiver(
        Hex source,
        HexDirections direction,
        TerrainTriangulationData triangulationData,
        Dictionary <HexDirections, bool> roadEdges,
        HexRiverData riverData,
        float hexOuterRadius,
        int wrapSize,
        MapMeshChunkLayer terrain,
        FeatureContainer features
        )
    {
        if (riverData.HasRiverInDirection(direction.NextClockwise()))
        {
/* If the direction has a river on either side, it has a slight curve.
 * The center vertex of river-adjacent triangle needs to be moved toward
 * the edge so they don't overlap the river.
 */
//            if (hex.HasRiverThroughEdge(direction.Previous())) {
            if (
                riverData.HasRiverInDirection(direction.PreviousClockwise())
                )
            {
                triangulationData.terrainCenter += HexagonPoint.GetSolidEdgeMiddle(
                    direction,
                    hexOuterRadius
                    ) * (HexagonConstants.INNER_TO_OUTER_RATIO * 0.5f);
            }

/* If the hex has a river through the previous previous direction,
 * it has a river flowing through the hex. Move the center vertex
 * of the river-adjacent triangle so that it does not overlap the river.
 */
            else if (
                riverData.HasRiverInDirection(
                    direction.PreviousClockwise2()
                    )
                )
            {
                triangulationData.terrainCenter +=
                    HexagonPoint.GetFirstSolidCorner(
                        direction,
                        hexOuterRadius
                        ) * 0.25f;
            }
        }

/* Second case of straight-river-adjacent triangle. Need to move center
 * so it doesn't overlap the river.
 */
        else if (
            riverData.HasRiverInDirection(direction.PreviousClockwise()) &&
            riverData.HasRiverInDirection(direction.NextClockwise2())
            )
        {
            triangulationData.terrainCenter += HexagonPoint.GetSecondSolidCorner(
                direction,
                hexOuterRadius
                ) * 0.25f;
        }

        EdgeVertices middle = new EdgeVertices(
            Vector3.Lerp(
                triangulationData.terrainCenter,
                triangulationData.centerEdgeVertices.vertex1,
                0.5f
                ),
            Vector3.Lerp(
                triangulationData.terrainCenter,
                triangulationData.centerEdgeVertices.vertex5,
                0.5f
                )
            );

        TriangulateEdgeStripTerrain(
            middle,
            _weights1,
            source.Index,
            triangulationData.centerEdgeVertices,
            _weights1,
            source.Index,
            hexOuterRadius,
            wrapSize,
            terrain
            );

        TriangulateEdgeFan(
            triangulationData.terrainCenter,
            middle,
            source.Index,
            hexOuterRadius,
            wrapSize,
            terrain
            );

        if (!source.IsUnderwater && roadEdges[direction])
        {
            features.AddFeature(
                source,
                (
                    triangulationData.terrainCenter +
                    triangulationData.centerEdgeVertices.vertex1 +
                    triangulationData.centerEdgeVertices.vertex5
                ) * (1f / 3f),
                hexOuterRadius,
                wrapSize
                );
        }

        return(triangulationData);
    }
Ejemplo n.º 2
0
    private TerrainTriangulationData TriangulateTerrainCenter(
        HexRiverData riverData,
        HexDirections direction,
        Hex source,
        TerrainTriangulationData data,
        float hexOuterRadius,
        int wrapSize,
        MapMeshChunkLayer terrain,
        FeatureContainer features,
        Dictionary <HexDirections, bool> roadEdges
        )
    {
        if (riverData.HasRiver)
        {
            if (riverData.HasRiverInDirection(direction))
            {
                data.centerEdgeVertices.vertex3.y = source.StreamBedY;

                if (riverData.HasRiverStartOrEnd)
                {
                    data = TriangulateRiverBeginOrEndTerrain(
                        source,
                        data,
                        hexOuterRadius,
                        wrapSize,
                        terrain
                        );
                }
                else
                {
                    data = TriangulateRiverBanks(
                        data,
                        riverData,
                        direction,
                        hexOuterRadius
                        );

                    data = TriangulateRiverTerrain(
                        source,
                        data,
                        hexOuterRadius,
                        wrapSize,
                        terrain
                        );
                }
            }
            else
            {
                data = TriangulateTerrainAdjacentToRiver(
                    source,
                    direction,
                    data,
                    roadEdges,
                    riverData,
                    hexOuterRadius,
                    wrapSize,
                    terrain,
                    features
                    );
            }
        }
        else
        {
            // Triangulate terrain center without river, basic edge fan.
            TriangulateEdgeFan(
                data.terrainCenter,
                data.centerEdgeVertices,
                source.Index,
                hexOuterRadius,
                wrapSize,
                terrain
                );

            if (
                !source.IsUnderwater &&
                !roadEdges[direction]
                )
            {
                features.AddFeature(
                    source,
                    (
                        data.terrainCenter +
                        data.centerEdgeVertices.vertex1 +
                        data.centerEdgeVertices.vertex5
                    ) * (1f / 3f),
                    hexOuterRadius,
                    wrapSize
                    );
            }
        }

        return(data);
    }
Ejemplo n.º 3
0
    /// <summary>
    /// Triangulate the mesh geometry of an individual hex.
    /// </summary>
    /// <param name="source">
    /// The hex to whose mesh geometry is to be triangluated.
    /// </param>
    /// <param name="hexOuterRadius">
    /// The outer radius of the hex to be triangulated.
    /// </param>
    /// <param name="adjacencyGraph">
    ///
    /// </param>
    /// <param name="riverDigraph"></param>
    /// <param name="roadUndirectedGraph"></param>
    /// <param name="elevationDigraph"></param>
    /// <param name="wrapSize"></param>
    private void TriangulateHex(
        Hex source,
        Dictionary <HexDirections, Hex> neighbors,
        List <HexDirections> borderDirections,
        float hexOuterRadius,
        HexRiverData riverData,
        Dictionary <HexDirections, bool> roadEdges,
        Dictionary <HexDirections, ElevationEdgeTypes> elevationEdgeTypes,
        int wrapSize,
        TerrainChunkLayer terrainLayer,
        RiversChunkLayer riversLayer,
        RoadsChunkLayer roadsLayer,
        OpenWaterChunkLayer openWaterLayer,
        WaterShoreChunkLayer waterShoreLayer,
        EstuariesChunkLayer estuariesLayer,
        FeatureContainer features
        )
    {
        foreach (
            KeyValuePair <HexDirections, Hex> pair in neighbors
            )
        {
            // Initialize triangulation data.
            HexDirections direction = pair.Key;
            Hex           neighbor  = pair.Value;

            TerrainTriangulationData terrainTriData =
                new TerrainTriangulationData();

            terrainTriData.terrainCenter =
                source.Position;

            terrainTriData = GetCenterEdgeVertices(
                direction,
                terrainTriData,
                hexOuterRadius
                );

            if (direction <= HexDirections.Southeast)
            {
                terrainTriData = GetConnectionEdgeVertices(
                    source,
                    neighbor,
                    direction,
                    terrainTriData,
                    hexOuterRadius
                    );
            }

            // Triangulate layers for non-border edge.
            terrainTriData =
                terrainLayer.TriangulateHexTerrainEdge(
                    source,
                    neighbor,
                    terrainTriData,
                    neighbors,
                    direction,
                    riverData,
                    features,
                    roadEdges,
                    elevationEdgeTypes,
                    hexOuterRadius,
                    wrapSize
                    );

            terrainTriData =
                roadsLayer.TriangulateHexRoadEdge(
                    source,
                    neighbor,
                    terrainTriData,
                    direction,
                    riverData,
                    features,
                    roadEdges,
                    elevationEdgeTypes,
                    hexOuterRadius,
                    wrapSize
                    );

            terrainTriData =
                riversLayer.TriangulateHexRiverEdge(
                    source,
                    neighbor,
                    direction,
                    roadEdges,
                    riverData,
                    terrainTriData,
                    hexOuterRadius,
                    wrapSize
                    );

            WaterTriangulationData waterTriData =
                new WaterTriangulationData();

            waterTriData = GetWaterData(
                source,
                neighbor,
                waterTriData,
                direction,
                hexOuterRadius,
                wrapSize
                );

            waterTriData =
                openWaterLayer.TriangulateHexOpenWaterEdge(
                    source,
                    neighbor,
                    neighbors,
                    direction,
                    waterTriData,
                    terrainTriData,
                    hexOuterRadius,
                    wrapSize
                    );

            waterTriData =
                waterShoreLayer.TriangulateHexWaterShoreEdge(
                    source,
                    neighbor,
                    neighbors,
                    direction,
                    riverData,
                    waterTriData,
                    hexOuterRadius,
                    wrapSize
                    );

            waterTriData =
                estuariesLayer.TriangulateHexEstuaryEdge(
                    source,
                    neighbor,
                    direction,
                    riverData,
                    waterTriData,
                    hexOuterRadius,
                    wrapSize
                    );
        }

        bool anyEdge = false;

        foreach (KeyValuePair <HexDirections, bool> pair in roadEdges)
        {
            if (pair.Value)
            {
                anyEdge = true;
                break;
            }
        }

        // Add feature or special to hex.
        if (!source.IsUnderwater)
        {
            if (
                !riverData.HasRiver &&
                !anyEdge
                )
            {
                features.AddFeature(
                    source,
                    source.Position,
                    hexOuterRadius,
                    wrapSize
                    );
            }

            if (source.IsSpecial)
            {
                features.AddSpecialFeature(
                    source,
                    source.Position,
                    hexOuterRadius,
                    wrapSize
                    );
            }
        }
    }