// objectstatic.cpp -- an object static from a flightgear scenery tile // // Written by Frederic Bouvier, started March 2002. // // Copyright (C) 2002 Frederic Bouvier - fredb@users.sourceforge.net // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as // published by the Free Software Foundation; either version 2 of the // License, or (at your option) any later version. // // This program 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 // General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // // $Id: objectstatic.cpp,v 1.26 2005/05/09 07:02:10 fredb Exp $ #ifdef _MSC_VER #pragma warning( disable : 4786 4800 4503 ) #define _USE_MATH_DEFINES #endif #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "objectstatic.hpp" #include "tile.hpp" #include "sdutil.hpp" #include "mire.c" double FGSD_ObjectStatic::_symbol[][ 2 ] = { { 0.0, -.3 }, { 0.0, 1.0 }, { -.3, 0.0 }, { 0.3, 0.0 }, { -.1, 0.8 }, { 0.1, 0.8 } }; FGSD_ObjectStatic::FGSD_ObjectStatic( FGSD_Tile *__tile, const std::string &name, double lon, double lat, double elev, double hdg, bool shared, double ground_elev ) : FGSD_BaseObject( __tile, ObjectStatic ) , _name( name ) , _lon( lon ) , _lat( lat ) , _elev( elev ) , _hdg( hdg ) , _offset( 0.0 ) , _agl( false ) , _shared( shared ) { _offset = elev - ground_elev; if ( !_shared ) { size_t pos = _name.find_last_of( '/' ); if ( pos != std::string::npos ) { _path = std::string( _name, 0, pos ); _name.erase( 0, pos + 1 ); } } transformSymbol(); } FGSD_ObjectStatic::FGSD_ObjectStatic( const std::string &name, const std::vector &textures ) : FGSD_BaseObject( 0, ObjectStatic ) , _name( name ) , _textures( textures ) , _lon( 1000 ) , _lat( 0 ) , _elev( 0 ) , _hdg( 0 ) , _offset( 0.0 ) , _agl( false ) , _shared( false ) { size_t pos = _name.find_last_of( '/' ); if ( pos != std::string::npos ) { _path = std::string( _name, 0, pos ); _name.erase( 0, pos + 1 ); } } void FGSD_ObjectStatic::draw( double alpha, bool lines, DrawType drawType, double minx, double maxx, double miny, double maxy, double zLevel ) { // Save previous state glPushAttrib( GL_CURRENT_BIT | GL_POINT_BIT | GL_LINE_BIT | GL_POLYGON_BIT ); // Set new state glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); double xscale = 0.002 / zLevel; double yscale = xscale * cos( _lat * M_PI / 180 ); glColor4f( 1.0, 0.0, 0.0, 1.0 ); glLineWidth( 2.0 ); // Draw symbol glBegin( GL_LINES ); // heading glVertex2d( _lon + _points[ 0 ][ 0 ] * xscale, _lat + _points[ 0 ][ 1 ] * yscale ); glVertex2d( _lon + _points[ 1 ][ 0 ] * xscale, _lat + _points[ 1 ][ 1 ] * yscale ); // traversal glVertex2d( _lon + _points[ 2 ][ 0 ] * xscale, _lat + _points[ 2 ][ 1 ] * yscale ); glVertex2d( _lon + _points[ 3 ][ 0 ] * xscale, _lat + _points[ 3 ][ 1 ] * yscale ); // left side of arrow glVertex2d( _lon + _points[ 4 ][ 0 ] * xscale, _lat + _points[ 4 ][ 1 ] * yscale ); glVertex2d( _lon + _points[ 1 ][ 0 ] * xscale, _lat + _points[ 1 ][ 1 ] * yscale ); // right side of arrow glVertex2d( _lon + _points[ 1 ][ 0 ] * xscale, _lat + _points[ 1 ][ 1 ] * yscale ); glVertex2d( _lon + _points[ 5 ][ 0 ] * xscale, _lat + _points[ 5 ][ 1 ] * yscale ); glEnd(); // Restore previous state glPopAttrib(); } bool FGSD_ObjectStatic::propertiesUnderMouse( double lon, double lat, double &height, std::string &material, std::string &airportID ) const { bool ret = false; return ret; } bool FGSD_ObjectStatic::objectUnderMouse( double lon, double lat, double zLevel ) { double xscale = 0.0002 / zLevel; double yscale = xscale * cos( _lat * M_PI / 180 ); double minx = _lon - xscale; double miny = _lat - yscale; double maxx = _lon + xscale; double maxy = _lat + yscale; if ( lon >= minx && lon < maxx && lat >= miny && lat < maxy ) { return true; } return false; } bool FGSD_ObjectStatic::visible( double minx, double maxx, double miny, double maxy ) const { return _lon >= minx && _lon < maxx && _lat >= miny && _lat < maxy; } bool FGSD_ObjectStatic::visible( double lon, double lat ) const { // return lon >= _minx && lon < _maxx && lat >= _miny && lat < _maxy; return true; } std::string FGSD_ObjectStatic::getName() const { return _name; } void FGSD_ObjectStatic::transformSymbol() { // Matrix: // a11 a12 // a21 a22 double a11 = cos( ( 180 - _hdg ) * M_PI / 180 ); double a21 = sin( ( 180 - _hdg ) * M_PI / 180 ); double a12 = -a21; double a22 = a11; for ( size_t i = 0; i < NB_POINTS; i++ ) { _points[ i ][ 0 ] = a11 * _symbol[ i ][ 0 ] + a21 * _symbol[ i ][ 1 ]; _points[ i ][ 1 ] = a12 * _symbol[ i ][ 0 ] + a22 * _symbol[ i ][ 1 ]; } } void *FGSD_ObjectStatic::convertTo( FGSD_BaseObject::ObjectType __type ) { if ( __type == FGSD_BaseObject::ObjectStatic ) { return this; } return 0; } void FGSD_ObjectStatic::changeHeading( double __hdg ) { _hdg = __hdg; transformSymbol(); _modified = true; } void FGSD_ObjectStatic::changePosition( double __lon, double __lat ) { double height; std::string mat, aptid; bool ok = _tile->propertiesUnderMouse( __lon, __lat, height, mat, aptid ); if ( ok ) { changePosition( __lon, __lat, height ); } _tile->setModified(); } void FGSD_ObjectStatic::changePosition( double __lon, double __lat, double __height ) { _lon = __lon; _lat = __lat; _elev = __height + _offset; _modified = true; } void FGSD_ObjectStatic::saveTo( std::ostream &out, const std::string &path, bool objectStatic, bool objectShared ) { if ( _shared && objectShared ) { out << "OBJECT_SHARED " << _name << " " << std::setprecision( 10 ) << _lon << " " << std::setprecision( 10 ) << _lat << " " << _elev << " " << _hdg << std::endl; } else if ( !_shared && objectStatic ) { std::string objpath = _name; if ( _path.size() ) { objpath = _path + "/" + _name; } out << "OBJECT_STATIC " << _name << " " << std::setprecision( 10 ) << _lon << " " << std::setprecision( 10 ) << _lat << " " << _elev << " " << _hdg << std::endl; FGSD_Util::copyToFolder( objpath.c_str(), path.c_str() ); size_t nb = _textures.size(); for ( size_t i = 0; i < nb; i++ ) { FGSD_Util::copyToFolder( _textures[ i ].c_str(), path.c_str() ); } } }