use of org.spongepowered.api.util.AABB in project SpongeCommon by SpongePowered.
the class SpongeAABBTest method testOffsetCoordinates.
@Test
void testOffsetCoordinates() {
final AABB aabb1 = new SpongeAABB(new Vector3d(1, 2, 3), new Vector3d(7, 10, 13));
final AABB aabb2 = new SpongeAABB(new Vector3d(11, 0, 4), new Vector3d(17, 8, 14));
Assertions.assertEquals(aabb2, aabb1.offset(10, -2, 1));
}
use of org.spongepowered.api.util.AABB in project LanternServer by LanternPowered.
the class LanternEntity method getBoundingBox.
@Override
public Optional<AABB> getBoundingBox() {
AABB boundingBox = this.boundingBox;
if (boundingBox == null && this.boundingBoxBase != null) {
boundingBox = this.boundingBoxBase.offset(this.position);
this.boundingBox = boundingBox;
}
return Optional.ofNullable(boundingBox);
}
use of org.spongepowered.api.util.AABB in project LanternServer by LanternPowered.
the class LanternChunk method getIntersectingCollisionBoxes.
@Override
public Set<AABB> getIntersectingCollisionBoxes(Entity owner, AABB box) {
checkNotNull(owner, "owner");
checkNotNull(box, "box");
final ImmutableSet.Builder<AABB> collisionBoxes = ImmutableSet.builder();
final int maxYSection = fixEntityYSection(((int) Math.ceil(box.getMax().getY() + 2.0)) >> 4);
final int minYSection = fixEntityYSection(((int) Math.floor(box.getMin().getY() - 2.0)) >> 4);
for (int i = minYSection; i <= maxYSection; i++) {
forEachEntity(i, entity -> {
final Optional<AABB> aabb = entity.getBoundingBox();
if (aabb.isPresent() && aabb.get().intersects(box)) {
collisionBoxes.add(aabb.get());
}
});
}
final Vector3i min = box.getMin().toInt();
final Vector3i max = box.getMax().toInt();
for (int x = min.getX(); x <= max.getX(); x++) {
for (int y = min.getY(); y <= max.getY(); y++) {
for (int z = min.getZ(); z <= max.getZ(); z++) {
final Optional<AABB> aabb = getBlockSelectionBox(x, y, z);
if (aabb.isPresent() && aabb.get().intersects(box)) {
collisionBoxes.add(aabb.get());
}
}
}
}
return collisionBoxes.build();
}
use of org.spongepowered.api.util.AABB in project LanternServer by LanternPowered.
the class ChestInteractionBehavior method validateOpenableChestSpace.
static boolean validateOpenableChestSpace(BehaviorContext context, Location<World> loc, List<Runnable> tasks) {
final Location<World> relLoc = loc.getBlockRelative(Direction.UP);
final AABB relAabb = relLoc.getExtent().getBlockSelectionBox(relLoc.getBlockPosition()).orElse(null);
if (relAabb != null) {
AABB aabb = loc.getExtent().getBlockSelectionBox(loc.getBlockPosition()).get();
aabb = aabb.offset(0, 1, 0);
aabb = new AABB(aabb.getMin(), aabb.getMax().mul(1, 0, 1).add(0, aabb.getMin().getY() + 0.43, 0));
if (aabb.intersects(relAabb)) {
final ReplaceableProperty replaceableProperty = relLoc.getProperty(ReplaceableProperty.class).orElse(null);
// Replaceable blocks will be replaced when opened
if (replaceableProperty != null && replaceableProperty.getValue()) {
tasks.add(() -> context.addBlockChange(BlockSnapshotBuilder.create().location(relLoc).blockState(BlockTypes.AIR.getDefaultState()).build()));
// TODO: Use break block pipeline instead
} else {
return false;
}
}
}
return true;
}
use of org.spongepowered.api.util.AABB in project LanternServer by LanternPowered.
the class BlockTypeBuilderImpl method build.
@Override
public LanternBlockType build(String pluginId, String id) {
MutableBehaviorPipeline<Behavior> behaviorPipeline = this.behaviorPipeline;
if (behaviorPipeline == null) {
behaviorPipeline = new MutableBehaviorPipelineImpl<>(Behavior.class, new ArrayList<>());
} else {
behaviorPipeline = new MutableBehaviorPipelineImpl<>(Behavior.class, new ArrayList<>(behaviorPipeline.getBehaviors()));
}
TranslationProvider translationProvider = this.translationProvider;
if (translationProvider == null) {
String path = "tile." + id + ".name";
if (!pluginId.equals("minecraft")) {
path = pluginId + '.' + path;
}
translationProvider = TranslationProvider.of(tr(path));
}
PropertyProviderCollection.Builder properties;
if (this.propertiesBuilder != null) {
properties = this.propertiesBuilder;
} else {
properties = PropertyProviderCollections.DEFAULT.toBuilder();
}
ExtendedBlockStateProvider extendedBlockStateProvider = this.extendedBlockStateProvider;
if (extendedBlockStateProvider == null) {
extendedBlockStateProvider = new ExtendedBlockStateProvider() {
@Override
public BlockState get(BlockState blockState, @Nullable Location<World> location, @Nullable Direction face) {
return blockState;
}
@Override
public BlockState remove(BlockState blockState) {
return blockState;
}
};
}
final LanternBlockType blockType = new LanternBlockType(pluginId, id, this.traits, translationProvider, behaviorPipeline, this.tileEntityProvider, extendedBlockStateProvider);
// Override the default solid cube property provider if necessary
final PropertyProvider<SolidCubeProperty> provider = properties.build().get(SolidCubeProperty.class).orElse(null);
ObjectProvider<AABB> boundingBoxProvider = this.boundingBoxProvider;
if (boundingBoxProvider instanceof SimpleObjectProvider) {
// noinspection unchecked
boundingBoxProvider = new CachedSimpleObjectProvider(blockType, ((SimpleObjectProvider) boundingBoxProvider).getProvider());
}
// noinspection ConstantConditions
if (provider instanceof ConstantObjectProvider && provider.get(null, null, null).getValue()) {
if (boundingBoxProvider instanceof ConstantObjectProvider) {
// noinspection ConstantConditions
final AABB aabb = boundingBoxProvider.get(null, null, null);
final boolean isSolid = isSolid(aabb);
if (isSolid) {
properties.add(solidCube(true));
properties.add(solidSide(true));
} else {
properties.add(solidCube(false));
final BitSet solidSides = compileSidePropertyBitSet(aabb);
// Check if all the direction bits are set
final byte[] bytes = solidSides.toByteArray();
if (bytes.length == 0 || bytes[0] != (1 << DIRECTION_INDEXES) - 1) {
properties.add(solidSide((blockState, location, face) -> {
final int index = getDirectionIndex(face);
return index != -1 && solidSides.get(index);
}));
} else {
properties.add(solidSide(false));
}
}
} else if (boundingBoxProvider instanceof CachedSimpleObjectProvider) {
final List<AABB> values = ((CachedSimpleObjectProvider<AABB>) boundingBoxProvider).getValues();
final BitSet bitSet = new BitSet();
int count = 0;
for (int i = 0; i < values.size(); i++) {
if (isSolid(values.get(i))) {
bitSet.set(i);
count++;
}
}
final boolean flag1 = count == values.size();
final boolean flag2 = count == 0;
// Use the best possible solid cube property
if (flag1) {
properties.add(solidCube(true));
properties.add(solidSide(false));
} else if (flag2) {
properties.add(solidCube(false));
} else {
properties.add(solidCube(((blockState, location, face) -> bitSet.get(((LanternBlockState) blockState).getInternalId()))));
}
if (!flag1) {
final BitSet[] solidSides = new BitSet[values.size()];
int solidCount = 0;
for (int i = 0; i < values.size(); i++) {
solidSides[i] = compileSidePropertyBitSet(values.get(i));
// Check if all the direction bits are set
final byte[] bytes = solidSides[i].toByteArray();
if (bytes.length != 0 && bytes[0] == (1 << DIRECTION_INDEXES) - 1) {
solidCount++;
}
}
if (solidCount == 0) {
properties.add(solidSide(false));
} else {
properties.add(solidSide((blockState, location, face) -> {
final int index = getDirectionIndex(face);
if (index == -1) {
return false;
}
final int state = ((LanternBlockState) blockState).getInternalId();
return solidSides[state].get(index);
}));
}
}
} else {
final ObjectProvider<AABB> boundingBoxProvider1 = boundingBoxProvider;
properties.add(solidCube(((blockState, location, face) -> isSolid(boundingBoxProvider1.get(blockState, location, face)))));
properties.add(solidSide(((blockState, location, face) -> isSideSolid(boundingBoxProvider1.get(blockState, location, face), face))));
}
}
blockType.setBoundingBoxProvider(boundingBoxProvider);
blockType.setPropertyProviderCollection(properties.build());
if (this.defaultStateProvider != null) {
blockType.setDefaultBlockState(this.defaultStateProvider.apply(blockType.getDefaultState()));
}
if (this.itemTypeBuilder != null) {
final ItemType itemType = this.itemTypeBuilder.blockType(blockType).behaviors(pipeline -> {
// Only add the default behavior if there isn't any interaction behavior present
if (pipeline.pipeline(InteractWithItemBehavior.class).getBehaviors().isEmpty()) {
pipeline.add(new InteractWithBlockItemBehavior());
}
}).build(blockType.getPluginId(), blockType.getName());
blockType.setItemType(itemType);
}
return blockType;
}
Aggregations