Java tutorial
/* * Copyright (C) 2014 Helix Engine Developers (http://github.com/fauu/HelixEngine) * * This software is licensed under the GNU General Public License * (version 3 or later). See the COPYING file in this distribution. * * You should have received a copy of the GNU Library General Public License * along with this software. If not, see <http://www.gnu.org/licenses/>. * * Authored by: Piotr Grabowski <fau999@gmail.com> */ package com.github.fauu.helix.core; import com.badlogic.gdx.graphics.*; import com.badlogic.gdx.graphics.g2d.TextureAtlas; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.graphics.g3d.Model; import com.badlogic.gdx.math.Matrix3; import com.badlogic.gdx.math.Matrix4; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector3; public class MapRegionMesh extends Mesh { public static final int NUM_POSITION_COMPONENTS = 3; public static final int NUM_TEXTURE_COMPONENTS = 2; public static final int NUM_COLOR_COMPONENTS = 1; public static final int NUM_COMPONENTS = 6; private boolean ready = false; private int[] tileOffsets; private GeometrySet geometrySet; private TextureAtlas textureAtlas; private Tile[] tiles; private int numVertices; public MapRegionMesh(Tile[] tiles, GeometrySet geometrySet, TextureAtlas textureAtlas) { super(true, 1024 * tiles.length, 0, new VertexAttribute(VertexAttributes.Usage.Position, NUM_POSITION_COMPONENTS, "a_position"), new VertexAttribute(VertexAttributes.Usage.TextureCoordinates, NUM_TEXTURE_COMPONENTS, "a_texCoord0"), new VertexAttribute(VertexAttributes.Usage.ColorPacked, 4, "a_color")); this.numVertices = 1024 * tiles.length; this.geometrySet = geometrySet; this.textureAtlas = textureAtlas; this.tiles = tiles; this.update(); } public void update() { ready = false; tileOffsets = new int[tiles.length]; final float[] vertices = new float[numVertices]; int vertexCount = 0; for (int i = 0; i < tiles.length; i++) { final Tile tile = tiles[i]; final Model tileGeometryModel = geometrySet.getGeometry(tile.getGeometryId()).getModel(); float[] geometryVertices = new float[(NUM_COMPONENTS - NUM_COLOR_COMPONENTS) * tileGeometryModel.meshes.first().getNumVertices()]; final Texture texture = textureAtlas.getTextures().first(); final TextureRegion tileTextureRegion = textureAtlas.getRegions().get(tile.getTextureId()); final Vector2 tileTextureCoords = new Vector2(tileTextureRegion.getU(), tileTextureRegion.getV2()); final Vector2 tileTextureScaling = new Vector2( (float) tileTextureRegion.getRegionWidth() / texture.getWidth(), (float) tileTextureRegion.getRegionHeight() / texture.getHeight()); float rotationDegrees = 0; switch (tile.getFacing()) { case SOUTH: rotationDegrees = -90; break; case WEST: rotationDegrees = -180; break; case NORTH: rotationDegrees = 90; break; case EAST: rotationDegrees = 0; break; default: } final Matrix3 transformationMatrixUV = new Matrix3().translate(tileTextureCoords) .scale(1 * tileTextureScaling.x, -1 * tileTextureScaling.y).translate(0, -1); final Matrix4 transformationMatrix = new Matrix4().translate( new Vector3(0.5f + tile.getPosition().x, tile.getElevation(), 0.5f + tile.getPosition().y)) .rotate(new Vector3(0, 1, 0), rotationDegrees); // Not sure if copying isn't slower than detransforming the original, but it fixes glitchy // edges final Mesh tileGeometryMesh = tileGeometryModel.meshes.first().copy(true); tileGeometryMesh.transform(transformationMatrix); tileGeometryMesh.transformUV(transformationMatrixUV); tileGeometryMesh.getVertices(geometryVertices); final float[] coloredVertices = new float[NUM_COMPONENTS * tileGeometryModel.meshes.get(0).getNumVertices()]; final Color tileColor = tile.getColor(); for (int j = 0, k = 0; j < coloredVertices.length; j++) { if ((j + 1) % 6 != 0) { coloredVertices[j] = geometryVertices[k++]; } else { coloredVertices[j] = tileColor.toFloatBits(); } } tileOffsets[i] = vertexCount; System.arraycopy(coloredVertices, 0, vertices, vertexCount, coloredVertices.length); vertexCount += coloredVertices.length; } setVertices(vertices, 0, vertexCount); ready = true; } public void updateTileColor(Tile tile) { ready = false; final Model tileGeometryModel = this.geometrySet.getGeometry(tile.getGeometryId()).getModel(); final int numVertices = NUM_COMPONENTS * tileGeometryModel.meshes.first().getNumVertices(); final float[] tileVertices = new float[numVertices]; Color tileColor; if (tile.isHighlighted()) { tileColor = new Color(0.5f, 0.5f, 0.5f, 1); } else { tileColor = tile.getColor(); } getVertices(this.tileOffsets[tile.getNo()], numVertices, tileVertices); for (int i = 0; i < numVertices; i++) { if ((i + 1) % 6 == 0) { tileVertices[i] = tileColor.toFloatBits(); } } updateVertices(this.tileOffsets[tile.getNo()], tileVertices); ready = true; } public boolean isReady() { return ready; } public void setReady(boolean ready) { this.ready = ready; } }