Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* 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);
}
}
}