From 9e508bb29cbdd3876787162d1bd32a781ccf055f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolaj=20=C3=98sterby=20Jensen?= Date: Tue, 22 Oct 2024 18:48:33 +0200 Subject: [PATCH 1/5] Fix XY swap and add Rect2D and Rect3D --- RLBotCS/ManagerTools/PerfMonitor.cs | 4 +- RLBotCS/ManagerTools/QuickChat.cs | 8 +- RLBotCS/ManagerTools/Rendering.cs | 110 ++++++++++++++++++++++++++-- RLBotCS/lib/Bridge.dll | Bin 137728 -> 137216 bytes flatbuffers-schema | 2 +- 5 files changed, 112 insertions(+), 12 deletions(-) diff --git a/RLBotCS/ManagerTools/PerfMonitor.cs b/RLBotCS/ManagerTools/PerfMonitor.cs index 84c41b1..67800a9 100644 --- a/RLBotCS/ManagerTools/PerfMonitor.cs +++ b/RLBotCS/ManagerTools/PerfMonitor.cs @@ -75,8 +75,8 @@ public void RenderSummary(Rendering rendering, GameState gameState, float deltaT var renderText = new String2DT() { - Y = 10f / 1920f, - X = 200f / 1080f, + X = 10f / Rendering.ResolutionWidthPixels, + Y = 200f / Rendering.ResolutionHeightPixels, Text = message, Foreground = TextColor, Background = BackColor, diff --git a/RLBotCS/ManagerTools/QuickChat.cs b/RLBotCS/ManagerTools/QuickChat.cs index f5d97a6..73711f9 100644 --- a/RLBotCS/ManagerTools/QuickChat.cs +++ b/RLBotCS/ManagerTools/QuickChat.cs @@ -71,7 +71,7 @@ public void RenderChats(Rendering rendering, GameState gameState) return; _hasUpdate = false; - int xVal = 10; + float yVal = 10f; List renderMessages = new(); foreach (var chat in _chats) @@ -82,8 +82,8 @@ public void RenderChats(Rendering rendering, GameState gameState) new() { Text = chat.Item2.Display, - Y = 10f / 1920f, - X = xVal / 1080f, + X = 10f / Rendering.ResolutionWidthPixels, + Y = yVal / Rendering.ResolutionHeightPixels, Scale = 1, Foreground = textColor, Background = BackgroundColor, @@ -95,7 +95,7 @@ public void RenderChats(Rendering rendering, GameState gameState) new RenderMessageT() { Variety = RenderTypeUnion.FromString2D(message), } ); - xVal += 20; + yVal += Rendering.FontHeightPixels; } if (renderMessages.Count > 0) diff --git a/RLBotCS/ManagerTools/Rendering.cs b/RLBotCS/ManagerTools/Rendering.cs index 8c01749..8f50798 100644 --- a/RLBotCS/ManagerTools/Rendering.cs +++ b/RLBotCS/ManagerTools/Rendering.cs @@ -1,21 +1,29 @@ +using System.Text; using Bridge.Controller; using Bridge.State; using Bridge.TCP; +using Microsoft.Extensions.Primitives; using rlbot.flat; using RLBotCS.Conversion; +using Color = System.Drawing.Color; namespace RLBotCS.ManagerTools; public class Rendering(TcpMessenger tcpMessenger) { - private static int MaxClearsPerTick = 1024; + private const int MaxClearsPerTick = 1024; + public const int ResolutionWidthPixels = 1920; + public const int ResolutionHeightPixels = 1080; + public const int FontWidthPixels = 10; + public const int FontHeightPixels = 20; + private readonly RenderingSender _renderingSender = new(tcpMessenger); private readonly Dictionary>> _clientRenderTracker = []; private readonly Queue _RenderClearQueue = new(); - private ushort? RenderItem(RenderTypeUnion renderItem, GameState gameState) => + private ushort RenderItem(RenderTypeUnion renderItem, GameState gameState) => renderItem.Value switch { Line3DT { Start: var start, End: var end, Color: var color } @@ -69,9 +77,100 @@ public class Rendering(TcpMessenger tcpMessenger) (byte)vAlign, scale ), - _ => null + Rect2DT rect2Dt => SendRect2D(rect2Dt), + Rect3DT rect3Dt => SendRect3D(rect3Dt, gameState), + _ => throw new NotImplementedException("Unknown RenderMessage"), }; + private ushort SendRect2D(Rect2DT rect2Dt) + { + // Move rect left/up when width/height is negative + var adjustedX = !rect2Dt.Centered && rect2Dt.Width < 0 ? rect2Dt.X - rect2Dt.Width : rect2Dt.X; + var adjustedY = !rect2Dt.Centered && rect2Dt.Height < 0 ? rect2Dt.Y - rect2Dt.Height : rect2Dt.X; + + // Fake a filled rectangle using a string with colored background + var (text, scale) = MakeFakeRectangleString( + (int)Math.Abs(rect2Dt.Width * ResolutionWidthPixels), + (int)Math.Abs(rect2Dt.Height * ResolutionHeightPixels)); + + var hAlign = rect2Dt.Centered ? TextHAlign.Center : TextHAlign.Left; + var vAlign = rect2Dt.Centered ? TextHAlign.Center : TextHAlign.Left; + + return _renderingSender.AddText2D( + text, + adjustedX, + adjustedY, + Color.Transparent, // Foreground + FlatToModel.ToColor(rect2Dt.Color), // Background + (byte)hAlign, + (byte)vAlign, + scale + ); + } + + private ushort SendRect3D(Rect3DT rect3Dt, GameState gameState) + { + // Fake a filled rectangle using a string with colored background + var (text, scale) = MakeFakeRectangleString( + (int)Math.Abs(rect3Dt.Width * ResolutionWidthPixels), + (int)Math.Abs(rect3Dt.Height * ResolutionHeightPixels)); + + return _renderingSender.AddText3D( + text, + FlatToModel.ToRenderAnchor(rect3Dt.Anchor, gameState), + Color.Transparent, + FlatToModel.ToColor(rect3Dt.Color), + (byte)TextHAlign.Center, + (byte)TextVAlign.Center, + scale + ); + } + + /// + /// Computes a string in the shape of a rectangle. The rectangle has the given width and height in pixels when + /// scaled the string is scaled with returned scaling factor. We use this as a hack to created filled rectangles + /// for rectangle rendering. + /// + /// + private (string, float) MakeFakeRectangleString(int width, int height) + { + int Gcd(int a, int b) + { + // Greatest common divisor by Euclidean algorithm https://stackoverflow.com/a/41766138 + while (a != 0 && b != 0) + { + if (a > b) + a %= b; + else + b %= a; + } + + return a | b; + } + + // We use the greatest common divisor to simplify the fraction (width/height) + // minimizing the characters needed for the rectangle. + int gcd = Gcd(width, height); + int cols = (width / gcd) * (FontHeightPixels / FontWidthPixels); + int rows = height / gcd; + + StringBuilder str = new StringBuilder(cols * rows + rows); + for (int r = 0; r < rows; r++) + { + for (int c = 0; c < cols; c++) + { + str.Append(' '); + } + + if (r + 1 < rows) + { + str.Append('\n'); + } + } + + return (str.ToString(), gcd / (float)FontHeightPixels); + } + public void AddRenderGroup( int clientId, int renderId, @@ -86,8 +185,9 @@ GameState gameState List renderGroup = []; foreach (RenderMessageT renderItem in renderItems) - if (RenderItem(renderItem.Variety, gameState) is { } renderItemId) - renderGroup.Add(renderItemId); + { + renderGroup.Add(RenderItem(renderItem.Variety, gameState)); + } _renderingSender.Send(); diff --git a/RLBotCS/lib/Bridge.dll b/RLBotCS/lib/Bridge.dll index 98c006769bad49947d83785627a417a1480e557b..4bfedc0f3e2272604bd8c8eefda70f7a7cd4ecd8 100644 GIT binary patch delta 1821 zcmaKte@q)?7{{OIEe8b(Tq!@waEu=z6i_IocV$jwbDiim1_~G!_luHNk+@rgX$;Y_ z7}>JKLAhj|ZgYPa3^N)9hGiil%WyFolqDl%{;@5_xVgXp`7v=$eXhN3V>MoL-+Mma z@B6;J=km7Kc1GLwg|_oh=A~5w--CKwgUpO*Gz0JqAUt5+D)fBvLhOk`29=7jp1}@{ zC&QrI!$3#eM!_R;276TAjyX{aaWpZVY+gQ$`4}&Mi8+`gU%||jaT=%`&(O($gAoJ5 zNGbw)Gvb-8zlya@yKhjIiJ)&D1Bl9A6K!e+$j>&lkVYj%$3ui^3L%QMKEWWYIwHC5 z0jo6BdNR~13$>`B;9BnB`WxB^%Nh`kX|A@6#g)aD9(8{~nypQ%% zb{v>)Q72NP3Ns2csW6L>5GB2;(wq`W1bO{8=GI}_@5H8E9E7vh8d}!0n@SyPt)*Hk z&C46+S0ygckjF4DFdz^~i}JpCtNXUH*dHW;Oj=%9N>+OA4@A#l!-ax>E3ROTIK=@16c{13rfHR0s5W{`6ix)J3c7wn`7ixLat z1cQs#Qtdai3*H83q3cu%)zvMpHST?hegFV_t^)MXdRevAp#6n@T*{6quYJ}|S0izc zoV!$py8gzclW8eOM1+Ibo|{3sqV}yx#MSlgOF}P>#3D`g(1=;0?zkY`A-Z;tG-5Bl z&j&Ld(Wsve(7eZq*6Wq5ov4jy(N71Un&m?u#>D$GV_&>N=6fW&#Xj5|Kp5hVS^Ke0 zr5^4B@eDSpbd)<{9mF?P8smPlp2b5d{mji+htR8%#L3pLuv?{fI8Ved_NlbU<-;(J z2Z(M)7M;U*Qw`n5kHxPsk^YCM3x7C*g#m)&$b@rPrc#%|E{x(fmAdgW@dCcAk_U&y zF?>&@Ph*Z*C-AuM)EkJ#vMY@sSNxFr9g|yo5 zzsTEt!cjb#!d(>-#B$%{=QtM;c|rJ1$Po*~{l1GnEY}z&G}n!jbWUi_Mo-c?t#SJD zhp;z|x9h%(9r^a))`5z>?Ypt~v~TJ%o)R>X5zN~W$4ZsLHy+2jaOYZ!*=8wjs241b z2CGGM2{va#iPPqA6*LNq<)hYn>Q2agka2BYdLLh-J6&*@pJ zhTa<9>v~r1i%np|ta2?_zzjChVrYPR5U6rcWu>bKE@B%viAzXrl(?XXRHTtgWhQme dOb30Gyu_QD%zlkb54_1{%Y1qxn?a8`;$L(rgD?O9 delta 1855 zcmaKt4{Q@v9LImZ*WOmPuDfxP73iA70R zu$vk*NN}ZY#UMdLNG6#MwuOT&Ow3S>5koWtrbL%zQ3K)_`-4*l{_c81YK@n?-@VWG z`+o1<@9wp);kd4$OV{*f=Ft417ErGN$h5?w6~M#*qC%p<>OZ#D&^4FAld|wIgAE$L zB|*QDfu8sP8EF9vdoZvL=fouPl$b%XDX<6gF)?rw=U__U2h2>pNdx6;88rqRe35`~ zaV7!=T}jN*xr#O1@LeY_6Tz4s8x!Tdh7gk-mE#4-&(7ISG1ja%p)ThJ>8!qlfwn@I z{M3C?X{0niQd$rxQBBHRzWXM7By!loNNG`|R2C^Mj+B;6OL>rB)xcFMJPUnl<-dh0 ze@UtQ<$o$4Rw{p#Qp=|+4@oN`rN<(r$0MaD!X%$E|H?3pBy-r){*PGws(&Z5`qk4? z-Zk$w+E&@|kaLr!^=wvQM20N{X|i=ormd|`%<{^#+(niy)<0O+ruTBde z(yPm+J;UlN=|P?evL3=bR=r{8K4F5BEhaTQSy4cEMOTsikiUru`-JKaS!9P zfnDP^g5%@%(!|ebAG`w4K=)r$sb8`E#mz5lqTc{O-H!mRG+$O_1tbmu@baEnTDiQ8 z?hg>R1uPQ_(9r3cI5a!8Nkn)9cjsCthV`Z7B%I~)T@p^rV3JAkQaVgB72l&~pV)!rA%q_8 zfV~qps?^H8Cw8G%r50|V{S-E;bbATr@oT&mLkgfihAu2tzMwu_(R zHkJH%R=j}CDz(KOuwTL>Qg8=iO4eT1VH(s&gh@6LcT!lx?T`Cfct_DU$o*jZ z+bE>37wa@E_Fc$@_4+|=E)*KuwX0#LzK>#g^46fH2?hLJayH=+Zn2kt-%$X4hPhAx zS^Pz@0P^{Mibecgit~6Kxr_KE6j$)&6f5}WC_c^CQLI+b+ zaU^=idEvT{D_X@J(isVtY7#DMeopD9c3E>ewx8OFW|NfMgC}P5u36uHoW3t*argJn zy#Cgg3lBJs48+etHc_Y&21|za=6`9F2UihE);5u zYn?Wm=&%=yg<_FY0MH@C`YnmUy+)=tcNrO6RSypOK5$3wXZS5<4IL+R3I)G0vJxr7 z%mz?0m{>1cSp`Ml04G#|2sPjW8@Qv*eVG_zs!TciI5wK|OZ diff --git a/flatbuffers-schema b/flatbuffers-schema index 15d09b4..9780405 160000 --- a/flatbuffers-schema +++ b/flatbuffers-schema @@ -1 +1 @@ -Subproject commit 15d09b465b0620ec3eac114d9996a673b478d258 +Subproject commit 9780405f7a7e1966c271a11de92ff06d5b985eef From 89674a1749d71ab4da138d32f0e54aa87bb7c854 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolaj=20=C3=98sterby=20Jensen?= Date: Tue, 22 Oct 2024 18:49:01 +0200 Subject: [PATCH 2/5] Fix RLBOT_AGENT_ID for scripts --- RLBotCS/ManagerTools/LaunchManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RLBotCS/ManagerTools/LaunchManager.cs b/RLBotCS/ManagerTools/LaunchManager.cs index ce11da6..4f89201 100644 --- a/RLBotCS/ManagerTools/LaunchManager.cs +++ b/RLBotCS/ManagerTools/LaunchManager.cs @@ -180,7 +180,7 @@ int rlbotSocketsPort if (script.Location != "") scriptProcess.StartInfo.WorkingDirectory = script.Location; - scriptProcess.StartInfo.EnvironmentVariables["RLBOT_GROUP_ID"] = script.AgentId; + scriptProcess.StartInfo.EnvironmentVariables["RLBOT_AGENT_ID"] = script.AgentId; scriptProcess.StartInfo.EnvironmentVariables["RLBOT_SERVER_PORT"] = rlbotSocketsPort.ToString(); From 963e4bbf4df419ddd6e5407bd89000c242cf8704 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolaj=20=C3=98sterby=20Jensen?= Date: Tue, 22 Oct 2024 22:02:55 +0200 Subject: [PATCH 3/5] Update bridge and flatbuffers --- RLBotCS/lib/Bridge.dll | Bin 137216 -> 137216 bytes flatbuffers-schema | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/RLBotCS/lib/Bridge.dll b/RLBotCS/lib/Bridge.dll index 4bfedc0f3e2272604bd8c8eefda70f7a7cd4ecd8..15c99d5e5c697a8e54b7342898b0edd9e4000665 100644 GIT binary patch delta 173 zcmZqJz|pXQV?qbZjAsweH}-7pVYIm^z+}pK{*vq@*Hz5IhR1646}R8G$yj2po@i`j zW@>7joMK>*m~50{nQWeDo@kn8oM>!joM>rcX_07XV40S-y;zVblG!(r!I;5_!HmHa z2#pz%8B!PwfG`orG6J$KfwVc02g0TdX+RYq^=4q&lEDNhZvhlB1nRH^%BF3X6lHqO F1OQm2E9U?J delta 173 zcmZqJz|pXQV?qbZ6{)SK8+*3)FxuP{aN#+{ci=?3&sN{Ows=P4mD_LJWGpdPw=^;^ zH!@C6G&M>}HZd|wGc`|5wn#NkN;6C{OH4B~NJ}$LN=h}~UM$EI$?R*%V8md+U=AdW z8Il diff --git a/flatbuffers-schema b/flatbuffers-schema index 9780405..89c82c6 160000 --- a/flatbuffers-schema +++ b/flatbuffers-schema @@ -1 +1 @@ -Subproject commit 9780405f7a7e1966c271a11de92ff06d5b985eef +Subproject commit 89c82c69a26c31995faad771b4f911e55afb31bc From eb7c614d061f1f1c7139beb15dbd67f835933050 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolaj=20=C3=98sterby=20Jensen?= Date: Tue, 22 Oct 2024 22:16:00 +0200 Subject: [PATCH 4/5] Fix bridge and flatbuffer schema --- RLBotCS/lib/Bridge.dll | Bin 137216 -> 137216 bytes flatbuffers-schema | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/RLBotCS/lib/Bridge.dll b/RLBotCS/lib/Bridge.dll index 15c99d5e5c697a8e54b7342898b0edd9e4000665..f1a9d420e5af14a30e04c94d1cb70e0f49e7d29e 100644 GIT binary patch delta 176 zcmZqJz|pXQV?qZ@+3DcZjXhg?7;SC}Xx86&X2SK_eZq(TjZ5dVZrFa~CS!@YMoMCm zNlL1jp|OQ=a;mw3frUkKs*$mUd7_DNqJ>G4g^`JwQJT3~;`S0jrU+*L6oy2GBnA_P z6oym=GX_HjV+IQ#P6qPK84Q5X0ti7oBe0A)P_+q=l?W6y0qU~=ikkrS88M^*)tfOS LZkHBidddU7joMK>*m~50{nQWeDo@kn8oM>!joM>rcX_07XV40R?vAsl)DT3KQk-?b3h{24( z6bOwOk{MDM41h2Z$T9-5ErGN-kO#u13~4|WAoXTo+LFNpC~pB2F$C(c1j?o{SZtRT IWqQg40O4mWS^xk5 diff --git a/flatbuffers-schema b/flatbuffers-schema index 89c82c6..a01a99d 160000 --- a/flatbuffers-schema +++ b/flatbuffers-schema @@ -1 +1 @@ -Subproject commit 89c82c69a26c31995faad771b4f911e55afb31bc +Subproject commit a01a99dedbe9f7b58e3f91191dbd20e90c476d84 From c29ef2426cdc7dbbdf504b1798205bb9711e6d5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolaj=20=C3=98sterby=20Jensen?= Date: Tue, 22 Oct 2024 22:21:53 +0200 Subject: [PATCH 5/5] Formatting --- RLBotCS/ManagerTools/Rendering.cs | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/RLBotCS/ManagerTools/Rendering.cs b/RLBotCS/ManagerTools/Rendering.cs index 8f50798..4fb9e1f 100644 --- a/RLBotCS/ManagerTools/Rendering.cs +++ b/RLBotCS/ManagerTools/Rendering.cs @@ -2,7 +2,6 @@ using Bridge.Controller; using Bridge.State; using Bridge.TCP; -using Microsoft.Extensions.Primitives; using rlbot.flat; using RLBotCS.Conversion; using Color = System.Drawing.Color; @@ -17,7 +16,7 @@ public class Rendering(TcpMessenger tcpMessenger) public const int ResolutionHeightPixels = 1080; public const int FontWidthPixels = 10; public const int FontHeightPixels = 20; - + private readonly RenderingSender _renderingSender = new(tcpMessenger); private readonly Dictionary>> _clientRenderTracker = []; @@ -85,17 +84,20 @@ private ushort RenderItem(RenderTypeUnion renderItem, GameState gameState) => private ushort SendRect2D(Rect2DT rect2Dt) { // Move rect left/up when width/height is negative - var adjustedX = !rect2Dt.Centered && rect2Dt.Width < 0 ? rect2Dt.X - rect2Dt.Width : rect2Dt.X; - var adjustedY = !rect2Dt.Centered && rect2Dt.Height < 0 ? rect2Dt.Y - rect2Dt.Height : rect2Dt.X; - + var adjustedX = + !rect2Dt.Centered && rect2Dt.Width < 0 ? rect2Dt.X - rect2Dt.Width : rect2Dt.X; + var adjustedY = + !rect2Dt.Centered && rect2Dt.Height < 0 ? rect2Dt.Y - rect2Dt.Height : rect2Dt.X; + // Fake a filled rectangle using a string with colored background var (text, scale) = MakeFakeRectangleString( - (int)Math.Abs(rect2Dt.Width * ResolutionWidthPixels), - (int)Math.Abs(rect2Dt.Height * ResolutionHeightPixels)); - + (int)Math.Abs(rect2Dt.Width * ResolutionWidthPixels), + (int)Math.Abs(rect2Dt.Height * ResolutionHeightPixels) + ); + var hAlign = rect2Dt.Centered ? TextHAlign.Center : TextHAlign.Left; var vAlign = rect2Dt.Centered ? TextHAlign.Center : TextHAlign.Left; - + return _renderingSender.AddText2D( text, adjustedX, @@ -112,9 +114,10 @@ private ushort SendRect3D(Rect3DT rect3Dt, GameState gameState) { // Fake a filled rectangle using a string with colored background var (text, scale) = MakeFakeRectangleString( - (int)Math.Abs(rect3Dt.Width * ResolutionWidthPixels), - (int)Math.Abs(rect3Dt.Height * ResolutionHeightPixels)); - + (int)Math.Abs(rect3Dt.Width * ResolutionWidthPixels), + (int)Math.Abs(rect3Dt.Height * ResolutionHeightPixels) + ); + return _renderingSender.AddText3D( text, FlatToModel.ToRenderAnchor(rect3Dt.Anchor, gameState), @@ -151,7 +154,7 @@ int Gcd(int a, int b) // We use the greatest common divisor to simplify the fraction (width/height) // minimizing the characters needed for the rectangle. int gcd = Gcd(width, height); - int cols = (width / gcd) * (FontHeightPixels / FontWidthPixels); + int cols = (width / gcd) * (FontHeightPixels / FontWidthPixels); int rows = height / gcd; StringBuilder str = new StringBuilder(cols * rows + rows);