Revision: 491 http://skycastle.svn.sourceforge.net/skycastle/?rev=491&view=rev Author: zzorn Date: 2008-04-27 16:20:35 -0700 (Sun, 27 Apr 2008) Log Message: ----------- The projection error was because the projection is being corrected when the screen is resized. Added a resize handler, but needs some more work. Modified Paths: -------------- trunk/skycastle/modules/ui/src/main/java/org/skycastle/opengl/Canvas3D.java trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchView.java Added Paths: ----------- trunk/skycastle/modules/ui/src/main/java/org/skycastle/opengl/ResizeHandler.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-27 22:46:43 UTC (rev 490) +++ trunk/skycastle/modules/ui/src/main/java/org/skycastle/opengl/Canvas3D.java 2008-04-27 23:20:35 UTC (rev 491) @@ -71,6 +71,23 @@ private boolean myInitialized = false; + private ResizeHandler myResizeHandler = new ResizeHandler() + { + + public void onScreenResized( final float newCanvasWidth, + final float newCanvasHeight, + final float canvasAspectRatio, + final Camera camera ) + { + // Sets the aspect ratio of the camera to the aspect ratio of the viewport size. + camera.setFrustumPerspective( DEFAULT_FIELD_OF_VIEW_DEGREES, + canvasAspectRatio, + camera.getFrustumNear(), + camera.getFrustumFar() ); + } + + }; + //====================================================================== // Private Constants @@ -79,6 +96,7 @@ private static final int CANVAS_REPAINT_INTERVAL_MS = 10; private static final int DEFAULT_VIEW_DISTANCE = 100000; + private static final float DEFAULT_FIELD_OF_VIEW_DEGREES = 45; //====================================================================== // Public Methods @@ -333,6 +351,26 @@ myInitializers.add( initializer ); } + + /** + * @return a {@link ResizeHandler} that gets called in a render thread when the canvas is resized. Used to + * update the camera projection as necessary. + */ + public ResizeHandler getResizeHandler() + { + return myResizeHandler; + } + + + /** + * @param resizeHandler a {@link ResizeHandler} that gets called in a render thread when the canvas is + * resized. Used to update the camera projection as necessary. + */ + public void setResizeHandler( final ResizeHandler resizeHandler ) + { + myResizeHandler = resizeHandler; + } + //====================================================================== // Private Methods @@ -475,11 +513,6 @@ private boolean myAspectRatioNeedsCorrecting = true; //====================================================================== - // Private Constants - - private static final float DEFAULT_FIELD_OF_VIEW_DEGREES = 45; - - //====================================================================== // Public Methods //---------------------------------------------------------------------- @@ -600,46 +633,41 @@ } + @Override public void simpleRender() { // Setup aspect ratio for camera on the first frame (the camera is not created before the rendering starts) if ( myAspectRatioNeedsCorrecting ) { - correctCameraAspectRatio(); + final Renderer canvasRenderer = getRenderer(); + if ( canvasRenderer != null ) + { + // Get size on screen + final float canvasHeight = canvasRenderer.getHeight(); + final float canvasWidth = canvasRenderer.getWidth(); - myAspectRatioNeedsCorrecting = false; - } - } + // Calculate aspect ratio + float aspectRatio = 1; + if ( canvasHeight > 0 ) + { + aspectRatio = canvasWidth / canvasHeight; + } - //====================================================================== - // Private Methods + final Camera camera = getCamera(); - /** - * Sets the aspect ratio of the camera to the aspect ratio of the viewport size. - */ - private void correctCameraAspectRatio() - { - final Renderer renderer = getRenderer(); + myResizeHandler.onScreenResized( canvasWidth, + canvasHeight, + aspectRatio, + camera ); - if ( renderer != null ) - { - // Get size on screen - final float height = renderer.getHeight(); - final float width = renderer.getWidth(); - - // Calculate aspect ratio - float aspectRatio = 1; - if ( height > 0 ) - { - aspectRatio = width / height; +/* + // TODO: Not sure if this is needed? + camera.update(); +*/ } - // Set aspect ratio and field of view to camera - final Camera camera = getCamera(); - camera.setFrustumPerspective( DEFAULT_FIELD_OF_VIEW_DEGREES, - aspectRatio, - camera.getFrustumNear(), - camera.getFrustumFar() ); + + myAspectRatioNeedsCorrecting = false; } } Added: trunk/skycastle/modules/ui/src/main/java/org/skycastle/opengl/ResizeHandler.java =================================================================== --- trunk/skycastle/modules/ui/src/main/java/org/skycastle/opengl/ResizeHandler.java (rev 0) +++ trunk/skycastle/modules/ui/src/main/java/org/skycastle/opengl/ResizeHandler.java 2008-04-27 23:20:35 UTC (rev 491) @@ -0,0 +1,33 @@ +package org.skycastle.opengl; + +import com.jme.renderer.Camera; + +/** + * Called when the {@link Canvas3D} is resized. + * <p/> + * Can handle camera projection update. + * <p/> + * Called in a render thread, so should use SwingUtilities.invokeLater if it needs to do something in the + * swing thread. + * + * @author Hans Haggstrom + */ +public interface ResizeHandler +{ + + /** + * Called when the canvas is resized. + * <p/> + * Called in a render thread, so should use SwingUtilities.invokeLater if it needs to do something in the + * swing thread. + * + * @param newCanvasWidth new width of the canvas, in pixels. + * @param newCanvasHeight new height of the canvas, in pixels. + * @param canvasAspectRatio aspect ratio of the canvas (widht / heght). + * @param camera the camera of the canvas. Changes can be made to it. + */ + void onScreenResized( final float newCanvasWidth, + final float newCanvasHeight, + final float canvasAspectRatio, + final Camera camera ); +} 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-27 22:46:43 UTC (rev 490) +++ trunk/skycastle/modules/ui/src/main/java/org/skycastle/sketch/SketchView.java 2008-04-27 23:20:35 UTC (rev 491) @@ -8,6 +8,7 @@ import jpen.PenManager; import org.skycastle.opengl.Canvas3D; import org.skycastle.opengl.CanvasInitializer; +import org.skycastle.opengl.ResizeHandler; import org.skycastle.opengl.navigationgestures.NavigationGesture; import org.skycastle.sketch.model.Sketch; import org.skycastle.sketch.model.group.Group; @@ -96,11 +97,27 @@ myPenManager = new PenManager( myCanvas3D.get3DView() ); + myCanvas3D.setResizeHandler( createResizeHandler() ); + // Make all popup menus and tooltips heavyweight so that they can overlap the 3D view JPopupMenu.setDefaultLightWeightPopupEnabled( false ); ToolTipManager.sharedInstance().setLightWeightPopupEnabled( false ); } + private ResizeHandler createResizeHandler() + { + return new ResizeHandler() + { + public void onScreenResized( final float newCanvasWidth, + final float newCanvasHeight, + final float canvasAspectRatio, + final Camera camera ) + { + // TODO + } + }; + } + //---------------------------------------------------------------------- // Other Public Methods @@ -207,10 +224,10 @@ { final float width = view.getWidth(); final float height = view.getHeight(); - final float scale = myViewSizeHorizontally / ( 10.0f * width ); - listener.onProjectionChanged( myCameraX + 0.5f * width * scale, + final float scale = myViewSizeHorizontally / width; + listener.onProjectionChanged( myCameraX - 0.5f * width * scale, myCameraY - 0.5f * height * scale, - -scale, + scale, scale ); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.