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); }
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); }
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); } }
/// <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); } }
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); }
/// <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); } }
/// <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; } }
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); } }
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); }