Skip to content

Commit

Permalink
feat: adapt new accurate collision shape data
Browse files Browse the repository at this point in the history
  • Loading branch information
smartcmd committed Feb 9, 2025
1 parent aa8a6a4 commit 5eddd77
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 67 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ Unless otherwise specified, any version comparison below is the comparison of se
- (API) Removed `PlayerStorage#tick` and `PlayerStorage#shutdown` methods, these methods shouldn't be in api module.
- (API) Removed `Registries#BLOCK_STATE_DATA`. This registry is moved to `InternalRegistries`.
- (API) Removed `Registries#ITEM_DATA`. This registry is moved to `InternalRegistries`.
- (API) Removed `VoxelShapes#buildStairShape` method, we now have accurate collision shape data dumped from BDS.
- Removed `Extension#afterServerStarted` method.
- Removed `org.allaymc.server.datastruct.collections.nb.*`, we now use the implementations provided by JCTools. Consider using `NonBlockingHashMap`
and `NonBlockingHashMapLong` if your plugins use these classes.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,35 @@ public class BlockStateData {
protected static Gson SERIALIZER = new GsonBuilder()
.registerTypeAdapter(VoxelShape.class, (JsonDeserializer<Object>) (json, typeOfT, context) -> {
var array = json.getAsJsonArray();
var minX = array.get(0).getAsDouble();
var minY = array.get(1).getAsDouble();
var minZ = array.get(2).getAsDouble();
var maxX = array.get(3).getAsDouble();
var maxY = array.get(4).getAsDouble();
var maxZ = array.get(5).getAsDouble();
if (minX == 0 && minY == 0 && minZ == 0 && maxX == 0 && maxY == 0 && maxZ == 0) {
return VoxelShape.EMPTY;
if (array.isEmpty() || array.get(0).isJsonArray()) {
// collisionShape field is a list of AABBs, and can be an empty array
var builder = VoxelShape.builder();
array.forEach(e -> {
var a = e.getAsJsonArray();
var minX = a.get(0).getAsDouble();
var minY = a.get(1).getAsDouble();
var minZ = a.get(2).getAsDouble();
var maxX = a.get(3).getAsDouble();
var maxY = a.get(4).getAsDouble();
var maxZ = a.get(5).getAsDouble();

builder.solid(minX, minY, minZ, maxX, maxY, maxZ);
});
return builder.build();
} else {
var minX = array.get(0).getAsDouble();
var minY = array.get(1).getAsDouble();
var minZ = array.get(2).getAsDouble();
var maxX = array.get(3).getAsDouble();
var maxY = array.get(4).getAsDouble();
var maxZ = array.get(5).getAsDouble();

if (minX == 0 && minY == 0 && minZ == 0 && maxX == 0 && maxY == 0 && maxZ == 0) {
return VoxelShape.EMPTY;
}

return VoxelShape.builder().solid(new AABBd(minX, minY, minZ, maxX, maxY, maxZ)).build();
}
return VoxelShape.builder().solid(new AABBd(minX, minY, minZ, maxX, maxY, maxZ)).build();
})
.registerTypeAdapter(Color.class, (JsonDeserializer<Object>) (json, typeOfT, context) -> {
// Example: #4c4c4cff
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,50 +2,17 @@

import lombok.experimental.UtilityClass;
import org.allaymc.api.block.component.BlockLiquidBaseComponent;
import org.allaymc.api.block.data.BlockFace;
import org.allaymc.api.block.property.type.BlockPropertyTypes;
import org.allaymc.api.block.type.BlockState;

import java.util.EnumMap;
import java.util.Map;

/**
* VoxelShapes contains some useful voxel shapes.
*
* @author daoge_cmd
*/
@UtilityClass
public final class VoxelShapes {

// Stairs
private static final BlockFace[] STAIR_DIRECTION_VALUE_TO_BLOCK_FACE = {BlockFace.EAST, BlockFace.WEST, BlockFace.SOUTH, BlockFace.NORTH};
private static final Map<BlockFace, VoxelShape> UPWARDS_STAIR_SHAPES = new EnumMap<>(BlockFace.class);
private static final Map<BlockFace, VoxelShape> DOWNWARDS_STAIR_SHAPES = new EnumMap<>(BlockFace.class);

private static final VoxelShape UPWARDS_STAIR_SHAPE = VoxelShape.builder()
.solid(0, 0, 0, 1, 0.5f, 1)
.solid(0.5f, 0.5f, 0, 1, 1, 1)
.build();
private static final VoxelShape DOWNWARDS_STAIR_SHAPE = VoxelShape.builder()
.solid(0, 0.5f, 0, 1, 1, 1)
.solid(0.5f, 0, 0, 1, 0.5f, 1)
.build();

static {
for (var face : BlockFace.getHorizontalBlockFaces()) {
UPWARDS_STAIR_SHAPES.put(face, UPWARDS_STAIR_SHAPE.rotate(face));
DOWNWARDS_STAIR_SHAPES.put(face, DOWNWARDS_STAIR_SHAPE.rotate(face));
}
}

public static VoxelShape buildStairShape(BlockState stairBlockState) {
var isDownwards = stairBlockState.getPropertyValue(BlockPropertyTypes.UPSIDE_DOWN_BIT);
var face = STAIR_DIRECTION_VALUE_TO_BLOCK_FACE[stairBlockState.getPropertyValue(BlockPropertyTypes.WEIRDO_DIRECTION)];
return isDownwards ? DOWNWARDS_STAIR_SHAPES.get(face) : UPWARDS_STAIR_SHAPES.get(face);
}

public static VoxelShape buildLiquidShape(BlockState liquidBlockState) {
if (!(liquidBlockState.getBehavior() instanceof BlockLiquidBaseComponent liquidBaseComponent)) {
if (!(liquidBlockState.getBehavior() instanceof BlockLiquidBaseComponent)) {
throw new IllegalArgumentException("The liquidBlockState must implement BlockLiquidBaseComponent!");
}
return VoxelShape.builder()
Expand Down
2 changes: 1 addition & 1 deletion data/resources/block_states.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion data/resources/unpacked/block_states_raw.json

Large diffs are not rendered by default.

40 changes: 26 additions & 14 deletions data/src/main/java/org/allaymc/data/BlockStateDataProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public static class RawBlockStateData {
public int burnOdds = 0;
public boolean canContainLiquidSource;
public String liquidReactionOnTouch;
public float[] collisionShape;
public float[][] collisionShape;
public float[] liquidClipShape;
public float[] outlineShape;
public float[] uiShape;
Expand All @@ -59,7 +59,7 @@ public static class NewBlockStateData {
public int burnOdds = 0;
public boolean canContainLiquidSource;
public String liquidReactionOnTouch;
public float[] collisionShape;
public float[][] collisionShape;
public float[] shape;
public float hardness;
public float explosionResistance;
Expand Down Expand Up @@ -97,32 +97,44 @@ public static NewBlockStateData fromRaw(RawBlockStateData raw) {
data.name = raw.name;
data.blockStateHash = raw.blockStateHash;

if (isEmptyShape(raw.collisionShape)) {
if (raw.collisionShape.length == 0) {
data.shape = clampShape(raw.outlineShape);
} else {
data.shape = data.collisionShape;
data.shape = unionShapes(data.collisionShape);
}

return data;
}

public static boolean isEmptyShape(float[] shape) {
for (var f : shape) {
if (f != 0) {
return false;
}
public static float[][] clampShape(float[][] shapes) {
for (var shape : shapes) {
clampShape(shape);
}
return true;

return shapes;
}

public static float[] clampShape(float[] shape) {
private static float[] clampShape(float[] shape) {
for (var i = 0; i < shape.length; i++) {
// Clamp the value between 0 and 1
// because bigger than 1 is not allowed
// in allay
// Clamp the value between 0 and 1 because bigger than 1 is not allowed in allay
shape[i] = Math.max(0, Math.min(1, shape[i]));
}

return shape;
}

public static float[] unionShapes(float[][] shapes) {
var unionShape = new float[6];
for (var shape : shapes) {
for (var i = 0; i < 3; i++) {
unionShape[i] = Math.min(unionShape[i], shape[i]);
}
for (var i = 3; i < 6; i++) {
unionShape[i] = Math.max(unionShape[i], shape[i]);
}
}

return unionShape;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -494,8 +494,7 @@ private static <T extends BlockBehavior> AllayBlockType.Builder stairsBuilder(Cl
return AllayBlockType
.builder(clazz)
.vanillaBlock(id)
.setProperties(BlockPropertyTypes.UPSIDE_DOWN_BIT, BlockPropertyTypes.WEIRDO_DIRECTION)
.addComponent(BlockStateDataComponentImpl.ofRedefinedCollisionShape(VoxelShapes::buildStairShape));
.setProperties(BlockPropertyTypes.UPSIDE_DOWN_BIT, BlockPropertyTypes.WEIRDO_DIRECTION);
}

public static void initSlab() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@ class BlockStateDataTest {
"burnOdds": 0,
"canContainLiquidSource": false,
"collisionShape": [
0.0005,
0.0005,
0.0005,
0.9995,
0.1825,
0.9995
[
0.0005,
0.0005,
0.0005,
0.9995,
0.1825,
0.9995
]
],
"hardness": 1.25,
"explosionResistance": 1.25,
Expand Down

0 comments on commit 5eddd77

Please sign in to comment.