I'm using an orthographic camera. Due to the direction and position of the cam, I needed a rotation-matrix for the isometric perspective. (As described in my 3rd post)
But the image is drawn at the default y/x, because I don't apply the rotation-matrix on it.
The spritebatch's projection matrix is set to the orthographic camera's combined one.
Source code:
package com.androtest.iso;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputAdapter;
import com.badlogic.gdx.graphics.*;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.SpriteCache;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.math.Intersector;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.math.Plane;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.math.collision.Ray;
public class Init extends ApplicationAdapter {
public static final int SCREEN_WIDTH = 800;
public static final int SCREEN_HEIGHT = 480;
int WORLD_WIDTH = 200;
int WORLD_HEIGHT = 200;
float screenAspectRatio;
Texture terrain;
Texture squareDummy;
Texture tex;
SpriteBatch batch;
public class OrthoCamController extends InputAdapter {
final OrthographicCamera camera;
final Plane xzPlane = new Plane(new Vector3(0, 1, 0), 0);
final Vector3 intersection = new Vector3();
Sprite lastSelectedTile = null;
int zoomLevel = 0;
public OrthoCamController (OrthographicCamera camera) {
this.camera = camera;
}
final Vector3 curr = new Vector3();
final Vector3 last = new Vector3(-1, -1, -1);
final Vector3 delta = new Vector3();
@Override public boolean touchDragged (int x, int y, int pointer) {
Ray pickRay = camOrtho.getPickRay(x, y);
Intersector.intersectRayPlane(pickRay, xzPlane, curr);
if( !(last.x == -1 && last.y == -1 && last.z == -1) ) {
pickRay = camOrtho.getPickRay(last.x, last.y);
Intersector.intersectRayPlane(pickRay, xzPlane, delta);
delta.sub(curr);
camOrtho.position.add(delta.x, delta.y, delta.z);
}
last.set(x, y, 0);
return false;
}
@Override public boolean touchUp(int x, int y, int pointer, int button) {
last.set(-1, -1, -1);
return false;
}
}
OrthographicCamera camOrtho;
OrthoCamController ctrl;
final Sprite[][] sprites = new Sprite[3][3];
final Matrix4 XYtoXZmatrix = new Matrix4();
final Matrix4 imageFaceCameraMatrix = new Matrix4();
ShapeRenderer sr;
static final int LAYERS = 1;
static final int TILES_X = 20;
static final int TILES_Z = 20;
static final int TILE_WIDTH = 30;
static final int TILE_HEIGHT = 30;
static final int TILE_HEIGHT_DIAMOND = 28;
SpriteCache[] caches = new SpriteCache[LAYERS];
int[] layers = new int[LAYERS];
@Override
public void create(){
terrain = new Texture(Gdx.files.internal("tile_grass.png"));
squareDummy = new Texture(Gdx.files.internal("b2.png"));
Pixmap pxm = new Pixmap(2,2, Pixmap.Format.RGBA8888);
pxm.setColor(0f, 0.5f, 1f, 0.2f);
pxm.fill();
tex = new Texture(pxm);
batch = new SpriteBatch();
camOrtho = new OrthographicCamera(WORLD_WIDTH, WORLD_HEIGHT*(Gdx.graphics.getWidth()/Gdx.graphics.getHeight()) );
camOrtho.position.set(WORLD_WIDTH*2, WORLD_HEIGHT, WORLD_WIDTH*2);
camOrtho.direction.set(-1,-1,-1);
camOrtho.near = 1;
camOrtho.far = 10000;
camOrtho.update();
ctrl = new OrthoCamController(camOrtho);
Gdx.input.setInputProcessor(ctrl);
XYtoXZmatrix.setToRotation(new Vector3(1,0,0), 90);
//imageFaceCameraMatrix.setToRotation(new Vector3(0, 1f, 0), 45);
//imageFaceCameraMatrix.setToRotation(new Vector3(1f, 0f, -1f), -45);
//imageFaceCameraMatrix.setToRotation(new Vector3(1f, 0f, 1f), 30);
imageFaceCameraMatrix.setToLookAt(new Vector3(1f,1f,1f), new Vector3(0,1,0));
sr = new ShapeRenderer();
for(int z = 0; z < 3; z++) {
for(int x = 0; x < 3; x++) {
sprites[x][z] = new Sprite(terrain);
sprites[x][z].setPosition(x,z);
sprites[x][z].setSize(TILE_WIDTH, TILE_HEIGHT);
sprites[x][z].flip(false, true);
}
}
for (int i = 0; i < LAYERS; i++) {
caches[i] = new SpriteCache();
SpriteCache cache = caches[i];
cache.beginCache();
int colX = 0;
int colZ = 0;
for (int x = 0; x < TILES_X; x++) {
for (int z = 0; z < TILES_Z; z++) {
int tileX = colX + x*TILE_WIDTH;
int tileZ = colZ + z*TILE_HEIGHT;
cache.add(tex, tileX*1.1f, tileZ*1.1f, 0, 0, TILE_WIDTH, TILE_HEIGHT);
}
}
layers[i] = cache.endCache();
}
}
@Override
public void render() {
Gdx.gl.glClearColor( 0.154f, 0.200f, 0.184f, 1f );
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT );
Gdx.gl.glEnable(GL20.GL_BLEND);
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
camOrtho.update();
for (int i = 0; i < LAYERS; i++) {
SpriteCache cache = caches[i];
cache.setProjectionMatrix(camOrtho.combined);
cache.setTransformMatrix(XYtoXZmatrix);
cache.begin();
cache.draw(layers[i]);
cache.end();
}
batch.setProjectionMatrix(camOrtho.combined);
batch.setTransformMatrix(imageFaceCameraMatrix);
batch.begin();
batch.draw(squareDummy, 0, 0);
batch.end();
sr.setProjectionMatrix(camOrtho.combined);
sr.setTransformMatrix(XYtoXZmatrix);
sr.begin(ShapeRenderer.ShapeType.Line);
sr.setColor(1, 1, 1, 1);
sr.line(0, 0, 500, 0);
sr.line(0, 0, 0, 500);
sr.setTransformMatrix(new Matrix4().setToRotation(new Vector3(1,0,0),0));
//x
sr.setColor(Color.RED);
sr.line(0,0,0, 500,0,0);
//y
sr.setColor(Color.GREEN);
sr.line(0,0,0, 0,500,0);
//z
sr.setColor(Color.BLUE);
sr.line(0,0,0, 0,0,500);
sr.end();
}
@Override
public void resize(int width, int height) {
camOrtho.viewportWidth = width;
camOrtho.viewportHeight = height;
camOrtho.update();
}
@Override
public void dispose() {
terrain.dispose();
building.dispose();
tex.dispose();
batch.dispose();
sr.dispose();
}
}