Skip to content

Commit 973ff9e

Browse files
committed
WIP checkin - new requirements system?
1 parent f8145d7 commit 973ff9e

31 files changed

Lines changed: 1229 additions & 55 deletions

spatial/src/main/java/dev/compactmods/spatial/aabb/AABBAligner.java

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@ public abstract class AABBAligner {
1717
/**
1818
* How large the AABB instance to be aligned is.
1919
*/
20-
protected final Vector3d size;
20+
protected final Vector3dc size;
2121

2222
/**
2323
* Where the center of the AABB instance will be after alignment.
2424
*/
2525
protected Vector3d center;
2626

27-
private AABBAligner(Vector3d center, Vector3d size) {
27+
private AABBAligner(Vector3d center, Vector3dc size) {
2828
this.size = size;
2929
this.center = center;
3030
}
@@ -38,17 +38,17 @@ public static AABBAligner.Unbounded create(AABB original) {
3838
}
3939

4040
public AABB align() {
41-
return AABB.ofSize(VectorUtils.convert3d(center), size.x, size.y, size.z);
41+
return AABB.ofSize(VectorUtils.convert3d(center), size.x(), size.y(), size.z());
4242
}
4343

4444
public static AABB center(AABB source, Vec3 center) {
4545
final var size = AABBHelper.sizeOf(source);
46-
return AABB.ofSize(center, size.x, size.y, size.z);
46+
return AABB.ofSize(center, size.x(), size.y(), size.z());
4747
}
4848

4949
public static AABB center(AABB source, Vector3dc center) {
5050
final var size = AABBHelper.sizeOf(source);
51-
return AABB.ofSize(VectorUtils.convert3d(center), size.x, size.y, size.z);
51+
return AABB.ofSize(VectorUtils.convert3d(center), size.x(), size.y(), size.z());
5252
}
5353

5454
public static AABB floor(AABB source, AABB within) {
@@ -79,13 +79,13 @@ public static class Bounded extends AABBAligner {
7979
*/
8080
private final AABB targetBoundaries;
8181

82-
private Bounded(AABB outerBounds, Vector3d center, Vector3d size) {
82+
private Bounded(AABB outerBounds, Vector3d center, Vector3dc size) {
8383
super(center, size);
8484
this.targetBoundaries = outerBounds;
8585
}
8686

8787
/**
88-
* Changes the center point of the AABB to the centerpoint of the boundaries.
88+
* Changes the center vector3d of the AABB to the centerpoint of the boundaries.
8989
*
9090
* @return Aligner instance, for chaining
9191
*/
@@ -95,7 +95,7 @@ public AABBAligner.Bounded center() {
9595
}
9696

9797
/**
98-
* Changes the center point of the AABB to an exact location.
98+
* Changes the center vector3d of the AABB to an exact location.
9999
* Must be within the outer boundaries.
100100
*
101101
* @param center The position to align on.
@@ -107,7 +107,7 @@ public AABBAligner.Bounded center(Vector3dc center) {
107107
}
108108

109109
/**
110-
* Changes the center point of the AABB to an exact location.
110+
* Changes the center vector3d of the AABB to an exact location.
111111
* Must be within the outer boundaries.
112112
*
113113
* @param center The position to align on.
@@ -121,9 +121,10 @@ public AABBAligner.Bounded center(Vec3 center) {
121121

122122
public AABBAligner.Bounded normalize() {
123123
final var corner = new Vector3d();
124+
final var offset = new Vector3d(size).mul(0.5d);
124125
corner.sub(AABBHelper.minCorner(targetBoundaries))
125126
.negate()
126-
.add(new Vector3d(size.x / 2, size.y / 2, size.z / 2));
127+
.add(offset);
127128

128129
return this.center(corner);
129130
}
@@ -139,7 +140,7 @@ public AABBAligner.Bounded boundedDirection(Direction direction) {
139140
var outerEdge = DirectionalMath.directionalEdge(direction, targetBoundaries);
140141
var targetPoint = DirectionalMath.directionalEdge(direction, center, size);
141142

142-
var offset = outerEdge.sub(targetPoint);
143+
var offset = new Vector3d(outerEdge).sub(targetPoint);
143144
center.add(offset);
144145

145146
return this;
@@ -162,7 +163,7 @@ public AABBAligner.Unbounded center(Vec3 center) {
162163
}
163164

164165
/**
165-
* Sets the center point to the center of a given block position.
166+
* Sets the center vector3d to the center of a given block position.
166167
*
167168
* @param center The block position to center on.
168169
* @return The aligner, for chaining.

spatial/src/main/java/dev/compactmods/spatial/aabb/AABBHelper.java

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,20 @@
22

33
import dev.compactmods.spatial.vector.VectorUtils;
44
import net.minecraft.core.BlockPos;
5+
import net.minecraft.core.Direction;
56
import net.minecraft.world.level.ChunkPos;
67
import net.minecraft.world.phys.AABB;
78
import net.minecraft.world.phys.Vec3;
9+
import org.joml.Vector2d;
10+
import org.joml.Vector2dc;
811
import org.joml.Vector3d;
912
import org.joml.Vector3dc;
1013

1114
import java.util.stream.Stream;
1215

1316
public abstract class AABBHelper {
1417

15-
public static Vector3d sizeOf(AABB aabb) {
18+
public static Vector3dc sizeOf(AABB aabb) {
1619
return new Vector3d(aabb.getXsize(), aabb.getYsize(), aabb.getZsize());
1720
}
1821

@@ -24,6 +27,11 @@ public static AABB zeroOriginSized(Vector3dc size) {
2427
return AABB.ofSize(Vec3.ZERO, size.x(), size.y(), size.z());
2528
}
2629

30+
public static AABB fullWidthSlice(AABB original, int yStart, int height) {
31+
final var size = sizeOf(original);
32+
return AABB.ofSize(Vec3.ZERO.add(0, yStart, 0), size.x(), height, size.z());
33+
}
34+
2735
public static boolean fitsInside(AABB aabb, Vec3 dimensions) {
2836
return fitsInside(aabb, VectorUtils.convert3d(dimensions));
2937
}
@@ -35,30 +43,17 @@ public static boolean fitsInside(AABB aabb, Vector3dc dimensions) {
3543
}
3644

3745
public static boolean fitsInside(AABB outer, AABB inner) {
38-
if(!fitsInside(inner, sizeOf(outer))) return false;
39-
return outer.contains(VectorUtils.convert3d(minCorner(inner))) &&
40-
outer.contains(VectorUtils.convert3d(maxCorner(outer)));
46+
if (!fitsInside(inner, sizeOf(outer))) return false;
47+
return outer.contains(inner.getMinPosition()) &&
48+
outer.contains(inner.getMaxPosition());
4149
}
4250

4351
public static Stream<BlockPos> blocksInside(AABB bounds) {
4452
return BlockPos.betweenClosedStream(bounds.contract(1, 1, 1));
4553
}
4654

47-
public static Stream<BlockPos> allCorners(AABB bounds) {
48-
Stream.Builder<BlockPos> stream = Stream.builder();
49-
stream.add(BlockPos.containing(bounds.maxX - 1, bounds.maxY - 1, bounds.maxZ - 1));
50-
stream.add(BlockPos.containing(bounds.minX, bounds.maxY - 1, bounds.maxZ - 1));
51-
stream.add(BlockPos.containing(bounds.maxX - 1, bounds.minY, bounds.maxZ - 1));
52-
stream.add(BlockPos.containing(bounds.minX, bounds.minY, bounds.maxZ - 1));
53-
stream.add(BlockPos.containing(bounds.maxX - 1, bounds.maxY - 1, bounds.minZ));
54-
stream.add(BlockPos.containing(bounds.minX, bounds.maxY - 1, bounds.minZ));
55-
stream.add(BlockPos.containing(bounds.maxX - 1, bounds.minY, bounds.minZ));
56-
stream.add(BlockPos.containing(bounds.minX, bounds.minY, bounds.minZ));
57-
return stream.build();
58-
}
59-
6055
public static Vector3dc minCorner(AABB aabb) {
61-
return new Vector3d(aabb.minX, aabb.minY, aabb.minZ);
56+
return VectorUtils.convert3d(aabb.getMinPosition());
6257
}
6358

6459
public static ChunkPos minCornerChunk(AABB aabb) {
@@ -67,7 +62,7 @@ public static ChunkPos minCornerChunk(AABB aabb) {
6762
}
6863

6964
public static Vector3dc maxCorner(AABB aabb) {
70-
return new Vector3d(aabb.maxX, aabb.maxY, aabb.maxZ);
65+
return VectorUtils.convert3d(aabb.getMaxPosition());
7166
}
7267

7368
public static ChunkPos maxCornerChunk(AABB aabb) {
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package dev.compactmods.spatial.aabb;
2+
3+
import net.minecraft.core.BlockPos;
4+
import net.minecraft.core.Direction;
5+
import net.minecraft.core.Direction8;
6+
import net.minecraft.world.phys.AABB;
7+
import org.jetbrains.annotations.NotNull;
8+
import org.joml.Vector3d;
9+
import org.joml.Vector3dc;
10+
11+
import java.util.stream.Stream;
12+
13+
public record AABBPositionHelper(AABB boundaries) {
14+
15+
@NotNull
16+
public Stream<BlockPos> blocks() {
17+
return BlockPos.betweenClosedStream(boundaries.contract(1, 1, 1));
18+
}
19+
20+
public Vector3dc center() {
21+
return new Vector3d(boundaries.getCenter().toVector3f());
22+
}
23+
24+
public Vector3dc planarLocation(Direction8 direction, double y) {
25+
final var center = boundaries.getCenter();
26+
Vector3d point = new Vector3d(0, y, 0);
27+
int stepX = direction.getStepX();
28+
int stepZ = direction.getStepZ();
29+
30+
switch (stepX) {
31+
case -1 -> point.x = boundaries.minX;
32+
case 0 -> point.x = center.x;
33+
case 1 -> point.x = boundaries.maxX;
34+
}
35+
36+
switch (stepZ) {
37+
case -1 -> point.z = boundaries.minZ;
38+
case 0 -> point.z = center.z;
39+
case 1 -> point.z = boundaries.maxZ;
40+
}
41+
42+
return point;
43+
}
44+
45+
public double axisLength(Direction.Axis axis) {
46+
// pick X Y or Z size from directional AXIS
47+
// offset = AXIS --> BOUNDARY SIZE
48+
return axis.choose(boundaries.getXsize(), boundaries.getYsize(), boundaries.getZsize());
49+
}
50+
51+
public double centerToEdgeLength(Direction direction) {
52+
var axisSize = axisLength(direction.getAxis());
53+
54+
// Half the axis size so we measure center to edge
55+
return axisSize / 2d;
56+
}
57+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package dev.compactmods.spatial.aabb;
2+
3+
import net.minecraft.core.Direction;
4+
import net.minecraft.core.Vec3i;
5+
import net.minecraft.world.phys.AABB;
6+
import net.minecraft.world.phys.Vec3;
7+
8+
public class BlockSpaceUtil {
9+
10+
public static AABB getPlanarNormal(Direction direction) {
11+
if (direction.getAxis().isHorizontal())
12+
return getPlanarNormal(Direction.UP, direction.getCounterClockWise());
13+
else
14+
return getPlanarNormal(direction == Direction.UP ? Direction.SOUTH : Direction.NORTH,
15+
direction.getClockWise(Direction.Axis.Z));
16+
}
17+
18+
public static AABB getPlanarNormal(Direction up, Direction right) {
19+
Vec3i rightNorm = right.getNormal();
20+
Vec3i upNorm = up.getNormal();
21+
22+
return AABB.ofSize(Vec3.ZERO, rightNorm.getX() + upNorm.getX(),
23+
rightNorm.getY() + upNorm.getY(),
24+
rightNorm.getZ() + upNorm.getZ());
25+
}
26+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package dev.compactmods.spatial.blocks;
2+
3+
import net.minecraft.core.BlockPos;
4+
import net.minecraft.world.level.block.state.BlockState;
5+
6+
import java.util.function.Predicate;
7+
import java.util.stream.Stream;
8+
9+
public interface FilterableBlockContext {
10+
Stream<BlockPos> matchingState(Predicate<BlockState> filter);
11+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package dev.compactmods.spatial.blocks;
2+
3+
import net.minecraft.core.HolderLookup;
4+
import net.minecraft.world.level.block.Block;
5+
import net.minecraft.world.level.block.state.BlockState;
6+
7+
import java.util.Set;
8+
import java.util.function.Predicate;
9+
10+
public interface ResolvableBlockPalette extends Predicate<BlockState> {
11+
Set<BlockState> resolve(HolderLookup.RegistryLookup<Block> blockRegistry);
12+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package dev.compactmods.spatial.blocks.context;
2+
3+
import net.minecraft.core.BlockPos;
4+
import net.minecraft.world.level.block.entity.BlockEntity;
5+
import net.minecraft.world.level.block.state.BlockState;
6+
7+
import java.util.Optional;
8+
import java.util.stream.Stream;
9+
10+
public interface BlockContext {
11+
boolean isEmpty();
12+
13+
Stream<BlockPos> blockPositions();
14+
15+
BlockState getBlockState(BlockPos pos);
16+
17+
Optional<BlockEntity> getBlockEntity(BlockPos pos);
18+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package dev.compactmods.spatial.blocks.context;
2+
3+
import net.minecraft.core.BlockPos;
4+
import net.minecraft.world.level.levelgen.structure.BoundingBox;
5+
6+
import java.util.stream.Stream;
7+
8+
public interface BoundedBlockContext extends BlockContext {
9+
10+
BoundingBox bounds();
11+
12+
@Override
13+
default Stream<BlockPos> blockPositions() {
14+
return BlockPos.betweenClosedStream(bounds());
15+
}
16+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package dev.compactmods.spatial.blocks.context;
2+
3+
import dev.compactmods.spatial.blocks.FilterableBlockContext;
4+
import dev.compactmods.spatial.blocks.filters.EmptyBlockFilter;
5+
import dev.compactmods.spatial.blocks.snapshot.LevelBlockSnapshot;
6+
import net.minecraft.core.BlockPos;
7+
import net.minecraft.world.level.LevelReader;
8+
import net.minecraft.world.level.block.entity.BlockEntity;
9+
import net.minecraft.world.level.block.state.BlockState;
10+
import net.minecraft.world.level.levelgen.structure.BoundingBox;
11+
import org.jetbrains.annotations.NotNull;
12+
13+
import java.lang.ref.WeakReference;
14+
import java.util.Optional;
15+
import java.util.function.Predicate;
16+
import java.util.stream.Stream;
17+
18+
public record FixedBoxBoundariesBlockContext(
19+
WeakReference<LevelReader> levelReader,
20+
LevelBlockSnapshot snapshot
21+
) implements BlockContext, FilterableBlockContext, AutoCloseable {
22+
23+
@NotNull
24+
public static FixedBoxBoundariesBlockContext create(LevelReader levelReader, BoundingBox bounds) {
25+
final var ref = new WeakReference<>(levelReader);
26+
final var snapshot = LevelBlockSnapshot.from(levelReader, bounds);
27+
return new FixedBoxBoundariesBlockContext(ref, snapshot);
28+
}
29+
30+
@Override
31+
public boolean isEmpty() {
32+
final var filter = EmptyBlockFilter.INSTANCE.negate();
33+
return snapshot.matchingState(filter)
34+
.findAny()
35+
.isPresent();
36+
}
37+
38+
@Override
39+
public Stream<BlockPos> blockPositions() {
40+
return snapshot.positions();
41+
}
42+
43+
@Override
44+
public BlockState getBlockState(BlockPos pos) {
45+
return snapshot.getBlockState(pos);
46+
}
47+
48+
@Override
49+
public Optional<BlockEntity> getBlockEntity(BlockPos pos) {
50+
return snapshot.getBlockEntityData(pos).map(data -> {
51+
final var state = getBlockState(pos);
52+
if(levelReader.get() instanceof LevelReader reader) {
53+
final var provider = reader.registryAccess();
54+
return BlockEntity.loadStatic(pos, state, data, provider);
55+
} else {
56+
return null;
57+
}
58+
});
59+
}
60+
61+
@Override
62+
public Stream<BlockPos> matchingState(Predicate<BlockState> filter) {
63+
return snapshot.matchingState(filter);
64+
}
65+
66+
@Override
67+
public void close() {
68+
levelReader.clear();
69+
}
70+
}

0 commit comments

Comments
 (0)