/** * Get the value of a particular vector value in the event out array. * * @param index The position to get the vectory value from. * @param vec The array to place the value in where. vec[0] = X<br> * vec[1] = Y<br> * vec[2] = Z * @exception ArrayIndexOutOfBoundsException The provided array was too small or the index was * outside the current data array bounds. */ public void get1Value(int index, float[] vec) { if (storedOutput) System.arraycopy(storedOutputValue, index * 3, vec, 0, 3); else { checkReadAccess(); VRMLFieldData data = theNode.getFieldValue(fieldIndex); // floatArrayValue may be null if numElements == 0 if (index < 0 || index >= data.numElements) throw new ArrayIndexOutOfBoundsException(); else System.arraycopy(data.floatArrayValue, index * 3, vec, 0, 3); } }
/** * Get the values of the event out flattened into a single 1D array. The array must be at least 3 * times the size of the array. * * @param vec The array to be filled in where the vec[i + 0] = X<br> * vec[i + 1] = Y<br> * vec[i + 2] = Z<br> * @exception ArrayIndexOutOfBoundsException The provided array was too small */ public void getValue(float[] vec) { if (storedOutput) { System.arraycopy(storedOutputValue, 0, vec, 0, storedOutputValue.length); } else { checkReadAccess(); VRMLFieldData data = theNode.getFieldValue(fieldIndex); if (data.numElements != 0) System.arraycopy(data.floatArrayValue, 0, vec, 0, data.numElements * 3); } }
/** * Magical method to make room for a new image to replace a current one. The newly reallocated * image is not validly formatted. Replaces storedInputValue with a new array. */ void rewriteImageToSize(int imageIndex, int newWidth, int newHeight) { int startOfImage = findStartOfImage(imageIndex, storedInputValue); int newSize = newWidth * newHeight + 3; int oldSize = storedInputValue[startOfImage] * storedInputValue[startOfImage + 1] + 3; int newArray[] = new int[storedInputValue.length - oldSize + newSize]; System.arraycopy(storedInputValue, 0, newArray, 0, startOfImage); System.arraycopy( storedInputValue, startOfImage + oldSize, newArray, startOfImage + newSize, storedInputValue.length - startOfImage - oldSize); storedInputValue = newArray; // throw new RuntimeException("Not yet implemented"); }
/** @see org.web3d.x3d.sai.MFVec3f#insertValue(int, float[]) */ public void insertValue(int index, float[] value) throws ArrayIndexOutOfBoundsException { checkReadAccess(); checkWriteAccess(); synchronized (theEventQueue.eventLock) { MFVec3fWrapper queuedElement = (MFVec3fWrapper) theEventQueue.getLast(this); boolean newEvent = false; if (queuedElement == null || !queuedElement.isSetOneValue) { // Input and output buffers do not mix if (!storedInput && !storedOutput) { queuedElement = this; loadInputValue(); isSetOneValue = true; } else { queuedElement = new MFVec3fWrapper(theNode, fieldIndex, theEventQueue, theEventAdapterFactory, true); queuedElement.isSetOneValue = true; } newEvent = true; } queuedElement.ensureArraySize(queuedElement.storedInputLength + 3); System.arraycopy( queuedElement.storedInputValue, index * 3, queuedElement.storedInputValue, index * 3 + 3, queuedElement.storedInputLength - index * 3); queuedElement.storedInputValue[index * 3] = value[0]; queuedElement.storedInputValue[index * 3 + 1] = value[1]; queuedElement.storedInputValue[index * 3 + 2] = value[2]; queuedElement.storedInputLength += 3; if (newEvent) theEventQueue.processEvent(queuedElement); } }
/** * Ensures that there is atleast a certain number of elements in the storedInputValue array. * * @param newSize The size to ensure. */ protected void ensureArraySize(int newSize) { if (storedInputValue != null && newSize < storedInputValue.length) return; float newArray[] = new float[newSize]; if (storedInputValue != null) System.arraycopy(storedInputValue, 0, newArray, 0, storedInputLength); storedInputValue = newArray; }
/** Load the current field value from the underlying node and store it as the output value. */ public void loadOutputValue() { if (!isWritable()) return; VRMLFieldData value = theNode.getFieldValue(fieldIndex); if (storedOutputValue == null || storedOutputValue.length != value.numElements) storedOutputValue = new float[value.numElements * 3]; if (value.numElements != 0) System.arraycopy(value.floatArrayValue, 0, storedOutputValue, 0, value.numElements * 3); storedOutput = true; }
/** Load the current field value from the underlying node and store it as the input value. */ private void loadInputValue() { if (!isReadable()) return; VRMLFieldData value = theNode.getFieldValue(fieldIndex); if (storedInputValue == null || storedInputValue.length != value.numElements * 3) storedInputValue = new float[value.numElements * 3]; if (value.numElements != 0) System.arraycopy(value.floatArrayValue, 0, storedInputValue, 0, value.numElements * 3); storedInput = true; storedInputLength = storedInputValue.length; }
/** Load the current field value from the underlying node and store it as the output value. */ public void loadOutputValue() { if (!isWritable()) return; // throw new RuntimeException("Not yet implemented"); VRMLFieldData value = theNode.getFieldValue(fieldIndex); int requiredSize = value.numElements; // calculateRequiredStorage(value.numElements,value.intArrayValue); if (storedOutputValue == null || storedOutputValue.length < requiredSize) storedOutputValue = new int[requiredSize]; System.arraycopy(value.intArrayValue, 0, storedOutputValue, 0, requiredSize); storedOutput = true; }
/** Load the current field value from the underlying node and store it as the input value. */ private void loadInputValue() { if (!isReadable()) return; VRMLFieldData value = theNode.getFieldValue(fieldIndex); int requiredSize = value.numElements; // calculateRequiredStorage(value.numElements,value.intArrayValue); if (storedInputValue == null || storedInputValue.length < requiredSize) storedInputValue = new int[requiredSize]; System.arraycopy(value.intArrayValue, 0, storedInputValue, 0, requiredSize); storedInput = true; storedInputLength = storedInputValue.length; }
/** * Set the image value in the given writable field. * <P> * Image values are specified using a width, height and the number of * components. The number of items in the pixels array must be at least * <CODE>width * height<CODE>. If there are less items than this an * ArrayIndexOutOfBoundsException will be generated. The integer values * are represented according to the number of components. If the integer * contains values in bytes that are not used by the number of components * for that image, the values are ignored. * <P> * <B>1 Component Images</B><BR> * The integer has the intensity value stored in the lowest byte and can be * obtained: * <PRE> * intensity = (pixel[i] ) & 0xFF; * </PRE> * <P> * <B>2 Component Images</B><BR> * The integer has the transparency value stored in the lowest byte and the * intensity in the next byte: * <PRE> * intensity = (pixel[i] >> 8) & 0xFF; * alpha = (pixel[i] ) & 0xFF; * </PRE> * <P> * <B>3 Component Images</B><BR> * The three color components are stored in the integer array as follows: * <PRE> * red = (pixel[i] >> 16) & 0xFF; * green = (pixel[i] >> 8) & 0xFF; * blue = (pixel[i] ) & 0xFF; * </PRE> * <P> * <B>4 Component Images</B><BR> * The integer has the value stored in the array as follows: * <PRE> * red = (pixel[i] >> 24) & 0xFF; * green = (pixel[i] >> 16) & 0xFF; * blue = (pixel[i] >> 8) & 0xFF; * alpha = (pixel[i] ) & 0xFF; * </PRE> * <P> * The width and height values must be greater than or equal to zero. The * number of components is between 1 and 4. Any value outside of these * bounds will generate an IllegalArgumentException. * * @param imgIndex The index of the image in the array * @param width The width of the image in pixels * @param height The height of the image in pixels * @param components The number of colour components [1-4] * @param pixels The array of pixel values as specified above. * * @exception IllegalArgumentException The number of components or width/ * height are illegal values. * @exception ArrayIndexOutOfBoundsException The number of pixels provided by the * caller is not enough for the width * height. */ public void set1Value(int imgIndex, int width, int height, int components, int[] pixels) { if (imgIndex < 0) throw new ArrayIndexOutOfBoundsException(); if (width < 0 || height < 0 || components < 0 || components > 4) throw new IllegalArgumentException(); checkWriteAccess(); synchronized (theEventQueue.eventLock) { MFImageWrapper queuedElement = (MFImageWrapper) theEventQueue.getLast(this); if (queuedElement == null || !queuedElement.isSetOneValue) { // Input and output buffers do not mix if (!storedInput && !storedOutput) { // Avoid clogging this buffer if // index out of bounds if (imgIndex >= storedInputValue.length) throw new ArrayIndexOutOfBoundsException(); queuedElement = this; loadInputValue(); isSetOneValue = true; } else { // If this generates an ArrayIndexOutOfBounds its okay, // the element will be garbage. queuedElement = new MFImageWrapper(theNode, fieldIndex, theEventQueue, theEventAdapterFactory, true); queuedElement.isSetOneValue = true; } queuedElement.rewriteImageToSize(imgIndex, width, height); int startingIndex = queuedElement.findStartOfInputImage(imgIndex); queuedElement.storedInputValue[startingIndex + 2] = components; if (pixels.length != 0) System.arraycopy( pixels, 0, queuedElement.storedInputValue, startingIndex + 3, pixels.length); theEventQueue.processEvent(queuedElement); } else { checkDataSanity(); queuedElement.rewriteImageToSize(imgIndex, width, height); int startingIndex = queuedElement.findStartOfInputImage(imgIndex); queuedElement.storedInputValue[startingIndex + 2] = components; if (pixels.length != 0) System.arraycopy( pixels, 0, queuedElement.storedInputValue, startingIndex + 3, pixels.length); } } }
/** * Set the value of the array of 3D vectors. Input is an array of doubles If value[i] does not * contain at least three values it will generate an ArrayIndexOutOfBoundsException. If value[i] * contains more than three items only the first three values will be used and the rest ignored. * * <p>If one or more of the values for value[i] are null then the resulting event that is sent to * the VRML scenegraph is implementation dependent but no error indicator will be set here. * * @param numVec The number of items to copy from the array * @param value The array of vec2f values where<br> * value[i] = X<br> * value[i+1] = Y<br> * value[i+2] = Z * @exception ArrayIndexOutOfBoundsException A value did not contain at least three values for the * vector definition. */ public void setValue(int numVec, float[] value) { checkWriteAccess(); MFVec3fWrapper queuedElement = this; // Input and output buffers do not mix, and further don't overwrite // set1Value calls. if (isSetOneValue || storedInput || storedOutput) { queuedElement = new MFVec3fWrapper(theNode, fieldIndex, theEventQueue, theEventAdapterFactory); } queuedElement.storedInput = true; if (queuedElement.storedInputValue == null || queuedElement.storedInputValue.length != numVec * 3) queuedElement.storedInputValue = new float[numVec * 3]; System.arraycopy(value, 0, queuedElement.storedInputValue, 0, numVec * 3); queuedElement.storedInputLength = numVec * 3; theEventQueue.processEvent(queuedElement); }
/** * Get the image pixel value in the given eventOut. * <P> * The number of items in the pixels array will be * <CODE>width * height<CODE>. If there are less items than this an * ArrayIndexOutOfBoundsException will be generated. The integer values * are represented according to the number of components. * <P> * <B>1 Component Images</B><BR> * The integer has the intensity value stored in the lowest byte and can be * obtained: * <PRE> * intensity = (pixel[i] ) & 0xFF; * </PRE> * <P> * <B>2 Component Images</B><BR> * The integer has the transparency value stored in the lowest byte and the * intensity in the next byte: * <PRE> * intensity = (pixel[i] >> 8) & 0xFF; * alpha = (pixel[i] ) & 0xFF; * </PRE> * <P> * <B>3 Component Images</B><BR> * The three color components are stored in the integer array as follows: * <PRE> * red = (pixel[i] >> 16) & 0xFF; * green = (pixel[i] >> 8) & 0xFF; * blue = (pixel[i] ) & 0xFF; * </PRE> * <P> * <B>4 Component Images</B><BR> * The integer has the value stored in the array as follows: * <PRE> * red = (pixel[i] >> 24) & 0xFF; * green = (pixel[i] >> 16) & 0xFF; * blue = (pixel[i] >> 8) & 0xFF; * alpha = (pixel[i] ) & 0xFF; * </PRE> * <P> * The width and height values must be greater than or equal to zero. The * number of components is between 1 and 4. Any value outside of these * bounds will generate an IllegalArgumentException. * * @param imgIndex The index of the image in the array * @param pixels The array to copy pixel values into */ public void getPixels(int imgIndex, int[] pixels) { // throw new RuntimeException("Not yet implemented"); int startOfImageData; int pixelSource[]; if (storedOutput) { if (imgIndex < 0) throw new ArrayIndexOutOfBoundsException(); pixelSource = storedOutputValue; } else { checkReadAccess(); VRMLFieldData data = theNode.getFieldValue(fieldIndex); if (imgIndex < 0 || imgIndex >= countActualImages(data.intArrayValue, data.numElements)) throw new ArrayIndexOutOfBoundsException(); pixelSource = data.intArrayValue; } startOfImageData = findStartOfImage(imgIndex, pixelSource); int imageSize = pixelSource[startOfImageData] * pixelSource[startOfImageData + 1]; System.arraycopy(pixelSource, startOfImageData + 3, pixels, 0, imageSize); }
/** @see org.web3d.x3d.sai.MFImage#removeValue(int) */ public void removeValue(int index) throws ArrayIndexOutOfBoundsException { checkReadAccess(); checkWriteAccess(); synchronized (theEventQueue.eventLock) { MFImageWrapper queuedElement = (MFImageWrapper) theEventQueue.getLast(this); boolean newEvent = false; if (queuedElement == null || !queuedElement.isSetOneValue) { // Input and output buffers do not mix if (!storedInput && !storedOutput) { queuedElement = this; loadInputValue(); isSetOneValue = true; } else { queuedElement = new MFImageWrapper(theNode, fieldIndex, theEventQueue, theEventAdapterFactory, true); queuedElement.isSetOneValue = true; } newEvent = true; } // Removing a raw byte, rather than an image value. if (queuedElement.storedInputLength > 0) { if (index + 1 < queuedElement.storedInputLength) System.arraycopy( queuedElement.storedInputValue, index + 1, queuedElement.storedInputValue, index, queuedElement.storedInputLength - index - 1); queuedElement.storedInputLength--; queuedElement.rogueInputData = true; if (newEvent) theEventQueue.processEvent(queuedElement); } else { // Free up the buffer before throwing the exception if (newEvent) queuedElement.isSetOneValue = false; throw new ArrayIndexOutOfBoundsException(); } } }