001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/ogcwebservices/wpvs/j3d/HeightMapTerrain.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     This class uses some code fragments taken from J3D.org open source project
026     which has been publish under LGPL at www.jd3.org.
027    
028     Contact:
029    
030     Andreas Poth
031     lat/lon GmbH
032     Aennchenstr. 19
033     53177 Bonn
034     Germany
035     E-Mail: poth@lat-lon.de
036    
037     Prof. Dr. Klaus Greve
038     Department of Geography
039     University of Bonn
040     Meckenheimer Allee 166
041     53115 Bonn
042     Germany
043     E-Mail: greve@giub.uni-bonn.de
044    
045     ---------------------------------------------------------------------------*/
046    package org.deegree.ogcwebservices.wpvs.j3d;
047    
048    // Standard imports
049    import java.awt.Color;
050    
051    import javax.media.j3d.GeometryArray;
052    import javax.media.j3d.IndexedGeometryArray;
053    import javax.media.j3d.IndexedQuadArray;
054    import javax.media.j3d.IndexedTriangleArray;
055    import javax.media.j3d.IndexedTriangleFanArray;
056    import javax.media.j3d.IndexedTriangleStripArray;
057    import javax.media.j3d.QuadArray;
058    import javax.media.j3d.TriangleArray;
059    import javax.media.j3d.TriangleFanArray;
060    import javax.media.j3d.TriangleStripArray;
061    import javax.vecmath.Color3f;
062    import javax.vecmath.Vector3f;
063    
064    import org.j3d.geom.GeometryData;
065    import org.j3d.geom.UnsupportedTypeException;
066    import org.j3d.geom.terrain.ColorRampGenerator;
067    import org.j3d.geom.terrain.ElevationGridGenerator;
068    
069    /**
070     * 
071     * 
072     * 
073     * @version $Revision: 9345 $
074     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
075     * @author last edited by: $Author: apoth $
076     * 
077     * @version 1.0. $Revision: 9345 $, $Date: 2007-12-27 17:22:25 +0100 (Do, 27 Dez 2007) $
078     * 
079     * @since 2.0
080     */
081    public class HeightMapTerrain extends TerrainModel {
082    
083        /** Width of the terrain to generate */
084        private float terrainWidth;
085    
086        /** Depth of the terrain to generate */
087        private float terrainDepth;
088    
089        /** The last generated terrain heights */
090        private float[][] terrainHeights;
091    
092        /** coloring informations */
093        private ColorRampGenerator colorGenerator;
094    
095        private int geometryType;
096    
097        private boolean centerTerrain;
098    
099        private Vector3f translation;
100    
101        /**
102         * 
103         * @param width
104         *            width of the terrains bbox
105         * @param depth
106         *            depth/height of the terrains bbox
107         * @param heights
108         *            terrain data; heights
109         * @param translation
110         *            of the lowerleft point of the heightmap to the lowerleftpoint of the Java3D model.
111         * @param geometryType
112         *            defines the type/format of the used GeometryArray. supported are:
113         *            <ul>
114         *            <li>GeometryData.TRIANGLES
115         *            <li>GeometryData.QUADS
116         *            <li>GeometryData.INDEXED_QUADS
117         *            <li>GeometryData.INDEXED_TRIANGLES
118         *            <li>GeometryData.TRIANGLE_STRIPS
119         *            <li>GeometryData.TRIANGLE_FANS
120         *            <li>GeometryData.INDEXED_TRIANGLE_STRIPS:
121         *            <li>GeometryData.INDEXED_TRIANGLE_FANS
122         *            </ul>
123         * @param centerTerrain
124         */
125        public HeightMapTerrain( float width, float depth, float[][] heights, Vector3f translation,
126                                int geometryType, boolean centerTerrain ) {
127            terrainWidth = width;
128            terrainDepth = depth;
129            this.terrainHeights = heights;
130            this.translation = translation;
131            colorGenerator = createDefaultColorGenerator();
132            this.geometryType = geometryType;
133            this.centerTerrain = centerTerrain;
134        }
135    
136        /**
137         * 
138         * @param width
139         *            width of the terrains bbox
140         * @param depth
141         *            depth/height of the terrains bbox
142         * @param heights
143         *            terrain data; heights
144         * @param geometryType
145         *            for a description see
146         *            {@link HeightMapTerrain#HeightMapTerrain(float, float, float[][], Vector3f, int, boolean)}
147         * @param centerTerrain
148         * @param colorGenerator
149         */
150        public HeightMapTerrain( float width, float depth, float[][] heights, int geometryType,
151                                boolean centerTerrain, ColorRampGenerator colorGenerator ) {
152    
153            terrainWidth = width;
154            terrainDepth = depth;
155            this.terrainHeights = heights;
156            this.colorGenerator = colorGenerator;
157            if ( this.colorGenerator == null )
158                this.colorGenerator = createDefaultColorGenerator();
159            this.geometryType = geometryType;
160            this.centerTerrain = centerTerrain;
161        }
162    
163        /**
164         * Generate height values only based on the current configuration.
165         * 
166         * @return The last generated height values
167         */
168        public float[][] getTerrainHeights() {
169            return terrainHeights;
170        }
171    
172        /**
173         * Must be called before rendering the terrain!!
174         * 
175         * 
176         */
177        @Override
178        public void createTerrain() {
179    
180            ElevationGridGenerator gridGenerator = new ElevationGridGenerator(
181                                                                               terrainWidth,
182                                                                               terrainDepth,
183                                                                               terrainHeights[0].length,
184                                                                               terrainHeights.length,
185                                                                               translation,
186                                                                               centerTerrain );
187    
188            // set the terrain into the elevation grid handler
189            gridGenerator.setTerrainDetail( terrainHeights, 0 );
190    
191            GeometryData data = new GeometryData();
192            data.geometryType = geometryType;
193            data.geometryComponents = GeometryData.NORMAL_DATA;
194    
195            try {
196                gridGenerator.generate( data );
197            } catch ( UnsupportedTypeException ute ) {
198                System.out.println( "Geometry type is not supported" );
199            }
200    
201            int format = GeometryArray.COORDINATES | GeometryArray.NORMALS | GeometryArray.COLOR_3;
202            colorGenerator.generate( data );
203    
204            GeometryArray geom = createGeometryArray( data, format );
205    
206            geom.setCoordinates( 0, data.coordinates );
207            geom.setNormals( 0, data.normals );
208            //geom.setColors( 0, data.colors );
209    
210            setGeometry( geom );
211        }
212    
213        /**
214         * @return the terrainDepth value.
215         */
216        public float getTerrainDepth() {
217            return terrainDepth;
218        }
219    
220        /**
221         * @return the terrainWidth value.
222         */
223        public float getTerrainWidth() {
224            return terrainWidth;
225        }
226    
227        /**
228         * @return true if the Terrain should be centered.
229         */
230        public boolean isTerrainCentered() {
231            return centerTerrain;
232        }
233    
234        /**
235         * @return the geometryType. For a description of possible values see
236         *         {@link HeightMapTerrain#HeightMapTerrain(float, float, float[][], Vector3f, int, boolean)}
237         */
238        public int getGeometryType() {
239            return geometryType;
240        }
241    
242        /**
243         * Methodfor creating a GeometryArray depending on the passed array format. supported are:
244         * 
245         * @param data
246         *            actual geometry
247         * @param format
248         *            the Internal formats the GeometryArray should have see
249         *            {@link GeometryArray#GeometryArray(int, int)};
250         * @return a GeometryArray instantiated according to the GeometryType in the GeometryData.
251         */
252        protected GeometryArray createGeometryArray( GeometryData data, int format ) {
253            GeometryArray geom = null;
254            IndexedGeometryArray i_geom;
255    
256            switch ( data.geometryType ) {
257            case GeometryData.TRIANGLES:
258                geom = new TriangleArray( data.vertexCount, format );
259                break;
260    
261            case GeometryData.QUADS:
262                geom = new QuadArray( data.vertexCount, format );
263                break;
264    
265            case GeometryData.INDEXED_QUADS:
266    
267                i_geom = new IndexedQuadArray( data.vertexCount, format, data.indexesCount );
268                i_geom.setCoordinateIndices( 0, data.indexes );
269                i_geom.setColorIndices( 0, data.indexes );
270                i_geom.setNormalIndices( 0, data.indexes );
271                geom = i_geom;
272                break;
273            case GeometryData.INDEXED_TRIANGLES:
274    
275                i_geom = new IndexedTriangleArray( data.vertexCount, format, data.indexesCount );
276                i_geom.setCoordinateIndices( 0, data.indexes );
277                i_geom.setColorIndices( 0, data.indexes );
278                i_geom.setNormalIndices( 0, data.indexes );
279                geom = i_geom;
280                break;
281    
282            case GeometryData.TRIANGLE_STRIPS:
283                geom = new TriangleStripArray( data.vertexCount, format, data.stripCounts );
284                break;
285    
286            case GeometryData.TRIANGLE_FANS:
287                geom = new TriangleFanArray( data.vertexCount, format, data.stripCounts );
288                break;
289    
290            case GeometryData.INDEXED_TRIANGLE_STRIPS:
291                i_geom = new IndexedTriangleStripArray( data.vertexCount, format, data.indexesCount,
292                                                        data.stripCounts );
293                i_geom.setCoordinateIndices( 0, data.indexes );
294                i_geom.setColorIndices( 0, data.indexes );
295                i_geom.setNormalIndices( 0, data.indexes );
296                geom = i_geom;
297                break;
298    
299            case GeometryData.INDEXED_TRIANGLE_FANS:
300                i_geom = new IndexedTriangleFanArray( data.vertexCount, format, data.indexesCount,
301                                                      data.stripCounts );
302                i_geom.setCoordinateIndices( 0, data.indexes );
303                i_geom.setColorIndices( 0, data.indexes );
304                i_geom.setNormalIndices( 0, data.indexes );
305                geom = i_geom;
306                break;
307            }
308            return geom;
309        }
310    
311        private ColorRampGenerator createDefaultColorGenerator() {
312            Color3f[] colors = new Color3f[2];
313            colors[0] = new Color3f( Color.WHITE );
314            colors[1] = new Color3f( Color.BLACK );
315            float[] heights = new float[2];
316            heights[0] = -150;
317            heights[1] = 1500;
318            return new ColorRampGenerator( heights, colors );
319        }
320    
321        /**
322         * @return the translation value.
323         */
324        public Vector3f getTranslation() {
325            return translation;
326        }
327    
328    }