001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_testing/src/org/deegree/ogcwebservices/wpvs/j3d/HeightMapTerrain.java $
002    /*----------------------------------------------------------------------------
003     This file is part of deegree.
004     Copyright (C) 2001-2009 by:
005     Department of Geography, University of Bonn
006     http://www.geographie.uni-bonn.de/deegree/
007     and
008     lat/lon GmbH
009     http://lat-lon.de/
010    
011     Additional copyright notes:
012    
013     This class uses some code fragments taken from J3D.org open source project
014     which has been published under LGPL at www.jd3.org.
015    
016     This library is free software; you can redistribute it and/or modify it under
017     the terms of the GNU Lesser General Public License as published by the Free
018     Software Foundation; either version 2.1 of the License, or (at your option)
019     any later version.
020     This library is distributed in the hope that it will be useful, but WITHOUT
021     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
022     FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
023     details.
024     You should have received a copy of the GNU Lesser General Public License
025     along with this library; if not, write to the Free Software Foundation, Inc.,
026     59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
027    
028     Contact information:
029    
030     lat/lon GmbH
031     Aennchenstr. 19, 53177 Bonn
032     Germany
033    
034     Department of Geography, University of Bonn
035     Prof. Dr. Klaus Greve
036     Postfach 1147, 53001 Bonn
037     Germany
038    
039     e-mail: info@deegree.org
040     ----------------------------------------------------------------------------*/
041    
042    package org.deegree.ogcwebservices.wpvs.j3d;
043    
044    // import java.awt.Color;
045    
046    import java.awt.Color;
047    
048    import javax.media.j3d.GeometryArray;
049    import javax.media.j3d.IndexedGeometryArray;
050    import javax.media.j3d.IndexedQuadArray;
051    import javax.media.j3d.IndexedTriangleArray;
052    import javax.media.j3d.IndexedTriangleFanArray;
053    import javax.media.j3d.IndexedTriangleStripArray;
054    import javax.media.j3d.QuadArray;
055    import javax.media.j3d.TriangleArray;
056    import javax.media.j3d.TriangleFanArray;
057    import javax.media.j3d.TriangleStripArray;
058    import javax.vecmath.Color3f;
059    import javax.vecmath.Vector3f;
060    
061    import org.j3d.geom.GeometryData;
062    import org.j3d.geom.UnsupportedTypeException;
063    import org.j3d.geom.terrain.ColorRampGenerator;
064    import org.j3d.geom.terrain.ElevationGridGenerator;
065    
066    /**
067     * 
068     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
069     * @author last edited by: $Author: rbezema $
070     * 
071     * @version $Revision: 20601 $, $Date: 2009-11-05 16:25:55 +0100 (Do, 05. Nov 2009) $
072     */
073    public class HeightMapTerrain extends TerrainModel {
074    
075        /** Width of the terrain to generate */
076        private float terrainWidth;
077    
078        /** Depth of the terrain to generate */
079        private float terrainDepth;
080    
081        /** The last generated terrain heights */
082        private float[][] terrainHeights;
083    
084        /** coloring informations */
085        private ColorRampGenerator colorGenerator;
086    
087        private int geometryType;
088    
089        private boolean centerTerrain;
090    
091        private Vector3f translation;
092    
093        /**
094         * 
095         * @param width
096         *            width of the terrains bbox
097         * @param depth
098         *            depth/height of the terrains bbox
099         * @param heights
100         *            terrain data; heights
101         * @param translation
102         *            of the lowerleft point of the heightmap to the lowerleftpoint of the Java3D model.
103         * @param geometryType
104         *            defines the type/format of the used GeometryArray. supported are:
105         *            <ul>
106         *            <li>GeometryData.TRIANGLES
107         *            <li>GeometryData.QUADS
108         *            <li>GeometryData.INDEXED_QUADS
109         *            <li>GeometryData.INDEXED_TRIANGLES
110         *            <li>GeometryData.TRIANGLE_STRIPS
111         *            <li>GeometryData.TRIANGLE_FANS
112         *            <li>GeometryData.INDEXED_TRIANGLE_STRIPS:
113         *            <li>GeometryData.INDEXED_TRIANGLE_FANS
114         *            </ul>
115         * @param centerTerrain
116         */
117        public HeightMapTerrain( float width, float depth, float[][] heights, Vector3f translation, int geometryType,
118                                 boolean centerTerrain ) {
119            terrainWidth = width;
120            terrainDepth = depth;
121            this.terrainHeights = heights;
122            this.translation = translation;
123            colorGenerator = createDefaultColorGenerator();
124            this.geometryType = geometryType;
125            this.centerTerrain = centerTerrain;
126        }
127    
128        /**
129         * 
130         * @param width
131         *            width of the terrains bbox
132         * @param depth
133         *            depth/height of the terrains bbox
134         * @param heights
135         *            terrain data; heights
136         * @param geometryType
137         *            for a description see
138         *            {@link HeightMapTerrain#HeightMapTerrain(float, float, float[][], Vector3f, int, boolean)}
139         * @param centerTerrain
140         * @param colorGenerator
141         */
142        public HeightMapTerrain( float width, float depth, float[][] heights, int geometryType, boolean centerTerrain,
143                                 ColorRampGenerator colorGenerator ) {
144    
145            terrainWidth = width;
146            terrainDepth = depth;
147            this.terrainHeights = heights;
148            this.colorGenerator = colorGenerator;
149            if ( this.colorGenerator == null )
150                this.colorGenerator = createDefaultColorGenerator();
151            this.geometryType = geometryType;
152            this.centerTerrain = centerTerrain;
153        }
154    
155        /**
156         * Generate height values only based on the current configuration.
157         * 
158         * @return The last generated height values
159         */
160        public float[][] getTerrainHeights() {
161            return terrainHeights;
162        }
163    
164        /**
165         * Must be called before rendering the terrain!!
166         * 
167         * 
168         */
169        @Override
170        public void createTerrain() {
171    
172            ElevationGridGenerator gridGenerator = new ElevationGridGenerator( terrainWidth, terrainDepth,
173                                                                               terrainHeights[0].length,
174                                                                               terrainHeights.length, translation,
175                                                                               centerTerrain );
176    
177            // set the terrain into the elevation grid handler
178            gridGenerator.setTerrainDetail( terrainHeights, 0 );
179    
180            GeometryData data = new GeometryData();
181            data.geometryType = geometryType;
182            data.geometryComponents = GeometryData.NORMAL_DATA;
183            try {
184                gridGenerator.generate( data );
185            } catch ( UnsupportedTypeException ute ) {
186                System.out.println( "Geometry type is not supported" );
187            }
188    
189            int format = GeometryArray.COORDINATES | GeometryArray.NORMALS | GeometryArray.COLOR_3;
190            colorGenerator.generate( data );
191    
192            GeometryArray geom = createGeometryArray( data, format );
193    
194            geom.setCoordinates( 0, data.coordinates );
195            geom.setNormals( 0, data.normals );
196            // geom.setColors( 0, data.colors );
197    
198            setGeometry( geom );
199        }
200    
201        /**
202         * @return the terrainDepth value.
203         */
204        public float getTerrainDepth() {
205            return terrainDepth;
206        }
207    
208        /**
209         * @return the terrainWidth value.
210         */
211        public float getTerrainWidth() {
212            return terrainWidth;
213        }
214    
215        /**
216         * @return true if the Terrain should be centered.
217         */
218        public boolean isTerrainCentered() {
219            return centerTerrain;
220        }
221    
222        /**
223         * @return the geometryType. For a description of possible values see
224         *         {@link HeightMapTerrain#HeightMapTerrain(float, float, float[][], Vector3f, int, boolean)}
225         */
226        public int getGeometryType() {
227            return geometryType;
228        }
229    
230        /**
231         * Methodfor creating a GeometryArray depending on the passed array format. supported are:
232         * 
233         * @param data
234         *            actual geometry
235         * @param format
236         *            the Internal formats the GeometryArray should have see {@link GeometryArray#GeometryArray(int, int)};
237         * @return a GeometryArray instantiated according to the GeometryType in the GeometryData.
238         */
239        protected GeometryArray createGeometryArray( GeometryData data, int format ) {
240            GeometryArray geom = null;
241            IndexedGeometryArray i_geom;
242    
243            switch ( data.geometryType ) {
244            case GeometryData.TRIANGLES:
245                geom = new TriangleArray( data.vertexCount, format );
246                break;
247    
248            case GeometryData.QUADS:
249                geom = new QuadArray( data.vertexCount, format );
250                break;
251    
252            case GeometryData.INDEXED_QUADS:
253    
254                i_geom = new IndexedQuadArray( data.vertexCount, format, data.indexesCount );
255                i_geom.setCoordinateIndices( 0, data.indexes );
256                i_geom.setColorIndices( 0, data.indexes );
257                i_geom.setNormalIndices( 0, data.indexes );
258                geom = i_geom;
259                break;
260            case GeometryData.INDEXED_TRIANGLES:
261    
262                i_geom = new IndexedTriangleArray( data.vertexCount, format, data.indexesCount );
263                i_geom.setCoordinateIndices( 0, data.indexes );
264                i_geom.setColorIndices( 0, data.indexes );
265                i_geom.setNormalIndices( 0, data.indexes );
266                geom = i_geom;
267                break;
268    
269            case GeometryData.TRIANGLE_STRIPS:
270                geom = new TriangleStripArray( data.vertexCount, format, data.stripCounts );
271                break;
272    
273            case GeometryData.TRIANGLE_FANS:
274                geom = new TriangleFanArray( data.vertexCount, format, data.stripCounts );
275                break;
276    
277            case GeometryData.INDEXED_TRIANGLE_STRIPS:
278                i_geom = new IndexedTriangleStripArray( data.vertexCount, format, data.indexesCount, data.stripCounts );
279                i_geom.setCoordinateIndices( 0, data.indexes );
280                i_geom.setColorIndices( 0, data.indexes );
281                i_geom.setNormalIndices( 0, data.indexes );
282                geom = i_geom;
283                break;
284    
285            case GeometryData.INDEXED_TRIANGLE_FANS:
286                i_geom = new IndexedTriangleFanArray( data.vertexCount, format, data.indexesCount, data.stripCounts );
287                i_geom.setCoordinateIndices( 0, data.indexes );
288                i_geom.setColorIndices( 0, data.indexes );
289                i_geom.setNormalIndices( 0, data.indexes );
290                geom = i_geom;
291                break;
292            }
293            return geom;
294        }
295    
296        private ColorRampGenerator createDefaultColorGenerator() {
297            Color3f[] colors = new Color3f[2];
298            colors[0] = new Color3f( Color.WHITE );
299            colors[1] = new Color3f( Color.BLACK );
300            float[] heights = new float[2];
301            heights[0] = -150;
302            heights[1] = 1500;
303            return new ColorRampGenerator( heights, colors );
304        }
305    
306        /**
307         * @return the translation value.
308         */
309        public Vector3f getTranslation() {
310            return translation;
311        }
312    }