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; }
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 AssetUri getDefaultTile(BlockDefinition blockDef, AssetUri uri) { String defaultName = uri.toSimpleString(); if (!blockDef.tile.isEmpty()) { defaultName = blockDef.tile; } return new AssetUri(AssetType.BLOCK_TILE, defaultName); }
private List<FreeformFamily> loadAutoBlocks() { logger.debug("Loading Auto Blocks..."); List<FreeformFamily> result = Lists.newArrayList(); for (AssetUri blockTileUri : Assets.list(AssetType.BLOCK_TILE)) { if (assetManager .getAssetURLs(blockTileUri) .get(0) .getPath() .contains(AUTO_BLOCK_URL_FRAGMENT)) { logger.debug("Loading auto block {}", blockTileUri); BlockUri uri = new BlockUri(blockTileUri.getModuleName(), blockTileUri.getAssetName()); result.add(new FreeformFamily(uri)); } } return result; }
@Test public void testColorTransformedToAssetUriTransformedToColor() throws Exception { Color expectedColor = Color.RED; AssetUri assetUri = TextureUtil.getTextureUriForColor(expectedColor); Color actualColor = TextureUtil.getColorForColorName(assetUri.getAssetName().substring("color.".length())); assertEquals(expectedColor, actualColor); int red = 0x12; int green = 0x3; int blue = 0xc4; int alpha = 0xe; expectedColor = new Color(red, green, blue, alpha); assetUri = TextureUtil.getTextureUriForColor(expectedColor); actualColor = TextureUtil.getColorForColorName(assetUri.getAssetName().substring("color.".length())); assertEquals(expectedColor, actualColor); }
@Override public String toString() { AssetUri prefabUri = getPrefabURI(); StringBuilder builder = new StringBuilder(); builder.append("EntityRef{id = "); builder.append(getId()); NetworkComponent networkComponent = getComponent(NetworkComponent.class); if (networkComponent != null) { builder.append(", netId = "); builder.append(networkComponent.getNetworkId()); } if (prefabUri != null) { builder.append(", prefab = '"); builder.append(prefabUri.toSimpleString()); builder.append("'"); } builder.append("}"); return builder.toString(); }
private JsonObject inheritData(AssetUri rootAssetUri, JsonObject blockDefJson) { JsonObject parentObj = blockDefJson; while (parentObj.has("basedOn")) { AssetUri parentUri = Assets.resolveAssetUri( AssetType.BLOCK_DEFINITION, parentObj.get("basedOn").getAsString()); if (rootAssetUri.equals(parentUri)) { logger.error("Circular inheritance detected in {}", rootAssetUri); break; } else if (!parentUri.isValid()) { logger.error( "{} based on invalid uri: {}", rootAssetUri, parentObj.get("basedOn").getAsString()); break; } JsonObject parent = readJson(parentUri).getAsJsonObject(); JsonMergeUtil.mergeOnto(parent, blockDefJson); parentObj = parent; } return blockDefJson; }
@Override public SkeletalMesh load(InputStream stream, AssetUri uri, List<URL> urls) throws IOException { try { MD5 md5 = parse(stream); SkeletalMesh skeleton = new SkeletalMesh(uri); List<Bone> bones = Lists.newArrayListWithCapacity(md5.numJoints); for (int i = 0; i < md5.numJoints; ++i) { MD5Joint joint = md5.joints[i]; Bone bone = new Bone(i, joint.name, joint.position, joint.orientation); bones.add(bone); if (joint.parent != -1) { bones.get(joint.parent).addChild(bone); } skeleton.addBone(bone); } if (md5.meshes.length > 0) { // TODO: Support multiple mesh somehow? MD5Mesh mesh = md5.meshes[0]; List<BoneWeight> boneWeights = Lists.newArrayListWithCapacity(mesh.numWeights); for (MD5Weight weight : mesh.weightList) { boneWeights.add(new BoneWeight(weight.position, weight.bias, weight.jointIndex)); } skeleton.setWeights(boneWeights); List<Vector2f> uvs = Lists.newArrayList(); TIntList vertexStartWeight = new TIntArrayList(mesh.numVertices); TIntList vertexWeightCount = new TIntArrayList(mesh.numVertices); for (MD5Vertex vert : mesh.vertexList) { uvs.add(vert.uv); vertexStartWeight.add(vert.startWeight); vertexWeightCount.add(vert.countWeight); } skeleton.setVertexWeights(vertexStartWeight, vertexWeightCount); skeleton.setUvs(uvs); TIntList indices = new TIntArrayList(mesh.indexList.length); for (int i = 0; i < mesh.numTriangles; ++i) { indices.add(mesh.indexList[i * 3]); indices.add(mesh.indexList[i * 3 + 2]); indices.add(mesh.indexList[i * 3 + 1]); } skeleton.setIndices(indices); skeleton.calculateNormals(); } return skeleton; } catch (NumberFormatException e) { throw new IOException("Error parsing " + uri.toString(), e); } }
@Test public void testColorTransformedToTextureUri() throws Exception { AssetUri assetUri = TextureUtil.getTextureUriForColor(Color.RED); assertEquals(AssetType.TEXTURE, assetUri.getAssetType()); assertEquals("engine", assetUri.getModuleName()); assertEquals("color.ff0000ff", assetUri.getAssetName()); int red = 0x12; int green = 0x3; int blue = 0xc4; int alpha = 0xe; assetUri = TextureUtil.getTextureUriForColor(new Color(red, green, blue, alpha)); assertEquals(AssetType.TEXTURE, assetUri.getAssetType()); assertEquals("engine", assetUri.getModuleName()); assertEquals("color.1203c40e", assetUri.getAssetName()); }
@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; }