-use absolute x/y position and scale in MapPosition
- scale calculations look much nicer now, better always use 'double' unless you are sure about precision required - finally got rid of zoomLevel relative coordinates - cleanup MapPosition and MercatorProjection API functions
This commit is contained in:
@@ -35,7 +35,6 @@ import org.oscim.core.Tile;
|
||||
import org.oscim.renderer.layer.Layers;
|
||||
import org.oscim.renderer.overlays.RenderOverlay;
|
||||
import org.oscim.theme.RenderTheme;
|
||||
import org.oscim.utils.FastMath;
|
||||
import org.oscim.utils.GlUtils;
|
||||
import org.oscim.utils.Matrix4;
|
||||
import org.oscim.view.MapView;
|
||||
@@ -317,31 +316,21 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
||||
for (int i = 0; i < mDrawTiles.cnt; i++)
|
||||
tiles[i].isVisible = false;
|
||||
|
||||
// relative zoom-level, 'tiles' could not have been updated after
|
||||
// zoom-level changed.
|
||||
float div = FastMath.pow(pos.zoomLevel - tiles[0].zoomLevel);
|
||||
int z = tiles[0].zoomLevel;
|
||||
|
||||
// draw additional tiles on max zoom-level:
|
||||
// to make sure buildings that are half visible but
|
||||
// the not ground tile are still drawn.
|
||||
float scale = pos.scale;
|
||||
if (scale > 2)
|
||||
scale = 2;
|
||||
double curScale = Tile.TILE_SIZE * pos.scale;
|
||||
double tileScale = Tile.TILE_SIZE * (pos.scale / (1 << z));
|
||||
|
||||
// transform screen coordinates to tile coordinates
|
||||
float tileScale = scale * div * Tile.TILE_SIZE;
|
||||
double px = pos.x * scale;
|
||||
double py = pos.y * scale;
|
||||
for (int i = 0; i < 8; i += 2) {
|
||||
coords[i + 0] = (float) (px + coords[i + 0]) / tileScale;
|
||||
coords[i + 1] = (float) (py + coords[i + 1]) / tileScale;
|
||||
coords[i + 0] = (float) ((pos.x * curScale + coords[i + 0]) / tileScale);
|
||||
coords[i + 1] = (float) ((pos.y * curScale + coords[i + 1]) / tileScale);
|
||||
}
|
||||
|
||||
// count placeholder tiles
|
||||
mNumTileHolder = 0;
|
||||
|
||||
// check visibile tiles
|
||||
mScanBox.scan(coords, tiles[0].zoomLevel);
|
||||
mScanBox.scan(coords, z);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -451,21 +440,23 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
||||
return;
|
||||
|
||||
boolean tilesChanged = false;
|
||||
boolean positionChanged = false;
|
||||
|
||||
// check if the tiles have changed...
|
||||
if (serial != mDrawTiles.serial) {
|
||||
mMapPosition.zoomLevel = -1;
|
||||
tilesChanged = true;
|
||||
// FIXME needed?
|
||||
positionChanged = true;
|
||||
}
|
||||
|
||||
// get current MapPosition, set mTileCoords (mapping of screen to model
|
||||
// coordinates)
|
||||
MapPosition pos = mMapPosition;
|
||||
boolean positionChanged;
|
||||
|
||||
synchronized (mMapViewPosition) {
|
||||
mMapViewPosition.updateAnimation();
|
||||
|
||||
positionChanged = mMapViewPosition.getMapPosition(pos);
|
||||
positionChanged |= mMapViewPosition.getMapPosition(pos);
|
||||
|
||||
if (positionChanged)
|
||||
mMapViewPosition.getMapViewProjection(mTileCoords);
|
||||
|
||||
@@ -23,7 +23,6 @@ import static android.opengl.GLES20.glUniform1f;
|
||||
import static android.opengl.GLES20.glVertexAttribPointer;
|
||||
|
||||
import org.oscim.core.MapPosition;
|
||||
import org.oscim.generator.TileGenerator;
|
||||
import org.oscim.renderer.GLRenderer.Matrices;
|
||||
import org.oscim.renderer.layer.Layer;
|
||||
import org.oscim.renderer.layer.Layers;
|
||||
@@ -130,15 +129,17 @@ public final class LineRenderer {
|
||||
//glUniformMatrix4fv(hLineMatrix[mode], 1, false, matrix, 0);
|
||||
m.mvp.setAsUniform(hLineMatrix[mode]);
|
||||
|
||||
//int zoom = FastMath.log2((int) pos.absScale);
|
||||
int zoom = pos.zoomLevel;
|
||||
float scale = pos.scale;
|
||||
|
||||
double scale = pos.getZoomScale();
|
||||
|
||||
// Line scale factor for non fixed lines: Within a zoom-
|
||||
// level lines would be scaled by the factor 2 by view-matrix.
|
||||
// Though lines should only scale by sqrt(2). This is achieved
|
||||
// by inverting scaling of extrusion vector with: width/sqrt(s).
|
||||
// within one zoom-level: 1 <= s <= 2
|
||||
float s = scale / div;
|
||||
double s = scale / div;
|
||||
float lineScale = (float) Math.sqrt(s * 2 / 2.2);
|
||||
|
||||
// scale factor to map one pixel on tile to one pixel on screen:
|
||||
@@ -146,7 +147,7 @@ public final class LineRenderer {
|
||||
float pixel = 0;
|
||||
|
||||
if (mode == 1)
|
||||
pixel = 1.5f / s;
|
||||
pixel = (float) (1.5 / s);
|
||||
|
||||
glUniform1f(uLineScale, pixel);
|
||||
int lineMode = 0;
|
||||
@@ -154,7 +155,7 @@ public final class LineRenderer {
|
||||
|
||||
boolean blur = false;
|
||||
// dont increase scale when max is reached
|
||||
boolean strokeMaxZoom = zoom > TileGenerator.STROKE_MAX_ZOOM_LEVEL;
|
||||
//boolean strokeMaxZoom = zoom > TileGenerator.STROKE_MAX_ZOOM_LEVEL;
|
||||
|
||||
Layer l = curLayer;
|
||||
for (; l != null && l.type == Layer.LINE; l = l.next) {
|
||||
@@ -167,7 +168,7 @@ public final class LineRenderer {
|
||||
} else if (line.fade > zoom) {
|
||||
continue;
|
||||
} else {
|
||||
float alpha = (scale > 1.2f ? scale : 1.2f) - 1f;
|
||||
float alpha = (float) (scale > 1.2 ? scale : 1.2) - 1;
|
||||
GlUtils.setColor(uLineColor, line.color, alpha);
|
||||
}
|
||||
|
||||
@@ -180,10 +181,10 @@ public final class LineRenderer {
|
||||
// draw linelayers references by this outline
|
||||
for (LineLayer o = ll.outlines; o != null; o = o.outlines) {
|
||||
|
||||
if (o.line.fixed || strokeMaxZoom) {
|
||||
width = (ll.width + o.width) / s;
|
||||
if (o.line.fixed /* || strokeMaxZoom */) {
|
||||
width = (float) ((ll.width + o.width) / s);
|
||||
} else {
|
||||
width = ll.width / s + o.width / lineScale;
|
||||
width = (float) (ll.width / s + o.width / lineScale);
|
||||
|
||||
// check min-size for outline
|
||||
if (o.line.min > 0 && o.width * lineScale < o.line.min * 2)
|
||||
@@ -193,7 +194,7 @@ public final class LineRenderer {
|
||||
glUniform1f(uLineWidth, width * COORD_SCALE_BY_DIR_SCALE);
|
||||
|
||||
if (line.blur != 0) {
|
||||
glUniform1f(uLineScale, 1f - (line.blur / s));
|
||||
glUniform1f(uLineScale, (float) (1 - (line.blur / s)));
|
||||
blur = true;
|
||||
} else if (mode == 1) {
|
||||
glUniform1f(uLineScale, pixel / width);
|
||||
@@ -212,10 +213,10 @@ public final class LineRenderer {
|
||||
}
|
||||
} else {
|
||||
|
||||
if (line.fixed || strokeMaxZoom) {
|
||||
if (line.fixed /* || strokeMaxZoom */) {
|
||||
// invert scaling of extrusion vectors so that line
|
||||
// width stays the same.
|
||||
width = ll.width / s;
|
||||
width = (float) (ll.width / s);
|
||||
} else {
|
||||
// reduce linear scaling of extrusion vectors so that
|
||||
// line width increases by sqrt(2.2).
|
||||
|
||||
@@ -130,7 +130,9 @@ public class LineTexRenderer {
|
||||
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, layers.vbo.id);
|
||||
|
||||
float s = pos.scale / div;
|
||||
float scale = (float)pos.getZoomScale();
|
||||
|
||||
float s = scale / div;
|
||||
|
||||
//GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexID[0]);
|
||||
|
||||
@@ -146,7 +148,7 @@ public class LineTexRenderer {
|
||||
GLES20.glUniform1f(hPatternScale, (GLRenderer.COORD_SCALE * line.stipple) / ps);
|
||||
GLES20.glUniform1f(hPatternWidth, line.stippleWidth);
|
||||
|
||||
GLES20.glUniform1f(hScale, pos.scale);
|
||||
GLES20.glUniform1f(hScale, scale);
|
||||
// keep line width fixed
|
||||
GLES20.glUniform1f(hWidth, ll.width / s * COORD_SCALE_BY_DIR_SCALE);
|
||||
|
||||
|
||||
@@ -24,6 +24,9 @@ import org.oscim.renderer.layer.TextItem;
|
||||
*/
|
||||
public final class MapTile extends JobTile {
|
||||
|
||||
public double x;
|
||||
public double y;
|
||||
|
||||
/**
|
||||
* Tile data set by TileGenerator.
|
||||
*/
|
||||
@@ -73,6 +76,8 @@ public final class MapTile extends JobTile {
|
||||
|
||||
MapTile(int tileX, int tileY, byte zoomLevel) {
|
||||
super(tileX, tileY, zoomLevel);
|
||||
this.x = (double)tileX / (1 << zoomLevel);
|
||||
this.y = (double)tileY / (1 << zoomLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -179,6 +179,8 @@ public final class PolygonRenderer {
|
||||
|
||||
int start = cur;
|
||||
|
||||
float scale = (float)pos.getZoomScale();
|
||||
|
||||
Layer l = layer;
|
||||
for (; l != null && l.type == Layer.POLYGON; l = l.next) {
|
||||
PolygonLayer pl = (PolygonLayer) l;
|
||||
@@ -204,13 +206,13 @@ public final class PolygonRenderer {
|
||||
|
||||
// draw up to 7 layers into stencil buffer
|
||||
if (cur == STENCIL_BITS - 1) {
|
||||
fillPolygons(start, cur, zoom, pos.scale);
|
||||
fillPolygons(start, cur, zoom, scale);
|
||||
start = cur = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (cur > 0)
|
||||
fillPolygons(start, cur, zoom, pos.scale);
|
||||
fillPolygons(start, cur, zoom, scale);
|
||||
|
||||
if (clip) {
|
||||
if (first) {
|
||||
@@ -318,7 +320,9 @@ public final class PolygonRenderer {
|
||||
glColorMask(false, false, false, false);
|
||||
}
|
||||
// always pass stencil test:
|
||||
glStencilFunc(GL_ALWAYS, 0x00, 0x00);
|
||||
//glStencilFunc(GL_ALWAYS, 0x00, 0x00);
|
||||
glStencilFunc(GL_EQUAL, CLIP_BIT, CLIP_BIT);
|
||||
|
||||
// write to all bits
|
||||
glStencilMask(0xFF);
|
||||
// zero out area to draw to
|
||||
|
||||
@@ -122,7 +122,7 @@ public final class TextureRenderer {
|
||||
+ " pos = u_proj * (u_mv * vec4(vertex.xy + dir * u_scale, 0.0, 1.0));"
|
||||
+ " } else {" // place as billboard
|
||||
+ " vec4 center = u_mv * vec4(vertex.xy, 0.0, 1.0);"
|
||||
+ " pos = u_proj * (center + vec4(dir * (coord_scale * u_swidth), 0.1, 0.0));"
|
||||
+ " pos = u_proj * (center + vec4(dir * (coord_scale * u_swidth), 0.0, 0.0));"
|
||||
+ " }"
|
||||
+ " gl_Position = pos;"
|
||||
+ " tex_c = tex_coord * div;"
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.oscim.generator.JobTile;
|
||||
import org.oscim.generator.TileDistanceSort;
|
||||
import org.oscim.renderer.layer.TextItem;
|
||||
import org.oscim.renderer.layer.VertexPool;
|
||||
import org.oscim.utils.FastMath;
|
||||
import org.oscim.view.MapView;
|
||||
import org.oscim.view.MapViewPosition;
|
||||
|
||||
@@ -42,6 +43,8 @@ import android.util.Log;
|
||||
*/
|
||||
public class TileManager {
|
||||
static final String TAG = TileManager.class.getSimpleName();
|
||||
private final static int MAX_ZOOMLEVEL = 17;
|
||||
private final static int MIN_ZOOMLEVEL = 2;
|
||||
|
||||
// limit number tiles with new data not uploaded to GL
|
||||
// TODO this should depend on the number of tiles displayed
|
||||
@@ -148,10 +151,10 @@ public class TileManager {
|
||||
* 2. Add not yet loaded (or loading) tiles to JobQueue.
|
||||
* 3. Manage cache
|
||||
*
|
||||
* @param mapPosition
|
||||
* @param pos
|
||||
* current MapPosition
|
||||
*/
|
||||
public synchronized void update(MapPosition mapPosition) {
|
||||
public synchronized void update(MapPosition pos) {
|
||||
// clear JobQueue and set tiles to state == NONE.
|
||||
// one could also append new tiles and sort in JobQueue
|
||||
// but this has the nice side-effect that MapWorkers dont
|
||||
@@ -162,22 +165,38 @@ public class TileManager {
|
||||
|
||||
// scale and translate projection to tile coordinates
|
||||
// load some tiles more than currently visible (* 0.75)
|
||||
float scale = mapPosition.scale * 0.75f;
|
||||
float tileScale = scale * Tile.TILE_SIZE;
|
||||
double px = mapPosition.x * scale;
|
||||
double py = mapPosition.y * scale;
|
||||
// float scale = mapPosition.scale * 0.75f;
|
||||
// float tileScale = scale * Tile.TILE_SIZE;
|
||||
// double px = mapPosition.x * scale;
|
||||
// double py = mapPosition.y * scale;
|
||||
//
|
||||
// float[] coords = mTileCoords;
|
||||
// mMapViewPosition.getMapViewProjection(coords);
|
||||
// for (int i = 0; i < 8; i += 2) {
|
||||
// coords[i + 0] = (float)(px + coords[i + 0]) / tileScale;
|
||||
// coords[i + 1] = (float)(py + coords[i + 1]) / tileScale;
|
||||
// }
|
||||
|
||||
// scale and translate projection to tile coordinates
|
||||
// load some tiles more than currently visible (* 0.75)
|
||||
double scale = pos.scale * 0.75f;
|
||||
double curScale = Tile.TILE_SIZE * scale;
|
||||
int zoomLevel = FastMath.clamp(pos.zoomLevel, MIN_ZOOMLEVEL, MAX_ZOOMLEVEL);
|
||||
|
||||
double tileScale = Tile.TILE_SIZE * (scale / (1 << zoomLevel));
|
||||
|
||||
float[] coords = mTileCoords;
|
||||
mMapViewPosition.getMapViewProjection(coords);
|
||||
|
||||
for (int i = 0; i < 8; i += 2) {
|
||||
coords[i + 0] = (float)(px + coords[i + 0]) / tileScale;
|
||||
coords[i + 1] = (float)(py + coords[i + 1]) / tileScale;
|
||||
coords[i + 0] = (float) ((pos.x * curScale + coords[i + 0]) / tileScale);
|
||||
coords[i + 1] = (float) ((pos.y * curScale + coords[i + 1]) / tileScale);
|
||||
}
|
||||
|
||||
// scan visible tiles. callback function calls 'addTile'
|
||||
// which sets mNewTiles
|
||||
mNewTiles.cnt = 0;
|
||||
mScanBox.scan(coords, mapPosition.zoomLevel);
|
||||
mScanBox.scan(coords, zoomLevel);
|
||||
|
||||
MapTile[] newTiles = mNewTiles.tiles;
|
||||
MapTile[] curTiles = mCurrentTiles.tiles;
|
||||
@@ -225,7 +244,7 @@ public class TileManager {
|
||||
|
||||
JobTile[] jobs = new JobTile[mJobs.size()];
|
||||
jobs = mJobs.toArray(jobs);
|
||||
updateTileDistances(jobs, jobs.length, mapPosition);
|
||||
updateTileDistances(jobs, jobs.length, pos);
|
||||
|
||||
// sets tiles to state == LOADING
|
||||
mMapView.addJobs(jobs);
|
||||
@@ -237,7 +256,7 @@ public class TileManager {
|
||||
if (remove > CACHE_THRESHOLD ||
|
||||
mTilesForUpload > MAX_TILES_IN_QUEUE)
|
||||
|
||||
limitCache(mapPosition, remove);
|
||||
limitCache(pos, remove);
|
||||
}
|
||||
|
||||
// need to keep track of TileSets to clear on reset...
|
||||
@@ -295,7 +314,7 @@ public class TileManager {
|
||||
tile = QuadTree.getTile(x, y, zoomLevel);
|
||||
|
||||
if (tile == null) {
|
||||
tile = new MapTile(x, y, (byte)zoomLevel);
|
||||
tile = new MapTile(x, y, (byte) zoomLevel);
|
||||
QuadTree.add(tile);
|
||||
mJobs.add(tile);
|
||||
addToCache(tile);
|
||||
@@ -389,11 +408,13 @@ public class TileManager {
|
||||
|
||||
private static void updateTileDistances(Object[] tiles, int size, MapPosition mapPosition) {
|
||||
// TODO there is probably a better quad-tree distance function
|
||||
double x = mapPosition.x;
|
||||
double y = mapPosition.y;
|
||||
|
||||
int zoom = mapPosition.zoomLevel;
|
||||
int h = Tile.TILE_SIZE >> 1;
|
||||
long center = h << zoom;
|
||||
double x = mapPosition.x * (1 << zoom);
|
||||
double y = mapPosition.y * (1 << zoom);
|
||||
|
||||
final float h = 0.5f;
|
||||
long center = (long)(h * (1 << zoom));
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
JobTile t = (JobTile) tiles[i];
|
||||
@@ -405,16 +426,16 @@ public class TileManager {
|
||||
dz = 0;
|
||||
|
||||
if (diff == 0) {
|
||||
dx = (t.pixelX + h) - x;
|
||||
dy = (t.pixelY + h) - y;
|
||||
dx = (t.tileX + h) - x;
|
||||
dy = (t.tileY + h) - y;
|
||||
scale = 0.5f;
|
||||
} else if (diff > 0) {
|
||||
// tile zoom level is greater than current
|
||||
// NB: distance increase by the factor 2
|
||||
// with each zoom-level, so that children
|
||||
// will be kept less likely than parent tiles.
|
||||
dx = (t.pixelX + h) - x * (1 << diff);
|
||||
dy = (t.pixelY + h) - y * (1 << diff);
|
||||
dx = (t.tileX + h) - x * (1 << diff);
|
||||
dy = (t.tileY + h) - y * (1 << diff);
|
||||
// add tilesize/2 with each zoom-level
|
||||
// so that children near the current
|
||||
// map position but a few levels above
|
||||
@@ -424,8 +445,8 @@ public class TileManager {
|
||||
} else {
|
||||
diff = -diff;
|
||||
// tile zoom level is smaller than current
|
||||
dx = (t.pixelX + h) - x / (1 << diff);
|
||||
dy = (t.pixelY + h) - y / (1 << diff);
|
||||
dx = (t.tileX + h) - x / (1 << diff);
|
||||
dy = (t.tileY + h) - y / (1 << diff);
|
||||
dz = diff * h;
|
||||
scale = 0.5f * (1 << diff);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import static android.opengl.GLES20.glStencilMask;
|
||||
import static org.oscim.generator.JobTile.STATE_READY;
|
||||
|
||||
import org.oscim.core.MapPosition;
|
||||
import org.oscim.core.Tile;
|
||||
import org.oscim.renderer.GLRenderer.Matrices;
|
||||
import org.oscim.renderer.layer.Layer;
|
||||
import org.oscim.utils.FastMath;
|
||||
@@ -68,21 +69,25 @@ public class TileRenderer {
|
||||
drawTile(t, pos);
|
||||
}
|
||||
|
||||
double scale = pos.getZoomScale();
|
||||
|
||||
// Draw parent or children as proxy for visibile tiles that dont
|
||||
// have data yet. Proxies are clipped to the region where nothing
|
||||
// was drawn to depth buffer.
|
||||
// TODO draw proxies for placeholder
|
||||
for (int i = 0; i < tileCnt; i++) {
|
||||
MapTile t = tiles[i];
|
||||
if (t.isVisible && (t.state != STATE_READY) && (t.holder == null))
|
||||
drawProxyTile(t, pos, true);
|
||||
if (t.isVisible && (t.state != STATE_READY) && (t.holder == null)){
|
||||
boolean preferParent = (scale > 1.5) || (pos.zoomLevel - t.zoomLevel < 0);
|
||||
drawProxyTile(t, pos, true, preferParent);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw grandparents
|
||||
for (int i = 0; i < tileCnt; i++) {
|
||||
MapTile t = tiles[i];
|
||||
if (t.isVisible && (t.state != STATE_READY) && (t.holder == null))
|
||||
drawProxyTile(t, pos, false);
|
||||
drawProxyTile(t, pos, false, false);
|
||||
}
|
||||
|
||||
// make sure stencil buffer write is disabled
|
||||
@@ -116,13 +121,18 @@ public class TileRenderer {
|
||||
GLES20.glBindBuffer(GL_ARRAY_BUFFER, t.layers.vbo.id);
|
||||
|
||||
// place tile relative to map position
|
||||
float div = FastMath.pow(tile.zoomLevel - pos.zoomLevel);
|
||||
float x = (float) (tile.pixelX - pos.x * div);
|
||||
float y = (float) (tile.pixelY - pos.y * div);
|
||||
float scale = pos.scale / div;
|
||||
int z = tile.zoomLevel;
|
||||
|
||||
float div = FastMath.pow(z - pos.zoomLevel);
|
||||
|
||||
double curScale = Tile.TILE_SIZE * pos.scale;
|
||||
double scale = (pos.scale / (1 << z));
|
||||
|
||||
float x = (float) ((tile.x - pos.x) * curScale);
|
||||
float y = (float) ((tile.y - pos.y) * curScale);
|
||||
|
||||
Matrices m = mMatrices;
|
||||
m.mvp.setTransScale(x * scale, y * scale, scale / GLRenderer.COORD_SCALE);
|
||||
m.mvp.setTransScale(x, y, (float)(scale / GLRenderer.COORD_SCALE));
|
||||
|
||||
m.mvp.multiplyMM(mProjMatrix, m.mvp);
|
||||
|
||||
@@ -168,7 +178,8 @@ public class TileRenderer {
|
||||
}
|
||||
|
||||
// clear clip-region and could also draw 'fade-effect'
|
||||
PolygonRenderer.drawOver(m, true, 0x22000000);
|
||||
//PolygonRenderer.drawOver(m, true, 0x22000000);
|
||||
PolygonRenderer.drawOver(m, false, 0);
|
||||
}
|
||||
|
||||
private static int drawProxyChild(MapTile tile, MapPosition pos) {
|
||||
@@ -187,12 +198,14 @@ public class TileRenderer {
|
||||
return drawn;
|
||||
}
|
||||
|
||||
private static void drawProxyTile(MapTile tile, MapPosition pos, boolean parent) {
|
||||
int diff = pos.zoomLevel - tile.zoomLevel;
|
||||
// just FIXME!
|
||||
private static void drawProxyTile(MapTile tile, MapPosition pos, boolean parent, boolean preferParent) {
|
||||
//int diff = pos.zoomLevel - tile.zoomLevel;
|
||||
QuadTree r = tile.rel;
|
||||
MapTile proxy;
|
||||
|
||||
if (pos.scale > 1.5f || diff < 0) {
|
||||
|
||||
if (!preferParent) {
|
||||
// prefer drawing children
|
||||
if (drawProxyChild(tile, pos) == 4)
|
||||
return;
|
||||
|
||||
@@ -46,35 +46,36 @@ public abstract class BasicOverlay extends RenderOverlay {
|
||||
* use synchronized when modifying layers
|
||||
*/
|
||||
@Override
|
||||
public synchronized void render(MapPosition pos, Matrices m) {
|
||||
public synchronized void render(MapPosition curPos, Matrices m) {
|
||||
MapPosition pos = mMapPosition;
|
||||
|
||||
float div = FastMath.pow(mMapPosition.zoomLevel - pos.zoomLevel);
|
||||
float div = FastMath.pow(pos.zoomLevel - curPos.zoomLevel);
|
||||
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, layers.vbo.id);
|
||||
GLState.test(false, false);
|
||||
|
||||
if (layers.baseLayers != null) {
|
||||
setMatrix(pos, m, true);
|
||||
setMatrix(curPos, m, true);
|
||||
|
||||
for (Layer l = layers.baseLayers; l != null;) {
|
||||
switch (l.type) {
|
||||
case Layer.POLYGON:
|
||||
l = PolygonRenderer.draw(pos, l, m, true, false);
|
||||
l = PolygonRenderer.draw(curPos, l, m, true, false);
|
||||
break;
|
||||
case Layer.LINE:
|
||||
l = LineRenderer.draw(layers, l, pos, m, div, 0);
|
||||
l = LineRenderer.draw(layers, l, curPos, m, div, 0);
|
||||
break;
|
||||
case Layer.TEXLINE:
|
||||
l = LineTexRenderer.draw(layers, l, pos, m, div);
|
||||
l = LineTexRenderer.draw(layers, l, curPos, m, div);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (layers.textureLayers != null) {
|
||||
setMatrix(pos, m, false);
|
||||
setMatrix(curPos, m, false);
|
||||
|
||||
float scale = (mMapPosition.scale / pos.scale) * div;
|
||||
float scale = (float)(pos.scale / curPos.scale);
|
||||
|
||||
for (Layer l = layers.textureLayers; l != null;) {
|
||||
l = TextureRenderer.draw(l, scale, m);
|
||||
|
||||
@@ -19,6 +19,7 @@ import java.nio.ByteOrder;
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
import org.oscim.core.MapPosition;
|
||||
import org.oscim.core.Tile;
|
||||
import org.oscim.generator.JobTile;
|
||||
import org.oscim.renderer.GLRenderer;
|
||||
import org.oscim.renderer.GLRenderer.Matrices;
|
||||
@@ -26,7 +27,6 @@ import org.oscim.renderer.GLState;
|
||||
import org.oscim.renderer.MapTile;
|
||||
import org.oscim.renderer.TileSet;
|
||||
import org.oscim.renderer.layer.ExtrusionLayer;
|
||||
import org.oscim.utils.FastMath;
|
||||
import org.oscim.utils.GlUtils;
|
||||
import org.oscim.view.MapView;
|
||||
|
||||
@@ -173,7 +173,7 @@ public class ExtrusionOverlay extends RenderOverlay {
|
||||
|
||||
MapTile[] tiles = mTiles;
|
||||
|
||||
float div = FastMath.pow(tiles[0].zoomLevel - pos.zoomLevel);
|
||||
//float div = FastMath.pow(tiles[0].zoomLevel - pos.zoomLevel);
|
||||
|
||||
int shaderMode = 1;
|
||||
int uExtAlpha = hAlpha[shaderMode];
|
||||
@@ -195,7 +195,7 @@ public class ExtrusionOverlay extends RenderOverlay {
|
||||
for (int i = 0; i < mTileCnt; i++) {
|
||||
ExtrusionLayer el = (ExtrusionLayer) tiles[i].layers.extrusionLayers;
|
||||
|
||||
setMatrix(pos, m, tiles[i], div, 0);
|
||||
setMatrix(pos, m, tiles[i], 0);
|
||||
m.mvp.setAsUniform(uExtMatrix);
|
||||
|
||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, el.mIndicesBufferID);
|
||||
@@ -230,7 +230,7 @@ public class ExtrusionOverlay extends RenderOverlay {
|
||||
|
||||
GLState.useProgram(shaderProgram[shaderMode]);
|
||||
GLState.enableVertexArrays(uExtVertexPosition, -1);
|
||||
if (pos.scale < 2) {
|
||||
if (pos.scale < (1 << 18)) {
|
||||
// chances are high that one moves through a building
|
||||
// with scale > 2 also draw back sides in this case.
|
||||
GLES20.glEnable(GLES20.GL_CULL_FACE);
|
||||
@@ -247,7 +247,7 @@ public class ExtrusionOverlay extends RenderOverlay {
|
||||
MapTile t = tiles[i];
|
||||
ExtrusionLayer el = (ExtrusionLayer) t.layers.extrusionLayers;
|
||||
int d = GLRenderer.depthOffset(t) * 10;
|
||||
setMatrix(pos, m, t, div, d);
|
||||
setMatrix(pos, m, t, d);
|
||||
m.mvp.setAsUniform(uExtMatrix);
|
||||
|
||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, el.mIndicesBufferID);
|
||||
@@ -273,7 +273,7 @@ public class ExtrusionOverlay extends RenderOverlay {
|
||||
|
||||
GLES20.glDepthFunc(GLES20.GL_EQUAL);
|
||||
int d = GLRenderer.depthOffset(t) * 10;
|
||||
setMatrix(pos, m, t, div, d);
|
||||
setMatrix(pos, m, t, d);
|
||||
m.mvp.setAsUniform(uExtMatrix);
|
||||
|
||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, el.mIndicesBufferID);
|
||||
@@ -316,19 +316,28 @@ public class ExtrusionOverlay extends RenderOverlay {
|
||||
tiles[i] = null;
|
||||
}
|
||||
|
||||
if (pos.scale < 2)
|
||||
if (pos.scale < (1 << 18))
|
||||
GLES20.glDisable(GLES20.GL_CULL_FACE);
|
||||
|
||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
private static void setMatrix(MapPosition mapPosition, Matrices m,
|
||||
MapTile tile, float div, int delta) {
|
||||
private static void setMatrix(MapPosition pos, Matrices m,
|
||||
MapTile tile, int delta) {
|
||||
|
||||
float x = (float) (tile.pixelX - mapPosition.x * div);
|
||||
float y = (float) (tile.pixelY - mapPosition.y * div);
|
||||
float scale = mapPosition.scale / div;
|
||||
int z = tile.zoomLevel;
|
||||
double curScale = Tile.TILE_SIZE * pos.scale;
|
||||
float scale = (float)(pos.scale / (1 << z));
|
||||
|
||||
m.mvp.setTransScale(x * scale, y * scale, scale / GLRenderer.COORD_SCALE);
|
||||
float x = (float) ((tile.x - pos.x) * curScale);
|
||||
float y = (float) ((tile.y - pos.y) * curScale);
|
||||
m.mvp.setTransScale(x, y, scale / GLRenderer.COORD_SCALE);
|
||||
|
||||
// float x = (float) (tile.pixelX - mapPosition.x * div);
|
||||
// float y = (float) (tile.pixelY - mapPosition.y * div);
|
||||
// float scale = mapPosition.scale / div;
|
||||
//
|
||||
// m.mvp.setTransScale(x * scale, y * scale, scale / GLRenderer.COORD_SCALE);
|
||||
|
||||
// scale height
|
||||
m.mvp.setValue(10, scale / 10);
|
||||
|
||||
@@ -93,7 +93,6 @@ public class GridOverlay extends BasicOverlay {
|
||||
}
|
||||
}
|
||||
tl.prepare();
|
||||
|
||||
layers.textureLayers = tl;
|
||||
}
|
||||
|
||||
@@ -101,30 +100,28 @@ public class GridOverlay extends BasicOverlay {
|
||||
private int mCurY = -1;
|
||||
private int mCurZ = -1;
|
||||
|
||||
private boolean finished;
|
||||
|
||||
|
||||
@Override
|
||||
public synchronized void update(MapPosition curPos, boolean positionChanged,
|
||||
boolean tilesChanged, Matrices matrices) {
|
||||
|
||||
mMapPosition.copy(curPos);
|
||||
int z = 1 << curPos.zoomLevel;
|
||||
|
||||
// fix map position to tile coordinates
|
||||
float size = Tile.TILE_SIZE;
|
||||
int x = (int) (mMapPosition.x / size);
|
||||
int y = (int) (mMapPosition.y / size);
|
||||
mMapPosition.x = x * size;
|
||||
mMapPosition.y = y * size;
|
||||
|
||||
if (!finished)
|
||||
mMapPosition.scale = 1;
|
||||
int x = (int) (curPos.x * z);
|
||||
int y = (int) (curPos.y * z);
|
||||
|
||||
// update layers when map moved by at least one tile
|
||||
if (x != mCurX || y != mCurY || mMapPosition.zoomLevel != mCurZ) {
|
||||
if (x != mCurX || y != mCurY || z != mCurZ) {
|
||||
|
||||
MapPosition pos = mMapPosition;
|
||||
|
||||
pos.copy(curPos);
|
||||
pos.x = (double) x / z;
|
||||
pos.y = (double) y / z;
|
||||
pos.scale = z;
|
||||
|
||||
mCurX = x;
|
||||
mCurY = y;
|
||||
mCurZ = mMapPosition.zoomLevel;
|
||||
mCurZ = z;
|
||||
|
||||
layers.clear();
|
||||
|
||||
@@ -134,9 +131,7 @@ public class GridOverlay extends BasicOverlay {
|
||||
ll.addLine(mPoints, mIndex, false);
|
||||
|
||||
addLabels(x, y, mCurZ);
|
||||
|
||||
newData = true;
|
||||
finished = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ import org.oscim.core.MapPosition;
|
||||
import org.oscim.core.Tile;
|
||||
import org.oscim.renderer.GLRenderer;
|
||||
import org.oscim.renderer.GLRenderer.Matrices;
|
||||
import org.oscim.utils.FastMath;
|
||||
import org.oscim.view.MapView;
|
||||
|
||||
public abstract class RenderOverlay {
|
||||
@@ -51,7 +50,8 @@ public abstract class RenderOverlay {
|
||||
* true when current tiles changed
|
||||
* @param matrices TODO
|
||||
*/
|
||||
public abstract void update(MapPosition curPos, boolean positionChanged, boolean tilesChanged, Matrices matrices);
|
||||
public abstract void update(MapPosition curPos, boolean positionChanged, boolean tilesChanged,
|
||||
Matrices matrices);
|
||||
|
||||
/**
|
||||
* called 2. compile everything for drawing
|
||||
@@ -70,44 +70,40 @@ public abstract class RenderOverlay {
|
||||
public abstract void render(MapPosition pos, Matrices m);
|
||||
|
||||
/**
|
||||
* Utility: set m.mvp matrix relative to the difference of current MapPosition
|
||||
* Utility: set m.mvp matrix relative to the difference of current
|
||||
* MapPosition
|
||||
* and the last updated Overlay MapPosition
|
||||
*
|
||||
* @param curPos ...
|
||||
* @param m ...
|
||||
* @param curPos
|
||||
* current MapPosition
|
||||
* @param m
|
||||
* current Matrices
|
||||
* @param project
|
||||
* apply view and projection, or just view otherwise
|
||||
* apply view and projection, or just view otherwise
|
||||
*/
|
||||
protected void setMatrix(MapPosition curPos, Matrices m, boolean project) {
|
||||
MapPosition oPos = mMapPosition;
|
||||
|
||||
float div = FastMath.pow(oPos.zoomLevel - curPos.zoomLevel);
|
||||
double tileScale = Tile.TILE_SIZE * curPos.scale;
|
||||
|
||||
// translate relative to map center
|
||||
float x = (float) (oPos.x - curPos.x * div);
|
||||
float y = (float) (oPos.y - curPos.y * div);
|
||||
double x = oPos.x - curPos.x;
|
||||
double y = oPos.y - curPos.y;
|
||||
|
||||
// flip around date-line
|
||||
float max = (Tile.TILE_SIZE << oPos.zoomLevel);
|
||||
if (x < -max / 2)
|
||||
x = max + x;
|
||||
else if (x > max / 2)
|
||||
x = x - max;
|
||||
// wrap around date-line
|
||||
while (x < 0)
|
||||
x += 1.0;
|
||||
while (x > 1)
|
||||
x -= 1.0;
|
||||
|
||||
// scale to current tile world coordinates
|
||||
float scale = curPos.scale / div;
|
||||
|
||||
// set scale to be relative to current scale
|
||||
float s = (curPos.scale / oPos.scale) / div;
|
||||
|
||||
m.mvp.setTransScale(x * scale, y * scale,
|
||||
s / GLRenderer.COORD_SCALE);
|
||||
m.mvp.setTransScale((float) (x * tileScale), (float) (y * tileScale),
|
||||
(float) ((curPos.scale / oPos.scale) / GLRenderer.COORD_SCALE));
|
||||
|
||||
m.mvp.multiplyMM(project ? m.viewproj : m.view, m.mvp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility: set m.mvp matrix relative to the difference of current MapPosition
|
||||
* Utility: set m.mvp matrix relative to the difference of current
|
||||
* MapPosition
|
||||
* and the last updated Overlay MapPosition and add m.viewproj
|
||||
*
|
||||
* @param curPos ...
|
||||
@@ -116,13 +112,4 @@ public abstract class RenderOverlay {
|
||||
protected void setMatrix(MapPosition curPos, Matrices m) {
|
||||
setMatrix(curPos, m, true);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Utility: update mMapPosition
|
||||
// *
|
||||
// * @return true if position has changed
|
||||
// */
|
||||
// protected boolean updateMapPosition() {
|
||||
// return mMapView.getMapViewPosition().getMapPosition(mMapPosition);
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -246,6 +246,7 @@ public class TextOverlay extends BasicOverlay {
|
||||
|
||||
private Layers mDebugLayer;
|
||||
private final static float[] mDebugPoints = new float[4];
|
||||
|
||||
//private final Matrix4 mMVP = new Matrix4();
|
||||
|
||||
//void addTile(MapTile t) {
|
||||
@@ -313,9 +314,15 @@ public class TextOverlay extends BasicOverlay {
|
||||
// this scales MapPosition to the zoomlevel of mTiles...
|
||||
// TODO create a helper function in MapPosition
|
||||
MapTile[] tiles = mTileSet.tiles;
|
||||
|
||||
//int zoom = tiles[0].zoomLevel;
|
||||
|
||||
int diff = tiles[0].zoomLevel - pos.zoomLevel;
|
||||
float div = FastMath.pow(diff);
|
||||
float scale = pos.scale * div;
|
||||
|
||||
double scale = pos.getZoomScale() * div;
|
||||
|
||||
//float scale = (float)(pos.absScale / (1 << zoom) );
|
||||
|
||||
double angle = Math.toRadians(pos.angle);
|
||||
float cos = (float) Math.cos(angle);
|
||||
@@ -330,11 +337,17 @@ public class TextOverlay extends BasicOverlay {
|
||||
|
||||
mRelabelCnt++;
|
||||
|
||||
double tileX = (pos.x * (Tile.TILE_SIZE << pos.zoomLevel));
|
||||
double tileY = (pos.y * (Tile.TILE_SIZE << pos.zoomLevel));
|
||||
|
||||
for (l = mPrevLabels; l != null;) {
|
||||
|
||||
// transform screen coordinates to tile coordinates
|
||||
float s = FastMath.pow(l.tile.zoomLevel - pos.zoomLevel);
|
||||
float sscale = pos.scale / s;
|
||||
|
||||
//float sscale = (float)((1 << l.tile.zoomLevel) / pos.absScale);
|
||||
|
||||
float sscale = (float) (pos.getZoomScale() / s);
|
||||
|
||||
if (l.width > l.length * sscale) {
|
||||
//Log.d(TAG, "- scale " + lp + " " + s + " " + sscale + " " + lp.length + " " + lp.width);
|
||||
@@ -342,8 +355,8 @@ public class TextOverlay extends BasicOverlay {
|
||||
continue;
|
||||
}
|
||||
|
||||
float dx = (float) (l.tile.pixelX - pos.x * s);
|
||||
float dy = (float) (l.tile.pixelY - pos.y * s);
|
||||
float dx = (float) (l.tile.tileX * Tile.TILE_SIZE - tileX * s);
|
||||
float dy = (float) (l.tile.tileY * Tile.TILE_SIZE - tileY * s);
|
||||
|
||||
// flip around date-line
|
||||
if (dx > maxx)
|
||||
@@ -399,8 +412,8 @@ public class TextOverlay extends BasicOverlay {
|
||||
if (t.state != JobTile.STATE_READY)
|
||||
continue;
|
||||
|
||||
float dx = (float) (t.pixelX - pos.x);
|
||||
float dy = (float) (t.pixelY - pos.y);
|
||||
float dx = (float) (t.tileX * Tile.TILE_SIZE - tileX);
|
||||
float dy = (float) (t.tileY * Tile.TILE_SIZE - tileY);
|
||||
|
||||
// flip around date-line
|
||||
if (dx > maxx)
|
||||
@@ -422,7 +435,7 @@ public class TextOverlay extends BasicOverlay {
|
||||
continue;
|
||||
|
||||
l.clone(ti);
|
||||
l.move(ti, dx, dy, scale);
|
||||
l.move(ti, dx, dy, (float) scale);
|
||||
|
||||
// set line endpoints relative to view to be able to
|
||||
// check intersections with label from other tiles
|
||||
@@ -448,7 +461,7 @@ public class TextOverlay extends BasicOverlay {
|
||||
overlaps = checkOverlap(tl, l);
|
||||
|
||||
if (dbg != null)
|
||||
addDebugBox(dbg, l, ti, overlaps, false, scale);
|
||||
addDebugBox(dbg, l, ti, overlaps, false, (float) scale);
|
||||
|
||||
if (overlaps == 0) {
|
||||
tl.addText(l);
|
||||
@@ -466,8 +479,8 @@ public class TextOverlay extends BasicOverlay {
|
||||
if (t.state != JobTile.STATE_READY)
|
||||
continue;
|
||||
|
||||
float dx = (float) (t.pixelX - pos.x);
|
||||
float dy = (float) (t.pixelY - pos.y);
|
||||
float dx = (float) (t.tileX * Tile.TILE_SIZE - tileX);
|
||||
float dy = (float) (t.tileY * Tile.TILE_SIZE - tileY);
|
||||
|
||||
// flip around date-line
|
||||
if (dx > maxx)
|
||||
@@ -484,7 +497,7 @@ public class TextOverlay extends BasicOverlay {
|
||||
l = getLabel();
|
||||
|
||||
l.clone(ti);
|
||||
l.move(ti, dx, dy, scale);
|
||||
l.move(ti, dx, dy, (float) scale);
|
||||
if (!nodeIsVisible(l))
|
||||
continue;
|
||||
|
||||
@@ -678,7 +691,7 @@ public class TextOverlay extends BasicOverlay {
|
||||
|
||||
@Override
|
||||
public synchronized void render(MapPosition pos, Matrices m) {
|
||||
float div = FastMath.pow(mMapPosition.zoomLevel - pos.zoomLevel);
|
||||
//float div = FastMath.pow(mMapPosition.zoomLevel - pos.zoomLevel);
|
||||
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, layers.vbo.id);
|
||||
GLState.test(false, false);
|
||||
@@ -690,7 +703,10 @@ public class TextOverlay extends BasicOverlay {
|
||||
if (l.type == Layer.POLYGON) {
|
||||
l = PolygonRenderer.draw(pos, l, m, true, false);
|
||||
} else {
|
||||
float scale = pos.scale * div;
|
||||
//float scale = pos.getScale() * div;
|
||||
|
||||
float scale = (float) ((1 << mMapPosition.zoomLevel) / pos.scale);
|
||||
|
||||
l = LineRenderer.draw(layers, l, pos, m, scale, 0);
|
||||
}
|
||||
}
|
||||
@@ -698,7 +714,8 @@ public class TextOverlay extends BasicOverlay {
|
||||
|
||||
setMatrix(pos, m);
|
||||
for (Layer l = layers.textureLayers; l != null;) {
|
||||
float scale = (mMapPosition.scale / pos.scale) * div;
|
||||
float scale = (float) (mMapPosition.scale / pos.scale);
|
||||
//float scale = (mMapPosition.getScale() / pos.getScale()) * div;
|
||||
|
||||
l = TextureRenderer.draw(l, scale, m);
|
||||
}
|
||||
@@ -709,14 +726,22 @@ public class TextOverlay extends BasicOverlay {
|
||||
protected void setMatrix(MapPosition curPos, Matrices m) {
|
||||
MapPosition oPos = mMapPosition;
|
||||
|
||||
float div = FastMath.pow(oPos.zoomLevel - curPos.zoomLevel);
|
||||
float x = (float) (oPos.x - curPos.x * div);
|
||||
float y = (float) (oPos.y - curPos.y * div);
|
||||
double tileScale = Tile.TILE_SIZE * curPos.scale;
|
||||
double scale = (curPos.scale / oPos.scale);
|
||||
|
||||
float scale = (curPos.scale / mMapPosition.scale) / div;
|
||||
float s = curPos.scale / div;
|
||||
m.mvp.setTransScale(x * s, y * s,
|
||||
scale / GLRenderer.COORD_SCALE);
|
||||
float x = (float) ((oPos.x - curPos.x) * tileScale);
|
||||
float y = (float) ((oPos.y - curPos.y) * tileScale);
|
||||
|
||||
m.mvp.setTransScale(x, y, (float) (scale / GLRenderer.COORD_SCALE));
|
||||
|
||||
// float div = FastMath.pow(oPos.zoomLevel - curPos.zoomLevel);
|
||||
// float x = (float) (oPos.x - curPos.x * div);
|
||||
// float y = (float) (oPos.y - curPos.y * div);
|
||||
//
|
||||
// float scale = (curPos.getScale() / oPos.getScale()) / div;
|
||||
// float s = curPos.getScale() / div;
|
||||
// m.mvp.setTransScale(x * s, y * s,
|
||||
// scale / GLRenderer.COORD_SCALE);
|
||||
|
||||
m.mvp.multiplyMM(m.view, m.mvp);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user