private List<BlockFamily> processMultiBlockFamily( AssetUri blockDefUri, BlockDefinition blockDef) { List<BlockFamily> result = Lists.newArrayList(); for (String shapeString : blockDef.shapes) { BlockShape shape = (BlockShape) Assets.get(AssetType.SHAPE, shapeString); if (shape != null) { BlockUri familyUri; if (shape.equals(cubeShape)) { familyUri = new BlockUri(blockDefUri.getModuleName(), blockDefUri.getAssetName()); } else { familyUri = new BlockUri( blockDefUri.getModuleName(), blockDefUri.getAssetName(), shape.getURI().getModuleName(), shape.getURI().getAssetName()); } blockDef.shape = shapeString; if (shape.isCollisionYawSymmetric()) { Block block = constructSingleBlock(blockDefUri, blockDef); result.add(new SymmetricFamily(familyUri, block, blockDef.categories)); } else { Map<Side, Block> blockMap = Maps.newEnumMap(Side.class); constructHorizontalBlocks(blockDefUri, blockDef, blockMap); result.add(new HorizontalBlockFamily(familyUri, blockMap, blockDef.categories)); } } } return result; }
public BlockFamily loadWithShape(BlockUri uri) { try (ModuleContext.ContextSpan ignored = ModuleContext.setContext(uri.getModuleName())) { BlockShape shape = cubeShape; if (uri.hasShape()) { AssetUri shapeUri = uri.getShapeUri(); if (!shapeUri.isValid()) { return null; } shape = (BlockShape) Assets.get(shapeUri); if (shape == null) { return null; } } AssetUri blockDefUri = new AssetUri(AssetType.BLOCK_DEFINITION, uri.getModuleName(), uri.getFamilyName()); BlockDefinition def; if (assetManager.getAssetURLs(blockDefUri).isEmpty()) { // An auto-block def = new BlockDefinition(); } else { def = createBlockDefinition( inheritData(blockDefUri, readJson(blockDefUri).getAsJsonObject())); } def.shape = (shape.getURI().toSimpleString()); if (shape.isCollisionYawSymmetric()) { Block block = constructSingleBlock(blockDefUri, def); if (block.getDisplayName().isEmpty()) { block.setDisplayName(shape.getDisplayName()); } else if (!shape.getDisplayName().isEmpty()) { block.setDisplayName(block.getDisplayName() + " " + shape.getDisplayName()); } return new SymmetricFamily(uri, block, def.categories); } else { Map<Side, Block> blockMap = Maps.newEnumMap(Side.class); constructHorizontalBlocks(blockDefUri, def, blockMap); for (Block block : blockMap.values()) { if (block.getDisplayName().isEmpty()) { block.setDisplayName(shape.getDisplayName()); } else if (!shape.getDisplayName().isEmpty()) { block.setDisplayName(block.getDisplayName() + " " + shape.getDisplayName()); } } return new HorizontalBlockFamily(uri, blockMap, def.categories); } } catch (Exception e) { logger.error("Error loading block shape {}", uri, e); } return null; }
@Override public BlockFamily createBlockFamily( BlockFamilyDefinition definition, BlockShape shape, BlockBuilderHelper blockBuilder) { if (shape.isCollisionYawSymmetric()) { return symmetric.createBlockFamily(definition, shape, blockBuilder); } else { return horizontal.createBlockFamily(definition, shape, blockBuilder); } }
private void applyLoweredShape(Block block, BlockShape shape, Map<BlockPart, AssetUri> tileUris) { for (Side side : Side.values()) { BlockPart part = BlockPart.fromSide(side); BlockMeshPart meshPart = shape .getMeshPart(part) .rotate(Rotation.none().getQuat4f()) .mapTexCoords( atlas.getTexCoords(tileUris.get(part), true), atlas.getRelativeTileSize()); block.setLoweredLiquidMesh(part.getSide(), meshPart); } }
private BlockAppearance createAppearance( BlockShape shape, Map<BlockPart, AssetUri> tileUris, 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 = atlas.getTexCoords(tileUris.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, atlas.getRelativeTileSize())); } } return new BlockAppearance(meshParts, textureAtlasPositions); }
@Override public Block constructTransformedBlock( AssetUri blockDefUri, BlockDefinition blockDef, Rotation rotation) { Map<BlockPart, AssetUri> tileUris = prepareTiles(blockDef, blockDefUri); Map<BlockPart, Block.ColorSource> colorSourceMap = prepareColorSources(blockDef); Map<BlockPart, Vector4f> colorOffsetsMap = prepareColorOffsets(blockDef); BlockShape shape = getShape(blockDef); Block block = createRawBlock(blockDef, blockDefUri.getAssetName()); block.setDirection(rotation.rotate(Side.FRONT)); block.setPrimaryAppearance(createAppearance(shape, tileUris, rotation)); setBlockFullSides(block, shape, rotation); block.setCollision(shape.getCollisionOffset(rotation), shape.getCollisionShape(rotation)); for (BlockPart part : BlockPart.values()) { block.setColorSource(part, colorSourceMap.get(part)); block.setColorOffset(part, colorOffsetsMap.get(part)); } return block; }
private Block constructSingleBlock(AssetUri blockDefUri, BlockDefinition blockDef) { Map<BlockPart, AssetUri> tileUris = prepareTiles(blockDef, blockDefUri); Map<BlockPart, Block.ColorSource> colorSourceMap = prepareColorSources(blockDef); Map<BlockPart, Vector4f> colorOffsetsMap = prepareColorOffsets(blockDef); BlockShape shape = getShape(blockDef); Block block = createRawBlock(blockDef, blockDefUri.getAssetName()); block.setPrimaryAppearance(createAppearance(shape, tileUris, Rotation.none())); setBlockFullSides(block, shape, Rotation.none()); block.setCollision( shape.getCollisionOffset(Rotation.none()), shape.getCollisionShape(Rotation.none())); for (BlockPart part : BlockPart.values()) { block.setColorSource(part, colorSourceMap.get(part)); block.setColorOffset(part, colorOffsetsMap.get(part)); } // Lowered mesh for liquids if (block.isLiquid()) { applyLoweredShape(block, loweredShape, tileUris); } return block; }
public LoadBlockDefinitionResults loadBlockDefinitions() { logger.info("Loading Blocks..."); LoadBlockDefinitionResults result = new LoadBlockDefinitionResults(); for (AssetUri blockDefUri : Assets.list(AssetType.BLOCK_DEFINITION)) { try (ModuleContext.ContextSpan ignored = ModuleContext.setContext(blockDefUri.getModuleName())) { JsonElement rawJson = readJson(blockDefUri); if (rawJson != null) { JsonObject blockDefJson = rawJson.getAsJsonObject(); // Don't process templates if (blockDefJson.has("template") && blockDefJson.get("template").getAsBoolean()) { continue; } logger.debug("Loading {}", blockDefUri); BlockDefinition blockDef = createBlockDefinition(inheritData(blockDefUri, blockDefJson)); if (isShapelessBlockFamily(blockDef)) { result.shapelessDefinitions.add( new FreeformFamily( new BlockUri(blockDefUri.getModuleName(), blockDefUri.getAssetName()), blockDef.categories)); } else { if (blockDef.liquid) { blockDef.rotation = null; blockDef.shapes.clear(); blockDef.shape = trimmedLoweredShape.getURI().toSimpleString(); } if (blockDef.shapes.isEmpty()) { BlockFamilyFactory familyFactory = blockFamilyFactoryRegistry.getBlockFamilyFactory(blockDef.rotation); result.families.add( familyFactory.createBlockFamily(this, blockDefUri, blockDef, blockDefJson)); } else { result.families.addAll(processMultiBlockFamily(blockDefUri, blockDef)); } } } } catch (Exception e) { logger.error("Error loading block {}", blockDefUri, e); } } result.shapelessDefinitions.addAll(loadAutoBlocks()); return result; }
private void setBlockFullSides(Block block, BlockShape shape, Rotation rot) { for (Side side : Side.values()) { BlockPart targetPart = BlockPart.fromSide(rot.rotate(side)); block.setFullSide(targetPart.getSide(), shape.isBlockingSide(side)); } }