Search in sources :

Example 36 with Block

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

the class ServerImpl method onChunkReady.

@Override
public void onChunkReady(Vector3ic chunkPos) {
    WorldProvider worldProvider = CoreRegistry.get(WorldProvider.class);
    List<NetData.BlockChangeMessage> updateBlockMessages = awaitingChunkReadyBlockUpdates.removeAll(new Vector3i(chunkPos));
    for (NetData.BlockChangeMessage message : updateBlockMessages) {
        Vector3i pos = NetMessageUtil.convert(message.getPos());
        Block newBlock = blockManager.getBlock((short) message.getNewBlock());
        worldProvider.setBlock(pos, newBlock);
    }
    List<NetData.ExtraDataChangeMessage> updateExtraDataMessages = awaitingChunkReadyExtraDataUpdates.removeAll(new Vector3i(chunkPos));
    for (NetData.ExtraDataChangeMessage message : updateExtraDataMessages) {
        Vector3i pos = NetMessageUtil.convert(message.getPos());
        int newValue = message.getNewData();
        int i = message.getIndex();
        worldProvider.setExtraData(i, pos, newValue);
    }
}
Also used : NetData(org.terasology.protobuf.NetData) WorldProvider(org.terasology.engine.world.WorldProvider) Vector3i(org.joml.Vector3i) Block(org.terasology.engine.world.block.Block)

Example 37 with Block

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

the class VoxelWorldSystem method onNewChunk.

/**
 * new chunks that are loaded need to update pass the data to bullet
 *
 * @param chunkAvailable the chunk
 * @param worldEntity world entity
 */
@ReceiveEvent(components = WorldComponent.class)
public void onNewChunk(OnChunkLoaded chunkAvailable, EntityRef worldEntity) {
    Vector3ic chunkPos = chunkAvailable.getChunkPos();
    Chunk chunk = chunkProvider.getChunk(chunkPos);
    ByteBuffer buffer = ByteBuffer.allocateDirect(2 * (Chunks.SIZE_X * Chunks.SIZE_Y * Chunks.SIZE_Z));
    buffer.order(ByteOrder.nativeOrder());
    for (int z = 0; z < Chunks.SIZE_Z; z++) {
        for (int x = 0; x < Chunks.SIZE_X; x++) {
            for (int y = 0; y < Chunks.SIZE_Y; y++) {
                Block block = chunk.getBlock(x, y, z);
                colliders.forEach(k -> k.registerBlock(block));
                buffer.putShort(block.getId());
            }
        }
    }
    buffer.rewind();
    colliders.forEach(k -> k.loadChunk(chunk, buffer.duplicate().asShortBuffer()));
}
Also used : Vector3ic(org.joml.Vector3ic) OnChangedBlock(org.terasology.engine.world.OnChangedBlock) Block(org.terasology.engine.world.block.Block) Chunk(org.terasology.engine.world.chunks.Chunk) ByteBuffer(java.nio.ByteBuffer) ReceiveEvent(org.terasology.engine.entitySystem.event.ReceiveEvent)

Example 38 with Block

use of org.terasology.engine.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) {
    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);
    }
}
Also used : Side(org.terasology.engine.math.Side) Colorc(org.terasology.nui.Colorc) BlockAppearance(org.terasology.engine.world.block.BlockAppearance) Vector3ic(org.joml.Vector3ic) Color(org.terasology.nui.Color) Block(org.terasology.engine.world.block.Block) BlockMeshPart(org.terasology.engine.world.block.shapes.BlockMeshPart)

Example 39 with Block

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

the class ChunkTessellator method generateMesh.

public ChunkMesh generateMesh(ChunkView chunkView, float scale, int border) {
    PerformanceMonitor.startActivity("GenerateMesh");
    ChunkMeshImpl mesh = new ChunkMeshImpl();
    final Stopwatch watch = Stopwatch.createStarted();
    watch.stop();
    mesh.setTimeToGenerateBlockVertices((int) watch.elapsed(TimeUnit.MILLISECONDS));
    watch.reset().start();
    // gaps between LOD chunks of different scales, but also avoid multiple overlapping ocean surfaces.
    for (int x = 0; x < Chunks.SIZE_X; x++) {
        for (int z = 0; z < Chunks.SIZE_Z; z++) {
            for (int y = 0; y < Chunks.SIZE_Y - border * 2; y++) {
                Block block = chunkView.getBlock(x, y, z);
                block.getMeshGenerator().generateChunkMesh(chunkView, mesh, x, y, z);
            }
        }
    }
    if (border != 0) {
        float totalScale = scale * Chunks.SIZE_X / (Chunks.SIZE_X - 2 * border);
        for (ChunkMesh.RenderType type : ChunkMesh.RenderType.values()) {
            ChunkMesh.VertexElements elements = mesh.getVertexElements(type);
            Vector3f pos = new Vector3f();
            for (int x = 0; x < elements.position.elements(); x++) {
                elements.position.get(x, pos);
                elements.position.set(x, pos.sub(border, 2 * border, border).mul(totalScale));
            }
        }
    }
    watch.stop();
    mesh.setTimeToGenerateOptimizedBuffers((int) watch.elapsed(TimeUnit.MILLISECONDS));
    statVertexArrayUpdateCount++;
    PerformanceMonitor.endActivity();
    return mesh;
}
Also used : Vector3f(org.joml.Vector3f) Stopwatch(com.google.common.base.Stopwatch) Block(org.terasology.engine.world.block.Block)

Example 40 with Block

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

the class BlockMeshShapeGenerator method getStandaloneMesh.

@Override
public Mesh getStandaloneMesh() {
    if (mesh == null || mesh.isDisposed()) {
        Block block = getBlock();
        StandardMeshData meshData = new StandardMeshData();
        int nextIndex = 0;
        Vector3f light0 = new Vector3f(1, 1, 1);
        for (BlockPart dir : BlockPart.allParts()) {
            BlockMeshPart part = block.getPrimaryAppearance().getPart(dir);
            if (part != null) {
                for (int i = 0; i < part.size(); i++) {
                    meshData.position.put(part.getVertex(i));
                    meshData.color0.put(Color.white);
                    meshData.normal.put(part.getNormal(i));
                    meshData.uv0.put(part.getTexCoord(i));
                    meshData.light0.put(light0);
                }
                for (int i = 0; i < part.indicesSize(); ++i) {
                    meshData.indices.put(nextIndex + part.getIndex(i));
                }
                if (block.isDoubleSided()) {
                    for (int i = 0; i < part.indicesSize(); i += 3) {
                        meshData.indices.put(nextIndex + part.getIndex(i + 1));
                        meshData.indices.put(nextIndex + part.getIndex(i));
                        meshData.indices.put(nextIndex + part.getIndex(i + 2));
                    }
                }
                nextIndex += part.size();
            }
        }
        mesh = Assets.generateAsset(new ResourceUrn(getBaseUrn(), block.getURI().toString()), meshData, Mesh.class);
    }
    return mesh;
}
Also used : BlockPart(org.terasology.engine.world.block.BlockPart) StandardMeshData(org.terasology.engine.rendering.assets.mesh.StandardMeshData) Vector3f(org.joml.Vector3f) Block(org.terasology.engine.world.block.Block) Mesh(org.terasology.engine.rendering.assets.mesh.Mesh) ResourceUrn(org.terasology.gestalt.assets.ResourceUrn) BlockMeshPart(org.terasology.engine.world.block.shapes.BlockMeshPart)

Aggregations

Block (org.terasology.engine.world.block.Block)54 Vector3i (org.joml.Vector3i)23 EntityRef (org.terasology.engine.entitySystem.entity.EntityRef)13 Vector3ic (org.joml.Vector3ic)12 Vector3f (org.joml.Vector3f)9 OnChangedBlock (org.terasology.engine.world.OnChangedBlock)9 ReceiveEvent (org.terasology.engine.entitySystem.event.ReceiveEvent)7 Side (org.terasology.engine.math.Side)7 Map (java.util.Map)6 BlockFamily (org.terasology.engine.world.block.family.BlockFamily)6 EntityManager (org.terasology.engine.entitySystem.entity.EntityManager)5 BlockComponent (org.terasology.engine.world.block.BlockComponent)5 Chunk (org.terasology.engine.world.chunks.Chunk)5 BeforeEach (org.junit.jupiter.api.BeforeEach)4 EngineEntityManager (org.terasology.engine.entitySystem.entity.internal.EngineEntityManager)4 Maps (com.google.common.collect.Maps)3 Optional (java.util.Optional)3 ComponentSystemManager (org.terasology.engine.core.ComponentSystemManager)3 LocationComponent (org.terasology.engine.logic.location.LocationComponent)3 BlockEntityRegistry (org.terasology.engine.world.BlockEntityRegistry)3