public void TriangulateNextCornerTerracesCliff(
        Vector3 begin, HexCell beginCell, Vector3 left,
        Vector3 right, HexCell neighbor, HexCell nextNeighbor
        )
    {
        float   b        = 1.6f / (nextNeighbor.Position.y - beginCell.Position.y);
        Vector3 boundary = Vector3.Lerp(HexMetrics.Perturb(right), HexMetrics.Perturb(begin), b);
        Vector3 v3       = HexMetrics.Perturb(HexMetrics.TerraceLerp(left, begin, 1));

        //bottom quad
        terrain.AddQuadUnperturbed(boundary, HexMetrics.Perturb(right), v3, HexMetrics.Perturb(left));
        terrain.AddQuadColor(neighbor.Color);

        //middle tris
        for (int i = 2; i < HexMetrics.terraceSteps; i++)
        {
            Vector3 v1 = v3;
            v3 = HexMetrics.Perturb(HexMetrics.TerraceLerp(left, begin, i));
            terrain.AddTriangleUnperturbed(boundary, v3, v1);
            terrain.AddTriangleColor(neighbor.Color);
        }

        //top tri
        terrain.AddTriangleUnperturbed(HexMetrics.Perturb(begin), v3, boundary);
        terrain.AddTriangleColor(neighbor.Color);
    }
예제 #2
0
    void TriangulateWaterfallInWater(Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, float y1, float y2, float waterY, Vector3 indices)
    {
        v1.y = v2.y = y1;
        v3.y = v4.y = y2;
        v1   = HexMetrics.Perturb(v1);
        v2   = HexMetrics.Perturb(v2);
        v3   = HexMetrics.Perturb(v3);
        v4   = HexMetrics.Perturb(v4);
        float t = (waterY - y2) / (y1 - y2);

        v3 = Vector3.Lerp(v3, v1, t);
        v4 = Vector3.Lerp(v4, v2, t);
        rivers.AddQuadUnperturbed(v1, v2, v3, v4);
        rivers.AddQuadUV(0f, 1f, 0.8f, 1f);
        rivers.AddQuadCellData(indices, weights1, weights2);
    }
예제 #3
0
    void AddWallSegment(
        Vector3 nearLeft, Vector3 farLeft, Vector3 nearRight, Vector3 farRight,
        bool addTower = false
        )
    {
        nearLeft  = HexMetrics.Perturb(nearLeft);
        farLeft   = HexMetrics.Perturb(farLeft);
        nearRight = HexMetrics.Perturb(nearRight);
        farRight  = HexMetrics.Perturb(farRight);

        Vector3 left  = HexMetrics.WallLerp(nearLeft, farLeft);
        Vector3 right = HexMetrics.WallLerp(nearRight, farRight);

        Vector3 leftThicknessOffset =
            HexMetrics.WallThicknessOffset(nearLeft, farLeft);
        Vector3 rightThicknessOffset =
            HexMetrics.WallThicknessOffset(nearRight, farRight);

        float leftTop  = left.y + HexMetrics.wallHeight;
        float rightTop = right.y + HexMetrics.wallHeight;

        Vector3 v1, v2, v3, v4;

        v1   = v3 = left - leftThicknessOffset;
        v2   = v4 = right - rightThicknessOffset;
        v3.y = leftTop;
        v4.y = rightTop;
        walls.AddQuadUnperturbed(v1, v2, v3, v4);
        walls.AddQuadCellData(v1, new Color(0, 0, 0, 1), new Color(featureColor.r / 2, featureColor.g / 2, featureColor.b / 2, 1), new Color(featureColor.r / 2, featureColor.g / 2, featureColor.b / 2, 1), featureColor);
        Vector3 t1 = v3, t2 = v4;

        v1   = v3 = left + leftThicknessOffset;
        v2   = v4 = right + rightThicknessOffset;
        v3.y = leftTop;
        v4.y = rightTop;
        walls.AddQuadUnperturbed(v2, v1, v4, v3);
        walls.AddQuadCellData(v1, new Color(0, 0, 0, 1f), new Color(featureColor.r / 2, featureColor.g / 2, featureColor.b / 2, 1), new Color(featureColor.r / 2, featureColor.g / 2, featureColor.b / 2, 1), featureColor);

        walls.AddQuadUnperturbed(t1, t2, v3, v4);
        walls.AddQuadCellData(v1, new Color(0, 0, 0, 1f), new Color(featureColor.r / 2, featureColor.g / 2, featureColor.b / 2, 1), new Color(featureColor.r / 2, featureColor.g / 2, featureColor.b / 2, 1), featureColor);

        if (addTower)
        {
            Transform towerInstance = Instantiate(wallTower);
            towerInstance.transform.localPosition = (left + right) * 0.5f;
            Vector3 rightDirection = right - left;
            rightDirection.y = 0f;
            towerInstance.transform.right = rightDirection;
            foreach (MeshRenderer renderer in towerInstance.GetComponentsInChildren <MeshRenderer>())
            {
                renderer.material.color = secondaryColor;
            }
            towerInstance.SetParent(container, false);
        }
    }
예제 #4
0
    /// <summary>
    /// Для создания основных участков стены
    /// </summary>
    /// <param name="nearLeft"></param>
    /// <param name="farLeft"></param>
    /// <param name="nearRight"></param>
    /// <param name="farRight"></param>
    private void AddWallSegment(
        Vector3 nearLeft, Vector3 farLeft, Vector3 nearRight, Vector3 farRight, bool addTower = false
        )
    {
        //заранее искажаем вершины
        nearLeft  = HexMetrics.Perturb(nearLeft);
        farLeft   = HexMetrics.Perturb(farLeft);
        nearRight = HexMetrics.Perturb(nearRight);
        farRight  = HexMetrics.Perturb(farRight);

        //края середины соединения
        Vector3 left  = HexMetrics.WallLerp(nearLeft, farLeft);
        Vector3 right = HexMetrics.WallLerp(nearRight, farRight);

        float leftTop  = left.y + HexMetrics.wallHeight;
        float rightTop = right.y + HexMetrics.wallHeight;
        //смещение краев(толщина стены)
        Vector3 leftThicknessOffset =
            HexMetrics.WallThicknessOffset(nearLeft, farLeft);
        Vector3 rightThicknessOffset =
            HexMetrics.WallThicknessOffset(nearRight, farRight);

        Vector3 v1, v2, v3, v4;

        v1   = v3 = left - leftThicknessOffset;
        v2   = v4 = right - rightThicknessOffset;
        v3.y = leftTop;
        v4.y = rightTop;
        walls.AddQuadUnperturbed(v1, v2, v3, v4);

        Vector3 t1 = v3, t2 = v4;//верхняя часть стен

        v1   = v3 = left + leftThicknessOffset;
        v2   = v4 = right + rightThicknessOffset;
        v3.y = leftTop;
        v4.y = rightTop;
        walls.AddQuadUnperturbed(v2, v1, v4, v3);

        walls.AddQuadUnperturbed(t1, t2, v3, v4);//верхняя часть стен

        //спавн башни
        if (addTower)
        {
            Transform towerInstance = Instantiate(wallTower);
            towerInstance.transform.localPosition = (left + right) * 0.5f;
            Vector3 rightDirection = right - left;
            rightDirection.y = 0f;
            towerInstance.transform.right = rightDirection;
            towerInstance.SetParent(container, false);
        }
    }
예제 #5
0
    public void AddWallSegment(Vector3 nearLeft, Vector3 farLeft, Vector3 nearRight, Vector3 farRight, bool addTower = false)
    {
        nearLeft  = HexMetrics.PerturbVector(nearLeft);
        farLeft   = HexMetrics.PerturbVector(farLeft);
        nearRight = HexMetrics.PerturbVector(nearRight);
        farRight  = HexMetrics.PerturbVector(farRight);


        Vector3 left  = HexMetrics.WallLerp(nearLeft, farLeft);
        Vector3 right = HexMetrics.WallLerp(nearRight, farRight);

        Vector3 leftOffset  = HexMetrics.WallThicknessOffset(nearLeft, farLeft);
        Vector3 rightOffset = HexMetrics.WallThicknessOffset(nearRight, farRight);


        float leftTop  = left.y + HexMetrics.WallHeight;
        float rightTop = right.y + HexMetrics.WallHeight;

        Vector3 v1, v2, v3, v4;

        v1   = v3 = left - leftOffset;
        v2   = v4 = right - rightOffset;
        v3.y = leftTop;
        v4.y = rightTop;

        Walls.AddQuadUnperturbed(v1, v2, v3, v4);

        Vector3 t1 = v3, t2 = v4;


        v1 = v3 = left + leftOffset;
        v2 = v4 = right + rightOffset;

        v3.y = leftTop;
        v4.y = rightTop;

        Walls.AddQuadUnperturbed(v2, v1, v4, v3);

        // top
        Walls.AddQuadUnperturbed(t1, t2, v3, v4);

        if (addTower)
        {
            Transform towerInstance = Instantiate(WallTower);
            towerInstance.transform.localPosition = (left + right) * 0.5f;
            Vector3 rightDirection = right - left;
            rightDirection.y = 0;
            towerInstance.transform.right = rightDirection;
            towerInstance.SetParent(m_container, false);
        }
    }
    /// <summary>
    /// Creates a quad perpendicular to the wall to close off the side. Usefull in wall openings
    /// for road passage for example.
    /// </summary>
    void AddWallCap(Vector3 near, Vector3 far)
    {
        near = HexMetrics.Perturb(near);
        far  = HexMetrics.Perturb(far);

        Vector3 center    = HexMetrics.WallLerp(near, far);
        Vector3 thickness = HexMetrics.WallThicknessOffset(near, far);

        Vector3 v1, v2, v3, v4;

        v1   = v3 = center - thickness;
        v2   = v4 = center + thickness;
        v3.y = v4.y = center.y + HexMetrics.WallHeight;
        Walls.AddQuadUnperturbed(v1, v2, v3, v4);
    }
예제 #7
0
    /// <summary>
    /// 创建一段围墙
    /// </summary>
    /// <param name="nearLeft">内侧边的左顶点</param>
    /// <param name="farLeft">外侧边左顶点</param>
    /// <param name="nearRight">内侧点的右顶点</param>
    /// <param name="farRight">外侧边右顶点</param>
    /// <param name="addTower">是否在本段围墙添加塔楼</param>
    void AddWallSegment(Vector3 nearLeft, Vector3 farLeft, Vector3 nearRight, Vector3 farRight, bool addTower = false)
    {
        // 先对六边形的顶点进行微扰再计算围墙,以免用算出围墙之后再被微扰导致围墙厚薄不一
        nearLeft  = HexMetrics.Perturb(nearLeft);
        farLeft   = HexMetrics.Perturb(farLeft);
        nearRight = HexMetrics.Perturb(nearRight);
        farRight  = HexMetrics.Perturb(farRight);

        Vector3 left  = HexMetrics.WallLerp(nearLeft, farLeft);
        Vector3 right = HexMetrics.WallLerp(nearRight, farRight);

        Vector3 leftOffset  = HexMetrics.WallThicknessOffset(nearLeft, farLeft);   // 左侧顶点近处指向远处的向量,向量长度为墙壁厚度的一半
        Vector3 rightOffset = HexMetrics.WallThicknessOffset(nearRight, farRight); // 右侧顶点近处指向远处的向量,向量长度为墙壁厚度的一半

        float leftTop  = left.y + HexMetrics.wallHeight;                           // 计算左上方顶点坐标
        float rightTop = right.y + HexMetrics.wallHeight;                          // 计算右上方顶点坐标

        Vector3 v1, v2, v3, v4;

        v1   = v3 = left - leftOffset;
        v2   = v4 = right - rightOffset;
        v3.y = leftTop;                                     // 左顶点高度
        v4.y = rightTop;                                    // 右顶点高度

        walls.AddQuadUnperturbed(v1, v2, v3, v4);           // 生成围墙内侧四边形

        Vector3 t1 = v3, t2 = v4;                           // 记录内侧围墙四边形顶部两个顶点

        v1   = v3 = left + leftOffset;
        v2   = v4 = right + rightOffset;
        v3.y = leftTop;                                     // 左顶点高度
        v4.y = rightTop;                                    // 右顶点高度

        walls.AddQuadUnperturbed(v2, v1, v4, v3);           // 生成围墙外侧四边形

        walls.AddQuadUnperturbed(t1, t2, v3, v4);           // 生成围墙顶部四边形

        // 实例化塔楼
        if (addTower)
        {
            Transform towerInstance = Instantiate(wallTower);
            towerInstance.transform.localPosition = (left + right) * 0.5f;  // 坐标设为围墙中心线的中点
            Vector3 rightDirection = right - left;
            rightDirection.y = 0f;
            towerInstance.transform.right = rightDirection;                 // 设置旋转
            towerInstance.SetParent(container, false);
        }
    }
예제 #8
0
    /// <summary>
    /// 三角化瀑布
    /// </summary>
    /// <param name="v1">从瀑布上方,自上而下看,上方左边的顶点</param>
    /// <param name="v2">上右顶点</param>
    /// <param name="v3">下左顶点</param>
    /// <param name="v4">下右顶点</param>
    /// <param name="y1">上方所在六边形河流高度</param>
    /// <param name="y2">下方所在六边形河流高度</param>
    /// <param name="waterY">下方水平面高度</param>
    void TriangulateWaterfallInWater(Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, float y1, float y2, float waterY, Vector3 indices)
    {
        // 让桥边线顶点高度变成河流高度
        v1.y = v2.y = y1;
        v3.y = v4.y = y2;

        // 由于底部顶点的位置已经改变了,它们和原始顶点受微扰的程度不一样。
        // 这意味着最后的结果和原始瀑布不相符。为了解决这个问题,我们需要在插值前手动微扰顶点,然后加上一个未被微扰的四边形。
        v1 = HexMetrics.Perturb(v1);
        v2 = HexMetrics.Perturb(v2);
        v3 = HexMetrics.Perturb(v3);
        v4 = HexMetrics.Perturb(v4);

        // 用插值的方法获得v3->v1向量、v4->v2向量与水平面的交点
        float t = (waterY - y2) / (y1 - y2);

        v3 = Vector3.Lerp(v3, v1, t);
        v4 = Vector3.Lerp(v4, v2, t);

        rivers.AddQuadUnperturbed(v1, v2, v3, v4);
        rivers.AddQuadUV(0f, 1f, 0.8f, 1f);
        rivers.AddQuadCellData(indices, weights1, weights2);
    }
    private void AddWallSegment(Vector3 nearLeft, Vector3 farLeft, Vector3 nearRight, Vector3 farRight, bool addTower = false)
    {
        nearLeft  = HexMetrics.Perturb(nearLeft);
        nearRight = HexMetrics.Perturb(nearRight);
        farLeft   = HexMetrics.Perturb(farLeft);
        farRight  = HexMetrics.Perturb(farRight);

        var left  = HexMetrics.WallLerp(nearLeft, farLeft);
        var right = HexMetrics.WallLerp(nearRight, farRight);

        var leftThicknessOffset  = HexMetrics.WallThicknessOffset(nearLeft, farLeft);
        var rightThicknessOffset = HexMetrics.WallThicknessOffset(nearRight, farRight);

        var leftTop  = left.y + HexMetrics.wallHeight;
        var rightTop = right.y + HexMetrics.wallHeight;

        Vector3 v1, v2, v3, v4;

        v1   = v3 = left - leftThicknessOffset;
        v2   = v4 = right - rightThicknessOffset;
        v3.y = leftTop;
        v4.y = rightTop;
        walls.AddQuadUnperturbed(v1, v2, v3, v4);

        Vector3 t1 = v3, t2 = v4;

        v1   = v3 = left + leftThicknessOffset;
        v2   = v4 = right + rightThicknessOffset;
        v3.y = leftTop;
        v4.y = rightTop;
        walls.AddQuadUnperturbed(v2, v1, v4, v3);

        walls.AddQuadUnperturbed(t1, t2, v3, v4);

        if (addTower)
        {
            var tower = Instantiate(wallTower, container, false);
            tower.transform.localPosition = (left + right) * .5f;
            var rightDir = right - left;
            rightDir.y            = 0;
            tower.transform.right = rightDir;
        }
    }
예제 #10
0
    void AddWallSegment(Vector3 nearLeft, Vector3 farLeft, Vector3 nearRight, Vector3 farRight, bool addTower = false)
    {
        nearLeft  = HexMetrics.Perturb(nearLeft);
        farLeft   = HexMetrics.Perturb(farLeft);
        nearRight = HexMetrics.Perturb(nearRight);
        farRight  = HexMetrics.Perturb(farRight);

        Vector3 left  = HexMetrics.WallLerp(nearLeft, farLeft);
        Vector3 right = HexMetrics.WallLerp(nearRight, farRight);

        Vector3 leftThicknessOffset = HexMetrics.WallThicknessOffset(nearLeft, farLeft);
        Vector3 rightThicknessOfsset = HexMetrics.WallThicknessOffset(nearRight, farRight);
        Vector3 topLeftNear, topRightNear;

        Vector3 v1, v2, v3, v4;

        v1   = v3 = left - leftThicknessOffset;
        v2   = v4 = right - rightThicknessOfsset;
        v3.y = left.y + HexMetrics.wallHeight;
        v4.y = right.y + HexMetrics.wallHeight;
        walls.AddQuadUnperturbed(v1, v2, v3, v4);
        topLeftNear  = v3;
        topRightNear = v4;
        v1           = v3 = left + leftThicknessOffset;
        v2           = v4 = right + rightThicknessOfsset;
        v3.y         = left.y + HexMetrics.wallHeight;
        v4.y         = right.y + HexMetrics.wallHeight;
        walls.AddQuadUnperturbed(v2, v1, v4, v3);
        walls.AddQuadUnperturbed(topLeftNear, topRightNear, v3, v4);

        if (addTower)
        {
            Transform towerInstance = Instantiate(wallTower);
            towerInstance.transform.localPosition = (left + right) * 0.5f;
            Vector3 rightDirection = right - left;
            rightDirection.y = 0f;
            towerInstance.transform.right = rightDirection;
            towerInstance.SetParent(container, false);
        }
    }
예제 #11
0
    void AddWallSegment(
        Vector3 nearLeft, Vector3 farLeft, Vector3 nearRight, Vector3 farRight
        )
    {
        nearLeft  = HexMetrics.Perturb(nearLeft);
        farLeft   = HexMetrics.Perturb(farLeft);
        nearRight = HexMetrics.Perturb(nearRight);
        farRight  = HexMetrics.Perturb(farRight);

        Vector3 left  = HexMetrics.WallLerp(nearLeft, farLeft);
        Vector3 right = HexMetrics.WallLerp(nearRight, farRight);

        Vector3 leftThicknessOffset =
            HexMetrics.WallThicknessOffset(nearLeft, farLeft);
        Vector3 rightThicknessOffset =
            HexMetrics.WallThicknessOffset(nearRight, farRight);

        float leftTop  = left.y + HexMetrics.wallHeight;
        float rightTop = right.y + HexMetrics.wallHeight;

        Vector3 v1, v2, v3, v4;

        v1   = v3 = left - leftThicknessOffset;
        v2   = v4 = right - rightThicknessOffset;
        v3.y = leftTop;
        v4.y = rightTop;
        walls.AddQuadUnperturbed(v1, v2, v3, v4);

        Vector3 t1 = v3, t2 = v4;

        v1   = v3 = left + leftThicknessOffset;
        v2   = v4 = right + rightThicknessOffset;
        v3.y = leftTop;
        v4.y = rightTop;
        walls.AddQuadUnperturbed(v2, v1, v4, v3);

        walls.AddQuadUnperturbed(t1, t2, v3, v4);
    }