001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/ogcwebservices/wpvs/j3d/InteractiveWPVSRenderer.java $
002    
003    /*----------------    FILE HEADER  ------------------------------------------
004     
005    This file is part of deegree.
006    Copyright (C) 2001-2008 by:
007    EXSE, Department of Geography, University of Bonn
008    http://www.giub.uni-bonn.de/deegree/
009    lat/lon GmbH
010    http://www.lat-lon.de
011     
012    This library is free software; you can redistribute it and/or
013    modify it under the terms of the GNU Lesser General Public
014    License as published by the Free Software Foundation; either
015    version 2.1 of the License, or (at your option) any later version.
016     
017    This library is distributed in the hope that it will be useful,
018    but WITHOUT ANY WARRANTY; without even the implied warranty of
019    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
020    Lesser General Public License for more details.
021     
022    You should have received a copy of the GNU Lesser General Public
023    License along with this library; if not, write to the Free Software
024    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
025     
026    Contact:
027     
028    Andreas Poth
029    lat/lon GmbH
030    Aennchenstr. 19
031    53177 Bonn
032    Germany
033    E-Mail: poth@lat-lon.de
034     
035    Prof. Dr. Klaus Greve
036    Department of Geography
037    University of Bonn
038    Meckenheimer Allee 166
039    53115 Bonn
040    Germany
041    E-Mail: greve@giub.uni-bonn.de
042     
043     
044     ---------------------------------------------------------------------------*/
045    package org.deegree.ogcwebservices.wpvs.j3d;
046    
047    import java.awt.image.BufferedImage;
048    import java.awt.image.RenderedImage;
049    
050    import javax.media.j3d.BoundingSphere;
051    import javax.media.j3d.BranchGroup;
052    import javax.media.j3d.Canvas3D;
053    import javax.media.j3d.Group;
054    import javax.media.j3d.ImageComponent;
055    import javax.media.j3d.ImageComponent2D;
056    import javax.media.j3d.Light;
057    import javax.media.j3d.Locale;
058    import javax.media.j3d.OrderedGroup;
059    import javax.media.j3d.View;
060    import javax.media.j3d.VirtualUniverse;
061    import javax.vecmath.Point3d;
062    
063    import com.sun.j3d.utils.behaviors.mouse.MouseRotate;
064    import com.sun.j3d.utils.behaviors.mouse.MouseTranslate;
065    import com.sun.j3d.utils.behaviors.mouse.MouseZoom;
066    
067    
068    /**
069     * This class sill/shoud provide the ability to render a scence object (s. 
070     * com.sun.j3d.loaders.Scene) or a Canvas3D. It's currently used for testing. 
071     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
072     * @version $Revision: 9345 $ $Date: 2007-12-27 17:22:25 +0100 (Do, 27 Dez 2007) $
073     */
074    public class InteractiveWPVSRenderer extends Abstract3DRenderingEngine {     
075        
076        private int width  = 800;
077        
078        private int height = 600;
079        
080        private Canvas3D offScreenCanvas3D;
081        
082        private View view;  
083        
084        private boolean newSize;
085        
086        /**
087         * initialzies the render class with a default width and height (801x601)
088         * @param scene 
089         */
090        public InteractiveWPVSRenderer(WPVSScene scene)
091        {        
092            this( scene, 801, 601 );          
093        }
094        
095        /**
096         * initialzies the render class with the submitted width and height 
097         * @param scene 
098         * @param width 
099         * @param height 
100         */
101        public InteractiveWPVSRenderer(WPVSScene scene, int width, int height)
102        {        
103            super( scene, 2 );
104            this.width = width;
105            this.height = height;
106            view = new View();        
107        }
108        
109        /**
110         * @param scene
111         */
112        public void setScene(WPVSScene scene) {
113            this.scene = scene;
114        }
115        
116        /**Create the VirtualUniverse for the application.
117         * @return the VirtualUniverse for the application.
118         */
119        protected VirtualUniverse createVirtualUniverse() {
120            return new VirtualUniverse();
121        }
122        
123        /**
124         * Simple utility method that creates a Locale for the
125         * VirtualUniverse
126         * @param u the universe
127         * @return the Locale
128         */
129        protected Locale createLocale( VirtualUniverse u ) {
130            return new Locale( u );
131        }
132        
133        /**
134         * returns the width of the offscreen rendering target
135         * @return the width of the offscreen rendering target
136         */
137        public int getWidth() {
138            return width;
139        }
140        
141        /**
142         * @param width the new width of the screen
143         */
144        public void setWidth( int width ) {   
145            newSize = true;
146            this.width = width;
147        }
148        
149        /**
150         * returns the height of the offscreen rendering target
151         * @return the height of the offscreen rendering target
152         */
153        public int getHeight() {
154            return height;
155        }
156        
157        /**
158         * @param height the new Height of the screen
159         */
160        public void setHeight( int height ) {
161            newSize = true;
162            this.height = height;  
163        }
164        
165        /** renders the scene to an <code>BufferedImage</code>
166         * @return a <code>BufferedImage</code> where the scene has been rendered to
167         */
168        public Object renderScene( ) {
169            if ( newSize ) {
170                view.removeCanvas3D( offScreenCanvas3D );
171    
172                offScreenCanvas3D = createOffscreenCanvas3D();
173    
174                newSize = false;
175            }
176            view.addCanvas3D( offScreenCanvas3D );     
177            view.startView();
178            
179            // The viewGroup contains nodes necessary for rendering, viewing, etc
180            // View, ViewPlatform, Canvas3D, PhysBody, PhysEnviron, and Lights
181            BranchGroup viewGroup = new BranchGroup();
182            
183            // The sceneGroup conatins obejcts of the scene graph
184            BranchGroup sceneGroup = new BranchGroup();
185            
186            setView( view,  viewGroup );
187    //        createMouseBehaviours( viewGroup );
188            
189            OrderedGroup terrainGroup = new OrderedGroup();
190            
191            addBackground( scene.getViewPoint(), terrainGroup, scene.getBackground() );
192            
193            // add the lights to the view
194            Light[] lights = scene.getLights();
195            for (int i = 0; i < lights.length; i++) {
196                viewGroup.addChild( lights[i] );
197            }
198            /*
199            // add the terrain to the view
200            Shape3D terrain[] = scene.getTerrain();
201            for (int i = terrain.length-1; i >= 0; i--) {
202                terrainGroup.addChild( terrain[i] );
203            }        
204            sceneGroup.addChild( terrainGroup );
205            
206            // add the features to the view
207            Group[] features = scene.getFeatures();
208            for (int i = 0; i < features.length; i++) {   
209                sceneGroup.addChild( features[i] );
210            }                
211            */
212            sceneGroup.compile();
213            
214            viewGroup.compile();
215            
216            VirtualUniverse universe = createVirtualUniverse();
217            Locale locale = createLocale( universe );  
218    
219            locale.addBranchGraph(sceneGroup);
220            locale.addBranchGraph(viewGroup);
221            
222            //BranchGroup mainGroup = new BranchGroup();
223    //        mainGroup.addChild( sceneGroup );
224    //        mainGroup.addChild( viewGroup );
225    //        mainGroup.addChild( bg[0] );
226            
227            return offScreenCanvas3D;
228        }
229        
230        /**
231         * creates and returns a canvas for offscreen rendering
232         * @return a canvas for rendering
233         */
234        protected Canvas3D createOffscreenCanvas3D()
235        {   
236            Canvas3D offScreenCanvas3D = createCanvas( false );
237            
238    //        offScreenCanvas3D.getScreen3D().setSize( width, height );
239            
240            offScreenCanvas3D.getScreen3D().setPhysicalScreenHeight( 0.0254/90 * height );
241            offScreenCanvas3D.getScreen3D().setPhysicalScreenWidth( 0.0254/90 * width );
242    
243            BufferedImage renderedImage = 
244                new BufferedImage( width, height, BufferedImage.TYPE_3BYTE_BGR );        
245    
246            ImageComponent2D imageComponent = 
247                new ImageComponent2D( ImageComponent.FORMAT_RGB8, renderedImage );
248    
249            imageComponent.setCapability( ImageComponent.ALLOW_IMAGE_READ );
250    
251    //        offScreenCanvas3D.setOffScreenBuffer( imageComponent );
252            
253            return offScreenCanvas3D;
254        }
255        
256        @SuppressWarnings("unused")
257        private void createMouseBehaviours( Group scene  ){
258            Point3d origin = new Point3d(-2584400.880145242, 528.7904086212667, 5615449.9824785);  
259            BoundingSphere bounds = new BoundingSphere(origin, 250000);
260    //        TransformGroup viewTrans = vp.getViewPlatformTransform();
261                
262    //      Create the rotate behavior node
263            MouseRotate behavior1 = new MouseRotate(offScreenCanvas3D);
264            scene.addChild(behavior1);
265            behavior1.setSchedulingBounds(bounds);
266    
267            // Create the zoom behavior node
268            MouseZoom behavior2 = new MouseZoom(offScreenCanvas3D);
269            scene.addChild(behavior2);
270            behavior2.setSchedulingBounds(bounds);
271    
272            // Create the translate behavior node
273            MouseTranslate behavior3 = new MouseTranslate(offScreenCanvas3D);
274            scene.addChild(behavior3);
275            behavior3.setSchedulingBounds(bounds);
276        }
277        
278        /**
279         * Called to render the scene into the offscreen Canvas3D
280         * @param offScreenCanvas3D the canvas to render into
281         * @return the Rendered Image 
282         */
283        protected RenderedImage getImage(Canvas3D offScreenCanvas3D)
284        {        
285            offScreenCanvas3D.renderOffScreenBuffer();
286            offScreenCanvas3D.waitForOffScreenRendering();
287            
288            ImageComponent2D imageComponent = offScreenCanvas3D.getOffScreenBuffer();
289            
290            return imageComponent.getImage();
291                
292        }
293        
294    }