Search in sources :

Example 31 with Block

use of org.terasology.world.block.Block in project Terasology by MovingBlocks.

the class MapWorldProvider method getBlock.

@Override
public Block getBlock(int x, int y, int z) {
    Vector3i pos = new Vector3i(x, y, z);
    Block block = blocks.get(pos);
    if (block != null) {
        return block;
    }
    // TODO block & biome manager
    Vector3i chunkPos = ChunkMath.calcChunkPos(pos);
    Chunk chunk = chunks.get(chunkPos);
    if (chunk == null && worldGenerator != null) {
        chunk = new ChunkImpl(chunkPos, blockManager, biomeManager);
        worldGenerator.createChunk(chunk, entityBuffer);
        chunks.put(chunkPos, chunk);
    }
    if (chunk != null) {
        return chunk.getBlock(ChunkMath.calcBlockPos(pos.x, pos.y, pos.z));
    }
    return null;
}
Also used : ChunkImpl(org.terasology.world.chunks.internal.ChunkImpl) Vector3i(org.terasology.math.geom.Vector3i) Block(org.terasology.world.block.Block) Chunk(org.terasology.world.chunks.Chunk)

Example 32 with Block

use of org.terasology.world.block.Block in project Terasology by MovingBlocks.

the class BlockMeshGeneratorSingleShape method generateChunkMesh.

@Override
public void generateChunkMesh(ChunkView view, ChunkMesh chunkMesh, int x, int y, int z) {
    Biome selfBiome = view.getBiome(x, y, z);
    Block selfBlock = view.getBlock(x, y, z);
    // TODO: Needs review - too much hardcoded special cases and corner cases resulting from this.
    ChunkVertexFlag vertexFlag = ChunkVertexFlag.NORMAL;
    if (selfBlock.isWater()) {
        if (view.getBlock(x, y + 1, z).isWater()) {
            vertexFlag = ChunkVertexFlag.WATER;
        } else {
            vertexFlag = ChunkVertexFlag.WATER_SURFACE;
        }
    } else if (selfBlock.isLava()) {
        vertexFlag = ChunkVertexFlag.LAVA;
    } else if (selfBlock.isWaving() && selfBlock.isDoubleSided()) {
        vertexFlag = ChunkVertexFlag.WAVING;
    } else if (selfBlock.isWaving()) {
        vertexFlag = ChunkVertexFlag.WAVING_BLOCK;
    }
    // Gather adjacent blocks
    Map<Side, Block> adjacentBlocks = Maps.newEnumMap(Side.class);
    for (Side side : Side.values()) {
        Vector3i offset = side.getVector3i();
        Block blockToCheck = view.getBlock(x + offset.x, y + offset.y, z + offset.z);
        adjacentBlocks.put(side, blockToCheck);
    }
    BlockAppearance blockAppearance = selfBlock.getAppearance(adjacentBlocks);
    /*
         * Determine the render process.
         */
    ChunkMesh.RenderType renderType = ChunkMesh.RenderType.TRANSLUCENT;
    if (!selfBlock.isTranslucent()) {
        renderType = ChunkMesh.RenderType.OPAQUE;
    }
    // TODO: Review special case, or alternatively compare uris.
    if (selfBlock.isWater() || selfBlock.isIce()) {
        renderType = ChunkMesh.RenderType.WATER_AND_ICE;
    }
    if (selfBlock.isDoubleSided()) {
        renderType = ChunkMesh.RenderType.BILLBOARD;
    }
    if (blockAppearance.getPart(BlockPart.CENTER) != null) {
        Vector4f colorOffset = selfBlock.calcColorOffsetFor(BlockPart.CENTER, selfBiome);
        blockAppearance.getPart(BlockPart.CENTER).appendTo(chunkMesh, x, y, z, colorOffset, renderType, vertexFlag);
    }
    boolean[] drawDir = new boolean[6];
    for (Side side : Side.values()) {
        drawDir[side.ordinal()] = blockAppearance.getPart(BlockPart.fromSide(side)) != null && isSideVisibleForBlockTypes(adjacentBlocks.get(side), selfBlock, side);
    }
    // If the selfBlock is lowered, some more faces may have to be drawn
    if (selfBlock.isLiquid()) {
        Block bottomBlock = adjacentBlocks.get(Side.BOTTOM);
        // Draw horizontal sides if visible from below
        for (Side side : Side.horizontalSides()) {
            Vector3i offset = side.getVector3i();
            Block adjacentBelow = view.getBlock(x + offset.x, y - 1, z + offset.z);
            Block adjacent = adjacentBlocks.get(side);
            boolean visible = (blockAppearance.getPart(BlockPart.fromSide(side)) != null && isSideVisibleForBlockTypes(adjacentBelow, selfBlock, side) && !isSideVisibleForBlockTypes(bottomBlock, adjacent, side.reverse()));
            drawDir[side.ordinal()] |= visible;
        }
        // Draw the top if below a non-lowered selfBlock
        // TODO: Don't need to render the top if each side and the selfBlock above each side are either liquid or opaque solids.
        Block blockToCheck = adjacentBlocks.get(Side.TOP);
        drawDir[Side.TOP.ordinal()] |= !blockToCheck.isLiquid();
        if (bottomBlock.isLiquid() || bottomBlock.getMeshGenerator() == null) {
            for (Side dir : Side.values()) {
                if (drawDir[dir.ordinal()]) {
                    Vector4f colorOffset = selfBlock.calcColorOffsetFor(BlockPart.fromSide(dir), selfBiome);
                    selfBlock.getLoweredLiquidMesh(dir).appendTo(chunkMesh, x, y, z, colorOffset, renderType, vertexFlag);
                }
            }
            return;
        }
    }
    for (Side dir : Side.values()) {
        if (drawDir[dir.ordinal()]) {
            Vector4f colorOffset = selfBlock.calcColorOffsetFor(BlockPart.fromSide(dir), selfBiome);
            // TODO: Needs review since the new per-vertex flags introduce a lot of special scenarios - probably a per-side setting?
            if (selfBlock.isGrass() && dir != Side.TOP && dir != Side.BOTTOM) {
                blockAppearance.getPart(BlockPart.fromSide(dir)).appendTo(chunkMesh, x, y, z, colorOffset, renderType, ChunkVertexFlag.COLOR_MASK);
            } else {
                if (blockAppearance.getPart(BlockPart.fromSide(dir)) == null) {
                    // TODO: This would catch something like water blocks attempting to render with a "fixed" trimmedLoweredCube shape
                    // That shape has its top trimmed down a bit to let water sit slightly lower than land, however, underwater this shouldn't show
                    // Normally we would configure that shape with CENTER instead of TOP, that way the trimmed part wouldn't occlude in a stack
                    // But with that handling you don't get water blocks occluding tops underwater... and there's no TOP to retrieve below -> NPE
                    logger.debug("Cannot render side '{}' for a block - no stored block appearance for it. renderType {}, vertexFlag {}", dir, renderType, vertexFlag);
                } else {
                    blockAppearance.getPart(BlockPart.fromSide(dir)).appendTo(chunkMesh, x, y, z, colorOffset, renderType, vertexFlag);
                }
            }
        }
    }
}
Also used : Side(org.terasology.math.Side) Biome(org.terasology.world.biomes.Biome) BlockAppearance(org.terasology.world.block.BlockAppearance) Vector4f(org.terasology.math.geom.Vector4f) Vector3i(org.terasology.math.geom.Vector3i) Block(org.terasology.world.block.Block)

Example 33 with Block

use of org.terasology.world.block.Block in project Terasology by MovingBlocks.

the class ChunkTessellator method generateMesh.

public ChunkMesh generateMesh(ChunkView chunkView, int meshHeight, int verticalOffset) {
    PerformanceMonitor.startActivity("GenerateMesh");
    ChunkMesh mesh = new ChunkMesh(bufferPool);
    final Stopwatch watch = Stopwatch.createStarted();
    for (int x = 0; x < ChunkConstants.SIZE_X; x++) {
        for (int z = 0; z < ChunkConstants.SIZE_Z; z++) {
            for (int y = verticalOffset; y < verticalOffset + meshHeight; y++) {
                Block block = chunkView.getBlock(x, y, z);
                if (block != null && block.getMeshGenerator() != null) {
                    block.getMeshGenerator().generateChunkMesh(chunkView, mesh, x, y, z);
                }
            }
        }
    }
    watch.stop();
    mesh.setTimeToGenerateBlockVertices((int) watch.elapsed(TimeUnit.MILLISECONDS));
    watch.reset().start();
    generateOptimizedBuffers(chunkView, mesh);
    watch.stop();
    mesh.setTimeToGenerateOptimizedBuffers((int) watch.elapsed(TimeUnit.MILLISECONDS));
    statVertexArrayUpdateCount++;
    PerformanceMonitor.endActivity();
    return mesh;
}
Also used : Stopwatch(com.google.common.base.Stopwatch) Block(org.terasology.world.block.Block)

Example 34 with Block

use of org.terasology.world.block.Block in project Terasology by MovingBlocks.

the class BlockEntitySystem method defaultDropsHandling.

@ReceiveEvent(priority = EventPriority.PRIORITY_TRIVIAL)
public void defaultDropsHandling(CreateBlockDropsEvent event, EntityRef entity, ActAsBlockComponent blockComponent) {
    if (blockComponent.block != null) {
        if (entity.hasComponent(BlockRegionComponent.class)) {
            BlockRegionComponent blockRegion = entity.getComponent(BlockRegionComponent.class);
            if (blockComponent.dropBlocksInRegion) {
                // loop through all the blocks in this region and drop them
                for (Vector3i location : blockRegion.region) {
                    Block blockInWorld = worldProvider.getBlock(location);
                    commonDefaultDropsHandling(event, entity, location, blockInWorld.getBlockFamily().getArchetypeBlock());
                }
            } else {
                // just drop the ActAsBlock block
                Vector3i location = new Vector3i(blockRegion.region.center(), RoundingMode.HALF_UP);
                commonDefaultDropsHandling(event, entity, location, blockComponent.block.getArchetypeBlock());
            }
        } else if (entity.hasComponent(LocationComponent.class)) {
            LocationComponent locationComponent = entity.getComponent(LocationComponent.class);
            Vector3i location = new Vector3i(locationComponent.getWorldPosition(), RoundingMode.HALF_UP);
            commonDefaultDropsHandling(event, entity, location, blockComponent.block.getArchetypeBlock());
        }
    }
}
Also used : BlockRegionComponent(org.terasology.world.block.regions.BlockRegionComponent) Vector3i(org.terasology.math.geom.Vector3i) Block(org.terasology.world.block.Block) LocationComponent(org.terasology.logic.location.LocationComponent) ReceiveEvent(org.terasology.entitySystem.event.ReceiveEvent)

Example 35 with Block

use of org.terasology.world.block.Block in project Terasology by MovingBlocks.

the class NeighbourBlockFamilyUpdateSystem method processUpdateForBlockLocation.

private void processUpdateForBlockLocation(Vector3i blockLocation) {
    for (Side side : Side.values()) {
        Vector3i neighborLocation = new Vector3i(blockLocation);
        neighborLocation.add(side.getVector3i());
        if (worldProvider.isBlockRelevant(neighborLocation)) {
            Block neighborBlock = worldProvider.getBlock(neighborLocation);
            final BlockFamily blockFamily = neighborBlock.getBlockFamily();
            if (blockFamily instanceof UpdatesWithNeighboursFamily) {
                UpdatesWithNeighboursFamily neighboursFamily = (UpdatesWithNeighboursFamily) blockFamily;
                Block neighborBlockAfterUpdate = neighboursFamily.getBlockForNeighborUpdate(worldProvider, blockEntityRegistry, neighborLocation, neighborBlock);
                if (neighborBlock != neighborBlockAfterUpdate) {
                    worldProvider.setBlock(neighborLocation, neighborBlockAfterUpdate);
                }
            }
        }
    }
}
Also used : Side(org.terasology.math.Side) UpdatesWithNeighboursFamily(org.terasology.world.block.family.UpdatesWithNeighboursFamily) Vector3i(org.terasology.math.geom.Vector3i) Block(org.terasology.world.block.Block) OnChangedBlock(org.terasology.world.OnChangedBlock) BlockFamily(org.terasology.world.block.family.BlockFamily)

Aggregations

Block (org.terasology.world.block.Block)67 Vector3i (org.terasology.math.geom.Vector3i)32 EntityRef (org.terasology.entitySystem.entity.EntityRef)16 ReceiveEvent (org.terasology.entitySystem.event.ReceiveEvent)11 Side (org.terasology.math.Side)11 Vector3f (org.terasology.math.geom.Vector3f)9 LocationComponent (org.terasology.logic.location.LocationComponent)7 BlockUri (org.terasology.world.block.BlockUri)7 BlockFamily (org.terasology.world.block.family.BlockFamily)7 PlaySoundEvent (org.terasology.audio.events.PlaySoundEvent)6 OnChangedBlock (org.terasology.world.OnChangedBlock)6 BlockComponent (org.terasology.world.block.BlockComponent)5 BlockManager (org.terasology.world.block.BlockManager)5 BlockRegionComponent (org.terasology.world.block.regions.BlockRegionComponent)5 HashMap (java.util.HashMap)4 Map (java.util.Map)4 Before (org.junit.Before)3 ResourceUrn (org.terasology.assets.ResourceUrn)3 EntityBuilder (org.terasology.entitySystem.entity.EntityBuilder)3 DoDamageEvent (org.terasology.logic.health.DoDamageEvent)3