📄 font3d.java
字号:
// Compute islandCounts[][] and outVerts[][] UnorderList islandsList = new UnorderList(10, IslandsNode.class); islandsTree.collectOddLevelNode(islandsList, 0); IslandsNode nodes[] = (IslandsNode []) islandsList.toArray(false); int islandCounts[][] = new int[islandsList.arraySize()][]; Point3f outVerts[][] = new Point3f[islandCounts.length][]; int nchild, sum; IslandsNode node; for (i=0; i < islandCounts.length; i++) { node = nodes[i]; nchild = node.numChild(); islandCounts[i] = new int[nchild + 1]; islandCounts[i][0] = node.numVertices(); sum = 0; sum += islandCounts[i][0]; for (j=0; j < nchild; j++) { islandCounts[i][j+1] = node.getChild(j).numVertices(); sum += islandCounts[i][j+1]; } outVerts[i] = new Point3f[sum]; startIdx = 0; for (k=node.startIdx; k < node.endIdx; k++) { outVerts[i][startIdx++] = vertices[k]; } for (j=0; j < nchild; j++) { endIdx = node.getChild(j).endIdx; for (k=node.getChild(j).startIdx; k < endIdx; k++) { outVerts[i][startIdx++] = vertices[k]; } } } islandsTree = null; // Free memory islandsList = null; vertices = null; contourCounts = new int[1]; int currCoordIndex = 0, vertOffset = 0; ArrayList triangData = new ArrayList(); Point3f q1 = new Point3f(), q2 = new Point3f(), q3 = new Point3f(); Vector3f n1 = new Vector3f(), n2 = new Vector3f(); numPoints = 0; //Now loop thru each island, calling triangulator once per island. //Combine triangle data for all islands together in one object. for (i=0;i < islandCounts.length;i++) { contourCounts[0] = islandCounts[i].length; numPoints += outVerts[i].length; gi = new GeometryInfo(GeometryInfo.POLYGON_ARRAY); gi.setCoordinates(outVerts[i]); gi.setStripCounts(islandCounts[i]); gi.setContourCounts(contourCounts); ng.generateNormals(gi); GeometryArray ga = gi.getGeometryArray(false, false, false); vertOffset += ga.getVertexCount(); triangData.add(ga); } // Multiply by 2 since we create 2 faces of the font // Second term is for side-faces along depth of the font if (fontExtrusion == null) vertCnt = vertOffset; else{ if (fontExtrusion.shape == null) vertCnt = vertOffset * 2 + numPoints *6; else{ vertCnt = vertOffset * 2 + numPoints * 6 * (fontExtrusion.pnts.length -1); } } // XXXX: Should use IndexedTriangleArray to avoid // duplication of vertices. To create triangles for // side faces, every vertex is duplicated currently. TriangleArray triAry = new TriangleArray(vertCnt, GeometryArray.COORDINATES | GeometryArray.NORMALS); boolean flip_orient[] = new boolean[islandCounts.length]; boolean findOrient; // last known non-degenerate normal Vector3f goodNormal = new Vector3f(); for (j=0;j < islandCounts.length;j++) { GeometryArray ga = (GeometryArray)triangData.get(j); vertOffset = ga.getVertexCount(); findOrient = false; //Create the triangle array for (i= 0; i < vertOffset; i+= 3, currCoordIndex += 3){ //Get 3 points. Since triangle is known to be flat, normal // must be same for all 3 points. ga.getCoordinate(i, p1); ga.getNormal(i, n1); ga.getCoordinate(i+1, p2); ga.getCoordinate(i+2, p3); if (!findOrient) { //Check here if triangles are wound incorrectly and need //to be flipped. if (!getNormal(p1,p2, p3, n2)) { continue; } if (n2.z >= EPS) { flip_orient[j] = false; } else if (n2.z <= -EPS) { flip_orient[j] = true; } else { continue; } findOrient = true; } if (flip_orient[j]){ //New Triangulator preserves contour orientation. If contour //input is wound incorrectly, swap 2nd and 3rd points to //sure all triangles are wound correctly for j3d. q1.x = p2.x; q1.y = p2.y; q1.z = p2.z; p2.x = p3.x; p2.y = p3.y; p2.z = p3.z; p3.x = q1.x; p3.y = q1.y; p3.z = q1.z; n1.x = -n1.x; n1.y = -n1.y; n1.z = -n1.z; } if (fontExtrusion != null) { n2.x = -n1.x;n2.y = -n1.y;n2.z = -n1.z; triAry.setCoordinate(currCoordIndex, p1); triAry.setNormal(currCoordIndex, n2); triAry.setCoordinate(currCoordIndex+1, p3); triAry.setNormal(currCoordIndex+1, n2); triAry.setCoordinate(currCoordIndex+2, p2); triAry.setNormal(currCoordIndex+2, n2); q1.x = p1.x; q1.y = p1.y; q1.z = p1.z + fontExtrusion.length; q2.x = p2.x; q2.y = p2.y; q2.z = p2.z + fontExtrusion.length; q3.x = p3.x; q3.y = p3.y; q3.z = p3.z + fontExtrusion.length; triAry.setCoordinate(currCoordIndex+vertOffset, q1); triAry.setNormal(currCoordIndex+vertOffset, n1); triAry.setCoordinate(currCoordIndex+1+vertOffset, q2); triAry.setNormal(currCoordIndex+1+vertOffset, n1); triAry.setCoordinate(currCoordIndex+2+vertOffset, q3); triAry.setNormal(currCoordIndex+2+vertOffset, n1); } else { triAry.setCoordinate(currCoordIndex, p1); triAry.setNormal(currCoordIndex, n1); triAry.setCoordinate(currCoordIndex+1, p2); triAry.setNormal(currCoordIndex+1, n1); triAry.setCoordinate(currCoordIndex+2, p3); triAry.setNormal(currCoordIndex+2, n1); } } if (fontExtrusion != null) { currCoordIndex += vertOffset; } } //Now add side triangles in both cases. // Since we duplicated triangles with different Z, make sure // currCoordIndex points to correct location. if (fontExtrusion != null){ if (fontExtrusion.shape == null){ boolean smooth; // we'll put a crease if the angle between the normals is // greater than 44 degrees float threshold = (float) Math.cos(44.0*Math.PI/180.0); float cosine; // need the previous normals to check for smoothing Vector3f pn1 = null, pn2 = null; // need the next normals to check for smoothing Vector3f n3 = new Vector3f(), n4 = new Vector3f(); // store the normals for each point because they are // the same for both triangles Vector3f p1Normal = new Vector3f(); Vector3f p2Normal = new Vector3f(); Vector3f p3Normal = new Vector3f(); Vector3f q1Normal = new Vector3f(); Vector3f q2Normal = new Vector3f(); Vector3f q3Normal = new Vector3f(); for (i=0;i < islandCounts.length;i++){ for (j=0, k=0, num =0;j < islandCounts[i].length;j++){ num += islandCounts[i][j]; p1.x = outVerts[i][num - 1].x; p1.y = outVerts[i][num - 1].y; p1.z = 0.0f; q1.x = p1.x; q1.y = p1.y; q1.z = p1.z+fontExtrusion.length; p2.z = 0.0f; q2.z = p2.z+fontExtrusion.length; for (int m=0; m < num;m++) { p2.x = outVerts[i][m].x; p2.y = outVerts[i][m].y; q2.x = p2.x; q2.y = p2.y; if (getNormal(p1, q1, p2, n1)) { if (!flip_side_orient) { n1.negate(); } goodNormal.set(n1); break; } } for (;k < num;k++){ p2.x = outVerts[i][k].x;p2.y = outVerts[i][k].y;p2.z = 0.0f; q2.x = p2.x; q2.y = p2.y; q2.z = p2.z+fontExtrusion.length; if (!getNormal(p1, q1, p2, n1)) { n1.set(goodNormal); } else { if (!flip_side_orient) { n1.negate(); } goodNormal.set(n1); } if (!getNormal(p2, q1, q2, n2)) { n2.set(goodNormal); } else { if (!flip_side_orient) { n2.negate(); } goodNormal.set(n2); } // if there is a previous normal, see if we need to smooth // this normal or make a crease if (pn1 != null) { cosine = n1.dot(pn2); smooth = cosine > threshold; if (smooth) { p1Normal.x = (pn1.x + pn2.x + n1.x); p1Normal.y = (pn1.y + pn2.y + n1.y); p1Normal.z = (pn1.z + pn2.z + n1.z); normalize(p1Normal); q1Normal.x = (pn2.x + n1.x + n2.x); q1Normal.y = (pn2.y + n1.y + n2.y); q1Normal.z = (pn2.z + n1.z + n2.z); normalize(q1Normal); } // if smooth else { p1Normal.x = n1.x; p1Normal.y = n1.y; p1Normal.z = n1.z; q1Normal.x = n1.x+n2.x; q1Normal.y = n1.y+n2.y; q1Normal.z = n1.z+ n2.z; normalize(q1Normal); } // else } // if pn1 != null else { pn1 = new Vector3f(); pn2 = new Vector3f(); p1Normal.x = n1.x; p1Normal.y = n1.y; p1Normal.z = n1.z; q1Normal.x = (n1.x + n2.x); q1Normal.y = (n1.y + n2.y); q1Normal.z = (n1.z + n2.z); normalize(q1Normal); } // else // if there is a next, check if we should smooth normal if (k+1 < num) { p3.x = outVerts[i][k+1].x; p3.y = outVerts[i][k+1].y; p3.z = 0.0f; q3.x = p3.x; q3.y = p3.y; q3.z = p3.z + fontExtrusion.length; if (!getNormal(p2, q2, p3, n3)) { n3.set(goodNormal); } else { if (!flip_side_orient) { n3.negate(); } goodNormal.set(n3); } if (!getNormal(p3, q2, q3, n4)) { n4.set(goodNormal); } else { if (!flip_side_orient) { n4.negate(); } goodNormal.set(n4); } cosine = n2.dot(n3); smooth = cosine > threshold; if (smooth) { p2Normal.x = (n1.x + n2.x + n3.x); p2Normal.y = (n1.y + n2.y + n3.y); p2Normal.z = (n1.z + n2.z + n3.z); normalize(p2Normal); q2Normal.x = (n2.x + n3.x + n4.x); q2Normal.y = (n2.y + n3.y + n4.y); q2Normal.z = (n2.z + n3.z + n4.z); normalize(q2Normal); } else { // if smooth p2Normal.x = n1.x + n2.x; p2Normal.y = n1.y + n2.y; p2Normal.z = n1.z + n2.z; normalize(p2Normal); q2Normal.x = n2.x; q2Normal.y = n2.y; q2Normal.z = n2.z; } // else } else { // if k+1 < num p2Normal.x = (n1.x + n2.x); p2Normal.y = (n1.y + n2.y); p2Normal.z = (n1.z + n2.z); normalize(p2Normal); q2Normal.x = n2.x; q2Normal.y = n2.y; q2Normal.z = n2.z; } // else // add pts for the 2 tris // p1, q1, p2 and p2, q1, q2 if (flip_side_orient) { triAry.setCoordinate(currCoordIndex, p1); triAry.setNormal(currCoordIndex, p1Normal); currCoordIndex++; triAry.setCoordinate(currCoordIndex, q1); triAry.setNormal(currCoordIndex, q1Normal); currCoordIndex++; triAry.setCoordinate(currCoordIndex, p2); triAry.setNormal(currCoordIndex, p2Normal); currCoordIndex++; triAry.setCoordinate(currCoordIndex, p2); triAry.setNormal(currCoordIndex, p2Normal); currCoordIndex++; triAry.setCoordinate(currCoordIndex, q1); triAry.setNormal(currCoordIndex, q1Normal); currCoordIndex++; } else { triAry.setCoordinate(currCoordIndex, q1); triAry.setNormal(currCoordIndex, q1Normal); currCoordIndex++; triAry.setCoordinate(currCoordIndex, p1); triAry.setNormal(currCoordIndex, p1Normal); currCoordIndex++; triAry.setCoordinate(currCoordIndex, p2); triAry.setNormal(currCoordIndex, p2Normal); currCoordIndex++; triAry.setCoordinate(currCoordIndex, q1); triAry.setNormal(currCoordIndex, q1Normal); currCoordIndex++; triAry.setCoordinate(currCoordIndex, p2); triAry.setNormal(currCoordIndex, p2Normal); currCoordIndex++; } triAry.setCoordinate(currCoordIndex, q2); triAry.setNormal(currCoordIndex, q2Normal); currCoordIndex++; pn1.x = n1.x; pn1.y = n1.y; pn1.z = n1.z; pn2.x = n2.x; pn2.y = n2.y; pn2.z = n2.z; p1.x = p2.x; p1.y = p2.y; p1.z = p2.z; q1.x = q2.x; q1.y = q2.y; q1.z = q2.z; }// for k
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -