145 lines
		
	
	
	
		
			4.9 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			145 lines
		
	
	
	
		
			4.9 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| package net.minecraft.client.renderer;
 | |
| 
 | |
| import net.fabricmc.api.EnvType;
 | |
| import net.fabricmc.api.Environment;
 | |
| import net.minecraft.client.Minecraft;
 | |
| import net.minecraft.client.renderer.chunk.SectionRenderDispatcher;
 | |
| import net.minecraft.core.BlockPos;
 | |
| import net.minecraft.core.SectionPos;
 | |
| import net.minecraft.world.level.Level;
 | |
| import net.minecraft.world.level.LevelHeightAccessor;
 | |
| import org.jetbrains.annotations.Nullable;
 | |
| 
 | |
| @Environment(EnvType.CLIENT)
 | |
| public class ViewArea {
 | |
| 	protected final LevelRenderer levelRenderer;
 | |
| 	protected final Level level;
 | |
| 	protected int sectionGridSizeY;
 | |
| 	protected int sectionGridSizeX;
 | |
| 	protected int sectionGridSizeZ;
 | |
| 	private int viewDistance;
 | |
| 	private SectionPos cameraSectionPos;
 | |
| 	public SectionRenderDispatcher.RenderSection[] sections;
 | |
| 
 | |
| 	public ViewArea(SectionRenderDispatcher sectionRenderDispatcher, Level level, int viewDistance, LevelRenderer levelRenderer) {
 | |
| 		this.levelRenderer = levelRenderer;
 | |
| 		this.level = level;
 | |
| 		this.setViewDistance(viewDistance);
 | |
| 		this.createSections(sectionRenderDispatcher);
 | |
| 		this.cameraSectionPos = SectionPos.of(this.viewDistance + 1, 0, this.viewDistance + 1);
 | |
| 	}
 | |
| 
 | |
| 	protected void createSections(SectionRenderDispatcher sectionRenderDispatcher) {
 | |
| 		if (!Minecraft.getInstance().isSameThread()) {
 | |
| 			throw new IllegalStateException("createSections called from wrong thread: " + Thread.currentThread().getName());
 | |
| 		} else {
 | |
| 			int i = this.sectionGridSizeX * this.sectionGridSizeY * this.sectionGridSizeZ;
 | |
| 			this.sections = new SectionRenderDispatcher.RenderSection[i];
 | |
| 
 | |
| 			for (int j = 0; j < this.sectionGridSizeX; j++) {
 | |
| 				for (int k = 0; k < this.sectionGridSizeY; k++) {
 | |
| 					for (int l = 0; l < this.sectionGridSizeZ; l++) {
 | |
| 						int m = this.getSectionIndex(j, k, l);
 | |
| 						this.sections[m] = sectionRenderDispatcher.new RenderSection(m, SectionPos.asLong(j, k + this.level.getMinSectionY(), l));
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	public void releaseAllBuffers() {
 | |
| 		for (SectionRenderDispatcher.RenderSection renderSection : this.sections) {
 | |
| 			renderSection.reset();
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	private int getSectionIndex(int x, int y, int z) {
 | |
| 		return (z * this.sectionGridSizeY + y) * this.sectionGridSizeX + x;
 | |
| 	}
 | |
| 
 | |
| 	protected void setViewDistance(int renderDistanceChunks) {
 | |
| 		int i = renderDistanceChunks * 2 + 1;
 | |
| 		this.sectionGridSizeX = i;
 | |
| 		this.sectionGridSizeY = this.level.getSectionsCount();
 | |
| 		this.sectionGridSizeZ = i;
 | |
| 		this.viewDistance = renderDistanceChunks;
 | |
| 	}
 | |
| 
 | |
| 	public int getViewDistance() {
 | |
| 		return this.viewDistance;
 | |
| 	}
 | |
| 
 | |
| 	public LevelHeightAccessor getLevelHeightAccessor() {
 | |
| 		return this.level;
 | |
| 	}
 | |
| 
 | |
| 	public void repositionCamera(SectionPos newSectionPos) {
 | |
| 		for (int i = 0; i < this.sectionGridSizeX; i++) {
 | |
| 			int j = newSectionPos.x() - this.viewDistance;
 | |
| 			int k = j + Math.floorMod(i - j, this.sectionGridSizeX);
 | |
| 
 | |
| 			for (int l = 0; l < this.sectionGridSizeZ; l++) {
 | |
| 				int m = newSectionPos.z() - this.viewDistance;
 | |
| 				int n = m + Math.floorMod(l - m, this.sectionGridSizeZ);
 | |
| 
 | |
| 				for (int o = 0; o < this.sectionGridSizeY; o++) {
 | |
| 					int p = this.level.getMinSectionY() + o;
 | |
| 					SectionRenderDispatcher.RenderSection renderSection = this.sections[this.getSectionIndex(i, o, l)];
 | |
| 					long q = renderSection.getSectionNode();
 | |
| 					if (q != SectionPos.asLong(k, p, n)) {
 | |
| 						renderSection.setSectionNode(SectionPos.asLong(k, p, n));
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		this.cameraSectionPos = newSectionPos;
 | |
| 		this.levelRenderer.getSectionOcclusionGraph().invalidate();
 | |
| 	}
 | |
| 
 | |
| 	public SectionPos getCameraSectionPos() {
 | |
| 		return this.cameraSectionPos;
 | |
| 	}
 | |
| 
 | |
| 	public void setDirty(int sectionX, int sectionY, int sectionZ, boolean reRenderOnMainThread) {
 | |
| 		SectionRenderDispatcher.RenderSection renderSection = this.getRenderSection(sectionX, sectionY, sectionZ);
 | |
| 		if (renderSection != null) {
 | |
| 			renderSection.setDirty(reRenderOnMainThread);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	@Nullable
 | |
| 	protected SectionRenderDispatcher.RenderSection getRenderSectionAt(BlockPos pos) {
 | |
| 		return this.getRenderSection(SectionPos.asLong(pos));
 | |
| 	}
 | |
| 
 | |
| 	@Nullable
 | |
| 	protected SectionRenderDispatcher.RenderSection getRenderSection(long sectionPos) {
 | |
| 		int i = SectionPos.x(sectionPos);
 | |
| 		int j = SectionPos.y(sectionPos);
 | |
| 		int k = SectionPos.z(sectionPos);
 | |
| 		return this.getRenderSection(i, j, k);
 | |
| 	}
 | |
| 
 | |
| 	@Nullable
 | |
| 	private SectionRenderDispatcher.RenderSection getRenderSection(int x, int y, int z) {
 | |
| 		if (!this.containsSection(x, y, z)) {
 | |
| 			return null;
 | |
| 		} else {
 | |
| 			int i = y - this.level.getMinSectionY();
 | |
| 			int j = Math.floorMod(x, this.sectionGridSizeX);
 | |
| 			int k = Math.floorMod(z, this.sectionGridSizeZ);
 | |
| 			return this.sections[this.getSectionIndex(j, i, k)];
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	private boolean containsSection(int x, int y, int z) {
 | |
| 		if (y >= this.level.getMinSectionY() && y <= this.level.getMaxSectionY()) {
 | |
| 			return x < this.cameraSectionPos.x() - this.viewDistance || x > this.cameraSectionPos.x() + this.viewDistance
 | |
| 				? false
 | |
| 				: z >= this.cameraSectionPos.z() - this.viewDistance && z <= this.cameraSectionPos.z() + this.viewDistance;
 | |
| 		} else {
 | |
| 			return false;
 | |
| 		}
 | |
| 	}
 | |
| }
 |