001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/ogcwebservices/wpvs/j3d/TexturedSurface.java $ 002 /*---------------- FILE HEADER ------------------------------------------ 003 004 This file is part of deegree. 005 Copyright (C) 2001-2006 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 Aennchenstr. 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.awt.image.BufferedImage; 046 import java.io.IOException; 047 import java.net.URL; 048 049 import javax.media.j3d.Appearance; 050 import javax.media.j3d.Material; 051 import javax.media.j3d.TexCoordGeneration; 052 import javax.media.j3d.Texture; 053 import javax.vecmath.Vector4f; 054 055 import org.deegree.framework.util.ImageUtils; 056 import org.deegree.model.spatialschema.Position; 057 import org.deegree.model.spatialschema.Ring; 058 import org.deegree.model.spatialschema.Surface; 059 import org.deegree.ogcwebservices.wpvs.configuration.RenderingConfiguration; 060 061 import com.sun.j3d.utils.geometry.GeometryInfo; 062 import com.sun.j3d.utils.geometry.NormalGenerator; 063 import com.sun.j3d.utils.image.TextureLoader; 064 065 /** 066 * 067 * 068 * 069 * @version $Revision: 6259 $ 070 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a> 071 * @author last edited by: $Author: bezema $ 072 * 073 * @version 1.0. $Revision: 6259 $, $Date: 2007-03-20 10:15:15 +0100 (Di, 20 Mär 2007) $ 074 * 075 * @since 2.0 076 */ 077 public class TexturedSurface extends ColoredSurface { 078 079 private Texture texture = null; 080 081 private BufferedImage textureImg = null; 082 083 private float[][] textureCoords = null; 084 085 /** 086 * creates a TexturedSurface from a geometry, color informations and a texture image. Since a 087 * texture image be somehow transparent it is useful to be able to define a surfaces color. This 088 * constructor will use default coordinates to adjust a texture onto a surface. 089 * 090 * @param objectID 091 * an Id for this Surface, for example a db primary key 092 * @param parentID 093 * an Id for the parent of this Surface, for example if this is a wall the parent is 094 * the building. 095 * @param surface 096 * the ogc:geometry surface which holds the point references of a polygon, not to be 097 * confused with a j3d Object which this class represents. 098 * @param red 099 * @param green 100 * @param blue 101 * @param transparency 102 * @param textureImg 103 */ 104 public TexturedSurface( String objectID, String parentID, Surface surface, float red, 105 float green, float blue, float transparency, BufferedImage textureImg ) { 106 super( objectID, parentID, surface, red, green, blue, transparency ); 107 this.textureImg = textureImg; 108 createTexture( textureImg ); 109 setAppearance( createAppearance() ); 110 } 111 112 /** 113 * creates a TexturedSurface from a geometry, Material and a texture image. Since a texture 114 * image be somehow transparent it is useful to be able to define a surfaces color. This 115 * constructor will use default coordinates to adjust a texture onto a surface. 116 * 117 * @param objectID 118 * an Id for this Surface, for example a db primary key 119 * @param parentID 120 * an Id for the parent of this Surface, for example if this is a wall the parent is 121 * the building. 122 * @param surface 123 * the ogc:geometry surface which holds the point references of a polygon, not to be 124 * confused with a j3d Object which this class represents. 125 * @param material 126 * @param transparency 127 * @param textureImg 128 */ 129 public TexturedSurface( String objectID, String parentID, Surface surface, Material material, 130 float transparency, BufferedImage textureImg ) { 131 super( objectID, parentID, surface, material, transparency ); 132 this.textureImg = textureImg; 133 createTexture( textureImg ); 134 setAppearance( createAppearance() ); 135 } 136 137 /** 138 * creates a TexturedSurface from a geometry, color informations and a reference to a texture 139 * image. Since a texture image be somehow transparent it is useful to be able to define a 140 * surfaces color. This constructor will use default coordinates to adjust a texture onto a 141 * surface. 142 * 143 * @param objectID 144 * an Id for this Surface, for example a db primary key 145 * @param parentID 146 * an Id for the parent of this Surface, for example if this is a wall the parent is 147 * the building. 148 * @param surface 149 * the ogc:geometry surface which holds the point references of a polygon, not to be 150 * confused with a j3d Object which this class represents. 151 * @param red 152 * @param green 153 * @param blue 154 * @param transparency 155 * @param textureImg 156 * @throws IOException 157 */ 158 public TexturedSurface( String objectID, String parentID, Surface surface, float red, 159 float green, float blue, float transparency, URL textureImg ) 160 throws IOException { 161 super( objectID, parentID, surface, red, green, blue, transparency ); 162 this.textureImg = ImageUtils.loadImage( textureImg ); 163 createTexture( this.textureImg ); 164 setAppearance( createAppearance() ); 165 } 166 167 /** 168 * creates a TexturedSurface from a geometry, Material and a reference to a texture image. Since 169 * a texture image be somehow transparent it is useful to be able to define a surfaces color. 170 * This constructor will use default coordinates to adjust a texture onto a surface. 171 * 172 * @param objectID 173 * an Id for this Surface, for example a db primary key 174 * @param parentID 175 * an Id for the parent of this Surface, for example if this is a wall the parent is 176 * the building. 177 * @param surface 178 * the ogc:geometry surface which holds the point references of a polygon, not to be 179 * confused with a j3d Object which this class represents. 180 * @param material 181 * @param transparency 182 * @param textureImg 183 * @throws IOException 184 */ 185 public TexturedSurface( String objectID, String parentID, Surface surface, Material material, 186 float transparency, URL textureImg ) throws IOException { 187 super( objectID, parentID, surface, material, transparency ); 188 189 this.textureImg = ImageUtils.loadImage( textureImg ); 190 createTexture( this.textureImg ); 191 setAppearance( createAppearance() ); 192 } 193 194 /** 195 * creates a TexturedSurface from a geometry, color informations and a texture image. Since a 196 * texture image be somehow transparent it is useful to be able to define a surfaces color. 197 * 198 * @param objectID 199 * an Id for this Surface, for example a db primary key 200 * @param parentID 201 * an Id for the parent of this Surface, for example if this is a wall the parent is 202 * the building. 203 * @param surface 204 * the ogc:geometry surface which holds the point references of a polygon, not to be 205 * confused with a j3d Object which this class represents. 206 * @param red 207 * @param green 208 * @param blue 209 * @param transparency 210 * @param textureImg 211 * @param textureCoords 212 */ 213 public TexturedSurface( String objectID, String parentID, Surface surface, float red, 214 float green, float blue, float transparency, BufferedImage textureImg, 215 float[][] textureCoords ) { 216 super( objectID, parentID, surface, red, green, blue, transparency ); 217 218 this.textureImg = textureImg; 219 this.textureCoords = textureCoords; 220 createTexture( textureImg ); 221 setAppearance( createAppearance() ); 222 223 } 224 225 /** 226 * creates a TexturedSurface from a geometry, Material and a texture image. Since a texture 227 * image be somehow transparent it is useful to be able to define a surfaces color. 228 * 229 * @param objectID 230 * an Id for this Surface, for example a db primary key 231 * @param parentID 232 * an Id for the parent of this Surface, for example if this is a wall the parent is 233 * the building. 234 * @param surface 235 * the ogc:geometry surface which holds the point references of a polygon, not to be 236 * confused with a j3d Object which this class represents. 237 * @param material 238 * @param transparency 239 * @param textureImg 240 * @param textureCoords 241 */ 242 public TexturedSurface( String objectID, String parentID, Surface surface, Material material, 243 float transparency, BufferedImage textureImg, float[][] textureCoords ) { 244 super( objectID, parentID, surface, material, transparency ); 245 246 this.textureImg = textureImg; 247 this.textureCoords = textureCoords; 248 createTexture( textureImg ); 249 setAppearance( createAppearance() ); 250 } 251 252 /** 253 * creates a TexturedSurface from a geometry, color informations and a reference to a texture 254 * image. Since a texture image be somehow transparent it is useful to be able to define a 255 * surfaces color. 256 * 257 * @param objectID 258 * an Id for this Surface, for example a db primary key 259 * @param parentID 260 * an Id for the parent of this Surface, for example if this is a wall the parent is 261 * the building. 262 * @param surface 263 * the ogc:geometry surface which holds the point references of a polygon, not to be 264 * confused with a j3d Object which this class represents. 265 * @param red 266 * @param green 267 * @param blue 268 * @param transparency 269 * @param textureImg 270 * @param textureCoords 271 * @throws IOException 272 */ 273 public TexturedSurface( String objectID, String parentID, Surface surface, float red, 274 float green, float blue, float transparency, URL textureImg, 275 float[][] textureCoords ) throws IOException { 276 super( objectID, parentID, surface, red, green, blue, transparency ); 277 278 this.textureImg = ImageUtils.loadImage( textureImg ); 279 this.textureCoords = textureCoords; 280 createTexture( this.textureImg ); 281 setAppearance( createAppearance() ); 282 } 283 284 /** 285 * creates a TexturedSurface from a geometry, Material and a reference to a texture image. Since 286 * a texture image be somehow transparent it is useful to be able to define a surfaces color. 287 * 288 * @param objectID 289 * an Id for this Surface, for example a db primary key 290 * @param parentID 291 * an Id for the parent of this Surface, for example if this is a wall the parent is 292 * the building. 293 * @param surface 294 * the ogc:geometry surface which holds the point references of a polygon, not to be 295 * confused with a j3d Object which this class represents. 296 * @param material 297 * @param transparency 298 * @param textureImg 299 * @param textureCoords 300 * @throws IOException 301 */ 302 public TexturedSurface( String objectID, String parentID, Surface surface, Material material, 303 float transparency, URL textureImg, float[][] textureCoords ) 304 throws IOException { 305 super( objectID, parentID, surface, material, transparency ); 306 this.textureImg = ImageUtils.loadImage( textureImg ); 307 this.textureCoords = textureCoords; 308 createTexture( this.textureImg ); 309 setAppearance( createAppearance() ); 310 } 311 312 private void createTexture( BufferedImage textureImg ) { 313 try { 314 texture = new TextureLoader( textureImg ).getTexture(); 315 texture.setEnable( true ); 316 texture.setCapability( Texture.ALLOW_ENABLE_WRITE ); 317 } catch ( Exception e ) { 318 e.printStackTrace(); 319 } 320 } 321 322 /** 323 * @return the texture of this surface. 324 */ 325 public BufferedImage getTexture() { 326 return textureImg; 327 } 328 329 /** 330 * this method must be called before addin the surface to a Group 331 */ 332 @Override 333 public void compile() { 334 335 GeometryInfo geometryInfo = new GeometryInfo( GeometryInfo.POLYGON_ARRAY ); 336 337 Position[] pos = surface.getSurfaceBoundary().getExteriorRing().getPositions(); 338 Ring[] innerRings = surface.getSurfaceBoundary().getInteriorRings(); 339 int k = 1; 340 int l = 3 * ( pos.length ); 341 if ( innerRings != null ) { 342 for ( int i = 0; i < innerRings.length; i++ ) { 343 k++; 344 l += ( 3 * innerRings[i].getPositions().length ); 345 } 346 } 347 348 float[] coords = new float[l]; 349 int contourCounts[] = { k }; 350 int[] stripCounts = new int[k]; 351 k = 0; 352 stripCounts[k++] = pos.length; 353 354 int z = 0; 355 for ( int i = 0; i < pos.length; i++ ) { 356 coords[z++] = (float) pos[i].getX(); 357 coords[z++] = (float) pos[i].getY(); 358 coords[z++] = (float) pos[i].getZ(); 359 } 360 361 if ( innerRings != null ) { 362 for ( int j = 0; j < innerRings.length; j++ ) { 363 pos = innerRings[j].getPositions(); 364 stripCounts[k++] = pos.length; 365 for ( int i = 0; i < pos.length; i++ ) { 366 coords[z++] = (float) pos[i].getX(); 367 coords[z++] = (float) pos[i].getY(); 368 coords[z++] = (float) pos[i].getZ(); 369 } 370 } 371 } 372 373 geometryInfo.setCoordinates( coords ); 374 geometryInfo.setStripCounts( stripCounts ); 375 geometryInfo.setContourCounts( contourCounts ); 376 377 // manually set texture coordinates must be done befor 378 // normals all calculated 379 if ( textureCoords != null ) { 380 geometryInfo.setTextureCoordinateParams( textureCoords.length, 2 ); 381 for ( int i = 0; i < textureCoords.length; i++ ) { 382 geometryInfo.setTextureCoordinates( i, textureCoords[i] ); 383 } 384 } 385 386 NormalGenerator ng = new NormalGenerator(); 387 ng.generateNormals( geometryInfo ); 388 389 setGeometry( geometryInfo.getGeometryArray() ); 390 391 setAppearanceOverrideEnable( true ); 392 } 393 394 private Appearance createAppearance() { 395 Appearance ap = getAppearance(); 396 if ( texture != null ) { 397 ap.setTexture( texture ); 398 ap.setTextureAttributes( RenderingConfiguration.getInstance().getTextureAttributes() ); 399 400 if ( textureCoords == null ) { 401 // automatic creation of texture coordinates is behavior of 402 // the appearance 403 TexCoordGeneration tcg = new TexCoordGeneration( 404 TexCoordGeneration.OBJECT_LINEAR, 405 TexCoordGeneration.TEXTURE_COORDINATE_2 ); 406 tcg.setPlaneS( new Vector4f( 1, 1, 0, 0 ) ); 407 tcg.setPlaneT( new Vector4f( 0, 0, 1, 0 ) ); 408 ap.setTexCoordGeneration( tcg ); 409 } 410 } 411 return ap; 412 } 413 414 } 415