obj.read_bin() followed by obj.write_bin() or obj.write_ascii()
"Dale E. Edmons" <[email protected]> Wed, 12 Jan 2005 04:14:53 -0800
| Newsgroups | gmane.games.flightgear.terragear.devel |
|---|---|
| Message-ID | <[email protected]> |
Hi,
I've implemented my SPX conversion stuff in TerraGear/SimGear. It seems
to work real well. However, I'm trying to write a btg2spx command that
will read existing files via SGBinObject::read_bin() and then re-write
it with SGBinObject::write_bin() {actually, write_spx()}. This will be
useful for changing the center of a model by changing the local_offset.
(Nearly identical to decode_binobj.cxx if decode_binobj called
write_ascii() instead of duplicating the library function.)
I've got the code almost completely working, however, I can't seem to
work out how to get the coordinates back into a form suitable to calling
sgGeodToCart(). My code compiles but I never get similar coordinates as
those generated using my modified TerraGear version.
Normally, before you do a obj.write_bin() you do something like the
following (from TerraGear/src/Airports/GenAirports/build.cxx):
---------------------
// calculate wgs84 mapping of nodes
point_list wgs84_nodes;
for ( i = 0; i < (int)geod_nodes.size(); ++i ) {
p.setx( geod_nodes[i].x() * SGD_DEGREES_TO_RADIANS );
p.sety( geod_nodes[i].y() * SGD_DEGREES_TO_RADIANS );
p.setz( geod_nodes[i].z() );
SG_LOG(SG_GENERAL, SG_DEBUG, "geod pt = " << geod_nodes[i] );
Point3D cart = sgGeodToCart( p );
SG_LOG(SG_GENERAL, SG_DEBUG, " cart pt = " << cart );
wgs84_nodes.push_back( cart );
}
... then:
obj.set_gbs_center( gbs_center );
obj.set_gbs_radius( gbs_radius );
obj.set_wgs84_nodes( wgs84_nodes );
...
obj.write_bin( objpath, name, b );
--------------
Here is my working version from my modified TerraGear...
----------------------
// calculate wgs84 mapping of nodes
point_list wgs84_nodes;
for ( i = 0; i < (int)geod_nodes.size(); ++i ) {
p.setx( geod_nodes[i].x() * SGD_DEGREES_TO_RADIANS );
p.sety( geod_nodes[i].y() * SGD_DEGREES_TO_RADIANS );
p.setz( geod_nodes[i].z() );
SG_LOG(SG_GENERAL, SG_DEBUG, "geod pt = " << geod_nodes[i] );
Point3D cart = sgGeodToCart( p );
SG_LOG(SG_GENERAL, SG_DEBUG, " cart pt = " << cart );
wgs84_nodes.push_back( cart );
}
//+dee
// calculate UTM mapping of nodes for SPX
point_list utm_nodes;
for ( i = 0; i < (int)geod_nodes.size(); ++i ) {
p.setx( geod_nodes[i].x() * SGD_DEGREES_TO_RADIANS );
p.sety( geod_nodes[i].y() * SGD_DEGREES_TO_RADIANS );
p.setz( geod_nodes[i].z() );
SG_LOG(SG_GENERAL, SG_DEBUG, "geod pt = " << geod_nodes[i] );
Point3D utm = sgGeodToUTM( p );
SG_LOG(SG_GENERAL, SG_DEBUG, " utm pt = " << utm );
utm_nodes.push_back( utm );
}
//-dee
.... (clip)...
//+dee
Point3D utm_center = sgCalcCenter( utm_nodes);
utm_center.setelev( 0.0 );
spxobj = obj;
spxobj.set_gbs_center( utm_center ); // actual center (may be
changed)
spxobj.set_wgs84_nodes( utm_nodes );
// Unify all UTM offsets by changing gbs to common value
spxobj.set_utm_offset( objpath, offset_name, b); // gbs likely
changed now
result = spxobj.write_spx( objpath, spx_name, b );
----------------------
The only difference is that my btg2spx.cxx does obj.read_bin() to set up
the object. I can't directly write because the nodes are offset so I
need to restore them to actual coordinates, convert them to geodetic via
sgCartToGeod() {I believe} where I can call my sgGeodToUTM(). Here is
my code if anybody has time to look and make suggestions:
int main( int argc, char **argv )
{
int i, j;
long int bindex;
string binname, spxname, base, name, path;
// check usage
if ( argc != 3 ) {
cout << "Usage: " << argv[0] << " base_path binary_obj_file" <<
endl;
exit(-1);
}
base = argv[1];
name = argv[2];
bindex = atoi(name.c_str());
SGBucket b(bindex); // FIXME: only works for numerics (can't
convert KSEA.btg.gz...)
path = base + b.gen_base_path();
binname = path + "/" + name + ".btg.gz";
cout << "opening: " << binname << endl;
//spxname = name + ".mac";
spxname = name;
SGBinObject obj, spxobj;
bool result = obj.read_bin( binname );
if ( !result ) {
cout << "error loading: " << binname << endl;
exit(-1);
}
point_list wgs84_nodes, utm_nodes;
Point3D geodr,geod, utm, center, cart;
double radius;
spxobj = obj; // This seems to work correctly.
// wgs84_nodes.clear();
// utm_nodes.clear();
center = obj.get_gbs_center();
radius = obj.get_gbs_radius();
//SGBucket b(center.x(), center.y());
wgs84_nodes = obj.get_wgs84_nodes();
cout << "converting " << wgs84_nodes.size() << " nodes to UTM" << endl;
cout << "center = " << center << endl;
for(int i=0; i < (int)wgs84_nodes.size(); i++) {
cart = wgs84_nodes[i] + center + Point3D(0.0,0.0,radius); //
radius made things worse
geodr = sgCartToGeod(cart);
geod.setx( geodr.x() / SGD_DEGREES_TO_RADIANS);
geod.sety( geodr.y() / SGD_DEGREES_TO_RADIANS);
geod.setz( geodr.z() / SGD_DEGREES_TO_RADIANS);
cout << "converting: " << geod << endl;
utm = sgGeodToUTM( geod ); // required!
cout << "result = " << utm << "\n" << endl;
utm_nodes.push_back( utm );
}
cout << "converted " << utm_nodes.size() << " nodes to UTM" << endl;
Point3D utm_center = sgCalcCenter( utm_nodes );
utm_center.setelev( 0.0 );
spxobj.set_gbs_center( utm_center );
spxobj.set_wgs84_nodes( utm_nodes );
spxobj.set_utm_offset( base, spxname, b);
result = spxobj.write_spx( base, spxname, b);
if( !result ) {
throw sg_exception("error writing spx file.");
}
------------
Thanks in advance if anybody has suggestions.
Dale
_______________________________________________
Terragear-devel mailing list
[email protected]
http://mail.flightgear.org/mailman/listinfo/terragear-devel
2f585eeea02e2c79d7b1d8c4963bae2d