Search in sources :

Example 1 with NearEntitiesIterator

use of io.xol.chunkstories.api.world.World.NearEntitiesIterator in project chunkstories by Hugobros3.

the class WorldEntitiesHolder method getEntitiesInBox.

public NearEntitiesIterator getEntitiesInBox(Vector3dc center, Vector3dc boxSize) {
    return new NearEntitiesIterator() {

        int centerVoxel_x = (int) (double) center.x();

        int centerVoxel_y = (int) (double) center.y();

        int centerVoxel_z = (int) (double) center.z();

        int box_ceil_x = (int) Math.ceil((double) boxSize.x());

        int box_ceil_y = (int) Math.ceil((double) boxSize.y());

        int box_ceil_z = (int) Math.ceil((double) boxSize.z());

        int box_start_x = sanitizeHorizontalCoordinate(centerVoxel_x - box_ceil_x);

        int box_start_y = sanitizeVerticalCoordinate(centerVoxel_y - box_ceil_y);

        int box_start_z = sanitizeHorizontalCoordinate(centerVoxel_z - box_ceil_z);

        int box_end_x = sanitizeHorizontalCoordinate(centerVoxel_x + box_ceil_x);

        int box_end_y = sanitizeVerticalCoordinate(centerVoxel_y + box_ceil_y);

        int box_end_z = sanitizeHorizontalCoordinate(centerVoxel_z + box_ceil_z);

        // We currently sort this out by regions, chunks would be more appropriate ?
        int region_start_x = box_start_x / 256;

        int region_start_y = box_start_y / 256;

        int region_start_z = box_start_z / 256;

        int region_end_x = box_end_x / 256;

        int region_end_y = box_end_y / 256;

        int region_end_z = box_end_z / 256;

        int region_x = region_start_x;

        int region_y = region_start_y;

        int region_z = region_start_z;

        Region currentRegion = world.getRegion(region_x, region_y, region_z);

        Iterator<Entity> currentRegionIterator = currentRegion == null ? null : currentRegion.getEntitiesWithinRegion();

        Entity next = null;

        double distance = 0D;

        private void seekNextEntity() {
            next = null;
            while (true) {
                // Break the loop if we find an entity in the region
                if (seekNextEntityWithinRegion())
                    break;
                else {
                    // Seek a suitable region if we failed to find anything above
                    if (seekNextRegion())
                        continue;
                    else
                        break;
                }
            }
        }

        private boolean seekNextEntityWithinRegion() {
            if (currentRegionIterator == null)
                return false;
            while (currentRegionIterator.hasNext()) {
                Entity entity = currentRegionIterator.next();
                // Check if it's inside the box for realz
                Location loc = entity.getLocation();
                int locx = (int) (double) loc.x();
                // Normal case, check if it's in the bounds, wrap-arround case, check if it's outside
                if ((box_start_x > box_end_x) == (locx >= box_start_x && locx <= box_end_x))
                    continue;
                int locy = (int) (double) loc.y();
                // Normal case, check if it's in the bounds, wrap-arround case, check if it's outside
                if ((box_start_y > box_end_y) == (locy >= box_start_y && locy <= box_end_y))
                    continue;
                int locz = (int) (double) loc.z();
                // Normal case, check if it's in the bounds, wrap-arround case, check if it's outside
                if ((box_start_z > box_end_z) == (locz >= box_start_z && locz <= box_end_z))
                    continue;
                // if(Math.abs(check.getX()) <= boxSize.getX() && Math.abs(check.getY()) <= boxSize.getY() && Math.abs(check.getZ()) <= boxSize.getZ())
                {
                    // Found a good one
                    this.next = entity;
                    Vector3d check = new Vector3d(loc);
                    check.sub(center);
                    this.distance = check.length();
                    return true;
                }
            }
            // We found nothing :(
            currentRegionIterator = null;
            return false;
        }

        private boolean seekNextRegion() {
            currentRegion = null;
            while (true) {
                // Found one !
                if (currentRegion != null) {
                    currentRegionIterator = currentRegion.getEntitiesWithinRegion();
                    return true;
                }
                region_x++;
                // Wrap arround in X dimension to Y
                if (region_x > region_end_x) {
                    region_x = 0;
                    region_y++;
                }
                // Then Y to Z
                if (region_y > region_end_y) {
                    region_y = 0;
                    region_z++;
                }
                // We are done here
                if (region_z > region_end_z)
                    return false;
                currentRegion = world.getRegion(region_x, region_y, region_z);
            }
        }

        @Override
        public boolean hasNext() {
            if (next == null)
                seekNextEntity();
            return next != null;
        }

        @Override
        public Entity next() {
            Entity entity = next;
            seekNextEntity();
            return entity;
        }

        @Override
        public double distance() {
            return distance;
        }
    };
}
Also used : Entity(io.xol.chunkstories.api.entity.Entity) NearEntitiesIterator(io.xol.chunkstories.api.world.World.NearEntitiesIterator) Vector3d(org.joml.Vector3d) Iterator(java.util.Iterator) NearEntitiesIterator(io.xol.chunkstories.api.world.World.NearEntitiesIterator) Region(io.xol.chunkstories.api.world.region.Region) Location(io.xol.chunkstories.api.Location)

Aggregations

Location (io.xol.chunkstories.api.Location)1 Entity (io.xol.chunkstories.api.entity.Entity)1 NearEntitiesIterator (io.xol.chunkstories.api.world.World.NearEntitiesIterator)1 Region (io.xol.chunkstories.api.world.region.Region)1 Iterator (java.util.Iterator)1 Vector3d (org.joml.Vector3d)1