package net.kennux.cubicworld.item; import java.util.HashMap; import java.util.Map.Entry; import net.kennux.cubicworld.assets.TextureAtlas; import net.kennux.cubicworld.voxel.VoxelEngine; import net.kennux.cubicworld.voxel.VoxelType; import com.badlogic.gdx.graphics.Mesh; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.VertexAttribute; import com.badlogic.gdx.graphics.VertexAttributes.Usage; import com.badlogic.gdx.graphics.g3d.Model; import com.badlogic.gdx.graphics.g3d.model.data.ModelData; import com.badlogic.gdx.graphics.g3d.model.data.ModelMesh; import com.badlogic.gdx.math.Vector2; /** * <pre> * The main item system class. * The item system handles item registration and instantiation. * * Items are divided into normal "useless" items, which can only get dropped or used for crafting. * There are also "tools" which change the behaviour of the fps rendering, for example it can be an * Weapon or a tool like a pickaxe. * The last type are "food", food is used to regenerate health. * * </pre> * * @author kennux * */ public class ItemSystem { /** * Do this directly after you added all textures. */ public static void compileTextureAtlas() { textureAtlas.compileTexture(); } /** * Creates item types for all voxel types registered in VoxelEngine. * It creates block models for all voxel types. * The block model's 0|0|0 origin is their center. * Their diameter is 0.2 units. * * TODO: Use meshbuilder */ public static void createItemsForVoxelTypes() { // Get all voxel types VoxelType[] voxelTypes = VoxelEngine.getVoxelTypes(); // Construct models for (int i = 0; i < voxelTypes.length; i++) { // Prepare model data ModelData modelData = new ModelData(); ModelMesh modelMesh = new ModelMesh(); // Setup attributes modelMesh.attributes = new VertexAttribute[] { new VertexAttribute(Usage.Position, 4, "a_position"), // new VertexAttribute(Usage.Normal, 4, "a_normal"), new VertexAttribute(Usage.TextureCoordinates, 2, "a_uv"), }; // Setup vertices float[] vertices = new float[] { -0.1f, -0.1f, -0.1f, 0, 0, 0.1f, -0.1f, -0.1f, 0, 0, 0.1f, 0.1f, -0.1f, 0, 0, -0.1f, 0.1f, -0.1f, 0, 0, -0.1f, -0.1f, 0.1f, 0, 0, 0.1f, -0.1f, 0.1f, 0, 0, 0.1f, 0.1f, 0.1f, 0, 0, -0.1f, 0.1f, 0.1f, 0, 0 }; modelMesh.vertices = vertices; Model voxelModel = new Model(modelData); // Set item type information @SuppressWarnings("unused") int itemId = ItemSystem.registerItemType(VoxelEngine.getNameByVoxelId(voxelTypes[i].voxelId)).setItemModel(voxelModel).getItemId(); } } /** * Finalizes the item system's texture atlas. * This will set the texture atlas reference where it is not already set. * Will get called after all items were registered to the system. */ public static void finalizeTextureAtlas() { for (Entry<Integer, ItemType> e : itemTypes.entrySet()) { if (e.getValue().getTextureAtlas() == null) { e.getValue().setTextureAtlas(ItemSystem.textureAtlas.atlasTexture); } } } /** * Returns the item type for the given item id. * * @param itemId * @return */ public static ItemType getItemType(int itemId) { return itemTypes.get(itemId); } /** * Returns the item id for a given item name. * IMPORTANT: Try to avoid this method, as it performs a very expensive search. * Returns -1 if the item was not found. * * @param name * @return */ public static int getItemTypeIdByName(String name) { for (Entry<Integer, String> e : typeDictionary.entrySet()) { if (e.getValue() == name) { return e.getKey().intValue(); } } return -1; } /** * Returns the texture with the given texture id. Returns null if the * texture is not found. * * @param textureId * @return */ public static Texture getTexture(int textureId) { // Search texture by id Integer texId = new Integer(textureId); if (textures.containsKey(texId)) { return textures.get(texId); } return null; } /** * Returns the texture coordinates for the given texture id. * * @param textureId * @return */ public static Vector2[] getUvForTexture(int textureId) { return textureAtlas.getUvForTexture(textureId); } public static ItemType[] getItemTypes() { return itemTypes.values().toArray(new ItemType[itemTypes.size()]); } /** * Initializes all hashmaps if they aren't already. */ public static void initialize(int textureWidth, int textureHeight) { typeDictionary = new HashMap<Integer, String>(); itemTypes = new HashMap<Integer, ItemType>(); textures = new HashMap<Integer, Texture>(); textureDictionary = new HashMap<String, Integer>(); textureAtlas = new TextureAtlas(textureWidth, textureHeight); typeIdCounter = 0; // Init static meshes /* * itemBillboardingMesh = new Mesh(true, 4, 4, new VertexAttribute(Usage.Position, 3, "a_position"), new VertexAttribute(Usage.TextureCoordinates, 1, "a_uv")); * float[] vertices = new float[] * { * 0,0,0,1, * 1,0,0,2, * 1,1,0,3, * 0,1,0,4 * }; * short[] indices = new short[] { 1,2,3,4 }; * itemBillboardingMesh.setVertices(vertices); * itemBillboardingMesh.setIndices(indices); */ } /** * Registers an item type to this item system. * * @return The id of the registered item. */ public static ItemType registerItemType(String name) { if (!typeDictionary.containsValue(name)) { ItemType type = new ItemType().setItemName(name).setItemId(typeIdCounter); typeDictionary.put(typeIdCounter, name); itemTypes.put(typeIdCounter, type); typeIdCounter++; return type; } else { return ItemSystem.getItemType(ItemSystem.getItemTypeIdByName(name)); } } /** * Registers a texture and returns it's texture id. * * @param textureName * @return */ public static int registerTexture(String textureName, Texture texture) { if (!textureDictionary.containsKey(textureName)) { int textureId = textureAtlas.addTexture(texture); textureDictionary.put(textureName, textureId); textures.put(textureId, texture); return textureId; } else { return textureDictionary.get(textureName).intValue(); } } /** * The key in this hashmap maps to the item id as value. * The item id is generated while registering items. */ private static HashMap<Integer, String> typeDictionary; /** * Contains all item types registered to the item system. */ private static HashMap<Integer, ItemType> itemTypes; /** * The type id counter used for getting item ids. */ private static int typeIdCounter = 0; /** * The voxel textures registered in the engine */ private static HashMap<Integer, Texture> textures; /** * The types dictionary maps type names to shorts. */ private static HashMap<String, Integer> textureDictionary; /** * The item billboarding mesh. * Initialized in initalize(). */ public static Mesh itemBillboardingMesh; public static TextureAtlas textureAtlas; }