VulkanShader_1.21.10-0.0.4-alpha.jar
Download file
package net.vulkanmod.render.chunk.frustum;
import java.util.Arrays;
import net.vulkanmod.render.chunk.ChunkArea;
import net.vulkanmod.render.chunk.ChunkAreaManager;
import org.joml.Vector3i;
public class FrustumOctree {
static final int LEVELS = 2;
public static void updateFrustumVisibility(VFrustum frustum, ChunkArea[] chunkAreas) {
int width = 1 << ChunkAreaManager.AREA_SH_XZ + 4;
for(ChunkArea chunkArea : chunkAreas) {
Vector3i position = chunkArea.getPosition();
int minX2 = position.x;
int minY2 = position.y;
int minZ2 = position.z;
int frustumResult = frustum.cubeInFrustum((float)minX2, (float)minY2, (float)minZ2, (float)(minX2 + width), (float)(minY2 + width), (float)(minZ2 + width));
byte[] buffer = chunkArea.getFrustumBuffer();
if (frustumResult != -1) {
Arrays.fill(buffer, (byte)frustumResult);
} else {
innerCube(frustum, buffer, 2, (float)minX2, (float)minY2, (float)minZ2, width, 0);
}
}
}
static void innerCube(VFrustum frustum, byte[] buffer, int level, float xMin, float yMin, float zMin, int prevWidth, int beginIdx) {
if (level == 1) {
lastInnerCube(frustum, buffer, xMin, yMin, zMin, prevWidth, beginIdx);
} else {
int width = prevWidth >> 1;
int lvlShift = (level - 1) * 3;
for(int x = 0; x < 2; ++x) {
float xMin2 = xMin + (float)(x * width);
float xMax2 = xMin2 + (float)width;
for(int y = 0; y < 2; ++y) {
float yMin2 = yMin + (float)(y * width);
float yMax2 = yMin2 + (float)width;
for(int z = 0; z < 2; ++z) {
float zMin2 = zMin + (float)(z * width);
float zMax2 = zMin2 + (float)width;
int frustumResult = frustum.cubeInFrustum(xMin2, yMin2, zMin2, xMax2, yMax2, zMax2);
int idx = beginIdx + getOffset(lvlShift, x, y, z);
int endIdx = idx + (1 << lvlShift);
if (frustumResult != -1) {
fillResultBuffer(buffer, idx, endIdx, (byte)frustumResult);
} else {
innerCube(frustum, buffer, level - 1, xMin2, yMin2, zMin2, width, idx);
}
}
}
}
}
}
static void lastInnerCube(VFrustum frustum, byte[] buffer, float xMin, float yMin, float zMin, int prevWidth, int beginIdx) {
int width = prevWidth >> 1;
for(int x = 0; x < 2; ++x) {
float xMin2 = xMin + (float)(x * width);
float xMax2 = xMin2 + (float)width;
for(int y = 0; y < 2; ++y) {
float yMin2 = yMin + (float)(y * width);
float yMax2 = yMin2 + (float)width;
for(int z = 0; z < 2; ++z) {
float zMin2 = zMin + (float)(z * width);
float zMax2 = zMin2 + (float)width;
int frustumResult = frustum.cubeInFrustum(xMin2, yMin2, zMin2, xMax2, yMax2, zMax2);
int idx = beginIdx + (x << 2) + (y << 1) + z;
buffer[idx] = (byte)frustumResult;
}
}
}
}
static int getOffset(int baseShift, int x, int y, int z) {
return (x << 2 + baseShift) + (y << 1 + baseShift) + (z << baseShift);
}
static void fillResultBuffer(byte[] buffer, int beginIdx, int endIdx, byte result) {
for(int i = beginIdx; i < endIdx; ++i) {
buffer[i] = result;
}
}
}
Download file