public Obb CalcObbInWorld([CanBeNull] Obb world) { var rotation = Rotation; var leftTopPosition = LocalLeftTopPosition; var parent = Parent; while (parent != world) { var rad = parent.Rotation * Mathf.Deg2Rad; var atan = Mathf.Atan2(leftTopPosition.y, leftTopPosition.x); var radCos = Mathf.Cos(rad + atan); var radSin = Mathf.Sin(rad + atan); var r = Mathf.Sqrt(leftTopPosition.x * leftTopPosition.x + leftTopPosition.y * leftTopPosition.y); leftTopPosition = new Vector2( parent.LocalLeftTopPosition.x + r * radCos, parent.LocalLeftTopPosition.y + r * radSin ); rotation += parent.Rotation; parent = parent.Parent; } return(new Obb { LocalLeftTopPosition = leftTopPosition, Size = Size, Rotation = rotation, Parent = world }); }
private Obb CalcPosition(XdObjectJson xdObject, Obb parentObb, XdObjectJson[] parents) { var obb = new Obb { Parent = parentObb, LocalLeftTopPosition = new Vector2(xdObject.Transform?.Tx ?? 0f, xdObject.Transform?.Ty ?? 0f), Rotation = xdObject.Meta?.Ux?.Rotation ?? 0f // サイズは子供のサイズが無いと決まらない }; var children = new Obb[] { }; if (xdObject.Group != null) { children = CalcPosition(xdObject.Group.Children, obb, parents.Concat(new[] { xdObject }).ToArray()); } foreach (var parser in _objectParsers) { if (!parser.Is(xdObject)) { continue; } var rect = parser.CalcSize(xdObject); obb.ApplyRect(rect); foreach (var child in children) { child.LocalLeftTopPosition -= rect.position; } _obbHolder.Set(xdObject, obb); return(obb); } if (xdObject.Type == "group") { var rect = Obb.MinMaxRect(children); foreach (var parser in _groupParsers) { if (!parser.Is(xdObject, parents)) { continue; } rect = parser.CalcSize(xdObject, rect); break; } obb.ApplyRect(rect); foreach (var child in children) { child.LocalLeftTopPosition -= rect.position; } _obbHolder.Set(xdObject, obb); return(obb); } throw new Exception($"Unknown object type {xdObject.Type}"); }
public void Set(XdObjectJson xdObject, Obb obb) { var key = xdObject.Guid ?? xdObject.Id; if (_obb.ContainsKey(key)) { throw new Exception($"{key} already exists"); } _obb[key] = obb; }
public (IComponent[], IAsset[]) Render(XdObjectJson xdObject, Obb obb, XdAssetHolder assetHolder) { var(imageComponent, assets) = ShapeObjectParser.RenderImage(xdObject, obb, assetHolder); IComponent scrollbar = new VerticalScrollbarComponent(imageComponent); if (xdObject.HasParameter("horizontal")) { scrollbar = new HorizontalScrollbarComponent(imageComponent); } return(new[] { scrollbar }, assets); }
public (IComponent[], IAsset[]) Render(XdObjectJson xdObject, Obb obb, XdAssetHolder assetHolder) { var components = new List <IComponent>(); var font = xdObject.Style.Font; var fontSize = font.Size; var color = xdObject.GetFillUnityColor(); var rawText = xdObject.Text.RawText; var textAlign = TextComponent.TextAlign.MiddleLeft; var wrap = false; var paragraphAlign = xdObject.Style?.TextAttributes?.ParagraphAlign ?? "left"; if (xdObject.Text?.Frame?.Type == "positioned") { wrap = false; if (paragraphAlign == "left") { textAlign = TextComponent.TextAlign.MiddleLeft; } if (paragraphAlign == "center") { textAlign = TextComponent.TextAlign.MiddleCenter; } if (paragraphAlign == "right") { textAlign = TextComponent.TextAlign.MiddleRight; } } if (xdObject.Text?.Frame?.Type == "area" || xdObject.Text?.Frame?.Type == "autoHeight") { wrap = true; if (paragraphAlign == "left") { textAlign = TextComponent.TextAlign.UpperLeft; } if (paragraphAlign == "center") { textAlign = TextComponent.TextAlign.UpperCenter; } if (paragraphAlign == "right") { textAlign = TextComponent.TextAlign.UpperRight; } } var lineHeight = xdObject.Style?.TextAttributes?.LineHeight; components.Add(new TextComponent(rawText, fontSize, color, textAlign, font.PostscriptName, wrap, lineHeight)); return(components.ToArray(), new IAsset[] { }); }
public XdRenderer(XdArtboard xdArtboard, XdAssetHolder xdAssetHolder, IXdObjectParser[] objectParsers, IXdGroupParser[] groupParsers, AkyuiXdImportTrigger[] triggers) { var resources = xdArtboard.Resources; _xdAssetHolder = xdAssetHolder; _objectParsers = objectParsers; _groupParsers = groupParsers; Elements = new List <IElement>(); Assets = new List <IAsset>(); _obbHolder = new ObbHolder(); CreateRefObjectMap(resources.Resources); var xdResourcesArtboardsJson = resources.Artboards[xdArtboard.Manifest.Path.Replace("artboard-", "")]; var rootObb = new Obb { Size = new Vector2(xdResourcesArtboardsJson.Width, xdResourcesArtboardsJson.Height) }; var rootArtboard = xdArtboard.Artboard.Children[0]; var xdObjectJsons = rootArtboard.Artboard.Children; var convertedXdObjectJsons = ConvertRefObject(xdObjectJsons, triggers); var childrenObbs = CalcPosition(convertedXdObjectJsons, rootObb); foreach (var childObb in childrenObbs) { childObb.LocalLeftTopPosition -= new Vector2(xdResourcesArtboardsJson.X, xdResourcesArtboardsJson.Y); } var children = Render(convertedXdObjectJsons, rootObb); var rootComponents = new List <IComponent>(); if (rootArtboard.Style?.Fill != null && rootArtboard.Style.Fill.Type == "solid") { var color = rootArtboard.GetFillUnityColor(); rootComponents.Add(new ImageComponent(null, color, Vector2Int.one)); } var root = new ObjectElement( 0, xdArtboard.Name, Vector2.zero, rootObb.Size, AnchorXType.Center, AnchorYType.Middle, 0f, true, rootComponents.ToArray(), children.Select(x => x.Eid).ToArray() ); Elements.Add(root); }
// CalcPositionは子供から確定させていく private Obb[] CalcPosition(XdObjectJson[] xdObjects, Obb parent) { var obbList = new List <Obb>(); foreach (var xdObject in xdObjects) { try { obbList.Add(CalcPosition(xdObject, parent)); } catch (Exception) { Debug.LogError($"Cause exception in CalcPosition {xdObject.Name}(id: {xdObject.Id}, guid: {xdObject.Guid})"); throw; } } return(obbList.ToArray()); }
private IElement[] Render(XdObjectJson[] xdObjects, [CanBeNull] Obb parent) { var children = new List <IElement>(); foreach (var xdObject in xdObjects) { try { children.AddRange(Render(xdObject, parent)); } catch (Exception) { Debug.LogError($"Cause exception in Render {xdObject.Name}(id: {xdObject.Id}, guid: {xdObject.Guid})"); throw; } } return(children.ToArray()); }
// Renderは親から子供の順番 private IElement[] Render(XdObjectJson xdObject, [CanBeNull] Obb parent) { var eid = _nextEid; _nextEid++; var originalObb = _obbHolder.Get(xdObject); var obb = originalObb.CalcObbInWorld(parent); var position = obb.CalcLocalRect().center - (parent?.Size ?? Vector2.zero) / 2f; var size = obb.Size; var anchorX = AnchorXType.Center; var anchorY = AnchorYType.Middle; var rotation = obb.Rotation; if (Mathf.Abs(rotation) < 0.0001f) { rotation = 0f; } var constRight = xdObject.Meta.Ux.ConstraintRight; var constLeft = xdObject.Meta.Ux.ConstraintLeft; if (constRight && constLeft) { anchorX = AnchorXType.Stretch; } else if (constRight) { anchorX = AnchorXType.Right; } else if (constLeft) { anchorX = AnchorXType.Left; } var constTop = xdObject.Meta.Ux.ConstraintTop; var constBottom = xdObject.Meta.Ux.ConstraintBottom; if (constTop && constBottom) { anchorY = AnchorYType.Stretch; } else if (constTop) { anchorY = AnchorYType.Top; } else if (constBottom) { anchorY = AnchorYType.Bottom; } foreach (var parser in _objectParsers) { if (!parser.Is(xdObject)) { continue; } var(components, assets) = parser.Render(xdObject, obb, _xdAssetHolder); var children = new IElement[] { }; if (xdObject.Group != null) { children = Render(xdObject.Group.Children, originalObb); } var element = new ObjectElement( eid, xdObject.GetSimpleName(), position, size, anchorX, anchorY, rotation, xdObject.Visible ?? true, components, children.Select(x => x.Eid).ToArray() ); foreach (var asset in assets) { if (Assets.Any(x => x.FileName == asset.FileName)) { continue; } Assets.Add(asset); } Elements.Add(element); return(new IElement[] { element }); } if (xdObject.Type == "group") { var components = new List <IComponent>(); foreach (var parser in _groupParsers) { if (!parser.Is(xdObject)) { continue; } var(c, assets) = parser.Render(xdObject, _xdAssetHolder, _obbHolder); components.AddRange(c); foreach (var asset in assets) { if (Assets.Any(x => x.FileName == asset.FileName)) { continue; } Assets.Add(asset); } break; } var generatedChildren = new IElement[] { }; if (xdObject.Group != null) { generatedChildren = Render(xdObject.Group.Children, originalObb); } var group = new ObjectElement( eid, xdObject.GetSimpleName(), position, size, anchorX, anchorY, rotation, xdObject.Visible ?? true, components.ToArray(), generatedChildren.Select(x => x.Eid).ToArray() ); Elements.Add(group); return(new IElement[] { group }); } throw new Exception($"Unknown object type {xdObject.Type}"); }
public static (ImageComponent, IAsset[]) RenderImage(XdObjectJson xdObject, Obb obb, XdAssetHolder assetHolder) { ImageComponent imageComponent = null; SpriteAsset asset = null; var color = xdObject.GetFillUnityColor(); var ux = xdObject.Style?.Fill?.Pattern?.Meta?.Ux; var flipX = ux?.FlipX ?? false; var flipY = ux?.FlipY ?? false; var direction = new Vector2Int(flipX ? -1 : 1, flipY ? -1 : 1); var shapeType = xdObject.Shape?.Type; if (!string.IsNullOrWhiteSpace(ux?.Uid)) { var spriteUid = $"{xdObject.GetSimpleName()}_{ux?.Uid.Substring(0, 8)}.png"; asset = new SpriteAsset(spriteUid, xdObject.Style.Fill.Pattern.Meta.Ux.HrefLastModifiedDate, obb.Size, null, null); imageComponent = new ImageComponent( spriteUid, color, direction ); assetHolder.Save(spriteUid, xdObject.Style.Fill.Pattern.Meta); } else if (SvgUtil.Types.Contains(shapeType)) { var spriteUid = $"{xdObject.GetSimpleName()}_{xdObject.Id.Substring(0, 8)}.png"; var svg = SvgUtil.CreateSvg(xdObject); var svgHash = FastHash.CalculateHash(svg); var cachedSvg = assetHolder.GetCachedSvg(svgHash); if (cachedSvg != null) { spriteUid = cachedSvg.SpriteUid; } else { asset = new SpriteAsset(spriteUid, svgHash, obb.Size, null, null); var xdImportSettings = XdImporter.Settings; assetHolder.Save(spriteUid, () => SvgToPng.Convert(svg, obb.Size, xdImportSettings)); assetHolder.SaveCacheSvg(spriteUid, svgHash); } imageComponent = new ImageComponent( spriteUid, new Color(1f, 1f, 1f, color.a), direction ); } else { Debug.LogError($"Unknown shape type {shapeType} in {xdObject.Name}({xdObject.Id}, {xdObject.Guid})"); } var assets = new List <IAsset>(); if (!xdObject.HasParameter("placeholder") && asset != null) { assets.Add(asset); } return(imageComponent, assets.ToArray()); }
public (IComponent[], IAsset[]) Render(XdObjectJson xdObject, Obb obb, XdAssetHolder assetHolder) { var(imageComponent, assets) = RenderImage(xdObject, obb, assetHolder); return(new IComponent[] { imageComponent }, assets); }
private Obb CalcPosition(XdObjectJson xdObject, Obb parentObb, XdObjectJson[] parents) { var obb = new Obb { Parent = parentObb, LocalLeftTopPosition = new Vector2(xdObject.Transform?.Tx ?? 0f, xdObject.Transform?.Ty ?? 0f), Rotation = xdObject.Meta?.Ux?.Rotation ?? 0f // サイズは子供のサイズが無いと決まらない }; var children = new Obb[] { }; if (xdObject.Group != null) { children = CalcPosition(xdObject.Group.Children, obb, parents.Concat(new[] { xdObject }).ToArray()); } foreach (var parser in _objectParsers) { if (!parser.Is(xdObject)) { continue; } var rect = parser.CalcSize(xdObject); obb.ApplyRect(rect); foreach (var child in children) { child.LocalLeftTopPosition -= rect.position; } _obbHolder.Set(xdObject, obb); return(obb); } if (xdObject.Type == "group") { var rect = Obb.MinMaxRect(children); var pivotObject = xdObject.Group?.Children?.FirstOrDefault(x => x.HasParameter("pivot")); if (pivotObject != null) { var pivotObb = _obbHolder.Get(pivotObject); var pivotCenter = pivotObb.CalcLocalRect().center; var delta = rect.center - pivotCenter; var newCenter = pivotCenter; var newWidth = rect.width + Mathf.Abs(delta.x) * 2f; var newHeight = rect.height + Mathf.Abs(delta.y) * 2f; rect.width = newWidth; rect.height = newHeight; rect.center = newCenter; } foreach (var parser in _groupParsers) { if (!parser.Is(xdObject, parents)) { continue; } rect = parser.CalcSize(xdObject, rect); break; } obb.ApplyRect(rect); foreach (var child in children) { child.LocalLeftTopPosition -= rect.position; } _obbHolder.Set(xdObject, obb); return(obb); } throw new Exception($"Unknown object type {xdObject.Type}"); }
public abstract (IComponent[], IAsset[]) Render(XdObjectJson xdObject, Obb obb, XdAssetHolder assetHolder);