From 55030c116694a1ecfc7307ef5ad520361f5d4cc3 Mon Sep 17 00:00:00 2001 From: Hannes Janetzek <hannes.janetzek@gmail.com> Date: Fri, 15 Feb 2013 16:56:13 +0100 Subject: [PATCH] refactor: dont pass matrices with MapPosition -> use GLRender.Matrices --- src/org/oscim/core/MapPosition.java | 15 -- src/org/oscim/overlay/ItemizedOverlay.java | 11 +- src/org/oscim/overlay/PathOverlay.java | 10 +- src/org/oscim/renderer/BaseMap.java | 5 +- src/org/oscim/renderer/GLRenderer.java | 64 +++---- src/org/oscim/renderer/TileManager.java | 10 +- .../oscim/renderer/overlays/BasicOverlay.java | 32 ++-- .../renderer/overlays/BuildingOverlay.java | 29 ++- .../renderer/overlays/CustomOverlay.java | 12 +- .../renderer/overlays/ExtrusionOverlay.java | 41 ++-- .../oscim/renderer/overlays/ModelOverlay.java | 26 +-- .../renderer/overlays/RenderOverlay.java | 37 ++-- .../renderer/overlays/TestLineOverlay.java | 77 ++++---- .../oscim/renderer/overlays/TextOverlay.java | 11 +- .../renderer/overlays/TextOverlayExp.java | 178 +++++++++++------- src/org/oscim/utils/FastMath.java | 6 + src/org/oscim/view/MapViewPosition.java | 70 ++++--- 17 files changed, 362 insertions(+), 272 deletions(-) diff --git a/src/org/oscim/core/MapPosition.java b/src/org/oscim/core/MapPosition.java index c2169ba1..59ece2e7 100644 --- a/src/org/oscim/core/MapPosition.java +++ b/src/org/oscim/core/MapPosition.java @@ -15,7 +15,6 @@ */ package org.oscim.core; -import android.opengl.Matrix; /** A MapPosition Container. */ public class MapPosition { @@ -31,11 +30,6 @@ public class MapPosition { public double x; public double y; - public float[] viewMatrix; - - // // DO NOT MODIFY! shared with MapViewPosition - // public float[] projMatrix; - public MapPosition() { this.zoomLevel = (byte) 1; this.scale = 1; @@ -46,15 +40,6 @@ public class MapPosition { this.y = MercatorProjection.latitudeToPixelY(this.lat, zoomLevel); } - // FIXME remove this here - public void init() { - viewMatrix = new float[16]; - Matrix.setIdentityM(viewMatrix, 0); - // - // rotateMatrix = new float[16]; - // Matrix.setIdentityM(rotateMatrix, 0); - } - // public Point geopointToMap(GeoPoint in, Point reuse) { // Point out = reuse == null ? new Point() : reuse; // out.x = (int) (MercatorProjection.longitudeToPixelX(in.getLongitude(), zoomLevel) - x); diff --git a/src/org/oscim/overlay/ItemizedOverlay.java b/src/org/oscim/overlay/ItemizedOverlay.java index 19ae72b8..6ac3665c 100644 --- a/src/org/oscim/overlay/ItemizedOverlay.java +++ b/src/org/oscim/overlay/ItemizedOverlay.java @@ -73,9 +73,9 @@ public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay class ItemOverlay extends BasicOverlay { - private SymbolLayer mSymbolLayer; - private float[] mMvp = new float[16]; - private float[] mVec = new float[4]; + private final SymbolLayer mSymbolLayer; + private final float[] mMvp = new float[16]; + private final float[] mVec = new float[4]; public ItemOverlay(MapView mapView) { super(mapView); @@ -84,7 +84,8 @@ public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay // note: this is called from GL-Thread. so check your syncs! @Override - public synchronized void update(MapPosition curPos, boolean positionChanged, + public synchronized void update(MapPosition curPos, + boolean positionChanged, boolean tilesChanged) { if (!tilesChanged && !mUpdate) @@ -97,7 +98,7 @@ public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay int my = (int) curPos.y; // TODO could pass mvp as param - mMapView.getMapViewPosition().getMVP(mMvp); + mMapView.getMapViewPosition().getMatrix(null, null, mMvp); float[] matrix = mMvp; float[] vec = mVec; diff --git a/src/org/oscim/overlay/PathOverlay.java b/src/org/oscim/overlay/PathOverlay.java index 2df6a023..7723b1c7 100644 --- a/src/org/oscim/overlay/PathOverlay.java +++ b/src/org/oscim/overlay/PathOverlay.java @@ -25,6 +25,7 @@ import org.oscim.renderer.layer.Layer; import org.oscim.renderer.layer.LineLayer; import org.oscim.renderer.overlays.BasicOverlay; import org.oscim.theme.renderinstruction.Line; +import org.oscim.utils.FastMath; import org.oscim.view.MapView; import android.content.Context; @@ -52,10 +53,10 @@ public class PathOverlay extends Overlay { // projected points private float[] mPPoints; - private short[] mIndex; + private final short[] mIndex; private int mSize; - private Line mLine; + private final Line mLine; // limit coords private final int max = 2048; @@ -70,7 +71,8 @@ public class PathOverlay extends Overlay { // note: this is called from GL-Thread. so check your syncs! // TODO use an Overlay-Thread to build up layers (like for Labeling) @Override - public synchronized void update(MapPosition curPos, boolean positionChanged, + public synchronized void update(MapPosition curPos, + boolean positionChanged, boolean tilesChanged) { if (!tilesChanged && !mUpdatePoints) @@ -144,7 +146,7 @@ public class PathOverlay extends Overlay { // skip too near points int dx = x - px; int dy = y - py; - if ((i == 0) || dx > MIN_DIST || dx < -MIN_DIST || dy > MIN_DIST || dy < -MIN_DIST) { + if ((i == 0) || FastMath.absMaxCmp(dx, dy, MIN_DIST)) { projected[i + 0] = px = x; projected[i + 1] = py = y; i += 2; diff --git a/src/org/oscim/renderer/BaseMap.java b/src/org/oscim/renderer/BaseMap.java index effc8715..2ad3a1c6 100644 --- a/src/org/oscim/renderer/BaseMap.java +++ b/src/org/oscim/renderer/BaseMap.java @@ -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.renderer.GLRenderer.Matrices; import org.oscim.renderer.layer.Layer; import org.oscim.utils.FastMath; import org.oscim.utils.GlUtils; @@ -49,10 +50,10 @@ public class BaseMap { mfProjMatrix[14] = 0; } - static void draw(MapTile[] tiles, int tileCnt, MapPosition pos) { + static void draw(MapTile[] tiles, int tileCnt, MapPosition pos, Matrices m) { mDrawCnt = 0; - Matrix.multiplyMM(mVPMatrix, 0, mfProjMatrix, 0, pos.viewMatrix, 0); + Matrix.multiplyMM(mVPMatrix, 0, mfProjMatrix, 0, m.view, 0); GLES20.glDepthFunc(GLES20.GL_LESS); diff --git a/src/org/oscim/renderer/GLRenderer.java b/src/org/oscim/renderer/GLRenderer.java index e87c5045..7a33b55a 100644 --- a/src/org/oscim/renderer/GLRenderer.java +++ b/src/org/oscim/renderer/GLRenderer.java @@ -74,12 +74,21 @@ public class GLRenderer implements GLSurfaceView.Renderer { // bytes currently loaded in VBOs private static int mBufferMemoryUsage; - private static float[] mMVPMatrix = new float[16]; - private static float[] mProjMatrix = new float[16]; - private static float[] mTmpMatrix = new float[16]; + private static float[] mTileCoords = new float[8]; private static float[] mDebugCoords = new float[8]; + public class Matrices { + public final float[] viewproj = new float[16]; + public final float[] proj = new float[16]; + public final float[] view = new float[16]; + + // for temporary use by callee + public final float[] mvp = new float[16]; + } + + private static Matrices mMatrices; + //private static float[] mClearColor = null; private static boolean mUpdateColor = false; @@ -171,9 +180,9 @@ public class GLRenderer implements GLSurfaceView.Renderer { mMapView = mapView; mMapViewPosition = mapView.getMapViewPosition(); mMapPosition = new MapPosition(); - mMapPosition.init(); - Matrix.setIdentityM(mMVPMatrix, 0); + //Matrix.setIdentityM(mMVPMatrix, 0); + mMatrices = new Matrices(); // add half pixel to tile clip/fill coordinates to avoid rounding issues short min = -4; @@ -366,7 +375,12 @@ public class GLRenderer implements GLSurfaceView.Renderer { // coordinates) MapPosition pos = mMapPosition; float[] coords = mTileCoords; - boolean changed = mMapViewPosition.getMapPosition(pos, coords); + boolean changed; + synchronized(mMapViewPosition){ + changed = mMapViewPosition.getMapPosition(pos); + mMapViewPosition.getMapViewProjection(coords); + mMapViewPosition.getMatrix(mMatrices.view, null, mMatrices.viewproj); + } int tileCnt = mDrawTiles.cnt; MapTile[] tiles = mDrawTiles.tiles; @@ -455,7 +469,7 @@ public class GLRenderer implements GLSurfaceView.Renderer { overlays.get(i).update(mMapPosition, changed, tilesChanged); /* draw base layer */ - BaseMap.draw(tiles, tileCnt, pos); + BaseMap.draw(tiles, tileCnt, pos, mMatrices); /* draw overlays */ for (int i = 0, n = overlays.size(); i < n; i++) { @@ -466,7 +480,7 @@ public class GLRenderer implements GLSurfaceView.Renderer { renderOverlay.newData = false; } if (renderOverlay.isReady) - renderOverlay.render(mMapPosition, mMVPMatrix, mProjMatrix); + renderOverlay.render(mMapPosition, mMatrices); } if (MapView.debugFrameTime) { @@ -490,15 +504,12 @@ public class GLRenderer implements GLSurfaceView.Renderer { mDebugCoords[6] = max; mDebugCoords[7] = -ymax; - PolygonRenderer.debugDraw(mProjMatrix, mDebugCoords, 0); + PolygonRenderer.debugDraw(mMatrices.proj, mDebugCoords, 0); pos.zoomLevel = -1; - mMapViewPosition.getMapPosition(pos, mDebugCoords); + mMapViewPosition.getMapViewProjection(mDebugCoords); - Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, - pos.viewMatrix, 0); - - PolygonRenderer.debugDraw(mMVPMatrix, mDebugCoords, 1); + PolygonRenderer.debugDraw(mMatrices.viewproj, mDebugCoords, 1); } @@ -560,32 +571,21 @@ public class GLRenderer implements GLSurfaceView.Renderer { mWidth = width; mHeight = height; - GLES20.glScissor(0, 0, mWidth, mHeight); - - float s = MapViewPosition.VIEW_SCALE; - float aspect = mHeight / (float) mWidth; - - Matrix.frustumM(mProjMatrix, 0, -s, s, - aspect * s, -aspect * s, MapViewPosition.VIEW_NEAR, - MapViewPosition.VIEW_FAR); - - Matrix.setIdentityM(mTmpMatrix, 0); - Matrix.translateM(mTmpMatrix, 0, 0, 0, -MapViewPosition.VIEW_DISTANCE); - Matrix.multiplyMM(mProjMatrix, 0, mProjMatrix, 0, mTmpMatrix, 0); + mMapViewPosition.getMatrix(null, mMatrices.proj, null); if (debugView) { // modify this to scale only the view, to see better which tiles are // rendered - Matrix.setIdentityM(mMVPMatrix, 0); - Matrix.scaleM(mMVPMatrix, 0, 0.5f, 0.5f, 1); - Matrix.multiplyMM(mProjMatrix, 0, mMVPMatrix, 0, mProjMatrix, 0); + Matrix.setIdentityM(mMatrices.mvp, 0); + Matrix.scaleM(mMatrices.mvp, 0, 0.5f, 0.5f, 1); + Matrix.multiplyMM(mMatrices.proj, 0, mMatrices.mvp, 0, mMatrices.proj, 0); } - BaseMap.setProjection(mProjMatrix); + BaseMap.setProjection(mMatrices.proj); GLES20.glViewport(0, 0, width, height); - //GLES20.glScissor(0, 0, width, height); - //GLES20.glEnable(GLES20.GL_SCISSOR_TEST); + GLES20.glScissor(0, 0, width, height); + GLES20.glEnable(GLES20.GL_SCISSOR_TEST); GLES20.glClearStencil(0x00); diff --git a/src/org/oscim/renderer/TileManager.java b/src/org/oscim/renderer/TileManager.java index 551e16a1..58a09f66 100644 --- a/src/org/oscim/renderer/TileManager.java +++ b/src/org/oscim/renderer/TileManager.java @@ -29,6 +29,7 @@ import org.oscim.generator.TileDistanceSort; import org.oscim.renderer.layer.TextItem; import org.oscim.renderer.layer.VertexPool; import org.oscim.view.MapView; +import org.oscim.view.MapViewPosition; import android.util.Log; @@ -49,6 +50,7 @@ public class TileManager { private static final int CACHE_THRESHOLD = 30; private final MapView mMapView; + private final MapViewPosition mMapViewPosition; private final MapPosition mMapPosition; private boolean mInitialized; private int mWidth = 0; @@ -82,7 +84,7 @@ public class TileManager { public TileManager(MapView mapView) { mMapView = mapView; - + mMapViewPosition = mapView.getMapViewPosition(); mMapPosition = new MapPosition(); mJobs = new ArrayList<JobTile>(); mTiles = new MapTile[GLRenderer.CACHE_TILES]; @@ -159,7 +161,11 @@ public class TileManager { MapPosition mapPosition = mMapPosition; float[] coords = mTileCoords; - changedPos = mMapView.getMapViewPosition().getMapPosition(mapPosition, coords); + + synchronized(mMapViewPosition){ + changedPos = mMapViewPosition.getMapPosition(mapPosition); + mMapViewPosition.getMapViewProjection(coords); + } if (changedPos) { mMapView.render(); diff --git a/src/org/oscim/renderer/overlays/BasicOverlay.java b/src/org/oscim/renderer/overlays/BasicOverlay.java index fd980b18..33d84ee4 100644 --- a/src/org/oscim/renderer/overlays/BasicOverlay.java +++ b/src/org/oscim/renderer/overlays/BasicOverlay.java @@ -17,6 +17,7 @@ package org.oscim.renderer.overlays; import org.oscim.core.MapPosition; import org.oscim.renderer.BufferObject; import org.oscim.renderer.GLRenderer; +import org.oscim.renderer.GLRenderer.Matrices; import org.oscim.renderer.GLState; import org.oscim.renderer.LineRenderer; import org.oscim.renderer.PolygonRenderer; @@ -27,7 +28,6 @@ import org.oscim.utils.FastMath; import org.oscim.view.MapView; import android.opengl.GLES20; -import android.opengl.Matrix; // Base class to use the Layers drawing 'API' public abstract class BasicOverlay extends RenderOverlay { @@ -47,25 +47,33 @@ public abstract class BasicOverlay extends RenderOverlay { * use synchronized when modifying layers */ @Override - public synchronized void render(MapPosition pos, float[] mv, float[] proj) { - setMatrix(pos, mv); - float div = FastMath.pow(mMapPosition.zoomLevel - pos.zoomLevel); + public synchronized void render(MapPosition pos, Matrices m) { - Matrix.multiplyMM(mvp, 0, proj, 0, mv, 0); + float div = FastMath.pow(mMapPosition.zoomLevel - pos.zoomLevel); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbo.id); GLState.test(false, false); - for (Layer l = layers.layers; l != null;) { - if (l.type == Layer.POLYGON) { - l = PolygonRenderer.draw(pos, l, mvp, true, false); - } else { - l = LineRenderer.draw(pos, l, mvp, div, 0, layers.lineOffset); + if (layers.layers != null) { + setMatrix(pos, m, true); + + for (Layer l = layers.layers; l != null;) { + if (l.type == Layer.POLYGON) { + l = PolygonRenderer.draw(pos, l, m.mvp, true, false); + } else { + l = LineRenderer.draw(pos, l, m.mvp, div, 0, layers.lineOffset); + } } } - for (Layer l = layers.textureLayers; l != null;) { - l = TextureRenderer.draw(l, (mMapPosition.scale / pos.scale) * div, proj, mv); + if (layers.textureLayers != null) { + setMatrix(pos, m, false); + + float scale = (mMapPosition.scale / pos.scale) * div; + + for (Layer l = layers.textureLayers; l != null;) { + l = TextureRenderer.draw(l, scale, m.proj, m.mvp); + } } } diff --git a/src/org/oscim/renderer/overlays/BuildingOverlay.java b/src/org/oscim/renderer/overlays/BuildingOverlay.java index c443c24c..87fb68f3 100644 --- a/src/org/oscim/renderer/overlays/BuildingOverlay.java +++ b/src/org/oscim/renderer/overlays/BuildingOverlay.java @@ -21,6 +21,7 @@ import java.nio.ShortBuffer; import org.oscim.core.MapPosition; import org.oscim.core.Tile; import org.oscim.renderer.GLRenderer; +import org.oscim.renderer.GLRenderer.Matrices; import org.oscim.renderer.GLState; import org.oscim.renderer.layer.VertexPool; import org.oscim.renderer.layer.VertexPoolItem; @@ -58,7 +59,7 @@ public class BuildingOverlay extends RenderOverlay { private VertexPoolItem mVertices, mCurVertices; private VertexPoolItem mIndices[], mCurIndices[]; - private int mIndiceCnt[] = { 0, 0, 0 }; + private final int mIndiceCnt[] = { 0, 0, 0 }; private void addOutline(float[] points, float height) { int len = points.length; @@ -338,21 +339,19 @@ public class BuildingOverlay extends RenderOverlay { mNumVertices * 4 * 2, sbuf, GLES20.GL_STATIC_DRAW); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); - mMapView.getMapViewPosition().getMapPosition(mMapPosition, null); + mMapView.getMapViewPosition().getMapPosition(mMapPosition); // tell GLRenderer to call 'render' isReady = true; } @Override - public synchronized void render(MapPosition pos, float[] mv, float[] proj) { - - setMatrix(pos, mv); - Matrix.multiplyMM(mv, 0, proj, 0, mv, 0); + public synchronized void render(MapPosition pos, Matrices m) { + setMatrix(pos, m); GLState.useProgram(buildingProgram); - GLES20.glUniformMatrix4fv(hBuildingMatrix, 1, false, mv, 0); + GLES20.glUniformMatrix4fv(hBuildingMatrix, 1, false, m.mvp, 0); GLES20.glUniform4f(hBuildingColor, 0.5f, 0.5f, 0.5f, 0.7f); GLState.enableVertexArrays(hBuildingVertexPosition, hBuildingLightPosition); @@ -413,7 +412,7 @@ public class BuildingOverlay extends RenderOverlay { } @Override - protected void setMatrix(MapPosition curPos, float[] matrix) { + protected void setMatrix(MapPosition curPos, Matrices m) { MapPosition oPos = mMapPosition; @@ -432,19 +431,19 @@ public class BuildingOverlay extends RenderOverlay { float scale = curPos.scale / div; - Matrix.setIdentityM(matrix, 0); + Matrix.setIdentityM(m.mvp, 0); // translate relative to map center - matrix[12] = x * scale; - matrix[13] = y * scale; + m.mvp[12] = x * scale; + m.mvp[13] = y * scale; // scale to current tile world coordinates scale = (curPos.scale / oPos.scale) / div; scale /= GLRenderer.COORD_MULTIPLIER; - matrix[0] = scale; - matrix[5] = scale; - matrix[10] = scale / 1000f; + m.mvp[0] = scale; + m.mvp[5] = scale; + m.mvp[10] = scale / 1000f; - Matrix.multiplyMM(matrix, 0, curPos.viewMatrix, 0, matrix, 0); + Matrix.multiplyMM(m.mvp, 0, m.viewproj, 0, m.mvp, 0); } final static String buildingVertexShader = "" diff --git a/src/org/oscim/renderer/overlays/CustomOverlay.java b/src/org/oscim/renderer/overlays/CustomOverlay.java index c048dd2d..14371ddd 100644 --- a/src/org/oscim/renderer/overlays/CustomOverlay.java +++ b/src/org/oscim/renderer/overlays/CustomOverlay.java @@ -19,12 +19,12 @@ import java.nio.ByteOrder; import java.nio.FloatBuffer; import org.oscim.core.MapPosition; +import org.oscim.renderer.GLRenderer.Matrices; import org.oscim.renderer.GLState; import org.oscim.utils.GlUtils; import org.oscim.view.MapView; import android.opengl.GLES20; -import android.opengl.Matrix; /* * This is an example how to integrate custom OpenGL drawing routines as map overlay @@ -84,7 +84,7 @@ public class CustomOverlay extends RenderOverlay { } @Override - public void render(MapPosition pos, float[] tmp, float[] proj) { + public void render(MapPosition pos, Matrices m) { // Use the program object GLState.useProgram(mProgramObject); @@ -106,12 +106,14 @@ public class CustomOverlay extends RenderOverlay { /* apply view and projection matrices */ // set mvp (tmp) matrix relative to mMapPosition // i.e. fixed on the map - setMatrix(pos, tmp); - Matrix.multiplyMM(tmp, 0, proj, 0, tmp, 0); + setMatrix(pos, m); + + //Matrix.multiplyMM(tmp, 0, proj, 0, tmp, 0); + // or set mvp matrix fixed on screen center // Matrix.multiplyMM(tmp, 0, proj, 0, pos.viewMatrix, 0); - GLES20.glUniformMatrix4fv(hMatrixPosition, 1, false, tmp, 0); + GLES20.glUniformMatrix4fv(hMatrixPosition, 1, false, m.mvp, 0); // Draw the triangle GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); diff --git a/src/org/oscim/renderer/overlays/ExtrusionOverlay.java b/src/org/oscim/renderer/overlays/ExtrusionOverlay.java index f281186a..b7c9f868 100644 --- a/src/org/oscim/renderer/overlays/ExtrusionOverlay.java +++ b/src/org/oscim/renderer/overlays/ExtrusionOverlay.java @@ -21,6 +21,7 @@ import java.nio.ShortBuffer; import org.oscim.core.MapPosition; import org.oscim.generator.JobTile; import org.oscim.renderer.GLRenderer; +import org.oscim.renderer.GLRenderer.Matrices; import org.oscim.renderer.GLState; import org.oscim.renderer.MapTile; import org.oscim.renderer.TileSet; @@ -54,7 +55,7 @@ public class ExtrusionOverlay extends RenderOverlay { private boolean initialized = false; // FIXME sum up size used while filling layer only up to: - private int BUFFERSIZE = 65536 * 2; + private final int BUFFERSIZE = 65536 * 2; private TileSet mTileSet; private ShortBuffer mShortBuffer; private MapTile[] mTiles; @@ -64,7 +65,7 @@ public class ExtrusionOverlay extends RenderOverlay { public void update(MapPosition curPos, boolean positionChanged, boolean tilesChanged) { - mMapView.getMapViewPosition().getMapPosition(mMapPosition, null); + mMapView.getMapViewPosition().getMapPosition(mMapPosition); if (!initialized) { initialized = true; @@ -155,16 +156,16 @@ public class ExtrusionOverlay extends RenderOverlay { return null; } - private boolean debug = false; - private final float[] mVPMatrix = new float[16]; + private final boolean debug = false; + //private final float[] mVPMatrix = new float[16]; @Override - public void render(MapPosition pos, float[] mv, float[] proj) { + public void render(MapPosition pos, Matrices m) { // TODO one could render in one pass to texture and then draw the texture // with alpha... might be faster. - Matrix.multiplyMM(mVPMatrix, 0, proj, 0, pos.viewMatrix, 0); - proj = mVPMatrix; + //Matrix.multiplyMM(mVPMatrix, 0, proj, 0, pos.viewMatrix, 0); + //proj = mVPMatrix; MapTile[] tiles = mTiles; @@ -190,8 +191,8 @@ public class ExtrusionOverlay extends RenderOverlay { for (int i = 0; i < mTileCnt; i++) { ExtrusionLayer el = (ExtrusionLayer) tiles[i].layers.extrusionLayers; - setMatrix(pos, mv, proj, tiles[i], div, 0); - GLES20.glUniformMatrix4fv(uExtMatrix, 1, false, mv, 0); + setMatrix(pos, m, tiles[i], div, 0); + GLES20.glUniformMatrix4fv(uExtMatrix, 1, false, m.mvp, 0); GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, el.mIndicesBufferID); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, el.mVertexBufferID); @@ -242,8 +243,8 @@ public class ExtrusionOverlay extends RenderOverlay { MapTile t = tiles[i]; ExtrusionLayer el = (ExtrusionLayer) t.layers.extrusionLayers; int d = GLRenderer.depthOffset(t) * 10; - setMatrix(pos, mv, proj, t, div, d); - GLES20.glUniformMatrix4fv(uExtMatrix, 1, false, mv, 0); + setMatrix(pos, m, t, div, d); + GLES20.glUniformMatrix4fv(uExtMatrix, 1, false, m.mvp, 0); GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, el.mIndicesBufferID); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, el.mVertexBufferID); @@ -268,8 +269,8 @@ public class ExtrusionOverlay extends RenderOverlay { GLES20.glDepthFunc(GLES20.GL_EQUAL); int d = GLRenderer.depthOffset(t) * 10; - setMatrix(pos, mv, proj, t, div, d); - GLES20.glUniformMatrix4fv(uExtMatrix, 1, false, mv, 0); + setMatrix(pos, m, t, div, d); + GLES20.glUniformMatrix4fv(uExtMatrix, 1, false, m.mvp, 0); GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, el.mIndicesBufferID); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, el.mVertexBufferID); @@ -298,8 +299,8 @@ public class ExtrusionOverlay extends RenderOverlay { // drawing gl_lines with the same coordinates does not result in // same depth values as polygons, so add offset and draw gl_lequal: GLES20.glDepthFunc(GLES20.GL_LEQUAL); - GlUtils.addOffsetM(mv, 100); - GLES20.glUniformMatrix4fv(uExtMatrix, 1, false, mv, 0); + GlUtils.addOffsetM(m.mvp, 100); + GLES20.glUniformMatrix4fv(uExtMatrix, 1, false, m.mvp, 0); GLES20.glUniform1i(uExtMode, 3); GLES20.glDrawElements(GLES20.GL_LINES, el.mIndiceCnt[3], @@ -315,20 +316,20 @@ public class ExtrusionOverlay extends RenderOverlay { GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0); } - private static void setMatrix(MapPosition mapPosition, float[] matrix, float[] proj, + private static void setMatrix(MapPosition mapPosition, Matrices m, MapTile tile, float div, int delta) { float x = (float) (tile.pixelX - mapPosition.x * div); float y = (float) (tile.pixelY - mapPosition.y * div); float scale = mapPosition.scale / div; - GlUtils.setTileMatrix(matrix, x, y, scale); + GlUtils.setTileMatrix(m.mvp, x, y, scale); // scale height - matrix[10] = scale / (1000f * GLRenderer.COORD_MULTIPLIER); + m.mvp[10] = scale / (1000f * GLRenderer.COORD_MULTIPLIER); - Matrix.multiplyMM(matrix, 0, proj, 0, matrix, 0); + Matrix.multiplyMM(m.mvp, 0, m.viewproj, 0, m.mvp, 0); - GlUtils.addOffsetM(matrix, delta); + GlUtils.addOffsetM(m.mvp, delta); } private final float _a = 0.86f; diff --git a/src/org/oscim/renderer/overlays/ModelOverlay.java b/src/org/oscim/renderer/overlays/ModelOverlay.java index 25202e08..c658bb12 100644 --- a/src/org/oscim/renderer/overlays/ModelOverlay.java +++ b/src/org/oscim/renderer/overlays/ModelOverlay.java @@ -22,6 +22,7 @@ import java.nio.ShortBuffer; import org.oscim.core.MapPosition; import org.oscim.core.Tile; import org.oscim.renderer.GLRenderer; +import org.oscim.renderer.GLRenderer.Matrices; import org.oscim.renderer.GLState; import org.oscim.utils.FastMath; import org.oscim.utils.GlUtils; @@ -160,17 +161,16 @@ public class ModelOverlay extends RenderOverlay { GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, 64 * 4, fbuf, GLES20.GL_STATIC_DRAW); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); - mMapView.getMapViewPosition().getMapPosition(mMapPosition, null); + mMapView.getMapViewPosition().getMapPosition(mMapPosition); // tell GLRenderer to call 'render' isReady = true; } @Override - public synchronized void render(MapPosition pos, float[] mv, float[] proj) { + public synchronized void render(MapPosition pos, Matrices m) { - setMatrix(pos, mv); - Matrix.multiplyMM(mv, 0, proj, 0, mv, 0); + setMatrix(pos, m); GLState.useProgram(polygonProgram); @@ -182,7 +182,7 @@ public class ModelOverlay extends RenderOverlay { GLES20.glVertexAttribPointer(hPolygonVertexPosition, 3, GLES20.GL_FLOAT, false, 16, 0); GLES20.glVertexAttribPointer(hPolygonLightPosition, 1, GLES20.GL_FLOAT, false, 16, 12); - GLES20.glUniformMatrix4fv(hPolygonMatrix, 1, false, mv, 0); + GLES20.glUniformMatrix4fv(hPolygonMatrix, 1, false, m.mvp, 0); GLES20.glUniform4f(hPolygonColor, 0.5f, 0.5f, 0.5f, 0.7f); // draw to depth buffer @@ -211,7 +211,7 @@ public class ModelOverlay extends RenderOverlay { } @Override - protected void setMatrix(MapPosition curPos, float[] matrix) { + protected void setMatrix(MapPosition curPos, Matrices m) { // TODO if oPos == curPos this could be simplified MapPosition oPos = mMapPosition; @@ -231,19 +231,19 @@ public class ModelOverlay extends RenderOverlay { float scale = curPos.scale / div; - Matrix.setIdentityM(matrix, 0); + Matrix.setIdentityM(m.mvp, 0); // translate relative to map center - matrix[12] = x * scale; - matrix[13] = y * scale; + m.mvp[12] = x * scale; + m.mvp[13] = y * scale; // scale to current tile world coordinates scale = (curPos.scale / oPos.scale) / div; scale /= GLRenderer.COORD_MULTIPLIER; - matrix[0] = scale; - matrix[5] = scale; - matrix[10] = scale; // 1000f; + m.mvp[0] = scale; + m.mvp[5] = scale; + m.mvp[10] = scale; // 1000f; - Matrix.multiplyMM(matrix, 0, curPos.viewMatrix, 0, matrix, 0); + Matrix.multiplyMM(m.mvp, 0, m.viewproj, 0, m.mvp, 0); } @Override diff --git a/src/org/oscim/renderer/overlays/RenderOverlay.java b/src/org/oscim/renderer/overlays/RenderOverlay.java index a9f3e6f0..4bf93e80 100644 --- a/src/org/oscim/renderer/overlays/RenderOverlay.java +++ b/src/org/oscim/renderer/overlays/RenderOverlay.java @@ -17,6 +17,7 @@ package org.oscim.renderer.overlays; 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.utils.GlUtils; import org.oscim.view.MapView; @@ -65,21 +66,21 @@ public abstract class RenderOverlay { * * @param pos * current MapPosition - * @param mv - * current model-view matrix - * @param proj - * current projection matrix + * @param m + * current render matrices + matrix for temporary use */ - public abstract void render(MapPosition pos, float[] mv, float[] proj); + public abstract void render(MapPosition pos, Matrices m); /** - * Utility: set 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 matrix ... + * @param m ... + * @param project + * apply view and projection, or just view otherwise */ - protected void setMatrix(MapPosition curPos, float[] matrix) { + protected void setMatrix(MapPosition curPos, Matrices m, boolean project) { MapPosition oPos = mMapPosition; float div = FastMath.pow(oPos.zoomLevel - curPos.zoomLevel); @@ -101,10 +102,24 @@ public abstract class RenderOverlay { // set scale to be relative to current scale float s = (curPos.scale / oPos.scale) / div; - GlUtils.setMatrix(matrix, x * scale, y * scale, + GlUtils.setMatrix(m.mvp, x * scale, y * scale, s / GLRenderer.COORD_MULTIPLIER); - Matrix.multiplyMM(matrix, 0, curPos.viewMatrix, 0, matrix, 0); + if (project) + Matrix.multiplyMM(m.mvp, 0, m.viewproj, 0, m.mvp, 0); + else + Matrix.multiplyMM(m.mvp, 0, m.view, 0, m.mvp, 0); + } + + /** + * Utility: set m.mvp matrix relative to the difference of current MapPosition + * and the last updated Overlay MapPosition and add m.viewproj + * + * @param curPos ... + * @param m ... + */ + protected void setMatrix(MapPosition curPos, Matrices m) { + setMatrix(curPos, m, true); } /** @@ -113,6 +128,6 @@ public abstract class RenderOverlay { * @return true if position has changed */ protected boolean updateMapPosition() { - return mMapView.getMapViewPosition().getMapPosition(mMapPosition, null); + return mMapView.getMapViewPosition().getMapPosition(mMapPosition); } } diff --git a/src/org/oscim/renderer/overlays/TestLineOverlay.java b/src/org/oscim/renderer/overlays/TestLineOverlay.java index 6a0a7f9e..9c5fb502 100644 --- a/src/org/oscim/renderer/overlays/TestLineOverlay.java +++ b/src/org/oscim/renderer/overlays/TestLineOverlay.java @@ -21,6 +21,7 @@ import java.nio.ShortBuffer; import org.oscim.core.MapPosition; import org.oscim.core.Tile; import org.oscim.renderer.GLRenderer; +import org.oscim.renderer.GLRenderer.Matrices; import org.oscim.renderer.GLState; import org.oscim.utils.FastMath; import org.oscim.utils.GlUtils; @@ -73,31 +74,31 @@ public class TestLineOverlay extends RenderOverlay { // -> max line length is 2^12/4=1024 // - texture 'end' is 'length'-'start' - private final short[] box = { - // '-' start - 0, 0, 0, 0, - // 0. - -800, 0, 255, 0, - // 2. - 100, 0, 255, 0, - // 1. - 0, 0, 255, 1, - // 3. - 800, 0, 255, 1, - - -800, 200, 127, 0, - 0, 200, 127, 0, - 0, 200, 127, 1, - 800, 200, 127, 1, - - -800, 400, 255, 0, - 0, 400, 255, 0, - 0, 400, 255, 1, - 800, 400, 255, 1, - - // '-' end - 0, 0, 0, 0, - }; + // private final short[] box = { + // // '-' start + // 0, 0, 0, 0, + // // 0. + // -800, 0, 255, 0, + // // 2. + // 100, 0, 255, 0, + // // 1. + // 0, 0, 255, 1, + // // 3. + // 800, 0, 255, 1, + // + // -800, 200, 127, 0, + // 0, 200, 127, 0, + // 0, 200, 127, 1, + // 800, 200, 127, 1, + // + // -800, 400, 255, 0, + // 0, 400, 255, 0, + // 0, 400, 255, 1, + // 800, 400, 255, 1, + // + // // '-' end + // 0, 0, 0, 0, + // }; private short[] indices = { 0, 1, 2, @@ -298,17 +299,17 @@ public class TestLineOverlay extends RenderOverlay { GLES20.GL_STATIC_DRAW); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); - mMapView.getMapViewPosition().getMapPosition(mMapPosition, null); + mMapView.getMapViewPosition().getMapPosition(mMapPosition); // tell GLRenderer to call 'render' isReady = true; } @Override - public synchronized void render(MapPosition pos, float[] mv, float[] proj) { + public synchronized void render(MapPosition pos, Matrices m) { - setMatrix(pos, mv); - Matrix.multiplyMM(mv, 0, proj, 0, mv, 0); + setMatrix(pos, m); + //Matrix.multiplyMM(mv, 0, proj, 0, mv, 0); GLState.useProgram(testProgram); GLES20.glDisable(GLES20.GL_CULL_FACE); @@ -319,7 +320,7 @@ public class TestLineOverlay extends RenderOverlay { GLES20.glEnableVertexAttribArray(htestVertexFlip); - GLES20.glUniformMatrix4fv(htestMatrix, 1, false, mv, 0); + GLES20.glUniformMatrix4fv(htestMatrix, 1, false, m.mvp, 0); GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mIndicesBufferID); @@ -355,7 +356,7 @@ public class TestLineOverlay extends RenderOverlay { } @Override - protected void setMatrix(MapPosition curPos, float[] matrix) { + protected void setMatrix(MapPosition curPos, Matrices m) { MapPosition oPos = mMapPosition; byte z = oPos.zoomLevel; @@ -373,19 +374,19 @@ public class TestLineOverlay extends RenderOverlay { float scale = curPos.scale / div; - Matrix.setIdentityM(matrix, 0); + Matrix.setIdentityM(m.mvp, 0); // translate relative to map center - matrix[12] = x * scale; - matrix[13] = y * scale; + m.mvp[12] = x * scale; + m.mvp[13] = y * scale; // scale to current tile world coordinates scale = (curPos.scale / oPos.scale) / div; scale /= GLRenderer.COORD_MULTIPLIER; - matrix[0] = scale; - matrix[5] = scale; - matrix[10] = 1; //scale; // 1000f; + m.mvp[0] = scale; + m.mvp[5] = scale; + m.mvp[10] = 1; //scale; // 1000f; - Matrix.multiplyMM(matrix, 0, curPos.viewMatrix, 0, matrix, 0); + Matrix.multiplyMM(m.mvp, 0, m.viewproj, 0, m.mvp, 0); } @Override diff --git a/src/org/oscim/renderer/overlays/TextOverlay.java b/src/org/oscim/renderer/overlays/TextOverlay.java index bf2ffd92..8ba9c341 100644 --- a/src/org/oscim/renderer/overlays/TextOverlay.java +++ b/src/org/oscim/renderer/overlays/TextOverlay.java @@ -18,6 +18,7 @@ package org.oscim.renderer.overlays; import org.oscim.core.MapPosition; import org.oscim.core.Tile; import org.oscim.renderer.GLRenderer; +import org.oscim.renderer.GLRenderer.Matrices; import org.oscim.renderer.MapTile; import org.oscim.renderer.TileSet; import org.oscim.renderer.layer.Layer; @@ -45,7 +46,7 @@ public class TextOverlay extends BasicOverlay { private final static String TAG = TextOverlay.class.getName(); private TileSet mTiles; - private LabelThread mThread; + private final LabelThread mThread; private MapPosition mWorkPos; @@ -170,7 +171,7 @@ public class TextOverlay extends BasicOverlay { if (mTiles.cnt == 0) return; - mMapView.getMapViewPosition().getMapPosition(mWorkPos, null); + mMapView.getMapViewPosition().getMapPosition(mWorkPos); TextLayer tl = mWorkLayer; @@ -415,7 +416,7 @@ public class TextOverlay extends BasicOverlay { } @Override - protected void setMatrix(MapPosition curPos, float[] matrix) { + protected void setMatrix(MapPosition curPos, Matrices m) { MapPosition oPos = mMapPosition; float div = FastMath.pow(oPos.zoomLevel - curPos.zoomLevel); @@ -424,10 +425,10 @@ public class TextOverlay extends BasicOverlay { float scale = curPos.scale / div; - GlUtils.setMatrix(matrix, x * scale, y * scale, + GlUtils.setMatrix(m.mvp, x * scale, y * scale, scale / GLRenderer.COORD_MULTIPLIER); - Matrix.multiplyMM(matrix, 0, curPos.viewMatrix, 0, matrix, 0); + Matrix.multiplyMM(m.mvp, 0, m.view, 0, m.mvp, 0); } private boolean mHolding; diff --git a/src/org/oscim/renderer/overlays/TextOverlayExp.java b/src/org/oscim/renderer/overlays/TextOverlayExp.java index e72c60e1..11c112bc 100644 --- a/src/org/oscim/renderer/overlays/TextOverlayExp.java +++ b/src/org/oscim/renderer/overlays/TextOverlayExp.java @@ -17,12 +17,13 @@ package org.oscim.renderer.overlays; // TODO // 1. rewrite :) +// 1.1 test if label is actually visible // 2. compare previous to current state // 2.1 test for new labels to be placed // 2.2 handle collisions // 3 join segments that belong to one feature // 4 handle zoom-level changes -// 5 3D-Tree might be handy +// 5 R-Tree might be handy // import java.util.HashMap; @@ -32,6 +33,7 @@ import org.oscim.core.Tile; import org.oscim.generator.JobTile; import org.oscim.renderer.BufferObject; import org.oscim.renderer.GLRenderer; +import org.oscim.renderer.GLRenderer.Matrices; import org.oscim.renderer.GLState; import org.oscim.renderer.LineRenderer; import org.oscim.renderer.MapTile; @@ -49,6 +51,7 @@ import org.oscim.utils.GlUtils; import org.oscim.utils.OBB2D; import org.oscim.utils.PausableThread; import org.oscim.view.MapView; +import org.oscim.view.MapViewPosition; import android.graphics.Color; import android.graphics.Paint.Cap; @@ -60,6 +63,7 @@ import android.util.Log; public class TextOverlayExp extends BasicOverlay { private final static String TAG = TextOverlayExp.class.getName(); + private final MapViewPosition mMapViewPosition; private TileSet mTileSet; private final LabelThread mThread; @@ -70,6 +74,8 @@ public class TextOverlayExp extends BasicOverlay { // TextLayer that is ready to be added to 'layers' private TextLayer mNextLayer; + private final float[] mTmpCoords = new float[8]; + /* package */boolean mRun; class LabelThread extends PausableThread { @@ -102,6 +108,7 @@ public class TextOverlayExp extends BasicOverlay { public TextOverlayExp(MapView mapView) { super(mapView); + mMapViewPosition = mapView.getMapViewPosition(); layers.textureLayers = new TextLayer(); mTmpLayer = new TextLayer(); @@ -145,10 +152,6 @@ public class TextOverlayExp extends BasicOverlay { private byte checkOverlap(TextLayer tl, TextItem ti) { for (TextItem lp = tl.labels; lp != null;) { - if (lp.text.caption) { - lp = lp.next; - continue; - } // check bounding box if (!TextItem.bboxOverlaps(ti, lp, 100)) { @@ -186,11 +189,12 @@ public class TextOverlayExp extends BasicOverlay { if (ti.bbox == null) { ti.bbox = new OBB2D(ti.x, ti.y, ti.x1, ti.y1, - ti.width + 10, ti.text.fontHeight + 10); + ti.width + 5, ti.text.fontHeight + 5); } + if (lp.bbox == null) { lp.bbox = new OBB2D(lp.x, lp.y, lp.x1, lp.y1, - lp.width + 10, lp.text.fontHeight + 10); + lp.width + 5, lp.text.fontHeight + 5); } boolean intersect = ti.bbox.overlaps(lp.bbox); @@ -203,9 +207,8 @@ public class TextOverlayExp extends BasicOverlay { //Log.d(TAG, "intersection " + lp.string + " <> " + ti.string // + " at " + ti.x + ":" + ti.y); - if (lp.text.priority > ti.text.priority || lp.length < ti.length) { - //if (lp.length > ti.length) { - //Log.d(TAG, "drop " + lp.string); + if (!lp.text.caption + && (lp.text.priority > ti.text.priority || lp.length < ti.length)) { TextItem tmp = lp; lp = lp.next; @@ -241,35 +244,50 @@ public class TextOverlayExp extends BasicOverlay { return 0; } + private int mMinX; + private int mMinY; + private int mMaxX; + private int mMaxY; + + private boolean isVisible(TextItem ti) { + + return true; + } + private Layers mDebugLayer; + private final float[] mMVP = new float[16]; boolean updateLabels() { if (mTmpLayer == null) return false; + // get current tiles mTileSet = GLRenderer.getVisibleTiles(mTileSet); if (mTileSet.cnt == 0) return false; + // reuse text layer TextLayer tl = mTmpLayer; mTmpLayer = null; - Layers dbg = null;//new Layers(); + Layers dbg = null; //new Layers(); + + float[] coords = mTmpCoords; + synchronized (mMapViewPosition) { + mMapViewPosition.getMapPosition(mTmpPos); + mMapViewPosition.getMapViewProjection(coords); + mMapViewPosition.getMatrix(null, null, mMVP); + } // mTiles might be from another zoomlevel than the current: // this scales MapPosition to the zoomlevel of mTiles... // TODO create a helper function in MapPosition - mMapView.getMapViewPosition().getMapPosition(mTmpPos, null); - // capture current state - MapTile[] tiles = mTileSet.tiles; - int diff = tiles[0].zoomLevel - mTmpPos.zoomLevel; - float div = FastMath.pow(diff); - float scale = mTmpPos.scale * div; + double angle = Math.toRadians(mTmpPos.angle); float cos = (float) Math.cos(angle); float sin = (float) Math.sin(angle); @@ -301,9 +319,6 @@ public class TextOverlayExp extends BasicOverlay { if (t.state == JobTile.STATE_NONE || t.state == JobTile.STATE_LOADING) continue; - //if (t.joined != MapTile.JOINED) - // joinTile() - float dx = (float) (t.pixelX - mTmpPos.x); float dy = (float) (t.pixelY - mTmpPos.y); @@ -329,33 +344,70 @@ public class TextOverlayExp extends BasicOverlay { } } - if (ti.text.caption) { - ti2.move(ti, dx, dy, scale); - ti2.setAxisAlignedBBox(); - ti2.bbox = new OBB2D(ti2.x, ti2.y, cos, -sin, ti2.width + 6, - ti2.text.fontHeight + 6, true); - - boolean overlaps = false; - for (TextItem lp = tl.labels; lp != null; lp = lp.next) { - if (!lp.text.caption) - continue; - - if (ti2.bbox.overlaps(lp.bbox)) { - Log.d(TAG, "overlap > " + ti2.string + " " + lp.string); - //if (TextItem.bboxOverlaps(ti2, lp, 4)) { - overlaps = true; - break; - } - } - if (!overlaps) { - tl.addText(ti2); - ti2 = null; - } - + if (!ti.text.caption) continue; + + ti2.move(ti, dx, dy, scale); + ti2.setAxisAlignedBBox(); + + ti2.bbox = new OBB2D(ti2.x, ti2.y, cos, -sin, ti2.width + 6, + ti2.text.fontHeight + 6, true); + + boolean overlaps = false; + for (TextItem lp = tl.labels; lp != null; lp = lp.next) { + if (!lp.text.caption) + continue; + + if (ti2.bbox.overlaps(lp.bbox)) { + Log.d(TAG, "overlap > " + ti2.string + " " + lp.string); + //if (TextItem.bboxOverlaps(ti2, lp, 4)) { + overlaps = true; + break; + } + } + if (!overlaps) { + tl.addText(ti2); + ti2 = null; } - /* text is way label */ + } + } + + /* add way labels */ + for (int i = 0, n = mTileSet.cnt; i < n; i++) { + + MapTile t = tiles[i]; + + if (t.state == JobTile.STATE_NONE || t.state == JobTile.STATE_LOADING) + continue; + + float dx = (float) (t.pixelX - mTmpPos.x); + float dy = (float) (t.pixelY - mTmpPos.y); + + // flip around date-line + if (dx > maxx) { + dx = dx - maxx * 2; + } else if (dx < -maxx) { + dx = dx + maxx * 2; + } + dx *= scale; + dy *= scale; + + for (TextItem ti = t.labels; ti != null; ti = ti.next) { + + if (ti.text.caption) + continue; + + // acquire a TextItem to add to TextLayer + if (ti2 == null) { + if (mPool == null) + ti2 = TextItem.get(); + else { + ti2 = mPool; + mPool = mPool.next; + ti2.next = null; + } + } // check if path at current scale is long enough for text if (dbg == null && ti.width > ti.length * scale) @@ -423,6 +475,7 @@ public class TextOverlayExp extends BasicOverlay { } } } + for (TextItem ti = tl.labels; ti != null; ti = ti.next) { // scale back to fixed zoom-level. could be done in setMatrix ti.x /= scale; @@ -457,9 +510,7 @@ public class TextOverlayExp extends BasicOverlay { tl.setScale(scale); tl.prepare(); - //TextItem.printPool(); - //Log.d(TAG, "new labels: " + count); - + // remove tile locks GLRenderer.releaseTiles(mTileSet); // pass new labels for rendering @@ -514,12 +565,8 @@ public class TextOverlayExp extends BasicOverlay { @Override public void compile() { int newSize = layers.getSize(); - //if (newSize == 0) - // Log.d(TAG, "text layer size " + newSize); if (newSize == 0) { - //BufferObject.release(vbo); - //vbo = null; isReady = false; return; } @@ -535,31 +582,34 @@ public class TextOverlayExp extends BasicOverlay { } @Override - public synchronized void render(MapPosition pos, float[] mv, float[] proj) { - setMatrix(pos, mv); + public synchronized void render(MapPosition pos, Matrices m) { float div = FastMath.pow(mMapPosition.zoomLevel - pos.zoomLevel); - Matrix.multiplyMM(mvp, 0, proj, 0, mv, 0); - GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbo.id); GLState.test(false, false); - for (Layer l = layers.layers; l != null;) { - if (l.type == Layer.POLYGON) { - l = PolygonRenderer.draw(pos, l, mvp, true, false); - } else { - l = LineRenderer.draw(pos, l, mvp, div, 0, layers.lineOffset); + if (layers.layers != null) { + setMatrix(pos, m); + Matrix.multiplyMM(m.mvp, 0, m.proj, 0, m.mvp,0); + for (Layer l = layers.layers; l != null;) { + if (l.type == Layer.POLYGON) { + l = PolygonRenderer.draw(pos, l, m.mvp, true, false); + } else { + l = LineRenderer.draw(pos, l, m.mvp, div, 0, layers.lineOffset); + } } } + setMatrix(pos, m); for (Layer l = layers.textureLayers; l != null;) { - l = TextureRenderer.draw(l, (mMapPosition.scale / pos.scale) * div, proj, mv); + float scale = (mMapPosition.scale / pos.scale) * div; + l = TextureRenderer.draw(l, scale, m.proj, m.mvp); } } @Override - protected void setMatrix(MapPosition curPos, float[] matrix) { + protected void setMatrix(MapPosition curPos, Matrices m) { MapPosition oPos = mMapPosition; float div = FastMath.pow(oPos.zoomLevel - curPos.zoomLevel); @@ -568,10 +618,10 @@ public class TextOverlayExp extends BasicOverlay { float scale = curPos.scale / div; - GlUtils.setMatrix(matrix, x * scale, y * scale, + GlUtils.setMatrix(m.mvp, x * scale, y * scale, scale / GLRenderer.COORD_MULTIPLIER); - Matrix.multiplyMM(matrix, 0, curPos.viewMatrix, 0, matrix, 0); + Matrix.multiplyMM(m.mvp, 0, m.view, 0, m.mvp, 0); } private boolean mHolding; diff --git a/src/org/oscim/utils/FastMath.java b/src/org/oscim/utils/FastMath.java index b8b257d7..e5bb1bd6 100644 --- a/src/org/oscim/utils/FastMath.java +++ b/src/org/oscim/utils/FastMath.java @@ -65,7 +65,13 @@ public class FastMath { return a2 < a1 ? a1 : a2; } + // test if any absolute value is greater than 'cmp' public static boolean absMaxCmp(float value1, float value2, float cmp){ return value1 < -cmp || value1 > cmp || value2 < -cmp || value2 > cmp; } + + // test if any absolute value is greater than 'cmp' + public static boolean absMaxCmp(int value1, int value2, int cmp){ + return value1 < -cmp || value1 > cmp || value2 < -cmp || value2 > cmp; + } } diff --git a/src/org/oscim/view/MapViewPosition.java b/src/org/oscim/view/MapViewPosition.java index c75ef901..c3444d80 100644 --- a/src/org/oscim/view/MapViewPosition.java +++ b/src/org/oscim/view/MapViewPosition.java @@ -66,7 +66,7 @@ public class MapViewPosition { private double mPosX; private double mPosY; - private AnimationHandler mHandler; + private final AnimationHandler mHandler; MapViewPosition(MapView mapView) { mMapView = mapView; @@ -81,18 +81,19 @@ public class MapViewPosition { mHandler = new AnimationHandler(this); } - private float[] mProjMatrix = new float[16]; - private float[] mProjMatrixI = new float[16]; - private float[] mUnprojMatrix = new float[16]; - private float[] mViewMatrix = new float[16]; - private float[] mRotMatrix = new float[16]; - private float[] mTmpMatrix = new float[16]; + private final float[] mProjMatrix = new float[16]; + private final float[] mProjMatrixI = new float[16]; + private final float[] mUnprojMatrix = new float[16]; + private final float[] mViewMatrix = new float[16]; + private final float[] mVPMatrix = new float[16]; + private final float[] mRotMatrix = new float[16]; + private final float[] mTmpMatrix = new float[16]; // temporary vars: only use in synchronized functions! - private Point2D mMovePoint = new Point2D(); - private float[] mv = { 0, 0, 0, 1 }; - private float[] mu = { 0, 0, 0, 1 }; - private float[] mBBoxCoords = new float[8]; + private final Point2D mMovePoint = new Point2D(); + private final float[] mv = { 0, 0, 0, 1 }; + private final float[] mu = { 0, 0, 0, 1 }; + private final float[] mBBoxCoords = new float[8]; private float mHeight, mWidth; @@ -120,8 +121,7 @@ public class MapViewPosition { updateMatrix(); } - public synchronized boolean getMapPosition(final MapPosition mapPosition, - final float[] projection) { + public synchronized boolean getMapPosition(final MapPosition mapPosition) { // if (!isValid()) // return false; @@ -145,21 +145,34 @@ public class MapViewPosition { mapPosition.x = mPosX; mapPosition.y = mPosY; - if (mapPosition.viewMatrix != null) - System.arraycopy(mViewMatrix, 0, mapPosition.viewMatrix, 0, 16); + return true; + } - if (projection == null) - return true; + /** + * get a copy of current matrices + * @param view ... + * @param proj ... + * @param vp view and projection + */ + public synchronized void getMatrix(float[] view, float[] proj, float[] vp) { + if (view != null) + System.arraycopy(mViewMatrix, 0, view, 0, 16); + if (proj!= null) + System.arraycopy(mProjMatrix, 0, proj, 0, 16); + + if (vp != null) + System.arraycopy(mVPMatrix, 0, vp, 0, 16); + } + + public synchronized void getMapViewProjection(float[] box) { float t = getZ(1); float t2 = getZ(-1); - unproject(1, -1, t, projection, 0); // top-right - unproject(-1, -1, t, projection, 2); // top-left - unproject(-1, 1, t2, projection, 4); // bottom-left - unproject(1, 1, t2, projection, 6); // bottom-right - - return true; + unproject(1, -1, t, box, 0); // top-right + unproject(-1, -1, t, box, 2); // top-left + unproject(-1, 1, t2, box, 4); // bottom-left + unproject(1, 1, t2, box, 6); // bottom-right } // get the z-value of the map-plane for a point on screen @@ -365,8 +378,9 @@ public class MapViewPosition { mv[2] = 0; mv[3] = 1; - Matrix.multiplyMV(mv, 0, mViewMatrix, 0, mv, 0); - Matrix.multiplyMV(mv, 0, mProjMatrix, 0, mv, 0); + // Matrix.multiplyMV(mv, 0, mViewMatrix, 0, mv, 0); + // Matrix.multiplyMV(mv, 0, mProjMatrix, 0, mv, 0); + Matrix.multiplyMV(mv, 0, mVPMatrix, 0, mv, 0); out.x = (int) (mv[0] / mv[3] * mWidth / 2); out.y = (int) (mv[1] / mv[3] * mHeight / 2); @@ -376,10 +390,6 @@ public class MapViewPosition { return out; } - public synchronized void getMVP(float[] matrix) { - Matrix.multiplyMM(matrix, 0, mProjMatrix, 0, mViewMatrix, 0); - } - // public static Point project(float x, float y, float[] matrix, float[] tmpVec, Point reuse) { // Point out = reuse == null ? new Point() : reuse; // @@ -420,6 +430,8 @@ public class MapViewPosition { Matrix.multiplyMM(mViewMatrix, 0, mRotMatrix, 0, mTmpMatrix, 0); + Matrix.multiplyMM(mVPMatrix, 0, mProjMatrix, 0, mViewMatrix, 0); + //--- unproject matrix: // Matrix.multiplyMM(mTmpMatrix, 0, mProjMatrix, 0, mViewMatrix, 0); // Matrix.invertM(mUnprojMatrix, 0, mTmpMatrix, 0);