- keep screen-to-map-plane projection in Matrices so that this stays consistent for a frame

- dont modify map-plane coord array that is passed to ScanBox
This commit is contained in:
Hannes Janetzek 2013-05-07 08:02:45 +02:00
parent 9bbfef02ad
commit 0174c0229d
3 changed files with 93 additions and 98 deletions

View File

@ -26,29 +26,29 @@ import org.oscim.utils.ScanBox;
import org.oscim.view.MapView;
import android.util.Log;
public class TileRenderLayer extends RenderLayer {
private final static String TAG = TileRenderLayer.class.getName();
private final float[] mBoxCoords;
private final TileManager mTileManager;
public TileRenderLayer(MapView mapView, TileManager tileManager) {
super(mapView);
mTileManager = tileManager;
mBoxCoords = new float[8];
}
boolean mFaded;
public void setFaded(boolean faded){
public void setFaded(boolean faded) {
mFaded = faded;
}
@Override
public void update(MapPosition pos, boolean positionChanged, Matrices m) {
int serial = 0;
mMapPosition.copy(pos);
int serial = 0;
if (mDrawTiles != null)
serial = mDrawTiles.getSerial();
@ -60,25 +60,18 @@ public class TileRenderLayer extends RenderLayer {
if (mDrawTiles == null || mDrawTiles.cnt == 0)
return;
boolean changed = false;
//boolean positionChanged = false;
boolean tilesChanged = false;
// check if the tiles have changed...
if (serial != mDrawTiles.getSerial()) {
changed = true;
// FIXME needed?
//positionChanged = true;
}
// check if tiles have changed.
if (serial != mDrawTiles.getSerial())
tilesChanged = true;
int tileCnt = mDrawTiles.cnt;
MapTile[] tiles = mDrawTiles.tiles;
if (changed || positionChanged){
float[] box = mBoxCoords;
mMapView.getMapViewPosition().getMapViewProjection(box);
if (tilesChanged || positionChanged)
updateTileVisibility(m.mapPlane);
updateTileVisibility(box);
}
tileCnt += mNumTileHolder;
/* prepare tile for rendering */
@ -95,7 +88,6 @@ public class TileRenderLayer extends RenderLayer {
@Override
public void render(MapPosition pos, Matrices m) {
}
/** compile tile layer data and upload to VBOs */
@ -236,78 +228,77 @@ public class TileRenderLayer extends RenderLayer {
td.cnt = 0;
}
// Add additional tiles that serve as placeholer when flipping
// over date-line.
// I dont really like this but cannot think of a better solution:
// the other option would be to run scanbox each time for upload,
// drawing, proxies and text layer. needing to add placeholder only
// happens rarely, unless you live on Fidschi
// over date-line.
// I dont really like this but cannot think of a better solution:
// The other option would be to run scanbox each time for upload,
// drawing, proxies and text layer. Adding placeholder only
// happens rarely, unless you live on Fidschi
/* package */int mNumTileHolder;
/* package */TileSet mDrawTiles;
/* package */int mNumTileHolder;
/* package */TileSet mDrawTiles;
// scanline fill class used to check tile visibility
private final ScanBox mScanBox = new ScanBox() {
@Override
protected void setVisible(int y, int x1, int x2) {
int cnt = mDrawTiles.cnt;
// scanline fill class used to check tile visibility
private final ScanBox mScanBox = new ScanBox() {
@Override
protected void setVisible(int y, int x1, int x2) {
int cnt = mDrawTiles.cnt;
MapTile[] tiles = mDrawTiles.tiles;
MapTile[] tiles = mDrawTiles.tiles;
for (int i = 0; i < cnt; i++) {
MapTile t = tiles[i];
if (t.tileY == y && t.tileX >= x1 && t.tileX < x2)
t.isVisible = true;
}
int xmax = 1 << mZoom;
if (x1 >= 0 && x2 < xmax)
return;
// add placeholder tiles to show both sides
// of date line. a little too complicated...
for (int x = x1; x < x2; x++) {
MapTile holder = null;
MapTile tile = null;
boolean found = false;
if (x >= 0 && x < xmax)
continue;
int xx = x;
if (x < 0)
xx = xmax + x;
else
xx = x - xmax;
if (xx < 0 || xx >= xmax)
continue;
for (int i = cnt; i < cnt + mNumTileHolder; i++)
if (tiles[i].tileX == x && tiles[i].tileY == y) {
found = true;
break;
}
if (found)
continue;
for (int i = 0; i < cnt; i++)
if (tiles[i].tileX == xx && tiles[i].tileY == y) {
tile = tiles[i];
break;
}
if (tile == null)
continue;
holder = new MapTile(x, y, (byte) mZoom);
holder.isVisible = true;
holder.holder = tile;
tile.isVisible = true;
tiles[cnt + mNumTileHolder++] = holder;
}
for (int i = 0; i < cnt; i++) {
MapTile t = tiles[i];
if (t.tileY == y && t.tileX >= x1 && t.tileX < x2)
t.isVisible = true;
}
};
int xmax = 1 << mZoom;
if (x1 >= 0 && x2 < xmax)
return;
// add placeholder tiles to show both sides
// of date line. a little too complicated...
for (int x = x1; x < x2; x++) {
MapTile holder = null;
MapTile tile = null;
boolean found = false;
if (x >= 0 && x < xmax)
continue;
int xx = x;
if (x < 0)
xx = xmax + x;
else
xx = x - xmax;
if (xx < 0 || xx >= xmax)
continue;
for (int i = cnt; i < cnt + mNumTileHolder; i++)
if (tiles[i].tileX == x && tiles[i].tileY == y) {
found = true;
break;
}
if (found)
continue;
for (int i = 0; i < cnt; i++)
if (tiles[i].tileX == xx && tiles[i].tileY == y) {
tile = tiles[i];
break;
}
if (tile == null)
continue;
holder = new MapTile(x, y, (byte) mZoom);
holder.isVisible = true;
holder.holder = tile;
tile.isVisible = true;
tiles[cnt + mNumTileHolder++] = holder;
}
}
};
}

View File

@ -74,13 +74,12 @@ public class GLRenderer implements GLSurfaceView.Renderer {
// bytes currently loaded in VBOs
private static int mBufferMemoryUsage;
private static float[] mBoxCoords;
public class Matrices {
// do not modify any of these
public final Matrix4 viewproj = new Matrix4();
public final Matrix4 proj = new Matrix4();
public final Matrix4 view = new Matrix4();
public final float[] mapPlane = new float[8];
// for temporary use by callee
public final Matrix4 mvp = new Matrix4();
@ -132,7 +131,6 @@ public class GLRenderer implements GLSurfaceView.Renderer {
mMapPosition = new MapPosition();
mMatrices = new Matrices();
mBoxCoords = new float[8];
// tile fill coords
short min = 0;
@ -291,7 +289,7 @@ public class GLRenderer implements GLSurfaceView.Renderer {
| GLES20.GL_DEPTH_BUFFER_BIT
| GLES20.GL_STENCIL_BUFFER_BIT);
boolean positionChanged = false;
boolean changed = false;
// get current MapPosition, set mBoxCoords (mapping of screen to model
// coordinates)
@ -300,10 +298,10 @@ public class GLRenderer implements GLSurfaceView.Renderer {
synchronized (mMapViewPosition) {
mMapViewPosition.updateAnimation();
positionChanged = mMapViewPosition.getMapPosition(pos);
changed = mMapViewPosition.getMapPosition(pos);
if (positionChanged)
mMapViewPosition.getMapViewProjection(mBoxCoords);
if (changed)
mMapViewPosition.getMapViewProjection(mMatrices.mapPlane);
mMapViewPosition.getMatrix(mMatrices.view, null, mMatrices.viewproj);
@ -317,7 +315,7 @@ public class GLRenderer implements GLSurfaceView.Renderer {
RenderLayer[] overlays = mMapView.getLayerManager().getRenderLayers();
for (int i = 0, n = overlays.length; i < n; i++)
overlays[i].update(mMapPosition, positionChanged, mMatrices);
overlays[i].update(pos, changed, mMatrices);
/* draw layers */
for (int i = 0, n = overlays.length; i < n; i++) {

View File

@ -33,7 +33,9 @@ import org.oscim.core.Tile;
* */
public abstract class ScanBox {
public static void transScale(double x, double y, double scale, int zoom, float[] box){
private final float[] mBox = new float[8];
private float[] transScale(double x, double y, double scale, int zoom, float[] box){
scale *= Tile.SIZE;
//double curScale = Tile.SIZE * scale;
@ -43,10 +45,12 @@ public abstract class ScanBox {
y *= scale;
for (int i = 0; i < 8; i += 2) {
box[i + 0] = (float) ((x + box[i + 0]) / div);
box[i + 1] = (float) ((y + box[i + 1]) / div);
mBox[i + 0] = (float) ((x + box[i + 0]) / div);
mBox[i + 1] = (float) ((y + box[i + 1]) / div);
}
return mBox;
}
/*
* ported from Polymaps: Layer.js
*/
@ -74,6 +78,7 @@ public abstract class ScanBox {
private Edge ab = new Edge();
private Edge bc = new Edge();
private Edge ca = new Edge();
private int minX, maxX;
protected int mZoom;
@ -82,7 +87,8 @@ public abstract class ScanBox {
public void scan(double x, double y, double scale, int zoom, float[] box) {
mZoom = zoom;
transScale(x, y, scale, zoom, box);
// this does not modify 'box' parameter
box = transScale(x, y, scale, zoom, box);
// clip result to min/max as steep angles
// cause overshooting in x direction.