int endy = (width[1] > getWidth() - 3) ? getHeight() - 1
: getHeight() - 2;
int beginx = (width[2] == getHeight()) ? 0 : 1;
int endx = (width[0] > getHeight() - 3) ? getWidth() : getWidth() - 1;
vertexarraydatarect = new Rect2D(new Point2D(beginx, beginy),
new Point2D(endx - beginx, endy - beginy));
stripsize = (endx - beginx) * 2;
if (vertexarraysize < stripsize * (getHeight() - 1)) {
vertexarraysize = getWidth() * 2 * (getHeight());
texcoordarray = null;
vertexarray = new Point3D[vertexarraysize];
texcoordarray = new Point2D[vertexarraysize];
} else {
if (innerGenerated) {
/* move old data to new positions */
int oldstripsize = (oldEndx - oldBeginx) * 2;
int offset = (oldBeginx - beginx) * 2;
int destoffset = offset > 0 ? offset : 0;
int sourceoffset = offset < 0 ? -offset : 0;
if (oldstripsize > stripsize) {
for (int row = 0; row < oldEndy - oldBeginy; row++) {
memmove(vertexarray, row * stripsize + destoffset,
vertexarray, row * oldstripsize + sourceoffset,
stripsize);
memmove(texcoordarray, row * stripsize + destoffset,
texcoordarray, row * oldstripsize
+ sourceoffset, stripsize);
}
} else {
for (int row = oldEndy - oldBeginy - 1; row > 0; row--) {
memmove(vertexarray, row * stripsize + destoffset,
vertexarray, row * oldstripsize + sourceoffset,
stripsize);
memmove(texcoordarray, row * stripsize + destoffset,
texcoordarray, row * oldstripsize
+ sourceoffset, stripsize);
}
}
if (oldBeginy > beginy) {
// insert one row
memmove(vertexarray, stripsize, vertexarray, 0, stripsize
* (getHeight() - 1));
memmove(texcoordarray, stripsize, texcoordarray, 0,
stripsize * (getHeight() - 1));
}
if (oldBeginy < beginy) {
// remove one row
memmove(vertexarray, 0, vertexarray, stripsize, stripsize
* (getHeight() - 1));
memmove(texcoordarray, 0, texcoordarray, stripsize,
stripsize * (getHeight() - 1));
}
}
}
/* create vertexarray for the inner rectangle */
int vertexnr = 0;
BufferedImage image = getUncompressedImage();
Raster raster = image.getData();
double minfy = (double) (beginy) / (getHeight() - 1), maxfy = 0;
for (int y = beginy; y < endy; y++) {
vertexnr = (y - beginy) * stripsize;
vertexarray[vertexnr] = geometry.getPoint(rect.p.add(new Point2D(
(rect.size.x / (getWidth() - 1)) * beginx,
(rect.size.y / (getHeight() - 1)) * y)), 1 + (raster
.getSample(beginx, y, 0) / radius));
// #ifdef RELATIVETRANSFORM
// vertexarray[vertexnr] -= vertexorigin;
// vertexarray[vertexnr] /= vertexscale;
// #endif
texcoordarray[vertexnr++] = new Point2D((double) (beginx)
/ (getWidth() - 1), (double) (y) / (getHeight() - 1));
vertexarray[vertexnr] = geometry.getPoint(rect.p.add(new Point2D(
(rect.size.x / (getWidth() - 1)) * beginx,
(rect.size.y / (getHeight() - 1)) * (y + 1))), 1 + (raster
.getSample(beginx, (y + 1), 0) / radius));
// #ifdef RELATIVETRANSFORM
// vertexarray[vertexnr] -= vertexorigin;
// vertexarray[vertexnr] /= vertexscale;
// #endif
texcoordarray[vertexnr++] = new Point2D((double) (beginx)
/ (getWidth() - 1), (double) (y + 1) / (getHeight() - 1));
// }
// else {
// vertexnr += 2;
// }
double rectxfactor = (rect.size.x / (getWidth() - 1));
double rectyfactor = (rect.size.y / (getHeight() - 1));
for (int x = beginx + 1; x < endx; x++) {
if (x <= 1 || x >= oldEndx - 2 || y < 2 || y >= oldEndy - 2
|| !innerGenerated) {
if (y > beginy) { // use the vertices of the last row
vertexarray[vertexnr] = vertexarray[vertexnr
- stripsize + 1];
} else {
vertexarray[vertexnr] = geometry.getPoint(rect.p
.add(new Point2D(rectxfactor * x, rectyfactor
* y)),
1 + (raster.getSample(x, y, 0) / radius));
// #ifdef RELATIVETRANSFORM
// vertexarray[vertexnr] -= vertexorigin;
// vertexarray[vertexnr] /= vertexscale;
// #endif
}
double fx = (double) (x) / (getWidth() - 1);
double fy = (double) (y) / (getHeight() - 1);
texcoordarray[vertexnr++] = new Point2D(fx, fy);
assert (fx >= 0 && fx <= 1);
// assert(fy>=0 && fy<=1);
minfy = Math.min(fy, minfy);
maxfy = Math.max(fy, maxfy);
vertexarray[vertexnr] = geometry.getPoint(rect.p
.add(new Point2D(rectxfactor * x, rectyfactor
* (y + 1))), 1 + (raster.getSample(x,
(y + 1), 0) / radius));
// #ifdef RELATIVETRANSFORM
// vertexarray[vertexnr] -= vertexorigin;
// vertexarray[vertexnr] /= vertexscale;
// #endif
fy = (double) (y + 1) / (getHeight() - 1);
minfy = Math.min(fy, minfy);
maxfy = Math.max(fy, maxfy);
texcoordarray[vertexnr++] = new Point2D(fx, fy);
// assert(fy>=0 && fy<=1);
} else {
vertexnr += 2;
}
}
// if (y>=30) {
// printf("2 generate y(%i)=%f yb=%f\n", y+1,
// image[endx-1+(y+1)*getWidth()], rect.p.y);
// }
assert (vertexnr == (y - beginy + 1) * stripsize);
}
// #ifdef DEBUG
// printf("minfy: %f maxfy: %f\n", minfy, maxfy);
// #endif
vertexcount = vertexnr;
oldBeginx = beginx;
oldEndx = endx;
oldBeginy = beginy;
oldEndy = endy;
innerGenerated = true;
/* create vertexarray for the border triangle fans */
for (int direction = 0; direction < 4; direction++) {
if (width[direction] == getWidth()) { // no fan
assert(getWidth()==Global.HEIGHTFIELDWIDTH+1);
fancount[direction] = 0;
} else {
int borderwidth = (direction & 1) != 0 ? getWidth()
: getHeight();
int arraysize = borderwidth * 2 + width[direction] * 2 + 20; // FIXME
// for every point on the outer border one fan
fancount[direction] = width[direction];
/* create the necessary arrays */
fansize[direction] = new int[fancount[direction]];
int thisfancount = 0;
fanvertexarray[direction] = new Point3D[arraysize];
fantexcoordarray[direction] = new Point2D[arraysize];
/* fill in the values */
Point3D nextvertex[] = fanvertexarray[direction];
int nextvertex_i = 0;
Point2D nexttexcoord[] = fantexcoordarray[direction];
int nexttexcoord_i = 0;
int x = 0, y = 0, r = 0, nextx = 0, nexty = 0;
int step;
if (width[direction] - 1 > 1) {
step = borderwidth / (width[direction] - 1);
} else {
step = borderwidth - 1;
}
int trianglecount;
// printf("width=%i, step=%i\n", width[direction], step);
for (int outerborder = 0; outerborder < width[direction]; outerborder++) {
trianglecount = 0;
/* start with the middle of the fan */
r = step * outerborder;
switch (direction) {
case 0:
y = r;
x = getWidth() - 1;
nextx = x;
nexty = y + step;
break;
case 1:
x = r;
y = getHeight() - 1;
nextx = x + step;
nexty = y;
break;
case 2:
y = r;
x = 0;
nextx = x;
nexty = y + step;
break;
case 3:
x = r;
y = 0;
nextx = x + step;
nexty = y;
break;
}
nextvertex[nextvertex_i] = geometry.getPoint(
rect.p.add(new Point2D(
(rect.size.x / (getWidth() - 1)) * x,
(rect.size.y / (getHeight() - 1)) * y)),
1 + (raster.getSample(x, y, 0) / radius));
// #ifdef RELATIVETRANSFORM
// *nextvertex -= vertexorigin;
// *nextvertex /= vertexscale;
// #endif
nexttexcoord[nexttexcoord_i] = new Point2D((double) (x)
/ (getWidth() - 1), (double) (y)
/ (getHeight() - 1));
// if (direction==0) {
// printf("generate y(%i)=%f yb=%f\n", y,
// image[x+y*getWidth()], rect.size.y);
// }
nextvertex_i++;
nexttexcoord_i++;
trianglecount++;
/*
* and now the outer points of the fan, the inner points of
* the tile, ordered clockwise
*/
int istart = outerborder * step - (step / 2), istop = outerborder
* step + (step / 2), istep = 1;
if (direction == 1 || direction == 2) {
int itmp = istop;
istop = istart;
istart = itmp;
istep = -1;
/* add next outerborder point here */
if (nextx < getWidth() && nexty < getHeight()) {
nextvertex[nextvertex_i] = geometry.getPoint(rect.p
.add(new Point2D(
(rect.size.x / (getWidth() - 1))
* nextx,
(rect.size.y / (getHeight() - 1))
* nexty)), 1 + (raster
.getSample(nextx, nexty, 0) / radius));
// #ifdef RELATIVETRANSFORM
// *nextvertex -= vertexorigin;
// *nextvertex /= vertexscale;
// #endif
nexttexcoord[nexttexcoord_i] = new Point2D(
(double) (nextx) / (getWidth() - 1),
(double) (nexty) / (getHeight() - 1));
nextvertex_i++;
nexttexcoord_i++;
trianglecount++;
}
}
for (int innerborder = istart; (direction == 1 || direction == 2) ? innerborder >= istop
: innerborder <= istop; innerborder += istep) {
if (innerborder >= 0 && innerborder < borderwidth) {
r = innerborder;
switch (direction) {
case 0:
y = r;
x = getWidth() - 2;
break;
case 1:
x = r;
y = getHeight() - 2;
break;
case 2:
y = r;
x = 1;
break;
case 3:
x = r;
y = 1;
break;
}
nextvertex[nextvertex_i] = geometry.getPoint(rect.p
.add(new Point2D(
(rect.size.x / (getWidth() - 1))
* x,
(rect.size.y / (getHeight() - 1))
* y)), 1 + (raster
.getSample(x, y, 0) / radius));
// #ifdef RELATIVETRANSFORM
// *nextvertex -= vertexorigin;
// *nextvertex /= vertexscale;
// #endif
nexttexcoord[nexttexcoord_i] = new Point2D(
(double) (x) / (getWidth() - 1),
(double) (y) / (getHeight() - 1));
nextvertex_i++;
nexttexcoord_i++;
trianglecount++;
}
}
if (direction == 3 || direction == 0) {
/* add next outerborder point here */
if (nextx < getWidth() && nexty < getHeight()) {
nextvertex[nextvertex_i] = geometry.getPoint(rect.p
.add(new Point2D(
(rect.size.x / (getWidth() - 1))
* nextx,
(rect.size.y / (getHeight() - 1))
* nexty)), 1 + (raster
.getSample(nextx, nexty, 0) / radius));
// #ifdef RELATIVETRANSFORM
// *nextvertex -= vertexorigin;
// *nextvertex /= vertexscale;
// #endif
nexttexcoord[nexttexcoord_i] = new Point2D(
(double) (nextx) / (getWidth() - 1),
(double) (nexty) / (getHeight() - 1));
nextvertex_i++;
nexttexcoord_i++;
trianglecount++;