use of org.joml.Vector3ic in project Terasology by MovingBlocks.
the class BlockMeshGeneratorSingleShape method generateChunkMesh.
@Override
public void generateChunkMesh(ChunkView view, ChunkMesh chunkMesh, int x, int y, int z) {
final BlockAppearance blockAppearance = block.getPrimaryAppearance();
if (!blockAppearance.hasAppearance()) {
// perf: Skip mesh generation for blocks without appearance, e.g., air blocks.
return;
}
Color colorCache = new Color();
// Gather adjacent blocks
Block[] adjacentBlocks = new Block[Side.allSides().size()];
for (Side side : Side.allSides()) {
Vector3ic offset = side.direction();
Block blockToCheck = view.getBlock(x + offset.x(), y + offset.y(), z + offset.z());
adjacentBlocks[side.ordinal()] = blockToCheck;
}
final ChunkMesh.RenderType renderType = getRenderType(block);
final ChunkVertexFlag vertexFlag = getChunkVertexFlag(view, x, y, z, block);
boolean isRendered = false;
for (final Side side : Side.allSides()) {
if (isSideVisibleForBlockTypes(adjacentBlocks[side.ordinal()], block, side)) {
isRendered = true;
BlockMeshPart blockMeshPart = blockAppearance.getPart(BlockPart.fromSide(side));
// If the selfBlock isn't lowered, some more faces may have to be drawn
if (block.isLiquid()) {
final Block topBlock = adjacentBlocks[Side.TOP.ordinal()];
// Draw horizontal sides if visible from below
if (topBlock.isLiquid() && Side.horizontalSides().contains(side)) {
final Vector3ic offset = side.direction();
final Block adjacentAbove = view.getBlock(x + offset.x(), y + 1, z + offset.z());
final Block adjacent = adjacentBlocks[side.ordinal()];
if (adjacent.isLiquid() && !adjacentAbove.isLiquid()) {
blockMeshPart = block.getTopLiquidMesh(side);
}
} else {
if (blockMeshPart != null) {
blockMeshPart = block.getLowLiquidMesh(side);
}
}
}
if (blockMeshPart != null) {
// TODO: Needs review since the new per-vertex flags introduce a lot of special scenarios - probably a per-side setting?
ChunkVertexFlag sideVertexFlag = vertexFlag;
if (block.isGrass() && side != Side.TOP && side != Side.BOTTOM) {
sideVertexFlag = ChunkVertexFlag.COLOR_MASK;
}
Colorc colorOffset = block.getColorOffset(BlockPart.fromSide(side));
Colorc colorSource = block.getColorSource(BlockPart.fromSide(side)).calcColor(view, x, y, z);
colorCache.setRed(colorSource.rf() * colorOffset.rf()).setGreen(colorSource.gf() * colorOffset.gf()).setBlue(colorSource.bf() * colorOffset.bf()).setAlpha(colorSource.af() * colorOffset.af());
blockMeshPart.appendTo(chunkMesh, view, x, y, z, renderType, colorCache, sideVertexFlag);
}
}
}
if (isRendered && blockAppearance.getPart(BlockPart.CENTER) != null) {
Colorc colorOffset = block.getColorOffset(BlockPart.CENTER);
Colorc colorSource = block.getColorSource(BlockPart.CENTER).calcColor(view, x, y, z);
colorCache.setRed(colorSource.rf() * colorOffset.rf()).setGreen(colorSource.gf() * colorOffset.gf()).setBlue(colorSource.bf() * colorOffset.bf()).setAlpha(colorSource.af() * colorOffset.af());
blockAppearance.getPart(BlockPart.CENTER).appendTo(chunkMesh, view, x, y, z, renderType, colorCache, vertexFlag);
}
}
use of org.joml.Vector3ic in project Terasology by MovingBlocks.
the class ChunkRelevanceRegion method reviewRelevantChunks.
private void reviewRelevantChunks(Vector3ic distance) {
Vector3i extents = new Vector3i(distance.x() / 2, distance.y() / 2, distance.z() / 2);
BlockRegion retainRegion = new BlockRegion(center).expand(extents);
Iterator<Vector3ic> iter = relevantChunks.iterator();
while (iter.hasNext()) {
Vector3ic pos = iter.next();
if (!retainRegion.contains(pos)) {
sendChunkIrrelevant(pos);
iter.remove();
}
}
}
use of org.joml.Vector3ic in project Terasology by MovingBlocks.
the class LocalChunkProvider method processReadyChunk.
private void processReadyChunk(final Chunk chunk) {
Vector3ic chunkPos = chunk.getPosition();
if (chunkCache.get(chunkPos) != null) {
// TODO move it in pipeline;
return;
}
chunkCache.put(new Vector3i(chunkPos), chunk);
chunk.markReady();
// TODO, it is not clear if the activate/addedBlocks event logic is correct.
// See https://github.com/MovingBlocks/Terasology/issues/3244
ChunkStore store = this.storageManager.loadChunkStore(chunkPos);
TShortObjectMap<TIntList> mappings = createBatchBlockEventMappings(chunk);
if (store != null) {
store.restoreEntities();
PerformanceMonitor.startActivity("Sending OnAddedBlocks");
mappings.forEachEntry((id, positions) -> {
if (positions.size() > 0) {
blockManager.getBlock(id).getEntity().send(new OnAddedBlocks(positions, registry));
}
return true;
});
PerformanceMonitor.endActivity();
// send on activate
PerformanceMonitor.startActivity("Sending OnActivateBlocks");
mappings.forEachEntry((id, positions) -> {
if (positions.size() > 0) {
blockManager.getBlock(id).getEntity().send(new OnActivatedBlocks(positions, registry));
}
return true;
});
PerformanceMonitor.endActivity();
} else {
PerformanceMonitor.startActivity("Generating queued Entities");
generateQueuedEntities.remove(chunkPos).forEach(this::generateQueuedEntities);
PerformanceMonitor.endActivity();
// send on activate
PerformanceMonitor.startActivity("Sending OnActivateBlocks");
mappings.forEachEntry((id, positions) -> {
if (positions.size() > 0) {
blockManager.getBlock(id).getEntity().send(new OnActivatedBlocks(positions, registry));
}
return true;
});
PerformanceMonitor.endActivity();
worldEntity.send(new OnChunkGenerated(chunkPos));
}
worldEntity.send(new OnChunkLoaded(chunkPos));
}
use of org.joml.Vector3ic in project Terasology by MovingBlocks.
the class LocalChunkProvider method purgeWorld.
@Override
public void purgeWorld() {
ChunkMonitor.fireChunkProviderDisposed(this);
loadingPipeline.shutdown();
unloadRequestTaskMaster.shutdown(new ChunkUnloadRequest(), true);
getAllChunks().stream().filter(Chunk::isReady).forEach(chunk -> {
worldEntity.send(new BeforeChunkUnload(chunk.getPosition(new Vector3i())));
storageManager.deactivateChunk(chunk);
chunk.dispose();
});
chunkCache.clear();
storageManager.deleteWorld();
worldEntity.send(new PurgeWorldEvent());
loadingPipeline = new ChunkProcessingPipeline(this::getChunk, relevanceSystem.createChunkTaskComporator());
loadingPipeline.addStage(ChunkTaskProvider.create("Chunk generate internal lightning", (Consumer<Chunk>) InternalLightProcessor::generateInternalLighting)).addStage(ChunkTaskProvider.create("Chunk deflate", Chunk::deflate)).addStage(ChunkTaskProvider.createMulti("Light merging", chunks -> {
Chunk[] localChunks = chunks.toArray(new Chunk[0]);
return LightMerger.merge(localChunks);
}, LightMerger::requiredChunks)).addStage(ChunkTaskProvider.create("Chunk ready", readyChunks::add));
unloadRequestTaskMaster = TaskMaster.createFIFOTaskMaster("Chunk-Unloader", 8);
ChunkMonitor.fireChunkProviderInitialized(this);
for (ChunkRelevanceRegion chunkRelevanceRegion : relevanceSystem.getRegions()) {
for (Vector3ic pos : chunkRelevanceRegion.getCurrentRegion()) {
createOrLoadChunk(pos);
}
chunkRelevanceRegion.setUpToDate();
}
}
use of org.joml.Vector3ic in project Terasology by MovingBlocks.
the class LocalChunkProvider method checkForUnload.
private void checkForUnload() {
PerformanceMonitor.startActivity("Unloading irrelevant chunks");
int unloaded = 0;
Iterator<Vector3ic> iterator = Iterators.concat(Iterators.transform(chunkCache.keySet().iterator(), v -> new Vector3i(v.x(), v.y(), v.z())), loadingPipeline.getProcessingPosition().iterator());
while (iterator.hasNext()) {
Vector3ic pos = iterator.next();
// TODO: move it to relevance system.
boolean keep = relevanceSystem.isChunkInRegions(pos);
if (!keep && unloadChunkInternal(pos)) {
iterator.remove();
if (++unloaded >= UNLOAD_PER_FRAME) {
break;
}
}
}
if (unloaded > 0) {
logger.debug("Unload {} chunks", unloaded);
}
PerformanceMonitor.endActivity();
}
Aggregations