internal static void MakeText(MeshInfo meshInfo, Vector2 offset, MeshBuilder.AllocMeshData meshAlloc) { int num = MeshBuilder.LimitTextVertices(meshInfo.vertexCount, true); int num2 = num / 4; MeshWriteData meshWriteData = meshAlloc.Allocate((uint)(num2 * 4), (uint)(num2 * 6)); int i = 0; int num3 = 0; int num4 = 0; while (i < num2) { meshWriteData.SetNextVertex(MeshBuilder.ConvertTextVertexToUIRVertex(meshInfo, num3, offset)); meshWriteData.SetNextVertex(MeshBuilder.ConvertTextVertexToUIRVertex(meshInfo, num3 + 1, offset)); meshWriteData.SetNextVertex(MeshBuilder.ConvertTextVertexToUIRVertex(meshInfo, num3 + 2, offset)); meshWriteData.SetNextVertex(MeshBuilder.ConvertTextVertexToUIRVertex(meshInfo, num3 + 3, offset)); meshWriteData.SetNextIndex((ushort)num3); meshWriteData.SetNextIndex((ushort)(num3 + 1)); meshWriteData.SetNextIndex((ushort)(num3 + 2)); meshWriteData.SetNextIndex((ushort)(num3 + 2)); meshWriteData.SetNextIndex((ushort)(num3 + 3)); meshWriteData.SetNextIndex((ushort)num3); i++; num3 += 4; num4 += 6; } }
public static void TessellateBorder(MeshGenerationContextUtils.BorderParams borderParams, float posZ, MeshBuilder.AllocMeshData meshAlloc) { if (borderParams.rect.width < kEpsilon || borderParams.rect.height < kEpsilon) { return; } Profiler.BeginSample("TessellateBorder"); var halfSize = new Vector2(borderParams.rect.width * 0.5f, borderParams.rect.height * 0.5f); borderParams.topLeftRadius = Vector2.Min(borderParams.topLeftRadius, halfSize); borderParams.topRightRadius = Vector2.Min(borderParams.topRightRadius, halfSize); borderParams.bottomRightRadius = Vector2.Min(borderParams.bottomRightRadius, halfSize); borderParams.bottomLeftRadius = Vector2.Min(borderParams.bottomLeftRadius, halfSize); borderParams.leftWidth = Mathf.Min(borderParams.leftWidth, halfSize.x); borderParams.topWidth = Mathf.Min(borderParams.topWidth, halfSize.y); borderParams.rightWidth = Mathf.Min(borderParams.rightWidth, halfSize.x); borderParams.bottomWidth = Mathf.Min(borderParams.bottomWidth, halfSize.y); UInt16 vertexCount = 0, indexCount = 0; CountBorderTriangles(ref borderParams, ref vertexCount, ref indexCount); var mesh = meshAlloc.Allocate(vertexCount, indexCount); vertexCount = 0; indexCount = 0; TessellateBorderInternal(ref borderParams, posZ, mesh, ref vertexCount, ref indexCount); Debug.Assert(vertexCount == mesh.vertexCount); Debug.Assert(indexCount == mesh.indexCount); Profiler.EndSample(); }
///<summary> /// Tessellates the border OR the content: /// If any of the left/right/top/bottom border parameters is greater than Epsilon, we tessellate ONLY a border. /// Otherwise we tessellate ONLY the content. /// </summary> /// <param name="vertexFlags">Flags are only used for content, not for a border.</param> public static void TessellateRect(MeshGenerationContextUtils.RectangleParams rectParams, float posZ, MeshBuilder.AllocMeshData meshAlloc) { if (rectParams.rect.width < kEpsilon || rectParams.rect.height < kEpsilon) { return; } Profiler.BeginSample("TessellateRect"); var halfSize = new Vector2(rectParams.rect.width * 0.5f, rectParams.rect.height * 0.5f); rectParams.topLeftRadius = Vector2.Min(rectParams.topLeftRadius, halfSize); rectParams.topRightRadius = Vector2.Min(rectParams.topRightRadius, halfSize); rectParams.bottomRightRadius = Vector2.Min(rectParams.bottomRightRadius, halfSize); rectParams.bottomLeftRadius = Vector2.Min(rectParams.bottomLeftRadius, halfSize); UInt16 vertexCount = 0, indexCount = 0; CountRectTriangles(ref rectParams, ref vertexCount, ref indexCount); var mesh = meshAlloc.Allocate(vertexCount, indexCount); vertexCount = 0; indexCount = 0; TessellateRectInternal(ref rectParams, posZ, mesh, ref vertexCount, ref indexCount); if ((mesh.m_Flags == VertexFlags.IsAtlasTexturedPoint) || (mesh.m_Flags == VertexFlags.IsAtlasTexturedBilinear) || (mesh.m_Flags == VertexFlags.IsCustomTextured)) { ComputeUVs(rectParams.rect, rectParams.uv, mesh.uvRegion, mesh.m_Vertices); } Debug.Assert(vertexCount == mesh.vertexCount); Debug.Assert(indexCount == mesh.indexCount); Profiler.EndSample(); }
private static void MakeVectorGraphics9SliceBackground(Vertex[] svgVertices, ushort[] svgIndices, float svgWidth, float svgHeight, Rect targetRect, Vector4 sliceLTRB, bool stretch, Color tint, int settingIndexOffset, MeshBuilder.AllocMeshData meshAlloc) { MeshWriteData meshWriteData = meshAlloc.alloc((uint)svgVertices.Length, (uint)svgIndices.Length, ref meshAlloc); meshWriteData.SetAllIndices(svgIndices); bool flag = !stretch; if (flag) { throw new NotImplementedException("Support for repeating 9-slices is not done yet"); } MeshBuilder.s_VectorGraphics9Slice.Begin(); Rect uvRegion = meshWriteData.uvRegion; int num = svgVertices.Length; Vector2 vector = new Vector2(1f / (svgWidth - sliceLTRB.z - sliceLTRB.x), 1f / (svgHeight - sliceLTRB.w - sliceLTRB.y)); Vector2 vector2 = new Vector2(targetRect.width - svgWidth, targetRect.height - svgHeight); for (int i = 0; i < num; i++) { Vertex vertex = svgVertices[i]; Vector2 vector3; vector3.x = Mathf.Clamp01((vertex.position.x - sliceLTRB.x) * vector.x); vector3.y = Mathf.Clamp01((vertex.position.y - sliceLTRB.y) * vector.y); vertex.position.x = vertex.position.x + vector3.x * vector2.x; vertex.position.y = vertex.position.y + vector3.y * vector2.y; vertex.uv.x = vertex.uv.x * uvRegion.width + uvRegion.xMin; vertex.uv.y = vertex.uv.y * uvRegion.height + uvRegion.yMin; vertex.tint *= tint; uint num2 = (uint)(((int)vertex.opacityPageSVGSettingIndex.b << 8 | (int)vertex.opacityPageSVGSettingIndex.a) + settingIndexOffset); vertex.opacityPageSVGSettingIndex.b = (byte)(num2 >> 8); vertex.opacityPageSVGSettingIndex.a = (byte)num2; meshWriteData.SetNextVertex(vertex); } MeshBuilder.s_VectorGraphics9Slice.End(); }
internal static void MakeVectorGraphicsStretchBackground(Vertex[] svgVertices, ushort[] svgIndices, float svgWidth, float svgHeight, Rect targetRect, Rect sourceUV, ScaleMode scaleMode, Color tint, int settingIndexOffset, MeshBuilder.AllocMeshData meshAlloc, out int finalVertexCount, out int finalIndexCount) { Vector2 vector = new Vector2(svgWidth * sourceUV.width, svgHeight * sourceUV.height); Vector2 vector2 = new Vector2(sourceUV.xMin * svgWidth, sourceUV.yMin * svgHeight); Rect rect = new Rect(vector2, vector); bool flag = sourceUV.xMin != 0f || sourceUV.yMin != 0f || sourceUV.width != 1f || sourceUV.height != 1f; float num = vector.x / vector.y; float num2 = targetRect.width / targetRect.height; Vector2 vector3; Vector2 vector4; switch (scaleMode) { case ScaleMode.StretchToFill: vector3 = new Vector2(0f, 0f); vector4.x = targetRect.width / vector.x; vector4.y = targetRect.height / vector.y; break; case ScaleMode.ScaleAndCrop: { vector3 = new Vector2(0f, 0f); bool flag2 = num2 > num; if (flag2) { vector4.x = (vector4.y = targetRect.width / vector.x); float num3 = targetRect.height / vector4.y; float num4 = rect.height / 2f - num3 / 2f; vector3.y -= num4 * vector4.y; rect.y += num4; rect.height = num3; flag = true; } else { bool flag3 = num2 < num; if (flag3) { vector4.x = (vector4.y = targetRect.height / vector.y); float num5 = targetRect.width / vector4.x; float num6 = rect.width / 2f - num5 / 2f; vector3.x -= num6 * vector4.x; rect.x += num6; rect.width = num5; flag = true; } else { vector4.x = (vector4.y = targetRect.width / vector.x); } } break; } case ScaleMode.ScaleToFit: { bool flag4 = num2 > num; if (flag4) { vector4.x = (vector4.y = targetRect.height / vector.y); vector3.x = (targetRect.width - vector.x * vector4.x) * 0.5f; vector3.y = 0f; } else { vector4.x = (vector4.y = targetRect.width / vector.x); vector3.x = 0f; vector3.y = (targetRect.height - vector.y * vector4.y) * 0.5f; } break; } default: throw new NotImplementedException(); } MeshBuilder.s_VectorGraphicsStretch.Begin(); vector3 -= vector2 * vector4; int num7 = svgVertices.Length; int num8 = svgIndices.Length; MeshBuilder.ClipCounts clipCounts = default(MeshBuilder.ClipCounts); Vector4 zero = Vector4.zero; bool flag5 = flag; if (flag5) { bool flag6 = rect.width <= 0f || rect.height <= 0f; if (flag6) { finalVertexCount = (finalIndexCount = 0); MeshBuilder.s_VectorGraphicsStretch.End(); return; } zero = new Vector4(rect.xMin, rect.yMin, rect.xMax, rect.yMax); clipCounts = MeshBuilder.UpperBoundApproximateRectClippingResults(svgVertices, svgIndices, zero); num7 += clipCounts.clippedTriangles * 6; num8 += clipCounts.addedTriangles * 3; num8 -= clipCounts.degenerateTriangles * 3; } MeshWriteData meshWriteData = meshAlloc.alloc((uint)num7, (uint)num8, ref meshAlloc); bool flag7 = flag; if (flag7) { MeshBuilder.RectClip(svgVertices, svgIndices, zero, meshWriteData, clipCounts, ref num7); } else { meshWriteData.SetAllIndices(svgIndices); } Debug.Assert(meshWriteData.currentVertex == 0); Rect uvRegion = meshWriteData.uvRegion; int num9 = svgVertices.Length; for (int i = 0; i < num9; i++) { Vertex vertex = svgVertices[i]; vertex.position.x = vertex.position.x * vector4.x + vector3.x; vertex.position.y = vertex.position.y * vector4.y + vector3.y; vertex.uv.x = vertex.uv.x * uvRegion.width + uvRegion.xMin; vertex.uv.y = vertex.uv.y * uvRegion.height + uvRegion.yMin; vertex.tint *= tint; uint num10 = (uint)(((int)vertex.opacityPageSVGSettingIndex.b << 8 | (int)vertex.opacityPageSVGSettingIndex.a) + settingIndexOffset); vertex.opacityPageSVGSettingIndex.b = (byte)(num10 >> 8); vertex.opacityPageSVGSettingIndex.a = (byte)num10; meshWriteData.SetNextVertex(vertex); } for (int j = num9; j < num7; j++) { Vertex vertex2 = meshWriteData.m_Vertices[j]; vertex2.position.x = vertex2.position.x * vector4.x + vector3.x; vertex2.position.y = vertex2.position.y * vector4.y + vector3.y; vertex2.uv.x = vertex2.uv.x * uvRegion.width + uvRegion.xMin; vertex2.uv.y = vertex2.uv.y * uvRegion.height + uvRegion.yMin; vertex2.tint *= tint; uint num11 = (uint)(((int)vertex2.opacityPageSVGSettingIndex.b << 8 | (int)vertex2.opacityPageSVGSettingIndex.a) + settingIndexOffset); vertex2.opacityPageSVGSettingIndex.b = (byte)(num11 >> 8); vertex2.opacityPageSVGSettingIndex.a = (byte)num11; meshWriteData.SetNextVertex(vertex2); } finalVertexCount = meshWriteData.vertexCount; finalIndexCount = meshWriteData.indexCount; MeshBuilder.s_VectorGraphicsStretch.End(); }
internal static void MakeVectorGraphics(MeshGenerationContextUtils.RectangleParams rectParams, int settingIndexOffset, MeshBuilder.AllocMeshData meshAlloc, out int finalVertexCount, out int finalIndexCount) { VectorImage vectorImage = rectParams.vectorImage; Debug.Assert(vectorImage != null); finalVertexCount = 0; finalIndexCount = 0; int num = vectorImage.vertices.Length; Vertex[] array = new Vertex[num]; for (int i = 0; i < num; i++) { VectorImageVertex vectorImageVertex = vectorImage.vertices[i]; array[i] = new Vertex { position = vectorImageVertex.position, tint = vectorImageVertex.tint, uv = vectorImageVertex.uv, opacityPageSVGSettingIndex = new Color32(0, 0, (byte)(vectorImageVertex.settingIndex >> 8), (byte)vectorImageVertex.settingIndex) }; } bool flag = (float)rectParams.leftSlice <= Mathf.Epsilon && (float)rectParams.topSlice <= Mathf.Epsilon && (float)rectParams.rightSlice <= Mathf.Epsilon && (float)rectParams.bottomSlice <= Mathf.Epsilon; if (flag) { MeshBuilder.MakeVectorGraphicsStretchBackground(array, vectorImage.indices, vectorImage.size.x, vectorImage.size.y, rectParams.rect, rectParams.uv, rectParams.scaleMode, rectParams.color, settingIndexOffset, meshAlloc, out finalVertexCount, out finalIndexCount); } else { Vector4 sliceLTRB = new Vector4((float)rectParams.leftSlice, (float)rectParams.topSlice, (float)rectParams.rightSlice, (float)rectParams.bottomSlice); MeshBuilder.MakeVectorGraphics9SliceBackground(array, vectorImage.indices, vectorImage.size.x, vectorImage.size.y, rectParams.rect, sliceLTRB, true, rectParams.color, settingIndexOffset, meshAlloc); } }
internal static void MakeSlicedQuad(ref MeshGenerationContextUtils.RectangleParams rectParams, float posZ, MeshBuilder.AllocMeshData meshAlloc) { MeshWriteData meshWriteData = meshAlloc.Allocate(16u, 54u); float num = 1f; Texture2D texture2D = rectParams.texture as Texture2D; bool flag = texture2D != null; if (flag) { num = texture2D.pixelsPerPoint; } float num2 = (float)rectParams.texture.width; float num3 = (float)rectParams.texture.height; float num4 = num / num2; float num5 = num / num3; float num6 = Mathf.Max(0f, (float)rectParams.leftSlice); float num7 = Mathf.Max(0f, (float)rectParams.rightSlice); float num8 = Mathf.Max(0f, (float)rectParams.bottomSlice); float num9 = Mathf.Max(0f, (float)rectParams.topSlice); float num10 = Mathf.Clamp(num6 * num4, 0f, 1f); float num11 = Mathf.Clamp(num7 * num4, 0f, 1f); float num12 = Mathf.Clamp(num8 * num5, 0f, 1f); float num13 = Mathf.Clamp(num9 * num5, 0f, 1f); MeshBuilder.k_TexCoordSlicesX[0] = rectParams.uv.min.x; MeshBuilder.k_TexCoordSlicesX[1] = rectParams.uv.min.x + num10; MeshBuilder.k_TexCoordSlicesX[2] = rectParams.uv.max.x - num11; MeshBuilder.k_TexCoordSlicesX[3] = rectParams.uv.max.x; MeshBuilder.k_TexCoordSlicesY[0] = rectParams.uv.max.y; MeshBuilder.k_TexCoordSlicesY[1] = rectParams.uv.max.y - num12; MeshBuilder.k_TexCoordSlicesY[2] = rectParams.uv.min.y + num13; MeshBuilder.k_TexCoordSlicesY[3] = rectParams.uv.min.y; Rect uvRegion = meshWriteData.uvRegion; for (int i = 0; i < 4; i++) { MeshBuilder.k_TexCoordSlicesX[i] = MeshBuilder.k_TexCoordSlicesX[i] * uvRegion.width + uvRegion.xMin; MeshBuilder.k_TexCoordSlicesY[i] = (rectParams.uv.min.y + rectParams.uv.max.y - MeshBuilder.k_TexCoordSlicesY[i]) * uvRegion.height + uvRegion.yMin; } float num14 = num6 + num7; bool flag2 = num14 > rectParams.rect.width; if (flag2) { float num15 = rectParams.rect.width / num14; num6 *= num15; num7 *= num15; } float num16 = num8 + num9; bool flag3 = num16 > rectParams.rect.height; if (flag3) { float num17 = rectParams.rect.height / num16; num8 *= num17; num9 *= num17; } MeshBuilder.k_PositionSlicesX[0] = rectParams.rect.x; MeshBuilder.k_PositionSlicesX[1] = rectParams.rect.x + num6; MeshBuilder.k_PositionSlicesX[2] = rectParams.rect.xMax - num7; MeshBuilder.k_PositionSlicesX[3] = rectParams.rect.xMax; MeshBuilder.k_PositionSlicesY[0] = rectParams.rect.yMax; MeshBuilder.k_PositionSlicesY[1] = rectParams.rect.yMax - num8; MeshBuilder.k_PositionSlicesY[2] = rectParams.rect.y + num9; MeshBuilder.k_PositionSlicesY[3] = rectParams.rect.y; for (int j = 0; j < 16; j++) { int num18 = j % 4; int num19 = j / 4; meshWriteData.SetNextVertex(new Vertex { position = new Vector3(MeshBuilder.k_PositionSlicesX[num18], MeshBuilder.k_PositionSlicesY[num19], posZ), uv = new Vector2(MeshBuilder.k_TexCoordSlicesX[num18], MeshBuilder.k_TexCoordSlicesY[num19]), tint = rectParams.color }); } meshWriteData.SetAllIndices(MeshBuilder.slicedQuadIndices); }
private static void MakeQuad(Rect rcPosition, Rect rcTexCoord, Color color, float posZ, MeshBuilder.AllocMeshData meshAlloc) { MeshWriteData meshWriteData = meshAlloc.Allocate(4u, 6u); float x = rcPosition.x; float xMax = rcPosition.xMax; float yMax = rcPosition.yMax; float y = rcPosition.y; Rect uvRegion = meshWriteData.uvRegion; float x2 = rcTexCoord.x * uvRegion.width + uvRegion.xMin; float x3 = rcTexCoord.xMax * uvRegion.width + uvRegion.xMin; float y2 = rcTexCoord.y * uvRegion.height + uvRegion.yMin; float y3 = rcTexCoord.yMax * uvRegion.height + uvRegion.yMin; meshWriteData.SetNextVertex(new Vertex { position = new Vector3(x, yMax, posZ), tint = color, uv = new Vector2(x2, y2) }); meshWriteData.SetNextVertex(new Vertex { position = new Vector3(xMax, yMax, posZ), tint = color, uv = new Vector2(x3, y2) }); meshWriteData.SetNextVertex(new Vertex { position = new Vector3(x, y, posZ), tint = color, uv = new Vector2(x2, y3) }); meshWriteData.SetNextVertex(new Vertex { position = new Vector3(xMax, y, posZ), tint = color, uv = new Vector2(x3, y3) }); meshWriteData.SetNextIndex(0); meshWriteData.SetNextIndex(2); meshWriteData.SetNextIndex(1); meshWriteData.SetNextIndex(1); meshWriteData.SetNextIndex(2); meshWriteData.SetNextIndex(3); }
internal static void MakeText(NativeArray <UnityEngine.UIElements.TextVertex> uiVertices, Vector2 offset, MeshBuilder.AllocMeshData meshAlloc) { int num = MeshBuilder.LimitTextVertices(uiVertices.Length, true); int num2 = num / 4; MeshWriteData meshWriteData = meshAlloc.Allocate((uint)(num2 * 4), (uint)(num2 * 6)); int i = 0; int num3 = 0; while (i < num2) { meshWriteData.SetNextVertex(MeshBuilder.ConvertTextVertexToUIRVertex(uiVertices[num3], offset)); meshWriteData.SetNextVertex(MeshBuilder.ConvertTextVertexToUIRVertex(uiVertices[num3 + 1], offset)); meshWriteData.SetNextVertex(MeshBuilder.ConvertTextVertexToUIRVertex(uiVertices[num3 + 2], offset)); meshWriteData.SetNextVertex(MeshBuilder.ConvertTextVertexToUIRVertex(uiVertices[num3 + 3], offset)); meshWriteData.SetNextIndex((ushort)num3); meshWriteData.SetNextIndex((ushort)(num3 + 1)); meshWriteData.SetNextIndex((ushort)(num3 + 2)); meshWriteData.SetNextIndex((ushort)(num3 + 2)); meshWriteData.SetNextIndex((ushort)(num3 + 3)); meshWriteData.SetNextIndex((ushort)num3); i++; num3 += 4; } }
internal static void MakeTexturedRect(MeshGenerationContextUtils.RectangleParams rectParams, float posZ, MeshBuilder.AllocMeshData meshAlloc) { bool flag = (float)rectParams.leftSlice <= Mathf.Epsilon && (float)rectParams.topSlice <= Mathf.Epsilon && (float)rectParams.rightSlice <= Mathf.Epsilon && (float)rectParams.bottomSlice <= Mathf.Epsilon; if (flag) { bool flag2 = !rectParams.HasRadius(Tessellation.kEpsilon); if (flag2) { MeshBuilder.MakeQuad(rectParams.rect, rectParams.uv, rectParams.color, posZ, meshAlloc); } else { Tessellation.TessellateRect(rectParams, posZ, meshAlloc, true); } } else { bool flag3 = rectParams.texture == null; if (flag3) { MeshBuilder.MakeQuad(rectParams.rect, rectParams.uv, rectParams.color, posZ, meshAlloc); } else { MeshBuilder.MakeSlicedQuad(ref rectParams, posZ, meshAlloc); } } }
internal static void MakeSolidRect(MeshGenerationContextUtils.RectangleParams rectParams, float posZ, MeshBuilder.AllocMeshData meshAlloc) { bool flag = !rectParams.HasRadius(Tessellation.kEpsilon); if (flag) { MeshBuilder.MakeQuad(rectParams.rect, Rect.zero, rectParams.color, posZ, meshAlloc); } else { Tessellation.TessellateRect(rectParams, posZ, meshAlloc, false); } }
internal static void MakeBorder(MeshGenerationContextUtils.BorderParams borderParams, float posZ, MeshBuilder.AllocMeshData meshAlloc) { Tessellation.TessellateBorder(borderParams, posZ, meshAlloc); }