private void TriangulateEdgeStripRoads( EdgeVertices edge1, Color weight1, float index1, EdgeVertices edge2, Color weight2, float index2, float hexOuterRadius, int wrapSize, MapMeshChunkLayer roads ) { Vector3 indices; indices.x = indices.z = index1; indices.y = index2; TriangulateRoadSegment( edge1.vertex2, edge1.vertex3, edge1.vertex4, edge2.vertex2, edge2.vertex3, edge2.vertex4, weight1, weight2, indices, hexOuterRadius, wrapSize, roads ); }
private void TriangulateEdgeTerracesRoad( EdgeVertices begin, Hex beginHex, EdgeVertices end, Hex endHex, bool hasRoad, float hexOuterRadius, int wrapSize, MapMeshChunkLayer roads ) { EdgeVertices edge2 = EdgeVertices.TerraceLerp(begin, end, 1); Color weight2 = HexagonPoint.TerraceLerp(_weights1, _weights2, 1); float index1 = beginHex.Index; float index2 = endHex.Index; TriangulateEdgeStripRoads( begin, _weights1, index1, edge2, weight2, index2, hexOuterRadius, wrapSize, roads ); for (int i = 2; i < HexagonPoint.terraceSteps; i++) { EdgeVertices edge1 = edge2; Color weight1 = weight2; edge2 = EdgeVertices.TerraceLerp(begin, end, i); weight2 = HexagonPoint.TerraceLerp(_weights1, _weights2, i); TriangulateEdgeStripRoads( edge1, weight1, index1, edge2, weight2, index2, hexOuterRadius, wrapSize, roads ); } TriangulateEdgeStripRoads( edge2, weight2, index1, end, _weights2, index2, hexOuterRadius, wrapSize, roads ); }
public static MapMeshChunkLayer CreateEmpty( Material material, bool useCollider, bool useHexData, bool useUVCoordinates, bool useUV2Coordinates ) { GameObject resultObj = new GameObject("Map Mesh Chunk Layer"); MapMeshChunkLayer resultMono = resultObj.AddComponent <MapMeshChunkLayer>(); resultMono.GetComponent <MeshRenderer>().material = material; resultMono._useCollider = useCollider; if (useCollider) { resultMono._meshCollider = resultObj.AddComponent <MeshCollider>(); } resultMono._useHexData = useHexData; resultMono._useUVCoordinates = useUVCoordinates; resultMono._useUV2Coordinates = useUV2Coordinates; return(resultMono); }
private void TriangulateRoadEdge( Vector3 center, Vector3 middleLeft, Vector3 middleRight, float index, float hexOuterRadius, int wrapSize, MapMeshChunkLayer roads ) { roads.AddTrianglePerturbed( center, middleLeft, middleRight, hexOuterRadius, wrapSize ); roads.AddTriangleUV( new Vector2(1f, 0f), new Vector2(0f, 0f), new Vector2(0f, 0f) ); Vector3 indices; indices.x = indices.y = indices.z = index; roads.AddTriangleHexData(indices, _weights1); }
private void TriangulateRiverQuad( Vector3 vertex1, Vector3 vertex2, Vector3 vertex3, Vector3 vertex4, float y, float v, bool reversed, Vector3 indices, float hexOuterRadius, int wrapSize, MapMeshChunkLayer rivers ) { TriangulateRiverQuad( vertex1, vertex2, vertex3, vertex4, y, y, v, reversed, indices, hexOuterRadius, wrapSize, rivers ); }
private void TriangulateEdgeStripTerrain( EdgeVertices edge1, Color weight1, float index1, EdgeVertices edge2, Color weight2, float index2, float hexOuterRadius, int wrapSize, MapMeshChunkLayer terrain ) { terrain.AddQuadPerturbed( edge1.vertex1, edge1.vertex2, edge2.vertex1, edge2.vertex2, hexOuterRadius, wrapSize ); terrain.AddQuadPerturbed( edge1.vertex2, edge1.vertex3, edge2.vertex2, edge2.vertex3, hexOuterRadius, wrapSize ); terrain.AddQuadPerturbed( edge1.vertex3, edge1.vertex4, edge2.vertex3, edge2.vertex4, hexOuterRadius, wrapSize ); terrain.AddQuadPerturbed( edge1.vertex4, edge1.vertex5, edge2.vertex4, edge2.vertex5, hexOuterRadius, wrapSize ); Vector3 indices; indices.x = indices.z = index1; indices.y = index2; terrain.AddQuadHexData(indices, weight1, weight2); terrain.AddQuadHexData(indices, weight1, weight2); terrain.AddQuadHexData(indices, weight1, weight2); terrain.AddQuadHexData(indices, weight1, weight2); }
private void TriangulateWaterfallInWater( Vector3 vertex1, Vector3 vertex2, Vector3 vertex3, Vector3 vertex4, float y1, float y2, float waterY, Vector3 indices, float hexOuterRadius, int wrapSize, MapMeshChunkLayer rivers ) { vertex1.y = vertex2.y = y1; vertex3.y = vertex4.y = y2; vertex1 = HexagonPoint.Perturb( vertex1, hexOuterRadius, wrapSize ); vertex2 = HexagonPoint.Perturb( vertex2, hexOuterRadius, wrapSize ); vertex3 = HexagonPoint.Perturb( vertex3, hexOuterRadius, wrapSize ); vertex4 = HexagonPoint.Perturb( vertex4, hexOuterRadius, wrapSize ); float t = (waterY - y2) / (y1 - y2); vertex3 = Vector3.Lerp(vertex3, vertex1, t); vertex4 = Vector3.Lerp(vertex4, vertex2, t); rivers.AddQuadUnperturbed( vertex1, vertex2, vertex3, vertex4 ); rivers.AddQuadUV(0f, 1f, 0.8f, 1f); rivers.AddQuadHexData(indices, _weights1, _weights2); }
private void TriangulateWaterShoreWithRiver( EdgeVertices edge1, EdgeVertices edge2, bool incomingRiver, Vector3 indices, float hexOuterRadius, int wrapSize, MapMeshChunkLayer waterShore ) { waterShore.AddTrianglePerturbed( edge2.vertex1, edge1.vertex2, edge1.vertex1, hexOuterRadius, wrapSize ); waterShore.AddTrianglePerturbed( edge2.vertex5, edge1.vertex5, edge1.vertex4, hexOuterRadius, wrapSize ); 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.AddTriangleHexData( indices, _weights2, _weights1, _weights1 ); waterShore.AddTriangleHexData( indices, _weights2, _weights1, _weights1 ); }
private TerrainTriangulationData TriangulateTerrainConnectionRoads( Hex source, Hex neighbor, TerrainTriangulationData data, HexDirections direction, HexRiverData riverData, Dictionary <HexDirections, bool> roadEdges, Dictionary <HexDirections, ElevationEdgeTypes> elevationEdgeTypes, float hexOuterRadius, int wrapSize, MapMeshChunkLayer roads ) { bool hasRoad = roadEdges[direction]; if ( // hex.GetEdgeType(direction) == ElevationEdgeTypes.Slope elevationEdgeTypes[direction] == ElevationEdgeTypes.Slope ) { if (hasRoad) { TriangulateEdgeTerracesRoads( data.centerEdgeVertices, source, data.connectionEdgeVertices, neighbor, hasRoad, hexOuterRadius, wrapSize, roads ); } } else { if (hasRoad) { TriangulateEdgeStripRoads( data.centerEdgeVertices, _weights1, source.Index, data.connectionEdgeVertices, _weights2, neighbor.Index, hexOuterRadius, wrapSize, roads ); } } return(data); }
protected void TriangulateEdgeFan( Vector3 center, EdgeVertices edge, float index, float hexOuterRadius, int wrapSize, MapMeshChunkLayer terrain ) { terrain.AddTrianglePerturbed( center, edge.vertex1, edge.vertex2, hexOuterRadius, wrapSize ); terrain.AddTrianglePerturbed( center, edge.vertex2, edge.vertex3, hexOuterRadius, wrapSize ); terrain.AddTrianglePerturbed( center, edge.vertex3, edge.vertex4, hexOuterRadius, wrapSize ); terrain.AddTrianglePerturbed( center, edge.vertex4, edge.vertex5, hexOuterRadius, wrapSize ); // All three cell indices corresponing to the sides of this // edge are of one cell. Vector3 indices; indices.x = indices.y = indices.z = index; terrain.AddTriangleHexData(indices, _weights1); terrain.AddTriangleHexData(indices, _weights1); terrain.AddTriangleHexData(indices, _weights1); terrain.AddTriangleHexData(indices, _weights1); }
private TerrainTriangulationData TriangulateCenterRiverQuads( Hex source, TerrainTriangulationData triangulationData, HexDirections direction, HexRiverData riverData, float hexOuterRadius, int wrapSize, MapMeshChunkLayer rivers ) { bool reversed = riverData.HasIncomingRiverInDirection( direction ); Vector3 centerHexIndices; centerHexIndices.x = centerHexIndices.y = centerHexIndices.z = source.Index; TriangulateRiverQuad( triangulationData.riverCenterLeft, triangulationData.riverCenterRight, triangulationData.middleEdgeVertices.vertex2, triangulationData.middleEdgeVertices.vertex4, source.RiverSurfaceY, 0.4f, reversed, centerHexIndices, hexOuterRadius, wrapSize, rivers ); TriangulateRiverQuad( triangulationData.middleEdgeVertices.vertex2, triangulationData.middleEdgeVertices.vertex4, triangulationData.centerEdgeVertices.vertex2, triangulationData.centerEdgeVertices.vertex4, source.RiverSurfaceY, 0.6f, reversed, centerHexIndices, hexOuterRadius, wrapSize, rivers ); return(triangulationData); }
private TerrainTriangulationData TriangulateCenterRiverSurface( HexRiverData riverData, HexDirections direction, Hex source, TerrainTriangulationData data, float hexOuterRadius, int wrapSize, MapMeshChunkLayer rivers, Dictionary <HexDirections, bool> roadEdges ) { if (riverData.HasRiver) { if (riverData.HasRiverInDirection(direction)) { // If the triangle has a river through the edge, lower center edge vertex // to simulate stream bed. if (riverData.HasRiverStartOrEnd) { if (!source.IsUnderwater) { data = TriangulateRiverBeginOrEndRiver( source, data, riverData, hexOuterRadius, wrapSize, rivers ); } } else if (!source.IsUnderwater) { data = TriangulateCenterRiverQuads( source, data, direction, riverData, hexOuterRadius, wrapSize, rivers ); } } } return(data); }
private TerrainTriangulationData TriangulateRiverBeginOrEndTerrain( Hex source, TerrainTriangulationData data, float hexOuterRadius, int wrapSize, MapMeshChunkLayer terrain ) { data.middleEdgeVertices = new EdgeVertices( Vector3.Lerp( data.terrainCenter, data.centerEdgeVertices.vertex1, 0.5f ), Vector3.Lerp( data.terrainCenter, data.centerEdgeVertices.vertex5, 0.5f ) ); data.middleEdgeVertices.vertex3.y = source.StreamBedY; TriangulateEdgeStripTerrain( data.middleEdgeVertices, _weights1, source.Index, data.centerEdgeVertices, _weights1, source.Index, hexOuterRadius, wrapSize, terrain ); TriangulateEdgeFan( data.terrainCenter, data.middleEdgeVertices, source.Index, hexOuterRadius, wrapSize, terrain ); return(data); }
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); }
protected void TriangulateRoadSegment( Vector3 vertex1, Vector3 vertex2, Vector3 vertex3, Vector3 vertex4, Vector3 vertex5, Vector3 vertex6, Color weight1, Color weight2, Vector3 indices, float hexOuterRadius, int wrapSize, MapMeshChunkLayer roads ) { roads.AddQuadPerturbed( vertex1, vertex2, vertex4, vertex5, hexOuterRadius, wrapSize ); roads.AddQuadPerturbed( vertex2, vertex3, vertex5, vertex6, hexOuterRadius, wrapSize ); roads.AddQuadUV(0f, 1f, 0f, 0f); roads.AddQuadUV(1f, 0f, 0f, 0f); roads.AddQuadHexData(indices, weight1, weight2); roads.AddQuadHexData(indices, weight1, weight2); }
private void TriangulateRoadWithoutRiver( Hex source, HexDirections direction, EdgeVertices edgeVertices, Dictionary <HexDirections, bool> roadEdges, Vector3 center, float hexOuterRadius, int wrapSize, MapMeshChunkLayer roads ) { Vector2 interpolators = GetRoadInterpolators( source, direction, roadEdges ); TriangulateRoad( center, Vector3.Lerp( center, edgeVertices.vertex1, interpolators.x ), Vector3.Lerp( center, edgeVertices.vertex5, interpolators.y ), edgeVertices, // hex.HasRoadThroughEdge(direction), roadEdges[direction], source.Index, hexOuterRadius, wrapSize, roads ); }
private void TriangulateRiverQuad( Vector3 vertex1, Vector3 vertex2, Vector3 vertex3, Vector3 vertex4, float y1, float y2, float v, bool reversed, Vector3 indices, float hexOuterRadius, int wrapSize, MapMeshChunkLayer rivers ) { vertex1.y = vertex2.y = y1; vertex3.y = vertex4.y = y2; rivers.AddQuadPerturbed( vertex1, vertex2, vertex3, vertex4, hexOuterRadius, wrapSize ); if (reversed) { rivers.AddQuadUV(1f, 0f, 0.8f - v, 0.6f - v); } else { rivers.AddQuadUV(0f, 1f, v, v + 0.2f); } rivers.AddQuadHexData(indices, _weights1, _weights2); }
private TerrainTriangulationData TryTriangulateNeighborTerrainCorner( Hex source, Hex neighbor, TerrainTriangulationData data, HexDirections direction, Dictionary <HexDirections, Hex> neighbors, float hexOuterRadius, int wrapSize, MapMeshChunkLayer terrain, FeatureContainer features ) { Hex nextNeighbor; if ( neighbors.TryGetValue( direction.NextClockwise(), out nextNeighbor ) && direction <= HexDirections.East ) { TriangulateNeighborTerrainCorner( source, neighbor, nextNeighbor, direction, data, hexOuterRadius, wrapSize, terrain, features ); } return(data); }
private TerrainTriangulationData TriangulateTerrainConnection( Hex source, Hex neighbor, TerrainTriangulationData data, HexDirections direction, HexRiverData riverData, Dictionary <HexDirections, bool> roadEdges, Dictionary <HexDirections, ElevationEdgeTypes> elevationEdgeTypes, float hexOuterRadius, int wrapSize, MapMeshChunkLayer terrain, FeatureContainer features ) { if (riverData.HasRiverInDirection(direction)) { data.connectionEdgeVertices.vertex3.y = neighbor.StreamBedY; } bool hasRoad = roadEdges[direction]; if ( // hex.GetEdgeType(direction) == ElevationEdgeTypes.Slope elevationEdgeTypes[direction] == ElevationEdgeTypes.Slope ) { TriangulateEdgeTerracesTerrain( data.centerEdgeVertices, source, data.connectionEdgeVertices, neighbor, hexOuterRadius, wrapSize, terrain ); } else { TriangulateEdgeStripTerrain( data.centerEdgeVertices, _weights1, source.Index, data.connectionEdgeVertices, _weights2, neighbor.Index, hexOuterRadius, wrapSize, terrain ); } features.AddWall( data.centerEdgeVertices, source, data.connectionEdgeVertices, neighbor, riverData.HasRiverInDirection(direction), hasRoad, hexOuterRadius, wrapSize ); return(data); }
private void TriangulateCornerTerraces( Vector3 begin, Hex beginHex, Vector3 left, Hex leftHex, Vector3 right, Hex rightHex, float hexOuterRadius, int wrapSize, MapMeshChunkLayer terrain ) { Vector3 vertex3 = HexagonPoint.TerraceLerp(begin, left, 1); Vector3 vertex4 = HexagonPoint.TerraceLerp(begin, right, 1); Color weight3 = HexagonPoint.TerraceLerp(_weights1, _weights2, 1); Color weight4 = HexagonPoint.TerraceLerp(_weights1, _weights3, 1); Vector3 indices; indices.x = beginHex.Index; indices.y = leftHex.Index; indices.z = rightHex.Index; terrain.AddTrianglePerturbed( begin, vertex3, vertex4, hexOuterRadius, wrapSize ); terrain.AddTriangleHexData( indices, _weights1, weight3, weight4 ); for (int i = 2; i < HexagonPoint.terraceSteps; i++) { Vector3 vertex1 = vertex3; Vector3 vertex2 = vertex4; Color weight1 = weight3; Color weight2 = weight4; vertex3 = HexagonPoint.TerraceLerp(begin, left, i); vertex4 = HexagonPoint.TerraceLerp(begin, right, i); weight3 = HexagonPoint.TerraceLerp(_weights1, _weights2, i); weight4 = HexagonPoint.TerraceLerp(_weights1, _weights3, i); terrain.AddQuadPerturbed( vertex1, vertex2, vertex3, vertex4, hexOuterRadius, wrapSize ); terrain.AddQuadHexData( indices, weight1, weight2, weight3, weight4 ); } terrain.AddQuadPerturbed( vertex3, vertex4, left, right, hexOuterRadius, wrapSize ); terrain.AddQuadHexData( indices, weight3, weight4, _weights2, _weights3 ); }
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); }
private void TriangulateTerrainCorner( Vector3 begin, Hex beginHex, Vector3 left, Hex leftHex, Vector3 right, Hex rightHex, float hexOuterRadius, int wrapSize, MapMeshChunkLayer terrain, FeatureContainer features ) { ElevationEdgeTypes leftEdgeType = beginHex.GetEdgeType(leftHex); ElevationEdgeTypes rightEdgeType = beginHex.GetEdgeType(rightHex); if (leftEdgeType == ElevationEdgeTypes.Slope) { if (rightEdgeType == ElevationEdgeTypes.Slope) { // Corner is also a terrace. Slope-Slope-Flat. TriangulateCornerTerraces( begin, beginHex, left, leftHex, right, rightHex, hexOuterRadius, wrapSize, terrain ); } // If the right edge is flat, must terrace from left instead of bottom. // Slope-Flat-Slope else if (rightEdgeType == ElevationEdgeTypes.Flat) { TriangulateCornerTerraces( left, leftHex, right, rightHex, begin, beginHex, hexOuterRadius, wrapSize, terrain ); } else { /* At least one edge is a cliff. Slope-Cliff-Slope or Slope-Cliff-Cliff. Standard case * because slope on left and flat on right. */ TriangulateCornerTerracesCliff( begin, beginHex, left, leftHex, right, rightHex, hexOuterRadius, wrapSize, terrain ); } } else if (rightEdgeType == ElevationEdgeTypes.Slope) { if (leftEdgeType == ElevationEdgeTypes.Flat) { /* If the right edge is a slope, and the left edge is flat, must terrace from right instead * of bottom. Flat-Slope-Slope. */ TriangulateCornerTerraces( right, rightHex, begin, beginHex, left, leftHex, hexOuterRadius, wrapSize, terrain ); } else { /* At least one edge is a cliff. Slope-Cliff-Slope or Slope-Cliff-Cliff. Mirror case because * slope on right and flat on left. */ TriangulateCornerCliffTerraces( begin, beginHex, left, leftHex, right, rightHex, hexOuterRadius, wrapSize, terrain ); } } /* Neither the left or right hex edge type is a slope. If the right hex type of the left hex * is a slope, then terraces must be calculated for a corner between two cliff edges. * Cliff-Cliff-Slope Right, or Cliff-Cliff-Slope Left. */ else if (leftHex.GetEdgeType(rightHex) == ElevationEdgeTypes.Slope) { // If Cliff-Cliff-Slope-Left if (leftHex.elevation < rightHex.elevation) { TriangulateCornerCliffTerraces( right, rightHex, begin, beginHex, left, leftHex, hexOuterRadius, wrapSize, terrain ); } // If Cliff-Cliff-Slope-Right else { TriangulateCornerTerracesCliff( left, leftHex, right, rightHex, begin, beginHex, hexOuterRadius, wrapSize, terrain ); } } // Else all edges are cliffs. Simply draw a triangle. else { terrain.AddTrianglePerturbed( begin, left, right, hexOuterRadius, wrapSize ); Vector3 indices; indices.x = beginHex.Index; indices.y = leftHex.Index; indices.z = rightHex.Index; terrain.AddTriangleHexData( indices, _weights1, _weights2, _weights3 ); } features.AddWall( begin, beginHex, left, leftHex, right, rightHex, hexOuterRadius, wrapSize ); }
private TerrainTriangulationData TriangulateNeighborTerrainCorner( Hex source, Hex neighbor, Hex nextNeighbor, HexDirections direction, TerrainTriangulationData data, float hexOuterRadius, int wrapSize, MapMeshChunkLayer terrain, FeatureContainer features ) { // Create a 5th vertex and assign it with the elevation of the neighbor // under consideration. This will be used as the final vertex in the // triangle which fills the gap between bridges. Vector3 vertex5 = data.centerEdgeVertices.vertex5 + HexagonPoint.GetBridge( direction.NextClockwise(), hexOuterRadius ); vertex5.y = nextNeighbor.Position.y; if (source.elevation <= neighbor.elevation) { if (source.elevation <= nextNeighbor.elevation) { // This hex has lowest elevation, no rotation. TriangulateTerrainCorner( data.centerEdgeVertices.vertex5, source, data.connectionEdgeVertices.vertex5, neighbor, vertex5, nextNeighbor, hexOuterRadius, wrapSize, terrain, features ); } else { // Next neighbor has lowest elevation, rotate counter-clockwise. TriangulateTerrainCorner( vertex5, nextNeighbor, data.centerEdgeVertices.vertex5, source, data.connectionEdgeVertices.vertex5, neighbor, hexOuterRadius, wrapSize, terrain, features ); } } else if (neighbor.elevation <= nextNeighbor.elevation) { // Neighbor is lowest hex, rotate triangle clockwise. TriangulateTerrainCorner( data.connectionEdgeVertices.vertex5, neighbor, vertex5, nextNeighbor, data.centerEdgeVertices.vertex5, source, hexOuterRadius, wrapSize, terrain, features ); } else { // Next neighbor has lowest elevation, rotate counter-clockwise. TriangulateTerrainCorner( vertex5, nextNeighbor, data.centerEdgeVertices.vertex5, source, data.connectionEdgeVertices.vertex5, neighbor, hexOuterRadius, wrapSize, terrain, features ); } return(data); }
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 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 void TriangulateCornerCliffTerraces( Vector3 begin, Hex beginHex, Vector3 left, Hex leftHex, Vector3 right, Hex rightHex, float hexOuterRadius, int wrapSize, MapMeshChunkLayer terrain ) { /* Set boundary distance to 1 elevation level above the bottom-most hex * in the case. */ float boundaryDistance = 1f / (leftHex.elevation - beginHex.elevation); // If boundary distance becomes negative, CCSR and CCSL case will have strange behavior. if (boundaryDistance < 0) { boundaryDistance = -boundaryDistance; } // Must interpolate between the perturbed points, not the original points. Vector3 boundary = Vector3.Lerp( HexagonPoint.Perturb( begin, hexOuterRadius, wrapSize ), HexagonPoint.Perturb( left, hexOuterRadius, wrapSize ), boundaryDistance ); Color boundaryWeights = Color.Lerp( _weights1, _weights2, boundaryDistance ); Vector3 indices; indices.x = beginHex.Index; indices.y = leftHex.Index; indices.z = rightHex.Index; TriangulateBoundaryTriangle( right, _weights3, begin, _weights1, boundary, boundaryWeights, indices, hexOuterRadius, wrapSize, terrain ); // Slope-Cliff-Slope. Triangulate a slope. if (leftHex.GetEdgeType(rightHex) == ElevationEdgeTypes.Slope) { TriangulateBoundaryTriangle( left, _weights2, right, _weights3, boundary, boundaryWeights, indices, hexOuterRadius, wrapSize, terrain ); } // Slope-Cliff-Cliff. Triangulate a cliff. else { /* Add perturbation to all vertices except the boundary vertex * to handle the Slope-Cliff-Cliff case of the Cliff-Slope perturbation * problem. */ terrain.AddTriangleUnperturbed( HexagonPoint.Perturb( left, hexOuterRadius, wrapSize ), HexagonPoint.Perturb( right, hexOuterRadius, wrapSize ), boundary ); terrain.AddTriangleHexData( indices, _weights2, _weights3, boundaryWeights ); } }
protected void TriangulateBoundaryTriangle( Vector3 begin, Color beginWeights, Vector3 left, Color leftWeights, Vector3 boundary, Color boundaryWeights, Vector3 indices, float hexOuterRadius, int wrapSize, MapMeshChunkLayer terrain ) { /* Immediately perturb vertex 2 as an optimization since it is not * being used to derive any other point. */ Vector3 vertex2 = HexagonPoint.Perturb( HexagonPoint.TerraceLerp(begin, left, 1), hexOuterRadius, wrapSize ); Color weight2 = HexagonPoint.TerraceLerp( beginWeights, leftWeights, 1 ); /* Perturb all vertices except the boundary vertex, to avoid moving * the vertex out of alignment with a cliff. vertex2 has already been * perturbed. Handles the Cliff-Slope-Slope and Slope-Cliff-Slope cases * of the Cliff-Slope perturbation problem. */ terrain.AddTriangleUnperturbed( HexagonPoint.Perturb( begin, hexOuterRadius, wrapSize ), vertex2, boundary ); terrain.AddTriangleHexData( indices, beginWeights, weight2, boundaryWeights ); for (int i = 2; i < HexagonPoint.terraceSteps; i++) { /* vertex2 has already been perturbed, need not pertub * vertex1 as it is derived from vertex2. */ Vector3 vertex1 = vertex2; Color weight1 = weight2; vertex2 = HexagonPoint.Perturb( HexagonPoint.TerraceLerp(begin, left, i), hexOuterRadius, wrapSize ); weight2 = HexagonPoint.TerraceLerp( beginWeights, leftWeights, i ); terrain.AddTriangleUnperturbed(vertex1, vertex2, boundary); terrain.AddTriangleHexData( indices, weight1, weight2, boundaryWeights ); } terrain.AddTriangleUnperturbed( vertex2, HexagonPoint.Perturb( left, hexOuterRadius, wrapSize ), boundary ); terrain.AddTriangleHexData(indices, weight2, leftWeights, boundaryWeights); }
private TerrainTriangulationData TriangulateRiverTerrain( Hex source, TerrainTriangulationData triangulationData, float hexOuterRadius, int wrapSize, MapMeshChunkLayer terrain ) { TriangulateEdgeStripTerrain( triangulationData.middleEdgeVertices, _weights1, source.Index, triangulationData.centerEdgeVertices, _weights1, source.Index, hexOuterRadius, wrapSize, terrain ); terrain.AddTrianglePerturbed( triangulationData.riverCenterLeft, triangulationData.middleEdgeVertices.vertex1, triangulationData.middleEdgeVertices.vertex2, hexOuterRadius, wrapSize ); terrain.AddQuadPerturbed( triangulationData.riverCenterLeft, triangulationData.terrainCenter, triangulationData.middleEdgeVertices.vertex2, triangulationData.middleEdgeVertices.vertex3, hexOuterRadius, wrapSize ); terrain.AddQuadPerturbed( triangulationData.terrainCenter, triangulationData.riverCenterRight, triangulationData.middleEdgeVertices.vertex3, triangulationData.middleEdgeVertices.vertex4, hexOuterRadius, wrapSize ); terrain.AddTrianglePerturbed( triangulationData.riverCenterRight, triangulationData.middleEdgeVertices.vertex4, triangulationData.middleEdgeVertices.vertex5, hexOuterRadius, wrapSize ); Vector3 centerHexIndices; centerHexIndices.x = centerHexIndices.y = centerHexIndices.z = source.Index; terrain.AddTriangleHexData( centerHexIndices, _weights1 ); terrain.AddQuadHexData( centerHexIndices, _weights1 ); terrain.AddQuadHexData( centerHexIndices, _weights1 ); terrain.AddTriangleHexData( centerHexIndices, _weights1 ); return(triangulationData); }
public static FeatureContainer GetFeatureContainer(MapMeshChunkLayer walls) { GameObject resultObj = new GameObject("Feature Container"); FeatureContainer resultMono = resultObj.AddComponent<FeatureContainer>(); resultMono.urbanCollections = new FeatureCollection[3]; resultMono.farmCollections = new FeatureCollection[3]; resultMono.plantCollections = new FeatureCollection[3]; resultMono.special = new Transform[3]; resultMono.walls = walls; resultMono.wallTower = Resources.Load<Transform>("Wall Tower"); resultMono.bridge = Resources.Load<Transform>("Bridge"); resultMono.urbanCollections[0] = new FeatureCollection( new Transform[] { Resources.Load<Transform>("Urban High 1"), Resources.Load<Transform>("Urban High 2") } ); resultMono.urbanCollections[1] = new FeatureCollection( new Transform[] { Resources.Load<Transform>("Urban Medium 1"), Resources.Load<Transform>("Urban Medium 2") } ); resultMono.urbanCollections[2] = new FeatureCollection( new Transform[] { Resources.Load<Transform>("Urban Low 1"), Resources.Load<Transform>("Urban Low 2") } ); resultMono.farmCollections[0] = new FeatureCollection( new Transform[] { Resources.Load<Transform>("Farm High 1"), Resources.Load<Transform>("Farm High 2") } ); resultMono.farmCollections[1] = new FeatureCollection( new Transform[] { Resources.Load<Transform>("Farm Medium 1"), Resources.Load<Transform>("Farm Medium 2") } ); resultMono.farmCollections[2] = new FeatureCollection( new Transform[] { Resources.Load<Transform>("Farm Low 1"), Resources.Load<Transform>("Farm Low 2") } ); resultMono.plantCollections[0] = new FeatureCollection( new Transform[] { Resources.Load<Transform>("Plant High 1"), Resources.Load<Transform>("Plant High 2") } ); resultMono.plantCollections[1] = new FeatureCollection( new Transform[] { Resources.Load<Transform>("Plant Medium 1"), Resources.Load<Transform>("Plant Medium 2") } ); resultMono.plantCollections[2] = new FeatureCollection( new Transform[] { Resources.Load<Transform>("Plant Low 1"), Resources.Load<Transform>("Plant Low 2") } ); resultMono.special[0] = Resources.Load<Transform>("Castle"); resultMono.special[1] = Resources.Load<Transform>("Ziggurat"); resultMono.special[2] = Resources.Load<Transform>("Megaflora"); return resultMono; }
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); }