Package javax.media.j3d

Source Code of javax.media.j3d.IndexedGeometryArrayRetained

/*
* 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);
  }
    }
}
TOP

Related Classes of javax.media.j3d.IndexedGeometryArrayRetained

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.