Example #1
0
        protected override void OnUpdate()
        {
            if (!HasSingleton <CanvasRoot>())
            {
                TextUtility.CreateCanvas(EntityManager);
                SetSingleton(default(CanvasRoot));
            }

            m_vertexCounter.Value      = 0;
            m_vertexIndexCounter.Value = 0;
            m_subMeshCounter.Value     = 0;
            var changedVerticesCount = m_vertexDataQuery.CalculateEntityCount();

            if (changedVerticesCount == 0)
            {
                return;
            }
            m_vertexDataQuery.ResetFilter();

            var length           = m_vertexDataQuery.CalculateEntityCount();
            var canvasRootEntity = GetSingletonEntity <CanvasRoot>();
            var sortedEntities   = EntityManager.GetAllSortedEntities(this, Allocator.TempJob);

            Dependency = m_vertexDataQuery.ToEntityIndexMap(EntityManager, ref m_entityIndexMap, Dependency);

            Dependency = JobHandle.CombineDependencies(
                m_offsets.Resize(length, Dependency),
                m_sharedFontIndices.Resize(length, Dependency));

            Dependency = new GatherSharedComponentIndices <FontMaterial> {
                ChunkSharedComponentType = GetArchetypeChunkSharedComponentType <FontMaterial>(),
                Indices = m_sharedFontIndices.AsDeferredJobArray()
            }.Schedule(m_vertexDataQuery, Dependency);

            CreateOffsets(
                m_entityIndexMap,
                sortedEntities,
                m_sharedFontIndices.AsDeferredJobArray(),
                m_offsets.AsDeferredJobArray(),
                m_vertexCounter,
                m_vertexIndexCounter,
                m_subMeshCounter);

            Dependency = JobHandle.CombineDependencies(
                m_canvasdRootQuery.ResizeBufferDeferred <Vertex>(this, m_vertexCounter, Dependency),
                m_canvasdRootQuery.ResizeBufferDeferred <VertexIndex>(this, m_vertexIndexCounter, Dependency),
                m_canvasdRootQuery.ResizeBufferDeferred <SubMeshInfo>(this, m_subMeshCounter, Dependency));

            MergeBatching(canvasRootEntity, m_offsets.AsDeferredJobArray());
            Dependency = sortedEntities.Dispose(Dependency);
            m_vertexDataQuery.SetChangedVersionFilter(m_filterChanged);
        }
        protected override void OnUpdate()
        {
            Entities.ForEach((TextMeshPro textMesh, MeshFilter meshFilter) => {
                // We must disable the text mesh for it to be skipped by MeshRenderer conversion system
                meshFilter.mesh = null;
                var font        = textMesh.font;
                var entity      = GetPrimaryEntity(textMesh);
                if (!m_textFontAssets.TryGetValue(font, out var fontEntity))
                {
                    fontEntity = TextUtility.CreateTextFontAsset(DstEntityManager, font);
                    m_textFontAssets.Add(font, fontEntity);
                }

                DstEntityManager.AddSharedComponentData(entity, new FontMaterial {
                    Value = font.material
                });
                var materialId = DstEntityManager.GetSharedComponentDataIndex <FontMaterial>(entity);

                DstEntityManager.AddComponentData(entity, new TextRenderer()
                {
                    Font       = fontEntity,
                    MaterialId = materialId,
                    Size       = textMesh.fontSize,
                    Alignment  = textMesh.alignment,
                    Bold       = (textMesh.fontStyle & FontStyles.Bold) == FontStyles.Bold,
                    Italic     = (textMesh.fontStyle & FontStyles.Italic) == FontStyles.Italic
                });
                DstEntityManager.AddComponentData(entity, new TextData {
                    Value = textMesh.text
                });
                DstEntityManager.AddComponentData(entity, new VertexColor()
                {
                    Value = textMesh.color.ToFloat4()
                });
                DstEntityManager.AddComponentData(entity, new VertexColorMultiplier()
                {
                    Value = new float4(1.0f, 1.0f, 1.0f, 1.0f)
                });
                DstEntityManager.AddBuffer <Vertex>(entity);
                DstEntityManager.AddBuffer <VertexIndex>(entity);
                DstEntityManager.AddBuffer <TextLine>(entity);
                if (!DstEntityManager.HasComponent <RenderBounds>(entity))
                {
                    // RenderBounds will be calculated on TextMeshBuildSystem
                    DstEntityManager.AddComponentData(entity, default(RenderBounds));
                }
            });
        }
            private void PopulateMesh(
                LocalRectTransform rectTransform,
                float4x4 localToWorld,
                TextRenderer textRenderer,
                float4 color,
                TextData textData,
                DynamicBuffer <Vertex> vertices,
                DynamicBuffer <VertexIndex> triangles,
                DynamicBuffer <TextLine> lines)
            {
                var verticalAlignment   = (_VerticalAlignmentOptions)textRenderer.Alignment;
                var horizontalAlignment = (_HorizontalAlignmentOptions)textRenderer.Alignment;

                var font      = FontAssetFromEntity[textRenderer.Font];
                var glyphData = FontGlyphFromEntity[textRenderer.Font];

                float2 canvasScale = textRenderer.Size / font.PointSize * 0.1f;

                float stylePadding         = 1.25f + (textRenderer.Bold ? font.BoldStyle / 4.0f : font.NormalStyle / 4.0f);
                float styleSpaceMultiplier = 1.0f + (textRenderer.Bold ? font.BoldSpace * 0.01f : font.NormalSpace * 0.01f);

                TextUtility.CalculateLines(rectTransform, canvasScale, styleSpaceMultiplier, glyphData, textData, lines);
                float textBlockHeight = lines.Length * font.LineHeight * canvasScale.y;

                float2 alignedStartPosition = TextUtility.GetAlignedStartPosition(rectTransform, textRenderer, font, textBlockHeight, canvasScale);
                float2 currentCharacter     = alignedStartPosition;

                int lineIdx = 0;

                for (int i = 0; i < textData.Value.LengthInBytes; i++)
                {
                    if (lineIdx < lines.Length && i == lines[lineIdx].CharacterOffset)
                    {
                        currentCharacter = new float2(
                            TextUtility.GetAlignedLinePosition(rectTransform, lines[lineIdx].LineWidth, horizontalAlignment),
                            alignedStartPosition.y - font.LineHeight * canvasScale.y * lineIdx);
                        lineIdx++;
                    }

                    var character = textData.Value.GetChar(i);
                    if (TextUtility.GetGlyph(character, glyphData, out FontGlyph ch))
                    {
                        int startVertexIndex   = i * 4;
                        int startTriangleIndex = i * 6;

                        float2 uv2 = new float2(ch.Scale, ch.Scale) * math.select(canvasScale, -canvasScale, textRenderer.Bold);

                        float3 min = new float3(currentCharacter, 0) +
                                     new float3(ch.Metrics.horizontalBearingX - stylePadding, ch.Metrics.horizontalBearingY - ch.Metrics.height - stylePadding, 0) *
                                     new float3(canvasScale, 1f);
                        float3 max = min +
                                     new float3(ch.Metrics.width + stylePadding * 2.0f, ch.Metrics.height + stylePadding * 2.0f, 0) *
                                     new float3(canvasScale, 1f);

                        var v0     = math.mul(localToWorld, float4x4.Translate(min)).Position();
                        var v1     = math.mul(localToWorld, float4x4.Translate(new float3(max.x, min.y, min.z))).Position();
                        var v2     = math.mul(localToWorld, float4x4.Translate(max)).Position();
                        var v3     = math.mul(localToWorld, float4x4.Translate(new float3(min.x, max.y, min.z))).Position();
                        var normal = math.mul(
                            new float4x4(localToWorld.Rotation(), new float3()),
                            float4x4.Translate(new float3(0, 0, -1))).c3;
                        float4 uv = new float4(
                            ch.Rect.x - stylePadding, ch.Rect.y - stylePadding,
                            ch.Rect.x + ch.Rect.width + stylePadding,
                            ch.Rect.y + ch.Rect.height + stylePadding) /
                                    new float4(font.AtlasSize, font.AtlasSize);

                        triangles[startTriangleIndex]     = startVertexIndex + 2;
                        triangles[startTriangleIndex + 1] = startVertexIndex + 1;
                        triangles[startTriangleIndex + 2] = startVertexIndex;

                        triangles[startTriangleIndex + 3] = startVertexIndex + 3;
                        triangles[startTriangleIndex + 4] = startVertexIndex + 2;
                        triangles[startTriangleIndex + 5] = startVertexIndex;

                        vertices[startVertexIndex] = new Vertex()
                        {
                            Position  = v0,
                            Normal    = (half4)normal,
                            TexCoord0 = (half2)uv.xy,
                            TexCoord1 = (half2)uv2,
                            Color     = (half4)color
                        };
                        vertices[startVertexIndex + 1] = new Vertex()
                        {
                            Position  = v1,
                            Normal    = (half4)normal,
                            TexCoord0 = (half2)uv.zy,
                            TexCoord1 = (half2)uv2,
                            Color     = (half4)color
                        };
                        vertices[startVertexIndex + 2] = new Vertex()
                        {
                            Position  = v2,
                            Normal    = (half4)normal,
                            TexCoord0 = (half2)uv.zw,
                            TexCoord1 = (half2)uv2,
                            Color     = (half4)color
                        };
                        vertices[startVertexIndex + 3] = new Vertex()
                        {
                            Position  = v3,
                            Normal    = (half4)normal,
                            TexCoord0 = (half2)uv.xw,
                            TexCoord1 = (half2)uv2,
                            Color     = (half4)color
                        };
                        currentCharacter +=
                            new float2(ch.Metrics.horizontalAdvance * styleSpaceMultiplier, 0.0f) * canvasScale;
                    }
                }
            }
        protected override JobHandle OnUpdate(JobHandle inputDeps)
        {
            if (!HasSingleton <CanvasRoot>())
            {
                TextUtility.CreateCanvas(EntityManager);
                SetSingleton(default(CanvasRoot));
            }

            m_vertexCounter.Value      = 0;
            m_vertexIndexCounter.Value = 0;
            m_subMeshCounter.Value     = 0;
            var changedVerticesCount = m_vertexDataQuery.CalculateEntityCount();

            if (changedVerticesCount == 0)
            {
                return(inputDeps);
            }
            m_vertexDataQuery.ResetFilter();

            var length           = m_vertexDataQuery.CalculateEntityCount();
            var canvasRootEntity = GetSingletonEntity <CanvasRoot>();
            var sortedEntities   = EntityManager.GetAllSortedEntities(this, Allocator.TempJob);

            inputDeps = m_vertexDataQuery.ToEntityIndexMap(EntityManager, ref m_entityIndexMap, inputDeps);

            inputDeps = JobHandle.CombineDependencies(
                m_offsets.Resize(length, inputDeps),
                m_sharedFontIndices.Resize(length, inputDeps));

            inputDeps = new GatherSharedComponentIndices <FontMaterial> {
                ChunkSharedComponentType = GetArchetypeChunkSharedComponentType <FontMaterial>(),
                Indices = m_sharedFontIndices.AsDeferredJobArray()
            }.Schedule(m_vertexDataQuery, inputDeps);

            inputDeps = new CreateOffsets {
                EntitiesIndexMap       = m_entityIndexMap,
                SortedEntities         = sortedEntities,
                Offsets                = m_offsets.AsDeferredJobArray(),
                SharedComponentIndices = m_sharedFontIndices.AsDeferredJobArray(),
                Vertices               = GetBufferFromEntity <Vertex>(true),
                VertexIndices          = GetBufferFromEntity <VertexIndex>(true),
                VertexCounter          = m_vertexCounter,
                VertexIndexCounter     = m_vertexIndexCounter,
                SubMeshCounter         = m_subMeshCounter
            }.Schedule(inputDeps);

            inputDeps = JobHandle.CombineDependencies(
                m_canvasdRootQuery.ResizeBufferDeferred <Vertex>(this, m_vertexCounter, inputDeps),
                m_canvasdRootQuery.ResizeBufferDeferred <VertexIndex>(this, m_vertexIndexCounter, inputDeps),
                m_canvasdRootQuery.ResizeBufferDeferred <SubMeshInfo>(this, m_subMeshCounter, inputDeps));

            inputDeps = new MeshBatching {
                CanvasRootEntity          = canvasRootEntity,
                MeshVertexFromEntity      = GetBufferFromEntity <Vertex>(false),
                MeshVertexIndexFromEntity = GetBufferFromEntity <VertexIndex>(false),
                SubMeshInfoFromEntity     = GetBufferFromEntity <SubMeshInfo>(false),
                Offsets = m_offsets.AsDeferredJobArray(),
            }.Schedule(m_vertexDataQuery, inputDeps);

            inputDeps = sortedEntities.Dispose(inputDeps);
            m_vertexDataQuery.SetChangedVersionFilter(m_filterChanged);
            return(inputDeps);
        }