LineLayer refactor:
- extract addLine() - expand variable names
This commit is contained in:
parent
0ef16b6c5b
commit
fdda6988ba
@ -54,7 +54,7 @@ public final class LineLayer extends RenderElement {
|
|||||||
* not quite right.. need to go back so that additional
|
* not quite right.. need to go back so that additional
|
||||||
* bevel vertices are at least MIN_DIST apart
|
* bevel vertices are at least MIN_DIST apart
|
||||||
*/
|
*/
|
||||||
//private static final float JOIN_BEVEL = MIN_DIST
|
private static final float BEVEL_MIN = MIN_DIST * 4;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mask for packing last two bits of extrusion vector with texture
|
* mask for packing last two bits of extrusion vector with texture
|
||||||
@ -107,10 +107,10 @@ public final class LineLayer extends RenderElement {
|
|||||||
addLine(points, null, numPoints, closed);
|
addLine(points, null, numPoints, closed);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addLine(float[] points, short[] index, int numPoints, boolean closed) {
|
private static int tmax = Tile.SIZE + 4;
|
||||||
|
private static int tmin = -4;
|
||||||
|
|
||||||
int tmax = Tile.SIZE + 4;
|
private void addLine(float[] points, short[] index, int numPoints, boolean closed) {
|
||||||
int tmin = -4;
|
|
||||||
|
|
||||||
boolean rounded = false;
|
boolean rounded = false;
|
||||||
boolean squared = false;
|
boolean squared = false;
|
||||||
@ -123,9 +123,7 @@ public final class LineLayer extends RenderElement {
|
|||||||
if (vertexItems == null)
|
if (vertexItems == null)
|
||||||
vertexItems = pool.get();
|
vertexItems = pool.get();
|
||||||
|
|
||||||
VertexItem si = Inlist.last(vertexItems);
|
VertexItem vertexItem = Inlist.last(vertexItems);
|
||||||
short v[] = si.vertices;
|
|
||||||
int opos = si.used;
|
|
||||||
|
|
||||||
/* Note: just a hack to save some vertices, when there are
|
/* Note: just a hack to save some vertices, when there are
|
||||||
* more than 200 lines per type. FIXME make optional! */
|
* more than 200 lines per type. FIXME make optional! */
|
||||||
@ -157,13 +155,6 @@ public final class LineLayer extends RenderElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0, pos = 0; i < n; i++) {
|
for (int i = 0, pos = 0; i < n; i++) {
|
||||||
float ux, uy;
|
|
||||||
float vx, vy;
|
|
||||||
float wx, wy;
|
|
||||||
float x, y;
|
|
||||||
float nextX, nextY;
|
|
||||||
double a;
|
|
||||||
|
|
||||||
if (index != null)
|
if (index != null)
|
||||||
length = index[i];
|
length = index[i];
|
||||||
|
|
||||||
@ -171,490 +162,446 @@ public final class LineLayer extends RenderElement {
|
|||||||
if (length < 0)
|
if (length < 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* need at least two points */
|
|
||||||
if (length < 4) {
|
|
||||||
pos += length;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* amount of vertices used
|
|
||||||
* + 2 for drawing triangle-strip
|
|
||||||
* + 4 for round caps
|
|
||||||
* + 2 for closing polygons */
|
|
||||||
numVertices += length + (rounded ? 6 : 2) + (closed ? 2 : 0);
|
|
||||||
|
|
||||||
int ipos = pos;
|
int ipos = pos;
|
||||||
|
pos += length;
|
||||||
|
|
||||||
x = points[ipos++];
|
/* need at least two points */
|
||||||
y = points[ipos++];
|
if (length < 4)
|
||||||
|
continue;
|
||||||
|
|
||||||
nextX = points[ipos++];
|
|
||||||
nextY = points[ipos++];
|
|
||||||
|
|
||||||
/* Calculate triangle corners for the given width */
|
|
||||||
vx = nextX - x;
|
|
||||||
vy = nextY - y;
|
|
||||||
|
|
||||||
/* Unit vector to next node */
|
vertexItem = addLine(vertexItem, points, ipos, length, rounded, squared, closed);
|
||||||
a = (float) Math.sqrt(vx * vx + vy * vy);
|
|
||||||
|
|
||||||
vx /= a;
|
}
|
||||||
vy /= a;
|
}
|
||||||
|
|
||||||
/* perpendicular on the first segment */
|
private void addVertex(short[] v, int pos, short x, short y, short dx, short dy) {
|
||||||
ux = -vy;
|
v[pos + 0] = x;
|
||||||
uy = vx;
|
v[pos + 1] = y;
|
||||||
|
v[pos + 2] = dx;
|
||||||
|
v[pos + 3] = dy;
|
||||||
|
}
|
||||||
|
|
||||||
int ddx, ddy;
|
private VertexItem addVertex(VertexItem vertexItem,
|
||||||
|
float x, float y,
|
||||||
|
float vNextX, float vNextY,
|
||||||
|
float vPrevX, float vPrevY) {
|
||||||
|
|
||||||
/* vertex point coordinate */
|
float ux = vNextX + vPrevX;
|
||||||
short ox = (short) (x * COORD_SCALE);
|
float uy = vNextY + vPrevY;
|
||||||
short oy = (short) (y * COORD_SCALE);
|
|
||||||
|
|
||||||
/* vertex extrusion vector, last two bit
|
/* vPrev times perpendicular of sum(vNext, vPrev) */
|
||||||
* encode texture coord. */
|
double a = uy * vPrevX - ux * vPrevY;
|
||||||
short dx, dy;
|
|
||||||
|
|
||||||
/* when the endpoint is outside the tile region omit round caps. */
|
if (a < 0.01 && a > -0.01) {
|
||||||
boolean outside = (x < tmin || x > tmax || y < tmin || y > tmax);
|
ux = -vPrevY;
|
||||||
|
uy = vPrevX;
|
||||||
|
} else {
|
||||||
|
ux /= a;
|
||||||
|
uy /= a;
|
||||||
|
}
|
||||||
|
|
||||||
if (opos == SIZE) {
|
short ox = (short) (x * COORD_SCALE);
|
||||||
si = pool.getNext(si);
|
short oy = (short) (y * COORD_SCALE);
|
||||||
v = si.vertices;
|
|
||||||
|
int ddx = (int) (ux * DIR_SCALE);
|
||||||
|
int ddy = (int) (uy * DIR_SCALE);
|
||||||
|
|
||||||
|
int opos = vertexItem.used;
|
||||||
|
short[] v = vertexItem.vertices;
|
||||||
|
|
||||||
|
if (opos == SIZE) {
|
||||||
|
vertexItem = pool.getNext(vertexItem);
|
||||||
|
v = vertexItem.vertices;
|
||||||
|
opos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
v[opos + 0] = ox;
|
||||||
|
v[opos + 1] = oy;
|
||||||
|
v[opos + 2] = (short) (0 | ddx & DIR_MASK);
|
||||||
|
v[opos + 3] = (short) (1 | ddy & DIR_MASK);
|
||||||
|
|
||||||
|
if ((opos += 4) == SIZE) {
|
||||||
|
vertexItem = pool.getNext(vertexItem);
|
||||||
|
v = vertexItem.vertices;
|
||||||
|
opos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
v[opos + 0] = ox;
|
||||||
|
v[opos + 1] = oy;
|
||||||
|
v[opos + 2] = (short) (2 | -ddx & DIR_MASK);
|
||||||
|
v[opos + 3] = (short) (1 | -ddy & DIR_MASK);
|
||||||
|
|
||||||
|
vertexItem.used = opos + 4;
|
||||||
|
return vertexItem;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private VertexItem addLine(VertexItem vertexItem, float[] points, int start, int length,
|
||||||
|
boolean rounded, boolean squared, boolean closed) {
|
||||||
|
|
||||||
|
float ux, uy;
|
||||||
|
float vPrevX, vPrevY;
|
||||||
|
float vNextX, vNextY;
|
||||||
|
float curX, curY;
|
||||||
|
float nextX, nextY;
|
||||||
|
double a;
|
||||||
|
|
||||||
|
short v[] = vertexItem.vertices;
|
||||||
|
int opos = vertexItem.used;
|
||||||
|
|
||||||
|
/* amount of vertices used
|
||||||
|
* + 2 for drawing triangle-strip
|
||||||
|
* + 4 for round caps
|
||||||
|
* + 2 for closing polygons */
|
||||||
|
numVertices += length + (rounded ? 6 : 2) + (closed ? 2 : 0);
|
||||||
|
|
||||||
|
int ipos = start;
|
||||||
|
|
||||||
|
curX = points[ipos++];
|
||||||
|
curY = points[ipos++];
|
||||||
|
|
||||||
|
nextX = points[ipos++];
|
||||||
|
nextY = points[ipos++];
|
||||||
|
|
||||||
|
/* Unit vector to next node */
|
||||||
|
vPrevX = nextX - curX;
|
||||||
|
vPrevY = nextY - curY;
|
||||||
|
a = (float) Math.sqrt(vPrevX * vPrevX + vPrevY * vPrevY);
|
||||||
|
vPrevX /= a;
|
||||||
|
vPrevY /= a;
|
||||||
|
|
||||||
|
/* perpendicular on the first segment */
|
||||||
|
ux = -vPrevY;
|
||||||
|
uy = vPrevX;
|
||||||
|
|
||||||
|
int ddx, ddy;
|
||||||
|
|
||||||
|
/* vertex point coordinate */
|
||||||
|
short ox = (short) (curX * COORD_SCALE);
|
||||||
|
short oy = (short) (curY * COORD_SCALE);
|
||||||
|
|
||||||
|
/* vertex extrusion vector, last two bit
|
||||||
|
* encode texture coord. */
|
||||||
|
short dx, dy;
|
||||||
|
|
||||||
|
/* when the endpoint is outside the tile region omit round caps. */
|
||||||
|
boolean outside = (curX < tmin || curX > tmax || curY < tmin || curY > tmax);
|
||||||
|
|
||||||
|
if (opos == SIZE) {
|
||||||
|
vertexItem = pool.getNext(vertexItem);
|
||||||
|
v = vertexItem.vertices;
|
||||||
|
opos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rounded && !outside) {
|
||||||
|
ddx = (int) ((ux - vPrevX) * DIR_SCALE);
|
||||||
|
ddy = (int) ((uy - vPrevY) * DIR_SCALE);
|
||||||
|
dx = (short) (0 | ddx & DIR_MASK);
|
||||||
|
dy = (short) (2 | ddy & DIR_MASK);
|
||||||
|
|
||||||
|
addVertex(v, opos, ox, oy, dx, dy);
|
||||||
|
|
||||||
|
if ((opos += 4) == SIZE) {
|
||||||
|
vertexItem = pool.getNext(vertexItem);
|
||||||
|
v = vertexItem.vertices;
|
||||||
opos = 0;
|
opos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rounded && !outside) {
|
addVertex(v, opos, ox, oy, dx, dy);
|
||||||
/* add first vertex twice */
|
|
||||||
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 == SIZE) {
|
|
||||||
si = pool.getNext(si);
|
|
||||||
v = si.vertices;
|
|
||||||
opos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
v[opos++] = ox;
|
|
||||||
v[opos++] = oy;
|
|
||||||
v[opos++] = dx;
|
|
||||||
v[opos++] = dy;
|
|
||||||
|
|
||||||
if (opos == SIZE) {
|
|
||||||
si = pool.getNext(si);
|
|
||||||
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 == SIZE) {
|
|
||||||
si = pool.getNext(si);
|
|
||||||
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 == SIZE) {
|
|
||||||
si = pool.getNext(si);
|
|
||||||
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 */
|
|
||||||
float tx = vx;
|
|
||||||
float ty = vy;
|
|
||||||
|
|
||||||
if (squared) {
|
|
||||||
tx = 0;
|
|
||||||
ty = 0;
|
|
||||||
} else if (!outside) {
|
|
||||||
tx *= 0.5;
|
|
||||||
ty *= 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rounded)
|
|
||||||
numVertices -= 2;
|
|
||||||
|
|
||||||
/* add first vertex twice */
|
|
||||||
ddx = (int) ((ux - tx) * DIR_SCALE);
|
|
||||||
ddy = (int) ((uy - ty) * 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 == SIZE) {
|
|
||||||
si = pool.getNext(si);
|
|
||||||
v = si.vertices;
|
|
||||||
opos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
v[opos++] = ox;
|
|
||||||
v[opos++] = oy;
|
|
||||||
v[opos++] = dx;
|
|
||||||
v[opos++] = dy;
|
|
||||||
|
|
||||||
if (opos == SIZE) {
|
|
||||||
si = pool.getNext(si);
|
|
||||||
v = si.vertices;
|
|
||||||
opos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ddx = (int) (-(ux + tx) * DIR_SCALE);
|
|
||||||
ddy = (int) (-(uy + ty) * DIR_SCALE);
|
|
||||||
|
|
||||||
v[opos++] = ox;
|
|
||||||
v[opos++] = oy;
|
|
||||||
v[opos++] = (short) (2 | ddx & DIR_MASK);
|
|
||||||
v[opos++] = (short) (1 | ddy & DIR_MASK);
|
|
||||||
|
|
||||||
|
if ((opos += 4) == SIZE) {
|
||||||
|
vertexItem = pool.getNext(vertexItem);
|
||||||
|
v = vertexItem.vertices;
|
||||||
|
opos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
x = nextX;
|
ddx = (int) (-(ux + vPrevX) * DIR_SCALE);
|
||||||
y = nextY;
|
ddy = (int) (-(uy + vPrevY) * DIR_SCALE);
|
||||||
/* Unit vector pointing back to previous node */
|
|
||||||
vx *= -1;
|
|
||||||
vy *= -1;
|
|
||||||
|
|
||||||
int end = pos + length;
|
addVertex(v, opos, ox, oy,
|
||||||
|
(short) (2 | ddx & DIR_MASK),
|
||||||
|
(short) (2 | ddy & DIR_MASK));
|
||||||
|
|
||||||
for (;;) {
|
if ((opos += 4) == SIZE) {
|
||||||
if (ipos < end) {
|
vertexItem = pool.getNext(vertexItem);
|
||||||
nextX = points[ipos++];
|
v = vertexItem.vertices;
|
||||||
nextY = points[ipos++];
|
opos = 0;
|
||||||
} else if (closed && ipos < end + 2) {
|
}
|
||||||
/* add startpoint == endpoint */
|
|
||||||
nextX = points[pos];
|
|
||||||
nextY = points[pos + 1];
|
|
||||||
ipos += 2;
|
|
||||||
} else
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Unit vector pointing forward to next node */
|
/* Start of line */
|
||||||
wx = nextX - x;
|
ddx = (int) (ux * DIR_SCALE);
|
||||||
wy = nextY - y;
|
ddy = (int) (uy * DIR_SCALE);
|
||||||
a = Math.sqrt(wx * wx + wy * wy);
|
|
||||||
/* skip too short segmets */
|
|
||||||
if (a < mMinDist) {
|
|
||||||
numVertices -= 2;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
wx /= a;
|
|
||||||
wy /= a;
|
|
||||||
|
|
||||||
double dotp = (wx * vx + wy * vy);
|
addVertex(v, opos, ox, oy,
|
||||||
|
(short) (0 | ddx & DIR_MASK),
|
||||||
|
(short) (1 | ddy & DIR_MASK));
|
||||||
|
|
||||||
//log.debug("acos " + dotp);
|
if ((opos += 4) == SIZE) {
|
||||||
if (dotp > 0.7) {
|
vertexItem = pool.getNext(vertexItem);
|
||||||
/* add bevel join to avoid miter going to infinity */
|
v = vertexItem.vertices;
|
||||||
numVertices += 2;
|
opos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
//dotp = FastMath.clamp(dotp, -1, 1);
|
addVertex(v, opos, ox, oy,
|
||||||
//double cos = Math.acos(dotp);
|
(short) (2 | -ddx & DIR_MASK),
|
||||||
//log.debug("cos " + Math.toDegrees(cos));
|
(short) (1 | -ddy & DIR_MASK));
|
||||||
//log.debug("back " + (mMinDist * 2 / Math.sin(cos + Math.PI / 2)));
|
|
||||||
|
|
||||||
float px, py;
|
} else {
|
||||||
if (dotp > 0.999) {
|
/* outside means line is probably clipped
|
||||||
/* 360 degree angle, set points aside */
|
* TODO should align ending with tile boundary
|
||||||
ux = vx + wx;
|
* for now, just extend the line a little */
|
||||||
uy = vy + wy;
|
float tx = vPrevX;
|
||||||
a = wx * uy - wy * ux;
|
float ty = vPrevY;
|
||||||
if (a < 0.1 && a > -0.1) {
|
|
||||||
/* Almost straight */
|
|
||||||
ux = -wy;
|
|
||||||
uy = wx;
|
|
||||||
} else {
|
|
||||||
ux /= a;
|
|
||||||
uy /= a;
|
|
||||||
}
|
|
||||||
//log.debug("aside " + a + " " + ux + " " + uy);
|
|
||||||
px = x - ux * MIN_DIST * 2;
|
|
||||||
py = y - uy * MIN_DIST * 2;
|
|
||||||
x = x + ux * MIN_DIST * 2;
|
|
||||||
y = y + uy * MIN_DIST * 2;
|
|
||||||
} else {
|
|
||||||
//log.debug("back");
|
|
||||||
/* go back by min dist */
|
|
||||||
px = x + vx * MIN_DIST * 2;
|
|
||||||
py = y + vy * MIN_DIST * 2;
|
|
||||||
/* go forward by min dist */
|
|
||||||
x = x + wx * MIN_DIST * 2;
|
|
||||||
y = y + wy * MIN_DIST * 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Unit vector pointing forward to next node */
|
if (squared) {
|
||||||
wx = x - px;
|
tx = 0;
|
||||||
wy = y - py;
|
ty = 0;
|
||||||
a = Math.sqrt(wx * wx + wy * wy);
|
} else if (!outside) {
|
||||||
wx /= a;
|
tx *= 0.5;
|
||||||
wy /= a;
|
ty *= 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
ux = vx + wx;
|
if (rounded)
|
||||||
uy = vy + wy;
|
numVertices -= 2;
|
||||||
a = wx * uy - wy * ux;
|
|
||||||
if (a < 0.01 && a > -0.01) {
|
/* add first vertex twice */
|
||||||
ux = -wy;
|
ddx = (int) ((ux - tx) * DIR_SCALE);
|
||||||
uy = wx;
|
ddy = (int) ((uy - ty) * DIR_SCALE);
|
||||||
|
dx = (short) (0 | ddx & DIR_MASK);
|
||||||
|
dy = (short) (1 | ddy & DIR_MASK);
|
||||||
|
|
||||||
|
addVertex(v, opos, ox, oy, dx, dy);
|
||||||
|
|
||||||
|
if ((opos += 4) == SIZE) {
|
||||||
|
vertexItem = pool.getNext(vertexItem);
|
||||||
|
v = vertexItem.vertices;
|
||||||
|
opos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
addVertex(v, opos, ox, oy, dx, dy);
|
||||||
|
|
||||||
|
if ((opos += 4) == SIZE) {
|
||||||
|
vertexItem = pool.getNext(vertexItem);
|
||||||
|
v = vertexItem.vertices;
|
||||||
|
opos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ddx = (int) (-(ux + tx) * DIR_SCALE);
|
||||||
|
ddy = (int) (-(uy + ty) * DIR_SCALE);
|
||||||
|
|
||||||
|
addVertex(v, opos, ox, oy,
|
||||||
|
(short) (2 | ddx & DIR_MASK),
|
||||||
|
(short) (1 | ddy & DIR_MASK));
|
||||||
|
}
|
||||||
|
|
||||||
|
curX = nextX;
|
||||||
|
curY = nextY;
|
||||||
|
|
||||||
|
/* Unit vector pointing back to previous node */
|
||||||
|
vPrevX *= -1;
|
||||||
|
vPrevY *= -1;
|
||||||
|
|
||||||
|
vertexItem.used = opos + 4;
|
||||||
|
|
||||||
|
for (int end = start + length;;) {
|
||||||
|
|
||||||
|
if (ipos < end) {
|
||||||
|
nextX = points[ipos++];
|
||||||
|
nextY = points[ipos++];
|
||||||
|
} else if (closed && ipos < end + 2) {
|
||||||
|
/* add startpoint == endpoint */
|
||||||
|
nextX = points[start];
|
||||||
|
nextY = points[start + 1];
|
||||||
|
ipos += 2;
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* unit vector pointing forward to next node */
|
||||||
|
vNextX = nextX - curX;
|
||||||
|
vNextY = nextY - curY;
|
||||||
|
a = Math.sqrt(vNextX * vNextX + vNextY * vNextY);
|
||||||
|
/* skip too short segmets */
|
||||||
|
if (a < mMinDist) {
|
||||||
|
numVertices -= 2;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
vNextX /= a;
|
||||||
|
vNextY /= a;
|
||||||
|
|
||||||
|
double dotp = (vNextX * vPrevX + vNextY * vPrevY);
|
||||||
|
|
||||||
|
//log.debug("acos " + dotp);
|
||||||
|
if (dotp > 0.65) {
|
||||||
|
/* add bevel join to avoid miter going to infinity */
|
||||||
|
numVertices += 2;
|
||||||
|
|
||||||
|
//dotp = FastMath.clamp(dotp, -1, 1);
|
||||||
|
//double cos = Math.acos(dotp);
|
||||||
|
//log.debug("cos " + Math.toDegrees(cos));
|
||||||
|
//log.debug("back " + (mMinDist * 2 / Math.sin(cos + Math.PI / 2)));
|
||||||
|
|
||||||
|
float px, py;
|
||||||
|
if (dotp > 0.999) {
|
||||||
|
/* 360 degree angle, set points aside */
|
||||||
|
ux = vPrevX + vNextX;
|
||||||
|
uy = vPrevY + vNextY;
|
||||||
|
a = vNextX * uy - vNextY * ux;
|
||||||
|
if (a < 0.1 && a > -0.1) {
|
||||||
|
/* Almost straight */
|
||||||
|
ux = -vNextY;
|
||||||
|
uy = vNextX;
|
||||||
} else {
|
} else {
|
||||||
ux /= a;
|
ux /= a;
|
||||||
uy /= a;
|
uy /= a;
|
||||||
}
|
}
|
||||||
|
//log.debug("aside " + a + " " + ux + " " + uy);
|
||||||
ox = (short) (px * COORD_SCALE);
|
px = curX - ux * BEVEL_MIN;
|
||||||
oy = (short) (py * COORD_SCALE);
|
py = curY - uy * BEVEL_MIN;
|
||||||
|
curX = curX + ux * BEVEL_MIN;
|
||||||
ddx = (int) (ux * DIR_SCALE);
|
curY = curY + uy * BEVEL_MIN;
|
||||||
ddy = (int) (uy * DIR_SCALE);
|
|
||||||
|
|
||||||
if (opos == SIZE) {
|
|
||||||
si = pool.getNext(si);
|
|
||||||
v = si.vertices;
|
|
||||||
opos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
v[opos++] = ox;
|
|
||||||
v[opos++] = oy;
|
|
||||||
v[opos++] = (short) (0 | ddx & DIR_MASK);
|
|
||||||
v[opos++] = (short) (1 | ddy & DIR_MASK);
|
|
||||||
|
|
||||||
if (opos == SIZE) {
|
|
||||||
si = pool.getNext(si);
|
|
||||||
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);
|
|
||||||
|
|
||||||
/* flip unit vector to point back */
|
|
||||||
vx = -wx;
|
|
||||||
vy = -wy;
|
|
||||||
|
|
||||||
/* Unit vector pointing forward to next node */
|
|
||||||
wx = nextX - x;
|
|
||||||
wy = nextY - y;
|
|
||||||
a = Math.sqrt(wx * wx + wy * wy);
|
|
||||||
wx /= a;
|
|
||||||
wy /= a;
|
|
||||||
}
|
|
||||||
|
|
||||||
ux = vx + wx;
|
|
||||||
uy = vy + wy;
|
|
||||||
a = wx * uy - wy * ux;
|
|
||||||
|
|
||||||
if (a < 0.01 && a > -0.01) {
|
|
||||||
/* Almost straight */
|
|
||||||
ux = -wy;
|
|
||||||
uy = wx;
|
|
||||||
} else {
|
} else {
|
||||||
ux /= a;
|
//log.debug("back");
|
||||||
uy /= a;
|
/* go back by min dist */
|
||||||
|
px = curX + vPrevX * BEVEL_MIN;
|
||||||
|
py = curY + vPrevY * BEVEL_MIN;
|
||||||
|
/* go forward by min dist */
|
||||||
|
curX = curX + vNextX * BEVEL_MIN;
|
||||||
|
curY = curY + vNextY * BEVEL_MIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
ox = (short) (x * COORD_SCALE);
|
/* unit vector pointing forward to next node */
|
||||||
oy = (short) (y * COORD_SCALE);
|
vNextX = curX - px;
|
||||||
|
vNextY = curY - py;
|
||||||
|
a = Math.sqrt(vNextX * vNextX + vNextY * vNextY);
|
||||||
|
vNextX /= a;
|
||||||
|
vNextY /= a;
|
||||||
|
|
||||||
ddx = (int) (ux * DIR_SCALE);
|
vertexItem = addVertex(vertexItem, px, py, vPrevX, vPrevY, vNextX, vNextY);
|
||||||
ddy = (int) (uy * DIR_SCALE);
|
|
||||||
|
|
||||||
if (opos == SIZE) {
|
|
||||||
si = pool.getNext(si);
|
|
||||||
v = si.vertices;
|
|
||||||
opos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
v[opos++] = ox;
|
|
||||||
v[opos++] = oy;
|
|
||||||
v[opos++] = (short) (0 | ddx & DIR_MASK);
|
|
||||||
v[opos++] = (short) (1 | ddy & DIR_MASK);
|
|
||||||
|
|
||||||
if (opos == SIZE) {
|
|
||||||
si = pool.getNext(si);
|
|
||||||
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);
|
|
||||||
|
|
||||||
x = nextX;
|
|
||||||
y = nextY;
|
|
||||||
|
|
||||||
/* flip unit vector to point back */
|
/* flip unit vector to point back */
|
||||||
vx = -wx;
|
vPrevX = -vNextX;
|
||||||
vy = -wy;
|
vPrevY = -vNextY;
|
||||||
|
|
||||||
|
/* unit vector pointing forward to next node */
|
||||||
|
vNextX = nextX - curX;
|
||||||
|
vNextY = nextY - curY;
|
||||||
|
a = Math.sqrt(vNextX * vNextX + vNextY * vNextY);
|
||||||
|
vNextX /= a;
|
||||||
|
vNextY /= a;
|
||||||
}
|
}
|
||||||
|
|
||||||
ux = vy;
|
vertexItem = addVertex(vertexItem, curX, curY, vPrevX, vPrevY, vNextX, vNextY);
|
||||||
uy = -vx;
|
|
||||||
|
|
||||||
outside = (x < tmin || x > tmax || y < tmin || y > tmax);
|
curX = nextX;
|
||||||
|
curY = nextY;
|
||||||
|
|
||||||
if (opos == SIZE) {
|
/* flip vector to point back */
|
||||||
si = pool.getNext(si);
|
vPrevX = -vNextX;
|
||||||
opos = 0;
|
vPrevY = -vNextY;
|
||||||
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 == SIZE) {
|
|
||||||
si = pool.getNext(si);
|
|
||||||
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);
|
|
||||||
|
|
||||||
if (opos == SIZE) {
|
|
||||||
si = pool.getNext(si);
|
|
||||||
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 == SIZE) {
|
|
||||||
si = pool.getNext(si);
|
|
||||||
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 == SIZE) {
|
|
||||||
si = pool.getNext(si);
|
|
||||||
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)
|
|
||||||
numVertices -= 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 == SIZE) {
|
|
||||||
si = pool.getNext(si);
|
|
||||||
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 == SIZE) {
|
|
||||||
si = pool.getNext(si);
|
|
||||||
v = si.vertices;
|
|
||||||
opos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
v[opos++] = ox;
|
|
||||||
v[opos++] = oy;
|
|
||||||
v[opos++] = dx;
|
|
||||||
v[opos++] = dy;
|
|
||||||
}
|
|
||||||
pos += length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
si.used = opos;
|
opos = vertexItem.used;
|
||||||
|
v = vertexItem.vertices;
|
||||||
|
|
||||||
|
ux = vPrevY;
|
||||||
|
uy = -vPrevX;
|
||||||
|
|
||||||
|
outside = (curX < tmin || curX > tmax || curY < tmin || curY > tmax);
|
||||||
|
|
||||||
|
if (opos == SIZE) {
|
||||||
|
vertexItem = pool.getNext(vertexItem);
|
||||||
|
v = vertexItem.vertices;
|
||||||
|
opos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ox = (short) (curX * COORD_SCALE);
|
||||||
|
oy = (short) (curY * COORD_SCALE);
|
||||||
|
|
||||||
|
if (rounded && !outside) {
|
||||||
|
ddx = (int) (ux * DIR_SCALE);
|
||||||
|
ddy = (int) (uy * DIR_SCALE);
|
||||||
|
|
||||||
|
addVertex(v, opos, ox, oy,
|
||||||
|
(short) (0 | ddx & DIR_MASK),
|
||||||
|
(short) (1 | ddy & DIR_MASK));
|
||||||
|
|
||||||
|
if ((opos += 4) == SIZE) {
|
||||||
|
vertexItem = pool.getNext(vertexItem);
|
||||||
|
v = vertexItem.vertices;
|
||||||
|
opos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
addVertex(v, opos, ox, oy,
|
||||||
|
(short) (2 | -ddx & DIR_MASK),
|
||||||
|
(short) (1 | -ddy & DIR_MASK));
|
||||||
|
|
||||||
|
if ((opos += 4) == SIZE) {
|
||||||
|
vertexItem = pool.getNext(vertexItem);
|
||||||
|
v = vertexItem.vertices;
|
||||||
|
opos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For rounded line edges */
|
||||||
|
ddx = (int) ((ux - vPrevX) * DIR_SCALE);
|
||||||
|
ddy = (int) ((uy - vPrevY) * DIR_SCALE);
|
||||||
|
|
||||||
|
addVertex(v, opos, ox, oy,
|
||||||
|
(short) (0 | ddx & DIR_MASK),
|
||||||
|
(short) (0 | ddy & DIR_MASK));
|
||||||
|
|
||||||
|
/* last vertex */
|
||||||
|
ddx = (int) (-(ux + vPrevX) * DIR_SCALE);
|
||||||
|
ddy = (int) (-(uy + vPrevY) * DIR_SCALE);
|
||||||
|
dx = (short) (2 | ddx & DIR_MASK);
|
||||||
|
dy = (short) (0 | ddy & DIR_MASK);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (squared) {
|
||||||
|
vPrevX = 0;
|
||||||
|
vPrevY = 0;
|
||||||
|
} else if (!outside) {
|
||||||
|
vPrevX *= 0.5;
|
||||||
|
vPrevY *= 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rounded)
|
||||||
|
numVertices -= 2;
|
||||||
|
|
||||||
|
ddx = (int) ((ux - vPrevX) * DIR_SCALE);
|
||||||
|
ddy = (int) ((uy - vPrevY) * DIR_SCALE);
|
||||||
|
|
||||||
|
addVertex(v, opos, ox, oy,
|
||||||
|
(short) (0 | ddx & DIR_MASK),
|
||||||
|
(short) (1 | ddy & DIR_MASK));
|
||||||
|
|
||||||
|
/* last vertex */
|
||||||
|
ddx = (int) (-(ux + vPrevX) * DIR_SCALE);
|
||||||
|
ddy = (int) (-(uy + vPrevY) * DIR_SCALE);
|
||||||
|
dx = (short) (2 | ddx & DIR_MASK);
|
||||||
|
dy = (short) (1 | ddy & DIR_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add last vertex twice */
|
||||||
|
if ((opos += 4) == SIZE) {
|
||||||
|
vertexItem = pool.getNext(vertexItem);
|
||||||
|
v = vertexItem.vertices;
|
||||||
|
opos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
addVertex(v, opos, ox, oy, dx, dy);
|
||||||
|
|
||||||
|
if ((opos += 4) == SIZE) {
|
||||||
|
vertexItem = pool.getNext(vertexItem);
|
||||||
|
v = vertexItem.vertices;
|
||||||
|
opos = 0;
|
||||||
|
}
|
||||||
|
addVertex(v, opos, ox, oy, dx, dy);
|
||||||
|
|
||||||
|
vertexItem.used = opos + 4;
|
||||||
|
|
||||||
|
return vertexItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class Renderer {
|
public static final class Renderer {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user