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