VulkanShader_1.21.10-0.0.4-alpha.jar
Download file
package net.vulkanmod.render.chunk.graph;
import com.google.common.collect.Lists;
import java.util.List;
import net.minecraft.class_10209;
import net.minecraft.class_1937;
import net.minecraft.class_2338;
import net.minecraft.class_243;
import net.minecraft.class_310;
import net.minecraft.class_3532;
import net.minecraft.class_3695;
import net.minecraft.class_4076;
import net.minecraft.class_4184;
import net.minecraft.class_4604;
import net.vulkanmod.Initializer;
import net.vulkanmod.interfaces.FrustumMixed;
import net.vulkanmod.render.chunk.ChunkAreaManager;
import net.vulkanmod.render.chunk.RenderSection;
import net.vulkanmod.render.chunk.SectionGrid;
import net.vulkanmod.render.chunk.WorldRenderer;
import net.vulkanmod.render.chunk.build.RenderRegionBuilder;
import net.vulkanmod.render.chunk.build.task.TaskDispatcher;
import net.vulkanmod.render.chunk.frustum.VFrustum;
import net.vulkanmod.render.chunk.util.AreaSetQueue;
import net.vulkanmod.render.chunk.util.ResettableQueue;
import net.vulkanmod.render.profiling.Profiler;
public class SectionGraph {
class_310 minecraft;
private final class_1937 level;
private final SectionGrid sectionGrid;
private final ChunkAreaManager chunkAreaManager;
private final TaskDispatcher taskDispatcher;
private final ResettableQueue<RenderSection> sectionQueue = new ResettableQueue<RenderSection>();
private AreaSetQueue chunkAreaQueue;
private short lastFrame = 0;
private final ResettableQueue<RenderSection> blockEntitiesSections = new ResettableQueue<RenderSection>();
private final ResettableQueue<RenderSection> rebuildQueue = new ResettableQueue<RenderSection>();
private VFrustum frustum;
public RenderRegionBuilder renderRegionCache;
int nonEmptyChunks;
public SectionGraph(class_1937 level, SectionGrid sectionGrid, TaskDispatcher taskDispatcher) {
this.level = level;
this.sectionGrid = sectionGrid;
this.chunkAreaManager = sectionGrid.getChunkAreaManager();
this.taskDispatcher = taskDispatcher;
this.chunkAreaQueue = new AreaSetQueue(sectionGrid.getChunkAreaManager().size);
this.minecraft = class_310.method_1551();
this.renderRegionCache = WorldRenderer.getInstance().renderRegionCache;
}
public void update(class_4184 camera, class_4604 frustum, boolean spectator) {
Profiler profiler = Profiler.getMainProfiler();
class_3695 mcProfiler = class_10209.method_64146();
class_2338 blockpos = camera.method_19328();
mcProfiler.method_15405("update");
boolean flag = this.minecraft.field_1730;
if (spectator && this.level.method_8320(blockpos).method_26216()) {
flag = false;
}
profiler.push("frustum");
this.frustum = ((FrustumMixed)frustum).customFrustum().offsetToFullyIncludeCameraCube(8);
this.sectionGrid.updateFrustumVisibility(this.frustum);
profiler.pop();
mcProfiler.method_15396("partial_update");
this.initUpdate();
this.initializeQueueForFullUpdate(camera);
if (flag) {
this.updateRenderChunks();
} else {
this.updateRenderChunksSpectator();
}
this.scheduleRebuilds();
mcProfiler.method_15407();
}
private void initializeQueueForFullUpdate(class_4184 camera) {
class_243 vec3 = camera.method_19326();
class_2338 blockpos = camera.method_19328();
RenderSection renderSection = this.sectionGrid.getSectionAtBlockPos(blockpos);
if (renderSection == null) {
boolean flag = blockpos.method_10264() > this.level.method_31607();
int y = flag ? this.level.method_31600() - 8 : this.level.method_31607() + 8;
int x = class_3532.method_15357(vec3.field_1352 / (double)16.0F) * 16;
int z = class_3532.method_15357(vec3.field_1350 / (double)16.0F) * 16;
List<RenderSection> list = Lists.newArrayList();
int renderDistance = WorldRenderer.getInstance().getRenderDistance();
for(int x1 = -renderDistance; x1 <= renderDistance; ++x1) {
for(int z1 = -renderDistance; z1 <= renderDistance; ++z1) {
RenderSection renderSection1 = this.sectionGrid.getSectionAtBlockPos(new class_2338(x + class_4076.method_32205(x1, 8), y, z + class_4076.method_32205(z1, 8)));
if (renderSection1 != null) {
initFirstNode(renderSection1, this.lastFrame);
list.add(renderSection1);
}
}
}
this.sectionQueue.ensureCapacity(list.size());
for(RenderSection chunkInfo : list) {
this.sectionQueue.add(chunkInfo);
}
} else {
initFirstNode(renderSection, this.lastFrame);
this.sectionQueue.add(renderSection);
}
}
private static void initFirstNode(RenderSection renderSection, short frame) {
renderSection.mainDir = 7;
renderSection.sourceDirs = -128;
renderSection.directions = -1;
renderSection.setLastFrame(frame);
renderSection.visibility |= initVisibility();
renderSection.directionChanges = 0;
renderSection.steps = 0;
}
private static long initVisibility() {
long vis = 0L;
for(int dir = 0; dir < 6; ++dir) {
vis |= 1L << 48 + dir;
vis |= 1L << 56 + dir;
}
return vis;
}
private void initUpdate() {
this.resetUpdateQueues();
++this.lastFrame;
this.nonEmptyChunks = 0;
}
private void resetUpdateQueues() {
this.chunkAreaQueue.clear();
this.sectionGrid.getChunkAreaManager().resetQueues();
this.sectionQueue.clear();
this.blockEntitiesSections.clear();
this.rebuildQueue.clear();
}
private void updateRenderChunks() {
int maxDirectionsChanges = Initializer.CONFIG.advCulling - 1;
while(this.sectionQueue.hasNext()) {
RenderSection renderSection = this.sectionQueue.poll();
if (!this.notInFrustum(renderSection) && renderSection.directionChanges <= maxDirectionsChanges) {
if (!renderSection.isCompletelyEmpty()) {
renderSection.getChunkArea().sectionQueue.add(renderSection);
this.chunkAreaQueue.add(renderSection.getChunkArea());
++this.nonEmptyChunks;
}
if (renderSection.containsBlockEntities()) {
this.blockEntitiesSections.ensureCapacity(1);
this.blockEntitiesSections.add(renderSection);
}
if (renderSection.isDirty()) {
this.rebuildQueue.ensureCapacity(1);
this.rebuildQueue.add(renderSection);
}
byte dirs = (byte)(renderSection.getVisibilityDirs() & renderSection.getDirections());
this.visitAdjacentNodes(renderSection, dirs);
}
}
}
private void scheduleRebuilds() {
for(int i = 0; i < this.rebuildQueue.size(); ++i) {
RenderSection section = this.rebuildQueue.get(i);
section.rebuildChunkAsync(this.taskDispatcher, this.renderRegionCache);
section.setNotDirty();
}
this.rebuildQueue.clear();
}
private boolean notInFrustum(RenderSection renderSection) {
byte frustumRes = renderSection.getChunkArea().inFrustum(renderSection.frustumIndex);
if (frustumRes > -1) {
return true;
} else if (frustumRes == -1) {
return !this.frustum.testFrustum((float)renderSection.xOffset, (float)renderSection.yOffset, (float)renderSection.zOffset, (float)(renderSection.xOffset + 16), (float)(renderSection.yOffset + 16), (float)(renderSection.zOffset + 16));
} else {
return false;
}
}
private void visitAdjacentNodes(RenderSection renderSection, byte dirs) {
dirs = (byte)(dirs & renderSection.adjDirs);
this.sectionQueue.ensureCapacity(6);
RenderSection relativeSection = renderSection.adjDown;
this.checkToAdd(renderSection, relativeSection, (byte)0, (byte)1, dirs);
relativeSection = renderSection.adjUp;
this.checkToAdd(renderSection, relativeSection, (byte)1, (byte)0, dirs);
relativeSection = renderSection.adjNorth;
this.checkToAdd(renderSection, relativeSection, (byte)2, (byte)3, dirs);
relativeSection = renderSection.adjSouth;
this.checkToAdd(renderSection, relativeSection, (byte)3, (byte)2, dirs);
relativeSection = renderSection.adjWest;
this.checkToAdd(renderSection, relativeSection, (byte)4, (byte)5, dirs);
relativeSection = renderSection.adjEast;
this.checkToAdd(renderSection, relativeSection, (byte)5, (byte)4, dirs);
}
private void checkToAdd(RenderSection renderSection, RenderSection relativeSection, byte dir, byte opposite, byte dirs) {
if ((dirs & 1 << dir) != 0) {
this.addNode(renderSection, relativeSection, dir, opposite);
}
}
private void updateRenderChunksSpectator() {
while(this.sectionQueue.hasNext()) {
RenderSection renderSection = this.sectionQueue.poll();
if (!this.notInFrustum(renderSection)) {
if (!renderSection.isCompletelyEmpty()) {
renderSection.getChunkArea().sectionQueue.add(renderSection);
this.chunkAreaQueue.add(renderSection.getChunkArea());
++this.nonEmptyChunks;
}
if (renderSection.isDirty()) {
this.rebuildQueue.ensureCapacity(1);
this.rebuildQueue.add(renderSection);
}
byte dirs = (byte)(renderSection.adjDirs & renderSection.getDirections());
this.visitAdjacentNodes(renderSection, dirs);
}
}
}
private void addNode(RenderSection renderSection, RenderSection relativeSection, byte direction, byte opposite) {
if (relativeSection.getLastFrame() != this.lastFrame) {
relativeSection.setLastFrame(this.lastFrame);
relativeSection.mainDir = direction;
relativeSection.sourceDirs = (byte)(1 << direction);
byte steps = (byte)(renderSection.steps + 1);
relativeSection.directionChanges = (byte)(steps < 10 ? 0 : 127);
relativeSection.steps = steps;
relativeSection.directions = (byte)(renderSection.directions & ~(1 << opposite));
this.sectionQueue.add(relativeSection);
}
relativeSection.addDir(direction);
boolean increase = (renderSection.sourceDirs & 1 << direction) == 0 && !renderSection.isCompletelyEmpty();
byte dc = increase ? (byte)(renderSection.directionChanges + 1) : renderSection.directionChanges;
relativeSection.directionChanges = dc < relativeSection.directionChanges ? dc : relativeSection.directionChanges;
}
public AreaSetQueue getChunkAreaQueue() {
return this.chunkAreaQueue;
}
public ResettableQueue<RenderSection> getSectionQueue() {
return this.sectionQueue;
}
public ResettableQueue<RenderSection> getBlockEntitiesSections() {
return this.blockEntitiesSections;
}
public short getLastFrame() {
return this.lastFrame;
}
public String getStatistics() {
int totalSections = this.sectionGrid.getSectionCount();
int sections = this.sectionQueue.size();
int renderDistance = WorldRenderer.getInstance().getRenderDistance();
String tasksInfo = this.taskDispatcher == null ? "null" : this.taskDispatcher.getStats();
return String.format("Chunks: %d(%d)/%d D: %d, %s", this.nonEmptyChunks, sections, totalSections, renderDistance, tasksInfo);
}
}
Download file