private static void TessellateRectInternal(ref MeshGenerationContextUtils.RectangleParams rectParams, float posZ, VertexFlags vertexFlags, NativeSlice <Vertex>?vertices, NativeSlice <UInt16>?indices, ref UInt16 vertexCount, ref UInt16 indexCount, bool countOnly = false) { if (!rectParams.HasRadius(kEpsilon)) { UInt16 indexOffset = 0; TessellateQuad(rectParams.rect, TessellationType.Content, rectParams.color, posZ, vertexFlags, vertices, indices, ref indexOffset, ref vertexCount, ref indexCount, countOnly); } else { TessellateRoundedCorners(ref rectParams, posZ, vertexFlags, vertices, indices, ref vertexCount, ref indexCount, countOnly); } }
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); } }
public void DrawVisualElementBackground() { bool flag = this.currentElement.layout.width <= Mathf.Epsilon || this.currentElement.layout.height <= Mathf.Epsilon; if (!flag) { ComputedStyle computedStyle = this.currentElement.computedStyle; bool flag2 = computedStyle.backgroundColor != Color.clear; if (flag2) { MeshGenerationContextUtils.RectangleParams rectParams = new MeshGenerationContextUtils.RectangleParams { rect = GUIUtility.AlignRectToDevice(this.currentElement.rect), color = computedStyle.backgroundColor.value, playmodeTintColor = ((this.currentElement.panel.contextType == ContextType.Editor) ? UIElementsUtility.editorPlayModeTintColor : Color.white) }; MeshGenerationContextUtils.GetVisualElementRadii(this.currentElement, out rectParams.topLeftRadius, out rectParams.bottomLeftRadius, out rectParams.topRightRadius, out rectParams.bottomRightRadius); this.DrawRectangle(rectParams); } Background value = computedStyle.backgroundImage.value; bool flag3 = value.texture != null || value.vectorImage != null; if (flag3) { MeshGenerationContextUtils.RectangleParams rectParams2 = default(MeshGenerationContextUtils.RectangleParams); bool flag4 = value.texture != null; if (flag4) { rectParams2 = MeshGenerationContextUtils.RectangleParams.MakeTextured(GUIUtility.AlignRectToDevice(this.currentElement.rect), new Rect(0f, 0f, 1f, 1f), value.texture, computedStyle.unityBackgroundScaleMode.value, this.currentElement.panel.contextType); } else { bool flag5 = value.vectorImage != null; if (flag5) { rectParams2 = MeshGenerationContextUtils.RectangleParams.MakeVectorTextured(GUIUtility.AlignRectToDevice(this.currentElement.rect), new Rect(0f, 0f, 1f, 1f), value.vectorImage, computedStyle.unityBackgroundScaleMode.value, this.currentElement.panel.contextType); } } MeshGenerationContextUtils.GetVisualElementRadii(this.currentElement, out rectParams2.topLeftRadius, out rectParams2.bottomLeftRadius, out rectParams2.topRightRadius, out rectParams2.bottomRightRadius); rectParams2.leftSlice = computedStyle.unitySliceLeft.value; rectParams2.topSlice = computedStyle.unitySliceTop.value; rectParams2.rightSlice = computedStyle.unitySliceRight.value; rectParams2.bottomSlice = computedStyle.unitySliceBottom.value; bool flag6 = computedStyle.unityBackgroundImageTintColor != Color.clear; if (flag6) { rectParams2.color = computedStyle.unityBackgroundImageTintColor.value; } this.DrawRectangle(rectParams2); } } }
private static void TessellateRoundedCorners(ref MeshGenerationContextUtils.RectangleParams rectParams, float posZ, MeshWriteData mesh, ref UInt16 vertexCount, ref UInt16 indexCount, bool countOnly) { // To tessellate the 4 corners, the rect is divided in 4 quadrants and every quadrant is computed as if they were the top-left corner. // The quadrants are then mirrored and the triangles winding flipped as necessary. UInt16 indexOffset = 0; UInt16 startVc = 0, startIc = 0; var halfSize = new Vector2(rectParams.rect.width * 0.5f, rectParams.rect.height * 0.5f); var quarterRect = new Rect(rectParams.rect.x, rectParams.rect.y, halfSize.x, halfSize.y); // Top-left TessellateRoundedCorner(quarterRect, rectParams.color, posZ, rectParams.topLeftRadius, mesh, ref indexOffset, ref vertexCount, ref indexCount, countOnly); // Top-right startVc = vertexCount; startIc = indexCount; TessellateRoundedCorner(quarterRect, rectParams.color, posZ, rectParams.topRightRadius, mesh, ref indexOffset, ref vertexCount, ref indexCount, countOnly); if (!countOnly) { MirrorVertices(quarterRect, mesh.m_Vertices, startVc, vertexCount - startVc, true); FlipWinding(mesh.m_Indices, startIc, indexCount - startIc); } // Bottom-right startVc = vertexCount; startIc = indexCount; TessellateRoundedCorner(quarterRect, rectParams.color, posZ, rectParams.bottomRightRadius, mesh, ref indexOffset, ref vertexCount, ref indexCount, countOnly); if (!countOnly) { MirrorVertices(quarterRect, mesh.m_Vertices, startVc, vertexCount - startVc, true); MirrorVertices(quarterRect, mesh.m_Vertices, startVc, vertexCount - startVc, false); } // Bottom-left startVc = vertexCount; startIc = indexCount; TessellateRoundedCorner(quarterRect, rectParams.color, posZ, rectParams.bottomLeftRadius, mesh, ref indexOffset, ref vertexCount, ref indexCount, countOnly); if (!countOnly) { MirrorVertices(quarterRect, mesh.m_Vertices, startVc, vertexCount - startVc, false); FlipWinding(mesh.m_Indices, startIc, indexCount - startIc); } }
internal static void MakeVectorGraphics(MeshGenerationContextUtils.RectangleParams rectParams, int settingIndexOffset, AllocMeshData meshAlloc, out int finalVertexCount, out int finalIndexCount) { var vi = rectParams.vectorImage; Debug.Assert(vi != null); finalVertexCount = 0; finalIndexCount = 0; if (rectParams.leftSlice <= Mathf.Epsilon && rectParams.topSlice <= Mathf.Epsilon && rectParams.rightSlice <= Mathf.Epsilon && rectParams.bottomSlice <= Mathf.Epsilon) { MeshBuilder.MakeVectorGraphicsStretchBackground(vi.vertices, vi.indices, vi.size.x, vi.size.y, rectParams.rect, rectParams.uv, rectParams.scaleMode, rectParams.color, settingIndexOffset, meshAlloc, out finalVertexCount, out finalIndexCount); } else { var sliceLTRB = new Vector4(rectParams.leftSlice, rectParams.topSlice, rectParams.rightSlice, rectParams.bottomSlice); MeshBuilder.MakeVectorGraphics9SliceBackground(vi.vertices, vi.indices, vi.size.x, vi.size.y, rectParams.rect, sliceLTRB, true, rectParams.color, settingIndexOffset, meshAlloc); } }
internal static void MakeVectorGraphics(MeshGenerationContextUtils.RectangleParams rectParams, int settingIndexOffset, AllocMeshData meshAlloc, out int finalVertexCount, out int finalIndexCount) { var vi = rectParams.vectorImage; Debug.Assert(vi != null); finalVertexCount = 0; finalIndexCount = 0; // Convert the VectorImage's serializable vertices to Vertex instances int vertexCount = vi.vertices.Length; var vertices = new Vertex[vertexCount]; for (int i = 0; i < vertexCount; ++i) { var v = vi.vertices[i]; vertices[i] = new Vertex() { position = v.position, tint = v.tint, uv = v.uv, opacityPageSVGSettingIndex = new Color32(0, 0, (byte)(v.settingIndex >> 8), (byte)v.settingIndex) }; } if (rectParams.leftSlice <= Mathf.Epsilon && rectParams.topSlice <= Mathf.Epsilon && rectParams.rightSlice <= Mathf.Epsilon && rectParams.bottomSlice <= Mathf.Epsilon) { MeshBuilder.MakeVectorGraphicsStretchBackground(vertices, vi.indices, vi.size.x, vi.size.y, rectParams.rect, rectParams.uv, rectParams.scaleMode, rectParams.color, settingIndexOffset, meshAlloc, out finalVertexCount, out finalIndexCount); } else { var sliceLTRB = new Vector4(rectParams.leftSlice, rectParams.topSlice, rectParams.rightSlice, rectParams.bottomSlice); MeshBuilder.MakeVectorGraphics9SliceBackground(vertices, vi.indices, vi.size.x, vi.size.y, rectParams.rect, sliceLTRB, true, rectParams.color, settingIndexOffset, meshAlloc); } }
private static void CountRectTriangles(ref MeshGenerationContextUtils.RectangleParams rectParams, ref UInt16 vertexCount, ref UInt16 indexCount) { // To count the required triangles, we call the tessellation method with a "countOnly=true" flag, which skips // tessellation and only update the vertex and index counts. TessellateRectInternal(ref rectParams, 0, null, ref vertexCount, ref indexCount, true); }
internal static void MakeSlicedQuad(ref MeshGenerationContextUtils.RectangleParams rectParams, float posZ, AllocMeshData meshAlloc) { var mesh = meshAlloc.Allocate(16, 9 * 6); float pixelsPerPoint = 1; var texture2D = rectParams.texture as Texture2D; if (texture2D != null) { pixelsPerPoint = texture2D.pixelsPerPoint; } float texWidth = rectParams.texture.width; float texHeight = rectParams.texture.height; float uConversion = pixelsPerPoint / texWidth; float vConversion = pixelsPerPoint / texHeight; float leftSlice = Mathf.Max(0.0f, rectParams.leftSlice); float rightSlice = Mathf.Max(0.0f, rectParams.rightSlice); float bottomSlice = Mathf.Max(0.0f, rectParams.bottomSlice); float topSlice = Mathf.Max(0.0f, rectParams.topSlice); // Clamp UVs in the [0,1] range float uvLeftSlice = Mathf.Clamp(leftSlice * uConversion, 0.0f, 1.0f); float uvRightSlice = Mathf.Clamp(rightSlice * uConversion, 0.0f, 1.0f); float uvBottomSlice = Mathf.Clamp(bottomSlice * vConversion, 0.0f, 1.0f); float uvTopslice = Mathf.Clamp(topSlice * vConversion, 0.0f, 1.0f); k_TexCoordSlicesX[0] = rectParams.uv.min.x; k_TexCoordSlicesX[1] = rectParams.uv.min.x + uvLeftSlice; k_TexCoordSlicesX[2] = rectParams.uv.max.x - uvRightSlice; k_TexCoordSlicesX[3] = rectParams.uv.max.x; k_TexCoordSlicesY[0] = rectParams.uv.max.y; k_TexCoordSlicesY[1] = rectParams.uv.max.y - uvBottomSlice; k_TexCoordSlicesY[2] = rectParams.uv.min.y + uvTopslice; k_TexCoordSlicesY[3] = rectParams.uv.min.y; var uvRegion = mesh.uvRegion; for (int i = 0; i < 4; i++) { k_TexCoordSlicesX[i] = k_TexCoordSlicesX[i] * uvRegion.width + uvRegion.xMin; k_TexCoordSlicesY[i] = (rectParams.uv.min.y + rectParams.uv.max.y - k_TexCoordSlicesY[i]) * uvRegion.height + uvRegion.yMin; } // Prevent overlapping slices float sliceWidth = (leftSlice + rightSlice); if (sliceWidth > rectParams.rect.width) { float rescale = rectParams.rect.width / sliceWidth; leftSlice *= rescale; rightSlice *= rescale; } float sliceHeight = (bottomSlice + topSlice); if (sliceHeight > rectParams.rect.height) { float rescale = rectParams.rect.height / sliceHeight; bottomSlice *= rescale; topSlice *= rescale; } k_PositionSlicesX[0] = rectParams.rect.x; k_PositionSlicesX[1] = rectParams.rect.x + leftSlice; k_PositionSlicesX[2] = rectParams.rect.xMax - rightSlice; k_PositionSlicesX[3] = rectParams.rect.xMax; k_PositionSlicesY[0] = rectParams.rect.yMax; k_PositionSlicesY[1] = rectParams.rect.yMax - bottomSlice; k_PositionSlicesY[2] = rectParams.rect.y + topSlice; k_PositionSlicesY[3] = rectParams.rect.y; for (int i = 0; i < 16; ++i) { int x = i % 4; int y = i / 4; mesh.SetNextVertex(new Vertex() { position = new Vector3(k_PositionSlicesX[x], k_PositionSlicesY[y], posZ), uv = new Vector2(k_TexCoordSlicesX[x], k_TexCoordSlicesY[y]), tint = rectParams.color }); } mesh.SetAllIndices(slicedQuadIndices); }
public void DrawRectangle(MeshGenerationContextUtils.RectangleParams rectParams) { }
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); }