2222
2323package io .github .axolotlclient .waypoints .waypoints ;
2424
25- import java .util .concurrent .atomic .AtomicBoolean ;
25+ import java .util .concurrent .atomic .AtomicReference ;
2626
2727import com .mojang .blaze3d .systems .RenderSystem ;
2828import com .mojang .blaze3d .vertex .PoseStack ;
29+ import io .github .axolotlclient .AxolotlClientConfig .api .util .Colors ;
2930import io .github .axolotlclient .waypoints .AxolotlClientWaypoints ;
3031import io .github .axolotlclient .waypoints .mixin .GameRendererAccessor ;
3132import net .minecraft .client .Camera ;
3536import net .minecraft .client .renderer .MultiBufferSource ;
3637import net .minecraft .client .renderer .RenderType ;
3738import net .minecraft .world .phys .Vec3 ;
39+ import org .jetbrains .annotations .Nullable ;
3840import org .joml .Matrix4f ;
3941import org .joml .Quaternionf ;
42+ import org .joml .Vector3f ;
4043import org .joml .Vector4f ;
4144
4245public class WaypointRenderer {
@@ -46,19 +49,20 @@ public class WaypointRenderer {
4649 private final Matrix4f view = new Matrix4f ();
4750 private final Vector4f viewProj = new Vector4f ();
4851
49- public void render (PoseStack stack , MultiBufferSource .BufferSource source ) {
52+ public void render (PoseStack stack , MultiBufferSource .BufferSource source , float tick ) {
5053 var profiler = Minecraft .getInstance ().getProfiler ();
5154 profiler .popPush ("waypoints" );
5255 stack .pushPose ();
5356 var cam = minecraft .gameRenderer .getMainCamera ();
5457 var camPos = cam .getPosition ();
5558 minecraft .gameRenderer .resetProjectionMatrix (minecraft .gameRenderer .getProjectionMatrix (((GameRendererAccessor ) minecraft .gameRenderer ).invokeGetFov (cam , 0 , false )));
5659 RenderSystem .enableBlend ();
60+ float fov = (float ) ((GameRendererAccessor ) minecraft .gameRenderer ).invokeGetFov (cam , tick , true );
5761
5862 for (Waypoint waypoint : AxolotlClientWaypoints .getCurrentWaypoints ()) {
5963 if (waypoint .closerToThan (camPos .x (), camPos .y (), camPos .z (), CUTOFF_DIST / minecraft .getWindow ().getGuiScale ())) {
6064 profiler .push (waypoint .name ());
61- renderWaypoint (waypoint , stack , camPos , cam , source );
65+ renderWaypoint (waypoint , stack , camPos , cam , source , fov );
6266 profiler .pop ();
6367 }
6468 }
@@ -69,16 +73,25 @@ public void render(PoseStack stack, MultiBufferSource.BufferSource source) {
6973 }
7074 }
7175
72- private void renderWaypoint (Waypoint waypoint , PoseStack stack , Vec3 camPos , Camera cam , MultiBufferSource .BufferSource bufferSource ) {
76+ private void renderWaypoint (Waypoint waypoint , PoseStack stack , Vec3 camPos , Camera cam , MultiBufferSource .BufferSource bufferSource , float fov ) {
77+ int textWidth = minecraft .font .width (waypoint .display ());
78+ int width = textWidth + Waypoint .displayXOffset () * 2 ;
79+ int textHeight = minecraft .font .lineHeight ;
80+ int height = textHeight + Waypoint .displayYOffset () * 2 ;
81+ var displayStart = projectToScreen (cam , fov , width , height , waypoint .x () - (width / 2f * 0.04 ), waypoint .y () - (height / 2f * 0.04 ), waypoint .z ());
82+ if (displayStart == null ) return ;
83+ var displayEnd = projectToScreen (cam , fov , width , height , waypoint .x () + (width / 2f * 0.04 ), waypoint .y () + (height / 2f * 0.04 ), waypoint .z ());
84+ if (displayEnd == null ) return ;
85+ float projWidth = Math .abs (displayEnd .x () - displayStart .x ());
86+ float projHeight = Math .abs (displayEnd .y () - displayStart .y ());
87+ if (projWidth / width <= 1 && projHeight / height <= 1 ) {
88+ return ;
89+ }
7390 stack .pushPose ();
7491 stack .translate (waypoint .x () - camPos .x (), waypoint .y () - camPos .y (), waypoint .z () - camPos .z ());
7592 stack .mulPose (cam .rotation ());
7693 float scale = 0.04F ;
7794 stack .scale (-scale , -scale , scale );
78- int textWidth = minecraft .font .width (waypoint .display ());
79- //int width = textWidth + Waypoint.displayXOffset() * 2;
80- int textHeight = minecraft .font .lineHeight ;
81- //int height = textHeight + Waypoint.displayYOffset() * 2;
8295 //fillRect(stack, bufferSource, -width / 2f, -height / 2f, 0f, width / 2f, height / 2f, waypoint.color().toInt());
8396 drawFontBatch (waypoint .display (), -textWidth / 2f , -textHeight / 2f , stack .last ().pose (), bufferSource , waypoint .color ().toInt ());
8497 stack .popPose ();
@@ -106,73 +119,101 @@ public void renderWaypoints(GuiGraphics graphics, float delta) {
106119
107120 graphics .pose ().pushPose ();
108121 graphics .pose ().translate (0.0F , 0.0F , -100.0F );
109- var positionDrawn = new AtomicBoolean ();
122+ var positionDrawer = new AtomicReference < Runnable > ();
110123 for (Waypoint waypoint : AxolotlClientWaypoints .getCurrentWaypoints ()) {
111124 graphics .pose ().pushPose ();
112- renderWaypoint (waypoint , graphics , delta , cam , positionDrawn );
125+ renderWaypoint (waypoint , graphics , delta , cam , positionDrawer );
113126 graphics .pose ().popPose ();
114127 }
128+ if (positionDrawer .get () != null ) {
129+ positionDrawer .get ().run ();
130+ }
115131 graphics .pose ().popPose ();
116132 profiler .pop ();
117133 }
118134
119- private void renderWaypoint (Waypoint waypoint , GuiGraphics graphics , float tick , Camera camera , AtomicBoolean positionDrawn ) {
135+ private void renderWaypoint (Waypoint waypoint , GuiGraphics graphics , float tick , Camera camera , AtomicReference < Runnable > positionDrawn ) {
120136 var fov = ((GameRendererAccessor ) minecraft .gameRenderer ).invokeGetFov (camera , tick , true );
121137 var pose = graphics .pose ();
122138
123139 var textWidth = minecraft .font .width (waypoint .display ());
124140 int width = textWidth + Waypoint .displayXOffset () * 2 ;
125141 int textHeight = minecraft .font .lineHeight ;
126142 int height = textHeight + Waypoint .displayYOffset () * 2 ;
143+ var camPos = camera .getPosition ();
144+
145+ var displayStart = projectToScreen (camera , fov , width , height , waypoint .x () - (width / 2f * 0.04 ), waypoint .y () - (height / 2f * 0.04 ), waypoint .z ());
146+ if (displayStart == null ) return ;
147+ var displayEnd = projectToScreen (camera , fov , width , height , waypoint .x () + (width / 2f * 0.04 ), waypoint .y () + (height / 2f * 0.04 ), waypoint .z ());
148+ if (displayEnd == null ) return ;
149+ float projWidth = Math .abs (displayEnd .x () - displayStart .x ());
150+ float projHeight = Math .abs (displayEnd .y () - displayStart .y ());
151+ Result result = projectToScreen (camera , fov , width , height , waypoint .x (), waypoint .y (), waypoint .z ());
152+ if (result == null ) return ;
153+
154+ pose .translate (result .x (), result .y (), 0 );
155+
156+ if (!AxolotlClientWaypoints .renderOutOfViewWaypointsOnScreenEdge .get () && (result .x () < -width / 2f || result .x () > graphics .guiWidth () + width / 2f || result .y () < -height / 2f || result .y () > graphics .guiHeight () + height / 2f )) {
157+ return ;
158+ }
159+ if (projWidth / width > 1 || projHeight / height > 1 ) {
160+ return ;
161+ }
162+
163+ if (positionDrawn .get () == null && Math .abs (result .x () - graphics .guiWidth () / 2f ) < width / 2f && Math .abs (result .y () - graphics .guiHeight () / 2f ) < height / 2f ) {
164+ pose .pushPose ();
165+ pose .translate (0 , height / 2f + 2 , 0 );
166+ var pos = pose .last ().pose ().transformPosition (new Vector3f ());
167+ positionDrawn .set (() -> {
168+ var line1 = waypoint .name ();
169+ pose .pushPose ();
170+ pose .last ().pose ().translate (pos );
171+ int line1W = minecraft .font .width (line1 );
172+ graphics .fill (-line1W / 2 - 2 , -2 , line1W / 2 + 2 , minecraft .font .lineHeight + 2 , Colors .GRAY .withAlpha (100 ).toInt ());
173+ graphics .renderOutline (-line1W / 2 - 2 , -2 , line1W + 4 , minecraft .font .lineHeight + 4 , Colors .GRAY .toInt ());
174+ graphics .drawString (minecraft .font , line1 , -line1W / 2 , 0 , -1 , true );
175+ if (!waypoint .closerToThan (camPos .x (), camPos .y (), camPos .z (), CUTOFF_DIST )) {
176+ pose .translate (0 , minecraft .font .lineHeight + 4 , 0 );
177+ var line2 = AxolotlClientWaypoints .tr ("distance" , "%.2f" .formatted (waypoint .distTo (camPos .x (), camPos .y (), camPos .z ())));
178+ graphics .drawString (minecraft .font , line2 , -minecraft .font .width (line2 ) / 2 , 0 , -1 , false );
179+ }
180+ pose .popPose ();
181+ });
182+ pose .popPose ();
183+ }
184+
185+ graphics .fill (-width / 2 , -height / 2 , width / 2 , height / 2 , waypoint .color ().toInt ());
186+ graphics .drawString (minecraft .font , waypoint .display (), -textWidth / 2 , -textHeight / 2 , -1 , false );
187+ }
127188
128- viewProj .set (waypoint .x (), waypoint .y (), waypoint .z (), 1 );
189+ private @ Nullable Result projectToScreen (Camera camera , double fov , int width , int height , double x , double y , double z ) {
190+ viewProj .set (x , y , z , 1 );
129191 view .rotation (camera .rotation ().rotateY ((float ) -(Math .PI ), new Quaternionf ()).invert ()).translate (camera .getPosition ().toVector3f ().negate ());
130192
131193 Matrix4f projection = minecraft .gameRenderer .getProjectionMatrix (fov );
132194 projection .mul (view );
133195 viewProj .mul (projection );
134196
135- var camPos = camera .getPosition ();
136197
137198 if (AxolotlClientWaypoints .renderOutOfViewWaypointsOnScreenEdge .get ()) {
138199 viewProj .w = Math .max (Math .abs (viewProj .x ()), Math .max (Math .abs (viewProj .y ()), viewProj .w ()));
139200 }
140201
141202 if (viewProj .w () <= 0 ) {
142- return ;
203+ return null ;
143204 }
144205 viewProj .div (viewProj .w ());
145206
146207 float projX = viewProj .x ();
147208 float projY = viewProj .y ();
148209
149210 //float x = (graphics.guiWidth()/2f) + ((graphics.guiWidth() - width) * (viewProj.x() / 2f));
150- float x = 0.5f * (graphics . guiWidth () * (projX + 1 ) - width * projX );
211+ float resultX = 0.5f * (minecraft . getWindow (). getGuiScaledWidth () * (projX + 1 ) - width * projX );
151212 //float y = graphics.guiHeight() - (graphics.guiHeight()/2f + (graphics.guiHeight()-height) * (viewProj.y() / 2f));
152- float y = graphics .guiHeight () * (0.5f - projY / 2 ) + (height * projY ) / 2f ;
153-
154- pose .translate (x , y , 0 );
155-
156- if (!AxolotlClientWaypoints .renderOutOfViewWaypointsOnScreenEdge .get () && (x < -width / 2f || x > graphics .guiWidth () + width / 2f || y < -height / 2f || y > graphics .guiHeight () + height / 2f )) {
157- return ;
158- }
159- if (waypoint .closerToThan (camPos .x (), camPos .y (), camPos .z (), CUTOFF_DIST / minecraft .getWindow ().getGuiScale ())) {
160- return ;
161- }
162-
163- if (!positionDrawn .get () && Math .abs (x - graphics .guiWidth () / 2f ) < 8 && Math .abs (y - graphics .guiHeight () / 2f ) < 8 ) {
164- positionDrawn .set (true );
165- pose .pushPose ();
166- pose .translate (0 , height / 2f + 2 , 0 );
167- var line1 = waypoint .name ();
168- graphics .drawString (minecraft .font , line1 , -minecraft .font .width (line1 ) / 2 , 0 , -1 , false );
169- pose .translate (0 , minecraft .font .lineHeight + 2 , 0 );
170- var line2 = AxolotlClientWaypoints .tr ("distance" , "%.2f" .formatted (waypoint .distTo (camPos .x (), camPos .y (), camPos .z ())));
171- graphics .drawString (minecraft .font , line2 , -minecraft .font .width (line2 ) / 2 , 0 , -1 , false );
172- pose .popPose ();
173- }
213+ float resultY = minecraft .getWindow ().getGuiScaledWidth () * (0.5f - projY / 2 ) + (height * projY ) / 2f ;
214+ return new Result (resultX , resultY );
215+ }
174216
175- graphics .fill (-width / 2 , -height / 2 , width / 2 , height / 2 , waypoint .color ().toInt ());
176- graphics .drawString (minecraft .font , waypoint .display (), -textWidth / 2 , -textHeight / 2 , -1 , false );
217+ private record Result (float x , float y ) {
177218 }
178219}
0 commit comments