//$Header: /home/deegree/jail/deegreerepository/deegree/src/org/deegree/ogcwebservices/wpvs/j3d/Attic/BuildingsFactory.java,v 1.19 2006/11/27 09:07:52 poth Exp $ /*---------------- FILE HEADER ------------------------------------------ This file is part of deegree. Copyright (C) 2001-2006 by: EXSE, Department of Geography, University of Bonn http://www.giub.uni-bonn.de/deegree/ lat/lon GmbH http://www.lat-lon.de This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Contact: Andreas Poth lat/lon GmbH Aennchenstraße 19 53177 Bonn Germany E-Mail: poth@lat-lon.de Prof. Dr. Klaus Greve Department of Geography University of Bonn Meckenheimer Allee 166 53115 Bonn Germany E-Mail: greve@giub.uni-bonn.de ---------------------------------------------------------------------------*/ package org.deegree.ogcwebservices.wpvs.j3d; /** * Factory class for creating Java3D objects out of CityGMl features. This class is project-specific * and won't be available in future releases of deegree. * * @author <a href="mailto:taddei@lat-lon.de">Ugo Taddei</a> * @author last edited by: $Author: poth $ * * @version 2.0, $Revision: 1.19 $, $Date: 2006/11/27 09:07:52 $ * * @since 2.0 */ //public class BuildingsFactory implements ThreeDObjectFactory { // // private static ILogger LOG = LoggerFactory.getLogger( BuildingsFactory.class ); // // private static final Color DEFAULT_BUILDING_COLOR; // // private static final URI APP_URI; // // static { // URI tmp = null; // try { // tmp = new URI( "http://www.deegree.org/app" ); // } catch ( Exception e ) { // e.printStackTrace(); // } finally { // APP_URI = tmp; // } // // Color tmpColor = Color.LIGHT_GRAY.brighter(); // try { // tmpColor = Color.decode( BuildingsFactoryProperties.getString( "BuildingsFactory.DEFAULT_BUILDING_COLOR" ) ); // } catch ( Exception e ) { // // TODO log // e.printStackTrace(); // } // DEFAULT_BUILDING_COLOR = tmpColor; // // } // // private static final QualifiedName FRONT_TEXT_QNAME = new QualifiedName( "app:front_texture", // APP_URI ); // // private static final QualifiedName FRONT_RED_QNAME = new QualifiedName( "app:front_color_red", // APP_URI ); // // private static final QualifiedName FRONT_GREEN_QNAME = new QualifiedName( // "app:front_color_green", // APP_URI ); // // private static final QualifiedName FRONT_BLUE_QNAME = new QualifiedName( // "app:front_color_blue", // APP_URI ); // // private static final QualifiedName FRONT_TEX_QNAME = new QualifiedName( // "app:front_texture_coordinates", // APP_URI ); // // private static final QualifiedName FRONT_OPACITY_QNAME = new QualifiedName( // "app:front_opacity", // APP_URI ); // // private static Map<URL, Texture> imagesCache; // // /* the minimum altitude, used to put building on the floor */ // // private float minimumAltitude; // private boolean forceToZeroAltitude; // // /** // * Creates a new factory for CityGML buildings // * // */ // public BuildingsFactory() { // // imagesCache = new HashMap<URL, Texture>( 20 ); // // minimumAltitude = subtractMinAltitude ? Float.POSITIVE_INFINITY : 0f; // } // // // public void setForceObjectsToZeroAltitude( boolean force ) { // this.forceToZeroAltitude = force; // } // // /* (non-Javadoc) // * @see org.deegree.ogcwebservices.wpvs.j3d.FeatureCollectionAdapter#createJ3DGeometry() // */ // public TriangleArray createJ3DGeometry() { // // TODO Auto-generated method stub // return null; // } // // /** // * // * @see ThreeDObjectFactory#create3DObjectsFromFeatureCollection // */ // public List<Group> create3DObjectsFromFeatureCollection( FeatureCollection featureCollection ) { // // List<Group> buildingGroup = new ArrayList<Group>( featureCollection.size() ); // // Feature[] features = featureCollection.toArray(); // Group building = new Group(); // // NormalGenerator normalGenerator = new NormalGenerator(); // normalGenerator.setCreaseAngle( (float) Math.toRadians( 16 ) ); // // for ( Feature feature : features ) { // // List<StyledSurface> list = new ArrayList<StyledSurface>(); // collectStyledGeometries( feature, list ); // // float minimumAltitude = 0; // // if ( forceToZeroAltitude ) { // calculate min of each feature (building) // minimumAltitude = Float.MAX_VALUE; // for ( Iterator iter = list.iterator(); iter.hasNext(); ) { // StyledSurface stylSurf = (StyledSurface) iter.next(); // Geometry geom = stylSurf.getGeom(); // float tmp = calcMinAltitude( geom ); // minimumAltitude = Math.min( minimumAltitude, tmp ); // } // } // // for ( Iterator iter = list.iterator(); iter.hasNext(); ) { // StyledSurface stylSurf = (StyledSurface) iter.next(); // // Geometry geom = stylSurf.getGeom(); // // float[] coords = toCoords( geom, minimumAltitude ); // // if ( coords != null ) { // float[] texCoords = stylSurf.getTexCoords(); // if ( texCoords == null ) { // texCoords = toTextCoords( coords ); // } // GeometryInfo geomInfo = new GeometryInfo( GeometryInfo.POLYGON_ARRAY ); // // geomInfo.setCoordinates( coords ); // geomInfo.setTextureCoordinateParams( 1, 2 ); // geomInfo.setTextureCoordinates( 0, texCoords ); // // geomInfo.setContourCounts( new int[] { 1 } ); // geomInfo.setStripCounts( new int[] { coords.length / 3 } ); // // normalGenerator.generateNormals( geomInfo ); // GeometryArray ga = geomInfo.getGeometryArray(); // // Shape3D shape = new Shape3D( ga ); // shape.setAppearance( createBuildingApperance( stylSurf ) ); // // building.addChild( shape ); // // } // } // } // buildingGroup.add( building ); // // return buildingGroup; // } // // // //// /** //// * //// * @see ThreeDObjectFactory#create3DObjectsFromFeatureCollection //// */ //// public List<Group> create3DObjectsFromFeatureCollection( FeatureCollection featureCollection ) { //// //// List<Group> buildingGroup = new ArrayList<Group>( featureCollection.size() ); //// //// Feature[] features = featureCollection.toArray(); //// Group building = new Group(); //// //// NormalGenerator normalGenerator = new NormalGenerator(); //// normalGenerator.setCreaseAngle( (float) Math.toRadians( 16 ) ); //// //// for ( Feature feature : features ) { //// //// List<StyledSurface> list = new ArrayList<StyledSurface>(); //// collectStyledGeometries( feature, list ); //// //// float minimumAltitude = 0; //// //// if ( forceToZeroAltitude ) { // calculate min of each feature (building) //// minimumAltitude = Float.MAX_VALUE; //// for ( Iterator iter = list.iterator(); iter.hasNext(); ) { //// StyledSurface stylSurf = (StyledSurface) iter.next(); //// Geometry geom = stylSurf.getGeom(); //// float tmp = calcMinAltitude( geom ); //// minimumAltitude = Math.min( minimumAltitude, tmp ); //// } //// } //// //// for ( Iterator iter = list.iterator(); iter.hasNext(); ) { //// StyledSurface stylSurf = (StyledSurface) iter.next(); //// //// Geometry geom = stylSurf.getGeom(); //// //// float[] coords = toCoords( geom, minimumAltitude ); //// //// if ( coords != null ) { //// float[] texCoords = stylSurf.getTexCoords(); //// if ( texCoords == null ) { //// texCoords = toTextCoords( coords ); //// } //// GeometryInfo geomInfo = new GeometryInfo( GeometryInfo.POLYGON_ARRAY ); //// //// geomInfo.setCoordinates( coords ); //// geomInfo.setTextureCoordinateParams( 1, 2 ); //// geomInfo.setTextureCoordinates( 0, texCoords ); //// //// geomInfo.setContourCounts( new int[] { 1 } ); //// geomInfo.setStripCounts( new int[] { coords.length / 3 } ); //// //// normalGenerator.generateNormals( geomInfo ); //// GeometryArray ga = geomInfo.getGeometryArray(); //// //// Shape3D shape = new Shape3D( ga ); //// shape.setAppearance( createBuildingApperance( stylSurf ) ); //// //// building.addChild( shape ); //// //// } //// } //// } //// buildingGroup.add( building ); //// //// return buildingGroup; //// } // // /** // * Iterates over the properties of the feature and collect all found geometry properties in the list // * @param feature the feature from which all geometry objects (be them direct properties or properties // * of its properties) will be extracted and collected // * @param list the list into which to put the collected geometry properties and its style information // */ // private void collectStyledGeometries( Feature feature, List<StyledSurface> list ) { // // FeatureProperty[] props = feature.getProperties(); // if ( props != null ) { // for ( int i = 0; i < props.length; i++ ) { // // Object value = props[i].getValue(); // if ( value != null ) { // // if ( value instanceof DefaultFeature ) { // DefaultFeature newFeature = (DefaultFeature) value; // // Geometry geom = newFeature.getDefaultGeometryPropertyValue(); // // //calcMinAltitude( geom ); // // Object tex = null; // if ( newFeature != null ) { // // FeatureProperty featureProperty = newFeature.getDefaultProperty( FRONT_TEXT_QNAME ); // if ( featureProperty != null ) { // tex = featureProperty.getValue(); // } // // Object r = null; // featureProperty = newFeature.getDefaultProperty( FRONT_RED_QNAME ); // if ( featureProperty != null ) { // r = featureProperty.getValue(); // } // Object g = null; // featureProperty = newFeature.getDefaultProperty( FRONT_GREEN_QNAME ); // if ( featureProperty != null ) { // g = featureProperty.getValue(); // } // Object b = null; // featureProperty = newFeature.getDefaultProperty( FRONT_BLUE_QNAME ); // if ( featureProperty != null ) { // b = featureProperty.getValue(); // } // // Object o = null; // float opacity = 1f; // // featureProperty = newFeature.getDefaultProperty( FRONT_OPACITY_QNAME ); // if ( featureProperty != null ) { // o = featureProperty.getValue(); // if ( o != null ) { // opacity = ( (Double) o ).floatValue(); // } // } // // Color c = DEFAULT_BUILDING_COLOR; // if ( r != null && g != null && b != null ) { // // try { // c = new Color( ( (Double) r ).floatValue(), // ( (Double) g ).floatValue(), // ( (Double) b ).floatValue() ); // } catch ( Exception e ) { // LOG.logError( e.getMessage(), e ); // e.printStackTrace(); // } // } // // float[] texCoords = null; // featureProperty = newFeature.getDefaultProperty( FRONT_TEX_QNAME ); // if ( featureProperty != null ) { // b = featureProperty.getValue(); // if ( b != null ) { // texCoords = toTextCoords( (Geometry) b ); // } // } // // if ( geom != null ) { // // list.add( new StyledSurface( geom, c, (String) tex, texCoords, // opacity ) ); // } // // } // collectStyledGeometries( newFeature, list ); // // } // } // // } // // } // // } // // /** // * Creates a J3D Appearance for the styled surface // * @param stylSurf the object containing geometry and style info (texture, colors , etc.) // * @return a new Appearance object // */ // private static Appearance createBuildingApperance( StyledSurface stylSurf ) { // // Appearance app = new Appearance(); // // Color3f defaultColor = new Color3f( stylSurf.getForeColor() ); // // ColoringAttributes ca = new ColoringAttributes(); // ca.setShadeModel( ColoringAttributes.SHADE_GOURAUD ); // app.setColoringAttributes( ca ); // // Material material = new Material(); // material.setAmbientColor( defaultColor ); // material.setDiffuseColor( defaultColor ); // float s = 0.0f; // material.setSpecularColor( new Color3f( s, s, s ) ); // material.setShininess( 1f ); // material.setLightingEnable( true ); // // float e = 0.145f; // // material.setEmissiveColor( e, e, e ); // // app.setMaterial( material ); // // String tex = stylSurf.getTexture(); // String texUrlString = stylSurf.getTexture(); // /* // if ( tex != null && texUrlString != null && texUrlString.length() != 0 ) { // // TextureAttributes texAttr = new TextureAttributes(); // texAttr.setTextureMode( TextureAttributes.MODULATE ); // app.setTextureAttributes( texAttr ); // // URL texUrl = null; // try { // // texUrl = new URL( texUrlString ); // Texture texture = imagesCache.get( texUrl ); // if ( texture == null ) { // texture = new TextureLoader( texUrl, null ).getTexture(); // } // app.setTexture( texture ); // // } catch ( Exception e ) { // LOG.logError( e.getMessage(), e ); // } // // } // */ // PolygonAttributes pa = new PolygonAttributes(); // pa.setCullFace( PolygonAttributes.CULL_NONE ); // pa.setBackFaceNormalFlip( true ); // // pa.setPolygonMode( PolygonAttributes.POLYGON_LINE ); // app.setPolygonAttributes( pa ); // // float transpareny = 1f - stylSurf.getOpacity(); // if ( transpareny != 0f ) { // TransparencyAttributes transpAtt = new TransparencyAttributes( // TransparencyAttributes.BLENDED, // transpareny ); // app.setTransparencyAttributes( transpAtt ); // // } // // return app; // } // // /** // * Reads the exterior rigns of Surfaces only and transform them into a float array // * @param geom the Surface geometry (other types are ignored) // * @return a new float array with -x0,z0,y0, -x1,z1,y1, -xn,zn,yn, etc // */ // private float[] toCoords( Geometry geom, float minimumAltitude ) { // // //TODO really check if Polygon??? // // TODO interior rings... // // float[] coords = null; // // if ( geom instanceof Surface ) { // // Surface p = (Surface) geom; // Position[] positions = p.getSurfaceBoundary().getExteriorRing().getPositions(); // coords = new float[3 * ( positions.length - 1 )]; // // for ( int i = 0; i < positions.length - 1; i++ ) { // // int ix = 3 * i; // coords[ix] = (float) positions[i].getX(); // coords[ix + 1] = (float) positions[i].getY(); // float f = (float) positions[i].getZ() - minimumAltitude; // coords[ix + 2] = f; // // } // // } // return coords; // } // // /** // * @see toCoords( Geometry ) // */ // private float[] toTextCoords( float[] coords ) { // // float[] texCoords = null; // // if ( coords.length == 12 ) { // return new float[] { 0, 1, 1, 1, 1, 0, 0, 0 }; // } // float minX = Float.POSITIVE_INFINITY; // float minY = Float.POSITIVE_INFINITY; // float maxX = Float.NEGATIVE_INFINITY; // float maxY = Float.NEGATIVE_INFINITY; // // for ( int i = 0; i < coords.length; i += 3 ) { // float x = -coords[i]; // // if ( x < minX ) { // minX = x; // } // if ( x > maxX ) { // maxX = x; // } // // float y = coords[i + 2]; // if ( y < minY ) { // minY = y; // } // if ( y > maxY ) { // maxY = y; // } // // } // // float w = maxX - minX; // if ( w == 0 ) { // w = 1f; // } // float h = maxY - minY; // if ( h == 0 ) { // h = 1f; // } // // texCoords = new float[coords.length / 3 * 2]; // // int c = 0; // for ( int i = 0; i < coords.length; i += 3 ) { // texCoords[c] = Math.abs( ( -coords[i] - minX ) / w ); // texCoords[c + 1] = ( coords[i + 2] - minY ) / h; // // c += 2; // } // // return texCoords; // } // // private float[] toTextCoords( Geometry texPoly ) { // // float[] coords = null; // // if ( texPoly instanceof Surface ) { // // Surface p = (Surface) texPoly; // Position[] positions = p.getSurfaceBoundary().getExteriorRing().getPositions(); // coords = new float[2 * ( positions.length - 1 )]; // // for ( int i = 0; i < positions.length - 1; i++ ) { // // int ix = 2 * i; // coords[ix] = (float) positions[i].getX(); // coords[ix + 1] = (float) positions[i].getY(); // } // } // return coords; // } // // /** // * Iterates over positions of the exterior rig of the geom, assuming it's a Surface, // * and update the minimum altitude value of this obejtc. // * @param geom the geometry from which minimum altitude value will be calculated // */ // private float calcMinAltitude( Geometry geom ) { // // float minimumAltitude = Float.POSITIVE_INFINITY; // // if ( geom instanceof Surface ) { // // Surface p = (Surface) geom; // Position[] positions = p.getSurfaceBoundary().getExteriorRing().getPositions(); // // for ( int i = 0; i < positions.length - 1; i++ ) { // float z = (float) positions[i].getZ(); // minimumAltitude = Math.min( minimumAltitude, z ); // // } // } else { // //safer to return 0 because it is used in subtraction ;-) // minimumAltitude = 0; // } // // return minimumAltitude; // } // // /** // * // * A convenience class to pack together geometry and style information for buildings. // * // * @author <a href="mailto:taddei@lat-lon.de">Ugo Taddei</a> // * @author last edited by: $Author: poth $ // * // * @version 2.0, $Revision: 1.19 $, $Date: 2006/11/27 09:07:52 $ // * // * @since 2.0 // */ // private static class StyledSurface { // // private final Geometry geom; // // private final Color foreColor; // // private final String tex; // // private final float[] texCoords; // // private final float opacity; // // /** // * Createa new instance of a Styled Suface. // * @param g the object geometry // * @param foregroundColor the foreground color // * @param texture the URL of the texture // * @param textureCoords the array with the texture coordinates // * @param opacity the opacity value // */ // StyledSurface( Geometry g, Color foregroundColor, String texture, float[] textureCoords, // float opacity ) { // this.geom = g; // this.texCoords = textureCoords; // this.foreColor = foregroundColor; // this.tex = texture; // this.opacity = opacity; // } // // public Color getForeColor() { // return foreColor; // } // // public Geometry getGeom() { // return geom; // } // // public String getTexture() { // return tex; // } // // public float[] getTexCoords() { // return texCoords; // } // // public float getOpacity() { // return opacity; // } // } //} /* ******************************************************************** Changes to this class. What the people have been up to: $Log: BuildingsFactory.java,v $ Revision 1.19 2006/11/27 09:07:52 poth JNI integration of proj4 has been removed. The CRS functionality now will be done by native deegree code. Revision 1.18 2006/11/23 11:46:40 bezema The initial version of the new wpvs Revision 1.17 2006/07/05 15:58:58 poth bug fix - calculating objects minimum z-value Revision 1.16 2006/07/05 14:08:04 taddei attempt to put budligns at z = 0; buggy for reasons not understood Revision 1.15 2006/07/05 11:24:02 taddei now sets EM to zero plane (if EM == null) Revision 1.14 2006/07/04 09:08:06 taddei buildings factory props, and possibility of setting builds to z = 0 Revision 1.13 2006/06/20 10:16:01 taddei clean up and javadoc Revision 1.12 2006/06/20 07:45:49 taddei removed println Revision 1.11 2006/05/12 13:13:16 taddei changed light props Revision 1.10 2006/05/05 12:42:09 taddei added properties for material constants Revision 1.9 2006/04/28 15:05:49 taddei null checking and clean up Revision 1.8 2006/04/18 18:20:26 poth *** empty log message *** Revision 1.7 2006/04/06 20:25:28 poth *** empty log message *** Revision 1.6 2006/04/05 08:58:28 taddei supports tex now (if not in fc, then create some default) Revision 1.4 2006/03/29 15:03:23 taddei with + or - working texs Revision 1.3 2006/03/27 14:15:17 taddei code for conputing text coords Revision 1.2 2006/03/27 08:35:25 taddei working: color, normal (no tex yet) Revision 1.1 2006/03/24 08:52:21 taddei factory for building buildings ********************************************************************** */