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 ); }
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 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 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 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 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 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); }
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 TerrainTriangulationData TriangulateRiverBeginOrEndRiver( Hex source, TerrainTriangulationData triangulationData, HexRiverData riverData, float hexOuterRadius, int wrapSize, MapMeshChunkLayer rivers ) { Vector3 riverSurfaceCenter = triangulationData.terrainCenter; // bool reversed = hex.HasIncomingRiver; bool reversed = riverData.HasIncomingRiver; Vector3 indices = new Vector3( source.Index, source.Index, source.Index ); TriangulateRiverQuad( triangulationData.middleEdgeVertices.vertex2, triangulationData.middleEdgeVertices.vertex4, triangulationData.centerEdgeVertices.vertex2, triangulationData.centerEdgeVertices.vertex4, source.RiverSurfaceY, 0.6f, reversed, indices, hexOuterRadius, wrapSize, rivers ); riverSurfaceCenter.y = triangulationData.middleEdgeVertices.vertex2.y = triangulationData.middleEdgeVertices.vertex4.y = source.RiverSurfaceY; rivers.AddTrianglePerturbed( riverSurfaceCenter, triangulationData.middleEdgeVertices.vertex2, triangulationData.middleEdgeVertices.vertex4, hexOuterRadius, wrapSize ); if (reversed) { 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.AddTriangleHexData(indices, _weights1); return(triangulationData); }
private void TriangulateEstuary( EdgeVertices edge1, EdgeVertices edge2, bool incomingRiver, Vector3 waterSourceRelativeHexIndices, float hexOuterRadius, int wrapSize, MapMeshChunkLayer estuaries ) { estuaries.AddQuadPerturbed( edge2.vertex1, edge1.vertex2, edge2.vertex2, edge1.vertex3, hexOuterRadius, wrapSize ); estuaries.AddTrianglePerturbed( edge1.vertex3, edge2.vertex2, edge2.vertex4, hexOuterRadius, wrapSize ); estuaries.AddQuadPerturbed( edge1.vertex3, edge1.vertex4, edge2.vertex4, edge2.vertex5, hexOuterRadius, wrapSize ); estuaries.AddQuadUV( new Vector2(0f, 1f), new Vector2(0f, 0f), new Vector2(1f, 1f), new Vector2(0f, 0f) ); estuaries.AddQuadHexData( waterSourceRelativeHexIndices, _weights2, _weights1, _weights2, _weights1 ); estuaries.AddTriangleHexData(waterSourceRelativeHexIndices, _weights1, _weights2, _weights2); estuaries.AddQuadHexData(waterSourceRelativeHexIndices, _weights1, _weights2); 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) ); 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) ); } }
private void TriangulateRoad( Vector3 center, Vector3 middleLeft, Vector3 middleRight, EdgeVertices edgeVertices, bool hasRoadThroughHexEdge, float index, float hexOuterRadius, int wrapSize, MapMeshChunkLayer roads ) { Vector3 indices; indices.x = indices.y = indices.z = index; if (hasRoadThroughHexEdge) { Vector3 middleCenter = Vector3.Lerp(middleLeft, middleRight, 0.5f); TriangulateRoadSegment( middleLeft, middleCenter, middleRight, edgeVertices.vertex2, edgeVertices.vertex3, edgeVertices.vertex4, _weights1, _weights1, indices, hexOuterRadius, wrapSize, roads ); roads.AddTrianglePerturbed( center, middleLeft, middleCenter, hexOuterRadius, wrapSize ); roads.AddTrianglePerturbed( center, middleCenter, middleRight, hexOuterRadius, wrapSize ); 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.AddTriangleHexData(indices, _weights1); roads.AddTriangleHexData(indices, _weights1); } else { TriangulateRoadEdge( center, middleLeft, middleRight, index, hexOuterRadius, wrapSize, roads ); } }
private void TriangulateWaterShore( Hex source, Hex target, Vector3 waterSourceRelativeHexIndices, HexDirections direction, Dictionary <HexDirections, Hex> neighbors, HexRiverData riverData, Vector3 center, float hexOuterRadius, int wrapSize, MapMeshChunkLayer waterShore, EdgeVertices edge1, EdgeVertices edge2, float hexInnerDiameter ) { // hex.HasRiverThroughEdge(direction) if (riverData.HasRiverInDirection(direction)) { TriangulateWaterShoreWithRiver( edge1, edge2, riverData.HasIncomingRiverInDirection(direction), waterSourceRelativeHexIndices, hexOuterRadius, wrapSize, waterShore ); } else { waterShore.AddQuadPerturbed( edge1.vertex1, edge1.vertex2, edge2.vertex1, edge2.vertex2, hexOuterRadius, wrapSize ); waterShore.AddQuadPerturbed( edge1.vertex2, edge1.vertex3, edge2.vertex2, edge2.vertex3, hexOuterRadius, wrapSize ); waterShore.AddQuadPerturbed( edge1.vertex3, edge1.vertex4, edge2.vertex3, edge2.vertex4, hexOuterRadius, wrapSize ); waterShore.AddQuadPerturbed( edge1.vertex4, edge1.vertex5, edge2.vertex4, edge2.vertex5, hexOuterRadius, wrapSize ); waterShore.AddQuadUV(0f, 0f, 0f, 1f); waterShore.AddQuadUV(0f, 0f, 0f, 1f); waterShore.AddQuadUV(0f, 0f, 0f, 1f); waterShore.AddQuadUV(0f, 0f, 0f, 1f); waterShore.AddQuadHexData( waterSourceRelativeHexIndices, _weights1, _weights2 ); waterShore.AddQuadHexData( waterSourceRelativeHexIndices, _weights1, _weights2 ); waterShore.AddQuadHexData( waterSourceRelativeHexIndices, _weights1, _weights2 ); waterShore.AddQuadHexData( waterSourceRelativeHexIndices, _weights1, _weights2 ); } Hex nextNeighbor; // hex.GetNeighbor(direction.NextClockwise()); if ( neighbors.TryGetValue( direction.NextClockwise(), out nextNeighbor ) ) { Vector3 center3 = nextNeighbor.Position; if (nextNeighbor.ColumnIndex < source.ColumnIndex - 1) { center3.x += wrapSize * hexInnerDiameter; } else if (nextNeighbor.ColumnIndex > source.ColumnIndex + 1) { center3.x -= wrapSize * hexInnerDiameter; } // Work backward from the shore to obtain the triangle if the neighbor is // underwater, otherwise obtain normal triangle. Vector3 vertex3 = center3 + ( nextNeighbor.IsUnderwater ? HexagonPoint.GetFirstWaterCorner( direction.PreviousClockwise(), hexOuterRadius ) : HexagonPoint.GetFirstSolidCorner( direction.PreviousClockwise(), hexOuterRadius ) ); vertex3.y = center.y; waterShore.AddTrianglePerturbed( edge1.vertex5, edge2.vertex5, vertex3, hexOuterRadius, wrapSize ); waterSourceRelativeHexIndices.z = nextNeighbor.Index; waterShore.AddTriangleHexData( waterSourceRelativeHexIndices, _weights1, _weights2, _weights3 ); waterShore.AddTriangleUV( new Vector2(0f, 0f), new Vector2(0f, 1f), new Vector2(0f, nextNeighbor.IsUnderwater ? 0f : 1f) ); } }