diff --git a/src/main/java/com/logisticscraft/occlusionculling/DataProvider.java b/src/main/java/com/logisticscraft/occlusionculling/DataProvider.java deleted file mode 100644 index 5ab4600..0000000 --- a/src/main/java/com/logisticscraft/occlusionculling/DataProvider.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.logisticscraft.occlusionculling; - -import com.logisticscraft.occlusionculling.util.Vec3d; - -public interface DataProvider { - - /** - * Prepares the requested chunk. Returns true if the chunk is ready, false when - * not loaded. Should not reload the chunk when the x and y are the same as the - * last request! - * - * @param chunkX - * @param chunkZ - * @return - */ - boolean prepareChunk(int chunkX, int chunkZ); - - /** - * Location is inside the chunk. - * - * @param x - * @param y - * @param z - * @return - */ - boolean isOpaqueFullCube(int x, int y, int z); - - default void cleanup() { - } - - default void checkingPosition(Vec3d[] targetPoints, int size, Vec3d viewerPosition) { - } - -} diff --git a/src/main/java/com/logisticscraft/occlusionculling/OcclusionCullingInstance.java b/src/main/java/com/logisticscraft/occlusionculling/OcclusionCullingInstance.java deleted file mode 100644 index 6ac017c..0000000 --- a/src/main/java/com/logisticscraft/occlusionculling/OcclusionCullingInstance.java +++ /dev/null @@ -1,514 +0,0 @@ -package com.logisticscraft.occlusionculling; - -import java.util.Arrays; -import java.util.BitSet; - -import com.logisticscraft.occlusionculling.cache.ArrayOcclusionCache; -import com.logisticscraft.occlusionculling.cache.OcclusionCache; -import com.logisticscraft.occlusionculling.util.MathUtilities; -import com.logisticscraft.occlusionculling.util.Vec3d; - -public class OcclusionCullingInstance { - - private static final int ON_MIN_X = 0x01; - private static final int ON_MAX_X = 0x02; - private static final int ON_MIN_Y = 0x04; - private static final int ON_MAX_Y = 0x08; - private static final int ON_MIN_Z = 0x10; - private static final int ON_MAX_Z = 0x20; - - private final int reach; - private final double aabbExpansion; - private final DataProvider provider; - private final OcclusionCache cache; - - // Reused allocated data structures - private final BitSet skipList = new BitSet(); // Grows bigger in case some mod introduces giant hitboxes - private final Vec3d[] targetPoints = new Vec3d[15]; - private final Vec3d targetPos = new Vec3d(0, 0, 0); - private final int[] cameraPos = new int[3]; - private final boolean[] dotselectors = new boolean[14]; - private boolean allowRayChecks = false; - private final int[] lastHitBlock = new int[3]; - private boolean allowWallClipping = false; - - - public OcclusionCullingInstance(int maxDistance, DataProvider provider) { - this(maxDistance, provider, new ArrayOcclusionCache(maxDistance), 0.5); - } - - public OcclusionCullingInstance(int maxDistance, DataProvider provider, OcclusionCache cache, double aabbExpansion) { - this.reach = maxDistance; - this.provider = provider; - this.cache = cache; - this.aabbExpansion = aabbExpansion; - for(int i = 0; i < targetPoints.length; i++) { - targetPoints[i] = new Vec3d(0, 0, 0); - } - } - - public boolean isAABBVisible(Vec3d aabbMin, Vec3d aabbMax, Vec3d viewerPosition) { - try { - int maxX = MathUtilities.floor(aabbMax.x - + aabbExpansion); - int maxY = MathUtilities.floor(aabbMax.y - + aabbExpansion); - int maxZ = MathUtilities.floor(aabbMax.z - + aabbExpansion); - int minX = MathUtilities.floor(aabbMin.x - - aabbExpansion); - int minY = MathUtilities.floor(aabbMin.y - - aabbExpansion); - int minZ = MathUtilities.floor(aabbMin.z - - aabbExpansion); - - cameraPos[0] = MathUtilities.floor(viewerPosition.x); - cameraPos[1] = MathUtilities.floor(viewerPosition.y); - cameraPos[2] = MathUtilities.floor(viewerPosition.z); - - Relative relX = Relative.from(minX, maxX, cameraPos[0]); - Relative relY = Relative.from(minY, maxY, cameraPos[1]); - Relative relZ = Relative.from(minZ, maxZ, cameraPos[2]); - - if(relX == Relative.INSIDE && relY == Relative.INSIDE && relZ == Relative.INSIDE) { - return true; // We are inside of the AABB, don't cull - } - - skipList.clear(); - - // Just check the cache first - int id = 0; - for (int x = minX; x <= maxX; x++) { - for (int y = minY; y <= maxY; y++) { - for (int z = minZ; z <= maxZ; z++) { - int cachedValue = getCacheValue(x, y, z); - - if (cachedValue == 1) { - // non-occluding - return true; - } - - if (cachedValue != 0) { - // was checked and it wasn't visible - skipList.set(id); - } - id++; - } - } - } - - // only after the first hit wall the cache becomes valid. - allowRayChecks = false; - - // since the cache wasn't helpfull - id = 0; - for (int x = minX; x <= maxX; x++) { - byte visibleOnFaceX = 0; - byte faceEdgeDataX = 0; - faceEdgeDataX |= (x == minX) ? ON_MIN_X : 0; - faceEdgeDataX |= (x == maxX) ? ON_MAX_X : 0; - visibleOnFaceX |= (x == minX && relX == Relative.POSITIVE) ? ON_MIN_X : 0; - visibleOnFaceX |= (x == maxX && relX == Relative.NEGATIVE) ? ON_MAX_X : 0; - for (int y = minY; y <= maxY; y++) { - byte faceEdgeDataY = faceEdgeDataX; - byte visibleOnFaceY = visibleOnFaceX; - faceEdgeDataY |= (y == minY) ? ON_MIN_Y : 0; - faceEdgeDataY |= (y == maxY) ? ON_MAX_Y : 0; - visibleOnFaceY |= (y == minY && relY == Relative.POSITIVE) ? ON_MIN_Y : 0; - visibleOnFaceY |= (y == maxY && relY == Relative.NEGATIVE) ? ON_MAX_Y : 0; - for (int z = minZ; z <= maxZ; z++) { - byte faceEdgeData = faceEdgeDataY; - byte visibleOnFace = visibleOnFaceY; - faceEdgeData |= (z == minZ) ? ON_MIN_Z : 0; - faceEdgeData |= (z == maxZ) ? ON_MAX_Z : 0; - visibleOnFace |= (z == minZ && relZ == Relative.POSITIVE) ? ON_MIN_Z : 0; - visibleOnFace |= (z == maxZ && relZ == Relative.NEGATIVE) ? ON_MAX_Z : 0; - if(skipList.get(id)) { // was checked and it wasn't visible - id++; - continue; - } - - if (visibleOnFace != 0) { - targetPos.set(x, y, z); - if (isVoxelVisible(viewerPosition, targetPos, faceEdgeData, visibleOnFace)) { - return true; - } - } - id++; - } - } - } - - return false; - } catch (Throwable t) { - // Failsafe - t.printStackTrace(); - } - return true; - } - - /** - * @param viewerPosition - * @param position - * @param faceData contains rather this Block is on the outside for a given face - * @param visibleOnFace contains rather a face should be concidered - * @return - */ - private boolean isVoxelVisible(Vec3d viewerPosition, Vec3d position, byte faceData, byte visibleOnFace) { - int targetSize = 0; - Arrays.fill(dotselectors, false); - if((visibleOnFace & ON_MIN_X) == ON_MIN_X){ - dotselectors[0] = true; - if((faceData & ~ON_MIN_X) != 0) { - dotselectors[1] = true; - dotselectors[4] = true; - dotselectors[5] = true; - } - dotselectors[8] = true; - } - if((visibleOnFace & ON_MIN_Y) == ON_MIN_Y){ - dotselectors[0] = true; - if((faceData & ~ON_MIN_Y) != 0) { - dotselectors[3] = true; - dotselectors[4] = true; - dotselectors[7] = true; - } - dotselectors[9] = true; - } - if((visibleOnFace & ON_MIN_Z) == ON_MIN_Z){ - dotselectors[0] = true; - if((faceData & ~ON_MIN_Z) != 0) { - dotselectors[1] = true; - dotselectors[4] = true; - dotselectors[5] = true; - } - dotselectors[10] = true; - } - if((visibleOnFace & ON_MAX_X) == ON_MAX_X){ - dotselectors[4] = true; - if((faceData & ~ON_MAX_X) != 0) { - dotselectors[5] = true; - dotselectors[6] = true; - dotselectors[7] = true; - } - dotselectors[11] = true; - } - if((visibleOnFace & ON_MAX_Y) == ON_MAX_Y){ - dotselectors[1] = true; - if((faceData & ~ON_MAX_Y) != 0) { - dotselectors[2] = true; - dotselectors[5] = true; - dotselectors[6] = true; - } - dotselectors[12] = true; - } - if((visibleOnFace & ON_MAX_Z) == ON_MAX_Z){ - dotselectors[2] = true; - if((faceData & ~ON_MAX_Z) != 0) { - dotselectors[3] = true; - dotselectors[6] = true; - dotselectors[7] = true; - } - dotselectors[13] = true; - } - - if (dotselectors[0])targetPoints[targetSize++].setAdd(position, 0.05, 0.05, 0.05); - if (dotselectors[1])targetPoints[targetSize++].setAdd(position, 0.05, 0.95, 0.05); - if (dotselectors[2])targetPoints[targetSize++].setAdd(position, 0.05, 0.95, 0.95); - if (dotselectors[3])targetPoints[targetSize++].setAdd(position, 0.05, 0.05, 0.95); - if (dotselectors[4])targetPoints[targetSize++].setAdd(position, 0.95, 0.05, 0.05); - if (dotselectors[5])targetPoints[targetSize++].setAdd(position, 0.95, 0.95, 0.05); - if (dotselectors[6])targetPoints[targetSize++].setAdd(position, 0.95, 0.95, 0.95); - if (dotselectors[7])targetPoints[targetSize++].setAdd(position, 0.95, 0.05, 0.95); - // middle points - if (dotselectors[8])targetPoints[targetSize++].setAdd(position, 0.05, 0.5, 0.5); - if (dotselectors[9])targetPoints[targetSize++].setAdd(position, 0.5, 0.05, 0.5); - if (dotselectors[10])targetPoints[targetSize++].setAdd(position, 0.5, 0.5, 0.05); - if (dotselectors[11])targetPoints[targetSize++].setAdd(position, 0.95, 0.5, 0.5); - if (dotselectors[12])targetPoints[targetSize++].setAdd(position, 0.5, 0.95, 0.5); - if (dotselectors[13])targetPoints[targetSize++].setAdd(position, 0.5, 0.5, 0.95); - - return isVisible(viewerPosition, targetPoints, targetSize); - } - - private boolean rayIntersection(int[] b, Vec3d rayOrigin, Vec3d rayDir) { - Vec3d rInv = new Vec3d(1, 1, 1).div(rayDir); - - double t1 = (b[0] - rayOrigin.x) * rInv.x; - double t2 = (b[0] + 1 - rayOrigin.x) * rInv.x; - double t3 = (b[1] - rayOrigin.y) * rInv.y; - double t4 = (b[1] + 1 - rayOrigin.y) * rInv.y; - double t5 = (b[2] - rayOrigin.z) * rInv.z; - double t6 = (b[2] + 1 - rayOrigin.z) * rInv.z; - - double tmin = Math.max(Math.max(Math.min(t1, t2), Math.min(t3, t4)), Math.min(t5, t6)); - double tmax = Math.min(Math.min(Math.max(t1, t2), Math.max(t3, t4)), Math.max(t5, t6)); - - // if tmax > 0, ray (line) is intersecting AABB, but the whole AABB is behind us - if (tmax > 0) { - return false; - } - - // if tmin > tmax, ray doesn't intersect AABB - if (tmin > tmax) { - return false; - } - - return true; - } - - /** - * returns the grid cells that intersect with this Vec3d
- * http://playtechs.blogspot.de/2007/03/raytracing-on-grid.html - *

- * Caching assumes that all Vec3d's are inside the same block - */ - private boolean isVisible(Vec3d start, Vec3d[] targets, int size) { - // start cell coordinate - int x = cameraPos[0]; - int y = cameraPos[1]; - int z = cameraPos[2]; - - for (int v = 0; v < size; v++) { - // ray-casting target - Vec3d target = targets[v]; - - double relativeX = start.x - target.getX(); - double relativeY = start.y - target.getY(); - double relativeZ = start.z - target.getZ(); - - if(allowRayChecks && rayIntersection(lastHitBlock, start, new Vec3d(relativeX, relativeY, relativeZ).normalize())) { - continue; - } - - // horizontal and vertical cell amount spanned - double dimensionX = Math.abs(relativeX); - double dimensionY = Math.abs(relativeY); - double dimensionZ = Math.abs(relativeZ); - - // distance between horizontal intersection points with cell border as a - // fraction of the total Vec3d length - double dimFracX = 1f / dimensionX; - // distance between vertical intersection points with cell border as a fraction - // of the total Vec3d length - double dimFracY = 1f / dimensionY; - double dimFracZ = 1f / dimensionZ; - - // total amount of intersected cells - int intersectCount = 1; - - // 1, 0 or -1 - // determines the direction of the next cell (horizontally / vertically) - int x_inc, y_inc, z_inc; - - // the distance to the next horizontal / vertical intersection point with a cell - // border as a fraction of the total Vec3d length - double t_next_y, t_next_x, t_next_z; - - if (dimensionX == 0f) { - x_inc = 0; - t_next_x = dimFracX; // don't increment horizontally because the Vec3d is perfectly vertical - } else if (target.x > start.x) { - x_inc = 1; // target point is horizontally greater than starting point so increment every - // step by 1 - intersectCount += MathUtilities.floor(target.x) - x; // increment total amount of intersecting cells - t_next_x = (float) ((x + 1 - start.x) * dimFracX); // calculate the next horizontal - // intersection - // point based on the position inside - // the first cell - } else { - x_inc = -1; // target point is horizontally smaller than starting point so reduce every step - // by 1 - intersectCount += x - MathUtilities.floor(target.x); // increment total amount of intersecting cells - t_next_x = (float) ((start.x - x) - * dimFracX); // calculate the next horizontal - // intersection point - // based on the position inside - // the first cell - } - - if (dimensionY == 0f) { - y_inc = 0; - t_next_y = dimFracY; // don't increment vertically because the Vec3d is perfectly horizontal - } else if (target.y > start.y) { - y_inc = 1; // target point is vertically greater than starting point so increment every - // step by 1 - intersectCount += MathUtilities.floor(target.y) - y; // increment total amount of intersecting cells - t_next_y = (float) ((y + 1 - start.y) - * dimFracY); // calculate the next vertical - // intersection - // point based on the position inside - // the first cell - } else { - y_inc = -1; // target point is vertically smaller than starting point so reduce every step - // by 1 - intersectCount += y - MathUtilities.floor(target.y); // increment total amount of intersecting cells - t_next_y = (float) ((start.y - y) - * dimFracY); // calculate the next vertical intersection - // point - // based on the position inside - // the first cell - } - - if (dimensionZ == 0f) { - z_inc = 0; - t_next_z = dimFracZ; // don't increment vertically because the Vec3d is perfectly horizontal - } else if (target.z > start.z) { - z_inc = 1; // target point is vertically greater than starting point so increment every - // step by 1 - intersectCount += MathUtilities.floor(target.z) - z; // increment total amount of intersecting cells - t_next_z = (float) ((z + 1 - start.z) - * dimFracZ); // calculate the next vertical - // intersection - // point based on the position inside - // the first cell - } else { - z_inc = -1; // target point is vertically smaller than starting point so reduce every step - // by 1 - intersectCount += z - MathUtilities.floor(target.z); // increment total amount of intersecting cells - t_next_z = (float) ((start.z - z) - * dimFracZ); // calculate the next vertical intersection - // point - // based on the position inside - // the first cell - } - - boolean finished = stepRay(start, x, y, z, - dimFracX, dimFracY, dimFracZ, intersectCount, x_inc, y_inc, - z_inc, t_next_y, t_next_x, t_next_z); - provider.cleanup(); - if (finished) { - cacheResult(targets[0], true); - return true; - } else { - allowRayChecks = true; - } - } - cacheResult(targets[0], false); - return false; - } - - private boolean stepRay(Vec3d start, int currentX, int currentY, - int currentZ, double distInX, double distInY, - double distInZ, int n, int x_inc, int y_inc, - int z_inc, double t_next_y, double t_next_x, - double t_next_z) { - allowWallClipping = true; // initially allow rays to go through walls till they are on the outside - // iterate through all intersecting cells (n times) - for (; n > 1; n--) { // n-1 times because we don't want to check the last block - // towards - where from - - - // get cached value, 0 means uncached (default) - int cVal = getCacheValue(currentX, currentY, currentZ); - - if (cVal == 2 && !allowWallClipping) { - // block cached as occluding, stop ray - lastHitBlock[0] = currentX; - lastHitBlock[1] = currentY; - lastHitBlock[2] = currentZ; - return false; - } - - if (cVal == 0) { - // save current cell - int chunkX = currentX >> 4; - int chunkZ = currentZ >> 4; - if (!provider.prepareChunk(chunkX, chunkZ)) { // Chunk not ready - return false; - } - - if (provider.isOpaqueFullCube(currentX, currentY, currentZ)) { - if (!allowWallClipping) { - cache.setLastHidden(); - lastHitBlock[0] = currentX; - lastHitBlock[1] = currentY; - lastHitBlock[2] = currentZ; - return false; - } - } else { - // outside of wall, now clipping is not allowed - allowWallClipping = false; - cache.setLastVisible(); - } - } - - if(cVal == 1) { - // outside of wall, now clipping is not allowed - allowWallClipping = false; - } - - - if (t_next_y < t_next_x && t_next_y < t_next_z) { // next cell is upwards/downwards because the distance to - // the next vertical - // intersection point is smaller than to the next horizontal intersection point - currentY += y_inc; // move up/down - t_next_y += distInY; // update next vertical intersection point - } else if (t_next_x < t_next_y && t_next_x < t_next_z) { // next cell is right/left - currentX += x_inc; // move right/left - t_next_x += distInX; // update next horizontal intersection point - } else { - currentZ += z_inc; // move right/left - t_next_z += distInZ; // update next horizontal intersection point - } - - } - return true; - } - - // -1 = invalid location, 0 = not checked yet, 1 = visible, 2 = occluding - private int getCacheValue(int x, int y, int z) { - x -= cameraPos[0]; - y -= cameraPos[1]; - z -= cameraPos[2]; - if (Math.abs(x) > reach - 2 || Math.abs(y) > reach - 2 - || Math.abs(z) > reach - 2) { - return -1; - } - - // check if target is already known - return cache.getState(x + reach, y + reach, z + reach); - } - - - private void cacheResult(int x, int y, int z, boolean result) { - int cx = x - cameraPos[0] + reach; - int cy = y - cameraPos[1] + reach; - int cz = z - cameraPos[2] + reach; - if (result) { - cache.setVisible(cx, cy, cz); - } else { - cache.setHidden(cx, cy, cz); - } - } - - private void cacheResult(Vec3d vector, boolean result) { - int cx = MathUtilities.floor(vector.x) - cameraPos[0] + reach; - int cy = MathUtilities.floor(vector.y) - cameraPos[1] + reach; - int cz = MathUtilities.floor(vector.z) - cameraPos[2] + reach; - if (result) { - cache.setVisible(cx, cy, cz); - } else { - cache.setHidden(cx, cy, cz); - } - } - - public void resetCache() { - this.cache.resetCache(); - } - - private enum Relative { - INSIDE, POSITIVE, NEGATIVE; - - public static Relative from(int min, int max, int pos) { - if (max > pos && min > pos) { - return POSITIVE; - } else if (min < pos && max < pos) { - return NEGATIVE; - } - return INSIDE; - } - } - -} diff --git a/src/main/java/com/logisticscraft/occlusionculling/cache/ArrayOcclusionCache.java b/src/main/java/com/logisticscraft/occlusionculling/cache/ArrayOcclusionCache.java deleted file mode 100644 index 08f0ddb..0000000 --- a/src/main/java/com/logisticscraft/occlusionculling/cache/ArrayOcclusionCache.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.logisticscraft.occlusionculling.cache; - -import java.util.Arrays; - -public class ArrayOcclusionCache implements OcclusionCache { - - private final int reachX2; - private final byte[] cache; - private int positionKey; - private int entry; - private int offset; - - public ArrayOcclusionCache(int reach) { - this.reachX2 = reach * 2; - this.cache = new byte[(reachX2 * reachX2 * reachX2) / 4]; - } - - @Override - public void resetCache() { - Arrays.fill(cache, (byte) 0); - } - - @Override - public void setVisible(int x, int y, int z) { - positionKey = x + y * reachX2 + z * reachX2 * reachX2; - entry = positionKey / 4; - offset = (positionKey % 4) * 2; - cache[entry] |= 1 << offset; - } - - @Override - public void setHidden(int x, int y, int z) { - positionKey = x + y * reachX2 + z * reachX2 * reachX2; - entry = positionKey / 4; - offset = (positionKey % 4) * 2; - cache[entry] |= 1 << offset + 1; - } - - @Override - public int getState(int x, int y, int z) { - positionKey = x + y * reachX2 + z * reachX2 * reachX2; - entry = positionKey / 4; - offset = (positionKey % 4) * 2; - return cache[entry] >> offset & 3; - } - - @Override - public void setLastVisible() { - cache[entry] |= 1 << offset; - } - - @Override - public void setLastHidden() { - cache[entry] |= 1 << offset + 1; - } - -} diff --git a/src/main/java/com/logisticscraft/occlusionculling/cache/OcclusionCache.java b/src/main/java/com/logisticscraft/occlusionculling/cache/OcclusionCache.java deleted file mode 100644 index 2a2e562..0000000 --- a/src/main/java/com/logisticscraft/occlusionculling/cache/OcclusionCache.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.logisticscraft.occlusionculling.cache; - -public interface OcclusionCache { - - void resetCache(); - - void setVisible(int x, int y, int z); - - void setHidden(int x, int y, int z); - - int getState(int x, int y, int z); - - void setLastHidden(); - - void setLastVisible(); - -} diff --git a/src/main/java/com/logisticscraft/occlusionculling/util/MathUtilities.java b/src/main/java/com/logisticscraft/occlusionculling/util/MathUtilities.java deleted file mode 100644 index fb28265..0000000 --- a/src/main/java/com/logisticscraft/occlusionculling/util/MathUtilities.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.logisticscraft.occlusionculling.util; - -/** - * Contains MathHelper methods - */ -public final class MathUtilities { - - private MathUtilities() { - } - - public static int floor(double d) { - int i = (int) d; - return d < (double) i ? i - 1 : i; - } - - public static int fastFloor(double d) { - return (int) (d + 1024.0) - 1024; - } - - public static int ceil(double d) { - int i = (int) d; - return d > (double) i ? i + 1 : i; - } - -} diff --git a/src/main/java/com/logisticscraft/occlusionculling/util/Vec3d.java b/src/main/java/com/logisticscraft/occlusionculling/util/Vec3d.java deleted file mode 100644 index 7e3cb9e..0000000 --- a/src/main/java/com/logisticscraft/occlusionculling/util/Vec3d.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.logisticscraft.occlusionculling.util; - -public class Vec3d { - - public double x; - public double y; - public double z; - - public Vec3d(double x, double y, double z) { - this.x = x; - this.y = y; - this.z = z; - } - - public double getX() { - return x; - } - - public double getY() { - return y; - } - - public double getZ() { - return z; - } - - public void set(double x, double y, double z) { - this.x = x; - this.y = y; - this.z = z; - } - - public void setAdd(Vec3d vec, double x, double y, double z) { - this.x = vec.x + x; - this.y = vec.y + y; - this.z = vec.z + z; - } - - public Vec3d div(Vec3d rayDir) { - this.x /= rayDir.x; - this.z /= rayDir.z; - this.y /= rayDir.y; - return this; - } - - public Vec3d normalize() { - double mag = Math.sqrt(x*x+y*y+z*z); - this.x /= mag; - this.y /= mag; - this.z /= mag; - return this; - } - - public boolean equals(Object other) { - if (this == other) { - return true; - } - if (!(other instanceof Vec3d)) { - return false; - } - Vec3d vec3d = (Vec3d) other; - if (Double.compare(vec3d.x, x) != 0) { - return false; - } - if (Double.compare(vec3d.y, y) != 0) { - return false; - } - return Double.compare(vec3d.z, z) == 0; - } - - @Override - public int hashCode() { - long l = Double.doubleToLongBits(x); - int i = (int) (l ^ l >>> 32); - l = Double.doubleToLongBits(y); - i = 31 * i + (int) (l ^ l >>> 32); - l = Double.doubleToLongBits(z); - i = 31 * i + (int) (l ^ l >>> 32); - return i; - } - - @Override - public String toString() { - return "(" + x + ", " + y + ", " + z + ")"; - } - -} diff --git a/src/main/java/net/hoosiertransfer/Culling/CullTask.java b/src/main/java/net/hoosiertransfer/Culling/CullTask.java deleted file mode 100644 index e7d5c57..0000000 --- a/src/main/java/net/hoosiertransfer/Culling/CullTask.java +++ /dev/null @@ -1,146 +0,0 @@ -package net.hoosiertransfer.Culling; - -import java.util.ConcurrentModificationException; -import java.util.Iterator; -import java.util.Set; - -import com.logisticscraft.occlusionculling.OcclusionCullingInstance; -import com.logisticscraft.occlusionculling.util.Vec3d; - -import net.hoosiertransfer.Config; -import net.minecraft.client.Minecraft; -import net.minecraft.entity.Entity; -import net.minecraft.entity.item.EntityArmorStand; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.math.AxisAlignedBB; -import net.minecraft.util.math.BlockPos; - -public class CullTask implements Runnable { - public boolean requestCull = false; - - private final OcclusionCullingInstance culling; - private final Set unCullable; - private final Minecraft client = Minecraft.getMinecraft(); - - private final int hitboxLimit = Config.hitboxLimit; - - public long lastTime = 0; - - private Vec3d lastPos = new Vec3d(0, 0, 0); - private Vec3d aabbMin = new Vec3d(0, 0, 0); - private Vec3d aabbMax = new Vec3d(0, 0, 0); - - public CullTask(OcclusionCullingInstance culling, Set unCullable) { - this.culling = culling; - this.unCullable = unCullable; - } - - @Override - public void run() { - // while (client != null) { - // try { - // Thread.sleep(Config.SleepDuration); - - // if (Config.enableCulling && client.theWorld != null && client.thePlayer != - // null && client.thePlayer.ticksExisted > 0 && client.getRenderViewEntity() != - // null) { - // Vec3 cameraMC = getCameraPos(); - // if (requestCull || !(cameraMC.xCoord == lastPos.x && cameraMC.yCoord == - // lastPos.y && cameraMC.zCoord == lastPos.z)) { - // long start = System.currentTimeMillis(); - // requestCull = false; - // lastPos.set(cameraMC.xCoord, cameraMC.yCoord, cameraMC.zCoord); - // Vec3d camera = lastPos; - // culling.resetCache(); - // boolean noCulling = client.thePlayer.isSpectator() || - // client.gameSettings.thirdPersonView != 0; - // Iterator iterator = - // client.theWorld.loadedTileEntityList.iterator(); - // TileEntity entry; - // while(iterator.hasNext()) { - // try { - // entry = iterator.next(); - // } catch(NullPointerException | ConcurrentModificationException ex) { - // break; // We are not synced to the main thread, so NPE's/CME are allowed here - // and way less - // // overhead probably than trying to sync stuff up for no really good reason - // } - // if (unCullable.contains(entry.getBlockType().getUnlocalizedName())) { - // continue; - // } - // if (!entry.isForcedVisible()) { - // if (noCulling) { - // entry.setCulled(true); - // continue; - // } - // BlockPos pos = entry.getPos(); - // if(pos.distanceSq(cameraMC.xCoord, cameraMC.yCoord, cameraMC.zCoord) < 64*64) - // { // 64 is the fixed max tile view distance - // aabbMin.set(pos.getX(), pos.getY(), pos.getZ()); - // aabbMax.set(pos.getX()+1d, pos.getY()+1d, pos.getZ()+1d); - // boolean visible = culling.isAABBVisible(aabbMin, aabbMax, camera); - // entry.setCulled(!visible); - // } - // } - // } - // Entity entity = null; - // Iterator iterable = client.theWorld.getLoadedEntityList().iterator(); - // while(iterable.hasNext()) { - // try { - // entity = iterable.next(); - // } catch(NullPointerException | ConcurrentModificationException ex) { - // break; // We are not synced to the main thread, so NPE's/CME are allowed here - // and way less - // // overhead probably than trying to sync stuff up for no really good reason - // } - // if (entity == null) { - // continue; - // } - // if (!entity.isForcedVisible()) { - // if (noCulling || isSkippableArmorstand(entity)) { - // entity.setCulled(false); - // continue; - // } - // if(entity.getPositionVector().squareDistanceTo(cameraMC) > - // Config.tracingDistance * Config.tracingDistance) { - // entity.setCulled(false); // If your entity view distance is larger than - // tracingDistance just render it - // continue; - // } - // AxisAlignedBB boundingBox = entity.getEntityBoundingBox(); - // if(boundingBox.maxX - boundingBox.minX > hitboxLimit || boundingBox.maxY - - // boundingBox.minY > hitboxLimit || boundingBox.maxZ - boundingBox.minZ > - // hitboxLimit) { - // entity.setCulled(false); // To big to bother to cull - // continue; - // } - // aabbMin.set(boundingBox.minX, boundingBox.minY, boundingBox.minZ); - // aabbMax.set(boundingBox.maxX, boundingBox.maxY, boundingBox.maxZ); - // boolean visible = culling.isAABBVisible(aabbMin, aabbMax, camera); - // entity.setCulled(!visible); - // } - // } - // lastTime = (System.currentTimeMillis()-start); - // } - // } - // } catch (Exception e) { - // e.printStackTrace(); - // } - // } - // System.out.println("Culling thread stopped"); - } - - private net.minecraft.util.math.Vec3d getCameraPos() { - if (client.gameSettings.thirdPersonView == 0) { - return client.thePlayer.getPositionEyes(0); - } - return client.getRenderViewEntity().getPositionEyes(0); - } - - private boolean isSkippableArmorstand(Entity entity) { - if (!Config.skipMarkerArmorStands) - return false; - return entity instanceof EntityArmorStand && ((EntityArmorStand) entity).func_181026_s(); // i think this is the - // marker flag - } -} diff --git a/src/main/java/net/hoosiertransfer/Culling/Provider.java b/src/main/java/net/hoosiertransfer/Culling/Provider.java deleted file mode 100644 index e5994f6..0000000 --- a/src/main/java/net/hoosiertransfer/Culling/Provider.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.hoosiertransfer.Culling; - -import com.logisticscraft.occlusionculling.DataProvider; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.multiplayer.WorldClient; -import net.minecraft.util.math.BlockPos; - -public class Provider implements DataProvider { - private final Minecraft client = Minecraft.getMinecraft(); - private WorldClient world = null; - - @Override - public boolean prepareChunk(int chunkX, int chunkZ) { - world = client.theWorld; - return world != null; - } - - @Override - public boolean isOpaqueFullCube(int x, int y, int z) { - BlockPos pos = new BlockPos(x, y, z); - return world.getBlockState(pos).getBlock().isOpaqueCube(); - } - - @Override - public void cleanup() { - world = null; - } -} \ No newline at end of file diff --git a/src/main/java/net/hoosiertransfer/CullingMod.java b/src/main/java/net/hoosiertransfer/CullingMod.java deleted file mode 100644 index d5cda52..0000000 --- a/src/main/java/net/hoosiertransfer/CullingMod.java +++ /dev/null @@ -1,34 +0,0 @@ -package net.hoosiertransfer; - -import com.logisticscraft.occlusionculling.OcclusionCullingInstance; - -import net.hoosiertransfer.Culling.CullTask; -import net.hoosiertransfer.Culling.Provider; - -public class CullingMod { - public static OcclusionCullingInstance culling; - public static CullTask cullTask; - private static Thread cullThread; - - public static int skippedBlockEntities = 0; - public static int renderedBlockEntities = 0; - public static int skippedEntities = 0; - public static int renderedEntities = 0; - - public static void intialize() { - culling = new OcclusionCullingInstance(Config.tracingDistance, new Provider()); - cullTask = new CullTask(culling, Config.blockEntityWhitelist); - - cullThread = new Thread(cullTask, "CullThread"); - - cullThread.setUncaughtExceptionHandler((thread, throwable) -> { - System.err.println("Error in culling thread"); - throwable.printStackTrace(); - }); - cullThread.start(); - } - - public static void setRequestCull(boolean cull) { - cullTask.requestCull = cull; - } -} \ No newline at end of file diff --git a/src/main/java/net/minecraft/client/Minecraft.java b/src/main/java/net/minecraft/client/Minecraft.java index 17a4277..a73d4d3 100644 --- a/src/main/java/net/minecraft/client/Minecraft.java +++ b/src/main/java/net/minecraft/client/Minecraft.java @@ -19,7 +19,6 @@ import org.apache.commons.lang3.Validate; import com.google.common.collect.Lists; -import net.hoosiertransfer.CullingMod; import net.hoosiertransfer.Alfheim.ILightUpdatesProcessor; import net.hoosiertransfer.Config; @@ -361,7 +360,6 @@ public class Minecraft implements IThreadListener { } public void run() { - CullingMod.intialize(); this.running = true; try { @@ -1313,7 +1311,6 @@ public class Minecraft implements IThreadListener { * Runs the current tick. */ public void runTick() throws IOException { - CullingMod.setRequestCull(true); if (this.rightClickDelayTimer > 0) { --this.rightClickDelayTimer; } diff --git a/src/main/java/net/minecraft/client/gui/GuiOverlayDebug.java b/src/main/java/net/minecraft/client/gui/GuiOverlayDebug.java index e51c2f2..a874b60 100644 --- a/src/main/java/net/minecraft/client/gui/GuiOverlayDebug.java +++ b/src/main/java/net/minecraft/client/gui/GuiOverlayDebug.java @@ -14,8 +14,6 @@ import java.util.TimeZone; import com.google.common.base.Strings; import com.google.common.collect.Lists; -import net.hoosiertransfer.Config; -import net.hoosiertransfer.CullingMod; import net.lax1dude.eaglercraft.v1_8.Display; import net.lax1dude.eaglercraft.v1_8.EagRuntime; import net.lax1dude.eaglercraft.v1_8.HString; @@ -428,16 +426,6 @@ public class GuiOverlayDebug extends Gui { arraylist.add(HString.format("Looking at: %d %d %d", new Object[] { Integer.valueOf(blockpos1.getX()), Integer.valueOf(blockpos1.getY()), Integer.valueOf(blockpos1.getZ()) })); } - arraylist.add("[Culling] Last pass: " + CullingMod.cullTask.lastTime + "ms"); - arraylist.add("[Culling] Rendered Block Entities: " + CullingMod.renderedBlockEntities + " Skipped: " - + CullingMod.skippedBlockEntities); - arraylist.add("[Culling] Rendered Entities: " + CullingMod.renderedEntities + " Skipped: " - + CullingMod.skippedEntities); - - CullingMod.renderedBlockEntities = 0; - CullingMod.skippedBlockEntities = 0; - CullingMod.renderedEntities = 0; - CullingMod.skippedEntities = 0; return arraylist; } diff --git a/src/main/java/net/minecraft/client/renderer/entity/RenderManager.java b/src/main/java/net/minecraft/client/renderer/entity/RenderManager.java index 5f6e43a..6cfa25b 100644 --- a/src/main/java/net/minecraft/client/renderer/entity/RenderManager.java +++ b/src/main/java/net/minecraft/client/renderer/entity/RenderManager.java @@ -6,7 +6,6 @@ import com.google.common.collect.Maps; import net.lax1dude.eaglercraft.v1_8.EagRuntime; import net.hoosiertransfer.Config; -import net.hoosiertransfer.CullingMod; import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager; import net.lax1dude.eaglercraft.v1_8.opengl.OpenGlHelper; import net.lax1dude.eaglercraft.v1_8.opengl.WorldRenderer; @@ -408,17 +407,6 @@ public class RenderManager { public boolean doRenderEntity(Entity entity, double x, double y, double z, float entityYaw, float partialTicks, boolean parFlag) { - if (!entity.isForcedVisible() && entity.isCulled()) { - Render render = getEntityRenderObject(entity); - if (Config.renderNameTagsThroguthWalls && render.canRenderName(entity)) { - render.renderLivingLabel(entity, entity.getDisplayName().getFormattedText(), x, y, z, 64); - } - CullingMod.skippedEntities++; - return false; - } - CullingMod.renderedEntities++; - entity.setOutOfCamera(false); - Render render = null; try { diff --git a/src/main/java/net/minecraft/client/renderer/tileentity/TileEntityRendererDispatcher.java b/src/main/java/net/minecraft/client/renderer/tileentity/TileEntityRendererDispatcher.java index e2d4b71..adad829 100644 --- a/src/main/java/net/minecraft/client/renderer/tileentity/TileEntityRendererDispatcher.java +++ b/src/main/java/net/minecraft/client/renderer/tileentity/TileEntityRendererDispatcher.java @@ -4,7 +4,6 @@ import java.util.Map; import com.google.common.collect.Maps; -import net.hoosiertransfer.CullingMod; import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager; import net.lax1dude.eaglercraft.v1_8.opengl.OpenGlHelper; import net.lax1dude.eaglercraft.v1_8.opengl.ext.dynamiclights.DynamicLightsStateManager; @@ -156,12 +155,6 @@ public class TileEntityRendererDispatcher { */ public void renderTileEntityAt(TileEntity tileEntityIn, double x, double y, double z, float partialTicks, int destroyStage) { - if (!tileEntityIn.isForcedVisible() && tileEntityIn.isCulled()) { - CullingMod.skippedBlockEntities++; - return; - } - CullingMod.renderedBlockEntities++; - TileEntitySpecialRenderer tileentityspecialrenderer = this.getSpecialRenderer(tileEntityIn); if (tileentityspecialrenderer != null) { try { diff --git a/src/main/java/net/minecraft/entity/Entity.java b/src/main/java/net/minecraft/entity/Entity.java index 5e68b55..2ffa715 100644 --- a/src/main/java/net/minecraft/entity/Entity.java +++ b/src/main/java/net/minecraft/entity/Entity.java @@ -161,46 +161,11 @@ public abstract class Entity implements ICommandSender { protected EaglercraftUUID entityUniqueID; private final CommandResultStats cmdResultStats; - private long lastTime = 0; - private boolean culled = false; - private boolean outOfCamera = false; - private long displayNameCachedAt; private ITextComponent cachedDisplayName; protected boolean glowing; - public void setTimeout() { - lastTime = System.currentTimeMillis() + 1000; - } - - public boolean isForcedVisible() { - return lastTime > System.currentTimeMillis(); - } - - public void setCulled(boolean value) { - this.culled = value; - if (!value) { - setTimeout(); - } - } - - public boolean isCulled() { - if (!Config.enableCulling) - return false; - return culled; - } - - public void setOutOfCamera(boolean value) { - this.outOfCamera = value; - } - - public boolean isOutOfCamera() { - if (!Config.enableCulling) - return false; - return outOfCamera; - } - public int getEntityId() { return this.entityId; } diff --git a/src/main/java/net/minecraft/tileentity/TileEntity.java b/src/main/java/net/minecraft/tileentity/TileEntity.java index 9657b29..0f44511 100644 --- a/src/main/java/net/minecraft/tileentity/TileEntity.java +++ b/src/main/java/net/minecraft/tileentity/TileEntity.java @@ -58,41 +58,6 @@ public abstract class TileEntity { private int blockMetadata = -1; protected Block blockType; - private long lastTime = 0; - private boolean culled = false; - private boolean outOfCamera = false; - - public void setTimeout() { - lastTime = System.currentTimeMillis() + 1000; - } - - public boolean isForcedVisible() { - return lastTime > System.currentTimeMillis(); - } - - public void setCulled(boolean value) { - this.culled = value; - if (!value) { - setTimeout(); - } - } - - public boolean isCulled() { - if (!Config.enableCulling) - return false; - return culled; - } - - public void setOutOfCamera(boolean value) { - this.outOfCamera = value; - } - - public boolean isOutOfCamera() { - if (!Config.enableCulling) - return false; - return outOfCamera; - } - /** * + * Adds a new two-way mapping between the class and its string