Search in sources :

Example 1 with BlockAppearance

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

the class BlockDamageAuthoritySystem method createBlockParticleEffect.

/**
 * Creates a new entity for the block damage particle effect.
 *
 * If the terrain texture of the damaged block is available, the particles will have the block texture. Otherwise,
 * the default sprite (smoke) is used.
 *
 * @param family the {@link BlockFamily} of the damaged block
 * @param location the location of the damaged block
 */
private void createBlockParticleEffect(BlockFamily family, Vector3f location) {
    EntityBuilder builder = entityManager.newBuilder("core:defaultBlockParticles");
    builder.getComponent(LocationComponent.class).setWorldPosition(location);
    Optional<Texture> terrainTexture = Assets.getTexture("engine:terrain");
    if (terrainTexture.isPresent() && terrainTexture.get().isLoaded()) {
        final BlockAppearance blockAppearance = family.getArchetypeBlock().getPrimaryAppearance();
        final float relativeTileSize = worldAtlas.getRelativeTileSize();
        final float particleScale = 0.25f;
        final float spriteSize = relativeTileSize * particleScale;
        ParticleDataSpriteComponent spriteComponent = builder.getComponent(ParticleDataSpriteComponent.class);
        spriteComponent.texture = terrainTexture.get();
        spriteComponent.textureSize.set(spriteSize, spriteSize);
        final List<Vector2f> offsets = computeOffsets(blockAppearance, particleScale);
        TextureOffsetGeneratorComponent textureOffsetGeneratorComponent = builder.getComponent(TextureOffsetGeneratorComponent.class);
        textureOffsetGeneratorComponent.validOffsets.addAll(offsets);
    }
    builder.build();
}
Also used : ParticleDataSpriteComponent(org.terasology.particles.components.ParticleDataSpriteComponent) TextureOffsetGeneratorComponent(org.terasology.particles.components.generators.TextureOffsetGeneratorComponent) BlockAppearance(org.terasology.world.block.BlockAppearance) Vector2f(org.terasology.math.geom.Vector2f) EntityBuilder(org.terasology.entitySystem.entity.EntityBuilder) LocationComponent(org.terasology.logic.location.LocationComponent) Texture(org.terasology.rendering.assets.texture.Texture)

Example 2 with BlockAppearance

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

the class BlockBuilder method createAppearance.

private BlockAppearance createAppearance(BlockShape shape, Map<BlockPart, BlockTile> tiles, Rotation rot) {
    Map<BlockPart, BlockMeshPart> meshParts = Maps.newEnumMap(BlockPart.class);
    Map<BlockPart, Vector2f> textureAtlasPositions = Maps.newEnumMap(BlockPart.class);
    for (BlockPart part : BlockPart.values()) {
        // TODO: Need to be more sensible with the texture atlas. Because things like block particles read from a part that may not exist, we're being fairly lenient
        Vector2f atlasPos;
        if (tiles.get(part) == null) {
            atlasPos = new Vector2f();
        } else {
            atlasPos = worldAtlas.getTexCoords(tiles.get(part), shape.getMeshPart(part) != null);
        }
        BlockPart targetPart = part.rotate(rot);
        textureAtlasPositions.put(targetPart, atlasPos);
        if (shape.getMeshPart(part) != null) {
            meshParts.put(targetPart, shape.getMeshPart(part).rotate(rot.getQuat4f()).mapTexCoords(atlasPos, worldAtlas.getRelativeTileSize()));
        }
    }
    return new BlockAppearance(meshParts, textureAtlasPositions);
}
Also used : BlockPart(org.terasology.world.block.BlockPart) BlockAppearance(org.terasology.world.block.BlockAppearance) Vector2f(org.terasology.math.geom.Vector2f) BlockMeshPart(org.terasology.world.block.shapes.BlockMeshPart)

Example 3 with BlockAppearance

use of org.terasology.world.block.BlockAppearance 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)

Aggregations

BlockAppearance (org.terasology.world.block.BlockAppearance)3 Vector2f (org.terasology.math.geom.Vector2f)2 EntityBuilder (org.terasology.entitySystem.entity.EntityBuilder)1 LocationComponent (org.terasology.logic.location.LocationComponent)1 Side (org.terasology.math.Side)1 Vector3i (org.terasology.math.geom.Vector3i)1 Vector4f (org.terasology.math.geom.Vector4f)1 ParticleDataSpriteComponent (org.terasology.particles.components.ParticleDataSpriteComponent)1 TextureOffsetGeneratorComponent (org.terasology.particles.components.generators.TextureOffsetGeneratorComponent)1 Texture (org.terasology.rendering.assets.texture.Texture)1 Biome (org.terasology.world.biomes.Biome)1 Block (org.terasology.world.block.Block)1 BlockPart (org.terasology.world.block.BlockPart)1 BlockMeshPart (org.terasology.world.block.shapes.BlockMeshPart)1