use of io.xol.chunkstories.api.world.chunk.ChunkHolder 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.chunk.ChunkHolder in project chunkstories by Hugobros3.
the class ConverterWorkers method dropAll.
public void dropAll() {
CompoundFence readyAll = new CompoundFence();
CompoundFence doneAll = new CompoundFence();
SimpleFence atSignal = new SimpleFence();
for (int i = 0; i < workers.length; i++) {
SimpleFence ready = new SimpleFence();
readyAll.add(ready);
SimpleFence done = new SimpleFence();
doneAll.add(done);
scheduleTask(new Task() {
@Override
protected boolean task(TaskExecutor taskExecutor) {
ready.signal();
atSignal.traverse();
ConverterWorkerThread cwt = (ConverterWorkerThread) taskExecutor;
for (ChunkHolder holder : cwt.registeredCS_Holders) {
holder.unregisterUser(cwt);
cwt.chunksAquired--;
}
for (Heightmap summary : cwt.registeredCS_Summaries) summary.unregisterUser(cwt);
cwt.registeredCS_Summaries.clear();
cwt.registeredCS_Holders.clear();
done.signal();
return true;
}
});
}
readyAll.traverse();
atSignal.signal();
doneAll.traverse();
}
use of io.xol.chunkstories.api.world.chunk.ChunkHolder in project chunkstories by Hugobros3.
the class MultithreadedOfflineWorldConverter method stepThreeSpreadLightning.
protected void stepThreeSpreadLightning(WorldTool csWorld) {
verbose("Entering step three: spreading light");
csWorld.setLightning(true);
WorldSize size = csWorld.getWorldInfo().getSize();
int maxHeightPossible = 256;
int done = 0;
int todo = (size.sizeInChunks) * (size.sizeInChunks);
double completion = 0.0;
long lastPercentageShow = System.currentTimeMillis();
Set<ChunkHolder> registeredCS_Holders = new HashSet<ChunkHolder>();
Set<Heightmap> registeredCS_Summaries = new HashSet<Heightmap>();
int chunksAquired = 0;
WorldUser worldUser = this;
int waveSize = this.threadsCount * 32;
int wave = 0;
CompoundFence waveFence = new CompoundFence();
for (int chunkX = 0; chunkX < size.sizeInChunks; chunkX++) {
for (int chunkZ = 0; chunkZ < size.sizeInChunks; chunkZ++) {
wave++;
CompoundFence loadRelevantData = new CompoundFence();
Heightmap sum = csWorld.getRegionsSummariesHolder().aquireHeightmapChunkCoordinates(worldUser, chunkX, chunkZ);
registeredCS_Summaries.add(sum);
loadRelevantData.add(sum.waitForLoading());
// Loads 3x3 arround relevant chunks
for (int i = -1; i < 2; i++) {
for (int j = -1; j < 2; j++) {
for (int chunkY = 0; chunkY <= maxHeightPossible / 32; chunkY++) {
ChunkHolder chunkHolder = csWorld.aquireChunkHolder(worldUser, chunkX + i, chunkY, chunkZ + j);
if (chunkHolder != null) {
loadRelevantData.add(chunkHolder.waitForLoading());
if (registeredCS_Holders.add(chunkHolder))
chunksAquired++;
}
}
}
}
assert chunksAquired == registeredCS_Holders.size();
// Wait for everything to actually load
loadRelevantData.traverse();
// Spreads lightning, from top to botton
for (int chunkY = maxHeightPossible / 32; chunkY >= 0; chunkY--) {
CubicChunk chunk = csWorld.getChunk(chunkX, chunkY, chunkZ);
Fence fence = chunk.lightBaker.requestLightningUpdate();
// TaskLightChunk task = new TaskLightChunk(chunk, true);
// workers.scheduleTask(task);
waveFence.add(fence);
}
if (wave >= waveSize) {
waveFence.traverse();
waveFence.clear();
while (true) {
if (workers.size() > 0) {
// endless tasks
try {
Thread.sleep(50L);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else
break;
}
wave = 0;
// Show progress
done += waveSize;
if (Math.floor(((double) done / (double) todo) * 100) > completion) {
completion = Math.floor(((double) done / (double) todo) * 100);
if (completion >= 100.0 || (System.currentTimeMillis() - lastPercentageShow > 5000)) {
verbose(completion + "% ... using " + Runtime.getRuntime().freeMemory() / 1024 / 1024 + "/" + Runtime.getRuntime().maxMemory() / 1024 / 1024 + "Mb ");
lastPercentageShow = System.currentTimeMillis();
}
}
if (registeredCS_Holders.size() > targetChunksToKeepInRam) {
for (ChunkHolder holder : registeredCS_Holders) {
holder.unregisterUser(worldUser);
chunksAquired--;
}
for (Heightmap summary : registeredCS_Summaries) summary.unregisterUser(worldUser);
registeredCS_Summaries.clear();
registeredCS_Holders.clear();
csWorld.unloadUselessData().traverse();
// verbose("Done.");
}
}
}
}
waveFence.traverse();
wave = 0;
// Terminate
for (ChunkHolder holder : registeredCS_Holders) {
holder.unregisterUser(worldUser);
chunksAquired--;
}
for (Heightmap summary : registeredCS_Summaries) summary.unregisterUser(worldUser);
registeredCS_Summaries.clear();
registeredCS_Holders.clear();
csWorld.unloadUselessData().traverse();
/*csWorld.saveEverything();
for (ChunkHolder holder : registeredCS_Holders)
holder.unregisterUser(worldUser);
csWorld.unloadUselessData().traverse();*/
}
use of io.xol.chunkstories.api.world.chunk.ChunkHolder in project chunkstories by Hugobros3.
the class TaskBuildHeightmap method task.
@Override
protected boolean task(TaskExecutor taskExecutor) {
ConverterWorkerThread cwt = (ConverterWorkerThread) taskExecutor;
// We wait on a bunch of stuff to load everytime
CompoundFence loadRelevantData = new CompoundFence();
HeightmapImplementation summary = csWorld.getRegionsSummariesHolder().aquireHeightmap(cwt, regionX, regionZ);
loadRelevantData.add(summary.waitForLoading());
// Aquires the chunks we want to make the summaries of.
for (int innerCX = 0; innerCX < 8; innerCX++) for (int innerCZ = 0; innerCZ < 8; innerCZ++) for (int chunkY = 0; chunkY < OfflineWorldConverter.mcWorldHeight / 32; chunkY++) {
ChunkHolder holder = csWorld.aquireChunkHolder(cwt, regionX * 8 + innerCX, chunkY, regionZ * 8 + innerCZ);
if (holder != null) {
loadRelevantData.add(holder.waitForLoading());
if (cwt.registeredCS_Holders.add(holder))
cwt.chunksAquired++;
}
}
// Wait until all of that crap loads
loadRelevantData.traverse();
// Descend from top
for (int i = 0; i < 256; i++) for (int j = 0; j < 256; j++) {
for (int h = OfflineWorldConverter.mcWorldHeight; h > 0; h--) {
CellData data = csWorld.peekSafely(regionX * 256 + i, h, regionZ * 256 + j);
if (!data.getVoxel().isAir()) {
Voxel vox = data.getVoxel();
if (vox.getDefinition().isSolid() || vox.getDefinition().isLiquid()) {
summary.setTopCell(data);
break;
}
}
}
}
Fence waitForSummarySave = summary.saveSummary();
// cwt.converter().verbose("Waiting for summary saving...");
waitForSummarySave.traverse();
// cwt.converter().verbose("Done.");
// We don't need the summary anymore
summary.unregisterUser(cwt);
return true;
}
use of io.xol.chunkstories.api.world.chunk.ChunkHolder in project chunkstories by Hugobros3.
the class TaskConvertMcChunk method task.
@Override
protected boolean task(TaskExecutor taskExecutor) {
ConverterWorkerThread cwt = (ConverterWorkerThread) taskExecutor;
WorldTool csWorld = cwt.world();
// Is it within our borders ?
// if (chunkStoriesCurrentChunkX >= 0 && chunkStoriesCurrentChunkX < cwt.size().sizeInChunks * 32 && chunkStoriesCurrentChunkZ >= 0 && chunkStoriesCurrentChunkZ < cwt.size().sizeInChunks * 32)
{
// MinecraftChunk minecraftChunk = null;
try {
if (minecraftChunk != null) {
// If it succeed, we first require to load the corresponding chunkstories stuff
// Ignore the summaries for now
/*Heightmap summary = csWorld.getRegionsSummariesHolder().aquireRegionSummaryWorldCoordinates(this, chunkStoriesCurrentChunkX, chunkStoriesCurrentChunkZ);
if(summary != null)
registeredCS_Summaries.add(summary);*/
CompoundFence loadRelevantData = new CompoundFence();
// Then the chunks
for (int y = 0; y < OfflineWorldConverter.mcWorldHeight; y += 32) {
ChunkHolder holder = csWorld.aquireChunkHolderWorldCoordinates(cwt, chunkStoriesCurrentChunkX, y, chunkStoriesCurrentChunkZ);
if (holder != null) {
loadRelevantData.add(holder.waitForLoading());
if (cwt.registeredCS_Holders.add(holder))
cwt.chunksAquired++;
}
}
// Wait for them to actually load
loadRelevantData.traverse();
for (int x = 0; x < 16; x++) for (int z = 0; z < 16; z++) for (int y = 0; y < OfflineWorldConverter.mcWorldHeight; y++) {
// Translate each block
int mcId = minecraftChunk.getBlockID(x, y, z) & 0xFFF;
byte meta = (byte) (minecraftChunk.getBlockMeta(x, y, z) & 0xF);
// Ignore air blocks
if (mcId != 0) {
Mapper mapper = this.mappers.getMapper(mcId, meta);
if (mapper == null)
continue;
if (mapper instanceof NonTrivialMapper) {
((NonTrivialMapper) mapper).output(csWorld, chunkStoriesCurrentChunkX + x, y, chunkStoriesCurrentChunkZ + z, mcId, meta, minecraftRegion, minecraftCurrentChunkXinsideRegion, minecraftCuurrentChunkZinsideRegion, x, y, z);
} else {
FutureCell future = new FutureCell(csWorld, chunkStoriesCurrentChunkX + x, y, chunkStoriesCurrentChunkZ + z, csWorld.getContent().voxels().air());
// Directly set trivial blocks
mapper.output(mcId, meta, future);
if (!future.getVoxel().isAir())
csWorld.pokeSimpleSilently(future);
}
}
}
// Converts external data such as signs
// SpecialBlocksHandler.processAdditionalStuff(minecraftChunk, csWorld, chunkStoriesCurrentChunkX, 0, chunkStoriesCurrentChunkZ);
}
} catch (Exception e) {
cwt.converter().verbose("Issue with chunk " + minecraftCurrentChunkXinsideRegion + " " + minecraftCuurrentChunkZinsideRegion + " of region " + minecraftRegionX + " " + minecraftRegionZ + ".");
e.printStackTrace();
}
}
return true;
}
Aggregations