001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/ogcwebservices/wpvs/j3d/TexturedSurface.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 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: 9345 $
070 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
071 * @author last edited by: $Author: apoth $
072 *
073 * @version 1.0. $Revision: 9345 $, $Date: 2007-12-27 17:22:25 +0100 (Do, 27 Dez 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 //the last point is the same as the first, therefore not needed.
340 int numberOfPointsInSurface = pos.length -1;
341 int k = 1;
342 int l = 3 * (numberOfPointsInSurface );
343 if ( innerRings != null ) {
344 for ( int i = 0; i < innerRings.length; i++ ) {
345 k++;
346 l += ( 3 * innerRings[i].getPositions().length );
347 }
348 }
349
350 float[] coords = new float[l];
351 int contourCounts[] = { k };
352 int[] stripCounts = new int[k];
353 k = 0;
354 stripCounts[k++] = numberOfPointsInSurface;
355 //System.out.println( "surface length: " + pos.length );
356 int z = 0;
357 for ( int i = 0; i < numberOfPointsInSurface; i++ ) {
358 coords[z++] = (float) pos[i].getX();
359 coords[z++] = (float) pos[i].getY();
360 coords[z++] = (float) pos[i].getZ();
361 }
362
363 if ( innerRings != null ) {
364 for ( int j = 0; j < innerRings.length; j++ ) {
365 pos = innerRings[j].getPositions();
366 stripCounts[k++] = pos.length;
367 for ( int i = 0; i < pos.length; i++ ) {
368 coords[z++] = (float) pos[i].getX();
369 coords[z++] = (float) pos[i].getY();
370 coords[z++] = (float) pos[i].getZ();
371 }
372 }
373 }
374
375 geometryInfo.setCoordinates( coords );
376 geometryInfo.setStripCounts( stripCounts );
377 geometryInfo.setContourCounts( contourCounts );
378
379 // manually set texture coordinates must be done befor
380 // normals all calculated
381 if ( textureCoords != null ) {
382 geometryInfo.setTextureCoordinateParams( textureCoords.length, 2 );
383
384 float[] texc = new float[numberOfPointsInSurface*2];
385 for ( int i = 0; i < textureCoords.length ; i++ ) {
386 for( int newCount = 0; newCount < (numberOfPointsInSurface*2); newCount++ ){
387 texc[newCount] = textureCoords[i][newCount];
388 }
389 geometryInfo.setTextureCoordinates( i, texc );
390 }
391 }
392
393 NormalGenerator ng = new NormalGenerator();
394 ng.generateNormals( geometryInfo );
395
396 setGeometry( geometryInfo.getGeometryArray() );
397
398 setAppearanceOverrideEnable( true );
399 }
400
401 private Appearance createAppearance() {
402 Appearance ap = getAppearance();
403 if ( texture != null ) {
404 ap.setTexture( texture );
405 ap.setTextureAttributes( RenderingConfiguration.getInstance().getTextureAttributes() );
406
407 if ( textureCoords == null ) {
408 // automatic creation of texture coordinates is behavior of
409 // the appearance
410 TexCoordGeneration tcg = new TexCoordGeneration(
411 TexCoordGeneration.OBJECT_LINEAR,
412 TexCoordGeneration.TEXTURE_COORDINATE_2 );
413 tcg.setPlaneS( new Vector4f( 1, 1, 0, 0 ) );
414 tcg.setPlaneT( new Vector4f( 0, 0, 1, 0 ) );
415 ap.setTexCoordGeneration( tcg );
416 }
417 }
418 return ap;
419 }
420
421 }
422