private TerrainTriangulationData TriangulateTerrainAdjacentToRiver( Hex source, HexDirections direction, TerrainTriangulationData triangulationData, Dictionary <HexDirections, bool> roadEdges, HexRiverData riverData, float hexOuterRadius, int wrapSize, MapMeshChunkLayer terrain, FeatureContainer features ) { if (riverData.HasRiverInDirection(direction.NextClockwise())) { /* If the direction has a river on either side, it has a slight curve. * The center vertex of river-adjacent triangle needs to be moved toward * the edge so they don't overlap the river. */ // if (hex.HasRiverThroughEdge(direction.Previous())) { if ( riverData.HasRiverInDirection(direction.PreviousClockwise()) ) { triangulationData.terrainCenter += HexagonPoint.GetSolidEdgeMiddle( direction, hexOuterRadius ) * (HexagonConstants.INNER_TO_OUTER_RATIO * 0.5f); } /* If the hex has a river through the previous previous direction, * it has a river flowing through the hex. Move the center vertex * of the river-adjacent triangle so that it does not overlap the river. */ else if ( riverData.HasRiverInDirection( direction.PreviousClockwise2() ) ) { triangulationData.terrainCenter += HexagonPoint.GetFirstSolidCorner( direction, hexOuterRadius ) * 0.25f; } } /* Second case of straight-river-adjacent triangle. Need to move center * so it doesn't overlap the river. */ else if ( riverData.HasRiverInDirection(direction.PreviousClockwise()) && riverData.HasRiverInDirection(direction.NextClockwise2()) ) { triangulationData.terrainCenter += HexagonPoint.GetSecondSolidCorner( direction, hexOuterRadius ) * 0.25f; } EdgeVertices middle = new EdgeVertices( Vector3.Lerp( triangulationData.terrainCenter, triangulationData.centerEdgeVertices.vertex1, 0.5f ), Vector3.Lerp( triangulationData.terrainCenter, triangulationData.centerEdgeVertices.vertex5, 0.5f ) ); TriangulateEdgeStripTerrain( middle, _weights1, source.Index, triangulationData.centerEdgeVertices, _weights1, source.Index, hexOuterRadius, wrapSize, terrain ); TriangulateEdgeFan( triangulationData.terrainCenter, middle, source.Index, hexOuterRadius, wrapSize, terrain ); if (!source.IsUnderwater && roadEdges[direction]) { features.AddFeature( source, ( triangulationData.terrainCenter + triangulationData.centerEdgeVertices.vertex1 + triangulationData.centerEdgeVertices.vertex5 ) * (1f / 3f), hexOuterRadius, wrapSize ); } return(triangulationData); }
private TerrainTriangulationData TriangulateTerrainCenter( HexRiverData riverData, HexDirections direction, Hex source, TerrainTriangulationData data, float hexOuterRadius, int wrapSize, MapMeshChunkLayer terrain, FeatureContainer features, Dictionary <HexDirections, bool> roadEdges ) { if (riverData.HasRiver) { if (riverData.HasRiverInDirection(direction)) { data.centerEdgeVertices.vertex3.y = source.StreamBedY; if (riverData.HasRiverStartOrEnd) { data = TriangulateRiverBeginOrEndTerrain( source, data, hexOuterRadius, wrapSize, terrain ); } else { data = TriangulateRiverBanks( data, riverData, direction, hexOuterRadius ); data = TriangulateRiverTerrain( source, data, hexOuterRadius, wrapSize, terrain ); } } else { data = TriangulateTerrainAdjacentToRiver( source, direction, data, roadEdges, riverData, hexOuterRadius, wrapSize, terrain, features ); } } else { // Triangulate terrain center without river, basic edge fan. TriangulateEdgeFan( data.terrainCenter, data.centerEdgeVertices, source.Index, hexOuterRadius, wrapSize, terrain ); if ( !source.IsUnderwater && !roadEdges[direction] ) { features.AddFeature( source, ( data.terrainCenter + data.centerEdgeVertices.vertex1 + data.centerEdgeVertices.vertex5 ) * (1f / 3f), hexOuterRadius, wrapSize ); } } return(data); }
/// <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 ); } } }