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);
}
}
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()));
}
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);
}
}
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;
}
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;
}
Aggregations