Di Pasqua, Aldo wrote: > Kelvin, > > is bug id 4732956 the same bug that we have experienced: placing the raster > at a z=6400000 and x=0, y=0 (real world coordinates) and with the > appropriate front/back clipping planes, the setDstOffset at any thing but > (0,0) culls out the raster. This culling also occurs when the CLIP_IMAGE is > set for the clip mode. >
Yes, I believe it is the same bug. Since in your case setting setDstOffset (0, 0) works. - Kelvin --------------- Java 3D Team Sun Microsystems Inc. > -----Original Message----- > From: Kelvin Chung [mailto:[EMAIL PROTECTED]] > Sent: Friday, August 16, 2002 6:47 PM > To: [EMAIL PROTECTED] > Subject: Re: [JAVA3D] Raster Bugs? > > > Hi Paul, > > I've filed bug 4732956 > - Raster z value set incorrectly when setDstOffset() or CLIP_IMAGE mode > is used > > for problem (1). > Culling works fine if setDstOffset() and CLIP_IMAGE mode is not used. > > > For (2),(3) RasterTextLabel is contruct with alwaysOnTop = true > so depth buffer test and depth write is disable. > > The menu option "alwaysOnTop" only change the Sphere renderingAttributes > but not the RasterTextLabel (which remain disable depth test and write). > Since rendering order is undefined unless OrderedGroup is used, > the behavior is not unexpected. > > For (5) bug 4732965 > - Raster CLIP_IMAGE mode cause flickering when part of it is clipped > > > For (4) > Doc. mention that position (x, y, z) set by user is in object space > (same as other vertex) and transformed to the device coordinates. > (x', y', z') which is used to put the raster. I don't see > any confusion here. > > For (6), From Doc. > > /** > * 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. > */ > > The center of Raster, instead of upper left corner, is > shift to right (for positive X) and down (for position Y). > The is the convention use for image since the specification > mention upper left corner is (0, 0). As a result of center > shift right and down, it appears that image move left and up. > > Thanks for your bug report. > > - Kelvin > -------------------- > Java 3D Team > Sun Microsystems Inc. > > > Paul Pantera wrote: > > >>OK, I've composed a small program demonstrating the problems I'm >>seeing. It has a sphere and a label both at the same position. >> >> >>>1) Rasters ignoring front and back clipping planes. >>> >> >> >>Zoom way in, zoom way out. The sphere disappears, the label >>never does. >> >> >> >>>2) Rasters ignoring setDepthBufferEnable and always doing depth >>> buffer compare. >>> >> >> >>This demo isn't showing this. Justin suggested that maybe it's a >>rendering order issue. When alwaysOnTop is true (depth buffering >>is disabled) the raster is always either entirely in front of >>the sphere or entirely behind it. Justin suggested I use >>OrderedGroup to make sure my rasters are rendered last. >> >>OrderedGroup may be the only way to do what I need to do. >>Since I can't control the depth of my rasters, I can use >>OrderedGroup to render my objects in a specific order so >>that objects in front of the scene obscure labels behind >>them. Any comments on this? Is the use of OrderedGroup >>going to slow me down? I guess I'll find out soon enough. . . >> >> >>>3) A raster and another Shape transformed by the same transforms >>> end up at different depths. >>> >> >>Use the menu to turn off alwaysOnTop. Zoom in and notice how the >>sphere comes right through the label. The label and the sphere >>are at the same position, so the label should always be in the >>center of the sphere. Depending on the position of the sphere, >>the label moves relative to it in Z. >> >> >>>4) Documentation unclear about the meaning of a Raster's position. >>> (Perhaps more bugs here too, depending on the meaning.) >>> >> >>I'm not setting the raster's position in this example program, for >>simplicity. >> >> >>>5) CLIP_IMAGE causes flickering >>> >> >>Move the sphere over to the left so the left side of the raster is >>clipped. Now spin the sphere and watch the label flicker. >> >> >>>6) Sign problem with setDstOffset >>> >> >>This may not be a bug, but you may want to document it because it's >>not clear to me why positive X and Y offsets move the raster up and >>to the left. >> >>-Paul >> >> >>------------------------------------------------------------------------ >> >> >> > /*************************************************************************** > ** > >> * J3D.org Copyright (c) 2000 >> * Java Source >> * >> * This source is licensed under the GNU LGPL v2.1 >> * Please read http://www.gnu.org/copyleft/lgpl.html for more information >> * >> >> > **************************************************************************** > / > >>package org.j3d.geom; >> >>// Standard imports >>import javax.media.j3d.*; >> >>import java.awt.AlphaComposite; >>import java.awt.Color; >>import java.awt.Font; >>import java.awt.FontMetrics; >>import java.awt.Graphics; >>import java.awt.Graphics2D; >>import java.awt.geom.Rectangle2D; >>import java.awt.image.BufferedImage; >> >>import javax.vecmath.Point3f; >> >>// Application specific imports >> >>/** >> * A text label for labelling objects on screen that uses a Java 3D Raster >> * to produce the overlay effect. >> * <p> >> * >> * If the label text is null, then no label will be displayed. All of the >> * setup will be done, but no raster will be created. >> * <p> >> * >> * The text label can come in a number of flavours depending on how you >> * configure it through the constructors. You may build a label that is >> * only static, always fixed size regardless of text length, and/or may >> * be hidden from other objects v always on the top. Once configured to >> > one > >> * of these versions, it cannot be changed. >> * <p> >> * >> * If running dynamic text, the internal images will only resize to a >> * larger size. That is, if a new string comes in that is smaller than >> * the original string, the image will stay the larger length than the >> * original. The idea is to reduce the amount of garbage generated. >> > However, > >> * in some instances this may not produce acceptable visual behaviour, >> * so the crop() method is introduced that will force the image size to >> * be reduced to the smallest possible size for the next time a string >> * is set. There are also variants on the setText() methods to do this >> * as well with a flag. Cropping is independent of the fixedSize flag but >> > is > >> * still subject to the dynamic flag on the constructor. >> * >> * @author Justin Couch >> * @version $Revision: 2.0 $ >> */ >>public class RasterTextLabel extends Shape3D >>{ >> /** Message when the text label is not setup for dynamic changes */ >> private static final String CANT_CHANGE_MSG = >> "Attempting to make a change to a label that was not originally " >> > + > >> "configured to be dynamic"; >> >> /** The clear colour used to clear the background of the image */ >> private static final Color CLEAR_COLOR = new Color(0, 0, 0, 0); >> >> /** The inset between the text and the border if one is required. */ >> private static final int BORDER_INSETS = 2; >> >> /** The current color of the text */ >> private Color textColor; >> >> /** The current color of the border. Null if not in use */ >> private Color borderColor; >> >> /** The background color of the image */ >> private Color backgroundColor; >> >> /** The font of the label. Null if using system default */ >> private Font labelFont; >> >> /** The raster object that we put the information in */ >> private Raster raster; >> >> /** The image component that holds the image used by the raster */ >> private ImageComponent2D component; >> >> /** >> * Flag to say if the implementation should resize the underlying >> > label > >> * for each text update or not. >> */ >> private boolean adjustImageSize; >> >> /** Flag indicating if this is a dynamic label */ >> private boolean isDynamic; >> >> /** Underlying image used. Only set if this is a dynamic label */ >> private BufferedImage textImage; >> >> /** The current image width */ >> private int imageWidth; >> >> /** The current image height */ >> private int imageHeight; >> >> /** >> * Create a new blank label with no text. It is located at the origin. >> > It > >> * is assumed to be dynamic and always on top. >> */ >> public RasterTextLabel() >> { >> this(null, null, true, true, 0, 0, 0, null, null); >> } >> >> /** >> * Create a new blank label with the given text located at the origin. >> * If the text color is not specified, white is used and the code >> > assumes > >> * static text, it will always be on top. >> * >> * @param label The string to use on the label >> * @param col The text color to be drawn in >> */ >> public RasterTextLabel(String label, Color col) >> { >> this(label, col, false, true, 0, 0, 0, null, null); >> } >> >> /** >> * Create a new blank label with the given text located at the origin. >> * If the text color is not specified, white is used and the code >> > assumes > >> * static text, it will always be on top. >> * >> * @param label The string to use on the label >> * @param col The text color to be drawn in >> * @param alwaysOnTop true if this should never be obscured by content >> */ >> public RasterTextLabel(String label, Color col, boolean alwaysOnTop) >> { >> this(label, col, alwaysOnTop, false, 0, 0, 0, null, null); >> } >> >> /** >> * Create a new blank label with the given text located at the origin. >> * If the text color is not specified, white is used. >> * >> * @param label The string to use on the label >> * @param col The text color to be drawn in >> * @param dynamic True if this will change text over time >> * @param alwaysOnTop true if this should never be obscured by content >> */ >> public RasterTextLabel(String label, >> Color col, >> boolean alwaysOnTop, >> boolean dynamic) >> { >> this(label, col, alwaysOnTop, dynamic, 0, 0, 0, null, null); >> } >> >> /** >> * Create a new blank label with the given text located at a specific >> * point in 3D world coordinates. The code assumes a static label. >> * >> * @param label The string to use on the label >> * @param col The text color to be drawn in >> * @param alwaysOnTop true if this should never be obscured by content >> * @param x The x world coordinate to place the label >> * @param y The y world coordinate to place the label >> * @param z The z world coordinate to place the label >> */ >> public RasterTextLabel(String label, >> Color col, >> boolean alwaysOnTop, >> float x, >> float y, >> float z) >> { >> this(label, col, alwaysOnTop, false, x, y, z, null, null); >> } >> >> /** >> * Create a new blank label with the given text located at a specific >> * point in 3D world coordinates. >> * >> * @param label The string to use on the label >> * @param col The text color to be drawn in >> * @param x The x world coordinate to place the label >> * @param y The y world coordinate to place the label >> * @param z The z world coordinate to place the label >> * @param alwaysOnTop true if this should never be obscured by content >> * @param dynamic True if this will change text over time >> */ >> public RasterTextLabel(String label, >> Color col, >> boolean alwaysOnTop, >> boolean dynamic, >> float x, >> float y, >> float z) >> { >> this(label, col, alwaysOnTop, dynamic, x, y, z, null, null); >> } >> >> /** >> * Create a new blank label with the given text located at a specific >> * point in 3D world coordinates and an option to show a border and >> * selected font. If the border color is specified, it will show a 1 >> * pixel wide border in that color. If no font is defined, the system >> * default font will be used. >> * >> * @param label The string to use on the label >> * @param col The text color to be drawn in >> * @param x The x world coordinate to place the label >> * @param y The y world coordinate to place the label >> * @param z The z world coordinate to place the label >> * @param border The color to use for the border or null for none >> * @param font The font to draw the string in or null for default >> * @param dynamic True if this will change text over time >> */ >> public RasterTextLabel(String label, >> Color col, >> boolean alwaysOnTop, >> boolean dynamic, >> float x, >> float y, >> float z, >> Color border, >> Font font) >> { >> adjustImageSize = false; >> >> textColor = (col != null) ? col : Color.white; >> borderColor = border; >> labelFont = font; >> isDynamic = dynamic; >> >> Appearance app = new Appearance(); >> RenderingAttributes ra = new RenderingAttributes(); >> ra.setAlphaTestFunction(RenderingAttributes.GREATER); >> >> if(alwaysOnTop) >> { >> ra.setDepthBufferEnable(false); >> ra.setDepthBufferWriteEnable(false); >> } >> >> app.setRenderingAttributes(ra); >> setAppearance(app); >> >> // create a disposable 1x1 image so that we can fetch the font >> // metrics associated with the font and text label. This will >> > allow > >> // us to determine the real image size. This is kludgy, but I >> > can't > >> // think of a better way of doing it! >> BufferedImage tmp_img = >> new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB); >> >> Graphics graphics = tmp_img.getGraphics(); >> FontMetrics fm; >> >> if(labelFont == null) >> fm = graphics.getFontMetrics(); >> else >> fm = graphics.getFontMetrics(labelFont); >> >> int width = 0; >> int height = 0; >> >> if(label == null) >> { >> // No label? Create an empty (default) raster object then. >> > This > >> // should result in nothing being rendered on screen, but >> > leaves > >> // us a placeholder for later. >> raster = new Raster(); >> raster.setPosition(new Point3f(x, y, z)); >> } >> else >> { >> // now we have the metrics, let's work out how big the label >> > is! > >> Rectangle2D dimensions = fm.getStringBounds(label, graphics); >> >> graphics.dispose(); >> tmp_img.flush(); >> tmp_img = null; >> >> width = (int)dimensions.getWidth(); >> height = (int)dimensions.getHeight(); >> int ascent = fm.getMaxAscent(); >> >> if(border != null) >> { >> width += BORDER_INSETS * 2 + 2; // one pixel border * 2 >> height += BORDER_INSETS * 2 + 2; >> } >> >> textImage = new BufferedImage(width, >> height, >> BufferedImage.TYPE_INT_ARGB); >> >> graphics = textImage.getGraphics(); >> >> renderImage(graphics, label, width, height, ascent); >> >> graphics.dispose(); >> >> component = new ImageComponent2D(ImageComponent2D.FORMAT_RGBA, >> textImage); >> >> raster = new Raster(new Point3f(x, y, z), >> Raster.RASTER_COLOR, >> 0, >> 0, >> width, >> height, >> component, >> null); >> >> // clear the reference if not dynamic >> if(!dynamic) >> { >> component = null; >> textImage = null; >> } >> } >> >> if(dynamic) >> { >> component.setCapability(ImageComponent2D.ALLOW_IMAGE_WRITE); >> raster.setCapability(Raster.ALLOW_SIZE_WRITE); >> raster.setCapability(Raster.ALLOW_IMAGE_WRITE); >> raster.clearCapabilityIsFrequent(Raster.ALLOW_IMAGE_WRITE); >> } >> >> setGeometry(raster); >> } >> >> /** >> * Set the label string that is to be rendered. This maintains the >> * current text color. If this was not set up to be a dynamic image, >> > an > >> * exception is thrown. >> * >> * @param text The string to be rendered >> * @throws IllegalStateException The label was not set up to be >> > dynamic > >> * in the constructor >> */ >> public void setText(String text) throws IllegalStateException >> { >> if(!isDynamic) >> throw new IllegalStateException(CANT_CHANGE_MSG); >> >> updateText(text); >> } >> >> /** >> * Set the label string that is to be rendered with the option of >> > croping > >> * it to the length of the string. This maintains the current text >> > color. > >> * If this was not set up to be a dynamic image, an exception is >> > thrown. > >> * >> * @param text The string to be rendered >> * @param crop true to crop the underlying raster >> * @throws IllegalStateException The label was not set up to be >> > dynamic > >> * in the constructor >> */ >> public void setText(String text, boolean crop) throws >> > IllegalStateException > >> { >> if(!isDynamic) >> throw new IllegalStateException(CANT_CHANGE_MSG); >> >> if(crop) >> textImage = null; >> >> updateText(text); >> } >> >> /** >> * Set the label string that is to be rendered and changes the color >> * to the new value. If this was not set up to be a dynamic image, an >> * exception is thrown. >> * >> * @param text The string to be rendered >> * @param col The new color to be used or null for the default (white) >> * @throws IllegalStateException The label was not set up to be >> > dynamic > >> * in the constructor >> */ >> public void setText(String text, Color col) throws >> > IllegalStateException > >> { >> if(!isDynamic) >> throw new IllegalStateException(CANT_CHANGE_MSG); >> >> textColor = (col != null) ? col : Color.white; >> >> updateText(text); >> } >> >> /** >> * Set the label string that is to be rendered and changes the color >> * to the new value. If this was not set up to be a dynamic image, an >> * exception is thrown. >> * >> * @param text The string to be rendered >> * @param col The new color to be used or null for the default (white) >> * @param crop true to crop the underlying raster >> * @throws IllegalStateException The label was not set up to be >> > dynamic > >> * in the constructor >> */ >> public void setText(String text, Color col, boolean crop) >> throws IllegalStateException >> { >> if(!isDynamic) >> throw new IllegalStateException(CANT_CHANGE_MSG); >> >> if(crop) >> textImage = null; >> >> textColor = (col != null) ? col : Color.white; >> >> updateText(text); >> } >> >> >> /** >> * Set the condition of whether the implementation should resize the >> * canvas after each new label is set or just stick to a fixed size >> * canvas. A fixed size label is useful when you are making fast >> > updates > >> * such as a counter. When this is called, the label will not be >> > resized > >> * from it's current dimensions. This may be changed dynamically and >> > will > >> * only take effect next time a text string is set and the size is >> > based > >> * on the biggest image used to date, not on the next string that is >> * set. >> * >> * @param fixed true if the label size should remain fixed >> * @throws IllegalStateException The label was not set up to be >> > dynamic > >> * in the constructor >> */ >> public void fixSize(boolean fixed) >> throws IllegalStateException >> { >> if(!isDynamic) >> throw new IllegalStateException(CANT_CHANGE_MSG); >> >> adjustImageSize = fixed; >> } >> >> /** >> * Crop the image used for the raster to the length of the string the >> > next > >> * time a string is set. This will not crop the current string, only >> > the > >> * next one. >> * >> * @throws IllegalStateException The label was not set up to be >> > dynamic > >> * in the constructor >> */ >> public void crop() >> throws IllegalStateException >> { >> if(!isDynamic) >> throw new IllegalStateException(CANT_CHANGE_MSG); >> >> // easiest way to force a rebuild is to remove the textImage >> > reference > >> // completely and treat it like a new image with no text set. >> textImage = null; >> } >> >> /** >> * Update the raster to display the new text. >> * >> * @param label The new text string to draw >> * @param fontChanged true if the font changed >> */ >> private void updateText(String label) >> { >> // If we have no text to display, just set the size to display >> // nothing and leave immediately. >> if(label == null) >> { >> raster.setSize(0, 0); >> return; >> } >> >> int width = 0; >> int height = 0; >> FontMetrics metrics = null; >> Graphics graphics = null; >> >> // Work on the null image first because adjustSize may also be set >> // but would crash with a null source image. >> if(textImage == null) >> { >> BufferedImage tmp_img = >> new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB); >> >> graphics = tmp_img.getGraphics(); >> >> if(labelFont == null) >> metrics = graphics.getFontMetrics(); >> else >> metrics = graphics.getFontMetrics(labelFont); >> >> Rectangle2D dimensions = metrics.getStringBounds(label, >> > graphics); > >> graphics.dispose(); >> tmp_img.flush(); >> >> width = (int)dimensions.getWidth(); >> height = (int)dimensions.getHeight(); >> >> if(borderColor != null) >> { >> width += BORDER_INSETS * 2 + 2; // one pixel border * 2 >> height += BORDER_INSETS * 2 + 2; >> } >> >> textImage = new BufferedImage(width, >> height, >> BufferedImage.TYPE_INT_ARGB); >> >> graphics = textImage.createGraphics(); >> renderImage(graphics, label, width, height, >> > metrics.getAscent()); > >> component = new ImageComponent2D(ImageComponent2D.FORMAT_RGBA, >> textImage); >> component.setCapability(ImageComponent2D.ALLOW_IMAGE_WRITE); >> >> raster.setSize(width, height); >> raster.setImage(component); >> } >> else if(adjustImageSize) >> { >> // recalc size and compare against current. >> graphics = textImage.getGraphics(); >> >> if(labelFont == null) >> metrics = graphics.getFontMetrics(); >> else >> metrics = graphics.getFontMetrics(labelFont); >> >> Rectangle2D dimensions = metrics.getStringBounds(label, >> > graphics); > >> width = (int)dimensions.getWidth(); >> height = (int)dimensions.getHeight(); >> >> if(borderColor != null) >> { >> width += BORDER_INSETS * 2 + 2; // one pixel border * 2 >> height += BORDER_INSETS * 2 + 2; >> } >> >> // So now we know the required size. Is it bigger than the >> > current > >> // image size? Resize if new size if bigger than the old. >> if((width > textImage.getWidth(null)) || >> (height > textImage.getHeight(null))) >> { >> textImage.flush(); >> textImage = new BufferedImage(width, >> height, >> >> > BufferedImage.TYPE_INT_ARGB); > >> graphics = textImage.createGraphics(); >> >> // Probably superfluous, but in for correctness. >> if(labelFont == null) >> metrics = graphics.getFontMetrics(); >> else >> metrics = graphics.getFontMetrics(labelFont); >> >> renderImage(graphics, label, width, height, >> > metrics.getAscent()); > >> component = new >> > ImageComponent2D(ImageComponent2D.FORMAT_RGBA, > >> textImage); >> >> > component.setCapability(ImageComponent2D.ALLOW_IMAGE_WRITE); > >> raster.setSize(width, height); >> raster.setImage(component); >> } >> else >> { >> renderImage(graphics, label, width, height, >> > metrics.getAscent()); > >> component.set(textImage); >> raster.setSize(width, height); >> } >> } >> else >> { >> // fixed size >> graphics = textImage.createGraphics(); >> >> if(labelFont == null) >> metrics = graphics.getFontMetrics(); >> else >> metrics = graphics.getFontMetrics(labelFont); >> >> Rectangle2D dimensions = metrics.getStringBounds(label, >> > graphics); > >> width = (int)dimensions.getWidth(); >> height = (int)dimensions.getHeight(); >> >> if(borderColor != null) >> { >> width += BORDER_INSETS * 2 + 2; // one pixel border * 2 >> height += BORDER_INSETS * 2 + 2; >> } >> >> renderImage(graphics, label, width, height, >> > metrics.getAscent()); > >> component.set(textImage); >> raster.setSize(width, height); >> } >> >> graphics.dispose(); >> } >> >> /** >> * Convenience method to render the image given the font information. >> > When > >> * this method exits, it will have changed the global imageWidth and >> * imageHeight variables to the given width and height values. >> * >> * @param graphics The graphics context for textImage >> * @param label The string to render >> * @param width The width of the image drawn to >> * @param height The height of the image drawn to >> * @param ascent The ascent of the font in use >> */ >> private void renderImage(Graphics graphics, >> String label, >> int width, >> int height, >> int ascent) >> { >> Graphics2D g = (Graphics2D)graphics; >> g.setComposite(AlphaComposite.Src); >> >> g.setColor(CLEAR_COLOR); >> g.fillRect(0, 0, imageWidth, imageHeight); >> >> if(borderColor != null) >> { >> g.setColor(borderColor); >> g.drawRect(0, 0, width - 1, height - 1); >> >> g.setColor(textColor); >> g.setFont(labelFont); >> g.drawString(label, >> BORDER_INSETS + 1, >> ascent + BORDER_INSETS + 1); >> } >> else >> { >> g.setColor(textColor); >> g.setFont(labelFont); >> g.drawString(label, 0, ascent); >> } >> >> imageWidth = width; >> imageHeight = height; >> } >>} >> >> >>------------------------------------------------------------------------ >> >>import java.awt.*; >>import java.awt.event.*; >>import java.awt.Rectangle; >>import java.util.AbstractList; >>import java.util.ArrayList; >>import java.util.Enumeration; >>import java.util.Iterator; >> >>import javax.media.j3d.*; >>import javax.vecmath.*; >>import javax.swing.*; >> >>import com.sun.j3d.utils.geometry.Sphere; >>import com.sun.j3d.utils.universe.PlatformGeometry; >>import com.sun.j3d.utils.universe.SimpleUniverse; >>import com.sun.j3d.utils.universe.ViewingPlatform; >>import com.sun.j3d.utils.image.TextureLoader; >>import com.sun.j3d.utils.behaviors.vp.OrbitBehavior; >>import com.sun.j3d.utils.behaviors.keyboard.KeyNavigatorBehavior; >>import com.sun.j3d.utils.applet.JMainFrame; >>import org.j3d.geom.RasterTextLabel; >> >> >>import org.j3d.geom.*; >> >>public final class RasterBugs extends JApplet { >> >> private static final Geometry sphereGeometry; >> >> private KeyNavigatorBehavior keyBehavior; >> >> private TransformGroup vptg; >> >> private static final float MOVE_BACK = 2.0f; >> >> private BranchGroup objRoot = null; >> >> private static final Color3f BLACK = new Color3f(0f, 0f, 0f); >> private static final Color3f WHITE = new Color3f(1f, 1f, 1f); >> private static final Color3f GREEN = new Color3f(0.5f, 1f, 0.5f); >> >> private SimpleUniverse u; >> >> private PlatformGeometry pg; >> >> private BoundingSphere bounds; >> >> private static final Point3d D_ORIGIN = new Point3d(0, 0, 0); >> >> private Canvas3D c3d; >> >> private boolean alwaysOnTop = true; >> >> private RenderingAttributes ra; >> >> static { >> final int SPHERE_TESSELATION = 20; >> >> Sphere s = >> new Sphere(1.0f, Sphere.GENERATE_NORMALS, SPHERE_TESSELATION, null); >> sphereGeometry = s.getShape().getGeometry(); >> } // End of static initializer >> >> >> >> /** >> * Set up keyboard navigation. >> */ >> private void addKeyBehavior(BranchGroup b) { >> // Set up keyboard navigation >> keyBehavior = new KeyNavigatorBehavior( >> u.getViewingPlatform().getViewPlatformTransform()); >> keyBehavior.setSchedulingBounds(bounds); >> // Add behavior to scenegraph >> b.addChild(keyBehavior); >> } // End of addKeyBehavior >> >> >> /** >> * Initialize and return the Canvas3D we'll be using for rendering. >> */ >> public void init() { >> >> bounds = new BoundingSphere(D_ORIGIN, Double.POSITIVE_INFINITY); >> >> // Use utility to get the right graphics destination >> GraphicsConfiguration config = >> SimpleUniverse.getPreferredConfiguration(); >> >> // Create a canvas on the device >> c3d = new Canvas3D(config); >> >> Container contentPane = getContentPane(); >> contentPane.setLayout(new BorderLayout()); >> contentPane.add(c3d, "Center"); >> JPopupMenu.setDefaultLightWeightPopupEnabled(false); >> JMenuBar menuBar = new JMenuBar(); >> setJMenuBar(menuBar); >> JMenu viewMenu = new JMenu("View"); >> menuBar.add(viewMenu); >> JMenuItem inFrontItem = new JMenuItem("not alwaysOnTop"); >> viewMenu.add(inFrontItem); >> inFrontItem.addActionListener( >> new ActionListener() { >> public void actionPerformed(ActionEvent e) { >> JMenuItem inFrontItem = (JMenuItem)e.getSource(); >> alwaysOnTop = !alwaysOnTop; >> if (alwaysOnTop) { >> inFrontItem.setText("not alwaysOnTop"); >> ra.setDepthBufferEnable(false); >> ra.setDepthBufferWriteEnable(false); >> } else { >> inFrontItem.setText("alwaysOnTop"); >> ra.setDepthBufferEnable(true); >> ra.setDepthBufferWriteEnable(true); >> } >> } >> } >> ); >> >> >> // Use utility to create default universe >> u = new SimpleUniverse(c3d); >> >> // Set the viewpoint back from the origin and point toward the origin >> ViewingPlatform vp = u.getViewingPlatform(); >> >> >> vp.setNominalViewingTransform(); >> vptg = vp.getViewPlatformTransform(); >> Transform3D vpt = new Transform3D(); >> vptg.getTransform(vpt); >> Transform3D translate = new Transform3D(); >> translate.setTranslation(new Vector3f(0f,0f,MOVE_BACK)); >> vpt.mul(translate); >> vptg.setTransform(vpt); >> >> // Allow mouse manipulation >> OrbitBehavior orbit = new OrbitBehavior(c3d, >> > OrbitBehavior.REVERSE_ALL); > >> // Behavior is only enabled within its bounds >> bounds = new BoundingSphere(D_ORIGIN, 100.0); >> orbit.setSchedulingBounds(bounds); >> >> // Attach behavior to ViewingPlatform >> vp.setViewPlatformBehavior(orbit); >> >> // Will add lights here so they are "headlights" >> // that move with the viewer >> pg = new PlatformGeometry(); >> >> // Set up the ambient light >> Color3f ambientColor = new Color3f(0.1f, 0.1f, 0.1f); >> AmbientLight ambientLightNode = new AmbientLight(ambientColor); >> ambientLightNode.setInfluencingBounds(bounds); >> pg.addChild(ambientLightNode); >> >> // Set up the directional lights >> Color3f light1Color = new Color3f(1.0f, 1.0f, 0.9f); >> Vector3f light1Direction = new Vector3f(1.0f, 1.0f, 1.0f); >> Color3f light2Color = new Color3f(1.0f, 1.0f, 1.0f); >> Vector3f light2Direction = new Vector3f(-1.0f, -1.0f, -1.0f); >> >> DirectionalLight light1 >> = new DirectionalLight(light1Color, light1Direction); >> light1.setInfluencingBounds(bounds); >> pg.addChild(light1); >> >> DirectionalLight light2 >> = new DirectionalLight(light2Color, light2Direction); >> light2.setInfluencingBounds(bounds); >> pg.addChild(light2); >> >> vp.setPlatformGeometry(pg); >> >> objRoot = new BranchGroup(); >> objRoot.setCapability(objRoot.ALLOW_DETACH); >> objRoot.setCapability(objRoot.ALLOW_CHILDREN_EXTEND); >> objRoot.setCapability(objRoot.ALLOW_CHILDREN_WRITE); >> >> addKeyBehavior(objRoot); >> >> objRoot.compile(); >> >> u.addBranchGraph(objRoot); >> >> addNode(); >> >> } // End of init >> >> >> /** >> * Add a node to the graph. >> */ >> public void addNode() >> { >> // Each node is connected by a BranchGroup (to allow it to >> // be removed) >> BranchGroup root = new BranchGroup(); >> >> // Transform Group to hold position transform >> TransformGroup posTg = new TransformGroup(); >> Transform3D pos = new Transform3D(); >> Vector3f translate = new Vector3f(0.2f,0f,0f); >> pos.setTranslation(translate); >> posTg.setTransform(pos); >> root.addChild(posTg); >> >> // TransformGroup to hold scale transform >> TransformGroup scaleTg = new TransformGroup(); >> Transform3D scale = new Transform3D(); >> scale.setScale(0.2); >> scaleTg.setTransform(scale); >> posTg.addChild(scaleTg); >> >> // Set appearance of node >> ra = new RenderingAttributes(); >> Material mat = new Material(BLACK, BLACK, GREEN, WHITE, 128.0f); >> Appearance a = new Appearance(); >> a.setMaterial(mat); >> a.setRenderingAttributes(ra); >> >> Shape3D shape = new Shape3D(sphereGeometry, a); >> >> scaleTg.addChild(shape); >> >> BranchGroup bg = new BranchGroup(); >> >> RasterTextLabel rtl = new RasterTextLabel( >> "RasterTextLabel", Color.WHITE, alwaysOnTop, false, 0f, 0f, 0f); >> >> Raster labelText = (Raster)rtl.getGeometry(); >> labelText.setClipMode(Raster.CLIP_IMAGE); >> >> Appearance ap = rtl.getAppearance(); >> ra = ap.getRenderingAttributes(); >> ra.setCapability(RenderingAttributes.ALLOW_DEPTH_ENABLE_WRITE); >> >> Dimension dim = new Dimension(); >> labelText.getSize(dim); >> labelText.setDstOffset(dim.width / 2, dim.height / 2); >> posTg.addChild(rtl); >> >> root.compile(); >> >> objRoot.addChild(root); >> } // End of addNode >> >> >> public static void main(String[] args) { >> new JMainFrame(new RasterBugs(args), 500, 500); >> } >> >> public RasterBugs(String[] args) >> { >> } >> >> public RasterBugs() >> { >> } >>} // End of file RenderEngine.java >> >> > > =========================================================================== > To unsubscribe, send email to [EMAIL PROTECTED] and include in the body > of the message "signoff JAVA3D-INTEREST". For general help, send email to > [EMAIL PROTECTED] and include in the body of the message "help". > > =========================================================================== > To unsubscribe, send email to [EMAIL PROTECTED] and include in the body > of the message "signoff JAVA3D-INTEREST". For general help, send email to > [EMAIL PROTECTED] and include in the body of the message "help". > =========================================================================== To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message "signoff JAVA3D-INTEREST". For general help, send email to [EMAIL PROTECTED] and include in the body of the message "help".
