📄 geometryinfo.java
字号:
indices[i] = i; // Put into hash table and remember the index table.put(list[i], new Integer(i)); } else { // We've seen this object indices[i] = idx.intValue(); } } return indices; } // End of getListIndices // Class to hash 'size' integers private class IndexRow { int[] val; int size; private static final int HASHCONST = 0xBABEFACE; public int hashCode() { int bits = 0; for (int i = 0 ; i < size ; i++) { bits ^= (bits * HASHCONST) << 2; } return bits; } // End of IndexRow.hashCode public boolean equals(Object obj) { for (int i = 0 ; i < size ; i++) { if (((IndexRow)obj).get(i) != val[i]) return false; } return true; } // End of IndexRow.equals() public int get(int index) { return val[index]; } // End of IndexRow.get public void set(int index, int value) { val[index] = value; } // End of IndexRow.set IndexRow(int numColumns) { size = numColumns; val = new int[size]; } // End of IndexRow constructor } // End of class IndexRow /** * Create index lists for all data lists. * Identical data entries are guaranteed to * use the same index value. Does not remove unused data values * from the object - call compact() to do this. * @param useCoordIndexOnly Reformat the data into the * GeometryArray.USE_COORD_INDEX_ONLY format where there is only * one index list. If the data is already in the USE_COORD_INDEX_ONLY * format, sending false (or calling indexify()) will change * it to the normal indexed format. * @throws IllegalArgumentException if coordinate data is missing, * if the index lists aren't all the * same length, if an index list is set and the corresponding data * list isn't set, if a data list is set and the corresponding * index list is unset (unless all index lists are unset or in * USE_COORD_INDEX_ONLY format), * if StripCounts or ContourCounts is inconsistent with the current * primitive, if the sum of the contourCounts array doesn't equal * the length of the StripCounts array, or if the number of vertices * isn't a multiple of three (for triangles) or four (for quads). */ public void indexify(boolean useCoordIndexOnly) { checkForBadData(); if (useCoordIndexOnly) { // Return if already in this format if (coordOnly) return; // Start from normal indexed format indexify(false); // Reformat data to USE_COORD_INDEX_ONLY format // Need to make an index into the index lists using each // row of indexes as one value // First, find out how many index lists there are; int numLists = 1; // Always have coordinates if (colorIndices != null) numLists++; if (normalIndices != null) numLists++; numLists += texCoordSetCount; // Make single array containing all indices int n = coordinateIndices.length; IndexRow[] ir = new IndexRow[n]; int j; for (int i = 0 ; i < n ; i++) { ir[i] = new IndexRow(numLists); j = 0; ir[i].set(j++, coordinateIndices[i]); if (colorIndices != null) ir[i].set(j++, colorIndices[i]); if (normalIndices != null) ir[i].set(j++, normalIndices[i]); for (int k = 0 ; k < texCoordSetCount ; k++) { ir[i].set(j++, texCoordIndexSets[k][i]); } } // Get index into that array int[] coordOnlyIndices = getListIndices(ir); // Get rid of duplicate rows int newInd[] = new int[coordOnlyIndices.length]; ir = (IndexRow[])compactData(coordOnlyIndices, ir, newInd); coordOnlyIndices = newInd; // Reformat data lists to correspond to new index // Allocate arrays to hold reformatted data Point3f[] newCoords = new Point3f[ir.length]; Color3f[] newColors3 = null; Color4f[] newColors4 = null; Vector3f[] newNormals = null; Object newTexCoordSets[][] = null; if (colors3 != null) newColors3 = new Color3f[ir.length]; else if (colors4 != null) newColors4 = new Color4f[ir.length]; if (normals != null) newNormals = new Vector3f[ir.length]; for (int i = 0 ; i < texCoordSetCount ; i++) { if (texCoordDim == 2) { if (i == 0) newTexCoordSets = new TexCoord2f[texCoordSetCount][]; newTexCoordSets[i] = new TexCoord2f[ir.length]; } else if (texCoordDim == 3) { if (i == 0) newTexCoordSets = new TexCoord3f[texCoordSetCount][]; newTexCoordSets[i] = new TexCoord3f[ir.length]; } else if (texCoordDim == 4) { if (i == 0) newTexCoordSets = new TexCoord4f[texCoordSetCount][]; newTexCoordSets[i] = new TexCoord4f[ir.length]; } } // Copy data into new arrays n = ir.length; for (int i = 0 ; i < n ; i++) { j = 0; newCoords[i] = coordinates[(ir[i]).get(j++)]; if (colors3 != null) { newColors3[i] = colors3[(ir[i]).get(j++)]; } else if (colors4 != null) { newColors4[i] = colors4[(ir[i]).get(j++)]; } if (normals != null) newNormals[i] = normals[(ir[i]).get(j++)]; for (int k = 0 ; k < texCoordSetCount ; k++) { newTexCoordSets[k][i] = texCoordSets[k][(ir[i]).get(j++)]; } } // Replace old arrays with new arrays coordinates = newCoords; colors3 = newColors3; colors4 = newColors4; normals = newNormals; texCoordSets = newTexCoordSets; coordinateIndices = coordOnlyIndices; colorIndices = null; normalIndices = null; texCoordIndexSets = new int[texCoordSetCount][]; coordOnly = true; } else if (coordOnly) { // Need to change from useCoordIndexOnly format to normal // indexed format. Should make a more efficient implementation // later. int n = coordinateIndices.length; if ((colors3 != null) || (colors4 != null)) { colorIndices = new int[n]; for (int i = 0 ; i < n ; i++) colorIndices[i] = coordinateIndices[i]; } if (normals != null) { normalIndices = new int[n]; for (int i = 0 ; i < n ; i++) normalIndices[i] = coordinateIndices[i]; } texCoordIndexSets = new int[texCoordSetCount][]; for (int i = 0 ; i < texCoordSetCount ; i++) { texCoordIndexSets[i] = new int[n]; for (int j = 0 ; j < n ; j++) { texCoordIndexSets[i][j] = coordinateIndices[j]; } } coordOnly = false; } else { // No need to indexify if already indexed if (coordinateIndices != null) return; coordinateIndices = getListIndices(coordinates); if (colors3 != null) colorIndices = getListIndices(colors3); else if (colors4 != null) colorIndices = getListIndices(colors4); if (normals != null) normalIndices = getListIndices(normals); texCoordIndexSets = new int[texCoordSetCount][]; for(int i = 0 ; i < texCoordSetCount ; i++) { texCoordIndexSets[i] = getListIndices(texCoordSets[i]); } coordOnly = false; } if ((DEBUG & 1) == 1) { System.out.println("Coordinate Array:"); for (int i = 0 ; i < coordinates.length ; i++) { System.out.println(" " + i + " " + coordinates[i] + " " + coordinates[i].hashCode()); } System.out.println("Index array:"); for (int i = 0 ; i < coordinateIndices.length ; i++) { System.out.println(" " + i + " " + coordinateIndices[i]); } } } // End of indexify public void indexify() { indexify(false); } // End of indexify() /** * Allocates an array of the same type as the input type. This allows us to * use a generic compactData method. * * @param data Array of coordinate, color, normal or texture coordinate data * The data can be in one of the following formats - Point3f, Color3f, * Color4f, TexCoord2f, TexCoord3f, TexCoord4f. * * @param num The size of the array to be allocated * * @return An array of size num of the same type as the input type * * @exception IllegalArgumentException if the input array is not one of the * types listed above. */ Object[] allocateArray(Object data[], int num) { Object newData[] = null; if (data instanceof javax.vecmath.Point3f[]) { newData = new Point3f[num]; } else if (data instanceof javax.vecmath.Vector3f[]) { newData = new Vector3f[num]; } else if (data instanceof javax.vecmath.Color3f[]) { newData = new Color3f[num]; } else if (data instanceof javax.vecmath.Color4f[]) { newData = new Color4f[num]; } else if (data instanceof javax.vecmath.TexCoord2f[]) { newData = new TexCoord2f[num]; } else if (data instanceof javax.vecmath.TexCoord3f[]) { newData = new TexCoord3f[num]; } else if (data instanceof javax.vecmath.TexCoord4f[]) { newData = new TexCoord4f[num]; } else if (data instanceof IndexRow[]) { // Hack so we can use compactData for coordIndexOnly newData = new IndexRow[num]; } else throw new IllegalArgumentException( J3dUtilsI18N.getString("GeometryInfo9")); return newData; } // End of allocateArray /** * Generic method that compacts (ie removes unreferenced/duplicate data) * any type of indexed data. * Used to compact coordinate, color, normal and texture coordinate data. * @param indices Array of indices * @param data Array of coordinate, color, normal or texture coordinate data * The data can be in one of the following formats - Point3f, Color3f, * Color4f, TexCoord2f, TexCoord3f, TexCoord4f. * @param newInd The new array of indexes after the data has been compacted. * This must be allocated by the calling method. On return, this array will * contain the new index data. The size of this array must be equal to * indices.length * @return Array of the data with unreferenced and duplicate entries removed. * The return type will be the same as the type that was passed in data. */ // TODO: Remove duplicate entries in data lists. private Object[] compactData(int indices[], Object data[], int newInd[]) { Object newData[] = null; /* * This is a three step process. * First, find out how many unique indexes are used. This * will be the size of the new data array. */ int numUnique = 0; int translationTable[] = new int[data.length]; for (int i = 0 ; i < indices.length ; i++) { if (translationTable[indices[i]] == 0) { numUnique++; translationTable[indices[i]] = 1; } } /* * Second, build the new data list. Remember the new indexes so * we can use the table to translate the old indexes to the new */ newData = allocateArray(data, numUnique); int newIdx = 0; for (int i = 0 ; i < translationTable.length ; i++) { if (translationTable[i] != 0) { newData[newIdx] = data[i]; translationTable[i] = newIdx++; } } /* * Third, make the new index list */ for (int i = 0 ; i < indices.length ; i++) { newInd[i] = translationTable[indices[i]]; } return newData; } // End of compactData /** * Remove unused data from an indexed dataset. * Indexed data may contain data entries that are never referenced by * the dataset. This routine will remove those entries where * appropriate and renumber the indices to match the new values. * @throws IllegalArgumentException if coordinate data is missing, * if the index lists aren't all the * same length, if an index list is set and the corresponding data * list isn't set, if a data list is set and the corresponding * index list is unset (unless all index lists are unset or in * USE_COORD_INDEX_ONLY format), * if StripCounts or ContourCounts is inconsistent with the current * primitive, if the sum of the contourCounts array doesn't equal * the length of the StripCounts array, or if the number of vertices * isn't a multiple of three (for triangles) or four (for quads). */ public void compact() { checkForBadData(); // Only usable on indexed data if (coordinateIndices == null) return; // USE_COORD_INDEX_ONLY never has unused data if (coordOnly) return; int newInd[] = new int[coordinateIndices.length]; coordinates = (Point3f[])compactData(coordinateIndices, coordinates, newInd); coordinateIndices = newInd; if (colorIndices != null) { newInd = new int[colorIndices.length]; if (colors3 != null) colors3 = (Color3f[])compactData(colorIndices, colors3, newInd); else if (colors4 != null) colors4 = (Color4f[])compactData(colorIndices, colors4, newInd); colorIndices = newInd; } if (normalIndices != null) { newInd = new int[normalIndices.length]; normals = (Vector3f[])compactData(normalIndices, normals, newInd); normalIndices = newInd; } for (int i =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -