From f54ecc4e357f550f564d8820ae1764dc679c7928 Mon Sep 17 00:00:00 2001 From: gered Date: Tue, 15 Apr 2014 12:25:21 -0400 Subject: [PATCH] initial pass at moving TileMesh loading code out into a separate loader class --- .../json/tilemesh/TileMeshJsonLoader.java | 218 ++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100644 src/main/java/ca/blarg/gdx/tilemap3d/json/tilemesh/TileMeshJsonLoader.java diff --git a/src/main/java/ca/blarg/gdx/tilemap3d/json/tilemesh/TileMeshJsonLoader.java b/src/main/java/ca/blarg/gdx/tilemap3d/json/tilemesh/TileMeshJsonLoader.java new file mode 100644 index 0000000..2d865b7 --- /dev/null +++ b/src/main/java/ca/blarg/gdx/tilemap3d/json/tilemesh/TileMeshJsonLoader.java @@ -0,0 +1,218 @@ +package ca.blarg.gdx.tilemap3d.json.tilemesh; + +import ca.blarg.gdx.Bitfield; +import ca.blarg.gdx.graphics.atlas.TextureAtlas; +import ca.blarg.gdx.loaders.textureatlas.TextureAtlasJsonLoader; +import ca.blarg.gdx.tilemap3d.tilemesh.*; +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.assets.AssetManager; +import com.badlogic.gdx.assets.loaders.ModelLoader; +import com.badlogic.gdx.files.FileHandle; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.graphics.g3d.Model; +import com.badlogic.gdx.graphics.g3d.loader.G3dModelLoader; +import com.badlogic.gdx.math.Vector3; +import com.badlogic.gdx.utils.Json; +import com.badlogic.gdx.utils.JsonReader; + +public class TileMeshJsonLoader { + public static JsonTileMesh load(FileHandle file) { + Json json = new Json(); + return json.fromJson(JsonTileMesh.class, file); + } + + public static TileMesh create(JsonTileMesh definition) { + return create(definition, null); + } + + public static TileMesh create(JsonTileMesh definition, AssetManager assetManager) { + if (!definition.cube && definition.model == null && definition.models == null) + throw new RuntimeException("One of cube, model or models must be specified for each tile."); + if (definition.materials != null && definition.textureAtlas != null) + throw new RuntimeException("materials and textureAtlas cannot both be set."); + if (definition.model != null && definition.materials == null) + throw new RuntimeException("Missing materials section but using models to define tiles. When using models, a materials section to map model textures to texture atlas regions is required."); + if (definition.collisionModel != null && definition.collisionShape != null) + throw new RuntimeException("collisionModel and collisionShape cannot both be set."); + + ModelLoader loader = null; + if (assetManager == null) + loader = new G3dModelLoader(new JsonReader()); + + MaterialTileMapping materials = null; + TextureAtlas atlas = null; + if (assetManager != null) { + if (definition.materials != null) + materials = assetManager.get(definition.materials, MaterialTileMapping.class); + else if (definition.textureAtlas != null) + atlas = assetManager.get(definition.textureAtlas, TextureAtlas.class); + } else { + if (definition.materials != null) + materials = MaterialTileMappingJsonLoader.loadAndCreate(Gdx.files.internal(definition.materials)); + else if (definition.textureAtlas != null) + atlas = TextureAtlasJsonLoader.loadAndCreate(Gdx.files.internal(definition.textureAtlas)); + } + + boolean isCube = definition.cube; + TextureRegion texture = null; + TextureRegion topTexture = null; + TextureRegion bottomTexture = null; + TextureRegion frontTexture = null; + TextureRegion backTexture = null; + TextureRegion leftTexture = null; + TextureRegion rightTexture = null; + byte faces = 0; + Model model = null; + Model collisionModel; + byte opaqueSides = 0; + byte lightValue; + boolean alpha; + float translucency; + Color color = new Color(Color.WHITE); + Vector3 scaleToSize = null; + Vector3 positionOffset = null; + Vector3 collisionPositionOffset = null; + + if (definition.opaqueSides != null) { + if (definition.opaqueSides.contains("ALL")) + opaqueSides = TileMesh.SIDE_ALL; + else { + if (definition.opaqueSides.contains("TOP")) + opaqueSides = Bitfield.set(TileMesh.SIDE_TOP, opaqueSides); + if (definition.opaqueSides.contains("BOTTOM")) + opaqueSides = Bitfield.set(TileMesh.SIDE_BOTTOM, opaqueSides); + if (definition.opaqueSides.contains("FRONT")) + opaqueSides = Bitfield.set(TileMesh.SIDE_FRONT, opaqueSides); + if (definition.opaqueSides.contains("BACK")) + opaqueSides = Bitfield.set(TileMesh.SIDE_BACK, opaqueSides); + if (definition.opaqueSides.contains("LEFT")) + opaqueSides = Bitfield.set(TileMesh.SIDE_LEFT, opaqueSides); + if (definition.opaqueSides.contains("RIGHT")) + opaqueSides = Bitfield.set(TileMesh.SIDE_RIGHT, opaqueSides); + } + } + + lightValue = (byte)definition.light; + alpha = definition.alpha; + translucency = definition.translucency; + if (definition.color != null) + color.set(definition.color); + if (definition.scaleToSize != null) + scaleToSize = new Vector3(definition.scaleToSize); + if (definition.positionOffset != null) + positionOffset = new Vector3(definition.positionOffset); + if (definition.collisionPositionOffset != null) + collisionPositionOffset = new Vector3(definition.collisionPositionOffset); + + if (isCube) { + if (definition.textures != null) { + if (definition.textures.top >= 0) + topTexture = atlas.get(definition.textures.top); + if (definition.textures.bottom >= 0) + bottomTexture = atlas.get(definition.textures.bottom); + if (definition.textures.front >= 0) + frontTexture = atlas.get(definition.textures.front); + if (definition.textures.back >= 0) + backTexture = atlas.get(definition.textures.back); + if (definition.textures.left >= 0) + leftTexture = atlas.get(definition.textures.left); + if (definition.textures.right >= 0) + rightTexture = atlas.get(definition.textures.right); + } else if (definition.texture >= 0) + texture = atlas.get(definition.texture); + else + throw new RuntimeException("No cube texture specified."); + + if (definition.faces != null) { + if (definition.faces.contains("ALL")) + faces = TileMesh.SIDE_ALL; + else { + if (definition.faces.contains("TOP")) + faces = Bitfield.set(TileMesh.SIDE_TOP, opaqueSides); + if (definition.faces.contains("BOTTOM")) + faces = Bitfield.set(TileMesh.SIDE_BOTTOM, opaqueSides); + if (definition.faces.contains("FRONT")) + faces = Bitfield.set(TileMesh.SIDE_FRONT, opaqueSides); + if (definition.faces.contains("BACK")) + faces = Bitfield.set(TileMesh.SIDE_BACK, opaqueSides); + if (definition.faces.contains("LEFT")) + faces = Bitfield.set(TileMesh.SIDE_LEFT, opaqueSides); + if (definition.faces.contains("RIGHT")) + faces = Bitfield.set(TileMesh.SIDE_RIGHT, opaqueSides); + } + } + + if (texture != null) + return new CubeTileMesh(texture, texture, texture, texture, texture, texture, faces, opaqueSides, lightValue, alpha, translucency, color); + else + return new CubeTileMesh(topTexture, bottomTexture, frontTexture, backTexture, leftTexture, rightTexture, faces, opaqueSides, lightValue, alpha, translucency, color); + + } else if (definition.model != null) { + if (assetManager != null) + model = assetManager.get(definition.model, Model.class); + else + model = loader.loadModel(Gdx.files.internal(definition.model)); + + collisionModel = model; // default is to use the same model + + if (definition.collisionModel != null) { + // override with a specific collision model + if (assetManager != null) + collisionModel = assetManager.get(definition.collisionModel, Model.class); + else + collisionModel = loader.loadModel(Gdx.files.internal(definition.collisionModel)); + + } else if (definition.collisionShape != null) { + collisionModel = CollisionShapes.get(definition.collisionShape); + if (collisionModel == null) + throw new RuntimeException("collisionShape not recognized."); + } + + return new ModelTileMesh(model, collisionModel, materials, opaqueSides, lightValue, alpha, translucency, color, scaleToSize, positionOffset, collisionPositionOffset); + + } else if (definition.models != null) { + int numModels = definition.models.size(); + Model[] submodels = new Model[numModels]; + Color[] colors = new Color[numModels]; + Vector3[] scaleToSizes = new Vector3[numModels]; + Vector3[] positionOffsets = new Vector3[numModels]; + + for (int j = 0; j < numModels; ++j) { + JsonTileMesh.SubModels subModelDef = definition.models.get(j); + + if (assetManager != null) + submodels[j] = assetManager.get(subModelDef.submodel, Model.class); + else + submodels[j] = loader.loadModel(Gdx.files.internal(subModelDef.submodel)); + + if (subModelDef.color == null) + colors[j] = new Color(Color.WHITE); + else + colors[j] = new Color(subModelDef.color); + + scaleToSizes[j] = subModelDef.scaleToSize; + positionOffsets[j] = subModelDef.positionOffset; + } + + collisionModel = null; // TODO: a nice default would be all vertices for all submodels combined + + if (definition.collisionModel != null) { + //override with a specific collision model + if (assetManager != null) + collisionModel = assetManager.get(definition.collisionModel, Model.class); + else + collisionModel = loader.loadModel(Gdx.files.internal(definition.collisionModel)); + } + if (definition.collisionShape != null) { + collisionModel = CollisionShapes.get(definition.collisionShape); + if (collisionModel == null) + throw new RuntimeException("collisionShape not recognized."); + } + + return new MultiModelTileMesh(submodels, colors, scaleToSizes, positionOffsets, collisionModel, materials, opaqueSides, lightValue, alpha, translucency, color, scaleToSize, positionOffset, collisionPositionOffset); + + } else + throw new RuntimeException("Unrecognized tile mesh type."); + } +}