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);
}
}
}
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);
}
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));
}
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();
}
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();
}
Aggregations