예제 #1
0
        internal static void MakeText(TextCore.MeshInfo meshInfo, Vector2 offset, AllocMeshData meshAlloc)
        {
            int vertexCount = LimitTextVertices(meshInfo.vertexCount);
            int quadCount   = vertexCount / 4;
            var mesh        = meshAlloc.Allocate((uint)(quadCount * 4), (uint)(quadCount * 6));

            for (int q = 0, v = 0, i = 0; q < quadCount; ++q, v += 4, i += 6)
            {
                mesh.SetNextVertex(ConvertTextVertexToUIRVertex(meshInfo, v + 0, offset));
                mesh.SetNextVertex(ConvertTextVertexToUIRVertex(meshInfo, v + 1, offset));
                mesh.SetNextVertex(ConvertTextVertexToUIRVertex(meshInfo, v + 2, offset));
                mesh.SetNextVertex(ConvertTextVertexToUIRVertex(meshInfo, v + 3, offset));

                mesh.SetNextIndex((UInt16)(v + 0));
                mesh.SetNextIndex((UInt16)(v + 1));
                mesh.SetNextIndex((UInt16)(v + 2));
                mesh.SetNextIndex((UInt16)(v + 2));
                mesh.SetNextIndex((UInt16)(v + 3));
                mesh.SetNextIndex((UInt16)(v + 0));
            }
        }
예제 #2
0
 internal static void MakeSolidRect(MeshGenerationContextUtils.RectangleParams rectParams, float posZ, AllocMeshData meshAlloc)
 {
     if (!rectParams.HasRadius(Tessellation.kEpsilon))
     {
         MakeQuad(rectParams.rect, Rect.zero, rectParams.color, posZ, meshAlloc);
     }
     else
     {
         Tessellation.TessellateRect(rectParams, posZ, meshAlloc, false);
     }
 }
예제 #3
0
        internal static void MakeVectorGraphicsStretchBackground(Vertex[] svgVertices, UInt16[] svgIndices, float svgWidth, float svgHeight, Rect targetRect, Rect sourceUV, ScaleMode scaleMode, Color tint, int settingIndexOffset, AllocMeshData meshAlloc, out int finalVertexCount, out int finalIndexCount)
        {
            // Determine position offset and scale according to scale mode
            Vector2 svgSubRectSize   = new Vector2(svgWidth * sourceUV.width, svgHeight * sourceUV.height);
            Vector2 svgSubRectOffset = new Vector2(sourceUV.xMin * svgWidth, sourceUV.yMin * svgHeight);
            Rect    svgSubRect       = new Rect(svgSubRectOffset, svgSubRectSize);

            bool    isSubRect = sourceUV.xMin != 0 || sourceUV.yMin != 0 || sourceUV.width != 1 || sourceUV.height != 1;
            float   srcAspect = svgSubRectSize.x / svgSubRectSize.y;
            float   destAspect = targetRect.width / targetRect.height;
            Vector2 posOffset, posScale;

            switch (scaleMode)
            {
            case ScaleMode.StretchToFill:
                posOffset  = new Vector2(0, 0);
                posScale.x = targetRect.width / svgSubRectSize.x;
                posScale.y = targetRect.height / svgSubRectSize.y;
                break;

            case ScaleMode.ScaleAndCrop:
                // ScaleAndCrop keeps the content centered to follow the same behavior as textures
                posOffset = new Vector2(0, 0);
                if (destAspect > srcAspect)
                {
                    // Fill on x and crop top/bottom sides
                    posScale.x = posScale.y = targetRect.width / svgSubRectSize.x;
                    var   height = targetRect.height / posScale.y;
                    float offset = svgSubRect.height / 2.0f - height / 2.0f;
                    posOffset.y      -= offset * posScale.y;
                    svgSubRect.y     += offset;
                    svgSubRect.height = height;
                    isSubRect         = true;
                }
                else if (destAspect < srcAspect)
                {
                    // Fill on y and crop left/right sides
                    posScale.x = posScale.y = targetRect.height / svgSubRectSize.y;
                    var   width  = targetRect.width / posScale.x;
                    float offset = svgSubRect.width / 2.0f - width / 2.0f;
                    posOffset.x     -= offset * posScale.x;
                    svgSubRect.x    += offset;
                    svgSubRect.width = width;
                    isSubRect        = true;
                }
                else
                {
                    posScale.x = posScale.y = targetRect.width / svgSubRectSize.x;      // Just scale, cropping is not involved
                }
                break;

            case ScaleMode.ScaleToFit:
                if (destAspect > srcAspect)
                {
                    // Fill on y and offset on x
                    posScale.x  = posScale.y = targetRect.height / svgSubRectSize.y;
                    posOffset.x = (targetRect.width - svgSubRectSize.x * posScale.x) * 0.5f;
                    posOffset.y = 0;
                }
                else
                {
                    // Fill on x and offset on y
                    posScale.x  = posScale.y = targetRect.width / svgSubRectSize.x;
                    posOffset.x = 0;
                    posOffset.y = (targetRect.height - svgSubRectSize.y * posScale.y) * 0.5f;
                }
                break;

            default:
                throw new NotImplementedException();
            }

            s_VectorGraphicsStretch.Begin();

            posOffset -= svgSubRectOffset * posScale;

            int        newVertexCount   = svgVertices.Length;
            int        newIndexCount    = svgIndices.Length;
            ClipCounts cc               = new ClipCounts();
            Vector4    svgSubRectMinMax = Vector4.zero;

            if (isSubRect)
            {
                if (svgSubRect.width <= 0 || svgSubRect.height <= 0)
                {
                    finalVertexCount = finalIndexCount = 0;
                    s_VectorGraphicsStretch.End();
                    return; // Totally clipped
                }
                svgSubRectMinMax = new Vector4(svgSubRect.xMin, svgSubRect.yMin, svgSubRect.xMax, svgSubRect.yMax);
                cc = UpperBoundApproximateRectClippingResults(svgVertices, svgIndices, svgSubRectMinMax);

                // We never kill vertices, just triangles.. so the clipper will only cause growth in the vertex count
                newVertexCount += cc.clippedTriangles * 6;    // 6 new vertices per clipped triangle
                newIndexCount  += cc.addedTriangles * 3;
                newIndexCount  -= cc.degenerateTriangles * 3; // We will not add the indices of degenerate triangles, so discount them
            }

            var mwd = meshAlloc.alloc((uint)newVertexCount, (uint)newIndexCount, ref meshAlloc);

            // Copy indices straight. If clipping is involved, perform clipping. This will fill all the indices
            // as well as register some new vertices at the end of the original set of vertices
            if (isSubRect)
            {
                RectClip(svgVertices, svgIndices, svgSubRectMinMax, mwd, cc, ref newVertexCount);
            }
            else
            {
                mwd.SetAllIndices(svgIndices);
            }

            // Transform all original vertices, vertices generated by clipping will use those directly
            var uvRegion   = mwd.uvRegion;
            int vertsCount = svgVertices.Length;

            for (int i = 0; i < vertsCount; i++)
            {
                var v = svgVertices[i];
                v.position.x = v.position.x * posScale.x + posOffset.x;
                v.position.y = v.position.y * posScale.y + posOffset.y;
                v.uv.x       = v.uv.x * uvRegion.width + uvRegion.xMin;
                v.uv.y       = v.uv.y * uvRegion.height + uvRegion.yMin;
                v.tint      *= tint;
                uint settingIndex = (uint)(((v.opacityPageSVGSettingIndex.b << 8) | v.opacityPageSVGSettingIndex.a) + settingIndexOffset);
                v.opacityPageSVGSettingIndex.b = (byte)(settingIndex >> 8);
                v.opacityPageSVGSettingIndex.a = (byte)settingIndex;
                mwd.SetNextVertex(v);
            }

            // Transform newely generated vertices as well (if any)
            for (int i = vertsCount; i < newVertexCount; i++)
            {
                var v = mwd.m_Vertices[i];
                v.position.x = v.position.x * posScale.x + posOffset.x;
                v.position.y = v.position.y * posScale.y + posOffset.y;
                v.uv.x       = v.uv.x * uvRegion.width + uvRegion.xMin;
                v.uv.y       = v.uv.y * uvRegion.height + uvRegion.yMin;
                v.tint      *= tint;
                uint settingIndex = (uint)(((v.opacityPageSVGSettingIndex.b << 8) | v.opacityPageSVGSettingIndex.a) + settingIndexOffset);
                v.opacityPageSVGSettingIndex.b = (byte)(settingIndex >> 8);
                v.opacityPageSVGSettingIndex.a = (byte)settingIndex;
                mwd.m_Vertices[i] = v;
            }

            finalVertexCount = mwd.vertexCount;
            finalIndexCount  = mwd.indexCount;

            s_VectorGraphicsStretch.End();
        }
예제 #4
0
 internal static void MakeBorder(MeshGenerationContextUtils.BorderParams borderParams, float posZ, AllocMeshData meshAlloc)
 {
     Tessellation.TessellateBorder(borderParams, posZ, meshAlloc);
 }
예제 #5
0
        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);
            }
        }
예제 #6
0
        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);
        }
예제 #7
0
        private static void MakeQuad(Rect rcPosition, Rect rcTexCoord, Color color, float posZ, AllocMeshData meshAlloc)
        {
            var mesh = meshAlloc.Allocate(4, 6);

            float x0 = rcPosition.x;
            float x3 = rcPosition.xMax;
            float y0 = rcPosition.yMax;
            float y3 = rcPosition.y;

            var   uvRegion = mesh.uvRegion;
            float u0       = rcTexCoord.x * uvRegion.width + uvRegion.xMin;
            float u3       = rcTexCoord.xMax * uvRegion.width + uvRegion.xMin;
            float v0       = rcTexCoord.y * uvRegion.height + uvRegion.yMin;
            float v3       = rcTexCoord.yMax * uvRegion.height + uvRegion.yMin;

            mesh.SetNextVertex(new Vertex()
            {
                position = new Vector3(x0, y0, posZ),
                tint     = color,
                uv       = new Vector2(u0, v0)
            });
            mesh.SetNextVertex(new Vertex()
            {
                position = new Vector3(x3, y0, posZ),
                tint     = color,
                uv       = new Vector2(u3, v0)
            });
            mesh.SetNextVertex(new Vertex()
            {
                position = new Vector3(x0, y3, posZ),
                tint     = color,
                uv       = new Vector2(u0, v3)
            });
            mesh.SetNextVertex(new Vertex()
            {
                position = new Vector3(x3, y3, posZ),
                tint     = color,
                uv       = new Vector2(u3, v3)
            });

            mesh.SetNextIndex(0);
            mesh.SetNextIndex(1);
            mesh.SetNextIndex(2);

            mesh.SetNextIndex(1);
            mesh.SetNextIndex(3);
            mesh.SetNextIndex(2);
        }
예제 #8
0
 internal static void MakeRect(RectStylePainterParameters rectParams, float posZ, AllocMeshData meshAlloc)
 {
     if (IsSimpleRect(rectParams.border))
     {
         MakeQuad(rectParams.rect, Rect.zero, rectParams.color, posZ, VertexFlags.IsSolid, meshAlloc);
     }
     else
     {
         UIRTessellation.TessellateBorderedRect(rectParams.rect, Rect.zero, rectParams.color, rectParams.border, posZ, VertexFlags.IsSolid, meshAlloc);
     }
 }
예제 #9
0
        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);
            }
        }
예제 #10
0
        private static void MakeSlicedQuad(ref MeshGenerationContextUtils.RectangleParams rectParams, float posZ, VertexFlags vertexFlags, AllocMeshData meshAlloc)
        {
            var mesh = meshAlloc(16, 9 * 6);

            float pixelsPerPoint = 1;
            var   texture2D      = rectParams.texture as Texture2D;

            if (texture2D != null)
            {
                pixelsPerPoint = texture2D.pixelsPerPoint;
            }

            // The following offsets are in texels (not normalized).
            float uvSliceLeft   = rectParams.leftSlice * pixelsPerPoint;
            float uvSliceTop    = rectParams.topSlice * pixelsPerPoint;
            float uvSliceRight  = rectParams.rightSlice * pixelsPerPoint;
            float uvSliceBottom = rectParams.bottomSlice * pixelsPerPoint;

            // When an atlas is used, relative coordinates must not be used.
            bool  isAtlassed  = vertexFlags == VertexFlags.IsAtlasTexturedPoint || vertexFlags == VertexFlags.IsAtlasTexturedBilinear;
            float uConversion = isAtlassed ? 1 : 1f / rectParams.texture.width;
            float vConversion = isAtlassed ? 1 : 1f / rectParams.texture.height;

            k_TexCoordSlicesX[0] = rectParams.uv.min.x;
            k_TexCoordSlicesX[1] = rectParams.uv.min.x + uvSliceLeft * uConversion;
            k_TexCoordSlicesX[2] = rectParams.uv.max.x - uvSliceRight * uConversion;
            k_TexCoordSlicesX[3] = rectParams.uv.max.x;

            k_TexCoordSlicesY[0] = rectParams.uv.max.y;
            k_TexCoordSlicesY[1] = rectParams.uv.max.y - uvSliceBottom * vConversion;
            k_TexCoordSlicesY[2] = rectParams.uv.min.y + uvSliceTop * vConversion;
            k_TexCoordSlicesY[3] = rectParams.uv.min.y;

            k_PositionSlicesX[0] = rectParams.rect.x;
            k_PositionSlicesX[1] = rectParams.rect.x + rectParams.leftSlice;
            k_PositionSlicesX[2] = rectParams.rect.xMax - rectParams.rightSlice;
            k_PositionSlicesX[3] = rectParams.rect.xMax;

            k_PositionSlicesY[0] = rectParams.rect.yMax;
            k_PositionSlicesY[1] = rectParams.rect.yMax - rectParams.bottomSlice;
            k_PositionSlicesY[2] = rectParams.rect.y + rectParams.topSlice;
            k_PositionSlicesY[3] = rectParams.rect.y;

            for (int i = 0; i < 16; ++i)
            {
                int x = i % 4;
                int y = i / 4;
                mesh.vertices[i] = new Vertex()
                {
                    position = new Vector3(k_PositionSlicesX[x], k_PositionSlicesY[y], posZ),
                    uv       = new Vector2(k_TexCoordSlicesX[x], rectParams.uv.min.y + rectParams.uv.max.y - k_TexCoordSlicesY[y]),
                    tint     = rectParams.color,
                    flags    = (float)vertexFlags
                };
            }
            mesh.indices.CopyFrom(slicedQuadIndices);
        }
예제 #11
0
        private static void MakeQuad(Rect rcPosition, Rect rcTexCoord, Color color, float posZ, VertexFlags vertexFlags, AllocMeshData meshAlloc)
        {
            float x0 = rcPosition.x;
            float x3 = rcPosition.xMax;
            float y0 = rcPosition.yMax;
            float y3 = rcPosition.y;

            float u0 = rcTexCoord.x;
            float u3 = rcTexCoord.xMax;
            float v0 = rcTexCoord.y;
            float v3 = rcTexCoord.yMax;

            var mesh = meshAlloc(4, 6);

            mesh.vertices[0] = new Vertex()
            {
                position = new Vector3(x0, y0, posZ),
                tint     = color,
                uv       = new Vector2(u0, v0),
                flags    = (float)vertexFlags
            };
            mesh.vertices[1] = new Vertex()
            {
                position = new Vector3(x3, y0, posZ),
                tint     = color,
                uv       = new Vector2(u3, v0),
                flags    = (float)vertexFlags
            };
            mesh.vertices[2] = new Vertex()
            {
                position = new Vector3(x0, y3, posZ),
                tint     = color,
                uv       = new Vector2(u0, v3),
                flags    = (float)vertexFlags
            };
            mesh.vertices[3] = new Vertex()
            {
                position = new Vector3(x3, y3, posZ),
                tint     = color,
                uv       = new Vector2(u3, v3),
                flags    = (float)vertexFlags
            };

            mesh.indices[0] = 0;
            mesh.indices[1] = 1;
            mesh.indices[2] = 2;

            mesh.indices[3] = 1;
            mesh.indices[4] = 3;
            mesh.indices[5] = 2;
        }
예제 #12
0
        internal static void MakeText(NativeArray <TextVertex> uiVertices, Vector2 offset, AllocMeshData meshAlloc)
        {
            int vertexCount = LimitTextVertices(uiVertices.Length);
            int quadCount   = vertexCount / 4;
            var mesh        = meshAlloc.Allocate((uint)(quadCount * 4), (uint)(quadCount * 6));

            for (int q = 0, v = 0; q < quadCount; ++q, v += 4)
            {
                mesh.SetNextVertex(ConvertTextVertexToUIRVertex(uiVertices[v + 0], offset));
                mesh.SetNextVertex(ConvertTextVertexToUIRVertex(uiVertices[v + 1], offset));
                mesh.SetNextVertex(ConvertTextVertexToUIRVertex(uiVertices[v + 2], offset));
                mesh.SetNextVertex(ConvertTextVertexToUIRVertex(uiVertices[v + 3], offset));

                mesh.SetNextIndex((UInt16)(v + 0));
                mesh.SetNextIndex((UInt16)(v + 1));
                mesh.SetNextIndex((UInt16)(v + 2));
                mesh.SetNextIndex((UInt16)(v + 2));
                mesh.SetNextIndex((UInt16)(v + 3));
                mesh.SetNextIndex((UInt16)(v + 0));
            }
        }
예제 #13
0
        private 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 uConversion = pixelsPerPoint / rectParams.texture.width;
            float vConversion = pixelsPerPoint / rectParams.texture.height;

            k_TexCoordSlicesX[0] = rectParams.uv.min.x;
            k_TexCoordSlicesX[1] = rectParams.uv.min.x + rectParams.leftSlice * uConversion;
            k_TexCoordSlicesX[2] = rectParams.uv.max.x - rectParams.rightSlice * uConversion;
            k_TexCoordSlicesX[3] = rectParams.uv.max.x;

            k_TexCoordSlicesY[0] = rectParams.uv.max.y;
            k_TexCoordSlicesY[1] = rectParams.uv.max.y - rectParams.bottomSlice * vConversion;
            k_TexCoordSlicesY[2] = rectParams.uv.min.y + rectParams.topSlice * vConversion;
            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;
            }

            k_PositionSlicesX[0] = rectParams.rect.x;
            k_PositionSlicesX[1] = rectParams.rect.x + rectParams.leftSlice;
            k_PositionSlicesX[2] = rectParams.rect.xMax - rectParams.rightSlice;
            k_PositionSlicesX[3] = rectParams.rect.xMax;

            k_PositionSlicesY[0] = rectParams.rect.yMax;
            k_PositionSlicesY[1] = rectParams.rect.yMax - rectParams.bottomSlice;
            k_PositionSlicesY[2] = rectParams.rect.y + rectParams.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);
        }
예제 #14
0
 internal static void MakeTexture(TextureStylePainterParameters textureParams, float posZ, VertexFlags vertexFlags, AllocMeshData meshAlloc)
 {
     if (textureParams.sliceLeft <= Mathf.Epsilon &&
         textureParams.sliceTop <= Mathf.Epsilon &&
         textureParams.sliceRight <= Mathf.Epsilon &&
         textureParams.sliceBottom <= Mathf.Epsilon)
     {
         if (IsSimpleRect(textureParams.border))
         {
             MakeQuad(textureParams.rect, textureParams.uv, textureParams.color, posZ, vertexFlags, meshAlloc);
         }
         else
         {
             UIRTessellation.TessellateBorderedRect(textureParams.rect, textureParams.uv, textureParams.color, textureParams.border, posZ, vertexFlags, meshAlloc);
         }
     }
     else
     {
         MakeSlicedQuad(textureParams, posZ, vertexFlags, meshAlloc);
     }
 }
예제 #15
0
 internal static void MakeTexturedRect(MeshGenerationContextUtils.RectangleParams rectParams, float posZ, AllocMeshData meshAlloc)
 {
     if (rectParams.leftSlice <= Mathf.Epsilon &&
         rectParams.topSlice <= Mathf.Epsilon &&
         rectParams.rightSlice <= Mathf.Epsilon &&
         rectParams.bottomSlice <= Mathf.Epsilon)
     {
         if (!rectParams.HasRadius(Tessellation.kEpsilon))
         {
             MakeQuad(rectParams.rect, rectParams.uv, rectParams.color, posZ, meshAlloc);
         }
         else
         {
             Tessellation.TessellateRect(rectParams, posZ, meshAlloc, true);
         }
     }
     else if (rectParams.texture == null)
     {
         MakeQuad(rectParams.rect, rectParams.uv, rectParams.color, posZ, meshAlloc);
     }
     else
     {
         MakeSlicedQuad(ref rectParams, posZ, meshAlloc);
     }
 }
예제 #16
0
        internal static void MakeText(NativeArray <TextVertex> uiVertices, Vector2 offset, AllocMeshData meshAlloc)
        {
            int quadCount = uiVertices.Length / 4;

            if (quadCount > k_MaxTextQuadCount)
            {
                Debug.LogError("MakeTextMeshHandle: text is too long and generates too many vertices");
                quadCount = k_MaxTextQuadCount;
            }

            var mesh = meshAlloc.Allocate((uint)(quadCount * 4), (uint)(quadCount * 6));

            for (int q = 0, v = 0; q < quadCount; ++q, v += 4)
            {
                mesh.SetNextVertex(ConvertTextVertexToUIRVertex(uiVertices[v + 0], offset));
                mesh.SetNextVertex(ConvertTextVertexToUIRVertex(uiVertices[v + 1], offset));
                mesh.SetNextVertex(ConvertTextVertexToUIRVertex(uiVertices[v + 2], offset));
                mesh.SetNextVertex(ConvertTextVertexToUIRVertex(uiVertices[v + 3], offset));

                mesh.SetNextIndex((UInt16)(v + 0));
                mesh.SetNextIndex((UInt16)(v + 2));
                mesh.SetNextIndex((UInt16)(v + 1));
                mesh.SetNextIndex((UInt16)(v + 2));
                mesh.SetNextIndex((UInt16)(v + 0));
                mesh.SetNextIndex((UInt16)(v + 3));
            }
        }
예제 #17
0
        private static void MakeVectorGraphics9SliceBackground(Vertex[] svgVertices, UInt16[] svgIndices, float svgWidth, float svgHeight, Rect targetRect, Vector4 sliceLTRB, bool stretch, Color tint, int settingIndexOffset, AllocMeshData meshAlloc)
        {
            var mwd = meshAlloc.alloc((uint)svgVertices.Length, (uint)svgIndices.Length, ref meshAlloc);

            mwd.SetAllIndices(svgIndices);

            if (!stretch)
            {
                throw new NotImplementedException("Support for repeating 9-slices is not done yet");
            }

            s_VectorGraphics9Slice.Begin();

            var     uvRegion      = mwd.uvRegion;
            int     vertsCount    = svgVertices.Length;
            Vector2 sliceInvSize  = new Vector2(1.0f / (svgWidth - sliceLTRB.z - sliceLTRB.x), 1.0f / (svgHeight - sliceLTRB.w - sliceLTRB.y));
            Vector2 stretchAmount = new Vector2(targetRect.width - svgWidth, targetRect.height - svgHeight);

            for (int i = 0; i < vertsCount; i++)
            {
                var     v = svgVertices[i];
                Vector2 skinWeight;
                skinWeight.x = Mathf.Clamp01((v.position.x - sliceLTRB.x) * sliceInvSize.x);
                skinWeight.y = Mathf.Clamp01((v.position.y - sliceLTRB.y) * sliceInvSize.y);

                v.position.x += skinWeight.x * stretchAmount.x;
                v.position.y += skinWeight.y * stretchAmount.y;
                v.uv.x        = v.uv.x * uvRegion.width + uvRegion.xMin;
                v.uv.y        = v.uv.y * uvRegion.height + uvRegion.yMin;
                v.tint       *= tint;
                uint settingIndex = (uint)(((v.opacityPageSVGSettingIndex.b << 8) | v.opacityPageSVGSettingIndex.a) + settingIndexOffset);
                v.opacityPageSVGSettingIndex.b = (byte)(settingIndex >> 8);
                v.opacityPageSVGSettingIndex.a = (byte)settingIndex;
                mwd.SetNextVertex(v);
            }

            s_VectorGraphics9Slice.End();
        }
예제 #18
0
        private static void MakeSlicedQuad(TextureStylePainterParameters texParams, float posZ, VertexFlags vertexFlags, AllocMeshData meshAlloc)
        {
            var texture = texParams.texture;

            if (texture == null)
            {
                // Early exit without slicing.
                MakeQuad(texParams.rect, texParams.uv, texParams.color, posZ, vertexFlags, meshAlloc);
                return;
            }

            var mesh = meshAlloc(16, 9 * 6);

            float pixelsPerPoint = 1;
            var   texture2D      = texParams.texture as Texture2D;

            if (texture2D != null)
            {
                pixelsPerPoint = texture2D.pixelsPerPoint;
            }

            // The following offsets are in texels (not normalized).
            float uvSliceLeft   = texParams.sliceLeft * pixelsPerPoint;
            float uvSliceTop    = texParams.sliceTop * pixelsPerPoint;
            float uvSliceRight  = texParams.sliceRight * pixelsPerPoint;
            float uvSliceBottom = texParams.sliceBottom * pixelsPerPoint;

            // When an atlas is used, relative coordinates must not be used.
            bool  isAtlassed  = vertexFlags == VertexFlags.IsTextured;
            float uConversion = isAtlassed ? 1 : 1f / texture.width;
            float vConversion = isAtlassed ? 1 : 1f / texture.height;

            k_TexCoordSlicesX[0] = texParams.uv.min.x;
            k_TexCoordSlicesX[1] = texParams.uv.min.x + uvSliceLeft * uConversion;
            k_TexCoordSlicesX[2] = texParams.uv.max.x - uvSliceRight * uConversion;
            k_TexCoordSlicesX[3] = texParams.uv.max.x;

            k_TexCoordSlicesY[0] = texParams.uv.max.y;
            k_TexCoordSlicesY[1] = texParams.uv.max.y - uvSliceBottom * vConversion;
            k_TexCoordSlicesY[2] = texParams.uv.min.y + uvSliceTop * vConversion;
            k_TexCoordSlicesY[3] = texParams.uv.min.y;

            k_PositionSlicesX[0] = texParams.rect.x;
            k_PositionSlicesX[1] = texParams.rect.x + texParams.sliceLeft;
            k_PositionSlicesX[2] = texParams.rect.xMax - texParams.sliceRight;
            k_PositionSlicesX[3] = texParams.rect.xMax;

            k_PositionSlicesY[0] = texParams.rect.yMax;
            k_PositionSlicesY[1] = texParams.rect.yMax - texParams.sliceBottom;
            k_PositionSlicesY[2] = texParams.rect.y + texParams.sliceTop;
            k_PositionSlicesY[3] = texParams.rect.y;

            for (int i = 0; i < 16; ++i)
            {
                int x = i % 4;
                int y = i / 4;
                mesh.vertices[i] = new Vertex()
                {
                    position = new Vector3(k_PositionSlicesX[x], k_PositionSlicesY[y], posZ),
                    uv       = new Vector2(k_TexCoordSlicesX[x], texParams.uv.min.y + texParams.uv.max.y - k_TexCoordSlicesY[y]),
                    tint     = texParams.color,
                    flags    = (float)vertexFlags
                };
            }
            mesh.indices.CopyFrom(slicedQuadIndices);
        }