osgEarth 2.1.1
|
00001 /* -*-c++-*- */ 00002 /* osgEarth - Dynamic map generation toolkit for OpenSceneGraph 00003 * Copyright 2008-2010 Pelican Mapping 00004 * http://osgearth.org 00005 * 00006 * osgEarth is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU Lesser General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public License 00017 * along with this program. If not, see <http://www.gnu.org/licenses/> 00018 */ 00019 #include <osgEarthSymbology/MarkerResource> 00020 #include <osgEarth/StringUtils> 00021 #include <osgEarth/ImageUtils> 00022 00023 #include <osg/AutoTransform> 00024 #include <osg/Depth> 00025 #include <osg/Geometry> 00026 #include <osg/TextureRectangle> 00027 00028 #define LC "[MarkerResource] " 00029 00030 using namespace osgEarth; 00031 using namespace osgEarth::Symbology; 00032 00033 //--------------------------------------------------------------------------- 00034 00035 namespace 00036 { 00037 osg::Node* buildImageModel(osg::Image* image) 00038 { 00039 float width = image->s(); 00040 float height = image->t(); 00041 00042 osg::Geometry* geometry = new osg::Geometry; 00043 00044 osg::Vec3Array* verts = new osg::Vec3Array(4); 00045 (*verts)[0] = osg::Vec3(-width/2.0f, -height/2.0, 0.0f); 00046 (*verts)[1] = osg::Vec3(width/2.0f, -height/2.0, 0.0f); 00047 (*verts)[2] = osg::Vec3(width/2.0f, height/2.0, 0.0f); 00048 (*verts)[3] = osg::Vec3(-width/2.0f,height/2.0, 0.0f); 00049 geometry->setVertexArray( verts ); 00050 00051 bool flip = image->getOrigin()==osg::Image::TOP_LEFT; 00052 00053 osg::Vec2Array* texcoords = new osg::Vec2Array(4); 00054 (*texcoords)[0].set(0.0f,flip ? height-1.0f : 0.0f); 00055 (*texcoords)[1].set(width-1.0f,flip ? height-1.0f : 0.0f); 00056 (*texcoords)[2].set(width-1.0f,flip ? 0.0 : height-1.0f); 00057 (*texcoords)[3].set(0.0f,flip ? 0.0 : height-1.0f); 00058 geometry->setTexCoordArray(0, texcoords); 00059 00060 osg::Vec4Array* colors = new osg::Vec4Array(1); 00061 (*colors)[0].set(1,1,1,1); 00062 geometry->setColorArray( colors ); 00063 geometry->setColorBinding( osg::Geometry::BIND_OVERALL ); 00064 00065 geometry->addPrimitiveSet( new osg::DrawArrays(GL_QUADS, 0, 4)); 00066 00067 osg::StateSet* stateSet = geometry->getOrCreateStateSet(); 00068 00069 osg::TextureRectangle* texture = new osg::TextureRectangle( image ); 00070 stateSet->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON); 00071 00072 stateSet->setMode( GL_BLEND, 1 ); 00073 stateSet->setRenderBinDetails( 95, "RenderBin" ); 00074 stateSet->setAttributeAndModes( new osg::Depth(osg::Depth::ALWAYS,false), 1 ); 00075 00076 osg::Geode* geode = new osg::Geode; 00077 geode->addDrawable( geometry ); 00078 00079 //PixelAutoTransform* at = new PixelAutoTransform; 00080 //at->setMinPixelWidth( width ); 00081 osg::AutoTransform* at = new osg::AutoTransform; 00082 at->setAutoScaleToScreen( true ); 00083 at->setAutoRotateMode( osg::AutoTransform::ROTATE_TO_SCREEN ); 00084 at->addChild( geode ); 00085 return at; 00086 } 00087 } 00088 00089 //--------------------------------------------------------------------------- 00090 00091 MarkerResource::MarkerResource( const Config& conf ) : 00092 Resource( conf ) 00093 { 00094 mergeConfig( conf ); 00095 } 00096 00097 void 00098 MarkerResource::mergeConfig( const Config& conf ) 00099 { 00100 conf.getIfSet( "url", _markerURI ); 00101 } 00102 00103 Config 00104 MarkerResource::getConfig() const 00105 { 00106 Config conf = Resource::getConfig(); 00107 conf.key() = "marker"; 00108 00109 conf.updateIfSet( "url", _markerURI ); 00110 00111 return conf; 00112 } 00113 00114 osg::Node* 00115 MarkerResource::createNode() const 00116 { 00117 return createNodeFromURI( _markerURI.value() ); 00118 } 00119 00120 osg::Node* 00121 MarkerResource::createNodeFromURI( const URI& uri ) const 00122 { 00123 osg::ref_ptr<osg::Object> obj = uri.readObject(); 00124 if ( obj.valid() ) 00125 { 00126 if ( dynamic_cast<osg::Image*>( obj.get() ) ) 00127 { 00128 return buildImageModel( dynamic_cast<osg::Image*>( obj.get() ) ); 00129 } 00130 else if ( dynamic_cast<osg::Node*>( obj.get() ) ) 00131 { 00132 return dynamic_cast<osg::Node*>( obj.release() ); 00133 } 00134 } 00135 00136 else // failing that, fall back on the old encoding format.. 00137 { 00138 StringVector tok; 00139 StringTokenizer( *uri, tok, "()" ); 00140 if (tok.size() >= 2) 00141 return createNodeFromURI( URI(tok[1]) ); 00142 } 00143 00144 // fail 00145 return 0L; 00146 } 00147 00148