fix bug in extrusion layer where triangulation did modify the point array as side-effect

This commit is contained in:
Hannes Janetzek 2013-04-08 22:06:00 +02:00
parent 129a780c41
commit 02812d30f5

View File

@ -18,6 +18,7 @@ import java.nio.ByteBuffer;
import java.nio.ByteOrder; import java.nio.ByteOrder;
import java.nio.ShortBuffer; import java.nio.ShortBuffer;
import org.oscim.core.GeometryBuffer;
import org.oscim.core.Tile; import org.oscim.core.Tile;
import org.oscim.database.IMapDatabaseCallback.WayData; import org.oscim.database.IMapDatabaseCallback.WayData;
import org.oscim.renderer.BufferObject; import org.oscim.renderer.BufferObject;
@ -76,13 +77,9 @@ public class ExtrusionLayer extends Layer {
} }
public void addBuildings(WayData way) { public void addBuildings(WayData way) {
//
// start outer ring short[] index = way.geom.index;
int outer = 0; float[] points = way.geom.points;
boolean simple = true;
int startVertex = mNumVertices;
float height = way.height; float height = way.height;
float minHeight = way.minHeight; float minHeight = way.minHeight;
@ -105,9 +102,19 @@ public class ExtrusionLayer extends Layer {
height *= 0.85; height *= 0.85;
minHeight *= 0.85; minHeight *= 0.85;
int length = 0; int length = 0, ipos = 0, ppos = 0;
for (int ipos = 0, ppos = 0, n = way.geom.index.length; ipos < n; ipos++, ppos += length) {
length = way.geom.index[ipos]; boolean complexOutline = false;
int geomIndexPos = 0;
int geomPointPos = 0;
boolean simpleOutline = true;
// current vertex id
int startVertex = mNumVertices;
for (int n = index.length; ipos < n; ipos++, ppos += length) {
length = index[ipos];
// end marker // end marker
if (length < 0) if (length < 0)
@ -115,9 +122,12 @@ public class ExtrusionLayer extends Layer {
// start next polygon // start next polygon
if (length == 0) { if (length == 0) {
outer = ipos + 1; if (complexOutline)
addRoof(startVertex, way.geom, geomIndexPos, geomPointPos);
startVertex = mNumVertices; startVertex = mNumVertices;
simple = true; simpleOutline = true;
complexOutline = false;
continue; continue;
} }
@ -125,8 +135,8 @@ public class ExtrusionLayer extends Layer {
int len = length; int len = length;
if (!MapView.enableClosePolygons) { if (!MapView.enableClosePolygons) {
len -= 2; len -= 2;
} else if (way.geom.points[ppos] == way.geom.points[ppos + len - 2] } else if (points[ppos] == points[ppos + len - 2]
&& way.geom.points[ppos + 1] == way.geom.points[ppos + len - 1]) { && points[ppos + 1] == points[ppos + len - 1]) {
// vector-tile-map does not produce implicty closed // vector-tile-map does not produce implicty closed
// polygons (yet) // polygons (yet)
len -= 2; len -= 2;
@ -137,17 +147,23 @@ public class ExtrusionLayer extends Layer {
continue; continue;
// check if polygon contains inner rings // check if polygon contains inner rings
if (simple && (ipos < n - 1) && (way.geom.index[ipos + 1] > 0)) if (simpleOutline && (ipos < n - 1) && (index[ipos + 1] > 0))
simple = false; simpleOutline = false;
boolean convex = addOutline(way.geom.points, ppos, len, minHeight, height, simple); boolean convex = addOutline(points, ppos, len, minHeight, height, simpleOutline);
if (simple && (convex || len <= 8)) if (simpleOutline && (convex || len <= 8))
addRoofSimple(startVertex, len); addRoofSimple(startVertex, len);
else if (ipos == outer) { // add roof only once else if (!complexOutline) {
addRoof(startVertex, way.geom.index, ipos, way.geom.points, ppos); complexOutline = true;
// keep start postion of polygon and defer roof building
// as it modifies the geometry array.
geomIndexPos = ipos;
geomPointPos = ppos;
} }
} }
if (complexOutline)
addRoof(startVertex, way.geom, geomIndexPos, geomPointPos);
} }
private void addRoofSimple(int startVertex, int len) { private void addRoofSimple(int startVertex, int len) {
@ -172,7 +188,10 @@ public class ExtrusionLayer extends Layer {
mCurIndices[IND_ROOF].used = i; mCurIndices[IND_ROOF].used = i;
} }
private void addRoof(int startVertex, short[] index, int ipos, float[] points, int ppos) { private void addRoof(int startVertex, GeometryBuffer geom, int ipos, int ppos) {
short[] index = geom.index;
float[] points = geom.points;
int len = 0; int len = 0;
int rings = 0; int rings = 0;