Ejemplo n.º 1
0
    public WaterTriangulationData TriangulateHexWaterShoreEdge(
        Hex source,
        Hex neighbor,
        Dictionary <HexDirections, Hex> neighbors,
        HexDirections direction,
        HexRiverData riverData,
        WaterTriangulationData triangulationData,
        float hexOuterRadius,
        int wrapSize
        )
    {
        if (source.IsUnderwater)
        {
            if (
                !neighbor.IsUnderwater
                )
            {
                Vector3 center2 = neighbor.Position;

                float hexInnerRadius =
                    HexagonPoint.OuterToInnerRadius(hexOuterRadius);

                float hexInnerDiameter = hexInnerRadius * 2f;

                //            / | y
                //           /  |
                //           |  |
                //source x/z |  | target
                //           |  |
                //           \  |
                //            \ | y

                Vector3 waterShoreHexIndices;

                waterShoreHexIndices.x     =
                    waterShoreHexIndices.z = source.Index;

                waterShoreHexIndices.y = neighbor.Index;

                TriangulateWaterShore(
                    source,
                    neighbor,
                    waterShoreHexIndices,
                    direction,
                    neighbors,
                    riverData,
                    triangulationData.waterSurfaceCenter,
                    hexOuterRadius,
                    wrapSize,
                    this,
                    triangulationData.sourceWaterEdge,
                    triangulationData.neighborWaterEdge,
                    hexInnerDiameter
                    );
            }
        }

        return(triangulationData);
    }
    public WaterTriangulationData TriangulateHexOpenWaterEdge(
        Hex source,
        Hex neighbor,
        Dictionary <HexDirections, Hex> neighbors,
        HexDirections direction,
        WaterTriangulationData waterTriData,
        TerrainTriangulationData terrainTriData,
        float hexOuterRadius,
        int wrapSize
        )
    {
        if (source.IsUnderwater)
        {
            if (
                !neighbor.IsUnderwater
                )
            {
                waterTriData = TriangulateShoreOpenWater(
                    source,
                    neighbor,
                    waterTriData.waterSurfaceCenter,
                    waterTriData.sourceWaterEdge,
                    hexOuterRadius,
                    wrapSize,
                    this,
                    waterTriData
                    );
            }
            else
            {
                waterTriData = TriangulateOpenWaterCenter(
                    source,
                    waterTriData,
                    direction,
                    hexOuterRadius,
                    wrapSize,
                    this
                    );

                waterTriData = TriangulateOpenWaterConnection(
                    source,
                    neighbor,
                    direction,
                    waterTriData,
                    terrainTriData,
                    neighbors,
                    hexOuterRadius,
                    wrapSize,
                    this
                    );
            }
        }

        return(waterTriData);
    }
Ejemplo n.º 3
0
    public WaterTriangulationData TriangulateHexEstuaryEdge(
        Hex source,
        Hex neighbor,
        HexDirections direction,
        HexRiverData riverData,
        WaterTriangulationData triangulationData,
        float hexOuterRadius,
        int wrapSize
        )
    {
        if (source.IsUnderwater)
        {
            if (!neighbor.IsUnderwater)
            {
                if (riverData.HasRiverInDirection(direction))
                {
                    //            / | y
                    //           /  |
                    //           |  |
                    //source x/z |  | target
                    //           |  |
                    //           \  |
                    //            \ | y

                    Vector3 waterShoreHexIndices;

                    waterShoreHexIndices.x     =
                        waterShoreHexIndices.z = source.Index;

                    waterShoreHexIndices.y = neighbor.Index;

                    TriangulateEstuary(
                        triangulationData.sourceWaterEdge,
                        triangulationData.neighborWaterEdge,
                        riverData.HasIncomingRiverInDirection(direction),
                        waterShoreHexIndices,
                        hexOuterRadius,
                        wrapSize,
                        this
                        );
                }
            }
        }

        return(triangulationData);
    }
    private WaterTriangulationData TriangulateOpenWaterCenter(
        Hex source,
        WaterTriangulationData triangulationData,
        HexDirections direction,
        float hexOuterRadius,
        int wrapSize,
        MapMeshChunkLayer water
        )
    {
        triangulationData.waterSurfaceCornerLeft =
            triangulationData.waterSurfaceCenter +
            HexagonPoint.GetFirstWaterCorner(
                direction,
                hexOuterRadius
                );

        triangulationData.waterSurfaceCornerRight =
            triangulationData.waterSurfaceCenter +
            HexagonPoint.GetSecondWaterCorner(
                direction,
                hexOuterRadius
                );

        water.AddTrianglePerturbed(
            triangulationData.waterSurfaceCenter,
            triangulationData.waterSurfaceCornerLeft,
            triangulationData.waterSurfaceCornerRight,
            hexOuterRadius,
            wrapSize
            );

        Vector3 openWaterCenterIndices;

        openWaterCenterIndices.x         =
            openWaterCenterIndices.y     =
                openWaterCenterIndices.z =
                    source.Index;

        water.AddTriangleHexData(
            openWaterCenterIndices,
            _weights1
            );

        return(triangulationData);
    }
    private WaterTriangulationData TriangulateShoreOpenWater(
        Hex source,
        Hex target,
        Vector3 waterSurfaceCenter,
        EdgeVertices sourceWaterEdge,
        float hexOuterRadius,
        int wrapSize,
        MapMeshChunkLayer water,
        WaterTriangulationData triangulationData
        )
    {
        water.AddTrianglePerturbed(
            waterSurfaceCenter,
            sourceWaterEdge.vertex1,
            sourceWaterEdge.vertex2,
            hexOuterRadius,
            wrapSize
            );

        water.AddTrianglePerturbed(
            waterSurfaceCenter,
            sourceWaterEdge.vertex2,
            sourceWaterEdge.vertex3,
            hexOuterRadius,
            wrapSize
            );

        water.AddTrianglePerturbed(
            waterSurfaceCenter,
            sourceWaterEdge.vertex3,
            sourceWaterEdge.vertex4,
            hexOuterRadius,
            wrapSize
            );

        water.AddTrianglePerturbed(
            waterSurfaceCenter,
            sourceWaterEdge.vertex4,
            sourceWaterEdge.vertex5,
            hexOuterRadius,
            wrapSize
            );

        //            / | y
        //           /  |
        //           |  |
        //source x/z |  | target
        //           |  |
        //           \  |
        //            \ | y

        Vector3 waterShoreHexIndices;

        waterShoreHexIndices.x     =
            waterShoreHexIndices.z = source.Index;

        waterShoreHexIndices.y = target.Index;

        water.AddTriangleHexData(
            waterShoreHexIndices,
            _weights1
            );

        water.AddTriangleHexData(
            waterShoreHexIndices,
            _weights1
            );

        water.AddTriangleHexData(
            waterShoreHexIndices,
            _weights1
            );

        water.AddTriangleHexData(
            waterShoreHexIndices,
            _weights1
            );

        return(triangulationData);
    }
    private WaterTriangulationData TriangulateOpenWaterConnection(
        Hex source,
        Hex target,
        HexDirections direction,
        WaterTriangulationData waterTriData,
        TerrainTriangulationData terrainTriData,
        Dictionary <HexDirections, Hex> neighbors,
        float hexOuterRadius,
        int wrapSize,
        MapMeshChunkLayer water
        )
    {
        if (
            direction <= HexDirections.Southeast
            )
        {
            Vector3 bridge = HexagonPoint.GetWaterBridge(
                direction,
                hexOuterRadius
                );

            Vector3 edge1 = waterTriData.waterSurfaceCornerLeft + bridge;
            Vector3 edge2 = waterTriData.waterSurfaceCornerRight + bridge;

            water.AddQuadPerturbed(
                waterTriData.waterSurfaceCornerLeft,
                waterTriData.waterSurfaceCornerRight,
                edge1,
                edge2,
                hexOuterRadius,
                wrapSize
                );

            Vector3 openWaterIndices;
            openWaterIndices.x     =
                openWaterIndices.z =
                    source.Index;

            openWaterIndices.y = target.Index;

            water.AddQuadHexData(
                openWaterIndices,
                _weights1,
                _weights2
                );

            if (direction <= HexDirections.East)
            {
                Hex nextNeighbor;

                if (
                    neighbors.TryGetValue(
                        direction.NextClockwise(),
                        out nextNeighbor
                        ) &&
                    nextNeighbor.IsUnderwater
                    )
                {
                    water.AddTrianglePerturbed(
                        waterTriData.waterSurfaceCornerRight,
                        edge2,
                        waterTriData.waterSurfaceCornerRight +
                        HexagonPoint.GetWaterBridge(
                            direction.NextClockwise(),
                            hexOuterRadius
                            ),
                        hexOuterRadius,
                        wrapSize
                        );

                    openWaterIndices.z =
                        nextNeighbor.Index;

                    water.AddTriangleHexData(
                        openWaterIndices,
                        _weights1,
                        _weights2,
                        _weights3
                        );
                }
            }
        }

        return(waterTriData);
    }
Ejemplo n.º 7
0
    private WaterTriangulationData GetWaterData(
        Hex source,
        Hex neighbor,
        WaterTriangulationData waterTriData,
        HexDirections direction,
        float hexOuterRadius,
        int wrapSize
        )
    {
        waterTriData.waterSurfaceCenter   = source.Position;
        waterTriData.waterSurfaceCenter.y = source.WaterSurfaceY;

        waterTriData.sourceWaterEdge = new EdgeVertices(
            waterTriData.waterSurfaceCenter +
            HexagonPoint.GetFirstWaterCorner(
                direction,
                hexOuterRadius
                ),
            waterTriData.waterSurfaceCenter +
            HexagonPoint.GetSecondWaterCorner(
                direction,
                hexOuterRadius
                )
            );

        Vector3 neighborCenter = neighbor.Position;

        float hexInnerRadius =
            HexagonPoint.OuterToInnerRadius(hexOuterRadius);

        float hexInnerDiameter = hexInnerRadius * 2f;

// TODO: This will not work once the column index is removed from
//       Hex class.
// If the neighbor outside the wrap boundaries, adjust accordingly.
        if (neighbor.ColumnIndex < source.ColumnIndex - 1)
        {
            neighborCenter.x +=
                wrapSize * hexInnerDiameter;
        }
        else if (neighbor.ColumnIndex > source.ColumnIndex + 1)
        {
            neighborCenter.x -=
                wrapSize * hexInnerDiameter;
        }

        neighborCenter.y = waterTriData.waterSurfaceCenter.y;

        waterTriData.neighborWaterEdge = new EdgeVertices(
            neighborCenter + HexagonPoint.GetSecondSolidCorner(
                direction.Opposite(),
                hexOuterRadius
                ),
            neighborCenter + HexagonPoint.GetFirstSolidCorner(
                direction.Opposite(),
                hexOuterRadius
                )
            );

        return(waterTriData);
    }
Ejemplo n.º 8
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
                    );
            }
        }
    }