- add multi-linestrings / -polygons in one go

This commit is contained in:
Hannes Janetzek 2012-09-07 21:10:09 +02:00
parent 7c95930ba3
commit 18d10e744c
6 changed files with 491 additions and 464 deletions

View File

@ -37,7 +37,7 @@ class GLMapTile extends MapTile {
boolean newData; boolean newData;
// pointer in TileTree // pointer to access relatives in TileTree
TreeTile rel; TreeTile rel;
GLMapTile(int tileX, int tileY, byte zoomLevel) { GLMapTile(int tileX, int tileY, byte zoomLevel) {

View File

@ -23,9 +23,9 @@ import android.util.FloatMath;
class LineLayer { class LineLayer {
private static final float COORD_SCALE = MapRenderer.COORD_MULTIPLIER; private static final float COORD_SCALE = MapRenderer.COORD_MULTIPLIER;
// scale factor mapping direction vector to short values // scale factor mapping extrusion vector to short values
private static final float DIR_SCALE = 2048; private static final float DIR_SCALE = 2048;
// mask for packing last two bits of direction vector with texture coordinates // mask for packing last two bits of extrusion vector with texture coordinates
private static final int DIR_MASK = 0xFFFFFFFC; private static final int DIR_MASK = 0xFFFFFFFC;
// next layer // next layer
@ -66,11 +66,14 @@ class LineLayer {
/* /*
* line extrusion is based on code from GLMap (https://github.com/olofsj/GLMap/) by olofsj * line extrusion is based on code from GLMap (https://github.com/olofsj/GLMap/) by olofsj
*/ */
void addLine(float[] points, int pos, int length) {
void addLine(float[] points, short[] index) {
float x, y, nextX, nextY, prevX, prevY; float x, y, nextX, nextY, prevX, prevY;
float a, ux, uy, vx, vy, wx, wy; float a, ux, uy, vx, vy, wx, wy;
int ipos = pos; int tmax = Tile.TILE_SIZE + 10;
int tmin = -10;
boolean rounded = false; boolean rounded = false;
boolean squared = false; boolean squared = false;
@ -79,30 +82,6 @@ class LineLayer {
else if (line.cap == Cap.SQUARE) else if (line.cap == Cap.SQUARE)
squared = true; squared = true;
// amount of vertices used
verticesCnt += length + (rounded ? 6 : 2);
x = points[ipos++];
y = points[ipos++];
nextX = points[ipos++];
nextY = points[ipos++];
// Calculate triangle corners for the given width
vx = nextX - x;
vy = nextY - y;
a = FloatMath.sqrt(vx * vx + vy * vy);
vx = (vx / a);
vy = (vy / a);
ux = -vy;
uy = vx;
int tmax = Tile.TILE_SIZE + 10;
int tmin = -10;
if (pool == null) { if (pool == null) {
pool = curItem = ShortPool.get(); pool = curItem = ShortPool.get();
} }
@ -111,199 +90,273 @@ class LineLayer {
short v[] = si.vertices; short v[] = si.vertices;
int opos = si.used; int opos = si.used;
if (opos == ShortItem.SIZE) { for (int i = 0, pos = 0, n = index.length; i < n; i++) {
si.used = ShortItem.SIZE; int length = index[i];
si.next = ShortPool.get(); if (length < 0)
si = si.next; break;
opos = 0;
v = si.vertices;
}
short ox, oy, dx, dy; // save some vertices
int ddx, ddy; if (rounded && i > 200)
rounded = false;
ox = (short) (x * COORD_SCALE); int ipos = pos;
oy = (short) (y * COORD_SCALE);
boolean outside = (x < tmin || x > tmax || y < tmin || y > tmax); // need at least two points
if (length < 4) {
if (rounded && !outside) { pos += length;
// add first vertex twice continue;
ddx = (int) ((ux - vx) * DIR_SCALE);
ddy = (int) ((uy - vy) * DIR_SCALE);
dx = (short) (0 | ddx & DIR_MASK);
dy = (short) (2 | ddy & DIR_MASK);
v[opos++] = ox;
v[opos++] = oy;
v[opos++] = dx;
v[opos++] = dy;
if (opos == ShortItem.SIZE) {
si.used = ShortItem.SIZE;
si.next = ShortPool.get();
si = si.next;
opos = 0;
v = si.vertices;
} }
// amount of vertices used
verticesCnt += length + (rounded ? 6 : 2);
v[opos++] = ox; x = points[ipos++];
v[opos++] = oy; y = points[ipos++];
v[opos++] = dx;
v[opos++] = dy;
if (opos == ShortItem.SIZE) {
si.used = ShortItem.SIZE;
si.next = ShortPool.get();
si = si.next;
opos = 0;
v = si.vertices;
}
ddx = (int) (-(ux + vx) * DIR_SCALE);
ddy = (int) (-(uy + vy) * DIR_SCALE);
v[opos++] = ox;
v[opos++] = oy;
v[opos++] = (short) (2 | ddx & DIR_MASK);
v[opos++] = (short) (2 | ddy & DIR_MASK);
if (opos == ShortItem.SIZE) {
si.used = ShortItem.SIZE;
si.next = ShortPool.get();
si = si.next;
opos = 0;
v = si.vertices;
}
// Start of line
ddx = (int) (ux * DIR_SCALE);
ddy = (int) (uy * DIR_SCALE);
v[opos++] = ox;
v[opos++] = oy;
v[opos++] = (short) (0 | ddx & DIR_MASK);
v[opos++] = (short) (1 | ddy & DIR_MASK);
if (opos == ShortItem.SIZE) {
si.used = ShortItem.SIZE;
si.next = ShortPool.get();
si = si.next;
opos = 0;
v = si.vertices;
}
v[opos++] = ox;
v[opos++] = oy;
v[opos++] = (short) (2 | -ddx & DIR_MASK);
v[opos++] = (short) (1 | -ddy & DIR_MASK);
} else {
// outside means line is probably clipped
// TODO should align ending with tile boundary
// for now, just extend the line a little
if (squared) {
vx = 0;
vy = 0;
} else if (!outside) {
vx *= 0.5;
vy *= 0.5;
}
if (rounded)
verticesCnt -= 2;
// add first vertex twice
ddx = (int) ((ux - vx) * DIR_SCALE);
ddy = (int) ((uy - vy) * DIR_SCALE);
dx = (short) (0 | ddx & DIR_MASK);
dy = (short) (1 | ddy & DIR_MASK);
v[opos++] = ox;
v[opos++] = oy;
v[opos++] = dx;
v[opos++] = dy;
if (opos == ShortItem.SIZE) {
si.used = ShortItem.SIZE;
si.next = ShortPool.get();
si = si.next;
opos = 0;
v = si.vertices;
}
v[opos++] = ox;
v[opos++] = oy;
v[opos++] = dx;
v[opos++] = dy;
if (opos == ShortItem.SIZE) {
si.used = ShortItem.SIZE;
si.next = ShortPool.get();
si = si.next;
opos = 0;
v = si.vertices;
}
ddx = (int) (-(ux + vx) * DIR_SCALE);
ddy = (int) (-(uy + vy) * DIR_SCALE);
v[opos++] = ox;
v[opos++] = oy;
v[opos++] = (short) (2 | ddx & DIR_MASK);
v[opos++] = (short) (1 | ddy & DIR_MASK);
}
prevX = x;
prevY = y;
x = nextX;
y = nextY;
for (; ipos < pos + length;) {
nextX = points[ipos++]; nextX = points[ipos++];
nextY = points[ipos++]; nextY = points[ipos++];
// Unit vector pointing back to previous node // Calculate triangle corners for the given width
vx = prevX - x; vx = nextX - x;
vy = prevY - y; vy = nextY - y;
a = FloatMath.sqrt(vx * vx + vy * vy); a = FloatMath.sqrt(vx * vx + vy * vy);
vx = (vx / a); vx = (vx / a);
vy = (vy / a); vy = (vy / a);
// Unit vector pointing forward to next node ux = -vy;
wx = nextX - x; uy = vx;
wy = nextY - y;
a = FloatMath.sqrt(wx * wx + wy * wy); if (opos == ShortItem.SIZE) {
wx = (wx / a); si = si.next = ShortPool.get();
wy = (wy / a); v = si.vertices;
opos = 0;
// Sum of these two vectors points }
ux = vx + wx;
uy = vy + wy; short ox, oy, dx, dy;
int ddx, ddy;
a = -wy * ux + wx * uy;
ox = (short) (x * COORD_SCALE);
// boolean split = false; oy = (short) (y * COORD_SCALE);
if (a < 0.01f && a > -0.01f) {
// Almost straight boolean outside = (x < tmin || x > tmax || y < tmin || y > tmax);
ux = -wy;
uy = wx; if (opos == ShortItem.SIZE) {
} else { si = si.next = ShortPool.get();
ux = (ux / a); v = si.vertices;
uy = (uy / a); opos = 0;
}
// hack to avoid miter going to infinity
// note to myself: find my mathbook and do this properly! if (rounded && !outside) {
if (ux > 2.0f || ux < -2.0f || uy > 2.0f || uy < -2.0f) { // add first vertex twice
ux = -wy; ddx = (int) ((ux - vx) * DIR_SCALE);
uy = wx; ddy = (int) ((uy - vy) * DIR_SCALE);
} dx = (short) (0 | ddx & DIR_MASK);
} dy = (short) (2 | ddy & DIR_MASK);
v[opos++] = ox;
v[opos++] = oy;
v[opos++] = dx;
v[opos++] = dy;
if (opos == ShortItem.SIZE) {
si = si.next = ShortPool.get();
v = si.vertices;
opos = 0;
}
v[opos++] = ox;
v[opos++] = oy;
v[opos++] = dx;
v[opos++] = dy;
if (opos == ShortItem.SIZE) {
si = si.next = ShortPool.get();
v = si.vertices;
opos = 0;
}
ddx = (int) (-(ux + vx) * DIR_SCALE);
ddy = (int) (-(uy + vy) * DIR_SCALE);
v[opos++] = ox;
v[opos++] = oy;
v[opos++] = (short) (2 | ddx & DIR_MASK);
v[opos++] = (short) (2 | ddy & DIR_MASK);
if (opos == ShortItem.SIZE) {
si = si.next = ShortPool.get();
v = si.vertices;
opos = 0;
}
// Start of line
ddx = (int) (ux * DIR_SCALE);
ddy = (int) (uy * DIR_SCALE);
v[opos++] = ox;
v[opos++] = oy;
v[opos++] = (short) (0 | ddx & DIR_MASK);
v[opos++] = (short) (1 | ddy & DIR_MASK);
if (opos == ShortItem.SIZE) {
si = si.next = ShortPool.get();
v = si.vertices;
opos = 0;
}
v[opos++] = ox;
v[opos++] = oy;
v[opos++] = (short) (2 | -ddx & DIR_MASK);
v[opos++] = (short) (1 | -ddy & DIR_MASK);
} else {
// outside means line is probably clipped
// TODO should align ending with tile boundary
// for now, just extend the line a little
if (squared) {
vx = 0;
vy = 0;
} else if (!outside) {
vx *= 0.5;
vy *= 0.5;
}
if (rounded)
verticesCnt -= 2;
// add first vertex twice
ddx = (int) ((ux - vx) * DIR_SCALE);
ddy = (int) ((uy - vy) * DIR_SCALE);
dx = (short) (0 | ddx & DIR_MASK);
dy = (short) (1 | ddy & DIR_MASK);
v[opos++] = ox;
v[opos++] = oy;
v[opos++] = dx;
v[opos++] = dy;
if (opos == ShortItem.SIZE) {
si = si.next = ShortPool.get();
v = si.vertices;
opos = 0;
}
v[opos++] = ox;
v[opos++] = oy;
v[opos++] = dx;
v[opos++] = dy;
if (opos == ShortItem.SIZE) {
si = si.next = ShortPool.get();
v = si.vertices;
opos = 0;
}
ddx = (int) (-(ux + vx) * DIR_SCALE);
ddy = (int) (-(uy + vy) * DIR_SCALE);
v[opos++] = ox;
v[opos++] = oy;
v[opos++] = (short) (2 | ddx & DIR_MASK);
v[opos++] = (short) (1 | ddy & DIR_MASK);
}
prevX = x;
prevY = y;
x = nextX;
y = nextY;
for (; ipos < pos + length;) {
nextX = points[ipos++];
nextY = points[ipos++];
// Unit vector pointing back to previous node
vx = prevX - x;
vy = prevY - y;
a = FloatMath.sqrt(vx * vx + vy * vy);
vx = (vx / a);
vy = (vy / a);
// Unit vector pointing forward to next node
wx = nextX - x;
wy = nextY - y;
a = FloatMath.sqrt(wx * wx + wy * wy);
wx = (wx / a);
wy = (wy / a);
// Sum of these two vectors points
ux = vx + wx;
uy = vy + wy;
a = -wy * ux + wx * uy;
// boolean split = false;
if (a < 0.01f && a > -0.01f) {
// Almost straight
ux = -wy;
uy = wx;
} else {
ux = (ux / a);
uy = (uy / a);
// hack to avoid miter going to infinity
if (ux > 2.0f || ux < -2.0f || uy > 2.0f || uy < -2.0f) {
ux = -wy;
uy = wx;
}
}
if (opos == ShortItem.SIZE) {
si = si.next = ShortPool.get();
v = si.vertices;
opos = 0;
}
ox = (short) (x * COORD_SCALE);
oy = (short) (y * COORD_SCALE);
ddx = (int) (ux * DIR_SCALE);
ddy = (int) (uy * DIR_SCALE);
v[opos++] = ox;
v[opos++] = oy;
v[opos++] = (short) (0 | ddx & DIR_MASK);
v[opos++] = (short) (1 | ddy & DIR_MASK);
if (opos == ShortItem.SIZE) {
si = si.next = ShortPool.get();
v = si.vertices;
opos = 0;
}
v[opos++] = ox;
v[opos++] = oy;
v[opos++] = (short) (2 | -ddx & DIR_MASK);
v[opos++] = (short) (1 | -ddy & DIR_MASK);
prevX = x;
prevY = y;
x = nextX;
y = nextY;
}
vx = prevX - x;
vy = prevY - y;
a = FloatMath.sqrt(vx * vx + vy * vy);
vx = (vx / a);
vy = (vy / a);
ux = vy;
uy = -vx;
outside = (x < tmin || x > tmax || y < tmin || y > tmax);
if (opos == ShortItem.SIZE) { if (opos == ShortItem.SIZE) {
si.used = ShortItem.SIZE;
si.next = ShortPool.get(); si.next = ShortPool.get();
si = si.next; si = si.next;
opos = 0; opos = 0;
@ -313,181 +366,120 @@ class LineLayer {
ox = (short) (x * COORD_SCALE); ox = (short) (x * COORD_SCALE);
oy = (short) (y * COORD_SCALE); oy = (short) (y * COORD_SCALE);
ddx = (int) (ux * DIR_SCALE); if (rounded && !outside) {
ddy = (int) (uy * DIR_SCALE); ddx = (int) (ux * DIR_SCALE);
ddy = (int) (uy * DIR_SCALE);
v[opos++] = ox; v[opos++] = ox;
v[opos++] = oy; v[opos++] = oy;
v[opos++] = (short) (0 | ddx & DIR_MASK); v[opos++] = (short) (0 | ddx & DIR_MASK);
v[opos++] = (short) (1 | ddy & DIR_MASK); v[opos++] = (short) (1 | ddy & DIR_MASK);
if (opos == ShortItem.SIZE) { if (opos == ShortItem.SIZE) {
si.used = ShortItem.SIZE; si = si.next = ShortPool.get();
si.next = ShortPool.get(); v = si.vertices;
si = si.next; opos = 0;
opos = 0; }
v = si.vertices;
v[opos++] = ox;
v[opos++] = oy;
v[opos++] = (short) (2 | -ddx & DIR_MASK);
v[opos++] = (short) (1 | -ddy & DIR_MASK);
if (opos == ShortItem.SIZE) {
si = si.next = ShortPool.get();
v = si.vertices;
opos = 0;
}
// For rounded line edges
ddx = (int) ((ux - vx) * DIR_SCALE);
ddy = (int) ((uy - vy) * DIR_SCALE);
dx = (short) (0 | ddx & DIR_MASK);
dy = (short) (0 | ddy & DIR_MASK);
v[opos++] = ox;
v[opos++] = oy;
v[opos++] = dx;
v[opos++] = dy;
if (opos == ShortItem.SIZE) {
si = si.next = ShortPool.get();
v = si.vertices;
opos = 0;
}
// add last vertex twice
ddx = (int) (-(ux + vx) * DIR_SCALE);
ddy = (int) (-(uy + vy) * DIR_SCALE);
dx = (short) (2 | ddx & DIR_MASK);
dy = (short) (0 | ddy & DIR_MASK);
v[opos++] = ox;
v[opos++] = oy;
v[opos++] = dx;
v[opos++] = dy;
if (opos == ShortItem.SIZE) {
si = si.next = ShortPool.get();
v = si.vertices;
opos = 0;
}
v[opos++] = ox;
v[opos++] = oy;
v[opos++] = dx;
v[opos++] = dy;
} else {
if (squared) {
vx = 0;
vy = 0;
} else if (!outside) {
vx *= 0.5;
vy *= 0.5;
}
if (rounded)
verticesCnt -= 2;
ddx = (int) ((ux - vx) * DIR_SCALE);
ddy = (int) ((uy - vy) * DIR_SCALE);
v[opos++] = ox;
v[opos++] = oy;
v[opos++] = (short) (0 | ddx & DIR_MASK);
v[opos++] = (short) (1 | ddy & DIR_MASK);
if (opos == ShortItem.SIZE) {
si = si.next = ShortPool.get();
v = si.vertices;
opos = 0;
}
// add last vertex twice
ddx = (int) (-(ux + vx) * DIR_SCALE);
ddy = (int) (-(uy + vy) * DIR_SCALE);
dx = (short) (2 | ddx & DIR_MASK);
dy = (short) (1 | ddy & DIR_MASK);
v[opos++] = ox;
v[opos++] = oy;
v[opos++] = dx;
v[opos++] = dy;
if (opos == ShortItem.SIZE) {
si = si.next = ShortPool.get();
v = si.vertices;
opos = 0;
}
v[opos++] = ox;
v[opos++] = oy;
v[opos++] = dx;
v[opos++] = dy;
} }
pos += length;
v[opos++] = ox;
v[opos++] = oy;
v[opos++] = (short) (2 | -ddx & DIR_MASK);
v[opos++] = (short) (1 | -ddy & DIR_MASK);
prevX = x;
prevY = y;
x = nextX;
y = nextY;
}
vx = prevX - x;
vy = prevY - y;
a = FloatMath.sqrt(vx * vx + vy * vy);
vx = (vx / a);
vy = (vy / a);
ux = vy;
uy = -vx;
outside = (x < tmin || x > tmax || y < tmin || y > tmax);
if (opos == ShortItem.SIZE) {
si.used = ShortItem.SIZE;
si.next = ShortPool.get();
si = si.next;
opos = 0;
v = si.vertices;
}
ox = (short) (x * COORD_SCALE);
oy = (short) (y * COORD_SCALE);
if (rounded && !outside) {
ddx = (int) (ux * DIR_SCALE);
ddy = (int) (uy * DIR_SCALE);
v[opos++] = ox;
v[opos++] = oy;
v[opos++] = (short) (0 | ddx & DIR_MASK);
v[opos++] = (short) (1 | ddy & DIR_MASK);
if (opos == ShortItem.SIZE) {
si.used = ShortItem.SIZE;
si.next = ShortPool.get();
si = si.next;
opos = 0;
v = si.vertices;
}
v[opos++] = ox;
v[opos++] = oy;
v[opos++] = (short) (2 | -ddx & DIR_MASK);
v[opos++] = (short) (1 | -ddy & DIR_MASK);
if (opos == ShortItem.SIZE) {
si.used = ShortItem.SIZE;
si.next = ShortPool.get();
si = si.next;
opos = 0;
v = si.vertices;
}
// For rounded line edges
ddx = (int) ((ux - vx) * DIR_SCALE);
ddy = (int) ((uy - vy) * DIR_SCALE);
dx = (short) (0 | ddx & DIR_MASK);
dy = (short) (0 | ddy & DIR_MASK);
v[opos++] = ox;
v[opos++] = oy;
v[opos++] = dx;
v[opos++] = dy;
if (opos == ShortItem.SIZE) {
si.used = ShortItem.SIZE;
si.next = ShortPool.get();
si = si.next;
opos = 0;
v = si.vertices;
}
// add last vertex twice
ddx = (int) (-(ux + vx) * DIR_SCALE);
ddy = (int) (-(uy + vy) * DIR_SCALE);
dx = (short) (2 | ddx & DIR_MASK);
dy = (short) (0 | ddy & DIR_MASK);
v[opos++] = ox;
v[opos++] = oy;
v[opos++] = dx;
v[opos++] = dy;
if (opos == ShortItem.SIZE) {
si.used = ShortItem.SIZE;
si.next = ShortPool.get();
si = si.next;
opos = 0;
v = si.vertices;
}
v[opos++] = ox;
v[opos++] = oy;
v[opos++] = dx;
v[opos++] = dy;
} else {
if (squared) {
vx = 0;
vy = 0;
} else if (!outside) {
vx *= 0.5;
vy *= 0.5;
}
if (rounded)
verticesCnt -= 2;
ddx = (int) ((ux - vx) * DIR_SCALE);
ddy = (int) ((uy - vy) * DIR_SCALE);
v[opos++] = ox;
v[opos++] = oy;
v[opos++] = (short) (0 | ddx & DIR_MASK);
v[opos++] = (short) (1 | ddy & DIR_MASK);
if (opos == ShortItem.SIZE) {
si.used = ShortItem.SIZE;
si.next = ShortPool.get();
si = si.next;
opos = 0;
v = si.vertices;
}
// add last vertex twice
ddx = (int) (-(ux + vx) * DIR_SCALE);
ddy = (int) (-(uy + vy) * DIR_SCALE);
dx = (short) (2 | ddx & DIR_MASK);
dy = (short) (1 | ddy & DIR_MASK);
v[opos++] = ox;
v[opos++] = oy;
v[opos++] = dx;
v[opos++] = dy;
if (opos == ShortItem.SIZE) {
si.used = ShortItem.SIZE;
si.next = ShortPool.get();
si = si.next;
opos = 0;
v = si.vertices;
}
v[opos++] = ox;
v[opos++] = oy;
v[opos++] = dx;
v[opos++] = dy;
} }
si.used = opos; si.used = opos;

View File

@ -191,7 +191,14 @@ class LineLayers {
continue; continue;
for (ShortItem item = l.pool; item != null; item = item.next) { for (ShortItem item = l.pool; item != null; item = item.next) {
sbuf.put(item.vertices, 0, item.used);
if (item.next == null) {
sbuf.put(item.vertices, 0, item.used);
} else {
// item.used = ShortItem.SIZE;
sbuf.put(item.vertices);
}
last = item; last = item;
} }

View File

@ -351,26 +351,7 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
mCurLineLayer = lineLayer; mCurLineLayer = lineLayer;
boolean round = line.round; lineLayer.addLine(mWayNodes, mWays);
for (int i = 0, pos = 0, n = mWays.length; i < n; i++) {
int length = mWays[i];
if (length < 0)
break;
// save some vertices
if (round && i > 200) {
// Log.d(TAG, "WAY TOO MANY LINES!!!");
round = false;
}
// need at least two points
if (length >= 4) {
lineLayer.addLine(mWayNodes, pos, length);
countLines++;
countNodes += length;
}
pos += length;
}
} }
@Override @Override
@ -415,19 +396,7 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
mCurPolyLayer = layer; mCurPolyLayer = layer;
for (int i = 0, pos = 0, n = mWays.length; i < n; i++) { layer.addPolygon(mWayNodes, mWays);
int length = mWays[i];
if (length < 0)
break;
// need at least three points
if (length >= 6)
layer.addPolygon(mWayNodes, pos, length);
pos += length;
}
// if (area.line != null)
} }
@Override @Override

View File

@ -24,8 +24,8 @@ class PolygonLayer {
Area area; Area area;
// private static final float MapRenderer.COORD_MULTIPLIER = 8.0f; // private static final float MapRenderer.COORD_MULTIPLIER = 8.0f;
private boolean first = true; private boolean first = true;
private float originX; private short originX;
private float originY; private short originY;
ShortItem pool; ShortItem pool;
protected ShortItem curItem; protected ShortItem curItem;
@ -41,69 +41,121 @@ class PolygonLayer {
pool = curItem; pool = curItem;
} }
short[] getNextItem() { // short[] getNextItem() {
curItem.used = ShortItem.SIZE; // curItem.used = ShortItem.SIZE;
// curItem.next = ShortPool.get();
// curItem = curItem.next;
//
// return curItem.vertices;
// }
//
// void addPolygon(float[] points, int pos, int length) {
//
// verticesCnt += length / 2 + 2;
//
// if (first) {
// first = false;
// originX = (short) ((Tile.TILE_SIZE >> 1) * S);
// originY = (short) ((Tile.TILE_SIZE >> 1) * S);
// }
//
// short[] curVertices = curItem.vertices;
// int outPos = curItem.used;
//
// if (outPos == ShortItem.SIZE) {
// curVertices = getNextItem();
// outPos = 0;
// }
//
// curVertices[outPos++] = originX;
// curVertices[outPos++] = originY;
//
// int MAX = ShortItem.SIZE;
// int remaining = length;
// int inPos = pos;
// while (remaining > 0) {
//
// if (outPos == MAX) {
// curVertices = getNextItem();
// outPos = 0;
// }
//
// int len = remaining;
// if (len > MAX - outPos)
// len = MAX - outPos;
//
// for (int i = 0; i < len; i++)
// curVertices[outPos++] = (short) (points[inPos++] * S);
//
// remaining -= len;
// }
//
// if (outPos == MAX) {
// curVertices = getNextItem();
// outPos = 0;
// }
//
// curVertices[outPos++] = (short) (points[pos + 0] * S);
// curVertices[outPos++] = (short) (points[pos + 1] * S);
//
// curItem.used = outPos;
// }
curItem.next = ShortPool.get(); void addPolygon(float[] points, short[] index) {
curItem = curItem.next; short center = (short) ((Tile.TILE_SIZE >> 1) * S);
return curItem.vertices; ShortItem si = curItem;
} short[] v = si.vertices;
int outPos = si.used;
void addPolygon(float[] points, int pos, int length) { for (int i = 0, pos = 0, n = index.length; i < n; i++) {
int length = index[i];
if (length < 0)
break;
verticesCnt += length / 2 + 2; // need at least three points
if (length < 6) {
pos += length;
continue;
}
if (first) { verticesCnt += length / 2 + 2;
first = false;
originX = Tile.TILE_SIZE >> 1; // points[pos];
originY = Tile.TILE_SIZE >> 1; // points[pos + 1];
}
short[] curVertices = curItem.vertices; int inPos = pos;
int outPos = curItem.used;
if (outPos == ShortItem.SIZE) { if (outPos == ShortItem.SIZE) {
curVertices = getNextItem(); si = si.next = ShortPool.get();
outPos = 0; v = si.vertices;
}
curVertices[outPos++] = (short) (originX * S);
curVertices[outPos++] = (short) (originY * S);
int MAX = ShortItem.SIZE;
int remaining = length;
int inPos = pos;
while (remaining > 0) {
if (outPos == MAX) {
curVertices = getNextItem();
outPos = 0; outPos = 0;
} }
int len = remaining; v[outPos++] = center;
if (len > MAX - outPos) v[outPos++] = center;
len = MAX - outPos;
for (int i = 0; i < len; i++) for (int j = 0; j < length; j += 2) {
curVertices[outPos++] = (short) (points[inPos++] * S); if (outPos == ShortItem.SIZE) {
si = si.next = ShortPool.get();
v = si.vertices;
outPos = 0;
}
v[outPos++] = (short) (points[inPos++] * S);
v[outPos++] = (short) (points[inPos++] * S);
}
// System.arraycopy(points, inPos, curVertices, outPos, len); if (outPos == ShortItem.SIZE) {
si = si.next = ShortPool.get();
v = si.vertices;
outPos = 0;
}
// outPos += len; v[outPos++] = (short) (points[pos + 0] * S);
// inPos += len; v[outPos++] = (short) (points[pos + 1] * S);
remaining -= len; pos += length;
} }
if (outPos == MAX) { si.used = outPos;
curVertices = getNextItem(); curItem = si;
outPos = 0;
}
curVertices[outPos++] = (short) (points[pos + 0] * S);
curVertices[outPos++] = (short) (points[pos + 1] * S);
curItem.used = outPos;
} }
} }

View File

@ -260,7 +260,14 @@ class PolygonLayers {
for (PolygonLayer l = layers; l != null; l = l.next) { for (PolygonLayer l = layers; l != null; l = l.next) {
for (ShortItem item = l.pool; item != null; item = item.next) { for (ShortItem item = l.pool; item != null; item = item.next) {
sbuf.put(item.vertices, 0, item.used);
if (item.next == null) {
sbuf.put(item.vertices, 0, item.used);
} else {
// item.used = ShortItem.SIZE;
sbuf.put(item.vertices);
}
last = item; last = item;
} }