public HexEdgeType GetEdgeType(HexDirection direction) { return(HexMetrics.GetEdgeType( elevation, neighbors[(int)direction].elevation )); }
public static HexEdge Build(HexCell cell1, HexCell cell2, HexDirection direction) { EdgeVertices e1 = new EdgeVertices( cell1.Position + HexMetrics.GetFirstSolidCorner(direction), cell1.Position + HexMetrics.GetSecondSolidCorner(direction) ); EdgeVertices e2 = new EdgeVertices( cell2.Position + HexMetrics.GetSecondSolidCorner(direction.Opposite()), cell2.Position + HexMetrics.GetFirstSolidCorner(direction.Opposite()) ); HexEdge edge; HexEdgeType edgeType = HexMetrics.GetEdgeType(cell1.Elevation, cell2.Elevation); if (edgeType == HexEdgeType.Flat) { edge = new FlatHexEdge(e1, e2, cell1.Color, cell2.Color); } else if (edgeType == HexEdgeType.Slope) { edge = new SlopeHexEdge(e1, e2, cell1.Color, cell2.Color); } else { edge = new CliffHexEdge(e1, e2, cell1.Color, cell2.Color); } return(edge); }
///桥洞三角化 void TriangulateCorner(Vector3 bottom, Color bottomColor, Vector3 left, Color leftColor, Vector3 right, Color rightColor, ref DynamicBuffer <ColorBuffer> colorBuffer, ref DynamicBuffer <VertexBuffer> vertexBuffer, int bottomElevation, int leftElevation, int rightElevation) { HexMetrics.HexEdgeType leftEdgeType = HexMetrics.GetEdgeType(bottomElevation, leftElevation); HexMetrics.HexEdgeType rightEdgeType = HexMetrics.GetEdgeType(bottomElevation, rightElevation); if (leftEdgeType == HexMetrics.HexEdgeType.Slope) { if (rightEdgeType == HexMetrics.HexEdgeType.Slope) { TriangulateCornerTerraces(bottom, bottomColor, left, leftColor, right, rightColor, ref colorBuffer, ref vertexBuffer); } else if (rightEdgeType == HexMetrics.HexEdgeType.Flat) { TriangulateCornerTerraces(left, leftColor, right, rightColor, bottom, bottomColor, ref colorBuffer, ref vertexBuffer); } else { TriangulateCornerTerracesCliff(bottom, bottomColor, left, leftColor, right, rightColor, ref colorBuffer, ref vertexBuffer, bottomElevation, leftElevation, rightElevation); } } else if (rightEdgeType == HexMetrics.HexEdgeType.Slope) { if (leftEdgeType == HexMetrics.HexEdgeType.Flat) { TriangulateCornerTerraces(right, rightColor, bottom, bottomColor, left, leftColor, ref colorBuffer, ref vertexBuffer); } else { TriangulateCornerCliffTerraces(bottom, bottomColor, left, leftColor, right, rightColor, ref colorBuffer, ref vertexBuffer, bottomElevation, leftElevation, rightElevation); } } else if (HexMetrics.GetEdgeType(leftElevation, rightElevation) == HexMetrics.HexEdgeType.Slope) { if (leftElevation < rightElevation) { TriangulateCornerCliffTerraces(right, rightColor, bottom, bottomColor, left, leftColor, ref colorBuffer, ref vertexBuffer, rightElevation, bottomElevation, leftElevation); } else { TriangulateCornerTerracesCliff(left, leftColor, right, rightColor, bottom, bottomColor, ref colorBuffer, ref vertexBuffer, leftElevation, rightElevation, bottomElevation); } } else { ////两个单元处于同一平面,填充桥三角补丁,添加桥三角的3个顶点 AddTriangle(bottom, bottomColor, left, leftColor, right, rightColor, ref colorBuffer, ref vertexBuffer); } }
///峭壁镜像处理:左右对调 void TriangulateCornerCliffTerraces(Vector3 begin, Color beginCellColor, Vector3 left, Color leftCellColor, Vector3 right, Color rightCellColor, ref DynamicBuffer <ColorBuffer> colorBuffer, ref DynamicBuffer <VertexBuffer> vertexBuffer, int bottomElevation, int leftElevation, int rightElevation) { float b = 1f / (leftElevation - bottomElevation); if (b < 0) { b = -b; } Vector3 boundary = Vector3.Lerp(begin, left, b); Color boundaryColor = Color.Lerp(beginCellColor, leftCellColor, b); TriangulateBoundaryTriangle(right, rightCellColor, begin, beginCellColor, boundary, boundaryColor, ref colorBuffer, ref vertexBuffer); if (HexMetrics.GetEdgeType(leftElevation, rightElevation) == HexMetrics.HexEdgeType.Slope) { TriangulateBoundaryTriangle(left, leftCellColor, right, rightCellColor, boundary, boundaryColor, ref colorBuffer, ref vertexBuffer); } else { AddTriangle(left, leftCellColor, right, rightCellColor, boundary, boundaryColor, ref colorBuffer, ref vertexBuffer); } }
public override void Triangulate(HexMesh mesh) { float lerpCoef = (float)(rightCell.Elevation - beginCell.Elevation) / (leftCell.Elevation - beginCell.Elevation); if (lerpCoef < 0) { lerpCoef = -lerpCoef; } Vector3 boundary = Vector3.Lerp(HexMetrics.Perturb(beginCorner), HexMetrics.Perturb(leftCorner), lerpCoef); Color boundaryColor = Color.Lerp(beginCell.Color, leftCell.Color, lerpCoef); Corner.TriangulateBoundaryTriangle(mesh, rightCorner, rightCell, beginCorner, beginCell, boundary, boundaryColor); if (HexMetrics.GetEdgeType(leftCell.Elevation, rightCell.Elevation) == HexEdgeType.Slope) { TriangulateBoundaryTriangle(mesh, leftCorner, leftCell, rightCorner, rightCell, boundary, boundaryColor); } else { mesh.AddTriangle(HexMetrics.Perturb(leftCorner), HexMetrics.Perturb(rightCorner), boundary, false); mesh.AddTriangleColor(leftCell.Color, rightCell.Color, boundaryColor); } }
public HexEdgeType GetEdgeType(HexDirectionEnum direction) { return(HexMetrics.GetEdgeType(Elevation, GetNeighbor(direction).Elevation)); }
public HexEdgeType GetEdgeType(HexCell other) { return(HexMetrics.GetEdgeType(elevation, other.elevation)); }
public void Execute(Entity entity, int index, [ReadOnly] ref Cell cellData, [ReadOnly] ref NewDataTag tag, [ReadOnly] ref Neighbors neighbors, [ReadOnly] ref NeighborsIndex neighborsIndex, [ReadOnly] ref River river) { //0.获取单元索引,Execute的index不可靠,添加动态缓存 int cellIndex = cellData.Index; DynamicBuffer <ColorBuffer> colorBuffer = CommandBuffer.AddBuffer <ColorBuffer>(index, entity); DynamicBuffer <VertexBuffer> vertexBuffer = CommandBuffer.AddBuffer <VertexBuffer>(index, entity); //用于河流的动态缓存 DynamicBuffer <UvBuffer> uvBuffer = CommandBuffer.AddBuffer <UvBuffer>(index, entity); DynamicBuffer <RiverBuffer> riverBuffers = CommandBuffer.AddBuffer <RiverBuffer>(index, entity); //1.获取当前单元的中心位置 Vector3 currCellCenter = cellData.Position; //缓存当前单元的颜色 Color currCellColor = cellData.Color; //当前单元的海拔 int elevation = cellData.Elevation; ////保存需要混合的颜色,使用数组[]是为了方便循环 Color[] blendColors = new Color[6]; blendColors[0] = neighbors.NE; blendColors[1] = neighbors.E; blendColors[2] = neighbors.SE; blendColors[3] = neighbors.SW; blendColors[4] = neighbors.W; blendColors[5] = neighbors.NW; //前3个方向相邻单元的索引 int[] directionIndex = new int[6]; directionIndex[0] = neighborsIndex.NEIndex; directionIndex[1] = neighborsIndex.EIndex; directionIndex[2] = neighborsIndex.SEIndex; directionIndex[3] = neighborsIndex.SWIndex; directionIndex[4] = neighborsIndex.WIndex; directionIndex[5] = neighborsIndex.NWIndex; //前三个方向相邻单元的海拔 int[] elevations = new int[6]; elevations[0] = neighbors.NEElevation; elevations[1] = neighbors.EElevation; elevations[2] = neighbors.SEElevation; elevations[3] = neighbors.SWElevation; elevations[4] = neighbors.WElevation; elevations[5] = neighbors.NWElevation; //添加六边形单元六个方向的顶点、三角和颜色 for (int j = 0; j < 6; j++) { //1.添加中心区域的3个顶点 int next = (j + 1) > 5 ? 0 : (j + 1); EdgeVertices e = new EdgeVertices((currCellCenter + HexMetrics.SolidCorners[j]), (currCellCenter + HexMetrics.SolidCorners[next])); int prev = (j - 1) < 0 ? 5 : (j - 1); int next2 = (j + 2) <= 5 ? (j + 2) : (j - 4); int prev2 = (j - 2) >= 0 ? (j - 2) : (j + 4); //是否有河流通过 bool hasRiverThroughEdge = HasRiverThroughEdge(river, directionIndex[j]); float RiverSurfaceY = (elevation + HexMetrics.riverSurfaceElevationOffset) * HexMetrics.elevationStep; //如果有河流通过,则降低海拔来创造河道 if (cellData.HasRiver) { if (hasRiverThroughEdge) { e.v3.y = (elevation + HexMetrics.streamBedElevationOffset) * HexMetrics.elevationStep; if (river.HasOutgoingRiver != river.HasIncomingRiver) { //TriangulateWithRiverBeginOrEnd(directions[j], directions[prev], directions[next], currCellColor, currCellCenter, e, ref colorBuffer, ref vertexBuffer); EdgeVertices m = new EdgeVertices(Vector3.Lerp(currCellCenter, e.v1, 0.5f), Vector3.Lerp(currCellCenter, e.v5, 0.5f)); m.v3.y = e.v3.y; TriangulateEdgeStrip(m, currCellColor, e, currCellColor, ref colorBuffer, ref vertexBuffer); TriangulateEdgeFan(currCellCenter, m, currCellColor, ref colorBuffer, ref vertexBuffer); TriangulateRiverQuad(m.v2, m.v4, e.v2, e.v4, RiverSurfaceY, RiverSurfaceY, 0.6f, ref uvBuffer, ref riverBuffers, river.HasIncomingRiver); Vector3 center = currCellCenter; center.y = m.v2.y = m.v4.y = RiverSurfaceY; AddTriangle(center, m.v2, m.v4, ref riverBuffers); if (river.HasIncomingRiver) { AddTriangleUV(new Vector2(0.5f, 0.4f), new Vector2(1f, 0.2f), new Vector2(0f, 0.2f), ref uvBuffer); } else { AddTriangleUV(new Vector2(0.5f, 0.4f), new Vector2(0f, 0.6f), new Vector2(1f, 0.6f), ref uvBuffer); } } else { //TriangulateWithRiver(direction, directions[prev], directions[next], currCellColor, currCellCenter, e, ref colorBuffer, ref vertexBuffer, oppositeHasRiverThroughEdge); Vector3 centerL, centerR; //获取当前方向的相反方向,并判断是否有河流经过 if (HasRiverThroughEdge(river, directionIndex[OppositeDirection(j)])) { centerL = currCellCenter + HexMetrics.GetFirstSolidCorner(prev) * 0.25f; centerR = currCellCenter + HexMetrics.GetSecondSolidCorner(next) * 0.25f; } else if (HasRiverThroughEdge(river, directionIndex[next])) { centerL = currCellCenter; centerR = Vector3.Lerp(currCellCenter, e.v5, 2f / 3f); } else if (HasRiverThroughEdge(river, directionIndex[prev])) { centerL = Vector3.Lerp(currCellCenter, e.v1, 2f / 3f); centerR = currCellCenter; } else if (HasRiverThroughEdge(river, directionIndex[next2])) { centerL = currCellCenter; centerR = currCellCenter + HexMetrics.GetSolidEdgeMiddle(next) * (0.5f * HexMetrics.innerToOuter); } else { centerL = currCellCenter + HexMetrics.GetSolidEdgeMiddle(prev) * (0.5f * HexMetrics.innerToOuter); centerR = currCellCenter; } Vector3 center = Vector3.Lerp(centerL, centerR, 0.5f); EdgeVertices m = new EdgeVertices(Vector3.Lerp(centerL, e.v1, 0.5f), Vector3.Lerp(centerR, e.v5, 0.5f), 1f / 6f); m.v3.y = center.y = e.v3.y; TriangulateEdgeStrip(m, currCellColor, e, currCellColor, ref colorBuffer, ref vertexBuffer); AddTriangle(centerL, currCellColor, m.v1, currCellColor, m.v2, currCellColor, ref colorBuffer, ref vertexBuffer); AddQuad(centerL, currCellColor, center, currCellColor, m.v2, currCellColor, m.v3, currCellColor, ref colorBuffer, ref vertexBuffer); AddQuad(center, currCellColor, centerR, currCellColor, m.v3, currCellColor, m.v4, currCellColor, ref colorBuffer, ref vertexBuffer); AddTriangle(centerR, currCellColor, m.v4, currCellColor, m.v5, currCellColor, ref colorBuffer, ref vertexBuffer); bool reversed = river.IncomingRiver == directionIndex[j]; TriangulateRiverQuad(centerL, centerR, m.v2, m.v4, RiverSurfaceY, RiverSurfaceY, 0.4f, ref uvBuffer, ref riverBuffers, reversed); TriangulateRiverQuad(m.v2, m.v4, e.v2, e.v4, RiverSurfaceY, RiverSurfaceY, 0.6f, ref uvBuffer, ref riverBuffers, reversed); } } else { Vector3 center = currCellCenter; if (HasRiverThroughEdge(river, directionIndex[next])) { if (HasRiverThroughEdge(river, directionIndex[prev])) { center += HexMetrics.GetSolidEdgeMiddle(j) * (HexMetrics.innerToOuter * 0.5f); } else if (HasRiverThroughEdge(river, directionIndex[prev2])) { center += HexMetrics.GetFirstSolidCorner(j) * 0.25f; } } else if (HasRiverThroughEdge(river, directionIndex[prev]) && HasRiverThroughEdge(river, directionIndex[next2])) { center += HexMetrics.GetSecondSolidCorner(j) * 0.25f; } EdgeVertices m = new EdgeVertices( Vector3.Lerp(center, e.v1, 0.5f), Vector3.Lerp(center, e.v5, 0.5f) ); TriangulateEdgeStrip(m, currCellColor, e, currCellColor, ref colorBuffer, ref vertexBuffer); TriangulateEdgeFan(center, m, currCellColor, ref colorBuffer, ref vertexBuffer); } } else { TriangulateEdgeFan(currCellCenter, e, currCellColor, ref colorBuffer, ref vertexBuffer); } //Connection Between 2 cells #region Bridge=桥 //桥只连接前三个方向相邻的单元,从而避免重复连接 if (j <= 2) { if (directionIndex[j] == int.MinValue) {//如果没有相邻的单元,则跳过循环 continue; } //添加外围桥接区域的顶点 Vector3 bridge = (HexMetrics.GetBridge(j)); bridge.y = (elevations[j] - elevation) * HexMetrics.elevationStep; EdgeVertices e2 = new EdgeVertices(e.v1 + bridge, e.v5 + bridge); if (hasRiverThroughEdge) { float neighborRiverSurfaceY = (elevations[j] + HexMetrics.riverSurfaceElevationOffset) * HexMetrics.elevationStep; e2.v3.y = (elevations[j] + HexMetrics.streamBedElevationOffset) * HexMetrics.elevationStep; TriangulateRiverQuad(e.v2, e.v4, e2.v2, e2.v4, RiverSurfaceY, neighborRiverSurfaceY, 0.8f, ref uvBuffer, ref riverBuffers, river.HasIncomingRiver && river.IncomingRiver == directionIndex[j]); } #region 桥面 //判断当前单元与相邻单元的海拔高低差,如果是斜坡,则添加阶梯,平面和峭壁则无需阶梯 if (HexMetrics.GetEdgeType(elevation, elevations[j]) == HexMetrics.HexEdgeType.Slope) { TriangulateEdgeTerraces(e, e2, currCellColor, blendColors[j], ref colorBuffer, ref vertexBuffer); } else { Color bridgeColor = (currCellColor + blendColors[j]) * 0.5f; TriangulateEdgeStrip(e, currCellColor, e2, blendColors[j], ref colorBuffer, ref vertexBuffer); } #endregion #region 桥洞 //添加外圈区域三向颜色混合 if (j <= 1 && directionIndex[next] != int.MinValue) { //下一个相邻单元的海拔 int nextElevation = elevations[next]; Vector3 vertex5 = e.v5 + HexMetrics.GetBridge(next); vertex5.y = nextElevation * HexMetrics.elevationStep; //判断相邻的三个六边形单元的高低关系,按照最低(Bottom),左(Left),右(Right)的顺序进行三角化处理 if (elevation <= elevations[j]) { if (elevation <= nextElevation) { //当前单元海拔最低 TriangulateCorner(e.v5, currCellColor, e2.v5, blendColors[j], vertex5, blendColors[next], ref colorBuffer, ref vertexBuffer, elevation, elevations[j], nextElevation); } else { TriangulateCorner(vertex5, blendColors[next], e.v5, currCellColor, e2.v5, blendColors[j], ref colorBuffer, ref vertexBuffer, nextElevation, elevation, elevations[j]); } } else if (elevations[j] <= nextElevation) { TriangulateCorner(e2.v5, blendColors[j], vertex5, blendColors[next], e.v5, currCellColor, ref colorBuffer, ref vertexBuffer, elevations[j], nextElevation, elevation); } else { TriangulateCorner(vertex5, blendColors[next], e.v5, currCellColor, e2.v5, blendColors[j], ref colorBuffer, ref vertexBuffer, nextElevation, elevation, elevations[j]); } } #endregion } #endregion } //4.turn off cell system by remove NewDataTag CommandBuffer.RemoveComponent <NewDataTag>(index, entity); }
public HexEdgeType GetEdgeType(HexObject other) { return(HexMetrics.GetEdgeType(Elevation, other.Elevation)); }
public static Corner Build(HexCell begin, HexCell left, HexCell right, HexDirection leftDirection) { Vector3 beginCorner = begin.Position + HexMetrics.GetSecondSolidCorner(leftDirection); Vector3 leftCorner = left.Position + HexMetrics.GetFirstSolidCorner(leftDirection.Opposite()); Vector3 rightCorner = right.Position + HexMetrics.GetSecondSolidCorner(leftDirection.Previous2()); HexEdgeType leftEdgeType = HexMetrics.GetEdgeType(begin.Elevation, left.Elevation); HexEdgeType rightEdgeType = HexMetrics.GetEdgeType(begin.Elevation, right.Elevation); HexEdgeType endEdgeType = HexMetrics.GetEdgeType(left.Elevation, right.Elevation); Corner corner; if (leftEdgeType == HexEdgeType.Slope) { if (rightEdgeType == HexEdgeType.Slope) { corner = new TerracesCorner( beginCorner, leftCorner, rightCorner, begin, left, right ); } else if (rightEdgeType == HexEdgeType.Flat) { corner = new TerracesCorner( leftCorner, rightCorner, beginCorner, left, right, begin ); } else { corner = new TerraceCliffCorner( beginCorner, leftCorner, rightCorner, begin, left, right ); } } else if (rightEdgeType == HexEdgeType.Slope) { if (leftEdgeType == HexEdgeType.Flat) { corner = new TerracesCorner( rightCorner, beginCorner, leftCorner, right, begin, left ); } else { corner = new CliffTerraceCorner( beginCorner, leftCorner, rightCorner, begin, left, right ); } } else if (endEdgeType == HexEdgeType.Slope) { if (left.Elevation < right.Elevation) { corner = new CliffTerraceCorner( rightCorner, beginCorner, leftCorner, right, begin, left ); } else { corner = new TerraceCliffCorner( leftCorner, rightCorner, beginCorner, left, right, begin ); } } else { corner = new FlatCorner( beginCorner, leftCorner, rightCorner, begin, left, right ); } return(corner); }
public HexEdgeType GetEdgeType(HexDirection direction)//узнать тип угла в направлении { return(HexMetrics.GetEdgeType(elevation, neighbors[(int)direction].elevation)); }
public void GetEdgeTypeSlopeTest2() { Assert.AreEqual(HexEdgeType.Slope, HexMetrics.GetEdgeType(5, 4)); }
public void GetEdgeTypeCliffTest2() { Assert.AreEqual(HexEdgeType.Cliff, HexMetrics.GetEdgeType(5, 2)); }
public void GetEdgeTypeFlatTest() { Assert.AreEqual(HexEdgeType.Flat, HexMetrics.GetEdgeType(3, 3)); }
public HexEdgeType GetEdgeType(HexDirection dirction) { return(HexMetrics.GetEdgeType(elevation, GetNeighbor(dirction).elevation)); }
public HexEdgeType GetEdgeType(HexCell thatCell) { return(HexMetrics.GetEdgeType(elevation, thatCell.elevation)); }
public HexEdgeType GetEdgeType(HexDirection dir) { return(HexMetrics.GetEdgeType(Elevation, m_neighbours[(int)dir].Elevation)); }
public HexEdgeType GetEdgeType(HexCell otherCell)//узнать тип угла относительно двух ячеек { return(HexMetrics.GetEdgeType(elevation, otherCell.elevation)); }
public HexEdgeType GetEdgeType(HexCell otherCell) { return(HexMetrics.GetEdgeType(Elevation, otherCell.Elevation)); }
/// <summary> /// Returns the edge connection type with the neighboring cell at the given direction. /// </summary> public HexEdgeType GetEdgeType(HexDirection direction) { // ! If on the edge of the map this can throw NullReferenceException return(HexMetrics.GetEdgeType(elevation, Neighbors[(int)direction].Elevation)); }