public WaterTriangulationData TriangulateHexWaterShoreEdge( Hex source, Hex neighbor, Dictionary <HexDirections, Hex> neighbors, HexDirections direction, HexRiverData riverData, WaterTriangulationData triangulationData, float hexOuterRadius, int wrapSize ) { if (source.IsUnderwater) { if ( !neighbor.IsUnderwater ) { Vector3 center2 = neighbor.Position; float hexInnerRadius = HexagonPoint.OuterToInnerRadius(hexOuterRadius); float hexInnerDiameter = hexInnerRadius * 2f; // / | y // / | // | | //source x/z | | target // | | // \ | // \ | y Vector3 waterShoreHexIndices; waterShoreHexIndices.x = waterShoreHexIndices.z = source.Index; waterShoreHexIndices.y = neighbor.Index; TriangulateWaterShore( source, neighbor, waterShoreHexIndices, direction, neighbors, riverData, triangulationData.waterSurfaceCenter, hexOuterRadius, wrapSize, this, triangulationData.sourceWaterEdge, triangulationData.neighborWaterEdge, hexInnerDiameter ); } } return(triangulationData); }
public WaterTriangulationData TriangulateHexOpenWaterEdge( Hex source, Hex neighbor, Dictionary <HexDirections, Hex> neighbors, HexDirections direction, WaterTriangulationData waterTriData, TerrainTriangulationData terrainTriData, float hexOuterRadius, int wrapSize ) { if (source.IsUnderwater) { if ( !neighbor.IsUnderwater ) { waterTriData = TriangulateShoreOpenWater( source, neighbor, waterTriData.waterSurfaceCenter, waterTriData.sourceWaterEdge, hexOuterRadius, wrapSize, this, waterTriData ); } else { waterTriData = TriangulateOpenWaterCenter( source, waterTriData, direction, hexOuterRadius, wrapSize, this ); waterTriData = TriangulateOpenWaterConnection( source, neighbor, direction, waterTriData, terrainTriData, neighbors, hexOuterRadius, wrapSize, this ); } } return(waterTriData); }
public WaterTriangulationData TriangulateHexEstuaryEdge( Hex source, Hex neighbor, HexDirections direction, HexRiverData riverData, WaterTriangulationData triangulationData, float hexOuterRadius, int wrapSize ) { if (source.IsUnderwater) { if (!neighbor.IsUnderwater) { if (riverData.HasRiverInDirection(direction)) { // / | y // / | // | | //source x/z | | target // | | // \ | // \ | y Vector3 waterShoreHexIndices; waterShoreHexIndices.x = waterShoreHexIndices.z = source.Index; waterShoreHexIndices.y = neighbor.Index; TriangulateEstuary( triangulationData.sourceWaterEdge, triangulationData.neighborWaterEdge, riverData.HasIncomingRiverInDirection(direction), waterShoreHexIndices, hexOuterRadius, wrapSize, this ); } } } return(triangulationData); }
private WaterTriangulationData TriangulateOpenWaterCenter( Hex source, WaterTriangulationData triangulationData, HexDirections direction, float hexOuterRadius, int wrapSize, MapMeshChunkLayer water ) { triangulationData.waterSurfaceCornerLeft = triangulationData.waterSurfaceCenter + HexagonPoint.GetFirstWaterCorner( direction, hexOuterRadius ); triangulationData.waterSurfaceCornerRight = triangulationData.waterSurfaceCenter + HexagonPoint.GetSecondWaterCorner( direction, hexOuterRadius ); water.AddTrianglePerturbed( triangulationData.waterSurfaceCenter, triangulationData.waterSurfaceCornerLeft, triangulationData.waterSurfaceCornerRight, hexOuterRadius, wrapSize ); Vector3 openWaterCenterIndices; openWaterCenterIndices.x = openWaterCenterIndices.y = openWaterCenterIndices.z = source.Index; water.AddTriangleHexData( openWaterCenterIndices, _weights1 ); return(triangulationData); }
private WaterTriangulationData TriangulateShoreOpenWater( Hex source, Hex target, Vector3 waterSurfaceCenter, EdgeVertices sourceWaterEdge, float hexOuterRadius, int wrapSize, MapMeshChunkLayer water, WaterTriangulationData triangulationData ) { water.AddTrianglePerturbed( waterSurfaceCenter, sourceWaterEdge.vertex1, sourceWaterEdge.vertex2, hexOuterRadius, wrapSize ); water.AddTrianglePerturbed( waterSurfaceCenter, sourceWaterEdge.vertex2, sourceWaterEdge.vertex3, hexOuterRadius, wrapSize ); water.AddTrianglePerturbed( waterSurfaceCenter, sourceWaterEdge.vertex3, sourceWaterEdge.vertex4, hexOuterRadius, wrapSize ); water.AddTrianglePerturbed( waterSurfaceCenter, sourceWaterEdge.vertex4, sourceWaterEdge.vertex5, hexOuterRadius, wrapSize ); // / | y // / | // | | //source x/z | | target // | | // \ | // \ | y Vector3 waterShoreHexIndices; waterShoreHexIndices.x = waterShoreHexIndices.z = source.Index; waterShoreHexIndices.y = target.Index; water.AddTriangleHexData( waterShoreHexIndices, _weights1 ); water.AddTriangleHexData( waterShoreHexIndices, _weights1 ); water.AddTriangleHexData( waterShoreHexIndices, _weights1 ); water.AddTriangleHexData( waterShoreHexIndices, _weights1 ); return(triangulationData); }
private WaterTriangulationData TriangulateOpenWaterConnection( Hex source, Hex target, HexDirections direction, WaterTriangulationData waterTriData, TerrainTriangulationData terrainTriData, Dictionary <HexDirections, Hex> neighbors, float hexOuterRadius, int wrapSize, MapMeshChunkLayer water ) { if ( direction <= HexDirections.Southeast ) { Vector3 bridge = HexagonPoint.GetWaterBridge( direction, hexOuterRadius ); Vector3 edge1 = waterTriData.waterSurfaceCornerLeft + bridge; Vector3 edge2 = waterTriData.waterSurfaceCornerRight + bridge; water.AddQuadPerturbed( waterTriData.waterSurfaceCornerLeft, waterTriData.waterSurfaceCornerRight, edge1, edge2, hexOuterRadius, wrapSize ); Vector3 openWaterIndices; openWaterIndices.x = openWaterIndices.z = source.Index; openWaterIndices.y = target.Index; water.AddQuadHexData( openWaterIndices, _weights1, _weights2 ); if (direction <= HexDirections.East) { Hex nextNeighbor; if ( neighbors.TryGetValue( direction.NextClockwise(), out nextNeighbor ) && nextNeighbor.IsUnderwater ) { water.AddTrianglePerturbed( waterTriData.waterSurfaceCornerRight, edge2, waterTriData.waterSurfaceCornerRight + HexagonPoint.GetWaterBridge( direction.NextClockwise(), hexOuterRadius ), hexOuterRadius, wrapSize ); openWaterIndices.z = nextNeighbor.Index; water.AddTriangleHexData( openWaterIndices, _weights1, _weights2, _weights3 ); } } } return(waterTriData); }
private WaterTriangulationData GetWaterData( Hex source, Hex neighbor, WaterTriangulationData waterTriData, HexDirections direction, float hexOuterRadius, int wrapSize ) { waterTriData.waterSurfaceCenter = source.Position; waterTriData.waterSurfaceCenter.y = source.WaterSurfaceY; waterTriData.sourceWaterEdge = new EdgeVertices( waterTriData.waterSurfaceCenter + HexagonPoint.GetFirstWaterCorner( direction, hexOuterRadius ), waterTriData.waterSurfaceCenter + HexagonPoint.GetSecondWaterCorner( direction, hexOuterRadius ) ); Vector3 neighborCenter = neighbor.Position; float hexInnerRadius = HexagonPoint.OuterToInnerRadius(hexOuterRadius); float hexInnerDiameter = hexInnerRadius * 2f; // TODO: This will not work once the column index is removed from // Hex class. // If the neighbor outside the wrap boundaries, adjust accordingly. if (neighbor.ColumnIndex < source.ColumnIndex - 1) { neighborCenter.x += wrapSize * hexInnerDiameter; } else if (neighbor.ColumnIndex > source.ColumnIndex + 1) { neighborCenter.x -= wrapSize * hexInnerDiameter; } neighborCenter.y = waterTriData.waterSurfaceCenter.y; waterTriData.neighborWaterEdge = new EdgeVertices( neighborCenter + HexagonPoint.GetSecondSolidCorner( direction.Opposite(), hexOuterRadius ), neighborCenter + HexagonPoint.GetFirstSolidCorner( direction.Opposite(), hexOuterRadius ) ); return(waterTriData); }
/// <summary> /// Triangulate the mesh geometry of an individual hex. /// </summary> /// <param name="source"> /// The hex to whose mesh geometry is to be triangluated. /// </param> /// <param name="hexOuterRadius"> /// The outer radius of the hex to be triangulated. /// </param> /// <param name="adjacencyGraph"> /// /// </param> /// <param name="riverDigraph"></param> /// <param name="roadUndirectedGraph"></param> /// <param name="elevationDigraph"></param> /// <param name="wrapSize"></param> private void TriangulateHex( Hex source, Dictionary <HexDirections, Hex> neighbors, List <HexDirections> borderDirections, float hexOuterRadius, HexRiverData riverData, Dictionary <HexDirections, bool> roadEdges, Dictionary <HexDirections, ElevationEdgeTypes> elevationEdgeTypes, int wrapSize, TerrainChunkLayer terrainLayer, RiversChunkLayer riversLayer, RoadsChunkLayer roadsLayer, OpenWaterChunkLayer openWaterLayer, WaterShoreChunkLayer waterShoreLayer, EstuariesChunkLayer estuariesLayer, FeatureContainer features ) { foreach ( KeyValuePair <HexDirections, Hex> pair in neighbors ) { // Initialize triangulation data. HexDirections direction = pair.Key; Hex neighbor = pair.Value; TerrainTriangulationData terrainTriData = new TerrainTriangulationData(); terrainTriData.terrainCenter = source.Position; terrainTriData = GetCenterEdgeVertices( direction, terrainTriData, hexOuterRadius ); if (direction <= HexDirections.Southeast) { terrainTriData = GetConnectionEdgeVertices( source, neighbor, direction, terrainTriData, hexOuterRadius ); } // Triangulate layers for non-border edge. terrainTriData = terrainLayer.TriangulateHexTerrainEdge( source, neighbor, terrainTriData, neighbors, direction, riverData, features, roadEdges, elevationEdgeTypes, hexOuterRadius, wrapSize ); terrainTriData = roadsLayer.TriangulateHexRoadEdge( source, neighbor, terrainTriData, direction, riverData, features, roadEdges, elevationEdgeTypes, hexOuterRadius, wrapSize ); terrainTriData = riversLayer.TriangulateHexRiverEdge( source, neighbor, direction, roadEdges, riverData, terrainTriData, hexOuterRadius, wrapSize ); WaterTriangulationData waterTriData = new WaterTriangulationData(); waterTriData = GetWaterData( source, neighbor, waterTriData, direction, hexOuterRadius, wrapSize ); waterTriData = openWaterLayer.TriangulateHexOpenWaterEdge( source, neighbor, neighbors, direction, waterTriData, terrainTriData, hexOuterRadius, wrapSize ); waterTriData = waterShoreLayer.TriangulateHexWaterShoreEdge( source, neighbor, neighbors, direction, riverData, waterTriData, hexOuterRadius, wrapSize ); waterTriData = estuariesLayer.TriangulateHexEstuaryEdge( source, neighbor, direction, riverData, waterTriData, hexOuterRadius, wrapSize ); } bool anyEdge = false; foreach (KeyValuePair <HexDirections, bool> pair in roadEdges) { if (pair.Value) { anyEdge = true; break; } } // Add feature or special to hex. if (!source.IsUnderwater) { if ( !riverData.HasRiver && !anyEdge ) { features.AddFeature( source, source.Position, hexOuterRadius, wrapSize ); } if (source.IsSpecial) { features.AddSpecialFeature( source, source.Position, hexOuterRadius, wrapSize ); } } }