001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/ogcwebservices/wpvs/j3d/WPVSScene.java $
002    /*----------------    FILE HEADER  ------------------------------------------
003    
004     This file is part of deegree.
005     Copyright (C) 2001-2008 by:
006     EXSE, Department of Geography, University of Bonn
007     http://www.giub.uni-bonn.de/deegree/
008     lat/lon GmbH
009     http://www.lat-lon.de
010    
011     This library is free software; you can redistribute it and/or
012     modify it under the terms of the GNU Lesser General Public
013     License as published by the Free Software Foundation; either
014     version 2.1 of the License, or (at your option) any later version.
015    
016     This library is distributed in the hope that it will be useful,
017     but WITHOUT ANY WARRANTY; without even the implied warranty of
018     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
019     Lesser General Public License for more details.
020    
021     You should have received a copy of the GNU Lesser General Public
022     License along with this library; if not, write to the Free Software
023     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
024    
025     Contact:
026    
027     Andreas Poth
028     lat/lon GmbH
029     Aennchenstraße 19
030     53177 Bonn
031     Germany
032     E-Mail: poth@lat-lon.de
033    
034     Prof. Dr. Klaus Greve
035     Department of Geography
036     University of Bonn
037     Meckenheimer Allee 166
038     53115 Bonn
039     Germany
040     E-Mail: greve@giub.uni-bonn.de
041     
042     ---------------------------------------------------------------------------*/
043    package org.deegree.ogcwebservices.wpvs.j3d;
044    
045    import java.util.ArrayList;
046    import java.util.Calendar;
047    import java.util.GregorianCalendar;
048    import java.util.List;
049    
050    import javax.media.j3d.AmbientLight;
051    import javax.media.j3d.BoundingSphere;
052    import javax.media.j3d.DirectionalLight;
053    import javax.media.j3d.Light;
054    import javax.media.j3d.Node;
055    import javax.media.j3d.OrderedGroup;
056    import javax.vecmath.Color3f;
057    import javax.vecmath.Point3d;
058    import javax.vecmath.Vector3f;
059    
060    import org.deegree.framework.log.ILogger;
061    import org.deegree.framework.log.LoggerFactory;
062    import org.deegree.i18n.Messages;
063    import org.deegree.ogcwebservices.wpvs.utils.SunLight;
064    import org.deegree.ogcwebservices.wpvs.utils.SunPosition;
065    
066    /**
067     * This class represents the basic class for creation of a 3D perspective views as specified in the
068     * OGC Web Perpective View Service specification. A WPVS scene is defined by a scene model and a
069     * date determining the light conditions. Additional elements are 3D or 2.5D-features that are
070     * placed into the scene, atmospheric conditions influencing the light and visibility (e.g. fog,
071     * rain etc., but currently not implemented) and additional light placed into the scene (e.g. street
072     * lights, spots, lighted windows etc.).
073     * <p>
074     * -----------------------------------------------------------------------
075     * </p>
076     * 
077     * @author <a href="mailto:lupp@lat-lon.de">Katharina Lupp</a>
078     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
079     *
080     * @author last edited by: $Author: apoth $
081     * @version $Revision: 9345 $ $Date: 2007-12-27 17:22:25 +0100 (Do, 27 Dez 2007) $
082     */
083    public class WPVSScene {
084        
085        private static ILogger LOG = LoggerFactory.getLogger( WPVSScene.class );
086    
087        private Calendar calendar;
088    
089        private OrderedGroup scene;
090    
091        private List<Light> lights;
092    
093        private ViewPoint viewPoint;
094    
095        private Node background;
096    
097        /**
098         * Creates a new instance of WPVScene
099         * 
100         * @param scene
101         *            java3D representation of the scene.
102         * @param viewPoint
103         *            object that describes the viewers position and the looking direction
104         * @param calendar
105         *            describtion of the date and time for which the scene shall be rendered --> light
106         *            conditions
107         * @param lights
108         *            lights in addition to sun and ambient light (e.g. street lights, spots etc.)
109         * @param background
110         *            scene background; have to be a <code>Shape3D</code> or a <code>Background</code>
111         */
112        public WPVSScene( OrderedGroup scene, ViewPoint viewPoint, Calendar calendar,
113                         List<Light> lights, Node background ) {
114            if ( lights != null ) {
115                this.lights = lights;
116            } else {
117                this.lights = new ArrayList<Light>();
118            }
119            this.scene = scene;
120            this.viewPoint = viewPoint;
121            this.calendar = calendar;
122            if( calendar == null ){
123                LOG.logDebug( Messages.getMessage( "WPVS_STANDARD_TIME" ) );
124                this.calendar = new GregorianCalendar(2007, 2, 21, 12, 00 );
125            }
126            this.background = background;
127            createDayLight();
128        }
129    
130        /**
131         * creates the light that results from the sun (direct light) and the ambient of the sky.
132         */
133        private void createDayLight() {
134    
135            int latitute = 52;
136            SunPosition sp = new SunPosition( calendar );
137            SunLight sl = new SunLight( latitute, sp );
138            Color3f sunlightColor = sl.calculateSunlight(  );
139            double vPos = sp.getVerticalSunposition( latitute );
140            double hPos = sp.getHorizontalSunPosition(  );
141    
142            Point3d p = getViewPoint().getObserverPosition();
143            Point3d origin = new Point3d( p.x, p.y, p.z );
144            BoundingSphere light_bounds = new BoundingSphere( origin, 250000 );
145    
146            // Directional Light: A DirectionalLight node defines an oriented light with an origin at
147            // infinity.
148            DirectionalLight headlight = new DirectionalLight();
149            headlight.setInfluencingBounds( light_bounds );
150            headlight.setColor( sunlightColor );
151            headlight.setDirection( (float) Math.sin( hPos ), (float) Math.sin( vPos ), (float) -Math.abs( Math.cos( hPos ) ) );
152            Vector3f tmp = new Vector3f();
153            headlight.getDirection( tmp );
154            lights.add( headlight );
155            // Ambient Light: Ambient light is that light that seems to come from all directions.
156            // Ambient light has only an ambient reflection component.
157            // It does not have diffuse or specular reflection components.
158            AmbientLight al = new AmbientLight();
159            al.setInfluencingBounds( light_bounds );
160            al.setColor( new Color3f( 0.7f * sunlightColor.x, 0.65f * sunlightColor.y, 0.6f * sunlightColor.z ) );
161            
162            lights.add( al );
163        }
164    
165        /**
166         * @return the background object of the scene.
167         */
168        public Node getBackground() {
169            return background;
170        }
171    
172        /**
173         * @param background
174         *            sets the <code>Background</code> object of the scene
175         */
176        public void setBackground( Node background ) {
177            this.background = background;
178        }
179    
180    
181        /**
182         * get the date and the time for determining time depending the light conditions of the scene
183         * 
184         * @return describtion of the date and time for which the scene shall be rendered --> light
185         *         conditions
186         */
187        public Calendar getDate() {
188            return calendar;
189        }
190    
191        /**
192         * set the date and the time for determining time depending the light conditions of the scene
193         * 
194         * @param calendar
195         *            describtion of the date and time for which the scene shall be rendered --> light
196         *            conditions
197         */
198        public void setDate( Calendar calendar ) {
199            if ( calendar == null ) {
200                LOG.logDebug( Messages.getMessage( "WPVS_STANDARD_TIME" ) );
201                this.calendar = new GregorianCalendar(2007, 2, 21, 12, 00 );
202            }
203            this.calendar = calendar;
204        }
205    
206        /**
207         * @return Java3D representation of the scene.
208         */
209        public OrderedGroup getScene() {
210            return scene;
211        }
212    
213        /**
214         * gets the position of the viewer, the directions he looks and his field of view in radians
215         * 
216         * @return object that describes the viewers position and the point he looks at
217         */
218        public ViewPoint getViewPoint() {
219            return viewPoint;
220        }
221    
222        /**
223         * defines the position of the viewer and the point he looks at.
224         * 
225         * @param viewPoint
226         *            object that describes the viewers position and the point he looks at
227         */
228        public void setViewPoint( ViewPoint viewPoint ) {
229            this.viewPoint = viewPoint;
230        }
231    
232        /**
233         * adds a light to the scene. this can be ambient, directional and point light.
234         * 
235         * @param light
236         *            a light in addition to sun and basic ambient light (e.g. street lights, spots
237         *            etc.)
238         */
239        public void addLight( Light light ) {
240            this.lights.add( light );
241        }
242    
243        /**
244         * returns the lights of the scene
245         * 
246         * @return lights including sun and basic ambient light (e.g. street lights, spots etc.)
247         */
248        public Light[] getLights() {
249            return lights.toArray( new Light[lights.size()] );
250        }
251    
252        /**
253         * sets the lights of the scene. this can be ambient, directional and point light.
254         * 
255         * @param lights
256         *            lights in addition to sun and basic ambient light (e.g. street lights, spots etc.)
257         */
258        public void setLights( Light[] lights ) {
259            this.lights.clear();
260            setDate( calendar );
261            createDayLight();
262            if ( lights != null ) {
263                for ( int i = 0; i < lights.length; i++ ) {
264                    addLight( lights[i] );
265                }
266            }
267        }
268    }