Exemplo n.º 1
0
    public void TriangulateAllCells()
    {
        // This method could be invoked at any time, even when cells have already been triangulated earlier.
        // So we should begin by clearing the old data.
        Terrain.Clear();
        Rivers.Clear();
        Roads.Clear();
        Water.Clear();
        WaterShore.Clear();
        Estuaries.Clear();
        Features.Clear();

        for (int i = 0; i < _cells.Length; i++)
        {
            Precalculation(_cells[i]);
        }

        for (int i = 0; i < _cells.Length; i++)
        {
            TriangulateCell(_cells[i]);
            AddFeatures(_cells[i]);
        }

        Terrain.Apply();
        Rivers.Apply();
        Roads.Apply();
        Water.Apply();
        WaterShore.Apply();
        Estuaries.Apply();
        Features.Apply();
    }
Exemplo n.º 2
0
    void TriangulateEstuary(HexCell cell, HexDirection direction)
    {
        var neighbor = cell.GetNeighbor(direction);

        EdgeVertices closerWaterEdge  = cell.WaterEdges[(int)direction];
        EdgeVertices furtherWaterEdge = neighbor.WaterEdges[(int)direction.Opposite()];
        EdgeVertices furtherEdge      = neighbor.Edges[(int)direction.Opposite()];

        furtherEdge.V1.y = HexMetrics.WaterSurfaceY;
        furtherEdge.V2.y = HexMetrics.WaterSurfaceY;
        furtherEdge.V3.y = HexMetrics.WaterSurfaceY;
        furtherEdge.V4.y = HexMetrics.WaterSurfaceY;
        furtherEdge.V5.y = HexMetrics.WaterSurfaceY;

        WaterShore.AddTriangleUnperturbed(furtherEdge.V5, closerWaterEdge.V2, closerWaterEdge.V1);
        WaterShore.AddTriangleUnperturbed(furtherEdge.V1, closerWaterEdge.V5, closerWaterEdge.V4);
        WaterShore.AddTriangleUV(new Vector2(0f, 1f), new Vector2(0f, 0f), new Vector2(0f, 0f));
        WaterShore.AddTriangleUV(new Vector2(0f, 1f), new Vector2(0f, 0f), new Vector2(0f, 0f));

        // left quad
        // quad is rotated 90 degrees to the right so the diagonal connection is shorter
        // it is done to maintain the symetry with the other quad
        Estuaries.AddQuadUnperturbed(furtherEdge.V5, closerWaterEdge.V2, furtherEdge.V4, closerWaterEdge.V3);
        Estuaries.AddQuadUV(new Vector2(0f, 1f), new Vector2(0f, 0f), new Vector2(1f, 1f), new Vector2(0f, 0f));

        // big triangle in the middle
        Estuaries.AddTriangleUnperturbed(closerWaterEdge.V3, furtherEdge.V4, furtherEdge.V2);
        Estuaries.AddTriangleUV(new Vector2(0f, 0f), new Vector2(1f, 1f), new Vector2(0f, 1f));

        // right quad
        Estuaries.AddQuadUnperturbed(closerWaterEdge.V3, closerWaterEdge.V4, furtherEdge.V2, furtherEdge.V1);
        Estuaries.AddQuadUV(new Vector2(0f, 0f), new Vector2(0f, 0f), new Vector2(1f, 1f), new Vector2(0f, 1f));

        // is incoming river
        if (cell.IncomingRiver == direction)
        {
            Estuaries.AddQuadUV2(
                new Vector2(1.5f, 1f), new Vector2(0.7f, 1.15f),
                new Vector2(1f, 0.8f), new Vector2(0.5f, 1.1f));
            Estuaries.AddTriangleUV2(
                new Vector2(0.5f, 1.1f), new Vector2(1f, 0.8f), new Vector2(0f, 0.8f));
            Estuaries.AddQuadUV2(
                new Vector2(0.5f, 1.1f), new Vector2(0.3f, 1.15f),
                new Vector2(0f, 0.8f), new Vector2(-0.5f, 1f));
        }
        else
        {
            // the U coordinates have to be mirrored for outgoing rivers
            // the V coordinates are a little bit less straightforward
            Estuaries.AddQuadUV2(
                new Vector2(-0.5f, -0.2f), new Vector2(0.3f, -0.35f),
                new Vector2(0f, 0f), new Vector2(0.5f, -0.3f));
            Estuaries.AddTriangleUV2(
                new Vector2(0.5f, -0.3f), new Vector2(0f, 0f), new Vector2(1f, 0f));
            Estuaries.AddQuadUV2(
                new Vector2(0.5f, -0.3f), new Vector2(0.7f, -0.35f),
                new Vector2(1f, 0f), new Vector2(1.5f, -0.2f));
        }
    }
Exemplo n.º 3
0
    /// <summary>
    /// 在前边插入新的水岸线
    /// </summary>
    /// <param name="waterShore">Water shore.</param>
    private void JoinWaterShoreAtFront(WaterShore waterShore)
    {
        List <WaterShoreSegment> waterShoreSegmentList = waterShore.mWaterShoreSegmentList;

        waterShoreSegmentList.AddRange(mWaterShoreSegmentList);
        mWaterShoreSegmentList            = waterShoreSegmentList;
        waterShore.mWaterShoreSegmentList = null;
    }
        private void TriangulateEstuary(EdgeVertices e1, EdgeVertices e2, bool incomingRiver, Vector3 indices)
        {
            WaterShore.AddTriangle(e2.v1, e1.v2, e1.v1);
            WaterShore.AddTriangle(e2.v5, e1.v5, e1.v4);
            WaterShore.AddTriangleUV(
                new Vector2(0f, 1f), new Vector2(0f, 0f), new Vector2(0f, 0f)
                );
            WaterShore.AddTriangleUV(
                new Vector2(0f, 1f), new Vector2(0f, 0f), new Vector2(0f, 0f)
                );
            WaterShore.AddTriangleCellData(indices, weights2, weights1, weights1);
            WaterShore.AddTriangleCellData(indices, weights2, weights1, weights1);

            Estuaries.AddQuad(e2.v1, e1.v2, e2.v2, e1.v3);
            Estuaries.AddTriangle(e1.v3, e2.v2, e2.v4);
            Estuaries.AddQuad(e1.v3, e1.v4, e2.v4, e2.v5);

            Estuaries.AddQuadUV(
                new Vector2(0f, 1f), new Vector2(0f, 0f),
                new Vector2(1f, 1f), new Vector2(0f, 0f));
            Estuaries.AddTriangleUV(
                new Vector2(0f, 0f), new Vector2(1f, 1f), new Vector2(1f, 1f));
            Estuaries.AddQuadUV(
                new Vector2(0f, 0f), new Vector2(0f, 0f),
                new Vector2(1f, 1f), new Vector2(0f, 1f));

            Estuaries.AddQuadCellData(indices, weights2, weights1, weights2, weights1);
            Estuaries.AddTriangleCellData(indices, weights1, weights2, weights2);
            Estuaries.AddQuadCellData(indices, weights1, weights2);

            if (incomingRiver)
            {
                Estuaries.AddQuadUV2(
                    new Vector2(1.5f, 1f), new Vector2(0.7f, 1.15f),
                    new Vector2(1f, 0.8f), new Vector2(0.5f, 1.1f));
                Estuaries.AddTriangleUV2(
                    new Vector2(0.5f, 1.1f), new Vector2(1f, 0.8f), new Vector2(0f, 0.8f));
                Estuaries.AddQuadUV2(
                    new Vector2(0.5f, 1.1f), new Vector2(0.3f, 1.15f),
                    new Vector2(0f, 0.8f), new Vector2(-0.5f, 1f));
            }
            else
            {
                Estuaries.AddQuadUV2(
                    new Vector2(-0.5f, -0.2f), new Vector2(0.3f, -0.35f),
                    new Vector2(0f, 0f), new Vector2(0.5f, -0.3f));
                Estuaries.AddTriangleUV2(
                    new Vector2(0.5f, -0.3f), new Vector2(0f, 0f), new Vector2(1f, 0f));
                Estuaries.AddQuadUV2(
                    new Vector2(0.5f, -0.3f), new Vector2(0.7f, -0.35f),
                    new Vector2(1f, 0f), new Vector2(1.5f, -0.2f));
            }
        }
Exemplo n.º 5
0
    /// <summary>
    /// 把传入的海岸线和当前的相连起来
    /// </summary>
    /// <returns><c>true</c>, if water shore was joined, <c>false</c> otherwise.</returns>
    /// <param name="waterShore">Water shore.</param>
    public bool JoinWaterShore(WaterShore waterShore)
    {
        if (mWaterShoreSegmentList.Count == 0)
        {
            Debug.LogError("Water shore with no segment");
            return(false);
        }
        if (waterShore.mWaterShoreSegmentList.Count == 0)
        {
            Debug.LogError("Input Water shore with no segment");
            return(false);
        }
        bool needExchange = false;

        if (mWaterShoreSegmentList [0].CanJoinAtFront(waterShore.mWaterShoreSegmentList [waterShore.mWaterShoreSegmentList.Count - 1], out needExchange))
        {
            if (!needExchange)
            {
                JoinWaterShoreAtFront(waterShore);
                return(true);
            }
        }

        if (mWaterShoreSegmentList [0].CanJoinAtFront(waterShore.mWaterShoreSegmentList [0], out needExchange))
        {
            if (needExchange)
            {
                waterShore.RevertWaterLines();
                JoinWaterShoreAtFront(waterShore);
                return(true);
            }
        }

        if (mWaterShoreSegmentList [mWaterShoreSegmentList.Count - 1].CanJoinAtEnd(waterShore.mWaterShoreSegmentList [0], out needExchange))
        {
            if (!needExchange)
            {
                JoinWaterShoreAtEnd(waterShore);
                return(true);
            }
        }

        if (mWaterShoreSegmentList [mWaterShoreSegmentList.Count - 1].CanJoinAtEnd(waterShore.mWaterShoreSegmentList [waterShore.mWaterShoreSegmentList.Count - 1], out needExchange))
        {
            if (needExchange)
            {
                waterShore.RevertWaterLines();
                JoinWaterShoreAtEnd(waterShore);
                return(true);
            }
        }
        return(false);
    }
Exemplo n.º 6
0
    List <Water> GenerateWaters(List <WaterShore> waterShores)
    {
        //TODO 现在只是对大小进行了排序
        waterShores.Sort(delegate(WaterShore x, WaterShore y) {
            return(x.EdgeSize.CompareTo(y.EdgeSize));
        });

        List <Water> ret = new List <Water> ();
        Water        waitOutSideWater = null;

        for (int i = 0; i < waterShores.Count; ++i)
        {
            WaterShore waterShore = waterShores [i];

            bool isInsideWater = waterShore.IsInsideWater;
            if (waterShore.IsInvalidShore)
            {
                continue;
            }

            if (waterShore.IsInsideWater)
            {
                //水岸线的内圈是
                if (null != waitOutSideWater)
                {
                    waitOutSideWater.SetOutsideShore(waterShore);
                    ret.Add(waitOutSideWater);
                    waitOutSideWater = null;
                }
                else
                {
                    Water water = new Water();
                    water.SetSingleShore(waterShore);
                    ret.Add(water);
                }
            }
            else
            {
                //水岸线外圈是水,需要等待到下一个包含自己并且内圈是水的
                waitOutSideWater = new Water();
                waitOutSideWater.SetInsideShore(waterShore);
            }
        }
        if (null != waitOutSideWater)
        {
            Debug.LogError("发现没有匹配成功的");
            ret.Remove(waitOutSideWater);
        }
        Debug.Log("水的数量 " + ret.Count);
        return(ret);
    }
    /// <summary>
    /// Creates the estuary (when river meets shore) geometry.
    /// </summary>
    void TriangulateEstuary(EdgeVertices e1, EdgeVertices e2, bool incomingRiver, Vector3 indices)
    {
        // Some of the estuary is still water shore, namely one triangle on each side
        // that leaves the estuary itself with a trapezoid shape connecting the shore/river to water
        WaterShore.AddTriangle(e2.v1, e1.v2, e1.v1);
        WaterShore.AddTriangle(e2.v5, e1.v5, e1.v4);
        WaterShore.AddTriangleUV(new Vector2(0f, 1f), new Vector2(0f, 0f), new Vector2(0f, 0f));
        WaterShore.AddTriangleUV(new Vector2(0f, 1f), new Vector2(0f, 0f), new Vector2(0f, 0f));

        WaterShore.AddTriangleCellData(indices, weights2, weights1, weights1);
        WaterShore.AddTriangleCellData(indices, weights2, weights1, weights1);

        // Make the estuary trapezoid
        Estuaries.AddQuad(e2.v1, e1.v2, e2.v2, e1.v3);         // Adding it rotated for symetric geometry
        Estuaries.AddTriangle(e1.v3, e2.v2, e2.v4);
        Estuaries.AddQuad(e1.v3, e1.v4, e2.v4, e2.v5);

        // For shore effect
        Estuaries.AddQuadUV(
            new Vector2(0f, 1f), new Vector2(0f, 0f),
            new Vector2(1f, 1f), new Vector2(0f, 0f)
            );
        Estuaries.AddTriangleUV(
            new Vector2(0f, 0f), new Vector2(1f, 1f), new Vector2(1f, 1f)
            );
        Estuaries.AddQuadUV(
            new Vector2(0f, 0f), new Vector2(0f, 0f),
            new Vector2(1f, 1f), new Vector2(0f, 1f)
            );

        Estuaries.AddQuadCellData(indices, weights2, weights1, weights2, weights1);
        Estuaries.AddTriangleCellData(indices, weights1, weights2, weights2);
        Estuaries.AddQuadCellData(indices, weights1, weights2);

        // For river effect, depending on river flow direction UVs are different
        // That is if river flows into the water or out of the water (e.g. when a river starts from a lake)
        if (incomingRiver)
        {
            Estuaries.AddQuadUV2(new Vector2(1.5f, 1f), new Vector2(0.7f, 1.15f), new Vector2(1f, 0.8f), new Vector2(0.5f, 1.1f));
            Estuaries.AddTriangleUV2(new Vector2(0.5f, 1.1f), new Vector2(1f, 0.8f), new Vector2(0f, 0.8f));
            Estuaries.AddQuadUV2(new Vector2(0.5f, 1.1f), new Vector2(0.3f, 1.15f), new Vector2(0f, 0.8f), new Vector2(-0.5f, 1f));
        }
        else
        {
            Estuaries.AddQuadUV2(new Vector2(-0.5f, -0.2f), new Vector2(0.3f, -0.35f), new Vector2(0f, 0f), new Vector2(0.5f, -0.3f));
            Estuaries.AddTriangleUV2(new Vector2(0.5f, -0.3f), new Vector2(0f, 0f), new Vector2(1f, 0f));
            Estuaries.AddQuadUV2(new Vector2(0.5f, -0.3f), new Vector2(0.7f, -0.35f), new Vector2(1f, 0f), new Vector2(1.5f, -0.2f));
        }
    }
Exemplo n.º 8
0
    /// <summary>
    /// 传入的水岸线是否完全在当前的内部
    /// </summary>
    /// <returns><c>true</c> if this instance is water shore inside the specified other; otherwise, <c>false</c>.</returns>
    /// <param name="other">Other.</param>
    public bool IsWaterShoreInside(WaterShore other)
    {
        List <WaterShoreSegment> otherSegments = other.GetAllWaterShoreSegment();

        for (int i = 0; i < otherSegments.Count; ++i)
        {
            WaterShoreSegment waterSegment = otherSegments [i];
            if (!IsPointInSide(waterSegment.posOne))
            {
                return(false);
            }
            if (!IsPointInSide(waterSegment.posTwo))
            {
                return(false);
            }
        }
        return(true);
    }
 /// <summary>
 /// Builds the mesh of the hex grid out of the provided array of cells.
 /// </summary>
 public void Triangulate()
 {
     Terrain.Clear();
     Rivers.Clear();
     Roads.Clear();
     Water.Clear();
     WaterShore.Clear();
     Estuaries.Clear();
     Features.Clear();
     for (int i = 0; i < Cells.Length; i++)
     {
         Triangulate(Cells[i]);
     }
     Terrain.Apply();
     Rivers.Apply();
     Roads.Apply();
     Water.Apply();
     WaterShore.Apply();
     Estuaries.Apply();
     Features.Apply();
 }
Exemplo n.º 10
0
        public void Triangulate(HexCell[] cells)
        {
            Terrain.Clear();
            Rivers.Clear();
            Roads.Clear();
            Water.Clear();
            WaterShore.Clear();
            Estuaries.Clear();
            Features.Clear();

            foreach (var cell in cells)
            {
                TriangulateCell(cell);
            }

            Terrain.Apply();
            Rivers.Apply();
            Roads.Apply();
            Water.Apply();
            WaterShore.Apply();
            Estuaries.Apply();
            Features.Apply();
        }
    /// <summary>
    /// Creates geometry for water connection non water cell.
    /// </summary>
    void TriangulateWaterShore(HexDirection direction, HexCell cell, HexCell neighbor, Vector3 center)
    {
        // Careful to find the WATER corner not the solid corner
        // Careful to get the WATER bridge
        EdgeVertices e1 = new EdgeVertices(
            center + HexMetrics.GetFirstWaterCorner(direction),
            center + HexMetrics.GetSecondWaterCorner(direction)
            );

        // Triangle fan still part of open water
        Water.AddTriangle(center, e1.v1, e1.v2);
        Water.AddTriangle(center, e1.v2, e1.v3);
        Water.AddTriangle(center, e1.v3, e1.v4);
        Water.AddTriangle(center, e1.v4, e1.v5);
        Vector3 indices;

        indices.x = indices.z = cell.Index;
        indices.y = neighbor.Index;
        Water.AddTriangleCellData(indices, weights1);
        Water.AddTriangleCellData(indices, weights1);
        Water.AddTriangleCellData(indices, weights1);
        Water.AddTriangleCellData(indices, weights1);

        // Bridge - We get the bridge by finding the land hex center and working from there
        Vector3 center2 = neighbor.Position;

        if (neighbor.ColumnIndex < cell.ColumnIndex - 1)
        {
            center2.x += HexMetrics.WrapSize * HexMetrics.InnerDiameter;
        }
        else if (neighbor.ColumnIndex > cell.ColumnIndex + 1)
        {
            center2.x -= HexMetrics.WrapSize * HexMetrics.InnerDiameter;
        }
        center2.y = center.y;
        EdgeVertices e2 = new EdgeVertices(
            center2 + HexMetrics.GetSecondSolidCorner(direction.Opposite()),
            center2 + HexMetrics.GetFirstSolidCorner(direction.Opposite())
            );

        if (cell.HasRiverThroughEdge(direction))
        {
            TriangulateEstuary(e1, e2, cell.HasIncomingRiver && cell.IncomingRiver == direction, indices); // River and Shore meet -> Estuary -> different geometry
        }
        else                                                                                               // Else normal shore geometry
        {
            WaterShore.AddQuad(e1.v1, e1.v2, e2.v1, e2.v2);
            WaterShore.AddQuad(e1.v2, e1.v3, e2.v2, e2.v3);
            WaterShore.AddQuad(e1.v3, e1.v4, e2.v3, e2.v4);
            WaterShore.AddQuad(e1.v4, e1.v5, e2.v4, e2.v5);
            WaterShore.AddQuadUV(0f, 0f, 0f, 1f);             // U null, V -> 0 water side, 1 shore side
            WaterShore.AddQuadUV(0f, 0f, 0f, 1f);
            WaterShore.AddQuadUV(0f, 0f, 0f, 1f);
            WaterShore.AddQuadUV(0f, 0f, 0f, 1f);

            WaterShore.AddQuadCellData(indices, weights1, weights2);
            WaterShore.AddQuadCellData(indices, weights1, weights2);
            WaterShore.AddQuadCellData(indices, weights1, weights2);
            WaterShore.AddQuadCellData(indices, weights1, weights2);
        }

        // Corner tripple connection triangle - shore water
        HexCell nextNeighbor = cell.GetNeighbor(direction.Next());

        if (nextNeighbor != null)
        {
            Vector3 center3 = nextNeighbor.Position;
            if (nextNeighbor.ColumnIndex < cell.ColumnIndex - 1)
            {
                center3.x += HexMetrics.WrapSize * HexMetrics.InnerDiameter;
            }
            else if (nextNeighbor.ColumnIndex > cell.ColumnIndex + 1)
            {
                center3.x -= HexMetrics.WrapSize * HexMetrics.InnerDiameter;
            }
            // Since this is a tripple connection we need to check if neighbor is underwater or not
            // If he is underwater connect with WaterCorner if not with SolidCorner
            Vector3 v3 = center3 + (nextNeighbor.IsUnderwater ?
                                    HexMetrics.GetFirstWaterCorner(direction.Previous()) :
                                    HexMetrics.GetFirstSolidCorner(direction.Previous()));
            v3.y = center.y;
            WaterShore.AddTriangle(e1.v5, e2.v5, v3);
            WaterShore.AddTriangleUV(
                new Vector2(0f, 0f),
                new Vector2(0f, 1f),
                new Vector2(0f, nextNeighbor.IsUnderwater ? 0f : 1f)                 // U null, V -> 0 water side, 1 shore side
                );

            indices.z = nextNeighbor.Index;
            WaterShore.AddTriangleCellData(indices, weights1, weights2, weights3);
        }
    }
Exemplo n.º 12
0
 public void SetOutsideShore(WaterShore shore)
 {
     mOutsideShore = shore;
 }
Exemplo n.º 13
0
 public void SetInsideShore(WaterShore shore)
 {
     mInsideShore = shore;
 }
Exemplo n.º 14
0
 public void SetSingleShore(WaterShore shore)
 {
     mSingleShore = shore;
 }
Exemplo n.º 15
0
    void TriangulateWater(HexDirection direction, HexCell cell)
    {
        EdgeVertices closerWaterEdge = cell.WaterEdges[(int)direction];

        // water fan
        Water.AddTriangleUnperturbed(cell.WaterCenter, closerWaterEdge.V1, closerWaterEdge.V5);

        HexCell neighbor = cell.GetNeighbor(direction);

        if (neighbor == null)
        {
            return;
        }

        // estuary
        if (!neighbor.IsUnderwater && cell.HasRiverThroughEdge(direction))
        {
            TriangulateEstuary(cell, direction);
        }

        EdgeVertices furtherEdge      = neighbor.Edges[(int)direction.Opposite()];
        EdgeVertices furtherWaterEdge = neighbor.WaterEdges[(int)direction.Opposite()];
        HexDirection nextDirection    = direction.Next();
        HexCell      nextNeighbor     = cell.GetNeighbor(nextDirection);
        HexCell      previousNeighbor = cell.GetNeighbor(direction.Previous());

        // neighbor is under water as well
        if (neighbor.IsUnderwater)
        {
            if (direction <= HexDirection.SouthEast)
            {
                Water.AddQuadUnperturbed(closerWaterEdge.V1, closerWaterEdge.V5, furtherWaterEdge.V5, furtherWaterEdge.V1);
            }
        }
        // estuary is on the right side
        else if (nextNeighbor != null && nextNeighbor.HasEstuaryThroughEdge(direction.Previous()))
        {
            Vector3 v4 = furtherEdge.V1;
            v4.y = HexMetrics.WaterSurfaceY;
            WaterShore.AddQuadUnperturbed(closerWaterEdge.V1, closerWaterEdge.V5, furtherWaterEdge.V5, v4);
            WaterShore.AddQuadUV(0f, 0f, 0f, 1f);
        }
        // estuary is on the left side
        else if (previousNeighbor != null && previousNeighbor.HasEstuaryThroughEdge(direction.Next()))
        {
            Vector3 v3 = furtherEdge.V5;
            v3.y = HexMetrics.WaterSurfaceY;
            WaterShore.AddQuadUnperturbed(closerWaterEdge.V1, closerWaterEdge.V5, v3, furtherWaterEdge.V1);
            WaterShore.AddQuadUV(0f, 0f, 0f, 1f);
        }
        // standard connection quad
        else if (!cell.HasRiverThroughEdge(direction))
        {
            WaterShore.AddQuadUnperturbed(closerWaterEdge.V1, closerWaterEdge.V5, furtherWaterEdge.V5, furtherWaterEdge.V1);
            WaterShore.AddQuadUV(0f, 0f, 0f, 1f);
        }

        // calculate connection triangles
        if (neighbor.IsUnderwater)
        {
            if (direction <= HexDirection.East && nextNeighbor != null && nextNeighbor.IsUnderwater)
            {
                Vector3 v3 = nextNeighbor.WaterEdges[(int)nextDirection.Opposite()].V5;
                Water.AddTriangleUnperturbed(closerWaterEdge.V5, furtherWaterEdge.V1, v3);
            }
        }
        // calculate water shore
        else if (cell.HasRiverThroughEdge(direction) && nextNeighbor != null)
        {
            Vector3 v2 = neighbor.Edges[(int)direction.Opposite()].V1;
            v2.y = HexMetrics.WaterSurfaceY;
            Vector3 v3 = nextNeighbor.WaterEdges[(int)nextDirection.Opposite()].V5;

            WaterShore.AddTriangleUnperturbed(closerWaterEdge.V5, v2, v3);
            WaterShore.AddTriangleUV(new Vector2(0f, 0f), new Vector2(0f, 1f),
                                     new Vector2(0f, nextNeighbor.IsUnderwater ? 0f : 1f));
        }
        else if (nextNeighbor != null)
        {
            Vector3 v2, v3;
            // estuary is on the right side
            if (cell.HasRiverThroughEdge(nextDirection))
            {
                v2   = furtherWaterEdge.V1;
                v3   = nextNeighbor.Edges[(int)nextDirection.Opposite()].V5;
                v3.y = HexMetrics.WaterSurfaceY;
            }
            // estuary is on the left side
            else if (nextNeighbor.HasEstuaryThroughEdge(direction.Previous()))
            {
                v2   = furtherEdge.V1;
                v2.y = HexMetrics.WaterSurfaceY;
                v3   = nextNeighbor.WaterEdges[(int)nextDirection.Opposite()].V5;
            }
            else
            {
                v2 = furtherWaterEdge.V1;
                v3 = nextNeighbor.WaterEdges[(int)nextDirection.Opposite()].V5;
            }

            WaterShore.AddTriangleUnperturbed(closerWaterEdge.V5, v2, v3);
            WaterShore.AddTriangleUV(new Vector2(0f, 0f), new Vector2(0f, 1f),
                                     new Vector2(0f, nextNeighbor.IsUnderwater ? 0f : 1f));
        }
    }
Exemplo n.º 16
0
 /// <summary>
 /// 在后边加入新的水岸线
 /// </summary>
 /// <param name="waterShore">Water shore.</param>
 private void JoinWaterShoreAtEnd(WaterShore waterShore)
 {
     mWaterShoreSegmentList.AddRange(waterShore.mWaterShoreSegmentList);
     waterShore.mWaterShoreSegmentList = null;
 }
Exemplo n.º 17
0
    private List <WaterShore> GenerateWaterShoreList(List <WaterShoreSegment> waterShoreSegmentList)
    {
        List <WaterShore> waterShoreList = new List <WaterShore> ();

        //先把零散的线段第一次刷选,处理成一一系列的WaterInfo
        for (int i = 0; i < waterShoreSegmentList.Count; ++i)
        {
            WaterShoreSegment waterShoreSegment = waterShoreSegmentList [i];
            bool hasFind = false;
            for (int j = 0; j < waterShoreList.Count; ++j)
            {
                WaterShore waterShore = waterShoreList [j];
                if (waterShore.JoinWaterShoreSegment(waterShoreSegment))
                {
                    hasFind = true;
                    break;
                }
            }
            if (!hasFind)
            {
                WaterShore waterInfo = new WaterShore(waterHeight);
                waterInfo.JoinWaterShoreSegment(waterShoreSegment);
                waterShoreList.Add(waterInfo);
            }
        }

        bool hasJoinSuccess = false;

        for (int i = 0; i < waterShoreList.Count; ++i)
        {
            //之所以j从0开始,因为A连接B失败,但是B连接A有可能成功,可以优化连接函数
            for (int j = 0; j < waterShoreList.Count; ++j)
            {
                if (i == j)
                {
                    continue;
                }
                WaterShore waterShoreA = waterShoreList [i];
                WaterShore waterShoreB = waterShoreList [j];

                //可以为每一个WaterInfo设定唯一表示,并且拼接WaterLine后ID改变,在这里缓存拼接失败的ID对
                if (waterShoreA.JoinWaterShore(waterShoreB))
                {
                    hasJoinSuccess = true;
                    waterShoreList.RemoveAt(j);
                    break;
                }
            }

            //成功拼接后,waterInfos中的某一个数据已经无效,从新开始
            if (hasJoinSuccess)
            {
                i = -1;
                hasJoinSuccess = false;
            }
        }
        Debug.Log("waterInfos.cout:  " + waterShoreList.Count);

        for (int i = 0; i < waterShoreList.Count; ++i)
        {
            waterShoreList [i].CheckError();
        }
        return(waterShoreList);
    }
Exemplo n.º 18
0
        private void TriangulateWaterShore(HexDirection direction, HexCell cell, HexCell neighbour, Vector3 centre)
        {
            var e1 = new EdgeVertices(
                centre + HexMetrics.GetFirstWaterCorner(direction),
                centre + HexMetrics.GetSecondWaterCorner(direction)
                );

            Water.AddTriangle(centre, e1.v1, e1.v2);
            Water.AddTriangle(centre, e1.v2, e1.v3);
            Water.AddTriangle(centre, e1.v3, e1.v4);
            Water.AddTriangle(centre, e1.v4, e1.v5);

            var indices = new Vector3(cell.Index, neighbour.Index, cell.Index);

            Water.AddTriangleCellData(indices, weights1);
            Water.AddTriangleCellData(indices, weights1);
            Water.AddTriangleCellData(indices, weights1);
            Water.AddTriangleCellData(indices, weights1);

            var centre2 = neighbour.Position;

            if (neighbour.ColumnIndex < cell.ColumnIndex - 1)
            {
                centre2.x += HexMetrics.WrapSize * HexMetrics.InnerDiameter;
            }
            else if (neighbour.ColumnIndex > cell.ColumnIndex + 1)
            {
                centre2.x -= HexMetrics.WrapSize * HexMetrics.InnerDiameter;
            }

            centre2.y = centre.y;
            var e2 = new EdgeVertices(
                centre2 + HexMetrics.GetSecondSolidCorner(direction.Opposite()),
                centre2 + HexMetrics.GetFirstSolidCorner(direction.Opposite())
                ); // rather than calculating from current centre, work backwards from neighbour centre to find edge

            if (cell.HasRiverThroughEdge(direction))
            {
                TriangulateEstuary(e1, e2, cell.IncomingRiver == direction, indices);
            }
            else
            {
                WaterShore.AddQuad(e1.v1, e1.v2, e2.v1, e2.v2);
                WaterShore.AddQuad(e1.v2, e1.v3, e2.v2, e2.v3);
                WaterShore.AddQuad(e1.v3, e1.v4, e2.v3, e2.v4);
                WaterShore.AddQuad(e1.v4, e1.v5, e2.v4, e2.v5);
                WaterShore.AddQuadUV(0f, 0f, 0f, 1f);
                WaterShore.AddQuadUV(0f, 0f, 0f, 1f);
                WaterShore.AddQuadUV(0f, 0f, 0f, 1f);
                WaterShore.AddQuadUV(0f, 0f, 0f, 1f);
                WaterShore.AddQuadCellData(indices, weights1, weights2);
                WaterShore.AddQuadCellData(indices, weights1, weights2);
                WaterShore.AddQuadCellData(indices, weights1, weights2);
                WaterShore.AddQuadCellData(indices, weights1, weights2);
            }

            var nextNeighbour = cell.GetNeighbour(direction.Next());

            if (nextNeighbour == null)
            {
                return;
            }

            var centre3 = nextNeighbour.Position;

            if (nextNeighbour.ColumnIndex < cell.ColumnIndex - 1)
            {
                centre3.x += HexMetrics.WrapSize * HexMetrics.InnerDiameter;
            }
            else if (nextNeighbour.ColumnIndex > cell.ColumnIndex + 1)
            {
                centre3.x -= HexMetrics.WrapSize * HexMetrics.InnerDiameter;
            }

            var v3 = centre3 +
                     (nextNeighbour.IsUnderwater ?
                      HexMetrics.GetFirstWaterCorner(direction.Previous()) :
                      HexMetrics.GetFirstSolidCorner(direction.Previous()));

            v3.y = centre.y;
            WaterShore.AddTriangle(e1.v5, e2.v5, v3);
            WaterShore.AddTriangleUV(
                new Vector2(0f, 0f),
                new Vector2(0f, 1f),
                new Vector2(0f, nextNeighbour.IsUnderwater ? 0f : 1f));
            indices.z = nextNeighbour.Index;
            WaterShore.AddTriangleCellData(indices, weights1, weights2, weights3);
        }