mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-11-14 06:24:12 +01:00
Sunset box
- Unused in flywheel and not a productive utility for others with the new features
This commit is contained in:
parent
0c5995bad8
commit
c4c4d45b0b
@ -1,142 +0,0 @@
|
|||||||
package dev.engine_room.flywheel.lib.box;
|
|
||||||
|
|
||||||
import net.minecraft.util.Mth;
|
|
||||||
import net.minecraft.world.phys.AABB;
|
|
||||||
|
|
||||||
public interface Box {
|
|
||||||
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 isEmpty() {
|
|
||||||
// if any dimension has side length 0 this box contains no volume
|
|
||||||
return getMinX() == getMaxX() || getMinY() == getMaxY() || getMinZ() == getMaxZ();
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean sameAs(Box other) {
|
|
||||||
return getMinX() == other.getMinX() && getMinY() == other.getMinY() && getMinZ() == other.getMinZ() && getMaxX() == other.getMaxX() && getMaxY() == other.getMaxY() && getMaxZ() == other.getMaxZ();
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean sameAs(Box other, int margin) {
|
|
||||||
return getMinX() == other.getMinX() - margin &&
|
|
||||||
getMinY() == other.getMinY() - margin &&
|
|
||||||
getMinZ() == other.getMinZ() - margin &&
|
|
||||||
getMaxX() == other.getMaxX() + margin &&
|
|
||||||
getMaxY() == other.getMaxY() + margin &&
|
|
||||||
getMaxZ() == other.getMaxZ() + margin;
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean sameAs(AABB 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 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 boolean intersects(Box other) {
|
|
||||||
return this.intersects(other.getMinX(), other.getMinY(), other.getMinZ(), other.getMaxX(), other.getMaxY(), other.getMaxZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean contains(int x, int y, int z) {
|
|
||||||
return x >= getMinX()
|
|
||||||
&& x <= getMaxX()
|
|
||||||
&& y >= getMinY()
|
|
||||||
&& y <= getMaxY()
|
|
||||||
&& z >= getMinZ()
|
|
||||||
&& z <= getMaxZ();
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean contains(Box 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 void forEachContained(CoordinateConsumer func) {
|
|
||||||
int minX = getMinX();
|
|
||||||
int minY = getMinY();
|
|
||||||
int minZ = getMinZ();
|
|
||||||
int maxX = getMaxX();
|
|
||||||
int maxY = getMaxY();
|
|
||||||
int maxZ = getMaxZ();
|
|
||||||
|
|
||||||
for (int x = minX; x < maxX; x++) {
|
|
||||||
for (int y = minY; y < maxY; y++) {
|
|
||||||
for (int z = minZ; z < maxZ; z++) {
|
|
||||||
func.accept(x, y, z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean hasPowerOf2Sides() {
|
|
||||||
// this is only true if all individual side lengths are powers of 2
|
|
||||||
return Mth.isPowerOfTwo(volume());
|
|
||||||
}
|
|
||||||
|
|
||||||
default MutableBox union(Box 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 MutableBox(minX, minY, minZ, maxX, maxY, maxZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
default MutableBox intersect(Box 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 MutableBox(minX, minY, minZ, maxX, maxY, maxZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
default AABB toAABB() {
|
|
||||||
return new AABB(getMinX(), getMinY(), getMinZ(), getMaxX(), getMaxY(), getMaxZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
default MutableBox copy() {
|
|
||||||
return new MutableBox(getMinX(), getMinY(), getMinZ(), getMaxX(), getMaxY(), getMaxZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
interface CoordinateConsumer {
|
|
||||||
void accept(int x, int y, int z);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,329 +0,0 @@
|
|||||||
package dev.engine_room.flywheel.lib.box;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.core.Direction;
|
|
||||||
import net.minecraft.core.SectionPos;
|
|
||||||
import net.minecraft.core.Vec3i;
|
|
||||||
import net.minecraft.util.Mth;
|
|
||||||
import net.minecraft.world.phys.AABB;
|
|
||||||
|
|
||||||
public class MutableBox implements Box {
|
|
||||||
protected int minX;
|
|
||||||
protected int minY;
|
|
||||||
protected int minZ;
|
|
||||||
protected int maxX;
|
|
||||||
protected int maxY;
|
|
||||||
protected int maxZ;
|
|
||||||
|
|
||||||
public MutableBox() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public MutableBox(int minX, int minY, int minZ, int maxX, int maxY, int maxZ) {
|
|
||||||
this.minX = minX;
|
|
||||||
this.minY = minY;
|
|
||||||
this.minZ = minZ;
|
|
||||||
this.maxX = maxX;
|
|
||||||
this.maxY = maxY;
|
|
||||||
this.maxZ = maxZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MutableBox from(AABB aabb) {
|
|
||||||
int minX = (int) Math.floor(aabb.minX);
|
|
||||||
int minY = (int) Math.floor(aabb.minY);
|
|
||||||
int minZ = (int) Math.floor(aabb.minZ);
|
|
||||||
int maxX = (int) Math.ceil(aabb.maxX);
|
|
||||||
int maxY = (int) Math.ceil(aabb.maxY);
|
|
||||||
int maxZ = (int) Math.ceil(aabb.maxZ);
|
|
||||||
return new MutableBox(minX, minY, minZ, maxX, maxY, maxZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MutableBox from(Vec3i pos) {
|
|
||||||
return new MutableBox(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MutableBox from(SectionPos pos) {
|
|
||||||
return new MutableBox(pos.minBlockX(), pos.minBlockY(), pos.minBlockZ(), pos.maxBlockX() + 1, pos.maxBlockY() + 1, pos.maxBlockZ() + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MutableBox from(Vec3i start, Vec3i end) {
|
|
||||||
return new MutableBox(start.getX(), start.getY(), start.getZ(), end.getX() + 1, end.getY() + 1, end.getZ() + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MutableBox ofRadius(int radius) {
|
|
||||||
return new MutableBox(-radius, -radius, -radius, radius + 1, radius + 1, radius + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Box containingAll(Collection<BlockPos> positions) {
|
|
||||||
if (positions.isEmpty()) {
|
|
||||||
return new MutableBox();
|
|
||||||
}
|
|
||||||
int minX = Integer.MAX_VALUE;
|
|
||||||
int minY = Integer.MAX_VALUE;
|
|
||||||
int minZ = Integer.MAX_VALUE;
|
|
||||||
int maxX = Integer.MIN_VALUE;
|
|
||||||
int maxY = Integer.MIN_VALUE;
|
|
||||||
int maxZ = Integer.MIN_VALUE;
|
|
||||||
for (BlockPos pos : positions) {
|
|
||||||
minX = Math.min(minX, pos.getX());
|
|
||||||
minY = Math.min(minY, pos.getY());
|
|
||||||
minZ = Math.min(minZ, pos.getZ());
|
|
||||||
maxX = Math.max(maxX, pos.getX());
|
|
||||||
maxY = Math.max(maxY, pos.getY());
|
|
||||||
maxZ = Math.max(maxZ, pos.getZ());
|
|
||||||
}
|
|
||||||
return new MutableBox(minX, minY, minZ, maxX, maxY, maxZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
@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 void setMinX(int minX) {
|
|
||||||
this.minX = minX;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMinY(int minY) {
|
|
||||||
this.minY = minY;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MutableBox setMinZ(int minZ) {
|
|
||||||
this.minZ = minZ;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMaxX(int maxX) {
|
|
||||||
this.maxX = maxX;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMaxY(int maxY) {
|
|
||||||
this.maxY = maxY;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMaxZ(int maxZ) {
|
|
||||||
this.maxZ = maxZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMin(int x, int y, int z) {
|
|
||||||
minX = x;
|
|
||||||
minY = y;
|
|
||||||
minZ = z;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMax(int x, int y, int z) {
|
|
||||||
maxX = x;
|
|
||||||
maxY = y;
|
|
||||||
maxZ = z;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMin(Vec3i v) {
|
|
||||||
setMin(v.getX(), v.getY(), v.getZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMax(Vec3i v) {
|
|
||||||
setMax(v.getX(), v.getY(), v.getZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void assign(Box other) {
|
|
||||||
minX = other.getMinX();
|
|
||||||
minY = other.getMinY();
|
|
||||||
minZ = other.getMinZ();
|
|
||||||
maxX = other.getMaxX();
|
|
||||||
maxY = other.getMaxY();
|
|
||||||
maxZ = other.getMaxZ();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void assign(AABB other) {
|
|
||||||
minX = (int) Math.floor(other.minX);
|
|
||||||
minY = (int) Math.floor(other.minY);
|
|
||||||
minZ = (int) Math.floor(other.minZ);
|
|
||||||
maxX = (int) Math.ceil(other.maxX);
|
|
||||||
maxY = (int) Math.ceil(other.maxY);
|
|
||||||
maxZ = (int) Math.ceil(other.maxZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void assign(Vec3i start, Vec3i end) {
|
|
||||||
minX = start.getX();
|
|
||||||
minY = start.getY();
|
|
||||||
minZ = start.getZ();
|
|
||||||
maxX = end.getX() + 1;
|
|
||||||
maxY = end.getY() + 1;
|
|
||||||
maxZ = end.getZ() + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void unionAssign(Box other) {
|
|
||||||
minX = Math.min(this.minX, other.getMinX());
|
|
||||||
minY = Math.min(this.minY, other.getMinY());
|
|
||||||
minZ = Math.min(this.minZ, other.getMinZ());
|
|
||||||
maxX = Math.max(this.maxX, other.getMaxX());
|
|
||||||
maxY = Math.max(this.maxY, other.getMaxY());
|
|
||||||
maxZ = Math.max(this.maxZ, other.getMaxZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void unionAssign(AABB other) {
|
|
||||||
minX = Math.min(this.minX, (int) Math.floor(other.minX));
|
|
||||||
minY = Math.min(this.minY, (int) Math.floor(other.minY));
|
|
||||||
minZ = Math.min(this.minZ, (int) Math.floor(other.minZ));
|
|
||||||
maxX = Math.max(this.maxX, (int) Math.ceil(other.maxX));
|
|
||||||
maxY = Math.max(this.maxY, (int) Math.ceil(other.maxY));
|
|
||||||
maxZ = Math.max(this.maxZ, (int) Math.ceil(other.maxZ));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void intersectAssign(Box other) {
|
|
||||||
minX = Math.max(this.minX, other.getMinX());
|
|
||||||
minY = Math.max(this.minY, other.getMinY());
|
|
||||||
minZ = Math.max(this.minZ, other.getMinZ());
|
|
||||||
maxX = Math.min(this.maxX, other.getMaxX());
|
|
||||||
maxY = Math.min(this.maxY, other.getMaxY());
|
|
||||||
maxZ = Math.min(this.maxZ, other.getMaxZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fixMinMax() {
|
|
||||||
int minX = Math.min(this.minX, this.maxX);
|
|
||||||
int minY = Math.min(this.minY, this.maxY);
|
|
||||||
int minZ = Math.min(this.minZ, this.maxZ);
|
|
||||||
int maxX = Math.max(this.minX, this.maxX);
|
|
||||||
int maxY = Math.max(this.minY, this.maxY);
|
|
||||||
int maxZ = Math.max(this.minZ, this.maxZ);
|
|
||||||
|
|
||||||
this.minX = minX;
|
|
||||||
this.minY = minY;
|
|
||||||
this.minZ = minZ;
|
|
||||||
this.maxX = maxX;
|
|
||||||
this.maxY = maxY;
|
|
||||||
this.maxZ = maxZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void translate(int x, int y, int z) {
|
|
||||||
minX = minX + x;
|
|
||||||
maxX = maxX + x;
|
|
||||||
minY = minY + y;
|
|
||||||
maxY = maxY + y;
|
|
||||||
minZ = minZ + z;
|
|
||||||
maxZ = maxZ + z;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void translate(Vec3i by) {
|
|
||||||
translate(by.getX(), by.getY(), by.getZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void grow(int x, int y, int z) {
|
|
||||||
minX = minX - x;
|
|
||||||
minY = minY - y;
|
|
||||||
minZ = minZ - z;
|
|
||||||
maxX = maxX + x;
|
|
||||||
maxY = maxY + y;
|
|
||||||
maxZ = maxZ + z;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void grow(int s) {
|
|
||||||
this.grow(s, s, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Grow this box to have power of 2 side lengths, scaling from the minimum coords.
|
|
||||||
*/
|
|
||||||
public void nextPowerOf2() {
|
|
||||||
int sizeX = Mth.smallestEncompassingPowerOfTwo(sizeX());
|
|
||||||
int sizeY = Mth.smallestEncompassingPowerOfTwo(sizeY());
|
|
||||||
int sizeZ = Mth.smallestEncompassingPowerOfTwo(sizeZ());
|
|
||||||
|
|
||||||
maxX = minX + sizeX;
|
|
||||||
maxY = minY + sizeY;
|
|
||||||
maxZ = minZ + sizeZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Grow this box to have power of 2 side length, scaling from the center.
|
|
||||||
*/
|
|
||||||
public void nextPowerOf2Centered() {
|
|
||||||
int sizeX = sizeX();
|
|
||||||
int sizeY = sizeY();
|
|
||||||
int sizeZ = sizeZ();
|
|
||||||
|
|
||||||
int newSizeX = Mth.smallestEncompassingPowerOfTwo(sizeX);
|
|
||||||
int newSizeY = Mth.smallestEncompassingPowerOfTwo(sizeY);
|
|
||||||
int newSizeZ = Mth.smallestEncompassingPowerOfTwo(sizeZ);
|
|
||||||
|
|
||||||
int diffX = newSizeX - sizeX;
|
|
||||||
int diffY = newSizeY - sizeY;
|
|
||||||
int diffZ = newSizeZ - sizeZ;
|
|
||||||
|
|
||||||
minX = minX - diffX / 2; // floor division for the minimums
|
|
||||||
minY = minY - diffY / 2;
|
|
||||||
minZ = minZ - diffZ / 2;
|
|
||||||
maxX = maxX + (diffX + 1) / 2; // ceiling divison for the maximums
|
|
||||||
maxY = maxY + (diffY + 1) / 2;
|
|
||||||
maxZ = maxZ + (diffZ + 1) / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void mirrorAbout(Direction.Axis axis) {
|
|
||||||
Vec3i axisVec = Direction.get(Direction.AxisDirection.POSITIVE, axis)
|
|
||||||
.getNormal();
|
|
||||||
int flipX = axisVec.getX() - 1;
|
|
||||||
int flipY = axisVec.getY() - 1;
|
|
||||||
int flipZ = axisVec.getZ() - 1;
|
|
||||||
|
|
||||||
int maxX = this.maxX * flipX;
|
|
||||||
int maxY = this.maxY * flipY;
|
|
||||||
int maxZ = this.maxZ * flipZ;
|
|
||||||
this.maxX = this.minX * flipX;
|
|
||||||
this.maxY = this.minY * flipY;
|
|
||||||
this.maxZ = this.minZ * flipZ;
|
|
||||||
this.minX = maxX;
|
|
||||||
this.minY = maxY;
|
|
||||||
this.minZ = maxZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null) return false;
|
|
||||||
if (!(o instanceof Box that)) return false;
|
|
||||||
|
|
||||||
return this.sameAs(that);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
int result = minX;
|
|
||||||
result = 31 * result + minY;
|
|
||||||
result = 31 * result + minZ;
|
|
||||||
result = 31 * result + maxX;
|
|
||||||
result = 31 * result + maxY;
|
|
||||||
result = 31 * result + maxZ;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "(" + minX + ", " + minY + ", " + minZ + ")->(" + maxX + ", " + maxY + ", " + maxZ + ')';
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
package dev.engine_room.flywheel.lib.light;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility class for bit-twiddling light.
|
|
||||||
*/
|
|
||||||
public class LightPacking {
|
|
||||||
public static int getBlock(short packed) {
|
|
||||||
return (packed >> 4) & 0xF;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getSky(short packed) {
|
|
||||||
return (packed >> 12) & 0xF;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte packLightNibbles(byte block, byte sky) {
|
|
||||||
return (byte) (block | (sky << 4));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getBlock(byte packed) {
|
|
||||||
return packed & 0xF;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getSky(byte packed) {
|
|
||||||
return (packed >> 4) & 0xF;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,217 +0,0 @@
|
|||||||
package dev.engine_room.flywheel.lib.light;
|
|
||||||
|
|
||||||
import org.lwjgl.system.MemoryUtil;
|
|
||||||
|
|
||||||
import dev.engine_room.flywheel.lib.box.Box;
|
|
||||||
import dev.engine_room.flywheel.lib.box.MutableBox;
|
|
||||||
import dev.engine_room.flywheel.lib.memory.MemoryBlock;
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.core.SectionPos;
|
|
||||||
import net.minecraft.world.level.BlockAndTintGetter;
|
|
||||||
import net.minecraft.world.level.LightLayer;
|
|
||||||
|
|
||||||
public class LightVolume implements Box {
|
|
||||||
protected final BlockAndTintGetter level;
|
|
||||||
protected final MutableBox box = new MutableBox();
|
|
||||||
protected MemoryBlock lightData;
|
|
||||||
|
|
||||||
public LightVolume(BlockAndTintGetter level, Box sampleVolume) {
|
|
||||||
this.level = level;
|
|
||||||
this.setBox(sampleVolume);
|
|
||||||
|
|
||||||
this.lightData = MemoryBlock.malloc(this.box.volume() * 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Box getVolume() {
|
|
||||||
return box;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMinX() {
|
|
||||||
return box.getMinX();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMinY() {
|
|
||||||
return box.getMinY();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMinZ() {
|
|
||||||
return box.getMinZ();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMaxX() {
|
|
||||||
return box.getMaxX();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMaxY() {
|
|
||||||
return box.getMaxY();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMaxZ() {
|
|
||||||
return box.getMaxZ();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isInvalid() {
|
|
||||||
return lightData == null;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setBox(Box box) {
|
|
||||||
this.box.assign(box);
|
|
||||||
}
|
|
||||||
|
|
||||||
public short getPackedLight(int x, int y, int z) {
|
|
||||||
if (box.contains(x, y, z)) {
|
|
||||||
return MemoryUtil.memGetShort(levelPosToPtr(x, y, z));
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void move(Box newSampleVolume) {
|
|
||||||
if (lightData == null) return;
|
|
||||||
|
|
||||||
setBox(newSampleVolume);
|
|
||||||
int neededCapacity = box.volume() * 2;
|
|
||||||
if (neededCapacity > lightData.size()) {
|
|
||||||
lightData = lightData.realloc(neededCapacity);
|
|
||||||
}
|
|
||||||
initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Completely (re)populate this volume with block and sky lighting data.
|
|
||||||
* This is expensive and should be avoided.
|
|
||||||
*/
|
|
||||||
public void initialize() {
|
|
||||||
if (lightData == null) return;
|
|
||||||
|
|
||||||
copyLight(getVolume());
|
|
||||||
markDirty();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void markDirty() {
|
|
||||||
// noop
|
|
||||||
}
|
|
||||||
|
|
||||||
public void delete() {
|
|
||||||
lightData.free();
|
|
||||||
lightData = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy all light from the level into this volume.
|
|
||||||
*
|
|
||||||
* @param levelVolume the region in the level to copy data from.
|
|
||||||
*/
|
|
||||||
public void copyLight(Box levelVolume) {
|
|
||||||
BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos();
|
|
||||||
|
|
||||||
int xShift = box.getMinX();
|
|
||||||
int yShift = box.getMinY();
|
|
||||||
int zShift = box.getMinZ();
|
|
||||||
|
|
||||||
levelVolume.forEachContained((x, y, z) -> {
|
|
||||||
pos.set(x, y, z);
|
|
||||||
|
|
||||||
int block = this.level.getBrightness(LightLayer.BLOCK, pos);
|
|
||||||
int sky = this.level.getBrightness(LightLayer.SKY, pos);
|
|
||||||
|
|
||||||
writeLight(x - xShift, y - yShift, z - zShift, block, sky);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void writeLight(int x, int y, int z, int block, int sky) {
|
|
||||||
byte b = (byte) ((block & 0xF) << 4);
|
|
||||||
byte s = (byte) ((sky & 0xF) << 4);
|
|
||||||
|
|
||||||
long ptr = boxPosToPtr(x, y, z);
|
|
||||||
MemoryUtil.memPutByte(ptr, b);
|
|
||||||
MemoryUtil.memPutByte(ptr + 1, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy block light from the level into this volume.
|
|
||||||
*
|
|
||||||
* @param levelVolume the region in the level to copy data from.
|
|
||||||
*/
|
|
||||||
public void copyBlock(Box levelVolume) {
|
|
||||||
var pos = new BlockPos.MutableBlockPos();
|
|
||||||
|
|
||||||
int xShift = box.getMinX();
|
|
||||||
int yShift = box.getMinY();
|
|
||||||
int zShift = box.getMinZ();
|
|
||||||
|
|
||||||
levelVolume.forEachContained((x, y, z) -> {
|
|
||||||
int light = this.level.getBrightness(LightLayer.BLOCK, pos.set(x, y, z));
|
|
||||||
|
|
||||||
writeBlock(x - xShift, y - yShift, z - zShift, light);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void writeBlock(int x, int y, int z, int block) {
|
|
||||||
byte b = (byte) ((block & 0xF) << 4);
|
|
||||||
|
|
||||||
MemoryUtil.memPutByte(boxPosToPtr(x, y, z), b);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy sky light from the level into this volume.
|
|
||||||
*
|
|
||||||
* @param levelVolume the region in the level to copy data from.
|
|
||||||
*/
|
|
||||||
public void copySky(Box levelVolume) {
|
|
||||||
var pos = new BlockPos.MutableBlockPos();
|
|
||||||
|
|
||||||
int xShift = box.getMinX();
|
|
||||||
int yShift = box.getMinY();
|
|
||||||
int zShift = box.getMinZ();
|
|
||||||
|
|
||||||
levelVolume.forEachContained((x, y, z) -> {
|
|
||||||
int light = this.level.getBrightness(LightLayer.SKY, pos.set(x, y, z));
|
|
||||||
|
|
||||||
writeSky(x - xShift, y - yShift, z - zShift, light);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void writeSky(int x, int y, int z, int sky) {
|
|
||||||
byte s = (byte) ((sky & 0xF) << 4);
|
|
||||||
|
|
||||||
MemoryUtil.memPutByte(boxPosToPtr(x, y, z) + 1, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected long levelPosToPtr(int x, int y, int z) {
|
|
||||||
return lightData.ptr() + levelPosToPtrOffset(x, y, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected long boxPosToPtr(int x, int y, int z) {
|
|
||||||
return lightData.ptr() + boxPosToPtrOffset(x, y, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected int levelPosToPtrOffset(int x, int y, int z) {
|
|
||||||
x -= box.getMinX();
|
|
||||||
y -= box.getMinY();
|
|
||||||
z -= box.getMinZ();
|
|
||||||
return boxPosToPtrOffset(x, y, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected int boxPosToPtrOffset(int x, int y, int z) {
|
|
||||||
return (x + box.sizeX() * (y + z * box.sizeY())) * 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onLightUpdate(LightLayer type, SectionPos pos) {
|
|
||||||
if (lightData == null) return;
|
|
||||||
|
|
||||||
MutableBox vol = MutableBox.from(pos);
|
|
||||||
if (!vol.intersects(getVolume())) return;
|
|
||||||
vol.intersectAssign(getVolume()); // compute the region contained by us that has dirty lighting data.
|
|
||||||
|
|
||||||
if (type == LightLayer.BLOCK) copyBlock(vol);
|
|
||||||
else if (type == LightLayer.SKY) copySky(vol);
|
|
||||||
markDirty();
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user