/* * 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.awt.Dimension; import java.awt.Point; import javax.vecmath.Point3f; /** * The Raster object extends Geometry to allow drawing a raster image * that is attached to a 3D location in the virtual world. * It contains a 3D point that is defined in the local object * coordinate system of the Shape3D node that references the Raster. * It also contains a type specifier, a clipping mode, a reference to * a ImageComponent2D object and/or a DepthComponent object, an * integer x,y source offset and a size (width, height) to allow * reading or writing a portion of the referenced image, and an * integer x,y destination offset to position the raster relative to * the transformed 3D point. * In addition to being used as a type of geometry for drawing, * a Raster may be used to readback pixel data (color and/or z-buffer) * from the frame buffer in immediate mode. *
* The geometric extent of a Raster object is a single 3D point, specified * by the raster position. This means that geometry-based picking or * collision with a Raster object will only intersect the object at * this single point; the 2D raster image is neither pickable * nor collidable. */ public class Raster extends Geometry { /** * Specifies a Raster object with color data. * In this mode, the image reference must point to * a valid ImageComponent object. * * @see #setType */ public static final int RASTER_COLOR = 0x1; /** * Specifies a Raster object with depth (z-buffer) data. * In this mode, the depthImage reference must point to * a valid DepthComponent object. * * @see #setType */ public static final int RASTER_DEPTH = 0x2; /** * Specifies a Raster object with both color and depth (z-buffer) data. * In this mode, the image reference must point to * a valid ImageComponent object, and the depthImage reference * must point to a valid DepthComponent object. * * @see #setType */ public static final int RASTER_COLOR_DEPTH = RASTER_COLOR | RASTER_DEPTH; /** * Specifies that this raster object is not drawn * if the raster position is outside the viewing volume. * In this mode, the raster is not drawn when the transformed * raster position is clipped out, even if part of the raster would * have been visible. This is the default mode. * * @see #setClipMode * * @since Java 3D 1.3 */ public static final int CLIP_POSITION = 0; /** * Specifies that the raster object is clipped as an image after * the raster position has been transformed. In this mode, part * of the raster may be drawn even when the transformed raster * position is clipped out. * * @see #setClipMode * * @since Java 3D 1.3 */ public static final int CLIP_IMAGE = 1; /** * Specifies that this Raster allows reading the position. */ public static final int ALLOW_POSITION_READ = CapabilityBits.RASTER_ALLOW_POSITION_READ; /** * Specifies that this Raster allows writing the position. */ public static final int ALLOW_POSITION_WRITE = CapabilityBits.RASTER_ALLOW_POSITION_WRITE; /** * Specifies that this Raster allows reading the source or * destination offset. */ public static final int ALLOW_OFFSET_READ = CapabilityBits.RASTER_ALLOW_OFFSET_READ; /** * Specifies that this Raster allows writing the source or * destination offset. */ public static final int ALLOW_OFFSET_WRITE = CapabilityBits.RASTER_ALLOW_OFFSET_WRITE; /** * Specifies that this Raster allows reading the image. */ public static final int ALLOW_IMAGE_READ = CapabilityBits.RASTER_ALLOW_IMAGE_READ; /** * Specifies that this Raster allows writing the image. */ public static final int ALLOW_IMAGE_WRITE = CapabilityBits.RASTER_ALLOW_IMAGE_WRITE; /** * Specifies that this Raster allows reading the depth component. */ public static final int ALLOW_DEPTH_COMPONENT_READ = CapabilityBits.RASTER_ALLOW_DEPTH_COMPONENT_READ; /** * Specifies that this Raster allows writing the depth component. */ public static final int ALLOW_DEPTH_COMPONENT_WRITE = CapabilityBits.RASTER_ALLOW_DEPTH_COMPONENT_WRITE; /** * Specifies that this Raster allows reading the size. */ public static final int ALLOW_SIZE_READ = CapabilityBits.RASTER_ALLOW_SIZE_READ; /** * Specifies that this Raster allows writing the size. */ public static final int ALLOW_SIZE_WRITE = CapabilityBits.RASTER_ALLOW_SIZE_WRITE; /** * Specifies that this Raster allows reading the type. */ public static final int ALLOW_TYPE_READ = CapabilityBits.RASTER_ALLOW_TYPE_READ; /** * Specifies that this Raster allows reading the clip mode. * * @since Java 3D 1.3 */ public static final int ALLOW_CLIP_MODE_READ = CapabilityBits.RASTER_ALLOW_CLIP_MODE_READ; /** * Specifies that this Raster allows writing the clip mode. * * @since Java 3D 1.3 */ public static final int ALLOW_CLIP_MODE_WRITE = CapabilityBits.RASTER_ALLOW_CLIP_MODE_WRITE; // Array for setting default read capabilities private static final int[] readCapabilities = { ALLOW_POSITION_READ, ALLOW_OFFSET_READ, ALLOW_IMAGE_READ, ALLOW_DEPTH_COMPONENT_READ, ALLOW_SIZE_READ, ALLOW_TYPE_READ, ALLOW_CLIP_MODE_READ }; /** * Constructs a Raster object with default parameters. * The default values are as follows: *
setSrcOffset(int,int)
*/
public void setOffset(int xSrcOffset, int ySrcOffset) {
setSrcOffset(xSrcOffset, ySrcOffset);
}
/**
* @deprecated As of Java 3D version 1.3, replaced by
* setSrcOffset(java.awt.Point)
*/
public void setOffset(Point srcOffset) {
setSrcOffset(srcOffset);
}
/**
* @deprecated As of Java 3D version 1.3, replaced by
* getSrcOffset(java.awt.Point)
*/
public void getOffset(Point srcOffset) {
getSrcOffset(srcOffset);
}
/**
* Sets the offset within the source array of pixels
* at which to start copying.
* @param xSrcOffset the x offset within the source array of pixels
* at which to start copying
* @param ySrcOffset the y offset within the source array of pixels
* at which to start copying
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
*
* @since Java 3D 1.3
*/
public void setSrcOffset(int xSrcOffset, int ySrcOffset) {
if (isLiveOrCompiled())
if(!this.getCapability(ALLOW_OFFSET_WRITE))
throw new CapabilityNotSetException(J3dI18N.getString("Raster7"));
((RasterRetained)this.retained).setSrcOffset(xSrcOffset, ySrcOffset);
}
/**
* Sets the offset within the source array of pixels
* at which to start copying.
* @param srcOffset the new source pixel offset
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
*
* @since Java 3D 1.3
*/
public void setSrcOffset(Point srcOffset) {
if (isLiveOrCompiled())
if(!this.getCapability(ALLOW_OFFSET_WRITE))
throw new CapabilityNotSetException(J3dI18N.getString("Raster7"));
((RasterRetained)this.retained).setSrcOffset(srcOffset.x, srcOffset.y);
}
/**
* Retrieves the current source pixel offset.
* @param srcOffset the object that will receive the source offset
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
*
* @since Java 3D 1.3
*/
public void getSrcOffset(Point srcOffset) {
if (isLiveOrCompiled())
if(!this.getCapability(ALLOW_OFFSET_READ))
throw new CapabilityNotSetException(J3dI18N.getString("Raster8"));
((RasterRetained)this.retained).getSrcOffset(srcOffset);
}
/**
* Sets the number of pixels to be copied from the pixel array.
* @param width the number of columns in the array of pixels to copy
* @param height the number of rows in the array of pixels to copy
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
*/
public void setSize(int width, int height) {
if (isLiveOrCompiled())
if(!this.getCapability(ALLOW_SIZE_WRITE))
throw new CapabilityNotSetException(J3dI18N.getString("Raster9"));
((RasterRetained)this.retained).setSize(width, height);
}
/**
* Sets the size of the array of pixels to be copied.
* @param size the new size
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
*/
public void setSize(Dimension size) {
if (isLiveOrCompiled())
if(!this.getCapability(ALLOW_SIZE_WRITE))
throw new CapabilityNotSetException(J3dI18N.getString("Raster9"));
((RasterRetained)this.retained).setSize(size.width, size.height);
}
/**
* Retrieves the current raster size.
* @param size the object that will receive the size
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
*/
public void getSize(Dimension size) {
if (isLiveOrCompiled())
if(!this.getCapability(ALLOW_SIZE_READ))
throw new CapabilityNotSetException(J3dI18N.getString("Raster1"));
((RasterRetained)this.retained).getSize(size);
}
/**
* Sets the destination pixel offset of the upper-left corner of
* the rendered image relative to the transformed position. This
* pixel offset is added to the transformed raster position prior
* to rendering the image.
*
* @param xDstOffset the x coordinate of the new offset
* @param yDstOffset the y coordinate of the new offset
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
*
* @since Java 3D 1.3
*/
public void setDstOffset(int xDstOffset, int yDstOffset) {
if (isLiveOrCompiled())
if(!this.getCapability(ALLOW_OFFSET_WRITE))
throw new CapabilityNotSetException(J3dI18N.getString("Raster7"));
((RasterRetained)this.retained).setDstOffset(xDstOffset, yDstOffset);
}
/**
* Sets the destination pixel offset of the upper-left corner of
* the rendered image relative to the transformed position. This
* pixel offset is added to the transformed raster position prior
* to rendering the image.
*
* @param dstOffset the new destination pixel offset
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
*
* @since Java 3D 1.3
*/
public void setDstOffset(Point dstOffset) {
if (isLiveOrCompiled())
if(!this.getCapability(ALLOW_OFFSET_WRITE))
throw new CapabilityNotSetException(J3dI18N.getString("Raster7"));
((RasterRetained)this.retained).setDstOffset(dstOffset.x, dstOffset.y);
}
/**
* Retrieves the current destination pixel offset.
* @param dstOffset the object that will receive the destination offset
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
*
* @since Java 3D 1.3
*/
public void getDstOffset(Point dstOffset) {
if (isLiveOrCompiled())
if(!this.getCapability(ALLOW_OFFSET_READ))
throw new CapabilityNotSetException(J3dI18N.getString("Raster8"));
((RasterRetained)this.retained).getDstOffset(dstOffset);
}
/**
* Sets the pixel array used to copy pixels to/from a Canvas3D.
* This is used when the type is RASTER_COLOR or RASTER_COLOR_DEPTH.
*
* @param image the ImageComponent2D object containing the
* color data
*
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
*
* @exception IllegalSharingException if this Raster is live and
* the specified image is being used by a Canvas3D as an off-screen buffer.
*
* @exception IllegalArgumentException if the image class of the specified
* ImageComponent2D is ImageClass.NIO_IMAGE_BUFFER.
*
*/
public void setImage(ImageComponent2D image) {
if (isLiveOrCompiled())
if(!this.getCapability(ALLOW_IMAGE_WRITE))
throw new CapabilityNotSetException(J3dI18N.getString("Raster3"));
// Do illegal sharing check
if(image != null) {
ImageComponent2DRetained imageRetained = (ImageComponent2DRetained) image.retained;
if(imageRetained.getUsedByOffScreen()) {
if(isLive()) {
throw new IllegalSharingException(J3dI18N.getString("Raster12"));
}
}
}
((RasterRetained)this.retained).setImage(image);
}
/**
* Retrieves the current pixel array object.
* @return image the ImageComponent2D object containing the
* color data
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
*/
public ImageComponent2D getImage() {
if (isLiveOrCompiled())
if(!this.getCapability(ALLOW_IMAGE_READ))
throw new CapabilityNotSetException(J3dI18N.getString("Raster4"));
return (((RasterRetained)this.retained).getImage());
}
/**
* Sets the depth image used to copy pixels to/from a Canvas3D.
* This is used when the type is RASTER_DEPTH or RASTER_COLOR_DEPTH.
* @param depthComponent the DepthComponent object containing the
* depth (z-buffer) data
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
*/
public void setDepthComponent(DepthComponent depthComponent) {
if (isLiveOrCompiled())
if(!this.getCapability(ALLOW_DEPTH_COMPONENT_WRITE))
throw new CapabilityNotSetException(J3dI18N.getString("Raster5"));
((RasterRetained)this.retained).setDepthComponent(depthComponent);
}
/**
* Retrieves the current depth image object.
* @return depthImage DepthComponent containing the
* depth (z-buffer) data
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
*/
public DepthComponent getDepthComponent() {
if (isLiveOrCompiled())
if(!this.getCapability(ALLOW_DEPTH_COMPONENT_READ))
throw new CapabilityNotSetException(J3dI18N.getString("Raster6"));
return (((RasterRetained)this.retained).getDepthComponent());
}
/**
* @deprecated replaced with cloneNodeComponent(boolean forceDuplicate)
*/
@Override
public NodeComponent cloneNodeComponent() {
Raster r = new Raster();
r.duplicateNodeComponent(this);
return r;
}
/**
* NOTE: Applications should not call this method directly.
* It should only be called by the cloneNode method.
*
* @deprecated replaced with duplicateNodeComponent(
* NodeComponent originalNodeComponent, boolean forceDuplicate)
*/
@Override
public void duplicateNodeComponent(NodeComponent originalNodeComponent) {
checkDuplicateNodeComponent(originalNodeComponent);
}
/**
* Copies all node information from originalNodeComponent
into
* the current node. This method is called from the
* duplicateNode
method. This routine does
* the actual duplication of all "local data" (any data defined in
* this object).
*
* @param originalNodeComponent the original node to duplicate.
* @param forceDuplicate when set to true
, causes the
* duplicateOnCloneTree
flag to be ignored. When
* false
, the value of each node's
* duplicateOnCloneTree
variable determines whether
* NodeComponent data is duplicated or copied.
*
* @see Node#cloneTree
* @see NodeComponent#setDuplicateOnCloneTree
*/
@Override
void duplicateAttributes(NodeComponent originalNodeComponent,
boolean forceDuplicate) {
super.duplicateAttributes(originalNodeComponent, forceDuplicate);
RasterRetained raster = (RasterRetained) originalNodeComponent.retained;
RasterRetained rt = (RasterRetained) retained;
Point3f p = new Point3f();
raster.getPosition(p);
rt.setPosition(p);
rt.setType(raster.getType());
rt.setClipMode(raster.getClipMode());
Point offset = new Point();
raster.getSrcOffset(offset);
rt.setSrcOffset(offset.x, offset.y);
raster.getDstOffset(offset);
rt.setDstOffset(offset.x, offset.y);
Dimension dim = new Dimension();
raster.getSize(dim);
rt.setSize(dim.width, dim.height);
rt.setImage((ImageComponent2D) getNodeComponent(
raster.getImage(),
forceDuplicate,
originalNodeComponent.nodeHashtable));
rt.setDepthComponent((DepthComponent) getNodeComponent(
raster.getDepthComponent(),
forceDuplicate,
originalNodeComponent.nodeHashtable));
}
/**
* This function is called from getNodeComponent() to see if any of
* the sub-NodeComponents duplicateOnCloneTree flag is true.
* If it is the case, current NodeComponent needs to
* duplicate also even though current duplicateOnCloneTree flag is false.
* This should be overwrite by NodeComponent which contains sub-NodeComponent.
*/
@Override
boolean duplicateChild() {
if (getDuplicateOnCloneTree())
return true;
RasterRetained rt = (RasterRetained) retained;
NodeComponent nc = rt.getImage();
if ((nc != null) && nc.getDuplicateOnCloneTree())
return true;
nc = rt.getDepthComponent();
if ((nc != null) && nc.getDuplicateOnCloneTree())
return true;
return false;
}
}