Hello.
As a very first attempt to contribute to the flightgear source code, I
have tried to write a patch that automatically sets a scenery model's
elevation to ground level at the object's site if an elevation < 9999 is
defined in the .stg file.
At this point, many thanks to Melchior, who gave me a short description
of how to do this more than a year ago (I just didn't find the time to
do it until now... ;))
It seems to work, but I'm not sure if it is done well. It affects the
following files:
Scenery/tilemgr.hxx
Scenery/tilemgr.cxx
Scenery/tileentry.hxx
Scenery/tileentry.cxx
And it works the following way:
I extended FGDeferredModel to hold lat, lon, elev and hdg as double
attributes additionally to the transform matrix. When
FGTileEntry::load() pushes an object onto the model load queue, it sets
these attributes.
Later, when FGTileMgr::update_queues() loads the models, it checks if a
model's elev is < 9999, and if yes, it gets the ground elevation at the
model's coordinates, recalculates the transform matrix for the model and
updates it. One surely ugly thing with this is that at the moment, I've
simply copied the function WorldCoordinates() from tileentry.cxx to
tilemgr.cxx. This way the function code is duplicated, but I didn't want
to remove something or change dependencies.
I made a patch file and attached it to the message. It would be nice if
someone of you guys could take a look at it, give tips about how to
improve it (if neccessary) and/or put it into the cvs code.
Best regards,
Sebastian
Index: tilemgr.cxx
===================================================================
RCS file: /var/cvs/FlightGear-0.9/source/src/Scenery/tilemgr.cxx,v
retrieving revision 1.60
diff -r1.60 tilemgr.cxx
56a57,108
>
>
>
>
>
> static void WorldCoordinate2( osg::Matrix& obj_pos, double lat,
> double lon, double elev, double hdg )
> {
> double lon_rad = lon * SGD_DEGREES_TO_RADIANS;
> double lat_rad = lat * SGD_DEGREES_TO_RADIANS;
> double hdg_rad = hdg * SGD_DEGREES_TO_RADIANS;
>
> // setup transforms
> Point3D geod( lon_rad, lat_rad, elev );
> Point3D world_pos = sgGeodToCart( geod );
> Point3D offset = world_pos;
>
> sgdMat4 mat;
>
> double sin_lat = sin( lat_rad );
> double cos_lat = cos( lat_rad );
> double cos_lon = cos( lon_rad );
> double sin_lon = sin( lon_rad );
> double sin_hdg = sin( hdg_rad ) ;
> double cos_hdg = cos( hdg_rad ) ;
>
> mat[0][0] = cos_hdg * sin_lat * cos_lon - sin_hdg * sin_lon;
> mat[0][1] = cos_hdg * sin_lat * sin_lon + sin_hdg * cos_lon;
> mat[0][2] = -cos_hdg * cos_lat;
> mat[0][3] = SG_ZERO;
>
> mat[1][0] = -sin_hdg * sin_lat * cos_lon - cos_hdg * sin_lon;
> mat[1][1] = -sin_hdg * sin_lat * sin_lon + cos_hdg * cos_lon;
> mat[1][2] = sin_hdg * cos_lat;
> mat[1][3] = SG_ZERO;
>
> mat[2][0] = cos_lat * cos_lon;
> mat[2][1] = cos_lat * sin_lon;
> mat[2][2] = sin_lat;
> mat[2][3] = SG_ZERO;
>
> mat[3][0] = offset.x();
> mat[3][1] = offset.y();
> mat[3][2] = offset.z();
> mat[3][3] = SG_ONE ;
>
> for (unsigned i = 0; i < 4; ++i)
> for (unsigned j = 0; j < 4; ++j)
> obj_pos(i, j) = mat[i][j];
> }
>
>
309c361,400
< try {
---
> try {
>
> /* AUTO-ADAPT OBJECT ELEVATION TO GROUND LEVEL
> *
> /* if the defined elevation is < 9999. This feature
> allows
> * us to define objects without having to know the exact
> * ground elevation (of the scenery and/or in reality).
> *
> * There are two reasons why I wanted to implement this:
> *
> * First, I didn't understand why I always had to find
> * out the ground elevation at the site of some scenery
> * object just to place it -on the ground- while the
> * simulator already knows this value.
> *
> * Second, specifying the real world elevation too often
> * results in objects floating over or sticking in the
> * ground by a few meters because the ground elevation
> * in the scenery is practically never the same as the
> * real (or somewhere denoted) elevation.
> */
>
> if (dm->get_elev() < -9999) {
> const SGMaterial *mat;
> double newElev;
>
> if
> (globals->get_scenery()->get_elevation_m(dm->get_lat(), dm->get_lon(),
> 30000.0,
> newElev, &mat)) {
>
> osg::Matrix obj_pos;
> WorldCoordinate2( obj_pos, dm->get_lat(),
> dm->get_lon(), newElev, dm->get_hdg());
>
> dm->get_obj_trans()->setMatrix(obj_pos);
> }
> else {
> SG_LOG( SG_TERRAIN, SG_INFO, "Failed to set
> object elevation to ground level: Terrain tile not loaded." );
>
> }
> }
>
>
Index: tileentry.cxx
===================================================================
RCS file: /var/cvs/FlightGear-0.9/source/src/Scenery/tileentry.cxx,v
retrieving revision 1.58
diff -r1.58 tileentry.cxx
239,240c239,240
< {
< in >> name;
---
> {
> in >> name;
244c244
<
---
>
379c379
<
---
>
396c396
< osg::Matrix obj_pos;
---
> osg::Matrix obj_pos;
401a402
>
407,409c408,410
< FGDeferredModel *dm
< = new FGDeferredModel( custom_path.str(),
< obj->path.str(),
---
> FGDeferredModel *dm =
> new FGDeferredModel( custom_path.str(),
> obj->path.str(),
411,412c412,419
< this, obj_trans,
< obj->type == OBJECT_SHARED );
---
> this,
> obj_trans,
> obj->type == OBJECT_SHARED,
> obj->lat,
> obj->lon,
> obj->elev,
> obj->hdg);
>
Index: tileentry.hxx
===================================================================
RCS file: /var/cvs/FlightGear-0.9/source/src/Scenery/tileentry.hxx,v
retrieving revision 1.26
diff -r1.26 tileentry.hxx
81a82,87
>
> /* added by Seb*/
> double lat;
> double lon;
> double elev;
> double hdg;
88c94,95
< FGTileEntry *t, osg::MatrixTransform *ot, bool co
)
---
> FGTileEntry *t, osg::MatrixTransform *ot, bool
> co,
> double setLat, double setLon, double setElev,
> double setHdg )
90,95c97,107
< model_path = mp;
< texture_path = tp;
< bucket = b;
< tile = t;
< obj_trans = ot;
< cache_obj = co;
---
> model_path = mp;
> texture_path = tp;
> bucket = b;
> tile = t;
> obj_trans = ot;
> cache_obj = co;
>
> lat = setLat;
> lon = setLon;
> elev = setElev;
> hdg = setHdg;
96a109
>
98c111
< inline const string& get_model_path() const { return model_path; }
---
> inline const string& get_model_path() const { return model_path; }
103a117,125
>
> inline const double& get_lat() const { return lat; }
> inline const double& get_lon() const { return lon; }
> inline const double& get_elev() const { return elev; }
> inline const double& get_hdg() const { return hdg; }
>
> inline void set_obj_trans(osg::MatrixTransform *ot) {
> obj_trans = ot;
> }
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Flightgear-devel mailing list
Flightgear-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/flightgear-devel