mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-12-30 17:06:32 +01:00
Immutable view of GridAlignedBB
This commit is contained in:
parent
c055873bac
commit
1f7af0d8b2
7 changed files with 304 additions and 234 deletions
|
@ -5,7 +5,6 @@ import com.jozufozu.flywheel.core.AtlasStitcher;
|
||||||
import com.jozufozu.flywheel.core.Contexts;
|
import com.jozufozu.flywheel.core.Contexts;
|
||||||
import com.jozufozu.flywheel.core.Materials;
|
import com.jozufozu.flywheel.core.Materials;
|
||||||
import com.jozufozu.flywheel.core.PartialModel;
|
import com.jozufozu.flywheel.core.PartialModel;
|
||||||
import com.jozufozu.flywheel.light.debug.DebugView;
|
|
||||||
import com.jozufozu.flywheel.vanilla.VanillaInstances;
|
import com.jozufozu.flywheel.vanilla.VanillaInstances;
|
||||||
|
|
||||||
import net.minecraftforge.eventbus.api.IEventBus;
|
import net.minecraftforge.eventbus.api.IEventBus;
|
||||||
|
|
|
@ -10,6 +10,7 @@ import com.jozufozu.flywheel.light.GridAlignedBB;
|
||||||
import com.jozufozu.flywheel.light.ILightUpdateListener;
|
import com.jozufozu.flywheel.light.ILightUpdateListener;
|
||||||
import com.jozufozu.flywheel.light.LightProvider;
|
import com.jozufozu.flywheel.light.LightProvider;
|
||||||
import com.jozufozu.flywheel.light.ListenerStatus;
|
import com.jozufozu.flywheel.light.ListenerStatus;
|
||||||
|
import com.jozufozu.flywheel.light.ReadOnlyBox;
|
||||||
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.LightType;
|
import net.minecraft.world.LightType;
|
||||||
|
@ -73,7 +74,7 @@ public abstract class AbstractInstance implements IInstance, ILightUpdateListene
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLightUpdate(LightProvider world, LightType type, GridAlignedBB changed) {
|
public void onLightUpdate(LightProvider world, LightType type, ReadOnlyBox changed) {
|
||||||
updateLight();
|
updateLight();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
package com.jozufozu.flywheel.light;
|
package com.jozufozu.flywheel.light;
|
||||||
|
|
||||||
import static com.jozufozu.flywheel.util.RenderUtil.isPowerOf2;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.util.RenderUtil;
|
import com.jozufozu.flywheel.util.RenderUtil;
|
||||||
|
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
|
@ -10,13 +8,13 @@ import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.SectionPos;
|
import net.minecraft.util.math.SectionPos;
|
||||||
import net.minecraft.util.math.vector.Vector3i;
|
import net.minecraft.util.math.vector.Vector3i;
|
||||||
|
|
||||||
public class GridAlignedBB {
|
public class GridAlignedBB implements ReadOnlyBox {
|
||||||
public int minX;
|
private int minX;
|
||||||
public int minY;
|
private int minY;
|
||||||
public int minZ;
|
private int minZ;
|
||||||
public int maxX;
|
private int maxX;
|
||||||
public int maxY;
|
private int maxY;
|
||||||
public int maxZ;
|
private int maxZ;
|
||||||
|
|
||||||
public GridAlignedBB(int minX, int minY, int minZ, int maxX, int maxY, int maxZ) {
|
public GridAlignedBB(int minX, int minY, int minZ, int maxX, int maxY, int maxZ) {
|
||||||
this.minX = minX;
|
this.minX = minX;
|
||||||
|
@ -31,10 +29,6 @@ public class GridAlignedBB {
|
||||||
return new GridAlignedBB(-radius, -radius, -radius, radius + 1, radius + 1, radius + 1);
|
return new GridAlignedBB(-radius, -radius, -radius, radius + 1, radius + 1, radius + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GridAlignedBB copy(GridAlignedBB bb) {
|
|
||||||
return new GridAlignedBB(bb.minX, bb.minY, bb.minZ, bb.maxX, bb.maxY, bb.maxZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static GridAlignedBB from(AxisAlignedBB aabb) {
|
public static GridAlignedBB from(AxisAlignedBB aabb) {
|
||||||
int minX = (int) Math.floor(aabb.minX);
|
int minX = (int) Math.floor(aabb.minX);
|
||||||
int minY = (int) Math.floor(aabb.minY);
|
int minY = (int) Math.floor(aabb.minY);
|
||||||
|
@ -63,62 +57,20 @@ public class GridAlignedBB {
|
||||||
return new GridAlignedBB(startX, 0, startZ, startX + 16, 256, startZ + 16);
|
return new GridAlignedBB(startX, 0, startZ, startX + 16, 256, startZ + 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AxisAlignedBB toAABB(GridAlignedBB bb) {
|
|
||||||
return new AxisAlignedBB(bb.minX, bb.minY, bb.minZ, bb.maxX, bb.maxY, bb.maxZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
public GridAlignedBB copy() {
|
|
||||||
return copy(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean sameAs(GridAlignedBB other) {
|
|
||||||
return minX == other.minX && minY == other.minY && minZ == other.minZ && maxX == other.maxX && maxY == other.maxY && maxZ == other.maxZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean sameAs(AxisAlignedBB other) {
|
|
||||||
return minX == Math.floor(other.minX)
|
|
||||||
&& minY == Math.floor(other.minY)
|
|
||||||
&& minZ == Math.floor(other.minZ)
|
|
||||||
&& maxX == Math.ceil(other.maxX)
|
|
||||||
&& maxY == Math.ceil(other.maxY)
|
|
||||||
&& maxZ == Math.ceil(other.maxZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fixMinMax() {
|
public void fixMinMax() {
|
||||||
int minX = Math.min(this.minX, this.maxX);
|
int minX = Math.min(this.getMinX(), this.getMaxX());
|
||||||
int minY = Math.min(this.minY, this.maxY);
|
int minY = Math.min(this.getMinY(), this.getMaxY());
|
||||||
int minZ = Math.min(this.minZ, this.maxZ);
|
int minZ = Math.min(this.getMinZ(), this.getMaxZ());
|
||||||
int maxX = Math.max(this.minX, this.maxX);
|
int maxX = Math.max(this.getMinX(), this.getMaxX());
|
||||||
int maxY = Math.max(this.minY, this.maxY);
|
int maxY = Math.max(this.getMinY(), this.getMaxY());
|
||||||
int maxZ = Math.max(this.minZ, this.maxZ);
|
int maxZ = Math.max(this.getMinZ(), this.getMaxZ());
|
||||||
|
|
||||||
this.minX = minX;
|
this.setMinX(minX);
|
||||||
this.minY = minY;
|
this.setMinY(minY);
|
||||||
this.minZ = minZ;
|
this.setMinZ(minZ);
|
||||||
this.maxX = maxX;
|
this.setMaxX(maxX);
|
||||||
this.maxY = maxY;
|
this.setMaxY(maxY);
|
||||||
this.maxZ = maxZ;
|
this.setMaxZ(maxZ);
|
||||||
}
|
|
||||||
|
|
||||||
public int sizeX() {
|
|
||||||
return maxX - minX;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int sizeY() {
|
|
||||||
return maxY - minY;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int sizeZ() {
|
|
||||||
return maxZ - minZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int volume() {
|
|
||||||
return sizeX() * sizeY() * sizeZ();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean empty() {
|
|
||||||
// if any dimension has side length 0 this box contains no volume
|
|
||||||
return minX == maxX || minY == maxY || minZ == maxZ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void translate(Vector3i by) {
|
public void translate(Vector3i by) {
|
||||||
|
@ -126,12 +78,12 @@ public class GridAlignedBB {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void translate(int x, int y, int z) {
|
public void translate(int x, int y, int z) {
|
||||||
minX += x;
|
setMinX(getMinX() + x);
|
||||||
maxX += x;
|
setMaxX(getMaxX() + x);
|
||||||
minY += y;
|
setMinY(getMinY() + y);
|
||||||
maxY += y;
|
setMaxY(getMaxY() + y);
|
||||||
minZ += z;
|
setMinZ(getMinZ() + z);
|
||||||
maxZ += z;
|
setMaxZ(getMaxZ() + z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void mirrorAbout(Direction.Axis axis) {
|
public void mirrorAbout(Direction.Axis axis) {
|
||||||
|
@ -141,15 +93,15 @@ public class GridAlignedBB {
|
||||||
int flipY = axisVec.getY() - 1;
|
int flipY = axisVec.getY() - 1;
|
||||||
int flipZ = axisVec.getZ() - 1;
|
int flipZ = axisVec.getZ() - 1;
|
||||||
|
|
||||||
int maxX = this.maxX * flipX;
|
int maxX = this.getMaxX() * flipX;
|
||||||
int maxY = this.maxY * flipY;
|
int maxY = this.getMaxY() * flipY;
|
||||||
int maxZ = this.maxZ * flipZ;
|
int maxZ = this.getMaxZ() * flipZ;
|
||||||
this.maxX = this.minX * flipX;
|
this.setMaxX(this.getMinX() * flipX);
|
||||||
this.maxY = this.minY * flipY;
|
this.setMaxY(this.getMinY() * flipY);
|
||||||
this.maxZ = this.minZ * flipZ;
|
this.setMaxZ(this.getMinZ() * flipZ);
|
||||||
this.minX = maxX;
|
this.setMinX(maxX);
|
||||||
this.minY = maxY;
|
this.setMinY(maxY);
|
||||||
this.minZ = maxZ;
|
this.setMinZ(maxZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -168,12 +120,12 @@ public class GridAlignedBB {
|
||||||
int diffY = newSizeY - sizeY;
|
int diffY = newSizeY - sizeY;
|
||||||
int diffZ = newSizeZ - sizeZ;
|
int diffZ = newSizeZ - sizeZ;
|
||||||
|
|
||||||
minX -= diffX / 2; // floor division for the minimums
|
setMinX(getMinX() - diffX / 2); // floor division for the minimums
|
||||||
minY -= diffY / 2;
|
setMinY(getMinY() - diffY / 2);
|
||||||
minZ -= diffZ / 2;
|
setMinZ(getMinZ() - diffZ / 2);
|
||||||
maxX += (diffX + 1) / 2; // ceiling divison for the maximums
|
setMaxX(getMaxX() + (diffX + 1) / 2); // ceiling divison for the maximums
|
||||||
maxY += (diffY + 1) / 2;
|
setMaxY(getMaxY() + (diffY + 1) / 2);
|
||||||
maxZ += (diffZ + 1) / 2;
|
setMaxZ(getMaxZ() + (diffZ + 1) / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -184,14 +136,9 @@ public class GridAlignedBB {
|
||||||
int sizeY = RenderUtil.nextPowerOf2(sizeY());
|
int sizeY = RenderUtil.nextPowerOf2(sizeY());
|
||||||
int sizeZ = RenderUtil.nextPowerOf2(sizeZ());
|
int sizeZ = RenderUtil.nextPowerOf2(sizeZ());
|
||||||
|
|
||||||
this.maxX = this.minX + sizeX;
|
this.setMaxX(this.getMinX() + sizeX);
|
||||||
this.maxY = this.minY + sizeY;
|
this.setMaxY(this.getMinY() + sizeY);
|
||||||
this.maxZ = this.minZ + sizeZ;
|
this.setMaxZ(this.getMinZ() + sizeZ);
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasPowerOf2Sides() {
|
|
||||||
// this is only true if all individual side lengths are powers of 2
|
|
||||||
return isPowerOf2(volume());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void grow(int s) {
|
public void grow(int s) {
|
||||||
|
@ -199,109 +146,57 @@ public class GridAlignedBB {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void grow(int x, int y, int z) {
|
public void grow(int x, int y, int z) {
|
||||||
minX -= x;
|
setMinX(getMinX() - x);
|
||||||
minY -= y;
|
setMinY(getMinY() - y);
|
||||||
minZ -= z;
|
setMinZ(getMinZ() - z);
|
||||||
maxX += x;
|
setMaxX(getMaxX() + x);
|
||||||
maxY += y;
|
setMaxY(getMaxY() + y);
|
||||||
maxZ += z;
|
setMaxZ(getMaxZ() + z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GridAlignedBB intersect(GridAlignedBB other) {
|
public void intersectAssign(ReadOnlyBox other) {
|
||||||
int minX = Math.max(this.minX, other.minX);
|
this.setMinX(Math.max(this.getMinX(), other.getMinX()));
|
||||||
int minY = Math.max(this.minY, other.minY);
|
this.setMinY(Math.max(this.getMinY(), other.getMinY()));
|
||||||
int minZ = Math.max(this.minZ, other.minZ);
|
this.setMinZ(Math.max(this.getMinZ(), other.getMinZ()));
|
||||||
int maxX = Math.min(this.maxX, other.maxX);
|
this.setMaxX(Math.min(this.getMaxX(), other.getMaxX()));
|
||||||
int maxY = Math.min(this.maxY, other.maxY);
|
this.setMaxY(Math.min(this.getMaxY(), other.getMaxY()));
|
||||||
int maxZ = Math.min(this.maxZ, other.maxZ);
|
this.setMaxZ(Math.min(this.getMaxZ(), other.getMaxZ()));
|
||||||
return new GridAlignedBB(minX, minY, minZ, maxX, maxY, maxZ);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void intersectAssign(GridAlignedBB other) {
|
public void unionAssign(ReadOnlyBox other) {
|
||||||
this.minX = Math.max(this.minX, other.minX);
|
this.setMinX(Math.min(this.getMinX(), other.getMinX()));
|
||||||
this.minY = Math.max(this.minY, other.minY);
|
this.setMinY(Math.min(this.getMinY(), other.getMinY()));
|
||||||
this.minZ = Math.max(this.minZ, other.minZ);
|
this.setMinZ(Math.min(this.getMinZ(), other.getMinZ()));
|
||||||
this.maxX = Math.min(this.maxX, other.maxX);
|
this.setMaxX(Math.max(this.getMaxX(), other.getMaxX()));
|
||||||
this.maxY = Math.min(this.maxY, other.maxY);
|
this.setMaxY(Math.max(this.getMaxY(), other.getMaxY()));
|
||||||
this.maxZ = Math.min(this.maxZ, other.maxZ);
|
this.setMaxZ(Math.max(this.getMaxZ(), other.getMaxZ()));
|
||||||
}
|
|
||||||
|
|
||||||
public GridAlignedBB union(GridAlignedBB other) {
|
|
||||||
int minX = Math.min(this.minX, other.minX);
|
|
||||||
int minY = Math.min(this.minY, other.minY);
|
|
||||||
int minZ = Math.min(this.minZ, other.minZ);
|
|
||||||
int maxX = Math.max(this.maxX, other.maxX);
|
|
||||||
int maxY = Math.max(this.maxY, other.maxY);
|
|
||||||
int maxZ = Math.max(this.maxZ, other.maxZ);
|
|
||||||
return new GridAlignedBB(minX, minY, minZ, maxX, maxY, maxZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void unionAssign(GridAlignedBB other) {
|
|
||||||
this.minX = Math.min(this.minX, other.minX);
|
|
||||||
this.minY = Math.min(this.minY, other.minY);
|
|
||||||
this.minZ = Math.min(this.minZ, other.minZ);
|
|
||||||
this.maxX = Math.max(this.maxX, other.maxX);
|
|
||||||
this.maxY = Math.max(this.maxY, other.maxY);
|
|
||||||
this.maxZ = Math.max(this.maxZ, other.maxZ);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unionAssign(AxisAlignedBB other) {
|
public void unionAssign(AxisAlignedBB other) {
|
||||||
this.minX = Math.min(this.minX, (int) Math.floor(other.minX));
|
this.setMinX(Math.min(this.getMinX(), (int) Math.floor(other.minX)));
|
||||||
this.minY = Math.min(this.minY, (int) Math.floor(other.minY));
|
this.setMinY(Math.min(this.getMinY(), (int) Math.floor(other.minY)));
|
||||||
this.minZ = Math.min(this.minZ, (int) Math.floor(other.minZ));
|
this.setMinZ(Math.min(this.getMinZ(), (int) Math.floor(other.minZ)));
|
||||||
this.maxX = Math.max(this.maxX, (int) Math.ceil(other.maxX));
|
this.setMaxX(Math.max(this.getMaxX(), (int) Math.ceil(other.maxX)));
|
||||||
this.maxY = Math.max(this.maxY, (int) Math.ceil(other.maxY));
|
this.setMaxY(Math.max(this.getMaxY(), (int) Math.ceil(other.maxY)));
|
||||||
this.maxZ = Math.max(this.maxZ, (int) Math.ceil(other.maxZ));
|
this.setMaxZ(Math.max(this.getMaxZ(), (int) Math.ceil(other.maxZ)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void assign(AxisAlignedBB other) {
|
public void assign(AxisAlignedBB other) {
|
||||||
this.minX = (int) Math.floor(other.minX);
|
this.setMinX((int) Math.floor(other.minX));
|
||||||
this.minY = (int) Math.floor(other.minY);
|
this.setMinY((int) Math.floor(other.minY));
|
||||||
this.minZ = (int) Math.floor(other.minZ);
|
this.setMinZ((int) Math.floor(other.minZ));
|
||||||
this.maxX = (int) Math.ceil(other.maxX);
|
this.setMaxX((int) Math.ceil(other.maxX));
|
||||||
this.maxY = (int) Math.ceil(other.maxY);
|
this.setMaxY((int) Math.ceil(other.maxY));
|
||||||
this.maxZ = (int) Math.ceil(other.maxZ);
|
this.setMaxZ((int) Math.ceil(other.maxZ));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void assign(GridAlignedBB other) {
|
public void assign(ReadOnlyBox other) {
|
||||||
this.minX = other.minX;
|
this.setMinX(other.getMinX());
|
||||||
this.minY = other.minY;
|
this.setMinY(other.getMinY());
|
||||||
this.minZ = other.minZ;
|
this.setMinZ(other.getMinZ());
|
||||||
this.maxX = other.maxX;
|
this.setMaxX(other.getMaxX());
|
||||||
this.maxY = other.maxY;
|
this.setMaxY(other.getMaxY());
|
||||||
this.maxZ = other.maxZ;
|
this.setMaxZ(other.getMaxZ());
|
||||||
}
|
|
||||||
|
|
||||||
public boolean intersects(GridAlignedBB other) {
|
|
||||||
return this.intersects(other.minX, other.minY, other.minZ, other.maxX, other.maxY, other.maxZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean contains(GridAlignedBB other) {
|
|
||||||
return other.minX >= this.minX && other.maxX <= this.maxX && other.minY >= this.minY && other.maxY <= this.maxY && other.minZ >= this.minZ && other.maxZ <= this.maxZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isContainedBy(GridAlignedBB other) {
|
|
||||||
return other.contains(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean intersects(int minX, int minY, int minZ, int maxX, int maxY, int maxZ) {
|
|
||||||
return this.minX < maxX && this.maxX > minX && this.minY < maxY && this.maxY > minY && this.minZ < maxZ && this.maxZ > minZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void forEachContained(ICoordinateConsumer func) {
|
|
||||||
if (empty()) return;
|
|
||||||
|
|
||||||
for (int x = minX; x < maxX; x++) {
|
|
||||||
for (int y = Math.max(minY, 0); y < Math.min(maxY, 255); y++) { // clamp to world height limits
|
|
||||||
for (int z = minZ; z < maxZ; z++) {
|
|
||||||
func.consume(x, y, z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public AxisAlignedBB toAABB() {
|
|
||||||
return toAABB(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -309,19 +204,79 @@ public class GridAlignedBB {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
GridAlignedBB that = (GridAlignedBB) o;
|
ReadOnlyBox that = (ReadOnlyBox) o;
|
||||||
|
|
||||||
return this.sameAs(that);
|
return this.sameAs(that);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int result = minX;
|
int result = getMinX();
|
||||||
result = 31 * result + minY;
|
result = 31 * result + getMinY();
|
||||||
result = 31 * result + minZ;
|
result = 31 * result + getMinZ();
|
||||||
result = 31 * result + maxX;
|
result = 31 * result + getMaxX();
|
||||||
result = 31 * result + maxY;
|
result = 31 * result + getMaxY();
|
||||||
result = 31 * result + maxZ;
|
result = 31 * result + getMaxZ();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinX() {
|
||||||
|
return minX;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinY() {
|
||||||
|
return minY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinZ() {
|
||||||
|
return minZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxX() {
|
||||||
|
return maxX;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxY() {
|
||||||
|
return maxY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxZ() {
|
||||||
|
return maxZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GridAlignedBB setMinX(int minX) {
|
||||||
|
this.minX = minX;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GridAlignedBB setMinY(int minY) {
|
||||||
|
this.minY = minY;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GridAlignedBB setMinZ(int minZ) {
|
||||||
|
this.minZ = minZ;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GridAlignedBB setMaxX(int maxX) {
|
||||||
|
this.maxX = maxX;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GridAlignedBB setMaxY(int maxY) {
|
||||||
|
this.maxY = maxY;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GridAlignedBB setMaxZ(int maxZ) {
|
||||||
|
this.maxZ = maxZ;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,14 +4,14 @@ import net.minecraft.world.LightType;
|
||||||
|
|
||||||
public interface ILightUpdateListener {
|
public interface ILightUpdateListener {
|
||||||
|
|
||||||
GridAlignedBB getVolume();
|
ReadOnlyBox getVolume();
|
||||||
|
|
||||||
ListenerStatus status();
|
ListenerStatus status();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when a light updates in a chunk the implementor cares about.
|
* Called when a light updates in a chunk the implementor cares about.
|
||||||
*/
|
*/
|
||||||
void onLightUpdate(LightProvider world, LightType type, GridAlignedBB changed);
|
void onLightUpdate(LightProvider world, LightType type, ReadOnlyBox changed);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the server sends light data to the client.
|
* Called when the server sends light data to the client.
|
||||||
|
|
|
@ -50,17 +50,17 @@ public class LightUpdater {
|
||||||
if (listener instanceof IMovingListener)
|
if (listener instanceof IMovingListener)
|
||||||
movingListeners.add(((IMovingListener) listener));
|
movingListeners.add(((IMovingListener) listener));
|
||||||
|
|
||||||
GridAlignedBB box = listener.getVolume();
|
ReadOnlyBox box = listener.getVolume();
|
||||||
|
|
||||||
LongSet sections = this.sections.getAndResetContainment(listener);
|
LongSet sections = this.sections.getAndResetContainment(listener);
|
||||||
LongSet chunks = this.chunks.getAndResetContainment(listener);
|
LongSet chunks = this.chunks.getAndResetContainment(listener);
|
||||||
|
|
||||||
int minX = SectionPos.blockToSectionCoord(box.minX);
|
int minX = SectionPos.blockToSectionCoord(box.getMinX());
|
||||||
int minY = SectionPos.blockToSectionCoord(box.minY);
|
int minY = SectionPos.blockToSectionCoord(box.getMinY());
|
||||||
int minZ = SectionPos.blockToSectionCoord(box.minZ);
|
int minZ = SectionPos.blockToSectionCoord(box.getMinZ());
|
||||||
int maxX = SectionPos.blockToSectionCoord(box.maxX);
|
int maxX = SectionPos.blockToSectionCoord(box.getMaxX());
|
||||||
int maxY = SectionPos.blockToSectionCoord(box.maxY);
|
int maxY = SectionPos.blockToSectionCoord(box.getMaxY());
|
||||||
int maxZ = SectionPos.blockToSectionCoord(box.maxZ);
|
int maxZ = SectionPos.blockToSectionCoord(box.getMaxZ());
|
||||||
|
|
||||||
for (int x = minX; x <= maxX; x++) {
|
for (int x = minX; x <= maxX; x++) {
|
||||||
for (int z = minZ; z <= maxZ; z++) {
|
for (int z = minZ; z <= maxZ; z++) {
|
||||||
|
@ -88,10 +88,10 @@ public class LightUpdater {
|
||||||
|
|
||||||
set.removeIf(l -> l.status().shouldRemove());
|
set.removeIf(l -> l.status().shouldRemove());
|
||||||
|
|
||||||
GridAlignedBB chunkBox = GridAlignedBB.from(SectionPos.of(sectionPos));
|
ReadOnlyBox chunkBox = GridAlignedBB.from(SectionPos.of(sectionPos));
|
||||||
|
|
||||||
for (ILightUpdateListener listener : set) {
|
for (ILightUpdateListener listener : set) {
|
||||||
listener.onLightUpdate(provider, type, chunkBox.copy());
|
listener.onLightUpdate(provider, type, chunkBox);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ public class LightUpdater {
|
||||||
return sectionPos & 0xFFFFFFFFFFF_00000L;
|
return sectionPos & 0xFFFFFFFFFFF_00000L;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Stream<GridAlignedBB> getAllBoxes() {
|
public Stream<ReadOnlyBox> getAllBoxes() {
|
||||||
return chunks.stream().map(ILightUpdateListener::getVolume);
|
return chunks.stream().map(ILightUpdateListener::getVolume);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,36 +76,36 @@ public class LightVolume {
|
||||||
this.textureVolume.nextPowerOf2Centered();
|
this.textureVolume.nextPowerOf2Centered();
|
||||||
}
|
}
|
||||||
|
|
||||||
public GridAlignedBB getTextureVolume() {
|
public ReadOnlyBox getTextureVolume() {
|
||||||
return GridAlignedBB.copy(textureVolume);
|
return textureVolume;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GridAlignedBB getSampleVolume() {
|
public ReadOnlyBox getSampleVolume() {
|
||||||
return GridAlignedBB.copy(sampleVolume);
|
return sampleVolume;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMinX() {
|
public int getMinX() {
|
||||||
return textureVolume.minX;
|
return textureVolume.getMinX();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMinY() {
|
public int getMinY() {
|
||||||
return textureVolume.minY;
|
return textureVolume.getMinY();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMinZ() {
|
public int getMinZ() {
|
||||||
return textureVolume.minZ;
|
return textureVolume.getMinZ();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMaxX() {
|
public int getMaxX() {
|
||||||
return textureVolume.maxX;
|
return textureVolume.getMaxX();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMaxY() {
|
public int getMaxY() {
|
||||||
return textureVolume.maxY;
|
return textureVolume.getMaxY();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMaxZ() {
|
public int getMaxZ() {
|
||||||
return textureVolume.maxZ;
|
return textureVolume.getMaxZ();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSizeX() {
|
public int getSizeX() {
|
||||||
|
@ -144,7 +144,7 @@ public class LightVolume {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void notifyLightUpdate(LightProvider world, LightType type, GridAlignedBB changedVolume) {
|
public void notifyLightUpdate(LightProvider world, LightType type, ReadOnlyBox changedVolume) {
|
||||||
if (removed) return;
|
if (removed) return;
|
||||||
|
|
||||||
if (!changedVolume.intersects(sampleVolume)) return;
|
if (!changedVolume.intersects(sampleVolume)) return;
|
||||||
|
@ -173,9 +173,9 @@ public class LightVolume {
|
||||||
|
|
||||||
BlockPos.Mutable pos = new BlockPos.Mutable();
|
BlockPos.Mutable pos = new BlockPos.Mutable();
|
||||||
|
|
||||||
int shiftX = textureVolume.minX;
|
int shiftX = textureVolume.getMinX();
|
||||||
int shiftY = textureVolume.minY;
|
int shiftY = textureVolume.getMinY();
|
||||||
int shiftZ = textureVolume.minZ;
|
int shiftZ = textureVolume.getMinZ();
|
||||||
|
|
||||||
sampleVolume.forEachContained((x, y, z) -> {
|
sampleVolume.forEachContained((x, y, z) -> {
|
||||||
pos.set(x, y, z);
|
pos.set(x, y, z);
|
||||||
|
@ -194,10 +194,10 @@ public class LightVolume {
|
||||||
*
|
*
|
||||||
* @param worldVolume the region in the world to copy data from.
|
* @param worldVolume the region in the world to copy data from.
|
||||||
*/
|
*/
|
||||||
public void copyBlock(LightProvider world, GridAlignedBB worldVolume) {
|
public void copyBlock(LightProvider world, ReadOnlyBox worldVolume) {
|
||||||
int xShift = textureVolume.minX;
|
int xShift = textureVolume.getMinX();
|
||||||
int yShift = textureVolume.minY;
|
int yShift = textureVolume.getMinY();
|
||||||
int zShift = textureVolume.minZ;
|
int zShift = textureVolume.getMinZ();
|
||||||
|
|
||||||
worldVolume.forEachContained((x, y, z) -> {
|
worldVolume.forEachContained((x, y, z) -> {
|
||||||
int light = world.getLight(LightType.BLOCK, x, y, z);
|
int light = world.getLight(LightType.BLOCK, x, y, z);
|
||||||
|
@ -213,10 +213,10 @@ public class LightVolume {
|
||||||
*
|
*
|
||||||
* @param worldVolume the region in the world to copy data from.
|
* @param worldVolume the region in the world to copy data from.
|
||||||
*/
|
*/
|
||||||
public void copySky(LightProvider world, GridAlignedBB worldVolume) {
|
public void copySky(LightProvider world, ReadOnlyBox worldVolume) {
|
||||||
int xShift = textureVolume.minX;
|
int xShift = textureVolume.getMinX();
|
||||||
int yShift = textureVolume.minY;
|
int yShift = textureVolume.getMinY();
|
||||||
int zShift = textureVolume.minZ;
|
int zShift = textureVolume.getMinZ();
|
||||||
|
|
||||||
worldVolume.forEachContained((x, y, z) -> {
|
worldVolume.forEachContained((x, y, z) -> {
|
||||||
int light = world.getLight(LightType.SKY, x, y, z);
|
int light = world.getLight(LightType.SKY, x, y, z);
|
||||||
|
@ -232,12 +232,12 @@ public class LightVolume {
|
||||||
*
|
*
|
||||||
* @param worldVolume the region in the world to copy data from.
|
* @param worldVolume the region in the world to copy data from.
|
||||||
*/
|
*/
|
||||||
public void copyLight(LightProvider world, GridAlignedBB worldVolume) {
|
public void copyLight(LightProvider world, ReadOnlyBox worldVolume) {
|
||||||
BlockPos.Mutable pos = new BlockPos.Mutable();
|
BlockPos.Mutable pos = new BlockPos.Mutable();
|
||||||
|
|
||||||
int xShift = textureVolume.minX;
|
int xShift = textureVolume.getMinX();
|
||||||
int yShift = textureVolume.minY;
|
int yShift = textureVolume.getMinY();
|
||||||
int zShift = textureVolume.minZ;
|
int zShift = textureVolume.getMinZ();
|
||||||
|
|
||||||
worldVolume.forEachContained((x, y, z) -> {
|
worldVolume.forEachContained((x, y, z) -> {
|
||||||
pos.set(x, y, z);
|
pos.set(x, y, z);
|
||||||
|
|
115
src/main/java/com/jozufozu/flywheel/light/ReadOnlyBox.java
Normal file
115
src/main/java/com/jozufozu/flywheel/light/ReadOnlyBox.java
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
package com.jozufozu.flywheel.light;
|
||||||
|
|
||||||
|
import static com.jozufozu.flywheel.util.RenderUtil.isPowerOf2;
|
||||||
|
|
||||||
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
|
|
||||||
|
public interface ReadOnlyBox {
|
||||||
|
int getMinX();
|
||||||
|
|
||||||
|
int getMinY();
|
||||||
|
|
||||||
|
int getMinZ();
|
||||||
|
|
||||||
|
int getMaxX();
|
||||||
|
|
||||||
|
int getMaxY();
|
||||||
|
|
||||||
|
int getMaxZ();
|
||||||
|
|
||||||
|
default int sizeX() {
|
||||||
|
return getMaxX() - getMinX();
|
||||||
|
}
|
||||||
|
|
||||||
|
default int sizeY() {
|
||||||
|
return getMaxY() - getMinY();
|
||||||
|
}
|
||||||
|
|
||||||
|
default int sizeZ() {
|
||||||
|
return getMaxZ() - getMinZ();
|
||||||
|
}
|
||||||
|
|
||||||
|
default int volume() {
|
||||||
|
return sizeX() * sizeY() * sizeZ();
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean empty() {
|
||||||
|
// if any dimension has side length 0 this box contains no volume
|
||||||
|
return getMinX() == getMaxX() || getMinY() == getMaxY() || getMinZ() == getMaxZ();
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean sameAs(ReadOnlyBox other) {
|
||||||
|
return getMinX() == other.getMinX() && getMinY() == other.getMinY() && getMinZ() == other.getMinZ() && getMaxX() == other.getMaxX() && getMaxY() == other.getMaxY() && getMaxZ() == other.getMaxZ();
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean sameAs(AxisAlignedBB other) {
|
||||||
|
return getMinX() == Math.floor(other.minX)
|
||||||
|
&& getMinY() == Math.floor(other.minY)
|
||||||
|
&& getMinZ() == Math.floor(other.minZ)
|
||||||
|
&& getMaxX() == Math.ceil(other.maxX)
|
||||||
|
&& getMaxY() == Math.ceil(other.maxY)
|
||||||
|
&& getMaxZ() == Math.ceil(other.maxZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean hasPowerOf2Sides() {
|
||||||
|
// this is only true if all individual side lengths are powers of 2
|
||||||
|
return isPowerOf2(volume());
|
||||||
|
}
|
||||||
|
|
||||||
|
default GridAlignedBB intersect(ReadOnlyBox other) {
|
||||||
|
int minX = Math.max(this.getMinX(), other.getMinX());
|
||||||
|
int minY = Math.max(this.getMinY(), other.getMinY());
|
||||||
|
int minZ = Math.max(this.getMinZ(), other.getMinZ());
|
||||||
|
int maxX = Math.min(this.getMaxX(), other.getMaxX());
|
||||||
|
int maxY = Math.min(this.getMaxY(), other.getMaxY());
|
||||||
|
int maxZ = Math.min(this.getMaxZ(), other.getMaxZ());
|
||||||
|
return new GridAlignedBB(minX, minY, minZ, maxX, maxY, maxZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
default ReadOnlyBox union(ReadOnlyBox other) {
|
||||||
|
int minX = Math.min(this.getMinX(), other.getMinX());
|
||||||
|
int minY = Math.min(this.getMinY(), other.getMinY());
|
||||||
|
int minZ = Math.min(this.getMinZ(), other.getMinZ());
|
||||||
|
int maxX = Math.max(this.getMaxX(), other.getMaxX());
|
||||||
|
int maxY = Math.max(this.getMaxY(), other.getMaxY());
|
||||||
|
int maxZ = Math.max(this.getMaxZ(), other.getMaxZ());
|
||||||
|
return new GridAlignedBB(minX, minY, minZ, maxX, maxY, maxZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
default boolean intersects(ReadOnlyBox other) {
|
||||||
|
return this.intersects(other.getMinX(), other.getMinY(), other.getMinZ(), other.getMaxX(), other.getMaxY(), other.getMaxZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean contains(ReadOnlyBox other) {
|
||||||
|
return other.getMinX() >= this.getMinX() && other.getMaxX() <= this.getMaxX() && other.getMinY() >= this.getMinY() && other.getMaxY() <= this.getMaxY() && other.getMinZ() >= this.getMinZ() && other.getMaxZ() <= this.getMaxZ();
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean isContainedBy(GridAlignedBB other) {
|
||||||
|
return other.contains(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean intersects(int minX, int minY, int minZ, int maxX, int maxY, int maxZ) {
|
||||||
|
return this.getMinX() < maxX && this.getMaxX() > minX && this.getMinY() < maxY && this.getMaxY() > minY && this.getMinZ() < maxZ && this.getMaxZ() > minZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
default void forEachContained(ICoordinateConsumer func) {
|
||||||
|
if (empty()) return;
|
||||||
|
|
||||||
|
for (int x = getMinX(); x < getMaxX(); x++) {
|
||||||
|
for (int y = Math.max(getMinY(), 0); y < Math.min(getMaxY(), 255); y++) { // clamp to world height limits
|
||||||
|
for (int z = getMinZ(); z < getMaxZ(); z++) {
|
||||||
|
func.consume(x, y, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
default AxisAlignedBB toAABB() {
|
||||||
|
return new AxisAlignedBB(getMinX(), getMinY(), getMinZ(), getMaxX(), getMaxY(), getMaxZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
default GridAlignedBB copy() {
|
||||||
|
return new GridAlignedBB(getMinX(), getMinY(), getMinZ(), getMaxX(), getMaxY(), getMaxZ());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue