public void UpdateTransformRecursive(ref WorldSpaceRect parentLocalToWorldSpaceRect, WorldSpaceMask currentMask, Entity entity, float2 scale) { if (DisabledFromEntity.Exists(entity)) { return; } var childTransform = RectTransformFromEntity[entity]; var childLocalToWorld = RectTransformUtils.CalculateWorldSpaceRect(parentLocalToWorldSpaceRect, scale, childTransform); WorldSpaceRectFromEntity[entity] = childLocalToWorld; ElementScaleFromEntity[entity] = new ElementScale() { Value = scale }; UpdateRectMask(entity, childLocalToWorld, ref currentMask); WorldSpaceMaskFromEntity[entity] = currentMask; if (RebuildFlagFromEntity.Exists(entity)) { RebuildFlagFromEntity[entity] = new RebuildElementMeshFlag() { Rebuild = true } } ; if (ChildrenFromEntity.Exists(entity)) { var children = ChildrenFromEntity[entity]; for (int i = 0; i < children.Length; i++) { UpdateTransformRecursive(ref childLocalToWorld, currentMask, children[i].Value, scale); } } }
private void UpdateTransform(ref WorldSpaceRect parentLocalToWorldSpaceRect, WorldSpaceMask currentMask, Entity entity, float2 scale, int jobIdx) { var childTransform = RectTransformFromEntity[entity]; float2 start = math.lerp(parentLocalToWorldSpaceRect.Min, parentLocalToWorldSpaceRect.Max, math.lerp(childTransform.AnchorMin, childTransform.AnchorMax, childTransform.Pivot)) + childTransform.Position * scale; float2 anchorDiff = childTransform.AnchorMax - childTransform.AnchorMin; float2 size = (parentLocalToWorldSpaceRect.Max - parentLocalToWorldSpaceRect.Min) * anchorDiff + childTransform.SizeDelta * scale; float2 min = start - size * childTransform.Pivot; float2 max = start + size * (new float2(1.0f, 1.0f) - childTransform.Pivot); var childLocalToWorld = new WorldSpaceRect() { Min = min, Max = max, }; LocalToWorldFromEntity[entity] = childLocalToWorld; ElementScaleType[entity] = new ElementScale() { Value = scale }; UpdateRectMask(entity, childLocalToWorld, ref currentMask); WorldSpaceMaskFromEntity[entity] = currentMask; if (RebuildFlagType.Exists(entity)) { RebuildFlagType[entity] = new RebuildElementMeshFlag() { Rebuild = true } } ; if (ChildFromEntity.Exists(entity)) { var children = ChildFromEntity[entity]; for (int i = 0; i < children.Length; i++) { UpdateTransform(ref childLocalToWorld, currentMask, children[i].Value, scale, jobIdx); } } }
private void PopulateMesh(WorldSpaceRect rect, ElementScale scale, WorldSpaceMask mask, TextRenderer settings, float4 color, ref DynamicBuffer <TextData> textBuffer, ref DynamicBuffer <ControlVertexData> vertices, ref DynamicBuffer <ControlVertexIndex> triangles) { _VerticalAlignmentOptions verticalAlignment = (_VerticalAlignmentOptions)settings.Alignment; _HorizontalAlignmentOptions horizontalAlignment = (_HorizontalAlignmentOptions)settings.Alignment; var font = FontAssetFromEntity[settings.Font]; var glyphData = FontGlyphDataFromEntity[settings.Font]; float2 canvasScale = settings.Size * scale.Value / font.PointSize; float stylePadding = 1.25f + (settings.Bold ? font.BoldStyle / 4.0f : font.NormalStyle / 4.0f); float styleSpaceMultiplier = 1.0f + (settings.Bold ? font.BoldSpace * 0.01f : font.NormalSpace * 0.01f); NativeList <TextUtils.TextLineInfo> lines = new NativeList <TextUtils.TextLineInfo>(Allocator.Temp); TextUtils.CalculateLines(ref rect, canvasScale, styleSpaceMultiplier, ref glyphData, ref textBuffer, lines); float textBlockHeight = lines.Length * font.LineHeight * canvasScale.y; float2 alignedStartPosition = TextUtils.GetAlignedStartPosition(ref rect, ref settings, ref font, textBlockHeight, canvasScale); float2 currentCharacter = alignedStartPosition; int lineIdx = 0; for (int i = 0; i < textBuffer.Length; i++) { if (lineIdx < lines.Length && i == lines[lineIdx].CharacterOffset) { currentCharacter = new float2(TextUtils.GetAlignedLinePosition(ref rect, lines[lineIdx].LineWidth, horizontalAlignment), alignedStartPosition.y - font.LineHeight * canvasScale.y * lineIdx); lineIdx++; } var character = textBuffer[i].Value; if (character == (ushort)'\n') { // It's handled in GetLinesOffsets continue; } if (TextUtils.GetGlyph(character, ref glyphData, out FontGlyphData ch)) { int startIndex = vertices.Length; float2 uv2 = new float2(ch.Scale, ch.Scale) * math.select(canvasScale, -canvasScale, settings.Bold); float2 vMin = currentCharacter + new float2(ch.Metrics.horizontalBearingX - stylePadding, ch.Metrics.horizontalBearingY - ch.Metrics.height - stylePadding) * canvasScale; float2 vMax = vMin + new float2(ch.Metrics.width + stylePadding * 2.0f, ch.Metrics.height + stylePadding * 2.0f) * canvasScale; 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); RectMaskCut cut = SpriteUtility.GetRectangleMaskCut(vMin, vMax, uv.xy, uv.zw, ref mask); var cutSize = cut.Max + cut.Min; if (!(cutSize.x > vMax.x - vMin.x) && !(cutSize.y > vMax.y - vMin.y)) { float4 vertexPos = new float4(vMin + cut.Min, vMax - cut.Max); uv.xy = uv.xy + cut.UvMin; uv.zw = uv.zw - cut.UvMax; triangles.Add(new ControlVertexIndex() { Value = startIndex + 2 }); triangles.Add(new ControlVertexIndex() { Value = startIndex + 1 }); triangles.Add(new ControlVertexIndex() { Value = startIndex }); triangles.Add(new ControlVertexIndex() { Value = startIndex + 3 }); triangles.Add(new ControlVertexIndex() { Value = startIndex + 2 }); triangles.Add(new ControlVertexIndex() { Value = startIndex }); vertices.Add(new ControlVertexData() { Position = new float3(vertexPos.xy, 0.0f), Normal = new float3(0.0f, 0.0f, -1.0f), TexCoord0 = uv.xy, TexCoord1 = uv2, Color = color }); vertices.Add(new ControlVertexData() { Position = new float3(vertexPos.zy, 0.0f), Normal = new float3(0.0f, 0.0f, -1.0f), TexCoord0 = uv.zy, TexCoord1 = uv2, Color = color }); vertices.Add(new ControlVertexData() { Position = new float3(vertexPos.zw, 0.0f), Normal = new float3(0.0f, 0.0f, -1.0f), TexCoord0 = uv.zw, TexCoord1 = uv2, Color = color }); vertices.Add(new ControlVertexData() { Position = new float3(vertexPos.xw, 0.0f), Normal = new float3(0.0f, 0.0f, -1.0f), TexCoord0 = uv.xw, TexCoord1 = uv2, Color = color }); } currentCharacter += (new float2(ch.Metrics.horizontalAdvance * styleSpaceMultiplier, 0.0f) * canvasScale); } } }