📄 generalizedstrip.java
字号:
IntList stripCounts = new IntList(size) ; IntList fanCounts = new IntList(size) ; toStripsAndFans(vertices, frontFace, stripVerts, stripCounts, fanVerts, fanCounts) ; if (fanCounts.count == 0) if (stripCounts.count > 0) return new StripArray(stripVerts, stripCounts) ; else return null ; // convert each fan to one or more strips int i, v = 0 ; for (i = 0 ; i < fanCounts.count ; i++) { fanToStrips(v, fanCounts.ints[i], fanVerts.ints, stripVerts, stripCounts, false) ; v += fanCounts.ints[i] ; } // create the StripArray output StripArray sa = new StripArray(stripVerts, stripCounts) ; if (debug) { System.out.println("GeneralizedStrip.toTriangleStrips" + "\n number of strips: " + sa.stripCounts.count) ; if (sa.stripCounts.count > 0) { System.out.println(" number of vertices: " + sa.vertices.count + "\n vertices/strip: " + ((float)sa.vertices.count / (float)sa.stripCounts.count)) ; System.out.print(" strip counts: [") ; for (i = 0 ; i < sa.stripCounts.count-1 ; i++) System.out.print(sa.stripCounts.ints[i] + ", ") ; System.out.println(sa.stripCounts.ints[i] + "]") ; } System.out.println() ; } return sa ; } private static void fanToStrips(int v, int length, int fans[], IntList stripVerts, IntList stripCounts, boolean convexPlanar) { if (convexPlanar) { // Construct a strip by criss-crossing across the interior. stripCounts.add(length) ; stripVerts.add(fans[v]) ; int j = v + 1 ; int k = v + (length - 1) ; while (j <= k) { stripVerts.add(fans[j++]) ; if (j > k) break ; stripVerts.add(fans[k--]) ; } } else { // Traverse non-convex or non-planar fan, biting off 3-triangle // strips or less. First 5 vertices produce 1 strip of 3 // triangles, and every 4 vertices after that produce another // strip of 3 triangles. Each remaining strip adds 2 vertices. int fanStart = v ; v++ ; while (v+4 <= fanStart + length) { stripVerts.add(fans[v]) ; stripVerts.add(fans[v+1]) ; stripVerts.add(fans[fanStart]) ; stripVerts.add(fans[v+2]) ; stripVerts.add(fans[v+3]) ; stripCounts.add(5) ; v += 3 ; } // Finish off the fan. if (v+1 < fanStart + length) { stripVerts.add(fans[v]) ; stripVerts.add(fans[v+1]) ; stripVerts.add(fans[fanStart]) ; v++ ; if (v+1 < fanStart + length) { stripVerts.add(fans[v+1]) ; stripCounts.add(4) ; } else stripCounts.add(3) ; } } } /** * Interprets the vertex flags associated with a class implementing * GeneralizedStripFlags, constructing and returning an array of vertex * references representing the original generalized strip as individual * triangles. Each sequence of three consecutive vertex references in the * output defines a single triangle. * * @param vertices an object implementing GeneralizedStripFlags * @param frontFace a flag, either GeneralizedStripFlags.FRONTFACE_CW or * GeneralizedStripFlags.FRONTFACE_CCW, indicating front face winding * @return an array of indices into the original vertex array */ static int[] toTriangles(GeneralizedStripFlags vertices, int frontFace) { int vertexCount = 0 ; StripArray sa[] = toStripsAndFans(vertices, frontFace) ; if (sa[0] != null) vertexCount = 3 * getTriangleCount(sa[0].stripCounts) ; if (sa[1] != null) vertexCount += 3 * getTriangleCount(sa[1].stripCounts) ; if (debug) System.out.println("GeneralizedStrip.toTriangles\n" + " number of triangles: " + vertexCount/3 + "\n" + " number of vertices: " + vertexCount + "\n") ; int t = 0 ; int triangles[] = new int[vertexCount] ; if (sa[0] != null) t = stripsToTriangles(t, triangles, 0, sa[0].vertices.ints, 0, sa[0].stripCounts.ints, sa[0].stripCounts.count) ; if (sa[1] != null) t = fansToTriangles(t, triangles, 0, sa[1].vertices.ints, 0, sa[1].stripCounts.ints, sa[1].stripCounts.count) ; return triangles ; } private static int stripsToTriangles(int tstart, int tbuff[], int vstart, int vertices[], int stripStart, int stripCounts[], int stripCount) { int t = tstart ; int v = vstart ; for (int i = 0 ; i < stripCount ; i++) { for (int j = 0 ; j < stripCounts[i+stripStart] - 2 ; j++) { if ((j & 0x01) == 0) { // even-numbered triangles tbuff[t*3 +0] = vertices[v+0] ; tbuff[t*3 +1] = vertices[v+1] ; tbuff[t*3 +2] = vertices[v+2] ; } else { // odd-numbered triangles tbuff[t*3 +0] = vertices[v+1] ; tbuff[t*3 +1] = vertices[v+0] ; tbuff[t*3 +2] = vertices[v+2] ; } t++ ; v++ ; } v += 2 ; } return t ; } private static int fansToTriangles(int tstart, int tbuff[], int vstart, int vertices[], int stripStart, int stripCounts[], int stripCount) { int t = tstart ; int v = vstart ; for (int i = 0 ; i < stripCount ; i++) { for (int j = 0 ; j < stripCounts[i+stripStart] - 2 ; j++) { tbuff[t*3 +0] = vertices[v] ; tbuff[t*3 +1] = vertices[v+j+1] ; tbuff[t*3 +2] = vertices[v+j+2] ; t++ ; } v += stripCounts[i+stripStart] ; } return t ; } /** * Interprets the vertex flags associated with a class implementing * GeneralizedStripFlags, constructing and returning a 2-element array of * StripArray objects. The first StripArray will contain triangle strips * and the second will contain individual triangles in the vertices * field. Short strips will be converted to individual triangles. * * @param vertices an object implementing GeneralizedStripFlags * @param frontFace a flag, either GeneralizedStripFlags.FRONTFACE_CW or * GeneralizedStripFlags.FRONTFACE_CCW, indicating front face winding * @param shortStripSize strips this size or less will be converted to * individual triangles if there are more than maxShortStrips of them * @param maxShortStrips maximum number of short strips allowed before * creating individual triangles * @return a 2-element array containing strips in 0 and triangles in 1 */ static StripArray[] toStripsAndTriangles(GeneralizedStripFlags vertices, int frontFace, int shortStripSize, int maxShortStrips) { int longStripCount = 0 ; int longStripVertexCount = 0 ; int shortStripCount = 0 ; int triangleCount = 0 ; StripArray sa[] = new StripArray[2] ; StripArray ts = toTriangleStrips(vertices, frontFace) ; for (int i = 0 ; i < ts.stripCounts.count ; i++) if (ts.stripCounts.ints[i] <= shortStripSize) { shortStripCount++ ; triangleCount += ts.stripCounts.ints[i] - 2 ; } else { longStripCount++ ; longStripVertexCount += ts.stripCounts.ints[i] ; } if (debug) System.out.print("GeneralizedStrip.toStripsAndTriangles\n" + " short strip size: " + shortStripSize + " short strips tolerated: " + maxShortStrips + " number of short strips: " + shortStripCount + "\n\n") ; if (shortStripCount <= maxShortStrips) { sa[0] = ts ; sa[1] = null ; } else { int si = 0 ; int newStripVerts[] = new int[longStripVertexCount] ; int ci = 0 ; int newStripCounts[] = new int[longStripCount] ; int ti = 0 ; int triangles[] = new int[3*triangleCount] ; int vi = 0 ; for (int i = 0 ; i < ts.stripCounts.count ; i++) { if (ts.stripCounts.ints[i] <= shortStripSize) { ti = stripsToTriangles(ti, triangles, vi, ts.vertices.ints, i, ts.stripCounts.ints, 1) ; vi += ts.stripCounts.ints[i] ; } else { newStripCounts[ci++] = ts.stripCounts.ints[i] ; for (int j = 0 ; j < ts.stripCounts.ints[i] ; j++) newStripVerts[si++] = ts.vertices.ints[vi++] ; } } if (longStripCount > 0) sa[0] = new StripArray(new IntList(newStripVerts), new IntList(newStripCounts)) ; else sa[0] = null ; sa[1] = new StripArray(new IntList(triangles), null) ; if (debug) { System.out.println(" triangles separated: " + triangleCount) ; if (longStripCount > 0) { System.out.println (" new vertices/strip: " + ((float)longStripVertexCount/(float)longStripCount)) ; System.out.print(" long strip counts: [") ; for (int i = 0 ; i < longStripCount-1 ; i++) System.out.print(newStripCounts[i++] + ", ") ; System.out.println (newStripCounts[longStripCount-1] + "]\n") ; } } } return sa ; } /** * Interprets the vertex flags associated with a class implementing * GeneralizedStripFlags, constructing and returning a StripArray. * * RESTART_CW and RESTART_CCW are treated as equivalent, as are * REPLACE_MIDDLE and REPLACE_OLDEST. * * @param vertices an object implementing GeneralizedStripFlags * @return a StripArray representing an array of line strips */ static StripArray toLineStrips(GeneralizedStripFlags vertices) { int v, size, stripStart, stripLength, flag ; stripStart = 0 ; stripLength = 2 ; size = vertices.getFlagCount() ; // Initialize IntLists to worst-case sizes. IntList stripVerts = new IntList(size*2) ; IntList stripCounts = new IntList(size) ; // Vertex replace flags for the first two vertices are irrelevant. v = 2 ; while (v < size) { flag = vertices.getFlag(v) ; if ((flag != RESTART_CW) && (flag != RESTART_CCW)) { // proceed to the next vertex. stripLength++ ; v++ ; } else { // Record the last strip. stripCounts.add(stripLength) ; for (int i = stripStart ; i < stripStart+stripLength ; i++) stripVerts.add(i) ; // Start a new strip and skip to its 3rd vertex. stripStart = v ; stripLength = 2 ; v += 2 ; } } // Finish off the last strip. // If v > size then the strip is degenerate. if (v == size) { stripCounts.add(stripLength) ; for (int i = stripStart ; i < stripStart+stripLength ; i++) stripVerts.add(i) ; } else throw new IllegalArgumentException (J3dUtilsI18N.getString("GeneralizedStrip0")) ; if (debug) { System.out.println("GeneralizedStrip.toLineStrips\n") ; if (v > size) System.out.println(" ended with a degenerate line") ; System.out.println(" number of strips: " + stripCounts.count) ; if (stripCounts.count > 0) { System.out.println(" number of vertices: " + stripVerts.count) ; System.out.println(" vertices/strip: " + (float)stripVerts.count/stripCounts.count) ; System.out.println(" strip counts: " + stripCounts.toString()) ; // System.out.println(" indices: " + stripVerts.toString()) ; } System.out.println() ; } if (stripCounts.count > 0) return new StripArray(stripVerts, stripCounts) ; else return null ; } /** * Counts the number of lines defined by arrays of line strips. * * @param stripCounts array of strip counts, as used by the * GeometryStripArray object * @return number of lines in the strips */ static int getLineCount(int stripCounts[]) { int count = 0 ; for (int i = 0 ; i < stripCounts.length ; i++) count += (stripCounts[i] - 1) ; return count ; } /** * Counts the number of triangles defined by arrays of * triangle strips or fans. * * @param stripCounts array of strip counts, as used by the * GeometryStripArray object * @return number of triangles in the strips or fans */ static int getTriangleCount(int stripCounts[]) { int count = 0 ; for (int i = 0 ; i < stripCounts.length ; i++) count += (stripCounts[i] - 2) ; return count ; } /** * Counts the number of triangles defined by arrays of * triangle strips or fans. * * @param stripCounts IntList of strip counts * @return number of triangles in the strips or fans */ static int getTriangleCount(IntList stripCounts) { int count = 0 ; for (int i = 0 ; i < stripCounts.count ; i++) count += (stripCounts.ints[i] - 2) ; return count ; } /** * Breaks up triangle strips into separate triangles. * * @param stripCounts array of strip counts, as used by the * GeometryStripArray object * @return array of ints which index into the original vertex array; each * set of three consecutive vertex indices defines a single triangle */ static int[] stripsToTriangles(int stripCounts[]) { int triangleCount = getTriangleCount(stripCounts) ; int tbuff[] = new int[3*triangleCount] ; IntList vertices = new IntList(triangleCount + 2*stripCounts.length) ; vertices.fillAscending() ; stripsToTriangles(0, tbuff, 0, vertices.ints, 0, stripCounts, stripCounts.length) ; return tbuff ; } /** * Breaks up triangle fans into separate triangles. * * @param stripCounts array of strip counts, as used by the * GeometryStripArray object * @return array of ints which index into the original vertex array; each * set of three consecutive vertex indices defines a single triangle */ static int[] fansToTriangles(int stripCounts[]) { int triangleCount = getTriangleCount(stripCounts) ; int tbuff[] = new int[3*triangleCount] ; IntList vertices = new IntList(triangleCount + 2*stripCounts.length) ; vertices.fillAscending() ; fansToTriangles(0, tbuff, 0, vertices.ints, 0, stripCounts, stripCounts.length) ; return tbuff ; } /** * Takes a fan and converts it to one or more strips. * * @param v index into the fans array of the first vertex in the fan * @param length number of vertices in the fan * @param fans array of vertex indices representing one or more fans * @param convexPlanar if true indicates that the fan is convex and * planar; such fans will always be converted into a single strip * @return a StripArray containing the converted strips */ static StripArray fanToStrips(int v, int length, int fans[], boolean convexPlanar) { // Initialize IntLists to worst-case sizes. IntList stripVerts = new IntList(length*3) ; IntList stripCounts = new IntList(length) ; fanToStrips(v, length, fans, stripVerts, stripCounts, convexPlanar) ; return new StripArray(stripVerts, stripCounts) ; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -