capture projection/view matrices for world-to-screen projection
MatrixCapture keeps the matrices from the level render pass so 2d overlays (nametags) can project world positions onto the gui-scaled screen.
This commit is contained in:
@@ -7,6 +7,7 @@ import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.math.Axis;
|
||||
import cc.fros.event.impl.render.Render3DEvent;
|
||||
import cc.fros.event.impl.render.RenderBlockOutlineEvent;
|
||||
import cc.fros.util.render.MatrixCapture;
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.DeltaTracker;
|
||||
import net.minecraft.client.renderer.LevelRenderer;
|
||||
@@ -37,6 +38,9 @@ public class MixinLevelRenderer {
|
||||
Camera camera, Matrix4f positionMatrix, Matrix4f matrix4f, Matrix4f projectionMatrix,
|
||||
GpuBufferSlice fogBuffer, Vector4f fogColor, boolean renderSky, CallbackInfo ci, @Local ProfilerFiller profiler) {
|
||||
|
||||
MatrixCapture.projection = new Matrix4f(projectionMatrix);
|
||||
MatrixCapture.view = new Matrix4f(positionMatrix);
|
||||
|
||||
PoseStack stack = new PoseStack();
|
||||
stack.pushPose();
|
||||
stack.mulPose(Axis.XP.rotationDegrees(mc.gameRenderer.getMainCamera().xRot()));
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
package cc.fros.util.render;
|
||||
|
||||
import cc.fros.util.traits.Util;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector4f;
|
||||
|
||||
/**
|
||||
* Projection/view matrices captured during the level pass, used to project
|
||||
* world positions onto the gui-scaled screen for 2d overlays like nametags.
|
||||
*/
|
||||
public final class MatrixCapture implements Util {
|
||||
public static Matrix4f projection;
|
||||
public static Matrix4f view;
|
||||
|
||||
private MatrixCapture() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
public static float[] worldToScreen(double worldX, double worldY, double worldZ) {
|
||||
if (projection == null || view == null) return null;
|
||||
|
||||
Vec3 camPos = mc.gameRenderer.getMainCamera().position();
|
||||
Matrix4f mvp = projection.mul(view, new Matrix4f());
|
||||
|
||||
Vector4f point = new Vector4f(
|
||||
(float) (worldX - camPos.x()),
|
||||
(float) (worldY - camPos.y()),
|
||||
(float) (worldZ - camPos.z()),
|
||||
1.0f
|
||||
);
|
||||
mvp.transform(point);
|
||||
|
||||
if (point.w <= 0.0f) return null;
|
||||
|
||||
float ndcX = point.x / point.w;
|
||||
float ndcY = point.y / point.w;
|
||||
|
||||
if (ndcX < -1.1f || ndcX > 1.1f || ndcY < -1.1f || ndcY > 1.1f) return null;
|
||||
|
||||
int guiW = mc.getWindow().getGuiScaledWidth();
|
||||
int guiH = mc.getWindow().getGuiScaledHeight();
|
||||
|
||||
return new float[]{
|
||||
(ndcX + 1.0f) / 2.0f * guiW,
|
||||
(1.0f - ndcY) / 2.0f * guiH
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user