From a5eedba1d8264cd12fb6e1d9a259b91d64c3d021 Mon Sep 17 00:00:00 2001 From: benfry Date: Sun, 5 Nov 2006 15:49:20 +0000 Subject: [PATCH] fix several triangulation issues, bugs #97, #390, and #111 --- core/src/processing/core/PGraphics.java | 2 +- core/src/processing/core/PGraphics3D.java | 109 +++++++++++++++++----- core/todo.txt | 65 ++++++------- 3 files changed, 113 insertions(+), 63 deletions(-) diff --git a/core/src/processing/core/PGraphics.java b/core/src/processing/core/PGraphics.java index 7a02aa486..f2d26c624 100644 --- a/core/src/processing/core/PGraphics.java +++ b/core/src/processing/core/PGraphics.java @@ -1078,7 +1078,7 @@ public abstract class PGraphics extends PImage implements PConstants { } // when the coords are Float.MAX_VALUE, then treat as a 2D curve - int dimensions = (x == Float.MAX_VALUE) ? 2 : 3; + int dimensions = (z == Float.MAX_VALUE) ? 2 : 3; if (dimensions == 3) { vertex[MZ] = z; diff --git a/core/src/processing/core/PGraphics3D.java b/core/src/processing/core/PGraphics3D.java index fd249b7cd..2da7f95e4 100644 --- a/core/src/processing/core/PGraphics3D.java +++ b/core/src/processing/core/PGraphics3D.java @@ -553,9 +553,19 @@ public class PGraphics3D extends PGraphics { vertex_order = temp2; //message(CHATTER, "allocating more vertices " + vertices.length); } - float vertex[] = vertices[vertexCount++]; + float vertex[] = vertices[vertexCount]; //if (polygon.redundantVertex(x, y, z)) return; + if (vertexCount > 0) { + float pvertex[] = vertices[vertexCount-1]; + if ((abs(pvertex[MX] - x) < EPSILON) && + (abs(pvertex[MY] - y) < EPSILON) && + (abs(pvertex[MZ] - z) < EPSILON)) { + // this vertex is identical, don't add it, + // because it will anger the triangulator + return; + } + } // user called vertex(), so that invalidates anything queued // up for curve vertices. if this is internally called by @@ -606,6 +616,8 @@ public class PGraphics3D extends PGraphics { vertex[NZ] = normalZ; vertex[BEEN_LIT] = 0; + + vertexCount++; } @@ -832,16 +844,17 @@ public class PGraphics3D extends PGraphics { //case CONVEX_POLYGON: { // store index of first vertex - int first = lineCount; + //int first = lineCount; stop = vertex_end - 1; add_path(); for (int i = vertex_start; i < stop; i++) { add_line(i, i+1); + //System.out.println("adding line " + i); } if (mode == CLOSE) { // draw the last line connecting back to the first point in poly - add_line(stop, lines[first][VERTEX1]); + add_line(stop, vertex_start); //lines[first][VERTEX1]); } } break; @@ -918,7 +931,7 @@ public class PGraphics3D extends PGraphics { // TRANSFORM / LIGHT / CLIP if (lightCount > 0 && fill) { - handle_lighting(); + handle_lighting(); } else { handle_no_lighting(); @@ -1452,18 +1465,72 @@ public class PGraphics3D extends PGraphics { * bit of code from the web. */ private void triangulate_polygon() { + // this clipping algorithm only works in 2D, so in cases where a + // polygon is drawn perpendicular to the z-axis, the area will be zero, + // and triangulation will fail. as such, when the area calculates to + // zero, figure out whether x or y is empty, and calculate based on the + // two dimensions that actually contain information. + // http://dev.processing.org/bugs/show_bug.cgi?id=111 + int d1 = MX; + int d2 = MY; + // this brings up the nastier point that there may be cases where + // a polygon is irregular in space and will throw off the + // clockwise/counterclockwise calculation. for instance, if clockwise + // relative to x and z, but counter relative to y and z or something + // like that.. will wait to see if this is in fact a problem before + // hurting my head on the math. + // first we check if the polygon goes clockwise or counterclockwise - float area = 0.0f; + float area = 0; for (int p = vertex_end - 1, q = vertex_start; q < vertex_end; p = q++) { - area += (vertices[q][MX] * vertices[p][MY] - - vertices[p][MX] * vertices[q][MY]); - //area += (vertices[q][X] * vertices[p][Y] - - // vertices[p][X] * vertices[q][Y]); + area += (vertices[q][d1] * vertices[p][d2] - + vertices[p][d1] * vertices[q][d2]); + } + // rather than checking for the perpendicular case first, only do it + // when the area calculates to zero. checking for perpendicular would be + // a needless waste of time for the 99% case. + if (area == 0) { + // figure out which dimension is the perpendicular axis + boolean foundValidX = false; + boolean foundValidY = false; + for (int i = vertex_start; i < vertex_end; i++) { + if (vertices[i][MX] != 0) foundValidX = true; + if (vertices[i][MY] != 0) foundValidY = true; + } + if (foundValidX && !foundValidY) { + //d1 = MX; // already the case + d2 = MZ; + + } else if (!foundValidX && foundValidY) { + // ermm.. which is the proper order for cw/ccw here? + d1 = MY; + d2 = MZ; + + } else { + // screw it, this polygon is just f-ed up + return; + } + + // re-calculate the area, with what should be good values + for (int p = vertex_end - 1, q = vertex_start; q < vertex_end; p = q++) { + area += (vertices[q][d1] * vertices[p][d2] - + vertices[p][d1] * vertices[q][d2]); + } + } + + // don't allow polygons to come back and meet themselves, + // otherwise it will anger the triangulator + // http://dev.processing.org/bugs/show_bug.cgi?id=97 + float vfirst[] = vertices[vertex_start]; + float vlast[] = vertices[vertex_end-1]; + if ((abs(vfirst[MX] - vlast[MX]) < EPSILON) && + (abs(vfirst[MY] - vlast[MY]) < EPSILON) && + (abs(vfirst[MZ] - vlast[MZ]) < EPSILON)) { + vertex_end--; } // then sort the vertices so they are always in a counterclockwise order int j = 0; - //if (0.0f < area) { // def < if (area > 0) { for (int i = vertex_start; i < vertex_end; i++) { j = i - vertex_start; @@ -1494,14 +1561,12 @@ public class PGraphics3D extends PGraphics { int w = v + 1; if (vc <= w) w = 0; // next // triangle A B C - //float Ax, Ay, Bx, By, Cx, Cy, Px, Py; - - float Ax = -vertices[vertex_order[u]][MX]; - float Ay = vertices[vertex_order[u]][MY]; - float Bx = -vertices[vertex_order[v]][MX]; - float By = vertices[vertex_order[v]][MY]; - float Cx = -vertices[vertex_order[w]][MX]; - float Cy = vertices[vertex_order[w]][MY]; + float Ax = -vertices[vertex_order[u]][d1]; + float Ay = vertices[vertex_order[u]][d2]; + float Bx = -vertices[vertex_order[v]][d1]; + float By = vertices[vertex_order[v]][d2]; + float Cx = -vertices[vertex_order[w]][d1]; + float Cy = vertices[vertex_order[w]][d2]; // first we check if continues going ccw if (EPSILON > (((Bx-Ax) * (Cy-Ay)) - ((By-Ay) * (Cx-Ax)))) { @@ -1516,10 +1581,8 @@ public class PGraphics3D extends PGraphics { continue; } - //float Px = -vertices[vertex_order[p]][X]; - //float Py = vertices[vertex_order[p]][Y]; - float Px = -vertices[vertex_order[p]][MX]; - float Py = vertices[vertex_order[p]][MY]; + float Px = -vertices[vertex_order[p]][d1]; + float Py = vertices[vertex_order[p]][d2]; float ax = Cx - Bx; float ay = Cy - By; float bx = Ax - Cx; float by = Ay - Cy; @@ -3672,11 +3735,11 @@ public class PGraphics3D extends PGraphics { return (float)Math.pow(a, b); } - /* private final float abs(float a) { return (a < 0) ? -a : a; } + /* private final float sin(float angle) { return (float)Math.sin(angle); } diff --git a/core/todo.txt b/core/todo.txt index bb5c94770..6589579ad 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -5,9 +5,24 @@ X null incompatible with Global antialiasing enable key X fix issue where ambientLight(r, g, b) was instead ambientLight(r, g, r) X http://dev.processing.org/bugs/show_bug.cgi?id=412 X createFont() should always use native fonts -_ need to warn that fonts may not be installed -_ recommend that people include the ttf if that's the thing -_ or rather, that this is only recommended for offline use +X need to warn that fonts may not be installed +X recommend that people include the ttf if that's the thing +X or rather, that this is only recommended for offline use +X fix 3D tessellation problems with curveVertex and bezierVertex +X actually was z = Float.MAX_VALUE regression +X http://dev.processing.org/bugs/show_bug.cgi?id=390 +X two examples in sketchbook +X this has been reported several times +X concave polygons having trouble if points come back to meet +X tesselator/triangulator gets confused when points doubled up +X might need to avoid previous vertex hitting itself +X http://dev.processing.org/bugs/show_bug.cgi?id=97 +X graphics gems 5 has more about tessellation +X polygons perpendicular to axis not drawing +X is this a clipping error? +X probably a triangulation error, because triangles work ok +X http://dev.processing.org/bugs/show_bug.cgi?id=111 +X problem is that the area of the polygon isn't taking into account z _ saveFrame() produces a black background because bg not set correctly: _ http://dev.processing.org/bugs/show_bug.cgi?id=421 @@ -28,15 +43,6 @@ _ in which case it should be set to opaque _ have createGraphics() create a completely transparent image _ and also not require defaults() to be called -_ this produces a dark blue background: -colorMode(RGB, 100); -background(128); - -_ fix 3D tessellation problems with curveVertex and bezierVertex -_ http://dev.processing.org/bugs/show_bug.cgi?id=390 -_ two examples in sketchbook -_ this has been reported several times - _ image outofmemoryerror for casey's students _ http://dev.processing.org/bugs/show_bug.cgi?id=355 _ this may be related to a ton of other memory bugs @@ -47,26 +53,9 @@ _ maybe the image binding not getting unbound? _ loading lots of images is a problem, describe how to unload _ is it possible? necessary to call delay(5) or something? -_ make this work for JAVA2D and P3D +_ createGraphics() having problems with JAVA2D, and sometimes with P3D _ http://dev.processing.org/bugs/show_bug.cgi?id=419 -PGraphics pg; - -void setup() { - size(100, 100); - pg = createGraphics(80, 80, P3D); - pg.beginDraw(); - pg.background(102); - pg.stroke(255); - pg.line(20, 20, 80, 80); - pg.endDraw(); - noLoop(); -} - -void draw() { - image(pg, 10, 10); -} - _ detect when using full screen _ and if so, remove decoration and don't bother with bg present frame _ frame.setUndecorated(true); @@ -110,6 +99,7 @@ _ http://processing.org/discourse/yabb_beta/YaBB.cgi?board=SoftwareBugs;action _ alloc() stuff not fixed because of thread halting _ problem where alloc happens inside setup(), so, uh.. _ http://dev.processing.org/bugs/show_bug.cgi?id=369 +_ should instead create new buffer, and swap it in next time through opengl texture handling _ maybe break out a separate timage object in textures? @@ -775,15 +765,6 @@ _ rect() changes size as it changes position _ http://dev.processing.org/bugs/show_bug.cgi?id=95 _ lines skip on 200x200 surface because of fixed point rounding error _ http://dev.processing.org/bugs/show_bug.cgi?id=267 -_ polygons perpendicular to axis not drawing -_ is this a clipping error? -_ probably a triangulation error, because triangles work ok -_ http://dev.processing.org/bugs/show_bug.cgi?id=111 -_ concave polygons having trouble if points come back to meet -_ tesselator/triangulator gets confused when points doubled up -_ might need to avoid previous vertex hitting itself -_ http://dev.processing.org/bugs/show_bug.cgi?id=97 -_ graphics gems 5 has more about tessellation _ P3D not doing bilinear interpolation in text and images _ because smooth() has to be set (and smooth throws an error in P3D) _ how should this be handled? a hint? allowing smooth()? @@ -942,3 +923,9 @@ _ pdf export ignoring transparency on linux _ check to see if this is the case on other linux machines _ seems to be working fine on windows _ http://dev.processing.org/bugs/show_bug.cgi?id=345 + + +LATER + +_ setting a gray that's greater than the colorMode() can produce strange colors +_ http://dev.processing.org/bugs/show_bug.cgi?id=432