/// <summary> /// 三角化扇形内的道路 /// ----e /// mL--mR /// . /// </summary> /// <param name="center">六边形中点</param> /// <param name="mL">e.v1与center的中点</param> /// <param name="mR">e.v5与center的中点</param> /// <param name="e">扇形的弧(五顶点边)</param> /// <param name="hasRoadThroughCellEdge">该扇形是否有道路</param> /// <param name="index">六边形格子索引</param> void TriangulateRoad(Vector3 center, Vector3 mL, Vector3 mR, EdgeVertices e, bool hasRoadThroughCellEdge, int index) { if (hasRoadThroughCellEdge) { Vector3 indices; indices.x = indices.y = indices.z = index; // 外侧长方形 Vector3 mC = Vector3.Lerp(mL, mR, 0.5f); TriangulateRoadSegment(mL, mC, mR, e.v2, e.v3, e.v4, weights1, weights1, indices); // 内侧两个三角形 roads.AddTriangle(center, mL, mC); roads.AddTriangle(center, mC, mR); roads.AddTriangleUV(new Vector2(1f, 0f), new Vector2(0f, 0f), new Vector2(1f, 0f)); roads.AddTriangleUV(new Vector2(1f, 0f), new Vector2(1f, 0f), new Vector2(0f, 0f)); roads.AddTriangleCellData(indices, weights1); roads.AddTriangleCellData(indices, weights1); } else { TriangulateRoadEdge(center, mL, mR, index); } }
public void Triangulate(HexMesh mesh) { for (HexDirection direction = HexDirection.NE; direction <= HexDirection.NW; direction++) { Vector3 center = Position; EdgeVertices edge = new EdgeVertices( Position + HexMetrics.GetFirstSolidCorner(direction), Position + HexMetrics.GetSecondSolidCorner(direction) ); mesh.AddTriangle(Position, edge.v1, edge.v2); mesh.AddTriangleColor(Color, Color, Color); mesh.AddTriangle(Position, edge.v2, edge.v3); mesh.AddTriangleColor(Color, Color, Color); mesh.AddTriangle(Position, edge.v3, edge.v4); mesh.AddTriangleColor(Color, Color, Color); mesh.AddTriangle(Position, edge.v4, edge.v5); mesh.AddTriangleColor(Color, Color, Color); HexCell neighbor = GetNeighbor(direction); if (direction <= HexDirection.SE && neighbor != null) { edges[(int)direction] = HexEdge.Build(this, neighbor, direction); edges[(int)direction].Triangulate(mesh); HexCell nextNeighbor = GetNeighbor(direction.Next()); if (direction <= HexDirection.E && nextNeighbor != null) { corners[(int)direction] = Corner.Build(this, neighbor, nextNeighbor, direction); corners[(int)direction].Triangulate(mesh); } } } }
public void TriangulateRoadEdge(Vector3 center, Vector3 midLeft, Vector3 midRight, float index) { Roads.AddTriangle(center, midLeft, midRight); Roads.AddTriangleUV(new Vector2(1, 0), Vector2.zero, Vector2.zero); Vector3 indices = new Vector3(index, index, index); Roads.AddTriangleCellData(indices, Weights1); }
public void TriangulateWithRiver(HexDirection dir, HexCell cell, Vector3 center, EdgeVertices edges) { Vector3 centerL; Vector3 centerR; float centerLinePinch = 2.0f / 3.0f; if (cell.HasRiverThroughEdge(dir.Opposite())) { centerL = center + HexMetrics.GetFirstSolidCorner(dir.Previous()) * HexMetrics.SubdivideFraction; centerR = center + HexMetrics.GetSecondSolidCorner(dir.Next()) * HexMetrics.SubdivideFraction; center = (centerL + centerR) / 2.0f; } else if (cell.HasRiverThroughEdge(dir.Next())) { centerL = center; centerR = Vector3.Lerp(center, edges.v5, centerLinePinch); } else if (cell.HasRiverThroughEdge(dir.Previous())) { centerL = Vector3.Lerp(center, edges.v1, centerLinePinch); centerR = center; } else if (cell.HasRiverThroughEdge(dir.Next2())) { centerL = center; centerR = center + HexMetrics.GetSolidEdgeMiddle(dir.Next()) * (0.5f * HexMetrics.InnerToOuter); } else { centerL = center + HexMetrics.GetSolidEdgeMiddle(dir.Previous()) * (0.5f * HexMetrics.InnerToOuter); centerR = center; } EdgeVertices modifiedEdges = new EdgeVertices(Vector3.Lerp(centerL, edges.v1, 0.5f), Vector3.Lerp(centerR, edges.v5, 0.5f)); modifiedEdges.v3.y = center.y = edges.v3.y; TriangulateEdgeStrip(modifiedEdges, Weights1, cell.TerrainTypeIndex, edges, Weights1, cell.CellIndex); Terrain.AddTriangle(centerL, modifiedEdges.v1, modifiedEdges.v2); Terrain.AddQuad(centerL, center, modifiedEdges.v2, modifiedEdges.v3); Terrain.AddQuad(center, centerR, modifiedEdges.v3, modifiedEdges.v4); Terrain.AddTriangle(centerR, modifiedEdges.v4, modifiedEdges.v5); Vector3 indices = new Vector3(cell.CellIndex, cell.CellIndex, cell.CellIndex); Terrain.AddTriangleCellData(indices, Weights1); Terrain.AddQuadCellData(indices, Weights1); Terrain.AddQuadCellData(indices, Weights1); Terrain.AddTriangleCellData(indices, Weights1); if (!cell.IsUnderwater) { bool reverse = cell.IncomingRiverDirection == dir; TriangulateRiverQuad(centerL, centerR, modifiedEdges.v2, modifiedEdges.v4, cell.RiverSurfaceY, 0.4f, reverse, indices); TriangulateRiverQuad(modifiedEdges.v2, modifiedEdges.v4, edges.v2, edges.v4, cell.RiverSurfaceY, 0.6f, reverse, indices); } }
private void TriangulateWall(Vector3 center, Vector3 mL, Vector3 mR, EdgeVertices e, bool hasWallThroughCellEdge) { if (hasWallThroughCellEdge) { Vector3 mC = Vector3.Lerp(mL, mR, 0.5f); TriangulateWallSegment(mL, mC, mR, e.v2, e.v3, e.v4); _walls.AddTriangle(center, mL, mC); _walls.AddTriangle(center, mC, mR); } else { TriangulateWallEdge(center, mL, mR); } }
void TriangulateWithRiver(HexDirection direction, HexCell cell, Vector3 center, EdgeVertices e) { Vector3 centerL, centerR; if (cell.HasRiverThroughEdge(direction.Opposite())) { centerL = center + HexMetrics.GetFirstSolidCorner(direction.Previous()) * 0.25f; centerR = center + HexMetrics.GetSecondSolidCorner(direction.Next()) * 0.25f; } else if (cell.HasRiverThroughEdge(direction.Next())) { centerL = center; centerR = Vector3.Lerp(center, e.v5, 2f / 3f); } else if (cell.HasRiverThroughEdge(direction.Previous())) { centerL = Vector3.Lerp(center, e.v1, 2f / 3f); centerR = center; } else if (cell.HasRiverThroughEdge(direction.Next2())) { centerL = center; centerR = center + HexMetrics.GetSolidEdgeMiddle(direction.Next()) * (0.5f * HexMetrics.innerToOuter); } else { centerL = center + HexMetrics.GetSolidEdgeMiddle(direction.Previous()) * (0.5f * HexMetrics.innerToOuter); centerR = center; } 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, weights1, cell.Index, e, weights1, cell.Index); terrain.AddTriangle(centerL, m.v1, m.v2); terrain.AddQuad(centerL, center, m.v2, m.v3); terrain.AddQuad(center, centerR, m.v3, m.v4); terrain.AddTriangle(centerR, m.v4, m.v5); Vector3 indices; indices.x = indices.y = indices.z = cell.Index; terrain.AddTriangleCellData(indices, weights1); terrain.AddQuadCellData(indices, weights1); terrain.AddQuadCellData(indices, weights1); terrain.AddTriangleCellData(indices, weights1); if (!cell.IsUnderWater) { bool reversed = cell.IncomingRiver == direction; TriangulateRiverQuad(centerL, centerR, m.v2, m.v4, cell.RiverSurfaceY, 0.4f, reversed, indices); TriangulateRiverQuad(m.v2, m.v4, e.v2, e.v4, cell.RiverSurfaceY, 0.6f, reversed, indices); } }
void TriangulateCorner(Vector3 bottom, HexCell bottomCell, Vector3 left, HexCell leftCell, Vector3 right, HexCell rightCell) { HexEdgeType leftEdgeType = bottomCell.GetEdgeType(leftCell); HexEdgeType rightEdgeType = bottomCell.GetEdgeType(rightCell); if (leftEdgeType == HexEdgeType.Slope) { if (rightEdgeType == HexEdgeType.Slope) { TriangulateCornerTerraces(bottom, bottomCell, left, leftCell, right, rightCell); } else if (rightEdgeType == HexEdgeType.Flat) { TriangulateCornerTerraces(left, leftCell, right, rightCell, bottom, bottomCell); } else { TriangulateCornerTerracesCliff(bottom, bottomCell, left, leftCell, right, rightCell); } } else if (rightEdgeType == HexEdgeType.Slope) { if (leftEdgeType == HexEdgeType.Flat) { TriangulateCornerTerraces(right, rightCell, bottom, bottomCell, left, leftCell); } else { TriangulateCornerCliffTerraces(bottom, bottomCell, left, leftCell, right, rightCell); } } else if (leftCell.GetEdgeType(rightCell) == HexEdgeType.Slope) { if (leftCell.Elevation < rightCell.Elevation) { TriangulateCornerCliffTerraces(right, rightCell, bottom, bottomCell, left, leftCell); } else { TriangulateCornerTerracesCliff(left, leftCell, right, rightCell, bottom, bottomCell); } } else { terrain.AddTriangle(bottom, left, right); Vector3 indices; indices.x = bottomCell.Index; indices.y = leftCell.Index; indices.z = rightCell.Index; terrain.AddTriangleCellData(indices, weights1, weights2, weights3); } features.AddWall(bottom, bottomCell, left, leftCell, right, rightCell); }
void Triangulate(HexDirection direction, HexCell cell) { Vector3 center = cell.transform.localPosition; Vector3 vert1 = center + Hexmetrics.GetFirstSolidCorner(direction); Vector3 vert2 = center + Hexmetrics.GetSecondSolidCorner(direction); terrain.AddTriangle(center, vert1, vert2); terrain.AddTriangleColor(cell.color); if (direction <= HexDirection.SE) { TriangulateConnection(direction, cell, vert1, vert2); } }
void TriangulateCorner( Vector3 bottom, HexCell bottomCell, Vector3 left, HexCell leftCell, Vector3 right, HexCell rightCell) { HexEdgeType leftEdgeType = bottomCell.GetEdgeType(leftCell); HexEdgeType rightEdgeType = bottomCell.GetEdgeType(rightCell); if (leftEdgeType == HexEdgeType.Slope) { if (rightEdgeType == HexEdgeType.Slope) { TriangulateCornerTerraces(bottom, bottomCell, left, leftCell, right, rightCell); } else if (rightEdgeType == HexEdgeType.Flat) { TriangulateCornerTerraces(left, leftCell, right, rightCell, bottom, bottomCell); } else { TriangulateCornerTerracesCliff(bottom, bottomCell, left, leftCell, right, rightCell); } } else if (rightEdgeType == HexEdgeType.Slope) { if (leftEdgeType == HexEdgeType.Flat) { TriangulateCornerTerraces(right, rightCell, bottom, bottomCell, left, leftCell); } else { TriangulateCornerCliffTerraces(bottom, bottomCell, left, leftCell, right, rightCell); } } else if (leftCell.GetEdgeType(rightCell) == HexEdgeType.Slope) { if (leftCell.Elevation < rightCell.Elevation) { TriangulateCornerCliffTerraces(right, rightCell, bottom, bottomCell, left, leftCell); } else { TriangulateCornerTerracesCliff(left, leftCell, right, rightCell, bottom, bottomCell); } } else { terrain.AddTriangle(bottom, left, right); terrain.AddTriangleColor(color1, color2, color3); Vector3 types; types.x = bottomCell.TerrainTypeIndex; types.y = leftCell.TerrainTypeIndex; types.z = rightCell.TerrainTypeIndex; terrain.AddTriangleTerrainTypes(types); } features.AddWall(bottom, bottomCell, left, leftCell, right, rightCell); }
public void TriangulateWithRiverBeginningOrEnd(HexDirection dir, HexCell cell, Vector3 center, EdgeVertices edges) { EdgeVertices modifiedEdges = new EdgeVertices(Vector3.Lerp(center, edges.v1, 0.5f), Vector3.Lerp(center, edges.v5, 0.5f)); modifiedEdges.v3.y = edges.v3.y; Color color = Weights1; // cell.Color; TriangulateEdgeStrip(modifiedEdges, color, cell.TerrainTypeIndex, edges, color, cell.CellIndex); TriangulateEdgeFan(center, modifiedEdges, color, cell.CellIndex); if (!cell.IsUnderwater) { bool reverse = cell.HasIncomingRiver; Vector3 indices = new Vector3(cell.CellIndex, cell.CellIndex, cell.CellIndex); TriangulateRiverQuad(modifiedEdges.v2, modifiedEdges.v4, edges.v2, edges.v4, cell.RiverSurfaceY, 0.6f, reverse, indices); center.y = modifiedEdges.v2.y = modifiedEdges.v4.y = cell.RiverSurfaceY; Rivers.AddTriangle(center, modifiedEdges.v2, modifiedEdges.v4); if (reverse) { Rivers.AddTriangleUV(new Vector2(0.5f, 0.4f), new Vector2(1f, 0.2f), new Vector2(0f, 0.2f)); } else { Rivers.AddTriangleUV(new Vector2(0.5f, 0.4f), new Vector2(0f, 0.6f), new Vector2(1f, 0.6f)); } Rivers.AddTriangleCellData(indices, Weights1); } }
public void TriangulateEstuary(EdgeVertices edges1, EdgeVertices edges2, bool incomingRiver, Vector3 indices) { WaterShore.AddTriangle(edges2.v1, edges1.v2, edges1.v1); WaterShore.AddTriangle(edges2.v5, edges1.v5, edges1.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(edges2.v1, edges1.v2, edges2.v2, edges1.v3); Estuaries.AddTriangle(edges1.v3, edges2.v2, edges2.v4); Estuaries.AddQuad(edges1.v3, edges1.v4, edges2.v4, edges2.v5); Estuaries.AddQuadUV(new Vector2(0f, 1f), new Vector2(0f, 0f), new Vector2(0f, 1f), new Vector2(0f, 0f)); Estuaries.AddTriangleUV(new Vector2(0f, 0f), new Vector2(0f, 1f), new Vector2(0f, 1f)); Estuaries.AddQuadUV(0f, 0f, 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)); } }
public override void Triangulate(HexMesh mesh) { Vector3 v1 = beginCorner; Vector3 v2 = beginCorner; Color c1 = beginCell.Color; Color c2 = beginCell.Color; for (int step = 1; step < HexMetrics.terraceSteps + 1; ++step) { Vector3 v3 = HexMetrics.TerraceLerp(beginCorner, leftCorner, step); Vector3 v4 = HexMetrics.TerraceLerp(beginCorner, rightCorner, step); Color c3 = HexMetrics.ColorLerp(beginCell.Color, leftCell.Color, step); Color c4 = HexMetrics.ColorLerp(beginCell.Color, rightCell.Color, step); if (step == 1) { mesh.AddTriangle(v1, v3, v4); mesh.AddTriangleColor(c1, c3, c4); } else { mesh.AddQuad(v1, v2, v3, v4); mesh.AddQuadColor(c1, c2, c3, c4); } v1 = v3; v2 = v4; c1 = c3; c2 = c4; } }
void TriangulateWithRiverBeginOrEnd(HexDirection direction, HexCell cell, Vector3 center, EdgeVertices e) { EdgeVertices m = new EdgeVertices( Vector3.Lerp(center, e.v1, 0.5f), Vector3.Lerp(center, e.v5, 0.5f) ); m.v3.y = e.v3.y; TriangulateEdgeStrip(m, weights1, cell.Index, e, weights1, cell.Index); TriangulateEdgeFan(center, m, cell.Index); if (!cell.IsUnderWater) { bool reversed = cell.HasIncomingRiver; Vector3 indices; indices.x = indices.y = indices.z = cell.Index; TriangulateRiverQuad(m.v2, m.v4, e.v2, e.v4, cell.RiverSurfaceY, 0.6f, reversed, indices); center.y = m.v2.y = m.v4.y = cell.RiverSurfaceY; rivers.AddTriangle(center, m.v2, m.v4); if (reversed) { rivers.AddTriangleUV(new Vector2(0.5f, 0.5f), new Vector2(1f, 0.2f), new Vector2(0f, 0.2f)); } else { rivers.AddTriangleUV(new Vector2(0.5f, 0.4f), new Vector2(0f, 0.6f), new Vector2(1f, 0.6f)); } rivers.AddTriangleCellData(indices, weights1); } }
void TriangulateWithRiver(HexDirection direction, HexCell cell, Vector3 center, EdgeVertices e) { Vector3 centerL, centerR; if (cell.HasRiverThroughEdge(direction.Opposite())) { centerL = center + HexMetrics.GetFirstSolidCorner(direction.Previous()) * 0.25f; centerR = center + HexMetrics.GetSecondSolidCorner(direction.Next()) * 0.25f; } else if (cell.HasRiverThroughEdge(direction.Next())) { centerL = center; centerR = Vector3.Lerp(center, e.v5, 2f / 3f); } else if (cell.HasRiverThroughEdge(direction.Previous())) { centerL = Vector3.Lerp(center, e.v1, 2f / 3f); centerR = center; } else if (cell.HasRiverThroughEdge(direction.Next2())) { centerL = center; centerR = center + HexMetrics.GetSolidEdgeMiddle(direction.Next()) * (0.5f * HexMetrics.kInnerToOuter); } else { centerL = center + HexMetrics.GetSolidEdgeMiddle(direction.Previous()) * (0.5f * HexMetrics.kInnerToOuter); centerR = center; } 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, cell.Color, e, cell.Color); terrain.AddTriangle(centerL, m.v1, m.v2); terrain.AddTriangleColor(cell.Color); terrain.AddQuad(centerL, center, m.v2, m.v3); terrain.AddQuadColor(cell.Color); terrain.AddQuad(center, centerR, m.v3, m.v4); terrain.AddQuadColor(cell.Color); terrain.AddTriangle(centerR, m.v4, m.v5); terrain.AddTriangleColor(cell.Color); if (!cell.IsUnderwater) { bool reversed = cell.IncomingRiver == direction; TriangulateRiverQuad(centerL, centerR, m.v2, m.v4, cell.RiverSurfaceY, cell.RiverSurfaceY, 0.5f, HexMetrics.kRiverSolidUVStep, reversed); TriangulateRiverQuad(m.v2, m.v4, e.v2, e.v4, cell.RiverSurfaceY, cell.RiverSurfaceY, 0.5f + HexMetrics.kRiverSolidUVStep, HexMetrics.kRiverSolidUVStep, reversed); } }
// Each corner is connected to three edges, which could be flats, slopes, or cliffs. So there are many possible configurations. void TriangulateCorner(Vector3 bottom, HexCell bottomCell, Vector3 left, HexCell leftCell, Vector3 right, HexCell rightCell) { HexEdgeType leftEdgeType = bottomCell.GetEdgeType(leftCell); HexEdgeType rightEdgeType = bottomCell.GetEdgeType(rightCell); // If both edges are slopes, then we have terraces on both the left and the right side. // Also, because the bottom cell is the lowest, we know that those slopes go up. // Furthermore, this means that the left and right cell have the same elevation, so the top edge connection is flat. if (leftEdgeType == HexEdgeType.Slope) { if (rightEdgeType == HexEdgeType.Slope) { TriangulateCornerTerraces(bottom, bottomCell, left, leftCell, right, rightCell); } else if (rightEdgeType == HexEdgeType.Flat) { TriangulateCornerTerraces(left, leftCell, right, rightCell, bottom, bottomCell); } else { TriangulateCornerTerracesCliff(bottom, bottomCell, left, leftCell, right, rightCell); } return; } else if (rightEdgeType == HexEdgeType.Slope) { if (leftEdgeType == HexEdgeType.Flat) { TriangulateCornerTerraces(right, rightCell, bottom, bottomCell, left, leftCell); } else { TriangulateCornerCliffTerraces(bottom, bottomCell, left, leftCell, right, rightCell); } return; } else if (leftCell.GetEdgeType(rightCell) == HexEdgeType.Slope) { if (leftCell.Elevation < rightCell.Elevation) { TriangulateCornerCliffTerraces(right, rightCell, bottom, bottomCell, left, leftCell); } else { TriangulateCornerTerracesCliff(left, leftCell, right, rightCell, bottom, bottomCell); } return; } Terrain.AddTriangle(bottom, left, right); Terrain.AddTriangleColor(bottomCell.Color, leftCell.Color, rightCell.Color); }
void TriangulateEdgeFan(Vector3 center, EdgeVertices edge, Color color) { terrain.AddTriangle(center, edge.v1, edge.v2); terrain.AddTriangleColor(color); terrain.AddTriangle(center, edge.v2, edge.v3); terrain.AddTriangleColor(color); terrain.AddTriangle(center, edge.v3, edge.v4); terrain.AddTriangleColor(color); terrain.AddTriangle(center, edge.v4, edge.v5); terrain.AddTriangleColor(color); }
/* Creates a single triangle from cell center to cell edge */ void TriangulateWedge(HexDirection direction, HexCell cell) { Vector3 center = cell.transform.localPosition; EdgeVertices e = new EdgeVertices( center + HexMetrics.GetFirstSolidCorner(direction), center + HexMetrics.GetSecondSolidCorner(direction) ); cellMesh.AddTriangle(center, e.v1, e.v2); }
void TriangulateCorner( Vector3 bottom, HexCell bottomCell, Vector3 left, HexCell leftCell, Vector3 right, HexCell rightCell) { HexEdgeType leftEdgeType = bottomCell.GetEdgeType(leftCell); HexEdgeType rightEdgeType = bottomCell.GetEdgeType(rightCell); if (leftEdgeType == HexEdgeType.Slope) { if (rightEdgeType == HexEdgeType.Slope) { TriangulateCornerTerraces(bottom, bottomCell, left, leftCell, right, rightCell); } else if (rightEdgeType == HexEdgeType.Flat) { TriangulateCornerTerraces(left, leftCell, right, rightCell, bottom, bottomCell); } else { TriangulateCornerTerracesCliff(bottom, bottomCell, left, leftCell, right, rightCell); } } else if (rightEdgeType == HexEdgeType.Slope) { if (leftEdgeType == HexEdgeType.Flat) { TriangulateCornerTerraces(right, rightCell, bottom, bottomCell, left, leftCell); } else { TriangulateCornerTerraces(bottom, bottomCell, left, leftCell, right, rightCell); } } else if (leftCell.GetEdgeType(rightCell) == HexEdgeType.Slope) { if (leftCell.Elevation < rightCell.Elevation) { TriangulateCornerCliffTerraces(right, rightCell, bottom, bottomCell, left, leftCell); } else { TriangulateCornerTerracesCliff(left, leftCell, right, rightCell, bottom, bottomCell); } } else { terrain.AddTriangle(bottom, left, right); terrain.AddTriangleColor(bottomCell.Color, leftCell.Color, rightCell.Color); } features.AddWall(bottom, bottomCell, left, leftCell, right, rightCell); }
void Triangulate(HexDirection direction, HexCell cell) { Vector3 center = cell.transform.localPosition; map.AddTriangle( center, center + _hexMetrics.GetFirstCorner(direction), center + _hexMetrics.GetSecondCorner(direction) ); map.AddTriangleColor(cell.Color); }
void TriangulateOpenWater(HexDirection direction, HexCell cell, HexCell neighbor, Vector3 center) { Vector3 c1 = center + HexMetrics.GetFirstWaterCorner(direction); Vector3 c2 = center + HexMetrics.GetSecondWaterCorner(direction); water.AddTriangle(center, c1, c2); Vector3 indices; indices.x = indices.y = indices.z = cell.Index; water.AddTriangleCellData(indices, weights1); if (direction <= HexDirection.SE && neighbor != null) { Vector3 bridge = HexMetrics.GetWaterBridge(direction); Vector3 e1 = c1 + bridge; Vector3 e2 = c2 + bridge; water.AddQuad(c1, c2, e1, e2); indices.y = neighbor.Index; water.AddQuadCellData(indices, weights1, weights2); if (direction <= HexDirection.E) { HexCell nextNeighbor = cell.GetNeighbor(direction.Next()); if (nextNeighbor == null || !nextNeighbor.IsUnderWater) { return; } water.AddTriangle(c2, e2, c2 + HexMetrics.GetWaterBridge(direction.Next())); indices.z = nextNeighbor.Index; water.AddTriangleCellData(indices, weights1, weights2, weights3); } } }
void Triangulate(HexDirection direction, HexCell cell) { Vector3 center = cell.Position; Vector3 v1 = center + HexMetrics.GetFirstInnerCorner(direction); Vector3 v2 = center + HexMetrics.GetSecondInnerCorner(direction); Vector3 v1OuterBump = center + HexMetrics.GetFirstBumpOuterCorner(direction); Vector3 v2OuterBump = center + HexMetrics.GetSecondBumpOuterCorner(direction); Vector3 indices; indices.x = indices.y = indices.z = cell.Index; terrain.AddTriangle(center, v1, v2); terrain.AddTriangleCellData(indices, weights1); terrain.AddQuad(v1, v2, v1OuterBump, v2OuterBump); if (cell.IsUnderwater) { terrain.AddQuadCellData(indices, weights1, weights1); } else { terrain.AddQuadCellData(indices, terrainColorBump, terrainColorBump); } if (direction <= HexDirection.SE) { TriangulateConnection(direction, cell, v1OuterBump, v2OuterBump); } if (cell.IsUnderwater) { TriangulateWater(direction, cell, center); } if (!cell.IsUnderwater) { features.AddFeature(cell, (center + v1 + v2) * (1f / 3f)); } }
public void TriangulateOpenWater(HexDirection dir, HexCell cell, HexCell neighbour, Vector3 center) { Vector3 c1 = center + HexMetrics.GetFirstWaterCorner(dir); Vector3 c2 = center + HexMetrics.GetSecondWaterCorner(dir); Water.AddTriangle(center, c1, c2); Vector3 indices = new Vector3(cell.CellIndex, cell.CellIndex, cell.CellIndex); Water.AddTriangleCellData(indices, Weights1); if (dir <= HexDirection.SE && neighbour != null) { Vector3 bridge = HexMetrics.GetWaterBridge(dir); Vector3 e1 = c1 + bridge; Vector3 e2 = c2 + bridge; Water.AddQuad(c1, c2, e1, e2); indices.y = neighbour.CellIndex; Water.AddQuadCellData(indices, Weights1, Weights2); if (dir <= HexDirection.E) { HexCell nextNeightbour = cell.GetNeighbour(dir.Next()); if (nextNeightbour == null || !nextNeightbour.IsUnderwater) { return; } Water.AddTriangle(c2, e2, c2 + HexMetrics.GetWaterBridge(dir.Next())); indices.z = nextNeightbour.CellIndex; Water.AddTriangleCellData(indices, Weights1, Weights2, Weights3); } } }
void TriangulateEdgeFan(Vector3 center, EdgeVertices edge, float index) { terrain.AddTriangle(center, edge.v1, edge.v2); terrain.AddTriangle(center, edge.v2, edge.v3); terrain.AddTriangle(center, edge.v3, edge.v4); terrain.AddTriangle(center, edge.v4, edge.v5); Vector3 indices; indices.x = indices.y = indices.z = index; terrain.AddTriangleCellData(indices, weights1); terrain.AddTriangleCellData(indices, weights1); terrain.AddTriangleCellData(indices, weights1); terrain.AddTriangleCellData(indices, weights1); }
public void CreateMeshColliders() { mesh.Clear(); for (int i = 0; i < cells.Length; i++) { HexCell cell = cells[i]; for (int j = 0; j < 6; j++) { mesh.AddTriangle(cell.Position, cell.Position + HexMetrics.corners[j] * 0.95f, cell.Position + HexMetrics.corners[j + 1] * 0.95f); } } mesh.Apply(); }
void Triangulate(HexDirection direction, HexCell cell) { Vector3 center = cell.transform.localPosition; terrain.AddTriangle( center, center + HexMetrics.GetFirstCorner(direction), center + HexMetrics.GetSecondCorner(direction) ); HexCell prevNeighbor = cell.GetNeighbor(direction.Previous()) ?? cell; HexCell neighbor = cell.GetNeighbor(direction) ?? cell; HexCell nextNeighbor = cell.GetNeighbor(direction.Next()) ?? cell; terrain.AddTriangleColor(cell.Color); }
/// <summary> /// Creates the triangles for a side of the hexagon. /// </summary> void TriangulateEdgeFan(Vector3 center, EdgeVertices edge, float index) { // Add geometry Terrain.AddTriangle(center, edge.v1, edge.v2); Terrain.AddTriangle(center, edge.v2, edge.v3); Terrain.AddTriangle(center, edge.v3, edge.v4); Terrain.AddTriangle(center, edge.v4, edge.v5); // Add splat map colors and terrain type into cell data Vector3 indices; indices.x = indices.y = indices.z = index; Terrain.AddTriangleCellData(indices, weights1); Terrain.AddTriangleCellData(indices, weights1); Terrain.AddTriangleCellData(indices, weights1); Terrain.AddTriangleCellData(indices, weights1); }
/* creates the stage boundaries */ void TriangulateOuterWallPanelCorner(HexDirection direction, HexCell cell, HexCell neighbor) { Vector3 offset = new Vector3(0, wallHeight, 0); Vector3 endpoint = offset + cell.transform.localPosition + HexMetrics.GetSecondCorner(direction); EdgeVertices e1 = new EdgeVertices( cell.transform.localPosition + HexMetrics.GetSecondSolidCorner(direction), neighbor.transform.localPosition + HexMetrics.GetFirstSolidCorner(direction.Previous()) ); EdgeVertices e2 = new EdgeVertices( e1.v1 + offset, e1.v2 + offset ); edgeMesh.AddQuad(e1, e2); edgeMesh.AddTriangle(e2.v1, endpoint, e2.v2); }
/// <summary> /// 三角化河口 /// </summary> /// <param name="e1">自身纯色区扇形边(弧)</param> /// <param name="e2">邻居纯色区扇形边(弧)</param> /// <param name="incomingRiver">是否是流入河</param> /// <param name="indices">临近六边形</param> 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); // 第一个顶点位于邻居六边形内所以用weights2,第二三个顶点位于自身六边形所以用weights1 waterShore.AddTriangleCellData(indices, weights2, weights1, weights1); // 河口顶点 : e2: v1----v5 // e1: v2--v4 // 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); // 该UV的v用于判断离岸远近,u用于匹配瀑布水流消失插值(瀑布下方为1,扩散外围为0) 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) { // uv2 用于匹配河水流动, v为河水流动方向 // 由于是河口位于桥的下面,所以v坐标是0.8~1, // 由于水平面纯色区占比只有0.6,陆地水面交接处的桥是0.2+0.4,比陆地与陆地交接处的桥(0.2+0.2)大了50%,所以v坐标扩大50%,变成0.8~1.1 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)); } // 如果是流出河流的河口(翻转uv) 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)); } }
private void AddWallWedge(Vector3 near, Vector3 far, Vector3 point) { near = HexMetrics.Perturb(near); far = HexMetrics.Perturb(far); point = HexMetrics.Perturb(point); Vector3 center = HexMetrics.WallLerp(near, far); Vector3 thickness = HexMetrics.WallThicknessOffset(near, far); Vector3 v1; Vector3 v2; Vector3 v3 = v1 = center - thickness; Vector3 v4 = v2 = center + thickness; Vector3 pointTop = point; point.y = center.y; v3.y = v4.y = pointTop.y = center.y + HexMetrics.wallHeight; walls.AddQuad(v1, point, v3, pointTop); walls.AddQuad(point, v2, pointTop, v4); walls.AddTriangle(pointTop, v3, v4); }
protected static void TriangulateBoundaryTriangle( HexMesh mesh, Vector3 beginCorner, HexCell beginCell, Vector3 leftCorner, HexCell leftCell, Vector3 boundary, Color boundaryColor ) { Vector3 v1 = beginCorner; Color c1 = beginCell.Color; for (int step = 1; step < HexMetrics.terraceSteps + 1; ++step) { Vector3 v3 = HexMetrics.TerraceLerp(beginCorner, leftCorner, step); Color c3 = HexMetrics.ColorLerp(beginCell.Color, leftCell.Color, step); mesh.AddTriangle(HexMetrics.Perturb(v1), HexMetrics.Perturb(v3), boundary, false); mesh.AddTriangleColor(c1, c3, boundaryColor); v1 = v3; c1 = c3; } }