119 lines
		
	
	
	
		
			3.6 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			119 lines
		
	
	
	
		
			3.6 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| package net.minecraft.client.renderer.culling;
 | |
| 
 | |
| import net.fabricmc.api.EnvType;
 | |
| import net.fabricmc.api.Environment;
 | |
| import net.minecraft.world.level.levelgen.structure.BoundingBox;
 | |
| import net.minecraft.world.phys.AABB;
 | |
| import org.joml.FrustumIntersection;
 | |
| import org.joml.Matrix4f;
 | |
| import org.joml.Vector4f;
 | |
| 
 | |
| @Environment(EnvType.CLIENT)
 | |
| public class Frustum {
 | |
| 	public static final int OFFSET_STEP = 4;
 | |
| 	private final FrustumIntersection intersection = new FrustumIntersection();
 | |
| 	private final Matrix4f matrix = new Matrix4f();
 | |
| 	private Vector4f viewVector;
 | |
| 	private double camX;
 | |
| 	private double camY;
 | |
| 	private double camZ;
 | |
| 
 | |
| 	public Frustum(Matrix4f frustum, Matrix4f projection) {
 | |
| 		this.calculateFrustum(frustum, projection);
 | |
| 	}
 | |
| 
 | |
| 	public Frustum(Frustum other) {
 | |
| 		this.intersection.set(other.matrix);
 | |
| 		this.matrix.set(other.matrix);
 | |
| 		this.camX = other.camX;
 | |
| 		this.camY = other.camY;
 | |
| 		this.camZ = other.camZ;
 | |
| 		this.viewVector = other.viewVector;
 | |
| 	}
 | |
| 
 | |
| 	public Frustum offsetToFullyIncludeCameraCube(int offset) {
 | |
| 		double d = Math.floor(this.camX / offset) * offset;
 | |
| 		double e = Math.floor(this.camY / offset) * offset;
 | |
| 		double f = Math.floor(this.camZ / offset) * offset;
 | |
| 		double g = Math.ceil(this.camX / offset) * offset;
 | |
| 		double h = Math.ceil(this.camY / offset) * offset;
 | |
| 
 | |
| 		for (double i = Math.ceil(this.camZ / offset) * offset;
 | |
| 			this.intersection
 | |
| 					.intersectAab(
 | |
| 						(float)(d - this.camX), (float)(e - this.camY), (float)(f - this.camZ), (float)(g - this.camX), (float)(h - this.camY), (float)(i - this.camZ)
 | |
| 					)
 | |
| 				!= -2;
 | |
| 			this.camZ = this.camZ - this.viewVector.z() * 4.0F
 | |
| 		) {
 | |
| 			this.camX = this.camX - this.viewVector.x() * 4.0F;
 | |
| 			this.camY = this.camY - this.viewVector.y() * 4.0F;
 | |
| 		}
 | |
| 
 | |
| 		return this;
 | |
| 	}
 | |
| 
 | |
| 	public void prepare(double camX, double camY, double camZ) {
 | |
| 		this.camX = camX;
 | |
| 		this.camY = camY;
 | |
| 		this.camZ = camZ;
 | |
| 	}
 | |
| 
 | |
| 	private void calculateFrustum(Matrix4f frustum, Matrix4f projection) {
 | |
| 		projection.mul(frustum, this.matrix);
 | |
| 		this.intersection.set(this.matrix);
 | |
| 		this.viewVector = this.matrix.transformTranspose(new Vector4f(0.0F, 0.0F, 1.0F, 0.0F));
 | |
| 	}
 | |
| 
 | |
| 	public boolean isVisible(AABB aabb) {
 | |
| 		int i = this.cubeInFrustum(aabb.minX, aabb.minY, aabb.minZ, aabb.maxX, aabb.maxY, aabb.maxZ);
 | |
| 		return i == -2 || i == -1;
 | |
| 	}
 | |
| 
 | |
| 	public int cubeInFrustum(BoundingBox boundingBox) {
 | |
| 		return this.cubeInFrustum(boundingBox.minX(), boundingBox.minY(), boundingBox.minZ(), boundingBox.maxX() + 1, boundingBox.maxY() + 1, boundingBox.maxZ() + 1);
 | |
| 	}
 | |
| 
 | |
| 	private int cubeInFrustum(double minX, double minY, double minZ, double maxX, double maxY, double maxZ) {
 | |
| 		float f = (float)(minX - this.camX);
 | |
| 		float g = (float)(minY - this.camY);
 | |
| 		float h = (float)(minZ - this.camZ);
 | |
| 		float i = (float)(maxX - this.camX);
 | |
| 		float j = (float)(maxY - this.camY);
 | |
| 		float k = (float)(maxZ - this.camZ);
 | |
| 		return this.intersection.intersectAab(f, g, h, i, j, k);
 | |
| 	}
 | |
| 
 | |
| 	public Vector4f[] getFrustumPoints() {
 | |
| 		Vector4f[] vector4fs = new Vector4f[]{
 | |
| 			new Vector4f(-1.0F, -1.0F, -1.0F, 1.0F),
 | |
| 			new Vector4f(1.0F, -1.0F, -1.0F, 1.0F),
 | |
| 			new Vector4f(1.0F, 1.0F, -1.0F, 1.0F),
 | |
| 			new Vector4f(-1.0F, 1.0F, -1.0F, 1.0F),
 | |
| 			new Vector4f(-1.0F, -1.0F, 1.0F, 1.0F),
 | |
| 			new Vector4f(1.0F, -1.0F, 1.0F, 1.0F),
 | |
| 			new Vector4f(1.0F, 1.0F, 1.0F, 1.0F),
 | |
| 			new Vector4f(-1.0F, 1.0F, 1.0F, 1.0F)
 | |
| 		};
 | |
| 		Matrix4f matrix4f = this.matrix.invert(new Matrix4f());
 | |
| 
 | |
| 		for (int i = 0; i < 8; i++) {
 | |
| 			matrix4f.transform(vector4fs[i]);
 | |
| 			vector4fs[i].div(vector4fs[i].w());
 | |
| 		}
 | |
| 
 | |
| 		return vector4fs;
 | |
| 	}
 | |
| 
 | |
| 	public double getCamX() {
 | |
| 		return this.camX;
 | |
| 	}
 | |
| 
 | |
| 	public double getCamY() {
 | |
| 		return this.camY;
 | |
| 	}
 | |
| 
 | |
| 	public double getCamZ() {
 | |
| 		return this.camZ;
 | |
| 	}
 | |
| }
 |