From 64fe2ea6568c9399ac92927baf59694f61bbe6e3 Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Fri, 22 Oct 2010 16:50:32 +0000 Subject: [PATCH] JME is kind of an evolutionary dead end, so we're going to move all the JME code into the Bang project directly so as to confine the dependencies on JME libraries to the only thing that will ever need them. git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@1035 ed5b42cb-e716-0410-a449-f6a68f950b19 --- .classpath | 8 +- build.xml | 5 - etc/depends-incl.xml | 15 - etc/libs-incl.xml | 9 +- rsrc/media/jme/defaultfont.tga | Bin 197147 -> 0 bytes rsrc/media/jme/skin.frag | 56 - rsrc/media/jme/skin.vert | 67 - src/java/com/threerings/jme/JmeApp.java | 600 --------- src/java/com/threerings/jme/JmeCanvasApp.java | 202 --- src/java/com/threerings/jme/JmeContext.java | 59 - src/java/com/threerings/jme/Log.java | 33 - src/java/com/threerings/jme/StatsDisplay.java | 83 -- .../threerings/jme/camera/CameraHandler.java | 412 ------ .../com/threerings/jme/camera/CameraPath.java | 67 - .../threerings/jme/camera/GodViewHandler.java | 202 --- .../com/threerings/jme/camera/PanPath.java | 87 -- .../com/threerings/jme/camera/SplinePath.java | 111 -- .../com/threerings/jme/camera/SwingPath.java | 167 --- .../com/threerings/jme/camera/rotate_zoom.dia | Bin 1672 -> 0 bytes .../com/threerings/jme/camera/rotate_zoom.png | Bin 12816 -> 0 bytes .../com/threerings/jme/chat/ChatView.java | 203 --- .../jme/effect/FadeInOutEffect.java | 147 -- .../threerings/jme/effect/WindowSlider.java | 157 --- .../jme/model/BillboardController.java | 177 --- .../jme/model/EmissionController.java | 97 -- src/java/com/threerings/jme/model/Model.java | 1194 ----------------- .../threerings/jme/model/ModelController.java | 188 --- .../com/threerings/jme/model/ModelMesh.java | 904 ------------- .../com/threerings/jme/model/ModelNode.java | 414 ------ .../threerings/jme/model/ModelSpatial.java | 97 -- .../com/threerings/jme/model/Rotator.java | 109 -- .../com/threerings/jme/model/SkinMesh.java | 760 ----------- .../threerings/jme/model/TextureAnimator.java | 157 --- .../jme/model/TextureController.java | 95 -- .../threerings/jme/model/TextureProvider.java | 39 - .../jme/model/TextureTranslator.java | 122 -- .../com/threerings/jme/model/Translator.java | 130 -- src/java/com/threerings/jme/package.html | 15 - .../threerings/jme/sprite/BallisticPath.java | 92 -- .../jme/sprite/CubicSplinePath.java | 188 --- .../com/threerings/jme/sprite/LinePath.java | 60 - .../jme/sprite/LineSegmentPath.java | 103 -- .../jme/sprite/OrientingBallisticPath.java | 70 - src/java/com/threerings/jme/sprite/Path.java | 51 - .../threerings/jme/sprite/PathObserver.java | 44 - .../com/threerings/jme/sprite/PathUtil.java | 95 -- .../com/threerings/jme/sprite/Sprite.java | 244 ---- .../threerings/jme/sprite/SpriteObserver.java | 29 - .../jme/tile/FringeConfiguration.java | 163 --- .../com/threerings/jme/tile/TileFringer.java | 406 ------ .../tools/CompileFringeConfigurationTask.java | 75 -- .../tools/xml/FringeConfigurationParser.java | 82 -- .../threerings/jme/tools/AnimationDef.java | 212 --- .../threerings/jme/tools/BuildSphereMap.java | 164 --- .../jme/tools/BuildSphereMapTask.java | 86 -- .../threerings/jme/tools/CompileModel.java | 167 --- .../jme/tools/CompileModelTask.java | 87 -- .../threerings/jme/tools/ConvertModel.java | 100 -- .../jme/tools/ConvertModelTask.java | 136 -- .../com/threerings/jme/tools/ModelDef.java | 1031 -------------- .../com/threerings/jme/tools/ModelViewer.java | 1142 ---------------- .../jme/tools/xml/AnimationParser.java | 88 -- .../threerings/jme/tools/xml/ModelParser.java | 109 -- .../com/threerings/jme/util/BatchVisitor.java | 49 - .../com/threerings/jme/util/ImageCache.java | 410 ------ src/java/com/threerings/jme/util/JmeUtil.java | 186 --- .../jme/util/LinearTimeFunction.java | 42 - .../com/threerings/jme/util/ShaderCache.java | 263 ---- .../com/threerings/jme/util/ShaderConfig.java | 394 ------ .../threerings/jme/util/SpatialVisitor.java | 63 - .../com/threerings/jme/util/TimeFunction.java | 99 -- .../com/threerings/jme/JmeCanvasTestApp.java | 62 - .../com/threerings/jme/client/JabberApp.java | 161 --- .../threerings/jme/client/JabberClient.java | 238 ---- .../jme/client/JabberController.java | 19 - .../com/threerings/jme/client/JabberView.java | 50 - .../com/threerings/jme/data/JabberConfig.java | 27 - .../threerings/jme/server/JabberServer.java | 46 - .../threerings/jme/sprite/PathTestApp.java | 149 -- 79 files changed, 5 insertions(+), 14465 deletions(-) delete mode 100644 rsrc/media/jme/defaultfont.tga delete mode 100644 rsrc/media/jme/skin.frag delete mode 100644 rsrc/media/jme/skin.vert delete mode 100644 src/java/com/threerings/jme/JmeApp.java delete mode 100644 src/java/com/threerings/jme/JmeCanvasApp.java delete mode 100644 src/java/com/threerings/jme/JmeContext.java delete mode 100644 src/java/com/threerings/jme/Log.java delete mode 100644 src/java/com/threerings/jme/StatsDisplay.java delete mode 100644 src/java/com/threerings/jme/camera/CameraHandler.java delete mode 100644 src/java/com/threerings/jme/camera/CameraPath.java delete mode 100644 src/java/com/threerings/jme/camera/GodViewHandler.java delete mode 100644 src/java/com/threerings/jme/camera/PanPath.java delete mode 100644 src/java/com/threerings/jme/camera/SplinePath.java delete mode 100644 src/java/com/threerings/jme/camera/SwingPath.java delete mode 100644 src/java/com/threerings/jme/camera/rotate_zoom.dia delete mode 100644 src/java/com/threerings/jme/camera/rotate_zoom.png delete mode 100644 src/java/com/threerings/jme/chat/ChatView.java delete mode 100644 src/java/com/threerings/jme/effect/FadeInOutEffect.java delete mode 100644 src/java/com/threerings/jme/effect/WindowSlider.java delete mode 100644 src/java/com/threerings/jme/model/BillboardController.java delete mode 100644 src/java/com/threerings/jme/model/EmissionController.java delete mode 100644 src/java/com/threerings/jme/model/Model.java delete mode 100644 src/java/com/threerings/jme/model/ModelController.java delete mode 100644 src/java/com/threerings/jme/model/ModelMesh.java delete mode 100644 src/java/com/threerings/jme/model/ModelNode.java delete mode 100644 src/java/com/threerings/jme/model/ModelSpatial.java delete mode 100644 src/java/com/threerings/jme/model/Rotator.java delete mode 100644 src/java/com/threerings/jme/model/SkinMesh.java delete mode 100644 src/java/com/threerings/jme/model/TextureAnimator.java delete mode 100644 src/java/com/threerings/jme/model/TextureController.java delete mode 100644 src/java/com/threerings/jme/model/TextureProvider.java delete mode 100644 src/java/com/threerings/jme/model/TextureTranslator.java delete mode 100644 src/java/com/threerings/jme/model/Translator.java delete mode 100644 src/java/com/threerings/jme/package.html delete mode 100644 src/java/com/threerings/jme/sprite/BallisticPath.java delete mode 100644 src/java/com/threerings/jme/sprite/CubicSplinePath.java delete mode 100644 src/java/com/threerings/jme/sprite/LinePath.java delete mode 100644 src/java/com/threerings/jme/sprite/LineSegmentPath.java delete mode 100644 src/java/com/threerings/jme/sprite/OrientingBallisticPath.java delete mode 100644 src/java/com/threerings/jme/sprite/Path.java delete mode 100644 src/java/com/threerings/jme/sprite/PathObserver.java delete mode 100644 src/java/com/threerings/jme/sprite/PathUtil.java delete mode 100644 src/java/com/threerings/jme/sprite/Sprite.java delete mode 100644 src/java/com/threerings/jme/sprite/SpriteObserver.java delete mode 100644 src/java/com/threerings/jme/tile/FringeConfiguration.java delete mode 100644 src/java/com/threerings/jme/tile/TileFringer.java delete mode 100644 src/java/com/threerings/jme/tile/tools/CompileFringeConfigurationTask.java delete mode 100644 src/java/com/threerings/jme/tile/tools/xml/FringeConfigurationParser.java delete mode 100644 src/java/com/threerings/jme/tools/AnimationDef.java delete mode 100644 src/java/com/threerings/jme/tools/BuildSphereMap.java delete mode 100644 src/java/com/threerings/jme/tools/BuildSphereMapTask.java delete mode 100644 src/java/com/threerings/jme/tools/CompileModel.java delete mode 100644 src/java/com/threerings/jme/tools/CompileModelTask.java delete mode 100644 src/java/com/threerings/jme/tools/ConvertModel.java delete mode 100644 src/java/com/threerings/jme/tools/ConvertModelTask.java delete mode 100644 src/java/com/threerings/jme/tools/ModelDef.java delete mode 100644 src/java/com/threerings/jme/tools/ModelViewer.java delete mode 100644 src/java/com/threerings/jme/tools/xml/AnimationParser.java delete mode 100644 src/java/com/threerings/jme/tools/xml/ModelParser.java delete mode 100644 src/java/com/threerings/jme/util/BatchVisitor.java delete mode 100644 src/java/com/threerings/jme/util/ImageCache.java delete mode 100644 src/java/com/threerings/jme/util/JmeUtil.java delete mode 100644 src/java/com/threerings/jme/util/LinearTimeFunction.java delete mode 100644 src/java/com/threerings/jme/util/ShaderCache.java delete mode 100644 src/java/com/threerings/jme/util/ShaderConfig.java delete mode 100644 src/java/com/threerings/jme/util/SpatialVisitor.java delete mode 100644 src/java/com/threerings/jme/util/TimeFunction.java delete mode 100644 tests/src/java/com/threerings/jme/JmeCanvasTestApp.java delete mode 100644 tests/src/java/com/threerings/jme/client/JabberApp.java delete mode 100644 tests/src/java/com/threerings/jme/client/JabberClient.java delete mode 100644 tests/src/java/com/threerings/jme/client/JabberController.java delete mode 100644 tests/src/java/com/threerings/jme/client/JabberView.java delete mode 100644 tests/src/java/com/threerings/jme/data/JabberConfig.java delete mode 100644 tests/src/java/com/threerings/jme/server/JabberServer.java delete mode 100644 tests/src/java/com/threerings/jme/sprite/PathTestApp.java diff --git a/.classpath b/.classpath index ab1559e9..026b971f 100644 --- a/.classpath +++ b/.classpath @@ -1,14 +1,14 @@ - - + + - - + + diff --git a/build.xml b/build.xml index de051199..9856ff47 100644 --- a/build.xml +++ b/build.xml @@ -73,7 +73,6 @@ - @@ -219,10 +218,6 @@ - - - - diff --git a/etc/depends-incl.xml b/etc/depends-incl.xml index 780b7b93..5000f979 100644 --- a/etc/depends-incl.xml +++ b/etc/depends-incl.xml @@ -9,14 +9,6 @@ classname="org.lwjgl.LWJGLException" classpathref="classpath"/> - - - - - - @@ -29,13 +21,6 @@ classname="com.megginson.sax.DataWriter" classpathref="classpath"/> - - - - - - - diff --git a/etc/libs-incl.xml b/etc/libs-incl.xml index 523fc5f3..6f6bbedf 100644 --- a/etc/libs-incl.xml +++ b/etc/libs-incl.xml @@ -18,16 +18,9 @@ - + - - - - - - - diff --git a/rsrc/media/jme/defaultfont.tga b/rsrc/media/jme/defaultfont.tga deleted file mode 100644 index 563b0968b2b70fd70be532d01c577b50ae217721..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 197147 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 zEz|?*6!Presents networking system and - * targeting the framerate of the display. - */ -public class JmeApp - implements RunQueue -{ - /** - * Returns a context implementation that provides access to all the - * necessary bits. - */ - public JmeContext getContext () - { - return _ctx; - } - - /** - * Does the main initialization of the application. This method should - * be called first, and then the {@link #run} method should be called - * to begin the rendering/event loop. Derived classes can override - * this, being sure to call super before doing their own - * initalization. - * - * @return true if the application initialized successfully, false if - * initialization failed. (See {@link #reportInitFailure}.) - */ - public boolean init () - { - try { - // initialize the rendering system - initDisplay(); - if (!_display.isCreated()) { - throw new IllegalStateException( - "Failed to initialize display?"); - } - - // create an appropriate timer - _timer = Timer.getTimer(); - - // start with the target FPS equal to the refresh rate (but - // sometimes the refresh rate is reported as zero so don't let that - // freak us out) - setTargetFPS(Math.max(_display.getFrequency(), 60)); - - // initialize our main camera controls and user input handling - initInput(); - - // initialize the root node - initRoot(); - - // initialize the lighting - initLighting(); - - // initialize the UI support stuff - initInterface(); - - // update everything for the zeroth tick - _iface.updateRenderState(); - _geom.updateRenderState(); - _root.updateGeometricState(0f, true); - _root.updateRenderState(); - - return true; - - } catch (Throwable t) { - reportInitFailure(t); - return false; - } - } - - /** - * Configures whether or not we display FPS and other statistics atop the - * display. - */ - public void displayStatistics (boolean display) - { - if (display && (_stats == null)) { - _stats = new StatsDisplay(_display.getRenderer()); - _stats.updateGeometricState(0f, true); - _stats.updateRenderState(); - } else if (!display && (_stats != null)) { - _stats = null; - } - } - - /** - * Returns true if we are displaying statistics, false if not. - */ - public boolean showingStatistics () - { - return (_stats != null); - } - - /** - * Sets the target frames per second. - * - * @return the old target frames per second. - */ - public int setTargetFPS (int targetFPS) - { - int oldTargetFPS = _targetFPS; - _targetFPS = targetFPS; - _ticksPerFrame = _timer.getResolution() / _targetFPS; - return oldTargetFPS; - } - - /** - * Returns the frames per second averaged over the last 32 frames. - */ - public float getRecentFrameRate () - { - return _timer.getFrameRate(); - } - - /** - * Enables or disables the update and render part of the - * update/render/process events application loop. - */ - public void setEnabled (boolean update, boolean render) - { - _updateEnabled = update; - _renderEnabled = render; - } - - /** - * Starts up the main rendering and event processing loop. This method - * will not return until the application is terminated with a call to - * {@link #stop}. - */ - public void run () - { - synchronized (this) { - _dispatchThread = Thread.currentThread(); - } - - // enter the main rendering and event processing loop - while (!_finished) { - try { - // render the current frame - long frameStart = processFrame(); - - // and process events until it's time to render the next - PROCESS_EVENTS: - do { - Runnable r = _evqueue.getNonBlocking(); - if (r != null) { - r.run(); - } - if (_timer.getTime() - frameStart >= _ticksPerFrame) { - break PROCESS_EVENTS; - } else { - try { - Thread.sleep(1); - } catch (InterruptedException ie) { - } - } - } while (!_finished); - _failures = 0; - - } catch (Throwable t) { - log.warning(t); - // stick a fork in things if we fail too many times in a row - if (++_failures > MAX_SUCCESSIVE_FAILURES) { - stop(); - } - } - if (_display.isClosing()) { - stop(); - } - } - - try { - cleanup(); - } catch (Throwable t) { - log.warning(t); - } finally { - exit(); - } - } - - /** - * Returns the duration (in seconds) between the previous frame and the - * current frame. - */ - public float getFrameTime () - { - return _frameTime; - } - - /** - * Instructs the application to stop the main loop, cleanup and exit. - */ - public void stop () - { - _finished = true; - } - - // from interface RunQueue - public void postRunnable (Runnable r) - { - _evqueue.append(r); - } - - // from interface RunQueue - public boolean isDispatchThread () - { - return Thread.currentThread() == _dispatchThread; - } - - // from interface RunQueue - public boolean isRunning () - { - return !_finished; - } - - /** - * Determines the display configuration and creates the display. This must - * fill in {@link #_api} as a side-effect. - */ - protected DisplaySystem createDisplay () - throws JmeException - { - PropertiesIO props = new PropertiesIO(getConfigPath("jme.cfg")); - if (!props.load()) { - LWJGLPropertiesDialog dialog = - new LWJGLPropertiesDialog(props, (String)null); - while (dialog.isVisible()) { - try { - Thread.sleep(5); - } catch (InterruptedException e) { - log.warning("Error waiting for dialog system, " + - "using defaults."); - } - } - } - _api = props.getRenderer(); - DisplaySystem display = DisplaySystem.getDisplaySystem(_api); - display.createWindow(props.getWidth(), props.getHeight(), - props.getDepth(), props.getFreq(), - props.getFullscreen()); - return display; - } - - /** - * Initializes the underlying rendering system, creating a display of - * the proper resolution and depth. - */ - protected void initDisplay () - throws JmeException - { - // create the main display system - _display = createDisplay(); - - // create a camera - int width = _display.getWidth(), height = _display.getHeight(); - _camera = _display.getRenderer().createCamera(width, height); - - // start with a black background - _display.getRenderer().setBackgroundColor(ColorRGBA.black); - - // enable all of the "quick compares," which means that states will - // be refreshed only when necessary - Arrays.fill(RenderState.QUICK_COMPARE, true); - - // set up the camera - _camera.setFrustumPerspective(45.0f, width/(float)height, 1, 10000); - Vector3f loc = new Vector3f(0.0f, 0.0f, 25.0f); - Vector3f left = new Vector3f(-1.0f, 0.0f, 0.0f); - Vector3f up = new Vector3f(0.0f, 1.0f, 0.0f); - Vector3f dir = new Vector3f(0.0f, 0f, -1.0f); - _camera.setFrame(loc, left, up, dir); - _camera.update(); - _display.getRenderer().setCamera(_camera); - - // tell the renderer to keep track of rendering information (total - // triangles drawn, etc.) - _display.getRenderer().enableStatistics(true); - } - - /** - * Sets up a main input controller to handle the camera and deal with - * global user input. - */ - protected void initInput () - { - _camhand = createCameraHandler(_camera); - _input = createInputHandler(_camhand); - } - - /** - * Creates the camera handler which provides various camera manipulation - * functionality. - */ - protected CameraHandler createCameraHandler (Camera camera) - { - return new CameraHandler(camera); - } - - /** - * Creates the input handler used to control our camera and manage non-UI - * keyboard input. - */ - protected InputHandler createInputHandler (CameraHandler hand) - { - return new InputHandler(); - } - - /** - * Creates our root node and sets up the basic rendering system. - */ - protected void initRoot () - { - _root = new Node("Root"); - - // set up a node for our geometry - _geom = new Node("Geometry"); - - // make everything opaque by default - _geom.setRenderQueueMode(Renderer.QUEUE_OPAQUE); - - // set up a zbuffer - ZBufferState zbuf = _display.getRenderer().createZBufferState(); - zbuf.setEnabled(true); - zbuf.setFunction(ZBufferState.CF_LEQUAL); - _geom.setRenderState(zbuf); - _root.attachChild(_geom); - } - - /** - * Sets up some default lighting. - */ - protected void initLighting () - { - PointLight light = new PointLight(); - light.setDiffuse(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f)); - light.setAmbient(new ColorRGBA(0.5f, 0.5f, 0.5f, 1.0f)); - light.setLocation(new Vector3f(100, 100, 100)); - light.setEnabled(true); - - _lights = _display.getRenderer().createLightState(); - _lights.setEnabled(true); - _lights.attach(light); - _geom.setRenderState(_lights); - } - - /** - * Initializes our user interface bits. - */ - protected void initInterface () - { - // set up a node for our interface - _iface = new Node("Interface"); - _root.attachChild(_iface); - - // create our root node - _rnode = createRootNode(); - _iface.attachChild(_rnode); - - // we don't hide the cursor - MouseInput.get().setCursorVisible(true); - } - - /** - * Allows a customized root node to be created. - */ - protected BRootNode createRootNode () - { - return new PolledRootNode(_timer, _input); - } - - /** - * Called when initialization fails to give the application a chance - * to report the failure to the user. - */ - protected void reportInitFailure (Throwable t) - { - log.warning(t); - } - - /** - * Processes a single frame. - */ - protected final long processFrame () - { - // update our simulation and render a frame - long frameStart = _timer.getTime(); - if (_updateEnabled) { - update(frameStart); - } - if (_renderEnabled) { - render(frameStart); - _display.getRenderer().displayBackBuffer(); - } - return frameStart; - } - - /** - * Called every frame to update whatever sort of real time business we - * have that needs updating. - */ - protected void update (long frameTick) - { - // recalculate the frame rate - _timer.update(); - - // update the camera handler - _camhand.update(_frameTime); - - // run all of the controllers attached to nodes - _frameTime = (_lastTick == 0L) ? 0f : (float)(frameTick - _lastTick) / - _timer.getResolution(); - _lastTick = frameTick; - _root.updateGeometricState(_frameTime, true); - - // update our stats display if we have one - if (_stats != null) { - _stats.update(_timer, _display.getRenderer()); - } - } - - /** - * Called every frame to issue the rendering instructions for this frame. - */ - protected void render (float frameTime) - { - // clear out our previous information - _display.getRenderer().clearStatistics(); - _display.getRenderer().clearBuffers(); - - // draw the root node and all of its children - _display.getRenderer().draw(_root); - - // this would render bounding boxes - // _display.getRenderer().drawBounds(_root); - - // draw our stats atop everything - if (_stats != null) { - _display.getRenderer().draw(_stats); - } - } - - /** - * Called when the application is terminating cleanly after having - * successfully completed initialization and begun the main loop. - */ - protected void cleanup () - { - _display.reset(); - KeyInput.destroyIfInitalized(); - MouseInput.destroyIfInitalized(); - } - - /** - * Closes the display and exits the JVM process. - */ - protected void exit () - { - if (_display != null) { - _display.close(); - } - System.exit(0); - } - - /** - * Prepends the necessary bits onto the supplied path to properly - * locate it in our configuration directory. - */ - protected String getConfigPath (String file) - { - String cfgdir = ".narya"; - String home = System.getProperty("user.home"); - if (!StringUtil.isBlank(home)) { - cfgdir = home + File.separator + cfgdir; - } - // create the configuration directory if it does not already exist - File dir = new File(cfgdir); - if (!dir.exists()) { - dir.mkdir(); - } - return cfgdir + File.separator + file; - } - - /** Provides access to various needed bits. */ - protected JmeContext _ctx = new JmeContext() { - public DisplaySystem getDisplay () { - return _display; - } - - public Renderer getRenderer () { - return _display.getRenderer(); - } - - public CameraHandler getCameraHandler () { - return _camhand; - } - - public Node getGeometry () { - return _geom; - } - - public Node getInterface () { - return _iface; - } - - public InputHandler getInputHandler () { - return _input; - } - - public BRootNode getRootNode () { - return _rnode; - } - }; - - protected Timer _timer; - protected Thread _dispatchThread; - protected Queue _evqueue = Queue.newQueue(); - protected long _lastTick; - protected float _frameTime; - - protected String _api; - protected DisplaySystem _display; - protected Camera _camera; - protected CameraHandler _camhand; - - protected InputHandler _input; - protected BRootNode _rnode; - - protected long _ticksPerFrame; - protected int _targetFPS; - protected boolean _updateEnabled = true, _renderEnabled = true; - protected boolean _finished; - protected int _failures; - - protected Node _root, _geom, _iface; - protected LightState _lights; - protected StatsDisplay _stats; - - /** If we fail 100 frames in a row, stick a fork in ourselves. */ - protected static final int MAX_SUCCESSIVE_FAILURES = 100; -} diff --git a/src/java/com/threerings/jme/JmeCanvasApp.java b/src/java/com/threerings/jme/JmeCanvasApp.java deleted file mode 100644 index fe1b9c8a..00000000 --- a/src/java/com/threerings/jme/JmeCanvasApp.java +++ /dev/null @@ -1,202 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme; - -import java.awt.AWTEvent; -import java.awt.Canvas; -import java.awt.Graphics; -import java.awt.EventQueue; -import java.awt.event.ComponentAdapter; -import java.awt.event.ComponentEvent; - -import org.lwjgl.LWJGLException; - -import com.jme.renderer.lwjgl.LWJGLRenderer; -import com.jme.scene.Node; -import com.jme.system.DisplaySystem; -import com.jmex.awt.JMECanvas; -import com.jmex.awt.JMECanvasImplementor; -import com.jmex.awt.lwjgl.LWJGLCanvas; - -import com.jmex.bui.CanvasRootNode; - -import static com.threerings.jme.Log.log; - -/** - * Extends the basic {@link JmeApp} with the necessary wiring to use the - * GL/AWT bridge to display our GL interface in an AWT component. - */ -public class JmeCanvasApp extends JmeApp -{ - public JmeCanvasApp (int width, int height) - { - _display = DisplaySystem.getDisplaySystem("LWJGL"); - - // create a throwaway canvas so that the display system knows it's - // created, then create our custom canvas - _display.createCanvas(width, height); - try { - _canvas = createCanvas(); - } catch (LWJGLException e) { - log.warning("Failed to create LWJGL canvas [error=" + e + "]."); - } - ((JMECanvas)_canvas).setImplementor(_winimp); - _canvas.setBounds(0, 0, width, height); - _canvas.addComponentListener(new ComponentAdapter() { - public void componentResized (ComponentEvent ce) { - _winimp.resizeCanvas(_canvas.getWidth(), _canvas.getHeight()); - } - }); - } - - /** - * Returns the AWT canvas that contains our GL display. - */ - public Canvas getCanvas () - { - return _canvas; - } - - public void run () - { - Thread t = new Thread() { - public void run () { - while (!_finished) { - // queue up another repaint - _canvas.repaint(); - try { - Thread.sleep(10); - } catch (Exception e) { - } - } - } - }; - t.setDaemon(true); - t.start(); - } - - // documentation inherited from interface RunQueue - public void postRunnable (Runnable r) - { - EventQueue.invokeLater(r); - } - - // documentation inherited from interface RunQueue - public boolean isDispatchThread () - { - return EventQueue.isDispatchThread(); - } - - /** - * Creates and returns the LWJGL canvas instance. - */ - protected Canvas createCanvas () - throws LWJGLException - { - // LWJGL's canvas releases the context after painting. we make it - // current again, because we want it valid when we process events. - // block mouse and keyboard events until the context is valid. - return new LWJGLCanvas() { - public void addNotify () { - super.addNotify(); - disableEvents(MOUSE_KEY_EVENT_MASK); - } - public void update (Graphics g) { - super.update(g); - try { - makeCurrent(); - } catch (LWJGLException e) { - log.warning("Failed to make context current [error=" + - e + "]."); - } - } - protected void initGL () { - super.initGL(); - enableEvents(MOUSE_KEY_EVENT_MASK); - } - }; - } - - // documentation inherited - protected DisplaySystem createDisplay () - { - // we've already created our display earlier so just return it - _api = "LWJGL"; - return _display; - } - - // documentation inherited - protected void initInterface () - { - _iface = new Node("Interface"); - _root.attachChild(_iface); - - _rnode = new CanvasRootNode(_canvas); - _iface.attachChild(_rnode); - } - - /** This is used if we embed our GL display in an AWT component. */ - protected JMECanvasImplementor _winimp = new JMECanvasImplementor() { - public void doSetup () { - super.doSetup(); - - LWJGLRenderer renderer = - new LWJGLRenderer(_canvas.getWidth(), _canvas.getHeight()); - renderer.setHeadless(true); - setRenderer(renderer); - _display.setRenderer(renderer); - _display.getCurrentContext().setupRecords(renderer); - DisplaySystem.updateStates(renderer); - - if (!init()) { - log.warning("JmeCanvasApp init failed."); - } - } - - public void doUpdate () { - } - - public void doRender () { - // here we do our normal frame processing - try { - processFrame(); - // we don't process events as the AWT queue handles them - _failures = 0; - } catch (Throwable t) { - log.warning(t); - // stick a fork in things if we fail too many - // times in a row - if (++_failures > MAX_SUCCESSIVE_FAILURES) { - JmeCanvasApp.this.stop(); - } - } - } - }; - - protected Canvas _canvas; - - protected static final long MOUSE_KEY_EVENT_MASK = - AWTEvent.MOUSE_EVENT_MASK | - AWTEvent.MOUSE_MOTION_EVENT_MASK | - AWTEvent.MOUSE_WHEEL_EVENT_MASK | - AWTEvent.KEY_EVENT_MASK; -} diff --git a/src/java/com/threerings/jme/JmeContext.java b/src/java/com/threerings/jme/JmeContext.java deleted file mode 100644 index f5640710..00000000 --- a/src/java/com/threerings/jme/JmeContext.java +++ /dev/null @@ -1,59 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme; - -import com.jme.input.InputHandler; -import com.jme.renderer.Renderer; -import com.jme.scene.Node; -import com.jme.system.DisplaySystem; - -import com.jmex.bui.BRootNode; - -import com.threerings.jme.camera.CameraHandler; - -/** - * Provides access to the various bits needed by things that operate in - * JME land. - */ -public interface JmeContext -{ - /** Returns the display to which we are rendering. */ - public DisplaySystem getDisplay (); - - /** Returns the renderer being used to draw everything. */ - public Renderer getRenderer (); - - /** Returns the handler for the camera being used to view the scene. */ - public CameraHandler getCameraHandler (); - - /** Returns the main geometry of our scene graph. */ - public Node getGeometry (); - - /** Returns the main interface node of our scene graph. */ - public Node getInterface (); - - /** Returns our main input handler. */ - public InputHandler getInputHandler (); - - /** Returns our UI root node. */ - public BRootNode getRootNode (); -} diff --git a/src/java/com/threerings/jme/Log.java b/src/java/com/threerings/jme/Log.java deleted file mode 100644 index 79ddc4f1..00000000 --- a/src/java/com/threerings/jme/Log.java +++ /dev/null @@ -1,33 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme; - -import com.samskivert.util.Logger; - -/** - * Contains a reference to the log object used by this package. - */ -public class Log -{ - /** We dispatch our log messages through this logger. */ - public static Logger log = Logger.getLogger("com.threerings.nenya.jme"); -} diff --git a/src/java/com/threerings/jme/StatsDisplay.java b/src/java/com/threerings/jme/StatsDisplay.java deleted file mode 100644 index 402e54a5..00000000 --- a/src/java/com/threerings/jme/StatsDisplay.java +++ /dev/null @@ -1,83 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme; - -import com.jme.image.Texture; -import com.jme.renderer.Renderer; -import com.jme.scene.Node; -import com.jme.scene.Text; -import com.jme.scene.state.AlphaState; -import com.jme.scene.state.TextureState; -import com.jme.util.TextureManager; -import com.jme.util.Timer; - -/** - * Tracks and displays render statistics. - */ -public class StatsDisplay extends Node -{ - public StatsDisplay (Renderer renderer) - { - super("StatsNode"); - - // create an alpha state that will allow us to blend the text on - // top of whatever else is below - AlphaState astate = renderer.createAlphaState(); - astate.setBlendEnabled(true); - astate.setSrcFunction(AlphaState.SB_SRC_ALPHA); - astate.setDstFunction(AlphaState.DB_ONE); - astate.setTestEnabled(true); - astate.setTestFunction(AlphaState.TF_GREATER); - astate.setEnabled(true); - - // create a font texture - TextureState font = renderer.createTextureState(); - font.setTexture( - TextureManager.loadTexture( - getClass().getClassLoader().getResource(DEFAULT_JME_FONT), - Texture.MM_LINEAR, Texture.FM_LINEAR)); - font.setEnabled(true); - - _text = new Text("StatsLabel", ""); - _text.setCullMode(CULL_NEVER); - _text.setTextureCombineMode(TextureState.REPLACE); - - attachChild(_text); - setRenderState(font); - setRenderState(astate); - } - - public void update (Timer timer, Renderer renderer) - { - _stats.setLength(0); - _stats.append("FPS: ").append((int)timer.getFrameRate()); - _stats.append(" - ").append(renderer.getStatistics(_temp)); - _text.print(_stats.toString()); - } - - protected Text _text; - protected StringBuilder _stats = new StringBuilder(); - protected StringBuffer _temp = new StringBuffer(); - - protected static final String DEFAULT_JME_FONT = - "rsrc/media/jme/defaultfont.tga"; -} diff --git a/src/java/com/threerings/jme/camera/CameraHandler.java b/src/java/com/threerings/jme/camera/CameraHandler.java deleted file mode 100644 index 47715826..00000000 --- a/src/java/com/threerings/jme/camera/CameraHandler.java +++ /dev/null @@ -1,412 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.camera; - -import com.jme.math.FastMath; -import com.jme.math.Matrix3f; -import com.jme.math.Plane; -import com.jme.math.Vector3f; -import com.jme.renderer.Camera; - -import com.samskivert.util.ObserverList; -import com.threerings.jme.JmeApp; - -/** - * Provides various useful mechanisms for manipulating the camera. - */ -public class CameraHandler -{ - /** - * Creates a new camera handler. The camera begins life at the origin, - * facing in the negative z direction (pointing at the ground). - */ - public CameraHandler (Camera camera) - { - _camera = camera; - resetAxes(); - } - - /** - * Resets the camera orientation to its initial state. - */ - public void resetAxes () - { - _camera.getDirection().set(0, 0, -1); - _camera.getLeft().set(-1, 0, 0); - _camera.getUp().set(0, 1, 0); - _camera.update(); - - _rxdir.set(1, 0, 0); - _rydir.set(0, 1, 0); - } - - /** - * Configures limits on the camera tilt. - */ - public void setTiltLimits (float minAngle, float maxAngle) - { - _minTilt = minAngle; - _maxTilt = maxAngle; - } - - /** - * Configures limits on the distance the camera can be panned. - * - * @param boundViaFrustum if true instead of bounding the camera's - * position, we will compute the intersections of the view frustum with the - * ground plan and bound that rectangle into the specified bounds. - * Note: the camera must generally be pointing down at the ground - * (up to perhaps 45 degrees or so) for this to work. At higher angles the - * back of the view frustum will intersect the ground plane at or near - * infinity. - */ - public void setPanLimits (float minX, float minY, float maxX, float maxY, - boolean boundViaFrustum) - { - _minX = minX; - _minY = minY; - _maxX = maxX; - _maxY = maxY; - _boundViaFrustum = boundViaFrustum; - } - - /** - * Configures the minimum and maximum zoom values allowed for the - * camera. - */ - public void setZoomLimits (float minZoom, float maxZoom) - { - _minZoom = minZoom; - _maxZoom = maxZoom; - } - - /** - * Enables or disables the current set of limits. - */ - public void setLimitsEnabled (boolean enabled) - { - _limitsEnabled = enabled; - } - - /** - * Sets the camera zoom level to a value between zero (zoomed in maximally) - * and 1 (zoomed out maximally). Zoom limits must have already been set up - * via a call to {@link #setZoomLimits}. - */ - public void setZoomLevel (float level) - { -// Log.info("Zoom " + level + " " + _camera.getLocation()); - level = Math.max(0f, Math.min(level, 1f)); - _camera.getLocation().z = _minZ + (_maxZ - _minZ) * level; - _camera.update(); - } - - /** - * Returns the current camera zoom level. - */ - public float getZoomLevel () - { - return (_camera.getLocation().z - _minZ) / (_maxZ - _minZ); - } - - /** - * Adds a camera path observer. - */ - public void addCameraObserver (CameraPath.Observer camobs) - { - _campathobs.add(camobs); - } - - /** - * Removes a camera path observer. - */ - public void removeCameraObserver (CameraPath.Observer camobs) - { - _campathobs.remove(camobs); - } - - /** - * Starts the camera moving along a path which will be updated every tick - * until it is complete. - */ - public void moveCamera (CameraPath path) - { - if (_campath != null) { - _campath.abort(); - _campathobs.apply(new CompletedOp(_campath)); - } - _campath = path; - } - - /** - * Returns true if the camera is currently animating along a path, false if - * it is not. - */ - public boolean cameraIsMoving () - { - return (_campath != null); - } - - /** - * Skips immediately to the end of the current camera path. - */ - public void skipPath () - { - // fake an update far enough into the future to trick the camera path - // into thinking it's done - update(100); - } - - /** - * This is called by the {@link JmeApp} on every frame to allow the handler - * to update the camera as necessary. - */ - public void update (float frameTime) - { - if (_campath != null) { - if (_campath.tick(frameTime)) { - CameraPath opath = _campath; - _campath = null; - _campathobs.apply(new CompletedOp(opath)); - } - } - } - - /** - * Returns the camera being manipulated by this handler. - */ - public Camera getCamera () - { - return _camera; - } - - /** - * Adjusts the camera's location. The specified location will be bounded - * within the current pan and zoom limits. - */ - public void setLocation (Vector3f location) - { - _camera.setLocation(bound(location)); - _camera.update(); - } - - /** - * Pans the camera the specified distance in the x and y directions. These - * distances will be multiplied by the current "view" x and y axes and - * added to the camera's position. - */ - public void panCamera (float x, float y) - { - Vector3f loc = _camera.getLocation(); - loc.addLocal(_rxdir.mult(x, _temp)); - loc.addLocal(_rydir.mult(y, _temp)); - setLocation(loc); - } - - /** - * Zooms the camera in (distance < 0) and out (distance > 0) by the - * specified amount. The distance is multiplied by the camera's current - * direction and added to its current position, which is then bounded into - * the pan and zoom volume. - */ - public void zoomCamera (float distance) - { - Vector3f loc = _camera.getLocation(); - float dist = getGroundPoint().distance(loc), - ndist = Math.min(Math.max(dist + distance, _minZoom), _maxZoom); - if ((distance = ndist - dist) == 0f) { - return; - } - loc.subtractLocal(_camera.getDirection().mult(distance, _temp)); - setLocation(loc); - } - - /** - * Locates the point on the ground at which the camera is "looking" and - * rotates the camera from that point around the specified vector by the - * specified angle. Additionally zooms the camera in (deltaZoom < 0) or out - * (deltaZoom > 0) along its direction of view by the specified amount. - */ - public void rotateCamera ( - Vector3f spot, Vector3f axis, float deltaAngle, float deltaZoom) - { - // get a vector from the camera's current position to the point around - // which we're going to orbit - Vector3f direction = _camera.getLocation().subtract(spot); - - // if we're rotating around the left vector, impose tilt limits - if (axis == _camera.getLeft()) { - float angle = FastMath.asin(_ground.normal.dot(direction) / - direction.length()); - float nangle = Math.min(Math.max(angle + deltaAngle, _minTilt), - _maxTilt); - if ((deltaAngle = nangle - angle) == 0f) { - return; - } - } - - // create a rotation matrix - _rotm.fromAngleAxis(deltaAngle, axis); - - // rotate the direction vector and the camera itself - _rotm.mult(direction, direction); - _rotm.mult(_camera.getUp(), _camera.getUp()); - _rotm.mult(_camera.getLeft(), _camera.getLeft()); - _rotm.mult(_camera.getDirection(), _camera.getDirection()); - - // if we're rotating around the ground normal, we need to update our - // notion of side-to-side and forward for panning - if (axis == _ground.normal) { - _rotm.mult(_rxdir, _rxdir); - _rotm.mult(_rydir, _rydir); - } - - // finally move the camera to its new location, zooming in or out in - // the process - float scale = 1 + (deltaZoom / direction.length()); - direction.scaleAdd(scale, spot); - setLocation(direction); - } - - /** - * Swings the camera perpendicular to the ground normal, around the point - * on the ground at which it is looking. - */ - public void orbitCamera (float deltaAngle) - { - rotateCamera(getGroundPoint(), _ground.normal, deltaAngle, 0); - } - - /** - * Swings the camera perpendicular to its left vector around the point on - * the ground at which it is looking. - */ - public void tiltCamera (float deltaAngle) - { - rotateCamera(getGroundPoint(), _camera.getLeft(), deltaAngle, 0); - } - - /** - * Returns the point on the ground (z = 0) at which the camera is looking. - */ - public Vector3f getGroundPoint () - { - float dist = -1f * _ground.normal.dot(_camera.getLocation()) / - _ground.normal.dot(_camera.getDirection()); - return _camera.getLocation().add(_camera.getDirection().mult(dist)); - } - - /** - * Returns the ground normal. Z is the default ground plane and the normal - * points in the positive z direction. Do not modify this value. - */ - public Vector3f getGroundNormal () - { - return _ground.normal; - } - - protected Vector3f bound (Vector3f loc) - { - if (!_limitsEnabled) { - return loc; - } - if (_boundViaFrustum) { - bound(_camera.getFrustumLeft(), _camera.getFrustumTop(), loc); - bound(_camera.getFrustumLeft(), _camera.getFrustumBottom(), loc); - bound(_camera.getFrustumRight(), _camera.getFrustumTop(), loc); - bound(_camera.getFrustumRight(), _camera.getFrustumBottom(), loc); - } else { - loc.x = Math.max(Math.min(loc.x, _maxX), _minX); - loc.y = Math.max(Math.min(loc.y, _maxY), _minY); - } - loc.z = Math.max(Math.min(loc.z, _maxZ), _minZ); - return loc; - } - - protected void bound (float left, float up, Vector3f loc) - { - // start with the location of the camera moved out into the near - // frustum plane - _temp.set(loc); - _temp.scaleAdd(_camera.getFrustumNear(), _camera.getDirection(), loc); - - // then slide it over to a corner of the near frustum rectangle - _temp.scaleAdd(left, _camera.getLeft(), _temp); - _temp.scaleAdd(up, _camera.getUp(), _temp); - - // turn this into a vector with origin at the camera's location - _temp.subtractLocal(loc); - _temp.normalizeLocal(); - - // determine the intersection of said vector with the ground plane - float dist = -1f * _ground.normal.dot(loc) / _ground.normal.dot(_temp); - _temp.scaleAdd(dist, _temp, loc); - - // we then assume that if the corner of the "viewable ground rectangle" - // is outside our bounds that we can simply adjust the camera location - // by the amount it is out of bounds - if (_temp.x > _maxX) { - loc.x -= (_temp.x - _maxX); - } else if (_temp.x < _minX) { - loc.x += (_minX - _temp.x); - } - if (_temp.y > _maxY) { - loc.y -= (_temp.y - _maxY); - } else if (_temp.y < _minY) { - loc.y += (_minY - _temp.y); - } - } - - /** Used to dispatch {@link CameraPath.Observer#pathCompleted}. */ - protected static class CompletedOp implements ObserverList.ObserverOp - { - public CompletedOp (CameraPath path) { - _path = path; - } - public boolean apply (CameraPath.Observer observer) { - return observer.pathCompleted(_path); - } - protected CameraPath _path; - } - - protected Camera _camera; - protected CameraPath _campath; - protected ObserverList _campathobs = ObserverList.newSafeInOrder(); - - protected Matrix3f _rotm = new Matrix3f(); - protected Vector3f _temp = new Vector3f(); - - protected boolean _boundViaFrustum, _limitsEnabled = true; - protected float _minX = -Float.MAX_VALUE, _maxX = Float.MAX_VALUE; - protected float _minY = -Float.MAX_VALUE, _maxY = Float.MAX_VALUE; - protected float _minZ = -Float.MAX_VALUE, _maxZ = Float.MAX_VALUE; - protected float _minZoom = 0f, _maxZoom = Float.MAX_VALUE; - protected float _minTilt = -Float.MAX_VALUE, _maxTilt = Float.MAX_VALUE; - - protected Vector3f _rxdir = new Vector3f(1, 0, 0); - protected Vector3f _rydir = new Vector3f(0, 1, 0); - - protected static final Vector3f _xdir = new Vector3f(1, 0, 0); - protected static final Vector3f _ydir = new Vector3f(0, 1, 0); - - protected static final Plane _ground = new Plane(new Vector3f(0, 0, 1), 0); -} diff --git a/src/java/com/threerings/jme/camera/CameraPath.java b/src/java/com/threerings/jme/camera/CameraPath.java deleted file mode 100644 index fadbcd76..00000000 --- a/src/java/com/threerings/jme/camera/CameraPath.java +++ /dev/null @@ -1,67 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.camera; - -/** - * Used to move the camera along a particular path. - */ -public abstract class CameraPath -{ - /** Used to inform observers when a camera path is completed or aborted. */ - public interface Observer - { - /** - * Called when this path is finished (potentially early because another - * path was set before this path completed). - * - * @param path the path that was completed. - * - * @return true if the observer should remain in the list, false if it - * should be removed following this notification. - */ - public boolean pathCompleted (CameraPath path); - } - - /** - * This is called on every frame to allow the path to adjust the position - * of the camera. - * - * @return true if the path is completed and can be disposed, false if it - * is not yet completed. - */ - public abstract boolean tick (float secondsSince); - - /** - * Called if this path is aborted prior to completion due to being replaced - * by a new camera path. - */ - public void abort () - { - } - - protected CameraPath (CameraHandler camhand) - { - _camhand = camhand; - } - - protected CameraHandler _camhand; -} diff --git a/src/java/com/threerings/jme/camera/GodViewHandler.java b/src/java/com/threerings/jme/camera/GodViewHandler.java deleted file mode 100644 index 9a7a4dce..00000000 --- a/src/java/com/threerings/jme/camera/GodViewHandler.java +++ /dev/null @@ -1,202 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.camera; - -import com.jme.math.FastMath; - -import com.jme.input.InputHandler; -import com.jme.input.KeyBindingManager; -import com.jme.input.KeyInput; -import com.jme.input.action.*; -import com.jme.input.action.InputActionEvent; - -/** - * Sets up camera controls for moving around from a top-down perspective, - * suitable for strategy games and their ilk. The "ground" is assumed to be the - * XY plane. - */ -public class GodViewHandler extends InputHandler -{ - /** - * Creates the handler. - * - * @param camhand The camera to move with this handler. - */ - public GodViewHandler (CameraHandler camhand) - { - _camhand = camhand; - setKeyBindings(); - addActions(); - } - - protected void setKeyBindings () - { - KeyBindingManager keyboard = KeyBindingManager.getKeyBindingManager(); - - // the key bindings for the pan actions - keyboard.set("forward", KeyInput.KEY_W); - keyboard.set("arrow_forward", KeyInput.KEY_UP); - keyboard.set("backward", KeyInput.KEY_S); - keyboard.set("arrow_backward", KeyInput.KEY_DOWN); - keyboard.set("left", KeyInput.KEY_A); - keyboard.set("arrow_left", KeyInput.KEY_LEFT); - keyboard.set("right", KeyInput.KEY_D); - keyboard.set("arrow_right", KeyInput.KEY_RIGHT); - - // the key bindings for the zoom actions - keyboard.set("zoomIn", KeyInput.KEY_UP); - keyboard.set("zoomOut", KeyInput.KEY_DOWN); - - // the key bindings for the orbit actions - keyboard.set("turnRight", KeyInput.KEY_RIGHT); - keyboard.set("turnLeft", KeyInput.KEY_LEFT); - - // the key bindings for the tilt actions - keyboard.set("tiltForward", KeyInput.KEY_HOME); - keyboard.set("tiltBack", KeyInput.KEY_END); - - keyboard.set("screenshot", KeyInput.KEY_F12); - } - - protected void addActions () - { - addAction(new KeyScreenShotAction(), "screenshot", false); - addPanActions(); - addZoomActions(); - addOrbitActions(); - addTiltActions(); - } - - /** - * Adds actions for panning the camera around the scene. - */ - protected void addPanActions () - { - InputAction forward = new InputAction() { - public void performAction (InputActionEvent evt) { - _camhand.panCamera(0, speed * evt.getTime()); - } - }; - forward.setSpeed(0.5f); - addAction(forward, "forward", true); - addAction(forward, "arrow_forward", true); - - InputAction backward = new InputAction() { - public void performAction (InputActionEvent evt) { - _camhand.panCamera(0, -speed * evt.getTime()); - } - }; - backward.setSpeed(0.5f); - addAction(backward, "backward", true); - addAction(backward, "arrow_backward", true); - - InputAction left = new InputAction() { - public void performAction (InputActionEvent evt) { - _camhand.panCamera(-speed * evt.getTime(), 0); - } - }; - left.setSpeed(0.5f); - addAction(left, "left", true); - addAction(left, "arrow_left", true); - - InputAction right = new InputAction() { - public void performAction (InputActionEvent evt) { - _camhand.panCamera(speed * evt.getTime(), 0); - } - }; - right.setSpeed(0.5f); - addAction(right, "right", true); - addAction(right, "arrow_right", true); - } - - /** - * Adds actions for zooming the camaera in and out. - */ - protected void addZoomActions () - { - InputAction zoomIn = new InputAction() { - public void performAction (InputActionEvent evt) { - _camhand.zoomCamera(-speed * evt.getTime()); - } - }; - zoomIn.setSpeed(0.5f); - addAction(zoomIn, "zoomIn", true); - - InputAction zoomOut = new InputAction() { - public void performAction (InputActionEvent evt) { - _camhand.zoomCamera(speed * evt.getTime()); - } - }; - zoomOut.setSpeed(0.5f); - addAction(zoomOut, "zoomOut", true); - } - - /** - * Adds actions for orbiting the camera around the viewpoint. - */ - protected void addOrbitActions () - { - addAction(new OrbitAction(-FastMath.PI / 2), "turnRight", true); - addAction(new OrbitAction(FastMath.PI / 2), "turnLeft", true); - } - - /** - * Adds actions for tilting the camera (rotating around the yaw axis). - */ - protected void addTiltActions () - { - addAction(new TiltAction(-FastMath.PI / 2), "tiltForward", true); - addAction(new TiltAction(FastMath.PI / 2), "tiltBack", true); - } - - protected class OrbitAction extends InputAction - { - public OrbitAction (float radPerSec) - { - _radPerSec = radPerSec; - } - - public void performAction (InputActionEvent evt) - { - _camhand.orbitCamera(_radPerSec * evt.getTime()); - } - - protected float _radPerSec; - } - - protected class TiltAction extends InputAction - { - public TiltAction (float radPerSec) - { - _radPerSec = radPerSec; - } - - public void performAction (InputActionEvent evt) - { - _camhand.tiltCamera(_radPerSec * evt.getTime()); - } - - protected float _radPerSec; - } - - protected CameraHandler _camhand; -} diff --git a/src/java/com/threerings/jme/camera/PanPath.java b/src/java/com/threerings/jme/camera/PanPath.java deleted file mode 100644 index cda0b4af..00000000 --- a/src/java/com/threerings/jme/camera/PanPath.java +++ /dev/null @@ -1,87 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.camera; - -import com.jme.math.Quaternion; -import com.jme.math.Vector3f; -import com.jme.renderer.Camera; - -/** - * Pans the camera to the specified location in the specified amount of time. - */ -public class PanPath extends CameraPath -{ - /** - * Creates a panning path for the specified camera that will retain the - * camera's current orientation. - * - * @param target the target position for the camera. - * @param duration the number of seconds in which to pan the camera. - */ - public PanPath (CameraHandler camhand, Vector3f target, float duration) - { - this(camhand, target, null, duration); - } - - /** - * Creates a panning path for the specified camera. - * - * @param target the target position for the camera. - * @param trot the target rotation for the camera (or null to - * keep its current orientation) - * @param duration the number of seconds in which to pan the camera. - */ - public PanPath (CameraHandler camhand, Vector3f target, Quaternion trot, - float duration) - { - super(camhand); - - Camera cam = camhand.getCamera(); - _start = new Vector3f(cam.getLocation()); - _velocity = target.subtract(_start); - _velocity.divideLocal(duration); - if (trot != null) { - _irot = new Quaternion(); - _irot.fromAxes(cam.getLeft(), cam.getUp(), cam.getDirection()); - _trot = trot; - } - - _duration = duration; - } - - // documentation inherited - public boolean tick (float secondsSince) - { - _elapsed = Math.min(_elapsed + secondsSince, _duration); - _camloc.scaleAdd(_elapsed, _velocity, _start); - _camhand.setLocation(_camloc); - if (_irot != null) { - _camhand.getCamera().setAxes(_axes.slerp(_irot, _trot, - _elapsed / _duration)); - } - return (_elapsed >= _duration); - } - - protected Vector3f _start, _velocity, _camloc = new Vector3f(); - protected Quaternion _irot, _trot, _axes = new Quaternion(); - protected float _elapsed, _duration; -} diff --git a/src/java/com/threerings/jme/camera/SplinePath.java b/src/java/com/threerings/jme/camera/SplinePath.java deleted file mode 100644 index 880552f4..00000000 --- a/src/java/com/threerings/jme/camera/SplinePath.java +++ /dev/null @@ -1,111 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.camera; - -import com.jme.math.Vector3f; -import com.jme.renderer.Camera; - -/** - * Moves the camera along a cubic Hermite spline path defined by the start and - * end locations and directions. Spline formulas obtained from - * Wikipedia. - */ -public class SplinePath extends CameraPath -{ - /** - * Creates a cubic spline path for the camera to follow. - * - * @param tloc the target location - * @param tdir the target direction - * @param axis the heading axis (typically {@link Vector3f#UNIT_Z}) - * @param duration the duration of the path - * @param tension the tension parameter, which can range from zero to one: - * higher tension values create a more direct path with a sharper turn, - * lower values create a rounder path with a smoother turn - */ - public SplinePath (CameraHandler camhand, Vector3f tloc, - Vector3f tdir, Vector3f axis, float duration, float tension) - { - super(camhand); - - // get the spline function coefficients - Camera cam = camhand.getCamera(); - _p0 = new Vector3f(cam.getLocation()); - _p1 = new Vector3f(tloc); - float tscale = (1f - tension) * _p0.distance(_p1); - _m0 = cam.getDirection().mult(tscale); - _m1 = tdir.mult(tscale); - - _axis = axis; - _duration = duration; - } - - // documentation inherited - public boolean tick (float secondsSince) - { - _elapsed = Math.min(_elapsed + secondsSince, _duration); - float t = _elapsed / _duration, t2 = t*t, t3 = t2*t, - h00 = 2*t3 - 3*t2 + 1, - h00p = 6*t2 - 6*t, - h10 = t3 - 2*t2 + t, - h10p = 3*t2 - 4*t + 1, - h01 = -2*t3 + 3*t2, - h01p = -6*t2 + 6*t, - h11 = t3 - t2, - h11p = 3*t2 - 2*t; - - // take the derivative to find the direction - _p0.mult(h00p, _dir); - _dir.scaleAdd(h10p, _m0, _dir); - _dir.scaleAdd(h01p, _p1, _dir); - _dir.scaleAdd(h11p, _m1, _dir); - _dir.normalizeLocal(); - - // evaluate the spline function to find the location - _p0.mult(h00, _loc); - _loc.scaleAdd(h10, _m0, _loc); - _loc.scaleAdd(h01, _p1, _loc); - _loc.scaleAdd(h11, _m1, _loc); - - // compute the left and up vectors using the direction and - // axis vectors - Camera cam = _camhand.getCamera(); - _axis.cross(_dir, _left); - _left.normalizeLocal(); - _dir.cross(_left, _up); - - // update the camera's location and orientation - cam.setFrame(_loc, _left, _up, _dir); - - return _elapsed >= _duration; - } - - /** The parameters of the spline. */ - Vector3f _p0, _m0, _p1, _m1, _axis; - - /** Working vectors. */ - Vector3f _loc = new Vector3f(), _left = new Vector3f(), - _up = new Vector3f(), _dir = new Vector3f(); - - /** The elapsed time and total duration. */ - float _elapsed, _duration; -} diff --git a/src/java/com/threerings/jme/camera/SwingPath.java b/src/java/com/threerings/jme/camera/SwingPath.java deleted file mode 100644 index 61ccbcb4..00000000 --- a/src/java/com/threerings/jme/camera/SwingPath.java +++ /dev/null @@ -1,167 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.camera; - -import com.jme.math.FastMath; -import com.jme.math.Quaternion; -import com.jme.math.Vector3f; - -import static com.threerings.jme.Log.log; - -/** - * Swings the camera around a point of interest (which should be somewhere - * along the camera's view vector). Also optionally pans the camera and/or - * zooms it in or out (moves it along its view vector) in the process. - * - *

- */ -public class SwingPath extends CameraPath -{ - /** - * Creates a rotating, zooming path for the specified camera. - * - * @param spot the point of interest around which to swing the camera. - * @param axis the axis around which to rotate the camera. - * @param angle the angle through which to rotate the camera. - * @param angvel the (absolute value of the) velocity at which to rotate - * the camera (in radians per second). - * @param zoom the distance to zoom along the camera's view axis (negative - * = in, positive = out). - */ - public SwingPath (CameraHandler camhand, Vector3f spot, Vector3f axis, - float angle, float angvel, float zoom) - { - this(camhand, spot, axis, angle, angvel, null, 0f, null, zoom); - } - - /** - * Creates a rotating, panning, zooming path for the specified camera. - * - * @param spot the point of interest around which to swing the camera. - * @param paxis the primary axis around which to rotate the camera. - * @param pangle the angle through which to rotate the camera about the - * primary axis. - * @param angvel the (absolute value of the) velocity at which to rotate - * the camera (in radians per second) about the primary angle. - * @param saxis the secondary axis around which to rotate the camera, or - * null for none - * @param sangle the angle through which to rotate the camera about the - * secondary axis - * @param pan the amount to pan the camera, or null for none - * @param zoom the distance to zoom along the camera's view axis (negative - * = in, positive = out). - */ - public SwingPath (CameraHandler camhand, Vector3f spot, Vector3f paxis, - float pangle, float angvel, Vector3f saxis, float sangle, - Vector3f pan, float zoom) - { - super(camhand); - - if (pangle == 0) { - log.warning("Requested to swing camera through zero degrees " + - "[spot=" + spot + ", paxis=" + paxis + - ", angvel=" + angvel + ", zoom=" + zoom + "]."); - pangle = 0.0001f; - } - if (angvel <= 0) { - log.warning("Requested to swing camera with invalid velocity " + - "[spot=" + spot + ", paxis=" + paxis + ", pangle=" + - pangle + ", angvel=" + angvel + ", zoom=" + zoom + - "]."); - angvel = FastMath.PI; - } - - _spot = new Vector3f(spot); - _paxis = paxis; - _pangle = pangle; - _pangvel = (pangle > 0) ? angvel : -1 * angvel; - _saxis = (saxis == null) ? null : new Vector3f(saxis); - _sangle = sangle; - _sangvel = _sangle * _pangvel / _pangle; - _pan = pan; - if (_pan != null) { - _panvel = _pan.mult(_pangvel / _pangle); - _panned = new Vector3f(); - } - _zoom = zoom; - _zoomvel = _zoom * _pangvel / _pangle; - -// Log.info("Swinging camera [angle=" + _angle + ", angvel=" + _angvel + -// ", zoom=" + _zoom + ", zoomvel=" + _zoomvel + "]."); - } - - // documentation inherited - public boolean tick (float secondsSince) - { - float deltaPAngle = (secondsSince * _pangvel); - float deltaSAngle = (secondsSince * _sangvel); - float deltaZoom = (secondsSince * _zoomvel); - _protated += deltaPAngle; - _srotated += deltaSAngle; - _zoomed += deltaZoom; - if (_pan != null) { - _panvel.mult(secondsSince, _deltaPan); - _panned.addLocal(_deltaPan); - } - - // clamp our rotation at the target angle and determine whether or not - // we're done - boolean done = false; - if (_pangle > 0 && _protated > _pangle || - _pangle < 0 && _protated < _pangle) { - deltaPAngle -= (_protated - _pangle); - deltaSAngle -= (_srotated - _sangle); - deltaZoom -= (_zoomed - _zoom); - if (_pan != null) { - _deltaPan.subtractLocal(_panned).addLocal(_pan); - } - _protated = _pangle; - _srotated = _sangle; - _panned = _pan; - _zoomed = _zoom; - done = true; - } - - // have the camera handler do the necessary rotating, panning, zooming - if (_pan != null) { - _camhand.setLocation( - _camhand.getCamera().getLocation().addLocal(_deltaPan)); - _spot.addLocal(_deltaPan); - } - _camhand.rotateCamera(_spot, _paxis, deltaPAngle, deltaZoom); - if (_saxis != null) { - _rot.fromAngleAxis(deltaPAngle, _paxis).multLocal(_saxis); - _camhand.rotateCamera(_spot, _saxis, deltaSAngle, 0f); - } - - return done; - } - - protected Vector3f _spot, _paxis, _saxis; - protected float _pangle, _pangvel, _protated; - protected float _sangle, _sangvel, _srotated; - protected Vector3f _pan, _panvel, _panned; - protected float _zoom, _zoomvel, _zoomed; - - protected Quaternion _rot = new Quaternion(); - protected Vector3f _deltaPan = new Vector3f(); -} diff --git a/src/java/com/threerings/jme/camera/rotate_zoom.dia b/src/java/com/threerings/jme/camera/rotate_zoom.dia deleted file mode 100644 index 603bd5cc9de1b4a0407623bb8a8ad1d68226cfae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1672 zcmV;326y=%iwFP!000001MORFkJ>m8{=UB=qF+ak5Cq;9@VS)j^AUo9F3)`QPg}J4S)cFk?fqdBGk7XHpy;sE+rgiB*FIH^KpIfro`II>H!os7 z5mklv>7q&YWKtFFVD>th#pWxGE8!Ck&m)QvhQ9?ow*!pQBpI7zTF(A>o%a7vaciZM z)goF}q3c4j-p_|mOWd^PznXMm;8PJS`d=&Ua`2y@t&8Hi!N-s9dFFJQ)T!DYwxXK#n2DX9@AWi)sjwb|yp=C=v*tp@0Qk^+=9@ zLT~5-OCVqL@*H_yi-SDC;?7o7AisN&U8^M7IL>^05en;_|+t z@tN@c;_*31=ZL&A)>#?rqxqcIFc$C3SOh{@QpmniO2zu6tSu6yfK*bJfcLN^Ymb~4 zW;xJfs*GuLepl_7R{Hlp!#Jlsn{9@;G}pPAHuUsgXoNM@uuvh_!57!Pd%dvn8fK}J zY~YmyRyx7vqraK>!4$Rcb1FW4278;rTE`A6n>XGKbk{vka?v($yDh>acZ_X-bZlqI z!ql&6!=CG9^iN2|2gH(9uhFatnS&AQlT3{`_FKN2C(#b{W zq~0yBbaI|v@$Xq0nb>6BM`z0*ts$47E4c(n_!KEBFz>Z(%)v(jK$0X3!;wTH;Fy;+ zOKargddHm=JgSG>V+)yHJIL1#^0k9}Oa=BKjn}g@so_c4xd>xOFdFz01)*ZS7GVr= zfs5uWlZ1+*2ooXqLljUVTQ2?*3^P95j%w1eW~hKks$!A?2P8PqZ03d35QMk3-1ifj z{8BC(c6M2ycMhHd1scVq&-4yRIDnm{LW)TV`v!`z2$T=6gay62Y?F@l^(v>zFDDy@ z2ZrKOYN1D4%bnR}&vKZix*w)VhDCYEBuTG61tb(OP6{N3 S+4+{#-Oc}ihc=u^JpceP8b`YT diff --git a/src/java/com/threerings/jme/camera/rotate_zoom.png b/src/java/com/threerings/jme/camera/rotate_zoom.png deleted file mode 100644 index d04c2484f422a8a27350164573a83fbd4738af9b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12816 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 diff --git a/src/java/com/threerings/jme/chat/ChatView.java b/src/java/com/threerings/jme/chat/ChatView.java deleted file mode 100644 index 5ba8af53..00000000 --- a/src/java/com/threerings/jme/chat/ChatView.java +++ /dev/null @@ -1,203 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.chat; - -import com.jme.renderer.ColorRGBA; - -import com.jmex.bui.BButton; -import com.jmex.bui.BContainer; -import com.jmex.bui.BTextArea; -import com.jmex.bui.BTextField; -import com.jmex.bui.event.ActionEvent; -import com.jmex.bui.event.ActionListener; -import com.jmex.bui.layout.BorderLayout; -import com.jmex.bui.layout.GroupLayout; - -import com.threerings.crowd.chat.client.ChatDirector; -import com.threerings.crowd.chat.client.ChatDisplay; -import com.threerings.crowd.chat.client.SpeakService; -import com.threerings.crowd.chat.data.ChatCodes; -import com.threerings.crowd.chat.data.ChatMessage; -import com.threerings.crowd.chat.data.SystemMessage; -import com.threerings.crowd.chat.data.UserMessage; -import com.threerings.crowd.data.PlaceObject; - -import com.threerings.jme.JmeContext; - -import static com.threerings.jme.Log.log; - -/** - * Displays chat messages and allows for their input. - */ -public class ChatView extends BContainer - implements ChatDisplay -{ - public ChatView (JmeContext ctx, ChatDirector chatdtr) - { - _chatdtr = chatdtr; - setLayoutManager(new BorderLayout(2, 2)); - add(_text = new BTextArea(), BorderLayout.CENTER); - _incont = new BContainer(GroupLayout.makeHStretch()); - add(_incont, BorderLayout.SOUTH); - _incont.add(_input = new BTextField()); - _input.addListener(_inlist); - } - - public void willEnterPlace (PlaceObject plobj) - { - setSpeakService(plobj.speakService, null); - } - - public void didLeavePlace (PlaceObject plobj) - { - clearSpeakService(); - } - - public void setSpeakService (SpeakService spsvc, String localType) - { - if (spsvc != null) { - _spsvc = spsvc; - _localType = localType; - _chatdtr.addChatDisplay(this); - } - } - - public void clearSpeakService () - { - if (_spsvc != null) { - _chatdtr.removeChatDisplay(this); - _spsvc = null; - _localType = null; - } - } - - public void setChatButton (BButton button) - { - _inBtn = button; - _incont.add(_inBtn, GroupLayout.FIXED); - _inBtn.addListener(_inlist); - } - - /** - * Instructs our chat input field to request focus. - */ - public void requestFocus () - { - _input.requestFocus(); - } - - // documentation inherited from interface ChatDisplay - public void clear () - { - if (_input.hasFocus() || _inBtn.hasFocus()) { - _text.clearText(); - } - } - - // documentation inherited from interface ChatDisplay - public boolean displayMessage (ChatMessage msg, boolean alreadyDisplayed) - { - // we may be restricted in the chat types we handle - if (!handlesType(msg.localtype)) { - return false; - } - - if (msg instanceof UserMessage) { - UserMessage umsg = (UserMessage) msg; - if (ChatCodes.USER_CHAT_TYPE.equals(umsg.localtype)) { - append("[" + umsg.speaker + " whispers] ", ColorRGBA.green); - append(umsg.message + "\n"); - } else { - append("<" + umsg.speaker + "> ", ColorRGBA.blue); - append(umsg.message + "\n"); - } - return true; - - } else if (msg instanceof SystemMessage) { - append(msg.message + "\n", ColorRGBA.red); - return true; - - } else { - log.warning("Received unknown message type: " + msg + "."); - return false; - } - } - - // documentation inherited - public void setEnabled (boolean enabled) - { - _input.setEnabled(enabled); - } - - protected void displayError (String message) - { - append(message + "\n", ColorRGBA.red); - } - - protected void append (String text, ColorRGBA color) - { - _text.appendText(text, color); - } - - protected void append (String text) - { - _text.appendText(text); - } - - protected boolean handlesType (String localType) - { - return _localType == null || _localType.equals(localType); - } - - protected boolean handleInput (String text) - { - if (text.length() == 0) { - // no empty banter - return false; - } - String msg = _chatdtr.requestChat(_spsvc, text, true); - if (msg.equals(ChatCodes.SUCCESS)) { - return true; - } else { - _chatdtr.displayFeedback(null, msg); - return false; - } - } - - /** Used to trigger sending chat (on return key or button press). */ - protected ActionListener _inlist = new ActionListener() { - public void actionPerformed (ActionEvent event) { - if (handleInput(_input.getText())) { - _input.setText(""); - } - } - }; - - protected ChatDirector _chatdtr; - protected SpeakService _spsvc; - protected String _localType; - - protected BTextArea _text; - protected BContainer _incont; - protected BTextField _input; - protected BButton _inBtn; -} diff --git a/src/java/com/threerings/jme/effect/FadeInOutEffect.java b/src/java/com/threerings/jme/effect/FadeInOutEffect.java deleted file mode 100644 index 79cd62be..00000000 --- a/src/java/com/threerings/jme/effect/FadeInOutEffect.java +++ /dev/null @@ -1,147 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.effect; - -import com.jme.math.Vector3f; -import com.jme.renderer.ColorRGBA; -import com.jme.renderer.Renderer; -import com.jme.scene.Node; -import com.jme.scene.shape.Quad; -import com.jme.scene.state.AlphaState; -import com.jme.system.DisplaySystem; - -import com.threerings.jme.util.LinearTimeFunction; -import com.threerings.jme.util.TimeFunction; - -/** - * Fades a supplied quad (or one that covers the screen) in from a solid color - * or out to a solid color. - */ -public class FadeInOutEffect extends Node -{ - public FadeInOutEffect (ColorRGBA color, float startAlpha, float endAlpha, - float duration, boolean overUI) - { - this(color, new LinearTimeFunction(startAlpha, endAlpha, duration), - overUI); - } - - public FadeInOutEffect (ColorRGBA color, TimeFunction alphaFunc, - boolean overUI) - { - this(null, color, alphaFunc, overUI); - setQuad(createCurtain()); - } - - public FadeInOutEffect (Quad quad, ColorRGBA color, TimeFunction alphaFunc, - boolean overUI) - { - super("FadeInOut"); - - _color = new ColorRGBA( - color.r, color.g, color.b, alphaFunc.getValue(0)); - _alphaFunc = alphaFunc; - - DisplaySystem ds = DisplaySystem.getDisplaySystem(); - _astate = ds.getRenderer().createAlphaState(); - _astate.setBlendEnabled(true); - _astate.setSrcFunction(AlphaState.SB_SRC_ALPHA); - _astate.setDstFunction(AlphaState.DB_ONE_MINUS_SRC_ALPHA); - _astate.setEnabled(true); - - if (quad != null) { - setQuad(quad); - } - - setRenderQueueMode(Renderer.QUEUE_ORTHO); - setZOrder(overUI ? -1 : 1); - } - - /** - * Configures the quad that will be faded in or out. - */ - public void setQuad (Quad quad) - { - attachChild(quad); - quad.setDefaultColor(_color); - quad.setRenderState(_astate); - quad.updateRenderState(); - } - - /** - * Allows the fade to be paused. - */ - public void setPaused (boolean paused) - { - _paused = paused; - } - - /** - * Indicates whether or not the fade is paused. - */ - public boolean isPaused () - { - return _paused; - } - - // documentation inherited - public void updateGeometricState (float time, boolean initiator) - { - super.updateGeometricState(time, initiator); - if (_paused) { - return; - } - - float alpha = _alphaFunc.getValue(time); - _color.a = Math.min(1f, Math.max(0f, alpha)); - if (_alphaFunc.isComplete()) { - fadeComplete(); - } - } - - /** - * Called (only once) when we have reached the end of our fade. - * Automatically detaches this effect from the hierarchy. - */ - protected void fadeComplete () - { - getParent().detachChild(this); - } - - /** - * Creates a quad that covers the entire screen for full-screen fades. - */ - protected Quad createCurtain () - { - // create a quad the size of the screen - DisplaySystem ds = DisplaySystem.getDisplaySystem(); - float width = ds.getWidth(), height = ds.getHeight(); - Quad curtain = new Quad("curtain" + hashCode(), width, height); - curtain.setLocalTranslation(new Vector3f(width/2, height/2, 0f)); - return curtain; - } - - protected ColorRGBA _color; - protected AlphaState _astate; - protected TimeFunction _alphaFunc; - protected boolean _paused; -} diff --git a/src/java/com/threerings/jme/effect/WindowSlider.java b/src/java/com/threerings/jme/effect/WindowSlider.java deleted file mode 100644 index 7b397703..00000000 --- a/src/java/com/threerings/jme/effect/WindowSlider.java +++ /dev/null @@ -1,157 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.effect; - -import com.jme.scene.Node; -import com.jme.system.DisplaySystem; - -import com.jmex.bui.BWindow; - -import com.threerings.jme.util.LinearTimeFunction; -import com.threerings.jme.util.TimeFunction; - -/** - * Slides a window onto the center of the screen from offscreen or offscreen - * from the center of the screen. - */ -public class WindowSlider extends Node -{ - // slides from the specified location into the center of the screen - public static final int FROM_TOP = 0; - public static final int FROM_RIGHT = 1; - - // slides from the center of the screen off screen in the specified direction - public static final int TO_TOP = 2; - public static final int TO_RIGHT = 3; - - // slides down from the specified location stopping when whole window is visible (window - // remains "stuck" to the edge from which it slid in) - public static final int FROM_TOP_STICKY = 4; - - /** - * Creates a window slider with the specified mode and window that will - * slide the window either onto or off of the screen in the specified - * number of seconds. - * - * @param dx an offset applied to the starting or destination position - * along the x axis (starting for sliding off, destination for sliding on). - * @param dy an offset applied along the y axis. - */ - public WindowSlider (BWindow window, int mode, float duration, - int dx, int dy) - { - super("slider"); - - DisplaySystem ds = DisplaySystem.getDisplaySystem(); - int swidth = ds.getWidth(), sheight = ds.getHeight(); - int wwidth = window.getWidth(), wheight = window.getHeight(); - - int start = 0, end = 0; - switch (mode) { - case FROM_TOP: - start = sheight+wheight; - end = (sheight-wheight)/2 + dy; - window.setLocation((swidth-wwidth)/2 + dx, start); - break; - - case FROM_RIGHT: - start = swidth+wwidth; - end = (swidth-wwidth)/2 + dx; - window.setLocation(start, (sheight-wheight)/2 + dy); - break; - - case TO_TOP: - start = (sheight-wheight)/2 + dy; - end = sheight+wheight; - window.setLocation((swidth-wwidth)/2 + dx, start); - break; - - case TO_RIGHT: - start = (swidth-wwidth)/2 + dx; - end = swidth+wwidth; - window.setLocation(start, (sheight-wheight)/2 + dy); - break; - - case FROM_TOP_STICKY: - start = sheight+wheight; - end = sheight-wheight + dy; - window.setLocation((swidth-wwidth)/2 + dx, start); - } - - _mode = mode; - _window = window; - _tfunc = new LinearTimeFunction(start, end, duration); - } - - /** - * Allows some number of ticks to be skipped to give the window that is - * being slid a chance to be layed out before we start keeping track of - * time. The layout may be expensive and cause the frame rate to drop for a - * frame or two, thus booching our smooth sliding onto the screen. - */ - public void setSkipTicks (int skipTicks) - { - _skipTicks = skipTicks; - } - - // documentation inherited - public void updateGeometricState (float time, boolean initiator) - { - super.updateGeometricState(time, initiator); - - // skip ticks as long as we need to - if (_skipTicks-- > 0) { - return; - } - - int winx, winy; - if (_mode % 2 == 1) { - winx = (int)_tfunc.getValue(time); - winy = _window.getY(); - } else { - winx = _window.getX(); - winy = (int)_tfunc.getValue(time); - } - _window.setLocation(winx, winy); - - if (_tfunc.isComplete()) { - slideComplete(); - } - } - - /** - * Called (only once) when we have reached the end of our slide. - * Automatically detaches this effect from the hierarchy. - */ - protected void slideComplete () - { - getParent().detachChild(this); - } - - protected int _mode; - protected BWindow _window; - protected TimeFunction _tfunc; - - // skip two frames by default as that generally handles the normal window - // layout process - protected int _skipTicks = 2; -} diff --git a/src/java/com/threerings/jme/model/BillboardController.java b/src/java/com/threerings/jme/model/BillboardController.java deleted file mode 100644 index 60d14738..00000000 --- a/src/java/com/threerings/jme/model/BillboardController.java +++ /dev/null @@ -1,177 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.model; - -import java.io.IOException; - -import java.util.Properties; - -import com.jme.math.FastMath; -import com.jme.math.Quaternion; -import com.jme.math.Vector3f; -import com.jme.renderer.Camera; -import com.jme.scene.Controller; -import com.jme.scene.Spatial; -import com.jme.system.DisplaySystem; -import com.jme.util.export.JMEExporter; -import com.jme.util.export.JMEImporter; -import com.jme.util.export.InputCapsule; -import com.jme.util.export.OutputCapsule; - -/** - * Orients its target towards the camera plane. - */ -public class BillboardController extends ModelController -{ - /** Determines how the billboard is rotated. */ - public enum Alignment { - DIR_X_POS_Z(false, true), - DIR_X_DIR_Z(false, false), - POS_X_POS_Z(true, true), - DIR_Z(false), - POS_Z(true); - - /** Determines whether rotation is limited to the Z axis. */ - public boolean isAxial () { - return _axial; - } - - /** Determines whether to tilt in the direction of the vector from the eyepoint to the - * target's origin (the eye vector) as opposed to the camera direction. */ - public boolean isEyeRelativeX () { - return _eyeRelativeX; - } - - /** Determines whether to swivel in the direction of the eye vector as opposed to the - * camera direction. */ - public boolean isEyeRelativeZ () { - return _eyeRelativeZ; - } - - Alignment (boolean eyeRelativeX, boolean eyeRelativeZ) { - _eyeRelativeX = eyeRelativeX; - _eyeRelativeZ = eyeRelativeZ; - } - - Alignment (boolean eyeRelativeZ) { - _axial = true; - _eyeRelativeZ = eyeRelativeZ; - } - - protected boolean _axial, _eyeRelativeX, _eyeRelativeZ; - }; - - @Override - public void configure (Properties props, Spatial target) - { - super.configure(props, target); - _alignment = Enum.valueOf(Alignment.class, - props.getProperty("alignment", "dir_x_pos_z").toUpperCase()); - } - - // documentation inherited - public void update (float time) - { - Camera cam = DisplaySystem.getDisplaySystem().getRenderer().getCamera(); - if (!isActive() || cam == null) { - return; - } - if (_alignment.isEyeRelativeZ()) { - _target.getWorldTranslation().subtract(cam.getLocation(), _yvec); - } else { - _yvec.set(cam.getDirection()); - } - _zvec.set(_alignment.isAxial() ? Vector3f.UNIT_Z : cam.getUp()); - if (_alignment.isEyeRelativeX()) { - // use the forward vector as-is - _yvec.normalizeLocal().cross(_zvec, _xvec); - if (_xvec.length() < FastMath.FLT_EPSILON) { - return; - } - _xvec.normalizeLocal().cross(_yvec, _zvec); - - } else { - // project the forward vector onto the up plane - _yvec.scaleAdd(-_zvec.dot(_yvec), _zvec, _yvec); - if (_yvec.length() < FastMath.FLT_EPSILON) { - return; - } - _yvec.normalizeLocal().cross(_zvec, _xvec); - } - // compute the world rotation with the axes and rotate into - // parent's coordinate system - Quaternion lrot = _target.getLocalRotation(); - lrot.fromAxes(_xvec, _yvec, _zvec); - Spatial parent = _target.getParent(); - if (parent == null) { - _rot.loadIdentity(); - } else { - _rot.set(parent.getWorldRotation()).inverseLocal(); - } - _rot.mult(lrot, lrot); - } - - @Override - public Controller putClone ( - Controller store, Model.CloneCreator properties) - { - BillboardController bstore; - if (store == null) { - bstore = new BillboardController(); - } else { - bstore = (BillboardController)store; - } - super.putClone(bstore, properties); - bstore._alignment = _alignment; - return bstore; - } - - @Override - public void read (JMEImporter im) - throws IOException - { - super.read(im); - InputCapsule capsule = im.getCapsule(this); - _alignment = Enum.valueOf(Alignment.class, - capsule.readString("alignment", "DIR_X_POS_Z")); - } - - @Override - public void write (JMEExporter ex) - throws IOException - { - super.write(ex); - OutputCapsule capsule = ex.getCapsule(this); - capsule.write(_alignment.name(), "alignment", "DIR_X_POS_Z"); - } - - /** The alignment mode. */ - protected Alignment _alignment; - - /** A temporary quaternion. */ - protected Quaternion _rot = new Quaternion(); - - /** Temporary axis vectors. */ - protected Vector3f _xvec = new Vector3f(), _yvec = new Vector3f(), _zvec = new Vector3f(); - - private static final long serialVersionUID = 1; -} diff --git a/src/java/com/threerings/jme/model/EmissionController.java b/src/java/com/threerings/jme/model/EmissionController.java deleted file mode 100644 index d353fbd1..00000000 --- a/src/java/com/threerings/jme/model/EmissionController.java +++ /dev/null @@ -1,97 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.model; - -import java.io.IOException; - -import java.util.Properties; - -import com.jme.scene.Controller; -import com.jme.scene.Spatial; -import com.jme.util.export.JMEExporter; -import com.jme.util.export.JMEImporter; -import com.jme.util.export.InputCapsule; -import com.jme.util.export.OutputCapsule; - -/** - * A model controller whose target represents an emitter. - */ -public abstract class EmissionController extends ModelController -{ - @Override - public void configure (Properties props, Spatial target) - { - super.configure(props, target); - _hideTarget = Boolean.parseBoolean( - props.getProperty("hide_target", "true")); - } - - @Override - public void init (Model model) - { - super.init(model); - if (_hideTarget) { - _target.setCullMode(Spatial.CULL_ALWAYS); - if (_target instanceof ModelNode) { - // make sure the node isn't turned back on by an - // animation - ((ModelNode)_target).setForceCull(true); - } - } - } - - @Override - public Controller putClone ( - Controller store, Model.CloneCreator properties) - { - if (store == null) { - return null; - } - EmissionController estore = (EmissionController)store; - super.putClone(estore, properties); - estore._hideTarget = _hideTarget; - return estore; - } - - @Override - public void read (JMEImporter im) - throws IOException - { - super.read(im); - InputCapsule capsule = im.getCapsule(this); - _hideTarget = capsule.readBoolean("hideTarget", true); - } - - @Override - public void write (JMEExporter ex) - throws IOException - { - super.write(ex); - OutputCapsule capsule = ex.getCapsule(this); - capsule.write(_hideTarget, "hideTarget", true); - } - - /** Whether or not the target should be hidden from view. */ - protected boolean _hideTarget; - - private static final long serialVersionUID = 1; -} diff --git a/src/java/com/threerings/jme/model/Model.java b/src/java/com/threerings/jme/model/Model.java deleted file mode 100644 index 82995fa5..00000000 --- a/src/java/com/threerings/jme/model/Model.java +++ /dev/null @@ -1,1194 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.model; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; - -import java.nio.FloatBuffer; - -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Properties; - -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; - -import com.jme.bounding.BoundingVolume; -import com.jme.math.Quaternion; -import com.jme.math.Vector3f; -import com.jme.renderer.Camera; -import com.jme.renderer.Renderer; -import com.jme.scene.Controller; -import com.jme.scene.Node; -import com.jme.scene.Spatial; -import com.jme.util.export.JMEExporter; -import com.jme.util.export.JMEImporter; -import com.jme.util.export.InputCapsule; -import com.jme.util.export.OutputCapsule; -import com.jme.util.export.Savable; -import com.jme.util.export.binary.BinaryExporter; -import com.jme.util.export.binary.BinaryImporter; - -import com.samskivert.util.ArrayUtil; -import com.samskivert.util.ObserverList; -import com.samskivert.util.PropertiesUtil; -import com.samskivert.util.RandomUtil; -import com.samskivert.util.StringUtil; - -import com.threerings.jme.util.SpatialVisitor; - -import static com.threerings.jme.Log.log; - -/** - * The base node for models. - */ -public class Model extends ModelNode -{ - /** The supported types of animation in decreasing order of complexity. */ - public enum AnimationMode { - SKIN, MORPH, FLIPBOOK - }; - - /** Lets listeners know when animations are completed (which only happens - * for non-repeating animations) or cancelled. */ - public interface AnimationObserver - { - /** - * Called when an animation has started. - * - * @return true to remain on the observer list, false to remove self - */ - public boolean animationStarted (Model model, String anim); - - /** - * Called when a non-repeating animation has finished. - * - * @return true to remain on the observer list, false to remove self - */ - public boolean animationCompleted (Model model, String anim); - - /** - * Called when an animation has been cancelled. - * - * @return true to remain on the observer list, false to remove self - */ - public boolean animationCancelled (Model model, String anim); - } - - /** An animation for the model. */ - public static class Animation - implements Savable - { - /** The rate of the animation in frames per second. */ - public int frameRate; - - /** The animation repeat type ({@link Controller#RT_CLAMP}, - * {@link Controller#RT_CYCLE}, or {@link Controller#RT_WRAP}). */ - public int repeatType; - - /** Any nodes visible that never move within the model. */ - public Spatial[] staticTargets; - - /** The transformation targets of the animation. */ - public Spatial[] transformTargets; - - /** The animation transforms (one transform per target per frame). */ - public transient Transform[][] transforms; - - /** Uniquely identifies this animation within the model. */ - public transient int animId; - - /** For each frame, whether the frame has been stored in meshes. */ - public transient boolean[] stored; - - /** - * Returns this animation's duration in seconds. - */ - public float getDuration () - { - return (float)transforms.length / frameRate; - } - - /** - * Rebinds this animation for a prototype instance. - * - * @param pnodes a mapping from prototype nodes to instance nodes - */ - public Animation rebind (Map pnodes) - { - Animation anim = new Animation(); - anim.frameRate = frameRate; - anim.repeatType = repeatType; - anim.staticTargets = rebind(staticTargets, pnodes); - anim.transformTargets = rebind(transformTargets, pnodes); - anim.transforms = transforms; - anim.animId = animId; - anim.stored = stored; - return anim; - } - - /** - * Applies the transforms for a frame of this animation. - */ - public void applyFrame (int fidx) - { - Transform[] xforms = transforms[fidx]; - for (int ii = 0; ii < transformTargets.length; ii++) { - xforms[ii].apply(transformTargets[ii]); - } - } - - /** - * Blends the transforms between two frames of this animation. - */ - public void blendFrames (int fidx, int nidx, float alpha) - { - Transform[] xforms = transforms[fidx], nxforms = transforms[nidx]; - for (int ii = 0; ii < transformTargets.length; ii++) { - xforms[ii].blend(nxforms[ii], alpha, transformTargets[ii]); - } - } - - // documentation inherited - public Class getClassTag () - { - return getClass(); - } - - // documentation inherited - public void read (JMEImporter im) - throws IOException - { - InputCapsule capsule = im.getCapsule(this); - frameRate = capsule.readInt("frameRate", 0); - repeatType = capsule.readInt("repeatType", Controller.RT_CLAMP); - staticTargets = ArrayUtil.copy(capsule.readSavableArray( - "staticTargets", null), new Spatial[0]); - transformTargets = ArrayUtil.copy(capsule.readSavableArray( - "transformTargets", null), new Spatial[0]); - FloatBuffer pxforms = capsule.readFloatBuffer("transforms", null); - transforms = new Transform[pxforms.capacity() / - Transform.PACKED_SIZE / transformTargets.length][]; - for (int ii = 0; ii < transforms.length; ii++) { - Transform[] frame = transforms[ii] = - new Transform[transformTargets.length]; - for (int jj = 0; jj < frame.length; jj++) { - frame[jj] = new Transform(pxforms); - } - } - } - - // documentation inherited - public void write (JMEExporter ex) - throws IOException - { - OutputCapsule capsule = ex.getCapsule(this); - capsule.write(frameRate, "frameRate", 0); - capsule.write(repeatType, "repeatType", Controller.RT_CLAMP); - capsule.write(staticTargets, "staticTargets", null); - capsule.write(transformTargets, "transformTargets", null); - FloatBuffer pxforms = FloatBuffer.allocate( - transforms.length * transformTargets.length * Transform.PACKED_SIZE); - for (Transform[] frame : transforms) { - for (Transform xform : frame) { - xform.writeToBuffer(pxforms); - } - } - pxforms.rewind(); - capsule.write(pxforms, "transforms", null); - } - - protected Spatial[] rebind (Spatial[] targets, Map pnodes) - { - Spatial[] ntargets = new Spatial[targets.length]; - for (int ii = 0; ii < targets.length; ii++) { - ntargets[ii] = (Spatial)pnodes.get(targets[ii]); - } - return ntargets; - } - - private static final long serialVersionUID = 1; - } - - /** A frame element that manipulates the target's transform. */ - public static final class Transform - { - /** The number of floats required to store a packed transform. */ - public static final int PACKED_SIZE = 3 + 4 + 3; - - public Transform ( - Vector3f translation, Quaternion rotation, Vector3f scale) - { - _translation = translation; - _rotation = rotation; - _scale = scale; - } - - public Transform (FloatBuffer buf) - { - _translation = new Vector3f(buf.get(), buf.get(), buf.get()); - _rotation = new Quaternion(buf.get(), buf.get(), buf.get(), - buf.get()); - _scale = new Vector3f(buf.get(), buf.get(), buf.get()); - } - - public void apply (Spatial target) - { - target.getLocalTranslation().set(_translation); - target.getLocalRotation().set(_rotation); - target.getLocalScale().set(_scale); - } - - /** - * Blends between this transform and the next, applying the result to - * the given target. - * - * @param alpha the blend factor: 0.0 for entirely this frame, 1.0 for - * entirely the next - */ - public void blend (Transform next, float alpha, Spatial target) - { - target.getLocalTranslation().interpolate(_translation, - next._translation, alpha); - target.getLocalRotation().slerp(_rotation, next._rotation, alpha); - target.getLocalScale().interpolate(_scale, next._scale, alpha); - } - - /** - * Writes this transform to the current position in the supplied - * buffer. - */ - public void writeToBuffer (FloatBuffer buf) - { - buf.put(_translation.x); - buf.put(_translation.y); - buf.put(_translation.z); - - buf.put(_rotation.x); - buf.put(_rotation.y); - buf.put(_rotation.z); - buf.put(_rotation.w); - - buf.put(_scale.x); - buf.put(_scale.y); - buf.put(_scale.z); - } - - /** The transform at this frame. */ - protected Vector3f _translation, _scale; - protected Quaternion _rotation; - } - - /** Customized clone creator for models. */ - public static class CloneCreator - { - /** A shared seed used to select textures consistently. */ - public int random; - - /** Maps original objects to their copies. */ - public Map originalToCopy = Maps.newHashMap(); - - public CloneCreator (Model toCopy) - { - _toCopy = toCopy; - addProperty("vertices"); - addProperty("colors"); - addProperty("normals"); - addProperty("texcoords"); - addProperty("vboinfo"); - addProperty("indices"); - addProperty("obbtree"); - addProperty("displaylistid"); - addProperty("bound"); - } - - /** - * Sets the named property. - */ - public void addProperty (String name) - { - _properties.add(name); - } - - /** - * Clears the named property. - */ - public void removeProperty (String name) - { - _properties.remove(name); - } - - /** - * Checks whether the named property has been set. - */ - public boolean isSet (String name) - { - return _properties.contains(name); - } - - /** - * Creates a new copy of the target model. - */ - public Model createCopy () - { - random = RandomUtil.getInt(Integer.MAX_VALUE); - Model copy = (Model)_toCopy.putClone(null, this); - originalToCopy.clear(); // make sure no references remain - return copy; - } - - /** The model to copy. */ - protected Model _toCopy; - - /** The set of added properties. */ - protected HashSet _properties = Sets.newHashSet(); - } - - /** - * Attempts to read a model from the specified file. - */ - public static Model readFromFile (File file) - throws IOException - { - // read the serialized model and its children - FileInputStream fis = new FileInputStream(file); - Model model = (Model)BinaryImporter.getInstance().load(fis); - fis.close(); - - // initialize the model as a prototype - model.initPrototype(); - - return model; - } - - /** - * No-arg constructor for deserialization. - */ - public Model () - { - } - - /** - * Standard constructor. - */ - public Model (String name, Properties props) - { - super(name); - _props = props; - } - - /** - * Returns a reference to the properties of the model. - */ - public Properties getProperties () - { - return _props; - } - - /** - * Initializes this model as prototype. Only necessary when the prototype - * was not loaded through {@link #readFromFile}. - */ - public void initPrototype () - { - // initialize shared transient animation state - if (_anims != null) { - int nextId = 1; - for (Animation anim : _anims.values()) { - anim.animId = nextId++; - anim.stored = new boolean[anim.transforms.length]; - } - } - setReferenceTransforms(); - cullInvisibleNodes(); - initInstance(); - } - - /** - * Returns the names of the model's variant configurations. - */ - public String[] getVariantNames () - { - return StringUtil.parseStringArray(_props.getProperty("variants", "")); - } - - /** - * Adds an animation to the model's library. This should only be called by - * the model compiler. - */ - public void addAnimation (String name, Animation anim) - { - if (_anims == null) { - _anims = Maps.newHashMap(); - } - _anims.put(name, anim); - - // store the original transforms - Transform[] oxforms = new Transform[anim.transformTargets.length]; - for (int ii = 0; ii < anim.transformTargets.length; ii++) { - Spatial target = anim.transformTargets[ii]; - oxforms[ii] = new Transform( - new Vector3f(target.getLocalTranslation()), - new Quaternion(target.getLocalRotation()), - new Vector3f(target.getLocalScale())); - } - - // run through every frame of the animation, expanding the bounding - // volumes of any deformable meshes - for (int ii = 0; ii < anim.transforms.length; ii++) { - for (int jj = 0; jj < anim.transforms[ii].length; jj++) { - anim.transforms[ii][jj].apply(anim.transformTargets[jj]); - } - updateWorldData(0f); - expandModelBounds(); - } - - // restore the original transforms - for (int ii = 0; ii < anim.transformTargets.length; ii++) { - oxforms[ii].apply(anim.transformTargets[ii]); - } - updateWorldData(0f); - } - - /** - * Sets the animation mode to use for this model. This should be set - * on the prototype before any animations are started or any instances - * are created. - */ - public void setAnimationMode (AnimationMode mode) - { - _animMode = mode; - } - - /** - * Returns the animation mode configured for this model. - */ - public AnimationMode getAnimationMode () - { - return _animMode; - } - - /** - * Returns the names of the model's animations. - */ - public String[] getAnimationNames () - { - if (_prototype != null) { - return _prototype.getAnimationNames(); - } - return (_anims == null) ? new String[0] : - _anims.keySet().toArray(new String[_anims.size()]); - } - - /** - * Checks whether the unit has an animation with the given name. - */ - public boolean hasAnimation (String name) - { - if (_prototype != null) { - return _prototype.hasAnimation(name); - } - return (_anims == null) ? false : _anims.containsKey(name); - } - - /** - * Starts the named animation. - * - * @return the duration of the started animation (for looping animations, - * the duration of one cycle), or -1 if the animation was not found - */ - public float startAnimation (String name) - { - return startAnimation (name, 0, +1); - } - - /** - * Starts the named animation. - * - * @param fidx the frame to start with - * @param fdir the direction to go (+1 forward, -1 backward) - * - * @return the duration of the started animation (for looping animations, - * the duration of one cycle), or -1 if the animation was not found - */ - public float startAnimation (String name, int fidx, int fdir) - { - Animation anim = getAnimation(name); - if (anim == null) { - return -1f; - } - if (_anim != null) { - _animObservers.apply(new AnimCancelledOp(_animName)); - } - - // first cull all model nodes, then re-activate the ones in the target lists - cullModelNodes(); - for (Spatial target : anim.staticTargets) { - ((ModelNode)target).updateCullMode(); - } - for (Spatial target : anim.transformTargets) { - ((ModelNode)target).updateCullMode(); - } - - _paused = false; - _anim = anim; - _animName = name; - _fidx = fidx; - _nidx = fidx; - _fdir = fdir; - _elapsed = 0f; - advanceFrameCounter(); - _animObservers.apply(new AnimStartedOp(_animName)); - return anim.getDuration() / _animSpeed; - } - - /** - * Fast-forwards the current animation by the given number of seconds. - */ - public void fastForwardAnimation (float time) - { - updateAnimation(time); - } - - /** - * Gets a reference to the animation with the given name. - */ - public Animation getAnimation (String name) - { - if (_anims == null) { - return null; - } - Animation anim = _anims.get(name); - if (anim != null) { - return anim; - } - if (_prototype != null) { - Animation panim = _prototype._anims.get(name); - if (panim != null) { - _anims.put(name, anim = panim.rebind(_pnodes)); - return anim; - } - } - log.warning("Requested unknown animation [name=" + name + "]."); - return null; - } - - /** - * Returns a reference to the currently running animation, or - * null if no animation is running. - */ - public Animation getAnimation () - { - return _anim; - } - - /** - * Stops the currently running animation. - */ - public void stopAnimation () - { - if (_anim == null) { - return; - } - if (_outside) { - // make sure the meshes are in the right places when we come back into view - updateMeshes(); - } - _paused = false; - _anim = null; - _animObservers.apply(new AnimCancelledOp(_animName)); - } - - /** - * Sets the pause state of the animation. - */ - public void pauseAnimation (boolean pause) - { - _paused = pause; - } - - /** - * Returns the pause state of the animation. - */ - public boolean isAnimationPaused () - { - return _paused; - } - - /** - * Causes the animation to start running in reverse. - */ - public void reverseAnimation () - { - _fdir *= -1; - } - - /** - * Sets the animation speed, which acts as a multiplier for the frame rate - * of each animation. - */ - public void setAnimationSpeed (float speed) - { - _animSpeed = speed; - } - - /** - * Returns the currently configured animation speed. - */ - public float getAnimationSpeed () - { - return _animSpeed; - } - - /** - * Adds an animation observer. - */ - public void addAnimationObserver (AnimationObserver obs) - { - _animObservers.add(obs); - } - - /** - * Removes an animation observer. - */ - public void removeAnimationObserver (AnimationObserver obs) - { - _animObservers.remove(obs); - } - - /** - * Returns a reference to the node that contains this model's emissions - * (in world space, so the emissions do not move with the model). This - * node is created and added when this method is first called. - */ - public Node getEmissionNode () - { - if (_emissionNode == null) { - attachChild(_emissionNode = new Node("emissions") { - public void updateWorldVectors () { - worldTranslation.set(localTranslation); - worldRotation.set(localRotation); - worldScale.set(localScale); - } - }); - } - return _emissionNode; - } - - /** - * Writes this model out to a file. - */ - public void writeToFile (File file) - throws IOException - { - // start out by writing this node and its children - FileOutputStream fos = new FileOutputStream(file); - BinaryExporter.getInstance().save(this, fos); - fos.close(); - } - - @Override - public void read (JMEImporter im) - throws IOException - { - super.read(im); - InputCapsule capsule = im.getCapsule(this); - String[] propNames = capsule.readStringArray("propNames", null), - propValues = capsule.readStringArray("propValues", null); - _props = new Properties(); - for (int ii = 0; ii < propNames.length; ii++) { - _props.setProperty(propNames[ii], propValues[ii]); - } - String[] animNames = capsule.readStringArray("animNames", null); - if (animNames != null) { - Savable[] animValues = capsule.readSavableArray( - "animValues", null); - _anims = Maps.newHashMap(); - for (int ii = 0; ii < animNames.length; ii++) { - _anims.put(animNames[ii], (Animation)animValues[ii]); - } - } else { - _anims = null; - } - List controllers = capsule.readSavableArrayList("controllers", null); - if (controllers != null) { - for (Object ctrl : controllers) { - addController((Controller)ctrl); - } - } - } - - @Override - public void write (JMEExporter ex) - throws IOException - { - // don't serialize the emission node; it contains transient geometry - // created by controllers - if (_emissionNode != null) { - detachChild(_emissionNode); - } - super.write(ex); - if (_emissionNode != null) { - attachChild(_emissionNode); - } - OutputCapsule capsule = ex.getCapsule(this); - capsule.write(_props.keySet().toArray(new String[_props.size()]), - "propNames", null); - capsule.write(_props.values().toArray(new String[_props.size()]), - "propValues", null); - if (_anims != null) { - capsule.write(_anims.keySet().toArray( - new String[_anims.size()]), "animNames", null); - capsule.write(_anims.values().toArray( - new Animation[_anims.size()]), "animValues", null); - } - capsule.writeSavableArrayList(getControllers(), "controllers", null); - } - - @Override - public void resolveTextures (TextureProvider tprov) - { - super.resolveTextures(tprov); - for (Object ctrl : getControllers()) { - if (ctrl instanceof ModelController) { - ((ModelController)ctrl).resolveTextures(tprov); - } - } - } - - /** - * Creates a new prototype using the given variant configuration. - * Use {@link #createInstance} on the returned prototype to create - * additional instances of the variant. - */ - public Model createPrototype (String variant) - { - if (_prototype != null) { - return _prototype.createPrototype(variant); - } - // create an instance and rebind all animations - final Model prototype = createInstance(); - if (_anims != null) { - for (Map.Entry entry : _anims.entrySet()) { - prototype._anims.put(entry.getKey(), - entry.getValue().rebind(prototype._pnodes)); - } - } - prototype._prototype = null; - prototype._pnodes = null; - - // reconfigure meshes with new variant type - if (variant != null) { - prototype._props = PropertiesUtil.getFilteredProperties( - _props, variant); - new SpatialVisitor(ModelMesh.class) { - public void visit (ModelMesh mesh) { - mesh.reconfigure(PropertiesUtil.getFilteredProperties( - prototype._props, mesh.getParent().getName())); - } - }.traverse(prototype); - } - return prototype; - } - - /** - * Creates and returns a new instance of this model. - */ - public Model createInstance () - { - if (_prototype != null) { - return _prototype.createInstance(); - } - if (_ccreator == null) { - _ccreator = new CloneCreator(this); - } - Model instance = _ccreator.createCopy(); - instance.initInstance(); - return instance; - } - - /** - * Locks the transforms and bounds of this model in the expectation that it - * will never be moved from its current position. - */ - public void lockInstance () - { - // collect the instance's animation and controller targets and lock - // recursively - HashSet targets = Sets.newHashSet(); - for (String aname : getAnimationNames()) { - Collections.addAll(targets, getAnimation(aname).transformTargets); - } - for (Object ctrl : getControllers()) { - if (ctrl instanceof ModelController) { - targets.add(((ModelController)ctrl).getTarget()); - } - } - lockInstance(targets); - } - - @Override - public Spatial putClone (Spatial store, CloneCreator properties) - { - Model mstore = (Model)properties.originalToCopy.get(this); - if (mstore != null) { - return mstore; - } else if (store == null) { - mstore = new Model(getName(), _props); - } else { - mstore = (Model)store; - } - // don't clone the emission node, as it contains transient geometry - if (_emissionNode != null) { - detachChild(_emissionNode); - } - super.putClone(mstore, properties); - if (_emissionNode != null) { - attachChild(_emissionNode); - } - mstore._prototype = this; - if (_anims != null) { - mstore._anims = Maps.newHashMap(); - } - mstore._pnodes = Maps.newHashMap(properties.originalToCopy); - mstore._animMode = _animMode; - return mstore; - } - - @Override - public void updateGeometricState (float time, boolean initiator) - { - // if we were not visible the last time we were rendered, don't do a - // full update; just update the world bound and wait until we come - // into view - boolean wasOutside = _outside; - _outside = isOutsideFrustum() && worldBound != null; - - // slow evvvverything down by the animation speed - time *= _animSpeed; - if (_anim != null) { - updateAnimation(time); - } - - // update controllers and children with accumulated time - _accum += time; - if (_outside) { - if ((lockedMode & LOCKED_TRANSFORMS) != 0) { - return; // world bound will not changed - } - if (!wasOutside) { - storeWorldBound(); - } - updateWorldVectors(); - worldBound = _storedBound.transform(getWorldRotation(), - getWorldTranslation(), getWorldScale(), worldBound); - - } else { - super.updateGeometricState(_shouldAccumulate ? _accum : time, - initiator); - _accum = 0f; - } - } - - @Override - public void onDraw (Renderer r) - { - // if we switch from invisible to visible, we have to do a last-minute - // full update (which only works if our meshes are enqueued) - super.onDraw(r); - if (_outside && !isOutsideFrustum()) { - updateWorldData(0f); - } - } - - /** - * Transforms the current world bound into model space and stores it for - * when the model is offscreen. - */ - protected void storeWorldBound () - { - // update the bounds with an identity transform (which will be - // overwritten after this method is called) - getWorldRotation().loadIdentity(); - getWorldTranslation().set(Vector3f.ZERO); - getWorldScale().set(Vector3f.UNIT_XYZ); - for (int ii = 0, nn = getQuantity(); ii < nn; ii++) { - getChild(ii).updateGeometricState(0f, false); - } - updateWorldBound(); - - _storedBound = worldBound.clone(_storedBound); - } - - /** - * Determines whether this node was determined to be entirely outside the - * view frustum. - */ - protected boolean isOutsideFrustum () - { - for (Node node = this; node != null; node = node.getParent()) { - if (node.getLastFrustumIntersection() == Camera.OUTSIDE_FRUSTUM) { - return true; - } - } - return false; - } - - /** - * Initializes the per-instance state of this model. - */ - protected void initInstance () - { - // initialize the controllers - for (Object ctrl : getControllers()) { - if (ctrl instanceof ModelController) { - ModelController mctrl = (ModelController)ctrl; - mctrl.init(this); - _shouldAccumulate |= mctrl.shouldAccumulate(); - } - } - } - - /** - * Updates the model's state according to the current animation. - */ - protected void updateAnimation (float time) - { - // no need to update between frames for flipbook animation - if (_animMode == AnimationMode.FLIPBOOK && _elapsed > 0f && - _elapsed < 1f) { - _elapsed += (time * _anim.frameRate); - return; - } - - // advance the frame counter if necessary - while (_elapsed > 1f) { - if (!_paused) { - advanceFrameCounter(); - _elapsed -= 1f; - } else { - _elapsed = 1f; - } - } - - // update the target transforms and animation frame if not outside the - // view frustum - if (!_outside) { - updateMeshes(); - } - - // if the next index is the same as this one, we are finished - if (_fidx == _nidx && !_paused) { - _anim = null; - _animObservers.apply(new AnimCompletedOp(_animName)); - return; - } - _elapsed += (time * _anim.frameRate); - } - - /** - * Advances the frame counter by one frame. - */ - protected void advanceFrameCounter () - { - _fidx = _nidx; - int nframes = _anim.transforms.length; - if (_anim.repeatType == Controller.RT_CLAMP) { - _nidx = Math.max(0, Math.min(_nidx + _fdir, nframes - 1)); - - } else if (_anim.repeatType == Controller.RT_WRAP) { - // % is not a modulo operator, so is not guaranteed to be positive - _nidx = (_nidx + _fdir) % nframes; - if (_nidx < 0) { - _nidx += nframes; - } - - } else { // _anim.repeatType == Controller.RT_CYCLE - if ((_nidx + _fdir) < 0 || (_nidx + _fdir) >= nframes) { - _fdir *= -1; // reverse direction - } - _nidx += _fdir; - } - } - - /** - * Updates the states of the model's meshes according to the animation state. - */ - protected void updateMeshes () - { - if (_animMode == AnimationMode.FLIPBOOK) { - int frameId = (_anim.animId << 16) | _fidx; - _anim.applyFrame(_fidx); - if (!_anim.stored[_fidx]) { - storeMeshFrame(frameId, false); - updateWorldData(0f); - _anim.stored[_fidx] = true; - } - setMeshFrame(frameId); - - } else if (_animMode == AnimationMode.MORPH) { - int frameId1 = (_anim.animId << 16) | _fidx, - frameId2 = (_anim.animId << 16) | _nidx; - if (!_anim.stored[_fidx]) { - storeMeshFrame(frameId1, true); - _anim.applyFrame(_fidx); - updateWorldData(0f); - _anim.stored[_fidx] = true; - } - if (!_anim.stored[_nidx]) { - storeMeshFrame(frameId2, true); - _anim.applyFrame(_nidx); - updateWorldData(0f); - _anim.stored[_nidx] = true; - } - _anim.blendFrames(_fidx, _nidx, _elapsed); - blendMeshFrames(frameId1, frameId2, _elapsed); - - } else { // _animMode == AnimationMode.SKIN - _anim.blendFrames(_fidx, _nidx, _elapsed); - } - } - - /** A reference to the prototype, or null if this is a prototype. */ - protected Model _prototype; - - /** For prototype models, a customized clone creator used to generate instances. */ - protected CloneCreator _ccreator; - - /** The animation mode to use for this model. */ - protected AnimationMode _animMode; - - /** For instances, maps prototype nodes to their corresponding instance nodes. */ - protected Map _pnodes; - - /** The model properties. */ - protected Properties _props; - - /** The model animations. */ - protected HashMap _anims; - - /** The currently running animation, or null for none. */ - protected Animation _anim; - - /** The name of the currently running animation, if any. */ - protected String _animName; - - /** The current animation speed multiplier. */ - protected float _animSpeed = 1f; - - /** The index of the current and next frames. */ - protected int _fidx, _nidx; - - /** The direction for wrapping animations (+1 forward, -1 backward). */ - protected int _fdir; - - /** The frame portion elapsed since the start of the current frame. */ - protected float _elapsed; - - /** The pause status of this model. */ - protected boolean _paused; - - /** The amount of update time accumulated while outside of view frustum. */ - protected float _accum; - - /** Whether or not we should accumulate update time while out of view. */ - protected boolean _shouldAccumulate; - - /** The child node that contains the model's emissions in world space. */ - protected Node _emissionNode; - - /** The model space bounding volume stored for use when the model is - * offscreen. */ - protected BoundingVolume _storedBound; - - /** Whether or not we were outside the frustum at the last update. */ - protected boolean _outside; - - /** Animation completion listeners. */ - protected ObserverList _animObservers = - new ObserverList(ObserverList.FAST_UNSAFE_NOTIFY); - - /** Used to notify observers of animation initiation. */ - protected class AnimStartedOp - implements ObserverList.ObserverOp - { - public AnimStartedOp (String name) - { - _name = name; - } - - // documentation inherited from interface ObserverOp - public boolean apply (AnimationObserver obs) - { - return obs.animationStarted(Model.this, _name); - } - - /** The name of the animation started. */ - protected String _name; - } - - /** Used to notify observers of animation completion. */ - protected class AnimCompletedOp - implements ObserverList.ObserverOp - { - public AnimCompletedOp (String name) - { - _name = name; - } - - // documentation inherited from interface ObserverOp - public boolean apply (AnimationObserver obs) - { - return obs.animationCompleted(Model.this, _name); - } - - /** The name of the animation completed. */ - protected String _name; - } - - /** Used to notify observers of animation cancellation. */ - protected class AnimCancelledOp - implements ObserverList.ObserverOp - { - public AnimCancelledOp (String name) - { - _name = name; - } - - // documentation inherited from interface ObserverOp - public boolean apply (AnimationObserver obs) - { - return obs.animationCancelled(Model.this, _name); - } - - /** The name of the animation cancelled. */ - protected String _name; - } - - private static final long serialVersionUID = 1; -} diff --git a/src/java/com/threerings/jme/model/ModelController.java b/src/java/com/threerings/jme/model/ModelController.java deleted file mode 100644 index 91e32a25..00000000 --- a/src/java/com/threerings/jme/model/ModelController.java +++ /dev/null @@ -1,188 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.model; - -import java.io.IOException; - -import java.util.Collections; -import java.util.HashSet; -import java.util.Properties; - -import com.google.common.collect.Sets; - -import com.jme.scene.Controller; -import com.jme.scene.Spatial; -import com.jme.util.export.JMEExporter; -import com.jme.util.export.JMEImporter; -import com.jme.util.export.InputCapsule; -import com.jme.util.export.OutputCapsule; - -import com.samskivert.util.StringUtil; - -/** - * The superclass of procedural animation controllers for models. - */ -public abstract class ModelController extends Controller -{ - /** - * Configures this controller based on the supplied (sub-)properties and - * controller target. - */ - public void configure (Properties props, Spatial target) - { - _target = target; - String[] anims = StringUtil.parseStringArray( - props.getProperty("animations", "")); - if (anims.length == 0) { - return; - } - _animations = Sets.newHashSet(); - Collections.addAll(_animations, anims); - } - - /** - * Returns a reference to the controller's target. - */ - public Spatial getTarget () - { - return _target; - } - - /** - * Resolves any textures required by the controller. - */ - public void resolveTextures (TextureProvider tprov) - { - } - - /** - * Initializes this controller. - */ - public void init (Model model) - { - model.addAnimationObserver(_animobs); - if (_animations != null) { - setActive(false); - } - } - - /** - * Determines whether the controller updates should include time - * accumulated while the model was out of sight. Accumulating will - * be turned off only if all controllers are non-accumulating. - */ - public boolean shouldAccumulate () - { - return true; - } - - /** - * Creates or populates and returns a clone of this object using the given - * clone properties. - * - * @param store an instance of this class to populate, or null - * to create a new instance - */ - public Controller putClone ( - Controller store, Model.CloneCreator properties) - { - if (store == null) { - return null; - } - ModelController mstore = (ModelController)store; - mstore._target = ((ModelSpatial)_target).putClone(null, properties); - mstore._animations = _animations; - return mstore; - } - - @Override - public void read (JMEImporter im) - throws IOException - { - InputCapsule capsule = im.getCapsule(this); - _target = (Spatial)capsule.readSavable("target", null); - String[] anims = capsule.readStringArray("animations", null); - if (anims != null) { - _animations = Sets.newHashSet(); - Collections.addAll(_animations, anims); - } else { - _animations = null; - } - } - - @Override - public void write (JMEExporter ex) - throws IOException - { - OutputCapsule capsule = ex.getCapsule(this); - capsule.write(_target, "target", null); - capsule.write((_animations == null) ? - null : _animations.toArray(new String[_animations.size()]), - "animations", null); - } - - /** - * Called when an animation is started on the model. - */ - protected void animationStarted (String anim) - { - if (_animations != null && _animations.contains(anim)) { - setActive(true); - } - } - - /** - * Called when an animation is stopped on the model. - */ - protected void animationStopped (String anim) - { - if (_animations != null) { - setActive(false); - } - } - - /** The target to control. */ - protected Spatial _target; - - /** The animations for which this controller should be active, or - * null for all of them. */ - protected HashSet _animations; - - /** Listens to the model's animation state. */ - protected Model.AnimationObserver _animobs = - new Model.AnimationObserver() { - public boolean animationStarted (Model model, String anim) { - ModelController.this.animationStarted(anim); - return true; - } - public boolean animationCompleted (Model model, String anim) { - animationStopped(anim); - return true; - } - public boolean animationCancelled (Model model, String anim) { - animationStopped(anim); - return true; - } - }; - - private static final long serialVersionUID = 1; -} diff --git a/src/java/com/threerings/jme/model/ModelMesh.java b/src/java/com/threerings/jme/model/ModelMesh.java deleted file mode 100644 index f5a05c13..00000000 --- a/src/java/com/threerings/jme/model/ModelMesh.java +++ /dev/null @@ -1,904 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.model; - -import java.io.IOException; -import java.nio.FloatBuffer; -import java.nio.IntBuffer; - -import java.util.ArrayList; -import java.util.Properties; - -import com.google.common.collect.Lists; - -import com.jme.bounding.BoundingBox; -import com.jme.bounding.BoundingSphere; -import com.jme.bounding.BoundingVolume; -import com.jme.image.Image; -import com.jme.image.Texture; -import com.jme.math.FastMath; -import com.jme.math.Quaternion; -import com.jme.math.Vector3f; -import com.jme.renderer.ColorRGBA; -import com.jme.renderer.Renderer; -import com.jme.scene.Spatial; -import com.jme.scene.TriMesh; -import com.jme.scene.VBOInfo; -import com.jme.scene.batch.TriangleBatch; -import com.jme.scene.state.AlphaState; -import com.jme.scene.state.CullState; -import com.jme.scene.state.FogState; -import com.jme.scene.state.LightState; -import com.jme.scene.state.RenderState; -import com.jme.scene.state.TextureState; -import com.jme.scene.state.ZBufferState; -import com.jme.system.DisplaySystem; -import com.jme.util.export.JMEExporter; -import com.jme.util.export.JMEImporter; -import com.jme.util.export.InputCapsule; -import com.jme.util.export.OutputCapsule; -import com.jme.util.geom.BufferUtils; - -import com.samskivert.util.PropertiesUtil; -import com.samskivert.util.StringUtil; - -import com.threerings.jme.util.ShaderCache; - -/** - * A {@link TriMesh} with a serialization mechanism tailored to stored models. - */ -public class ModelMesh extends TriMesh - implements ModelSpatial -{ - /** - * No-arg constructor for deserialization. - */ - public ModelMesh () - { - super("mesh"); - } - - /** - * Creates a mesh with no vertex data. - */ - public ModelMesh (String name) - { - super(name); - } - - @Override - public int hashCode () - { - // hash on the name rather than the identity for consistent ordering - return getName().hashCode(); - } - - /** - * Reconfigures this model with a new set of (sub-)properties. Textures - * must be (re-)resolved after calling this method. - */ - public void reconfigure (Properties props) - { - configure(_solid, _textureKey, _transparent, props); - setRenderStates(); - } - - /** - * Configures this mesh based on the given parameters and (sub-)properties. - * - * @param texture the texture specified in the model export, if any (can be - * overridden by textures specified in the properties) - * @param solid whether or not the mesh allows back face culling - * @param transparent whether or not the mesh is (partially) transparent - */ - public void configure ( - boolean solid, String texture, boolean transparent, Properties props) - { - _textureKey = texture; - _textures = (texture == null) ? null : StringUtil.parseStringArray( - props.getProperty(texture, texture)); - Properties tprops = PropertiesUtil.getFilteredProperties( - props, texture); - _sphereMapped = Boolean.parseBoolean(tprops.getProperty("sphere_map")); - _filterMode = "nearest".equals(tprops.getProperty("filter")) ? - Texture.FM_NEAREST : Texture.FM_LINEAR; - _mipMapMode = getMipMapMode(tprops.getProperty("mipmap")); - _compress = Boolean.parseBoolean(tprops.getProperty("compress", "true")); - String emissive = tprops.getProperty("emissive"); - if (Boolean.parseBoolean(emissive)) { - _emissive = true; - } else { - _emissiveMap = emissive; - } - _additive = Boolean.parseBoolean(tprops.getProperty("additive")); - _solid = solid; - _transparent = transparent; - String threshold = tprops.getProperty("alpha_threshold"); - _alphaThreshold = (threshold == null) ? - DEFAULT_ALPHA_THRESHOLD : Float.parseFloat(threshold); - _translucent = _transparent && - Boolean.parseBoolean(tprops.getProperty("translucent")); - } - - /** - * Adjusts the vertices and the transform of the mesh so that the mesh's - * position lies at the center of its bounding volume. - */ - public void centerVertices () - { - Vector3f offset = getBatch(0).getModelBound().getCenter().negate(); - if (!offset.equals(Vector3f.ZERO)) { - getLocalTranslation().subtractLocal(offset); - getBatch(0).getModelBound().getCenter().set(Vector3f.ZERO); - getBatch(0).translatePoints(offset); - } - storeOriginalBuffers(); - } - - /** - * Adds an overlay layer to this mesh. After the mesh is rendered with - * its configured states, these states will be applied and the mesh will - * be rendered again. - */ - public void addOverlay (RenderState[] overlay) - { - if (_overlays == null) { - _overlays = Lists.newArrayListWithCapacity(1); - } - _overlays.add(overlay); - } - - /** - * Removes a layer from this mesh. - */ - public void removeOverlay (RenderState[] overlay) - { - if (_overlays != null) { - _overlays.remove(overlay); - if (_overlays.isEmpty()) { - _overlays = null; - } - } - } - - @Override - public void reconstruct ( - FloatBuffer vertices, FloatBuffer normals, FloatBuffer colors, - FloatBuffer textures, IntBuffer indices) - { - super.reconstruct(vertices, normals, colors, textures, indices); - for (int ii = 1, nn = getTextureCount(); ii < nn; ii++) { - setTextureBuffer(0, getTextureBuffer(0, 0), ii); - } - - // store any buffers that will be manipulated on a per-instance basis - storeOriginalBuffers(); - - // initialize the model if we're displaying - setRenderStates(); - } - - // documentation inherited from interface ModelSpatial - public Spatial putClone (Spatial store, Model.CloneCreator properties) - { - ModelMesh mstore = (ModelMesh)properties.originalToCopy.get(this); - if (mstore != null) { - return mstore; - } else if (store == null) { - mstore = new ModelMesh(getName()); - } else { - mstore = (ModelMesh)store; - } - properties.originalToCopy.put(this, mstore); - mstore.normalsMode = normalsMode; - mstore.cullMode = cullMode; - for (int ii = 0; ii < RenderState.RS_MAX_STATE; ii++) { - RenderState rstate = getRenderState(ii); - if (rstate != null) { - mstore.setRenderState(rstate); - } - } - mstore.renderQueueMode = renderQueueMode; - mstore.lockedMode = lockedMode; - mstore.lightCombineMode = lightCombineMode; - mstore.textureCombineMode = textureCombineMode; - mstore.name = name; - mstore.isCollidable = isCollidable; - mstore.localRotation.set(localRotation); - mstore.localTranslation.set(localTranslation); - mstore.localScale.set(localScale); - for (Object controller : getControllers()) { - if (controller instanceof ModelController) { - mstore.addController( - ((ModelController)controller).putClone(null, properties)); - } - } - TriangleBatch batch = getBatch(0), mbatch = mstore.getBatch(0); - mbatch.setVertexBuffer(properties.isSet("vertices") ? - batch.getVertexBuffer() : - BufferUtils.clone(batch.getVertexBuffer())); - mbatch.setColorBuffer(properties.isSet("colors") ? - batch.getColorBuffer() : - BufferUtils.clone(batch.getColorBuffer())); - mbatch.setNormalBuffer(properties.isSet("normals") ? - batch.getNormalBuffer() : - BufferUtils.clone(batch.getNormalBuffer())); - FloatBuffer texcoords; - for (int ii = 0; (texcoords = batch.getTextureBuffer(ii)) != null; - ii++) { - mbatch.setTextureBuffer(properties.isSet("texcoords") ? - texcoords : BufferUtils.clone(texcoords), ii); - } - mbatch.setIndexBuffer((properties.isSet("indices") && !_translucent) ? - batch.getIndexBuffer() : - BufferUtils.clone(batch.getIndexBuffer())); - if (properties.isSet("vboinfo")) { - mbatch.setVBOInfo(batch.getVBOInfo()); - } - if (properties.isSet("obbtree")) { - mbatch.setCollisionTree(batch.getCollisionTree()); - } - if (properties.isSet("displaylistid")) { - mbatch.setDisplayListID(batch.getDisplayListID()); - } - if (batch.getModelBound() != null) { - mbatch.setModelBound(properties.isSet("bound") ? - batch.getModelBound() : batch.getModelBound().clone(null)); - } - mstore._textureKey = _textureKey; - if (_textures != null && _textures.length > 1) { - int tidx = properties.random % _textures.length; - mstore._textures = new String[] { _textures[tidx] }; - mstore._tstates = new TextureState[] { _tstates[tidx] }; - mstore.setRenderState(_tstates[tidx]); - } else { - mstore._textures = _textures; - mstore._tstates = _tstates; - } - mstore._sphereMapped = _sphereMapped; - mstore._filterMode = _filterMode; - mstore._mipMapMode = _mipMapMode; - mstore._compress = _compress; - mstore._emissiveMap = _emissiveMap; - mstore._emissive = _emissive; - mstore._additive = _additive; - mstore._solid = _solid; - mstore._transparent = _transparent; - mstore._alphaThreshold = _alphaThreshold; - mstore._translucent = _translucent; - mstore._oibuf = _oibuf; - mstore._vbuf = _vbuf; - return mstore; - } - - @Override - public void updateWorldVectors () - { - if (!_transformLocked) { - super.updateWorldVectors(); - } - } - - @Override - public void read (JMEImporter im) - throws IOException - { - InputCapsule capsule = im.getCapsule(this); - setName(capsule.readString("name", null)); - setLocalTranslation((Vector3f)capsule.readSavable( - "localTranslation", null)); - setLocalRotation((Quaternion)capsule.readSavable( - "localRotation", null)); - setLocalScale((Vector3f)capsule.readSavable( - "localScale", null)); - TriangleBatch batch = getBatch(0); - batch.setModelBound((BoundingVolume)capsule.readSavable( - "modelBound", null)); - _textureKey = capsule.readString("textureKey", null); - _textures = capsule.readStringArray("textures", null); - _sphereMapped = capsule.readBoolean("sphereMapped", false); - _filterMode = capsule.readInt("filterMode", Texture.FM_LINEAR); - _mipMapMode = capsule.readInt("mipMapMode", Texture.MM_LINEAR_LINEAR); - _compress = capsule.readBoolean("compress", true); - _emissiveMap = capsule.readString("emissiveMap", null); - _emissive = capsule.readBoolean("emissive", false); - _additive = capsule.readBoolean("additive", false); - _solid = capsule.readBoolean("solid", true); - _transparent = capsule.readBoolean("transparent", false); - _alphaThreshold = capsule.readFloat("alphaThreshold", - DEFAULT_ALPHA_THRESHOLD); - _translucent = capsule.readBoolean("translucent", false); - - reconstruct(capsule.readFloatBuffer("vertexBuffer", null), - capsule.readFloatBuffer("normalBuffer", null), null, - capsule.readFloatBuffer("textureBuffer", null), - capsule.readIntBuffer("indexBuffer", null)); - } - - @Override - public void write (JMEExporter ex) - throws IOException - { - OutputCapsule capsule = ex.getCapsule(this); - capsule.write(getName(), "name", null); - capsule.write(getLocalTranslation(), "localTranslation", null); - capsule.write(getLocalRotation(), "localRotation", null); - capsule.write(getLocalScale(), "localScale", null); - capsule.write(getBatch(0).getModelBound(), "modelBound", null); - capsule.write(getVertexBuffer(0), "vertexBuffer", null); - capsule.write(getNormalBuffer(0), "normalBuffer", null); - capsule.write(getTextureBuffer(0, 0), "textureBuffer", null); - capsule.write(getIndexBuffer(0), "indexBuffer", null); - capsule.write(_textureKey, "textureKey", null); - capsule.write(_textures, "textures", null); - capsule.write(_sphereMapped, "sphereMapped", false); - capsule.write(_filterMode, "filterMode", Texture.FM_LINEAR); - capsule.write(_mipMapMode, "mipMapMode", Texture.MM_LINEAR_LINEAR); - capsule.write(_compress, "compress", true); - capsule.write(_emissiveMap, "emissiveMap", null); - capsule.write(_emissive, "emissive", false); - capsule.write(_additive, "additive", false); - capsule.write(_solid, "solid", true); - capsule.write(_transparent, "transparent", false); - capsule.write(_alphaThreshold, "alphaThreshold", - DEFAULT_ALPHA_THRESHOLD); - capsule.write(_translucent, "translucent", false); - } - - // documentation inherited from interface ModelSpatial - public void expandModelBounds () - { - // no-op - } - - // documentation inherited from interface ModelSpatial - public void setReferenceTransforms () - { - // no-op - } - - // documentation inherited from interface ModelSpatial - public void lockStaticMeshes ( - Renderer renderer, boolean useVBOs, boolean useDisplayLists) - { - if (useVBOs && renderer.supportsVBO()) { - VBOInfo vboinfo = new VBOInfo(true); - vboinfo.setVBOIndexEnabled(!_translucent); - setVBOInfo(vboinfo); - - } else if (useDisplayLists && !_translucent) { - lockMeshes(renderer); - } - } - - // documentation inherited from interface ModelSpatial - public void resolveTextures (TextureProvider tprov) - { - if (_textures == null) { - return; - } - Texture emissiveTex = null; - if (_emissiveMap != null && TextureState.getNumberOfFixedUnits() >= 2) { - TextureState tstate = tprov.getTexture(_emissiveMap); - emissiveTex = tstate.getTexture(); - emissiveTex.setApply(Texture.AM_BLEND); - emissiveTex.getBlendColor().set(ColorRGBA.white); - } - _tstates = new TextureState[_textures.length]; - for (int ii = 0; ii < _textures.length; ii++) { - _tstates[ii] = tprov.getTexture(_textures[ii]); - Texture tex = _tstates[ii].getTexture(); - if (_sphereMapped) { - tex.setEnvironmentalMapMode(Texture.EM_SPHERE); - } - tex.setFilter(_filterMode); - tex.setMipmapState(_mipMapMode); - if (_compress && _tstates[ii].isS3TCAvailable()) { - Image image = tex.getImage(); - int type = image.getType(); - if (type == Image.RGB888) { - image.setType(Image.RGB888_DXT1); - } else if (type == Image.RGBA8888) { - image.setType(Image.RGBA8888_DXT5); - } - } - if (emissiveTex != null) { - _tstates[ii] = DisplaySystem.getDisplaySystem(). - getRenderer().createTextureState(); - _tstates[ii].setTexture(emissiveTex, 0); - _tstates[ii].setTexture(tex, 1); - } - } - if (_tstates[0] != null) { - setRenderState(_tstates[0]); - } else { - clearRenderState(RenderState.RS_TEXTURE); - } - } - - // documentation inherited from interface ModelSpatial - public void configureShaders (ShaderCache scache) - { - // no-op - } - - // documentation inherited from interface ModelSpatial - public void storeMeshFrame (int frameId, boolean blend) - { - // no-op - } - - // documentation inherited from interface ModelSpatial - public void setMeshFrame (int frameId) - { - // no-op - } - - // documentation inherited from interface ModelSpatial - public void blendMeshFrames (int frameId1, int frameId2, float alpha) - { - // no-op - } - - @Override - protected void setupBatchList () - { - batchList = Lists.newArrayListWithCapacity(1); - TriangleBatch batch = createModelBatch(); - batch.setParentGeom(this); - batchList.add(batch); - } - - /** - * Creates a batch for this mesh. - */ - protected ModelBatch createModelBatch () - { - return new ModelBatch(); - } - - /** - * Returns the number of textures this mesh uses (they must all share the - * same texture coordinates). - */ - protected int getTextureCount () - { - return (_emissiveMap == null || TextureState.getNumberOfFixedUnits() < 2) ? 1 : 2; - } - - /** - * For buffers that must be manipulated in some fashion, this method stores - * the originals. - */ - protected void storeOriginalBuffers () - { - if (!_translucent) { - return; - } - IntBuffer ibuf = getIndexBuffer(0); - ibuf.rewind(); - IntBuffer.wrap(_oibuf = new int[ibuf.capacity()]).put(ibuf); - - FloatBuffer vbuf = getVertexBuffer(0); - vbuf.rewind(); - FloatBuffer.wrap(_vbuf = new float[vbuf.capacity()]).put(vbuf); - } - - /** - * Sets the model's render states (excluding the texture state, which is - * set by {@link #resolveTextures}) according to its configuration. - */ - protected void setRenderStates () - { - if (DisplaySystem.getDisplaySystem() == null) { - return; - } - if (_backCull == null) { - initSharedStates(); - } - if (_emissive) { - setRenderState(_emissiveLight); - } - if (_solid) { - setRenderState(_backCull); - } - if (_additive) { - setRenderQueueMode(Renderer.QUEUE_TRANSPARENT); - setRenderState(_addAlpha); - setRenderState(_overlayZBuffer); - setRenderState(_noFog); - } else if (_transparent) { - setRenderQueueMode(Renderer.QUEUE_TRANSPARENT); - if (_translucent) { - setRenderState(_blendAlpha); - setRenderState(_overlayZBuffer); - } else if (_alphaThreshold == DEFAULT_ALPHA_THRESHOLD) { - setRenderState(_defaultTestAlpha); - } else { - setRenderState(createTestAlpha(_alphaThreshold)); - } - } - } - - /** - * Locks the transform and bounds of this mesh on the assumption that its - * position will not change. - */ - protected void lockInstance () - { - lockBounds(); - _transformLocked = true; - } - - /** - * Returns the mip-map mode corresponding to the given string - * (defaulting to {@link Texture#MM_LINEAR_LINEAR}). - */ - protected static int getMipMapMode (String mmode) - { - if ("none".equals(mmode)) { - return Texture.MM_NONE; - } else if ("nearest".equals(mmode)) { - return Texture.MM_NEAREST; - } else if ("linear".equals(mmode)) { - return Texture.MM_LINEAR; - } else if ("nearest_nearest".equals(mmode)) { - return Texture.MM_NEAREST_NEAREST; - } else if ("nearest_linear".equals(mmode)) { - return Texture.MM_NEAREST_LINEAR; - } else if ("linear_nearest".equals(mmode)) { - return Texture.MM_LINEAR_NEAREST; - } else { - return Texture.MM_LINEAR_LINEAR; - } - } - - /** - * Initializes the states shared between all models. Requires an active - * display. - */ - protected static void initSharedStates () - { - Renderer renderer = DisplaySystem.getDisplaySystem().getRenderer(); - _backCull = renderer.createCullState(); - _backCull.setCullMode(CullState.CS_BACK); - _blendAlpha = renderer.createAlphaState(); - _blendAlpha.setBlendEnabled(true); - _addAlpha = renderer.createAlphaState(); - _addAlpha.setBlendEnabled(true); - _addAlpha.setDstFunction(AlphaState.DB_ONE); - _defaultTestAlpha = createTestAlpha(DEFAULT_ALPHA_THRESHOLD); - _overlayZBuffer = renderer.createZBufferState(); - _overlayZBuffer.setFunction(ZBufferState.CF_LEQUAL); - _overlayZBuffer.setWritable(false); - _emissiveLight = renderer.createLightState(); - _emissiveLight.setGlobalAmbient(ColorRGBA.white); - _noFog = renderer.createFogState(); - _noFog.setEnabled(false); - } - - /** - * Creates an alpha state what will throw away fragments with alpha - * values less than or equal to the given threshold. - */ - protected static AlphaState createTestAlpha (float threshold) - { - AlphaState astate = DisplaySystem.getDisplaySystem(). - getRenderer().createAlphaState(); - astate.setBlendEnabled(true); - astate.setTestEnabled(true); - astate.setTestFunction(AlphaState.TF_GREATER); - astate.setReference(threshold); - return astate; - } - - /** - * Sorts the encoded triangle index/distance pairs in {@link #_tcodes} - * using a two-pass (16 bit) radix sort (as described by - * Pierre - * Terdiman. {@link #_bcounts} is assumed to be initialized to the - * counts for the first radix. - */ - protected static void sortTriangleCodes (int tcount) - { - // initialize the offsets for the first radix (LSB) and clear - // the counts - initByteOffsets(); - - // sort by the first radix and get the counts for the second - // (swapping directions in the hope of using the cache more - // effectively) - if (_stcodes == null || _stcodes.length < tcount) { - _stcodes = new int[tcount]; - } - int tcode; - for (int ii = tcount - 1; ii >= 0; ii--) { - tcode = _tcodes[ii]; - _stcodes[_boffsets[tcode & 0xFF]++] = tcode; - _bcounts[(tcode >> 8) & 0xFF]++; - } - - // initialize offsets for the second radix, clear counts, and - // sort by the second radix - initByteOffsets(); - for (int ii = 0; ii < tcount; ii++) { - tcode = _stcodes[ii]; - _tcodes[_boffsets[(tcode >> 8) & 0xFF]++] = tcode; - } - } - - /** - * Sets the initial byte offsets used to place bytes within the sorted - * array using the byte counts, clearing the counts in the process. - */ - protected static void initByteOffsets () - { - _boffsets[0] = 0; - for (int ii = 1; ii < 256; ii++) { - _boffsets[ii] = _boffsets[ii - 1] + _bcounts[ii - 1]; - _bcounts[ii - 1] = 0; - } - _bcounts[255] = 0; - } - - /** Sorts triangles for transparent meshes and renders overlays as well as - * the base layer. */ - protected class ModelBatch extends TriangleBatch - { - @Override - public void draw (Renderer r) - { - boolean drawing = (isEnabled() && r.isProcessingQueue()); - if (drawing) { - if (_translucent) { - sortTriangles(r); - } - preDraw(); - } - super.draw(r); - if (_overlays != null && drawing) { - for (int ii = 0, nn = _overlays.size(); ii < nn; ii++) { - preDrawOverlay(ii); - r.draw(this); - postDrawOverlay(ii); - } - } - } - - /** - * Gives derived classes a chance to update states immediately before drawing. - */ - protected void preDraw () - { - } - - /** - * Updates the batch's states with those of the identified overlay. - */ - protected void preDrawOverlay (int oidx) - { - RenderState[] overlay = _overlays.get(oidx); - for (RenderState rstate : overlay) { - int idx = rstate.getType(); - _ostates[idx] = states[idx]; - states[idx] = rstate; - } - } - - /** - * Restores the batch's original states after drawing an overlay. - */ - protected void postDrawOverlay (int oidx) - { - RenderState[] overlay = _overlays.get(oidx); - for (RenderState rstate : overlay) { - int idx = rstate.getType(); - states[idx] = _ostates[idx]; - } - } - - /** - * Sorts the batch's triangles by their distance to the camera. - */ - protected void sortTriangles (Renderer r) - { - // using the camera's direction in model space and the position - // and size of the model bound, find a set of plane parameters - // that determine the distance to a camera-aligned plane - // that touches the near edge of the bounding volume, as well - // as a scaling factor that brings the distance into a 16-bit - // integer range - getParentGeom().getWorldRotation().inverse().mult( - r.getCamera().getDirection(), _cdir); - BoundingVolume mbound = getModelBound(); - Vector3f mc = mbound.getCenter(); - float radius; - if (mbound instanceof BoundingSphere) { - radius = ((BoundingSphere)mbound).getRadius(); - } else { // mbound instanceof BoundingBox - BoundingBox bbox = (BoundingBox)mbound; - radius = FastMath.sqrt(3f) * Math.max(bbox.xExtent, - Math.max(bbox.yExtent, bbox.zExtent)); - } - float a = _cdir.x, b = _cdir.y, c = _cdir.z, - d = radius - a*mc.x - b*mc.y - c*mc.z, - dscale = 65535f / (radius * 2); - - // premultiply the scale and averaging factor - a *= dscale / 3f; - b *= dscale / 3f; - c *= dscale / 3f; - d *= dscale; - - // encode the model's triangles into integers such that the - // high 16 bits represent the original triangle index and the - // low 16 bits represent the distance to the plane. also - // increment the byte counts used for radix sorting - int tcount = getTriangleCount(), idist; - if (_tcodes == null || _tcodes.length < tcount) { - _tcodes = new int[tcount]; - } - int i1, i2, i3; - for (int ii = 0, idx = 0; ii < tcount; ii++) { - i1 = _oibuf[idx++] * 3; - i2 = _oibuf[idx++] * 3; - i3 = _oibuf[idx++] * 3; - idist = (int)( - a * (_vbuf[i1++] + _vbuf[i2++] + _vbuf[i3++]) + - b * (_vbuf[i1++] + _vbuf[i2++] + _vbuf[i3++]) + - c * (_vbuf[i1++] + _vbuf[i2++] + _vbuf[i3++]) + d); - _tcodes[ii] = (ii << 16) | idist; - _bcounts[idist & 0xFF]++; - } - - // sort the encoded triangles by increasing distance - sortTriangleCodes(tcount); - - // reorder the triangles as dictated by the sorted codes, furthest - // triangles first - int icount = tcount * 3, idx; - if (_sibuf == null || _sibuf.length < icount) { - _sibuf = new int[icount]; - } - for (int ii = tcount - 1, sidx = 0; ii >= 0; ii--) { - idx = ((_tcodes[ii] >> 16) & 0xFFFF) * 3; - _sibuf[sidx++] = _oibuf[idx++]; - _sibuf[sidx++] = _oibuf[idx++]; - _sibuf[sidx++] = _oibuf[idx]; - } - - // copy the indices to the buffer - IntBuffer ibuf = getIndexBuffer(); - ibuf.rewind(); - ibuf.put(_sibuf, 0, icount); - } - - /** - * Gives derived classes a chance to update the states immediately before drawing. - * - * @param oidx the index of the overlay being rendered, or -1 for the base layer. - */ - protected void processStates (int oidx) - { - } - - /** Temporarily stores the original states. */ - protected RenderState[] _ostates = - new RenderState[RenderState.RS_MAX_STATE]; - } - - /** The name of the texture specified in the model file, which acts as a - * property key and a default value. */ - protected String _textureKey; - - /** The name of this model's textures, or null for none. */ - protected String[] _textures; - - /** Whether or not to use sphere mapping on this model's textures. */ - protected boolean _sphereMapped; - - /** The filter mode to use on magnification. */ - protected int _filterMode; - - /** The mipmap mode to use on minification. */ - protected int _mipMapMode; - - /** Whether or not to use compressed textures, if available. */ - protected boolean _compress; - - /** The emissive map, if specified. */ - protected String _emissiveMap; - - /** Whether or not this mesh is completely emissive. */ - protected boolean _emissive; - - /** Whether or not this mesh should be rendered with additive blending. */ - protected boolean _additive; - - /** Whether or not this mesh can enable back-face culling. */ - protected boolean _solid; - - /** Whether or not this mesh must be rendered as transparent. */ - protected boolean _transparent; - - /** The alpha threshold below which fragments are discarded. */ - protected float _alphaThreshold; - - /** Whether or not the triangles of this mesh should be depth-sorted before - * rendering. */ - protected boolean _translucent; - - /** If non-null, additional layers to render over the base layer. */ - protected ArrayList _overlays; - - /** For prototype meshes, the resolved texture states. */ - protected TextureState[] _tstates; - - /** Whether or not the transform has been locked. This operates in a - * slightly different way than JME's locking, in that it allows applying - * transformations to display lists. */ - protected boolean _transformLocked; - - /** For depth-sorted and skinned meshes, the array of vertices. */ - protected float[] _vbuf; - - /** For depth-sorted meshes, the original array of indices. */ - protected int[] _oibuf; - - /** The shared state for back face culling. */ - protected static CullState _backCull; - - /** The shared state for alpha blending. */ - protected static AlphaState _blendAlpha; - - /** The shared state for additive blending. */ - protected static AlphaState _addAlpha; - - /** The shared state for alpha testing with the default threshold. */ - protected static AlphaState _defaultTestAlpha; - - /** The shared state for checking, but not writing to, the z buffer. */ - protected static ZBufferState _overlayZBuffer; - - /** A light state that simulates emissivity. */ - protected static LightState _emissiveLight; - - /** A fog state that disables fog. */ - protected static FogState _noFog; - - /** Work vector to store the camera direction. */ - protected static Vector3f _cdir = new Vector3f(); - - /** Work arrays used to sort triangles. */ - protected static int[] _tcodes, _stcodes; - - /** Holds counts of each byte and array offsets for radix sorting. */ - protected static int[] _bcounts = new int[256], _boffsets = new int[256]; - - /** Work array used to hold indices of sorted triangles. */ - protected static int[] _sibuf; - - /** The default alpha threshold. */ - protected static final float DEFAULT_ALPHA_THRESHOLD = 0.5f; - - private static final long serialVersionUID = 1; -} diff --git a/src/java/com/threerings/jme/model/ModelNode.java b/src/java/com/threerings/jme/model/ModelNode.java deleted file mode 100644 index b31bf3e6..00000000 --- a/src/java/com/threerings/jme/model/ModelNode.java +++ /dev/null @@ -1,414 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.model; - -import java.io.IOException; - -import java.util.HashSet; -import java.util.List; - -import com.jme.math.Matrix4f; -import com.jme.math.Quaternion; -import com.jme.math.Vector3f; -import com.jme.renderer.Renderer; -import com.jme.scene.Node; -import com.jme.scene.Spatial; -import com.jme.scene.state.RenderState; -import com.jme.util.export.JMEExporter; -import com.jme.util.export.JMEImporter; -import com.jme.util.export.InputCapsule; -import com.jme.util.export.OutputCapsule; - -import com.threerings.jme.util.JmeUtil; -import com.threerings.jme.util.ShaderCache; - -/** - * A {@link Node} with a serialization mechanism tailored to stored models. - */ -public class ModelNode extends Node - implements ModelSpatial -{ - /** - * No-arg constructor for deserialization. - */ - public ModelNode () - { - super("node"); - } - - /** - * Standard constructor. - */ - public ModelNode (String name) - { - super(name); - } - - @Override - public int hashCode () - { - // hash on the name rather than the identity for consistent ordering - return getName().hashCode(); - } - - /** - * Recursively searches the scene graph rooted at this node for a - * node with the provided name. - */ - public Spatial getDescendant (String name) - { - for (int ii = 0, nn = getQuantity(); ii < nn; ii++) { - Spatial child = getChild(ii); - if (child.getName().equals(name)) { - return child; - } else if (child instanceof ModelNode) { - child = ((ModelNode)child).getDescendant(name); - if (child != null) { - return child; - } - } - } - return null; - } - - /** - * Returns a reference to the model space transform of the node. - */ - public Matrix4f getModelTransform () - { - return _modelTransform; - } - - @Override - public void updateWorldData (float time) - { - // we use locked bounds as an indication that we can skip the update - // altogether - if ((lockedMode & LOCKED_BOUNDS) == 0) { - super.updateWorldData(time); - } - } - - @Override - public void updateWorldBound () - { - // don't bother updating if we know there are no visible descendants - if (_hasVisibleDescendants) { - super.updateWorldBound(); - } - } - - @Override - public void updateWorldVectors () - { - super.updateWorldVectors(); - if (parent instanceof ModelNode) { - JmeUtil.setTransform(getLocalTranslation(), getLocalRotation(), - getLocalScale(), _localTransform); - ((ModelNode)parent).getModelTransform().mult(_localTransform, - _modelTransform); - - } else { - _modelTransform.loadIdentity(); - } - } - - // documentation inherited from interface ModelSpatial - public Spatial putClone (Spatial store, Model.CloneCreator properties) - { - ModelNode mstore = (ModelNode)properties.originalToCopy.get(this); - if (mstore != null) { - return mstore; - } else if (store == null) { - mstore = new ModelNode(getName()); - } else { - mstore = (ModelNode)store; - } - properties.originalToCopy.put(this, mstore); - mstore.normalsMode = normalsMode; - mstore.cullMode = cullMode; - for (int ii = 0; ii < RenderState.RS_MAX_STATE; ii++) { - RenderState rstate = getRenderState(ii); - if (rstate != null) { - mstore.setRenderState(rstate); - } - } - mstore.renderQueueMode = renderQueueMode; - mstore.lockedMode = lockedMode; - mstore.lightCombineMode = lightCombineMode; - mstore.textureCombineMode = textureCombineMode; - mstore.name = name; - mstore.isCollidable = isCollidable; - mstore.localRotation.set(localRotation); - mstore.localTranslation.set(localTranslation); - mstore.localScale.set(localScale); - for (Object controller : getControllers()) { - if (controller instanceof ModelController) { - mstore.addController( - ((ModelController)controller).putClone(null, properties)); - } - } - for (int ii = 0, nn = getQuantity(); ii < nn; ii++) { - Spatial child = getChild(ii); - if (child instanceof ModelSpatial) { - mstore.attachChild( - ((ModelSpatial)child).putClone(null, properties)); - } - } - mstore._hasVisibleDescendants = _hasVisibleDescendants; - return mstore; - } - - @Override - public void read (JMEImporter im) - throws IOException - { - InputCapsule capsule = im.getCapsule(this); - setName(capsule.readString("name", null)); - setLocalTranslation((Vector3f)capsule.readSavable( - "localTranslation", null)); - setLocalRotation((Quaternion)capsule.readSavable( - "localRotation", null)); - setLocalScale((Vector3f)capsule.readSavable( - "localScale", null)); - List children = capsule.readSavableArrayList("children", null); - if (children != null) { - for (Object child : children) { - attachChild((Spatial)child); - } - } - } - - @Override - public void write (JMEExporter ex) - throws IOException - { - OutputCapsule capsule = ex.getCapsule(this); - capsule.write(getName(), "name", null); - capsule.write(getLocalTranslation(), "localTranslation", null); - capsule.write(getLocalRotation(), "localRotation", null); - capsule.write(getLocalScale(), "localScale", null); - capsule.writeSavableArrayList(getChildren(), "children", null); - } - - // documentation inherited from interface ModelSpatial - public void expandModelBounds () - { - for (int ii = 0, nn = getQuantity(); ii < nn; ii++) { - Spatial child = getChild(ii); - if (child instanceof ModelSpatial) { - ((ModelSpatial)child).expandModelBounds(); - } - } - } - - // documentation inherited from interface ModelSpatial - public void setReferenceTransforms () - { - updateWorldVectors(); - for (int ii = 0, nn = getQuantity(); ii < nn; ii++) { - Spatial child = getChild(ii); - if (child instanceof ModelSpatial) { - ((ModelSpatial)child).setReferenceTransforms(); - } - } - } - - // documentation inherited from interface ModelSpatial - public void lockStaticMeshes ( - Renderer renderer, boolean useVBOs, boolean useDisplayLists) - { - for (int ii = 0, nn = getQuantity(); ii < nn; ii++) { - Spatial child = getChild(ii); - if (child instanceof ModelSpatial) { - ((ModelSpatial)child).lockStaticMeshes(renderer, useVBOs, - useDisplayLists); - } - } - } - - // documentation inherited from interface ModelSpatial - public void resolveTextures (TextureProvider tprov) - { - for (int ii = 0, nn = getQuantity(); ii < nn; ii++) { - Spatial child = getChild(ii); - if (child instanceof ModelSpatial) { - ((ModelSpatial)child).resolveTextures(tprov); - } - } - } - - // documentation inherited from interface ModelSpatial - public void configureShaders (ShaderCache scache) - { - for (int ii = 0, nn = getQuantity(); ii < nn; ii++) { - Spatial child = getChild(ii); - if (child instanceof ModelSpatial) { - ((ModelSpatial)child).configureShaders(scache); - } - } - } - - // documentation inherited from interface ModelSpatial - public void storeMeshFrame (int frameId, boolean blend) - { - for (int ii = 0, nn = getQuantity(); ii < nn; ii++) { - Spatial child = getChild(ii); - if (child instanceof ModelSpatial) { - ((ModelSpatial)child).storeMeshFrame(frameId, blend); - } - } - } - - // documentation inherited from interface ModelSpatial - public void setMeshFrame (int frameId) - { - for (int ii = 0, nn = getQuantity(); ii < nn; ii++) { - Spatial child = getChild(ii); - if (child instanceof ModelSpatial) { - ((ModelSpatial)child).setMeshFrame(frameId); - } - } - } - - // documentation inherited from interface ModelSpatial - public void blendMeshFrames (int frameId1, int frameId2, float alpha) - { - for (int ii = 0, nn = getQuantity(); ii < nn; ii++) { - Spatial child = getChild(ii); - if (child instanceof ModelSpatial) { - ((ModelSpatial)child).blendMeshFrames( - frameId1, frameId2, alpha); - } - } - } - - /** - * Sets whether this node should be culled even if it has mesh - * descendants. - */ - public void setForceCull (boolean force) - { - _forceCull = force; - } - - /** - * Checks whether this node should be culled even if it has mesh - * descendants. - */ - public boolean getForceCull () - { - return _forceCull; - } - - /** - * Sets the cull state of any nodes that do not contain geometric - * descendants to {@link CULL_ALWAYS} so that they don't waste - * rendering time. - * - * @return true if this node should be drawn, false if it contains - * no mesh descendants - */ - protected boolean cullInvisibleNodes () - { - for (int ii = 0, nn = getQuantity(); ii < nn; ii++) { - Spatial child = getChild(ii); - if (!(child instanceof ModelNode) || - ((ModelNode)child).cullInvisibleNodes()) { - _hasVisibleDescendants = true; - } - } - updateCullMode(); - return _hasVisibleDescendants; - } - - /** - * Locks the transforms and bounds of this instance with the assumption - * that the position will never change. - * - * @param targets the targets of the model's controllers, which determine - * the subset of nodes that can be locked - * @return true if this node is a target or contains any targets, otherwise - * false - */ - protected boolean lockInstance (HashSet targets) - { - updateWorldVectors(); - lockedMode |= LOCKED_TRANSFORMS; - - boolean containsTargets = false; - for (int ii = 0, nn = getQuantity(); ii < nn; ii++) { - Spatial child = getChild(ii); - if (targets.contains(child) || (child instanceof ModelNode && - ((ModelNode)child).lockInstance(targets))) { - containsTargets = true; - - } else if (child instanceof ModelMesh) { - ((ModelMesh)child).lockInstance(); - } - } - if (containsTargets) { - return true; - } else { - updateWorldBound(); - lockedMode |= LOCKED_BOUNDS; - return false; - } - } - - /** - * Recursively culls all model nodes under this one in preparation for - * activating the ones listed in an animation. - */ - protected void cullModelNodes () - { - for (int ii = 0, nn = getQuantity(); ii < nn; ii++) { - Spatial child = getChild(ii); - if (child instanceof ModelNode) { - child.setCullMode(CULL_ALWAYS); - ((ModelNode)child).cullModelNodes(); - } - } - } - - /** - * Makes this node visible if and only if it has visible descendants and - * has not been specifically culled. - */ - protected void updateCullMode () - { - setCullMode((_hasVisibleDescendants && !_forceCull) ? - CULL_INHERIT : CULL_ALWAYS); - } - - /** The node's transform in local and model space. */ - protected Matrix4f _localTransform = new Matrix4f(), - _modelTransform = new Matrix4f(); - - /** Whether or not this node has mesh descendants. */ - protected boolean _hasVisibleDescendants; - - /** If true, cull the node even if it has mesh descendants. */ - protected boolean _forceCull; - - private static final long serialVersionUID = 1; -} diff --git a/src/java/com/threerings/jme/model/ModelSpatial.java b/src/java/com/threerings/jme/model/ModelSpatial.java deleted file mode 100644 index 35f38592..00000000 --- a/src/java/com/threerings/jme/model/ModelSpatial.java +++ /dev/null @@ -1,97 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.model; - -import com.jme.renderer.Renderer; -import com.jme.scene.Spatial; - -import com.threerings.jme.util.ShaderCache; - -/** - * Contains method common to both {@link ModelNode}s and {@link ModelMesh}es. - */ -public interface ModelSpatial -{ - /** - * Recursively expands the model bounds of any deformable meshes so that - * they include the current vertex positions. - */ - public void expandModelBounds (); - - /** - * Recursively sets the reference transforms for any bones in the model. - */ - public void setReferenceTransforms (); - - /** - * Recursively compiles any static meshes to vertex buffer objects (VBOs) - * or display lists. - * - * @param useVBOs if true, use VBOs if the graphics card supports them - * @param useDisplayLists if true and not using VBOs, compile static - * objects to display lists - */ - public void lockStaticMeshes ( - Renderer renderer, boolean useVBOs, boolean useDisplayLists); - - /** - * Recursively resolves texture references using the given provider. - */ - public void resolveTextures (TextureProvider tprov); - - /** - * Recursively creates or reconfigures any shaders used by the model using the supplied cache. - */ - public void configureShaders (ShaderCache scache); - - /** - * Recursively requests that the current state of all skinned meshes be - * stored as an animation frame on the next update. - * - * @param frameId the frame id, which uniquely identifies one frame of - * one animation - * @param blend whether or not the stored frames will be retrieved by - * calls to {@link #blendMeshFrames} as opposed to {@link #setMeshFrame} - */ - public void storeMeshFrame (int frameId, boolean blend); - - /** - * Recursively switches all skinned meshes to a stored animation frame for - * the next update. - */ - public void setMeshFrame (int frameId); - - /** - * Recursively blends all skinned meshes between two stored animation - * frames for the next update. - */ - public void blendMeshFrames (int frameId1, int frameId2, float alpha); - - /** - * Creates or populates and returns a clone of this object using the given - * clone properties. - * - * @param store an instance of this class to populate, or null - * to create a new instance - */ - public Spatial putClone (Spatial store, Model.CloneCreator properties); -} diff --git a/src/java/com/threerings/jme/model/Rotator.java b/src/java/com/threerings/jme/model/Rotator.java deleted file mode 100644 index 7bff0ced..00000000 --- a/src/java/com/threerings/jme/model/Rotator.java +++ /dev/null @@ -1,109 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.model; - -import java.io.IOException; - -import java.util.Properties; - -import com.jme.math.Quaternion; -import com.jme.math.Vector3f; -import com.jme.scene.Controller; -import com.jme.scene.Spatial; -import com.jme.util.export.JMEExporter; -import com.jme.util.export.JMEImporter; -import com.jme.util.export.InputCapsule; -import com.jme.util.export.OutputCapsule; - -import com.threerings.jme.util.JmeUtil; - -/** - * A procedural animation that rotates a node around at a constant angular - * velocity. - */ -public class Rotator extends ModelController -{ - @Override - public void configure (Properties props, Spatial target) - { - super.configure(props, target); - _axis = JmeUtil.parseAxis(props.getProperty("axis", "x")); - _velocity = Float.parseFloat(props.getProperty("velocity", "3.14")); - } - - // documentation inherited - public void update (float time) - { - if (!isActive()) { - return; - } - _rot.fromAngleNormalAxis(time * _velocity, _axis); - _target.getLocalRotation().multLocal(_rot); - } - - @Override - public Controller putClone ( - Controller store, Model.CloneCreator properties) - { - Rotator rstore; - if (store == null) { - rstore = new Rotator(); - } else { - rstore = (Rotator)store; - } - super.putClone(rstore, properties); - rstore._axis = _axis; - rstore._velocity = _velocity; - return rstore; - } - - @Override - public void read (JMEImporter im) - throws IOException - { - super.read(im); - InputCapsule capsule = im.getCapsule(this); - _axis = (Vector3f)capsule.readSavable("axis", null); - _velocity = capsule.readFloat("velocity", 0f); - } - - @Override - public void write (JMEExporter ex) - throws IOException - { - super.write(ex); - OutputCapsule capsule = ex.getCapsule(this); - capsule.write(_axis, "axis", null); - capsule.write(_velocity, "velocity", 0f); - } - - /** The axis about which to rotate. */ - protected Vector3f _axis; - - /** The velocity at which to rotate in radians per second. */ - protected float _velocity; - - /** A temporary quaternion. */ - protected Quaternion _rot = new Quaternion(); - - private static final long serialVersionUID = 1; -} diff --git a/src/java/com/threerings/jme/model/SkinMesh.java b/src/java/com/threerings/jme/model/SkinMesh.java deleted file mode 100644 index d6554880..00000000 --- a/src/java/com/threerings/jme/model/SkinMesh.java +++ /dev/null @@ -1,760 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.model; - -import java.io.IOException; - -import java.nio.ByteBuffer; -import java.nio.FloatBuffer; -import java.nio.IntBuffer; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; - -import org.lwjgl.opengl.GLContext; - -import com.jme.bounding.BoundingVolume; -import com.jme.math.Matrix4f; -import com.jme.renderer.Renderer; -import com.jme.scene.Spatial; -import com.jme.scene.TriMesh; -import com.jme.scene.VBOInfo; -import com.jme.scene.batch.SharedBatch; -import com.jme.scene.batch.TriangleBatch; -import com.jme.scene.state.GLSLShaderObjectsState; -import com.jme.scene.state.RenderState; -import com.jme.system.DisplaySystem; -import com.jme.util.ShaderAttribute; -import com.jme.util.export.JMEExporter; -import com.jme.util.export.JMEImporter; -import com.jme.util.export.InputCapsule; -import com.jme.util.export.OutputCapsule; -import com.jme.util.export.Savable; -import com.jme.util.geom.BufferUtils; - -import com.samskivert.util.ArrayUtil; -import com.samskivert.util.HashIntMap; -import com.samskivert.util.ListUtil; - -import com.threerings.jme.util.JmeUtil; -import com.threerings.jme.util.ShaderCache; -import com.threerings.jme.util.ShaderConfig; - -/** - * A triangle mesh that deforms according to a bone hierarchy. - */ -public class SkinMesh extends ModelMesh -{ - /** The maximum number of bone matrices that we can use for hardware skinning. */ - public static final int MAX_SHADER_BONE_COUNT = 31; - - /** The maximum number of bones influencing a single vertex for hardware skinning. */ - public static final int MAX_SHADER_BONES_PER_VERTEX = 4; - - /** Represents the vertex weights of a group of vertices influenced by the - * same set of bones. */ - public static class WeightGroup - implements Savable - { - /** The number of vertices in this weight group. */ - public int vertexCount; - - /** The bones influencing this group. */ - public Bone[] bones; - - /** The array of interleaved weights (of length vertexCount * - * boneIndices.length): weights for first vertex, weights for - * second, etc. */ - public float[] weights; - - /** - * Rebinds this weight group for a prototype instance. - * - * @param bmap the mapping from prototype to instance bones - */ - public WeightGroup rebind (Map bmap) - { - WeightGroup wgroup = new WeightGroup(); - wgroup.vertexCount = vertexCount; - wgroup.bones = new Bone[bones.length]; - for (int ii = 0; ii < bones.length; ii++) { - wgroup.bones[ii] = bmap.get(bones[ii]); - } - wgroup.weights = weights; - return wgroup; - } - - // documentation inherited - public Class getClassTag () - { - return getClass(); - } - - // documentation inherited - public void read (JMEImporter im) - throws IOException - { - InputCapsule capsule = im.getCapsule(this); - vertexCount = capsule.readInt("vertexCount", 0); - bones = ArrayUtil.copy(capsule.readSavableArray("bones", null), - new Bone[0]); - weights = capsule.readFloatArray("weights", null); - } - - // documentation inherited - public void write (JMEExporter ex) - throws IOException - { - OutputCapsule capsule = ex.getCapsule(this); - capsule.write(vertexCount, "vertexCount", 0); - capsule.write(bones, "bones", null); - capsule.write(weights, "weights", null); - } - - private static final long serialVersionUID = 1; - } - - /** Represents a bone that influences the mesh. */ - public static class Bone - implements Savable - { - /** The node that defines the bone's position. */ - public ModelNode node; - - /** The inverse of the bone's model space reference transform. */ - public transient Matrix4f invRefTransform; - - /** The bone's current transform in model space. */ - public transient Matrix4f transform; - - public Bone (ModelNode node) - { - this(); - this.node = node; - } - - public Bone () - { - transform = new Matrix4f(); - } - - /** - * Rebinds this bone for a prototype instance. - * - * @param pnodes a mapping from prototype nodes to instance nodes - */ - public Bone rebind (Map pnodes) - { - Bone bone = new Bone((ModelNode)pnodes.get(node)); - bone.invRefTransform = invRefTransform; - bone.transform = new Matrix4f(); - return bone; - } - - // documentation inherited - public Class getClassTag () - { - return getClass(); - } - - // documentation inherited - public void read (JMEImporter im) - throws IOException - { - InputCapsule capsule = im.getCapsule(this); - node = (ModelNode)capsule.readSavable("node", null); - } - - // documentation inherited - public void write (JMEExporter ex) - throws IOException - { - OutputCapsule capsule = ex.getCapsule(this); - capsule.write(node, "node", null); - } - - private static final long serialVersionUID = 1; - } - - /** - * No-arg constructor for deserialization. - */ - public SkinMesh () - { - } - - /** - * Creates an empty mesh. - */ - public SkinMesh (String name) - { - super(name); - } - - /** - * Sets the array of weight groups that determine how bones affect - * each vertex. - */ - public void setWeightGroups (WeightGroup[] weightGroups) - { - _weightGroups = weightGroups; - - // compile a list of all referenced bones - HashSet bones = Sets.newHashSet(); - for (WeightGroup group : weightGroups) { - Collections.addAll(bones, group.bones); - } - _bones = bones.toArray(new Bone[bones.size()]); - } - - @Override - public void addOverlay (RenderState[] overlay) - { - // add a cloned state config (with same uniforms) for the overlay - super.addOverlay(overlay); - if (_sconfig == null) { - return; - } - if (_osconfigs == null) { - _osconfigs = Lists.newArrayListWithCapacity(1); - } - SkinShaderConfig osconfig = (SkinShaderConfig)_sconfig.clone(); - osconfig.getState().uniforms = _sconfig.getState().uniforms; - _osconfigs.add(osconfig); - } - - @Override - public void removeOverlay (RenderState[] overlay) - { - // remove the corresponding state config - int idx = (_overlays == null) ? -1 : _overlays.indexOf(overlay); - super.removeOverlay(overlay); - if (_osconfigs != null && idx >= 0) { - _osconfigs.remove(idx); - if (_osconfigs.isEmpty()) { - _osconfigs = null; - } - } - } - - @Override - public void reconstruct ( - FloatBuffer vertices, FloatBuffer normals, FloatBuffer colors, - FloatBuffer textures, IntBuffer indices) - { - super.reconstruct(vertices, normals, colors, textures, indices); - - // initialize the quantized frame table - _frames = new HashIntMap(); - } - - @Override - public Spatial putClone (Spatial store, Model.CloneCreator properties) - { - SkinMesh mstore = (SkinMesh)properties.originalToCopy.get(this); - if (mstore != null) { - return mstore; - } else if (store == null) { - mstore = new SkinMesh(getName()); - } else { - mstore = (SkinMesh)store; - } - GLSLShaderObjectsState sstate = (GLSLShaderObjectsState)getRenderState( - RenderState.RS_GLSL_SHADER_OBJECTS); - if (sstate == null) { - // vertices and normals must be cloned if not using a shader - properties.removeProperty("vertices"); - properties.removeProperty("normals"); - } - properties.removeProperty("displaylistid"); - super.putClone(mstore, properties); - if (sstate == null) { - properties.addProperty("vertices"); - properties.addProperty("normals"); - } - properties.addProperty("displaylistid"); - mstore._frames = _frames; - mstore._useDisplayLists = _useDisplayLists; - mstore._invRefTransform = _invRefTransform; - mstore._bones = new Bone[_bones.length]; - HashMap bmap = Maps.newHashMap(); - for (int ii = 0; ii < _bones.length; ii++) { - bmap.put(_bones[ii], mstore._bones[ii] = - _bones[ii].rebind(properties.originalToCopy)); - } - mstore._weightGroups = new WeightGroup[_weightGroups.length]; - for (int ii = 0; ii < _weightGroups.length; ii++) { - mstore._weightGroups[ii] = _weightGroups[ii].rebind(bmap); - } - mstore._ovbuf = _ovbuf; - mstore._onbuf = _onbuf; - mstore._vbuf = (sstate == null) ? new float[_vbuf.length] : _vbuf; - mstore._nbuf = (sstate == null) ? new float[_nbuf.length] : _nbuf; - if (_sconfig != null) { - mstore._sconfig = (SkinShaderConfig)_sconfig.clone(); - mstore.setRenderState(mstore._sconfig.getState()); - } - return mstore; - } - - @Override - public void read (JMEImporter im) - throws IOException - { - super.read(im); - InputCapsule capsule = im.getCapsule(this); - setWeightGroups(ArrayUtil.copy(capsule.readSavableArray( - "weightGroups", null), new WeightGroup[0])); - } - - @Override - public void write (JMEExporter ex) - throws IOException - { - super.write(ex); - OutputCapsule capsule = ex.getCapsule(this); - capsule.write(_weightGroups, "weightGroups", null); - } - - @Override - public void expandModelBounds () - { - BoundingVolume obound = getBatch(0).getModelBound().clone(null); - updateModelBound(); - getBatch(0).getModelBound().mergeLocal(obound); - } - - @Override - public void setReferenceTransforms () - { - _invRefTransform = new Matrix4f(); - if (parent instanceof ModelNode) { - Matrix4f transform = new Matrix4f(); - JmeUtil.setTransform(getLocalTranslation(), getLocalRotation(), - getLocalScale(), transform); - ((ModelNode)parent).getModelTransform().mult(transform, - _invRefTransform); - _invRefTransform.invertLocal(); - } - for (Bone bone : _bones) { - bone.invRefTransform = - _invRefTransform.mult(bone.node.getModelTransform()).invert(); - } - } - - @Override - public void lockStaticMeshes ( - Renderer renderer, boolean useVBOs, boolean useDisplayLists) - { - // we can use VBOs for color, texture, and indices if not using shaders - if (useVBOs && renderer.supportsVBO()) { - // use VBOs for shader attributes - GLSLShaderObjectsState sstate = (GLSLShaderObjectsState)getRenderState( - RenderState.RS_GLSL_SHADER_OBJECTS); - if (sstate != null) { - for (ShaderAttribute attrib : sstate.attribs.values()) { - attrib.useVBO = true; - } - } - - VBOInfo vboinfo = new VBOInfo(true); - if (sstate == null) { - vboinfo.setVBOVertexEnabled(false); - vboinfo.setVBONormalEnabled(false); - } - vboinfo.setVBOIndexEnabled(!_translucent); - setVBOInfo(vboinfo); - } - _useDisplayLists = useDisplayLists && !_translucent; - } - - @Override - public void configureShaders (ShaderCache scache) - { - if (_disableShaders || !GLContext.getCapabilities().GL_ARB_vertex_shader || - _bones.length > MAX_SHADER_BONE_COUNT) { - return; - } - int bonesPerVertex = 0; - for (WeightGroup group : _weightGroups) { - bonesPerVertex = Math.max(group.bones.length, bonesPerVertex); - } - if (bonesPerVertex > MAX_SHADER_BONES_PER_VERTEX) { - return; - } - _sconfig = new SkinShaderConfig(scache, _emissiveMap != null); - if (_sconfig.update(getBatch(0).states)) { - setShaderAttributes(); - setRenderState(_sconfig.getState()); - } else { - _sconfig = null; - _disableShaders = true; - } - } - - @Override - public void storeMeshFrame (int frameId, boolean blend) - { - _storeFrameId = frameId; - _storeBlend = blend; - } - - @Override - public void setMeshFrame (int frameId) - { - TriangleBatch batch = getBatch(0), - tbatch = (TriangleBatch)_frames.get(frameId); - if (batch instanceof SharedBatch) { - ((SharedBatch)batch).setTarget(tbatch); - } else { - clearBatches(); - addBatch(new SharedBatch(tbatch)); - getBatch(0).updateRenderState(); - } - } - - @Override - public void blendMeshFrames (int frameId1, int frameId2, float alpha) - { - BlendFrame frame1 = (BlendFrame)_frames.get(frameId1), - frame2 = (BlendFrame)_frames.get(frameId2); - frame1.blend(frame2, alpha, _vbuf, _nbuf); - FloatBuffer vbuf = getVertexBuffer(0), nbuf = getNormalBuffer(0); - vbuf.rewind(); - vbuf.put(_vbuf); - nbuf.rewind(); - nbuf.put(_nbuf); - } - - @Override - public void updateWorldData (float time) - { - super.updateWorldData(time); - if (_weightGroups == null || _storeFrameId == -1 || - (_storeFrameId == 0 && getCullMode() == CULL_ALWAYS)) { - return; - } - // update the bone transforms - for (Bone bone : _bones) { - _invRefTransform.mult(bone.node.getModelTransform(), - bone.transform); - bone.transform.multLocal(bone.invRefTransform); - } - - // if we're using shaders, initialize the uniform variables with the bone transforms - GLSLShaderObjectsState sstate = (GLSLShaderObjectsState)getRenderState( - RenderState.RS_GLSL_SHADER_OBJECTS); - if (sstate != null) { - for (int ii = 0; ii < _bones.length; ii++) { - sstate.setUniform("boneTransforms[" + ii + "]", _bones[ii].transform, true); - } - return; - } - - // deform the mesh according to the positions of the bones (this code - // is ugly as sin because it's optimized at a low level) - Bone[] bones; - int vertexCount, jj, kk, ww; - float[] weights; - Matrix4f m; - float weight, ovx, ovy, ovz, onx, ony, onz, vx, vy, vz, nx, ny, nz; - for (int ii = 0, bidx = 0; ii < _weightGroups.length; ii++) { - vertexCount = _weightGroups[ii].vertexCount; - bones = _weightGroups[ii].bones; - weights = _weightGroups[ii].weights; - for (jj = 0, ww = 0; jj < vertexCount; jj++) { - ovx = _ovbuf[bidx]; - ovy = _ovbuf[bidx + 1]; - ovz = _ovbuf[bidx + 2]; - onx = _onbuf[bidx]; - ony = _onbuf[bidx + 1]; - onz = _onbuf[bidx + 2]; - vx = vy = vz = 0f; - nx = ny = nz = 0f; - for (kk = 0; kk < bones.length; kk++) { - m = bones[kk].transform; - weight = weights[ww++]; - - vx += (ovx*m.m00 + ovy*m.m01 + ovz*m.m02 + m.m03) * weight; - vy += (ovx*m.m10 + ovy*m.m11 + ovz*m.m12 + m.m13) * weight; - vz += (ovx*m.m20 + ovy*m.m21 + ovz*m.m22 + m.m23) * weight; - - nx += (onx*m.m00 + ony*m.m01 + onz*m.m02) * weight; - ny += (onx*m.m10 + ony*m.m11 + onz*m.m12) * weight; - nz += (onx*m.m20 + ony*m.m21 + onz*m.m22) * weight; - } - _vbuf[bidx] = vx; - _vbuf[bidx + 1] = vy; - _vbuf[bidx + 2] = vz; - _nbuf[bidx++] = nx; - _nbuf[bidx++] = ny; - _nbuf[bidx++] = nz; - } - } - - // if skinning in real time, copy the data from arrays to buffers; - // otherwise, store the mesh as an animation frame - if (_storeFrameId == 0) { - FloatBuffer vbuf = getVertexBuffer(0), nbuf = getNormalBuffer(0); - vbuf.rewind(); - vbuf.put(_vbuf); - nbuf.rewind(); - nbuf.put(_nbuf); - } else { - storeFrame(); - _storeFrameId = -1; - } - } - - /** - * Stores the current frame data for later use. - */ - protected void storeFrame () - { - if (_storeBlend) { - _frames.put(_storeFrameId, new BlendFrame(_vbuf.clone(), _nbuf.clone())); - } else { - TriangleBatch batch = getBatch(0), tbatch = new TriangleBatch(); - tbatch.setParentGeom(DUMMY_MESH); - tbatch.setColorBuffer(batch.getColorBuffer()); - int nunits = batch.getNumberOfUnits(); - for (int ii = 0; ii < nunits; ii++) { - tbatch.setTextureBuffer(batch.getTextureBuffer(ii), ii); - } - tbatch.setIndexBuffer(batch.getIndexBuffer()); - tbatch.setVertexBuffer(BufferUtils.createFloatBuffer(_vbuf)); - tbatch.setNormalBuffer(BufferUtils.createFloatBuffer(_nbuf)); - VBOInfo ovboinfo = batch.getVBOInfo(); - if (ovboinfo != null) { - VBOInfo vboinfo = new VBOInfo(true); - vboinfo.setVBOIndexEnabled(!_translucent); - vboinfo.setVBOColorID(ovboinfo.getVBOColorID()); - for (int ii = 0; ii < nunits; ii++) { - vboinfo.setVBOTextureID(ii, ovboinfo.getVBOTextureID(ii)); - } - vboinfo.setVBOIndexID(ovboinfo.getVBOIndexID()); - tbatch.setVBOInfo(vboinfo); - } else if (_useDisplayLists) { - tbatch.lockMeshes( - DisplaySystem.getDisplaySystem().getRenderer()); - } - _frames.put(_storeFrameId, tbatch); - } - } - - @Override - protected ModelBatch createModelBatch () - { - // update the shader configs immediately before drawing - return new ModelBatch() { - protected void preDraw () { - if (_sconfig != null) { - _sconfig.update(states); - } - } - protected void preDrawOverlay (int oidx) { - super.preDrawOverlay(oidx); - if (_osconfigs != null) { - _ostates[RenderState.RS_GLSL_SHADER_OBJECTS] = - states[RenderState.RS_GLSL_SHADER_OBJECTS]; - SkinShaderConfig osconfig = _osconfigs.get(oidx); - states[RenderState.RS_GLSL_SHADER_OBJECTS] = osconfig.getState(); - _osconfigs.get(oidx).update(states); - } - } - protected void postDrawOverlay (int oidx) { - super.postDrawOverlay(oidx); - if (_osconfigs != null) { - states[RenderState.RS_GLSL_SHADER_OBJECTS] = - _ostates[RenderState.RS_GLSL_SHADER_OBJECTS]; - } - } - }; - } - - @Override - protected void storeOriginalBuffers () - { - super.storeOriginalBuffers(); - - FloatBuffer vbuf = getVertexBuffer(0), nbuf = getNormalBuffer(0); - vbuf.rewind(); - nbuf.rewind(); - FloatBuffer.wrap(_ovbuf = new float[vbuf.capacity()]).put(vbuf); - FloatBuffer.wrap(_onbuf = new float[nbuf.capacity()]).put(nbuf); - _vbuf = new float[_ovbuf.length]; - _nbuf = new float[_onbuf.length]; - } - - /** - * Initializes the skin shader attributes (bone indices and weights) in the supplied state. - */ - protected void setShaderAttributes () - { - int size = getBatch(0).getVertexCount() * 4; - ByteBuffer bibuf = BufferUtils.createByteBuffer(size); - FloatBuffer bwbuf = BufferUtils.createFloatBuffer(size); - - for (WeightGroup group : _weightGroups) { - byte[] indices = new byte[4]; - for (int ii = 0; ii < 4; ii++) { - indices[ii] = (byte)((ii < group.bones.length) ? - ListUtil.indexOf(_bones, group.bones[ii]) : 0); - } - for (int ii = 0, widx = 0; ii < group.vertexCount; ii++) { - bibuf.put(indices); - for (int jj = 0; jj < 4; jj++) { - bwbuf.put((jj < group.bones.length) ? group.weights[widx++] : 0f); - } - } - } - bibuf.rewind(); - bwbuf.rewind(); - - GLSLShaderObjectsState sstate = _sconfig.getState(); - sstate.setAttributePointer("boneIndices", 4, false, false, 0, bibuf); - sstate.setAttributePointer("boneWeights", 4, false, 0, bwbuf); - } - - /** Tracks the configuration of a skin shader. */ - protected static class SkinShaderConfig extends ShaderConfig - { - public SkinShaderConfig (ShaderCache scache, boolean emissiveMapped) - { - super(scache); - _emissiveMapped = emissiveMapped; - - // set bindings from texture units to samplers - if (emissiveMapped) { - _state.setUniform("diffuseMap", 1); - _state.setUniform("emissiveMap", 0); - } else { - _state.setUniform("diffuseMap", 0); - } - } - - @Override - protected String getVertexShader () - { - return "media/jme/skin.vert"; - } - - @Override - protected String getFragmentShader () - { - return "media/jme/skin.frag"; - } - - @Override - protected void getDefinitions (ArrayList defs) - { - super.getDefinitions(defs); - if (_emissiveMapped) { - defs.add("EMISSIVE_MAPPED"); - } - } - - @Override - protected void getDerivedDefinitions (ArrayList ddefs) - { - super.getDerivedDefinitions(ddefs); - ddefs.add("MAX_BONE_COUNT " + MAX_SHADER_BONE_COUNT); - } - - protected boolean _emissiveMapped; - } - - /** A stored frame used for linear blending. */ - protected static class BlendFrame - { - /** The skinned vertex and normal values. */ - public float[] vbuf, nbuf; - - public BlendFrame (float[] vbuf, float[] nbuf) - { - this.vbuf = vbuf; - this.nbuf = nbuf; - } - - public void blend ( - BlendFrame next, float alpha, float[] rvbuf, float[] rnbuf) - { - float[] nvbuf = next.vbuf, nnbuf = next.nbuf; - float ialpha = 1f - alpha; - for (int ii = 0, nn = vbuf.length; ii < nn; ii++) { - rvbuf[ii] = vbuf[ii] * ialpha + nvbuf[ii] * alpha; - rnbuf[ii] = nbuf[ii] * ialpha + nnbuf[ii] * alpha; - } - } - } - - /** Pre-skinned {@link TriangleBatch}es or {@link BlendFrame}s shared - * between all instances corresponding to frame ids from - * {@link #storeAnimationFrame}. */ - protected HashIntMap _frames; - - /** Whether or to use display lists if VBOs are unavailable for quantized - * meshes. */ - protected boolean _useDisplayLists; - - /** The inverse of the model space reference transform. */ - protected Matrix4f _invRefTransform; - - /** The groups of vertices influenced by different sets of bones. */ - protected WeightGroup[] _weightGroups; - - /** The bones referenced by the weight groups. */ - protected Bone[] _bones; - - /** The original (undeformed) vertex and normal buffers and the deformed - * versions. */ - protected float[] _onbuf, _ovbuf, _nbuf; - - /** The primary skin shader configuration. */ - protected SkinShaderConfig _sconfig; - - /** Skin shader configurations for each overlay. */ - protected ArrayList _osconfigs; - - /** The frame id to store on the next update. If 0, don't store any frame - * and skin the mesh as normal. If -1, a frame has been stored and thus - * skinning should only take place when further frames are requested. */ - protected int _storeFrameId; - - /** Whether or not the stored frame id will be used for blending. */ - protected boolean _storeBlend; - - /** Set if we determine that our shaders don't compile to prevent us from trying again. */ - protected static boolean _disableShaders; - - /** A dummy mesh that simply hold transformation values. */ - protected static final TriMesh DUMMY_MESH = new TriMesh(); - - private static final long serialVersionUID = 1; -} diff --git a/src/java/com/threerings/jme/model/TextureAnimator.java b/src/java/com/threerings/jme/model/TextureAnimator.java deleted file mode 100644 index fe2c0ad2..00000000 --- a/src/java/com/threerings/jme/model/TextureAnimator.java +++ /dev/null @@ -1,157 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.model; - -import java.io.IOException; - -import java.util.Properties; - -import com.jme.image.Texture; -import com.jme.math.Vector3f; -import com.jme.scene.Controller; -import com.jme.scene.Spatial; -import com.jme.util.export.JMEExporter; -import com.jme.util.export.JMEImporter; -import com.jme.util.export.InputCapsule; -import com.jme.util.export.OutputCapsule; - -import com.threerings.jme.util.JmeUtil; -import com.threerings.jme.util.JmeUtil.FrameState; - -/** - * Animates a model's textures by flipping between different parts. - */ -public class TextureAnimator extends TextureController -{ - @Override - public void configure (Properties props, Spatial target) - { - super.configure(props, target); - _frameWidth = Float.valueOf(props.getProperty("frame_width", "0.5")); - _frameHeight = Float.valueOf(props.getProperty("frame_height", "0.5")); - _frameCount = Integer.valueOf(props.getProperty("frame_count", "4")); - _frameRate = Float.valueOf(props.getProperty("frame_rate", "1")); - _repeatType = JmeUtil.parseRepeatType(props.getProperty("repeat_type"), - Controller.RT_WRAP); - } - - // documentation inherited - public void update (float time) - { - super.update(time); - if (!isActive()) { - return; - } - _fstate.update(time, _frameRate, _frameCount, _repeatType); - _translation.set( - (_fstate.idx % _hframes) * _frameWidth, - -(_fstate.idx / _hframes) * _frameHeight, - 0f); - } - - @Override - public Controller putClone ( - Controller store, Model.CloneCreator properties) - { - TextureAnimator tstore; - if (store == null) { - tstore = new TextureAnimator(); - } else { - tstore = (TextureAnimator)store; - } - super.putClone(tstore, properties); - tstore._frameWidth = _frameWidth; - tstore._frameHeight = _frameHeight; - tstore._frameCount = _frameCount; - tstore._frameRate = _frameRate; - tstore._repeatType = _repeatType; - return tstore; - } - - @Override - public void read (JMEImporter im) - throws IOException - { - super.read(im); - InputCapsule capsule = im.getCapsule(this); - _frameWidth = capsule.readFloat("frameWidth", 0.5f); - _frameHeight = capsule.readFloat("frameHeight", 0.5f); - _frameCount = capsule.readInt("frameCount", 4); - _frameRate = capsule.readFloat("frameRate", 1f); - _repeatType = capsule.readInt("repeatType", Controller.RT_WRAP); - } - - @Override - public void write (JMEExporter ex) - throws IOException - { - super.write(ex); - OutputCapsule capsule = ex.getCapsule(this); - capsule.write(_frameWidth, "frameWidth", 0.5f); - capsule.write(_frameHeight, "frameHeight", 0.5f); - capsule.write(_frameCount, "frameCount", 4); - capsule.write(_frameRate, "frameRate", 1f); - capsule.write(_repeatType, "repeatType", Controller.RT_WRAP); - } - - @Override - protected void initTextures () - { - super.initTextures(); - - // compute derived values - _hframes = (int)Math.floor(1f / _frameWidth); - _vframes = (int)Math.floor(1f / _frameHeight); - - // use the same translation vector for all textures - _translation = new Vector3f(); - for (Texture texture : _textures) { - texture.setTranslation(_translation); - } - } - - /** The width of the frames in texture units. */ - protected float _frameWidth; - - /** The height of the frames in texture units. */ - protected float _frameHeight; - - /** The number of frames in the texture. */ - protected int _frameCount; - - /** The rate at which to display the frames (frames per second). */ - protected float _frameRate; - - /** The repeat type (one of the constants in {@link Controller}). */ - protected int _repeatType; - - /** The number of frames on the horizontal and vertical axes. */ - protected transient int _hframes, _vframes; - - /** The animation position. */ - protected transient FrameState _fstate = new FrameState(); - - /** The shared texture translation. */ - protected transient Vector3f _translation; - - private static final long serialVersionUID = 1; -} diff --git a/src/java/com/threerings/jme/model/TextureController.java b/src/java/com/threerings/jme/model/TextureController.java deleted file mode 100644 index 99d0714f..00000000 --- a/src/java/com/threerings/jme/model/TextureController.java +++ /dev/null @@ -1,95 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.model; - -import java.util.HashMap; - -import com.google.common.collect.Maps; - -import com.jme.image.Texture; -import com.jme.scene.state.RenderState; -import com.jme.scene.state.TextureState; -import com.jme.system.DisplaySystem; - -import com.threerings.jme.util.SpatialVisitor; - -/** - * Base class for controllers that affect a model's textures. - */ -public abstract class TextureController extends ModelController -{ - @Override - public void resolveTextures (TextureProvider tprov) - { - // reinitialize the cloned textures if we re-resolve - super.resolveTextures(tprov); - _textures = null; - } - - // documentation inherited - public void update (float time) - { - // initialize the textures before the first update - if (_textures == null) { - initTextures(); - } - } - - /** - * Performs any per-instance initialization required for textures. - */ - protected void initTextures () - { - // find and clone all textures under the target - final HashMap clones = Maps.newHashMap(); - new SpatialVisitor(ModelMesh.class) { - protected void visit (ModelMesh mesh) { - TextureState otstate = (TextureState)mesh.getRenderState(RenderState.RS_TEXTURE); - if (otstate == null) { - return; - } - TextureState ntstate = - DisplaySystem.getDisplaySystem().getRenderer().createTextureState(); - for (int ii = 0, nn = otstate.getNumberOfSetTextures(); ii < nn; ii++) { - Texture tex = otstate.getTexture(ii), ctex = clones.get(tex); - if (ctex == null) { - if (tex.getTextureId() == 0) { - otstate.apply(); // load before cloning - } - clones.put(tex, ctex = tex.createSimpleClone()); - } - ntstate.setTexture(ctex, ii); - } - mesh.setRenderState(ntstate); - } - }.traverse(_target); - _target.updateRenderState(); - - // remember them for updates - _textures = clones.values().toArray(new Texture[0]); - } - - /** The cloned textures to manipulate. */ - protected transient Texture[] _textures; - - private static final long serialVersionUID = 1; -} diff --git a/src/java/com/threerings/jme/model/TextureProvider.java b/src/java/com/threerings/jme/model/TextureProvider.java deleted file mode 100644 index db51dfe7..00000000 --- a/src/java/com/threerings/jme/model/TextureProvider.java +++ /dev/null @@ -1,39 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.model; - -import com.jme.scene.state.TextureState; - -/** - * Provides a means for models to resolve their texture references. - */ -public interface TextureProvider -{ - /** - * Returns a texture state containing the named texture. - * - * @param name the name of the texture, which will be interpreted as an - * absolute resource path if it starts with a forward slash; otherwise, - * as a relative resource path - */ - public TextureState getTexture (String name); -} diff --git a/src/java/com/threerings/jme/model/TextureTranslator.java b/src/java/com/threerings/jme/model/TextureTranslator.java deleted file mode 100644 index 1735aa38..00000000 --- a/src/java/com/threerings/jme/model/TextureTranslator.java +++ /dev/null @@ -1,122 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.model; - -import java.io.IOException; - -import java.util.Properties; - -import com.jme.image.Texture; -import com.jme.math.Vector2f; -import com.jme.math.Vector3f; -import com.jme.scene.Controller; -import com.jme.scene.Spatial; -import com.jme.util.export.JMEExporter; -import com.jme.util.export.JMEImporter; -import com.jme.util.export.InputCapsule; -import com.jme.util.export.OutputCapsule; - -import com.samskivert.util.StringUtil; - -import static com.threerings.jme.Log.log; - -/** - * A procedural animation that translates the model's textures at a constant velocity. - */ -public class TextureTranslator extends TextureController -{ - @Override - public void configure (Properties props, Spatial target) - { - super.configure(props, target); - String velstr = props.getProperty("velocity", "1, 0"); - float[] vel = StringUtil.parseFloatArray(velstr); - if (vel != null && vel.length == 2) { - _velocity = new Vector2f(vel[0], vel[1]); - } else { - log.warning("Invalid velocity [velocity=" + velstr + "]."); - } - } - - // documentation inherited - public void update (float time) - { - super.update(time); - if (!isActive()) { - return; - } - _translation.addLocal(_velocity.x * time, _velocity.y * time, 0f); - } - - @Override - public Controller putClone ( - Controller store, Model.CloneCreator properties) - { - TextureTranslator tstore; - if (store == null) { - tstore = new TextureTranslator(); - } else { - tstore = (TextureTranslator)store; - } - super.putClone(tstore, properties); - tstore._velocity = _velocity; - return tstore; - } - - @Override - public void read (JMEImporter im) - throws IOException - { - super.read(im); - InputCapsule capsule = im.getCapsule(this); - _velocity = (Vector2f)capsule.readSavable("velocity", null); - } - - @Override - public void write (JMEExporter ex) - throws IOException - { - super.write(ex); - OutputCapsule capsule = ex.getCapsule(this); - capsule.write(_velocity, "velocity", null); - } - - @Override - protected void initTextures () - { - super.initTextures(); - - // use the same translation vector for all textures - _translation = new Vector3f(); - for (Texture texture : _textures) { - texture.setTranslation(_translation); - } - } - - /** The velocity at which to translate the texture. */ - protected Vector2f _velocity; - - /** The shared translation vector. */ - protected transient Vector3f _translation; - - private static final long serialVersionUID = 1; -} diff --git a/src/java/com/threerings/jme/model/Translator.java b/src/java/com/threerings/jme/model/Translator.java deleted file mode 100644 index a35441c2..00000000 --- a/src/java/com/threerings/jme/model/Translator.java +++ /dev/null @@ -1,130 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.model; - -import java.io.IOException; - -import java.util.Properties; - -import com.jme.math.Vector3f; -import com.jme.scene.Controller; -import com.jme.scene.Spatial; -import com.jme.util.export.JMEExporter; -import com.jme.util.export.JMEImporter; -import com.jme.util.export.InputCapsule; -import com.jme.util.export.OutputCapsule; - -import com.threerings.jme.util.JmeUtil; - -/** - * A procedural animation that moves a node along a straight line at a constant velocity (then - * either repeats or moves it in the other direction). - */ -public class Translator extends ModelController -{ - @Override - public void configure (Properties props, Spatial target) - { - super.configure(props, target); - _from = JmeUtil.parseVector3f(props.getProperty("from", "0, 0, 0")); - _to = JmeUtil.parseVector3f(props.getProperty("to", "10, 0, 0")); - _duration = Float.parseFloat(props.getProperty("duration", "1")); - _repeatType = JmeUtil.parseRepeatType(props.getProperty("repeat_type"), - Controller.RT_WRAP); - } - - // documentation inherited - public void update (float time) - { - if (!isActive()) { - return; - } - _elapsed += (time / _duration); - float alpha; - if (_repeatType == Controller.RT_CLAMP) { - alpha = Math.min(_elapsed, 1f); - } else if (_repeatType == Controller.RT_WRAP) { - alpha = (_elapsed - (int)_elapsed); - } else { // _repeatType == Controller.RT_CYCLE - int ipart = (int)_elapsed; - float fpart = (_elapsed - ipart); - alpha = (ipart % 2 == 0) ? fpart : (1f - fpart); - } - _target.getLocalTranslation().interpolate(_from, _to, alpha); - } - - @Override - public Controller putClone ( - Controller store, Model.CloneCreator properties) - { - Translator tstore; - if (store == null) { - tstore = new Translator(); - } else { - tstore = (Translator)store; - } - super.putClone(tstore, properties); - tstore._from = _from; - tstore._to = _to; - tstore._duration = _duration; - tstore._repeatType = _repeatType; - return tstore; - } - - @Override - public void read (JMEImporter im) - throws IOException - { - super.read(im); - InputCapsule capsule = im.getCapsule(this); - _from = (Vector3f)capsule.readSavable("from", null); - _to = (Vector3f)capsule.readSavable("to", null); - _duration = capsule.readFloat("duration", 1f); - _repeatType = capsule.readInt("repeatType", Controller.RT_WRAP); - } - - @Override - public void write (JMEExporter ex) - throws IOException - { - super.write(ex); - OutputCapsule capsule = ex.getCapsule(this); - capsule.write(_from, "from", null); - capsule.write(_to, "to", null); - capsule.write(_duration, "duration", 1f); - capsule.write(_repeatType, "repeatType", Controller.RT_WRAP); - } - - /** The beginning and end of the path. */ - protected Vector3f _from, _to; - - /** The duration of the path. */ - protected float _duration; - - /** What to do after reaching the destination. */ - protected int _repeatType; - - /** The accumulated amount of time elapsed. */ - protected transient float _elapsed; - - private static final long serialVersionUID = 1; -} diff --git a/src/java/com/threerings/jme/package.html b/src/java/com/threerings/jme/package.html deleted file mode 100644 index e6df5fa9..00000000 --- a/src/java/com/threerings/jme/package.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - Defines extensions to jMonkeyEngine - an OpenGL-based 3D rendering engine. An application framework is - provided that integrates jME with the Presents distributed object - system and other useful bits and bobs are also included. - - - diff --git a/src/java/com/threerings/jme/sprite/BallisticPath.java b/src/java/com/threerings/jme/sprite/BallisticPath.java deleted file mode 100644 index fb5e0699..00000000 --- a/src/java/com/threerings/jme/sprite/BallisticPath.java +++ /dev/null @@ -1,92 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.sprite; - -import com.jme.math.FastMath; -import com.jme.math.Vector3f; - -/** - * Moves a sprite ballistically. - */ -public class BallisticPath extends Path -{ - /** Gravity: it's the law. */ - public static final float G = -9.8f; - - /** - * Moves the supplied sprite from the starting coordinate (which will - * be modified) using the starting velocity, under the specified - * acceleration. - */ - public BallisticPath (Sprite sprite, Vector3f start, Vector3f velocity, - Vector3f accel, float duration) - { - super(sprite); - _curpos = start; - _velocity = velocity; - _accel = accel; - _duration = duration; - } - - // documentation inherited - public void update (float time) - { - // adjust the position - _velocity.mult(time, _temp); - _curpos.addLocal(_temp); - _sprite.setLocalTranslation(_curpos); - - // check to see if we're done - _accum += time; - if (_accum >= _duration) { - _sprite.pathCompleted(); - } else { - // adjust our velocity due to acceleration - _accel.mult(time, _temp); - _velocity.addLocal(_temp); - } - } - - /** - * Computes and returns the angle of elevation needed to launch a - * ballistic projectile at the specified velocity and have it travel - * the specified range (when it will once again reach the launch - * elevation). - */ - public static float computeElevation (float range, float vel, float accel) - { - return FastMath.asin(accel * range / (vel * vel)) / 2; - } - - /** - * Computes and returns the flight time of a projectile launched at an - * angle previously computed with {@link #computeElevation}.. - */ - public static float computeFlightTime (float range, float vel, float angle) - { - return range / (vel * FastMath.cos(angle)); - } - - protected Vector3f _curpos, _velocity, _accel; - protected float _duration, _accum; - protected Vector3f _temp = new Vector3f(0, 0, 0); -} diff --git a/src/java/com/threerings/jme/sprite/CubicSplinePath.java b/src/java/com/threerings/jme/sprite/CubicSplinePath.java deleted file mode 100644 index cb7b092f..00000000 --- a/src/java/com/threerings/jme/sprite/CubicSplinePath.java +++ /dev/null @@ -1,188 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.sprite; - -import com.jme.math.Vector3f; - -/** - * Moves a sprite along an interpolated spline based on a series of control - * points. - */ -public class CubicSplinePath extends Path -{ - /** - * Creates a path for the supplied sprite traversing the supplied - * series of points with the specified duration between points. The - * path assumes that all the control points exist on either the same - * x or y axis. The non-fixed x/y axis must be in order (either ascending - * or descending), and the z values will be interpolated. - * - * @param points a list of points to interpolate between. Currently - * all the points along one dimension must be equal. - * @param durations defines the elapsed time between each successive - * traversal. This will as a result be shorter by one element than the - * points array. - */ - public CubicSplinePath ( - Sprite sprite, Vector3f[] points, float[] durations) - { - super(sprite); - _isX = (points[0].x != points[1].x); - _x = new float[points.length]; - _y = new float[points.length]; - _z = (_isX ? points[0].y : points[0].x); - for (int ii = 0; ii < points.length; ii++) { - _x[ii] = (_isX ? points[ii].x : points[ii].y); - _y[ii] = points[ii].z; - } - _end = points[points.length - 1]; - _durations = durations; - calculateDerivatives(); - } - - // documentation inherited - public void update (float time) - { - // note the accumulated time - _accum += time; - - // if we have surpassed the time for this segment, subtract the - // segment time and move on to the next segment - while (_current < _durations.length && _accum > _durations[_current]) { - _accum -= _durations[_current]; - _current++; - } - - // if we have completed out path, move the sprite to the final - // position and wrap everything up - if (_current >= _durations.length) { - _sprite.setLocalTranslation(_end); - _sprite.pathCompleted(); - return; - } - - // move the sprite to the appropriate position between points - _sprite.getLocalTranslation().set(interpolate(0f)); - } - - /** - * Calculates the second derivative values for all the control points - * along the path. - */ - protected void calculateDerivatives () - { - float[] u = new float[_x.length]; - _y2 = new float[_x.length]; - for (int ii = 1; ii < _x.length - 1; ii++) { - float sig = (_x[ii] - _x[ii-1])/(_x[ii+1] - _x[ii-1]); - float p = sig * _y2[ii-1] + 2; - _y2[ii] = (sig - 1f) / p; - u[ii] = (6f * ((_y[ii+1] - _y[ii]) / (_x[ii+1] - _x[ii]) - - (_y[ii] - _y[ii-1]) / (_x[ii] - _x[ii-1])) / - (_x[ii+1] - _x[ii-1]) - sig * u[ii-1]) / p; - } - for (int ii = _x.length - 2; ii >= 0; ii--) { - _y2[ii] = _y2[ii] * _y2[ii + 1] + u[ii]; - } - } - - /** - * Interpolates the z value based on the current time point on the path. - * - * @param delta is the difference from the current time point to - * interpolate the point. - */ - protected Vector3f interpolate (float delta) - { - int idx = _current; - // no change, just use the current value - if (delta == 0f) { - delta = _accum; - - // find the control point after the current one for interpolating - } else if (delta + _accum > _durations[idx]) { - delta -= _durations[idx] - _accum; - while (idx < _durations.length - 1) { - idx++; - if (delta < _durations[idx]) { - break; - } - delta -= _durations[idx]; - } - if (delta > _durations[idx] || idx == _durations.length - 1) { - return _end; - } - - // find the control point before the current one for interpolating - } else if (_accum + delta < 0) { - delta += _accum; - while (idx > 0) { - idx--; - delta += _durations[idx]; - if (delta > 0) { - break; - } - } - if (delta < 0) { - delta = 0; - } - - // we're using the same control point, simply adjust the time point - } else { - delta += _accum; - } - - float h = _x[idx + 1] - _x[idx]; - // no different between these points, just return the current value - if (h == 0) { - if (_sprite != null) { - return new Vector3f(_sprite.getLocalTranslation()); - } - return new Vector3f(); - } - - float x = _x[idx] + h * (delta / _durations[idx]); - float a = (_x[idx + 1] - x) / h; - float b = (x - _x[idx]) / h; - float a3 = a * a * a, b3 = b * b * b; - float y = a * _y[idx] + b * _y[idx + 1] + - ((a3 - a) * _y2[idx] + (b3 - b) * _y2[idx + 1]) * - (h * h) / 6; - float z = y; - if (_isX) { - y = _z; - } else { - y = x; - x = _z; - } - return new Vector3f(x, y, z); - } - - /** The final path point */ - protected Vector3f _end; - /** The array of control points, derivatives and durations. */ - protected float[] _x, _y, _y2, _durations; - - protected float _accum, _z; - protected int _current; - protected boolean _isX; -} diff --git a/src/java/com/threerings/jme/sprite/LinePath.java b/src/java/com/threerings/jme/sprite/LinePath.java deleted file mode 100644 index 640482be..00000000 --- a/src/java/com/threerings/jme/sprite/LinePath.java +++ /dev/null @@ -1,60 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.sprite; - -import com.jme.math.Vector3f; - -/** - * Moves a sprite along a straight line. - */ -public class LinePath extends Path -{ - /** - * Moves the supplied sprite from the starting coordinate to the - * specified destination coordinate in the specified time. - */ - public LinePath (Sprite sprite, Vector3f start, Vector3f finish, - float duration) - { - super(sprite); - _start = start; - _finish = finish; - _duration = duration; - } - - // documentation inherited - public void update (float time) - { - _accum += time; - if (_accum >= _duration) { - _sprite.setLocalTranslation(_finish); - _sprite.pathCompleted(); - } else { - _temp.interpolate(_start, _finish, _accum / _duration); - _sprite.setLocalTranslation(_temp); - } - } - - protected Vector3f _start, _finish; - protected float _duration, _accum; - protected Vector3f _temp = new Vector3f(0, 0, 0); -} diff --git a/src/java/com/threerings/jme/sprite/LineSegmentPath.java b/src/java/com/threerings/jme/sprite/LineSegmentPath.java deleted file mode 100644 index 95f34f9f..00000000 --- a/src/java/com/threerings/jme/sprite/LineSegmentPath.java +++ /dev/null @@ -1,103 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.sprite; - -import com.jme.math.Quaternion; -import com.jme.math.Vector3f; - -/** - * Moves a sprite along a series of straight lines. - */ -public class LineSegmentPath extends Path -{ - /** - * Creates a path for the supplied sprite traversing the supplied - * series of points with the specified duration between points. - * - * @param points a list of points between which the sprite will be - * moved linearly (the sprite will be moved immediately to the first - * point). - * @param durations defines the elapsed time between each successive - * traversal. This will as a result be shorter by one element than the - * points array. - */ - public LineSegmentPath (Sprite sprite, Vector3f up, Vector3f orient, - Vector3f[] points, float[] durations) - { - super(sprite); - _up = up; - _orient = orient; - _points = points; - _durations = durations; - updateRotation(); - } - - // documentation inherited - public void update (float time) - { - // note the accumulated time - _accum += time; - - // if we have surpassed the time for this segment, subtract the - // segment time and move on to the next segment - while (_current < _durations.length && _accum > _durations[_current]) { - _accum -= _durations[_current]; - advance(); - } - - // if we have completed our path, move the sprite to the final - // position and wrap everything up - if (_current >= _durations.length) { - _sprite.setLocalTranslation(_points[_points.length-1]); - _sprite.pathCompleted(); - return; - } - - // move the sprite to the appropriate position between points - _temp.interpolate(_points[_current], _points[_current+1], - _accum / _durations[_current]); - _sprite.setLocalTranslation(_temp); - } - - protected void advance () - { - _current++; - if (_current < _points.length-1) { - updateRotation(); - } - } - - protected void updateRotation () - { - _points[_current+1].subtract(_points[_current], _temp); - PathUtil.computeRotation(_up, _orient, _temp, _rotate); - _sprite.getLocalRotation().set(_rotate); - } - - protected Vector3f _up, _orient; - protected Vector3f[] _points; - protected float[] _durations; - protected float _accum; - protected int _current; - protected Vector3f _temp = new Vector3f(0, 0, 0); - protected Quaternion _rotate = new Quaternion(); -} diff --git a/src/java/com/threerings/jme/sprite/OrientingBallisticPath.java b/src/java/com/threerings/jme/sprite/OrientingBallisticPath.java deleted file mode 100644 index 2aac2f74..00000000 --- a/src/java/com/threerings/jme/sprite/OrientingBallisticPath.java +++ /dev/null @@ -1,70 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.sprite; - -import com.jme.math.Quaternion; -import com.jme.math.Vector3f; - -/** - * A ballistic path that orients the sprite toward the velocity vector as - * it traverses the path. - */ -public class OrientingBallisticPath extends BallisticPath -{ - /** - * Creates a {@link BallisticPath} that will rotate the sprite so that - * the supplied orient is aligned with the velocity - * vector at all points along the path. If the provided orientation is - * not initially in line with the starting velocity, the sprite will - * be rotated immediately and then adjusted as it follows the path. - */ - public OrientingBallisticPath ( - Sprite sprite, Vector3f orient, Vector3f start, Vector3f velocity, - Vector3f accel, float duration) - { - super(sprite, start, velocity, accel, duration); - - // TODO: handle orient that is not (1, 0, 0) - _orient = orient; - - // compute the up vector (opposite of acceleration) - _up = accel.negate(); - _up.normalizeLocal(); - - _sprite.setLocalRotation( - PathUtil.computeAxisRotation(_up, velocity, _rotate)); - } - - // documentation inherited - public void update (float time) - { - // do the normal update - super.update(time); - - _sprite.setLocalRotation( - PathUtil.computeAxisRotation(_up, _velocity, _rotate)); - } - - protected Vector3f _orient; - protected Vector3f _up; - protected Quaternion _rotate = new Quaternion(); -} diff --git a/src/java/com/threerings/jme/sprite/Path.java b/src/java/com/threerings/jme/sprite/Path.java deleted file mode 100644 index 15b3a1dd..00000000 --- a/src/java/com/threerings/jme/sprite/Path.java +++ /dev/null @@ -1,51 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.sprite; - -import com.jme.scene.Controller; - -/** - * Defines a framework for moving sprites around and notifying interested - * parties when the sprite has completed its path or if the path has been - * cancelled. - */ -public abstract class Path extends Controller -{ - /** - * Creates and initializes this path with the sprite it will be - * manipulating. - */ - protected Path (Sprite sprite) - { - _sprite = sprite; - } - - /** - * Called when this path is removed from its sprite (either due to - * completion or cancellation). - */ - public void wasRemoved () - { - } - - protected Sprite _sprite; -} diff --git a/src/java/com/threerings/jme/sprite/PathObserver.java b/src/java/com/threerings/jme/sprite/PathObserver.java deleted file mode 100644 index 2ed59e3a..00000000 --- a/src/java/com/threerings/jme/sprite/PathObserver.java +++ /dev/null @@ -1,44 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.sprite; - -/** - * Implement this interface to find out when a sprite completes or cancels - * its path. - */ -public interface PathObserver extends SpriteObserver -{ - /** - * Called when a sprite's path is cancelled either because a new path - * was started or the path was explicitly cancelled with {@link - * Sprite#cancelMove}. - */ - public void pathCancelled (Sprite sprite, Path path); - - /** - * Called when a sprite completes its traversal of a path. - * - * @param sprite the sprite that completed its path. - * @param path the path that was completed. - */ - public void pathCompleted (Sprite sprite, Path path); -} diff --git a/src/java/com/threerings/jme/sprite/PathUtil.java b/src/java/com/threerings/jme/sprite/PathUtil.java deleted file mode 100644 index 95d4c5f0..00000000 --- a/src/java/com/threerings/jme/sprite/PathUtil.java +++ /dev/null @@ -1,95 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.sprite; - -import com.jme.math.FastMath; -import com.jme.math.Quaternion; -import com.jme.math.Vector3f; - -/** - * Path related utility functions. - */ -public class PathUtil -{ - /** - * Computes a rotation to align the X axis with the specified - * orientation and stores it in the provided target. The provided up - * vector is crossed with the new orientation to find the left vector - * and the left vector is recrossed with the orientation to find the - * correct up vector. - * - * @return the supplied target quaternion. - */ - public static Quaternion computeAxisRotation ( - Vector3f up, Vector3f orient, Quaternion target) - { - _axes[0].set(orient); - _axes[0].normalizeLocal(); - up.cross(_axes[0], _axes[1]); - _axes[1].normalizeLocal(); - _axes[0].cross(_axes[1], _axes[2]); - target.fromAxes(_axes); - return target; - } - - /** - * Computes a rotation from the one vector to another. - * - * @param axis will be used as the axis of rotation if the two vectors - * are parallel. - */ - public static Quaternion computeRotation ( - Vector3f axis, Vector3f from, Vector3f to, Quaternion target) - { - float angle = computeAngle(from, to); - if (angle == FastMath.PI) { // opposite - target.fromAngleAxis(angle, axis); - } else if (angle == 0) { // coincident - target.x = target.y = target.z = 0; - target.w = 1; - } else { - from.cross(to, _axis); - target.fromAngleAxis(angle, _axis); - } - return target; - } - - /** - * Computes the angle between two arbitrary vectors. - */ - public static float computeAngle (Vector3f one, Vector3f two) - { - return FastMath.acos(one.dot(two) / (one.length() * two.length())); - } - - /** - * Computes the angle between two normalized vectors. - */ - public static float computeAngleNormal (Vector3f one, Vector3f two) - { - return FastMath.acos(one.dot(two)); - } - - protected static Vector3f[] _axes = { - new Vector3f(), new Vector3f(), new Vector3f() }; - protected static Vector3f _axis = new Vector3f(); -} diff --git a/src/java/com/threerings/jme/sprite/Sprite.java b/src/java/com/threerings/jme/sprite/Sprite.java deleted file mode 100644 index d99c5dac..00000000 --- a/src/java/com/threerings/jme/sprite/Sprite.java +++ /dev/null @@ -1,244 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.sprite; - -import com.jme.scene.Node; -import com.jme.scene.Spatial; - -import com.samskivert.util.ObserverList; - -import static com.threerings.jme.Log.log; - -/** - * Represents a visual entity that one controls as a single unit. Sprites - * can be made to follow paths which is one of their primary reasons for - * existence. - */ -public class Sprite extends Node -{ - /** - * Walks down the hierarchy provided setting the animation speed on - * any controllers found along the way. - */ - public static void setAnimationSpeed (Spatial spatial, float speed) - { - for (int ii = 0; ii < spatial.getControllers().size(); ii++) { - spatial.getController(ii).setSpeed(speed); - } - if (spatial instanceof Node) { - Node node = (Node)spatial; - for (int ii = 0; ii < node.getQuantity(); ii++) { - setAnimationSpeed(node.getChild(ii), speed); - } - } - } - - /** - * Walks down the hierarchy provided turning on or off any controllers - * found along the way. - */ - public static void setAnimationActive (Spatial spatial, boolean active) - { - for (int ii = 0; ii < spatial.getControllers().size(); ii++) { - spatial.getController(ii).setActive(active); - } - if (spatial instanceof Node) { - Node node = (Node)spatial; - for (int ii = 0; ii < node.getQuantity(); ii++) { - setAnimationActive(node.getChild(ii), active); - } - } - } - - /** - * Walks down the hierarchy provided setting the animation repeat type on - * any controllers found along the way. - */ - public static void setAnimationRepeatType (Spatial spatial, int repeatType) - { - for (int ii = 0; ii < spatial.getControllers().size(); ii++) { - spatial.getController(ii).setRepeatType(repeatType); - } - if (spatial instanceof Node) { - Node node = (Node)spatial; - for (int ii = 0; ii < node.getQuantity(); ii++) { - setAnimationRepeatType(node.getChild(ii), repeatType); - } - } - } - - public Sprite () - { - super(""); - setName("sprite:" + hashCode()); - } - - /** - * Adds an observer to this sprite. Observers are notified when path - * related events take place. - */ - public void addObserver (SpriteObserver obs) - { - if (_observers == null) { - _observers = new ObserverList( - ObserverList.SAFE_IN_ORDER_NOTIFY); - } - _observers.add(obs); - } - - /** - * Removes the specified observer from this sprite. - */ - public void removeObserver (SpriteObserver obs) - { - if (_observers != null) { - _observers.remove(obs); - } - } - - /** - * Returns true if this sprite is moving along a path, false if not. - */ - public boolean isMoving () - { - return _path != null; - } - - /** - * Instructs this sprite to move along the specified path. Any - * currently executing path will be cancelled. - */ - public void move (Path path) - { - // if there's a previous path, let it know that it's going away - cancelMove(); - - // save off this path - _path = path; - addController(_path); - } - - /** - * Cancels any currently executing path. Any registered observers will - * be notified of the cancellation. - */ - public void cancelMove () - { - if (_path != null) { - Path oldpath = _path; - _path = null; - removeController(oldpath); - oldpath.wasRemoved(); - if (_observers != null) { - _observers.apply(new CancelledOp(this, oldpath)); - } - } - } - - /** - * Called by the active path when it has completed. Note: - * don't call this method unless you are implementing a {@link Path}. - */ - public void pathCompleted () - { - if (_path == null) { - log.warning("pathCompleted() called on pathless sprite " + - "(re-completed?) [sprite=" + this + "].", new Exception()); - return; - } - - Path oldpath = _path; - _path = null; - removeController(oldpath); - oldpath.wasRemoved(); - if (_observers != null) { - _observers.apply(new CompletedOp(this, oldpath)); - } - } - - /** - * Configures the speed of all controllers in our model hierarchy. - */ - public void setAnimationSpeed (float speed) - { - setAnimationSpeed(this, speed); - } - - /** - * Configures the active state of all controllers in our model hierarchy. - */ - public void setAnimationActive (boolean active) - { - setAnimationActive(this, active); - } - - /** - * Configures the repeat type of all controllers in our model hierarchy. - */ - public void setAnimationRepeatType (int repeatType) - { - setAnimationRepeatType(this, repeatType); - } - - /** Used to dispatch {@link PathObserver#pathCancelled}. */ - protected static class CancelledOp - implements ObserverList.ObserverOp - { - public CancelledOp (Sprite sprite, Path path) { - _sprite = sprite; - _path = path; - } - - public boolean apply (SpriteObserver observer) { - if (observer instanceof PathObserver) { - ((PathObserver)observer).pathCancelled(_sprite, _path); - } - return true; - } - - protected Sprite _sprite; - protected Path _path; - } - - /** Used to dispatch {@link PathObserver#pathCompleted}. */ - protected static class CompletedOp - implements ObserverList.ObserverOp - { - public CompletedOp (Sprite sprite, Path path) { - _sprite = sprite; - _path = path; - } - - public boolean apply (SpriteObserver observer) { - if (observer instanceof PathObserver) { - ((PathObserver)observer).pathCompleted(_sprite, _path); - } - return true; - } - - protected Sprite _sprite; - protected Path _path; - } - - protected ObserverList _observers; - protected Path _path; -} diff --git a/src/java/com/threerings/jme/sprite/SpriteObserver.java b/src/java/com/threerings/jme/sprite/SpriteObserver.java deleted file mode 100644 index 05813e07..00000000 --- a/src/java/com/threerings/jme/sprite/SpriteObserver.java +++ /dev/null @@ -1,29 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.sprite; - -/** - * The super-interface for all sprite observers. - */ -public interface SpriteObserver -{ -} diff --git a/src/java/com/threerings/jme/tile/FringeConfiguration.java b/src/java/com/threerings/jme/tile/FringeConfiguration.java deleted file mode 100644 index b9a78eda..00000000 --- a/src/java/com/threerings/jme/tile/FringeConfiguration.java +++ /dev/null @@ -1,163 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.tile; - -import java.io.Serializable; -import java.util.List; -import java.util.Map; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; - -import com.samskivert.util.StringUtil; - -import static com.threerings.jme.Log.log; - -/** - * Used to manage data about which tiles fringe on which others and how - * they fringe. - */ -public class FringeConfiguration implements Serializable -{ - /** Contains information on a type of tile and all of the fringe - * records associated with it. */ - public static class TileRecord implements Serializable - { - /** The type of tile to which this applies. */ - public String type; - - /** The fringe priority of this type. */ - public int priority; - - /** A list of the fringe records that can be used for fringing. */ - public List fringes = Lists.newArrayList(); - - /** Used when parsing from an XML definition. */ - public void addFringe (FringeRecord record) - { - if (record.isValid()) { - fringes.add(record); - } else { - log.warning("Not adding invalid fringe record [tile=" + this + - ", fringe=" + record + "]."); - } - } - - /** Did everything parse well? */ - public boolean isValid () - { - return ((type != null) && (priority > 0)); - } - - /** Generates a string representation of this instance. */ - public String toString () - { - return "[type=" + type + ", priority=" + priority + - ", fringes=" + StringUtil.toString(fringes) + "]"; - } - - /** Increase this value when object's serialized state is impacted - * by a class change (modification of fields, inheritance). */ - private static final long serialVersionUID = 1; - } - - /** Used to parse the type fringe definitions. */ - public static class FringeRecord implements Serializable - { - /** The name of the fringe tileset image. */ - public String name; - - /** Is this a mask? */ - public boolean mask; - - /** Did everything parse well? */ - public boolean isValid () - { - return (name != null); - } - - /** Generates a string representation of this instance. */ - public String toString () - { - return "[name=" + name + ", mask=" + mask + "]"; - } - - /** Increase this value when object's serialized state is impacted - * by a class change (modification of fields, inheritance). */ - private static final long serialVersionUID = 1; - } - - /** - * Adds a parsed fringe record to this instance. This is used when - * parsing the fringe records from xml. - */ - public void addTileRecord (TileRecord record) - { - if (record.isValid()) { - _trecs.put(record.type, record); - } else { - log.warning("Refusing to add invalid tile record " + - "[tile=" + record + "]."); - } - } - - /** - * If the first type fringes upon the second, return the fringe - * priority of the first type, otherwise return -1. - */ - public int fringesOn (String fringer, String fringed) - { - TileRecord f1 = _trecs.get(fringer); - - // we better have a fringe record for the fringer - if (null != f1) { - // it had better have some types defined - if (f1.fringes.size() > 0) { - TileRecord f2 = _trecs.get(fringed); - // and we only fringe if fringed doesn't have a fringe - // record or has a lower priority - if ((null == f2) || (f1.priority > f2.priority)) { - return f1.priority; - } - } - } - - return -1; - } - - /** - * Get a random FringeRecord from amongst the ones listed for the - * specified type. - */ - public FringeRecord getFringe (String type, int hashValue) - { - TileRecord t = _trecs.get(type); - return t.fringes.get(hashValue % t.fringes.size()); - } - - /** The mapping from tile type to tile record. */ - protected Map _trecs = Maps.newHashMap(); - - /** Increase this value when object's serialized state is impacted by - * a class change (modification of fields, inheritance). */ - private static final long serialVersionUID = 1; -} diff --git a/src/java/com/threerings/jme/tile/TileFringer.java b/src/java/com/threerings/jme/tile/TileFringer.java deleted file mode 100644 index be198eaf..00000000 --- a/src/java/com/threerings/jme/tile/TileFringer.java +++ /dev/null @@ -1,406 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.tile; - -import java.awt.Graphics2D; -import java.awt.Transparency; -import java.awt.image.BufferedImage; -import java.util.List; -import java.util.Map; - -import com.google.common.collect.Lists; - -import com.samskivert.util.QuickSort; - -import com.threerings.media.image.ImageUtil; -import com.threerings.media.tile.TileUtil; - -import static com.threerings.jme.Log.log; - -/** - * Computes fringe tile images according to the rules in an associated - * fringe configuration. - */ -public class TileFringer -{ - public static interface TileSource - { - /** Returns the type of tile at the specified coordinates or -1 if - * there is no tile at this coordinate. */ - public String getTileType (int x, int y); - - /** Returns the tile type to use when a coordinate has no tile. */ - public String getDefaultType (); - } - - public static interface ImageSource extends ImageUtil.ImageCreator - { - /** Creates a blank image into which various fringe images will be - * composited. */ - public BufferedImage createImage ( - int width, int height, int transparency); - - /** Returns the source image for a tile of the specified type. - * This can be randomly selected and change from call to call. */ - public BufferedImage getTileSource (String type); - - /** Returns the named fringe source image (one long strip). */ - public BufferedImage getFringeSource (String name); - } - - /** - * Creates a fringer that will fringe according to the rules in the - * supplied configuration. - */ - public TileFringer (FringeConfiguration config, ImageSource isrc) - { - _config = config; - _isrc = isrc; - } - - /** - * Computes, creates and returns the base tile with the appropriate - * fringe imagery applied to it for the specified location. - * - * @param masks used to cache intermediate images of tiles cut out - * using a fringe mask. - */ - public BufferedImage getFringeTile ( - TileSource tiles, int col, int row, Map masks) - { - // get the type of the tile we are considering - String baseType = tiles.getTileType(col, row); - if (baseType == null) { - baseType = tiles.getDefaultType(); - } - - // start with an empty fringer list - FringerRec fringers = null; - - // walk through our influence tiles - for (int y = row - 1, maxy = row + 2; y < maxy; y++) { - for (int x = col - 1, maxx = col + 2; x < maxx; x++) { - // we sensibly do not consider ourselves - if ((x == col) && (y == row)) { - continue; - } - - // determine the type of our fringing neighbor - String fringerType = tiles.getTileType(x, y); - if (fringerType == null) { - fringerType = tiles.getDefaultType(); - } - - // determine if it fringes on our tile - int pri = _config.fringesOn(fringerType, baseType); - if (pri == -1) { - continue; - } - - FringerRec fringer = (fringers == null) ? - null : fringers.find(fringerType); - if (fringer == null) { - fringer = fringers = - new FringerRec(fringerType, pri, fringers); - } - - // now turn on the appropriate fringebits - int dy = y - row, dx = x - col; - fringer.bits |= FLAGMATRIX[dy*3+dx+4]; - } - } - - // if nothing fringed, we're done - if (fringers == null) { - return null; - } - - // otherwise compose a fringe tile from the specified fringes - return composeFringeTile( - baseType, fringers.toArray(), masks, TileUtil.getTileHash(col, row)); - } - - /** - * Compose a fringe tile out of the various fringe images needed. - */ - protected BufferedImage composeFringeTile ( - String baseType, FringerRec[] fringers, Map masks, int hashValue) - { - // sort the array so that higher priority fringers get drawn first - QuickSort.sort(fringers); - - BufferedImage source = _isrc.getTileSource(baseType); - if (source == null) { - log.warning("Missing source tile [type=" + baseType + "]."); - return null; - } - - BufferedImage ftimg = _isrc.createImage( - source.getWidth(), source.getHeight(), Transparency.OPAQUE); - Graphics2D gfx = (Graphics2D)ftimg.getGraphics(); - try { - // start with the base tile image - gfx.drawImage(source, 0, 0, null); - - // and stamp the fringers on top of it - for (int ii = 0; ii < fringers.length; ii++) { - int[] indexes = getFringeIndexes(fringers[ii].bits); - for (int jj = 0; jj < indexes.length; jj++) { - stampTileImage(gfx, fringers[ii].fringerType, - indexes[jj], masks, hashValue); - } - } - - } finally { - gfx.dispose(); - } - return ftimg; - } - - /** - * Looks up or creates the appropriate fringe mask and draws it into - * the supplied graphics context. - */ - protected void stampTileImage ( - Graphics2D gfx, String fringerType, int index, - Map masks, int hashValue) - { - FringeConfiguration.FringeRecord frec = - _config.getFringe(fringerType, hashValue); - BufferedImage fsimg = (frec == null) ? null : - _isrc.getFringeSource(frec.name); - if (fsimg == null) { - log.warning("Missing fringe source image [type=" + fringerType + - ", hash=" + hashValue + ", frec=" + frec + "]."); - return; - } - - if (frec.mask) { - // it's a mask; look for it in the cache - String maskkey = fringerType + ":" + frec.name + ":" + index; - BufferedImage mimg = masks.get(maskkey); - if (mimg == null) { - BufferedImage fsrc = getSubimage(fsimg, index); - BufferedImage bsrc = _isrc.getTileSource(fringerType); - mimg = ImageUtil.composeMaskedImage(_isrc, fsrc, bsrc); - masks.put(maskkey, mimg); - } - gfx.drawImage(mimg, 0, 0, null); - - } else { - // this is a non-mask image so just use the data from the - // fringe source image directly - gfx.drawImage(getSubimage(fsimg, index), 0, 0, null); - } - } - - /** - * Returns the indexth tile image from the supplied - * source image. The source image is assumed to be a single strip of - * tile images, each with equal width and height. - */ - protected BufferedImage getSubimage (BufferedImage source, int index) - { - int size = source.getHeight(), x = size * index; - return source.getSubimage(x, 0, size, size); - } - - /** - * Get the fringe index specified by the fringebits. If no index - * is available, try breaking down the bits into contiguous regions of - * bits and look for indexes for those. - */ - protected int[] getFringeIndexes (int bits) - { - int index = BITS_TO_INDEX[bits]; - if (index != -1) { - int[] ret = new int[1]; - ret[0] = index; - return ret; - } - - // otherwise, split the bits into contiguous components - - // look for a zero and start our first split - int start = 0; - while ((((1 << start) & bits) != 0) && (start < NUM_FRINGEBITS)) { - start++; - } - - if (start == NUM_FRINGEBITS) { - // we never found an empty fringebit, and since index (above) - // was already -1, we have no fringe tile for these bits.. sad. - return new int[0]; - } - - List indexes = Lists.newArrayList(); - int weebits = 0; - for (int ii=(start + 1) % NUM_FRINGEBITS; ii != start; - ii = (ii + 1) % NUM_FRINGEBITS) { - - if (((1 << ii) & bits) != 0) { - weebits |= (1 << ii); - } else if (weebits != 0) { - index = BITS_TO_INDEX[weebits]; - if (index != -1) { - indexes.add(Integer.valueOf(index)); - } - weebits = 0; - } - } - if (weebits != 0) { - index = BITS_TO_INDEX[weebits]; - if (index != -1) { - indexes.add(Integer.valueOf(index)); - } - } - - int[] ret = new int[indexes.size()]; - for (int ii=0; ii < ret.length; ii++) { - ret[ii] = indexes.get(ii).intValue(); - } - return ret; - } - - /** A record for holding information about a particular fringe as - * we're computing what it will look like. */ - protected static class FringerRec implements Comparable - { - public String fringerType; - public int priority; - public int bits; - public FringerRec next; - - public FringerRec (String type, int pri, FringerRec next) { - fringerType = type; - priority = pri; - this.next = next; - } - - public FringerRec find (String type) - { - if (fringerType.equals(type)) { - return this; - } else if (next != null) { - return next.find(type); - } else { - return null; - } - } - - public FringerRec[] toArray () - { - return toArray(0); - } - - public int compareTo (FringerRec o) { - return priority - o.priority; - } - - public String toString () { - return "[type=" + fringerType + ", pri=" + priority + - ", bits=" + Integer.toString(bits, 16) + "]"; - } - - protected FringerRec[] toArray (int index) - { - FringerRec[] array; - if (next == null) { - array = new FringerRec[index+1]; - } else { - array = next.toArray(index+1); - } - array[index] = this; - return array; - } - } - - protected static final int NORTH = 1 << 0; - protected static final int NORTHEAST = 1 << 1; - protected static final int EAST = 1 << 2; - protected static final int SOUTHEAST = 1 << 3; - protected static final int SOUTH = 1 << 4; - protected static final int SOUTHWEST = 1 << 5; - protected static final int WEST = 1 << 6; - protected static final int NORTHWEST = 1 << 7; - - protected static final int NUM_FRINGEBITS = 8; - - /** A matrix mapping adjacent tiles to which fringe bits they affect. - * (x and y are offset by +1, since we can't have -1 as an array index). - * These are "upside down" thanks to OpenGL. */ - protected static final int[] FLAGMATRIX = { - SOUTHWEST, (SOUTHEAST | SOUTH | SOUTHWEST), SOUTHEAST, - (NORTHWEST | WEST | SOUTHWEST), 0, (NORTHEAST | EAST | SOUTHEAST), - NORTHWEST, (NORTHWEST | NORTH | NORTHEAST), NORTHEAST, - }; - - /** The fringe tiles we use. These are the 17 possible tiles made up - * of continuous fringebits sections. */ - protected static final int[] FRINGETILES = { - SOUTHEAST, - SOUTHWEST | SOUTH | SOUTHEAST, - SOUTHWEST, - NORTHEAST | EAST | SOUTHEAST, - NORTHWEST | WEST | SOUTHWEST, - NORTHEAST, - NORTHWEST | NORTH | NORTHEAST, - NORTHWEST, - - SOUTHWEST | WEST | NORTHWEST | NORTH | NORTHEAST, - NORTHWEST | NORTH | NORTHEAST | EAST | SOUTHEAST, - NORTHWEST | WEST | SOUTHWEST | SOUTH | SOUTHEAST, - SOUTHWEST | SOUTH | SOUTHEAST | EAST | NORTHEAST, - - NORTHEAST | NORTH | NORTHWEST | WEST | SOUTHWEST | SOUTH | SOUTHEAST, - SOUTHEAST | EAST | NORTHEAST | NORTH | NORTHWEST | WEST | SOUTHWEST, - SOUTHWEST | SOUTH | SOUTHEAST | EAST | NORTHEAST | NORTH | NORTHWEST, - NORTHWEST | WEST | SOUTHWEST | SOUTH | SOUTHEAST | EAST | NORTHEAST, - - // all the directions! - NORTH | NORTHEAST | EAST | SOUTHEAST | SOUTH | SOUTHWEST | - WEST | NORTHWEST - }; - - /** A reverse map of the {@link #FRINGETILES} array, for quickly - * looking up which tile we want. */ - protected static final int[] BITS_TO_INDEX; - - // Construct the BITS_TO_INDEX array. - static { - int num = (1 << NUM_FRINGEBITS); - BITS_TO_INDEX = new int[num]; - - // first clear everything to -1 (meaning there is no tile defined) - for (int ii=0; ii < num; ii++) { - BITS_TO_INDEX[ii] = -1; - } - - // then fill in with the defined tiles. - for (int ii=0; ii < FRINGETILES.length; ii++) { - BITS_TO_INDEX[FRINGETILES[ii]] = ii; - } - } - - protected ImageSource _isrc; - protected FringeConfiguration _config; -} diff --git a/src/java/com/threerings/jme/tile/tools/CompileFringeConfigurationTask.java b/src/java/com/threerings/jme/tile/tools/CompileFringeConfigurationTask.java deleted file mode 100644 index 6c5a8b2e..00000000 --- a/src/java/com/threerings/jme/tile/tools/CompileFringeConfigurationTask.java +++ /dev/null @@ -1,75 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.tile.tools; - -import java.io.File; -import java.io.Serializable; - -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.Task; - -import com.threerings.util.CompiledConfig; - -import com.threerings.jme.tile.tools.xml.FringeConfigurationParser; - -/** - * Compiles a fringe configuration from XML format into binary format. - */ -public class CompileFringeConfigurationTask extends Task -{ - public void setConfig (File config) - { - _config = config; - } - - public void setTarget (File target) - { - _target = target; - } - - public void execute () throws BuildException - { - // make sure the config file exists - if (!_config.exists()) { - throw new BuildException( - "Fringe configuration file not found [path=" + _config + "]."); - } - - FringeConfigurationParser parser = new FringeConfigurationParser(); - Serializable config; - try { - config = parser.parseConfig(_config); - } catch (Exception e) { - throw new BuildException("Failure parsing fringe config", e); - } - - try { - // and write it on out - CompiledConfig.saveConfig(_target, config); - } catch (Exception e) { - throw new BuildException("Failure writing serialized config", e); - } - } - - protected File _config; - protected File _target; -} diff --git a/src/java/com/threerings/jme/tile/tools/xml/FringeConfigurationParser.java b/src/java/com/threerings/jme/tile/tools/xml/FringeConfigurationParser.java deleted file mode 100644 index 0179105b..00000000 --- a/src/java/com/threerings/jme/tile/tools/xml/FringeConfigurationParser.java +++ /dev/null @@ -1,82 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.tile.tools.xml; - -import java.io.Serializable; - -import org.apache.commons.digester.Digester; - -import com.samskivert.xml.SetPropertyFieldsRule; - -import com.threerings.tools.xml.CompiledConfigParser; - -import com.threerings.jme.tile.FringeConfiguration.TileRecord; -import com.threerings.jme.tile.FringeConfiguration.FringeRecord; -import com.threerings.jme.tile.FringeConfiguration; - -/** - * Parses fringe config definitions, which look like so (with angle - * brackets instead of square): - *
- * [fringe]
- *   [tile type="water" priority="100"]
- *      [fringe name="water_fringe_1"/]
- *      [fringe name="water_fringe_2"/]
- *      [fringe name="water_fringe_3"/]
- *   [/tile]
- *   [tile type="dirt" priority="10"]
- *      [fringe name="dirt_fringe_1" mask="true"/]
- *   [/tile]
- *   [tile type="cobble" priority="100"]
- *      [fringe name="cobble_fringe_1" mask="false"/]
- *   [/tile]
- * [/fringe]
- * 
- */ -public class FringeConfigurationParser extends CompiledConfigParser -{ - // documentation inherited - protected Serializable createConfigObject () - { - return new FringeConfiguration(); - } - - // documentation inherited - protected void addRules (Digester digest) - { - // configure top-level constraints - String prefix = "fringe"; - digest.addRule(prefix, new SetPropertyFieldsRule()); - - // create and configure fringe config instances - prefix += "/tile"; - digest.addObjectCreate(prefix, TileRecord.class.getName()); - digest.addRule(prefix, new SetPropertyFieldsRule()); - digest.addSetNext(prefix, "addTileRecord"); - - // create the fringe type records in each tile record - prefix += "/fringe"; - digest.addObjectCreate(prefix, FringeRecord.class.getName()); - digest.addRule(prefix, new SetPropertyFieldsRule()); - digest.addSetNext(prefix, "addFringe"); - } -} diff --git a/src/java/com/threerings/jme/tools/AnimationDef.java b/src/java/com/threerings/jme/tools/AnimationDef.java deleted file mode 100644 index 978c102e..00000000 --- a/src/java/com/threerings/jme/tools/AnimationDef.java +++ /dev/null @@ -1,212 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.tools; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Properties; - -import com.google.common.collect.Lists; -import com.google.common.collect.Sets; - -import com.jme.math.Matrix4f; -import com.jme.math.Quaternion; -import com.jme.math.Vector3f; -import com.jme.scene.Controller; -import com.jme.scene.Node; -import com.jme.scene.Spatial; - -import com.samskivert.util.Tuple; - -import com.threerings.jme.model.Model; -import com.threerings.jme.util.JmeUtil; - -import com.threerings.jme.tools.ModelDef.TransformNode; - -/** - * A basic representation for keyframe animations. - */ -public class AnimationDef -{ - /** The rate of the animation in frames per second. */ - public int frameRate; - - /** A single frame of the animation. */ - public static class FrameDef - { - /** Transform for affected nodes. */ - public ArrayList transforms = Lists.newArrayList(); - - public void addTransform (TransformDef transform) - { - transforms.add(transform); - } - - /** Adds all transform targets in this frame to the supplied sets. */ - public void addTransformTargets ( - HashMap nodes, HashMap tnodes, - HashSet staticTargets, HashSet transformTargets) - { - for (int ii = 0, nn = transforms.size(); ii < nn; ii++) { - String name = transforms.get(ii).name; - Spatial target = nodes.get(name); - if (target == null) { - continue; - } - TransformNode tnode = tnodes.get(name); - if (tnode.baseLocalTransform != null) { - staticTargets.add(target); - } else { - transformTargets.add(target); - } - } - } - - /** Returns the array of transforms for this frame. */ - public Model.Transform[] getTransforms (Spatial[] targets) - { - Model.Transform[] mtransforms = - new Model.Transform[targets.length]; - for (int ii = 0; ii < targets.length; ii++) { - mtransforms[ii] = getTransform(targets[ii]); - } - return mtransforms; - } - - /** Returns the transform for the supplied target. */ - protected Model.Transform getTransform (Spatial target) - { - String name = target.getName(); - for (int ii = 0, nn = transforms.size(); ii < nn; ii++) { - TransformDef transform = transforms.get(ii); - if (name.equals(transform.name)) { - return transform.getTransform(); - } - } - return null; - } - } - - /** A transform for a single node. */ - public static class TransformDef - { - /** The name of the affected node. */ - public String name; - - /** The transformation parameters. */ - public float[] translation; - public float[] rotation; - public float[] scale; - - /** Returns the live transform object. */ - public Model.Transform getTransform () - { - return new Model.Transform( - new Vector3f(translation[0], translation[1], translation[2]), - new Quaternion(rotation[0], rotation[1], rotation[2], rotation[3]), - new Vector3f(scale[0], scale[1], scale[2])); - } - } - - /** The individual frames of the animation. */ - public ArrayList frames = Lists.newArrayList(); - - public void addFrame (FrameDef frame) - { - frames.add(frame); - } - - /** - * Runs through each frame of the animation, updating the transforms of the preprocessing - * node to keep track of which transforms diverge from their original states. - */ - public void filterTransforms (Node root, HashMap nodes) - { - // clear the nodes' transformed flags - for (TransformNode node : nodes.values()) { - node.transformed = false; - } - - // run through all animation frames - for (FrameDef frame : frames) { - for (TransformDef transform : frame.transforms) { - TransformNode node = nodes.get(transform.name); - if (node != null) { - node.setLocalTransform( - transform.translation, transform.rotation, transform.scale); - node.transformed = true; - } - } - root.updateGeometricState(0f, true); - for (TransformNode node : nodes.values()) { - node.cullDivergentTransforms(); - } - } - - // remove from merge candidates any pairs where one is visible and the other isn't - for (TransformNode node : nodes.values()) { - for (Iterator> it = node.relativeTransforms.iterator(); - it.hasNext(); ) { - if (it.next().left.transformed != node.transformed) { - it.remove(); - } - } - } - } - - /** - * Creates the "live" animation object that will be serialized with the - * object. - * - * @param props the animation properties - * @param nodes the nodes in the model, mapped by name - */ - public Model.Animation createAnimation ( - Properties props, HashMap nodes, HashMap tnodes) - { - // find all affected nodes - HashSet staticTargets = Sets.newHashSet(), - transformTargets = Sets.newHashSet(); - for (int ii = 0, nn = frames.size(); ii < nn; ii++) { - frames.get(ii).addTransformTargets(nodes, tnodes, staticTargets, transformTargets); - } - - // create and configure the animation - Model.Animation anim = new Model.Animation(); - anim.frameRate = frameRate; - anim.repeatType = JmeUtil.parseRepeatType(props.getProperty("repeat_type"), - Controller.RT_CLAMP); - - // collect all transforms - anim.staticTargets = staticTargets.toArray(new Spatial[staticTargets.size()]); - anim.transformTargets = transformTargets.toArray(new Spatial[transformTargets.size()]); - anim.transforms = new Model.Transform[frames.size()][transformTargets.size()]; - for (int ii = 0; ii < anim.transforms.length; ii++) { - anim.transforms[ii] = - frames.get(ii).getTransforms(anim.transformTargets); - } - - return anim; - } -} diff --git a/src/java/com/threerings/jme/tools/BuildSphereMap.java b/src/java/com/threerings/jme/tools/BuildSphereMap.java deleted file mode 100644 index ba2660ad..00000000 --- a/src/java/com/threerings/jme/tools/BuildSphereMap.java +++ /dev/null @@ -1,164 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.tools; - -import java.awt.image.BufferedImage; - -import java.io.File; -import java.io.IOException; - -import javax.imageio.ImageIO; - -import com.jme.math.FastMath; -import com.jme.math.Vector3f; - -/** - * A tool for converting cube maps (sky boxes) to sphere maps. - */ -public class BuildSphereMap -{ - public static void main (String[] args) - { - if (args.length < 7) { - System.err.println("Usage: BuildSphereMap front.ext back.ext " + - "left.ext right.ext up.ext dest.ext size"); - System.exit(-1); - } - - try { - execute(new File(args[0]), new File(args[1]), new File(args[2]), - new File(args[3]), new File(args[4]), new File(args[5]), - Integer.parseInt(args[6])); - - } catch (Exception e) { - e.printStackTrace(); - } - } - - /** - * Builds the sphere map. - * - * @param front the file containing the front side of the cube map - * @param back the file containing the back side of the cube map - * @param left the file containing the left side of the cube map - * @param right the file containing the right side of the cube map - * @param up the file containing the up side of the cube map - * @param target the file to contain the sphere map - * @param size the size of the sphere map to generate - */ - public static void execute (File front, File back, File left, File right, - File up, File target, int size) - throws IOException - { - // load up the sides of the cube map - BufferedImage[] sides = new BufferedImage[5]; - sides[FRONT] = ImageIO.read(front); - sides[BACK] = ImageIO.read(back); - sides[LEFT] = ImageIO.read(left); - sides[RIGHT] = ImageIO.read(right); - sides[UP] = ImageIO.read(up); - - // compute the pixels - int[] rgb = new int[size * size]; - Vector3f vec = new Vector3f(); - for (int y = 0, idx = 0; y < size; y++) { - for (int x = 0; x < size; x++, idx++) { - float vx = x / (size*0.5f) - 1f, vy = y / (size*0.5f) - 1f, d2 = vx*vx + vy*vy; - if (d2 <= 1f) { - vec.set(vx, vy, FastMath.sqrt(1f - d2)); - rgb[idx] = getCubeMapPixel(vec, sides); - } - } - } - - // create and write the image - BufferedImage image = new BufferedImage(size, size, - BufferedImage.TYPE_INT_RGB); - image.setRGB(0, 0, size, size, rgb, 0, size); - String dest = target.toString(), - ext = dest.substring(dest.lastIndexOf('.')+1); - ImageIO.write(image, ext, target); - } - - /** - * Returns the pixel from the cube map to which the given vector points. - */ - protected static int getCubeMapPixel (Vector3f vec, BufferedImage[] sides) - { - int side = getCubeMapSide(vec); - - float s, t; - switch (side) { - case FRONT: - s = -vec.x / vec.y; - t = vec.z / vec.y; - break; - case BACK: - s = -vec.x / vec.y; - t = -vec.z / vec.y; - break; - case LEFT: - s = vec.y / vec.x; - t = -vec.z / vec.x; - break; - case RIGHT: - s = vec.y / vec.x; - t = vec.z / vec.x; - break; - default: - case UP: - s = vec.x / vec.z; - t = -vec.y / vec.z; - break; - } - int width = sides[side].getWidth(), height = sides[side].getHeight(); - return sides[side].getRGB((int)((width-1) * (s+1f)/2f), - (int)((height-1) * (1f-t)/2f)); - } - - /** - * Returns the side index identifying the face of the cube map to which - * the given vector points. - */ - protected static int getCubeMapSide (Vector3f vec) - { - if (vec.x > vec.z && vec.x > vec.y && vec.x > -vec.y) { - return RIGHT; - - } else if (vec.x < -vec.z && vec.x < -vec.y && vec.x < vec.y) { - return LEFT; - - } else if (vec.y > vec.z) { - return FRONT; - - } else if (vec.y < -vec.z) { - return BACK; - - } else { - return UP; - } - } - - /** The sides of the cube map. */ - protected static final int FRONT = 0, BACK = 1, LEFT = 2, RIGHT = 3, - UP = 4; -} diff --git a/src/java/com/threerings/jme/tools/BuildSphereMapTask.java b/src/java/com/threerings/jme/tools/BuildSphereMapTask.java deleted file mode 100644 index 70c3d651..00000000 --- a/src/java/com/threerings/jme/tools/BuildSphereMapTask.java +++ /dev/null @@ -1,86 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.tools; - -import java.io.File; -import java.io.IOException; - -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.Task; - -/** - * An ant task for converting cube maps (sky boxes) to sphere maps. - */ -public class BuildSphereMapTask extends Task -{ - public void setFront (File front) - { - _front = front; - } - - public void setBack (File back) - { - _back = back; - } - - public void setLeft (File left) - { - _left = left; - } - - public void setRight (File right) - { - _right = right; - } - - public void setUp (File up) - { - _up = up; - } - - public void setTarget (File target) - { - _target = target; - } - - public void setSize (int size) - { - _size = size; - } - - public void execute () throws BuildException - { - try { - BuildSphereMap.execute(_front, _back, _left, _right, _up, _target, - _size); - - } catch (IOException e) { - throw new BuildException("Failure building sphere map", e); - } - } - - /** The files representing the sides of the cube map and the target. */ - protected File _front, _back, _left, _right, _up, _target; - - /** The size of the target image. */ - protected int _size; -} diff --git a/src/java/com/threerings/jme/tools/CompileModel.java b/src/java/com/threerings/jme/tools/CompileModel.java deleted file mode 100644 index 623aa370..00000000 --- a/src/java/com/threerings/jme/tools/CompileModel.java +++ /dev/null @@ -1,167 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.tools; - -import java.io.File; -import java.io.FileInputStream; - -import java.util.HashMap; -import java.util.Properties; -import java.util.logging.Level; - -import com.google.common.collect.Maps; - -import com.jme.scene.Node; -import com.jme.scene.Spatial; -import com.jme.util.LoggingSystem; -import com.jmex.model.XMLparser.Converters.DummyDisplaySystem; - -import com.samskivert.util.PropertiesUtil; -import com.samskivert.util.StringUtil; - -import com.threerings.jme.model.Model; -import com.threerings.jme.tools.ModelDef.TransformNode; -import com.threerings.jme.tools.xml.AnimationParser; -import com.threerings.jme.tools.xml.ModelParser; - -/** - * An application for compiling 3D models defined in XML to fast-loading binary files. - */ -public class CompileModel -{ - /** - * Loads the model described by the given properties file and compiles it to a - * .dat file in the same directory. - * - * @return the loaded model, or null if the compiled version is up-to-date - */ - public static Model compile (File source) - throws Exception - { - return compile(source, source.getParentFile()); - } - - /** - * Loads the model described by the given properties file and compiles it into a - * .dat file in the specified directory. - * - * @return the loaded model, or null if the compiled version is up-to-date - */ - public static Model compile (File source, File targetDir) - throws Exception - { - String sname = source.getName(); - int didx = sname.lastIndexOf('.'); - String root = (didx == -1) ? sname : sname.substring(0, didx); - File target = new File(targetDir, root + ".dat"); - File content = new File(source.getParentFile(), root + ".mxml"); - - boolean needsUpdate = false; - if (source.lastModified() >= target.lastModified() || - content.lastModified() >= target.lastModified()) { - needsUpdate = true; - } - - // load the model properties - Properties props = new Properties(); - FileInputStream in = new FileInputStream(source); - props.load(in); - in.close(); - - // locate the animations, if any - String[] anims = StringUtil.parseStringArray(props.getProperty("animations", "")); - File[] afiles = new File[anims.length]; - File dir = source.getParentFile(); - for (int ii = 0; ii < anims.length; ii++) { - afiles[ii] = new File(dir, anims[ii] + ".mxml"); - if (afiles[ii].lastModified() >= target.lastModified()) { - needsUpdate = true; - } - } - if (!needsUpdate) { - return null; - } - - System.out.println("Compiling to " + target + "..."); - - // parse the model and animations - ModelDef mdef = _mparser.parseModel(content.toString()); - AnimationDef[] adefs = new AnimationDef[anims.length]; - for (int ii = 0; ii < adefs.length; ii++) { - System.out.println(" Adding " + afiles[ii] + "..."); - adefs[ii] = _aparser.parseAnimation(afiles[ii].toString()); - } - - // preprocess the model and animations to determine which nodes never move, which never - // move within an animation, and which never move with respect to others - HashMap tnodes = Maps.newHashMap(); - Node troot = mdef.createTransformTree(props, tnodes); - for (AnimationDef adef : adefs) { - adef.filterTransforms(troot, tnodes); - } - mdef.mergeSpatials(tnodes); - - // load the model content - HashMap nodes = Maps.newHashMap(); - Model model = mdef.createModel(props, nodes); - model.initPrototype(); - - // load the animations, if any - for (int ii = 0; ii < anims.length; ii++) { - model.addAnimation(anims[ii], adefs[ii].createAnimation( - PropertiesUtil.getSubProperties(props, anims[ii]), nodes, tnodes)); - } - - // write and return the model - File parent = target.getParentFile(); - if (!parent.isDirectory() && !parent.mkdirs()) { - System.err.println("Unable to create target directory '" + parent + "'."); - } else { - model.writeToFile(target); - } - return model; - } - - public static void main (String[] args) - { - if (args.length < 1) { - System.err.println("Usage: CompileModel source.properties"); - System.exit(-1); - } - - // create a dummy display system - new DummyDisplaySystem(); - LoggingSystem.getLogger().setLevel(Level.WARNING); - - try { - compile(new File(args[0])); - } catch (Exception e) { - System.err.println("Error compiling model: " + e); - } - } - - /** A parser for the model definitions. */ - protected static ModelParser _mparser = new ModelParser(); - - /** A parser for the animation definitions. */ - protected static AnimationParser _aparser = new AnimationParser(); -} diff --git a/src/java/com/threerings/jme/tools/CompileModelTask.java b/src/java/com/threerings/jme/tools/CompileModelTask.java deleted file mode 100644 index 34010989..00000000 --- a/src/java/com/threerings/jme/tools/CompileModelTask.java +++ /dev/null @@ -1,87 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.tools; - -import java.io.File; - -import java.util.ArrayList; -import java.util.logging.Level; - -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.DirectoryScanner; -import org.apache.tools.ant.Task; -import org.apache.tools.ant.types.FileSet; - -import com.google.common.collect.Lists; - -import com.jme.util.LoggingSystem; -import com.jmex.model.XMLparser.Converters.DummyDisplaySystem; - -/** - * An ant task for compiling 3D models defined in XML to fast-loading binary files. - */ -public class CompileModelTask extends Task -{ - public void setDest (File dest) - { - _dest = dest; - } - - public void addFileset (FileSet set) - { - _filesets.add(set); - } - - public void init () throws BuildException - { - // create a dummy display system - new DummyDisplaySystem(); - LoggingSystem.getLogger().setLevel(Level.WARNING); - } - - public void execute () - throws BuildException - { - String baseDir = getProject().getBaseDir().getPath(); - for (FileSet fs : _filesets) { - DirectoryScanner ds = fs.getDirectoryScanner(getProject()); - File fromDir = fs.getDir(getProject()); - for (String file : ds.getIncludedFiles()) { - File source = new File(fromDir, file); - File destDir = (_dest == null) ? source.getParentFile() : - new File(source.getParent().replaceAll(baseDir, _dest.getPath())); - try { - CompileModel.compile(source, destDir); - } catch (Exception e) { - System.err.println("Error compiling " + source + ": " + e); - } - } - } - } - - /** The directory in which we will generate our model output (in a directory tree mirroring the - * source files. */ - protected File _dest; - - /** A list of filesets that contain XML models. */ - protected ArrayList _filesets = Lists.newArrayList(); -} diff --git a/src/java/com/threerings/jme/tools/ConvertModel.java b/src/java/com/threerings/jme/tools/ConvertModel.java deleted file mode 100644 index 17da81d2..00000000 --- a/src/java/com/threerings/jme/tools/ConvertModel.java +++ /dev/null @@ -1,100 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.tools; - -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.net.URL; - -import com.jmex.model.XMLparser.Converters.AseToJme; -import com.jmex.model.XMLparser.Converters.DummyDisplaySystem; -import com.jmex.model.XMLparser.Converters.FormatConverter; -import com.jmex.model.XMLparser.Converters.MaxToJme; -import com.jmex.model.XMLparser.Converters.Md2ToJme; -import com.jmex.model.XMLparser.Converters.Md3ToJme; -import com.jmex.model.XMLparser.Converters.ObjToJme; - -/** - * A tool for converting various 3D model formats into JME's internal - * format. - */ -public class ConvertModel -{ - public static void main (String[] args) - { - if (args.length < 2) { - System.err.println("Usage: ConvertModel source.ext dest.jme"); - System.exit(-1); - } - - // create a dummy display system which the converters need - new DummyDisplaySystem(); - - File source = new File(args[0]); - File target = new File(args[1]); - - String path = source.getPath().toLowerCase(); - String type = path.substring(path.lastIndexOf(".") + 1); - - // set up our converter - FormatConverter convert = null; - if (type.equals("obj")) { - convert = new ObjToJme(); - try { - convert.setProperty("mtllib", new URL("file:" + source)); - } catch (Exception e) { - System.err.println("Failed to create material URL: " + e); - System.exit(-1); - } - } else if (type.equals("3ds")) { - convert = new MaxToJme(); - } else if (type.equals("md2")) { - convert = new Md2ToJme(); - } else if (type.equals("md3")) { - convert = new Md3ToJme(); - } else if (type.equals("ase")) { - convert = new AseToJme(); - } else { - System.err.println("Unknown model type '" + type + "'."); - System.exit(-1); - } - - // and do the deed - try { - BufferedOutputStream bout = new BufferedOutputStream( - new FileOutputStream(target)); - BufferedInputStream bin = new BufferedInputStream( - new FileInputStream(source)); - convert.convert(bin, bout); - bout.close(); - } catch (IOException ioe) { - System.err.println("Error converting '" + source + - "' to '" + target + "'."); - ioe.printStackTrace(System.err); - System.exit(-1); - } - } -} diff --git a/src/java/com/threerings/jme/tools/ConvertModelTask.java b/src/java/com/threerings/jme/tools/ConvertModelTask.java deleted file mode 100644 index 921b9711..00000000 --- a/src/java/com/threerings/jme/tools/ConvertModelTask.java +++ /dev/null @@ -1,136 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.tools; - -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.net.URL; -import java.util.ArrayList; -import java.util.logging.Level; - -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.DirectoryScanner; -import org.apache.tools.ant.Task; -import org.apache.tools.ant.types.FileSet; - -import com.google.common.collect.Lists; - -import com.jme.util.LoggingSystem; -import com.jmex.model.XMLparser.Converters.AseToJme; -import com.jmex.model.XMLparser.Converters.DummyDisplaySystem; -import com.jmex.model.XMLparser.Converters.FormatConverter; -import com.jmex.model.XMLparser.Converters.MaxToJme; -import com.jmex.model.XMLparser.Converters.Md2ToJme; -import com.jmex.model.XMLparser.Converters.Md3ToJme; -import com.jmex.model.XMLparser.Converters.ObjToJme; - -/** - * An ant task for converting various 3D model formats into JME's internal - * format. - */ -public class ConvertModelTask extends Task -{ - public void addFileset (FileSet set) - { - _filesets.add(set); - } - - public void init () throws BuildException - { - // create a dummy display system which the converters need - new DummyDisplaySystem(); - LoggingSystem.getLogger().setLevel(Level.WARNING); - } - - public void execute () throws BuildException - { - for (FileSet fs : _filesets) { - DirectoryScanner ds = fs.getDirectoryScanner(getProject()); - File fromDir = fs.getDir(getProject()); - String[] srcFiles = ds.getIncludedFiles(); - - for (int f = 0; f < srcFiles.length; f++) { - File cfile = new File(fromDir, srcFiles[f]); - String target = srcFiles[f]; - int didx = target.lastIndexOf("."); - target = (didx == -1) ? target : target.substring(0, didx); - target += ".jme"; - convertModel(cfile, new File(fromDir, target)); - } - } - } - - protected void convertModel (File source, File target) - { - if (source.lastModified() < target.lastModified()) { - return; - } - - System.out.println("Converting " + source + "..."); - String path = source.getPath().toLowerCase(); - String type = path.substring(path.lastIndexOf(".") + 1); - - // set up our converter - FormatConverter convert = null; - if (type.equals("obj")) { - convert = new ObjToJme(); - try { - convert.setProperty("mtllib", new URL("file:" + source)); - } catch (Exception e) { - System.err.println("Failed to create material URL: " + e); - return; - } - } else if (type.equals("3ds")) { - convert = new MaxToJme(); - } else if (type.equals("md2")) { - convert = new Md2ToJme(); - } else if (type.equals("md3")) { - convert = new Md3ToJme(); - } else if (type.equals("ase")) { - convert = new AseToJme(); - } else { - System.err.println("Unknown model type '" + type + "'."); - return; - } - - // and do the deed - try { - BufferedOutputStream bout = new BufferedOutputStream( - new FileOutputStream(target)); - BufferedInputStream bin = new BufferedInputStream( - new FileInputStream(source)); - convert.convert(bin, bout); - bout.close(); - } catch (IOException ioe) { - System.err.println("Error converting '" + source + - "' to '" + target + "'."); - ioe.printStackTrace(System.err); - } - } - - /** A list of filesets that contain tileset bundle definitions. */ - protected ArrayList _filesets = Lists.newArrayList(); -} diff --git a/src/java/com/threerings/jme/tools/ModelDef.java b/src/java/com/threerings/jme/tools/ModelDef.java deleted file mode 100644 index 42ca4465..00000000 --- a/src/java/com/threerings/jme/tools/ModelDef.java +++ /dev/null @@ -1,1031 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.tools; - -import java.nio.FloatBuffer; -import java.nio.IntBuffer; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Properties; -import java.util.Set; - -import com.google.common.base.Objects; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; - -import com.jme.bounding.BoundingBox; -import com.jme.bounding.BoundingSphere; -import com.jme.math.FastMath; -import com.jme.math.Matrix4f; -import com.jme.math.Quaternion; -import com.jme.math.Vector3f; -import com.jme.scene.Node; -import com.jme.scene.Spatial; -import com.jme.util.geom.BufferUtils; - -import com.samskivert.util.PropertiesUtil; -import com.samskivert.util.StringUtil; -import com.samskivert.util.Tuple; - -import com.threerings.jme.model.Model; -import com.threerings.jme.model.ModelController; -import com.threerings.jme.model.ModelMesh; -import com.threerings.jme.model.ModelNode; -import com.threerings.jme.model.SkinMesh; -import com.threerings.jme.util.JmeUtil; - -import static com.threerings.jme.Log.log; - -/** - * An intermediate representation for models used to store data parsed from - * XML and convert it into JME nodes. - */ -public class ModelDef -{ - /** The base class of nodes in the model. */ - public abstract static class SpatialDef - { - /** The node's name. */ - public String name; - - /** The name of the node's parent. */ - public String parent; - - /** The node's transformation. */ - public float[] translation; - public float[] rotation; - public float[] scale; - - /** - * Stores the names of all bones referenced by this spatial in the supplied set. - */ - public void getBoneNames (HashSet bones) - { - // nothing by default - } - - /** Checks whether it's possible (disregarding issues of transformation) to merge - * the specified spatial into this one. */ - public abstract boolean canMerge (Properties props, SpatialDef other); - - /** Merges another spatial into this one. */ - public abstract void merge (SpatialDef other, Matrix4f xform); - - /** Returns a JME node for this definition. */ - public Spatial getSpatial (Properties props) - { - if (_spatial == null) { - _spatial = createSpatial( - PropertiesUtil.getFilteredProperties(props, name)); - setTransform(); - } - return _spatial; - } - - /** Sets the transform of the created node. */ - protected void setTransform () - { - _spatial.getLocalTranslation().set(translation[0], translation[1], - translation[2]); - _spatial.getLocalRotation().set(rotation[0], rotation[1], - rotation[2], rotation[3]); - _spatial.getLocalScale().set(scale[0], scale[1], scale[2]); - } - - /** Creates a JME node for this definition. */ - public abstract Spatial createSpatial (Properties props); - - /** Resolves any name references using the supplied map. */ - public void resolveReferences ( - HashMap nodes, HashSet referenced) - { - Spatial pnode = nodes.get(parent); - if (pnode instanceof ModelNode) { - ((ModelNode)pnode).attachChild(_spatial); - - } else if (parent != null) { - log.warning("Missing or invalid parent node [spatial=" + - name + ", parent=" + parent + "]."); - } - } - - /** The JME node created for this definition. */ - protected Spatial _spatial; - } - - /** A rigid triangle mesh. */ - public static class TriMeshDef extends SpatialDef - { - /** The geometry offset transform. */ - public float[] offsetTranslation; - public float[] offsetRotation; - public float[] offsetScale; - - /** Whether or not the mesh allows back face culling. */ - public boolean solid; - - /** The texture of the mesh, if any. */ - public String texture; - - /** Whether or not the mesh is (partially) transparent. */ - public boolean transparent; - - /** The vertices of the mesh. */ - public HashArrayList vertices = new HashArrayList(); - - /** The triangle indices. */ - public ArrayList indices = Lists.newArrayList(); - - /** Whether or not any of the vertices have texture coordinates. */ - public boolean tcoords; - - public void addVertex (Vertex vertex) - { - int idx = vertices.indexOf(vertex); - if (idx != -1) { - indices.add(idx); - } else { - indices.add(vertices.size()); - vertices.add(vertex); - } - tcoords = tcoords || vertex.tcoords != null; - } - - // documentation inherited - public boolean canMerge (Properties props, SpatialDef other) - { - if (getClass() != other.getClass()) { - return false; // require exact class match - } - TriMeshDef omesh = (TriMeshDef)other; - return solid == omesh.solid && transparent == omesh.transparent && - Objects.equal(texture, omesh.texture) && - PropertiesUtil.getSubProperties(props, name).equals( - PropertiesUtil.getSubProperties(props, omesh.name)); - } - - // documentation inherited - public void merge (SpatialDef other, Matrix4f xform) - { - TriMeshDef omesh = (TriMeshDef)other; - - // prepend the inverse of the offset transformation - xform = getOffsetTransform().invertLocal().multLocal(xform); - - // and append the other's offset - xform.multLocal(omesh.getOffsetTransform()); - - // extract the rotation to transform normals - Quaternion xrot = xform.toRotationQuat(); - - // transform the vertices and add them in - for (Vertex vertex : omesh.vertices) { - vertex.transform(xform, xrot); - } - for (int idx : omesh.indices) { - addVertex(omesh.vertices.get(idx)); - } - } - - // documentation inherited - public Spatial createSpatial (Properties props) - { - ModelNode node = new ModelNode(name); - if (indices.size() > 0) { - _mesh = createMesh(); - optimizeVertexOrder(); - configureMesh(props); - node.attachChild(_mesh); - } - return node; - } - - /** Gets the matrix representing the offset transform. */ - protected Matrix4f getOffsetTransform () - { - Vector3f otrans = new Vector3f(), oscale = new Vector3f(1f, 1f, 1f); - Quaternion orot = new Quaternion(); - if (offsetTranslation != null) { - otrans.set(offsetTranslation[0], offsetTranslation[1], offsetTranslation[2]); - } - if (offsetRotation != null) { - orot.set(offsetRotation[0], offsetRotation[1], offsetRotation[2], - offsetRotation[3]); - } - if (offsetScale != null) { - oscale.set(offsetScale[0], offsetScale[1], offsetScale[2]); - } - return JmeUtil.setTransform(otrans, orot, oscale, new Matrix4f()); - } - - /** Creates the mesh to attach to the node. */ - protected ModelMesh createMesh () - { - return new ModelMesh("mesh"); - } - - /** Reorders the vertices to optimize for vertex cache utilization. Uses the algorithm - * described in Tom Forsyth's article - * - * Linear-Speed Vertex Cache Optimization. - */ - protected void optimizeVertexOrder () - { - // start by compiling a list of triangles cross-linked with the vertices they use - // (we use a linked hash set to ensure consistent iteration order for serialization) - LinkedHashSet triangles = new LinkedHashSet(); - for (int ii = 0, nn = indices.size(); ii < nn; ii += 3) { - Vertex[] tverts = new Vertex[] { - vertices.get(indices.get(ii)), - vertices.get(indices.get(ii + 1)), - vertices.get(indices.get(ii + 2)) - }; - Triangle triangle = new Triangle(tverts); - for (Vertex tvert : tverts) { - if (tvert.triangles == null) { - tvert.triangles = Lists.newArrayList(); - } - tvert.triangles.add(triangle); - } - triangles.add(triangle); - } - - // init the scores - for (Vertex vertex : vertices) { - vertex.updateScore(Integer.MAX_VALUE); - } - - // clear the vertices and indices to prepare for readdition - vertices.clear(); - indices.clear(); - - // while there are triangles remaining, keep adding the one with the best score - // (as determined by its LRU cache position and number of remaining triangles) - HashArrayList vcache = new HashArrayList(); - while (!triangles.isEmpty()) { - // first look for triangles in the cache - Triangle bestTriangle = null; - float bestScore = -1f; - for (Vertex vertex : vcache) { - for (Triangle triangle : vertex.triangles) { - float score = triangle.getScore(); - if (score > bestScore) { - bestTriangle = triangle; - bestScore = score; - } - } - } - - // if that didn't work, scan the full list - if (bestTriangle == null) { - for (Triangle triangle : triangles) { - float score = triangle.getScore(); - if (score > bestScore) { - bestTriangle = triangle; - bestScore = score; - } - } - } - - // add and update the vertices from the best triangle - triangles.remove(bestTriangle); - for (Vertex vertex : bestTriangle.vertices) { - addVertex(vertex); - vertex.triangles.remove(bestTriangle); - vcache.remove(vertex); - vcache.add(0, vertex); - } - - // update the scores of the vertices in the cache - for (int ii = 0, nn = vcache.size(); ii < nn; ii++) { - vcache.get(ii).updateScore(ii); - } - - // trim the excess (if any) from the end of the cache - while (vcache.size() > 64) { - vcache.remove(vcache.size() - 1); - } - } - } - - /** Configures the mesh. */ - protected void configureMesh (Properties props) - { - // set the geometry offset - if (offsetTranslation != null) { - _mesh.getLocalTranslation().set(offsetTranslation[0], - offsetTranslation[1], offsetTranslation[2]); - } - if (offsetRotation != null) { - _mesh.getLocalRotation().set(offsetRotation[0], - offsetRotation[1], offsetRotation[2], offsetRotation[3]); - } - if (offsetScale != null) { - _mesh.getLocalScale().set(offsetScale[0], offsetScale[1], - offsetScale[2]); - } - - // make sure texture is just a filename - int sidx = (texture == null) ? -1 : - Math.max(texture.lastIndexOf('/'), texture.lastIndexOf('\\')); - if (sidx != -1) { - texture = texture.substring(sidx + 1); - } - - // configure using properties - _mesh.configure(solid, texture, transparent, props); - - // set the various buffers - int vsize = vertices.size(); - FloatBuffer vbuf = BufferUtils.createVector3Buffer(vsize), - nbuf = BufferUtils.createVector3Buffer(vsize), - tbuf = tcoords ? BufferUtils.createVector2Buffer(vsize) : null; - for (int ii = 0; ii < vsize; ii++) { - vertices.get(ii).setInBuffers(vbuf, nbuf, tbuf); - } - IntBuffer ibuf = BufferUtils.createIntBuffer(indices.size()); - for (int ii = 0, nn = indices.size(); ii < nn; ii++) { - ibuf.put(indices.get(ii)); - } - _mesh.reconstruct(vbuf, nbuf, null, tbuf, ibuf); - - _mesh.setModelBound("sphere".equals(props.getProperty("bound")) ? - new BoundingSphere() : new BoundingBox()); - _mesh.updateModelBound(); - - // set the mesh's origin to the center of its bounding box - _mesh.centerVertices(); - } - - /** The mesh that contains the actual geometry. */ - protected ModelMesh _mesh; - } - - /** A triangle mesh that deforms according to bone positions. */ - public static class SkinMeshDef extends TriMeshDef - { - @Override - public void getBoneNames (HashSet bones) - { - for (Vertex vertex : vertices) { - bones.addAll(((SkinVertex)vertex).boneWeights.keySet()); - } - } - - @Override - protected ModelMesh createMesh () - { - return new SkinMesh("mesh"); - } - - @Override - public void resolveReferences ( - HashMap nodes, HashSet referenced) - { - super.resolveReferences(nodes, referenced); - if (_mesh == null) { - return; - } - - // create and set the final weight groups - SkinMesh.WeightGroup[] wgroups = new SkinMesh.WeightGroup[_groups.size()]; - HashMap bones = Maps.newHashMap(); - int ii = 0; - int mweights = 0, tweights = 0; - for (Map.Entry, WeightGroupDef> entry : - _groups.entrySet()) { - SkinMesh.WeightGroup wgroup = new SkinMesh.WeightGroup(); - wgroup.vertexCount = entry.getValue().indices.size(); - wgroup.bones = new SkinMesh.Bone[entry.getKey().size()]; - int jj = 0; - for (String bname : entry.getKey()) { - SkinMesh.Bone bone = bones.get(bname); - if (bone == null) { - Spatial node = nodes.get(bname); - bones.put(bname, - bone = new SkinMesh.Bone((ModelNode)node)); - referenced.add(node); - } - wgroup.bones[jj++] = bone; - } - wgroup.weights = toArray(entry.getValue().weights); - tweights += wgroup.bones.length; - mweights = Math.max(wgroup.bones.length, mweights); - wgroups[ii++] = wgroup; - } - ((SkinMesh)_mesh).setWeightGroups(wgroups); - } - - @Override - protected void configureMesh (Properties props) - { - // divide the vertices up by weight groups - _groups = Maps.newHashMap(); - for (int ii = 0, nn = vertices.size(); ii < nn; ii++) { - SkinVertex svertex = (SkinVertex)vertices.get(ii); - Set bones = svertex.boneWeights.keySet(); - WeightGroupDef group = _groups.get(bones); - if (group == null) { - _groups.put(bones, group = new WeightGroupDef()); - } - group.indices.add(ii); - for (String bone : bones) { - group.weights.add(svertex.boneWeights.get(bone).weight); - } - } - - // reorder the vertices by group - ArrayList overts = vertices; - vertices = new HashArrayList(); - int[] imap = new int[overts.size()]; - for (Map.Entry, WeightGroupDef> entry : - _groups.entrySet()) { - for (int idx : entry.getValue().indices) { - imap[idx] = vertices.size(); - vertices.add(overts.get(idx)); - } - } - for (int ii = 0, nn = indices.size(); ii < nn; ii++) { - indices.set(ii, imap[indices.get(ii)]); - } - - super.configureMesh(props); - } - - /** The intermediate weight groups, mapped by bone names. */ - protected HashMap, WeightGroupDef> _groups; - } - - /** A generic node. */ - public static class NodeDef extends SpatialDef - { - // documentation inherited - public boolean canMerge (Properties props, SpatialDef other) - { - return false; - } - - // documentation inherited - public void merge (SpatialDef other, Matrix4f xform) - { - throw new UnsupportedOperationException(); - } - - // documentation inherited - public Spatial createSpatial (Properties props) - { - return new ModelNode(name); - } - } - - /** Represents a triangle for processing purposes. */ - public static class Triangle - { - public Vertex[] vertices; - - public Triangle (Vertex[] vertices) - { - this.vertices = vertices; - } - - public float getScore () - { - return vertices[0].score + vertices[1].score + vertices[2].score; - } - } - - /** A basic vertex. */ - public static class Vertex - { - public float[] location; - public float[] normal; - public float[] tcoords; - - public ArrayList triangles; - public float score; - - public void updateScore (int cacheIdx) - { - float pscore; - if (cacheIdx > 63) { - pscore = 0f; // outside the cache - } else if (cacheIdx < 3) { - pscore = 0.75f; // the three most recent vertices - } else { - pscore = FastMath.pow((63 - cacheIdx) / 60f, 1.5f); - } - score = pscore + 2f * FastMath.pow(triangles.size(), -0.5f); - } - - public void transform (Matrix4f xform, Quaternion xrot) - { - Vector3f xvec = new Vector3f(location[0], location[1], location[2]); - xform.mult(xvec, xvec); - location[0] = xvec.x; - location[1] = xvec.y; - location[2] = xvec.z; - - xvec.set(normal[0], normal[1], normal[2]); - xrot.mult(xvec, xvec); - normal[0] = xvec.x; - normal[1] = xvec.y; - normal[2] = xvec.z; - } - - public void setInBuffers ( - FloatBuffer vbuf, FloatBuffer nbuf, FloatBuffer tbuf) - { - vbuf.put(location); - nbuf.put(normal); - - if (tbuf != null) { - if (tcoords != null) { - tbuf.put(tcoords); - } else { - tbuf.put(0f); - tbuf.put(0f); - } - } - } - - public String toString () - { - return StringUtil.toString(location); - } - - @Override - public int hashCode () - { - return Arrays.hashCode(location) ^ Arrays.hashCode(normal) ^ Arrays.hashCode(tcoords); - } - - @Override - public boolean equals (Object obj) - { - Vertex overt = (Vertex)obj; - return Arrays.equals(location, overt.location) && - Arrays.equals(normal, overt.normal) && - Arrays.equals(tcoords, overt.tcoords); - } - } - - /** A vertex influenced by a number of bones. */ - public static class SkinVertex extends Vertex - { - /** The bones influencing the vertex, mapped by name. */ - public HashMap boneWeights = Maps.newHashMap(); - - public void addBoneWeight (BoneWeight weight) - { - if (weight.weight == 0f) { - return; - } - BoneWeight bweight = boneWeights.get(weight.bone); - if (bweight != null) { - bweight.weight += weight.weight; - } else { - boneWeights.put(weight.bone, weight); - } - } - - /** Finds the bone nodes influencing this vertex. */ - public HashSet getBones (HashMap nodes) - { - HashSet bones = Sets.newHashSet(); - for (String bone : boneWeights.keySet()) { - Spatial node = nodes.get(bone); - if (node instanceof ModelNode) { - bones.add((ModelNode)node); - } else { - log.warning("Missing or invalid bone for bone weight " + - "[bone=" + bone + "]."); - } - } - return bones; - } - - /** Returns the weight of the given bone. */ - public float getWeight (ModelNode bone) - { - BoneWeight bweight = boneWeights.get(bone.getName()); - return (bweight == null) ? 0f : bweight.weight; - } - } - - /** The influence of a bone on a vertex. */ - public static class BoneWeight - { - /** The name of the influencing bone. */ - public String bone; - - /** The amount of influence. */ - public float weight; - } - - /** A group of vertices influenced by the same bone. */ - public static class WeightGroupDef - { - /** The indices of the affected vertex. */ - public ArrayList indices = Lists.newArrayList(); - - /** The interleaved vertex weights. */ - public ArrayList weights = Lists.newArrayList(); - } - - /** Contains the transform of a node for preprocessing. */ - public static class TransformNode extends Node - { - /** The source definition. */ - public SpatialDef spatial; - - /** If true, this node is referenced by name (as a bone or parent) and cannot be merged - * into another. */ - public boolean referenced; - - /** If true, this node is a controller target; nodes beneath it can only be merged with - * other descendants. */ - public boolean controlled; - - /** The node's current local transform. */ - public Matrix4f localTransform = new Matrix4f(); - - /** The node's current world space transform. */ - public Matrix4f worldTransform = new Matrix4f(); - - /** The node's local transform in the original model, or null if the node's - * transform has diverged from the original. */ - public Matrix4f baseLocalTransform; - - /** The relative transforms between this and all other loosely compatible nodes not yet - * eliminated. As soon as the relative transform diverges in the course of preprocessing - * an animation, the node/transform pair is removed from the list. */ - public ArrayList> relativeTransforms; - - /** Marks this node as having been transformed in the course of an animation. */ - public boolean transformed; - - public TransformNode (SpatialDef spatial) - { - super(spatial.name); - this.spatial = spatial; - setLocalTransform(spatial.translation, spatial.rotation, spatial.scale); - } - - public void setLocalTransform (float[] translation, float[] rotation, float[] scale) - { - getLocalTranslation().set(translation[0], translation[1], translation[2]); - getLocalRotation().set(rotation[0], rotation[1], rotation[2], rotation[3]); - getLocalScale().set(scale[0], scale[1], scale[2]); - JmeUtil.setTransform( - getLocalTranslation(), getLocalRotation(), getLocalScale(), localTransform); - } - - @Override - public void updateWorldVectors () - { - super.updateWorldVectors(); - JmeUtil.setTransform( - getWorldTranslation(), getWorldRotation(), getWorldScale(), worldTransform); - } - - public boolean canMerge (Properties props, TransformNode onode) - { - // nodes must have same controlled ancestor - return !onode.referenced && spatial.canMerge(props, onode.spatial) && - getControlledAncestor() == onode.getControlledAncestor(); - } - - protected Node getControlledAncestor () - { - Node ref = this; - while (ref instanceof TransformNode && !((TransformNode)ref).controlled) { - ref = ref.getParent(); - } - return ref; - } - - public void cullDivergentTransforms () - { - if (baseLocalTransform != null && !epsilonEquals(localTransform, baseLocalTransform)) { - baseLocalTransform = null; - } - for (Iterator> it = relativeTransforms.iterator(); - it.hasNext(); ) { - Tuple tuple = it.next(); - if (!epsilonEquals(getRelativeTransform(tuple.left), tuple.right)) { - it.remove(); - } - } - } - - public Matrix4f getRelativeTransform (TransformNode other) - { - // return the matrix that takes vertices from the space of the other node - // into the space of this one - Matrix4f inv = new Matrix4f(); - worldTransform.invert(inv); - return inv.mult(other.worldTransform); - } - } - - /** The meshes and bones comprising the model. */ - public ArrayList spatials = Lists.newArrayList(); - - public void addSpatial (SpatialDef spatial) - { - // put nodes before meshes so that bones are updated before skin - spatials.add(spatial instanceof NodeDef ? 0 : spatials.size(), - spatial); - } - - /** - * Creates and returns a transform tree representing the model for preprocessing. - */ - public Node createTransformTree (Properties props, HashMap nodes) - { - // create the nodes and map them by name - for (SpatialDef spatial : spatials) { - nodes.put(spatial.name, new TransformNode(spatial)); - } - - // resolve the parents and collect the names of the bones - Node root = new Node("root"); - HashSet bones = Sets.newHashSet(); - for (TransformNode node : nodes.values()) { - if (node.spatial.parent == null) { - root.attachChild(node); - } else { - TransformNode pnode = nodes.get(node.spatial.parent); - if (pnode != null) { - pnode.attachChild(node); - pnode.referenced = true; - } - } - node.spatial.getBoneNames(bones); - } - - // mark the bones as referenced - for (String name : bones) { - TransformNode node = nodes.get(name); - if (node != null) { - node.referenced = true; - } - } - - // mark the controlled nodes - String[] controllers = StringUtil.parseStringArray(props.getProperty("controllers", "")); - for (String controller : controllers) { - Properties subProps = PropertiesUtil.getSubProperties(props, controller); - TransformNode node = nodes.get(subProps.getProperty("node", controller)); - if (node != null) { - node.referenced = node.controlled = true; - } - } - - // store the base transforms and relative transforms for merge candidates - root.updateGeometricState(0f, true); - for (TransformNode node : nodes.values()) { - node.baseLocalTransform = new Matrix4f(node.localTransform); - node.relativeTransforms = Lists.newArrayList(); - for (TransformNode onode : nodes.values()) { - if (node == onode || !node.canMerge(props, onode)) { - continue; - } - node.relativeTransforms.add(new Tuple( - onode, node.getRelativeTransform(onode))); - } - } - - return root; - } - - /** - * Merges compatible meshes that retain the same relative transform throughout all animations. - */ - public void mergeSpatials (HashMap nodes) - { - for (TransformNode node : nodes.values()) { - if (!spatials.contains(node.spatial)) { - continue; - } - for (Tuple tuple : node.relativeTransforms) { - if (spatials.contains(tuple.left.spatial)) { - node.spatial.merge(tuple.left.spatial, tuple.right); - spatials.remove(tuple.left.spatial); - } - } - } - } - - /** - * Creates the model node defined herein. - * - * @param props the properties of the model - * @param nodes a node map to populate - */ - public Model createModel (Properties props, HashMap nodes) - { - Model model = new Model(props.getProperty("name", "model"), props); - - // start by creating the spatials and mapping them to their names - for (int ii = 0, nn = spatials.size(); ii < nn; ii++) { - Spatial spatial = spatials.get(ii).getSpatial(props); - nodes.put(spatial.getName(), spatial); - } - - // then go through again, resolving any name references and attaching root children - HashSet referenced = Sets.newHashSet(); - for (int ii = 0, nn = spatials.size(); ii < nn; ii++) { - SpatialDef sdef = spatials.get(ii); - sdef.resolveReferences(nodes, referenced); - if (sdef.getSpatial(props).getParent() == null) { - model.attachChild(sdef.getSpatial(props)); - } - } - - // create any controllers listed - String[] controllers = StringUtil.parseStringArray( - props.getProperty("controllers", "")); - for (int ii = 0; ii < controllers.length; ii++) { - Properties subProps = - PropertiesUtil.getSubProperties(props, controllers[ii]); - String node = subProps.getProperty("node", controllers[ii]); - Spatial target = node.equals(model.getName()) ? - model : nodes.get(node); - if (target == null) { - log.warning("Missing controller node [name=" + node + "]."); - continue; - } - ModelController ctrl = createController(subProps, target); - if (ctrl != null) { - model.addController(ctrl); - referenced.add(target); - } - } - - // get rid of any nodes that serve no purpose - pruneUnusedNodes(model, nodes, referenced); - - // set the overall scale - model.setLocalScale(Float.parseFloat(props.getProperty("scale", "1"))); - - return model; - } - - /** Creates, configures, and returns a model controller. */ - protected ModelController createController ( - Properties props, Spatial target) - { - // attempt to create an instance of the controller - ModelController ctrl; - String cname = props.getProperty("class", ""); - try { - ctrl = (ModelController)Class.forName(cname).newInstance(); - } catch (Exception e) { - log.warning("Error instantiating controller [class=" + cname + - ", error=" + e + "]."); - return null; - } - ctrl.configure(props, target); - return ctrl; - } - - /** Recursively removes any unused nodes. */ - protected boolean pruneUnusedNodes ( - ModelNode node, HashMap nodes, - HashSet referenced) - { - boolean hasValidChildren = false; - for (int ii = node.getQuantity() - 1; ii >= 0; ii--) { - Spatial child = node.getChild(ii); - if (!(child instanceof ModelNode) || - pruneUnusedNodes((ModelNode)child, nodes, referenced)) { - hasValidChildren = true; - } else { - node.detachChildAt(ii); - nodes.remove(child.getName()); - } - } - return referenced.contains(node) || hasValidChildren; - } - - /** Determines whether a pair of matrices are "close enough" to equal. */ - public static boolean epsilonEquals (Matrix4f m1, Matrix4f m2) - { - for (int ii = 0; ii < 4; ii++) { - for (int jj = 0; jj < 4; jj++) { - if (FastMath.abs(m1.get(ii, jj) - m2.get(ii, jj)) > 0.0001f) { - return false; - } - } - } - return true; - } - - /** Converts a boxed Float list to an unboxed float array. */ - protected static float[] toArray (ArrayList list) - { - float[] array = new float[list.size()]; - for (int ii = 0, nn = list.size(); ii < nn; ii++) { - array[ii] = list.get(ii); - } - return array; - } - - /** Accelerates {@link ArrayList#indexOf}, {@link ArrayList#contains}, and - * {@link ArrayList#remove} using an internal hash map (assumes that all elements of the list - * are unique and non-null). */ - protected static class HashArrayList extends ArrayList - { - @Override - public boolean add (E element) - { - add(size(), element); - return true; - } - - @Override - public void add (int idx, E element) - { - super.add(idx, element); - remapFrom(idx); - } - - @Override - public E remove (int idx) - { - E element = super.remove(idx); - _indices.remove(element); - remapFrom(idx); - return element; - } - - @Override - public void clear () - { - super.clear(); - _indices.clear(); - } - - @Override - public int indexOf (Object obj) - { - Integer idx = _indices.get(obj); - return (idx == null ? -1 : idx); - } - - @Override - public boolean contains (Object obj) - { - return _indices.containsKey(obj); - } - - @Override - public boolean remove (Object obj) - { - Integer idx = _indices.remove(obj); - if (idx != null) { - super.remove(idx); - return true; - } else { - return false; - } - } - - protected void remapFrom (int idx) - { - for (int ii = idx, nn = size(); ii < nn; ii++) { - _indices.put(get(ii), ii); - } - } - - /** Maps elements to their indices in the list. */ - protected HashMap _indices = Maps.newHashMap(); - } -} diff --git a/src/java/com/threerings/jme/tools/ModelViewer.java b/src/java/com/threerings/jme/tools/ModelViewer.java deleted file mode 100644 index cb7ff5ba..00000000 --- a/src/java/com/threerings/jme/tools/ModelViewer.java +++ /dev/null @@ -1,1142 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.tools; - -import java.awt.BorderLayout; -import java.awt.Point; -import java.awt.event.ActionEvent; -import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.awt.event.MouseMotionListener; -import java.awt.event.MouseWheelEvent; -import java.awt.event.MouseWheelListener; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.PrintStream; - -import java.net.MalformedURLException; -import java.net.URL; - -import java.text.DecimalFormat; - -import java.util.HashMap; -import java.util.logging.Level; - -import javax.swing.AbstractAction; -import javax.swing.Action; -import javax.swing.BorderFactory; -import javax.swing.ButtonGroup; -import javax.swing.ButtonModel; -import javax.swing.DefaultComboBoxModel; -import javax.swing.JButton; -import javax.swing.JCheckBoxMenuItem; -import javax.swing.JComboBox; -import javax.swing.JDialog; -import javax.swing.JFileChooser; -import javax.swing.JFrame; -import javax.swing.JLabel; -import javax.swing.JMenu; -import javax.swing.JMenuBar; -import javax.swing.JMenuItem; -import javax.swing.JPanel; -import javax.swing.JPopupMenu; -import javax.swing.JRadioButtonMenuItem; -import javax.swing.JSlider; -import javax.swing.KeyStroke; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; -import javax.swing.filechooser.FileFilter; - -import com.google.common.base.Objects; -import com.google.common.collect.Maps; - -import com.jme.bounding.BoundingBox; -import com.jme.bounding.BoundingVolume; -import com.jme.image.Texture; -import com.jme.light.DirectionalLight; -import com.jme.math.FastMath; -import com.jme.math.Vector3f; -import com.jme.renderer.Camera; -import com.jme.renderer.ColorRGBA; -import com.jme.renderer.Renderer; -import com.jme.scene.Controller; -import com.jme.scene.Line; -import com.jme.scene.Node; -import com.jme.scene.Spatial; -import com.jme.scene.state.LightState; -import com.jme.scene.state.MaterialState; -import com.jme.scene.state.TextureState; -import com.jme.scene.state.WireframeState; -import com.jme.scene.state.ZBufferState; -import com.jme.system.JmeException; -import com.jme.util.LoggingSystem; -import com.jme.util.TextureKey; -import com.jme.util.TextureManager; -import com.jme.util.export.binary.BinaryImporter; -import com.jme.util.geom.Debugger; -import com.jmex.effects.particles.ParticleGeometry; - -import com.samskivert.swing.GroupLayout; -import com.samskivert.swing.Spacer; -import com.samskivert.util.PrefsConfig; -import com.samskivert.util.StringUtil; - -import com.threerings.resource.ResourceManager; -import com.threerings.util.MessageBundle; -import com.threerings.util.MessageManager; - -import com.threerings.jme.JmeCanvasApp; -import com.threerings.jme.camera.CameraHandler; -import com.threerings.jme.model.Model; -import com.threerings.jme.model.TextureProvider; -import com.threerings.jme.util.ShaderCache; -import com.threerings.jme.util.SpatialVisitor; - -import static com.threerings.jme.Log.log; - -/** - * A simple viewer application that allows users to examine models and their animations by loading - * them from their uncompiled .properties / .mxml representations or - * their compiled .dat representations. - */ -public class ModelViewer extends JmeCanvasApp -{ - public static void main (String[] args) - { - // write standard output and error to a log file - if (System.getProperty("no_log_redir") == null) { - String dlog = "viewer.log"; - try { - PrintStream logOut = new PrintStream( - new FileOutputStream(dlog), true); - System.setOut(logOut); - System.setErr(logOut); - - } catch (IOException ioe) { - log.warning("Failed to open debug log [path=" + dlog + - ", error=" + ioe + "]."); - } - } - LoggingSystem.getLoggingSystem().setLevel(Level.WARNING); - new ModelViewer(args.length > 0 ? args[0] : null); - } - - /** - * Creates and initializes an instance of the model viewer application. - * - * @param path the path of the model to view, or null for - * none - */ - public ModelViewer (String path) - { - super(1024, 768); - _rsrcmgr = new ResourceManager("rsrc"); - _scache = new ShaderCache(_rsrcmgr); - _msg = new MessageManager("rsrc.i18n").getBundle("jme.viewer"); - _path = path; - - JPopupMenu.setDefaultLightWeightPopupEnabled(false); - - _frame = new JFrame(_msg.get("m.title")); - _frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - - JMenuBar menu = new JMenuBar(); - _frame.setJMenuBar(menu); - - JMenu file = new JMenu(_msg.get("m.file_menu")); - file.setMnemonic(KeyEvent.VK_F); - menu.add(file); - Action load = new AbstractAction(_msg.get("m.file_load")) { - public void actionPerformed (ActionEvent e) { - showLoadDialog(); - } - }; - load.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_L); - load.putValue(Action.ACCELERATOR_KEY, - KeyStroke.getKeyStroke(KeyEvent.VK_L, KeyEvent.CTRL_MASK)); - file.add(load); - - Action importAction = new AbstractAction(_msg.get("m.file_import")) { - public void actionPerformed (ActionEvent e) { - showImportDialog(); - } - }; - importAction.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_I); - importAction.putValue(Action.ACCELERATOR_KEY, - KeyStroke.getKeyStroke(KeyEvent.VK_I, KeyEvent.CTRL_MASK)); - file.add(importAction); - - file.addSeparator(); - Action quit = new AbstractAction(_msg.get("m.file_quit")) { - public void actionPerformed (ActionEvent e) { - System.exit(0); - } - }; - quit.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_Q); - quit.putValue(Action.ACCELERATOR_KEY, - KeyStroke.getKeyStroke(KeyEvent.VK_Q, KeyEvent.CTRL_MASK)); - file.add(quit); - - JMenu view = new JMenu(_msg.get("m.view_menu")); - view.setMnemonic(KeyEvent.VK_V); - menu.add(view); - - Action wireframe = new AbstractAction(_msg.get("m.view_wireframe")) { - public void actionPerformed (ActionEvent e) { - _wfstate.setEnabled(!_wfstate.isEnabled()); - } - }; - wireframe.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_W); - wireframe.putValue(Action.ACCELERATOR_KEY, - KeyStroke.getKeyStroke(KeyEvent.VK_W, KeyEvent.CTRL_MASK)); - view.add(new JCheckBoxMenuItem(wireframe)); - view.addSeparator(); - - _pivots = new JCheckBoxMenuItem(_msg.get("m.view_pivots")); - _pivots.setMnemonic(KeyEvent.VK_P); - _pivots.setAccelerator( - KeyStroke.getKeyStroke(KeyEvent.VK_P, KeyEvent.CTRL_MASK)); - view.add(_pivots); - - _bounds = new JCheckBoxMenuItem(_msg.get("m.view_bounds")); - _bounds.setMnemonic(KeyEvent.VK_B); - _bounds.setAccelerator( - KeyStroke.getKeyStroke(KeyEvent.VK_B, KeyEvent.CTRL_MASK)); - view.add(_bounds); - - _normals = new JCheckBoxMenuItem(_msg.get("m.view_normals")); - _normals.setMnemonic(KeyEvent.VK_N); - _normals.setAccelerator( - KeyStroke.getKeyStroke(KeyEvent.VK_N, KeyEvent.CTRL_MASK)); - view.add(_normals); - view.addSeparator(); - - Action campos = new AbstractAction(_msg.get("m.view_campos")) { - public void actionPerformed (ActionEvent e) { - _campos.setVisible(!_campos.isVisible()); - } - }; - campos.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_A); - campos.putValue(Action.ACCELERATOR_KEY, - KeyStroke.getKeyStroke(KeyEvent.VK_A, KeyEvent.CTRL_MASK)); - view.add(new JCheckBoxMenuItem(campos)); - view.addSeparator(); - - _vmenu = new JMenu(_msg.get("m.model_variant")); - view.add(_vmenu); - - JMenu amode = new JMenu(_msg.get("m.animation_mode")); - final JRadioButtonMenuItem flipbook = - new JRadioButtonMenuItem(_msg.get("m.mode_flipbook")), - morph = new JRadioButtonMenuItem(_msg.get("m.mode_morph")), - skin = new JRadioButtonMenuItem(_msg.get("m.mode_skin")); - ButtonGroup mgroup = new ButtonGroup() { - public void setSelected (ButtonModel model, boolean b) { - super.setSelected(model, b); - if (b) { - if (flipbook.isSelected()) { - _animMode = Model.AnimationMode.FLIPBOOK; - } else if (morph.isSelected()) { - _animMode = Model.AnimationMode.MORPH; - } else { - _animMode = Model.AnimationMode.SKIN; - } - if (_loaded != null) { - loadModel(_loaded); // reload - } - } - } - }; - - mgroup.add(flipbook); - mgroup.add(morph); - mgroup.add(skin); - mgroup.setSelected(skin.getModel(), true); - amode.add(skin); - amode.add(morph); - amode.add(flipbook); - view.add(amode); - view.addSeparator(); - - Action rlight = new AbstractAction(_msg.get("m.view_light")) { - public void actionPerformed (ActionEvent e) { - if (_rldialog == null) { - _rldialog = new RotateLightDialog(); - _rldialog.pack(); - } - _rldialog.setVisible(true); - } - }; - rlight.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_R); - rlight.putValue(Action.ACCELERATOR_KEY, - KeyStroke.getKeyStroke(KeyEvent.VK_R, KeyEvent.CTRL_MASK)); - view.add(new JMenuItem(rlight)); - - Action rcamera = new AbstractAction(_msg.get("m.view_recenter")) { - public void actionPerformed (ActionEvent e) { - ((OrbitCameraHandler)_camhand).recenter(); - updateCameraPosition(); - } - }; - rcamera.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_C); - rcamera.putValue(Action.ACCELERATOR_KEY, - KeyStroke.getKeyStroke(KeyEvent.VK_C, KeyEvent.CTRL_MASK)); - view.add(new JMenuItem(rcamera)); - - _frame.getContentPane().add(getCanvas(), BorderLayout.CENTER); - - JPanel bpanel = new JPanel(new BorderLayout()); - _frame.getContentPane().add(bpanel, BorderLayout.SOUTH); - - _animctrls = new JPanel(); - _animctrls.setBorder(BorderFactory.createEtchedBorder()); - bpanel.add(_animctrls, BorderLayout.NORTH); - _animctrls.add(new JLabel(_msg.get("m.anim_select"))); - _animctrls.add(_animbox = new JComboBox()); - _animctrls.add(new JButton( - new AbstractAction(_msg.get("m.anim_start")) { - public void actionPerformed (ActionEvent e) { - String anim = (String)_animbox.getSelectedItem(); - if (_model.hasAnimation(anim)) { - _model.startAnimation(anim); - } else { // it's a sequence - if (_model.getAnimation() != null) { - _sequence = null; - _model.stopAnimation(); - } - _sequence = StringUtil.parseStringArray( - _model.getProperties().getProperty( - anim + ".animations", "")); - if (_sequence.length == 0) { - _sequence = null; - } else { - _model.startAnimation(_sequence[_seqidx = 0]); - } - } - } - })); - _animctrls.add(_animstop = new JButton( - new AbstractAction(_msg.get("m.anim_stop")) { - public void actionPerformed (ActionEvent e) { - _model.stopAnimation(); - } - })); - _animstop.setEnabled(false); - _animctrls.add(new Spacer(50, 1)); - _animctrls.add(new JLabel(_msg.get("m.anim_speed"))); - _animctrls.add(_animspeed = new JSlider(-100, +100, 0)); - _animspeed.setMajorTickSpacing(10); - _animspeed.setSnapToTicks(true); - _animspeed.setPaintTicks(true); - _animspeed.addChangeListener(new ChangeListener() { - public void stateChanged (ChangeEvent e) { - updateAnimationSpeed(); - } - }); - _animctrls.setVisible(false); - - JPanel spanel = new JPanel(new BorderLayout()); - bpanel.add(spanel, BorderLayout.SOUTH); - - _status = new JLabel(" "); - _status.setHorizontalAlignment(JLabel.LEFT); - _status.setBorder(BorderFactory.createEtchedBorder()); - spanel.add(_status, BorderLayout.CENTER); - - _campos = new JLabel(" "); - _campos.setBorder(BorderFactory.createEtchedBorder()); - _campos.setVisible(false); - spanel.add(_campos, BorderLayout.EAST); - - _frame.pack(); - _frame.setVisible(true); - - run(); - } - - @Override - public boolean init () - { - if (!super.init()) { - return false; - } - if (_path != null) { - loadModel(new File(_path)); - } - return true; - } - - @Override - protected void initDisplay () - throws JmeException - { - super.initDisplay(); - _ctx.getRenderer().setBackgroundColor(ColorRGBA.gray); - _ctx.getRenderer().getQueue().setTwoPassTransparency(false); - } - - @Override - protected void initInput () - { - super.initInput(); - - _camhand.setTiltLimits(-FastMath.HALF_PI, FastMath.HALF_PI); - _camhand.setZoomLimits(1f, 500f); - _camhand.tiltCamera(-FastMath.PI * 7.0f / 16.0f); - updateCameraPosition(); - - MouseOrbiter orbiter = new MouseOrbiter(); - _canvas.addMouseListener(orbiter); - _canvas.addMouseMotionListener(orbiter); - _canvas.addMouseWheelListener(orbiter); - } - - /** - * Updates the camera position label. - */ - protected void updateCameraPosition () - { - Camera cam = _camhand.getCamera(); - Vector3f pos = cam.getLocation(), dir = cam.getDirection(); - float heading = -FastMath.atan2(dir.x, dir.y) * FastMath.RAD_TO_DEG, - pitch = FastMath.asin(dir.z) * FastMath.RAD_TO_DEG; - _campos.setText( - "XYZ: " + CAMPOS_FORMAT.format(pos.x) + ", " + - CAMPOS_FORMAT.format(pos.y) + ", " + - CAMPOS_FORMAT.format(pos.z) + - " HP: " + CAMPOS_FORMAT.format(heading) + ", " + - CAMPOS_FORMAT.format(pitch)); - } - - @Override - protected CameraHandler createCameraHandler (Camera camera) - { - return new OrbitCameraHandler(camera); - } - - @Override - protected void initRoot () - { - super.initRoot(); - - // set default states - MaterialState mstate = _ctx.getRenderer().createMaterialState(); - mstate.getDiffuse().set(ColorRGBA.white); - mstate.getAmbient().set(ColorRGBA.white); - _ctx.getGeometry().setRenderState(mstate); - _ctx.getGeometry().setRenderState( - _wfstate = _ctx.getRenderer().createWireframeState()); - _ctx.getGeometry().setNormalsMode(Spatial.NM_GL_NORMALIZE_PROVIDED); - _wfstate.setEnabled(false); - - // create a grid on the XY plane to provide some reference - Vector3f[] points = new Vector3f[GRID_SIZE*2 + GRID_SIZE*2]; - float halfLength = (GRID_SIZE - 1) * GRID_SPACING / 2; - int idx = 0; - for (int xx = 0; xx < GRID_SIZE; xx++) { - points[idx++] = new Vector3f( - -halfLength + xx*GRID_SPACING, -halfLength, 0f); - points[idx++] = new Vector3f( - -halfLength + xx*GRID_SPACING, +halfLength, 0f); - } - for (int yy = 0; yy < GRID_SIZE; yy++) { - points[idx++] = new Vector3f( - -halfLength, -halfLength + yy*GRID_SPACING, 0f); - points[idx++] = new Vector3f( - +halfLength, -halfLength + yy*GRID_SPACING, 0f); - - } - Line grid = new Line("grid", points, null, null, null); - grid.getBatch(0).getDefaultColor().set(0.25f, 0.25f, 0.25f, 1f); - grid.setLightCombineMode(LightState.OFF); - grid.setModelBound(new BoundingBox()); - grid.updateModelBound(); - _ctx.getGeometry().attachChild(grid); - grid.updateRenderState(); - - // attach a dummy node to draw debugging views - _ctx.getGeometry().attachChild(new Node("debug") { - public void onDraw (Renderer r) { - if (_model == null) { - return; - } - if (_pivots.getState()) { - drawPivots(_model, r); - } - if (_bounds.getState()) { - Debugger.drawBounds(_model, r); - } - if (_normals.getState()) { - Debugger.drawNormals(_model, r, 5f, true); - } - } - }); - } - - /** - * Draws the pivot axes of the given node and its children. - */ - protected void drawPivots (Spatial spatial, Renderer r) - { - if (_axes == null) { - _axes = new Line("axes", - new Vector3f[] { Vector3f.ZERO, Vector3f.UNIT_X, Vector3f.ZERO, - Vector3f.UNIT_Y, Vector3f.ZERO, Vector3f.UNIT_Z }, null, - new ColorRGBA[] { ColorRGBA.red, ColorRGBA.red, - ColorRGBA.green, ColorRGBA.green, ColorRGBA.blue, - ColorRGBA.blue }, null); - _axes.setRenderQueueMode(Renderer.QUEUE_SKIP); - _axes.setRenderState(r.createZBufferState()); - LightState lstate = r.createLightState(); - lstate.setEnabled(false); - _axes.setRenderState(lstate); - _axes.updateRenderState(); - } - _axes.getRenderState(ZBufferState.RS_ZBUFFER).apply(); - _axes.getRenderState(LightState.RS_LIGHT).apply(); - _axes.getWorldTranslation().set(spatial.getWorldTranslation()); - _axes.getWorldRotation().set(spatial.getWorldRotation()); - _axes.draw(r); - - if (spatial instanceof Node) { - Node node = (Node)spatial; - for (int ii = 0, nn = node.getQuantity(); ii < nn; ii++) { - drawPivots(node.getChild(ii), r); - } - } - } - - @Override - protected void initLighting () - { - _dlight = new DirectionalLight(); - _dlight.setEnabled(true); - _dlight.getDirection().set(-1f, 0f, -1f).normalizeLocal(); - _dlight.getAmbient().set(0.25f, 0.25f, 0.25f, 1f); - - LightState lstate = _ctx.getRenderer().createLightState(); - lstate.attach(_dlight); - _ctx.getGeometry().setRenderState(lstate); - _ctx.getGeometry().setLightCombineMode(LightState.REPLACE); - } - - /** - * Shows the load model dialog. - */ - protected void showLoadDialog () - { - if (_chooser == null) { - _chooser = new JFileChooser(); - _chooser.setDialogTitle(_msg.get("m.load_title")); - _chooser.setFileFilter(new FileFilter() { - public boolean accept (File file) { - if (file.isDirectory()) { - return true; - } - String path = file.toString().toLowerCase(); - return path.endsWith(".properties") || - path.endsWith(".dat"); - } - public String getDescription () { - return _msg.get("m.load_filter"); - } - }); - File dir = new File(_config.getValue("dir", ".")); - if (dir.exists()) { - _chooser.setCurrentDirectory(dir); - } - } - if (_chooser.showOpenDialog(_frame) == JFileChooser.APPROVE_OPTION) { - loadModel(_chooser.getSelectedFile()); - } - _config.setValue("dir", _chooser.getCurrentDirectory().toString()); - } - - /** - * Attempts to load a model from the specified location. - */ - protected void loadModel (File file) - { - String fpath = file.toString(); - try { - if (fpath.endsWith(".properties")) { - compileModel(file); - } else if (fpath.endsWith(".dat")) { - loadCompiledModel(file); - } else { - throw new Exception(_msg.get("m.invalid_type")); - } - _status.setText(_msg.get("m.loaded_model", fpath)); - _loaded = file; - - } catch (Exception e) { - e.printStackTrace(); - _status.setText(_msg.get("m.load_error", fpath, e)); - } - } - - /** - * Attempts to compile and load a model. - */ - protected void compileModel (File file) - throws Exception - { - _status.setText(_msg.get("m.compiling_model", file)); - Model model = CompileModel.compile(file); - if (model != null) { - setModel(model, file); - return; - } - - // if compileModel returned null, the .dat file is up-to-date - String fpath = file.toString(); - int didx = fpath.lastIndexOf('.'); - fpath = (didx == -1) ? fpath : fpath.substring(0, didx); - loadCompiledModel(new File(fpath + ".dat")); - } - - /** - * Attempts to load a model that has already been compiled. - */ - protected void loadCompiledModel (File file) - throws IOException - { - _status.setText(_msg.get("m.loading_model", file)); - setModel(Model.readFromFile(file), file); - } - - /** - * Sets the model once it's been loaded. - * - * @param file the file from which the model was loaded - */ - protected void setModel (Model model, File file) - { - if (_model != null) { - _ctx.getGeometry().detachChild(_model); - } - _ctx.getGeometry().attachChild(_model = _omodel = model); - _model.setAnimationMode(_animMode); - _model.configureShaders(_scache); - _model.lockStaticMeshes(_ctx.getRenderer(), true, true); - - // load the model's textures - resolveModelTextures(file); - - // recenter the camera - _model.updateGeometricState(0f, true); - ((OrbitCameraHandler)_camhand).recenter(); - updateCameraPosition(); - - // configure the variant menu - _variant = null; - _vmenu.removeAll(); - ButtonGroup vgroup = new ButtonGroup() { - public void setSelected (ButtonModel model, boolean b) { - super.setSelected(model, b); - String variant = model.getActionCommand(); - if (b && !Objects.equal(variant, _variant)) { - setVariant(model.getActionCommand()); - } - } - }; - JRadioButtonMenuItem def = new JRadioButtonMenuItem( - _msg.get("m.variant_default")); - def.setActionCommand(null); - vgroup.add(def); - _vmenu.add(def); - for (String variant : _model.getVariantNames()) { - JRadioButtonMenuItem vitem = new JRadioButtonMenuItem(variant); - vitem.setActionCommand(variant); - vgroup.add(vitem); - _vmenu.add(vitem); - } - vgroup.setSelected(def.getModel(), true); - - // configure the animation panel - String[] anims = _model.getAnimationNames(); - if (anims.length == 0) { - _animctrls.setVisible(false); - return; - } - _model.addAnimationObserver(_animobs); - _animctrls.setVisible(true); - DefaultComboBoxModel abmodel = new DefaultComboBoxModel(anims); - _animbox.setModel(abmodel); - updateAnimationSpeed(); - - // if there are any sequences, add those as well - String[] seqs = StringUtil.parseStringArray( - _model.getProperties().getProperty("sequences", "")); - for (String seq : seqs) { - abmodel.addElement(seq); - } - } - - /** - * Switches to the named variant. - */ - protected void setVariant (String variant) - { - _model.stopAnimation(); - _ctx.getGeometry().detachChild(_model); - _ctx.getGeometry().attachChild( - _model = _omodel.createPrototype(variant)); - _model.addAnimationObserver(_animobs); - updateAnimationSpeed(); - resolveModelTextures(_loaded); - _variant = variant; - } - - /** - * Resolve the textures from the file's directory. - */ - protected void resolveModelTextures (File file) - { - final File dir = file.getParentFile(); - _model.resolveTextures(new TextureProvider() { - public TextureState getTexture (String name) { - TextureState tstate = _tstates.get(name); - if (tstate == null) { - File file; - if (name.startsWith("/")) { - file = _rsrcmgr.getResourceFile(name.substring(1)); - } else { - file = new File(dir, name); - } - Texture tex = TextureManager.loadTexture(file.toString(), - Texture.MM_LINEAR_LINEAR, Texture.FM_LINEAR); - if (tex == null) { - log.warning("Couldn't find texture [path=" + file + - "]."); - return null; - } - tex.setWrap(Texture.WM_WRAP_S_WRAP_T); - tstate = _ctx.getRenderer().createTextureState(); - tstate.setTexture(tex); - _tstates.put(name, tstate); - } - return tstate; - } - protected HashMap _tstates = Maps.newHashMap(); - }); - _model.updateRenderState(); - } - - /** - * Shows the import particle system dialog. - */ - protected void showImportDialog () - { - if (_ichooser == null) { - _ichooser = new JFileChooser(); - _ichooser.setDialogTitle(_msg.get("m.import_title")); - _ichooser.setFileFilter(new FileFilter() { - public boolean accept (File file) { - if (file.isDirectory()) { - return true; - } - String path = file.toString().toLowerCase(); - return path.endsWith(".jme"); - } - public String getDescription () { - return _msg.get("m.import_filter"); - } - }); - File dir = new File(_config.getValue("import_dir", ".")); - if (dir.exists()) { - _ichooser.setCurrentDirectory(dir); - } - } - if (_ichooser.showOpenDialog(_frame) == JFileChooser.APPROVE_OPTION) { - importFile(_ichooser.getSelectedFile()); - } - _config.setValue("import_dir", - _ichooser.getCurrentDirectory().toString()); - } - - /** - * Attempts to import the specified file as a JME binary scene. - */ - protected void importFile (File file) - { - final File parent = file.getParentFile(); - TextureKey.setLocationOverride(new TextureKey.LocationOverride() { - public URL getLocation (String name) - throws MalformedURLException { - return new URL(parent.toURI().toURL(), name); - } - }); - try { - new ImportDialog(file, - (Spatial)BinaryImporter.getInstance().load( - file)).setVisible(true); - - } catch (Exception e) { - e.printStackTrace(); - _status.setText(_msg.get("m.load_error", file, e)); - } - TextureKey.setLocationOverride(null); - } - - /** - * Updates the model's animation speed based on the position of the - * animation speed slider. - */ - protected void updateAnimationSpeed () - { - _model.setAnimationSpeed( - FastMath.pow(2f, _animspeed.getValue() / 25f)); - } - - /** The resource manager. */ - protected ResourceManager _rsrcmgr; - - /** The shader cache. */ - protected ShaderCache _scache; - - /** The translation bundle. */ - protected MessageBundle _msg; - - /** The path of the initial model to load. */ - protected String _path; - - /** The last model successfully loaded. */ - protected File _loaded; - - /** The viewer frame. */ - protected JFrame _frame; - - /** The variant menu. */ - protected JMenu _vmenu; - - /** Debug view switches. */ - protected JCheckBoxMenuItem _pivots, _bounds, _normals; - - /** The animation controls. */ - protected JPanel _animctrls; - - /** The animation selector. */ - protected JComboBox _animbox; - - /** The "stop animation" button. */ - protected JButton _animstop; - - /** The animation speed slider. */ - protected JSlider _animspeed; - - /** The status bar. */ - protected JLabel _status; - - /** The camera position display. */ - protected JLabel _campos; - - /** The model file chooser. */ - protected JFileChooser _chooser; - - /** The import file chooser. */ - protected JFileChooser _ichooser; - - /** The desired animation mode. */ - protected Model.AnimationMode _animMode; - - /** The desired variant. */ - protected String _variant; - - /** The light rotation dialog. */ - protected RotateLightDialog _rldialog; - - /** The scene light. */ - protected DirectionalLight _dlight; - - /** Used to toggle wireframe rendering. */ - protected WireframeState _wfstate; - - /** The currently loaded model. */ - protected Model _model; - - /** The original model (before switching to a variant). */ - protected Model _omodel; - - /** Reused to draw pivot axes. */ - protected Line _axes; - - /** The current animation sequence, if any. */ - protected String[] _sequence; - - /** The current index in the animation sequence. */ - protected int _seqidx; - - /** Enables and disables the stop button when animations start and stop. */ - protected Model.AnimationObserver _animobs = - new Model.AnimationObserver() { - public boolean animationStarted (Model model, String name) { - _animstop.setEnabled(true); - return true; - } - public boolean animationCompleted (Model model, String name) { - if (_sequence != null && ++_seqidx < _sequence.length) { - _model.startAnimation(_sequence[_seqidx]); - } else { - _animstop.setEnabled(false); - _sequence = null; - } - return true; - } - public boolean animationCancelled (Model model, String name) { - if (_sequence != null && ++_seqidx < _sequence.length && - _model.getAnimation(name).repeatType != Controller.RT_CLAMP) { - _model.startAnimation(_sequence[_seqidx]); - } else { - _animstop.setEnabled(false); - _sequence = null; - } - return true; - } - }; - - /** Allows users to manipulate an imported JME file. */ - protected class ImportDialog extends JDialog - implements ChangeListener - { - public ImportDialog (File file, Spatial spatial) - { - super(_frame, _msg.get("m.import", file), false); - _spatial = spatial; - - // rotate from y-up to z-up and set initial scale - _spatial.getLocalRotation().fromAngleNormalAxis(FastMath.HALF_PI, - Vector3f.UNIT_X); - _spatial.setLocalScale(0.025f); - - JPanel cpanel = GroupLayout.makeVBox(); - getContentPane().add(cpanel, BorderLayout.CENTER); - - JPanel spanel = new JPanel(); - spanel.add(new JLabel(_msg.get("m.scale"))); - spanel.add(_scale = new JSlider(0, 1000, 250)); - _scale.addChangeListener(this); - cpanel.add(spanel); - - JPanel bpanel = new JPanel(); - bpanel.add(new JButton(new AbstractAction( - _msg.get("m.respawn_particles")) { - public void actionPerformed (ActionEvent e) { - _respawner.traverse(_spatial); - } - })); - bpanel.add(new JButton(new AbstractAction(_msg.get("m.close")) { - public void actionPerformed (ActionEvent e) { - setVisible(false); - } - })); - getContentPane().add(bpanel, BorderLayout.SOUTH); - pack(); - } - - // documentation inherited from interface ChangeListener - public void stateChanged (ChangeEvent e) - { - _spatial.setLocalScale(_scale.getValue() * 0.0001f); - } - - @Override - public void setVisible (boolean visible) - { - super.setVisible(visible); - if (visible && _spatial.getParent() == null) { - _ctx.getGeometry().attachChild(_spatial); - _spatial.updateRenderState(); - } else if (!visible && _spatial.getParent() != null) { - _ctx.getGeometry().detachChild(_spatial); - } - } - - /** The imported scene. */ - protected Spatial _spatial; - - /** The scale slider. */ - protected JSlider _scale; - } - - /** Allows users to move the directional light around. */ - protected class RotateLightDialog extends JDialog - implements ChangeListener - { - public RotateLightDialog () - { - super(_frame, _msg.get("m.rotate_light"), false); - - JPanel cpanel = GroupLayout.makeVBox(); - getContentPane().add(cpanel, BorderLayout.CENTER); - - JPanel apanel = new JPanel(); - apanel.add(new JLabel(_msg.get("m.azimuth"))); - apanel.add(_azimuth = new JSlider(-180, +180, 0)); - _azimuth.addChangeListener(this); - cpanel.add(apanel); - - JPanel epanel = new JPanel(); - epanel.add(new JLabel(_msg.get("m.elevation"))); - epanel.add(_elevation = new JSlider(-90, +90, 45)); - _elevation.addChangeListener(this); - cpanel.add(epanel); - - JPanel bpanel = new JPanel(); - bpanel.add(new JButton(new AbstractAction(_msg.get("m.close")) { - public void actionPerformed (ActionEvent e) { - setVisible(false); - } - })); - getContentPane().add(bpanel, BorderLayout.SOUTH); - } - - // documentation inherited from interface ChangeListener - public void stateChanged (ChangeEvent e) - { - float az = _azimuth.getValue() * FastMath.DEG_TO_RAD, - el = _elevation.getValue() * FastMath.DEG_TO_RAD; - _dlight.getDirection().set( - -FastMath.cos(az) * FastMath.cos(el), - -FastMath.sin(az) * FastMath.cos(el), - -FastMath.sin(el)); - } - - /** Azimuth and elevation sliders. */ - protected JSlider _azimuth, _elevation; - } - - /** Moves the camera using mouse input. */ - protected class MouseOrbiter extends MouseAdapter - implements MouseMotionListener, MouseWheelListener - { - @Override - public void mousePressed (MouseEvent e) - { - _mloc.setLocation(e.getX(), e.getY()); - } - - // documentation inherited from interface MouseMotionListener - public void mouseMoved (MouseEvent e) - { - } - - // documentation inherited from interface MouseMotionListener - public void mouseDragged (MouseEvent e) - { - int dx = e.getX() - _mloc.x, dy = e.getY() - _mloc.y; - _mloc.setLocation(e.getX(), e.getY()); - int mods = e.getModifiers(); - if ((mods & MouseEvent.BUTTON1_MASK) != 0) { - _camhand.tiltCamera(dy * FastMath.PI / 1000); - _camhand.orbitCamera(-dx * FastMath.PI / 1000); - } else if ((mods & MouseEvent.BUTTON2_MASK) != 0) { - _camhand.zoomCamera(dy/8f); - } else { - _camhand.panCamera(-dx/8f, dy/8f); - } - updateCameraPosition(); - } - - // documentation inherited from interface MouseWheelListener - public void mouseWheelMoved (MouseWheelEvent e) - { - _camhand.zoomCamera(e.getWheelRotation() * 10f); - updateCameraPosition(); - } - - /** The last recorded position of the mouse cursor. */ - protected Point _mloc = new Point(); - } - - /** A camera handler that pans in directions orthogonal to the camera - * direction. */ - protected class OrbitCameraHandler extends CameraHandler - { - public OrbitCameraHandler (Camera camera) - { - super(camera); - _gpoint = super.getGroundPoint(); - } - - @Override - public void panCamera (float x, float y) { - Vector3f offset = _camera.getLeft().mult(-x).addLocal( - _camera.getUp().mult(y)); - getGroundPoint().addLocal(offset); - _camera.getLocation().addLocal(offset); - _camera.onFrameChange(); - } - - @Override - public Vector3f getGroundPoint () - { - return _gpoint; - } - - /** - * Resets the ground point to the center of the grid or, if there is - * one, the center of the model. - */ - public void recenter () - { - Vector3f target = new Vector3f(); - if (_model != null) { - BoundingVolume bound = _model.getWorldBound(); - if (bound != null) { - bound.getCenter(target); - } - } - Vector3f offset = target.subtract(_gpoint); - _camera.getLocation().addLocal(offset); - _camera.onFrameChange(); - _gpoint.set(target); - } - - /** The point at which the camera is looking. */ - protected Vector3f _gpoint; - } - - /** The app configuration. */ - protected static PrefsConfig _config = new PrefsConfig("com/threerings/jme/tools/ModelViewer"); - - /** Forces all particle systems to respawn. */ - protected static SpatialVisitor _respawner = - new SpatialVisitor(ParticleGeometry.class) { - protected void visit (ParticleGeometry geom) { - geom.forceRespawn(); - } - }; - - /** The number of lines on the grid in each direction. */ - protected static final int GRID_SIZE = 32; - - /** The spacing between lines on the grid. */ - protected static final float GRID_SPACING = 2.5f; - - /** The number formal used for the camera position. */ - protected static final DecimalFormat CAMPOS_FORMAT = - new DecimalFormat("+000.000;-000.000"); -} diff --git a/src/java/com/threerings/jme/tools/xml/AnimationParser.java b/src/java/com/threerings/jme/tools/xml/AnimationParser.java deleted file mode 100644 index ec938709..00000000 --- a/src/java/com/threerings/jme/tools/xml/AnimationParser.java +++ /dev/null @@ -1,88 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.tools.xml; - -import java.io.FileInputStream; -import java.io.IOException; - -import org.xml.sax.SAXException; -import org.apache.commons.digester.Digester; - -import com.samskivert.xml.SetPropertyFieldsRule; - -import com.threerings.jme.tools.AnimationDef; - -/** - * Parses XML files containing animations. - */ -public class AnimationParser -{ - public AnimationParser () - { - // create and configure our digester - _digester = new Digester(); - - // add the rules - String anim = "animation"; - _digester.addObjectCreate(anim, AnimationDef.class.getName()); - _digester.addRule(anim, new SetPropertyFieldsRule()); - _digester.addSetNext(anim, "setAnimation", - AnimationDef.class.getName()); - - String frame = anim + "/frame"; - _digester.addObjectCreate(frame, - AnimationDef.FrameDef.class.getName()); - _digester.addSetNext(frame, "addFrame", - AnimationDef.FrameDef.class.getName()); - - String xform = frame + "/transform"; - _digester.addObjectCreate(xform, - AnimationDef.TransformDef.class.getName()); - _digester.addRule(xform, new SetPropertyFieldsRule()); - _digester.addSetNext(xform, "addTransform", - AnimationDef.TransformDef.class.getName()); - } - - /** - * Parses the XML file at the specified path into an animation - * definition. - */ - public AnimationDef parseAnimation (String path) - throws IOException, SAXException - { - _animation = null; - _digester.push(this); - _digester.parse(new FileInputStream(path)); - return _animation; - } - - /** - * Called by the parser once the animation is parsed. - */ - public void setAnimation (AnimationDef animation) - { - _animation = animation; - } - - protected Digester _digester; - protected AnimationDef _animation; -} diff --git a/src/java/com/threerings/jme/tools/xml/ModelParser.java b/src/java/com/threerings/jme/tools/xml/ModelParser.java deleted file mode 100644 index 35a6fae5..00000000 --- a/src/java/com/threerings/jme/tools/xml/ModelParser.java +++ /dev/null @@ -1,109 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.tools.xml; - -import java.io.FileInputStream; -import java.io.IOException; - -import org.xml.sax.SAXException; -import org.apache.commons.digester.Digester; - -import com.samskivert.xml.SetPropertyFieldsRule; - -import com.threerings.jme.tools.ModelDef; - -/** - * Parses XML files containing 3D models. - */ -public class ModelParser -{ - public ModelParser () - { - // create and configure our digester - _digester = new Digester(); - - // add the rules - String model = "model"; - _digester.addObjectCreate(model, ModelDef.class.getName()); - _digester.addSetNext(model, "setModel", ModelDef.class.getName()); - - String tmesh = model + "/triMesh"; - _digester.addObjectCreate(tmesh, ModelDef.TriMeshDef.class.getName()); - _digester.addRule(tmesh, new SetPropertyFieldsRule()); - _digester.addSetNext(tmesh, "addSpatial", - ModelDef.SpatialDef.class.getName()); - - String smesh = model + "/skinMesh"; - _digester.addObjectCreate(smesh, - ModelDef.SkinMeshDef.class.getName()); - _digester.addRule(smesh, new SetPropertyFieldsRule()); - _digester.addSetNext(smesh, "addSpatial", - ModelDef.SpatialDef.class.getName()); - - String node = model + "/node"; - _digester.addObjectCreate(node, ModelDef.NodeDef.class.getName()); - _digester.addRule(node, new SetPropertyFieldsRule()); - _digester.addSetNext(node, "addSpatial", - ModelDef.SpatialDef.class.getName()); - - String vertex = tmesh + "/vertex", svertex = smesh + "/vertex"; - _digester.addObjectCreate(vertex, ModelDef.Vertex.class.getName()); - _digester.addObjectCreate(svertex, - ModelDef.SkinVertex.class.getName()); - _digester.addRule(vertex, new SetPropertyFieldsRule()); - _digester.addRule(svertex, new SetPropertyFieldsRule()); - _digester.addSetNext(vertex, "addVertex", - ModelDef.Vertex.class.getName()); - _digester.addSetNext(svertex, "addVertex", - ModelDef.Vertex.class.getName()); - - String bweight = smesh + "/vertex/boneWeight"; - _digester.addObjectCreate(bweight, - ModelDef.BoneWeight.class.getName()); - _digester.addRule(bweight, new SetPropertyFieldsRule()); - _digester.addSetNext(bweight, "addBoneWeight", - ModelDef.BoneWeight.class.getName()); - } - - /** - * Parses the XML file at the specified path into a model definition. - */ - public ModelDef parseModel (String path) - throws IOException, SAXException - { - _model = null; - _digester.push(this); - _digester.parse(new FileInputStream(path)); - return _model; - } - - /** - * Called by the parser once the model is parsed. - */ - public void setModel (ModelDef model) - { - _model = model; - } - - protected Digester _digester; - protected ModelDef _model; -} diff --git a/src/java/com/threerings/jme/util/BatchVisitor.java b/src/java/com/threerings/jme/util/BatchVisitor.java deleted file mode 100644 index 183ade14..00000000 --- a/src/java/com/threerings/jme/util/BatchVisitor.java +++ /dev/null @@ -1,49 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.util; - -import com.jme.scene.Geometry; -import com.jme.scene.batch.GeomBatch; - -/** - * Visits all of the {@link GeomBatch}es in a scene. - */ -public abstract class BatchVisitor extends SpatialVisitor -{ - public BatchVisitor () - { - super(Geometry.class); - } - - // documentation inherited from SpatialVisitor - protected void visit (Geometry geom) - { - for (int ii = 0, nn = geom.getBatchCount(); ii < nn; ii++) { - visit(geom.getBatch(ii)); - } - } - - /** - * Called once for each {@link GeomBatch} in the scene graph. - */ - protected abstract void visit (GeomBatch batch); -} diff --git a/src/java/com/threerings/jme/util/ImageCache.java b/src/java/com/threerings/jme/util/ImageCache.java deleted file mode 100644 index 823aa5cb..00000000 --- a/src/java/com/threerings/jme/util/ImageCache.java +++ /dev/null @@ -1,410 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.util; - -import java.lang.ref.WeakReference; -import java.util.HashMap; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -import java.awt.Graphics2D; -import java.awt.color.ColorSpace; -import java.awt.geom.AffineTransform; -import java.awt.image.BandCombineOp; -import java.awt.image.BufferedImage; -import java.awt.image.ComponentColorModel; -import java.awt.image.DataBuffer; -import java.awt.image.DataBufferByte; -import java.awt.image.Raster; - -import com.google.common.collect.Maps; - -import com.jme.image.Image; -import com.jmex.bui.BImage; - -import com.threerings.media.image.Colorization; -import com.threerings.media.image.ImageUtil; - -import com.threerings.resource.ResourceManager; - -import static com.threerings.jme.Log.log; - -/** - * Manages a weak cache of image data to make life simpler for callers that don't want to worry - * about coordinating shared use of the same images. - */ -public class ImageCache -{ - /** - * Creates a JME-compatible image from the supplied buffered image. - */ - public static Image createImage (BufferedImage bufimg, boolean flip) - { - return createImage(bufimg, 1f, flip); - } - - /** - * Colorizes the supplied buffered image (which must be an 8-bit colormapped image), then - * converts the colorized image into a form that JME can display. - */ - public static Image createImage (BufferedImage bufimg, Colorization[] zations, boolean flip) - { - return createImage(bufimg, zations, 1f, flip); - } - - /** - * Colorizes the supplied buffered image (which must be an 8-bit colormapped image), then - * converts the colorized image into a form that JME can display. - */ - public static Image createImage (BufferedImage bufimg, Colorization[] zations, float scale, - boolean flip) - { - return createImage(ImageUtil.recolorImage(bufimg, zations), scale, flip); - } - - /** - * Creates a JME-compatible image from the supplied buffered image. - */ - public static Image createImage (BufferedImage bufimg, float scale, boolean flip) - { - // make sure images are square powers of two - int width = (int)(bufimg.getWidth() * scale); - int height = (int)(bufimg.getHeight() * scale); - int tsize = nextPOT(Math.max(width, height)); - - // convert the the image to the format that OpenGL prefers - BufferedImage dispimg = createCompatibleImage( - tsize, tsize, bufimg.getColorModel().hasAlpha()); - - // flip the image to convert into OpenGL's coordinate system - AffineTransform tx = null; - if (flip) { - tx = AffineTransform.getScaleInstance(scale, -scale); - tx.translate((tsize - width) / 2, (height - tsize) / 2 - bufimg.getHeight()); - } - - // "convert" the image by rendering the old into the new - Graphics2D gfx = (Graphics2D)dispimg.getGraphics(); - gfx.drawImage(bufimg, tx, null); - gfx.dispose(); - - // now extract the image data into a JME image - return convertImage(dispimg); - } - - /** - * Creates a buffered image in a format compatible with LWJGL with the specified dimensions. - * - * @param transparent if true, the image will be four bytes per pixel (RGBA), if false it will - * be three (and have no alpha channel). - */ - public static BufferedImage createCompatibleImage (int width, int height, boolean transparent) - { - if (transparent) { - return new BufferedImage(GL_ALPHA_MODEL, Raster.createInterleavedRaster( - DataBuffer.TYPE_BYTE, width, height, 4, null), - false, null); - } else { - return new BufferedImage(GL_OPAQUE_MODEL, Raster.createInterleavedRaster( - DataBuffer.TYPE_BYTE, width, height, 3, null), - false, null); - } - } - - /** - * Converts an image that was created with {@link #createCompatibleImage} into a JME {@link - * Image}. The data is assumed to have already been "flipped". - */ - public static Image convertImage (BufferedImage bufimg) - { - Image image = new Image(); - image.setType(bufimg.getColorModel().hasAlpha() ? Image.RGBA8888 : Image.RGB888); - image.setWidth(bufimg.getWidth()); - image.setHeight(bufimg.getHeight()); - image.setData(convertImage(bufimg, null)); - return image; - } - - /** - * Converts the supplied image (which must have been created with {@link - * #createCompatibleImage}) into a {@link ByteBuffer} that can be passed to {@link - * Image#setData}. - * - * @param target the results of a previous call to {@link #convertImage} that will be - * overwritten or null if a new buffer should be allocated. Of course a reused buffer must be - * used with the same image or one with the exact same configuration. - */ - public static ByteBuffer convertImage (BufferedImage image, ByteBuffer target) - { - DataBufferByte dbuf = (DataBufferByte)image.getRaster().getDataBuffer(); - byte[] data = dbuf.getData(); - if (target == null) { - target = ByteBuffer.allocateDirect(data.length); - target.order(ByteOrder.nativeOrder()); - } - target.clear(); - target.put(data); - target.flip(); - return target; - } - - /** - * Creates an image cache that will obtain its image data from the supplied resource manager. - */ - public ImageCache (ResourceManager rsrcmgr) - { - _rsrcmgr = rsrcmgr; - } - - /** - * See {@link #getImage(String,boolean)}. - */ - public Image getImage (String rsrcPath) - { - return getImage(rsrcPath, 1f, true); - } - - /** - * See {@link #getImage(String,float,boolean)}. - */ - public Image getImage (String rsrcPath, float scale) - { - return getImage(rsrcPath, scale, true); - } - - /** - * Loads up an image from the cache if possible or from the resource manager otherwise, in - * which case it is prepared for use by JME and OpenGL. Note: these images are cached - * separately from the {@link BImage} and {@link BufferedImage} caches. - * - * @param flip whether or not to convert the image from normal computer coordinates into OpenGL - * coordinates when loading. Note: this information is not cached, an image must - * always be requested as flipped or not flipped. - */ - public Image getImage (String rsrcPath, boolean flip) - { - return getImage(rsrcPath, 1f, flip); - } - - /** - * Loads up an image from the cache if possible or from the resource manager otherwise, in - * which case it is prepared for use by JME and OpenGL. Note: these images are cached - * separately from the {@link BImage} and {@link BufferedImage} caches. - * - * @param flip whether or not to convert the image from normal computer coordinates into OpenGL - * coordinates when loading. Note: this information is not cached, an image must - * always be requested as flipped or not flipped. - * @param scale a scale factor to apply to the image. As with the flip setting, the scale - * factor is not cached. - */ - public Image getImage (String rsrcPath, float scale, boolean flip) - { - // first check the cache - WeakReference iref = _imgcache.get(rsrcPath); - Image image; - if (iref != null && (image = iref.get()) != null) { - return image; - } - - // load the image data from the resource manager - BufferedImage bufimg; - try { - bufimg = _rsrcmgr.getImageResource(rsrcPath); - } catch (Throwable t) { - log.warning("Unable to load image resource " + - "[path=" + rsrcPath + "].", t); - // cope; return an error image of abitrary size - bufimg = ImageUtil.createErrorImage(64, 64); - } - - // create and cache a new JME image with the appropriate data - image = createImage(bufimg, scale, flip); - _imgcache.put(rsrcPath, new WeakReference(image)); - return image; - } - - /** - * Loads up an image from the cache if possible or from the resource manager otherwise, in - * which case it is prepared for use by BUI. Note: these images are cached separately - * from the {@link Image} and {@link BufferedImage} caches. - */ - public BImage getBImage (String rsrcPath) - { - return getBImage(rsrcPath, 1f, false); - } - - /** - * Loads up an image from the cache if possible or from the resource manager otherwise, in - * which case it is prepared for use by BUI. Note: these images are cached separately - * from the {@link Image} and {@link BufferedImage} caches. - * - * @param scale If none-unity the image will be scaled by the supplied factor before being - * converted into a {@link BImage}. - * @param returnNull If set to true, will return a null instead of generating an error image on - * failure - */ - public BImage getBImage (String rsrcPath, float scale, boolean returnNull) - { - // first check the cache - String key = rsrcPath + ":" + scale; - WeakReference iref = _buicache.get(key); - BImage image; - if (iref != null && (image = iref.get()) != null) { - return image; - } - - // load the image data from the resource manager - BufferedImage bufimg; - try { - bufimg = _rsrcmgr.getImageResource(rsrcPath); - } catch (Throwable t) { - if (returnNull) { - return null; - } - log.warning("Unable to load image resource [path=" + rsrcPath + "].", t); - // cope; return an error image of abitrary size - bufimg = ImageUtil.createErrorImage(64, 64); - } - - // create and cache a new BUI image with the appropriate (scaled if necessary) data - image = new BImage(scale == 1f ? bufimg : - bufimg.getScaledInstance(Math.round(bufimg.getWidth()*scale), - Math.round(bufimg.getHeight()*scale), - BufferedImage.SCALE_SMOOTH), true); - _buicache.put(key, new WeakReference(image)); - return image; - } - - /** - * Loads up a silhouette image (in which all non-transparent pixels are set to black) from the - * cache if possible or from the resource manager otherwise, in which case it is prepared for - * use by BUI. - */ - public BImage getSilhouetteBImage (String rsrcPath, boolean returnNull) - { - // first check the cache - String key = "silhouette:" + rsrcPath; - WeakReference iref = _buicache.get(key); - BImage image; - if (iref != null && (image = iref.get()) != null) { - return image; - } - - // load the image data from the resource manager - BufferedImage bufimg, silimg; - try { - bufimg = _rsrcmgr.getImageResource(rsrcPath); - - // now turn it into a silhouette - silimg = new BufferedImage(bufimg.getWidth(), bufimg.getHeight(), - BufferedImage.TYPE_4BYTE_ABGR); - new BandCombineOp(NON_ALPHA_TO_BROWN, null).filter( - bufimg.getRaster(), silimg.getRaster()); - - } catch (Throwable t) { - if (returnNull) { - return null; - } - log.warning("Unable to load image resource [path=" + rsrcPath + "].", t); - // cope; return an error image of abitrary size - silimg = ImageUtil.createErrorImage(64, 64); - } - - // create and cache a new BUI image with the appropriate data - image = new BImage(silimg, true); - _buicache.put(key, new WeakReference(image)); - return image; - } - - /** - * Colorizes the image with supplied path (which must be an 8-bit colormapped image), then - * converts the colorized image into a form that JME can display. - */ - public BImage createColorizedBImage (String path, Colorization[] zations, boolean flip) - { - return new BImage(ImageUtil.recolorImage(getBufferedImage(path), zations), flip); - } - - /** - * Loads up a buffered image from the cache if possible or from the resource manager - * otherwise. Note: these images are cached separately from the {@link Image} and - * {@link BImage} caches. - */ - public BufferedImage getBufferedImage (String rsrcPath) - { - // first check the cache - WeakReference iref = _bufcache.get(rsrcPath); - BufferedImage image; - if (iref != null && (image = iref.get()) != null) { - return image; - } - - // load the image data from the resource manager - try { - image = _rsrcmgr.getImageResource(rsrcPath); - } catch (Throwable t) { - log.warning("Unable to load image resource [path=" + rsrcPath + "].", t); - // cope; return an error image of abitrary size - image = ImageUtil.createErrorImage(64, 64); - } - - _bufcache.put(rsrcPath, new WeakReference(image)); - return image; - } - - /** Rounds the supplied value up to a power of two. */ - protected static int nextPOT (int value) - { - return (Integer.bitCount(value) > 1) ? (Integer.highestOneBit(value) << 1) : value; - } - - /** Provides access to our image data. */ - protected ResourceManager _rsrcmgr; - - /** A cache of {@link Image} instances. */ - protected HashMap> _imgcache = Maps.newHashMap(); - - /** A cache of {@link BImage} instances. */ - protected HashMap> _buicache = Maps.newHashMap(); - - /** A cache of {@link BufferedImage} instances. */ - protected HashMap> _bufcache = Maps.newHashMap(); - - /** Used to create buffered images in a format compatible with OpenGL. */ - protected static ComponentColorModel GL_ALPHA_MODEL = new ComponentColorModel( - ColorSpace.getInstance(ColorSpace.CS_sRGB), new int[] { 8, 8, 8, 8 }, - true, false, ComponentColorModel.TRANSLUCENT, DataBuffer.TYPE_BYTE); - - /** Used to create buffered images in a format compatible with OpenGL. */ - protected static ComponentColorModel GL_OPAQUE_MODEL = new ComponentColorModel( - ColorSpace.getInstance(ColorSpace.CS_sRGB), new int[] { 8, 8, 8, 0 }, - false, false, ComponentColorModel.OPAQUE, DataBuffer.TYPE_BYTE); - - /** An operation that converts all channels except alpha to brown. */ - protected static final float[][] NON_ALPHA_TO_BROWN = { - { 0, 0, 0, 0x66/255f }, - { 0, 0, 0, 0x57/255f }, - { 0, 0, 0, 0x34/255f }, - { 0, 0, 0, 0.5f } - }; -} diff --git a/src/java/com/threerings/jme/util/JmeUtil.java b/src/java/com/threerings/jme/util/JmeUtil.java deleted file mode 100644 index cb2102a3..00000000 --- a/src/java/com/threerings/jme/util/JmeUtil.java +++ /dev/null @@ -1,186 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.util; - -import com.jme.math.Matrix4f; -import com.jme.math.Quaternion; -import com.jme.math.Vector3f; -import com.jme.scene.Controller; - -import com.samskivert.util.StringUtil; - -import static com.threerings.jme.Log.log; - -/** - * Some static classes and methods of general utility to applications using JME. - */ -public class JmeUtil -{ - /** - * Represents the current position and direction in an animation composed of a fixed number of - * discrete frames using one of the repeat types defined in {@link Controller}. - */ - public static class FrameState - { - /** The index of the current frame. */ - public int idx; - - /** The current direction of animation. */ - public int dir = +1; - - /** The fractional progress towards the next frame. */ - public float accum; - - /** - * Resets the state back to the beginning. - */ - public void reset () - { - set(0, +1, 0f); - } - - /** - * Sets the entire frame state. - */ - public void set (int idx, int dir, float accum) - { - this.idx = idx; - this.dir = dir; - this.accum = accum; - } - - /** - * Updates the frame state after some amount of time has elapsed. - */ - public void update (float elapsed, float frameRate, int frameCount, int repeatType) - { - float frames = elapsed * frameRate; - for (accum += frames; accum >= 1f; accum -= 1f) { - advance(frameCount, repeatType); - } - } - - /** - * Advances the position by one frame. - */ - public void advance (int frameCount, int repeatType) - { - if ((idx += dir) >= frameCount) { - if (repeatType == Controller.RT_CLAMP) { - idx = frameCount - 1; - dir = 0; - } else if (repeatType == Controller.RT_WRAP) { - idx = 0; - } else { // repeatType == Controller.RT_CYCLE - idx = frameCount - 2; - dir = -1; - } - } else if (idx < 0) { - idx = 1; - dir = +1; - } - } - } - - /** - * Sets a matrix to the transform defined by the given translation, - * rotation, and scale values. - */ - public static Matrix4f setTransform ( - Vector3f translation, Quaternion rotation, Vector3f scale, Matrix4f result) - { - result.setRotationQuaternion(rotation); - result.setTranslation(translation); - - result.m00 *= scale.x; - result.m01 *= scale.y; - result.m02 *= scale.z; - - result.m10 *= scale.x; - result.m11 *= scale.y; - result.m12 *= scale.z; - - result.m20 *= scale.x; - result.m21 *= scale.y; - result.m22 *= scale.z; - - return result; - } - - /** - * Attempts to parse a string containing an axis: either "x", "y", or "z", or three - * comma-delimited values representing an axis vector. The value returned may be one of - * JME's "constant" vectors (for example, {@link Vector3f#UNIT_X}), so don't modify it. - */ - public static Vector3f parseAxis (String axis) - { - if ("x".equalsIgnoreCase(axis)) { - return Vector3f.UNIT_X; - } else if ("y".equalsIgnoreCase(axis)) { - return Vector3f.UNIT_Y; - } else if ("z".equalsIgnoreCase(axis)) { - return Vector3f.UNIT_Z; - } else { - Vector3f vector = parseVector3f(axis); - if (vector != null) { - vector.normalizeLocal(); - } - return vector; - } - } - - /** - * Attempts to parse a string containing three comma-delimited values and return a - * {@link Vector3f}. - */ - public static Vector3f parseVector3f (String vector) - { - if (vector != null) { - float[] vals = StringUtil.parseFloatArray(vector); - if (vals != null && vals.length == 3) { - return new Vector3f(vals[0], vals[1], vals[2]); - } else { - log.warning("Invalid vector [vector=" + vector + "]."); - } - } - return null; - } - - /** - * Attempts to parse a string describing one of the repeat types defined in {@link Controller}: - * "clamp", "cycle", or "wrap". Will return the specified default if the type is - * null or invalid. - */ - public static int parseRepeatType (String type, int defaultType) - { - if ("clamp".equals(type)) { - return Controller.RT_CLAMP; - } else if ("cycle".equals(type)) { - return Controller.RT_CYCLE; - } else if ("wrap".equals(type)) { - return Controller.RT_WRAP; - } else if (type != null) { - log.warning("Invalid repeat type [type=" + type + "]."); - } - return defaultType; - } -} diff --git a/src/java/com/threerings/jme/util/LinearTimeFunction.java b/src/java/com/threerings/jme/util/LinearTimeFunction.java deleted file mode 100644 index 41a42345..00000000 --- a/src/java/com/threerings/jme/util/LinearTimeFunction.java +++ /dev/null @@ -1,42 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.util; - -/** - * Varies a value linearly with time. - */ -public class LinearTimeFunction extends TimeFunction -{ - public LinearTimeFunction (float start, float end, float duration) - { - super(start, end, duration); - _range = (end - start); - } - - // documentation inherited - protected float computeValue () - { - return (_elapsed * _range / _duration) + _start; - } - - protected float _range; -} diff --git a/src/java/com/threerings/jme/util/ShaderCache.java b/src/java/com/threerings/jme/util/ShaderCache.java deleted file mode 100644 index 6f223e06..00000000 --- a/src/java/com/threerings/jme/util/ShaderCache.java +++ /dev/null @@ -1,263 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.util; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; - -import java.nio.ByteBuffer; -import java.nio.IntBuffer; -import java.nio.charset.Charset; - -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; - -import org.lwjgl.opengl.ARBShaderObjects; - -import com.google.common.base.Objects; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; - -import com.jme.scene.state.GLSLShaderObjectsState; -import com.jme.system.DisplaySystem; -import com.jme.util.ShaderAttribute; -import com.jme.util.ShaderUniform; -import com.jme.util.geom.BufferUtils; - -import com.samskivert.util.ArrayUtil; - -import com.threerings.resource.ResourceManager; - -import static com.threerings.jme.Log.*; - -/** - * Caches shaders under their names and preprocessor definitions, ensuring that identical shaders - * are only compiled once. - */ -public class ShaderCache -{ - /** - * Create a shader cache that will obtain shader source from the supplied resource manager. - */ - public ShaderCache (ResourceManager rsrcmgr) - { - _rsrcmgr = rsrcmgr; - } - - /** - * Creates a new shader state with the supplied vertex shader, fragment shader, - * and preprocessor definitions. If a program with the given parameters has already been - * compiled, the state will use the program id of the existing shader. - * - * @return the newly created state, or null if there was an error and the - * program could not be compiled. - */ - public GLSLShaderObjectsState createState (String vert, String frag, String... defs) - { - GLSLShaderObjectsState sstate = - DisplaySystem.getDisplaySystem().getRenderer().createGLSLShaderObjectsState(); - return (configureState(sstate, vert, frag, defs) ? sstate : null); - } - - /** - * (Re)configures an existing shader state with the supplied parameters. - * - * @return true if the shader was successfully configured, false if the shader could not - * be compiled. - */ - public boolean configureState ( - GLSLShaderObjectsState sstate, String vert, String frag, String... defs) - { - return configureState(sstate, vert, frag, defs, null); - } - - /** - * (Re)configures an existing shader state with the supplied parameters. - * - * @param ddefs an optional array of derived preprocessor definitions that, unlike the - * principal definitions, need not be compared when differentiating between cached shaders. - * @return true if the shader was successfully configured, false if the shader could not - * be compiled. - */ - public boolean configureState ( - GLSLShaderObjectsState sstate, String vert, String frag, String[] defs, String[] ddefs) - { - ShaderKey key = new ShaderKey(vert, frag, defs); - Integer programId = _programIds.get(key); - if (programId == null) { - if (ddefs != null) { - defs = ArrayUtil.concatenate(defs, ddefs); - } - GLSLShaderObjectsState pstate = loadShaders(vert, frag, defs); - if (pstate == null) { - return false; - } - _programIds.put(key, programId = pstate.getProgramID()); - } - if (sstate.getProgramID() == programId) { - return true; - } - sstate.setProgramID(programId); - for (ShaderAttribute attrib : sstate.attribs.values()) { - attrib.attributeID = -1; - } - for (ShaderUniform uniform : sstate.uniforms.values()) { - uniform.uniformID = -1; - } - sstate.setNeedsRefresh(true); - return true; - } - - /** - * Checks whether the specified shader is already loaded. This is useful in order to avoid - * generating complex derived definitions when they won't be needed. - */ - public boolean isLoaded (String vert, String frag, String... defs) - { - return _programIds.containsKey(new ShaderKey(vert, frag, defs)); - } - - /** - * Loads the specified shaders (prepending the supplied preprocessor definitions) - * and returns a GLSL shader state. One of the supplied names may be null - * in order to use the fixed-function pipeline for that part. The method returns - * null if the shaders fail to compile (JME will log an error). - * - * @param defs a number of preprocessor definitions to be #defined in both shaders - * (e.g., "ENABLE_FOG", "NUM_LIGHTS 2"). - */ - protected GLSLShaderObjectsState loadShaders (String vert, String frag, String[] defs) - { - GLSLShaderObjectsState sstate = - DisplaySystem.getDisplaySystem().getRenderer().createGLSLShaderObjectsState(); - sstate.load( - (vert == null) ? null : getSource(vert, defs), - (frag == null) ? null : getSource(frag, defs)); - - // check its link status - IntBuffer ibuf = BufferUtils.createIntBuffer(1); - ARBShaderObjects.glGetObjectParameterARB(sstate.getProgramID(), - ARBShaderObjects.GL_OBJECT_LINK_STATUS_ARB, ibuf); - if (ibuf.get(0) == 0) { - return null; // failed to link - } - - // check the info log - ARBShaderObjects.glGetObjectParameterARB(sstate.getProgramID(), - ARBShaderObjects.GL_OBJECT_INFO_LOG_LENGTH_ARB, ibuf); - ByteBuffer bbuf = BufferUtils.createByteBuffer(ibuf.get(0)); - ARBShaderObjects.glGetInfoLogARB(sstate.getProgramID(), ibuf, bbuf); - String log = Charset.forName("US-ASCII").decode(bbuf).toString(); - - // if it runs in software mode, that counts as a failure - return (log.indexOf("software") == -1) ? sstate : null; - } - - /** - * Retrieves the source code to a shader as a single {@link String}, either by fetching it from - * the cache or loading it from the resource manager (and caching it). Returns - * null (after logging a warning) if the shader couldn't be found. - * - * @param defs an array of definitions to prepend to the result. - */ - protected String getSource (String shader, String[] defs) - { - // fetch the shader source - String source = _sources.get(shader); - if (source == null) { - StringBuilder buf = new StringBuilder(); - try { - BufferedReader reader = new BufferedReader( - new InputStreamReader(_rsrcmgr.getResource(shader))); - String line; - while ((line = reader.readLine()) != null) { - buf.append(line).append('\n'); - } - } catch (IOException e) { - log.warning("Failed to load shader [name=" + shader + ", error=" + e + "]."); - return null; - } - _sources.put(shader, (source = buf.toString())); - } - - // prepend the definitions (the version directive comes before anything else) - StringBuilder buf = new StringBuilder(); - buf.append("#version 110\n"); - for (String def : defs) { - buf.append("#define ").append(def).append('\n'); - } - buf.append(source); - return buf.toString(); - } - - /** Identifies a cached shader. */ - protected static class ShaderKey - { - /** The name of the vertex shader (or null for none). */ - public String vert; - - /** The name of the fragment shader (or null for none). */ - public String frag; - - /** The set of preprocessor definitions. */ - public HashSet defs = Sets.newHashSet(); - - public ShaderKey (String vert, String frag, String[] defs) - { - this.vert = vert; - this.frag = frag; - Collections.addAll(this.defs, defs); - } - - @Override - public int hashCode () - { - return (vert == null ? 0 : vert.hashCode()) + (frag == null ? 0 : frag.hashCode()) + - defs.hashCode(); - } - - @Override - public boolean equals (Object obj) - { - ShaderKey okey = (ShaderKey)obj; - return Objects.equal(vert, okey.vert) && Objects.equal(frag, okey.frag) && - defs.equals(okey.defs); - } - - @Override - public String toString () - { - return "[vert=" + vert + ", frag=" + frag + ", defs=" + defs + "]"; - } - } - - /** Provides access to shader source. */ - protected ResourceManager _rsrcmgr; - - /** Maps shader names to source strings. */ - protected HashMap _sources = Maps.newHashMap(); - - /** Maps shader keys to linked program ids. */ - protected HashMap _programIds = Maps.newHashMap(); -} diff --git a/src/java/com/threerings/jme/util/ShaderConfig.java b/src/java/com/threerings/jme/util/ShaderConfig.java deleted file mode 100644 index 362fa4f1..00000000 --- a/src/java/com/threerings/jme/util/ShaderConfig.java +++ /dev/null @@ -1,394 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.util; - -import java.util.ArrayList; - -import com.google.common.collect.Lists; - -import com.jme.image.Texture; -import com.jme.light.Light; -import com.jme.scene.state.FogState; -import com.jme.scene.state.GLSLShaderObjectsState; -import com.jme.scene.state.LightState; -import com.jme.scene.state.RenderState; -import com.jme.scene.state.TextureState; -import com.jme.system.DisplaySystem; -import com.jme.util.ShaderUniform; - -import com.samskivert.util.StringUtil; - -/** - * Tracks the configuration of a shader, which depends on (among other things) a set of - * {@link RenderState}s. When the state set changes, the shader must be reconfigured - * (recompiled or refetched from the {@link ShaderCache}). - */ -public abstract class ShaderConfig - implements Cloneable -{ - public ShaderConfig (ShaderCache scache) - { - _scache = scache; - _state = DisplaySystem.getDisplaySystem().getRenderer().createGLSLShaderObjectsState(); - } - - /** - * Returns a reference to the render state controlled by this configuration. - */ - public GLSLShaderObjectsState getState () - { - return _state; - } - - /** - * Updates the configuration according to the provided state set. If the configuration has - * changed, the shader will be recompiled or refetched from the cache in order to reflect the - * new configuration. - * - * @return true if all went all, false if the shader could not be compiled. - */ - public boolean update (RenderState[] states) - { - // update the configurations to determine if we must reconfigure - if (!updateConfigs(states) && _state.getProgramID() > 0) { - return true; - } - - // reconfigure the shader state, generating the derived definitions only if the - // required configuration isn't in the cache - String vert = getVertexShader(), frag = getFragmentShader(); - ArrayList defs = Lists.newArrayList(); - getDefinitions(defs); - String[] darray = defs.toArray(new String[defs.size()]), ddarray = null; - if (!_scache.isLoaded(vert, frag, darray)) { - ArrayList ddefs = Lists.newArrayList(); - getDerivedDefinitions(ddefs); - ddarray = ddefs.toArray(new String[ddefs.size()]); - } - return _scache.configureState(_state, vert, frag, darray, ddarray); - } - - @Override - public ShaderConfig clone () - { - try { - ShaderConfig other = (ShaderConfig)super.clone(); - other._state = - DisplaySystem.getDisplaySystem().getRenderer().createGLSLShaderObjectsState(); - other._state.setProgramID(_state.getProgramID()); - other._state.attribs = _state.attribs; - for (ShaderUniform uniform : _state.uniforms.values()) { - other._state.uniforms.put(uniform.name, (ShaderUniform)uniform.clone()); - } - if (_lights != null) { - other._lights = _lights.clone(); - for (int ii = 0; ii < _lights.length; ii++) { - other._lights[ii] = _lights[ii].clone(); - } - } - if (_textures != null) { - other._textures = _textures.clone(); - for (int ii = 0; ii < _textures.length; ii++) { - other._textures[ii] = _textures[ii].clone(); - } - } - return other; - - } catch (CloneNotSupportedException e) { - throw new AssertionError(e); - } - } - - /** - * Updates the component configurations according to the supplied state set, returning - * true if they have changed and the shader must be reconfigured. - */ - protected boolean updateConfigs (RenderState[] states) - { - // this is one place where we don't want short-circuit evaluation - boolean lchanged = updateLightConfigs((LightState)states[RenderState.RS_LIGHT]); - boolean tchanged = updateTextureConfigs((TextureState)states[RenderState.RS_TEXTURE]); - boolean fchanged = updateFogConfig((FogState)states[RenderState.RS_FOG]); - return lchanged || tchanged || fchanged; - } - - /** - * Updates the light configurations, returning true if they have changed. - */ - protected boolean updateLightConfigs (LightState lstate) - { - if (lstate == null || !lstate.isEnabled()) { - LightConfig[] olights = _lights; - _lights = null; - return (olights != null); - } - int lcount = Math.min(lstate.getQuantity(), MAX_LIGHTS); - if (_lights == null || _lights.length != lcount) { - _lights = new LightConfig[lcount]; - for (int ii = 0; ii < lcount; ii++) { - _lights[ii] = new LightConfig(); - _lights[ii].update(lstate.get(ii)); - } - return true; - } - boolean changed = false; - for (int ii = 0; ii < lcount; ii++) { - changed |= _lights[ii].update(lstate.get(ii)); - } - return changed; - } - - /** - * Updates the texture configurations, returning true if they have changed. - */ - protected boolean updateTextureConfigs (TextureState tstate) - { - if (tstate == null || !tstate.isEnabled()) { - TextureConfig[] otextures = _textures; - _textures = null; - return (otextures != null); - } - int tcount = tstate.getNumberOfSetTextures(); - if (_textures == null || _textures.length != tcount) { - _textures = new TextureConfig[tcount]; - for (int ii = 0; ii < tcount; ii++) { - _textures[ii] = new TextureConfig(); - _textures[ii].update(tstate.getTexture(ii)); - } - return true; - } - boolean changed = false; - for (int ii = 0; ii < tcount; ii++) { - changed |= _textures[ii].update(tstate.getTexture(ii)); - } - return changed; - } - - /** - * Updates the fog configuration, returning true if it has changed. - */ - protected boolean updateFogConfig (FogState fstate) - { - int ofunc = _fogDensityFunc; - _fogDensityFunc = (fstate == null || !fstate.isEnabled()) ? - -1 : fstate.getDensityFunction(); - return (ofunc != _fogDensityFunc); - } - - /** - * Returns the resource name of the vertex shader (or null for none). - */ - protected String getVertexShader () - { - return null; - } - - /** - * Returns the resource name of the fragment shader (or null for none). - */ - protected String getFragmentShader () - { - return null; - } - - /** - * Adds the preprocessor definitions that this configuration requires for its shader to the - * supplied list. - */ - protected void getDefinitions (ArrayList defs) - { - // the distinguishing definitions are just keys - if (_lights != null) { - defs.add("LIGHTS " + StringUtil.join(_lights, "/")); - } - if (_textures != null) { - defs.add("TEXTURES " + StringUtil.join(_textures, "/")); - } - if (_fogDensityFunc != -1) { - defs.add("FOG " + _fogDensityFunc); - } - } - - /** - * Adds the derived preprocessor definitions that this configuration requires to the supplied - * list. The derived definitions are not used to distinguish between cached shaders. - */ - protected void getDerivedDefinitions (ArrayList ddefs) - { - // add the def that sets the front color based on the light types - StringBuilder buf = new StringBuilder("SET_FRONT_COLOR "); - if (_lights != null) { - // start with the "scene color," which combines scene ambient, emissivity, etc. - buf.append("vec3 frontColor = gl_FrontLightModelProduct.sceneColor.rgb; "); - - // add snippets for each of the lights - for (int ii = 0; ii < _lights.length; ii++) { - String snippet = getLightSnippet(_lights[ii].type); - buf.append(snippet.replace("%", Integer.toString(ii))); - } - - // the alpha value comes from the diffuse color in the material - buf.append("gl_FrontColor = vec4(frontColor, gl_FrontMaterial.diffuse.a);"); - } else { - buf.append("gl_FrontColor = vec4(1.0, 1.0, 1.0, 1.0);"); - } - ddefs.add(buf.toString()); - - // add the def that sets the texture coordinates based on the env map modes - buf = new StringBuilder("SET_TEX_COORDS"); - if (_textures != null) { - for (int ii = 0; ii < _textures.length; ii++) { - TextureConfig texture = _textures[ii]; - if (texture.envMapMode == -1) { - continue; - } - buf.append(" gl_TexCoord[" + ii + "] = "); - if (texture.envMapMode == Texture.EM_SPHERE) { - buf.append("vec4(eyeNormal.xy * 0.5 + vec2(0.5, 0.5), 0.0, 1.0);"); - } else { - buf.append("gl_MultiTexCoord" + ii + ";"); - } - } - } - ddefs.add(buf.toString()); - - // add the definition that sets the fog alpha based on the density function - buf = new StringBuilder("SET_FOG_ALPHA"); - if (_fogDensityFunc == FogState.DF_EXP) { - buf.append(" fogAlpha = exp(gl_Fog.density * eyeVertex.z);"); - } - ddefs.add(buf.toString()); - } - - /** - * Returns a code snippet that adds the influence of a light of the specified type (after - * replacing '%' with the light index). - */ - protected String getLightSnippet (int type) - { - if (type == Light.LT_POINT) { - return POINT_LIGHT_SNIPPET; - } else if (type == Light.LT_DIRECTIONAL) { - return DIRECTIONAL_LIGHT_SNIPPET; - } else { - return ""; - } - } - - /** The configuration of a single light in a {@link LightState}. */ - protected static class LightConfig - implements Cloneable - { - /** The type of light (see {@link Light#getType}). */ - public int type = -1; - - public boolean update (Light light) - { - int otype = type; - type = (light == null) ? -1 : light.getType(); - return (otype != type); - } - - @Override - public LightConfig clone () - { - try { - return (LightConfig) super.clone(); - } catch (CloneNotSupportedException e) { - throw new AssertionError(e); - } - } - - @Override - public String toString () - { - return Integer.toString(type); - } - } - - /** The configuration of a single texture in a {@link TextureState}. */ - protected static class TextureConfig - implements Cloneable - { - /** The environment map mode (see {@link Texture#getEnvironmentalMapMode}). */ - public int envMapMode = -1; - - public boolean update (Texture texture) - { - int omode = envMapMode; - envMapMode = (texture == null) ? -1 : texture.getEnvironmentalMapMode(); - return (omode != envMapMode); - } - - @Override - public TextureConfig clone () - { - try { - return (TextureConfig) super.clone(); - } catch (CloneNotSupportedException e) { - throw new AssertionError(e); - } - } - - @Override - public String toString () - { - return Integer.toString(envMapMode); - } - } - - /** The cache used to reconfigure shaders. */ - protected ShaderCache _scache; - - /** The state object to reconfigure. */ - protected GLSLShaderObjectsState _state; - - /** The current light configurations (or null if lighting is disabled). */ - protected LightConfig[] _lights; - - /** The current texture configurations (or null if texturing is disabled). */ - protected TextureConfig[] _textures; - - /** The density function of the fog in the scene (or -1 for none). */ - protected int _fogDensityFunc = -1; - - /** To keep things sane, let's limit the total number of lights (OpenGL allows at least - * eight). */ - protected static final int MAX_LIGHTS = 4; - - /** A code snippet for adding the influence of a point light. */ - protected static final String POINT_LIGHT_SNIPPET = - "vec3 lvec% = gl_LightSource[%].position.xyz - eyeVertex; " + - "float ldist% = length(lvec%); " + - "frontColor += (gl_FrontLightProduct[%].ambient.rgb + " + - "gl_FrontLightProduct[%].diffuse.rgb * " + - "max(dot(eyeNormal, normalize(lvec%)), 0.0)) / " + - "(gl_LightSource[%].constantAttenuation + " + - "ldist% * gl_LightSource[%].linearAttenuation + " + - "ldist% * ldist% * gl_LightSource[%].quadraticAttenuation);"; - - /** A code snippet for adding the influence of a directional light. */ - protected static final String DIRECTIONAL_LIGHT_SNIPPET = - "frontColor += gl_FrontLightProduct[%].ambient.rgb + " + - "gl_FrontLightProduct[%].diffuse.rgb * " + - "max(dot(eyeNormal, gl_LightSource[%].position.xyz), 0.0);"; -} diff --git a/src/java/com/threerings/jme/util/SpatialVisitor.java b/src/java/com/threerings/jme/util/SpatialVisitor.java deleted file mode 100644 index 932060b9..00000000 --- a/src/java/com/threerings/jme/util/SpatialVisitor.java +++ /dev/null @@ -1,63 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.util; - -import com.jme.scene.Node; -import com.jme.scene.Spatial; - -/** - * Performs a depth-first scene graph traversal looking for {@link Spatial}s - * of a given class. - */ -public abstract class SpatialVisitor -{ - public SpatialVisitor (Class type) - { - _type = type; - } - - /** - * Traverses the given node in depth-first order, calling {@link #visit} - * for each {@link Spatial} of the configured class encountered. - */ - public void traverse (Spatial spatial) - { - if (_type.isInstance(spatial)) { - visit(_type.cast(spatial)); - } - if (spatial instanceof Node) { - Node node = (Node)spatial; - for (int ii = 0, nn = node.getQuantity(); ii < nn; ii++) { - traverse(node.getChild(ii)); - } - } - } - - /** - * Called once for each {@link Spatial} of the configured class in the - * scene graph. - */ - protected abstract void visit (T child); - - /** The type of spatial of interest. */ - protected Class _type; -} diff --git a/src/java/com/threerings/jme/util/TimeFunction.java b/src/java/com/threerings/jme/util/TimeFunction.java deleted file mode 100644 index 31eac71f..00000000 --- a/src/java/com/threerings/jme/util/TimeFunction.java +++ /dev/null @@ -1,99 +0,0 @@ -// -// $Id$ -// -// Nenya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://code.google.com/p/nenya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.util; - -/** - * Used to vary a value over time where time is provided at discrete increments - * (on the frame tick) and the value is computed appropriately. This can be - * used for fades and other effects where different functions (linear, ease-in - * ease-out, etc.) should be easy to plug in. - */ -public abstract class TimeFunction -{ - /** - * Every time function varies a value from some starting value to some - * ending value over some duration. The way in which it varies - * (linearly, for example) is up to the derived class. - * - * @param start the starting value. - * @param end the ending value. - * @param duration the duration in seconds. - */ - public TimeFunction (float start, float end, float duration) - { - _start = start; - _end = end; - _duration = duration; - } - - /** - * Returns the current value given the supplied elapsed time. The value - * will be bounded to the originally supplied starting and ending values at - * times 0 (and below) and {@link #_duration} (and above) respectively. - * - * @param deltaTime the amount of time that has elapsed since the last call - * to this method. - */ - public float getValue (float deltaTime) - { - _elapsed += deltaTime; - - if (_elapsed <= 0) { - return _start; - } else if (_elapsed >= _duration) { - return _end; - } else { - return computeValue(); - } - } - - /** - * Returns true if this function has proceeded the full length of its - * duration. This should be called after a call to {@link #getValue} has - * been made to update our internal elapsed time. - */ - public boolean isComplete () - { - return _elapsed >= _duration; - } - - /** Generates a string representation of this instance. */ - public String toString () - { - return _start + " to " + _end + ", " + _elapsed + " of " + _duration; - } - - /** - * This must be implemented by our derived class to compute our value given - * the currently stored {@link #_elapsed} time. - */ - protected abstract float computeValue (); - - /** Our starting and ending values. */ - protected float _start, _end; - - /** The number of milliseconds over which we vary our value. */ - protected float _duration; - - /** The number of seconds that have elapsed since we started. */ - protected float _elapsed; -} diff --git a/tests/src/java/com/threerings/jme/JmeCanvasTestApp.java b/tests/src/java/com/threerings/jme/JmeCanvasTestApp.java deleted file mode 100644 index f7d54ca3..00000000 --- a/tests/src/java/com/threerings/jme/JmeCanvasTestApp.java +++ /dev/null @@ -1,62 +0,0 @@ -// -// $Id$ - -package com.threerings.jme; - -import java.awt.BorderLayout; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import javax.swing.JButton; -import javax.swing.JFrame; - -import com.jme.bounding.BoundingBox; -import com.jme.math.Vector3f; -import com.jme.scene.shape.Box; - -/** - * Tests the JME/AWT integration bits. - */ -public class JmeCanvasTestApp extends JmeCanvasApp -{ - public static void main (String[] args) - { - final JmeCanvasTestApp app = new JmeCanvasTestApp(); - JFrame frame = new JFrame("JmeCanvasTest"); - frame.getContentPane().add(app.getCanvas(), BorderLayout.CENTER); - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - frame.setSize(800, 600); - frame.setVisible(true); - - JButton button = new JButton("Create box"); - frame.getContentPane().add(button, BorderLayout.SOUTH); - button.addActionListener(new ActionListener() { - public void actionPerformed (ActionEvent event) { - app.addBox(); - } - }); - app.run(); - } - - public void addBox () - { - Vector3f max = new Vector3f(5, 5, 5); - Vector3f min = new Vector3f(-5, -5, -5); - - Box box = new Box("Box", min, max); - box.setModelBound(new BoundingBox()); - box.updateModelBound(); - box.setLocalTranslation(new Vector3f(0, 0, -10)); - _geom.attachChild(box); - _geom.updateRenderState(); - } - - protected JmeCanvasTestApp () - { - super(800, 600); - } - - protected void initRoot () - { - super.initRoot(); - } -} diff --git a/tests/src/java/com/threerings/jme/client/JabberApp.java b/tests/src/java/com/threerings/jme/client/JabberApp.java deleted file mode 100644 index 92e165d8..00000000 --- a/tests/src/java/com/threerings/jme/client/JabberApp.java +++ /dev/null @@ -1,161 +0,0 @@ -// -// $Id: JabberApp.java 3098 2004-08-27 02:12:55Z mdb $ -// -// Narya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://www.threerings.net/code/narya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.client; - -import java.io.InputStream; -import java.io.InputStreamReader; - -import com.jme.bounding.BoundingBox; -import com.jme.math.FastMath; -import com.jme.math.Matrix3f; -import com.jme.math.Vector3f; -import com.jme.renderer.ColorRGBA; -import com.jme.scene.shape.Box; -import com.jme.util.LoggingSystem; -import com.jme.util.geom.BufferUtils; -import com.jmex.bui.BStyleSheet; - -import com.threerings.util.Name; - -import com.threerings.presents.client.Client; -import com.threerings.presents.net.UsernamePasswordCreds; - -import com.threerings.jme.JmeApp; - -import static com.threerings.jme.Log.log; - -/** - * The main point of entry for the Jabber client application. It creates - * and initializes the myriad components of the client and sets all the - * proper wheels in motion. - */ -public class JabberApp extends JmeApp -{ - /** Used to configure our user interface. */ - public static BStyleSheet stylesheet; - - // documentation inherited - public boolean init () - { - if (!super.init()) { - return false; - } - - // initialize our client instance - _client = new JabberClient(); - _client.init(this); - - // add some simple geometry for kicks - Vector3f max = new Vector3f(15, 15, 15); - Vector3f min = new Vector3f(5, 5, 5); - - Box t = new Box("Box", min, max); - t.setModelBound(new BoundingBox()); - t.updateModelBound(); - t.setLocalTranslation(new Vector3f(0, 0, -15)); - ColorRGBA[] colors = new ColorRGBA[24]; - for (int i = 0; i < 24; i++) { - colors[i] = ColorRGBA.randomColor(); - } - t.setColorBuffer(0, BufferUtils.createFloatBuffer(colors)); - _root.attachChild(t); - _root.updateRenderState(); - - // set up the camera - Vector3f loc = new Vector3f(0, -200, 200); - _camera.setLocation(loc); - Matrix3f rotm = new Matrix3f(); - rotm.fromAngleAxis(-FastMath.PI/5, _camera.getLeft()); - rotm.mult(_camera.getDirection(), _camera.getDirection()); - rotm.mult(_camera.getUp(), _camera.getUp()); - rotm.mult(_camera.getLeft(), _camera.getLeft()); - _camera.update(); - - // speed up key input - _input.setActionSpeed(100f); - - return true; - } - - public void run (String server, String username, String password) - { - Client client = _client.getContext().getClient(); - - // pass them on to the client - log.info("Using [server=" + server + "."); - client.setServer(server, Client.DEFAULT_SERVER_PORTS); - - // configure the client with some credentials and logon - if (username != null && password != null) { - // create and set our credentials - client.setCredentials( - new UsernamePasswordCreds(new Name(username), password)); - client.logon(); - } - - // now start up the main event loop - run(); - } - - // documentation inherited - public void stop () - { - // log off before we shutdown - Client client = _client.getContext().getClient(); - if (client.isLoggedOn()) { - client.logoff(false); - } - log.info("Stopping."); - super.stop(); - } - - public static void main (String[] args) - { - LoggingSystem.getLogger().setLevel(java.util.logging.Level.OFF); - - String server = "localhost"; - if (args.length > 0) { - server = args[0]; - } - - // load up the default BUI stylesheet - try { - InputStream stin = JabberApp.class.getClassLoader(). - getResourceAsStream("rsrc/style.bss"); - stylesheet = new BStyleSheet( - new InputStreamReader(stin), - new BStyleSheet.DefaultResourceProvider()); - } catch (Exception e) { - e.printStackTrace(System.err); - System.exit(-1); - } - - String username = (args.length > 1) ? args[1] : null; - String password = (args.length > 2) ? args[2] : null; - - JabberApp app = new JabberApp(); - app.init(); - app.run(server, username, password); - } - - protected JabberClient _client; -} diff --git a/tests/src/java/com/threerings/jme/client/JabberClient.java b/tests/src/java/com/threerings/jme/client/JabberClient.java deleted file mode 100644 index 67052121..00000000 --- a/tests/src/java/com/threerings/jme/client/JabberClient.java +++ /dev/null @@ -1,238 +0,0 @@ -// -// $Id: JabberClient.java 3283 2004-12-22 19:23:00Z ray $ -// -// Narya library - tools for developing networked games -// Copyright (C) 2002-2010 Three Rings Design, Inc., All Rights Reserved -// http://www.threerings.net/code/narya/ -// -// This library is free software; you can redistribute it and/or modify it -// under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 2.1 of the License, or -// (at your option) any later version. -// -// This library 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 -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package com.threerings.jme.client; - -import com.jmex.bui.BRootNode; -import com.jme.input.InputHandler; -import com.jme.renderer.Renderer; -import com.jme.scene.Node; -import com.jme.system.DisplaySystem; - -import com.samskivert.util.Config; -import com.threerings.util.MessageManager; - -import com.threerings.presents.client.Client; -import com.threerings.presents.client.SessionObserver; -import com.threerings.presents.dobj.DObjectManager; - -import com.threerings.crowd.chat.client.ChatDirector; -import com.threerings.crowd.client.LocationDirector; -import com.threerings.crowd.client.OccupantDirector; -import com.threerings.crowd.client.PlaceView; -import com.threerings.crowd.util.CrowdContext; - -import com.threerings.jme.JmeContext; -import com.threerings.jme.camera.CameraHandler; - -/** - * The Jabber client takes care of instantiating all of the proper - * managers and loading up all of the necessary configuration and getting - * the client bootstrapped. It can be extended by games that require an - * extended context implementation. - */ -public class JabberClient - implements SessionObserver -{ - /** - * Initializes a new client and provides it with a frame in which to - * display everything. - */ - public void init (JabberApp app) - { - _app = app; - - // create our context - _ctx = createContextImpl(); - - // create the directors/managers/etc. provided by the context - createContextServices(app); - - // for test purposes, hardcode the server info - _client.setServer("localhost", Client.DEFAULT_SERVER_PORTS); - _client.addClientObserver(this); - } - - /** - * Returns a reference to the context in effect for this client. This - * reference is valid for the lifetime of the application. - */ - public CrowdContext getContext () - { - return _ctx; - } - - // documentation inherited from interface SessionObserver - public void clientWillLogon (Client client) - { - // nada - } - - // documentation inherited from interface SessionObserver - public void clientDidLogon (Client client) - { - // enter the one and only chat room; giant hack warning: we know - // that the place we're headed to is ID 2 because there's only one - // place on the whole server; a normal client would either issue - // an invocation service request at this point or look at - // something in the BootstrapData to figure out what to do - _ctx.getLocationDirector().moveTo(2); - } - - // documentation inherited from interface SessionObserver - public void clientObjectDidChange (Client client) - { - // nada - } - - // documentation inherited from interface SessionObserver - public void clientDidLogoff (Client client) - { - System.exit(0); - } - - /** - * Creates the {@link JabberContext} implementation that will be - * passed around to all of the client code. Derived classes may wish - * to override this and create some extended context implementation. - */ - protected CrowdContext createContextImpl () - { - return new JabberContextImpl(); - } - - /** - * Creates and initializes the various services that are provided by - * the context. Derived classes that provide an extended context - * should override this method and create their own extended - * services. They should be sure to call - * super.createContextServices. - */ - protected void createContextServices (JabberApp app) - { - // create the handles on our various services - _client = new Client(null, app); - - // create our managers and directors - _locdir = new LocationDirector(_ctx); - _occdir = new OccupantDirector(_ctx); - _msgmgr = new MessageManager(MESSAGE_MANAGER_PREFIX); - _chatdir = new ChatDirector(_ctx, null); - } - - /** - * The context implementation. This provides access to all of the - * objects and services that are needed by the operating client. - */ - protected class JabberContextImpl implements CrowdContext, JmeContext - { - /** - * Apparently the default constructor has default access, rather - * than protected access, even though this class is declared to be - * protected. Why, I don't know, but we need to be able to extend - * this class elsewhere, so we need this. - */ - protected JabberContextImpl () { - } - - public Client getClient () { - return _client; - } - - public DObjectManager getDObjectManager () { - return _client.getDObjectManager(); - } - - public Config getConfig () { - return _config; - } - - public LocationDirector getLocationDirector () { - return _locdir; - } - - public OccupantDirector getOccupantDirector () { - return _occdir; - } - - public ChatDirector getChatDirector () { - return _chatdir; - } - - public MessageManager getMessageManager () { - return _msgmgr; - } - - public void setPlaceView (PlaceView view) { - // TBD - } - - public void clearPlaceView (PlaceView view) { - // we'll just let the next place view replace our old one - } - - public Renderer getRenderer () { - return _app.getContext().getRenderer(); - } - - public DisplaySystem getDisplay () { - return _app.getContext().getDisplay(); - } - - public CameraHandler getCameraHandler () { - return _app.getContext().getCameraHandler(); - } - - public Node getGeometry () { - return _app.getContext().getGeometry(); - } - - public Node getInterface () { - return _app.getContext().getInterface(); - } - - public InputHandler getInputHandler () { - return _app.getContext().getInputHandler(); - } - -// public InputHandler getBufferedInputHandler () { -// return _app.getContext().getBufferedInputHandler(); -// } - - public BRootNode getRootNode () { - return _app.getContext().getRootNode(); - } - } - - protected CrowdContext _ctx; - protected JabberApp _app; - protected Config _config = new Config("jabber"); - - protected Client _client; - protected LocationDirector _locdir; - protected OccupantDirector _occdir; - protected ChatDirector _chatdir; - protected MessageManager _msgmgr; - - /** The prefix prepended to localization bundle names before looking - * them up in the classpath. */ - protected static final String MESSAGE_MANAGER_PREFIX = "rsrc.i18n"; -} diff --git a/tests/src/java/com/threerings/jme/client/JabberController.java b/tests/src/java/com/threerings/jme/client/JabberController.java deleted file mode 100644 index 329381b6..00000000 --- a/tests/src/java/com/threerings/jme/client/JabberController.java +++ /dev/null @@ -1,19 +0,0 @@ -// -// $Id$ - -package com.threerings.jme.client; - -import com.threerings.crowd.client.PlaceController; -import com.threerings.crowd.client.PlaceView; -import com.threerings.crowd.util.CrowdContext; - -/** - * Handles the basic bits for our simple chat room. - */ -public class JabberController extends PlaceController -{ - protected PlaceView createPlaceView (CrowdContext ctx) - { - return new JabberView(ctx); - } -} diff --git a/tests/src/java/com/threerings/jme/client/JabberView.java b/tests/src/java/com/threerings/jme/client/JabberView.java deleted file mode 100644 index 26fc814e..00000000 --- a/tests/src/java/com/threerings/jme/client/JabberView.java +++ /dev/null @@ -1,50 +0,0 @@ -// -// $Id$ - -package com.threerings.jme.client; - -import com.jmex.bui.BWindow; -import com.jmex.bui.layout.BorderLayout; - -import com.threerings.crowd.client.PlaceView; -import com.threerings.crowd.data.PlaceObject; -import com.threerings.crowd.util.CrowdContext; - -import com.threerings.jme.JmeContext; -import com.threerings.jme.chat.ChatView; - -/** - * Manages the "view" when we're in the chat room. - */ -public class JabberView extends BWindow - implements PlaceView -{ - public JabberView (CrowdContext ctx) - { - super(JabberApp.stylesheet, new BorderLayout()); - - _ctx = ctx; - _jctx = (JmeContext)ctx; - _chat = new ChatView(_jctx, _ctx.getChatDirector()); - add(_chat, BorderLayout.CENTER); - - _jctx.getRootNode().addWindow(this); - setBounds(0, 40, 640, 240); - } - - // documentation inherited from interface PlaceView - public void willEnterPlace (PlaceObject plobj) - { - _chat.willEnterPlace(plobj); - } - - // documentation inherited from interface PlaceView - public void didLeavePlace (PlaceObject plobj) - { - _chat.didLeavePlace(plobj); - } - - protected CrowdContext _ctx; - protected JmeContext _jctx; - protected ChatView _chat; -} diff --git a/tests/src/java/com/threerings/jme/data/JabberConfig.java b/tests/src/java/com/threerings/jme/data/JabberConfig.java deleted file mode 100644 index 1b5c11da..00000000 --- a/tests/src/java/com/threerings/jme/data/JabberConfig.java +++ /dev/null @@ -1,27 +0,0 @@ -// -// $Id$ - -package com.threerings.jme.data; - -import com.threerings.crowd.client.PlaceController; -import com.threerings.crowd.data.PlaceConfig; -import com.threerings.jme.client.JabberController; - -/** - * Defines the necessary bits for our chat room. - */ -public class JabberConfig extends PlaceConfig -{ - // documentation inherited - public PlaceController createController () - { - return new JabberController(); - } - - // documentation inherited - public String getManagerClassName () - { - // nothing special needed on the server side - return "com.threerings.crowd.server.PlaceManager"; - } -} diff --git a/tests/src/java/com/threerings/jme/server/JabberServer.java b/tests/src/java/com/threerings/jme/server/JabberServer.java deleted file mode 100644 index 5d73798c..00000000 --- a/tests/src/java/com/threerings/jme/server/JabberServer.java +++ /dev/null @@ -1,46 +0,0 @@ -// -// $Id$ - -package com.threerings.jme.server; - -import com.google.inject.Guice; -import com.google.inject.Injector; - -import com.threerings.crowd.server.CrowdServer; -import com.threerings.crowd.server.PlaceManager; - -import com.threerings.jme.data.JabberConfig; - -import static com.threerings.crowd.Log.log; - -/** - * A basic server that creates a single room and sticks everyone in it where they can chat with one - * another. - */ -public class JabberServer extends CrowdServer -{ - @Override // from CrowdServer - public void init (Injector injector) - throws Exception - { - super.init(injector); - - // create a single location - _place = _plreg.createPlace(new JabberConfig()); - log.info("Created chat room " + _place.where() + "."); - } - - public static void main (String[] args) - { - Injector injector = Guice.createInjector(new Module()); - JabberServer server = injector.getInstance(JabberServer.class); - try { - server.init(injector); - server.run(); - } catch (Exception e) { - log.warning("Unable to initialize server.", e); - } - } - - protected PlaceManager _place; -} diff --git a/tests/src/java/com/threerings/jme/sprite/PathTestApp.java b/tests/src/java/com/threerings/jme/sprite/PathTestApp.java deleted file mode 100644 index cda54240..00000000 --- a/tests/src/java/com/threerings/jme/sprite/PathTestApp.java +++ /dev/null @@ -1,149 +0,0 @@ -// -// $Id$ - -package com.threerings.jme.sprite; - -import java.util.Arrays; -import java.util.logging.Level; - -import com.jme.math.FastMath; -import com.jme.math.Matrix3f; -import com.jme.math.Quaternion; -import com.jme.math.Vector3f; -import com.jme.renderer.ColorRGBA; -import com.jme.scene.shape.Box; -import com.jme.scene.shape.Disk; -import com.jme.scene.shape.Quad; -import com.jme.scene.state.LightState; -import com.jme.util.LoggingSystem; - -import com.threerings.jme.JmeApp; -import com.threerings.jme.sprite.LineSegmentPath; - -/** - * Used for testing paths. - */ -public class PathTestApp extends JmeApp -{ - protected void initRoot () - { - super.initRoot(); - - float dist = 10; - - // set up the camera - Vector3f loc = new Vector3f(0, -dist, 10); - _camera.setLocation(loc); - Matrix3f rotm = new Matrix3f(); - rotm.fromAngleAxis(-FastMath.PI/4, _camera.getLeft()); - rotm.multLocal(_camera.getDirection()); - rotm.multLocal(_camera.getUp()); - rotm.multLocal(_camera.getLeft()); - _camera.update(); - - for (int yy = -1; yy < 1; yy++) { - for (int xx = -1; xx < 1; xx++) { - Quad quad = new Quad("ground", 10, 10); - quad.setLightCombineMode(LightState.OFF); - int index = (yy+1)*2 + (xx+1); - quad.setSolidColor(COLORS[index]); - quad.setLocalTranslation( - new Vector3f(xx * 10 + 5, yy * 10 + 5, -1)); - _geom.attachChild(quad); - } - } - - for (int yy = -1; yy <= 1; yy++) { - for (int xx = -1; xx <= 1; xx++) { - if (xx != 0 || yy != 0) { - setup(xx * dist, yy * dist); - } - } - } - } - - protected void setup (float x, float y) - { - Box target = new Box("target", new Vector3f(-.1f, -.1f, -.1f), - new Vector3f(.1f, .1f, .1f)); - target.setLocalTranslation(new Vector3f(x, y, 0)); - _geom.attachChild(target); - - Box box = new Box("box", new Vector3f(-1, -0.5f, -0.25f), - new Vector3f(1, 0.5f, 0.25f)); - Disk disk = new Disk("dot", 10, 10, 0.5f); - disk.setLightCombineMode(LightState.OFF); - disk.setLocalTranslation(new Vector3f(0.5f, 0f, 0.3f)); - Sprite shot = new Sprite(); - shot.attachChild(box); - shot.attachChild(disk); - _geom.attachChild(shot); - - testBallistic(shot, target); -// testLineSegment(shot); - } - - protected void testBallistic (Sprite shot, Box target) - { - // start with the "cannon" pointed along the x axis - Vector3f diff = target.getLocalTranslation().subtract( - shot.getLocalTranslation()); - Vector3f vel = diff.normalize(); - float range = diff.length(), angle = -FastMath.PI/4; - - Vector3f axis = UP.cross(vel); - axis.normalizeLocal(); - - // rotate it up (around the y axis) the necessary elevation - Quaternion rot = new Quaternion(); - rot.fromAngleAxis(angle, axis); - rot.multLocal(vel); - - // give the cannon its muzzle velocity - float muzvel = FastMath.sqrt(range * BallisticPath.G / - FastMath.sin(2*angle)); - vel.multLocal(muzvel); - - Vector3f start = new Vector3f(0, 0, 0); - float time = BallisticPath.computeFlightTime(range, muzvel, angle); - shot.move(new OrientingBallisticPath( - shot, new Vector3f(1, 0, 0), start, vel, GRAVITY, time)); - - System.out.println("Range: " + range); - System.out.println("Muzzle velocity: " + muzvel); - System.out.println("Rotation axis: " + axis); - System.out.println("Angle: " + angle + " (" + - (angle * 180 / FastMath.PI) + ")"); - System.out.println("Flight time: " + time); - System.out.println("Velocity: " + vel); - } - - protected void testLineSegment (Sprite shot) - { - Vector3f[] points = new Vector3f[] { - new Vector3f(0, 0, 0), new Vector3f(2, 0, 0), new Vector3f(3, 0, 0), - new Vector3f(3, 2, 0), new Vector3f(5, 2, 0), new Vector3f(5, -2, 0), - new Vector3f(-4, -2, 0) - }; - float[] durations = new float[points.length]; - Arrays.fill(durations, 1f); - Vector3f up = new Vector3f(0, 0, 1); - Vector3f orient = new Vector3f(1, 0, 0); - shot.move(new LineSegmentPath(shot, up, orient, points, durations)); - } - - public static void main (String[] args) - { - LoggingSystem.getLogger().setLevel(Level.OFF); - PathTestApp test = new PathTestApp(); - if (!test.init()) { - System.exit(-1); - } - test.run(); - } - - protected static final Vector3f GRAVITY = new Vector3f(0, 0, -9.8f); - protected static final Vector3f UP = new Vector3f(0, 0, 1); - protected static final ColorRGBA[] COLORS = { - ColorRGBA.red, ColorRGBA.green, ColorRGBA.blue, ColorRGBA.gray }; -}