001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/ogcwebservices/wpvs/j3d/TriangleTerrain.java $ 002 /*---------------------------------------------------------------------------- 003 This file is part of deegree, http://deegree.org/ 004 Copyright (C) 2001-2009 by: 005 Department of Geography, University of Bonn 006 and 007 lat/lon GmbH 008 009 This library is free software; you can redistribute it and/or modify it under 010 the terms of the GNU Lesser General Public License as published by the Free 011 Software Foundation; either version 2.1 of the License, or (at your option) 012 any later version. 013 This library is distributed in the hope that it will be useful, but WITHOUT 014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 015 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 016 details. 017 You should have received a copy of the GNU Lesser General Public License 018 along with this library; if not, write to the Free Software Foundation, Inc., 019 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 020 021 Contact information: 022 023 lat/lon GmbH 024 Aennchenstr. 19, 53177 Bonn 025 Germany 026 http://lat-lon.de/ 027 028 Department of Geography, University of Bonn 029 Prof. Dr. Klaus Greve 030 Postfach 1147, 53001 Bonn 031 Germany 032 http://www.geographie.uni-bonn.de/deegree/ 033 034 e-mail: info@deegree.org 035 ----------------------------------------------------------------------------*/ 036 037 package org.deegree.ogcwebservices.wpvs.j3d; 038 039 import java.awt.image.BufferedImage; 040 import java.util.ArrayList; 041 import java.util.List; 042 043 import javax.vecmath.Point3d; 044 import javax.vecmath.Point3f; 045 import javax.vecmath.TexCoord2f; 046 047 import org.deegree.framework.log.ILogger; 048 import org.deegree.framework.log.LoggerFactory; 049 import org.deegree.model.spatialschema.Envelope; 050 import org.deegree.model.spatialschema.Position; 051 import org.deegree.ogcwebservices.wpvs.utils.VisADWrapper; 052 053 import com.sun.j3d.utils.geometry.GeometryInfo; 054 import com.sun.j3d.utils.geometry.NormalGenerator; 055 056 /** 057 * The <code>TriangleTerrain</code> class respresents the Java3D shape of a set of measurepoints. Before this Terrrain 058 * can be drawn the createTerrain method must be invoked, it will create triangles of the given measurepoints and will 059 * add the optional texture to the apearance of the Shap3D. 060 * 061 * @author <a href="mailto:bezema@lat-lon.de">Rutger Bezema</a> 062 * 063 * @author last edited by: $Author: mschneider $ 064 * 065 * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18 Jun 2009) $ 066 * 067 */ 068 069 public class TriangleTerrain extends TerrainModel { 070 071 private static ILogger LOG = LoggerFactory.getLogger( TriangleTerrain.class ); 072 073 private Envelope boundingBox; 074 075 private double terrainWidth; 076 077 private double terrainHeight; 078 079 private List<Point3d> measurePoints = null; 080 081 private double minimalHeightlevel; 082 083 084 private double scale; 085 086 /** 087 * @param measurePoints 088 * indicating height values inside this terrain. They will be triangulated in the createTerrain method. 089 * @param env the bbox of this triangle terrain. 090 * @param minimalHeightlevel 091 * which will be used if the measurepoints have no height set. 092 * @param scale 093 * to multiply onto the z-value of the measurepoints 094 */ 095 public TriangleTerrain( List<Point3d> measurePoints, Envelope env, double minimalHeightlevel, double scale ) { 096 super(); 097 this.measurePoints = measurePoints; 098 this.minimalHeightlevel = minimalHeightlevel; 099 this.scale = scale; 100 101 boundingBox = env; 102 103 this.terrainWidth = boundingBox.getWidth(); 104 this.terrainHeight = boundingBox.getHeight(); 105 } 106 107 /** 108 * @return the boundingBox of this TriangleTerrain 109 */ 110 public Envelope getBoundingBox() { 111 return boundingBox; 112 } 113 114 @Override 115 public void createTerrain() { 116 List<float[][]> triangles = new ArrayList<float[][]>(); 117 if ( measurePoints == null || measurePoints.size() == 0 ) { // just a square, asssuming a simple plane, 118 triangles = createFlatTerrain( ); 119 } else { 120 LOG.logDebug( "Trying to create triangles with the visad library" ); 121 long time = System.currentTimeMillis(); 122 VisADWrapper vw = new VisADWrapper( measurePoints, scale ); 123 triangles = vw.getTriangleCollectionAsList(); 124 if( triangles != null ){ 125 LOG.logDebug( new StringBuilder("Creation of ").append( triangles.size()).append( " triangles with the visad library was successfull. (took: ").append( (System.currentTimeMillis() - time) / 1000d).append(" seconds).").toString() ); 126 } else{ 127 LOG.logDebug( new StringBuilder("Creation of triangles with the visad library was NOT successfull. Creating a flat terrain.").toString() ); 128 triangles = createFlatTerrain( ); 129 } 130 131 } 132 133 double widthInv = 1d / terrainWidth; 134 double heightInv = 1d / terrainHeight; 135 Position originalLowerLeft = boundingBox.getMin(); 136 137 GeometryInfo geometryInfo = new GeometryInfo( GeometryInfo.TRIANGLE_ARRAY ); 138 139 BufferedImage texture = getTexture(); 140 if ( texture != null ){ 141 geometryInfo.setTextureCoordinateParams( 1, 2 ); 142 } 143 144 Point3f[] coordinates = new Point3f[triangles.size() * 3]; 145 TexCoord2f[] texCoords = new TexCoord2f[triangles.size() * 3]; 146 147 int coordNr = 0; 148 for ( float[][] triangleCoords : triangles ) { 149 for ( int k = 0; k < 3; k++ ) { 150 // System.out.println( Thread.currentThread() + "-> coordNR: " + coordNr ); 151 Point3f modelCoordinate = new Point3f( triangleCoords[k][0], triangleCoords[k][1], triangleCoords[k][2] ); 152 coordinates[coordNr] = modelCoordinate; 153 154 if ( texture != null ) { 155 double texCoordX = ( modelCoordinate.x - originalLowerLeft.getX() ) * widthInv; 156 double texCoordY = ( modelCoordinate.y - originalLowerLeft.getY() ) * heightInv; 157 texCoordX = ( texCoordX > 1 ) ? 1 : ( ( texCoordX < 0 ) ? 0 : texCoordX ); 158 texCoordY = ( texCoordY > 1 ) ? 1 : ( ( texCoordY < 0 ) ? 0 : texCoordY ); 159 texCoords[coordNr] = new TexCoord2f( (float)texCoordX ,(float) texCoordY ); 160 } 161 coordNr++; 162 } 163 164 } 165 geometryInfo.setCoordinates( coordinates ); 166 if ( texture != null ) { 167 geometryInfo.setTextureCoordinates( 0, texCoords ); 168 } 169 geometryInfo.recomputeIndices(); 170 NormalGenerator ng = new NormalGenerator(); 171 ng.generateNormals( geometryInfo ); 172 173 setGeometry( geometryInfo.getGeometryArray() ); 174 } 175 176 private List<float[][]> createFlatTerrain( ){ 177 LOG.logDebug( "Creating a flat square at minimalTerrain height, which will represent the terrain." ); 178 List<float[][]> triangles = new ArrayList<float[][]>(); 179 Position min = boundingBox.getMin(); 180 Position max = boundingBox.getMax(); 181 float[][] triangle = new float[3][3]; 182 triangle[0][0] = (float) min.getX(); 183 triangle[0][1] = (float) min.getY(); 184 triangle[0][2] = (float) minimalHeightlevel; 185 186 triangle[1][0] = (float) max.getX(); 187 triangle[1][1] = (float) min.getY(); 188 triangle[1][2] = (float) minimalHeightlevel; 189 190 triangle[2][0] = (float) min.getX(); 191 triangle[2][1] = (float) max.getY(); 192 triangle[2][2] = (float) minimalHeightlevel; 193 194 triangles.add( triangle ); 195 196 triangle = new float[3][3]; 197 triangle[0][0] = (float) max.getX(); 198 triangle[0][1] = (float) min.getY(); 199 triangle[0][2] = (float) minimalHeightlevel; 200 201 triangle[1][0] = (float) max.getX(); 202 triangle[1][1] = (float) max.getY(); 203 triangle[1][2] = (float) minimalHeightlevel; 204 205 triangle[2][0] = (float) min.getX(); 206 triangle[2][1] = (float) max.getY(); 207 triangle[2][2] = (float) minimalHeightlevel; 208 triangles.add( triangle ); 209 return triangles; 210 } 211 212 }