private static TreeNode CreateObjectTreeNode(TreeNodeCollection collection, RenderTreeNode viewNode) { var feObj = viewNode.FrontendObject; var nodeImageKey = feObj.Type switch { ObjectType.String => "TreeItem_String", ObjectType.Image => "TreeItem_Image", ObjectType.Group => "TreeItem_Group", ObjectType.Movie => "TreeItem_Movie", ObjectType.ColoredImage => "TreeItem_ColoredImage", ObjectType.MultiImage => "TreeItem_MultiImage", _ => null }; var nodeText = $"{feObj.Name ?? feObj.NameHash.ToString("X")}"; if (nodeImageKey == null) { nodeText = feObj.Type + " " + nodeText; } var objTreeNode = collection.Add(nodeText); objTreeNode.Tag = viewNode; if (nodeImageKey != null) { objTreeNode.ImageKey = objTreeNode.SelectedImageKey = nodeImageKey; } // Create nodes for scripts feObj.Scripts.ForEach(scr => CreateScriptTreeNode(objTreeNode.Nodes, scr)); return(objTreeNode); }
private void RenderNode(RenderTreeNode node, bool doBoundingBox = false) { switch (node.FrontendObject) { // there are some things we just don't need to handle case Group _: case Movie _: break; case SimpleImage _: RenderSimpleImage(node, doBoundingBox); break; case IImage <ImageData> image: RenderImage(node, image, doBoundingBox); break; case Text str: RenderString(node, str); break; default: Debug.Assert(false, "Unsupported object", "Type: {0}", node.FrontendObject.GetType()); break; } }
private void PrepareNodes(IEnumerable <RenderTreeNode> nodes, Matrix4x4 viewMatrix, RenderTreeNode parent = null) { var nodeList = nodes.ToList(); nodeList.ForEach(r => r.PrepareForRender(viewMatrix, parent, (int)_stopwatch.ElapsedMilliseconds, true)); foreach (var renderTreeGroup in nodeList.OfType <RenderTreeGroup>()) { PrepareNodes(renderTreeGroup, renderTreeGroup.ObjectMatrix, renderTreeGroup); } }
public void UpdateObjectDetails(RenderTreeNode nodeTag) { var obj = nodeTag.FrontendObject; labelObjType.Text = obj.Type.ToString(); labelObjHash.Text = $"{obj.NameHash:X}"; labelObjGUID.Text = $"{obj.Guid:X}"; labelObjFlags.Text = $"{obj.Flags}"; if (obj.ResourceRequest is {} resourceRequest) { // labelObjResID.Text = obj.ResourceIndex.ToString(); labelObjResID.Text = $"{resourceRequest.Name} ({resourceRequest.Type})"; }
private void RenderSimpleImage(RenderTreeNode node, bool doBoundingBox = false) { // top left, top right, bottom right, bottom left Vector4[] colors = new Vector4[4]; colors[0] = colors[1] = colors[2] = colors[3] = node.ObjectColor; var otkMat4 = node.ObjectMatrix * Matrix4x4.CreateTranslation(320, 240, 0); var q = new Quad(-0.5f, -0.5f, 0.5f, 0.5f, 1.0f, otkMat4, Vector2.Zero, Vector2.Zero, colors); if (doBoundingBox) { q.DrawBoundingBox(_gl); } else { q.Render(_gl); } }
private void RenderString(RenderTreeNode node, Text str) { var font = TextHelpers.GetFont(18); var(_, _, width, height) = TextHelpers.MeasureText(str.Value, new RendererOptions(font) { WrappingWidth = str.MaxWidth }); var xOffset = TextHelpers.CalculateXOffset((uint)str.Formatting, width); var yOffset = TextHelpers.CalculateYOffset((uint)str.Formatting, height); _glyphRenderer.Transform = node.ObjectMatrix * Matrix4x4.CreateTranslation(320, 240, 0); _glyphRenderer.Color = node.ObjectColor; _glyphRenderer.Formatting = str.Formatting; TextRenderer.RenderTextTo(_glyphRenderer, str.Value, new RendererOptions(font, new Vector2(xOffset, yOffset)) { WrappingWidth = str.MaxWidth, } ); }
private void RenderImage(RenderTreeNode node, IObject <ImageData> image, bool doBoundingBox = false) { var texture = GetTexture(image.ResourceRequest); if (texture == null) { return; } var otkMat4 = node.ObjectMatrix * Matrix4x4.CreateTranslation(320, 240, 0); // this is done by the game, basically a noop in most cases but sometimes relevant? // i think it's to do with square-ness and powers of two. or something uint CalculateDivisor(int value) { if (texture.Width == 0) { return(0); } var v10 = (uint)(value - 1) >> 1; uint divisor; for (divisor = 2; v10 != 0; divisor *= 2) { v10 >>= 1; } return(divisor); } var widthDivide = (float)CalculateDivisor(texture.Width); var heightDivide = (float)CalculateDivisor(texture.Height); var texUpLeft = new Vector2( texture.Width / widthDivide * node.UpperLeft.X, texture.Height / heightDivide * node.UpperLeft.Y ); var texLowRight = new Vector2( texture.Width / widthDivide * node.LowerRight.X, texture.Height / heightDivide * node.LowerRight.Y ); // top left, top right, bottom right, bottom left Vector4[] colors = new Vector4[4]; if (image is ColoredImage ci) { colors[0] = ci.Data.TopLeft; colors[1] = ci.Data.TopRight; colors[2] = ci.Data.BottomRight; colors[3] = ci.Data.BottomLeft; } else { colors[0] = colors[1] = colors[2] = colors[3] = node.ObjectColor; } var q = new Quad(-0.5f, -0.5f, 0.5f, 0.5f, 1.0f, otkMat4, texUpLeft, texLowRight, colors); if (doBoundingBox) { q.DrawBoundingBox(_gl); } else { q.Render(_gl, texture); } }