22
22
23
23
package io .github .axolotlclient .waypoints .waypoints ;
24
24
25
- import java .util .concurrent .atomic .AtomicBoolean ;
25
+ import java .util .concurrent .atomic .AtomicReference ;
26
26
27
27
import com .mojang .blaze3d .systems .RenderSystem ;
28
28
import com .mojang .blaze3d .vertex .PoseStack ;
29
+ import io .github .axolotlclient .AxolotlClientConfig .api .util .Colors ;
29
30
import io .github .axolotlclient .waypoints .AxolotlClientWaypoints ;
30
31
import io .github .axolotlclient .waypoints .mixin .GameRendererAccessor ;
31
32
import net .minecraft .client .Camera ;
35
36
import net .minecraft .client .renderer .MultiBufferSource ;
36
37
import net .minecraft .client .renderer .RenderType ;
37
38
import net .minecraft .world .phys .Vec3 ;
39
+ import org .jetbrains .annotations .Nullable ;
38
40
import org .joml .Matrix4f ;
39
41
import org .joml .Quaternionf ;
42
+ import org .joml .Vector3f ;
40
43
import org .joml .Vector4f ;
41
44
42
45
public class WaypointRenderer {
@@ -46,19 +49,20 @@ public class WaypointRenderer {
46
49
private final Matrix4f view = new Matrix4f ();
47
50
private final Vector4f viewProj = new Vector4f ();
48
51
49
- public void render (PoseStack stack , MultiBufferSource .BufferSource source ) {
52
+ public void render (PoseStack stack , MultiBufferSource .BufferSource source , float tick ) {
50
53
var profiler = Minecraft .getInstance ().getProfiler ();
51
54
profiler .popPush ("waypoints" );
52
55
stack .pushPose ();
53
56
var cam = minecraft .gameRenderer .getMainCamera ();
54
57
var camPos = cam .getPosition ();
55
58
minecraft .gameRenderer .resetProjectionMatrix (minecraft .gameRenderer .getProjectionMatrix (((GameRendererAccessor ) minecraft .gameRenderer ).invokeGetFov (cam , 0 , false )));
56
59
RenderSystem .enableBlend ();
60
+ float fov = (float ) ((GameRendererAccessor ) minecraft .gameRenderer ).invokeGetFov (cam , tick , true );
57
61
58
62
for (Waypoint waypoint : AxolotlClientWaypoints .getCurrentWaypoints ()) {
59
63
if (waypoint .closerToThan (camPos .x (), camPos .y (), camPos .z (), CUTOFF_DIST / minecraft .getWindow ().getGuiScale ())) {
60
64
profiler .push (waypoint .name ());
61
- renderWaypoint (waypoint , stack , camPos , cam , source );
65
+ renderWaypoint (waypoint , stack , camPos , cam , source , fov );
62
66
profiler .pop ();
63
67
}
64
68
}
@@ -69,16 +73,25 @@ public void render(PoseStack stack, MultiBufferSource.BufferSource source) {
69
73
}
70
74
}
71
75
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
+ }
73
90
stack .pushPose ();
74
91
stack .translate (waypoint .x () - camPos .x (), waypoint .y () - camPos .y (), waypoint .z () - camPos .z ());
75
92
stack .mulPose (cam .rotation ());
76
93
float scale = 0.04F ;
77
94
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;
82
95
//fillRect(stack, bufferSource, -width / 2f, -height / 2f, 0f, width / 2f, height / 2f, waypoint.color().toInt());
83
96
drawFontBatch (waypoint .display (), -textWidth / 2f , -textHeight / 2f , stack .last ().pose (), bufferSource , waypoint .color ().toInt ());
84
97
stack .popPose ();
@@ -106,73 +119,101 @@ public void renderWaypoints(GuiGraphics graphics, float delta) {
106
119
107
120
graphics .pose ().pushPose ();
108
121
graphics .pose ().translate (0.0F , 0.0F , -100.0F );
109
- var positionDrawn = new AtomicBoolean ();
122
+ var positionDrawer = new AtomicReference < Runnable > ();
110
123
for (Waypoint waypoint : AxolotlClientWaypoints .getCurrentWaypoints ()) {
111
124
graphics .pose ().pushPose ();
112
- renderWaypoint (waypoint , graphics , delta , cam , positionDrawn );
125
+ renderWaypoint (waypoint , graphics , delta , cam , positionDrawer );
113
126
graphics .pose ().popPose ();
114
127
}
128
+ if (positionDrawer .get () != null ) {
129
+ positionDrawer .get ().run ();
130
+ }
115
131
graphics .pose ().popPose ();
116
132
profiler .pop ();
117
133
}
118
134
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 ) {
120
136
var fov = ((GameRendererAccessor ) minecraft .gameRenderer ).invokeGetFov (camera , tick , true );
121
137
var pose = graphics .pose ();
122
138
123
139
var textWidth = minecraft .font .width (waypoint .display ());
124
140
int width = textWidth + Waypoint .displayXOffset () * 2 ;
125
141
int textHeight = minecraft .font .lineHeight ;
126
142
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
+ }
127
188
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 );
129
191
view .rotation (camera .rotation ().rotateY ((float ) -(Math .PI ), new Quaternionf ()).invert ()).translate (camera .getPosition ().toVector3f ().negate ());
130
192
131
193
Matrix4f projection = minecraft .gameRenderer .getProjectionMatrix (fov );
132
194
projection .mul (view );
133
195
viewProj .mul (projection );
134
196
135
- var camPos = camera .getPosition ();
136
197
137
198
if (AxolotlClientWaypoints .renderOutOfViewWaypointsOnScreenEdge .get ()) {
138
199
viewProj .w = Math .max (Math .abs (viewProj .x ()), Math .max (Math .abs (viewProj .y ()), viewProj .w ()));
139
200
}
140
201
141
202
if (viewProj .w () <= 0 ) {
142
- return ;
203
+ return null ;
143
204
}
144
205
viewProj .div (viewProj .w ());
145
206
146
207
float projX = viewProj .x ();
147
208
float projY = viewProj .y ();
148
209
149
210
//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 );
151
212
//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
+ }
174
216
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 ) {
177
218
}
178
219
}
0 commit comments