refactor: dont pass matrices with MapPosition -> use GLRender.Matrices

This commit is contained in:
Hannes Janetzek 2013-02-15 16:56:13 +01:00
parent 811ff6ed4a
commit 55030c1166
17 changed files with 362 additions and 272 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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();

View File

@ -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);
}
}
}

View File

@ -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 = ""

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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);
}
}

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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);