merge JobTile into MapTile

This commit is contained in:
Hannes Janetzek 2013-04-22 11:35:05 +02:00
parent 55fc510d51
commit fbb4d1d2ae
17 changed files with 117 additions and 138 deletions

View File

@ -15,7 +15,7 @@
*/ */
package org.oscim.database; package org.oscim.database;
import org.oscim.layers.tile.JobTile; import org.oscim.layers.tile.MapTile;
/** /**
* *
@ -32,7 +32,7 @@ public interface IMapDatabase {
* the callback which handles the extracted map elements. * the callback which handles the extracted map elements.
* @return true if successful * @return true if successful
*/ */
public abstract QueryResult executeQuery(JobTile tile, public abstract QueryResult executeQuery(MapTile tile,
IMapDatabaseCallback mapDatabaseCallback); IMapDatabaseCallback mapDatabaseCallback);
/** /**

View File

@ -27,7 +27,7 @@ import org.oscim.database.MapOptions;
import org.oscim.database.mapfile.header.MapFileHeader; import org.oscim.database.mapfile.header.MapFileHeader;
import org.oscim.database.mapfile.header.MapFileInfo; import org.oscim.database.mapfile.header.MapFileInfo;
import org.oscim.database.mapfile.header.SubFileParameter; import org.oscim.database.mapfile.header.SubFileParameter;
import org.oscim.layers.tile.JobTile; import org.oscim.layers.tile.MapTile;
import android.util.Log; import android.util.Log;
@ -209,7 +209,7 @@ public class MapDatabase implements IMapDatabase {
* org.oscim.map.reader.MapDatabaseCallback) * org.oscim.map.reader.MapDatabaseCallback)
*/ */
@Override @Override
public QueryResult executeQuery(JobTile tile, IMapDatabaseCallback mapDatabaseCallback) { public QueryResult executeQuery(MapTile tile, IMapDatabaseCallback mapDatabaseCallback) {
if (sMapFileHeader == null) if (sMapFileHeader == null)
return QueryResult.FAILED; return QueryResult.FAILED;

View File

@ -30,7 +30,7 @@ import org.oscim.database.IMapDatabase;
import org.oscim.database.IMapDatabaseCallback; import org.oscim.database.IMapDatabaseCallback;
import org.oscim.database.MapInfo; import org.oscim.database.MapInfo;
import org.oscim.database.MapOptions; import org.oscim.database.MapOptions;
import org.oscim.layers.tile.JobTile; import org.oscim.layers.tile.MapTile;
import android.os.Environment; import android.os.Environment;
import android.os.SystemClock; import android.os.SystemClock;
@ -65,7 +65,7 @@ public class MapDatabase implements IMapDatabase {
private IMapDatabaseCallback mMapGenerator; private IMapDatabaseCallback mMapGenerator;
private float mScaleFactor; private float mScaleFactor;
private JobTile mTile; private MapTile mTile;
private long mContentLenth; private long mContentLenth;
@ -76,7 +76,7 @@ public class MapDatabase implements IMapDatabase {
private final MapElement mElem = new MapElement(); private final MapElement mElem = new MapElement();
@Override @Override
public QueryResult executeQuery(JobTile tile, IMapDatabaseCallback mapDatabaseCallback) { public QueryResult executeQuery(MapTile tile, IMapDatabaseCallback mapDatabaseCallback) {
QueryResult result = QueryResult.SUCCESS; QueryResult result = QueryResult.SUCCESS;
mTile = tile; mTile = tile;

View File

@ -43,7 +43,7 @@ import org.oscim.database.IMapDatabase;
import org.oscim.database.IMapDatabaseCallback; import org.oscim.database.IMapDatabaseCallback;
import org.oscim.database.MapInfo; import org.oscim.database.MapInfo;
import org.oscim.database.MapOptions; import org.oscim.database.MapOptions;
import org.oscim.layers.tile.JobTile; import org.oscim.layers.tile.MapTile;
import android.os.Environment; import android.os.Environment;
import android.os.SystemClock; import android.os.SystemClock;
@ -90,7 +90,7 @@ public class MapDatabase implements IMapDatabase {
private IMapDatabaseCallback mMapGenerator; private IMapDatabaseCallback mMapGenerator;
private float mScaleFactor; private float mScaleFactor;
private JobTile mTile; private MapTile mTile;
private FileOutputStream mCacheFile; private FileOutputStream mCacheFile;
private String mHost; private String mHost;
@ -117,7 +117,7 @@ public class MapDatabase implements IMapDatabase {
}); });
@Override @Override
public QueryResult executeQuery(JobTile tile, IMapDatabaseCallback mapDatabaseCallback) { public QueryResult executeQuery(MapTile tile, IMapDatabaseCallback mapDatabaseCallback) {
QueryResult result = QueryResult.SUCCESS; QueryResult result = QueryResult.SUCCESS;
mCacheFile = null; mCacheFile = null;

View File

@ -26,7 +26,7 @@ import org.oscim.database.IMapDatabase;
import org.oscim.database.IMapDatabaseCallback; import org.oscim.database.IMapDatabaseCallback;
import org.oscim.database.MapInfo; import org.oscim.database.MapInfo;
import org.oscim.database.MapOptions; import org.oscim.database.MapOptions;
import org.oscim.layers.tile.JobTile; import org.oscim.layers.tile.MapTile;
/** /**
* *
@ -68,7 +68,7 @@ public class MapDatabase implements IMapDatabase {
private final boolean renderPlace = false; private final boolean renderPlace = false;
@Override @Override
public QueryResult executeQuery(JobTile tile, public QueryResult executeQuery(MapTile tile,
IMapDatabaseCallback mapDatabaseCallback) { IMapDatabaseCallback mapDatabaseCallback) {
int size = Tile.SIZE; int size = Tile.SIZE;

View File

@ -15,8 +15,8 @@
*/ */
package org.oscim.layers.tile; package org.oscim.layers.tile;
import static org.oscim.layers.tile.JobTile.STATE_LOADING; import static org.oscim.layers.tile.MapTile.STATE_LOADING;
import static org.oscim.layers.tile.JobTile.STATE_NONE; import static org.oscim.layers.tile.MapTile.STATE_NONE;
/** /**
* A JobQueue keeps the list of pending jobs for a MapView and prioritizes them. * A JobQueue keeps the list of pending jobs for a MapView and prioritizes them.
@ -24,14 +24,14 @@ import static org.oscim.layers.tile.JobTile.STATE_NONE;
public class JobQueue { public class JobQueue {
private int mCurrentJob = 0; private int mCurrentJob = 0;
private JobTile[] mJobs; private MapTile[] mJobs;
/** /**
* @param tiles * @param tiles
* the jobs to be added to this queue. * the jobs to be added to this queue.
*/ */
public synchronized void setJobs(JobTile[] tiles) { public synchronized void setJobs(MapTile[] tiles) {
for (JobTile t : tiles) for (MapTile t : tiles)
t.state = STATE_LOADING; t.state = STATE_LOADING;
mJobs = tiles; mJobs = tiles;
@ -46,7 +46,7 @@ public class JobQueue {
mCurrentJob = 0; mCurrentJob = 0;
return; return;
} }
JobTile[] tiles = mJobs; MapTile[] tiles = mJobs;
for (int i = mCurrentJob, n = mJobs.length; i < n; i++) { for (int i = mCurrentJob, n = mJobs.length; i < n; i++) {
tiles[i].state = STATE_NONE; tiles[i].state = STATE_NONE;
@ -66,7 +66,7 @@ public class JobQueue {
/** /**
* @return the most important job from this queue or null, if empty. * @return the most important job from this queue or null, if empty.
*/ */
public synchronized JobTile poll() { public synchronized MapTile poll() {
if (mJobs == null) if (mJobs == null)
return null; return null;
@ -76,7 +76,7 @@ public class JobQueue {
TileDistanceSort.sort(mJobs, 0, len); TileDistanceSort.sort(mJobs, 0, len);
} }
JobTile t = mJobs[mCurrentJob]; MapTile t = mJobs[mCurrentJob];
mJobs[mCurrentJob] = null; mJobs[mCurrentJob] = null;
if (++mCurrentJob == mJobs.length) if (++mCurrentJob == mJobs.length)

View File

@ -1,65 +0,0 @@
/*
* Copyright 2012, 2013 Hannes Janetzek
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.oscim.layers.tile;
import org.oscim.core.Tile;
import android.util.Log;
public class JobTile extends Tile {
private final static String TAG = JobTile.class.getName();
public final static int STATE_NONE = 0;
public final static int STATE_LOADING = 1 << 0;
public final static int STATE_NEW_DATA = 1 << 1;
public final static int STATE_READY = 1 << 2;
public final static int STATE_ERROR = 1 << 3;
public void clearState() {
state = STATE_NONE;
}
/**
* @return true if tile is loading, has new data or is ready for rendering
* */
public boolean isActive() {
return state > STATE_NONE && state < STATE_ERROR;
}
public void setLoading() {
if (state != STATE_NONE)
Log.d(TAG, "wrong state: " + state);
state = STATE_LOADING;
}
public byte state;
/**
* distance from map center
*/
public float distance;
/**
* @param tileX
* ...
* @param tileY
* ...
* @param zoomLevel
* ..
*/
public JobTile(int tileX, int tileY, byte zoomLevel) {
super(tileX, tileY, zoomLevel);
}
}

View File

@ -14,19 +14,57 @@
*/ */
package org.oscim.layers.tile; package org.oscim.layers.tile;
import org.oscim.core.Tile;
import org.oscim.renderer.layer.Layers; import org.oscim.renderer.layer.Layers;
import org.oscim.renderer.layer.TextItem; import org.oscim.renderer.layer.TextItem;
import org.oscim.utils.quadtree.QuadTree; import org.oscim.utils.quadtree.QuadTree;
/** /**
* Extends Tile class for concurrent use in TileManager, * Extends Tile class to hold state and data for concurrent use in
* TileGenerator and GLRenderer threads. * TileManager (Main Thread), TileGenerator (MapWorker Thread) and
* Rendering (GL Thread).
*/ */
public final class MapTile extends JobTile { public final class MapTile extends Tile {
public final static int STATE_NONE = 0;
/**
* STATE_LOADING means the tile is about to be loaded / loading.
* it belongs to MapWorker/TileGenerator thread.
*/
public final static int STATE_LOADING = 1 << 0;
/**
* STATE_NEW_DATA: tile data is prepared for rendering. While
* 'locked' it belongs to GL Thread.
*/
public final static int STATE_NEW_DATA = 1 << 1;
/**
* STATE_READY: tile data is uploaded to GL.While
* 'locked' it belongs to GL Thread.
*/
public final static int STATE_READY = 1 << 2;
/**
* TBD
*/
public final static int STATE_ERROR = 1 << 3;
/**
* absolute tile coordinates: tileX,Y / Math.pow(2, zoomLevel)
*/
public double x; public double x;
public double y; public double y;
/** STATE_* */
public byte state;
/**
* distance from map center
*/
public float distance;
/** /**
* Tile data set by TileGenerator. * Tile data set by TileGenerator.
*/ */
@ -43,9 +81,10 @@ public final class MapTile extends JobTile {
*/ */
public QuadTree<MapTile> rel; public QuadTree<MapTile> rel;
/** to avoid drawing a tile twice per frame
* FIXME what if multiple layers use the same tile? */
int lastDraw = 0; int lastDraw = 0;
// keep track which tiles are locked as proxy for this tile
public final static int PROXY_CHILD1 = 1 << 0; public final static int PROXY_CHILD1 = 1 << 0;
public final static int PROXY_CHILD2 = 1 << 1; public final static int PROXY_CHILD2 = 1 << 1;
public final static int PROXY_CHILD3 = 1 << 2; public final static int PROXY_CHILD3 = 1 << 2;
@ -54,20 +93,13 @@ public final class MapTile extends JobTile {
public final static int PROXY_GRAMPA = 1 << 5; public final static int PROXY_GRAMPA = 1 << 5;
public final static int PROXY_HOLDER = 1 << 6; public final static int PROXY_HOLDER = 1 << 6;
/** keep track which tiles are locked as proxy for this tile */
public byte proxies; public byte proxies;
// check which labels were joined /** counting the tiles that use this tile as proxy */
// public final static int JOIN_T = 1 << 0;
// public final static int JOIN_B = 1 << 1;
// public final static int JOIN_L = 1 << 2;
// public final static int JOIN_R = 1 << 3;
// public final static int JOINED = 15;
// public byte joined;
// counting the tiles that use this tile as proxy
byte refs; byte refs;
// up to 255 Threads may lock a tile /** up to 255 Threads may lock a tile */
byte locked; byte locked;
// only used GLRenderer when this tile sits in for another tile. // only used GLRenderer when this tile sits in for another tile.
@ -81,7 +113,7 @@ public final class MapTile extends JobTile {
} }
/** /**
* @return true if tile could be referenced by another thread * @return true when tile might be referenced by another thread.
*/ */
boolean isLocked() { boolean isLocked() {
return locked > 0 || refs > 0; return locked > 0 || refs > 0;
@ -134,4 +166,23 @@ public final class MapTile extends JobTile {
t.next = labels; t.next = labels;
labels = t; labels = t;
} }
public void clearState() {
state = STATE_NONE;
}
/**
* @return true if tile is loading, has new data or is ready for rendering
*/
public boolean isActive() {
return state > STATE_NONE && state < STATE_ERROR;
}
public void setLoading() {
//if (state != STATE_NONE)
//Log.d(TAG, "wrong state: " + state);
state = STATE_LOADING;
}
} }

View File

@ -58,7 +58,7 @@ public class MapWorker extends PausableThread {
@Override @Override
protected void doWork() { protected void doWork() {
JobTile tile = mJobQueue.poll(); MapTile tile = mJobQueue.poll();
if (tile == null) if (tile == null)
return; return;

View File

@ -21,7 +21,7 @@ package org.oscim.layers.tile;
*/ */
public class TileDistanceSort { public class TileDistanceSort {
public static void sort(JobTile[] a, int lo, int hi) { public static void sort(MapTile[] a, int lo, int hi) {
int nRemaining = hi - lo; int nRemaining = hi - lo;
if (nRemaining < 2) { if (nRemaining < 2) {
return; return;
@ -32,7 +32,7 @@ public class TileDistanceSort {
} }
static int compareTo(JobTile a, JobTile b) { static int compareTo(MapTile a, MapTile b) {
if (a == null) { if (a == null) {
if (b == null) if (b == null)
return 0; return 0;
@ -51,14 +51,14 @@ public class TileDistanceSort {
return 0; return 0;
} }
private static void binarySort(JobTile[] a, int lo, int hi, int start) private static void binarySort(MapTile[] a, int lo, int hi, int start)
{ {
assert ((lo <= start) && (start <= hi)); assert ((lo <= start) && (start <= hi));
if (start == lo) if (start == lo)
++start; ++start;
for (; start < hi; ++start) for (; start < hi; ++start)
{ {
JobTile pivot = a[start]; MapTile pivot = a[start];
int left = lo; int left = lo;
int right = start; int right = start;
@ -98,7 +98,7 @@ public class TileDistanceSort {
} }
} }
private static int countRunAndMakeAscending(JobTile[] a, int lo, int hi) private static int countRunAndMakeAscending(MapTile[] a, int lo, int hi)
{ {
assert (lo < hi); assert (lo < hi);
int runHi = lo + 1; int runHi = lo + 1;
@ -118,11 +118,11 @@ public class TileDistanceSort {
return (runHi - lo); return (runHi - lo);
} }
private static void reverseRange(JobTile[] a, int lo, int hi) private static void reverseRange(MapTile[] a, int lo, int hi)
{ {
--hi; --hi;
while (lo < hi) { while (lo < hi) {
JobTile t = a[lo]; MapTile t = a[lo];
a[(lo++)] = a[hi]; a[(lo++)] = a[hi];
a[(hi--)] = t; a[(hi--)] = t;
} }

View File

@ -17,7 +17,7 @@ package org.oscim.layers.tile;
import static org.oscim.core.MapElement.GEOM_LINE; import static org.oscim.core.MapElement.GEOM_LINE;
import static org.oscim.core.MapElement.GEOM_POINT; import static org.oscim.core.MapElement.GEOM_POINT;
import static org.oscim.core.MapElement.GEOM_POLY; import static org.oscim.core.MapElement.GEOM_POLY;
import static org.oscim.layers.tile.JobTile.STATE_NONE; import static org.oscim.layers.tile.MapTile.STATE_NONE;
import java.util.Arrays; import java.util.Arrays;
@ -140,12 +140,12 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
public void cleanup() { public void cleanup() {
} }
public boolean executeJob(JobTile jobTile) { public boolean executeJob(MapTile MapTile) {
if (mMapDatabase == null) if (mMapDatabase == null)
return false; return false;
mTile = (MapTile) jobTile; mTile = (MapTile) MapTile;
if (mTile.layers != null) { if (mTile.layers != null) {
// should be fixed now. // should be fixed now.

View File

@ -297,7 +297,7 @@ public class TileLayer extends Layer {
* @param jobs * @param jobs
* tile jobs * tile jobs
*/ */
public void addJobs(JobTile[] jobs) { public void addJobs(MapTile[] jobs) {
if (jobs == null) { if (jobs == null) {
mJobQueue.clear(); mJobQueue.clear();
return; return;

View File

@ -15,9 +15,9 @@
package org.oscim.layers.tile; package org.oscim.layers.tile;
import static org.oscim.layers.tile.JobTile.STATE_LOADING; import static org.oscim.layers.tile.MapTile.STATE_LOADING;
import static org.oscim.layers.tile.JobTile.STATE_NEW_DATA; import static org.oscim.layers.tile.MapTile.STATE_NEW_DATA;
import static org.oscim.layers.tile.JobTile.STATE_NONE; import static org.oscim.layers.tile.MapTile.STATE_NONE;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -73,7 +73,7 @@ public class TileManager {
private volatile int mTilesForUpload; private volatile int mTilesForUpload;
// new tile jobs for MapWorkers // new tile jobs for MapWorkers
private final ArrayList<JobTile> mJobs; private final ArrayList<MapTile> mJobs;
// counter to check whether current TileSet has changed // counter to check whether current TileSet has changed
private int mUpdateSerial; private int mUpdateSerial;
@ -121,7 +121,7 @@ public class TileManager {
mTileLayer = tileLayer; mTileLayer = tileLayer;
mMapViewPosition = mapView.getMapViewPosition(); mMapViewPosition = mapView.getMapViewPosition();
mJobs = new ArrayList<JobTile>(); mJobs = new ArrayList<MapTile>();
mTiles = new MapTile[CACHE_TILES_MAX]; mTiles = new MapTile[CACHE_TILES_MAX];
mTilesSize = 0; mTilesSize = 0;
@ -255,7 +255,7 @@ public class TileManager {
if (mJobs.isEmpty()) if (mJobs.isEmpty())
return; return;
JobTile[] jobs = new JobTile[mJobs.size()]; MapTile[] jobs = new MapTile[mJobs.size()];
jobs = mJobs.toArray(jobs); jobs = mJobs.toArray(jobs);
updateTileDistances(jobs, jobs.length, pos); updateTileDistances(jobs, jobs.length, pos);
@ -562,12 +562,11 @@ public class TileManager {
/** /**
* called from MapWorker Thread when tile is loaded by TileGenerator * called from MapWorker Thread when tile is loaded by TileGenerator
* *
* @param jobTile * @param tile
* Tile ready for upload to GL * Tile ready for upload to GL
* @return ... caller does not care * @return ... caller does not care
*/ */
public synchronized boolean passTile(JobTile jobTile) { public synchronized boolean passTile(MapTile tile) {
MapTile tile = (MapTile) jobTile;
if (tile.state != STATE_LOADING) { if (tile.state != STATE_LOADING) {
// - should rather be STATE_FAILED // - should rather be STATE_FAILED
@ -577,12 +576,6 @@ public class TileManager {
return true; return true;
} }
//if (tile.vbo != null) {
// // BAD Things(tm) happend: tile is already loaded
// Log.d(TAG, "BUG: tile loaded before " + tile);
// return true;
//}
tile.state = STATE_NEW_DATA; tile.state = STATE_NEW_DATA;
mTilesForUpload++; mTilesForUpload++;

View File

@ -14,8 +14,8 @@
*/ */
package org.oscim.layers.tile; package org.oscim.layers.tile;
import static org.oscim.layers.tile.JobTile.STATE_NEW_DATA; import static org.oscim.layers.tile.MapTile.STATE_NEW_DATA;
import static org.oscim.layers.tile.JobTile.STATE_READY; import static org.oscim.layers.tile.MapTile.STATE_READY;
import org.oscim.core.MapPosition; import org.oscim.core.MapPosition;
import org.oscim.renderer.BufferObject; import org.oscim.renderer.BufferObject;

View File

@ -16,7 +16,7 @@ package org.oscim.layers.tile;
import static android.opengl.GLES20.GL_ARRAY_BUFFER; import static android.opengl.GLES20.GL_ARRAY_BUFFER;
import static android.opengl.GLES20.glStencilMask; import static android.opengl.GLES20.glStencilMask;
import static org.oscim.layers.tile.JobTile.STATE_READY; import static org.oscim.layers.tile.MapTile.STATE_READY;
import org.oscim.core.MapPosition; import org.oscim.core.MapPosition;
import org.oscim.core.Tile; import org.oscim.core.Tile;

View File

@ -20,7 +20,7 @@ import java.nio.ShortBuffer;
import org.oscim.core.MapPosition; import org.oscim.core.MapPosition;
import org.oscim.core.Tile; import org.oscim.core.Tile;
import org.oscim.layers.tile.JobTile; import org.oscim.layers.tile.MapTile;
import org.oscim.layers.tile.MapTile; import org.oscim.layers.tile.MapTile;
import org.oscim.layers.tile.TileRenderLayer; import org.oscim.layers.tile.TileRenderLayer;
import org.oscim.layers.tile.TileSet; import org.oscim.layers.tile.TileSet;
@ -165,7 +165,7 @@ public class ExtrusionOverlay extends RenderOverlay {
private static ExtrusionLayer getLayer(MapTile t) { private static ExtrusionLayer getLayer(MapTile t) {
if (t.layers != null && t.layers.extrusionLayers != null if (t.layers != null && t.layers.extrusionLayers != null
&& t.state == JobTile.STATE_READY) && t.state == MapTile.STATE_READY)
return (ExtrusionLayer) t.layers.extrusionLayers; return (ExtrusionLayer) t.layers.extrusionLayers;
return null; return null;
} }

View File

@ -32,7 +32,7 @@ import org.oscim.core.MapPosition;
import org.oscim.core.Tile; import org.oscim.core.Tile;
import org.oscim.graphics.Color; import org.oscim.graphics.Color;
import org.oscim.graphics.Paint.Cap; import org.oscim.graphics.Paint.Cap;
import org.oscim.layers.tile.JobTile; import org.oscim.layers.tile.MapTile;
import org.oscim.layers.tile.MapTile; import org.oscim.layers.tile.MapTile;
import org.oscim.layers.tile.TileRenderLayer; import org.oscim.layers.tile.TileRenderLayer;
import org.oscim.layers.tile.TileSet; import org.oscim.layers.tile.TileSet;
@ -462,7 +462,7 @@ public class TextOverlay extends BasicOverlay {
/* add way labels */ /* add way labels */
for (int i = 0, n = mTileSet.cnt; i < n; i++) { for (int i = 0, n = mTileSet.cnt; i < n; i++) {
MapTile t = tiles[i]; MapTile t = tiles[i];
if (t.state != JobTile.STATE_READY) if (t.state != MapTile.STATE_READY)
continue; continue;
float dx = (float) (t.tileX * Tile.SIZE - tileX); float dx = (float) (t.tileX * Tile.SIZE - tileX);
@ -528,7 +528,7 @@ public class TextOverlay extends BasicOverlay {
/* add caption */ /* add caption */
for (int i = 0, n = mTileSet.cnt; i < n; i++) { for (int i = 0, n = mTileSet.cnt; i < n; i++) {
MapTile t = tiles[i]; MapTile t = tiles[i];
if (t.state != JobTile.STATE_READY) if (t.state != MapTile.STATE_READY)
continue; continue;
float dx = (float) (t.tileX * Tile.SIZE - tileX); float dx = (float) (t.tileX * Tile.SIZE - tileX);