public static void AddLine( ref VertexHelper vh, LineProperties lineProperties, PointsList.PointListProperties pointListProperties, Vector2 positionOffset, GeoUtils.OutlineProperties outlineProperties, Color32 color, Vector2 uv, ref PointsList.PointsData pointsData, GeoUtils.EdgeGradientData edgeGradientData ) { pointListProperties.SetPoints(); pointsData.IsClosed = lineProperties.Closed && pointListProperties.Positions.Length > 2; pointsData.GenerateRoundedCaps = lineProperties.LineCap == LineProperties.LineCapTypes.Round; pointsData.LineWeight = outlineProperties.LineWeight; if (pointsData.GenerateRoundedCaps) { lineProperties.RoundedCapResolution.UpdateAdjusted(outlineProperties.HalfLineWeight, 0.0f, 2.0f); pointsData.RoundedCapResolution = lineProperties.RoundedCapResolution.AdjustedResolution; } if (!PointsList.SetLineData(pointListProperties, ref pointsData)) { return; } // scale uv x for caps float uvXMin = 0.0f; float uvXLength = 1.0f; if ( !lineProperties.Closed && lineProperties.LineCap != LineProperties.LineCapTypes.Close ) { float uvStartOffset = outlineProperties.LineWeight / pointsData.TotalLength; uvXMin = uvStartOffset * 0.5f; uvXLength = 1.0f - uvXMin * 2.0f; } float innerOffset = outlineProperties.GetCenterDistace() - (outlineProperties.HalfLineWeight + edgeGradientData.ShadowOffset) * edgeGradientData.InnerScale; float outerOffset = outlineProperties.GetCenterDistace() + (outlineProperties.HalfLineWeight + edgeGradientData.ShadowOffset) * edgeGradientData.InnerScale; float capOffsetAmount = 0.0f; if (!lineProperties.Closed && lineProperties.LineCap == LineProperties.LineCapTypes.Close) { capOffsetAmount = edgeGradientData.ShadowOffset * (edgeGradientData.InnerScale * 2.0f - 1.0f); } int numVertices = vh.currentVertCount; int startVertex = numVertices - 1; int baseIndex; uv.x = uvXMin + pointsData.NormalizedPositionDistances[0] * uvXLength; uv.y = 0.0f; { tmpPos.x = positionOffset.x + pointsData.Positions[0].x + pointsData.PositionNormals[0].x * innerOffset + pointsData.StartCapOffset.x * capOffsetAmount; tmpPos.y = positionOffset.y + pointsData.Positions[0].y + pointsData.PositionNormals[0].y * innerOffset + pointsData.StartCapOffset.y * capOffsetAmount; } vh.AddVert(tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent); uv.y = 1.0f; { tmpPos.x = positionOffset.x + pointsData.Positions[0].x + pointsData.PositionNormals[0].x * outerOffset + pointsData.StartCapOffset.x * capOffsetAmount; tmpPos.y = positionOffset.y + pointsData.Positions[0].y + pointsData.PositionNormals[0].y * outerOffset + pointsData.StartCapOffset.y * capOffsetAmount; } vh.AddVert(tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent); for (int i = 1; i < pointsData.NumPositions - 1; i++) { uv.x = uvXMin + pointsData.NormalizedPositionDistances[i] * uvXLength; uv.y = 0.0f; { tmpPos.x = positionOffset.x + pointsData.Positions[i].x + pointsData.PositionNormals[i].x * innerOffset; tmpPos.y = positionOffset.y + pointsData.Positions[i].y + pointsData.PositionNormals[i].y * innerOffset; } vh.AddVert(tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent); uv.y = 1.0f; { tmpPos.x = positionOffset.x + pointsData.Positions[i].x + pointsData.PositionNormals[i].x * outerOffset; tmpPos.y = positionOffset.y + pointsData.Positions[i].y + pointsData.PositionNormals[i].y * outerOffset; } vh.AddVert(tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent); baseIndex = startVertex + i * 2; vh.AddTriangle(baseIndex - 1, baseIndex, baseIndex + 1); vh.AddTriangle(baseIndex, baseIndex + 2, baseIndex + 1); } // add end vertices int endIndex = pointsData.NumPositions - 1; uv.x = uvXMin + pointsData.NormalizedPositionDistances[endIndex] * uvXLength; uv.y = 0.0f; { tmpPos.x = positionOffset.x + pointsData.Positions[endIndex].x + pointsData.PositionNormals[endIndex].x * innerOffset + pointsData.EndCapOffset.x * capOffsetAmount; tmpPos.y = positionOffset.y + pointsData.Positions[endIndex].y + pointsData.PositionNormals[endIndex].y * innerOffset + pointsData.EndCapOffset.y * capOffsetAmount; } vh.AddVert(tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent); uv.y = 1.0f; { tmpPos.x = positionOffset.x + pointsData.Positions[endIndex].x + pointsData.PositionNormals[endIndex].x * outerOffset + pointsData.EndCapOffset.x * capOffsetAmount; tmpPos.y = positionOffset.y + pointsData.Positions[endIndex].y + pointsData.PositionNormals[endIndex].y * outerOffset + pointsData.EndCapOffset.y * capOffsetAmount; } vh.AddVert(tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent); baseIndex = startVertex + endIndex * 2; vh.AddTriangle(baseIndex - 1, baseIndex, baseIndex + 1); vh.AddTriangle(baseIndex, baseIndex + 2, baseIndex + 1); if (lineProperties.Closed) { uv.x = 1.0f; uv.y = 0.0f; { tmpPos.x = positionOffset.x + pointsData.Positions[0].x + pointsData.PositionNormals[0].x * innerOffset + pointsData.StartCapOffset.x * capOffsetAmount; tmpPos.y = positionOffset.y + pointsData.Positions[0].y + pointsData.PositionNormals[0].y * innerOffset + pointsData.StartCapOffset.y * capOffsetAmount; } vh.AddVert(tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent); uv.y = 1.0f; { tmpPos.x = positionOffset.x + pointsData.Positions[0].x + pointsData.PositionNormals[0].x * outerOffset + pointsData.StartCapOffset.x * capOffsetAmount; tmpPos.y = positionOffset.y + pointsData.Positions[0].y + pointsData.PositionNormals[0].y * outerOffset + pointsData.StartCapOffset.y * capOffsetAmount; } vh.AddVert(tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent); baseIndex = startVertex + endIndex * 2 + 2; vh.AddTriangle(baseIndex - 1, baseIndex, baseIndex + 1); vh.AddTriangle(baseIndex, baseIndex + 2, baseIndex + 1); } if (edgeGradientData.IsActive) { byte colorAlpha = color.a; innerOffset = outlineProperties.GetCenterDistace() - (outlineProperties.HalfLineWeight + edgeGradientData.ShadowOffset); outerOffset = outlineProperties.GetCenterDistace() + (outlineProperties.HalfLineWeight + edgeGradientData.ShadowOffset); innerOffset -= edgeGradientData.SizeAdd; outerOffset += edgeGradientData.SizeAdd; color.a = 0; int outerBaseIndex = numVertices + pointsData.NumPositions * 2; if (lineProperties.Closed) { outerBaseIndex += 2; } uv.x = uvXMin + pointsData.NormalizedPositionDistances[0] * uvXLength; uv.y = 0.0f; { tmpPos.x = positionOffset.x + pointsData.Positions[0].x + pointsData.PositionNormals[0].x * innerOffset; tmpPos.y = positionOffset.y + pointsData.Positions[0].y + pointsData.PositionNormals[0].y * innerOffset; } vh.AddVert(tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent); uv.y = 1.0f; { tmpPos.x = positionOffset.x + pointsData.Positions[0].x + pointsData.PositionNormals[0].x * outerOffset; tmpPos.y = positionOffset.y + pointsData.Positions[0].y + pointsData.PositionNormals[0].y * outerOffset; } vh.AddVert(tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent); for (int i = 1; i < pointsData.NumPositions; i++) { uv.x = uvXMin + pointsData.NormalizedPositionDistances[i] * uvXLength; uv.y = 0.0f; { tmpPos.x = positionOffset.x + pointsData.Positions[i].x + pointsData.PositionNormals[i].x * innerOffset; tmpPos.y = positionOffset.y + pointsData.Positions[i].y + pointsData.PositionNormals[i].y * innerOffset; } vh.AddVert(tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent); uv.y = 1.0f; { tmpPos.x = positionOffset.x + pointsData.Positions[i].x + pointsData.PositionNormals[i].x * outerOffset; tmpPos.y = positionOffset.y + pointsData.Positions[i].y + pointsData.PositionNormals[i].y * outerOffset; } vh.AddVert(tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent); // inner quad vh.AddTriangle(startVertex + i * 2 - 1, startVertex + i * 2 + 1, outerBaseIndex + i * 2); vh.AddTriangle(startVertex + i * 2 - 1, outerBaseIndex + i * 2, outerBaseIndex + i * 2 - 2); // outer quad vh.AddTriangle(startVertex + i * 2, outerBaseIndex + i * 2 - 1, startVertex + i * 2 + 2); vh.AddTriangle(startVertex + i * 2 + 2, outerBaseIndex + i * 2 - 1, outerBaseIndex + i * 2 + 1); } if (lineProperties.Closed) { int lastIndex = pointsData.NumPositions; uv.x = 1.0f; uv.y = 0.0f; { tmpPos.x = positionOffset.x + pointsData.Positions[0].x + pointsData.PositionNormals[0].x * innerOffset; tmpPos.y = positionOffset.y + pointsData.Positions[0].y + pointsData.PositionNormals[0].y * innerOffset; } vh.AddVert(tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent); uv.y = 1.0f; { tmpPos.x = positionOffset.x + pointsData.Positions[0].x + pointsData.PositionNormals[0].x * outerOffset; tmpPos.y = positionOffset.y + pointsData.Positions[0].y + pointsData.PositionNormals[0].y * outerOffset; } vh.AddVert(tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent); // inner quad vh.AddTriangle(startVertex + lastIndex * 2 - 1, startVertex + lastIndex * 2 + 1, outerBaseIndex + lastIndex * 2); vh.AddTriangle(startVertex + lastIndex * 2 - 1, outerBaseIndex + lastIndex * 2, outerBaseIndex + lastIndex * 2 - 2); // outer quad vh.AddTriangle(startVertex + lastIndex * 2, outerBaseIndex + lastIndex * 2 - 1, startVertex + lastIndex * 2 + 2); vh.AddTriangle(startVertex + lastIndex * 2 + 2, outerBaseIndex + lastIndex * 2 - 1, outerBaseIndex + lastIndex * 2 + 1); } color.a = colorAlpha; } // close line or add caps if (!lineProperties.Closed) { AddStartCap( ref vh, lineProperties, positionOffset, outlineProperties, color, uv, uvXMin, uvXLength, pointsData, edgeGradientData ); AddEndCap( ref vh, lineProperties, positionOffset, outlineProperties, color, uv, uvXMin, uvXLength, pointsData, edgeGradientData ); } }
public static void AddPolygon( ref VertexHelper vh, PolygonProperties polygonProperties, PointsList.PointListProperties pointListProperties, Vector2 positionOffset, Color32 color, Vector2 uv, ref PointsList.PointsData pointsData, GeoUtils.EdgeGradientData edgeGradientData ) { pointListProperties.SetPoints(); PointsList.SetLineData(pointListProperties, ref pointsData); int numVertices = vh.currentVertCount; int firstOuterVertex = vh.currentVertCount + polygonProperties.CutoutProperties.Resolution - 1; bool usesCutout = polygonProperties.CenterType == PolygonProperties.CenterTypes.Cutout; if (usesCutout) { float cutoutOffsetDistance = polygonProperties.CutoutProperties.Radius - edgeGradientData.ShadowOffset; cutoutOffsetDistance += Mathf.LerpUnclamped( pointsData.PositionNormals[0].magnitude * edgeGradientData.ShadowOffset * 3.0f, 0.0f, edgeGradientData.InnerScale ); for (int i = 0; i < polygonProperties.CutoutProperties.Resolution; i++) { tmpPos.x = polygonProperties.AdjustedCenter.x + positionOffset.x + polygonProperties.CutoutProperties.UnitPositionData.UnitPositions[i].x * cutoutOffsetDistance; tmpPos.y = polygonProperties.AdjustedCenter.y + positionOffset.y + polygonProperties.CutoutProperties.UnitPositionData.UnitPositions[i].y * cutoutOffsetDistance; tmpPos.z = 0.0f; vh.AddVert( tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent ); } } else { // add center tmpPos.x = polygonProperties.AdjustedCenter.x + positionOffset.x; tmpPos.y = polygonProperties.AdjustedCenter.y + positionOffset.y; tmpPos.z = 0.0f; vh.AddVert( tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent ); } // add first position tmpPos.x = positionOffset.x + Mathf.LerpUnclamped( polygonProperties.AdjustedCenter.x, pointsData.Positions[0].x + pointsData.PositionNormals[0].x * edgeGradientData.ShadowOffset, edgeGradientData.InnerScale ); tmpPos.y = positionOffset.y + Mathf.LerpUnclamped( polygonProperties.AdjustedCenter.y, pointsData.Positions[0].y + pointsData.PositionNormals[0].y * edgeGradientData.ShadowOffset, edgeGradientData.InnerScale ); tmpPos.z = 0.0f; vh.AddVert( tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent ); for (int i = 1; i < pointsData.NumPositions; i++) { tmpPos.x = positionOffset.x + Mathf.LerpUnclamped( polygonProperties.AdjustedCenter.x, pointsData.Positions[i].x + pointsData.PositionNormals[i].x * edgeGradientData.ShadowOffset, edgeGradientData.InnerScale ); tmpPos.y = positionOffset.y + Mathf.LerpUnclamped( polygonProperties.AdjustedCenter.y, pointsData.Positions[i].y + pointsData.PositionNormals[i].y * edgeGradientData.ShadowOffset, edgeGradientData.InnerScale ); vh.AddVert( tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent ); if (!usesCutout) { vh.AddTriangle(numVertices, numVertices + i, numVertices + i + 1); } } // add cutout indices if (usesCutout) { for (int i = 1; i < pointsData.NumPositions; i++) { vh.AddTriangle( numVertices + GeoUtils.SimpleMap(i, pointsData.NumPositions, polygonProperties.CutoutProperties.Resolution), firstOuterVertex + i, firstOuterVertex + i + 1 ); } for (int i = 1; i < polygonProperties.CutoutProperties.Resolution; i++) { vh.AddTriangle( numVertices + i, numVertices + i - 1, firstOuterVertex + Mathf.CeilToInt(GeoUtils.SimpleMap((float)i, (float)polygonProperties.CutoutProperties.Resolution, (float)pointsData.NumPositions)) ); } } // add last triangle if (usesCutout) { vh.AddTriangle( numVertices, firstOuterVertex + pointsData.NumPositions, firstOuterVertex + 1 ); vh.AddTriangle( numVertices, firstOuterVertex, firstOuterVertex + pointsData.NumPositions ); } else { vh.AddTriangle(numVertices, numVertices + pointsData.NumPositions, numVertices + 1); } if (edgeGradientData.IsActive) { color.a = 0; int outerFirstIndex = numVertices + pointsData.NumPositions; if (usesCutout) { outerFirstIndex = firstOuterVertex + pointsData.NumPositions; } else { firstOuterVertex = numVertices; } float offset = edgeGradientData.SizeAdd + edgeGradientData.ShadowOffset; vh.AddVert(positionOffset + pointsData.Positions[0] + pointsData.PositionNormals[0] * offset, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent); for (int i = 1; i < pointsData.NumPositions; i++) { vh.AddVert(positionOffset + pointsData.Positions[i] + pointsData.PositionNormals[i] * offset, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent); vh.AddTriangle(firstOuterVertex + i + 1, outerFirstIndex + i, outerFirstIndex + i + 1); vh.AddTriangle(firstOuterVertex + i + 1, outerFirstIndex + i + 1, firstOuterVertex + i + 2); } // fill last outer quad vh.AddTriangle(firstOuterVertex + 1, outerFirstIndex, outerFirstIndex + 1); vh.AddTriangle(firstOuterVertex + 2, firstOuterVertex + 1, outerFirstIndex + 1); if (usesCutout) { float radius = (polygonProperties.CutoutProperties.Radius - offset); for (int i = 0; i < polygonProperties.CutoutProperties.Resolution; i++) { tmpPos.x = polygonProperties.AdjustedCenter.x + positionOffset.x + polygonProperties.CutoutProperties.UnitPositionData.UnitPositions[i].x * radius; tmpPos.y = polygonProperties.AdjustedCenter.y + positionOffset.y + polygonProperties.CutoutProperties.UnitPositionData.UnitPositions[i].y * radius; tmpPos.z = 0.0f; vh.AddVert( tmpPos, color, uv, GeoUtils.ZeroV2, GeoUtils.UINormal, GeoUtils.UITangent ); } for (int i = 1; i < polygonProperties.CutoutProperties.Resolution; i++) { vh.AddTriangle( numVertices + i - 1, numVertices + i, outerFirstIndex + pointsData.NumPositions + i ); vh.AddTriangle( numVertices + i, outerFirstIndex + pointsData.NumPositions + i + 1, outerFirstIndex + pointsData.NumPositions + i ); } vh.AddTriangle( firstOuterVertex, numVertices, outerFirstIndex + pointsData.NumPositions + polygonProperties.CutoutProperties.Resolution ); vh.AddTriangle( numVertices, outerFirstIndex + pointsData.NumPositions + 1, outerFirstIndex + pointsData.NumPositions + polygonProperties.CutoutProperties.Resolution ); } } }