diff options
Diffstat (limited to 'src/javax/media/j3d/IndexedGeometryArrayRetained.java')
-rw-r--r-- | src/javax/media/j3d/IndexedGeometryArrayRetained.java | 1932 |
1 files changed, 1932 insertions, 0 deletions
diff --git a/src/javax/media/j3d/IndexedGeometryArrayRetained.java b/src/javax/media/j3d/IndexedGeometryArrayRetained.java new file mode 100644 index 0000000..528c46f --- /dev/null +++ b/src/javax/media/j3d/IndexedGeometryArrayRetained.java @@ -0,0 +1,1932 @@ +/* + * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +package javax.media.j3d; + +import java.nio.Buffer; +import java.nio.FloatBuffer; +import java.util.ArrayList; + +import javax.vecmath.TexCoord2f; +import javax.vecmath.TexCoord3f; + +/** + * The IndexedGeometryArray object contains arrays of positional coordinates, + * colors, normals and/or texture coordinates that describe + * point, line, or surface geometry. It is extended to create + * the various primitive types (e.g., lines, triangle_strips, etc.) + */ + +abstract class IndexedGeometryArrayRetained extends GeometryArrayRetained { + + // arrays to save indices for coord, color, normal, texcoord, vertexAttr + int[] indexCoord; + int[] indexColor; + int[] indexNormal; + int[][] indexTexCoord; + int[][] indexVertexAttr; + + int indexCount = 0; + + int initialIndexIndex = 0; + int validIndexCount = 0; + + // Following variables are only used in compile mode + int[] compileIndexCount; + int[] compileIndexOffset; + + int maxCoordIndex = 0; + int maxColorIndex = 0; + int maxNormalIndex = 0; + int[] maxTexCoordIndices = null; + int[] maxVertexAttrIndices = null; + + void createIndexedGeometryArrayData(int indexCount) { + this.indexCount = indexCount; + this.validIndexCount = indexCount; + + // Only allocate color, normal, texCoord, and vertexAttr + // index arrays if USE_COORD_INDEX_ONLY is not set + boolean notUCIO = (this.vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0; + + //NVaidya + // Only allocate indexCoord if BY_REFERENCE_INDICES not set + if(((this.vertexFormat & GeometryArray.COORDINATES) != 0) && + ((this.vertexFormat & GeometryArray.BY_REFERENCE_INDICES) == 0)) + this.indexCoord = new int[indexCount]; + + if(((this.vertexFormat & GeometryArray.NORMALS) != 0) && notUCIO) + this.indexNormal = new int[indexCount]; + + if(((this.vertexFormat & GeometryArray.COLOR) != 0) && notUCIO) + this.indexColor = new int[indexCount]; + + if((this.vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) { + this.indexTexCoord = new int[this.texCoordSetCount][]; + if(notUCIO) { + for (int i = 0; i < this.texCoordSetCount; i++) { + this.indexTexCoord[i] = new int[indexCount]; + } + } + maxTexCoordIndices = new int[texCoordSetCount]; + } + + if ((this.vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { + this.indexVertexAttr = new int[this.vertexAttrCount][]; + if (notUCIO) { + for (int i = 0; i < this.vertexAttrCount; i++) { + this.indexVertexAttr[i] = new int[indexCount]; + } + } + this.maxVertexAttrIndices = new int[this.vertexAttrCount]; + } + } + + + GeometryArrayRetained cloneNonIndexedGeometry() { + GeometryArrayRetained obj = null; + + switch (this.geoType) { + case GEO_TYPE_INDEXED_LINE_SET: + obj = new LineArrayRetained(); + break; + case GEO_TYPE_INDEXED_POINT_SET: + obj = new PointArrayRetained(); + break; + case GEO_TYPE_INDEXED_QUAD_SET: + obj = new QuadArrayRetained(); + break; + case GEO_TYPE_INDEXED_TRI_SET: + obj = new TriangleArrayRetained(); + break; + default: + assert false; // Should never get here + } + + obj.createGeometryArrayData(validIndexCount, + (vertexFormat & ~(GeometryArray.BY_REFERENCE|GeometryArray.INTERLEAVED|GeometryArray.USE_NIO_BUFFER)), + texCoordSetCount, texCoordSetMap, + vertexAttrCount, vertexAttrSizes); + obj.cloneSourceArray = this; + obj.unIndexify(this); + obj.source=source; + + return obj; + } + + + /** + * Gets current number of indices + * @return indexCount + */ + int getIndexCount(){ + return indexCount; + } + + void doErrorCheck(int newMax) { + doCoordCheck(newMax); + if ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) != 0) { + if ((vertexFormat & GeometryArray.COLOR) != 0) { + doColorCheck(newMax); + } + if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) { + for (int i = 0; i < texCoordSetCount; i++) { + doTexCoordCheck(newMax, i); + } + } + if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { + for (int i = 0; i < vertexAttrCount; i++) { + doVertexAttrCheck(newMax, i); + } + } + if ((vertexFormat & GeometryArray.NORMALS) != 0) { + doNormalCheck(newMax); + } + } + } + + void doCoordCheck(int newMax) { + // Check to make sure that the array length defined by the user is ateast maxCoordIndex long + if ((vertexFormat & GeometryArray.BY_REFERENCE) == 0) { + if (newMax >= vertexCount) { + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray23")); + } + } + else { + if(( vertexFormat & GeometryArray.USE_NIO_BUFFER) != 0) { + if ((vertexFormat & GeometryArray.INTERLEAVED) == 0) { + switch ((vertexType & GeometryArrayRetained.VERTEX_DEFINED)) { + case PF: + if(floatBufferRefCoords != null && 3 * newMax >= floatBufferRefCoords.limit() ) { + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray23")); + } + break; + case PD: + if(doubleBufferRefCoords != null && 3 * newMax >= doubleBufferRefCoords.limit() ) { + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray23")); + } + break; + } + } + else { + if(interleavedFloatBufferImpl != null && stride * newMax >= interleavedFloatBufferImpl.limit() ) { + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray23")); + } + } + } else { + if ((vertexFormat & GeometryArray.INTERLEAVED) == 0) { + switch ((vertexType & VERTEX_DEFINED)) { + case PF: + if (floatRefCoords != null && (3 * newMax >= floatRefCoords.length)) { + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray23")); + } + break; + case PD: + if (doubleRefCoords != null && (3 * newMax >= doubleRefCoords.length)) { + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray23")); + } + + break; + case P3F: + if (p3fRefCoords != null && (newMax >= p3fRefCoords.length)) { + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray23")); + } + break; + case P3D: + if (p3dRefCoords != null && (newMax >= p3dRefCoords.length)) { + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray23")); + } + break; + default: + break; + } + } + else { + if (interLeavedVertexData != null && (stride * newMax >= interLeavedVertexData.length)) { + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray23")); + } + } + } + } + + } + + void doColorCheck(int newMax) { + // If the new Value is greater than the old value, make sure there is array length + // to support the change + // Check to make sure that the array length defined by the user is ateast maxCoordIndex long + if ((vertexFormat & GeometryArray.COLOR) == 0) + return; + + if ((vertexFormat & GeometryArray.BY_REFERENCE) == 0) { + if (newMax >= vertexCount) { + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray24")); + } + } + else { + int multiplier = getColorStride(); + + if(( vertexFormat & GeometryArray.USE_NIO_BUFFER) != 0) { + if ((vertexFormat & GeometryArray.INTERLEAVED) == 0) { + switch ((vertexType & COLOR_DEFINED)) { + case CF: + if (floatBufferRefColors != null && multiplier * newMax >= floatBufferRefColors.limit()) { + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray24")); + } + break; + case CUB: + if (byteBufferRefColors != null && multiplier * newMax >= byteBufferRefColors.limit()) { + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray24")); + } + break; + } + } + else { + if(interleavedFloatBufferImpl != null && + stride * newMax >= interleavedFloatBufferImpl.limit()) { + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray24")); + } + } + } else { + if ((vertexFormat & GeometryArray.INTERLEAVED) == 0) { + switch ((vertexType & COLOR_DEFINED)) { + case CF: + if (floatRefColors != null && (multiplier * newMax >= floatRefColors.length)) { + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray24")); + } + break; + case CUB: + if (byteRefColors != null && (multiplier * newMax >= byteRefColors.length)) { + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray24")); + } + + break; + case C3F: + if (c3fRefColors != null && (newMax >= c3fRefColors.length)) { + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray24")); + } + break; + case C4F: + if (c4fRefColors != null && (newMax >= c4fRefColors.length)) { + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray24")); + } + break; + case C3UB: + if (c3bRefColors != null && (newMax >= c3bRefColors.length)) { + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray24")); + } + break; + case C4UB: + if (c4bRefColors != null && (newMax >= c4bRefColors.length)) { + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray24")); + } + break; + default: + break; + } + } else { + if (interLeavedVertexData != null && (stride * newMax >= interLeavedVertexData.length)) { + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray24")); + } + } + } + } + + } + + + void doNormalCheck(int newMax) { + if ((vertexFormat & GeometryArray.NORMALS) == 0) + return; + + // Check to make sure that the array length defined by the user is ateast maxCoordIndex long + if ((vertexFormat & GeometryArray.BY_REFERENCE) == 0) { + if (newMax >= vertexCount) { + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray26")); + } + } + else { + if(( vertexFormat & GeometryArray.USE_NIO_BUFFER) != 0) { + if ((vertexFormat & GeometryArray.INTERLEAVED) == 0) { + switch ((vertexType & GeometryArrayRetained.NORMAL_DEFINED)) { + case NF: + if(floatBufferRefNormals != null && 3 * newMax >= floatBufferRefNormals.limit() ) { + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray26")); + } + break; + } + } + else { + if(interleavedFloatBufferImpl != null && stride * newMax >= interleavedFloatBufferImpl.limit() ) { + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray26")); + } + } + } else { + if ((vertexFormat & GeometryArray.INTERLEAVED) == 0) { + switch ((vertexType & NORMAL_DEFINED)) { + case NF: + if (floatRefNormals != null && (3 * newMax >= floatRefNormals.length)) { + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray26")); + } + break; + case N3F: + if (v3fRefNormals != null && (newMax >= v3fRefNormals.length)) { + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray26")); + } + + break; + default: + break; + } + } + else { + if (interLeavedVertexData != null && (stride * newMax >= interLeavedVertexData.length)) { + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray26")); + } + } + } + } + + } + + + + void doTexCoordCheck(int newMax, int texCoordSet) { + + // Check to make sure that the array length defined by the user is ateast maxCoordIndex long + if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) == 0) + return; + + if ((vertexFormat & GeometryArray.BY_REFERENCE) == 0) { + if (newMax >= vertexCount) { + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray25")); + } + } + else { + int multiplier = getTexStride(); + + if(( vertexFormat & GeometryArray.USE_NIO_BUFFER) != 0) { + if ((vertexFormat & GeometryArray.INTERLEAVED) == 0) { + switch ((vertexType & GeometryArrayRetained.TEXCOORD_DEFINED)) { + case TF: + FloatBuffer texBuffer = (FloatBuffer)refTexCoordsBuffer[texCoordSet].getROBuffer(); + if(refTexCoords[texCoordSet] != null && multiplier * newMax >= texBuffer.limit()) { + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray25")); + } + break; + } + } + else { + if(interleavedFloatBufferImpl != null && stride * newMax >= interleavedFloatBufferImpl.limit() ) { + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray25")); + } + } + } else { + + if ((vertexFormat & GeometryArray.INTERLEAVED) == 0) { + switch ((vertexType & TEXCOORD_DEFINED)) { + case TF: + if (refTexCoords[texCoordSet] != null && (multiplier * newMax >= ((float[])refTexCoords[texCoordSet]).length)) { + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray25")); + } + break; + case T2F: + if (refTexCoords[texCoordSet] != null && (newMax >= ((TexCoord2f[])refTexCoords[texCoordSet]).length)) { + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray25")); + } + + break; + case T3F: + if (refTexCoords[texCoordSet] != null && (newMax >= ((TexCoord3f[])refTexCoords[texCoordSet]).length)) { + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray25")); + } + break; + default: + break; + } + } + else { + if (interLeavedVertexData != null && (stride * newMax >= interLeavedVertexData.length)) { + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray25")); + } + } + } + } + + } + + void doVertexAttrCheck(int newMax, int vertexAttrNum) { + + // Check to make sure that the array length defined by the user is ateast maxVertexAttrIndex long + if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) == 0) { + return; + } + + // Vertex attributes must not be interleaved + assert (vertexFormat & GeometryArray.INTERLEAVED) == 0; + + if ((vertexFormat & GeometryArray.BY_REFERENCE) == 0) { + if (newMax >= vertexCount) { + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray30")); + } + } else { + int multiplier = vertexAttrSizes[vertexAttrNum]; + + if(( vertexFormat & GeometryArray.USE_NIO_BUFFER) != 0) { + switch (vertexType & VATTR_DEFINED) { + case AF: + if(multiplier * newMax >= floatBufferRefVertexAttrs[vertexAttrNum].limit()) { + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray30")); + } + break; + } + } else { + switch (vertexType & VATTR_DEFINED) { + case AF: + if (multiplier * newMax >= floatRefVertexAttrs[vertexAttrNum].length) { + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray30")); + } + break; + } + } + } + } + + + /** + * Sets the coordinate index associated with the vertex at + * the specified index for this object. + * @param index the vertex index + * @param coordinateIndex the new coordinate index + */ + final void setCoordinateIndex(int index, int coordinateIndex) { + int newMax; + newMax = doIndexCheck(index, maxCoordIndex, indexCoord, coordinateIndex); + if (newMax > maxCoordIndex) { + doErrorCheck(newMax); + } + if ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) != 0) { + if ((vertexFormat & GeometryArray.COLOR) != 0) { + maxColorIndex = newMax; + } + if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) { + for (int i = 0; i < texCoordSetCount; i++) { + maxTexCoordIndices[i] = newMax; + } + } + if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { + for (int i = 0; i < vertexAttrCount; i++) { + maxVertexAttrIndices[i] = newMax; + } + } + if ((vertexFormat & GeometryArray.NORMALS) != 0) { + maxNormalIndex = newMax; + } + } + + boolean isLive = source!=null && source.isLive(); + if(isLive){ + geomLock.getLock(); + } + dirtyFlag |= INDEX_CHANGED; + this.indexCoord[index] = coordinateIndex; + maxCoordIndex = newMax; + if(isLive) { + geomLock.unLock(); + } + if (!inUpdater && isLive) { + sendDataChangedMessage(true); + } + } + + int doIndexCheck(int index, int maxIndex, int[] indices, int dataValue) { + int newMax = maxIndex; + if (index < initialIndexIndex) + return newMax; + + if (index >= (initialIndexIndex+validIndexCount)) + return newMax; + + if (dataValue < 0) { + // Throw an exception, since index is negative + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray27")); + + } + + if (newMax == indices[index]) { + if (dataValue >= newMax) { + newMax = dataValue; + } + // Go thru the entire list and look for the max + else { + for (int i = 0; i < indices.length; i++) { + if (indices[i] > newMax) { + newMax = indices[i]; + } + } + } + } + else if (dataValue > newMax) { + newMax = dataValue; + } + return newMax; + } + + int doIndicesCheck(int index, int maxIndex, int[] indices, int[] newIndices) { + int newMax = maxIndex; + boolean computeNewMax = false; + int i, j, num = newIndices.length; + boolean maxReset = false; + for (j = 0; j < num; j++) { + if ((index+j) < initialIndexIndex) + continue; + + if ((index+j) >= (initialIndexIndex+validIndexCount)) + continue; + if (newIndices[j] < 0) { + // Throw an exception, since index is negative + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray27")); + + } + if (indices[index+j] == maxIndex) { + if (newIndices[j] >= newMax) { + newMax = newIndices[j]; + computeNewMax = false; + maxReset = true; + } + // Go thru the entire list and look for the max + // If in the new list there is no value that is >= + // to the old maximum + else if (!maxReset){ + computeNewMax = true; + } + } + else if (newIndices[j] >= newMax) { + newMax = newIndices[j]; + computeNewMax = false; + maxReset = true; + } + } + if (computeNewMax) { + for (i = 0; i < indices.length; i++) { + if (indices[i] > newMax) { + newMax = indices[i]; + } + } + } + return newMax; + } + + + /** + * Sets the coordinate indices associated with the vertices starting at + * the specified index for this object. + * @param index the vertex index + * @param coordinateIndices an array of coordinate indices + */ + final void setCoordinateIndices(int index, int coordinateIndices[]) { + int newMax; + int i, j, num = coordinateIndices.length; + newMax = doIndicesCheck(index, maxCoordIndex, indexCoord, coordinateIndices); + if (newMax > maxCoordIndex) { + doErrorCheck(newMax); + } + if ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) != 0) { + if ((vertexFormat & GeometryArray.COLOR) != 0) { + maxColorIndex = newMax; + } + if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) { + for (i = 0; i < texCoordSetCount; i++) { + maxTexCoordIndices[i] = newMax; + } + } + if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { + for (i = 0; i < vertexAttrCount; i++) { + maxVertexAttrIndices[i] = newMax; + } + } + if ((vertexFormat & GeometryArray.NORMALS) != 0) { + maxNormalIndex = newMax; + } + } + + boolean isLive = source!=null && source.isLive(); + if(isLive){ + geomLock.getLock(); + } + dirtyFlag |= INDEX_CHANGED; + maxCoordIndex = newMax; + for (i=0, j = index; i < num;i++, j++) { + this.indexCoord[j] = coordinateIndices[i]; + } + if(isLive) { + geomLock.unLock(); + } + if (!inUpdater && isLive) { + sendDataChangedMessage(true); + } + } + + //NVaidya + /** + * Sets the coordinate indices by reference to the specified array + * @param coordinateIndices an array of coordinate indices + */ + final void setCoordIndicesRef(int coordinateIndices[]) { + int newMax = 0; + + if (coordinateIndices != null) { + if (coordinateIndices.length < initialIndexIndex + validIndexCount) { + throw new IllegalArgumentException(J3dI18N.getString("IndexedGeometryArray33")); + } + + // + // option 1: could fake the args to "re-use" doIndicesCheck() + //NVaidya + // newMax = doIndicesCheck(0, maxCoordIndex, coordinateIndices, coordinateIndices); + // if (newMax > maxCoordIndex) { + // doErrorCheck(newMax); + // } + // + // option 2: same logic as in setInitialIndexIndex: Better, I Think ? + // computeMaxIndex() doesn't check for index < 0 while doIndicesCheck() does. + // So, a new method computeMaxIndexWithCheck + //NVaidya + newMax = computeMaxIndexWithCheck(initialIndexIndex, validIndexCount, coordinateIndices); + if (newMax > maxCoordIndex) { + doErrorCheck(newMax); + } + } + + if ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) != 0) { + if ((vertexFormat & GeometryArray.COLOR) != 0) { + maxColorIndex = newMax; + } + if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) { + for (int i = 0; i < texCoordSetCount; i++) { + maxTexCoordIndices[i] = newMax; + } + } + if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { + for (int i = 0; i < vertexAttrCount; i++) { + maxVertexAttrIndices[i] = newMax; + } + } + if ((vertexFormat & GeometryArray.NORMALS) != 0) { + maxNormalIndex = newMax; + } + } + + boolean isLive = source!=null && source.isLive(); + if(isLive){ + geomLock.getLock(); + } + dirtyFlag |= INDEX_CHANGED; + maxCoordIndex = newMax; + this.indexCoord = coordinateIndices; + if(isLive) { + geomLock.unLock(); + } + if (!inUpdater && isLive) { + sendDataChangedMessage(true); + } + } + + //NVaidya + /** + * trigger from GeometryArrayRetained#updateData() + * to recompute maxCoordIndex and perform index integrity checks + */ + final void doPostUpdaterUpdate() { + // user may have called setCoordIndicesRef and/or + // changed contents of indexCoord array. Thus, need to + // recompute maxCoordIndex unconditionally (and redundantly + // if user had only invoked setCoordIndicesRef but not also + // changed contents). geomLock is currently locked. + + // Option 1: + // simply call setCoordIndicesRef(indexCoord); but this seems to cause + // deadlock or freeze - probably because the !inUpdater branch sends + // out too many sendDataChangedMessage(true) - occurs if updateData + // method is called rapidly. + // setCoordIndicesRef(indexCoord); + + // Option 2: + // use only necessary code from setCoordIndicesRef + // System.err.println("IndexedGeometryArrayretained#doUpdaterUpdate"); + int newMax = 0; + + if (indexCoord != null) { + newMax = computeMaxIndexWithCheck(initialIndexIndex, validIndexCount, indexCoord); + if (newMax > maxCoordIndex) { + doErrorCheck(newMax); + } + } + + if ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) != 0) { + if ((vertexFormat & GeometryArray.COLOR) != 0) { + maxColorIndex = newMax; + } + if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) { + for (int i = 0; i < texCoordSetCount; i++) { + maxTexCoordIndices[i] = newMax; + } + } + if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { + for (int i = 0; i < vertexAttrCount; i++) { + maxVertexAttrIndices[i] = newMax; + } + } + if ((vertexFormat & GeometryArray.NORMALS) != 0) { + maxNormalIndex = newMax; + } + } + + dirtyFlag |= INDEX_CHANGED; + maxCoordIndex = newMax; + } + + /** + * Sets the color index associated with the vertex at + * the specified index for this object. + * @param index the vertex index + * @param colorIndex the new color index + */ + final void setColorIndex(int index, int colorIndex) { + int newMax = maxColorIndex; + + newMax = doIndexCheck(index, maxColorIndex, indexColor, colorIndex); + if (newMax > maxColorIndex) { + doColorCheck(newMax); + } + boolean isLive = source!=null && source.isLive(); + if(isLive){ + geomLock.getLock(); + } + // No need to set INDEX_CHANGED since IndexBuffer + // is used only when USE_COORD_INDEX_ONLY specified. + // In this case only coordinate index array is + // considered. + this.indexColor[index] = colorIndex; + maxColorIndex = newMax; + if(isLive) { + geomLock.unLock(); + } + if (!inUpdater && isLive) { + sendDataChangedMessage(false); + } + } + + /** + * Sets the color indices associated with the vertices starting at + * the specified index for this object. + * @param index the vertex index + * @param colorIndices an array of color indices + */ + final void setColorIndices(int index, int colorIndices[]) { + int i, j, num = colorIndices.length; + int newMax; + + newMax = doIndicesCheck(index, maxColorIndex, indexColor, colorIndices); + if (newMax > maxColorIndex) { + doColorCheck(newMax); + } + boolean isLive = source!=null && source.isLive(); + if(isLive){ + geomLock.getLock(); + } + maxColorIndex = newMax; + for (i=0, j = index; i < num;i++, j++) { + this.indexColor[j] = colorIndices[i]; + } + if(isLive) { + geomLock.unLock(); + } + if (!inUpdater && isLive) { + sendDataChangedMessage(false); + } + } + + /** + * Sets the normal index associated with the vertex at + * the specified index for this object. + * @param index the vertex index + * @param normalIndex the new normal index + */ + final void setNormalIndex(int index, int normalIndex) { + int newMax; + + newMax = doIndexCheck(index, maxNormalIndex, indexNormal, normalIndex); + if (newMax > maxNormalIndex) { + doNormalCheck(newMax); + } + boolean isLive = source!=null && source.isLive(); + if(isLive){ + geomLock.getLock(); + } + maxNormalIndex = newMax; + this.indexNormal[index] = normalIndex; + if(isLive) { + geomLock.unLock(); + } + if (!inUpdater && isLive) { + sendDataChangedMessage(false); + } + } + + /** + * Sets the normal indices associated with the vertices starting at + * the specified index for this object. + * @param index the vertex index + * @param normalIndices an array of normal indices + */ + final void setNormalIndices(int index, int normalIndices[]) { + int i, j, num = normalIndices.length; + int newMax; + + newMax = doIndicesCheck(index, maxNormalIndex, indexNormal, normalIndices); + if (newMax > maxNormalIndex) { + doNormalCheck(newMax); + } + boolean isLive = source!=null && source.isLive(); + if(isLive){ + geomLock.getLock(); + } + for (i=0, j = index; i < num;i++, j++) { + this.indexNormal[j] = normalIndices[i]; + } + maxNormalIndex = newMax; + if(isLive) { + geomLock.unLock(); + } + if (!inUpdater && isLive) { + sendDataChangedMessage(false); + } + } + + /** + * Sets the texture coordinate index associated with the vertex at + * the specified index for this object. + * @param texCoordSet the texture coordinate set + * @param index the vertex index + * @param texCoordIndex the new texture coordinate index + */ + final void setTextureCoordinateIndex(int texCoordSet, int index, int texCoordIndex) { + int newMax; + int [] indices = this.indexTexCoord[texCoordSet]; + + newMax = doIndexCheck(index, maxTexCoordIndices[texCoordSet],indices, texCoordIndex); + if (newMax > maxTexCoordIndices[texCoordSet]) { + doTexCoordCheck(newMax, texCoordSet); + } + boolean isLive = source!=null && source.isLive(); + if(isLive){ + geomLock.getLock(); + } + maxTexCoordIndices[texCoordSet] = newMax; + indices[index] = texCoordIndex; + if(isLive) { + geomLock.unLock(); + } + if (!inUpdater && isLive) { + sendDataChangedMessage(false); + } + } + + /** + * Sets the texture coordinate indices associated with the vertices + * starting at the specified index for this object. + * @param texCoordSet the texture coordinate set + * @param index the vertex index + * @param texCoordIndices an array of texture coordinate indices + */ + final void setTextureCoordinateIndices(int texCoordSet, int index, int texCoordIndices[]) { + int i, j, num = texCoordIndices.length; + int [] indices = this.indexTexCoord[texCoordSet]; + + int newMax; + + newMax = doIndicesCheck(index, maxTexCoordIndices[texCoordSet], indices, texCoordIndices); + if (newMax > maxTexCoordIndices[texCoordSet]) { + doTexCoordCheck(newMax, texCoordSet); + } + boolean isLive = source!=null && source.isLive(); + if(isLive){ + geomLock.getLock(); + } + maxTexCoordIndices[texCoordSet] = newMax; + for (i=0, j = index; i < num;i++, j++) { + indices[j] = texCoordIndices[i]; + } + if(isLive) { + geomLock.unLock(); + } + if (!inUpdater && isLive) { + sendDataChangedMessage(false); + } + } + + /** + * Sets the vertex attribute index associated with the vertex at + * the specified index for the specified vertex attribute number + * for this object. + */ + void setVertexAttrIndex(int vertexAttrNum, + int index, + int vertexAttrIndex) { + + int newMax; + int [] indices = this.indexVertexAttr[vertexAttrNum]; + + newMax = doIndexCheck(index, maxVertexAttrIndices[vertexAttrNum],indices, vertexAttrIndex); + if (newMax > maxVertexAttrIndices[vertexAttrNum]) { + doVertexAttrCheck(newMax, vertexAttrNum); + } + boolean isLive = source!=null && source.isLive(); + if(isLive){ + geomLock.getLock(); + } + maxVertexAttrIndices[vertexAttrNum] = newMax; + indices[index] = vertexAttrIndex; + if(isLive) { + geomLock.unLock(); + } + if (!inUpdater && isLive) { + sendDataChangedMessage(false); + } + } + + /** + * Sets the vertex attribute indices associated with the vertices + * starting at the specified index for the specified vertex attribute number + * for this object. + */ + void setVertexAttrIndices(int vertexAttrNum, + int index, + int[] vertexAttrIndices) { + + int i, j, num = vertexAttrIndices.length; + int [] indices = this.indexVertexAttr[vertexAttrNum]; + + int newMax; + + newMax = doIndicesCheck(index, maxVertexAttrIndices[vertexAttrNum], indices, vertexAttrIndices); + if (newMax > maxVertexAttrIndices[vertexAttrNum]) { + doVertexAttrCheck(newMax, vertexAttrNum); + } + boolean isLive = source!=null && source.isLive(); + if(isLive){ + geomLock.getLock(); + } + maxVertexAttrIndices[vertexAttrNum] = newMax; + for (i=0, j = index; i < num;i++, j++) { + indices[j] = vertexAttrIndices[i]; + } + if(isLive) { + geomLock.unLock(); + } + if (!inUpdater && isLive) { + sendDataChangedMessage(false); + } + } + + /** + * Retrieves the coordinate index associated with the vertex at + * the specified index for this object. + * @param index the vertex index + * @return the coordinate index + */ + final int getCoordinateIndex(int index) { + return this.indexCoord[index]; + } + + /** + * Retrieves the coordinate indices associated with the vertices starting at + * the specified index for this object. + * @param index the vertex index + * @param coordinateIndices array that will receive the coordinate indices + */ + final void getCoordinateIndices(int index, int coordinateIndices[]) { + int i, j, num = coordinateIndices.length; + + for (i=0, j = index;i < num;i++, j++) { + coordinateIndices[i] = this.indexCoord[j]; + } + } + + //NVaidya + /** + * Returns a reference to the coordinate indices associated + * with the vertices + */ + final int[] getCoordIndicesRef() { + return this.indexCoord; + } + + /** + * Retrieves the color index associated with the vertex at + * the specified index for this object. + * @param index the vertex index + * @return the color index + */ + final int getColorIndex(int index) { + return this.indexColor[index]; + } + + /** + * Retrieves the color indices associated with the vertices starting at + * the specified index for this object. + * @param index the vertex index + * @param colorIndices array that will receive the color indices + */ + final void getColorIndices(int index, int colorIndices[]) { + int i, j, num = colorIndices.length; + + for (i=0, j = index;i < num;i++, j++) { + colorIndices[i] = this.indexColor[j]; + } + } + + /** + * Retrieves the normal index associated with the vertex at + * the specified index for this object. + * @param index the vertex index + * @return the normal index + */ + final int getNormalIndex(int index) { + return this.indexNormal[index]; + } + + /** + * Retrieves the normal indices associated with the vertices starting at + * the specified index for this object. + * @param index the vertex index + * @param normalIndices array that will receive the normal indices + */ + final void getNormalIndices(int index, int normalIndices[]) { + int i, j, num = normalIndices.length; + + for (i=0, j = index;i < num;i++, j++) { + normalIndices[i] = this.indexNormal[j]; + } + } + + /** + * Retrieves the texture coordinate index associated with the vertex at + * the specified index for this object. + * @param texCoordSet the texture coordinate set + * @param index the vertex index + * @return the texture coordinate index + */ + final int getTextureCoordinateIndex(int texCoordSet, int index) { + int [] indices = this.indexTexCoord[texCoordSet]; + + return indices[index]; + } + + /** + * Retrieves the texture coordinate indices associated with the vertices + * starting at the specified index for this object. + * @param texCoordSet the texture coordinate set + * @param index the vertex index + * @param texCoordIndices array that will receive the texture coordinate indices + */ + final void getTextureCoordinateIndices(int texCoordSet, int index, int texCoordIndices[]) { + int i, j, num = texCoordIndices.length; + int [] indices = this.indexTexCoord[texCoordSet]; + + for (i=0, j = index;i < num;i++, j++) { + texCoordIndices[i] = indices[j]; + } + } + + /** + * Retrieves the vertex attribute index associated with the vertex at + * the specified index for the specified vertex attribute number + * for this object. + */ + int getVertexAttrIndex(int vertexAttrNum, + int index) { + + int [] indices = this.indexVertexAttr[vertexAttrNum]; + + return indices[index]; + } + + /** + * Retrieves the vertex attribute indices associated with the vertices + * starting at the specified index for the specified vertex attribute number + * for this object. + */ + void getVertexAttrIndices(int vertexAttrNum, + int index, + int[] vertexAttrIndices) { + + int i, j, num = vertexAttrIndices.length; + int [] indices = this.indexVertexAttr[vertexAttrNum]; + + for (i=0, j = index;i < num;i++, j++) { + vertexAttrIndices[i] = indices[j]; + } + } + + + @Override + void execute(Canvas3D cv, RenderAtom ra, boolean isNonUniformScale, + boolean updateAlpha, float alpha, + int screen, boolean ignoreVertexColors) { + + int cdirty; + boolean useAlpha = false; + Object[] retVal; + if (mirrorGeometry != null) { + mirrorGeometry.execute(cv, ra, isNonUniformScale, updateAlpha, alpha, + screen, ignoreVertexColors); + return; + } + + // Check if index array is null; if yes, don't draw anything + if (indexCoord == null) { + return; + } + + //By reference with java array + if ((vertexFormat & GeometryArray.USE_NIO_BUFFER) == 0) { + if ((vertexFormat & GeometryArray.BY_REFERENCE) == 0) { + float[] vdata; + // System.err.println("by-copy"); + synchronized (this) { + cdirty = dirtyFlag; + if (updateAlpha && !ignoreVertexColors) { + // update the alpha values + retVal = updateAlphaInVertexData(cv, screen, alpha); + useAlpha = (retVal[0] == Boolean.TRUE); + vdata = (float[])retVal[1]; + + // D3D only + if (alpha != lastScreenAlpha) { + // handle multiple screen case + lastScreenAlpha = alpha; + cdirty |= COLOR_CHANGED; + } + } else { + vdata = vertexData; + // if transparency switch between on/off + if (lastScreenAlpha != -1) { + lastScreenAlpha = -1; + cdirty |= COLOR_CHANGED; + } + } + // geomLock is get in MasterControl when + // RenderBin render the geometry. So it is safe + // just to set the dirty flag here + dirtyFlag = 0; + } + + Pipeline.getPipeline().executeIndexedGeometry(cv.ctx, + this, geoType, isNonUniformScale, + useAlpha, + ignoreVertexColors, + initialIndexIndex, + validIndexCount, + // Vertex Count is maxCoordIndex + 1 + maxCoordIndex + 1, + ((vertexFormat & GeometryArray.COLOR) != 0)?(vertexFormat|GeometryArray.COLOR_4):vertexFormat, + vertexAttrCount, vertexAttrSizes, + texCoordSetCount, texCoordSetMap, + (texCoordSetMap == null) ? 0 : texCoordSetMap.length, + texCoordSetMapOffset, + cv.numActiveTexUnit, + vdata, null, + cdirty, indexCoord); + + + } // end of non by reference + else if ((vertexFormat & GeometryArray.INTERLEAVED) != 0) { + if(interLeavedVertexData == null) + return; + + float[] cdata = null; + + synchronized (this) { + cdirty = dirtyFlag; + if (updateAlpha && !ignoreVertexColors) { + // update the alpha values + retVal = updateAlphaInInterLeavedData(cv, screen, alpha); + useAlpha = (retVal[0] == Boolean.TRUE); + cdata = (float[])retVal[1]; + if (alpha != lastScreenAlpha) { + lastScreenAlpha = alpha; + cdirty |= COLOR_CHANGED; + } + } else { + // if transparency switch between on/off + if (lastScreenAlpha != -1) { + lastScreenAlpha = -1; + cdirty |= COLOR_CHANGED; + } + } + dirtyFlag = 0; + } + + Pipeline.getPipeline().executeIndexedGeometry(cv.ctx, + this, geoType, isNonUniformScale, + useAlpha, + ignoreVertexColors, + initialIndexIndex, + validIndexCount, + maxCoordIndex + 1, + vertexFormat, + vertexAttrCount, vertexAttrSizes, + texCoordSetCount, texCoordSetMap, + (texCoordSetMap == null) ? 0 : texCoordSetMap.length, + texCoordSetMapOffset, + cv.numActiveTexUnit, + interLeavedVertexData, cdata, + cdirty, indexCoord); + } //end of interleaved + else { + // Check if a vertexformat is set, but the array is null + // if yes, don't draw anything + if ((vertexType == 0) || + ((vertexType & VERTEX_DEFINED) == 0) || + (((vertexFormat & GeometryArray.COLOR) != 0) && + (vertexType & COLOR_DEFINED) == 0) || + (((vertexFormat & GeometryArray.NORMALS) != 0) && + (vertexType & NORMAL_DEFINED) == 0) || + (((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) && + (vertexType & VATTR_DEFINED) == 0) || + (((vertexFormat& GeometryArray.TEXTURE_COORDINATE) != 0) && + (vertexType & TEXCOORD_DEFINED) == 0)) { + return; + } else { + byte[] cbdata = null; + float[] cfdata = null; + + if ((vertexType & (CF | C3F | C4F )) != 0) { + synchronized (this) { + cdirty = dirtyFlag; + if (updateAlpha && !ignoreVertexColors) { + cfdata = updateAlphaInFloatRefColors(cv, + screen, alpha); + if (alpha != lastScreenAlpha) { + lastScreenAlpha = alpha; + cdirty |= COLOR_CHANGED; + } + } else { + cfdata = mirrorFloatRefColors[0]; + // if transparency switch between on/off + if (lastScreenAlpha != -1) { + lastScreenAlpha = -1; + cdirty |= COLOR_CHANGED; + } + + } + dirtyFlag = 0; + } + } else if ((vertexType & (CUB| C3UB | C4UB)) != 0) { + synchronized (this) { + cdirty = dirtyFlag; + if (updateAlpha && !ignoreVertexColors) { + cbdata = updateAlphaInByteRefColors( + cv, screen, alpha); + if (alpha != lastScreenAlpha) { + lastScreenAlpha = alpha; + cdirty |= COLOR_CHANGED; + } + } else { + cbdata = mirrorUnsignedByteRefColors[0]; + // if transparency switch between on/off + if (lastScreenAlpha != -1) { + lastScreenAlpha = -1; + cdirty |= COLOR_CHANGED; + } + } + dirtyFlag = 0; + } + } else { + cdirty = dirtyFlag; + } + + int vdefined = 0; + if((vertexType & (PF | P3F)) != 0) + vdefined |= COORD_FLOAT; + if((vertexType & (PD | P3D)) != 0) + vdefined |= COORD_DOUBLE; + if((vertexType & (CF | C3F | C4F)) != 0) + vdefined |= COLOR_FLOAT; + if((vertexType & (CUB| C3UB | C4UB)) != 0) + vdefined |= COLOR_BYTE; + if((vertexType & NORMAL_DEFINED) != 0) + vdefined |= NORMAL_FLOAT; + if((vertexType & VATTR_DEFINED) != 0) + vdefined |= VATTR_FLOAT; + if((vertexType & TEXCOORD_DEFINED) != 0) + vdefined |= TEXCOORD_FLOAT; + + Pipeline.getPipeline().executeIndexedGeometryVA(cv.ctx, + this, geoType, isNonUniformScale, + ignoreVertexColors, + initialIndexIndex, + validIndexCount, + maxCoordIndex + 1, + (vertexFormat | c4fAllocated), + vdefined, + mirrorFloatRefCoords, mirrorDoubleRefCoords, + cfdata, cbdata, + mirrorFloatRefNormals, + vertexAttrCount, vertexAttrSizes, + mirrorFloatRefVertexAttrs, + ((texCoordSetMap == null) ? 0:texCoordSetMap.length), + texCoordSetMap, + cv.numActiveTexUnit, + texCoordStride, + mirrorRefTexCoords, cdirty, indexCoord); + } + } // end of non interleaved and by reference + }//end of non io buffer + + else { + if ((vertexFormat & GeometryArray.INTERLEAVED) != 0) { + if( interleavedFloatBufferImpl == null) + return; + + float[] cdata = null; + + synchronized (this) { + cdirty = dirtyFlag; + if (updateAlpha && !ignoreVertexColors) { + // update the alpha values + retVal = updateAlphaInInterLeavedData(cv, screen, alpha); + useAlpha = (retVal[0] == Boolean.TRUE); + cdata = (float[])retVal[1]; + if (alpha != lastScreenAlpha) { + lastScreenAlpha = alpha; + cdirty |= COLOR_CHANGED; + } + } else { + // if transparency switch between on/off + if (lastScreenAlpha != -1) { + lastScreenAlpha = -1; + cdirty |= COLOR_CHANGED; + } + } + dirtyFlag = 0; + } + + Pipeline.getPipeline().executeIndexedGeometryBuffer(cv.ctx, + this, geoType, isNonUniformScale, + useAlpha, + ignoreVertexColors, + initialIndexIndex, + validIndexCount, + maxCoordIndex + 1, + vertexFormat, + texCoordSetCount, texCoordSetMap, + (texCoordSetMap == null) ? 0 : texCoordSetMap.length, + texCoordSetMapOffset, + cv.numActiveTexUnit, + interleavedFloatBufferImpl, cdata, + cdirty, indexCoord); + } //end of interleaved + else { + // Check if a vertexformat is set, but the array is null + // if yes, don't draw anything + if ((vertexType == 0) || + ((vertexType & VERTEX_DEFINED) == 0) || + (((vertexFormat & GeometryArray.COLOR) != 0) && + (vertexType & COLOR_DEFINED) == 0) || + (((vertexFormat & GeometryArray.NORMALS) != 0) && + (vertexType & NORMAL_DEFINED) == 0) || + (((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) && + (vertexType & VATTR_DEFINED) == 0) || + (((vertexFormat& GeometryArray.TEXTURE_COORDINATE) != 0) && + (vertexType & TEXCOORD_DEFINED) == 0)) { + return; + } else { + byte[] cbdata = null; + float[] cfdata = null; + + if ((vertexType & CF ) != 0) { + synchronized (this) { + cdirty = dirtyFlag; + if (updateAlpha && !ignoreVertexColors) { + cfdata = updateAlphaInFloatRefColors(cv, + screen, alpha); + if (alpha != lastScreenAlpha) { + lastScreenAlpha = alpha; + cdirty |= COLOR_CHANGED; + } + } else { + // XXXX: handle transparency case + //cfdata = null; + cfdata = mirrorFloatRefColors[0]; + // if transparency switch between on/off + if (lastScreenAlpha != -1) { + lastScreenAlpha = -1; + cdirty |= COLOR_CHANGED; + } + + } + dirtyFlag = 0; + } + } else if ((vertexType & CUB ) != 0) { + synchronized (this) { + cdirty = dirtyFlag; + if (updateAlpha && !ignoreVertexColors) { + cbdata = updateAlphaInByteRefColors( + cv, screen, alpha); + if (alpha != lastScreenAlpha) { + lastScreenAlpha = alpha; + cdirty |= COLOR_CHANGED; + } + } else { + // XXXX: handle transparency case + // cbdata = null; + cbdata = mirrorUnsignedByteRefColors[0]; + // if transparency switch between on/off + if (lastScreenAlpha != -1) { + lastScreenAlpha = -1; + cdirty |= COLOR_CHANGED; + } + } + dirtyFlag = 0; + } + } else { + cdirty = dirtyFlag; + } + + Buffer vcoord = null; + Buffer cdataBuffer = null; + FloatBuffer normal = null; + + int vdefined = 0; + if((vertexType & PF) != 0) { + vdefined |= COORD_FLOAT; + vcoord = floatBufferRefCoords; + } else if((vertexType & PD ) != 0) { + vdefined |= COORD_DOUBLE; + vcoord = doubleBufferRefCoords; + } + if((vertexType & CF ) != 0) { + vdefined |= COLOR_FLOAT; + cdataBuffer = floatBufferRefColors; + } else if((vertexType & CUB) != 0) { + vdefined |= COLOR_BYTE; + cdataBuffer = byteBufferRefColors; + } + + if((vertexType & NORMAL_DEFINED) != 0) { + vdefined |= NORMAL_FLOAT; + normal = floatBufferRefNormals; + } + + if ((vertexType & VATTR_DEFINED) != 0) { + vdefined |= VATTR_FLOAT; + } + + if ((vertexType & TEXCOORD_DEFINED) != 0) { + vdefined |= TEXCOORD_FLOAT; + } + + Pipeline.getPipeline().executeIndexedGeometryVABuffer(cv.ctx, + this, geoType, isNonUniformScale, + ignoreVertexColors, + initialIndexIndex, + validIndexCount, + maxCoordIndex + 1, + (vertexFormat | c4fAllocated), + vdefined, + vcoord, + cdataBuffer, + cfdata, cbdata, + normal, + vertexAttrCount, vertexAttrSizes, + floatBufferRefVertexAttrs, + ((texCoordSetMap == null) ? 0:texCoordSetMap.length), + texCoordSetMap, + cv.numActiveTexUnit, + texCoordStride, + refTexCoords, cdirty, indexCoord); + + } + } // end of non interleaved and by reference + } // end of nio buffer + } + + @Override + void buildGA(Canvas3D cv, RenderAtom ra, boolean isNonUniformScale, + boolean updateAlpha, float alpha, boolean ignoreVertexColors, + Transform3D xform, Transform3D nxform) { + int cdirty; + boolean useAlpha = false; + Object[] retVal; + if (mirrorGeometry != null) { + ((GeometryArrayRetained)mirrorGeometry).buildGA(cv, ra, isNonUniformScale, updateAlpha, alpha, + ignoreVertexColors, xform, nxform); + } + else { + + if ((vertexFormat & GeometryArray.BY_REFERENCE) == 0) { + float[] vdata; + // System.err.println("by-copy"); + synchronized (this) { + cdirty = dirtyFlag; + if (updateAlpha && !ignoreVertexColors) { + // update the alpha values + retVal = updateAlphaInVertexData(cv, cv.screen.screen, alpha); + useAlpha = (retVal[0] == Boolean.TRUE); + vdata = (float[])retVal[1]; + + // D3D only + if (alpha != lastScreenAlpha) { + // handle multiple screen case + lastScreenAlpha = alpha; + cdirty |= COLOR_CHANGED; + } + } else { + vdata = vertexData; + // if transparency switch between on/off + if (lastScreenAlpha != -1) { + lastScreenAlpha = -1; + cdirty |= COLOR_CHANGED; + } + } + // geomLock is get in MasterControl when + // RenderBin render the geometry. So it is safe + // just to set the dirty flag here + dirtyFlag = 0; + } + + Pipeline.getPipeline().buildIndexedGeometry(cv.ctx, + this, geoType, isNonUniformScale, + updateAlpha, alpha, ignoreVertexColors, + initialIndexIndex, + validIndexCount, + maxCoordIndex + 1, + vertexFormat, + vertexAttrCount, vertexAttrSizes, + texCoordSetCount, texCoordSetMap, + (texCoordSetMap == null) ? 0 : texCoordSetMap.length, + texCoordSetMapOffset, + (xform == null) ? null : xform.mat, + (nxform == null) ? null : nxform.mat, + vdata, indexCoord); + } + // XXXX: Note that there is no "else" clause here, and no + // buildIndexedGeometryForByRef() method. + // We would need to create one if we ever wanted to support by-ref + // indexed geometry in display lists. Better yet, we could fix + // canBeInDisplayList so that unindexified by-ref geometry could + // go into a display list. + } + } + + @Override + void mergeGeometryArrays(ArrayList list) { + int numMerge = list.size(); + int[] texCoord = null; + indexCount = 0; + for (int i=0; i < numMerge; i++) { + IndexedGeometryArrayRetained geo= (IndexedGeometryArrayRetained)list.get(i); + indexCount += geo.validIndexCount; + } + validIndexCount = indexCount; + initialIndexIndex = 0; + compileIndexCount = new int[numMerge]; + compileIndexOffset = new int[numMerge]; + indexCoord = new int[indexCount]; + boolean notUCIO = (vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0; + if (notUCIO) { + if ((vertexFormat & GeometryArray.COLOR) != 0) + indexColor = new int[indexCount]; + if ((vertexFormat & GeometryArray.NORMALS) != 0) + indexNormal = new int[indexCount]; + // We only merge if the texCoordSetCount is 1 and there are no + // vertex attrs + if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) { + indexTexCoord = new int[1][]; + indexTexCoord[0] = new int[indexCount]; + texCoord = indexTexCoord[0]; + } + } + int curDataOffset = 0; + int curIndexOffset = 0; + for (int i = 0; i < numMerge; i++) { + IndexedGeometryArrayRetained geo= (IndexedGeometryArrayRetained)list.get(i); + int curIndexCount = geo.validIndexCount; + compileIndexCount[i] = curIndexCount; + // Copy all the indices + for (int j = 0; j < curIndexCount; j++) { + indexCoord[j+curIndexOffset] = geo.indexCoord[j+geo.initialIndexIndex]+curDataOffset; + if (notUCIO) { + if ((vertexFormat & GeometryArray.COLOR) != 0) + indexColor[j+curIndexOffset] = geo.indexColor[j+geo.initialIndexIndex]+curDataOffset; + if ((vertexFormat & GeometryArray.NORMALS) != 0) + indexNormal[j+curIndexOffset] = geo.indexNormal[j+geo.initialIndexIndex]+curDataOffset; + if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) + texCoord[j+curIndexOffset] = geo.indexTexCoord[0][j+geo.initialIndexIndex]+curDataOffset; + } + } + maxCoordIndex = geo.maxCoordIndex +curDataOffset; + compileIndexOffset[i] = curIndexOffset; + curDataOffset += geo.vertexCount; + curIndexOffset += curIndexCount; + } + // reset the max Values + + // call the super to merge the vertex data + super.mergeGeometryArrays(list); + } + + + @Override + boolean isWriteStatic() { + + if (!super.isWriteStatic() || + source.getCapability(IndexedGeometryArray.ALLOW_COORDINATE_INDEX_WRITE ) || + source.getCapability(IndexedGeometryArray.ALLOW_COLOR_INDEX_WRITE) || + source.getCapability(IndexedGeometryArray.ALLOW_NORMAL_INDEX_WRITE) || + source.getCapability(IndexedGeometryArray.ALLOW_VERTEX_ATTR_INDEX_WRITE) || + source.getCapability(IndexedGeometryArray.ALLOW_TEXCOORD_INDEX_WRITE)) { + return false; + } + + return true; + } + + /** + * Gets current number of indices + * @return indexCount + */ + int getIndexCount(int id){ + return compileIndexCount[id]; + } + + int computeMaxIndex(int initial, int count, int[] indices) { + int maxIndex = 0; + if (indices != null) { + for (int i = initial; i < (initial+count); i++) { + if (indices[i] > maxIndex) { + maxIndex = indices[i]; + } + } + } + return maxIndex; + + } + + //NVaidya + // same as computeMaxIndex method but checks for index < 0 + int computeMaxIndexWithCheck(int initial, int count, int[] indices) { + int maxIndex = 0; + for (int i = initial; i < (initial+count); i++) { + // Throw an exception, since index is negative + if (indices[i] < 0) + throw new ArrayIndexOutOfBoundsException(J3dI18N.getString("IndexedGeometryArray27")); + if (indices[i] > maxIndex) { + maxIndex = indices[i]; + } + } + return maxIndex; + + } + + void setValidIndexCount(int validIndexCount) { + if (validIndexCount < 0) { + throw new IllegalArgumentException(J3dI18N.getString("IndexedGeometryArray21")); + } + if ((initialIndexIndex + validIndexCount) > indexCount) { + throw new IllegalArgumentException(J3dI18N.getString("IndexedGeometryArray22")); + } + if ((vertexFormat & GeometryArray.BY_REFERENCE_INDICES) != 0) { + if (indexCoord != null && indexCoord.length < initialIndexIndex + validIndexCount) { + throw new IllegalArgumentException(J3dI18N.getString("IndexedGeometryArray33")); + } + } + int newCoordMax =0; + int newColorIndex=0; + int newNormalIndex=0; + int[] newTexCoordIndex = null; + int[] newVertexAttrIndex = null; + + newCoordMax = computeMaxIndex(initialIndexIndex, validIndexCount,indexCoord ); + doErrorCheck(newCoordMax); + if ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0) { + if ((vertexFormat & GeometryArray.COLOR) != 0) { + newColorIndex = computeMaxIndex(initialIndexIndex, validIndexCount, indexColor); + doColorCheck(newColorIndex); + } + if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) { + newTexCoordIndex = new int[texCoordSetCount]; + for (int i = 0; i < texCoordSetCount; i++) { + newTexCoordIndex[i] = computeMaxIndex(initialIndexIndex,validIndexCount, + indexTexCoord[i]); + doTexCoordCheck(newTexCoordIndex[i], i); + } + } + if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { + newVertexAttrIndex = new int[vertexAttrCount]; + for (int i = 0; i < vertexAttrCount; i++) { + newVertexAttrIndex[i] = computeMaxIndex(initialIndexIndex, + validIndexCount, + indexVertexAttr[i]); + doVertexAttrCheck(newVertexAttrIndex[i], i); + } + } + if ((vertexFormat & GeometryArray.NORMALS) != 0) { + newNormalIndex = computeMaxIndex(initialIndexIndex, validIndexCount, indexNormal); + doNormalCheck(newNormalIndex); + } + } + + boolean isLive = source!=null && source.isLive(); + if(isLive){ + geomLock.getLock(); + } + this.validIndexCount = validIndexCount; + maxCoordIndex = newCoordMax; + if ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0) { + maxColorIndex = newColorIndex; + if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) { + for (int i = 0; i < texCoordSetCount; i++) { + maxTexCoordIndices[i] = newTexCoordIndex[i]; + } + } + if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { + for (int i = 0; i < vertexAttrCount; i++) { + maxVertexAttrIndices[i] = newVertexAttrIndex[i]; + } + } + maxNormalIndex = newNormalIndex; + } + else { + maxColorIndex = maxCoordIndex; + maxNormalIndex = maxCoordIndex; + if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) { + for (int i = 0; i < texCoordSetCount; i++) { + maxTexCoordIndices[i] = maxCoordIndex; + } + } + if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { + for (int i = 0; i < vertexAttrCount; i++) { + maxVertexAttrIndices[i] = maxCoordIndex; + } + } + } + if(isLive) { + geomLock.unLock(); + } + // bbox is computed for the entries list. + // so, send as false + if (!inUpdater && isLive) { + sendDataChangedMessage(true); + } + + } + + void setInitialIndexIndex(int initialIndexIndex) { + if ((initialIndexIndex + validIndexCount) > indexCount) { + throw new IllegalArgumentException(J3dI18N.getString("IndexedGeometryArray22")); + } + if ((vertexFormat & GeometryArray.BY_REFERENCE_INDICES) != 0) { + if (indexCoord != null && indexCoord.length < initialIndexIndex + validIndexCount) { + throw new IllegalArgumentException(J3dI18N.getString("IndexedGeometryArray33")); + } + } + + int newCoordMax =0; + int newColorIndex=0; + int newNormalIndex=0; + int[] newTexCoordIndex = null; + int[] newVertexAttrIndex = null; + + newCoordMax = computeMaxIndex(initialIndexIndex, validIndexCount, indexCoord); + doErrorCheck(newCoordMax); + if ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0) { + if ((vertexFormat & GeometryArray.COLOR) != 0) { + newColorIndex = computeMaxIndex(initialIndexIndex, validIndexCount, indexColor); + doColorCheck(newColorIndex); + } + if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) { + newTexCoordIndex = new int[texCoordSetCount]; + for (int i = 0; i < texCoordSetCount; i++) { + newTexCoordIndex[i] = computeMaxIndex(initialIndexIndex,validIndexCount, + indexTexCoord[i]); + doTexCoordCheck(newTexCoordIndex[i], i); + } + } + if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { + newVertexAttrIndex = new int[vertexAttrCount]; + for (int i = 0; i < vertexAttrCount; i++) { + newVertexAttrIndex[i] = computeMaxIndex(initialIndexIndex, + validIndexCount, + indexVertexAttr[i]); + doVertexAttrCheck(newVertexAttrIndex[i], i); + } + } + if ((vertexFormat & GeometryArray.NORMALS) != 0) { + newNormalIndex = computeMaxIndex(initialIndexIndex, validIndexCount, indexNormal); + doNormalCheck(newNormalIndex); + } + } + + boolean isLive = source!=null && source.isLive(); + if(isLive){ + geomLock.getLock(); + } + dirtyFlag |= INDEX_CHANGED; + this.initialIndexIndex = initialIndexIndex; + maxCoordIndex = newCoordMax; + if ((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0) { + maxColorIndex = newColorIndex; + if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) { + for (int i = 0; i < texCoordSetCount; i++) { + maxTexCoordIndices[i] = newTexCoordIndex[i]; + } + } + if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { + for (int i = 0; i < vertexAttrCount; i++) { + maxVertexAttrIndices[i] = newVertexAttrIndex[i]; + } + } + maxNormalIndex = newNormalIndex; + } + else { + maxColorIndex = maxCoordIndex; + maxNormalIndex = maxCoordIndex; + if ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0) { + for (int i = 0; i < texCoordSetCount; i++) { + maxTexCoordIndices[i] = maxCoordIndex; + } + } + if ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { + for (int i = 0; i < vertexAttrCount; i++) { + maxVertexAttrIndices[i] = maxCoordIndex; + } + } + } + if(isLive) { + geomLock.unLock(); + } + // bbox is computed for the entries list. + // so, send as false + if (!inUpdater && isLive) { + sendDataChangedMessage(true); + } + } + + int getInitialIndexIndex() { + return initialIndexIndex; + } + + int getValidIndexCount() { + return validIndexCount; + } + + @Override + void handleFrequencyChange(int bit) { + if ((bit == IndexedGeometryArray.ALLOW_COORDINATE_INDEX_WRITE) || + (((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0) && + ((vertexFormat & GeometryArray.COLOR) != 0) && + bit == IndexedGeometryArray.ALLOW_COLOR_INDEX_WRITE) || + (((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0) && + ((vertexFormat & GeometryArray.NORMALS) != 0) && + bit == IndexedGeometryArray.ALLOW_NORMAL_INDEX_WRITE) || + (((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0)&& + ((vertexFormat & GeometryArray.VERTEX_ATTRIBUTES) != 0)&& + bit == IndexedGeometryArray.ALLOW_VERTEX_ATTR_INDEX_WRITE) || + (((vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0)&& + ((vertexFormat & GeometryArray.TEXTURE_COORDINATE) != 0)&& + bit == IndexedGeometryArray.ALLOW_TEXCOORD_INDEX_WRITE)) { + + setFrequencyChangeMask(bit, 0x1); + } + else { + super.handleFrequencyChange(bit); + } + } +} |