Use binary gzip files to store intermediate and shared edge files
Sort the nodelist to speedup node lookup after all nodes inserted retrieve the node list just once in flatten elevation
This commit is contained in:
parent
b6a4dacf33
commit
c336c134bf
18 changed files with 757 additions and 199 deletions
|
@ -84,8 +84,8 @@ void TGConstruct::ConstructBucketStage1() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// STEP 1)
|
// STEP 1)
|
||||||
// Load grid of elevation data (Array)
|
// Load grid of elevation data (Array), and add the nodes
|
||||||
LoadElevationArray();
|
LoadElevationArray( true );
|
||||||
|
|
||||||
// STEP 2)
|
// STEP 2)
|
||||||
// Clip 2D polygons against one another
|
// Clip 2D polygons against one another
|
||||||
|
@ -131,37 +131,42 @@ void TGConstruct::ConstructBucketStage2() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// STEP 7)
|
// STEP 7)
|
||||||
// Need the array of elevation data for stage 2
|
// Need the array of elevation data for stage 2, but don't add the nodes - we already have them
|
||||||
LoadElevationArray();
|
LoadElevationArray( false );
|
||||||
|
|
||||||
// STEP 6)
|
// STEP 8)
|
||||||
// Merge in Shared data - should just be x,y nodes on the borders from stage1
|
// Merge in Shared data - should just be x,y nodes on the borders from stage1
|
||||||
LoadSharedEdgeData( 1 );
|
LoadSharedEdgeData( 1 );
|
||||||
|
|
||||||
// STEP 7)
|
// STEP 9)
|
||||||
// Fix T-Junctions by finding nodes that lie close to polygon edges, and
|
// Fix T-Junctions by finding nodes that lie close to polygon edges, and
|
||||||
// inserting them into the edge
|
// inserting them into the edge
|
||||||
FixTJunctions();
|
FixTJunctions();
|
||||||
|
|
||||||
// STEP 8)
|
// STEP 10)
|
||||||
// Generate triangles - we can't generate the node-face lookup table
|
// Generate triangles - we can't generate the node-face lookup table
|
||||||
// until all polys are tesselated, as extra nodes can still be generated
|
// until all polys are tesselated, as extra nodes can still be generated
|
||||||
TesselatePolys();
|
TesselatePolys();
|
||||||
|
|
||||||
// STEP 9)
|
// STEP 11)
|
||||||
|
// Optimize the node list now since linear add is faster than sorted add.
|
||||||
|
// no more nodes can be added from this point on
|
||||||
|
nodes.SortNodes();
|
||||||
|
|
||||||
|
// STEP 12)
|
||||||
// Generate triangle vertex coordinates to node index lists
|
// Generate triangle vertex coordinates to node index lists
|
||||||
// NOTE: After this point, no new nodes can be added
|
// NOTE: After this point, no new nodes can be added
|
||||||
LookupNodesPerVertex();
|
LookupNodesPerVertex();
|
||||||
|
|
||||||
// STEP 10)
|
// STEP 13)
|
||||||
// Interpolate elevations, and flatten stuff
|
// Interpolate elevations, and flatten stuff
|
||||||
CalcElevations();
|
CalcElevations();
|
||||||
|
|
||||||
// STEP 11)
|
// STEP 14)
|
||||||
// Generate face_connected list
|
// Generate face_connected list
|
||||||
LookupFacesPerNode();
|
LookupFacesPerNode();
|
||||||
|
|
||||||
// STEP 12)
|
// STEP 15)
|
||||||
// Save the tile boundary info for stage 3
|
// Save the tile boundary info for stage 3
|
||||||
// includes elevation info, and a list of connected triangles
|
// includes elevation info, and a list of connected triangles
|
||||||
SaveSharedEdgeData( 2 );
|
SaveSharedEdgeData( 2 );
|
||||||
|
@ -182,22 +187,24 @@ void TGConstruct::ConstructBucketStage3() {
|
||||||
strcpy( ds_name, "" );
|
strcpy( ds_name, "" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// STEP 16)
|
||||||
// Load in the neighbor faces and elevation data
|
// Load in the neighbor faces and elevation data
|
||||||
LoadSharedEdgeDataStage2();
|
LoadSharedEdgeDataStage2();
|
||||||
|
|
||||||
// STEP 12)
|
// STEP 17)
|
||||||
// Average out the elevation for nodes on tile boundaries
|
// Average out the elevation for nodes on tile boundaries
|
||||||
AverageEdgeElevations();
|
AverageEdgeElevations();
|
||||||
|
|
||||||
// STEP 12)
|
// STEP 18)
|
||||||
// Calculate Face Normals
|
// Calculate Face Normals
|
||||||
CalcFaceNormals();
|
CalcFaceNormals();
|
||||||
|
|
||||||
// STEP 13)
|
// STEP 19)
|
||||||
// Calculate Point Normals
|
// Calculate Point Normals
|
||||||
CalcPointNormals();
|
CalcPointNormals();
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
// STEP 20)
|
||||||
if ( c.get_cover().size() > 0 ) {
|
if ( c.get_cover().size() > 0 ) {
|
||||||
// Now for all the remaining "default" land cover polygons, assign
|
// Now for all the remaining "default" land cover polygons, assign
|
||||||
// each one it's proper type from the land use/land cover
|
// each one it's proper type from the land use/land cover
|
||||||
|
@ -206,15 +213,15 @@ void TGConstruct::ConstructBucketStage3() {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// STEP 14)
|
// STEP 21)
|
||||||
// Calculate Texture Coordinates
|
// Calculate Texture Coordinates
|
||||||
CalcTextureCoordinates();
|
CalcTextureCoordinates();
|
||||||
|
|
||||||
// STEP 16)
|
// STEP 22)
|
||||||
// Generate the btg file
|
// Generate the btg file
|
||||||
WriteBtgFile();
|
WriteBtgFile();
|
||||||
|
|
||||||
// STEP 17)
|
// STEP 23)
|
||||||
// Write Custom objects to .stg file
|
// Write Custom objects to .stg file
|
||||||
AddCustomObjects();
|
AddCustomObjects();
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,7 +120,7 @@ private:
|
||||||
bool IsOceanTile() { return isOcean; }
|
bool IsOceanTile() { return isOcean; }
|
||||||
|
|
||||||
// Load Data
|
// Load Data
|
||||||
void LoadElevationArray( void );
|
void LoadElevationArray( bool add_nodes );
|
||||||
int LoadLandclassPolys( void );
|
int LoadLandclassPolys( void );
|
||||||
// Load Data Helpers
|
// Load Data Helpers
|
||||||
bool load_poly(const std::string& path);
|
bool load_poly(const std::string& path);
|
||||||
|
@ -135,14 +135,14 @@ private:
|
||||||
// Shared edge Matching
|
// Shared edge Matching
|
||||||
void SaveSharedEdgeDataStage2( void );
|
void SaveSharedEdgeDataStage2( void );
|
||||||
void LoadSharedEdgeDataStage2( void );
|
void LoadSharedEdgeDataStage2( void );
|
||||||
void WriteSharedEdgeNeighboorFaces( std::ofstream& ofs_e, Point3D pt );
|
void WriteSharedEdgeNeighboorFaces( gzFile& fp, Point3D pt );
|
||||||
void LoadSharedEdgeData( int stage );
|
void LoadSharedEdgeData( int stage );
|
||||||
void LoadNeighboorEdgeDataStage1( SGBucket& b, point_list& north, point_list& south, point_list& east, point_list& west );
|
void LoadNeighboorEdgeDataStage1( SGBucket& b, point_list& north, point_list& south, point_list& east, point_list& west );
|
||||||
|
|
||||||
void SaveSharedEdgeData( int stage );
|
void SaveSharedEdgeData( int stage );
|
||||||
|
|
||||||
void ReadNeighborFaces( std::ifstream& ifs_e );
|
void ReadNeighborFaces( gzFile& fp );
|
||||||
void WriteNeighborFaces( std::ofstream& ofs_e, Point3D pt );
|
void WriteNeighborFaces( gzFile& fp, Point3D pt );
|
||||||
TGNeighborFaces* AddNeighborFaces( Point3D node );
|
TGNeighborFaces* AddNeighborFaces( Point3D node );
|
||||||
TGNeighborFaces* FindNeighborFaces( Point3D node );
|
TGNeighborFaces* FindNeighborFaces( Point3D node );
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ using std::string;
|
||||||
|
|
||||||
// Load elevation data from an Array file (a regular grid of elevation data)
|
// Load elevation data from an Array file (a regular grid of elevation data)
|
||||||
// and return list of fitted nodes.
|
// and return list of fitted nodes.
|
||||||
void TGConstruct::LoadElevationArray( void ) {
|
void TGConstruct::LoadElevationArray( bool add_nodes ) {
|
||||||
string base = bucket.gen_base_path();
|
string base = bucket.gen_base_path();
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -49,6 +49,7 @@ void TGConstruct::LoadElevationArray( void ) {
|
||||||
array.parse( bucket );
|
array.parse( bucket );
|
||||||
array.remove_voids( );
|
array.remove_voids( );
|
||||||
|
|
||||||
|
if ( add_nodes ) {
|
||||||
point_list corner_list = array.get_corner_list();
|
point_list corner_list = array.get_corner_list();
|
||||||
for (unsigned int i=0; i<corner_list.size(); i++) {
|
for (unsigned int i=0; i<corner_list.size(); i++) {
|
||||||
nodes.unique_add(corner_list[i]);
|
nodes.unique_add(corner_list[i]);
|
||||||
|
@ -59,6 +60,7 @@ void TGConstruct::LoadElevationArray( void ) {
|
||||||
nodes.unique_add(fit_list[i]);
|
nodes.unique_add(fit_list[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void calc_gc_course_dist( const Point3D& start, const Point3D& dest,
|
static void calc_gc_course_dist( const Point3D& start, const Point3D& dest,
|
||||||
double *course, double *dist ) {
|
double *course, double *dist ) {
|
||||||
|
@ -92,6 +94,7 @@ void TGConstruct::CalcElevations( void )
|
||||||
TGPolyNodes tri_nodes;
|
TGPolyNodes tri_nodes;
|
||||||
double e1, e2, e3, min;
|
double e1, e2, e3, min;
|
||||||
int n1, n2, n3;
|
int n1, n2, n3;
|
||||||
|
point_list raw_nodes;
|
||||||
Point3D p;
|
Point3D p;
|
||||||
|
|
||||||
SG_LOG(SG_GENERAL, SG_ALERT, "fixing node heights");
|
SG_LOG(SG_GENERAL, SG_ALERT, "fixing node heights");
|
||||||
|
@ -106,6 +109,7 @@ void TGConstruct::CalcElevations( void )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
raw_nodes = nodes.get_geod_nodes();
|
||||||
// now flatten some stuff
|
// now flatten some stuff
|
||||||
for (unsigned int area = 0; area < TG_MAX_AREA_TYPES; area++) {
|
for (unsigned int area = 0; area < TG_MAX_AREA_TYPES; area++) {
|
||||||
if ( is_lake_area( (AreaType)area ) ) {
|
if ( is_lake_area( (AreaType)area ) ) {
|
||||||
|
@ -153,7 +157,6 @@ void TGConstruct::CalcElevations( void )
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
point_list raw_nodes = nodes.get_geod_nodes();
|
|
||||||
|
|
||||||
n1 = tri_nodes.get_pt( tri, 0 );
|
n1 = tri_nodes.get_pt( tri, 0 );
|
||||||
e1 = nodes.get_node(n1).GetPosition().z();
|
e1 = nodes.get_node(n1).GetPosition().z();
|
||||||
|
@ -197,7 +200,6 @@ void TGConstruct::CalcElevations( void )
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
point_list raw_nodes = nodes.get_geod_nodes();
|
|
||||||
|
|
||||||
n1 = tri_nodes.get_pt( tri, 0 );
|
n1 = tri_nodes.get_pt( tri, 0 );
|
||||||
e1 = nodes.get_node(n1).GetPosition().z();
|
e1 = nodes.get_node(n1).GetPosition().z();
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
// indexes into the node array (cast as unsigned long)
|
// indexes into the node array (cast as unsigned long)
|
||||||
void TGConstruct::LookupNodesPerVertex( void )
|
void TGConstruct::LookupNodesPerVertex( void )
|
||||||
{
|
{
|
||||||
SG_LOG(SG_GENERAL, SG_ALERT, "LookupNodexPerVertex");
|
SG_LOG(SG_GENERAL, SG_ALERT, "LookupNodesPerVertex");
|
||||||
|
|
||||||
// for each node, traverse all the triangles - and create face lists
|
// for each node, traverse all the triangles - and create face lists
|
||||||
for ( unsigned int area = 0; area < TG_MAX_AREA_TYPES; area++ ) {
|
for ( unsigned int area = 0; area < TG_MAX_AREA_TYPES; area++ ) {
|
||||||
|
@ -50,6 +50,7 @@ void TGConstruct::LookupNodesPerVertex( void )
|
||||||
if (idx >= 0) {
|
if (idx >= 0) {
|
||||||
tri_nodes.add_node( tri, idx );
|
tri_nodes.add_node( tri, idx );
|
||||||
} else {
|
} else {
|
||||||
|
SG_LOG(SG_GENERAL, SG_ALERT, "didn't find vertex! " << tris.get_pt( tri, vertex ) );
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
#include <simgear/misc/sg_dir.hxx>
|
#include <simgear/misc/sg_dir.hxx>
|
||||||
#include <simgear/debug/logstream.hxx>
|
#include <simgear/debug/logstream.hxx>
|
||||||
|
#include <simgear/io/lowlevel.hxx>
|
||||||
|
|
||||||
#include <Geometry/poly_support.hxx>
|
#include <Geometry/poly_support.hxx>
|
||||||
|
|
||||||
|
@ -37,8 +38,7 @@ using std::string;
|
||||||
|
|
||||||
void TGConstruct::SaveSharedEdgeData( int stage )
|
void TGConstruct::SaveSharedEdgeData( int stage )
|
||||||
{
|
{
|
||||||
string dir;
|
string filepath;
|
||||||
string file;
|
|
||||||
|
|
||||||
switch( stage ) {
|
switch( stage ) {
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -48,48 +48,47 @@ void TGConstruct::SaveSharedEdgeData( int stage )
|
||||||
|
|
||||||
nodes.get_geod_edge( bucket, north, south, east, west );
|
nodes.get_geod_edge( bucket, north, south, east, west );
|
||||||
|
|
||||||
dir = share_base + "/stage1/" + bucket.gen_base_path();
|
filepath = share_base + "/stage1/" + bucket.gen_base_path() + "/" + bucket.gen_index_str() + "_edges";
|
||||||
|
SGPath file(filepath);
|
||||||
|
file.create_dir( 0755 );
|
||||||
|
|
||||||
SGPath sgp( dir );
|
gzFile fp;
|
||||||
sgp.append( "dummy" );
|
if ( (fp = gzopen( filepath.c_str(), "wb9" )) == NULL ) {
|
||||||
sgp.create_dir( 0755 );
|
SG_LOG( SG_GENERAL, SG_INFO, "ERROR: opening " << file.str() << " for writing!" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
file = dir + "/" + bucket.gen_index_str() + "_edges";
|
sgClearWriteError();
|
||||||
std::ofstream ofs_e( file.c_str() );
|
|
||||||
|
|
||||||
// first, set the precision
|
|
||||||
ofs_e << std::setprecision(12);
|
|
||||||
ofs_e << std::fixed;
|
|
||||||
|
|
||||||
// north
|
// north
|
||||||
nCount = north.size();
|
nCount = north.size();
|
||||||
ofs_e << nCount << "\n";
|
sgWriteInt( fp, nCount );
|
||||||
for (int i=0; i<nCount; i++) {
|
for (int i=0; i<nCount; i++) {
|
||||||
ofs_e << north[i];
|
sgWritePoint3D( fp, north[i] );
|
||||||
}
|
}
|
||||||
|
|
||||||
// south
|
// south
|
||||||
nCount = south.size();
|
nCount = south.size();
|
||||||
ofs_e << nCount << "\n";
|
sgWriteInt( fp, nCount );
|
||||||
for (int i=0; i<nCount; i++) {
|
for (int i=0; i<nCount; i++) {
|
||||||
ofs_e << south[i];
|
sgWritePoint3D( fp, south[i] );
|
||||||
}
|
}
|
||||||
|
|
||||||
// east
|
// east
|
||||||
nCount = east.size();
|
nCount = east.size();
|
||||||
ofs_e << nCount << "\n";
|
sgWriteInt( fp, nCount );
|
||||||
for (int i=0; i<nCount; i++) {
|
for (int i=0; i<nCount; i++) {
|
||||||
ofs_e << east[i];
|
sgWritePoint3D( fp, east[i] );
|
||||||
}
|
}
|
||||||
|
|
||||||
// west
|
// west
|
||||||
nCount = west.size();
|
nCount = west.size();
|
||||||
ofs_e << nCount << "\n";
|
sgWriteInt( fp, nCount );
|
||||||
for (int i=0; i<nCount; i++) {
|
for (int i=0; i<nCount; i++) {
|
||||||
ofs_e << west[i];
|
sgWritePoint3D( fp, west[i] );
|
||||||
}
|
}
|
||||||
|
|
||||||
ofs_e.close();
|
gzclose(fp);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -111,7 +110,7 @@ void TGConstruct::SaveSharedEdgeData( int stage )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TGConstruct::WriteNeighborFaces( std::ofstream& ofs_e, Point3D pt )
|
void TGConstruct::WriteNeighborFaces( gzFile& fp, Point3D pt )
|
||||||
{
|
{
|
||||||
// find all neighboors of this point
|
// find all neighboors of this point
|
||||||
int n = nodes.find( pt );
|
int n = nodes.find( pt );
|
||||||
|
@ -119,7 +118,7 @@ void TGConstruct::WriteNeighborFaces( std::ofstream& ofs_e, Point3D pt )
|
||||||
TGFaceList faces = node.GetFaces();
|
TGFaceList faces = node.GetFaces();
|
||||||
|
|
||||||
// write the number of neighboor faces
|
// write the number of neighboor faces
|
||||||
ofs_e << faces.size() << "\n";
|
sgWriteInt( fp, faces.size() );
|
||||||
|
|
||||||
// write out each face normal and size
|
// write out each face normal and size
|
||||||
for (unsigned int j=0; j<faces.size(); j++) {
|
for (unsigned int j=0; j<faces.size(); j++) {
|
||||||
|
@ -142,11 +141,10 @@ void TGConstruct::WriteNeighborFaces( std::ofstream& ofs_e, Point3D pt )
|
||||||
double face_area = triangle_area( p1, p2, p3 );
|
double face_area = triangle_area( p1, p2, p3 );
|
||||||
Point3D face_normal = Point3D::fromSGVec3( calc_normal( face_area, wgs_p1, wgs_p2, wgs_p3 ) );
|
Point3D face_normal = Point3D::fromSGVec3( calc_normal( face_area, wgs_p1, wgs_p2, wgs_p3 ) );
|
||||||
|
|
||||||
ofs_e << face_area << " ";
|
sgWriteDouble( fp, face_area );
|
||||||
ofs_e << face_normal;
|
sgWritePoint3D( fp, face_normal );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ofs_e << "\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TGNeighborFaces* TGConstruct::FindNeighborFaces( Point3D node )
|
TGNeighborFaces* TGConstruct::FindNeighborFaces( Point3D node )
|
||||||
|
@ -173,19 +171,19 @@ TGNeighborFaces* TGConstruct::AddNeighborFaces( Point3D node )
|
||||||
return &neighbor_faces[neighbor_faces.size()-1];
|
return &neighbor_faces[neighbor_faces.size()-1];
|
||||||
}
|
}
|
||||||
|
|
||||||
void TGConstruct::ReadNeighborFaces( std::ifstream& in )
|
void TGConstruct::ReadNeighborFaces( gzFile& fp )
|
||||||
{
|
{
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
// read the count
|
// read the count
|
||||||
in >> count;
|
sgReadInt( fp, &count );
|
||||||
|
|
||||||
for (int i=0; i<count; i++) {
|
for (int i=0; i<count; i++) {
|
||||||
TGNeighborFaces* pFaces;
|
TGNeighborFaces* pFaces;
|
||||||
Point3D node;
|
Point3D node;
|
||||||
int num_faces;
|
int num_faces;
|
||||||
|
|
||||||
in >> node;
|
sgReadPoint3D( fp, node );
|
||||||
|
|
||||||
// look to see if we already have this node
|
// look to see if we already have this node
|
||||||
// If we do, (it's a corner) add more faces to it.
|
// If we do, (it's a corner) add more faces to it.
|
||||||
|
@ -205,16 +203,16 @@ void TGConstruct::ReadNeighborFaces( std::ifstream& in )
|
||||||
// remember all of the elevation data for the node, so we can average
|
// remember all of the elevation data for the node, so we can average
|
||||||
pFaces->elevations.push_back( node.z() );
|
pFaces->elevations.push_back( node.z() );
|
||||||
|
|
||||||
in >> num_faces;
|
sgReadInt( fp, &num_faces );
|
||||||
for (int j=0; j<num_faces; j++)
|
for (int j=0; j<num_faces; j++)
|
||||||
{
|
{
|
||||||
double area;
|
double area;
|
||||||
Point3D normal;
|
Point3D normal;
|
||||||
|
|
||||||
in >> area;
|
sgReadDouble( fp, &area );
|
||||||
pFaces->face_areas.push_back( area );
|
pFaces->face_areas.push_back( area );
|
||||||
|
|
||||||
in >> normal;
|
sgReadPoint3D( fp, normal );
|
||||||
pFaces->face_normals.push_back( normal );
|
pFaces->face_normals.push_back( normal );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -225,7 +223,6 @@ void TGConstruct::SaveSharedEdgeDataStage2( void )
|
||||||
string dir;
|
string dir;
|
||||||
string file;
|
string file;
|
||||||
point_list north, south, east, west;
|
point_list north, south, east, west;
|
||||||
std::ofstream ofs_e;
|
|
||||||
int nCount;
|
int nCount;
|
||||||
|
|
||||||
nodes.get_geod_edge( bucket, north, south, east, west );
|
nodes.get_geod_edge( bucket, north, south, east, west );
|
||||||
|
@ -239,110 +236,123 @@ void TGConstruct::SaveSharedEdgeDataStage2( void )
|
||||||
|
|
||||||
// north edge
|
// north edge
|
||||||
file = dir + "/" + bucket.gen_index_str() + "_north_edge";
|
file = dir + "/" + bucket.gen_index_str() + "_north_edge";
|
||||||
ofs_e.open( file.c_str() );
|
gzFile fp;
|
||||||
ofs_e << std::setprecision(12);
|
if ( (fp = gzopen( file.c_str(), "wb9" )) == NULL ) {
|
||||||
ofs_e << std::fixed;
|
SG_LOG( SG_GENERAL, SG_INFO,"ERROR: opening " << file.c_str() << " for writing!" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sgClearWriteError();
|
||||||
|
|
||||||
nCount = north.size();
|
nCount = north.size();
|
||||||
ofs_e << nCount << "\n";
|
sgWriteInt( fp, nCount );
|
||||||
for (int i=0; i<nCount; i++) {
|
for (int i=0; i<nCount; i++) {
|
||||||
// write the 3d point
|
// write the 3d point
|
||||||
ofs_e << north[i];
|
sgWritePoint3D( fp, north[i] );
|
||||||
WriteNeighborFaces( ofs_e, north[i] );
|
WriteNeighborFaces( fp, north[i] );
|
||||||
}
|
}
|
||||||
ofs_e.close();
|
gzclose(fp);
|
||||||
|
|
||||||
// south edge
|
// south edge
|
||||||
file = dir + "/" + bucket.gen_index_str() + "_south_edge";
|
file = dir + "/" + bucket.gen_index_str() + "_south_edge";
|
||||||
ofs_e.open( file.c_str() );
|
if ( (fp = gzopen( file.c_str(), "wb9" )) == NULL ) {
|
||||||
ofs_e << std::setprecision(12);
|
SG_LOG( SG_GENERAL, SG_INFO,"ERROR: opening " << file.c_str() << " for writing!" );
|
||||||
ofs_e << std::fixed;
|
return;
|
||||||
|
}
|
||||||
|
sgClearWriteError();
|
||||||
|
|
||||||
nCount = south.size();
|
nCount = south.size();
|
||||||
ofs_e << nCount << "\n";
|
sgWriteInt( fp, nCount );
|
||||||
for (int i=0; i<nCount; i++) {
|
for (int i=0; i<nCount; i++) {
|
||||||
ofs_e << south[i];
|
sgWritePoint3D( fp, south[i] );
|
||||||
WriteNeighborFaces( ofs_e, south[i] );
|
WriteNeighborFaces( fp, south[i] );
|
||||||
}
|
}
|
||||||
ofs_e.close();
|
gzclose(fp);
|
||||||
|
|
||||||
// east edge
|
// east edge
|
||||||
file = dir + "/" + bucket.gen_index_str() + "_east_edge";
|
file = dir + "/" + bucket.gen_index_str() + "_east_edge";
|
||||||
ofs_e.open( file.c_str() );
|
if ( (fp = gzopen( file.c_str(), "wb9" )) == NULL ) {
|
||||||
ofs_e << std::setprecision(12);
|
SG_LOG( SG_GENERAL, SG_INFO,"ERROR: opening " << file.c_str() << " for writing!" );
|
||||||
ofs_e << std::fixed;
|
return;
|
||||||
|
}
|
||||||
|
sgClearWriteError();
|
||||||
|
|
||||||
nCount = east.size();
|
nCount = east.size();
|
||||||
ofs_e << nCount << "\n";
|
sgWriteInt( fp, nCount );
|
||||||
for (int i=0; i<nCount; i++) {
|
for (int i=0; i<nCount; i++) {
|
||||||
ofs_e << east[i];
|
sgWritePoint3D( fp, east[i] );
|
||||||
WriteNeighborFaces( ofs_e, east[i] );
|
WriteNeighborFaces( fp, east[i] );
|
||||||
}
|
}
|
||||||
ofs_e.close();
|
gzclose(fp);
|
||||||
|
|
||||||
// west egde
|
// west egde
|
||||||
file = dir + "/" + bucket.gen_index_str() + "_west_edge";
|
file = dir + "/" + bucket.gen_index_str() + "_west_edge";
|
||||||
ofs_e.open( file.c_str() );
|
if ( (fp = gzopen( file.c_str(), "wb9" )) == NULL ) {
|
||||||
ofs_e << std::setprecision(12);
|
SG_LOG( SG_GENERAL, SG_INFO,"ERROR: opening " << file.c_str() << " for writing!" );
|
||||||
ofs_e << std::fixed;
|
return;
|
||||||
|
}
|
||||||
|
sgClearWriteError();
|
||||||
|
|
||||||
nCount = west.size();
|
nCount = west.size();
|
||||||
ofs_e << nCount << "\n";
|
sgWriteInt( fp, nCount );
|
||||||
for (int i=0; i<nCount; i++) {
|
for (int i=0; i<nCount; i++) {
|
||||||
ofs_e << west[i];
|
sgWritePoint3D( fp, west[i] );
|
||||||
WriteNeighborFaces( ofs_e, west[i] );
|
WriteNeighborFaces( fp, west[i] );
|
||||||
}
|
}
|
||||||
ofs_e.close();
|
gzclose(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TGConstruct::LoadSharedEdgeDataStage2( void )
|
void TGConstruct::LoadSharedEdgeDataStage2( void )
|
||||||
{
|
{
|
||||||
string dir;
|
string dir;
|
||||||
string file;
|
string file;
|
||||||
std::ifstream ifs_edge;
|
|
||||||
double clon = bucket.get_center_lon();
|
double clon = bucket.get_center_lon();
|
||||||
double clat = bucket.get_center_lat();
|
double clat = bucket.get_center_lat();
|
||||||
|
gzFile fp;
|
||||||
SGBucket b;
|
SGBucket b;
|
||||||
|
|
||||||
// Read Northern tile and add its southern node faces
|
// Read Northern tile and add its southern node faces
|
||||||
b = sgBucketOffset(clon, clat, 0, 1);
|
b = sgBucketOffset(clon, clat, 0, 1);
|
||||||
dir = share_base + "/stage2/" + b.gen_base_path();
|
dir = share_base + "/stage2/" + b.gen_base_path();
|
||||||
file = dir + "/" + b.gen_index_str() + "_south_edge";
|
file = dir + "/" + b.gen_index_str() + "_south_edge";
|
||||||
ifs_edge.open( file.c_str() );
|
fp = gzopen( file.c_str(), "rb" );
|
||||||
if ( ifs_edge.is_open() ) {
|
if (fp) {
|
||||||
ReadNeighborFaces( ifs_edge );
|
sgClearReadError();
|
||||||
|
ReadNeighborFaces( fp );
|
||||||
|
gzclose( fp );
|
||||||
}
|
}
|
||||||
ifs_edge.close();
|
|
||||||
|
|
||||||
// Read Southern tile and add its northern node faces
|
// Read Southern tile and add its northern node faces
|
||||||
b = sgBucketOffset(clon, clat, 0, -1);
|
b = sgBucketOffset(clon, clat, 0, -1);
|
||||||
dir = share_base + "/stage2/" + b.gen_base_path();
|
dir = share_base + "/stage2/" + b.gen_base_path();
|
||||||
file = dir + "/" + b.gen_index_str() + "_north_edge";
|
file = dir + "/" + b.gen_index_str() + "_north_edge";
|
||||||
ifs_edge.open( file.c_str() );
|
fp = gzopen( file.c_str(), "rb" );
|
||||||
if ( ifs_edge.is_open() ) {
|
if (fp) {
|
||||||
ReadNeighborFaces( ifs_edge );
|
sgClearReadError();
|
||||||
|
ReadNeighborFaces( fp );
|
||||||
|
gzclose( fp );
|
||||||
}
|
}
|
||||||
ifs_edge.close();
|
|
||||||
|
|
||||||
// Read Eastern tile and add its western node faces
|
// Read Eastern tile and add its western node faces
|
||||||
b = sgBucketOffset(clon, clat, 1, 0);
|
b = sgBucketOffset(clon, clat, 1, 0);
|
||||||
dir = share_base + "/stage2/" + b.gen_base_path();
|
dir = share_base + "/stage2/" + b.gen_base_path();
|
||||||
file = dir + "/" + b.gen_index_str() + "_west_edge";
|
file = dir + "/" + b.gen_index_str() + "_west_edge";
|
||||||
ifs_edge.open( file.c_str() );
|
fp = gzopen( file.c_str(), "rb" );
|
||||||
if ( ifs_edge.is_open() ) {
|
if (fp) {
|
||||||
ReadNeighborFaces( ifs_edge );
|
sgClearReadError();
|
||||||
|
ReadNeighborFaces( fp );
|
||||||
|
gzclose( fp );
|
||||||
}
|
}
|
||||||
ifs_edge.close();
|
|
||||||
|
|
||||||
// Read Western tile and add its eastern node faces
|
// Read Western tile and add its eastern node faces
|
||||||
b = sgBucketOffset(clon, clat, -1, 0);
|
b = sgBucketOffset(clon, clat, -1, 0);
|
||||||
dir = share_base + "/stage2/" + b.gen_base_path();
|
dir = share_base + "/stage2/" + b.gen_base_path();
|
||||||
file = dir + "/" + b.gen_index_str() + "_east_edge";
|
file = dir + "/" + b.gen_index_str() + "_east_edge";
|
||||||
ifs_edge.open( file.c_str() );
|
fp = gzopen( file.c_str(), "rb" );
|
||||||
if ( ifs_edge.is_open() ) {
|
if (fp) {
|
||||||
ReadNeighborFaces( ifs_edge );
|
sgClearReadError();
|
||||||
|
ReadNeighborFaces( fp );
|
||||||
|
gzclose( fp );
|
||||||
}
|
}
|
||||||
ifs_edge.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -350,6 +360,7 @@ void TGConstruct::SaveToIntermediateFiles( int stage )
|
||||||
{
|
{
|
||||||
string dir;
|
string dir;
|
||||||
string file;
|
string file;
|
||||||
|
gzFile fp;
|
||||||
|
|
||||||
switch( stage ) {
|
switch( stage ) {
|
||||||
case 1: // Save the clipped polys and node list
|
case 1: // Save the clipped polys and node list
|
||||||
|
@ -363,22 +374,22 @@ void TGConstruct::SaveToIntermediateFiles( int stage )
|
||||||
sgp.create_dir( 0755 );
|
sgp.create_dir( 0755 );
|
||||||
|
|
||||||
file = dir + "/" + bucket.gen_index_str() + "_clipped_polys";
|
file = dir + "/" + bucket.gen_index_str() + "_clipped_polys";
|
||||||
std::ofstream ofs_cp( file.c_str() );
|
if ( (fp = gzopen( file.c_str(), "wb9" )) == NULL ) {
|
||||||
|
SG_LOG( SG_GENERAL, SG_INFO,"ERROR: opening " << file.c_str() << " for writing!" );
|
||||||
// first, set the precision
|
return;
|
||||||
ofs_cp << std::setprecision(15);
|
}
|
||||||
ofs_cp << std::fixed;
|
sgClearWriteError();
|
||||||
ofs_cp << polys_clipped;
|
polys_clipped.SaveToGzFile( fp );
|
||||||
ofs_cp.close();
|
gzclose( fp );
|
||||||
|
|
||||||
file = dir + "/" + bucket.gen_index_str() + "_nodes";
|
file = dir + "/" + bucket.gen_index_str() + "_nodes";
|
||||||
std::ofstream ofs_n( file.c_str() );
|
if ( (fp = gzopen( file.c_str(), "wb9" )) == NULL ) {
|
||||||
|
SG_LOG( SG_GENERAL, SG_INFO,"ERROR: opening " << file.c_str() << " for writing!" );
|
||||||
// first, set the precision
|
return;
|
||||||
ofs_n << std::setprecision(15);
|
}
|
||||||
ofs_n << std::fixed;
|
sgClearWriteError();
|
||||||
ofs_n << nodes;
|
nodes.SaveToGzFile( fp );
|
||||||
ofs_n.close();
|
gzclose( fp );
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -394,22 +405,22 @@ void TGConstruct::SaveToIntermediateFiles( int stage )
|
||||||
sgp.create_dir( 0755 );
|
sgp.create_dir( 0755 );
|
||||||
|
|
||||||
file = dir + "/" + bucket.gen_index_str() + "_clipped_polys";
|
file = dir + "/" + bucket.gen_index_str() + "_clipped_polys";
|
||||||
std::ofstream ofs_cp( file.c_str() );
|
if ( (fp = gzopen( file.c_str(), "wb9" )) == NULL ) {
|
||||||
|
SG_LOG( SG_GENERAL, SG_INFO,"ERROR: opening " << file.c_str() << " for writing!" );
|
||||||
// first, set the precision
|
return;
|
||||||
ofs_cp << std::setprecision(15);
|
}
|
||||||
ofs_cp << std::fixed;
|
sgClearWriteError();
|
||||||
ofs_cp << polys_clipped;
|
polys_clipped.SaveToGzFile( fp );
|
||||||
ofs_cp.close();
|
gzclose( fp );
|
||||||
|
|
||||||
file = dir + "/" + bucket.gen_index_str() + "_nodes";
|
file = dir + "/" + bucket.gen_index_str() + "_nodes";
|
||||||
std::ofstream ofs_n( file.c_str() );
|
if ( (fp = gzopen( file.c_str(), "wb9" )) == NULL ) {
|
||||||
|
SG_LOG( SG_GENERAL, SG_INFO,"ERROR: opening " << file.c_str() << " for writing!" );
|
||||||
// first, set the precision
|
return;
|
||||||
ofs_n << std::setprecision(15);
|
}
|
||||||
ofs_n << std::fixed;
|
sgClearWriteError();
|
||||||
ofs_n << nodes;
|
nodes.SaveToGzFile( fp );
|
||||||
ofs_n.close();
|
gzclose( fp );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -420,52 +431,53 @@ void TGConstruct::LoadNeighboorEdgeDataStage1( SGBucket& b, point_list& north, p
|
||||||
{
|
{
|
||||||
string dir;
|
string dir;
|
||||||
string file;
|
string file;
|
||||||
|
gzFile fp;
|
||||||
Point3D pt;
|
Point3D pt;
|
||||||
int nCount;
|
int nCount;
|
||||||
|
|
||||||
dir = share_base + "/stage1/" + b.gen_base_path();
|
dir = share_base + "/stage1/" + b.gen_base_path();
|
||||||
file = dir + "/" + b.gen_index_str() + "_edges";
|
file = dir + "/" + b.gen_index_str() + "_edges";
|
||||||
std::ifstream ifs_edges( file.c_str() );
|
fp = gzopen( file.c_str(), "rb" );
|
||||||
|
|
||||||
north.clear();
|
north.clear();
|
||||||
south.clear();
|
south.clear();
|
||||||
east.clear();
|
east.clear();
|
||||||
west.clear();
|
west.clear();
|
||||||
|
|
||||||
if ( ifs_edges.is_open() ) {
|
if (fp) {
|
||||||
// North
|
// North
|
||||||
ifs_edges >> nCount;
|
sgReadInt( fp, &nCount );
|
||||||
SG_LOG( SG_CLIPPER, SG_INFO, "loading " << nCount << "Points on " << b.gen_index_str() << " north boundary");
|
SG_LOG( SG_CLIPPER, SG_INFO, "loading " << nCount << "Points on " << b.gen_index_str() << " north boundary");
|
||||||
for (int i=0; i<nCount; i++) {
|
for (int i=0; i<nCount; i++) {
|
||||||
ifs_edges >> pt;
|
sgReadPoint3D( fp, pt );
|
||||||
north.push_back(pt);
|
north.push_back(pt);
|
||||||
}
|
}
|
||||||
|
|
||||||
// South
|
// South
|
||||||
ifs_edges >> nCount;
|
sgReadInt( fp, &nCount );
|
||||||
SG_LOG( SG_CLIPPER, SG_INFO, "loading " << nCount << "Points on " << b.gen_index_str() << " south boundary");
|
SG_LOG( SG_CLIPPER, SG_INFO, "loading " << nCount << "Points on " << b.gen_index_str() << " south boundary");
|
||||||
for (int i=0; i<nCount; i++) {
|
for (int i=0; i<nCount; i++) {
|
||||||
ifs_edges >> pt;
|
sgReadPoint3D( fp, pt );
|
||||||
south.push_back(pt);
|
south.push_back(pt);
|
||||||
}
|
}
|
||||||
|
|
||||||
// East
|
// East
|
||||||
ifs_edges >> nCount;
|
sgReadInt( fp, &nCount );
|
||||||
SG_LOG( SG_CLIPPER, SG_INFO, "loading " << nCount << "Points on " << b.gen_index_str() << " east boundary");
|
SG_LOG( SG_CLIPPER, SG_INFO, "loading " << nCount << "Points on " << b.gen_index_str() << " east boundary");
|
||||||
for (int i=0; i<nCount; i++) {
|
for (int i=0; i<nCount; i++) {
|
||||||
ifs_edges >> pt;
|
sgReadPoint3D( fp, pt );
|
||||||
east.push_back(pt);
|
east.push_back(pt);
|
||||||
}
|
}
|
||||||
|
|
||||||
// West
|
// West
|
||||||
ifs_edges >> nCount;
|
sgReadInt( fp, &nCount );
|
||||||
SG_LOG( SG_CLIPPER, SG_INFO, "loading " << nCount << "Points on " << b.gen_index_str() << " west boundary");
|
SG_LOG( SG_CLIPPER, SG_INFO, "loading " << nCount << "Points on " << b.gen_index_str() << " west boundary");
|
||||||
for (int i=0; i<nCount; i++) {
|
for (int i=0; i<nCount; i++) {
|
||||||
ifs_edges >> pt;
|
sgReadPoint3D( fp, pt );
|
||||||
west.push_back(pt);
|
west.push_back(pt);
|
||||||
}
|
}
|
||||||
|
|
||||||
ifs_edges.close();
|
gzclose( fp );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -517,6 +529,7 @@ void TGConstruct::LoadFromIntermediateFiles( int stage )
|
||||||
{
|
{
|
||||||
string dir;
|
string dir;
|
||||||
string file;
|
string file;
|
||||||
|
gzFile fp;
|
||||||
bool read_ok = false;
|
bool read_ok = false;
|
||||||
|
|
||||||
switch( stage ) {
|
switch( stage ) {
|
||||||
|
@ -524,18 +537,18 @@ void TGConstruct::LoadFromIntermediateFiles( int stage )
|
||||||
{
|
{
|
||||||
dir = share_base + "/stage1/" + bucket.gen_base_path();
|
dir = share_base + "/stage1/" + bucket.gen_base_path();
|
||||||
file = dir + "/" + bucket.gen_index_str() + "_clipped_polys";
|
file = dir + "/" + bucket.gen_index_str() + "_clipped_polys";
|
||||||
|
fp = gzopen( file.c_str(), "rb" );
|
||||||
|
|
||||||
std::ifstream ifs_cp( file.c_str() );
|
if ( fp ) {
|
||||||
if ( ifs_cp.good() ) {
|
polys_clipped.LoadFromGzFile( fp );
|
||||||
ifs_cp >> polys_clipped;
|
gzclose( fp );
|
||||||
ifs_cp.close();
|
|
||||||
|
|
||||||
file = dir + "/" + bucket.gen_index_str() + "_nodes";
|
file = dir + "/" + bucket.gen_index_str() + "_nodes";
|
||||||
|
fp = gzopen( file.c_str(), "rb" );
|
||||||
|
|
||||||
std::ifstream ifs_n( file.c_str() );
|
if ( fp ) {
|
||||||
if ( ifs_n.good() ) {
|
nodes.LoadFromGzFile( fp );
|
||||||
ifs_n >> nodes;
|
gzclose( fp );
|
||||||
ifs_n.close();
|
|
||||||
|
|
||||||
read_ok = true;
|
read_ok = true;
|
||||||
}
|
}
|
||||||
|
@ -548,18 +561,18 @@ void TGConstruct::LoadFromIntermediateFiles( int stage )
|
||||||
{
|
{
|
||||||
dir = share_base + "/stage2/" + bucket.gen_base_path();
|
dir = share_base + "/stage2/" + bucket.gen_base_path();
|
||||||
file = dir + "/" + bucket.gen_index_str() + "_clipped_polys";
|
file = dir + "/" + bucket.gen_index_str() + "_clipped_polys";
|
||||||
|
fp = gzopen( file.c_str(), "rb" );
|
||||||
|
|
||||||
std::ifstream ifs_cp( file.c_str() );
|
if ( fp ) {
|
||||||
if ( ifs_cp.good() ) {
|
polys_clipped.LoadFromGzFile( fp );
|
||||||
ifs_cp >> polys_clipped;
|
gzclose( fp );
|
||||||
ifs_cp.close();
|
|
||||||
|
|
||||||
file = dir + "/" + bucket.gen_index_str() + "_nodes";
|
file = dir + "/" + bucket.gen_index_str() + "_nodes";
|
||||||
|
fp = gzopen( file.c_str(), "rb" );
|
||||||
|
|
||||||
std::ifstream ifs_n( file.c_str() );
|
if ( fp ) {
|
||||||
if ( ifs_n.good() ) {
|
nodes.LoadFromGzFile( fp );
|
||||||
ifs_n >> nodes;
|
gzclose( fp );
|
||||||
ifs_n.close();
|
|
||||||
|
|
||||||
read_ok = true;
|
read_ok = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "tglandclass.hxx"
|
#include "tglandclass.hxx"
|
||||||
|
#include <simgear/io/lowlevel.hxx>
|
||||||
|
|
||||||
void TGLandclass::clear(void)
|
void TGLandclass::clear(void)
|
||||||
{
|
{
|
||||||
|
@ -61,6 +62,22 @@ std::istream& operator >> ( std::istream& in, TGLandclass& lc)
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TGLandclass::LoadFromGzFile(gzFile& fp)
|
||||||
|
{
|
||||||
|
int i, j, count;
|
||||||
|
|
||||||
|
// Load all landclass shapes
|
||||||
|
for (i=0; i<TG_MAX_AREA_TYPES; i++) {
|
||||||
|
sgReadInt( fp, &count );
|
||||||
|
|
||||||
|
for (j=0; j<count; j++) {
|
||||||
|
TGShape shape;
|
||||||
|
|
||||||
|
shape.LoadFromGzFile( fp );
|
||||||
|
shapes[i].push_back( shape );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
std::ostream& operator<< ( std::ostream& out, const TGLandclass& lc )
|
std::ostream& operator<< ( std::ostream& out, const TGLandclass& lc )
|
||||||
{
|
{
|
||||||
int i, j, count;
|
int i, j, count;
|
||||||
|
@ -77,4 +94,19 @@ std::ostream& operator<< ( std::ostream& out, const TGLandclass& lc )
|
||||||
}
|
}
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
void TGLandclass::SaveToGzFile(gzFile& fp)
|
||||||
|
{
|
||||||
|
int i, j, count;
|
||||||
|
TGShape shape;
|
||||||
|
|
||||||
|
// Save all landclass shapes
|
||||||
|
for (i=0; i<TG_MAX_AREA_TYPES; i++) {
|
||||||
|
count = shapes[i].size();
|
||||||
|
sgWriteInt( fp, count );
|
||||||
|
|
||||||
|
for (j=0; j<count; j++) {
|
||||||
|
shapes[i][j].SaveToGzFile( fp );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -33,6 +33,8 @@
|
||||||
# error This library requires C++
|
# error This library requires C++
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <simgear/math/sg_types.hxx>
|
||||||
|
#include <simgear/io/lowlevel.hxx>
|
||||||
#define TG_MAX_AREA_TYPES 128
|
#define TG_MAX_AREA_TYPES 128
|
||||||
|
|
||||||
#include "tgshape.hxx"
|
#include "tgshape.hxx"
|
||||||
|
@ -147,6 +149,8 @@ public:
|
||||||
{
|
{
|
||||||
return shapes[area][shape].sps[segment].set_tri_idxs( tis );
|
return shapes[area][shape].sps[segment].set_tri_idxs( tis );
|
||||||
}
|
}
|
||||||
|
void SaveToGzFile( gzFile& fp );
|
||||||
|
void LoadFromGzFile( gzFile& fp );
|
||||||
|
|
||||||
// Friends for serialization
|
// Friends for serialization
|
||||||
friend std::istream& operator>> ( std::istream&, TGLandclass& );
|
friend std::istream& operator>> ( std::istream&, TGLandclass& );
|
||||||
|
|
|
@ -103,11 +103,39 @@ std::istream& operator >> ( std::istream& in, TGShape& p)
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TGShape::LoadFromGzFile(gzFile& fp)
|
||||||
|
{
|
||||||
|
int i, count;
|
||||||
|
// First, load the clipmask
|
||||||
|
clip_mask.LoadFromGzFile( fp );
|
||||||
|
|
||||||
|
// Then load superpolys
|
||||||
|
sgReadInt( fp, &count );
|
||||||
|
for (i=0; i<count; i++) {
|
||||||
|
TGSuperPoly sp;
|
||||||
|
sp.LoadFromGzFile( fp );
|
||||||
|
sps.push_back( sp );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then load texparams
|
||||||
|
sgReadInt( fp, &count );
|
||||||
|
for (i=0; i<count; i++) {
|
||||||
|
TGTexParams tp;
|
||||||
|
tp.LoadFromGzFile( fp );
|
||||||
|
tps.push_back( tp );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the id, area type and textured flag
|
||||||
|
sgReadUInt( fp, &id );
|
||||||
|
sgReadInt( fp, (int*)&area );
|
||||||
|
sgReadInt( fp, (int*)&textured );
|
||||||
|
}
|
||||||
|
|
||||||
std::ostream& operator<< ( std::ostream& out, const TGShape& p )
|
std::ostream& operator<< ( std::ostream& out, const TGShape& p )
|
||||||
{
|
{
|
||||||
int i, count;
|
int i, count;
|
||||||
TGSuperPoly sp;
|
// TGSuperPoly sp;
|
||||||
TGTexParams tp;
|
// TGTexParams tp;
|
||||||
|
|
||||||
// First, save the clipmask
|
// First, save the clipmask
|
||||||
out << p.clip_mask;
|
out << p.clip_mask;
|
||||||
|
@ -133,3 +161,30 @@ std::ostream& operator<< ( std::ostream& out, const TGShape& p )
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TGShape::SaveToGzFile(gzFile& fp)
|
||||||
|
{
|
||||||
|
int i, count;
|
||||||
|
|
||||||
|
// First, load the clipmask
|
||||||
|
clip_mask.SaveToGzFile( fp );
|
||||||
|
|
||||||
|
// Then save superpolys
|
||||||
|
count = sps.size();
|
||||||
|
sgWriteInt( fp, count );
|
||||||
|
for (i=0; i<count; i++) {
|
||||||
|
sps[i].SaveToGzFile( fp );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then save texparams
|
||||||
|
count = tps.size();
|
||||||
|
sgWriteInt( fp, count );
|
||||||
|
for (i=0; i<count; i++) {
|
||||||
|
tps[i].SaveToGzFile( fp );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the id, area type and textured flag
|
||||||
|
sgWriteUInt( fp, id );
|
||||||
|
sgWriteInt( fp, (int)area );
|
||||||
|
sgWriteInt( fp, (int)textured );
|
||||||
|
}
|
|
@ -33,11 +33,9 @@
|
||||||
|
|
||||||
#define TG_MAX_AREA_TYPES 128
|
#define TG_MAX_AREA_TYPES 128
|
||||||
|
|
||||||
//#include <string>
|
#include <simgear/compiler.h>
|
||||||
//#include <vector>
|
#include <simgear/debug/logstream.hxx>
|
||||||
|
#include <simgear/io/lowlevel.hxx>
|
||||||
//#include <simgear/compiler.h>
|
|
||||||
//#include <simgear/debug/logstream.hxx>
|
|
||||||
|
|
||||||
#include <Polygon/superpoly.hxx>
|
#include <Polygon/superpoly.hxx>
|
||||||
#include <Polygon/texparams.hxx>
|
#include <Polygon/texparams.hxx>
|
||||||
|
@ -58,6 +56,8 @@ public:
|
||||||
void SetMask( TGPolygon mask );
|
void SetMask( TGPolygon mask );
|
||||||
void BuildMask( void );
|
void BuildMask( void );
|
||||||
void IntersectPolys( void );
|
void IntersectPolys( void );
|
||||||
|
void SaveToGzFile( gzFile& fp );
|
||||||
|
void LoadFromGzFile( gzFile& fp );
|
||||||
|
|
||||||
// Friends for serialization
|
// Friends for serialization
|
||||||
friend std::istream& operator>> ( std::istream&, TGShape& );
|
friend std::istream& operator>> ( std::istream&, TGShape& );
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
|
|
||||||
#include <simgear/math/SGMath.hxx>
|
#include <simgear/math/SGMath.hxx>
|
||||||
|
|
||||||
|
#include <simgear/io/lowlevel.hxx>
|
||||||
|
|
||||||
//const double fgPoint3_Epsilon = 0.0000001;
|
//const double fgPoint3_Epsilon = 0.0000001;
|
||||||
const double fgPoint3_Epsilon = 0.000001;
|
const double fgPoint3_Epsilon = 0.000001;
|
||||||
|
@ -173,6 +174,16 @@ inline std::ostream& operator<< ( std::ostream& out, const Point3D& p )
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void sgWritePoint3D ( gzFile fd, const Point3D& var ) {
|
||||||
|
sgWriteDouble ( fd, 3, var.get_n() ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void sgReadPoint3D ( gzFile fd, Point3D& var ) {
|
||||||
|
double data[3];
|
||||||
|
sgReadDouble ( fd, 3, data );
|
||||||
|
var = Point3D(data[0], data[1], data[2]);
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////
|
///////////////////////////
|
||||||
//
|
//
|
||||||
// Point3D Member functions
|
// Point3D Member functions
|
||||||
|
|
|
@ -3,9 +3,60 @@
|
||||||
|
|
||||||
#include "tg_nodes.hxx"
|
#include "tg_nodes.hxx"
|
||||||
|
|
||||||
|
// compare node's positions (x, then y)
|
||||||
|
int compare_position(const TGNode& n1, const TGNode& n2)
|
||||||
|
{
|
||||||
|
Point3D pos1 = n1.GetPosition();
|
||||||
|
Point3D pos2 = n2.GetPosition();
|
||||||
|
|
||||||
|
if ( pos1.x() == pos2.x() ) {
|
||||||
|
return ( pos1.y() < pos2.y() );
|
||||||
|
} else {
|
||||||
|
return ( pos1.x() < pos2.x() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int fuzzy_compare_xposition(const TGNode& n1, const TGNode& n2)
|
||||||
|
{
|
||||||
|
Point3D pos1 = n1.GetPosition();
|
||||||
|
Point3D pos2 = n2.GetPosition();
|
||||||
|
|
||||||
|
if ( fabs(pos1.x() - pos2.x()) < FG_PROXIMITY_EPSILON ) {
|
||||||
|
/* if x coords are within vacinity, then pos1 < pos2 */
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return compare_position( n1, n2 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TGNodes::SortNodes( void )
|
||||||
|
{
|
||||||
|
std::sort(tg_node_list.begin(), tg_node_list.end(), compare_position);
|
||||||
|
sorted = true;
|
||||||
|
}
|
||||||
// Find the index of the specified point (compair to the same
|
// Find the index of the specified point (compair to the same
|
||||||
// tolerance as unique_add(). Returns -1 if not found.
|
// tolerance as unique_add(). Returns -1 if not found.
|
||||||
int TGNodes::find( const Point3D& p ) const {
|
int TGNodes::sorted_find( const Point3D& p ) const {
|
||||||
|
TGNode node( p );
|
||||||
|
const_node_list_iterator lb, ub;
|
||||||
|
|
||||||
|
// first, find the range to search
|
||||||
|
ub=lower_bound( tg_node_list.begin(), tg_node_list.end(), node, fuzzy_compare_xposition );
|
||||||
|
lb=upper_bound( tg_node_list.begin(), tg_node_list.end(), node, fuzzy_compare_xposition );
|
||||||
|
|
||||||
|
// then do a normal linear search in the range
|
||||||
|
if ( lb != tg_node_list.end() ) {
|
||||||
|
for ( ; lb != ub; ++lb ) {
|
||||||
|
if ( close_enough_2d(p, lb->GetPosition()) ) {
|
||||||
|
return std::distance( tg_node_list.begin(), lb );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TGNodes::linear_find( const Point3D& p ) const {
|
||||||
const_node_list_iterator current, last;
|
const_node_list_iterator current, last;
|
||||||
Point3D pos;
|
Point3D pos;
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
|
@ -25,9 +76,45 @@ int TGNodes::find( const Point3D& p ) const {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TGNodes::unique_add( const Point3D& p ) {
|
#if 0
|
||||||
|
void TGNodes::sorted_unique_add( const Point3D& p ) {
|
||||||
|
# if 0
|
||||||
|
TGNode node( p );
|
||||||
|
node.SetFixedPosition( false );
|
||||||
|
|
||||||
|
node_list_iterator idx = std::lower_bound( tg_node_list.begin(), tg_node_list.end(), node, compare_position );
|
||||||
|
tg_node_list.insert( idx, node );
|
||||||
|
#else
|
||||||
|
TGNode node( p );
|
||||||
|
node.SetFixedPosition( false );
|
||||||
|
|
||||||
|
node_list_iterator lb, ub, idx;
|
||||||
|
|
||||||
|
// first, find the range to search
|
||||||
|
ub=lower_bound( tg_node_list.begin(), tg_node_list.end(), node, fuzzy_compare_xposition );
|
||||||
|
lb=upper_bound( tg_node_list.begin(), tg_node_list.end(), node, fuzzy_compare_xposition );
|
||||||
|
|
||||||
|
// then do a normal linear search in the range
|
||||||
|
if ( lb != tg_node_list.end() ) {
|
||||||
|
for ( ; lb != ub; ++lb ) {
|
||||||
|
if ( close_enough_2d(p, lb->GetPosition()) ) {
|
||||||
|
// return std::distance( tg_node_list.begin(), lb );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// we didn't find an existing node - insert new one in correct order
|
||||||
|
idx = std::lower_bound( lb, ub, node, compare_position );
|
||||||
|
tg_node_list.insert( idx, node );
|
||||||
|
|
||||||
|
// return std::distance( tg_node_list.begin(), idx );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void TGNodes::linear_unique_add( const Point3D& p ) {
|
||||||
node_list_iterator current, last;
|
node_list_iterator current, last;
|
||||||
int counter = 0;
|
|
||||||
|
|
||||||
// see if point already exists
|
// see if point already exists
|
||||||
current = tg_node_list.begin();
|
current = tg_node_list.begin();
|
||||||
|
@ -35,11 +122,9 @@ int TGNodes::unique_add( const Point3D& p ) {
|
||||||
|
|
||||||
for ( ; current != last; ++current ) {
|
for ( ; current != last; ++current ) {
|
||||||
if ( close_enough_2d(p, (*current).GetPosition() ) ) {
|
if ( close_enough_2d(p, (*current).GetPosition() ) ) {
|
||||||
// cout << "found an existing match!" << endl;
|
return;
|
||||||
return counter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
++counter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TGNode node( p );
|
TGNode node( p );
|
||||||
|
@ -47,13 +132,59 @@ int TGNodes::unique_add( const Point3D& p ) {
|
||||||
|
|
||||||
// add to list
|
// add to list
|
||||||
tg_node_list.push_back( node );
|
tg_node_list.push_back( node );
|
||||||
|
|
||||||
return counter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int TGNodes::unique_add_fixed_elevation( const Point3D& p ) {
|
#if 0
|
||||||
|
void TGNodes::sorted_unique_add_fixed_elevation( const Point3D& p ) {
|
||||||
|
# if 0
|
||||||
|
TGNode node( p );
|
||||||
|
node.SetFixedPosition(true);
|
||||||
|
|
||||||
|
node_list_iterator idx = std::lower_bound( tg_node_list.begin(), tg_node_list.end(), node, compare_position );
|
||||||
|
|
||||||
|
if ( idx != tg_node_list.end() ) {
|
||||||
|
if ( close_enough_2d( p, idx->GetPosition() ) ) {
|
||||||
|
SG_LOG(SG_GENERAL, SG_ALERT, "AddFixedLocation: node " << p << " exists at " << std::distance(tg_node_list.begin(), idx) );
|
||||||
|
idx->SetPosition( p );
|
||||||
|
idx->SetFixedPosition( true );
|
||||||
|
} else {
|
||||||
|
tg_node_list.insert( idx, node );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
TGNode node( p );
|
||||||
|
node.SetFixedPosition(true);
|
||||||
|
|
||||||
|
node_list_iterator lb, ub, idx;
|
||||||
|
|
||||||
|
// first, find the range to search
|
||||||
|
ub=lower_bound( tg_node_list.begin(), tg_node_list.end(), node, fuzzy_compare_xposition );
|
||||||
|
lb=upper_bound( tg_node_list.begin(), tg_node_list.end(), node, fuzzy_compare_xposition );
|
||||||
|
|
||||||
|
// then do a normal linear search in the range
|
||||||
|
if ( lb != tg_node_list.end() ) {
|
||||||
|
for ( ; lb != ub; ++lb ) {
|
||||||
|
if ( close_enough_2d(p, lb->GetPosition()) ) {
|
||||||
|
lb->SetPosition( p );
|
||||||
|
lb->SetFixedPosition( true );
|
||||||
|
|
||||||
|
// return std::distance( tg_node_list.begin(), lb );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// we didn't find an existing node - insert new one in correct order
|
||||||
|
idx = std::lower_bound( lb, ub, node, compare_position );
|
||||||
|
tg_node_list.insert( idx, node );
|
||||||
|
|
||||||
|
// return std::distance( tg_node_list.begin(), idx );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void TGNodes::linear_unique_add_fixed_elevation( const Point3D& p ) {
|
||||||
node_list_iterator current, last;
|
node_list_iterator current, last;
|
||||||
int counter = 0;
|
|
||||||
|
|
||||||
// see if point already exists
|
// see if point already exists
|
||||||
current = tg_node_list.begin();
|
current = tg_node_list.begin();
|
||||||
|
@ -61,16 +192,14 @@ int TGNodes::unique_add_fixed_elevation( const Point3D& p ) {
|
||||||
|
|
||||||
for ( ; current != last; ++current ) {
|
for ( ; current != last; ++current ) {
|
||||||
if ( close_enough_2d(p, (*current).GetPosition() ) ) {
|
if ( close_enough_2d(p, (*current).GetPosition() ) ) {
|
||||||
SG_LOG(SG_GENERAL, SG_ALERT, "Adding fixed elev node : node already exists at " << counter << " old position is " << (*current).GetPosition() << " new position is " << p );
|
|
||||||
|
|
||||||
// Force the match to our position, and mark as fixed
|
// Force the match to our position, and mark as fixed
|
||||||
(*current).SetPosition( p );
|
(*current).SetPosition( p );
|
||||||
(*current).SetFixedPosition( true );
|
(*current).SetFixedPosition( true );
|
||||||
|
|
||||||
return counter;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
++counter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TGNode node( p );
|
TGNode node( p );
|
||||||
|
@ -79,7 +208,6 @@ int TGNodes::unique_add_fixed_elevation( const Point3D& p ) {
|
||||||
// add to list
|
// add to list
|
||||||
tg_node_list.push_back( node );
|
tg_node_list.push_back( node );
|
||||||
|
|
||||||
return counter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
point_list TGNodes::get_geod_nodes( void ) const {
|
point_list TGNodes::get_geod_nodes( void ) const {
|
||||||
|
@ -97,6 +225,9 @@ point_list TGNodes::get_geod_nodes( void ) const {
|
||||||
return points;
|
return points;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: if the list is sorted, we should be able to get the range from x=min to x=max,
|
||||||
|
// then within that range, add each point where y is within ymin, max
|
||||||
|
// still linear search, but should be less points
|
||||||
point_list TGNodes::get_geod_inside( Point3D min, Point3D max ) const {
|
point_list TGNodes::get_geod_inside( Point3D min, Point3D max ) const {
|
||||||
point_list points;
|
point_list points;
|
||||||
const_node_list_iterator current, last;
|
const_node_list_iterator current, last;
|
||||||
|
@ -260,6 +391,30 @@ std::istream& operator >> ( std::istream& in, TGNode& n )
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TGNode::LoadFromGzFile(gzFile& fp)
|
||||||
|
{
|
||||||
|
int i, nCount;
|
||||||
|
|
||||||
|
// Load a tgnode
|
||||||
|
sgReadPoint3D( fp, position);
|
||||||
|
CalcWgs84();
|
||||||
|
|
||||||
|
sgReadPoint3D( fp, normal );
|
||||||
|
sgReadInt( fp, (int*)&fixed_position );
|
||||||
|
sgReadInt( fp, (int*)&fixed_normal );
|
||||||
|
|
||||||
|
sgReadInt( fp, &nCount );
|
||||||
|
for (i=0; i<nCount; i++) {
|
||||||
|
TGFaceLookup face;
|
||||||
|
|
||||||
|
sgReadUInt( fp, &face.area );
|
||||||
|
sgReadUInt( fp, &face.shape );
|
||||||
|
sgReadUInt( fp, &face.seg );
|
||||||
|
sgReadUInt( fp, &face.tri );
|
||||||
|
|
||||||
|
faces.push_back( face );
|
||||||
|
}
|
||||||
|
}
|
||||||
std::ostream& operator<< ( std::ostream& out, const TGNode& n )
|
std::ostream& operator<< ( std::ostream& out, const TGNode& n )
|
||||||
{
|
{
|
||||||
int i, nCount;
|
int i, nCount;
|
||||||
|
@ -282,11 +437,33 @@ std::ostream& operator<< ( std::ostream& out, const TGNode& n )
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TGNode::SaveToGzFile(gzFile& fp)
|
||||||
|
{
|
||||||
|
int i, nCount;
|
||||||
|
|
||||||
|
// Save a tgnode
|
||||||
|
sgWritePoint3D( fp, position );
|
||||||
|
sgWritePoint3D( fp, normal );
|
||||||
|
sgWriteInt( fp, (int)fixed_position );
|
||||||
|
sgWriteInt( fp, (int)fixed_normal );
|
||||||
|
|
||||||
|
nCount = faces.size();
|
||||||
|
sgWriteInt( fp, nCount );
|
||||||
|
for (i=0; i<nCount; i++) {
|
||||||
|
sgWriteUInt( fp, faces[i].area );
|
||||||
|
sgWriteUInt( fp, faces[i].shape );
|
||||||
|
sgWriteUInt( fp, faces[i].seg );
|
||||||
|
sgWriteUInt( fp, faces[i].tri );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// input from stream
|
// input from stream
|
||||||
std::istream& operator >> ( std::istream& in, TGNodes& ns )
|
std::istream& operator >> ( std::istream& in, TGNodes& ns )
|
||||||
{
|
{
|
||||||
int i, nCount;
|
int i, nCount;
|
||||||
|
|
||||||
|
// Load sorted flag
|
||||||
|
in >> ns.sorted;
|
||||||
// Load all tgnodes
|
// Load all tgnodes
|
||||||
in >> nCount;
|
in >> nCount;
|
||||||
|
|
||||||
|
@ -300,10 +477,30 @@ std::istream& operator >> ( std::istream& in, TGNodes& ns )
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TGNodes::LoadFromGzFile(gzFile& fp)
|
||||||
|
{
|
||||||
|
int i, nCount;
|
||||||
|
|
||||||
|
// Load sorted flag
|
||||||
|
sgReadInt( fp, (int*)&sorted );
|
||||||
|
|
||||||
|
// Load all tgnodes
|
||||||
|
sgReadInt( fp, &nCount );
|
||||||
|
|
||||||
|
for (i=0; i<nCount; i++) {
|
||||||
|
TGNode node;
|
||||||
|
node.LoadFromGzFile( fp );
|
||||||
|
|
||||||
|
tg_node_list.push_back( node );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::ostream& operator<< ( std::ostream& out, const TGNodes& ns )
|
std::ostream& operator<< ( std::ostream& out, const TGNodes& ns )
|
||||||
{
|
{
|
||||||
int i, nCount;
|
int i, nCount;
|
||||||
|
|
||||||
|
// Save sorted flag
|
||||||
|
out << ns.sorted << "\n";
|
||||||
// Save all tgnodes
|
// Save all tgnodes
|
||||||
nCount = ns.tg_node_list.size();
|
nCount = ns.tg_node_list.size();
|
||||||
out << nCount << "\n";
|
out << nCount << "\n";
|
||||||
|
@ -315,6 +512,21 @@ std::ostream& operator<< ( std::ostream& out, const TGNodes& ns )
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TGNodes::SaveToGzFile(gzFile& fp)
|
||||||
|
{
|
||||||
|
int i, nCount;
|
||||||
|
|
||||||
|
// Save sorted flag
|
||||||
|
sgWriteInt( fp, (int)sorted );
|
||||||
|
|
||||||
|
// Save all tgnodes
|
||||||
|
nCount = tg_node_list.size();
|
||||||
|
sgWriteInt( fp, nCount );
|
||||||
|
|
||||||
|
for (i=0; i<nCount; i++) {
|
||||||
|
tg_node_list[i].SaveToGzFile( fp );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
bool TGNodes::LookupFixedElevation( Point3D p, double* z )
|
bool TGNodes::LookupFixedElevation( Point3D p, double* z )
|
||||||
|
|
|
@ -1,15 +1,21 @@
|
||||||
#ifndef _TG_NODES_HXX
|
#ifndef _TG_NODES_HXX
|
||||||
#define _TG_NODES_HXX
|
#define _TG_NODES_HXX
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef __cplusplus
|
#ifndef __cplusplus
|
||||||
# error This library requires C++
|
# error This library requires C++
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
#include <simgear/compiler.h>
|
#include <simgear/compiler.h>
|
||||||
#include <simgear/bucket/newbucket.hxx>
|
#include <simgear/bucket/newbucket.hxx>
|
||||||
#include <Geometry/point3d.hxx>
|
|
||||||
#include <simgear/math/sg_types.hxx>
|
#include <simgear/math/sg_types.hxx>
|
||||||
|
#include <simgear/io/lowlevel.hxx>
|
||||||
|
|
||||||
|
#include <Geometry/point3d.hxx>
|
||||||
|
|
||||||
#define FG_PROXIMITY_EPSILON 0.000001
|
#define FG_PROXIMITY_EPSILON 0.000001
|
||||||
#define FG_COURSE_EPSILON 0.0001
|
#define FG_COURSE_EPSILON 0.0001
|
||||||
|
@ -93,6 +99,8 @@ public:
|
||||||
inline void SetNormal( const Point3D& n ) { normal = n; }
|
inline void SetNormal( const Point3D& n ) { normal = n; }
|
||||||
inline Point3D GetNormal( void ) const { return normal; }
|
inline Point3D GetNormal( void ) const { return normal; }
|
||||||
|
|
||||||
|
void SaveToGzFile( gzFile& fp );
|
||||||
|
void LoadFromGzFile( gzFile& fp );
|
||||||
// Friends for serialization
|
// Friends for serialization
|
||||||
friend std::istream& operator>> ( std::istream&, TGNode& );
|
friend std::istream& operator>> ( std::istream&, TGNode& );
|
||||||
friend std::ostream& operator<< ( std::ostream&, const TGNode& );
|
friend std::ostream& operator<< ( std::ostream&, const TGNode& );
|
||||||
|
@ -118,35 +126,53 @@ class TGNodes {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Constructor and destructor
|
// Constructor and destructor
|
||||||
TGNodes( void ) {}
|
TGNodes( void ) {
|
||||||
|
sorted = false;
|
||||||
|
}
|
||||||
~TGNodes( void ) {}
|
~TGNodes( void ) {}
|
||||||
|
|
||||||
// delete all the data out of node_list
|
// delete all the data out of node_list
|
||||||
inline void clear() { tg_node_list.clear(); }
|
inline void clear() {
|
||||||
|
tg_node_list.clear();
|
||||||
|
sorted = false;
|
||||||
|
}
|
||||||
|
|
||||||
// Add a point to the point list if it doesn't already exist.
|
// Add a point to the point list if it doesn't already exist.
|
||||||
// Returns the index (starting at zero) of the point in the list.
|
// Returns the index (starting at zero) of the point in the list.
|
||||||
int unique_add( const Point3D& p );
|
void unique_add( const Point3D& p ) {
|
||||||
|
if ( !sorted ) {
|
||||||
|
linear_unique_add( p );
|
||||||
|
} else {
|
||||||
|
SG_LOG(SG_GENERAL, SG_ALERT, "ADDING NODE AFTER SORT!");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Add a point to the point list if it doesn't already exist
|
// Add a point to the point list if it doesn't already exist
|
||||||
// (checking all three dimensions.) Returns the index (starting
|
// (checking all three dimensions.) Returns the index (starting
|
||||||
// at zero) of the point in the list.
|
// at zero) of the point in the list.
|
||||||
int unique_add_fixed_elevation( const Point3D& p );
|
void unique_add_fixed_elevation( const Point3D& p ) {
|
||||||
node_list get_fixed_elevation_nodes( void ) const;
|
if ( !sorted ) {
|
||||||
|
linear_unique_add_fixed_elevation( p );
|
||||||
// Add the point with no uniqueness checking
|
} else {
|
||||||
int simple_add( const Point3D& p );
|
SG_LOG(SG_GENERAL, SG_ALERT, "ADDING NODE AFTER SORT!");
|
||||||
|
exit(0);
|
||||||
// Add a point to the point list if it doesn't already exist.
|
}
|
||||||
// Returns the index (starting at zero) of the point in the list.
|
}
|
||||||
// Use a course proximity check
|
|
||||||
int course_add( const Point3D& p );
|
|
||||||
|
|
||||||
// Find the index of the specified point (compair to the same
|
// Find the index of the specified point (compair to the same
|
||||||
// tolerance as unique_add(). Returns -1 if not found.
|
// tolerance as unique_add(). Returns -1 if not found.
|
||||||
int find( const Point3D& p ) const;
|
int find( const Point3D& p ) const {
|
||||||
|
if ( sorted ) {
|
||||||
|
return sorted_find( p );
|
||||||
|
} else {
|
||||||
|
return linear_find( p );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// bool LookupFixedElevation( Point3D p, double* z );
|
node_list get_fixed_elevation_nodes( void ) const;
|
||||||
|
|
||||||
|
void SortNodes( void );
|
||||||
void SetElevation( int idx, double z ) { tg_node_list[idx].SetElevation( z ); }
|
void SetElevation( int idx, double z ) { tg_node_list[idx].SetElevation( z ); }
|
||||||
|
|
||||||
Point3D GetNormal( int idx ) const { return tg_node_list[idx].GetNormal(); }
|
Point3D GetNormal( int idx ) const { return tg_node_list[idx].GetNormal(); }
|
||||||
|
@ -184,13 +210,21 @@ public:
|
||||||
inline size_t size() const { return tg_node_list.size(); }
|
inline size_t size() const { return tg_node_list.size(); }
|
||||||
|
|
||||||
void Dump( void );
|
void Dump( void );
|
||||||
|
void SaveToGzFile( gzFile& fp );
|
||||||
|
void LoadFromGzFile( gzFile& fp );
|
||||||
|
|
||||||
// Friends for serialization
|
// Friends for serialization
|
||||||
friend std::istream& operator>> ( std::istream&, TGNodes& );
|
friend std::istream& operator>> ( std::istream&, TGNodes& );
|
||||||
friend std::ostream& operator<< ( std::ostream&, const TGNodes& );
|
friend std::ostream& operator<< ( std::ostream&, const TGNodes& );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void linear_unique_add( const Point3D& p );
|
||||||
|
void linear_unique_add_fixed_elevation( const Point3D& p );
|
||||||
|
|
||||||
|
int sorted_find( const Point3D& p ) const;
|
||||||
|
int linear_find( const Point3D& p ) const;
|
||||||
node_list tg_node_list;
|
node_list tg_node_list;
|
||||||
|
bool sorted;
|
||||||
|
|
||||||
// return true of the two points are "close enough" as defined by
|
// return true of the two points are "close enough" as defined by
|
||||||
// FG_PROXIMITY_EPSILON
|
// FG_PROXIMITY_EPSILON
|
||||||
|
|
|
@ -960,10 +960,30 @@ std::ostream& operator << (std::ostream &output, const TGPolygon &poly)
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TGPolygon::SaveToGzFile(gzFile& fp)
|
||||||
|
{
|
||||||
|
int nContours = poly.size();
|
||||||
|
|
||||||
|
// Save the number of contours
|
||||||
|
sgWriteInt( fp, nContours );
|
||||||
|
for (int i = 0; i < nContours; i++) {
|
||||||
|
int nPoints = poly[i].size();
|
||||||
|
|
||||||
|
// Save number of points in the contour
|
||||||
|
sgWriteInt( fp, nPoints );
|
||||||
|
|
||||||
|
// Then save the points
|
||||||
|
for ( int j = 0; j < nPoints; j++ ) {
|
||||||
|
sgWritePoint3D( fp, poly[i][j] );
|
||||||
|
}
|
||||||
|
|
||||||
|
sgWriteInt( fp, hole_list[i] );
|
||||||
|
}
|
||||||
|
}
|
||||||
// Read a polygon from input buffer.
|
// Read a polygon from input buffer.
|
||||||
std::istream& operator >> (std::istream &input, TGPolygon &poly)
|
std::istream& operator >> (std::istream &input, TGPolygon &poly)
|
||||||
{
|
{
|
||||||
int nContours = poly.contours();
|
int nContours;
|
||||||
double x, y, z;
|
double x, y, z;
|
||||||
|
|
||||||
// Read the number of contours
|
// Read the number of contours
|
||||||
|
@ -991,3 +1011,26 @@ std::istream& operator >> (std::istream &input, TGPolygon &poly)
|
||||||
|
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TGPolygon::LoadFromGzFile(gzFile& fp)
|
||||||
|
{
|
||||||
|
int nContours;
|
||||||
|
int nPoints;
|
||||||
|
int hole;
|
||||||
|
Point3D pt;
|
||||||
|
|
||||||
|
// Save the number of contours
|
||||||
|
sgReadInt( fp, &nContours );
|
||||||
|
for (int i = 0; i < nContours; i++) {
|
||||||
|
sgReadInt( fp, &nPoints );
|
||||||
|
|
||||||
|
// Then read the points
|
||||||
|
for ( int j = 0; j < nPoints; j++ ) {
|
||||||
|
sgReadPoint3D( fp, pt );
|
||||||
|
add_node( i, pt );
|
||||||
|
}
|
||||||
|
|
||||||
|
sgReadInt( fp, &hole );
|
||||||
|
set_hole_flag( i, hole );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -206,6 +206,9 @@ public:
|
||||||
// output
|
// output
|
||||||
void write_contour( const int contour, const std::string& file ) const;
|
void write_contour( const int contour, const std::string& file ) const;
|
||||||
|
|
||||||
|
void SaveToGzFile( gzFile& fp );
|
||||||
|
void LoadFromGzFile( gzFile& fp );
|
||||||
|
|
||||||
// Friends for serialization
|
// Friends for serialization
|
||||||
friend std::istream& operator>> ( std::istream&, TGPolygon& );
|
friend std::istream& operator>> ( std::istream&, TGPolygon& );
|
||||||
friend std::ostream& operator<< ( std::ostream&, const TGPolygon& );
|
friend std::ostream& operator<< ( std::ostream&, const TGPolygon& );
|
||||||
|
|
|
@ -81,10 +81,39 @@ std::ostream& operator<< ( std::ostream& output, const TGSuperPoly& sp )
|
||||||
} else {
|
} else {
|
||||||
output << sp.flag << "\n";
|
output << sp.flag << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TGSuperPoly::SaveToGzFile(gzFile& fp)
|
||||||
|
{
|
||||||
|
int nFaceNormals;
|
||||||
|
int nFaceAreas;
|
||||||
|
|
||||||
|
// Save the data
|
||||||
|
sgWriteString( fp, material.c_str() );
|
||||||
|
|
||||||
|
poly.SaveToGzFile( fp );
|
||||||
|
normals.SaveToGzFile( fp );
|
||||||
|
texcoords.SaveToGzFile( fp );
|
||||||
|
|
||||||
|
tris.SaveToGzFile( fp );
|
||||||
|
tri_idxs.SaveToGzFile( fp );
|
||||||
|
|
||||||
|
nFaceNormals = face_normals.size();
|
||||||
|
sgWriteInt( fp, nFaceNormals );
|
||||||
|
for ( int i = 0; i < nFaceNormals; i++ ) {
|
||||||
|
sgWritePoint3D( fp, face_normals[i] );
|
||||||
|
}
|
||||||
|
|
||||||
|
nFaceAreas = face_areas.size();
|
||||||
|
sgWriteInt( fp, nFaceAreas );
|
||||||
|
for ( int i = 0; i < nFaceAreas; i++ ) {
|
||||||
|
sgWriteDouble( fp, face_areas[i] );
|
||||||
|
}
|
||||||
|
|
||||||
|
sgWriteString( fp, flag.c_str() );
|
||||||
|
}
|
||||||
std::istream& operator>> ( std::istream& input, TGSuperPoly& sp )
|
std::istream& operator>> ( std::istream& input, TGSuperPoly& sp )
|
||||||
{
|
{
|
||||||
int nFaceNormals;
|
int nFaceNormals;
|
||||||
|
@ -117,6 +146,47 @@ std::istream& operator>> ( std::istream& input, TGSuperPoly& sp )
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TGSuperPoly::LoadFromGzFile(gzFile& fp)
|
||||||
|
{
|
||||||
|
int nFaceNormals;
|
||||||
|
int nFaceAreas;
|
||||||
|
Point3D normal;
|
||||||
|
double area;
|
||||||
|
char* strbuf;
|
||||||
|
|
||||||
|
// Load the data
|
||||||
|
sgReadString( fp, &strbuf );
|
||||||
|
if ( strbuf ) {
|
||||||
|
material = strbuf;
|
||||||
|
delete strbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
poly.LoadFromGzFile( fp );
|
||||||
|
normals.LoadFromGzFile( fp );
|
||||||
|
texcoords.LoadFromGzFile( fp );
|
||||||
|
|
||||||
|
tris.LoadFromGzFile( fp );
|
||||||
|
tri_idxs.LoadFromGzFile( fp );
|
||||||
|
|
||||||
|
sgReadInt( fp, &nFaceNormals );
|
||||||
|
for ( int i = 0; i < nFaceNormals; i++ ) {
|
||||||
|
sgReadPoint3D( fp, normal );
|
||||||
|
face_normals.push_back( normal );
|
||||||
|
}
|
||||||
|
|
||||||
|
sgReadInt( fp, &nFaceAreas );
|
||||||
|
for ( int i = 0; i < nFaceAreas; i++ ) {
|
||||||
|
sgReadDouble( fp, &area );
|
||||||
|
face_areas.push_back( area );
|
||||||
|
}
|
||||||
|
|
||||||
|
sgReadString( fp, &strbuf );
|
||||||
|
if ( strbuf ) {
|
||||||
|
flag = strbuf;
|
||||||
|
delete strbuf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::ostream& operator<< ( std::ostream& output, const TGPolyNodes& pn )
|
std::ostream& operator<< ( std::ostream& output, const TGPolyNodes& pn )
|
||||||
{
|
{
|
||||||
int nContours;
|
int nContours;
|
||||||
|
@ -137,6 +207,22 @@ std::ostream& operator<< ( std::ostream& output, const TGPolyNodes& pn )
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TGPolyNodes::SaveToGzFile(gzFile& fp)
|
||||||
|
{
|
||||||
|
int nContours;
|
||||||
|
int nPoints;
|
||||||
|
|
||||||
|
// Save the data
|
||||||
|
nContours = poly.size();
|
||||||
|
sgWriteInt( fp, nContours );
|
||||||
|
for(int i=0; i<nContours; i++) {
|
||||||
|
nPoints = poly[i].size();
|
||||||
|
sgWriteInt( fp, nPoints );
|
||||||
|
for (int j=0; j<nPoints; j++) {
|
||||||
|
sgWriteInt( fp, poly[i][j] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::istream& operator>> ( std::istream& input, TGPolyNodes& pn )
|
std::istream& operator>> ( std::istream& input, TGPolyNodes& pn )
|
||||||
{
|
{
|
||||||
|
@ -158,4 +244,24 @@ std::istream& operator>> ( std::istream& input, TGPolyNodes& pn )
|
||||||
}
|
}
|
||||||
|
|
||||||
return input;
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TGPolyNodes::LoadFromGzFile(gzFile& fp)
|
||||||
|
{
|
||||||
|
int nContours;
|
||||||
|
int nPoints;
|
||||||
|
int point;
|
||||||
|
|
||||||
|
// Load the data
|
||||||
|
sgReadInt( fp, &nContours );
|
||||||
|
for( int i=0; i<nContours; i++ ) {
|
||||||
|
int_list points;
|
||||||
|
|
||||||
|
sgReadInt( fp, &nPoints );
|
||||||
|
for (int j=0; j<nPoints; j++) {
|
||||||
|
sgReadInt( fp, &point );
|
||||||
|
points.push_back( point );
|
||||||
|
}
|
||||||
|
poly.push_back( points );
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -120,6 +120,9 @@ public:
|
||||||
poly[contour][i] = n;
|
poly[contour][i] = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SaveToGzFile( gzFile& fp );
|
||||||
|
void LoadFromGzFile( gzFile& fp );
|
||||||
|
|
||||||
// Friends for serialization
|
// Friends for serialization
|
||||||
friend std::istream& operator>> ( std::istream&, TGPolyNodes& );
|
friend std::istream& operator>> ( std::istream&, TGPolyNodes& );
|
||||||
friend std::ostream& operator<< ( std::ostream&, const TGPolyNodes& );
|
friend std::ostream& operator<< ( std::ostream&, const TGPolyNodes& );
|
||||||
|
@ -244,6 +247,9 @@ public:
|
||||||
// erase the polygon
|
// erase the polygon
|
||||||
void erase();
|
void erase();
|
||||||
|
|
||||||
|
void SaveToGzFile( gzFile& fp );
|
||||||
|
void LoadFromGzFile( gzFile& fp );
|
||||||
|
|
||||||
// Friends for serialization
|
// Friends for serialization
|
||||||
friend std::istream& operator>> ( std::istream&, TGSuperPoly& );
|
friend std::istream& operator>> ( std::istream&, TGSuperPoly& );
|
||||||
friend std::ostream& operator<< ( std::ostream&, const TGSuperPoly& );
|
friend std::ostream& operator<< ( std::ostream&, const TGSuperPoly& );
|
||||||
|
|
|
@ -17,6 +17,19 @@ std::ostream& operator << (std::ostream &output, const TGTexParams &tp)
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TGTexParams::SaveToGzFile(gzFile& fp)
|
||||||
|
{
|
||||||
|
sgWritePoint3D( fp, ref );
|
||||||
|
sgWriteDouble( fp, width );
|
||||||
|
sgWriteDouble( fp, length );
|
||||||
|
sgWriteDouble( fp, heading );
|
||||||
|
|
||||||
|
sgWriteDouble( fp, minu );
|
||||||
|
sgWriteDouble( fp, maxu );
|
||||||
|
sgWriteDouble( fp, minv );
|
||||||
|
sgWriteDouble( fp, maxv );
|
||||||
|
}
|
||||||
|
|
||||||
// Read a polygon from input buffer.
|
// Read a polygon from input buffer.
|
||||||
std::istream& operator >> (std::istream &input, TGTexParams &tp)
|
std::istream& operator >> (std::istream &input, TGTexParams &tp)
|
||||||
{
|
{
|
||||||
|
@ -32,4 +45,17 @@ std::istream& operator >> (std::istream &input, TGTexParams &tp)
|
||||||
input >> tp.maxv;
|
input >> tp.maxv;
|
||||||
|
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TGTexParams::LoadFromGzFile(gzFile& fp)
|
||||||
|
{
|
||||||
|
sgReadPoint3D( fp, ref );
|
||||||
|
sgReadDouble( fp, &width );
|
||||||
|
sgReadDouble( fp, &length );
|
||||||
|
sgReadDouble( fp, &heading );
|
||||||
|
|
||||||
|
sgReadDouble( fp, &minu );
|
||||||
|
sgReadDouble( fp, &maxu );
|
||||||
|
sgReadDouble( fp, &minv );
|
||||||
|
sgReadDouble( fp, &maxv );
|
||||||
|
}
|
||||||
|
|
|
@ -144,6 +144,9 @@ public:
|
||||||
maxv = x;
|
maxv = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SaveToGzFile( gzFile& fp );
|
||||||
|
void LoadFromGzFile( gzFile& fp );
|
||||||
|
|
||||||
// Friends for serialization
|
// Friends for serialization
|
||||||
friend std::istream& operator>> ( std::istream&, TGTexParams& );
|
friend std::istream& operator>> ( std::istream&, TGTexParams& );
|
||||||
friend std::ostream& operator<< ( std::ostream&, const TGTexParams& );
|
friend std::ostream& operator<< ( std::ostream&, const TGTexParams& );
|
||||||
|
|
Loading…
Add table
Reference in a new issue