Search in sources :

Example 1 with AABB

use of org.spongepowered.api.util.AABB in project SpongeCommon by SpongePowered.

the class MixinChunk method getIntersectingEntities.

private void getIntersectingEntities(Collection<Entity> entities, Vector3d start, Vector3d direction, double distance, java.util.function.Predicate<EntityHit> filter, Set<EntityHit> intersections) {
    // Check each entity in the list
    for (Entity entity : entities) {
        final org.spongepowered.api.entity.Entity spongeEntity = (org.spongepowered.api.entity.Entity) entity;
        final Optional<AABB> box = spongeEntity.getBoundingBox();
        // Can't intersect if the entity doesn't have a bounding box
        if (!box.isPresent()) {
            continue;
        }
        // Ignore entities that didn't intersect
        final Optional<Tuple<Vector3d, Vector3d>> optionalIntersection = box.get().intersects(start, direction);
        if (!optionalIntersection.isPresent()) {
            continue;
        }
        // Check that the entity isn't too far away
        final Tuple<Vector3d, Vector3d> intersection = optionalIntersection.get();
        final double distanceSquared = intersection.getFirst().sub(start).lengthSquared();
        if (distanceSquared > distance * distance) {
            continue;
        }
        // Now test the filter on the entity and intersection
        final EntityHit hit = new EntityHit(spongeEntity, intersection.getFirst(), intersection.getSecond(), Math.sqrt(distanceSquared));
        if (!filter.test(hit)) {
            continue;
        }
        // If everything passes we have an intersection!
        intersections.add(hit);
        // If the entity has part, recurse on these
        final Entity[] parts = entity.getParts();
        if (parts != null && parts.length > 0) {
            getIntersectingEntities(Arrays.asList(parts), start, direction, distance, filter, intersections);
        }
    }
}
Also used : TileEntity(net.minecraft.tileentity.TileEntity) IMixinEntity(org.spongepowered.common.interfaces.entity.IMixinEntity) IMixinTileEntity(org.spongepowered.common.interfaces.block.tile.IMixinTileEntity) Entity(net.minecraft.entity.Entity) Vector3d(com.flowpowered.math.vector.Vector3d) AABB(org.spongepowered.api.util.AABB) Tuple(org.spongepowered.api.util.Tuple)

Example 2 with AABB

use of org.spongepowered.api.util.AABB in project LanternServer by LanternPowered.

the class LanternItem method pulsePhysics.

private void pulsePhysics() {
    // Get the current velocity
    Vector3d velocity = getVelocity();
    // Update the position based on the velocity
    setPosition(getPosition().add(velocity));
    // We will check if there is a collision box under the entity
    boolean ground = false;
    final AABB thisBox = getBoundingBox().get().offset(0, -0.1, 0);
    final Set<AABB> boxes = getWorld().getIntersectingBlockCollisionBoxes(thisBox);
    for (AABB box : boxes) {
        final Vector3d factor = box.getCenter().sub(thisBox.getCenter());
        if (Direction.getClosest(factor).isUpright()) {
            ground = true;
        }
    }
    if (!ground) {
        final Optional<Double> gravityFactor = get(LanternKeys.GRAVITY_FACTOR);
        if (gravityFactor.isPresent()) {
            // Apply the gravity factor
            velocity = velocity.add(0, -gravityFactor.get(), 0);
        }
    }
    velocity = velocity.mul(0.98, 0.98, 0.98);
    if (ground) {
        velocity = velocity.mul(1, -0.5, 1);
    }
    // Offer the velocity back
    offer(Keys.VELOCITY, velocity);
}
Also used : Vector3d(com.flowpowered.math.vector.Vector3d) AABB(org.spongepowered.api.util.AABB)

Example 3 with AABB

use of org.spongepowered.api.util.AABB in project LanternServer by LanternPowered.

the class LanternChunk method getBlockSelectionBox.

@Override
public Optional<AABB> getBlockSelectionBox(int x, int y, int z) {
    final BlockState block = getBlock(x, y, z);
    if (block.getType() == BlockTypes.AIR) {
        return Optional.empty();
    }
    final ObjectProvider<AABB> aabbObjectProvider = ((LanternBlockType) block.getType()).getBoundingBoxProvider();
    if (aabbObjectProvider == null) {
        return Optional.empty();
    }
    final AABB aabb;
    if (aabbObjectProvider instanceof ConstantObjectProvider || aabbObjectProvider instanceof CachedSimpleObjectProvider || aabbObjectProvider instanceof SimpleObjectProvider) {
        aabb = aabbObjectProvider.get(block, null, null);
    } else {
        aabb = aabbObjectProvider.get(block, new Location<>(this.world, x, y, z), null);
    }
    return aabb == null ? Optional.empty() : Optional.of(aabb.offset(x, y, z));
}
Also used : BlockState(org.spongepowered.api.block.BlockState) ConstantObjectProvider(org.lanternpowered.server.block.provider.ConstantObjectProvider) CachedSimpleObjectProvider(org.lanternpowered.server.block.provider.CachedSimpleObjectProvider) LanternBlockType(org.lanternpowered.server.block.LanternBlockType) AABB(org.spongepowered.api.util.AABB) CachedSimpleObjectProvider(org.lanternpowered.server.block.provider.CachedSimpleObjectProvider) SimpleObjectProvider(org.lanternpowered.server.block.provider.SimpleObjectProvider) Location(org.spongepowered.api.world.Location)

Example 4 with AABB

use of org.spongepowered.api.util.AABB in project LanternServer by LanternPowered.

the class LanternChunk method getIntersectingBlockCollisionBoxes.

@Override
public Set<AABB> getIntersectingBlockCollisionBoxes(AABB box) {
    checkNotNull(box, "box");
    final Vector3i min = box.getMin().toInt();
    final Vector3i max = box.getMax().toInt();
    checkVolumeBounds(min);
    checkVolumeBounds(max);
    final ImmutableSet.Builder<AABB> builder = ImmutableSet.builder();
    final int minX = min.getX();
    final int minY = min.getY();
    final int minZ = min.getZ();
    final int maxX = max.getX();
    final int maxY = max.getY();
    final int maxZ = max.getZ();
    for (int x = minX; x <= maxX; x++) {
        for (int z = minZ; z <= maxZ; z++) {
            for (int y = minY; y <= maxY; y++) {
                final Optional<AABB> optAABB = getBlockSelectionBox(x, y, z);
                if (optAABB.isPresent()) {
                    final AABB aabb = optAABB.get();
                    if (aabb.intersects(box)) {
                        builder.add(box);
                    }
                }
            }
        }
    }
    return builder.build();
}
Also used : ImmutableSet(com.google.common.collect.ImmutableSet) Vector3i(com.flowpowered.math.vector.Vector3i) AABB(org.spongepowered.api.util.AABB)

Example 5 with AABB

use of org.spongepowered.api.util.AABB in project LanternServer by LanternPowered.

the class LanternWorld method getIntersectingBlockCollisionBoxes.

public Set<AABB> getIntersectingBlockCollisionBoxes(AABB box, @Nullable Predicate<Entity> filter) {
    checkNotNull(box, "box");
    final ImmutableSet.Builder<AABB> boxes = ImmutableSet.builder();
    int minY = box.getMin().getFloorY();
    final int maxY = box.getMax().getFloorY();
    if (minY >= LanternWorld.BLOCK_MAX.getY() || maxY < 0) {
        return boxes.build();
    }
    minY = Math.max(0, minY);
    final int maxX = box.getMax().getFloorX();
    final int minX = box.getMin().getFloorX();
    final int maxZ = box.getMax().getFloorZ();
    final int minZ = box.getMin().getFloorZ();
    final int maxChunkX = maxX >> 4;
    final int minChunkX = minX >> 4;
    final int maxChunkZ = maxZ >> 4;
    final int minChunkZ = minZ >> 4;
    final int maxChunkSection = maxY >> 4;
    final int minChunkSection = minY >> 4;
    for (int chunkX = minChunkX; chunkX <= maxChunkX; chunkX++) {
        for (int chunkZ = minChunkZ; chunkZ <= maxChunkZ; chunkZ++) {
            final LanternChunk chunk = getChunkManager().getChunkIfLoaded(chunkX, chunkZ);
            if (chunk == null) {
                continue;
            }
            final int startX = Math.max(minX, chunkX << 4);
            final int endX = Math.min(maxX, (chunkX << 4) | 0xf);
            final int startZ = Math.max(minZ, chunkZ << 4);
            final int endZ = Math.min(maxZ, (chunkZ << 4) | 0xf);
            for (int x = startX; x <= endX; x++) {
                for (int z = startZ; z <= endZ; z++) {
                    for (int y = minY; y <= maxY; y++) {
                        final Optional<AABB> boundingBox = chunk.getBlockSelectionBox(x, y, z);
                        if (boundingBox.isPresent() && boundingBox.get().intersects(box)) {
                            boxes.add(boundingBox.get());
                        }
                    }
                }
            }
            if (filter != null) {
                chunk.addIntersectingEntitiesBoxes(boxes, maxChunkSection, minChunkSection, box, filter);
            }
        }
    }
    return boxes.build();
}
Also used : ImmutableSet(com.google.common.collect.ImmutableSet) AABB(org.spongepowered.api.util.AABB) LanternChunk(org.lanternpowered.server.world.chunk.LanternChunk)

Aggregations

AABB (org.spongepowered.api.util.AABB)26 Test (org.junit.jupiter.api.Test)14 Vector3d (org.spongepowered.math.vector.Vector3d)13 Vector3d (com.flowpowered.math.vector.Vector3d)3 ImmutableSet (com.google.common.collect.ImmutableSet)3 World (org.spongepowered.api.world.World)3 Vector3i (org.spongepowered.math.vector.Vector3i)3 Vector3i (com.flowpowered.math.vector.Vector3i)2 CachedSimpleObjectProvider (org.lanternpowered.server.block.provider.CachedSimpleObjectProvider)2 ConstantObjectProvider (org.lanternpowered.server.block.provider.ConstantObjectProvider)2 SimpleObjectProvider (org.lanternpowered.server.block.provider.SimpleObjectProvider)2 ReplaceableProperty (org.spongepowered.api.data.property.block.ReplaceableProperty)2 Direction (org.spongepowered.api.util.Direction)2 Preconditions.checkNotNull (com.google.common.base.Preconditions.checkNotNull)1 Inject (com.google.inject.Inject)1 ArrayList (java.util.ArrayList)1 BitSet (java.util.BitSet)1 Collection (java.util.Collection)1 List (java.util.List)1 Consumer (java.util.function.Consumer)1