Exemplo n.º 1
0
    /// <summary>
    /// 获取传入的三个顶点组成的三角面和水平面相交的线段
    /// </summary>
    /// <returns>The water shore segment.</returns>
    /// <param name="pos1">Pos1.</param>
    /// <param name="pos2">Pos2.</param>
    /// <param name="pos3">Pos3.</param>
    private WaterShoreSegment GetWaterShoreSegment(Vector3 pos1, Vector3 pos2, Vector3 pos3)
    {
        //判断每一个边是否和水平面相交
        Vector3[] hitPoss     = new Vector3[3];
        int       curHitIndex = 0;

        if (IsLineIntersectWater(pos1, pos2, out hitPoss[curHitIndex]))
        {
            ++curHitIndex;
        }
        if (IsLineIntersectWater(pos2, pos3, out hitPoss[curHitIndex]))
        {
            ++curHitIndex;
        }
        if (IsLineIntersectWater(pos3, pos1, out hitPoss[curHitIndex]))
        {
            ++curHitIndex;
        }
        //三条边中只有有两个交点才代表三角面和水平面相交
        if (curHitIndex == 2)
        {
            WaterShoreSegment line = new WaterShoreSegment();
            line.posOne = hitPoss [0];
            line.posTwo = hitPoss [1];
            return(line);
        }
        return(null);
    }
Exemplo n.º 2
0
    void OnDrawGizmos()
    {
        return;

        //画所有的串联起来的边界线
        Color[] allColors = new Color[5];
        allColors [0] = Color.yellow;
        allColors [1] = Color.green;
        allColors [2] = Color.blue;
        allColors [3] = Color.black;

        for (int i = 0; i < waterList.Count; ++i)
        {
            Water water = waterList [i];
            Gizmos.color = allColors[i % allColors.Length];
            List <WaterShoreSegment> waterShoreSegments = water.GetAllWaterShoreSegment();
            for (int j = 0; j < waterShoreSegments.Count; ++j)
            {
                WaterShoreSegment waterSHoreSegment = waterShoreSegments [j];
                Vector3           posOne            = waterSHoreSegment.posOne;
                Vector3           posTwo            = waterSHoreSegment.posTwo;

                posOne.y += 0f;
                posTwo.y += 0f;

                Gizmos.DrawLine(posOne, posTwo);
            }
        }
    }
Exemplo n.º 3
0
 /// <summary>
 /// 获取圈中的任意一点
 /// </summary>
 /// <returns>The inside point.</returns>
 Vector3 GetInsidePoint()
 {
     //TODO 并不能保证这个点不是在其他的圈内部
     System.Text.StringBuilder sbLog = new System.Text.StringBuilder();
     for (int j = 1; j < 2; ++j)
     {
         float offsetDis = j * 0.01f;
         for (int i = 0; i < mWaterShoreSegmentList.Count; ++i)
         {
             WaterShoreSegment waterShore  = mWaterShoreSegmentList [i];
             Vector3           centerPos   = (waterShore.posOne + waterShore.posTwo) / 2;
             Vector3           verticalDir = Vector3.Cross((waterShore.posOne - centerPos).normalized, Vector3.up).normalized;
             Vector3           offsetPoint = centerPos + verticalDir * offsetDis;
             if (IsPointInSide(offsetPoint))
             {
                 return(offsetPoint);
             }
             sbLog.Append(offsetPoint.x + "  " + offsetPoint.z + "\n");
             offsetPoint = centerPos - verticalDir * offsetDis;
             if (IsPointInSide(offsetPoint))
             {
                 return(offsetPoint);
             }
             sbLog.Append(offsetPoint.x + "  " + offsetPoint.z + "\n");
         }
     }
     //TODO 这里真的出现过,需要调查
     IsInvalidShore = true;
     Debug.LogError("居然没有找到在圈内的点  " + ID + "\n" + sbLog.ToString());
     return(Vector3.zero);
 }
Exemplo n.º 4
0
    /// <summary>
    /// 把传入的线放入现有的链表中
    /// </summary>
    /// <returns><c>true</c>, if water line was joined, <c>false</c> otherwise.</returns>
    /// <param name="line">Line.</param>
    public bool  JoinWaterShoreSegment(WaterShoreSegment line)
    {
        if (mWaterShoreSegmentList.Count == 0)
        {
            mWaterShoreSegmentList.Add(line);
            return(true);
        }
        bool needExchange = false;

        if (mWaterShoreSegmentList [0].CanJoinAtFront(line, out needExchange))
        {
            if (needExchange)
            {
                line.ExchangePos();
            }
            mWaterShoreSegmentList.Insert(0, line);
            return(true);
        }
        if (mWaterShoreSegmentList [mWaterShoreSegmentList.Count - 1].CanJoinAtEnd(line, out needExchange))
        {
            if (needExchange)
            {
                line.ExchangePos();
            }
            mWaterShoreSegmentList.Add(line);
            return(true);
        }
        return(false);
    }
Exemplo n.º 5
0
 /// <summary>
 /// 获取所有水岸线的点
 /// </summary>
 /// <returns>The all shore point.</returns>
 public List <Vector3> GetAllShorePoint()
 {
     if (null == mWaterShorePointList)
     {
         mWaterShorePointList = new List <Vector3> ();
         for (int i = 0; i < mWaterShoreSegmentList.Count; ++i)
         {
             WaterShoreSegment shoreSegment = mWaterShoreSegmentList [i];
             if (mWaterShorePointList.Count == 0)
             {
                 mWaterShorePointList.Add(shoreSegment.posOne);
                 mWaterShorePointList.Add(shoreSegment.posTwo);
             }
             else
             {
                 if (!shoreSegment.IsPointNear(shoreSegment.posOne, mWaterShorePointList [mWaterShorePointList.Count - 1]))
                 {
                     mWaterShorePointList.Add(shoreSegment.posOne);
                 }
                 mWaterShorePointList.Add(shoreSegment.posTwo);
             }
         }
     }
     if (mWaterShorePointList[0].Equals(mWaterShorePointList[mWaterShorePointList.Count - 1]))
     {
         mWaterShorePointList.RemoveAt(mWaterShorePointList.Count - 1);
     }
     return(mWaterShorePointList);
 }
Exemplo n.º 6
0
 /// <summary>
 /// 传入的水的边界线是否能够连接在当前线段的后面,如果能够相连,是否需要自动变换前后坐标
 /// </summary>
 /// <returns><c>true</c>, if in front water line was joined, <c>false</c> otherwise.</returns>
 /// <param name="waterLine">Water line.</param>
 public bool CanJoinAtEnd(WaterShoreSegment segment, out bool needExchangePos)
 {
     needExchangePos = false;
     if (IsPointNear(posTwo, segment.posTwo))
     {
         needExchangePos = true;
         return(true);
     }
     if (IsPointNear(posTwo, segment.posOne))
     {
         return(true);
     }
     return(false);
 }
Exemplo n.º 7
0
    bool IsPointInSide(Vector3 point)
    {
        int intersectionCount = 0;

        for (int i = 0; i < mWaterShoreSegmentList.Count; ++i)
        {
            WaterShoreSegment shoreSegment = mWaterShoreSegmentList [i];
            if (Utils.IsLineIntersection(point, new Vector3(100f, mWaterHeight, 100f)
                                         , shoreSegment.posOne, shoreSegment.posTwo))
            {
                intersectionCount++;
            }
        }
        return(intersectionCount % 2 != 0);
    }
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);
    }
Exemplo n.º 9
0
 /// <summary>
 /// 裁减掉极小的不必要的线段
 /// </summary>
 /// <param name="waterLineLength">Water line length.</param>
 public void CullSmallShoreSegment(float waterLineLength)
 {
     if (mWaterShoreSegmentList.Count == 1)
     {
         return;
     }
     for (int i = mWaterShoreSegmentList.Count - 1; i >= 1; --i)
     {
         WaterShoreSegment curSegment   = mWaterShoreSegmentList [i];
         WaterShoreSegment frontSegment = mWaterShoreSegmentList [i - 1];
         if (curSegment.GetLength() < waterLineLength)
         {
             mWaterShoreSegmentList.RemoveAt(i);
             frontSegment.posTwo = curSegment.posTwo;
         }
     }
     GetAllShorePoint();
 }
Exemplo n.º 10
0
 /// <summary>
 /// 检查是否有问题
 /// </summary>
 public void CheckError()
 {
     for (int i = 0; i < mWaterShoreSegmentList.Count - 1; ++i)
     {
         WaterShoreSegment curSegment  = mWaterShoreSegmentList [i];
         WaterShoreSegment nextSegment = mWaterShoreSegmentList [i + 1];
         bool needExchange             = false;
         if (curSegment.CanJoinAtEnd(nextSegment, out needExchange))
         {
             if (!needExchange)
             {
                 continue;
             }
         }
         if (Vector3.Distance(curSegment.posTwo, nextSegment.posOne) > Vector3.Distance(curSegment.posTwo, nextSegment.posTwo))
         {
             Debug.LogError("CheckError    1:  " + curSegment.ToString() + "   " + nextSegment.ToString());
         }
         Debug.LogError("CheckError    2:  " + curSegment.ToString() + "   " + nextSegment.ToString());
     }
 }
Exemplo n.º 11
0
    private List <WaterShoreSegment> GetAllWaterShoreSegment()
    {
        List <WaterShoreSegment> waterShoreSegmentList = new List <WaterShoreSegment> ();

        float[,] heights = terrainData.GetHeights(0, 0, terrainData.heightmapWidth, terrainData.heightmapHeight);

        for (int i = 0; i < terrainData.heightmapWidth - 1; ++i)
        {
            for (int j = 0; j < terrainData.heightmapHeight - 1; ++j)
            {
                //遍历每一个正方形,每一个正方形对应两个三角面,正方形顶点反向为
                //  1 ----- 2
                //  |       |
                //  |       |
                //  0 ----- 3
                Vector3 pos0 = GetWorldPosByTerrainGrid(heights, i, j);
                Vector3 pos1 = GetWorldPosByTerrainGrid(heights, i, j + 1);
                Vector3 pos2 = GetWorldPosByTerrainGrid(heights, i + 1, j + 1);
                Vector3 pos3 = GetWorldPosByTerrainGrid(heights, i + 1, j);

                //第一个三角面三个顶点为0,1,2;
                WaterShoreSegment waterShoreSegment = GetWaterShoreSegment(pos0, pos1, pos2);
                if (waterShoreSegment != null)
                {
                    waterShoreSegmentList.Add(waterShoreSegment);
                }
                //第二个三角面三个顶点为0,2,3
                waterShoreSegment = GetWaterShoreSegment(pos0, pos2, pos3);
                if (waterShoreSegment != null)
                {
                    waterShoreSegmentList.Add(waterShoreSegment);
                }
            }
        }

        return(waterShoreSegmentList);
    }
Exemplo n.º 12
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);
    }