// Java 3D Test Applet // FogTest.java // Copyright (c) 1999 ENDO Yasuyuki // mailto:yasuyuki@javaopen.org // http://www.javaopen.org/j3dbook/index.html import java.applet.*; import java.awt.*; import java.awt.event.*; import javax.media.j3d.*; import javax.vecmath.*; import com.sun.j3d.utils.applet.MainFrame; import com.sun.j3d.utils.universe.SimpleUniverse; import com.sun.j3d.utils.geometry.Sphere; import com.sun.j3d.utils.image.TextureLoader; public class FogTest extends Applet { boolean isStandalone = false; private Canvas3D canvas = null; private SimpleUniverse universe = null; private BranchGroup scene = null; private Background background = null; private TextureLoader loader = null; private Appearance app = null; private Fog fog = null; private LinearFog lfog = null; private ExponentialFog efog = null; public FogTest() { this(false); } public FogTest(boolean isStandalone) { this.isStandalone = isStandalone; this.setLayout(new BorderLayout()); Panel uppanel = new Panel(); this.add(uppanel, BorderLayout.NORTH); uppanel.add( new Label("Background") ); Checkbox icheck = new Checkbox("Image", true); icheck.addItemListener( new ItemListener() { public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) { background.setImage(loader.getImage()); } else if (e.getStateChange() == ItemEvent.DESELECTED) { background.setImage(null); } } }); uppanel.add(icheck); uppanel.add( new Label("Color - R") ); TextField bgrfield = new TextField("0.0"); bgrfield.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { float r = 0.0f; try { r = Float.parseFloat(e.getActionCommand()); if (r < 0.0f) r = 0.0f; if (r > 1.0f) r = 1.0f; Color3f color = new Color3f(); background.getColor(color); color.x = r; background.setColor(color); } catch (NumberFormatException ex) {} } }); uppanel.add(bgrfield); uppanel.add( new Label("G") ); TextField bggfield = new TextField("0.0"); bggfield.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { float g = 0.0f; try { g = Float.parseFloat(e.getActionCommand()); if (g < 0.0f) g = 0.0f; if (g > 1.0f) g = 1.0f; Color3f color = new Color3f(); background.getColor(color); color.y = g; background.setColor(color); } catch (NumberFormatException ex) {} } }); uppanel.add(bggfield); uppanel.add( new Label("B") ); TextField bgbfield = new TextField("0.0"); bgbfield.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { float b = 0.0f; try { b = Float.parseFloat(e.getActionCommand()); if (b < 0.0f) b = 0.0f; if (b > 1.0f) b = 1.0f; Color3f color = new Color3f(); background.getColor(color); color.z = b; background.setColor(color); } catch (NumberFormatException ex) {} } }); uppanel.add(bgbfield); Panel downpanel = new Panel(); downpanel.setLayout( new GridLayout(3, 1) ); this.add(downpanel, BorderLayout.SOUTH); Panel[] dpanels = new Panel[3]; for (int i=0; i<3; i++) { dpanels[i] = new Panel(); downpanel.add(dpanels[i]); } dpanels[0].add( new Label("Model Color - R") ); TextField mrfield = new TextField("1.0"); mrfield.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { float r = 0.0f; try { r = Float.parseFloat(e.getActionCommand()); if (r < 0.0f) r = 0.0f; if (r > 1.0f) r = 1.0f; Color3f color = new Color3f(); app.getMaterial().getDiffuseColor(color); color.x = r; app.getMaterial().setDiffuseColor(color); } catch (NumberFormatException ex) {} } }); dpanels[0].add(mrfield); dpanels[0].add( new Label("G") ); TextField mgfield = new TextField("0.0"); mgfield.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { float g = 0.0f; try { g = Float.parseFloat(e.getActionCommand()); if (g < 0.0f) g = 0.0f; if (g > 1.0f) g = 1.0f; Color3f color = new Color3f(); app.getMaterial().getDiffuseColor(color); color.y = g; app.getMaterial().setDiffuseColor(color); } catch (NumberFormatException ex) {} } }); dpanels[0].add(mgfield); dpanels[0].add( new Label("B") ); TextField mbfield = new TextField("0.0"); mbfield.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { float b = 0.0f; try { b = Float.parseFloat(e.getActionCommand()); if (b < 0.0f) b = 0.0f; if (b > 1.0f) b = 1.0f; Color3f color = new Color3f(); app.getMaterial().getDiffuseColor(color); color.z = b; app.getMaterial().setDiffuseColor(color); } catch (NumberFormatException ex) {} } }); dpanels[0].add(mbfield); dpanels[0].add( new Label("BackClip") ); TextField bcfield = new TextField("10.0"); bcfield.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { double clip = 0.0; try { clip = Double.parseDouble(e.getActionCommand()); universe.getViewer().getView().setBackClipDistance(clip); } catch (NumberFormatException ex) {} } }); dpanels[0].add(bcfield); Panel fpanel = new Panel(); fpanel.setLayout( new GridLayout(1, 2) ); dpanels[1].add(fpanel); final Panel fdpanel = new Panel(); final CardLayout clayout = new CardLayout(); fdpanel.setLayout(clayout); dpanels[1].add(fdpanel); dpanels[2].add( new Label("Fog Color - R") ); final TextField rfield = new TextField("0.0"); rfield.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { float r = 0.0f; try { r = Float.parseFloat(e.getActionCommand()); if (r < 0.0f) r = 0.0f; if (r > 1.0f) r = 1.0f; Color3f color = new Color3f(); fog.getColor(color); color.x = r; fog.setColor(color); } catch (NumberFormatException ex) {} } }); dpanels[2].add(rfield); dpanels[2].add( new Label("G") ); final TextField gfield = new TextField("0.0"); gfield.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { float g = 0.0f; if (g < 0.0f) g = 0.0f; if (g > 1.0f) g = 1.0f; try { g = Float.parseFloat(e.getActionCommand()); Color3f color = new Color3f(); fog.getColor(color); color.y = g; fog.setColor(color); } catch (NumberFormatException ex) {} } }); dpanels[2].add(gfield); dpanels[2].add( new Label("B") ); final TextField bfield = new TextField("0.0"); bfield.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { float b = 0.0f; if (b < 0.0f) b = 0.0f; if (b > 1.0f) b = 1.0f; try { b = Float.parseFloat(e.getActionCommand()); Color3f color = new Color3f(); fog.getColor(color); color.z = b; fog.setColor(color); } catch (NumberFormatException ex) {} } }); dpanels[2].add(bfield); Panel[] fdpanels = new Panel[3]; for (int i=0; i<3; i++) { fdpanels[i] = new Panel(); fdpanel.add(fdpanels[i], Integer.toString(i)); } clayout.show(fdpanel, "2"); Panel fgpanel = new Panel(); fgpanel.setLayout( new GridLayout(1, 3) ); fpanel.add(fgpanel); CheckboxGroup cbg = new CheckboxGroup(); Checkbox ncheck = new Checkbox("None", cbg, false); ncheck.addItemListener( new ItemListener() { public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) { universe.getLocale().removeBranchGraph(scene); removeChild(scene, fog); clayout.show(fdpanel, "0"); universe.addBranchGraph(scene); } else if (e.getStateChange() == ItemEvent.DESELECTED) { universe.getLocale().removeBranchGraph(scene); addChild(scene, fog); universe.addBranchGraph(scene); } } }); fgpanel.add(ncheck); Checkbox lcheck = new Checkbox("Linear", cbg, false); lcheck.addItemListener( new ItemListener() { public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) { universe.getLocale().removeBranchGraph(scene); removeChild(scene, fog); fog = lfog; Color3f color = new Color3f(); fog.getColor(color); rfield.setText(Float.toString(color.x)); gfield.setText(Float.toString(color.y)); bfield.setText(Float.toString(color.z)); clayout.show(fdpanel, "1"); addChild(scene, fog); universe.addBranchGraph(scene); } } }); fgpanel.add(lcheck); Checkbox echeck = new Checkbox("Exp", cbg, true); echeck.addItemListener( new ItemListener() { public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) { universe.getLocale().removeBranchGraph(scene); removeChild(scene, fog); fog = efog; Color3f color = new Color3f(); fog.getColor(color); rfield.setText(Float.toString(color.x)); gfield.setText(Float.toString(color.y)); bfield.setText(Float.toString(color.z)); clayout.show(fdpanel, "2"); addChild(scene, fog); universe.addBranchGraph(scene); } } }); fgpanel.add(echeck); fdpanels[1].add( new Label("FrDistance") ); TextField frfield = new TextField("0.1"); frfield.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { double d = 0.0; try { d= Double.parseDouble(e.getActionCommand()); lfog.setFrontDistance(d); } catch (NumberFormatException ex) {} } }); fdpanels[1].add(frfield); fdpanels[1].add( new Label("BkDistance") ); TextField brfield = new TextField("1.0"); brfield.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { double d = 0.0; try { d = Double.parseDouble(e.getActionCommand()); lfog.setBackDistance(d); } catch (NumberFormatException ex) {} } }); fdpanels[1].add(brfield); fdpanels[2].add( new Label("Dencity") ); TextField dcfield = new TextField("1.0"); dcfield.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { float d = 0.0f; try { d = Float.parseFloat(e.getActionCommand()); efog.setDensity(d); } catch (NumberFormatException ex) {} } }); fdpanels[2].add(dcfield); } public void init() { GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration(); this.canvas = new Canvas3D(config); this.add(this.canvas, BorderLayout.CENTER); universe = new SimpleUniverse(canvas); universe.getViewingPlatform().setNominalViewingTransform(); scene = createSceneGraph(); universe.addBranchGraph(scene); } private BranchGroup createSceneGraph() { BranchGroup root = new BranchGroup(); root.setCapability(BranchGroup.ALLOW_DETACH); BoundingSphere bounds = new BoundingSphere(new Point3d(), 10000.0); background = createBackground(bounds); root.addChild(background); root.addChild(createLight(0.3f, -0.3f, -0.3f)); app = createAppearance(); double x = -2.0; double y = -2.0; double z = 2.0; for (int i=0; i<20; i++) { root.addChild( createSphere(0.5f, x, y, z, app) ); x += 0.3 * (double)i; y += 0.3 * (double)i; z -= (double)i; } lfog = new LinearFog(); lfog.setCapability(Fog.ALLOW_COLOR_READ); lfog.setCapability(Fog.ALLOW_COLOR_WRITE); lfog.setCapability(LinearFog.ALLOW_DISTANCE_WRITE); lfog.setInfluencingBounds(bounds); efog = new ExponentialFog(); efog.setCapability(Fog.ALLOW_COLOR_READ); efog.setCapability(Fog.ALLOW_COLOR_WRITE); efog.setCapability(ExponentialFog.ALLOW_DENSITY_WRITE); efog.setInfluencingBounds(bounds); fog = efog; root.addChild(fog); return root; } private Background createBackground(Bounds bounds) { // Texture の生成 Image image = null; if (this.isStandalone) { // アプリケーションとして実行されている Toolkit toolkit = Toolkit.getDefaultToolkit(); image = toolkit.getImage("bg.jpg"); } else { // アプレットとして実行されている image = getImage(getCodeBase(), "bg.jpg"); } MediaTracker mt = new MediaTracker(this); mt.addImage(image, 0); mt.checkAll(true); try { mt.waitForID(0); } catch (InterruptedException e) { e.printStackTrace(); } this.loader = new TextureLoader(image, this); Background bg = new Background(this.loader.getImage()); bg.setCapability(Background.ALLOW_COLOR_READ); bg.setCapability(Background.ALLOW_COLOR_WRITE); bg.setCapability(Background.ALLOW_IMAGE_WRITE); bg.setApplicationBounds(bounds); return bg; } private TransformGroup createSphere( float radius, double x, double y, double z, Appearance app) { Transform3D t3d = new Transform3D(); Vector3d position = new Vector3d(x, y, z); t3d.set(position); TransformGroup trans = new TransformGroup(t3d); trans.addChild( new Sphere(radius, Sphere.GENERATE_NORMALS, app) ); return trans; } private Appearance createAppearance() { Appearance app = new Appearance(); app.setCapability(Appearance.ALLOW_MATERIAL_READ); Material mat = new Material(); mat.setCapability(Material.ALLOW_COMPONENT_READ); mat.setCapability(Material.ALLOW_COMPONENT_WRITE); mat.setDiffuseColor(1.0f, 0.0f, 0.0f); mat.setSpecularColor(0.1f, 0.1f, 0.1f); app.setMaterial(mat); return app; } private Light createLight(float x, float y, float z) { DirectionalLight light = new DirectionalLight( true, new Color3f(1.0f, 1.0f, 1.0f), new Vector3f(x, y, z)); light.setInfluencingBounds(new BoundingSphere(new Point3d(), 100.0)); return light; } private void addChild(Group group, Node node) { for (int i=0; i