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