aboutsummaryrefslogtreecommitdiffstats
path: root/src/javax/media/j3d/IndexedGeometryArrayRetained.java
diff options
context:
space:
mode:
authorHarvey Harrison <[email protected]>2015-04-19 21:02:06 -0700
committerHarvey Harrison <[email protected]>2015-04-19 21:02:06 -0700
commit7a2e20caac9db6f789a7b3fab344b9758af45335 (patch)
treeb5236ff2570178de356eab569225108948eb4d30 /src/javax/media/j3d/IndexedGeometryArrayRetained.java
parentf76ce302c4bb2a9f03bbee571ec5d05c29633023 (diff)
j3dcore: flatten the directory structure a bit
Signed-off-by: Harvey Harrison <[email protected]>
Diffstat (limited to 'src/javax/media/j3d/IndexedGeometryArrayRetained.java')
-rw-r--r--src/javax/media/j3d/IndexedGeometryArrayRetained.java1932
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);
+ }
+ }
+}