Revision: 485 http://skycastle.svn.sourceforge.net/skycastle/?rev=485&view=rev Author: zzorn Date: 2008-04-26 17:02:04 -0700 (Sat, 26 Apr 2008) Log Message: ----------- Working on adding input support. Modified Paths: -------------- trunk/skycastle/modules/ui/src/main/java/org/skycastle/opengl/Canvas3D.java trunk/skycastle/modules/ui/src/main/java/org/skycastle/opengl/navigationgestures/AbstractNavigationGesture.java trunk/skycastle/modules/ui/src/main/java/org/skycastle/opengl/navigationgestures/NavigationGesture.java trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchController.java trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchView.java trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SkycastleSketch.java trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/StrokeRenderer.java Added Paths: ----------- trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/StrokeTool.java trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/old/ trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/old/JPenExample.java trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/old/Sketch3DUI.java Removed Paths: ------------- trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/PenInput.java trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/Sketch3DUI.java trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchRenderer.java trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchToolbarFactory.java Modified: trunk/skycastle/modules/ui/src/main/java/org/skycastle/opengl/Canvas3D.java =================================================================== --- trunk/skycastle/modules/ui/src/main/java/org/skycastle/opengl/Canvas3D.java 2008-04-26 20:42:11 UTC (rev 484) +++ trunk/skycastle/modules/ui/src/main/java/org/skycastle/opengl/Canvas3D.java 2008-04-27 00:02:04 UTC (rev 485) @@ -1,12 +1,14 @@ package org.skycastle.opengl; import com.jme.renderer.Camera; +import com.jme.renderer.ColorRGBA; import com.jme.renderer.Renderer; import com.jme.scene.Spatial; import com.jme.scene.state.CullState; import com.jme.system.DisplaySystem; import com.jmex.awt.JMECanvas; import com.jmex.awt.SimpleCanvasImpl; +import jpen.PenManager; import org.skycastle.opengl.navigationgestures.*; import org.skycastle.util.ParameterChecker; import org.skycastle.util.cursor.CursorChangerImpl; @@ -14,6 +16,7 @@ import javax.swing.*; import java.awt.Canvas; +import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.event.ComponentAdapter; @@ -24,7 +27,8 @@ /** * A 3D Canvas, showing a 3D object in an AWT Canvas component. * <p/> - * Allows registering Gestures, that can be used to navigate the 3D view (already has default gestures registered). + * Allows registering Gestures, that can be used to navigate the 3D view (already has default gestures + * registered). * <p/> * Also allows adding FrameListeners, that are called after each rendering frame in the swing thread. * @@ -37,6 +41,7 @@ //====================================================================== // Private Fields + private final ColorRGBA myBackgroundColor = new ColorRGBA(); private final Set<NavigationGesture> myNavigationGestures = new HashSet<NavigationGesture>(); private final CursorChangerImpl myCursorChanger = new CursorChangerImpl(); private final FpsCounter myFpsCounter = new FpsCounter(); @@ -113,7 +118,8 @@ /** * TODO: CHECK: Are the units meters? * - * @return distance in screen units to the far clipping plane - 3D geometry beyond this distance is not shown. + * @return distance in screen units to the far clipping plane - 3D geometry beyond this distance is not + * shown. */ public float getViewDistance() { @@ -124,7 +130,8 @@ /** * TODO: CHECK: Are the units meters? * - * @param viewDistance distance in screen units to the far clipping plane - 3D geometry beyond this distance is not shown. + * @param viewDistance distance in screen units to the far clipping plane - 3D geometry beyond this + * distance is not shown. */ public void setViewDistance( final float viewDistance ) { @@ -160,7 +167,8 @@ /** - * Adds the specified FrameListener. The listener is called after each frame is rendered in the swing thread. + * Adds the specified FrameListener. The listener is called after each frame is rendered in the swing + * thread. * * @param addedFrameListener should not be null or already added. */ @@ -191,8 +199,8 @@ /** - * @return the number of frames rendered per second, - * or a negative value if the canvas has not yet been rendered. + * @return the number of frames rendered per second, or a negative value if the canvas has not yet been + * rendered. */ public double getFramesPerSecond() { @@ -201,8 +209,8 @@ /** - * @return number of seconds between the previous frame and the frame before that, - * or a negative value if the canvas has not yet been rendered. + * @return number of seconds between the previous frame and the frame before that, or a negative value if + * the canvas has not yet been rendered. */ public double getSecondsBetweenFrames() { @@ -253,6 +261,7 @@ registerNavigationGestureListener( addedNavigationGesture ); } + private PenManager myPenManager; /** * @param removedNavigationGesture gesture to remove. @@ -283,6 +292,20 @@ } } + + /** + * Should be called before the canvas is initiated for it to take effect. + * + * @param color the background color to use for the {@link Canvas3D}. + */ + public void setBackgroundColor( final Color color ) + { + myBackgroundColor.set( color.getRed() / 255.0f, + color.getGreen() / 255.0f, + color.getBlue() / 255.0f, + color.getAlpha() / 255.0f ); + } + //====================================================================== // Private Methods @@ -291,6 +314,7 @@ if ( myCanvas != null ) { navigationGesture.init( myCanvas, myCursorChanger, myCameraAccessor ); + myPenManager.pen.addListener( navigationGesture ); } } @@ -319,8 +343,11 @@ myCanvasRenderer = new MyCanvasRenderer( width, height, my3DNode, myCanvas ); jmeCanvas.setImplementor( myCanvasRenderer ); + // Listen to tablet pen movement over the canvas + myPenManager = new PenManager( myCanvas ); + // Add navigation gesture listeners to the created 3D canvas - for ( NavigationGesture navigationGesture : myNavigationGestures ) + for ( final NavigationGesture navigationGesture : myNavigationGestures ) { registerNavigationGestureListener( navigationGesture ); } @@ -427,8 +454,8 @@ * * @param width initial size of the canvas. Should be larger than 0. * @param height initial size of the canvas. Should be larger than 0. - * @param canvasRootNode the 3D object to render. - * May be null, in which case nothing is rendered (black area) + * @param canvasRootNode the 3D object to render. May be null, in which case nothing is rendered + * (black area) * @param canvas the canvas we are rendering to. Needed for listening to resize events. */ public MyCanvasRenderer( final int width, @@ -462,8 +489,8 @@ // Other Public Methods /** - * @return the number of frames rendered per second, - * or a negative value if the canvas has not yet been rendered. + * @return the number of frames rendered per second, or a negative value if the canvas has not yet + * been rendered. */ public double getFramesPerSecond() { @@ -472,8 +499,8 @@ /** - * @return number of seconds between the previous frame and the frame before that, - * or a negative value if the canvas has not yet been rendered. + * @return number of seconds between the previous frame and the frame before that, or a negative value + * if the canvas has not yet been rendered. */ public double getSecondsBetweenFrames() { @@ -482,8 +509,8 @@ /** - * @param canvasRootNode the spatial to render with this CanvasRenderer. - * May be null, in which case nothing is rendered (black area) + * @param canvasRootNode the spatial to render with this CanvasRenderer. May be null, in which case + * nothing is rendered (black area) */ public void setCanvasRootNode( final Spatial canvasRootNode ) { @@ -517,6 +544,9 @@ } getCamera().setFrustumFar( myViewDistance ); + + // Set the background color + getRenderer().setBackgroundColor( myBackgroundColor ); } Modified: trunk/skycastle/modules/ui/src/main/java/org/skycastle/opengl/navigationgestures/AbstractNavigationGesture.java =================================================================== --- trunk/skycastle/modules/ui/src/main/java/org/skycastle/opengl/navigationgestures/AbstractNavigationGesture.java 2008-04-26 20:42:11 UTC (rev 484) +++ trunk/skycastle/modules/ui/src/main/java/org/skycastle/opengl/navigationgestures/AbstractNavigationGesture.java 2008-04-27 00:02:04 UTC (rev 485) @@ -2,6 +2,10 @@ import com.jme.math.Vector3f; import com.jme.renderer.Camera; +import jpen.PButtonEvent; +import jpen.PKindEvent; +import jpen.PLevelEvent; +import jpen.PScrollEvent; import org.skycastle.util.cursor.CursorChanger; import javax.swing.event.MouseInputAdapter; @@ -65,6 +69,34 @@ } //---------------------------------------------------------------------- + // PenListener Implementation + + + public void penKindEvent( final PKindEvent ev ) + { + } + + + public void penLevelEvent( final PLevelEvent ev ) + { + } + + + public void penButtonEvent( final PButtonEvent ev ) + { + } + + + public void penScrollEvent( final PScrollEvent ev ) + { + } + + + public void penTock( final long availableMillis ) + { + } + + //---------------------------------------------------------------------- // Other Public Methods /** @@ -95,6 +127,7 @@ mySensitivity = sensitivity; } + /** * Moves the mouse position to the specified canvas coordinates */ @@ -106,7 +139,8 @@ /** - * @return an interface that can be used to change the mouse cursor on the 3D canvas we are rendering to (or hide it). + * @return an interface that can be used to change the mouse cursor on the 3D canvas we are rendering to + * (or hide it). */ protected final CursorChanger getCursorChanger() { @@ -126,7 +160,8 @@ /** - * @return the camera that has been assigned to this navigation gesture listener, or null if no camera has yet been assigned. + * @return the camera that has been assigned to this navigation gesture listener, or null if no camera has + * yet been assigned. */ protected final Camera getCamera() { @@ -142,7 +177,8 @@ /** - * @return a multiplication factor calculated from the altitude, used to adjust the move and pan operations. + * @return a multiplication factor calculated from the altitude, used to adjust the move and pan + * operations. */ protected final float getAltitudeFactor() { @@ -174,8 +210,9 @@ * * @param location A location to calculate the altitude of. * - * @return the altitude of the specified location above the ground. The accuracy can be calculated relative to the altitude, - * if the location is closer to the ground, higher accuracy is used than if it is further from the ground. + * @return the altitude of the specified location above the ground. The accuracy can be calculated + * relative to the altitude, if the location is closer to the ground, higher accuracy is used than + * if it is further from the ground. */ private float getAltitudeAt( final Vector3f location ) { @@ -187,8 +224,9 @@ * REFACTOR: Move to some terrain or map class and make public. * * @param location some location in the world. Usually only the x and y values are used, z is ignored. - * The z value can be used to determine the accuracy to calculate the terrain height at. If the location is far above (or below) the ground, - * less accuracy is needed, while if it is close to the ground, greater accuracy is needed. + * The z value can be used to determine the accuracy to calculate the terrain height at. + * If the location is far above (or below) the ground, less accuracy is needed, while if + * it is close to the ground, greater accuracy is needed. * * @return the terrain height at the specified location. */ Modified: trunk/skycastle/modules/ui/src/main/java/org/skycastle/opengl/navigationgestures/NavigationGesture.java =================================================================== --- trunk/skycastle/modules/ui/src/main/java/org/skycastle/opengl/navigationgestures/NavigationGesture.java 2008-04-26 20:42:11 UTC (rev 484) +++ trunk/skycastle/modules/ui/src/main/java/org/skycastle/opengl/navigationgestures/NavigationGesture.java 2008-04-27 00:02:04 UTC (rev 485) @@ -1,6 +1,7 @@ package org.skycastle.opengl.navigationgestures; +import jpen.event.PenListener; import org.skycastle.util.cursor.CursorChanger; import javax.swing.event.MouseInputListener; @@ -13,24 +14,27 @@ * @author Hans H�ggstr�m */ public interface NavigationGesture - extends MouseInputListener, MouseWheelListener + extends MouseInputListener, MouseWheelListener, PenListener { /** * Initializes the navigation gesture. * - * @param component the component that the gesture should listen to. Can be asked e.g. the size and position. - * Might also be used to add rubber band graphics or similar on top of the component - * @param cursorChanger an interface that can be used to change the mouse cursor on the 3D canvas rendered to. - * @param cameraAccessor Can be asked for the camera that the navigation gesture listener should modify when gestures happen. + * @param component the component that the gesture should listen to. Can be asked e.g. the size and + * position. Might also be used to add rubber band graphics or similar on top of the + * component + * @param cursorChanger an interface that can be used to change the mouse cursor on the 3D canvas + * rendered to. + * @param cameraAccessor Can be asked for the camera that the navigation gesture listener should modify + * when gestures happen. */ void init( Component component, CursorChanger cursorChanger, CameraAccessor cameraAccessor ); /** - * De-initializes the navigation gesture. The navigation gesture should stop listening to the component, and should - * remove its cursor settings. + * De-initializes the navigation gesture. The navigation gesture should stop listening to the component, + * and should remove its cursor settings. */ void deInit(); Deleted: trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/PenInput.java =================================================================== --- trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/PenInput.java 2008-04-26 20:42:11 UTC (rev 484) +++ trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/PenInput.java 2008-04-27 00:02:04 UTC (rev 485) @@ -1,75 +0,0 @@ -package org.skycastle.sketch; - -import jpen.*; -import jpen.event.PenListener; - -import javax.swing.*; - -/** - * @author Hans Haggstrom - */ -public class PenInput - implements PenListener -{ - - //---------------------------------------------------------------------- - // Main Method - - public static void main( String... args ) - { - new PenInput(); - } - - //---------------------------------------------------------------------- - // Constructors - - PenInput() - { - JLabel l = new JLabel( "Move the pen or mouse over me!" ); - PenManager pm = new PenManager( l ); - pm.pen.addListener( this ); - - JFrame f = new JFrame( "JPen Example" ); - f.getContentPane().add( l ); - f.setSize( 300, 300 ); - f.setVisible( true ); - } - - //---------------------------------------------------------------------- - // PenListener Implementation - - @Override - public void penKindEvent( PKindEvent - ev ) - { - System.out.println( ev ); - } - - @Override - public void penLevelEvent( PLevelEvent - ev ) - { - System.out.println( ev ); - } - - @Override - public void penButtonEvent( PButtonEvent - ev ) - { - System.out.println( ev ); - } - - @Override - public void penScrollEvent( PScrollEvent - ev ) - { - System.out.println( ev ); - } - - @Override - public void penTock( long availableMillis ) - { - System.out.println( "TOCK - available period fraction: " + availableMillis ); - } - -} Deleted: trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/Sketch3DUI.java =================================================================== --- trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/Sketch3DUI.java 2008-04-26 20:42:11 UTC (rev 484) +++ trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/Sketch3DUI.java 2008-04-27 00:02:04 UTC (rev 485) @@ -1,279 +0,0 @@ -package org.skycastle.sketch; - -import com.jme.app.SimpleGame; -import com.jme.bounding.BoundingBox; -import com.jme.image.Texture; -import com.jme.input.*; -import com.jme.math.Vector3f; -import com.jme.renderer.ColorRGBA; -import com.jme.renderer.Renderer; -import com.jme.scene.Controller; -import com.jme.scene.Node; -import com.jme.scene.SceneElement; -import com.jme.scene.shape.Box; -import com.jme.scene.state.LightState; -import com.jme.scene.state.TextureState; -import com.jme.util.TextureManager; -import com.jmex.awt.swingui.JMEDesktop; - -import javax.swing.*; -import javax.swing.plaf.basic.BasicInternalFrameUI; -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Container; -import java.beans.PropertyVetoException; -import java.util.logging.Logger; - -/** - * OpenGL main loop for the sketch program. - * - * @author Hans Haggstrom - */ -@SuppressWarnings( { "MagicNumber" } ) -public class Sketch3DUI - extends SimpleGame -{ - - //====================================================================== - // Private Fields - - /** - * Keyboard look input handler. - */ - private KeyboardLookHandler lookHandler = null; - - /** - * Scene node for the GUI. - */ - private Node guiNode = null; - - /** - * JME desktop on which the GUI will be shown. - */ - private JMEDesktop desktop = null; - - //====================================================================== - // Non-Private Fields - - /** - * The color to be used as background color for the desktop. This is completely transparent right now. - */ - protected static final Color DESKTOP_BACKGROUND_COLOR = new Color( 0.5f, 0.5f, 0.5f, 0.0f ); - - //====================================================================== - // Private Constants - - private static final Logger LOGGER = Logger.getLogger( Sketch3DUI.class.getName() ); - - //====================================================================== - // Public Methods - - //---------------------------------------------------------------------- - // Other Public Methods - - /** - * Set up key bindings. - */ - public void initKeyBindings() - { - /* Remove some keybindings established by BaseSimpleGame, since they - are needed for chatting. - TODO: Find a more elegant solution. Maybe bind/rebind depending on - focus, or handling these during update. - Eventually, we may also need to implement our own base game - class. - */ - KeyBindingManager.getKeyBindingManager().remove( "toggle_pause" ); - KeyBindingManager.getKeyBindingManager().remove( "step" ); - KeyBindingManager.getKeyBindingManager().remove( "toggle_wire" ); - KeyBindingManager.getKeyBindingManager().remove( "toggle_lights" ); - KeyBindingManager.getKeyBindingManager().remove( "toggle_bounds" ); - KeyBindingManager.getKeyBindingManager().remove( "toggle_normals" ); - KeyBindingManager.getKeyBindingManager().remove( "camera_out" ); - KeyBindingManager.getKeyBindingManager().remove( "mem_report" ); - - // Bind the BaseSimpleGame functions to other keys. - KeyBindingManager.getKeyBindingManager().set( "toggle_pause", KeyInput.KEY_F4 ); - KeyBindingManager.getKeyBindingManager().set( "step", KeyInput.KEY_F5 ); - KeyBindingManager.getKeyBindingManager().set( "toggle_wire", KeyInput.KEY_F6 ); - KeyBindingManager.getKeyBindingManager().set( "toggle_lights", KeyInput.KEY_F7 ); - KeyBindingManager.getKeyBindingManager().set( "toggle_bounds", KeyInput.KEY_F8 ); - KeyBindingManager.getKeyBindingManager().set( "toggle_normals", KeyInput.KEY_F9 ); - KeyBindingManager.getKeyBindingManager().set( "camera_out", KeyInput.KEY_F10 ); - KeyBindingManager.getKeyBindingManager().set( "mem_report", KeyInput.KEY_F11 ); - } - - //====================================================================== - // Protected Methods - - /** - * Create the UI. Create the elements of the Swing UI. - */ - protected void initUI() - { - /// JME part of the GUI creation. - guiNode = new Node( "gui" ); - guiNode.setRenderQueueMode( Renderer.QUEUE_ORTHO ); - - desktop = new JMEDesktop( - "desktop", - display.getWidth(), - display.getHeight(), - input - ); - guiNode.attachChild( desktop ); - desktop.getLocalTranslation().set( - display.getWidth() / 2.0f, - display.getHeight() / 2.0f, 0 - ); - - // AWT/Swing part of the GUI creation. - desktop.getJDesktop().setBackground( DESKTOP_BACKGROUND_COLOR ); - - - JInternalFrame toolFrame = new JInternalFrame(); -// toolFrame.setLocation( 10, 10 ); -// toolFrame.setResizable( true ); - - toolFrame.setOpaque( false ); - Container contentPane = toolFrame.getContentPane(); - contentPane.setLayout( new BorderLayout() ); - contentPane.setBackground( new Color( 0, 0, 0, 0 ) ); - - contentPane.add( new JLabel( "foo" ), BorderLayout.EAST ); - contentPane.add( createNorthPanel(), BorderLayout.NORTH ); - - toolFrame.setBorder( BorderFactory.createEmptyBorder() ); - toolFrame.setTitle( null ); - - toolFrame.setVisible( true ); - toolFrame.pack(); - - final BasicInternalFrameUI basicInternalFrameUI = (BasicInternalFrameUI) toolFrame.getUI(); - basicInternalFrameUI.setNorthPane( null ); - - desktop.getJDesktop().add( toolFrame ); - -/* - toolFrame.putClientProperty( ); - - a) internalFrame.putClientProperty("JInternalFrame.isPalette", Boolean.TRUE); -*/ - -/* - final JLabel jLabel = new JLabel( "fooo" ); - - jLabel.setForeground( Color.WHITE ); - jDesktopPane.setLayout( new BorderLayout() ); - jDesktopPane.add( jLabel, BorderLayout.CENTER ); -*/ - try - { - toolFrame.setMaximum( true ); - } - catch ( PropertyVetoException e ) - { - e.printStackTrace(); - } - } - - private JComponent createNorthPanel() - { - SketchToolbarFactory sketchFactory = new SketchToolbarFactory(); - return sketchFactory.createToolbar(); - } - - - /** - * Create the 3D scene. In this case, this is just the rotating box. - */ - protected void create3DScene() - { - final Vector3f axis = new Vector3f( 1, 1, 0.5f ).normalizeLocal(); - final Box box = new Box( "Box", - new Vector3f( -5, -5, -5 ), - new Vector3f( 5, 5, 5 ) ); - - box.setModelBound( new BoundingBox() ); - box.updateModelBound(); - box.setLocalTranslation( new Vector3f( 0, 0, -10 ) ); - box.setLightCombineMode( LightState.OFF ); - - TextureState ts = display.getRenderer().createTextureState(); - ts.setEnabled( true ); - ts.setTexture( TextureManager.loadTexture( - Sketch3DUI.class.getClassLoader().getResource( - "org/skycastle/client/data/skycastle.png" ), - Texture.MM_LINEAR, - Texture.FM_LINEAR ) - ); - box.setRenderState( ts ); - box.addController( - // Controller which rotates the box. - new Controller() - { - - private static final long serialVersionUID = 1L; - - @Override - public void update( float time ) - { - box.getLocalRotation().fromAngleNormalAxis( - timer.getTimeInSeconds(), axis ); - } - - } - ); - - rootNode.attachChild( box ); - } - - - /** - * Initialize game. Overridden from SimpleGame. - */ - @Override - protected void simpleInitGame() - { - display.setTitle( "Skycastle 3D Client" ); - display.getRenderer().setBackgroundColor( ColorRGBA.black ); - - // Set up the keyboard look handler. - input = new InputHandler(); - lookHandler = new KeyboardLookHandler( cam, 50, 1 ); - input.addToAttachedHandlers( lookHandler ); - // Some changes to the BaseSimpleGame keyboard bindings. - initKeyBindings(); - - // Set up GUI, static 3D scene and chat client. - initUI(); - create3DScene(); - - // Always show the the GUI. - guiNode.setCullMode( SceneElement.CULL_NEVER ); - guiNode.setLightCombineMode( LightState.OFF ); - guiNode.updateRenderState(); - guiNode.updateGeometricState( 0, true ); - MouseInput.get().setCursorVisible( true ); - } - - - /** - * Update hook. Overridden from SimpleGame. - */ - @Override - protected void simpleUpdate() - { - } - - - /** - * Render hook. Overridden from SimpleGame. - */ - @Override - protected void simpleRender() - { - display.getRenderer().draw( guiNode ); - } - -} Modified: trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchController.java =================================================================== --- trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchController.java 2008-04-26 20:42:11 UTC (rev 484) +++ trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchController.java 2008-04-27 00:02:04 UTC (rev 485) @@ -15,8 +15,8 @@ /** * @author Hans Häggström */ -@SuppressWarnings( { "serial" } ) -public class SketchController +@SuppressWarnings( { "serial", "NonSerializableFieldInSerializableClass" } ) +public final class SketchController { //====================================================================== @@ -56,49 +56,60 @@ }; - private SketchView mySketchView; +/* + private final CommandAction myAddTestStrokeAction = new CommandAction( myCommandStack, + "Test Stroke", + "Add Test Stroke" ) + { - private Sketch mySketch; + private final Group myGroup = mySketch.getRootGroup(); - //====================================================================== - // Private Constants + { + ParameterChecker.checkNotNull( mySketch.getRootGroup(), "group" ); + } - private static final String APP_NAME = "Sketch Room"; - private final CommandAction myAddTestStrokeAction = new CommandAction( myCommandStack, - "Test Stroke", - "Adds a random test stroke to the Sketch" ) - { @Override protected Command createCommand() { - final Stroke testStroke = createTestStroke(); + final Stroke stroke = createTestStroke(); - return new AbstractCommand( "Test Stroke", true ) + return new AbstractCommand( "Stroke", true ) { public void doCommand() { - mySketch.getRootGroup().add( testStroke ); + myGroup.add( stroke ); } + @Override public void undoCommand() { - mySketch.getRootGroup().remove( testStroke ); + myGroup.remove( stroke ); } + }; } + }; +*/ + private SketchView mySketchView; + + private Sketch mySketch; + //====================================================================== + // Private Constants + + private static final String APP_NAME = "Sketch Room"; + private static final Logger LOGGER = Logger.getLogger( SketchController.class.getName() ); + + //====================================================================== // Public Methods //---------------------------------------------------------------------- // Constructors - private static final Logger LOGGER = Logger.getLogger( SketchController.class.getName() ); - - /** * Creates a new {@link org.skycastle.sketch.SketchController}. */ @@ -125,32 +136,51 @@ mySketchView.addMenuAction( "File", myExitAction ); mySketchView.addMenuAction( "Edit", myCommandStack.getUndoAction() ); mySketchView.addMenuAction( "Edit", myCommandStack.getRedoAction() ); +/* mySketchView.addMenuAction( "Debug", myAddTestStrokeAction ); mySketchView.addToolbarAction( myAddTestStrokeAction ); +*/ mySketchView.addToolbarAction( myCommandStack.getUndoAction() ); mySketchView.addToolbarAction( myCommandStack.getRedoAction() ); + mySketchView.addNavigationGesture( new StrokeTool( mySketch.getRootGroup(), myCommandStack ) ); + mySketchView.setSketch( mySketch ); } + //====================================================================== + // Private Methods private Stroke createTestStroke() { final StrokeImpl stroke = new StrokeImpl(); final Random random = new Random(); - float x = (float) ( random.nextGaussian() * 100 ); - float y = (float) ( random.nextGaussian() * 100 ); + float x = (float) ( random.nextGaussian() * 10 ); + float y = (float) ( random.nextGaussian() * 10 ); + float w = (float) ( 1 ); - for ( int i = 0; i < 100; i++ ) + float xv = 0; + float yv = 0; + float wv = 0; + + for ( int i = 0; i < 1000; i++ ) { - x += random.nextGaussian() * 10; - y += random.nextGaussian() * 10; + xv += random.nextGaussian() * 0.1; + yv += random.nextGaussian() * 0.1; + wv += random.nextGaussian() * 0.01; - stroke.addPoint( new StrokePointImpl( x, y ) ); + x += xv; + y += yv; + w += wv; + + final StrokePointImpl strokePoint = new StrokePointImpl( x, y ); + strokePoint.setProperty( "width", w ); + stroke.addPoint( strokePoint ); } return stroke; } + } Deleted: trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchRenderer.java =================================================================== --- trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchRenderer.java 2008-04-26 20:42:11 UTC (rev 484) +++ trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchRenderer.java 2008-04-27 00:02:04 UTC (rev 485) @@ -1,21 +0,0 @@ -package org.skycastle.sketch; - -import org.skycastle.sketch.model.Sketch; - -/** - * Helps with rendering a {@link Sketch}. - * - * @author Hans Häggström - */ -public class SketchRenderer -{ - - /** - * Creates a new {@link org.skycastle.sketch.SketchRenderer}. - */ - public SketchRenderer() - { - } - - -} Deleted: trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchToolbarFactory.java =================================================================== --- trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchToolbarFactory.java 2008-04-26 20:42:11 UTC (rev 484) +++ trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchToolbarFactory.java 2008-04-27 00:02:04 UTC (rev 485) @@ -1,60 +0,0 @@ -package org.skycastle.sketch; - -import javax.swing.*; -import java.awt.event.ActionEvent; - -/** - * @author Hans Haggstrom - */ -public class SketchToolbarFactory -{ - - public JToolBar createToolbar() - { - final JToolBar toolBar = new JToolBar(); - toolBar.add( new JButton( new AbstractAction( "Quit" ) - { - - public void actionPerformed( final ActionEvent e ) - { - System.exit( 0 ); - } - - } ) ); - toolBar.add( new JButton( new AbstractAction( "New Page" ) - { - - public void actionPerformed( final ActionEvent e ) - { - } - - } ) ); - toolBar.add( new JButton( new AbstractAction( "Zoom Out" ) - { - - public void actionPerformed( final ActionEvent e ) - { - } - - } ) ); - toolBar.add( new JButton( new AbstractAction( "Zoom In" ) - { - - public void actionPerformed( final ActionEvent e ) - { - } - - } ) ); - toolBar.add( new JButton( new AbstractAction( "Zoom to show all" ) - { - - public void actionPerformed( final ActionEvent e ) - { - } - - } ) ); - - toolBar.setVisible( true ); - return toolBar; - } -} Modified: trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchView.java =================================================================== --- trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchView.java 2008-04-26 20:42:11 UTC (rev 484) +++ trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchView.java 2008-04-27 00:02:04 UTC (rev 485) @@ -36,12 +36,12 @@ private final Map<String, Menu> myMenus = new HashMap<String, Menu>( 10 ); private final SimpleFrame myMainFrame; + private final Node myRoot3DNode; private Canvas3D myCanvas3D; private JToolBar myToolBar; private MenuBar myMenuBar; private Sketch mySketch; - private final Node myRoot3DNode; //====================================================================== // Public Methods @@ -52,7 +52,7 @@ /** * Creates a new {@link org.skycastle.sketch.SketchView}. */ - public SketchView( String applicationName ) + public SketchView( final String applicationName ) { ParameterChecker.checkNotNull( applicationName, "applicationName" ); @@ -63,7 +63,9 @@ myCanvas3D.removeAllNavigationGestures(); myRoot3DNode = new Node( "SketchView_RootNode" ); myCanvas3D.set3DNode( myRoot3DNode ); + myCanvas3D.setBackgroundColor( Color.WHITE ); + final JPanel panel = new JPanel( new BorderLayout() ); panel.add( myCanvas3D.get3DView(), BorderLayout.CENTER ); panel.add( myToolBar, BorderLayout.NORTH ); @@ -87,6 +89,7 @@ //---------------------------------------------------------------------- // Other Public Methods + /** * @param closeAction an action that is called when the close button of the main window is pressed, or the * application is attempted to be closed in some other way. @@ -209,9 +212,11 @@ reRender( sketch ); + //noinspection serial sketch.getRootGroup().addGroupListener( new CollectionListener<GroupElement>() { - public void onElementAdded( final ListenableCollection<GroupElement> groupElementListenableCollection, + + public void onElementAdded( final ListenableCollection<GroupElement> collection, final GroupElement addedElement ) { // TODO: Instead of this, just modify the 3D object for the stroke that was changed, @@ -219,16 +224,21 @@ reRender( sketch ); } - public void onElementRemoved( final ListenableCollection<GroupElement> groupElementListenableCollection, + + public void onElementRemoved( final ListenableCollection<GroupElement> collection, final GroupElement removedElement ) { // TODO: Instead of this, just modify the 3D object for the stroke that was changed, // or add a new one, or remove an removed one. reRender( sketch ); } + } ); } + //====================================================================== + // Private Methods + private void reRender( final Sketch sketch ) { // Clean out old nodes (NOTE: detach all is usually a bit buggy / weird.. ) @@ -237,6 +247,7 @@ renderGroup( sketch.getRootGroup() ); } + private void renderGroup( final Group group ) { for ( final GroupElement groupElement : group.getElements() ) @@ -246,7 +257,13 @@ if ( groupElement instanceof Stroke ) { final Stroke stroke = (Stroke) groupElement; - myRoot3DNode.attachChild( new StrokeRenderer( stroke ) ); + + // TODO: add capability to render points. + if ( stroke.getPoints().size() >= 2 ) + { + myRoot3DNode.attachChild( new StrokeRenderer( stroke ) ); + } + } else if ( groupElement instanceof Group ) { @@ -255,8 +272,6 @@ } } - //====================================================================== - // Private Methods private Menu getOrCreateMenu( final String menuName ) { Modified: trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SkycastleSketch.java =================================================================== --- trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SkycastleSketch.java 2008-04-26 20:42:11 UTC (rev 484) +++ trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SkycastleSketch.java 2008-04-27 00:02:04 UTC (rev 485) @@ -1,36 +1,13 @@ package org.skycastle.sketch; -import com.jme.bounding.BoundingBox; -import com.jme.math.Vector3f; -import com.jme.scene.Controller; -import com.jme.scene.Spatial; -import com.jme.scene.shape.Box; -import com.jme.scene.state.LightState; - -import java.util.logging.Level; -import java.util.logging.Logger; - /** * A simple sketch program, supporting a pen tablet as input, and running in opengl. * * @author Hans Haggstrom */ -public class SkycastleSketch +public final class SkycastleSketch { - //====================================================================== - // Private Fields - - private static float myBoxRotationCounter = 0; - - //====================================================================== - // Private Constants - - private static final Logger LOGGER = Logger.getLogger( SkycastleSketch.class.getName() ); - - //====================================================================== - // Public Methods - //---------------------------------------------------------------------- // Main Method @@ -39,74 +16,20 @@ */ public static void main( String[] args ) { - - // Do not show logging output below the WARNING level (JME outputs a lot of debugging info at INFO level). + // TODO: Do not show logging output below the WARNING level (JME outputs a lot of debugging info at INFO level). // This way the console output is a bit more relevant. - LOGGER.setLevel( Level.WARNING ); final SketchController sketchController = new SketchController(); sketchController.start(); - -/* - Sketch3DUI sketch3DUI = new Sketch3DUI(); - sketch3DUI.start(); -*/ } //====================================================================== // Private Methods - - /** - * Create the 3D scene. In this case, this is just the rotating box. - */ - private static Spatial create3DScene() + private SkycastleSketch() { - final Vector3f axis = new Vector3f( 1, 1, 0.5f ).normalizeLocal(); - final Box box = new Box( "Box", - new Vector3f( 5, 5, 5 ), - new Vector3f( -5, -5, -5 ) ); - - box.setModelBound( new BoundingBox() ); - box.updateModelBound(); - box.setLocalTranslation( new Vector3f( 0, 0, -10 ) ); - box.setLightCombineMode( LightState.OFF ); - - box.setRandomColors(); - -/* - TextureState ts = DisplaySystem.getDisplaySystem().getRenderer().createTextureState(); - ts.setEnabled( true ); - ts.setTexture( TextureManager.loadTexture( - Sketch3DUI.class.getClassLoader().getResource( - "org/skycastle/client/data/skycastle.png" ), - Texture.MM_LINEAR, - Texture.FM_LINEAR ) - ); - box.setRenderState( ts ); -*/ - - box.addController( - // Controller which rotates the box. - new Controller() - { - - private static final long serialVersionUID = 1L; - - @Override - public void update( float time ) - { - myBoxRotationCounter += time; - box.getLocalRotation().fromAngleNormalAxis( - myBoxRotationCounter, axis ); - } - - } - ); - - return box; } } Modified: trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/StrokeRenderer.java =================================================================== --- trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/StrokeRenderer.java 2008-04-26 20:42:11 UTC (rev 484) +++ trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/StrokeRenderer.java 2008-04-27 00:02:04 UTC (rev 485) @@ -6,8 +6,13 @@ import com.jme.math.Vector2f; import com.jme.math.Vector3f; import com.jme.renderer.ColorRGBA; +import com.jme.renderer.Renderer; import com.jme.scene.TriMesh; +import com.jme.scene.state.AlphaState; import com.jme.scene.state.TextureState; +import com.jme.system.DisplaySystem; +import com.jme.util.GameTaskQueue; +import com.jme.util.GameTaskQueueManager; import com.jme.util.TextureManager; import com.jme.util.geom.BufferUtils; import com.jmex.awt.swingui.ImageGraphics; @@ -19,12 +24,15 @@ import java.awt.image.BufferedImage; import java.nio.FloatBuffer; import java.nio.IntBuffer; +import java.util.concurrent.Callable; /** + * A 3D node that renders a {@link Stroke}. + * * @author Hans Häggström */ @SuppressWarnings( { "serial" } ) -public class StrokeRenderer +public final class StrokeRenderer extends TriMesh { @@ -88,6 +96,7 @@ this( stroke, 0 ); } + /** * Creates a new {@link org.skycastle.sketch.StrokeRenderer}. * @@ -124,7 +133,35 @@ // Stich together the vertices into triangles initializeIndices(); + updateBounds(); + + + GameTaskQueueManager.getManager().getQueue( GameTaskQueue.UPDATE ).enqueue( new Callable<Object>() + { + + public Object call() throws Exception + { + final Renderer renderer = DisplaySystem.getDisplaySystem().getRenderer(); + + final StrokeRenderer strokeRenderer = StrokeRenderer.this; + + // strokeRenderer.setRenderQueueMode( Renderer.QUEUE_TRANSPARENT ); + final AlphaState alphaState = renderer.createAlphaState(); + alphaState.setBlendEnabled( true ); + alphaState.setSrcFunction( AlphaState.SB_SRC_ALPHA ); + alphaState.setDstFunction( AlphaState.DB_ONE_MINUS_SRC_ALPHA ); + alphaState.setTestEnabled( false ); + alphaState.setEnabled( true ); + + strokeRenderer.setRenderState( alphaState ); + strokeRenderer.updateRenderState(); + + return null; + } + + } ); + } //---------------------------------------------------------------------- @@ -249,15 +286,15 @@ final Vector3f positionLeft = new Vector3f( xPos, yPos + width, zPos ); final ColorRGBA colorLeft = strokePoint.getProperty( "color", - new ColorRGBA( 0.1f, 0.1f, 0.1f, 1.0f ) ); + new ColorRGBA( 0, 0, 0, 0 ) ); final Vector3f positionMid = new Vector3f( xPos, yPos, zPos ); final ColorRGBA colorMid = strokePoint.getProperty( "color", - new ColorRGBA( 0.5f, 0.5f, 0.5f, 1.0f ) ); + new ColorRGBA( 0, 0, 0, 1 ) ); final Vector3f positionRight = new Vector3f( xPos, yPos - width, zPos ); final ColorRGBA colorRight = strokePoint.getProperty( "color", - new ColorRGBA( 0.1f, 0.1f, 0.1f, 1.0f ) ); + new ColorRGBA( 0, 0, 0, 0 ) ); setPointData( index + 0, positionLeft, colorLeft ); setPointData( index + 1, positionMid, colorMid ); Added: trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/StrokeTool.java =================================================================== --- trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/StrokeTool.java (rev 0) +++ trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/StrokeTool.java 2008-04-27 00:02:04 UTC (rev 485) @@ -0,0 +1,189 @@ +package org.skycastle.sketch; + +import jpen.PButton; +import jpen.PButtonEvent; +import jpen.PLevel; +import jpen.PLevelEvent; +import org.skycastle.opengl.navigationgestures.AbstractNavigationGesture; +import org.skycastle.sketch.model.group.Group; +import org.skycastle.sketch.model.point.StrokePointImpl; +import org.skycastle.sketch.model.stroke.Stroke; +import org.skycastle.sketch.model.stroke.StrokeImpl; +import org.skycastle.util.command.AbstractCommand; +import org.skycastle.util.command.CommandStack; + +/** + * @author Hans Haggstrom + */ +public class StrokeTool + extends AbstractNavigationGesture +{ + + //====================================================================== + // Private Fields + + private final CommandStack myCommandStack; + private Group myGroup; + + private boolean myStrokeActive = false; + + private float myStrokeX; + private float myStrokeY; + private float myStrokePressure; + private float myStrokeTiltX; + private float myStrokeTiltY; + + private Stroke myStroke; + + //====================================================================== + // Public Methods + + //---------------------------------------------------------------------- + // Constructors + + StrokeTool( final CommandStack commandStack ) + { + super( 1 ); + myCommandStack = commandStack; + } + + StrokeTool( final Group group, final CommandStack commandStack ) + { + super( 1 ); + + myGroup = group; + myCommandStack = commandStack; + } + + //---------------------------------------------------------------------- + // PenListener Implementation + + @Override + public void penLevelEvent( final PLevelEvent ev ) + { + if ( myStrokeActive ) + { + for ( final PLevel level : ev.levels ) + { + switch ( level.getType() ) + { + case X: + myStrokeX = level.value; + break; + case Y: + myStrokeY = level.value; + break; + case PRESSURE: + myStrokePressure = level.value; + break; + case TILT_X: + myStrokeTiltX = level.value; + break; + case TILT_Y: + myStrokeTiltY = level.value; + break; + default: + } + } + + addStrokeEvent( ev.getTime() ); + } + } + + + @Override + public void penButtonEvent( final PButtonEvent ev ) + { + if ( ev.button.getType() == PButton.Type.LEFT ) + { + final Boolean pressed = ev.button.value; + + if ( pressed ) + { + startStroke(); + } + else + { + endStroke(); + } + } + } + + //---------------------------------------------------------------------- + // Other Public Methods + + public Group getGroup() + { + return myGroup; + } + + + public void setGroup( final Group group ) + { + endStroke(); + + myGroup = group; + } + + //====================================================================== + // Private Methods + + private void addStrokeEvent( final long time ) + { + if ( myStrokeActive ) + { + // TODO: Get correct offset and scale (and rotation?) from camera to apply to the coordinates to + // project them to the canvas space. + final float x = myStrokeX + getCamera().getLocation().getX(); + final float y = myStrokeY + getCamera().getLocation().getY(); + final StrokePointImpl strokePoint = new StrokePointImpl( x, y ); + strokePoint.setProperty( "tiltX", myStrokeTiltX ); + strokePoint.setProperty( "tiltY", myStrokeTiltY ); + strokePoint.setProperty( "pressure", myStrokePressure ); + strokePoint.setProperty( "time", time ); + + myStroke.addPoint( strokePoint ); + } + } + + + private void endStroke() + { + if ( myStrokeActive ) + { + if ( myGroup != null ) + { + final Stroke stroke = myStroke; + final Group group = myGroup; + + myCommandStack.invoke( new AbstractCommand( "Stroke", true ) + { + public void doCommand() + { + group.add( stroke ); + + } + + @Override + public void undoCommand() + { + group.remove( stroke ); + + } + } ); + + } + + myStrokeActive = false; + myStroke = null; + } + } + + + private void startStroke() + { + myStrokeActive = true; + myStroke = new StrokeImpl(); + } + +} Copied: trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/old/JPenExample.java (from rev 481, trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/PenInput.java) =================================================================== --- trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/old/JPenExample.java (rev 0) +++ trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/old/JPenExample.java 2008-04-27 00:02:04 UTC (rev 485) @@ -0,0 +1,147 @@ +package org.skycastle.sketch.old; + +import jpen.*; +import jpen.event.PenListener; + +import javax.swing.*; + +/** + * @author Hans Haggstrom + */ +public class JPenExample + implements PenListener +{ + + //---------------------------------------------------------------------- + // Main Method + + public static void main( String... args ) + { + new JPenExample(); + } + + //---------------------------------------------------------------------- + // Constructors + + JPenExample() + { +/* + JLabel l = new JLabel( "Move the pen or mouse over me!" ); + PenManager pm = new PenManager( l ); + pm.pen.addListener( this ); + + JFrame f = new JFrame( "JPen Example" ); + f.getContentPane().add( l ); + f.setSize( 300, 300 ); + f.setVisible( true ); +*/ + + JLabel l = new JLabel( "Move the pen or mouse over me!" ); + PenManager pm = new PenManager( l ); + printSysInfo( pm ); // INSERTED LINE + + pm.pen.addListener( this ); + + JFrame f = new JFrame( "JPen Example" ); + f.getContentPane().add( l ); + f.setSize( 300, 300 ); + f.setVisible( true ); + } + + //---------------------------------------------------------------------- + // Static Methods + + static void printSysInfo( PenManager pm ) + { + StringBuilder sb = new StringBuilder(); + sb.append( "vvv JPen - System Info vvv" ); + sb.append( "\n* Date: " + new java.util.Date() ); + sb.append( "\n* JPen Version: " + jpen.provider.Utils.getDistVersion() ); + sb.append( "\n* System Properties:" ); + for ( Object propertyName : System.getProperties().keySet() ) + { + sb.append( "\n\t - " + propertyName + " = " + System.getProperty( propertyName.toString() ) ); + } + for ( PenProvider.Constructor constructor : pm.getConstructors() ) + { + sb.append( "\n* Constructor: " + constructor.getName() ); + Exception ex = pm.getConstructionException( constructor ); + if ( ex != null ) + { + java.io.StringWriter sw = new java.io.StringWriter(); + java.io.PrintWriter pw = new java.io.PrintWriter( sw ); + ex.printStackTrace( pw ); + pw.close(); + sb.append( "\n\t - Exception: " ); + sb.append( sw.toString() ); + } + if ( constructor.getName().equals( "System" ) ) + { + for ( jpen.PenDevice device : pm.getProvider( constructor ).getDevices() ) + { + device.setEnabled( false ); + sb.append( "\n\t - Disabled Device: " + device.getName() ); + } + } + } + sb.append( "\n^^^ JPen - System Info ^^^\n" ); + + String sysInfo = sb.toString(); + System.out.println( sysInfo ); + +/* + try + { + java.io.Writer w = new java.io.FileWriter( new java.io.File( "JPen-sysInfo.txt" ) ); + w.write( sysInfo ); + w.close(); + } + catch ( Exception ex ) + { + ex.printStackTrace(); + } +*/ + } + + //---------------------------------------------------------------------- + // PenListener Implementation + + @Override + public void penKindEvent( PKindEvent + ev ) + { + System.out.println( ev ); + } + + + @Override + public void penLevelEvent( PLevelEvent + ev ) + { + System.out.println( ev ); + } + + + @Override + public void penButtonEvent( PButtonEvent + ev ) + { + System.out.println( ev ); + } + + + @Override + public void penScrollEvent( PScrollEvent + ev ) + { + System.out.println( ev ); + } + + + @Override + public void penTock( long availableMillis ) + { + System.out.println( "TOCK - available period fraction: " + availableMillis ); + } + +} Copied: trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/old/Sketch3DUI.java (from rev 483, trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/Sketch3DUI.java) =================================================================== --- trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/old/Sketch3DUI.java (rev 0) +++ trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/old/Sketch3DUI.java 2008-04-27 00:02:04 UTC (rev 485) @@ -0,0 +1,280 @@ +package org.skycastle.sketch.old; + +import com.jme.app.SimpleGame; +import com.jme.bounding.BoundingBox; +import com.jme.image.Texture; +import com.jme.input.*; +import com.jme.math.Vector3f; +import com.jme.renderer.ColorRGBA; +import com.jme.renderer.Renderer; +import com.jme.scene.Controller; +import com.jme.scene.Node; +import com.jme.scene.SceneElement; +import com.jme.scene.shape.Box; +import com.jme.scene.state.LightState; +import com.jme.scene.state.TextureState; +import com.jme.util.TextureManager; +import com.jmex.awt.swingui.JMEDesktop; + +import javax.swing.*; +import javax.swing.plaf.basic.BasicInternalFrameUI; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Container; +import java.beans.PropertyVetoException; +import java.util.logging.Logger; + +/** + * OpenGL main loop for the sketch program. + * + * @author Hans Haggstrom + */ +@SuppressWarnings( { "MagicNumber" } ) +public class Sketch3DUI + extends SimpleGame +{ + + //====================================================================== + // Private Fields + + /** + * Keyboard look input handler. + */ + private KeyboardLookHandler lookHandler = null; + + /** + * Scene node for the GUI. + */ + private Node guiNode = null; + + /** + * JME desktop on which the GUI will be shown. + */ + private JMEDesktop desktop = null; + + //====================================================================== + // Non-Private Fields + + /** + * The color to be used as background color for the desktop. This is completely transparent right now. + */ + protected static final Color DESKTOP_BACKGROUND_COLOR = new Color( 0.5f, 0.5f, 0.5f, 0.0f ); + + //====================================================================== + // Private Constants + + private static final Logger LOGGER = Logger.getLogger( Sketch3DUI.class.getName() ); + + //====================================================================== + // Public Methods + + //---------------------------------------------------------------------- + // Other Public Methods + + /** + * Set up key bindings. + */ + public void initKeyBindings() + { + /* Remove some keybindings established by BaseSimpleGame, since they + are needed for chatting. + TODO: Find a more elegant solution. Maybe bind/rebind depending on + focus, or handling these during update. + Eventually, we may also need to implement our own base game + class. + */ + KeyBindingManager.getKeyBindingManager().remove( "toggle_pause" ); + KeyBindingManager.getKeyBindingManager().remove( "step" ); + KeyBindingManager.getKeyBindingManager().remove( "toggle_wire" ); + KeyBindingManager.getKeyBindingManager().remove( "toggle_lights" ); + KeyBindingManager.getKeyBindingManager().remove( "toggle_bounds" ); + KeyBindingManager.getKeyBindingManager().remove( "toggle_normals" ); + KeyBindingManager.getKeyBindingManager().remove( "camera_out" ); + KeyBindingManager.getKeyBindingManager().remove( "mem_report" ); + + // Bind the BaseSimpleGame functions to other keys. + KeyBindingManager.getKeyBindingManager().set( "toggle_pause", KeyInput.KEY_F4 ); + KeyBindingManager.getKeyBindingManager().set( "step", KeyInput.KEY_F5 ); + KeyBindingManager.getKeyBindingManager().set( "toggle_wire", KeyInput.KEY_F6 ); + KeyBindingManager.getKeyBindingManager().set( "toggle_lights", KeyInput.KEY_F7 ); + KeyBindingManager.getKeyBindingManager().set( "toggle_bounds", KeyInput.KEY_F8 ); + KeyBindingManager.getKeyBindingManager().set( "toggle_normals", KeyInput.KEY_F9 ); + KeyBindingManager.getKeyBindingManager().set( "camera_out", KeyInput.KEY_F10 ); + KeyBindingManager.getKeyBindingManager().set( "mem_report", KeyInput.KEY_F11 ); + } + + //====================================================================== + // Protected Methods + + /** + * Create the UI. Create the elements of the Swing UI. + */ + protected void initUI() + { + /// JME part of the GUI creation. + guiNode = new Node( "gui" ); + guiNode.setRenderQueueMode( Renderer.QUEUE_ORTHO ); + + desktop = new JMEDesktop( + "desktop", + display.getWidth(), + display.getHeight(), + input + ); + guiNode.attachChild( desktop ); + desktop.getLocalTranslation().set( + display.getWidth() / 2.0f, + display.getHeight() / 2.0f, 0 + ); + + // AWT/Swing part of the GUI creation. + desktop.getJDesktop().setBackground( DESKTOP_BACKGROUND_COLOR ); + + + JInternalFrame toolFrame = new JInternalFrame(); +// toolFrame.setLocation( 10, 10 ); +// toolFrame.setResizable( true ); + + toolFrame.setOpaque( false ); + Container contentPane = toolFrame.getContentPane(); + contentPane.setLayout( new BorderLayout() ); + contentPane.setBackground( new Color( 0, 0, 0, 0 ) ); + + contentPane.add( new JLabel( "foo" ), BorderLayout.EAST ); + contentPane.add( createNorthPanel(), BorderLayout.NORTH ); + + toolFrame.setBorder( BorderFactory.createEmptyBorder() ); + toolFrame.setTitle( null ); + + toolFrame.setVisible( true ); + toolFrame.pack(); + + final BasicInternalFrameUI basicInternalFrameUI = (BasicInternalFrameUI) toolFrame.getUI(); + basicInternalFrameUI.setNorthPane( null ); + + desktop.getJDesktop().add( toolFrame ); + +/* + toolFrame.putClientProperty( ); + + a) internalFrame.putClientProperty("JInternalFrame.isPalette", Boolean.TRUE); +*/ + +/* + final JLabel jLabel = new JLabel( "fooo" ); + + jLabel.setForeground( Color.WHITE ); + jDesktopPane.setLayout( new BorderLayout() ); + jDesktopPane.add( jLabel, BorderLayout.CENTER ); +*/ + try + { + toolFrame.setMaximum( true ); + } + catch ( PropertyVetoException e ) + { + e.printStackTrace(); + } + } + + private JComponent createNorthPanel() + { + final JToolBar bar = new JToolBar(); + bar.add( new JButton( "Foo" ) ); + return bar; + } + + + /** + * Create the 3D scene. In this case, this is just the rotating box. + */ + protected void create3DScene() + { + final Vector3f axis = new Vector3f( 1, 1, 0.5f ).normalizeLocal(); + final Box box = new Box( "Box", + new Vector3f( -5, -5, -5 ), + new Vector3f( 5, 5, 5 ) ); + + box.setModelBound( new BoundingBox() ); + box.updateModelBound(); + box.setLocalTranslation( new Vector3f( 0, 0, -10 ) ); + box.setLightCombineMode( LightState.OFF ); + + TextureState ts = display.getRenderer().createTextureState(); + ts.setEnabled( true ); + ts.setTexture( TextureManager.loadTexture( + Sketch3DUI.class.getClassLoader().getResource( + "org/skycastle/client/data/skycastle.png" ), + Texture.MM_LINEAR, + Texture.FM_LINEAR ) + ); + box.setRenderState( ts ); + box.addController( + // Controller which rotates the box. + new Controller() + { + + private static final long serialVersionUID = 1L; + + @Override + public void update( float time ) + { + box.getLocalRotation().fromAngleNormalAxis( + timer.getTimeInSeconds(), axis ); + } + + } + ); + + rootNode.attachChild( box ); + } + + + /** + * Initialize game. Overridden from SimpleGame. + */ + @Override + protected void simpleInitGame() + { + display.setTitle( "Skycastle 3D Client" ); + display.getRenderer().setBackgroundColor( ColorRGBA.black ); + + // Set up the keyboard look handler. + input = new InputHandler(); + lookHandler = new KeyboardLookHandler( cam, 50, 1 ); + input.addToAttachedHandlers( lookHandler ); + // Some changes to the BaseSimpleGame keyboard bindings. + initKeyBindings(); + + // Set up GUI, static 3D scene and chat client. + initUI(); + create3DScene(); + + // Always show the the GUI. + guiNode.setCullMode( SceneElement.CULL_NEVER ); + guiNode.setLightCombineMode( LightState.OFF ); + guiNode.updateRenderState(); + guiNode.updateGeometricState( 0, true ); + MouseInput.get().setCursorVisible( true ); + } + + + /** + * Update hook. Overridden from SimpleGame. + */ + @Override + protected void simpleUpdate() + { + } + + + /** + * Render hook. Overridden from SimpleGame. + */ + @Override + protected void simpleRender() + { + display.getRenderer().draw( guiNode ); + } + +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.