Search in sources :

Example 16 with Entity

use of io.xol.chunkstories.api.entity.Entity in project chunkstories by Hugobros3.

the class WorldImplementation method addEntity.

@Override
public void addEntity(final Entity entity) {
    // Assign an UUID to entities lacking one
    if (this instanceof WorldMaster && entity.getUUID() == -1) {
        long nextUUID = nextEntityId();
        entity.setUUID(nextUUID);
    }
    Entity check = this.getEntityByUUID(entity.getUUID());
    if (check != null) {
        logger().error("Added an entity twice " + check + " conflits with " + entity + " UUID: " + entity.getUUID());
        // logger().save();
        Thread.dumpStack();
        // System.exit(-1);
        return;
    }
    // Add it to the world
    ((EntityBase) entity).markHasSpawned();
    assert entity.getWorld() == this;
    Chunk chunk = this.getChunkWorldCoordinates(entity.getLocation());
    if (chunk != null) {
        ((EntityBase) entity).positionComponent.trySnappingToChunk();
    }
    this.entities.insertEntity(entity);
}
Also used : EntityBase(io.xol.chunkstories.api.entity.EntityBase) Entity(io.xol.chunkstories.api.entity.Entity) Chunk(io.xol.chunkstories.api.world.chunk.Chunk) CubicChunk(io.xol.chunkstories.world.chunk.CubicChunk) WorldMaster(io.xol.chunkstories.api.world.WorldMaster)

Example 17 with Entity

use of io.xol.chunkstories.api.entity.Entity in project chunkstories by Hugobros3.

the class ChunkHolderImplementation method unloadChunk.

private void unloadChunk() {
    chunkLock.writeLock().lock();
    CubicChunk chunk = this.chunk;
    if (chunk == null) {
        chunkLock.writeLock().unlock();
        return;
    }
    // Unlist it immediately
    regionLoadedChunks.remove(chunk);
    this.chunk = null;
    // Remove the entities from this chunk from the world
    region.world.entitiesLock.writeLock().lock();
    Iterator<Entity> i = chunk.localEntities.iterator();
    while (i.hasNext()) {
        Entity entity = i.next();
        if (entity instanceof EntityControllable && ((EntityControllable) entity).getController() != null) {
            // give grace to controlled entities
            continue;
        } else {
            region.world.removeEntityFromList(entity);
        }
    }
    region.world.entitiesLock.writeLock().unlock();
    // Lock it down
    chunk.entitiesLock.lock();
    // Kill any load chunk operation that is still scheduled
    if (loadChunkTask != null) {
        IOTask task = loadChunkTask;
        if (task != null)
            task.cancel();
        loadChunkTask = null;
    }
    // Compress chunk one last time before it has to go
    setCompressedData(compressChunkData(chunk));
    // destroy it (returns any internal data using up ressources)
    chunk.destroy();
    // unlock it (whoever messes with it now, his problem)
    chunk.entitiesLock.unlock();
    chunkLock.writeLock().unlock();
}
Also used : Entity(io.xol.chunkstories.api.entity.Entity) IOTask(io.xol.chunkstories.world.io.IOTasks.IOTask) EntityControllable(io.xol.chunkstories.api.entity.interfaces.EntityControllable)

Example 18 with Entity

use of io.xol.chunkstories.api.entity.Entity in project chunkstories by Hugobros3.

the class ChunkHolderImplementation method compressChunkData.

/**
 * This method is called assumming the chunk is well-locked
 */
private CompressedData compressChunkData(final CubicChunk chunk) {
    final int changesTakenIntoAccount = chunk.compr_uncomittedBlockModifications.get();
    // Stage 1: Compress the actual voxel data
    byte[] voxelCompressedData;
    if (!chunk.isAirChunk()) {
        // Heuristic value for the size of the buffer: fixed voxel size + factor of components & entities
        // + chunk.voxelComponents.size() * 1024 + chunk.localEntities.size() * 2048;
        int uncompressedStuffBufferSize = 32 * 32 * 32 * 4;
        ByteBuffer uncompressedStuff = MemoryUtil.memAlloc(uncompressedStuffBufferSize);
        uncompressedStuff.asIntBuffer().put(chunk.chunkVoxelData);
        // uncompressedStuff.flip();
        ByteBuffer compressedStuff = MemoryUtil.memAlloc(uncompressedStuffBufferSize + 2048);
        LZ4Compressor compressor = factory.fastCompressor();
        compressor.compress(uncompressedStuff, compressedStuff);
        // No longer need that buffer
        MemoryUtil.memFree(uncompressedStuff);
        // Make a Java byte[] array to put the final stuff in
        voxelCompressedData = new byte[compressedStuff.position()];
        compressedStuff.flip();
        compressedStuff.get(voxelCompressedData);
        // No longer need that buffer either
        MemoryUtil.memFree(compressedStuff);
    } else {
        // Just use a symbolic null here
        voxelCompressedData = null;
    }
    // Stage 2: Take care of the voxel components
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    DataOutputStream daos = new DataOutputStream(baos);
    // ByteBuffer smallBuffer = MemoryUtil.memAlloc(4096);
    // byte[] smallArray = new byte[4096];
    // ByteBufferOutputStream bbos = new ByteBufferOutputStream(smallBuffer);
    ByteArrayOutputStream bbos = new ByteArrayOutputStream();
    DataOutputStream dos = new DataOutputStream(bbos);
    try {
        // For all cells that have components
        for (CellComponentsHolder voxelComponents : chunk.allCellComponents.values()) {
            // Write a 1 then their in-chunk index
            daos.writeByte((byte) 0x01);
            daos.writeInt(voxelComponents.getIndex());
            // For all components in this cell
            for (Entry<String, VoxelComponent> entry : voxelComponents.all()) {
                // Write component name
                daos.writeUTF(entry.getKey());
                // Push the component in the temporary buffer
                entry.getValue().push(region.handler, dos);
                // smallBuffer.flip();
                byte[] bytesPushed = bbos.toByteArray();
                bbos.reset();
                // Write how many bytes the temporary buffer now contains
                // int bytesPushed = smallBuffer.limit();
                daos.writeShort(bytesPushed.length);
                // Get those bytes as an array then write it in the compressed stuff
                // smallBuffer.get(smallArray);
                daos.write(bytesPushed, 0, bytesPushed.length);
            // Reset the temporary buffer
            // smallBuffer.clear();
            }
            daos.writeUTF("\n");
        }
        // Write the final 00, so to be clear we are done with voxel components
        daos.writeByte((byte) 0x00);
    // Since we output to a local buffer, any failure is viewed as catastrophic
    } catch (IOException e) {
        assert false;
    }
    // Extract the byte array from the baos
    byte[] voxelComponentsData = baos.toByteArray();
    // MemoryUtil.memFree(smallBuffer);
    // Stage 3: Compress entities
    baos.reset();
    for (Entity entity : chunk.localEntities) {
        // Don't save controllable entities
        if (entity.exists() && !(entity instanceof EntityUnsaveable && !((EntityUnsaveable) entity).shouldSaveIntoRegion())) {
            EntitySerializer.writeEntityToStream(daos, region.handler, entity);
        }
    }
    EntitySerializer.writeEntityToStream(daos, region.handler, null);
    byte[] entityData = baos.toByteArray();
    // Remove whatever modifications existed when the method started, this is for avoiding concurrent modifications not being taken into account
    chunk.compr_uncomittedBlockModifications.addAndGet(-changesTakenIntoAccount);
    return new CompressedData(voxelCompressedData, voxelComponentsData, entityData);
}
Also used : EntityUnsaveable(io.xol.chunkstories.api.entity.interfaces.EntityUnsaveable) Entity(io.xol.chunkstories.api.entity.Entity) DataOutputStream(java.io.DataOutputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) CellComponentsHolder(io.xol.chunkstories.voxel.components.CellComponentsHolder) ByteBuffer(java.nio.ByteBuffer) LZ4Compressor(net.jpountz.lz4.LZ4Compressor) VoxelComponent(io.xol.chunkstories.api.voxel.components.VoxelComponent) PacketChunkCompressedData(io.xol.chunkstories.net.packets.PacketChunkCompressedData)

Example 19 with Entity

use of io.xol.chunkstories.api.entity.Entity 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)

Example 20 with Entity

use of io.xol.chunkstories.api.entity.Entity in project chunkstories by Hugobros3.

the class WorldRendererImplementation method blitFinalImage.

public void blitFinalImage(RenderingInterface renderingContext, boolean hideGui) {
    Texture finalBuffer = this.renderingGraph.getRenderPass("final").resolvedOutputs.get("finalBuffer");
    if (finalBuffer != null && finalBuffer instanceof Texture2D) {
        final Texture2D finalTexture = (Texture2D) (finalBuffer);
        // We render to the screen.
        renderingContext.getRenderTargetManager().setConfiguration(null);
        renderingContext.setDepthTestMode(DepthTestMode.DISABLED);
        renderingContext.setBlendMode(BlendMode.DISABLED);
        renderingContext.useShader("blit");
        renderingContext.bindTexture2D("diffuseTexture", finalTexture);
        renderingContext.drawFSQuad();
        if (!hideGui) {
            world.entitiesLock.readLock().lock();
            Iterator<Entity> ei = world.getAllLoadedEntities();
            Entity e;
            while (ei.hasNext()) {
                e = ei.next();
                if (e instanceof EntityOverlay) {
                    ((EntityOverlay) e).drawEntityOverlay(renderingContext);
                }
            }
            world.entitiesLock.readLock().unlock();
        }
    }
}
Also used : Entity(io.xol.chunkstories.api.entity.Entity) Texture2D(io.xol.chunkstories.api.rendering.textures.Texture2D) Texture(io.xol.chunkstories.api.rendering.textures.Texture) HeightmapArrayTexture(io.xol.chunkstories.renderer.terrain.HeightmapArrayTexture) EntityOverlay(io.xol.chunkstories.api.entity.interfaces.EntityOverlay)

Aggregations

Entity (io.xol.chunkstories.api.entity.Entity)44 Location (io.xol.chunkstories.api.Location)17 WorldMaster (io.xol.chunkstories.api.world.WorldMaster)12 Vector3d (org.joml.Vector3d)11 Player (io.xol.chunkstories.api.player.Player)9 EntityLiving (io.xol.chunkstories.api.entity.EntityLiving)7 EntityControllable (io.xol.chunkstories.api.entity.interfaces.EntityControllable)5 Voxel (io.xol.chunkstories.api.voxel.Voxel)4 World (io.xol.chunkstories.api.world.World)4 EntityPlayer (io.xol.chunkstories.core.entity.EntityPlayer)4 IOException (java.io.IOException)4 EntityBase (io.xol.chunkstories.api.entity.EntityBase)3 HitBox (io.xol.chunkstories.api.entity.EntityLiving.HitBox)3 EntityComponentInventory (io.xol.chunkstories.api.entity.components.EntityComponentInventory)3 WorldException (io.xol.chunkstories.api.exceptions.world.WorldException)3 ItemVoxel (io.xol.chunkstories.api.item.ItemVoxel)3 CollisionBox (io.xol.chunkstories.api.physics.CollisionBox)3 CellData (io.xol.chunkstories.api.world.cell.CellData)3 Vector3dc (org.joml.Vector3dc)3 LocalPlayer (io.xol.chunkstories.api.client.LocalPlayer)2