/***************************************************************************** * Web3d.org Copyright (c) 2001 * Java Source * * This source is licensed under the GNU LGPL v2.1 * Please read http://www.gnu.org/copyleft/lgpl.html for more information * * This software comes with the standard NO WARRANTY disclaimer for any * purpose. Use it at your own risk. If there's a problem you get to fix it. * ****************************************************************************/ // Standard library imports import javax.swing.*; import org.ietf.uri.*; import java.net.URL; import java.awt.BorderLayout; import java.awt.Container; import java.awt.Dimension; import java.io.File; import java.io.InputStream; import java.io.IOException; import java.net.MalformedURLException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import gl4java.GLCapabilities; import gl4java.GLContext; import gl4java.awt.GLAnimCanvas; import gl4java.drawable.GLDrawableFactory; // Application specific imports import org.web3d.vrml.sav.*; import org.web3d.vrml.nodes.*; import org.web3d.vrml.nodes.runtime.*; import org.web3d.vrml.nodes.loader.*; import org.web3d.browser.BrowserCore; import org.web3d.vrml.lang.VRMLException; import org.web3d.vrml.lang.VRMLExecutionSpace; import org.web3d.vrml.lang.TypeConstants; import org.web3d.vrml.parser.VRMLParserFactory; import org.web3d.vrml.parser.FactoryConfigurationError; import org.web3d.vrml.renderer.common.input.LinkSelectionListener; import org.web3d.vrml.renderer.common.input.NavigationStateListener; import org.web3d.vrml.renderer.ogl.OGLSceneBuilderFactory; import org.web3d.vrml.renderer.ogl.browser.OGLVRMLUniverse; import org.web3d.vrml.renderer.ogl.browser.PerFrameManager; import org.web3d.vrml.renderer.ogl.input.DefaultSensorManager; import org.web3d.vrml.renderer.ogl.input.OGLSensorManager; import org.web3d.vrml.renderer.ogl.nodes.OGLViewpointNodeType; import org.web3d.vrml.renderer.ogl.nodes.OGLVRMLNode; import org.web3d.vrml.renderer.ogl.sg.SGManager; import org.web3d.vrml.scripting.ScriptEngine; import org.web3d.vrml.scripting.jsai.VRML97ScriptEngine; import org.web3d.vrml.scripting.ecmascript.ECMAScriptEngine; /** * A demonstration application that shows how to put together all of the * Xj3D toolkit into a browser application using the OpenGL renderer. *
* * The simple browser does not respond to changes in the list of viewpoints * in the virtual world. This is OK because scripts are not used or needed in * this simple environment. Once we implement scripts, we have to look at * something different. * * @author Justin Couch * @version $Revision: 1.1.1.1 $ */ public class OGLBrowser extends DemoFrame implements LinkSelectionListener { /** The universe to place our scene into */ private OGLVRMLUniverse universe; /** The scene manager used for this node */ private SGManager sceneManager; /** Flag to indicate we are in the setup of the scene currently */ private boolean inSetup; /** Mapping of def'd Viewpoints to their real implementation */ private HashMap viewpointDefMap; /** The current viewpoint model */ private VRMLViewpointNodeType currentViewpoint; /** Place for error messages to go */ private ConsoleWindow console; /** Global clock */ private VRMLClock clock; /** World load manager to help us load files */ private WorldLoaderManager worldLoader; /** The GL drawable for this window */ private GLAnimCanvas canvas; /** * Create an instance of the demo class. */ public OGLBrowser() { super("OpenGL DIY VRML Browser"); JPopupMenu.setDefaultLightWeightPopupEnabled(false); viewpointDefMap = new HashMap(); OGLSceneBuilderFactory builder_fac = new OGLSceneBuilderFactory(false, true, true, true, true, true, true); VRMLParserFactory parser_fac = null; try { parser_fac = VRMLParserFactory.newVRMLParserFactory(); } catch(FactoryConfigurationError fce) { throw new RuntimeException("Failed to load factory"); } Container content_pane = getContentPane(); JPanel p1 = new JPanel(new BorderLayout()); content_pane.add(p1, BorderLayout.CENTER); console = new ConsoleWindow(); // We also need a canvas to display stuff with and a universe to set // the content in. if(!GLContext.doLoadNativeLibraries(null, null, null)) { System.out.println("Unable to load native library"); throw new RuntimeException(); } GLCapabilities caps = new GLCapabilities(); GLDrawableFactory fac = GLDrawableFactory.getFactory(); canvas = fac.createGLAnimCanvas(caps, 100, 100); sceneManager = new SGManager(canvas); sceneManager.setMinimumFrameCycleTime(15); AWTListenerEventBuffer i_buf = new AWTListenerEventBuffer(); canvas.addMouseListener(i_buf); canvas.addMouseMotionListener(i_buf); canvas.addKeyListener(i_buf); canvas.setUseFpsSleep(false); canvas.setUseRepaint(false); // ExternalLoadManager lm = new SimpleLoadManager(); ExternalLoadManager load_manager = new MemCacheLoadManager(); ScriptLoader script_loader = new DefaultScriptLoader(); ScriptManager script_manager = new DefaultScriptManager(); script_manager.setScriptLoader(script_loader); FrameStateManager state_manager = new GeneralisedFrameStateManager(); OGLSensorManager sensor_manager = new DefaultSensorManager(); sensor_manager.setInputBuffer(i_buf); RouteManager route_manager = new DefaultRouteManager(); // route_manager.setRouterFactory(new SimpleRouterFactory()); route_manager.setRouterFactory(new ListsRouterFactory()); worldLoader = new DefaultWorldLoaderManager(state_manager); worldLoader.setErrorReporter(console); worldLoader.registerBuilderFactory(BrowserCore.OPENGL_RENDERER, builder_fac); worldLoader.registerParserFactory(BrowserCore.OPENGL_RENDERER, parser_fac); EventModelEvaluator event_model = new GeneralisedEventModelEvaluator(); event_model.initialize(script_manager, route_manager, sensor_manager, state_manager, load_manager); event_model.setErrorReporter(console); universe = new OGLVRMLUniverse(event_model, sceneManager); universe.setLinkSelectionListener(this); clock = universe.getVRMLClock(); ScriptEngine jsai = new VRML97ScriptEngine(universe, route_manager, worldLoader); jsai.setErrorReporter(console); ScriptEngine ecma = new ECMAScriptEngine(universe, route_manager, worldLoader); ecma.setErrorReporter(console); script_loader.registerScriptingEngine(jsai); script_loader.registerScriptingEngine(ecma); p1.add(canvas, BorderLayout.CENTER); JPanel p2 = new JPanel(new BorderLayout()); p1.add(p2, BorderLayout.SOUTH); // universe.setNavigationStateListener(navToolbar); universe.setLinkSelectionListener(this); setupProperties(universe, worldLoader); console.setVisible(true); DownloadProgressListener dl_list = new DownloadProgressListener(statusLabel, console); ResourceConnection.addGlobalProgressListener(dl_list); } //---------------------------------------------------------- // Methods required by the LinkSelectionListener interface. //---------------------------------------------------------- /** * Invoked when a link node has been activated. This is the node that has * been selected. * * @param node The selected node */ public void linkSelected(VRMLLinkNodeType node) { String[] url_list = node.getUrl(); boolean success = false; for(int i = 0; i < url_list.length; i++) { if(url_list[i].charAt(0) == '#') { // move to the viewpoint. String def_name = url_list[i].substring(1); VRMLViewpointNodeType vp = (VRMLViewpointNodeType)viewpointDefMap.get(def_name); if(vp != null) { double time = clock.getTime(); if(currentViewpoint != null) currentViewpoint.setBind(false, true, time); vp.setBind(true, true, time); currentViewpoint = vp; } else { statusLabel.setText("Unknown Viewpoint " + def_name); console.warningReport("Unknown Viewpoint " + def_name, null); } } else { // load the world. try { URL url = new URL(url_list[i]); InputSource is = new InputSource(url); if(success = load(is)) break; } catch(MalformedURLException mue) { statusLabel.setText("Invalid URL"); console.warningReport("Invalid URL: " + url_list[i], mue); } } } if(!success) console.errorReport("No valid URLs were found", null); } //---------------------------------------------------------- // Implmentation of base class abstract methods //---------------------------------------------------------- /** * Go to the named URL location. No checking is done other than to make * sure it is a valid URL. * * @param url The URL to open */ public void gotoLocation(URL url) { InputSource is = new InputSource(url); load(is); } /** * Load the named file. The file is checked to make sure that it exists * before calling this method. * * @param file The file to load */ public void gotoLocation(File file) { InputSource is = new InputSource(file); load(is); } protected void setWarning(String msg) { statusLabel.setText(msg); console.warningReport(msg, null); } protected void setError(String msg) { statusLabel.setText(msg); console.errorReport(msg, null); } /** * When the browser is shown, start the canvas */ public void setVisible(boolean shown) { super.setVisible(shown); if(shown) { canvas.repaint(); canvas.start(); } else { canvas.stop(); } } //---------------------------------------------------------- // Local convenience methods //---------------------------------------------------------- /** * Do all the parsing work. Convenience method for all to call internally * * @param is The inputsource for this reader * @return true if the world loaded correctly */ private boolean load(InputSource is) { inSetup = true; boolean ret_val = false; WorldLoader loader = worldLoader.fetchLoader(); VRMLScene parsed_scene = null; try { parsed_scene = loader.loadNow(universe, is); } catch(Exception e) { e.printStackTrace(); console.errorReport("Failed to load ", e); worldLoader.releaseLoader(loader); return false; } worldLoader.releaseLoader(loader); universe.setScene(parsed_scene); ret_val = true; inSetup = false; return ret_val; } /** * Create an instance of this class and run it. The single argument, if * supplied is the name of the file to load initially. If not supplied it * will start with a blank document. * * @param argv The list of arguments for this application. */ public static void main(String[] argv) { try { OGLBrowser browser = new OGLBrowser(); browser.setVisible(true); } catch(RuntimeException re) { re.printStackTrace(); } } }