Search in sources :

Example 6 with Heightmap

use of io.xol.chunkstories.api.world.heightmap.Heightmap in project chunkstories by Hugobros3.

the class LocalClientLoadingAgent method updateUsedWorldBits.

public void updateUsedWorldBits() {
    Entity controlledEntity = player.getControlledEntity();
    if (controlledEntity == null)
        return;
    try {
        lock.lock();
        // Subscribe to nearby wanted chunks
        int cameraChunkX = Math2.floor((controlledEntity.getLocation().x()) / 32);
        int cameraChunkY = Math2.floor((controlledEntity.getLocation().y()) / 32);
        int cameraChunkZ = Math2.floor((controlledEntity.getLocation().z()) / 32);
        int chunksViewDistance = (int) (world.getClient().getConfiguration().getIntOption("client.rendering.viewDistance") / 32);
        for (int chunkX = (cameraChunkX - chunksViewDistance - 1); chunkX <= cameraChunkX + chunksViewDistance + 1; chunkX++) {
            for (int chunkZ = (cameraChunkZ - chunksViewDistance - 1); chunkZ <= cameraChunkZ + chunksViewDistance + 1; chunkZ++) for (int chunkY = cameraChunkY - 3; chunkY <= cameraChunkY + 3; chunkY++) {
                WorldInfo worldInfo = world.getWorldInfo();
                WorldInfo.WorldSize size = worldInfo.getSize();
                int filteredChunkX = chunkX & (size.maskForChunksCoordinates);
                int filteredChunkY = Math2.clampi(chunkY, 0, 31);
                int filteredChunkZ = chunkZ & (size.maskForChunksCoordinates);
                int summed = ((filteredChunkX << size.bitlengthOfVerticalChunksCoordinates) | filteredChunkY) << size.bitlengthOfHorizontalChunksCoordinates | filteredChunkZ;
                if (fastChunksMask.contains(summed))
                    continue;
                ChunkHolder holder = world.aquireChunkHolder(player, chunkX, chunkY, chunkZ);
                assert holder != null;
                if (holder == null)
                    continue;
                usedChunks.add(holder);
                fastChunksMask.add(summed);
                if (world instanceof WorldClientRemote) {
                    WorldClientRemote remote = (WorldClientRemote) world;
                    remote.getConnection().pushPacket(PacketWorldUser.registerChunkPacket(world, filteredChunkX, filteredChunkY, filteredChunkZ));
                }
            }
        }
        // Unsubscribe for far ones
        Iterator<ChunkHolder> i = usedChunks.iterator();
        while (i.hasNext()) {
            ChunkHolder holder = i.next();
            if ((LoopingMathHelper.moduloDistance(holder.getChunkCoordinateX(), cameraChunkX, world.getSizeInChunks()) > chunksViewDistance + 1) || (LoopingMathHelper.moduloDistance(holder.getChunkCoordinateZ(), cameraChunkZ, world.getSizeInChunks()) > chunksViewDistance + 1) || (Math.abs(holder.getChunkCoordinateY() - cameraChunkY) > 4)) {
                WorldInfo worldInfo = world.getWorldInfo();
                WorldInfo.WorldSize size = worldInfo.getSize();
                int filteredChunkX = holder.getChunkCoordinateX() & (size.maskForChunksCoordinates);
                int filteredChunkY = Math2.clampi(holder.getChunkCoordinateY(), 0, 31);
                int filteredChunkZ = holder.getChunkCoordinateZ() & (size.maskForChunksCoordinates);
                int summed = ((filteredChunkX << size.bitlengthOfVerticalChunksCoordinates) | filteredChunkY) << size.bitlengthOfHorizontalChunksCoordinates | filteredChunkZ;
                fastChunksMask.remove(summed);
                i.remove();
                holder.unregisterUser(player);
                if (world instanceof WorldClientRemote) {
                    WorldClientRemote remote = (WorldClientRemote) world;
                    remote.getConnection().pushPacket(PacketWorldUser.unregisterChunkPacket(world, filteredChunkX, filteredChunkY, filteredChunkZ));
                }
            }
        }
        // We load the region summaries we fancy
        int summaryDistance = 32;
        for (int chunkX = (cameraChunkX - summaryDistance); chunkX < cameraChunkX + summaryDistance; chunkX++) for (int chunkZ = (cameraChunkZ - summaryDistance); chunkZ < cameraChunkZ + summaryDistance; chunkZ++) {
            if (chunkX % 8 == 0 && chunkZ % 8 == 0) {
                int regionX = chunkX / 8;
                int regionZ = chunkZ / 8;
                // TODO bad to aquire each time!!!
                Heightmap regionSummary = world.getRegionsSummariesHolder().aquireHeightmap(player, regionX, regionZ);
                if (regionSummary != null) {
                    if (usedRegionSummaries.add(regionSummary)) {
                        if (world instanceof WorldClientRemote) {
                            WorldClientRemote remote = (WorldClientRemote) world;
                            remote.getConnection().pushPacket(PacketWorldUser.registerSummary(world, regionX, regionZ));
                        }
                    }
                }
            }
        }
        int cameraRegionX = cameraChunkX / 8;
        int cameraRegionZ = cameraChunkZ / 8;
        int distInRegions = summaryDistance / 8;
        int sizeInRegions = world.getSizeInChunks() / 8;
        // And we unload the ones we no longer need
        Iterator<Heightmap> iterator = usedRegionSummaries.iterator();
        while (iterator.hasNext()) {
            Heightmap entry = iterator.next();
            int regionX = entry.getRegionX();
            int regionZ = entry.getRegionZ();
            int dx = LoopingMathHelper.moduloDistance(cameraRegionX, regionX, sizeInRegions);
            int dz = LoopingMathHelper.moduloDistance(cameraRegionZ, regionZ, sizeInRegions);
            if (dx > distInRegions || dz > distInRegions) {
                entry.unregisterUser(player);
                iterator.remove();
                if (world instanceof WorldClientRemote) {
                    WorldClientRemote remote = (WorldClientRemote) world;
                    remote.getConnection().pushPacket(PacketWorldUser.unregisterSummary(world, regionX, regionZ));
                }
            }
        }
    } finally {
        lock.unlock();
    }
}
Also used : Entity(io.xol.chunkstories.api.entity.Entity) Heightmap(io.xol.chunkstories.api.world.heightmap.Heightmap) ChunkHolder(io.xol.chunkstories.api.world.chunk.ChunkHolder) WorldClientRemote(io.xol.chunkstories.world.WorldClientRemote) WorldInfo(io.xol.chunkstories.api.world.WorldInfo)

Example 7 with Heightmap

use of io.xol.chunkstories.api.world.heightmap.Heightmap in project chunkstories by Hugobros3.

the class HeightmapArrayTexture method update.

public void update() {
    Player player = client.getPlayer();
    Location playerPosition = player.getLocation();
    if (playerPosition == null)
        // We won't do shit with that going on
        return;
    World world = playerPosition.getWorld();
    int chunkX = (int) Math.floor(playerPosition.x / 32.0);
    int chunkZ = (int) Math.floor(playerPosition.z / 32.0);
    int regionX = chunkX / 8;
    int regionZ = chunkZ / 8;
    // Remap the array
    if (lastRegionX != regionX || lastRegionZ != regionZ || redo.compareAndSet(true, false)) {
        WriteLock writeLock = lock.writeLock();
        writeLock.lock();
        // We may need this
        ByteBuffer bb = MemoryUtil.memAlloc(4 * 256 * 256);
        bb.order(ByteOrder.LITTLE_ENDIAN);
        // Clear unused slots
        for (int i = 0; i < 81; i++) {
            ArrayTextureSlot slot = arrayTextureContents[i];
            if (slot == null)
                continue;
            // Frees slots immediately once out of the area we care about
            if (Math.abs(slot.regionX - regionX) >= 5 || Math.abs(slot.regionZ - regionZ) >= 5)
                arrayTextureContents[i] = null;
        }
        for (int i = -4; i <= 4; i++) for (int j = -4; j <= 4; j++) {
            int regionI = regionX + i;
            int regionJ = regionZ + j;
            // Wrap arround the world!
            if (regionI < 0)
                regionI += world.getSizeInChunks() / 256;
            if (regionJ < 0)
                regionJ += world.getSizeInChunks() / 256;
            // Look for a slot already containing our wanted textures
            int free = -1;
            int good = -1;
            for (int k = 0; k < 81; k++) {
                ArrayTextureSlot slot = arrayTextureContents[k];
                if (slot == null) {
                    if (free == -1)
                        free = k;
                } else {
                    if (slot.regionX == regionI && slot.regionZ == regionJ) {
                        good = k;
                        break;
                    }
                }
            }
            int slot;
            // If no good slot was found :(
            if (good == -1) {
                arrayTextureContents[free] = new ArrayTextureSlot();
                arrayTextureContents[free].regionX = regionI;
                arrayTextureContents[free].regionZ = regionJ;
                slot = free;
            } else {
                slot = good;
            }
            // If data is not yet in the slot, check if the world has data for it
            if (!arrayTextureContents[slot].hasData) {
                Heightmap sum = world.getRegionsSummariesHolder().getHeightmap(arrayTextureContents[slot].regionX, arrayTextureContents[slot].regionZ);
                if (sum != null && sum.isLoaded()) {
                    loadHeights((HeightmapImplementation) sum, bb, 0);
                    heights.uploadTextureData(slot, 0, bb);
                    for (int lod = 1; lod <= 8; lod++) {
                        loadHeights((HeightmapImplementation) sum, bb, lod);
                        heights.uploadTextureData(slot, lod, bb);
                    }
                    heights.setMipMapping(true);
                    heights.setMipmapLevelsRange(0, 8);
                    loadTopVoxels((HeightmapImplementation) sum, bb, 0);
                    topVoxels.uploadTextureData(slot, 0, bb);
                    for (int lod = 1; lod <= 8; lod++) {
                        loadTopVoxels((HeightmapImplementation) sum, bb, lod);
                        topVoxels.uploadTextureData(slot, lod, bb);
                    }
                    topVoxels.setMipMapping(true);
                    topVoxels.setMipmapLevelsRange(0, 8);
                    arrayTextureContents[slot].hasData = true;
                }
            }
            arrayTextureReference[i + 4][j + 4] = slot;
        }
        MemoryUtil.memFree(bb);
        lastRegionX = regionX;
        lastRegionZ = regionZ;
        writeLock.unlock();
    }
}
Also used : WriteLock(java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock) ReentrantReadWriteLock(java.util.concurrent.locks.ReentrantReadWriteLock) Player(io.xol.chunkstories.api.player.Player) Heightmap(io.xol.chunkstories.api.world.heightmap.Heightmap) HeightmapImplementation(io.xol.chunkstories.world.summary.HeightmapImplementation) World(io.xol.chunkstories.api.world.World) ByteBuffer(java.nio.ByteBuffer) Location(io.xol.chunkstories.api.Location)

Example 8 with Heightmap

use of io.xol.chunkstories.api.world.heightmap.Heightmap in project chunkstories by Hugobros3.

the class LocalClientLoadingAgent method handleServerResponse.

public void handleServerResponse(PacketWorldUser packet) throws IllegalPacketException {
    try {
        lock.lock();
        // The server refused to register us to this chunk. We gracefully accept.
        if (packet.getType() == Type.UNREGISTER_CHUNK) {
            ChunkHolder holder = world.getRegionChunkCoordinates(packet.getX(), packet.getY(), packet.getZ()).getChunkHolder(packet.getX(), packet.getY(), packet.getZ());
            // Apparently we already figured we didn't need this anyway
            if (holder == null)
                return;
            WorldInfo worldInfo = world.getWorldInfo();
            WorldInfo.WorldSize size = worldInfo.getSize();
            int filteredChunkX = holder.getChunkCoordinateX() & (size.maskForChunksCoordinates);
            int filteredChunkY = Math2.clampi(holder.getChunkCoordinateY(), 0, 31);
            int filteredChunkZ = holder.getChunkCoordinateZ() & (size.maskForChunksCoordinates);
            int summed = ((filteredChunkX << size.bitlengthOfVerticalChunksCoordinates) | filteredChunkY) << size.bitlengthOfHorizontalChunksCoordinates | filteredChunkZ;
            // We remove it from our list
            fastChunksMask.remove(summed);
            usedChunks.remove(holder);
            // And we unsub.
            holder.unregisterUser(player);
        // This is the same but for region summaries
        } else if (packet.getType() == Type.UNREGISTER_SUMMARY) {
            Heightmap regionSummary = world.getRegionsSummariesHolder().getHeightmap(packet.getX(), packet.getZ());
            if (regionSummary == null)
                return;
            usedRegionSummaries.remove(regionSummary);
            regionSummary.unregisterUser(player);
        } else
            // We only expect UNREGISTER packets from the server !
            throw new IllegalPacketException(packet);
    } finally {
        lock.unlock();
    }
}
Also used : Heightmap(io.xol.chunkstories.api.world.heightmap.Heightmap) ChunkHolder(io.xol.chunkstories.api.world.chunk.ChunkHolder) WorldInfo(io.xol.chunkstories.api.world.WorldInfo) IllegalPacketException(io.xol.chunkstories.api.exceptions.net.IllegalPacketException)

Aggregations

Heightmap (io.xol.chunkstories.api.world.heightmap.Heightmap)8 ChunkHolder (io.xol.chunkstories.api.world.chunk.ChunkHolder)6 Player (io.xol.chunkstories.api.player.Player)2 WorldInfo (io.xol.chunkstories.api.world.WorldInfo)2 CompoundFence (io.xol.chunkstories.util.concurrency.CompoundFence)2 Location (io.xol.chunkstories.api.Location)1 Entity (io.xol.chunkstories.api.entity.Entity)1 IllegalPacketException (io.xol.chunkstories.api.exceptions.net.IllegalPacketException)1 Fence (io.xol.chunkstories.api.util.concurrency.Fence)1 Task (io.xol.chunkstories.api.workers.Task)1 TaskExecutor (io.xol.chunkstories.api.workers.TaskExecutor)1 World (io.xol.chunkstories.api.world.World)1 WorldSize (io.xol.chunkstories.api.world.WorldInfo.WorldSize)1 WorldUser (io.xol.chunkstories.api.world.WorldUser)1 Chunk (io.xol.chunkstories.api.world.chunk.Chunk)1 SimpleFence (io.xol.chunkstories.util.concurrency.SimpleFence)1 WorldClientRemote (io.xol.chunkstories.world.WorldClientRemote)1 WorldImplementation (io.xol.chunkstories.world.WorldImplementation)1 CubicChunk (io.xol.chunkstories.world.chunk.CubicChunk)1 RegionImplementation (io.xol.chunkstories.world.region.RegionImplementation)1