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); }