checkpoint1
- all polys triangulated individually - shared edge loading should be working, but there are still issues.
This commit is contained in:
parent
3f996495c6
commit
e6ac493395
14 changed files with 2159 additions and 1004 deletions
|
@ -41,11 +41,8 @@
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
using std::cout;
|
|
||||||
using std::endl;
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
|
|
||||||
#define MASK_CLIP 1
|
#define MASK_CLIP 1
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,9 +62,9 @@ TGClipper::~TGClipper() {
|
||||||
// Initialize the clipper (empty all the polygon buckets.)
|
// Initialize the clipper (empty all the polygon buckets.)
|
||||||
bool TGClipper::init() {
|
bool TGClipper::init() {
|
||||||
for ( int i = 0; i < TG_MAX_AREA_TYPES; ++i ) {
|
for ( int i = 0; i < TG_MAX_AREA_TYPES; ++i ) {
|
||||||
polys_in.polys[i].clear();
|
polys_in.superpolys[i].clear();
|
||||||
}
|
}
|
||||||
fixed_elevations.clear();
|
nodes.clear();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -89,7 +86,7 @@ bool TGClipper::load_polys(const string& path) {
|
||||||
|
|
||||||
if ( !in ) {
|
if ( !in ) {
|
||||||
SG_LOG( SG_CLIPPER, SG_ALERT, "Cannot open file: " << path );
|
SG_LOG( SG_CLIPPER, SG_ALERT, "Cannot open file: " << path );
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TGPolygon poly;
|
TGPolygon poly;
|
||||||
|
@ -109,83 +106,86 @@ bool TGClipper::load_polys(const string& path) {
|
||||||
poly3d = false;
|
poly3d = false;
|
||||||
poly_name = first_line;
|
poly_name = first_line;
|
||||||
}
|
}
|
||||||
cout << "poly name = " << poly_name << endl;
|
SG_LOG( SG_CLIPPER, SG_INFO, "poly name = " << poly_name);
|
||||||
poly_type = get_area_type( poly_name );
|
poly_type = get_area_type( poly_name );
|
||||||
cout << "poly type (int) = " << (int)poly_type << endl;
|
SG_LOG( SG_CLIPPER, SG_INFO, "poly type (int) = " << (int)poly_type);
|
||||||
in >> contours;
|
in >> contours;
|
||||||
cout << "num contours = " << contours << endl;
|
SG_LOG( SG_CLIPPER, SG_INFO, "num contours = " << contours);
|
||||||
|
|
||||||
poly.erase();
|
poly.erase();
|
||||||
|
|
||||||
for ( i = 0; i < contours; ++i ) {
|
for ( i = 0; i < contours; ++i ) {
|
||||||
in >> count;
|
in >> count;
|
||||||
// cout << "Contour = " << i << " size = " << count << endl;
|
|
||||||
|
|
||||||
if ( count < 3 ) {
|
if ( count < 3 ) {
|
||||||
SG_LOG( SG_CLIPPER, SG_ALERT,
|
SG_LOG( SG_CLIPPER, SG_ALERT, "Polygon with less than 3 data points." );
|
||||||
"Polygon with less than 3 data points." );
|
exit(-1);
|
||||||
exit(-1);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
in >> hole_flag;
|
in >> hole_flag;
|
||||||
|
|
||||||
in >> startx;
|
in >> startx;
|
||||||
in >> starty;
|
in >> starty;
|
||||||
if ( poly3d ) {
|
if ( poly3d ) {
|
||||||
in >> startz;
|
in >> startz;
|
||||||
} else {
|
} else {
|
||||||
startz = -9999.0;
|
startz = -9999.0;
|
||||||
}
|
}
|
||||||
p = Point3D(startx+nudge, starty+nudge, startz);
|
p = Point3D(startx+nudge, starty+nudge, startz);
|
||||||
poly.add_node( i, p );
|
poly.add_node( i, p );
|
||||||
|
|
||||||
if ( poly3d ) {
|
if ( poly3d ) {
|
||||||
fixed_elevations.unique_add( p );
|
nodes.unique_add_fixed_elevation( p );
|
||||||
|
} else {
|
||||||
|
nodes.unique_add( p );
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( j = 1; j < count - 1; ++j ) {
|
for ( j = 1; j < count - 1; ++j ) {
|
||||||
in >> x;
|
in >> x;
|
||||||
in >> y;
|
in >> y;
|
||||||
if ( poly3d ) {
|
if ( poly3d ) {
|
||||||
in >> z;
|
in >> z;
|
||||||
} else {
|
} else {
|
||||||
z = -9999.0;
|
z = -9999.0;
|
||||||
}
|
}
|
||||||
p = Point3D( x+nudge, y+nudge, z );
|
p = Point3D( x+nudge, y+nudge, z );
|
||||||
poly.add_node( i, p );
|
poly.add_node( i, p );
|
||||||
if ( poly3d ) {
|
if ( poly3d ) {
|
||||||
fixed_elevations.unique_add( p );
|
nodes.unique_add_fixed_elevation( p );
|
||||||
|
} else {
|
||||||
|
nodes.unique_add( p );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
in >> lastx;
|
in >> lastx;
|
||||||
in >> lasty;
|
in >> lasty;
|
||||||
if ( poly3d ) {
|
if ( poly3d ) {
|
||||||
in >> lastz;
|
in >> lastz;
|
||||||
} else {
|
} else {
|
||||||
lastz = -9999.0;
|
lastz = -9999.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (fabs(startx - lastx) < SG_EPSILON)
|
if ( (fabs(startx - lastx) < SG_EPSILON) &&
|
||||||
&& (fabs(starty - lasty) < SG_EPSILON)
|
(fabs(starty - lasty) < SG_EPSILON) &&
|
||||||
&& (fabs(startz - lastz) < SG_EPSILON) ) {
|
(fabs(startz - lastz) < SG_EPSILON) ) {
|
||||||
// last point same as first, discard
|
// last point same as first, discard
|
||||||
} else {
|
} else {
|
||||||
p = Point3D( lastx+nudge, lasty+nudge, lastz );
|
p = Point3D( lastx+nudge, lasty+nudge, lastz );
|
||||||
poly.add_node( i, p );
|
poly.add_node( i, p );
|
||||||
if ( poly3d ) {
|
if ( poly3d ) {
|
||||||
fixed_elevations.unique_add( p );
|
nodes.unique_add_fixed_elevation( p );
|
||||||
|
} else {
|
||||||
|
nodes.unique_add( p );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int area = (int)poly_type;
|
int area = (int)poly_type;
|
||||||
|
string material = get_area_name( area );
|
||||||
|
|
||||||
add_poly(area, poly);
|
add_poly(area, poly, material);
|
||||||
|
|
||||||
// FILE *ofp= fopen("outfile", "w");
|
in >> skipcomment;
|
||||||
// gpc_write_polygon(ofp, &polys.landuse);
|
|
||||||
|
|
||||||
in >> skipcomment;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -195,7 +195,6 @@ bool TGClipper::load_polys(const string& path) {
|
||||||
// Load a polygon definition file containing osgb36 Eastings and Northings
|
// Load a polygon definition file containing osgb36 Eastings and Northings
|
||||||
// and convert them to WGS84 Latitude and Longitude
|
// and convert them to WGS84 Latitude and Longitude
|
||||||
bool TGClipper::load_osgb36_polys(const string& path) {
|
bool TGClipper::load_osgb36_polys(const string& path) {
|
||||||
// cout << "Loading osgb36 poly\n";
|
|
||||||
string poly_name;
|
string poly_name;
|
||||||
AreaType poly_type;
|
AreaType poly_type;
|
||||||
int contours, count, i, j;
|
int contours, count, i, j;
|
||||||
|
@ -208,100 +207,98 @@ bool TGClipper::load_osgb36_polys(const string& path) {
|
||||||
|
|
||||||
if ( !in ) {
|
if ( !in ) {
|
||||||
SG_LOG( SG_CLIPPER, SG_ALERT, "Cannot open file: " << path );
|
SG_LOG( SG_CLIPPER, SG_ALERT, "Cannot open file: " << path );
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// gpc_polygon *poly = new gpc_polygon;
|
|
||||||
// poly->num_contours = 0;
|
|
||||||
// poly->contour = NULL;
|
|
||||||
TGPolygon poly;
|
TGPolygon poly;
|
||||||
|
|
||||||
Point3D p;
|
Point3D p;
|
||||||
Point3D OSRef;
|
Point3D OSRef;
|
||||||
in >> skipcomment;
|
in >> skipcomment;
|
||||||
while ( !in.eof() ) {
|
while ( !in.eof() ) {
|
||||||
in >> poly_name;
|
in >> poly_name;
|
||||||
cout << "poly name = " << poly_name << endl;
|
SG_LOG( SG_CLIPPER, SG_INFO, "poly name = " << poly_name);
|
||||||
poly_type = get_area_type( poly_name );
|
poly_type = get_area_type( poly_name );
|
||||||
cout << "poly type (int) = " << (int)poly_type << endl;
|
SG_LOG( SG_CLIPPER, SG_INFO, "poly type (int) = " << (int)poly_type);
|
||||||
in >> contours;
|
in >> contours;
|
||||||
cout << "num contours = " << contours << endl;
|
SG_LOG( SG_CLIPPER, SG_INFO, "num contours = " << contours);
|
||||||
|
|
||||||
poly.erase();
|
poly.erase();
|
||||||
|
|
||||||
for ( i = 0; i < contours; ++i ) {
|
for ( i = 0; i < contours; ++i ) {
|
||||||
in >> count;
|
in >> count;
|
||||||
|
|
||||||
if ( count < 3 ) {
|
if ( count < 3 ) {
|
||||||
SG_LOG( SG_CLIPPER, SG_ALERT,
|
SG_LOG( SG_CLIPPER, SG_ALERT, "Polygon with less than 3 data points." );
|
||||||
"Polygon with less than 3 data points." );
|
exit(-1);
|
||||||
exit(-1);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
in >> hole_flag;
|
in >> hole_flag;
|
||||||
|
|
||||||
in >> startx;
|
in >> startx;
|
||||||
in >> starty;
|
in >> starty;
|
||||||
OSRef = Point3D(startx, starty, -9999.0);
|
OSRef = Point3D(startx, starty, -9999.0);
|
||||||
|
|
||||||
//Convert from OSGB36 Eastings/Northings to WGS84 Lat/Lon
|
//Convert from OSGB36 Eastings/Northings to WGS84 Lat/Lon
|
||||||
//Note that startx and starty themselves must not be altered since we compare them with unaltered lastx and lasty later
|
//Note that startx and starty themselves must not be altered since we compare them with unaltered lastx and lasty later
|
||||||
p = OSGB36ToWGS84(OSRef);
|
p = OSGB36ToWGS84(OSRef);
|
||||||
|
|
||||||
poly.add_node( i, p );
|
poly.add_node( i, p );
|
||||||
SG_LOG( SG_CLIPPER, SG_BULK, "0 = "
|
nodes.unique_add( p );
|
||||||
<< startx << ", " << starty );
|
|
||||||
|
|
||||||
for ( j = 1; j < count - 1; ++j ) {
|
SG_LOG( SG_CLIPPER, SG_BULK, "0 = " << startx << ", " << starty );
|
||||||
in >> x;
|
|
||||||
in >> y;
|
|
||||||
OSRef = Point3D( x, y, -9999.0 );
|
|
||||||
p = OSGB36ToWGS84(OSRef);
|
|
||||||
|
|
||||||
poly.add_node( i, p );
|
for ( j = 1; j < count - 1; ++j ) {
|
||||||
SG_LOG( SG_CLIPPER, SG_BULK, j << " = " << x << ", " << y );
|
in >> x;
|
||||||
}
|
in >> y;
|
||||||
|
OSRef = Point3D( x, y, -9999.0 );
|
||||||
|
p = OSGB36ToWGS84(OSRef);
|
||||||
|
|
||||||
in >> lastx;
|
poly.add_node( i, p );
|
||||||
in >> lasty;
|
nodes.unique_add( p );
|
||||||
|
SG_LOG( SG_CLIPPER, SG_BULK, j << " = " << x << ", " << y );
|
||||||
|
}
|
||||||
|
|
||||||
if ( (fabs(startx - lastx) < SG_EPSILON)
|
in >> lastx;
|
||||||
&& (fabs(starty - lasty) < SG_EPSILON) ) {
|
in >> lasty;
|
||||||
// last point same as first, discard
|
|
||||||
} else {
|
|
||||||
OSRef = Point3D( lastx, lasty, -9999.0 );
|
|
||||||
p = OSGB36ToWGS84(OSRef);
|
|
||||||
|
|
||||||
poly.add_node( i, p );
|
if ( (fabs(startx - lastx) < SG_EPSILON) &&
|
||||||
SG_LOG( SG_CLIPPER, SG_BULK, count - 1 << " = "
|
(fabs(starty - lasty) < SG_EPSILON) ) {
|
||||||
<< lastx << ", " << lasty );
|
// last point same as first, discard
|
||||||
}
|
} else {
|
||||||
|
OSRef = Point3D( lastx, lasty, -9999.0 );
|
||||||
|
p = OSGB36ToWGS84(OSRef);
|
||||||
|
|
||||||
// gpc_add_contour( poly, &v_list, hole_flag );
|
poly.add_node( i, p );
|
||||||
}
|
nodes.unique_add( p );
|
||||||
|
SG_LOG( SG_CLIPPER, SG_BULK, count - 1 << " = " << lastx << ", " << lasty );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int area = (int)poly_type;
|
int area = (int)poly_type;
|
||||||
|
string material = get_area_name( area );
|
||||||
|
|
||||||
add_poly( area, poly);
|
add_poly(area, poly, material);
|
||||||
|
|
||||||
// FILE *ofp= fopen("outfile", "w");
|
in >> skipcomment;
|
||||||
// gpc_write_polygon(ofp, &polys.landuse);
|
|
||||||
|
|
||||||
in >> skipcomment;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a polygon to the clipper.
|
// Add a polygon to the clipper.
|
||||||
void TGClipper::add_poly( int area, const TGPolygon &poly )
|
void TGClipper::add_poly( int area, const TGPolygon &poly, string material )
|
||||||
{
|
{
|
||||||
|
TGSuperPoly sp;
|
||||||
|
|
||||||
if ( area < TG_MAX_AREA_TYPES ) {
|
if ( area < TG_MAX_AREA_TYPES ) {
|
||||||
polys_in.polys[area].push_back(poly);
|
sp.set_poly( poly );
|
||||||
|
sp.set_material( material );
|
||||||
|
|
||||||
|
polys_in.superpolys[area].push_back(sp);
|
||||||
} else {
|
} else {
|
||||||
SG_LOG( SG_CLIPPER, SG_ALERT, "Polygon type out of range = "
|
SG_LOG( SG_CLIPPER, SG_ALERT, "Polygon type out of range = " << area);
|
||||||
<< area);
|
exit(-1);
|
||||||
exit(-1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,9 +307,6 @@ void TGClipper::add_poly( int area, const TGPolygon &poly )
|
||||||
void TGClipper::move_slivers( TGPolygon& in, TGPolygon& out ) {
|
void TGClipper::move_slivers( TGPolygon& in, TGPolygon& out ) {
|
||||||
// traverse each contour of the polygon and attempt to identify
|
// traverse each contour of the polygon and attempt to identify
|
||||||
// likely slivers
|
// likely slivers
|
||||||
|
|
||||||
// cout << "Begin move slivers" << endl;
|
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
out.erase();
|
out.erase();
|
||||||
|
@ -328,36 +322,27 @@ void TGClipper::move_slivers( TGPolygon& in, TGPolygon& out ) {
|
||||||
// process contours in reverse order so deleting a contour doesn't
|
// process contours in reverse order so deleting a contour doesn't
|
||||||
// foul up our sequence
|
// foul up our sequence
|
||||||
for ( i = in.contours() - 1; i >= 0; --i ) {
|
for ( i = in.contours() - 1; i >= 0; --i ) {
|
||||||
// cout << "contour " << i << endl;
|
min_angle = in.minangle_contour( i );
|
||||||
|
area = in.area_contour( i );
|
||||||
|
|
||||||
min_angle = in.minangle_contour( i );
|
if ( ((min_angle < angle_cutoff) && (area < area_cutoff)) ||
|
||||||
area = in.area_contour( i );
|
( area < area_cutoff / 10.0) ) {
|
||||||
|
// cout << " WE THINK IT'S A SLIVER!" << endl;
|
||||||
|
|
||||||
/* cout << " min_angle (rad) = "
|
// check if this is a hole
|
||||||
<< min_angle << endl;
|
hole_flag = in.get_hole_flag( i );
|
||||||
cout << " min_angle (deg) = "
|
|
||||||
<< min_angle * 180.0 / SGD_PI << endl;
|
|
||||||
cout << " area = " << area << endl; */
|
|
||||||
|
|
||||||
if ( ((min_angle < angle_cutoff) && (area < area_cutoff)) ||
|
if ( hole_flag ) {
|
||||||
( area < area_cutoff / 10.0) )
|
// just delete/eliminate/remove sliver holes
|
||||||
{
|
// cout << "just deleting a sliver hole" << endl;
|
||||||
// cout << " WE THINK IT'S A SLIVER!" << endl;
|
in.delete_contour( i );
|
||||||
|
} else {
|
||||||
// check if this is a hole
|
// move sliver contour to out polygon
|
||||||
hole_flag = in.get_hole_flag( i );
|
contour = in.get_contour( i );
|
||||||
|
in.delete_contour( i );
|
||||||
if ( hole_flag ) {
|
out.add_contour( contour, hole_flag );
|
||||||
// just delete/eliminate/remove sliver holes
|
}
|
||||||
// cout << "just deleting a sliver hole" << endl;
|
}
|
||||||
in.delete_contour( i );
|
|
||||||
} else {
|
|
||||||
// move sliver contour to out polygon
|
|
||||||
contour = in.get_contour( i );
|
|
||||||
in.delete_contour( i );
|
|
||||||
out.add_contour( contour, hole_flag );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,62 +358,44 @@ void TGClipper::merge_slivers( TGPolyList& clipped, TGPolygon& slivers ) {
|
||||||
point_list contour;
|
point_list contour;
|
||||||
int original_contours, result_contours;
|
int original_contours, result_contours;
|
||||||
bool done;
|
bool done;
|
||||||
int area, i, j, k;
|
int area, i, j;
|
||||||
|
|
||||||
for ( i = 0; i < slivers.contours(); ++i ) {
|
for ( i = 0; i < slivers.contours(); ++i ) {
|
||||||
// cout << "Merging sliver = " << i << endl;
|
// cout << "Merging sliver = " << i << endl;
|
||||||
|
|
||||||
// make the sliver polygon
|
// make the sliver polygon
|
||||||
contour = slivers.get_contour( i );
|
contour = slivers.get_contour( i );
|
||||||
sliver.erase();
|
sliver.erase();
|
||||||
sliver.add_contour( contour, 0 );
|
sliver.add_contour( contour, 0 );
|
||||||
done = false;
|
done = false;
|
||||||
|
|
||||||
for ( area = 0; area < TG_MAX_AREA_TYPES && !done; ++area ) {
|
for ( area = 0; area < TG_MAX_AREA_TYPES && !done; ++area ) {
|
||||||
|
|
||||||
if ( is_hole_area( area ) ) {
|
if ( is_hole_area( area ) ) {
|
||||||
// don't merge a non-hole sliver in with a hole
|
// don't merge a non-hole sliver in with a hole
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// cout << " testing area = " << area << " with "
|
// cout << " testing area = " << area << " with "
|
||||||
// << clipped.polys[area].size() << " polys" << endl;
|
// << clipped.polys[area].size() << " polys" << endl;
|
||||||
for ( j = 0;
|
for ( j = 0; j < (int)clipped.superpolys[area].size() && !done; ++j ) {
|
||||||
j < (int)clipped.polys[area].size() && !done;
|
// cout << " polygon = " << j << endl;
|
||||||
++j )
|
poly = clipped.superpolys[area][j].get_poly();
|
||||||
{
|
original_contours = poly.contours();
|
||||||
// cout << " polygon = " << j << endl;
|
result = tgPolygonUnion( poly, sliver );
|
||||||
|
result_contours = result.contours();
|
||||||
|
|
||||||
poly = clipped.polys[area][j];
|
if ( original_contours == result_contours ) {
|
||||||
original_contours = poly.contours();
|
// cout << " FOUND a poly to merge the sliver with" << endl;
|
||||||
result = tgPolygonUnion( poly, sliver );
|
clipped.superpolys[area][j].set_poly( result );
|
||||||
result_contours = result.contours();
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ( original_contours == result_contours ) {
|
if ( !done ) {
|
||||||
// cout << " FOUND a poly to merge the sliver with" << endl;
|
// cout << "no suitable polys found for sliver merge" << endl;
|
||||||
clipped.polys[area][j] = result;
|
}
|
||||||
done = true;
|
|
||||||
// poly.write("orig");
|
|
||||||
// sliver.write("sliver");
|
|
||||||
// result.write("result");
|
|
||||||
// cout << "press return: ";
|
|
||||||
// string input;
|
|
||||||
// cin >> input;
|
|
||||||
//} else {
|
|
||||||
// cout << " poly not a match" << endl;
|
|
||||||
// cout << " original = " << original_contours
|
|
||||||
// << " result = " << result_contours << endl;
|
|
||||||
// cout << " sliver = " << endl;
|
|
||||||
// for ( k = 0; k < (int)contour.size(); ++k ) {
|
|
||||||
// cout << " " << contour[k].x() << ", "
|
|
||||||
// << contour[k].y() << endl;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( !done ) {
|
|
||||||
// cout << "no suitable polys found for sliver merge" << endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -439,22 +406,31 @@ bool TGClipper::clip_all(const point2d& min, const point2d& max) {
|
||||||
TGPolygon accum, tmp;
|
TGPolygon accum, tmp;
|
||||||
TGPolygon slivers, remains;
|
TGPolygon slivers, remains;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
Point3D p;
|
||||||
// gpcpoly_iterator current, last;
|
|
||||||
|
|
||||||
SG_LOG( SG_CLIPPER, SG_INFO, "Running master clipper" );
|
SG_LOG( SG_CLIPPER, SG_INFO, "Running master clipper" );
|
||||||
|
SG_LOG( SG_CLIPPER, SG_INFO, " (" << min.x << "," << min.y << ") (" << max.x << "," << max.y << ")" );
|
||||||
|
|
||||||
accum.erase();
|
accum.erase();
|
||||||
|
|
||||||
cout << " (" << min.x << "," << min.y << ") ("
|
// set up clipping tile : and remember to add the nodes!
|
||||||
<< max.x << "," << max.y << ")" << endl;
|
|
||||||
|
|
||||||
// set up clipping tile
|
|
||||||
polys_in.safety_base.erase();
|
polys_in.safety_base.erase();
|
||||||
polys_in.safety_base.add_node( 0, Point3D(min.x, min.y, -9999.0) );
|
|
||||||
polys_in.safety_base.add_node( 0, Point3D(max.x, min.y, -9999.0) );
|
p = Point3D(min.x, min.y, -9999.0);
|
||||||
polys_in.safety_base.add_node( 0, Point3D(max.x, max.y, -9999.0) );
|
polys_in.safety_base.add_node( 0, p );
|
||||||
polys_in.safety_base.add_node( 0, Point3D(min.x, max.y, -9999.0) );
|
nodes.unique_add( p );
|
||||||
|
|
||||||
|
p = Point3D(max.x, min.y, -9999.0);
|
||||||
|
polys_in.safety_base.add_node( 0, p );
|
||||||
|
nodes.unique_add( p );
|
||||||
|
|
||||||
|
p = Point3D(max.x, max.y, -9999.0);
|
||||||
|
polys_in.safety_base.add_node( 0, p );
|
||||||
|
nodes.unique_add( p );
|
||||||
|
|
||||||
|
p = Point3D(min.x, max.y, -9999.0);
|
||||||
|
polys_in.safety_base.add_node( 0, p );
|
||||||
|
nodes.unique_add( p );
|
||||||
|
|
||||||
// set up land mask, we clip most things to this since it is our
|
// set up land mask, we clip most things to this since it is our
|
||||||
// best representation of land vs. ocean. If we have other less
|
// best representation of land vs. ocean. If we have other less
|
||||||
|
@ -467,31 +443,26 @@ bool TGClipper::clip_all(const point2d& min, const point2d& max) {
|
||||||
island_mask.erase();
|
island_mask.erase();
|
||||||
for ( i = 0; i < TG_MAX_AREA_TYPES; i++ ) {
|
for ( i = 0; i < TG_MAX_AREA_TYPES; i++ ) {
|
||||||
if ( is_landmass_area( i ) && !m_ignore_landmass ) {
|
if ( is_landmass_area( i ) && !m_ignore_landmass ) {
|
||||||
for ( unsigned j = 0; j < (int)polys_in.polys[i].size(); ++j ) {
|
for ( unsigned int j = 0; j < polys_in.superpolys[i].size(); ++j ) {
|
||||||
land_mask =
|
land_mask = tgPolygonUnion( land_mask, polys_in.superpolys[i][j].get_poly() );
|
||||||
tgPolygonUnion( land_mask, polys_in.polys[i][j] );
|
|
||||||
}
|
}
|
||||||
} else if ( is_water_area( i ) ) {
|
} else if ( is_water_area( i ) ) {
|
||||||
for (unsigned int j = 0; j < polys_in.polys[i].size(); j++) {
|
for (unsigned int j = 0; j < polys_in.superpolys[i].size(); j++) {
|
||||||
water_mask =
|
water_mask = tgPolygonUnion( water_mask, polys_in.superpolys[i][j].get_poly() );
|
||||||
tgPolygonUnion( water_mask, polys_in.polys[i][j] );
|
|
||||||
}
|
}
|
||||||
} else if ( is_island_area( i ) ) {
|
} else if ( is_island_area( i ) ) {
|
||||||
for (unsigned int j = 0; j < polys_in.polys[i].size(); j++) {
|
for (unsigned int j = 0; j < polys_in.superpolys[i].size(); j++) {
|
||||||
island_mask =
|
island_mask = tgPolygonUnion( island_mask, polys_in.superpolys[i][j].get_poly() );
|
||||||
tgPolygonUnion( island_mask, polys_in.polys[i][j] );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// process polygons in priority order
|
// process polygons in priority order
|
||||||
for ( i = 0; i < TG_MAX_AREA_TYPES; ++i ) {
|
for ( i = 0; i < TG_MAX_AREA_TYPES; ++i ) {
|
||||||
cout << "num polys of type (" << i << ") = "
|
SG_LOG( SG_CLIPPER, SG_INFO, "num polys of type (" << i << ") = " << polys_in.superpolys[i].size() );
|
||||||
<< polys_in.polys[i].size() << endl;
|
for( j = 0; j < (int)polys_in.superpolys[i].size(); ++j ) {
|
||||||
for( j = 0; j < (int)polys_in.polys[i].size(); ++j ) {
|
TGPolygon current = polys_in.superpolys[i][j].get_poly();
|
||||||
TGPolygon current = polys_in.polys[i][j];
|
SG_LOG( SG_CLIPPER, SG_INFO, get_area_name( (AreaType)i ) << " = " << current.contours() );
|
||||||
SG_LOG( SG_CLIPPER, SG_INFO, get_area_name( (AreaType)i )
|
|
||||||
<< " = " << current.contours() );
|
|
||||||
|
|
||||||
tmp = current;
|
tmp = current;
|
||||||
|
|
||||||
|
@ -502,61 +473,59 @@ bool TGClipper::clip_all(const point2d& min, const point2d& max) {
|
||||||
|
|
||||||
// Airport areas are limited to existing land mass and
|
// Airport areas are limited to existing land mass and
|
||||||
// never override water.
|
// never override water.
|
||||||
//
|
//
|
||||||
// 9/26/2005 - CLO: We are going to add the ability to
|
// 9/26/2005 - CLO: We are going to add the ability to
|
||||||
// manually define airport areas when the default area
|
// manually define airport areas when the default area
|
||||||
// isn't sufficient. It is clear that it is impossible to
|
// isn't sufficient. It is clear that it is impossible to
|
||||||
// auto-generate correct airport areas in all cases. For
|
// auto-generate correct airport areas in all cases. For
|
||||||
// now we default to topologically continuous scenery and
|
// now we default to topologically continuous scenery and
|
||||||
// wait for people to submit manual fixes.
|
// wait for people to submit manual fixes.
|
||||||
//
|
//
|
||||||
// if ( i == AirportArea ) {
|
// if ( i == AirportArea ) {
|
||||||
// tmp = tgPolygonInt( tmp, land_mask );
|
// tmp = tgPolygonInt( tmp, land_mask );
|
||||||
// tmp = tgPolygonDiff( tmp, water_mask );
|
// tmp = tgPolygonDiff( tmp, water_mask );
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// if a water area, cut out potential islands
|
// if a water area, cut out potential islands
|
||||||
if ( is_water_area( i ) ) {
|
if ( is_water_area( i ) ) {
|
||||||
// clip against island mask
|
// clip against island mask
|
||||||
tmp = tgPolygonDiff( tmp, island_mask );
|
tmp = tgPolygonDiff( tmp, island_mask );
|
||||||
}
|
}
|
||||||
|
|
||||||
TGPolygon result_union, result_diff;
|
TGPolygon result_union, result_diff;
|
||||||
|
|
||||||
if ( accum.contours() == 0 ) {
|
if ( accum.contours() == 0 ) {
|
||||||
result_diff = tmp;
|
result_diff = tmp;
|
||||||
result_union = tmp;
|
result_union = tmp;
|
||||||
} else {
|
} else {
|
||||||
result_diff = tgPolygonDiff( tmp, accum);
|
result_diff = tgPolygonDiff( tmp, accum);
|
||||||
result_union = tgPolygonUnion( tmp, accum);
|
result_union = tgPolygonUnion( tmp, accum);
|
||||||
}
|
}
|
||||||
|
|
||||||
// only add to output list if the clip left us with a polygon
|
// only add to output list if the clip left us with a polygon
|
||||||
if ( result_diff.contours() > 0 ) {
|
if ( result_diff.contours() > 0 ) {
|
||||||
// move slivers from result_diff polygon to slivers polygon
|
// move slivers from result_diff polygon to slivers polygon
|
||||||
move_slivers(result_diff, slivers);
|
move_slivers(result_diff, slivers);
|
||||||
|
|
||||||
// merge any slivers with previously clipped
|
// merge any slivers with previously clipped
|
||||||
// neighboring polygons
|
// neighboring polygons
|
||||||
if ( slivers.contours() > 0 ) {
|
if ( slivers.contours() > 0 ) {
|
||||||
merge_slivers(polys_clipped, slivers);
|
merge_slivers(polys_clipped, slivers);
|
||||||
}
|
}
|
||||||
|
|
||||||
// add the sliverless result polygon (from after the
|
// add the sliverless result polygon (from after the
|
||||||
// move_slivers) to the clipped polys list
|
// move_slivers) to the clipped polys list
|
||||||
if ( result_diff.contours() > 0 ) {
|
if ( result_diff.contours() > 0 ) {
|
||||||
polys_clipped.polys[i].push_back(result_diff);
|
TGSuperPoly sp;
|
||||||
|
string material = get_area_name( (AreaType)i );
|
||||||
|
|
||||||
// static int count = 0;
|
sp.set_material( material );
|
||||||
// cout << "Writing clipped polygon to next-result" << count
|
sp.set_poly( result_diff );
|
||||||
// << endl;
|
polys_clipped.superpolys[i].push_back( sp );
|
||||||
// char filename[256];
|
}
|
||||||
// sprintf(filename, "next-result-%02d-%02d", i, count++);
|
}
|
||||||
// result_diff.write(filename);
|
accum = result_union;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
accum = result_union;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// finally, what ever is left over goes to ocean
|
// finally, what ever is left over goes to ocean
|
||||||
|
@ -568,45 +537,31 @@ bool TGClipper::clip_all(const point2d& min, const point2d& max) {
|
||||||
remains = tgPolygonDiff( polys_in.safety_base, accum );
|
remains = tgPolygonDiff( polys_in.safety_base, accum );
|
||||||
|
|
||||||
if ( remains.contours() > 0 ) {
|
if ( remains.contours() > 0 ) {
|
||||||
// cout << "remains contours = " << remains.contours() << endl;
|
// cout << "remains contours = " << remains.contours() << endl;
|
||||||
// move slivers from remains polygon to slivers polygon
|
// move slivers from remains polygon to slivers polygon
|
||||||
move_slivers(remains, slivers);
|
move_slivers(remains, slivers);
|
||||||
// cout << " After sliver move:" << endl;
|
// cout << " After sliver move:" << endl;
|
||||||
// cout << " remains = " << remains.contours() << endl;
|
// cout << " remains = " << remains.contours() << endl;
|
||||||
// cout << " slivers = " << slivers.contours() << endl;
|
// cout << " slivers = " << slivers.contours() << endl;
|
||||||
|
|
||||||
// merge any slivers with previously clipped
|
// merge any slivers with previously clipped
|
||||||
// neighboring polygons
|
// neighboring polygons
|
||||||
if ( slivers.contours() > 0 ) {
|
if ( slivers.contours() > 0 ) {
|
||||||
merge_slivers(polys_clipped, slivers);
|
merge_slivers(polys_clipped, slivers);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( remains.contours() > 0 ) {
|
if ( remains.contours() > 0 ) {
|
||||||
polys_clipped.polys[(int)get_sliver_target_area_type()].push_back(remains);
|
TGSuperPoly sp;
|
||||||
}
|
string material = get_area_name(get_sliver_target_area_type());
|
||||||
|
|
||||||
|
sp.set_material( material );
|
||||||
|
sp.set_poly( remains );
|
||||||
|
|
||||||
|
polys_clipped.superpolys[(int)get_sliver_target_area_type()].push_back(sp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
FILE *ofp;
|
|
||||||
|
|
||||||
// tmp output accum
|
|
||||||
if ( accum.num_contours ) {
|
|
||||||
ofp = fopen("accum", "w");
|
|
||||||
gpc_write_polygon(ofp, 1, &accum);
|
|
||||||
fclose(ofp);
|
|
||||||
}
|
|
||||||
|
|
||||||
// tmp output safety_base
|
|
||||||
if ( remains->num_contours ) {
|
|
||||||
ofp= fopen("remains", "w");
|
|
||||||
gpc_write_polygon(ofp, 1, remains);
|
|
||||||
fclose(ofp);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SG_LOG( SG_CLIPPER, SG_INFO, " master clipper finished." );
|
SG_LOG( SG_CLIPPER, SG_INFO, " master clipper finished." );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -35,8 +35,10 @@
|
||||||
|
|
||||||
#include <simgear/compiler.h>
|
#include <simgear/compiler.h>
|
||||||
|
|
||||||
#include <Geometry/trinodes.hxx>
|
//#include <Geometry/trinodes.hxx>
|
||||||
#include <Polygon/polygon.hxx>
|
#include <Geometry/tg_nodes.hxx>
|
||||||
|
#include <Polygon/superpoly.hxx>
|
||||||
|
#include <Polygon/texparams.hxx>
|
||||||
#include <Polygon/point2d.hxx>
|
#include <Polygon/point2d.hxx>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -49,18 +51,21 @@
|
||||||
class TGPolyList
|
class TGPolyList
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
poly_list polys[TG_MAX_AREA_TYPES];
|
superpoly_list superpolys[TG_MAX_AREA_TYPES];
|
||||||
|
texparams_list texparams[TG_MAX_AREA_TYPES];
|
||||||
TGPolygon safety_base;
|
TGPolygon safety_base;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class TGClipper
|
class TGClipper
|
||||||
{
|
{
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
TGPolyList polys_in, polys_clipped;
|
TGPolyList polys_in, polys_clipped;
|
||||||
TGTriNodes fixed_elevations;
|
//TGTriNodes fixed_elevations;
|
||||||
|
TGNodes nodes;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -80,7 +85,7 @@ public:
|
||||||
bool load_osgb36_polys(const std::string& path);
|
bool load_osgb36_polys(const std::string& path);
|
||||||
|
|
||||||
// Add a polygon.
|
// Add a polygon.
|
||||||
void add_poly(int area, const TGPolygon &poly);
|
void add_poly(int area, const TGPolygon &poly, std::string material);
|
||||||
|
|
||||||
// Remove any slivers from in polygon and move them to out
|
// Remove any slivers from in polygon and move them to out
|
||||||
// polygon.
|
// polygon.
|
||||||
|
@ -99,7 +104,9 @@ public:
|
||||||
inline TGPolyList get_polys_clipped() const { return polys_clipped; }
|
inline TGPolyList get_polys_clipped() const { return polys_clipped; }
|
||||||
|
|
||||||
// Return the fixed elevation points list
|
// Return the fixed elevation points list
|
||||||
inline TGTriNodes get_fixed_elevations() const { return fixed_elevations; }
|
inline TGNodes get_nodes() const { return nodes; }
|
||||||
|
|
||||||
|
inline node_list get_fixed_elevations_nodes() { return nodes.get_fixed_elevation_nodes(); }
|
||||||
|
|
||||||
double nudge;
|
double nudge;
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <simgear/io/sg_binobj.hxx>
|
#include <simgear/io/sg_binobj.hxx>
|
||||||
#include <simgear/math/SGGeometry.hxx>
|
#include <simgear/math/SGGeometry.hxx>
|
||||||
#include <simgear/misc/texcoord.hxx>
|
#include <simgear/misc/texcoord.hxx>
|
||||||
|
#include <simgear/debug/logstream.hxx>
|
||||||
|
|
||||||
#include <Output/output.hxx>
|
#include <Output/output.hxx>
|
||||||
#include <Clipper/priorities.hxx>
|
#include <Clipper/priorities.hxx>
|
||||||
|
@ -49,7 +50,7 @@ void TGGenOutput::calc_gbs( TGConstruct& c ) {
|
||||||
gbs_center = SGVec3d::fromGeod( c.get_bucket().get_center() );
|
gbs_center = SGVec3d::fromGeod( c.get_bucket().get_center() );
|
||||||
|
|
||||||
double dist_squared, radius_squared = 0;
|
double dist_squared, radius_squared = 0;
|
||||||
for ( int i = 0; i < wgs84_nodes.size(); ++i ) {
|
for ( unsigned int i = 0; i < wgs84_nodes.size(); ++i ) {
|
||||||
dist_squared = distSqr(gbs_center, wgs84_nodes[i].toSGVec3d());
|
dist_squared = distSqr(gbs_center, wgs84_nodes[i].toSGVec3d());
|
||||||
if ( dist_squared > radius_squared ) {
|
if ( dist_squared > radius_squared ) {
|
||||||
radius_squared = dist_squared;
|
radius_squared = dist_squared;
|
||||||
|
@ -58,127 +59,45 @@ void TGGenOutput::calc_gbs( TGConstruct& c ) {
|
||||||
gbs_radius = sqrt(radius_squared);
|
gbs_radius = sqrt(radius_squared);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
#define FG_STANDARD_TEXTURE_DIMENSION 1000.0 // meters
|
|
||||||
|
|
||||||
// traverse the specified fan and attempt to calculate "none
|
|
||||||
// stretching" texture coordinates
|
|
||||||
int_list TGGenOutput::calc_tex_coords( TGConstruct& c, point_list geod_nodes,
|
|
||||||
int_list fan )
|
|
||||||
{
|
|
||||||
// cout << "calculating texture coordinates for a specific fan of size = "
|
|
||||||
// << fan.size() << endl;
|
|
||||||
|
|
||||||
SGBucket b = c.get_bucket();
|
|
||||||
double clat = b.get_center_lat();
|
|
||||||
double clat_rad = clat * SGD_DEGREES_TO_RADIANS;
|
|
||||||
double cos_lat = cos( clat_rad );
|
|
||||||
double local_radius = cos_lat * SG_EQUATORIAL_RADIUS_M;
|
|
||||||
double local_perimeter = 2.0 * local_radius * SGD_PI;
|
|
||||||
double degree_width = local_perimeter / 360.0;
|
|
||||||
|
|
||||||
// cout << "clat = " << clat << endl;
|
|
||||||
// cout << "clat (radians) = " << clat_rad << endl;
|
|
||||||
// cout << "cos(lat) = " << cos_lat << endl;
|
|
||||||
// cout << "local_radius = " << local_radius << endl;
|
|
||||||
// cout << "local_perimeter = " << local_perimeter << endl;
|
|
||||||
// cout << "degree_width = " << degree_width << endl;
|
|
||||||
|
|
||||||
double perimeter = 2.0 * SG_EQUATORIAL_RADIUS_M * SG_DPI;
|
|
||||||
double degree_height = perimeter / 360.0;
|
|
||||||
// cout << "degree_height = " << degree_height << endl;
|
|
||||||
|
|
||||||
// find min/max of fan
|
|
||||||
Point3D min, max, p, t;
|
|
||||||
bool first = true;
|
|
||||||
|
|
||||||
for ( int i = 0; i < (int)fan.size(); ++i ) {
|
|
||||||
p = geod_nodes[ fan[i] ];
|
|
||||||
t.setx( p.x() * ( degree_width / FG_STANDARD_TEXTURE_DIMENSION ) );
|
|
||||||
t.sety( p.y() * ( degree_height / FG_STANDARD_TEXTURE_DIMENSION ) );
|
|
||||||
|
|
||||||
if ( first ) {
|
|
||||||
min = max = t;
|
|
||||||
first = false;
|
|
||||||
} else {
|
|
||||||
if ( t.x() < min.x() ) {
|
|
||||||
min.setx( t.x() );
|
|
||||||
}
|
|
||||||
if ( t.y() < min.y() ) {
|
|
||||||
min.sety( t.y() );
|
|
||||||
}
|
|
||||||
if ( t.x() > max.x() ) {
|
|
||||||
max.setx( t.x() );
|
|
||||||
}
|
|
||||||
if ( t.y() > max.y() ) {
|
|
||||||
max.sety( t.y() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
min.setx( (double)( (int)min.x() - 1 ) );
|
|
||||||
min.sety( (double)( (int)min.y() - 1 ) );
|
|
||||||
// cout << "found min = " << min << endl;
|
|
||||||
|
|
||||||
// generate tex_list
|
|
||||||
Point3D shifted_t;
|
|
||||||
int index;
|
|
||||||
int_list tex;
|
|
||||||
tex.clear();
|
|
||||||
for ( int i = 0; i < (int)fan.size(); ++i ) {
|
|
||||||
p = geod_nodes[ fan[i] ];
|
|
||||||
t.setx( p.x() * ( degree_width / FG_STANDARD_TEXTURE_DIMENSION ) );
|
|
||||||
t.sety( p.y() * ( degree_height / FG_STANDARD_TEXTURE_DIMENSION ) );
|
|
||||||
shifted_t = t - min;
|
|
||||||
if ( shifted_t.x() < SG_EPSILON ) {
|
|
||||||
shifted_t.setx( 0.0 );
|
|
||||||
}
|
|
||||||
if ( shifted_t.y() < SG_EPSILON ) {
|
|
||||||
shifted_t.sety( 0.0 );
|
|
||||||
}
|
|
||||||
shifted_t.setz( 0.0 );
|
|
||||||
// cout << "shifted_t = " << shifted_t << endl;
|
|
||||||
index = tex_coords.unique_add( shifted_t );
|
|
||||||
tex.push_back( index );
|
|
||||||
}
|
|
||||||
|
|
||||||
return tex;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// build the necessary output structures based on the triangulation
|
// build the necessary output structures based on the triangulation
|
||||||
// data
|
// data
|
||||||
int TGGenOutput::build( TGConstruct& c ) {
|
int TGGenOutput::build_fans( TGConstruct& c ) {
|
||||||
int i, j, k;
|
// TGTriNodes trinodes = c.get_tri_nodes();
|
||||||
|
TGNodes* nodes = c.get_nodes();
|
||||||
|
|
||||||
TGTriNodes trinodes = c.get_tri_nodes();
|
string tile_id = c.get_bucket().gen_index_str();
|
||||||
|
|
||||||
// copy the geodetic node list into this class
|
// copy the geodetic node list into this class
|
||||||
geod_nodes = trinodes.get_node_list();
|
geod_nodes = nodes->get_geod_nodes();
|
||||||
|
|
||||||
// copy the triangle list into this class
|
// copy the triangle list into this class
|
||||||
tri_elements = c.get_tri_elements();
|
tri_elements = c.get_tri_elements();
|
||||||
|
|
||||||
// build the trifan list
|
// build the trifan list
|
||||||
cout << "total triangles = " << tri_elements.size() << endl;
|
cout << "total triangles = " << tri_elements.size() << endl;
|
||||||
|
|
||||||
TGGenFans f;
|
TGGenFans f;
|
||||||
for ( i = 0; i < TG_MAX_AREA_TYPES; ++i ) {
|
|
||||||
triele_list area_tris;
|
|
||||||
area_tris.erase( area_tris.begin(), area_tris.end() );
|
|
||||||
|
|
||||||
const_triele_list_iterator t_current = tri_elements.begin();
|
// Sort the triangles by area type
|
||||||
const_triele_list_iterator t_last = tri_elements.end();
|
// TODO: Need to sort on Material type - going to make the attribute an index
|
||||||
for ( ; t_current != t_last; ++t_current ) {
|
// into an array of texparams / material names
|
||||||
if ( (int)t_current->get_attribute() == i ) {
|
for ( unsigned int i = 0; i < TG_MAX_AREA_TYPES; ++i ) {
|
||||||
area_tris.push_back( *t_current );
|
triele_list area_tris;
|
||||||
}
|
area_tris.erase( area_tris.begin(), area_tris.end() );
|
||||||
}
|
|
||||||
|
|
||||||
if ( (int)area_tris.size() > 0 ) {
|
const_triele_list_iterator t_current = tri_elements.begin();
|
||||||
cout << "generating fans for area = " << i << endl;
|
const_triele_list_iterator t_last = tri_elements.end();
|
||||||
fans[i] = f.greedy_build( area_tris );
|
|
||||||
}
|
for ( ; t_current != t_last; ++t_current ) {
|
||||||
|
if ( t_current->get_attribute() == i ) {
|
||||||
|
area_tris.push_back( *t_current );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (int)area_tris.size() > 0 ) {
|
||||||
|
cout << "generating fans for area = " << i << endl;
|
||||||
|
primitives[i] = f.greedy_build( area_tris );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// build the texture coordinate list and make a parallel structure
|
// build the texture coordinate list and make a parallel structure
|
||||||
|
@ -187,37 +106,38 @@ int TGGenOutput::build( TGConstruct& c ) {
|
||||||
cout << "c.get_useUKGrid() = " << c.get_useUKGrid() << endl;
|
cout << "c.get_useUKGrid() = " << c.get_useUKGrid() << endl;
|
||||||
tex_coords.clear();
|
tex_coords.clear();
|
||||||
std::vector < SGGeod > convGeodNodes;
|
std::vector < SGGeod > convGeodNodes;
|
||||||
for ( k = 0; k < geod_nodes.size(); k++ ) {
|
for ( unsigned int k = 0; k < geod_nodes.size(); k++ ) {
|
||||||
Point3D node = geod_nodes[k];
|
Point3D node = geod_nodes[k];
|
||||||
convGeodNodes.push_back( SGGeod::fromDegM( node.x(), node.y(), node.z() ) );
|
convGeodNodes.push_back( SGGeod::fromDegM( node.x(), node.y(), node.z() ) );
|
||||||
}
|
}
|
||||||
for ( i = 0; i < TG_MAX_AREA_TYPES; ++i ) {
|
|
||||||
|
for ( unsigned int i = 0; i < TG_MAX_AREA_TYPES; ++i ) {
|
||||||
// cout << " area = " << i << endl;
|
// cout << " area = " << i << endl;
|
||||||
for ( j = 0; j < (int)fans[i].size(); ++j ) {
|
for ( unsigned int j = 0; j < primitives[i].size(); ++j ) {
|
||||||
// int_list t_list = calc_tex_coords( c, geod_nodes, fans[i][j] );
|
SG_LOG( SG_CLIPPER, SG_INFO, tile_id << ": Texturing " << get_area_name( (AreaType)i ) << " primitive " << j+1 << " of " << primitives[i].size() );
|
||||||
// cout << fans[i][j].size() << " === "
|
|
||||||
// << t_list.size() << endl;
|
|
||||||
SGBucket b = c.get_bucket();
|
|
||||||
Point3D ourPosition;
|
|
||||||
|
|
||||||
ourPosition.setlon(b.get_chunk_lon());
|
SGBucket b = c.get_bucket();
|
||||||
ourPosition.setlat(b.get_chunk_lat());
|
Point3D ourPosition;
|
||||||
|
|
||||||
int_list ti_list;
|
ourPosition.setlon(b.get_chunk_lon());
|
||||||
ti_list.clear();
|
ourPosition.setlat(b.get_chunk_lat());
|
||||||
//dcl - here read the flag to check if we are building UK grid
|
|
||||||
//If so - check if the bucket is within the UK lat & lon
|
int_list ti_list;
|
||||||
if( (c.get_useUKGrid()) && (isInUK(ourPosition)) ) {
|
ti_list.clear();
|
||||||
point_list tp_list;
|
|
||||||
tp_list = UK_calc_tex_coords( b, geod_nodes, fans[i][j], 1.0 );
|
//dcl - here read the flag to check if we are building UK grid
|
||||||
for ( k = 0; k < (int)tp_list.size(); ++k ) {
|
//If so - check if the bucket is within the UK lat & lon
|
||||||
|
if( (c.get_useUKGrid()) && (isInUK(ourPosition)) ) {
|
||||||
|
point_list tp_list;
|
||||||
|
tp_list = UK_calc_tex_coords( b, geod_nodes, primitives[i][j], 1.0 );
|
||||||
|
for ( unsigned int k = 0; k < tp_list.size(); ++k ) {
|
||||||
// cout << " tc = " << tp_list[k] << endl;
|
// cout << " tc = " << tp_list[k] << endl;
|
||||||
int index = tex_coords.simple_add( tp_list[k] );
|
int index = tex_coords.simple_add( tp_list[k] );
|
||||||
ti_list.push_back( index );
|
ti_list.push_back( index );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
std::vector< SGVec2f > tp_list = sgCalcTexCoords( b, convGeodNodes, fans[i][j] );
|
std::vector< SGVec2f > tp_list = sgCalcTexCoords( b, convGeodNodes, primitives[i][j] );
|
||||||
for ( k = 0; k < (int)tp_list.size(); ++k ) {
|
for ( unsigned int k = 0; k < tp_list.size(); ++k ) {
|
||||||
SGVec2f tc = tp_list[k];
|
SGVec2f tc = tp_list[k];
|
||||||
// SG_LOG(SG_GENERAL, SG_DEBUG, "base_tc = " << tc);
|
// SG_LOG(SG_GENERAL, SG_DEBUG, "base_tc = " << tc);
|
||||||
int index = tex_coords.simple_add( Point3D( tc.x(), tc.y(), 0 ) );
|
int index = tex_coords.simple_add( Point3D( tc.x(), tc.y(), 0 ) );
|
||||||
|
@ -225,8 +145,8 @@ int TGGenOutput::build( TGConstruct& c ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
textures[i].push_back( ti_list );
|
textures[i].push_back( ti_list );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate the global bounding sphere
|
// calculate the global bounding sphere
|
||||||
|
@ -237,21 +157,132 @@ int TGGenOutput::build( TGConstruct& c ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static opt_list tgGenTris( const triele_list tris ) {
|
||||||
|
triele_list remaining = tris;
|
||||||
|
opt_list tri_lists;
|
||||||
|
int_list tri;
|
||||||
|
|
||||||
|
tri_lists.clear();
|
||||||
|
for ( unsigned int i = 0; i < tris.size(); ++i ) {
|
||||||
|
tri.clear();
|
||||||
|
|
||||||
|
tri.push_back( tris[i].get_n1() );
|
||||||
|
tri.push_back( tris[i].get_n2() );
|
||||||
|
tri.push_back( tris[i].get_n3() );
|
||||||
|
|
||||||
|
tri_lists.push_back( tri );
|
||||||
|
}
|
||||||
|
|
||||||
|
return tri_lists;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TGGenOutput::build_tris( TGConstruct& c ) {
|
||||||
|
// TGTriNodes trinodes = c.get_tri_nodes();
|
||||||
|
TGNodes* nodes = c.get_nodes();
|
||||||
|
|
||||||
|
string tile_id = c.get_bucket().gen_index_str();
|
||||||
|
|
||||||
|
// copy the geodetic node list into this class
|
||||||
|
geod_nodes = nodes->get_geod_nodes();
|
||||||
|
|
||||||
|
// copy the triangle list into this class
|
||||||
|
tri_elements = c.get_tri_elements();
|
||||||
|
|
||||||
|
// build the trifan list
|
||||||
|
cout << "total triangles = " << tri_elements.size() << endl;
|
||||||
|
|
||||||
|
// Sort the triangles by area type
|
||||||
|
// TODO: Need to sort on Material type - going to make the attribute an index
|
||||||
|
// into an array of texparams / material names
|
||||||
|
for ( unsigned int i = 0; i < TG_MAX_AREA_TYPES; ++i ) {
|
||||||
|
triele_list area_tris;
|
||||||
|
area_tris.erase( area_tris.begin(), area_tris.end() );
|
||||||
|
|
||||||
|
const_triele_list_iterator t_current = tri_elements.begin();
|
||||||
|
const_triele_list_iterator t_last = tri_elements.end();
|
||||||
|
|
||||||
|
for ( ; t_current != t_last; ++t_current ) {
|
||||||
|
if ( t_current->get_attribute() == i ) {
|
||||||
|
area_tris.push_back( *t_current );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( area_tris.size() > 0 ) {
|
||||||
|
cout << "generating tris for area = " << i << endl;
|
||||||
|
primitives[i] = tgGenTris( area_tris );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// build the texture coordinate list and make a parallel structure
|
||||||
|
// to the fan list for pointers into the texture list
|
||||||
|
cout << "calculating texture coordinates" << endl;
|
||||||
|
cout << "c.get_useUKGrid() = " << c.get_useUKGrid() << endl;
|
||||||
|
tex_coords.clear();
|
||||||
|
std::vector < SGGeod > convGeodNodes;
|
||||||
|
for ( unsigned int k = 0; k < geod_nodes.size(); k++ ) {
|
||||||
|
Point3D node = geod_nodes[k];
|
||||||
|
convGeodNodes.push_back( SGGeod::fromDegM( node.x(), node.y(), node.z() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( unsigned int i = 0; i < TG_MAX_AREA_TYPES; ++i ) {
|
||||||
|
// cout << " area = " << i << endl;
|
||||||
|
for ( unsigned int j = 0; j < primitives[i].size(); ++j ) {
|
||||||
|
SG_LOG( SG_CLIPPER, SG_INFO, tile_id << ": Texturing " << get_area_name( (AreaType)i ) << " primitive " << j+1 << " of " << primitives[i].size() );
|
||||||
|
|
||||||
|
SGBucket b = c.get_bucket();
|
||||||
|
Point3D ourPosition;
|
||||||
|
|
||||||
|
ourPosition.setlon(b.get_chunk_lon());
|
||||||
|
ourPosition.setlat(b.get_chunk_lat());
|
||||||
|
|
||||||
|
int_list ti_list;
|
||||||
|
ti_list.clear();
|
||||||
|
|
||||||
|
//dcl - here read the flag to check if we are building UK grid
|
||||||
|
//If so - check if the bucket is within the UK lat & lon
|
||||||
|
if( (c.get_useUKGrid()) && (isInUK(ourPosition)) ) {
|
||||||
|
point_list tp_list;
|
||||||
|
tp_list = UK_calc_tex_coords( b, geod_nodes, primitives[i][j], 1.0 );
|
||||||
|
for ( unsigned int k = 0; k < tp_list.size(); ++k ) {
|
||||||
|
// cout << " tc = " << tp_list[k] << endl;
|
||||||
|
int index = tex_coords.simple_add( tp_list[k] );
|
||||||
|
ti_list.push_back( index );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
std::vector< SGVec2f > tp_list = sgCalcTexCoords( b, convGeodNodes, primitives[i][j] );
|
||||||
|
for ( unsigned int k = 0; k < tp_list.size(); ++k ) {
|
||||||
|
SGVec2f tc = tp_list[k];
|
||||||
|
// SG_LOG(SG_GENERAL, SG_DEBUG, "base_tc = " << tc);
|
||||||
|
int index = tex_coords.simple_add( Point3D( tc.x(), tc.y(), 0 ) );
|
||||||
|
ti_list.push_back( index );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
textures[i].push_back( ti_list );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate the global bounding sphere
|
||||||
|
calc_gbs( c );
|
||||||
|
cout << "center = " << gbs_center << " radius = " << gbs_radius << endl;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// calculate the bounding sphere for a list of triangle faces
|
// calculate the bounding sphere for a list of triangle faces
|
||||||
void TGGenOutput::calc_group_bounding_sphere( TGConstruct& c,
|
void TGGenOutput::calc_group_bounding_sphere( TGConstruct& c,
|
||||||
const opt_list& fans,
|
const opt_list& primitives,
|
||||||
Point3D *center, double *radius )
|
Point3D *center, double *radius )
|
||||||
{
|
{
|
||||||
cout << "calculate group bounding sphere for " << fans.size() << " fans."
|
cout << "calculate group bounding sphere for " << primitives.size() << " primitives." << endl;
|
||||||
<< endl;
|
|
||||||
|
|
||||||
point_list wgs84_nodes = c.get_wgs84_nodes();
|
point_list wgs84_nodes = c.get_wgs84_nodes();
|
||||||
|
|
||||||
// generate a list of unique points from the triangle list
|
// generate a list of unique points from the triangle list
|
||||||
TGTriNodes nodes;
|
TGTriNodes nodes;
|
||||||
|
|
||||||
const_opt_list_iterator f_current = fans.begin();
|
const_opt_list_iterator f_current = primitives.begin();
|
||||||
const_opt_list_iterator f_last = fans.end();
|
const_opt_list_iterator f_last = primitives.end();
|
||||||
for ( ; f_current != f_last; ++f_current ) {
|
for ( ; f_current != f_last; ++f_current ) {
|
||||||
const_int_list_iterator i_current = f_current->begin();
|
const_int_list_iterator i_current = f_current->begin();
|
||||||
const_int_list_iterator i_last = f_current->end();
|
const_int_list_iterator i_last = f_current->end();
|
||||||
|
@ -325,130 +356,8 @@ void TGGenOutput::calc_bounding_sphere( TGConstruct& c, const TGTriEle& t,
|
||||||
*radius = sqrt(max_squared);
|
*radius = sqrt(max_squared);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// write out the fgfs scenery file (using fans)
|
||||||
#if 0
|
int TGGenOutput::write_fans( TGConstruct &c ) {
|
||||||
// write out the fgfs scenery file
|
|
||||||
int TGGenOutput::write_orig( TGConstruct &c ) {
|
|
||||||
Point3D p;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
string base = c.get_output_base();
|
|
||||||
SGBucket b = c.get_bucket();
|
|
||||||
|
|
||||||
string dir = base + b.gen_base_path();
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
fg_mkdir( dir.c_str() );
|
|
||||||
#else
|
|
||||||
string command = "mkdir -p " + dir;
|
|
||||||
system(command.c_str());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
string file = dir + "/" + b.gen_index_str();
|
|
||||||
cout << "Output file = " << file << endl;
|
|
||||||
|
|
||||||
FILE *fp;
|
|
||||||
if ( (fp = fopen( file.c_str(), "w" )) == NULL ) {
|
|
||||||
cout << "ERROR: opening " << file << " for writing!" << endl;
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// write headers
|
|
||||||
fprintf(fp, "# FGFS Scenery\n");
|
|
||||||
fprintf(fp, "# Version %s\n", FG_SCENERY_FILE_FORMAT);
|
|
||||||
|
|
||||||
time_t calendar_time = time(NULL);
|
|
||||||
struct tm *local_tm;
|
|
||||||
local_tm = localtime( &calendar_time );
|
|
||||||
char time_str[256];
|
|
||||||
strftime( time_str, 256, "%a %b %d %H:%M:%S %Z %Y", local_tm);
|
|
||||||
fprintf(fp, "# Created %s\n", time_str );
|
|
||||||
fprintf(fp, "\n");
|
|
||||||
|
|
||||||
// write global bounding sphere
|
|
||||||
fprintf(fp, "# gbs %.5f %.5f %.5f %.2f\n",
|
|
||||||
gbs_center.x(), gbs_center.y(), gbs_center.z(), gbs_radius);
|
|
||||||
fprintf(fp, "\n");
|
|
||||||
|
|
||||||
// write nodes
|
|
||||||
point_list wgs84_nodes = c.get_wgs84_nodes();
|
|
||||||
cout << "writing nodes = " << wgs84_nodes.size() << endl;
|
|
||||||
fprintf(fp, "# vertex list\n");
|
|
||||||
const_point_list_iterator w_current = wgs84_nodes.begin();
|
|
||||||
const_point_list_iterator w_last = wgs84_nodes.end();
|
|
||||||
for ( ; w_current != w_last; ++w_current ) {
|
|
||||||
p = *w_current - gbs_center;
|
|
||||||
fprintf(fp, "v %.5f %.5f %.5f\n", p.x(), p.y(), p.z());
|
|
||||||
}
|
|
||||||
fprintf(fp, "\n");
|
|
||||||
|
|
||||||
// write vertex normals
|
|
||||||
point_list point_normals = c.get_point_normals();
|
|
||||||
cout << "writing normals = " << point_normals.size() << endl;
|
|
||||||
fprintf(fp, "# vertex normal list\n");
|
|
||||||
const_point_list_iterator n_current = point_normals.begin();
|
|
||||||
const_point_list_iterator n_last = point_normals.end();
|
|
||||||
for ( ; n_current != n_last; ++n_current ) {
|
|
||||||
p = *n_current;
|
|
||||||
fprintf(fp, "vn %.5f %.5f %.5f\n", p.x(), p.y(), p.z());
|
|
||||||
}
|
|
||||||
fprintf(fp, "\n");
|
|
||||||
|
|
||||||
// write texture coordinates
|
|
||||||
point_list tex_coord_list = tex_coords.get_node_list();
|
|
||||||
fprintf(fp, "# texture coordinate list\n");
|
|
||||||
for ( i = 0; i < (int)tex_coord_list.size(); ++i ) {
|
|
||||||
p = tex_coord_list[i];
|
|
||||||
fprintf(fp, "vt %.5f %.5f\n", p.x(), p.y());
|
|
||||||
}
|
|
||||||
fprintf(fp, "\n");
|
|
||||||
|
|
||||||
// write triangles (grouped by type for now)
|
|
||||||
Point3D center;
|
|
||||||
double radius;
|
|
||||||
fprintf(fp, "# triangle groups\n");
|
|
||||||
fprintf(fp, "\n");
|
|
||||||
|
|
||||||
int total_tris = 0;
|
|
||||||
for ( i = 0; i < TG_MAX_AREA_TYPES; ++i ) {
|
|
||||||
if ( (int)fans[i].size() > 0 ) {
|
|
||||||
string attr_name = get_area_name( (AreaType)i );
|
|
||||||
calc_group_bounding_sphere( c, fans[i], ¢er, &radius );
|
|
||||||
cout << "writing " << (int)fans[i].size() << " fans for "
|
|
||||||
<< attr_name << endl;
|
|
||||||
|
|
||||||
fprintf(fp, "# usemtl %s\n", attr_name.c_str() );
|
|
||||||
fprintf(fp, "# bs %.4f %.4f %.4f %.2f\n",
|
|
||||||
center.x(), center.y(), center.z(), radius);
|
|
||||||
|
|
||||||
for ( int j = 0; j < (int)fans[i].size(); ++j ) {
|
|
||||||
fprintf( fp, "tf" );
|
|
||||||
total_tris += fans[i][j].size() - 2;
|
|
||||||
for ( int k = 0; k < (int)fans[i][j].size(); ++k ) {
|
|
||||||
fprintf( fp, " %d/%d", fans[i][j][k], textures[i][j][k] );
|
|
||||||
}
|
|
||||||
fprintf( fp, "\n" );
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf( fp, "\n" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cout << "wrote " << total_tris << " tris to output file" << endl;
|
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
command = "gzip --force --best " + file;
|
|
||||||
system(command.c_str());
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// write out the fgfs scenery file
|
|
||||||
int TGGenOutput::write( TGConstruct &c ) {
|
|
||||||
int i;
|
|
||||||
|
|
||||||
// Assemble all the data into the final format
|
// Assemble all the data into the final format
|
||||||
|
|
||||||
SGBucket b = c.get_bucket();
|
SGBucket b = c.get_bucket();
|
||||||
|
@ -457,12 +366,12 @@ int TGGenOutput::write( TGConstruct &c ) {
|
||||||
name += ".btg";
|
name += ".btg";
|
||||||
|
|
||||||
std::vector< SGVec3d > wgs84_nodes;
|
std::vector< SGVec3d > wgs84_nodes;
|
||||||
for ( i = 0; i < c.get_wgs84_nodes().size(); i++ ) {
|
for ( unsigned int i = 0; i < c.get_wgs84_nodes().size(); i++ ) {
|
||||||
Point3D node = c.get_wgs84_nodes()[i];
|
Point3D node = c.get_wgs84_nodes()[i];
|
||||||
wgs84_nodes.push_back( node.toSGVec3d() );
|
wgs84_nodes.push_back( node.toSGVec3d() );
|
||||||
}
|
}
|
||||||
std::vector< SGVec3f > normals;
|
std::vector< SGVec3f > normals;
|
||||||
for ( i = 0; i < c.get_point_normals().size(); i++ ) {
|
for ( unsigned int i = 0; i < c.get_point_normals().size(); i++ ) {
|
||||||
Point3D node = c.get_point_normals()[i];
|
Point3D node = c.get_point_normals()[i];
|
||||||
normals.push_back( node.toSGVec3f() );
|
normals.push_back( node.toSGVec3f() );
|
||||||
}
|
}
|
||||||
|
@ -472,7 +381,7 @@ int TGGenOutput::write( TGConstruct &c ) {
|
||||||
printf("vn %.5f %.5f %.5f\n", p.x(), p.y(), p.z());
|
printf("vn %.5f %.5f %.5f\n", p.x(), p.y(), p.z());
|
||||||
} */
|
} */
|
||||||
std::vector< SGVec2f > texcoords;
|
std::vector< SGVec2f > texcoords;
|
||||||
for ( i = 0; i < tex_coords.get_node_list().size(); i++ ) {
|
for ( unsigned int i = 0; i < tex_coords.get_node_list().size(); i++ ) {
|
||||||
Point3D node = tex_coords.get_node_list()[i];
|
Point3D node = tex_coords.get_node_list()[i];
|
||||||
texcoords.push_back( node.toSGVec2f() );
|
texcoords.push_back( node.toSGVec2f() );
|
||||||
}
|
}
|
||||||
|
@ -487,17 +396,16 @@ int TGGenOutput::write( TGConstruct &c ) {
|
||||||
group_list fans_v; group_list fans_tc; string_list fan_materials;
|
group_list fans_v; group_list fans_tc; string_list fan_materials;
|
||||||
fans_v.clear(); fans_tc.clear(); fan_materials.clear();
|
fans_v.clear(); fans_tc.clear(); fan_materials.clear();
|
||||||
|
|
||||||
for ( i = 0; i < TG_MAX_AREA_TYPES; ++i ) {
|
for ( unsigned int i = 0; i < TG_MAX_AREA_TYPES; ++i ) {
|
||||||
if ( (int)fans[i].size() > 0 ) {
|
if ( primitives[i].size() > 0 ) {
|
||||||
cout << "creating " << fans[i].size() << " fans of type "
|
cout << "creating " << primitives[i].size() << " fans of type " << i << endl;
|
||||||
<< i << endl;
|
|
||||||
string attr_name = get_area_name( (AreaType)i );
|
string attr_name = get_area_name( (AreaType)i );
|
||||||
|
|
||||||
int_list vs, tcs;
|
int_list vs, tcs;
|
||||||
for ( int j = 0; j < (int)fans[i].size(); ++j ) {
|
for ( unsigned int j = 0; j < primitives[i].size(); ++j ) {
|
||||||
vs.clear(); tcs.clear();
|
vs.clear(); tcs.clear();
|
||||||
for ( int k = 0; k < (int)fans[i][j].size(); ++k ) {
|
for ( unsigned int k = 0; k < primitives[i][j].size(); ++k ) {
|
||||||
vs.push_back( fans[i][j][k] );
|
vs.push_back( primitives[i][j][k] );
|
||||||
tcs.push_back( textures[i][j][k] );
|
tcs.push_back( textures[i][j][k] );
|
||||||
}
|
}
|
||||||
fans_v.push_back( vs );
|
fans_v.push_back( vs );
|
||||||
|
@ -529,4 +437,83 @@ int TGGenOutput::write( TGConstruct &c ) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// write out the fgfs scenery file (using tris)
|
||||||
|
int TGGenOutput::write_tris( TGConstruct &c ) {
|
||||||
|
// Assemble all the data into the final format
|
||||||
|
|
||||||
|
SGBucket b = c.get_bucket();
|
||||||
|
string base = c.get_output_base();
|
||||||
|
string name = b.gen_index_str();
|
||||||
|
name += ".btg";
|
||||||
|
|
||||||
|
std::vector< SGVec3d > wgs84_nodes;
|
||||||
|
for ( unsigned int i = 0; i < c.get_wgs84_nodes().size(); i++ ) {
|
||||||
|
Point3D node = c.get_wgs84_nodes()[i];
|
||||||
|
wgs84_nodes.push_back( node.toSGVec3d() );
|
||||||
|
}
|
||||||
|
std::vector< SGVec3f > normals;
|
||||||
|
for ( unsigned int i = 0; i < c.get_point_normals().size(); i++ ) {
|
||||||
|
Point3D node = c.get_point_normals()[i];
|
||||||
|
normals.push_back( node.toSGVec3f() );
|
||||||
|
}
|
||||||
|
cout << "dumping normals = " << normals.size() << endl;
|
||||||
|
/* for ( i = 0; i < (int)normals.size(); ++i ) {
|
||||||
|
Point3D p = normals[i];
|
||||||
|
printf("vn %.5f %.5f %.5f\n", p.x(), p.y(), p.z());
|
||||||
|
} */
|
||||||
|
std::vector< SGVec2f > texcoords;
|
||||||
|
for ( unsigned int i = 0; i < tex_coords.get_node_list().size(); i++ ) {
|
||||||
|
Point3D node = tex_coords.get_node_list()[i];
|
||||||
|
texcoords.push_back( node.toSGVec2f() );
|
||||||
|
}
|
||||||
|
|
||||||
|
// allocate and initialize triangle group structures
|
||||||
|
group_list tris_v; group_list tris_tc; string_list tri_materials;
|
||||||
|
tris_v.clear(); tris_tc.clear(); tri_materials.clear();
|
||||||
|
|
||||||
|
group_list strips_v; group_list strips_tc; string_list strip_materials;
|
||||||
|
strips_v.clear(); strips_tc.clear(); strip_materials.clear();
|
||||||
|
|
||||||
|
group_list fans_v; group_list fans_tc; string_list fan_materials;
|
||||||
|
fans_v.clear(); fans_tc.clear(); fan_materials.clear();
|
||||||
|
|
||||||
|
for ( unsigned int i = 0; i < TG_MAX_AREA_TYPES; ++i ) {
|
||||||
|
if ( primitives[i].size() > 0 ) {
|
||||||
|
cout << "creating " << primitives[i].size() << " tris of type " << i << endl;
|
||||||
|
string attr_name = get_area_name( (AreaType)i );
|
||||||
|
|
||||||
|
int_list vs, tcs;
|
||||||
|
for ( unsigned int j = 0; j < primitives[i].size(); ++j ) {
|
||||||
|
vs.clear(); tcs.clear();
|
||||||
|
for ( unsigned int k = 0; k < primitives[i][j].size(); ++k ) {
|
||||||
|
vs.push_back( primitives[i][j][k] );
|
||||||
|
tcs.push_back( textures[i][j][k] );
|
||||||
|
}
|
||||||
|
tris_v.push_back( vs );
|
||||||
|
tris_tc.push_back( tcs );
|
||||||
|
tri_materials.push_back( attr_name );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SGBinObject obj;
|
||||||
|
|
||||||
|
obj.set_gbs_center( gbs_center );
|
||||||
|
obj.set_gbs_radius( gbs_radius );
|
||||||
|
obj.set_wgs84_nodes( wgs84_nodes );
|
||||||
|
obj.set_normals( normals );
|
||||||
|
obj.set_texcoords( texcoords );
|
||||||
|
obj.set_tris_v( tris_v );
|
||||||
|
obj.set_tris_tc( tris_tc );
|
||||||
|
obj.set_tri_materials( tri_materials );
|
||||||
|
obj.set_strips_v( strips_v );
|
||||||
|
obj.set_strips_tc( strips_tc );
|
||||||
|
obj.set_strip_materials( strip_materials );
|
||||||
|
obj.set_fans_v( fans_v );
|
||||||
|
obj.set_fans_tc( fans_tc );
|
||||||
|
obj.set_fan_materials( fan_materials );
|
||||||
|
|
||||||
|
obj.write_bin( base, name, b );
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
|
@ -59,8 +59,8 @@ private:
|
||||||
// texture coordinates
|
// texture coordinates
|
||||||
TGTriNodes tex_coords;
|
TGTriNodes tex_coords;
|
||||||
|
|
||||||
// fan list
|
// fan / triangle list
|
||||||
opt_list fans[TG_MAX_AREA_TYPES];
|
opt_list primitives[TG_MAX_AREA_TYPES];
|
||||||
|
|
||||||
// textures pointer list
|
// textures pointer list
|
||||||
tex_list textures[TG_MAX_AREA_TYPES];
|
tex_list textures[TG_MAX_AREA_TYPES];
|
||||||
|
@ -93,10 +93,12 @@ public:
|
||||||
|
|
||||||
// build the necessary output structures based on the
|
// build the necessary output structures based on the
|
||||||
// triangulation data
|
// triangulation data
|
||||||
int build( TGConstruct& c );
|
int build_fans( TGConstruct& c );
|
||||||
|
int build_tris( TGConstruct& c );
|
||||||
|
|
||||||
// write out the fgfs scenery file
|
// write out the fgfs scenery file
|
||||||
int write( TGConstruct &c );
|
int write_fans( TGConstruct &c );
|
||||||
|
int write_tris( TGConstruct &c );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -92,10 +92,11 @@ private:
|
||||||
|
|
||||||
// Fixed elevations (from polygon input data with z values
|
// Fixed elevations (from polygon input data with z values
|
||||||
// pre-specified)
|
// pre-specified)
|
||||||
TGTriNodes fixed_elevations;
|
node_list fixed_elevations;
|
||||||
|
|
||||||
// raw node list (after triangulation)
|
// raw node list (after triangulation)
|
||||||
TGTriNodes tri_nodes;
|
TGTriNodes tri_nodes;
|
||||||
|
TGNodes nodes;
|
||||||
|
|
||||||
// node list in geodetic coords (with fixed elevation)
|
// node list in geodetic coords (with fixed elevation)
|
||||||
point_list geod_nodes;
|
point_list geod_nodes;
|
||||||
|
@ -115,10 +116,6 @@ private:
|
||||||
// face normal list (for flat shading)
|
// face normal list (for flat shading)
|
||||||
point_list face_normals;
|
point_list face_normals;
|
||||||
|
|
||||||
// normal list (for each point) in cart coords (for smooth
|
|
||||||
// shading)
|
|
||||||
point_list point_normals;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
|
@ -167,33 +164,32 @@ public:
|
||||||
inline TGPolyList get_clipped_polys() const { return clipped_polys; }
|
inline TGPolyList get_clipped_polys() const { return clipped_polys; }
|
||||||
inline void set_clipped_polys( TGPolyList p ) { clipped_polys = p; }
|
inline void set_clipped_polys( TGPolyList p ) { clipped_polys = p; }
|
||||||
|
|
||||||
// Fixed elevations (from polygon input data with z values
|
// Fixed elevations (from polygon input data with z values pre-specified)
|
||||||
// pre-specified)
|
inline node_list get_fixed_elevations() const { return nodes.get_fixed_elevation_nodes(); }
|
||||||
inline TGTriNodes get_fixed_elevations() const { return fixed_elevations; }
|
|
||||||
inline void set_fixed_elevations( TGTriNodes n ) { fixed_elevations = n; }
|
|
||||||
|
|
||||||
// node list (after triangulation)
|
// node list (after triangulation) : No need - we won't add nodes....
|
||||||
inline TGTriNodes get_tri_nodes() const { return tri_nodes; }
|
// inline TGTriNodes get_tri_nodes() const { return tri_nodes; }
|
||||||
inline void set_tri_nodes( TGTriNodes n ) { tri_nodes = n; }
|
// inline void set_tri_nodes( TGTriNodes n ) { tri_nodes = n; }
|
||||||
|
|
||||||
// triangle elements (after triangulation)
|
inline TGNodes* get_nodes() { return &nodes; }
|
||||||
|
inline void set_nodes( TGNodes n ) { nodes = n; }
|
||||||
|
|
||||||
|
// triangle elements (after triangulation) : No need - will be in the triangulated polygons
|
||||||
inline triele_list get_tri_elements() const { return tri_elements; }
|
inline triele_list get_tri_elements() const { return tri_elements; }
|
||||||
inline void set_tri_elements( triele_list e ) { tri_elements = e; }
|
inline void set_tri_elements( triele_list e ) { tri_elements = e; }
|
||||||
inline void set_tri_attribute( int num, AreaType a ) {
|
inline void set_tri_attribute( int num, AreaType a ) { tri_elements[num].set_attribute( a ); }
|
||||||
tri_elements[num].set_attribute( a );
|
|
||||||
}
|
|
||||||
|
|
||||||
// edge segments (after triangulation)
|
// edge segments (after triangulation) : Same as above
|
||||||
inline TGTriSegments get_tri_segs() const { return tri_segs; }
|
inline TGTriSegments get_tri_segs() const { return tri_segs; }
|
||||||
inline void set_tri_segs( TGTriSegments s ) { tri_segs = s; }
|
inline void set_tri_segs( TGTriSegments s ) { tri_segs = s; }
|
||||||
|
|
||||||
// node list in geodetic coords (with fixed elevation)
|
// node list in geodetic coords (with fixed elevation)
|
||||||
inline point_list get_geod_nodes() const { return geod_nodes; }
|
inline point_list get_geod_nodes() const { return nodes.get_geod_nodes(); }
|
||||||
inline void set_geod_nodes( point_list n ) { geod_nodes = n; }
|
// inline void set_geod_nodes( point_list n ) { geod_nodes = n; }
|
||||||
|
|
||||||
// node list in cartesian coords (wgs84 model)
|
// node list in cartesian coords (wgs84 model)
|
||||||
inline point_list get_wgs84_nodes() const { return wgs84_nodes; }
|
inline point_list get_wgs84_nodes() const { return nodes.get_wgs84_nodes_as_Point3d(); }
|
||||||
inline void set_wgs84_nodes( point_list n ) { wgs84_nodes = n; }
|
// inline void set_wgs84_nodes( point_list n ) { wgs84_nodes = n; }
|
||||||
|
|
||||||
// for each node, a list of triangle indices that contain this node
|
// for each node, a list of triangle indices that contain this node
|
||||||
inline belongs_to_list get_reverse_ele_lookup() const {
|
inline belongs_to_list get_reverse_ele_lookup() const {
|
||||||
|
@ -209,8 +205,7 @@ public:
|
||||||
|
|
||||||
// normal list (for each point) in cart coords (for smooth
|
// normal list (for each point) in cart coords (for smooth
|
||||||
// shading)
|
// shading)
|
||||||
inline point_list get_point_normals() const { return point_normals; }
|
inline point_list get_point_normals() const { return nodes.get_normals(); }
|
||||||
inline void set_point_normals( point_list n ) { point_normals = n; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -27,9 +27,11 @@
|
||||||
|
|
||||||
#include <simgear/compiler.h>
|
#include <simgear/compiler.h>
|
||||||
#include <Geometry/point3d.hxx>
|
#include <Geometry/point3d.hxx>
|
||||||
|
#include <Geometry/tg_nodes.hxx>
|
||||||
#include <simgear/math/sg_geodesy.hxx>
|
#include <simgear/math/sg_geodesy.hxx>
|
||||||
#include <simgear/misc/sgstream.hxx>
|
#include <simgear/misc/sgstream.hxx>
|
||||||
#include <simgear/misc/sg_path.hxx>
|
#include <simgear/misc/sg_path.hxx>
|
||||||
|
#include <simgear/debug/logstream.hxx>
|
||||||
|
|
||||||
#include "match.hxx"
|
#include "match.hxx"
|
||||||
|
|
||||||
|
@ -369,6 +371,9 @@ void TGMatch::split_tile( TGConstruct& c ) {
|
||||||
point_list nodes = c.get_geod_nodes();
|
point_list nodes = c.get_geod_nodes();
|
||||||
point_list point_normals = c.get_point_normals();
|
point_list point_normals = c.get_point_normals();
|
||||||
|
|
||||||
|
SG_LOG(SG_GENERAL, SG_ALERT, "number of geod nodes = " << nodes.size() );
|
||||||
|
SG_LOG(SG_GENERAL, SG_ALERT, "number of normals = " << point_normals.size() );
|
||||||
|
|
||||||
for ( i = 0; i < (int)nodes.size(); ++i ) {
|
for ( i = 0; i < (int)nodes.size(); ++i ) {
|
||||||
Point3D node = nodes[i];
|
Point3D node = nodes[i];
|
||||||
Point3D normal = point_normals[i];
|
Point3D normal = point_normals[i];
|
||||||
|
@ -423,6 +428,7 @@ void TGMatch::split_tile( TGConstruct& c ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0 // UNUSED
|
||||||
// separate area edge segment into components
|
// separate area edge segment into components
|
||||||
cout << " extracting (shared) area edge segments" << endl;
|
cout << " extracting (shared) area edge segments" << endl;
|
||||||
|
|
||||||
|
@ -494,6 +500,10 @@ void TGMatch::split_tile( TGConstruct& c ) {
|
||||||
cout << " " << body_nodes[i] << endl;
|
cout << " " << body_nodes[i] << endl;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SG_LOG(SG_GENERAL, SG_ALERT, "SPLIT TILE COMPLETE " );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -677,6 +687,55 @@ void insert_normal( point_list& normals, Point3D n, int i ) {
|
||||||
normals[i] = n;
|
normals[i] = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Just add nodes and normals to the node list
|
||||||
|
void TGMatch::add_shared_nodes( TGConstruct& c ) {
|
||||||
|
TGNodes* nodes;
|
||||||
|
nodes = c.get_nodes();
|
||||||
|
|
||||||
|
cout << " BEFORE ADDING SHARED NODES: " << nodes->size() << endl;
|
||||||
|
|
||||||
|
if ( sw_flag ) {
|
||||||
|
nodes->unique_add_fixed_elevation( sw_node );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( se_flag ) {
|
||||||
|
nodes->unique_add_fixed_elevation( se_node );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( nw_flag ) {
|
||||||
|
nodes->unique_add_fixed_elevation( nw_node );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ne_flag ) {
|
||||||
|
nodes->unique_add_fixed_elevation( ne_node );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( north_flag ) {
|
||||||
|
for (unsigned int i = 0; i < north_nodes.size(); i++) {
|
||||||
|
nodes->unique_add_fixed_elevation( north_nodes[i] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( south_flag ) {
|
||||||
|
for (unsigned int i = 0; i < south_nodes.size(); i++) {
|
||||||
|
nodes->unique_add_fixed_elevation( south_nodes[i] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( east_flag ) {
|
||||||
|
for (unsigned int i = 0; i < east_nodes.size(); i++) {
|
||||||
|
nodes->unique_add_fixed_elevation( east_nodes[i] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( west_flag ) {
|
||||||
|
for (unsigned int i = 0; i < west_nodes.size(); i++) {
|
||||||
|
nodes->unique_add_fixed_elevation( west_nodes[i] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << " AFTER ADDING SHARED NODES: " << nodes->size() << endl;
|
||||||
|
}
|
||||||
|
|
||||||
// reassemble the tile pieces (combining the shared data and our own
|
// reassemble the tile pieces (combining the shared data and our own
|
||||||
// data)
|
// data)
|
||||||
|
@ -805,6 +864,7 @@ void TGMatch::assemble_tile( TGConstruct& c ) {
|
||||||
TGTriSeg(n1, n2, marker) );
|
TGTriSeg(n1, n2, marker) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0 // UNUSED
|
||||||
c.set_tri_nodes( new_nodes );
|
c.set_tri_nodes( new_nodes );
|
||||||
c.set_point_normals( new_normals );
|
c.set_point_normals( new_normals );
|
||||||
c.set_tri_segs( new_segs );
|
c.set_tri_segs( new_segs );
|
||||||
|
@ -812,5 +872,6 @@ void TGMatch::assemble_tile( TGConstruct& c ) {
|
||||||
cout << "after adding all segments (should be the same):" << endl;
|
cout << "after adding all segments (should be the same):" << endl;
|
||||||
cout << " new_nodes = " << new_nodes.size() << endl;
|
cout << " new_nodes = " << new_nodes.size() << endl;
|
||||||
cout << " new normals = " << new_normals.size() << endl;
|
cout << " new normals = " << new_normals.size() << endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,6 +95,10 @@ public:
|
||||||
// try to find info for the specified shared component
|
// try to find info for the specified shared component
|
||||||
void load_shared( const TGConstruct& c, neighbor_type n );
|
void load_shared( const TGConstruct& c, neighbor_type n );
|
||||||
|
|
||||||
|
// NEW TILE MATCHING - PRE TRIANGULATION
|
||||||
|
// Just add nodes and normals to the node list
|
||||||
|
void add_shared_nodes( TGConstruct& c );
|
||||||
|
|
||||||
// split up the tile between the shared edge points, normals, and
|
// split up the tile between the shared edge points, normals, and
|
||||||
// segments and the body. This must be done after calling
|
// segments and the body. This must be done after calling
|
||||||
// load_neighbor_data() and will ignore any shared data from the
|
// load_neighbor_data() and will ignore any shared data from the
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include <Geometry/poly_support.hxx>
|
#include <Geometry/poly_support.hxx>
|
||||||
#include <Polygon/polygon.hxx>
|
#include <Polygon/polygon.hxx>
|
||||||
|
#include <Polygon/superpoly.hxx>
|
||||||
#include <TriangleJRS/tri_support.h>
|
#include <TriangleJRS/tri_support.h>
|
||||||
|
|
||||||
#include "triangle.hxx"
|
#include "triangle.hxx"
|
||||||
|
@ -75,8 +76,9 @@ TGTriangle::build( const point_list& corner_list,
|
||||||
}
|
}
|
||||||
|
|
||||||
// next process the polygons
|
// next process the polygons
|
||||||
|
TGSuperPoly sp;
|
||||||
TGPolygon gpc_poly;
|
TGPolygon gpc_poly;
|
||||||
const_poly_list_iterator current, last;
|
const_superpoly_list_iterator current, last;
|
||||||
|
|
||||||
// process polygons in priority order
|
// process polygons in priority order
|
||||||
cout << "prepairing node list and polygons" << endl;
|
cout << "prepairing node list and polygons" << endl;
|
||||||
|
@ -84,16 +86,15 @@ TGTriangle::build( const point_list& corner_list,
|
||||||
for ( i = 0; i < TG_MAX_AREA_TYPES; ++i ) {
|
for ( i = 0; i < TG_MAX_AREA_TYPES; ++i ) {
|
||||||
polylist[i].clear();
|
polylist[i].clear();
|
||||||
|
|
||||||
cout << "area type = " << i << " polys = " << gpc_polys.polys[i].size()
|
cout << "area type = " << i << " polys = " << gpc_polys.superpolys[i].size() << endl;
|
||||||
<< endl;
|
|
||||||
debug_counter = 0;
|
debug_counter = 0;
|
||||||
current = gpc_polys.polys[i].begin();
|
current = gpc_polys.superpolys[i].begin();
|
||||||
last = gpc_polys.polys[i].end();
|
last = gpc_polys.superpolys[i].end();
|
||||||
for ( ; current != last; ++current ) {
|
for ( ; current != last; ++current ) {
|
||||||
gpc_poly = *current;
|
sp = *current;
|
||||||
|
gpc_poly = sp.get_poly();
|
||||||
|
|
||||||
cout << "processing a polygon, contours = "
|
// cout << "processing a polygon, contours = " << gpc_poly.contours() << endl;
|
||||||
<< gpc_poly.contours() << endl;
|
|
||||||
|
|
||||||
if (gpc_poly.contours() <= 0 ) {
|
if (gpc_poly.contours() <= 0 ) {
|
||||||
cout << "FATAL ERROR! no contours in this polygon" << endl;
|
cout << "FATAL ERROR! no contours in this polygon" << endl;
|
||||||
|
@ -102,9 +103,7 @@ TGTriangle::build( const point_list& corner_list,
|
||||||
|
|
||||||
int j;
|
int j;
|
||||||
for ( j = 0; j < gpc_poly.contours(); ++j ) {
|
for ( j = 0; j < gpc_poly.contours(); ++j ) {
|
||||||
cout << " processing contour = " << j << ", nodes = "
|
// cout << " processing contour = " << j << ", nodes = " << gpc_poly.contour_size( j ) << ", hole = " << gpc_poly.get_hole_flag( j ) << endl;
|
||||||
<< gpc_poly.contour_size( j ) << ", hole = "
|
|
||||||
<< gpc_poly.get_hole_flag( j ) << endl;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
char junkn[256];
|
char junkn[256];
|
||||||
|
@ -149,8 +148,7 @@ TGTriangle::build( const point_list& corner_list,
|
||||||
gpc_poly = remove_bad_contours( gpc_poly );
|
gpc_poly = remove_bad_contours( gpc_poly );
|
||||||
gpc_poly = remove_cycles( gpc_poly );
|
gpc_poly = remove_cycles( gpc_poly );
|
||||||
|
|
||||||
cout << "after sanity checks, contours = "
|
// cout << "after sanity checks, contours = " << gpc_poly.contours() << endl;
|
||||||
<< gpc_poly.contours() << endl;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
for ( j = 0; j < gpc_poly.contours(); ++j ) {
|
for ( j = 0; j < gpc_poly.contours(); ++j ) {
|
||||||
|
@ -162,9 +160,9 @@ TGTriangle::build( const point_list& corner_list,
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
cout << "before calc_points_inside()" << endl;
|
// cout << "before calc_points_inside()" << endl;
|
||||||
calc_points_inside( gpc_poly );
|
calc_points_inside( gpc_poly );
|
||||||
cout << "after calc_points_inside()" << endl;
|
// cout << "after calc_points_inside()" << endl;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// old way
|
// old way
|
||||||
|
@ -240,8 +238,7 @@ TGTriangle::build( const point_list& corner_list,
|
||||||
// process each polygon in list
|
// process each polygon in list
|
||||||
for ( ; tp_current != tp_last; ++tp_current ) {
|
for ( ; tp_current != tp_last; ++tp_current ) {
|
||||||
poly = *tp_current;
|
poly = *tp_current;
|
||||||
cout << " processing a polygon with contours = "
|
// cout << " processing a polygon with contours = " << poly.contours() << endl;
|
||||||
<< poly.contours() << endl;
|
|
||||||
for ( int j = 0; j < (int)poly.contours(); ++j) {
|
for ( int j = 0; j < (int)poly.contours(); ++j) {
|
||||||
for ( int k = 0; k < (int)(poly.contour_size(j) - 1); ++k ) {
|
for ( int k = 0; k < (int)(poly.contour_size(j) - 1); ++k ) {
|
||||||
p1 = poly.get_pt( j, k );
|
p1 = poly.get_pt( j, k );
|
||||||
|
@ -280,14 +277,15 @@ TGTriangle::build( const point_list& corner_list,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// populate this class based on the specified gpc_polys list
|
// populate this class based on the specified gpc_polys list
|
||||||
int TGTriangle::rebuild( TGConstruct& c ) {
|
int TGTriangle::rebuild( TGConstruct& c ) {
|
||||||
in_nodes.clear();
|
in_nodes.clear();
|
||||||
in_segs.clear();
|
in_segs.clear();
|
||||||
|
|
||||||
|
#if 0
|
||||||
in_nodes = c.get_tri_nodes();
|
in_nodes = c.get_tri_nodes();
|
||||||
in_segs = c.get_tri_segs();
|
in_segs = c.get_tri_segs();
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -307,8 +305,12 @@ int TGTriangle::run_triangulate( double angle, const int pass ) {
|
||||||
int counter;
|
int counter;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
|
|
||||||
// point list
|
// point list
|
||||||
point_list node_list = in_nodes.get_node_list();
|
point_list node_list = in_nodes.get_node_list();
|
||||||
|
|
||||||
|
cout << "TRIANGULATE : NUMBER OF INPUT NODES: " << node_list.size() << endl;
|
||||||
|
|
||||||
in.numberofpoints = node_list.size();
|
in.numberofpoints = node_list.size();
|
||||||
in.pointlist = (REAL *) malloc(in.numberofpoints * 2 * sizeof(REAL));
|
in.pointlist = (REAL *) malloc(in.numberofpoints * 2 * sizeof(REAL));
|
||||||
|
|
||||||
|
@ -465,6 +467,7 @@ int TGTriangle::run_triangulate( double angle, const int pass ) {
|
||||||
// use a quality value of 10 (q10) meaning no interior
|
// use a quality value of 10 (q10) meaning no interior
|
||||||
// triangle angles less than 10 degrees
|
// triangle angles less than 10 degrees
|
||||||
// tri_options = "pczAen";
|
// tri_options = "pczAen";
|
||||||
|
#if 0
|
||||||
if ( angle < 0.00001 ) {
|
if ( angle < 0.00001 ) {
|
||||||
tri_options = "pczAen";
|
tri_options = "pczAen";
|
||||||
} else {
|
} else {
|
||||||
|
@ -474,6 +477,13 @@ int TGTriangle::run_triangulate( double angle, const int pass ) {
|
||||||
tri_options += angle_str;
|
tri_options += angle_str;
|
||||||
tri_options += "Aen";
|
tri_options += "Aen";
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
// TEST TEST TEST : NO ADDING POINTS
|
||||||
|
tri_options = "pzenYYQ";
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
// // string tri_options = "pzAen";
|
// // string tri_options = "pzAen";
|
||||||
// // string tri_options = "pczq15S400Aen";
|
// // string tri_options = "pczq15S400Aen";
|
||||||
} else if ( pass == 2 ) {
|
} else if ( pass == 2 ) {
|
||||||
|
@ -495,6 +505,8 @@ int TGTriangle::run_triangulate( double angle, const int pass ) {
|
||||||
// now copy the results back into the corresponding TGTriangle
|
// now copy the results back into the corresponding TGTriangle
|
||||||
// structures
|
// structures
|
||||||
|
|
||||||
|
cout << "TRIANGULATE : NUMBER OF OUTPUT NODES: " << out.numberofpoints << endl;
|
||||||
|
|
||||||
// nodes
|
// nodes
|
||||||
out_nodes.clear();
|
out_nodes.clear();
|
||||||
for ( i = 0; i < out.numberofpoints; ++i ) {
|
for ( i = 0; i < out.numberofpoints; ++i ) {
|
||||||
|
|
|
@ -8,6 +8,7 @@ add_library(Geometry STATIC
|
||||||
poly_support.cxx
|
poly_support.cxx
|
||||||
poly_extra.cxx
|
poly_extra.cxx
|
||||||
rectangle.cxx
|
rectangle.cxx
|
||||||
|
tg_nodes.cxx
|
||||||
trinodes.cxx
|
trinodes.cxx
|
||||||
trisegs.cxx
|
trisegs.cxx
|
||||||
util.cxx
|
util.cxx
|
||||||
|
@ -17,6 +18,7 @@ add_library(Geometry STATIC
|
||||||
poly_support.hxx
|
poly_support.hxx
|
||||||
poly_extra.hxx
|
poly_extra.hxx
|
||||||
rectangle.hxx
|
rectangle.hxx
|
||||||
|
tg_nodes.hxx
|
||||||
trinodes.hxx
|
trinodes.hxx
|
||||||
trisegs.hxx
|
trisegs.hxx
|
||||||
util.hxx
|
util.hxx
|
||||||
|
|
|
@ -114,4 +114,67 @@ TGPolygon add_nodes_to_poly( const TGPolygon& poly,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Divide segment if there are other existing points on it, return the
|
||||||
|
// new polygon
|
||||||
|
void add_intermediate_tgnodes( int contour, const Point3D& start,
|
||||||
|
const Point3D& end, const TGNodes* nodes,
|
||||||
|
TGPolygon *result )
|
||||||
|
{
|
||||||
|
point_list points = nodes->get_geod_nodes();
|
||||||
|
|
||||||
|
SG_LOG(SG_GENERAL, SG_DEBUG, " add_intermediate_nodes()");
|
||||||
|
char buf[200];
|
||||||
|
snprintf(buf, 199, " %.7f %.7f %.7f <=> %.7f %.7f %.7f\n",
|
||||||
|
start.x(), start.y(), start.z(), end.x(), end.y(), end.z() );
|
||||||
|
SG_LOG(SG_GENERAL, SG_DEBUG, buf);
|
||||||
|
|
||||||
|
Point3D new_pt;
|
||||||
|
bool found_extra = find_intermediate_node( start, end, points, &new_pt );
|
||||||
|
|
||||||
|
if ( found_extra ) {
|
||||||
|
SG_LOG(SG_GENERAL, SG_DEBUG, "dividing " << start << " " << new_pt << " " << end);
|
||||||
|
add_intermediate_tgnodes( contour, start, new_pt, nodes, result );
|
||||||
|
|
||||||
|
result->add_node( contour, new_pt );
|
||||||
|
SG_LOG(SG_GENERAL, SG_INFO, " added = " << new_pt);
|
||||||
|
|
||||||
|
add_intermediate_tgnodes( contour, new_pt, end, nodes, result );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TGPolygon add_tgnodes_to_poly( const TGPolygon& poly,
|
||||||
|
const TGNodes* nodes ) {
|
||||||
|
TGPolygon result; result.erase();
|
||||||
|
Point3D p0, p1;
|
||||||
|
|
||||||
|
SG_LOG(SG_GENERAL, SG_DEBUG, "add_nodes_to_poly");
|
||||||
|
for ( int i = 0; i < poly.contours(); ++i ) {
|
||||||
|
SG_LOG(SG_GENERAL, SG_DEBUG, "contour = " << i);
|
||||||
|
for ( int j = 0; j < poly.contour_size(i) - 1; ++j ) {
|
||||||
|
p0 = poly.get_pt( i, j );
|
||||||
|
p1 = poly.get_pt( i, j + 1 );
|
||||||
|
|
||||||
|
// add start of segment
|
||||||
|
result.add_node( i, p0 );
|
||||||
|
|
||||||
|
// add intermediate points
|
||||||
|
add_intermediate_tgnodes( i, p0, p1, nodes, &result );
|
||||||
|
|
||||||
|
// end of segment is beginning of next segment
|
||||||
|
}
|
||||||
|
p0 = poly.get_pt( i, poly.contour_size(i) - 1 );
|
||||||
|
p1 = poly.get_pt( i, 0 );
|
||||||
|
|
||||||
|
// add start of segment
|
||||||
|
result.add_node( i, p0 );
|
||||||
|
|
||||||
|
// add intermediate points
|
||||||
|
add_intermediate_tgnodes( i, p0, p1, nodes, &result );
|
||||||
|
|
||||||
|
// maintain original hole flag setting
|
||||||
|
result.set_hole_flag( i, poly.get_hole_flag( i ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,8 @@
|
||||||
#include <Geometry/point3d.hxx>
|
#include <Geometry/point3d.hxx>
|
||||||
|
|
||||||
#include <Geometry/trinodes.hxx>
|
#include <Geometry/trinodes.hxx>
|
||||||
|
#include <Geometry/tg_nodes.hxx>
|
||||||
|
|
||||||
#include <Polygon/polygon.hxx>
|
#include <Polygon/polygon.hxx>
|
||||||
|
|
||||||
|
|
||||||
|
@ -46,5 +48,8 @@ void add_intermediate_nodes( int contour, const Point3D& start,
|
||||||
TGPolygon add_nodes_to_poly( const TGPolygon& poly,
|
TGPolygon add_nodes_to_poly( const TGPolygon& poly,
|
||||||
const TGTriNodes& tmp_nodes );
|
const TGTriNodes& tmp_nodes );
|
||||||
|
|
||||||
|
TGPolygon add_tgnodes_to_poly( const TGPolygon& poly,
|
||||||
|
const TGNodes* nodes );
|
||||||
|
|
||||||
|
|
||||||
#endif // _POLY_EXTRA_HXX
|
#endif // _POLY_EXTRA_HXX
|
||||||
|
|
185
src/Lib/Geometry/tg_nodes.cxx
Normal file
185
src/Lib/Geometry/tg_nodes.cxx
Normal file
|
@ -0,0 +1,185 @@
|
||||||
|
#include <simgear/debug/logstream.hxx>
|
||||||
|
|
||||||
|
#include "tg_nodes.hxx"
|
||||||
|
|
||||||
|
// Find the index of the specified point (compair to the same
|
||||||
|
// tolerance as unique_add(). Returns -1 if not found.
|
||||||
|
int TGNodes::find( const Point3D& p ) const {
|
||||||
|
const_node_list_iterator current, last;
|
||||||
|
Point3D pos;
|
||||||
|
int counter = 0;
|
||||||
|
|
||||||
|
// see if point already exists
|
||||||
|
current = tg_node_list.begin();
|
||||||
|
last = tg_node_list.end();
|
||||||
|
for ( ; current != last; ++current ) {
|
||||||
|
pos = current->GetPosition();
|
||||||
|
if ( close_enough_2d(p, pos ) ) {
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
++counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TGNodes::unique_add( const Point3D& p ) {
|
||||||
|
node_list_iterator current, last;
|
||||||
|
int counter = 0;
|
||||||
|
|
||||||
|
// see if point already exists
|
||||||
|
current = tg_node_list.begin();
|
||||||
|
last = tg_node_list.end();
|
||||||
|
|
||||||
|
for ( ; current != last; ++current ) {
|
||||||
|
if ( close_enough_3d(p, (*current).GetPosition() ) ) {
|
||||||
|
// cout << "found an existing match!" << endl;
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
++counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
TGNode node( p );
|
||||||
|
node.SetFixedPosition( false );
|
||||||
|
|
||||||
|
// add to list
|
||||||
|
tg_node_list.push_back( node );
|
||||||
|
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TGNodes::unique_add_fixed_elevation( const Point3D& p ) {
|
||||||
|
node_list_iterator current, last;
|
||||||
|
int counter = 0;
|
||||||
|
|
||||||
|
// see if point already exists
|
||||||
|
current = tg_node_list.begin();
|
||||||
|
last = tg_node_list.end();
|
||||||
|
|
||||||
|
for ( ; current != last; ++current ) {
|
||||||
|
if ( close_enough_3d(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
|
||||||
|
(*current).SetPosition( p );
|
||||||
|
(*current).SetFixedPosition( true );
|
||||||
|
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
++counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
TGNode node( p );
|
||||||
|
node.SetFixedPosition( true );
|
||||||
|
|
||||||
|
// add to list
|
||||||
|
tg_node_list.push_back( node );
|
||||||
|
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
point_list TGNodes::get_geod_nodes( void ) const {
|
||||||
|
point_list points;
|
||||||
|
const_node_list_iterator current, last;
|
||||||
|
|
||||||
|
// see if point already exists
|
||||||
|
current = tg_node_list.begin();
|
||||||
|
last = tg_node_list.end();
|
||||||
|
|
||||||
|
for ( ; current != last; ++current ) {
|
||||||
|
points.push_back( (*current).GetPosition() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector< SGVec3d > TGNodes::get_wgs84_nodes_as_SGVec3d( void ) const {
|
||||||
|
std::vector< SGVec3d > points;
|
||||||
|
Point3D pos;
|
||||||
|
const_node_list_iterator current, last;
|
||||||
|
|
||||||
|
current = tg_node_list.begin();
|
||||||
|
last = tg_node_list.end();
|
||||||
|
|
||||||
|
for ( ; current != last; ++current ) {
|
||||||
|
pos = (*current).GetPosition();
|
||||||
|
|
||||||
|
SGGeod geod = SGGeod::fromDegM( pos.x(), pos.y(), pos.z() );
|
||||||
|
SGVec3d cart = SGVec3d::fromGeod(geod);
|
||||||
|
|
||||||
|
points.push_back( cart );
|
||||||
|
}
|
||||||
|
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
point_list TGNodes::get_wgs84_nodes_as_Point3d( void ) const {
|
||||||
|
point_list points;
|
||||||
|
Point3D pos;
|
||||||
|
const_node_list_iterator current, last;
|
||||||
|
|
||||||
|
current = tg_node_list.begin();
|
||||||
|
last = tg_node_list.end();
|
||||||
|
|
||||||
|
for ( ; current != last; ++current ) {
|
||||||
|
pos = (*current).GetPosition();
|
||||||
|
|
||||||
|
SGGeod geod = SGGeod::fromDegM( pos.x(), pos.y(), pos.z() );
|
||||||
|
SGVec3d cart = SGVec3d::fromGeod(geod);
|
||||||
|
|
||||||
|
points.push_back( Point3D::fromSGVec3( cart ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
node_list TGNodes::get_fixed_elevation_nodes( void ) const {
|
||||||
|
node_list fixed_elev;
|
||||||
|
const_node_list_iterator current, last;
|
||||||
|
|
||||||
|
// see if point already exists
|
||||||
|
current = tg_node_list.begin();
|
||||||
|
last = tg_node_list.end();
|
||||||
|
|
||||||
|
for ( ; current != last; ++current ) {
|
||||||
|
if ( (*current).GetFixedPosition() ) {
|
||||||
|
fixed_elev.push_back( (*current) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fixed_elev;
|
||||||
|
}
|
||||||
|
|
||||||
|
point_list TGNodes::get_normals( void ) const {
|
||||||
|
point_list points;
|
||||||
|
const_node_list_iterator current, last;
|
||||||
|
|
||||||
|
// see if point already exists
|
||||||
|
current = tg_node_list.begin();
|
||||||
|
last = tg_node_list.end();
|
||||||
|
|
||||||
|
for ( ; current != last; ++current ) {
|
||||||
|
points.push_back( (*current).GetNormal() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TGNodes::LookupFixedElevation( Point3D p, double* z )
|
||||||
|
{
|
||||||
|
int index = find( p );
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
if (index >= 0) {
|
||||||
|
TGNode node = tg_node_list[index];
|
||||||
|
if ( node.GetFixedPosition() ) {
|
||||||
|
*z = tg_node_list[index].GetPosition().z();
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
192
src/Lib/Geometry/tg_nodes.hxx
Normal file
192
src/Lib/Geometry/tg_nodes.hxx
Normal file
|
@ -0,0 +1,192 @@
|
||||||
|
#ifndef _TG_NODES_HXX
|
||||||
|
#define _TG_NODES_HXX
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __cplusplus
|
||||||
|
# error This library requires C++
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <simgear/compiler.h>
|
||||||
|
#include <Geometry/point3d.hxx>
|
||||||
|
#include <simgear/math/sg_types.hxx>
|
||||||
|
|
||||||
|
#define FG_PROXIMITY_EPSILON 0.000001
|
||||||
|
#define FG_COURSE_EPSILON 0.0001
|
||||||
|
|
||||||
|
typedef std::vector < unsigned int > TGIdxList;
|
||||||
|
|
||||||
|
class TGNode {
|
||||||
|
public:
|
||||||
|
TGNode( Point3D p ) {
|
||||||
|
position = p;
|
||||||
|
normal = Point3D();
|
||||||
|
|
||||||
|
|
||||||
|
fixed_position = false; // no matter what - don't move x, y, or z (likely a hole around an airport generated ny genapts)
|
||||||
|
fixed_normal = false; // no matter what - don't modify the normal - likely on a normal generated on a shared edge
|
||||||
|
|
||||||
|
faces.clear();
|
||||||
|
neighbors.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void SetFixedPosition( bool fix )
|
||||||
|
{
|
||||||
|
if (!fixed_position) {
|
||||||
|
fixed_position = fix;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool GetFixedPosition( void ) const { return fixed_position; }
|
||||||
|
inline void SetFixedNormal( bool fix ) { fixed_normal = fix; }
|
||||||
|
inline bool GetFixedNormal( void ) const { return fixed_normal; }
|
||||||
|
|
||||||
|
inline void SetPosition( const Point3D& p )
|
||||||
|
{
|
||||||
|
if (!fixed_position) {
|
||||||
|
position = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void SetElevation( double z )
|
||||||
|
{
|
||||||
|
if (!fixed_position) {
|
||||||
|
position.setelev( z );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Point3D GetPosition( void ) const { return position; }
|
||||||
|
inline void SetNormal( const Point3D& n ) { normal = n; }
|
||||||
|
inline Point3D GetNormal( void ) const { return normal; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Point3D position;
|
||||||
|
Point3D normal;
|
||||||
|
|
||||||
|
bool fixed_position;
|
||||||
|
bool fixed_normal;
|
||||||
|
|
||||||
|
TGIdxList faces;
|
||||||
|
TGIdxList neighbors;
|
||||||
|
};
|
||||||
|
typedef std::vector < TGNode > node_list;
|
||||||
|
typedef node_list::iterator node_list_iterator;
|
||||||
|
typedef node_list::const_iterator const_node_list_iterator;
|
||||||
|
|
||||||
|
|
||||||
|
/* This class handles ALL of the nodes in a tile : 3d nodes in elevation data, 2d nodes generated from landclass, etc) */
|
||||||
|
|
||||||
|
class TGNodes {
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Constructor and destructor
|
||||||
|
TGNodes( void ) {}
|
||||||
|
~TGNodes( void ) {}
|
||||||
|
|
||||||
|
// delete all the data out of node_list
|
||||||
|
inline void clear() { tg_node_list.clear(); }
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
int unique_add( const Point3D& p );
|
||||||
|
|
||||||
|
// Add a point to the point list if it doesn't already exist
|
||||||
|
// (checking all three dimensions.) Returns the index (starting
|
||||||
|
// at zero) of the point in the list.
|
||||||
|
int unique_add_fixed_elevation( const Point3D& p );
|
||||||
|
node_list get_fixed_elevation_nodes( void ) const;
|
||||||
|
|
||||||
|
|
||||||
|
// Add the point with no uniqueness checking
|
||||||
|
int simple_add( const Point3D& p );
|
||||||
|
|
||||||
|
// 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
|
||||||
|
// tolerance as unique_add(). Returns -1 if not found.
|
||||||
|
int find( const Point3D& p ) const;
|
||||||
|
|
||||||
|
bool LookupFixedElevation( Point3D p, double* z );
|
||||||
|
void SetElevation( int idx, double z ) { tg_node_list[idx].SetElevation( z ); }
|
||||||
|
|
||||||
|
// return the master node list
|
||||||
|
inline node_list& get_node_list() { return tg_node_list; }
|
||||||
|
inline const node_list& get_node_list() const { return tg_node_list; }
|
||||||
|
|
||||||
|
// return a point list of geodetic nodes
|
||||||
|
point_list get_geod_nodes() const;
|
||||||
|
|
||||||
|
// return a point list of wgs84 nodes
|
||||||
|
std::vector< SGVec3d > get_wgs84_nodes_as_SGVec3d() const;
|
||||||
|
point_list get_wgs84_nodes_as_Point3d() const;
|
||||||
|
|
||||||
|
// return a point list of normals
|
||||||
|
point_list get_normals() const;
|
||||||
|
|
||||||
|
// return the ith point
|
||||||
|
inline TGNode get_node( int i ) const { return tg_node_list[i]; }
|
||||||
|
|
||||||
|
// return the size of the node list
|
||||||
|
inline size_t size() const { return tg_node_list.size(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
node_list tg_node_list;
|
||||||
|
|
||||||
|
// return true of the two points are "close enough" as defined by
|
||||||
|
// FG_PROXIMITY_EPSILON
|
||||||
|
bool close_enough_2d( const Point3D& p1, const Point3D& p2 ) const;
|
||||||
|
|
||||||
|
// return true of the two points are "close enough" as defined by
|
||||||
|
// FG_PROXIMITY_EPSILON
|
||||||
|
bool close_enough_3d( const Point3D& p1, const Point3D& p2 ) const;
|
||||||
|
|
||||||
|
// return true of the two points are "close enough" as defined by
|
||||||
|
// FG_COURSE_EPSILON
|
||||||
|
bool course_close_enough( const Point3D& p1, const Point3D& p2 );
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// return true of the two points are "close enough" as defined by
|
||||||
|
// FG_PROXIMITY_EPSILON checking just x and y dimensions
|
||||||
|
inline bool TGNodes::close_enough_2d( const Point3D& p1, const Point3D& p2 )
|
||||||
|
const
|
||||||
|
{
|
||||||
|
if ( ( fabs(p1.x() - p2.x()) < FG_PROXIMITY_EPSILON ) &&
|
||||||
|
( fabs(p1.y() - p2.y()) < FG_PROXIMITY_EPSILON ) ) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// return true of the two points are "close enough" as defined by
|
||||||
|
// FG_PROXIMITY_EPSILON check all three dimensions
|
||||||
|
inline bool TGNodes::close_enough_3d( const Point3D& p1, const Point3D& p2 )
|
||||||
|
const
|
||||||
|
{
|
||||||
|
if ( ( fabs(p1.x() - p2.x()) < FG_PROXIMITY_EPSILON ) &&
|
||||||
|
( fabs(p1.y() - p2.y()) < FG_PROXIMITY_EPSILON ) &&
|
||||||
|
( fabs(p1.z() - p2.z()) < FG_PROXIMITY_EPSILON ) ) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// return true of the two points are "close enough" as defined by
|
||||||
|
// FG_COURSE_EPSILON
|
||||||
|
inline bool TGNodes::course_close_enough( const Point3D& p1, const Point3D& p2 )
|
||||||
|
{
|
||||||
|
if ( ( fabs(p1.x() - p2.x()) < FG_COURSE_EPSILON ) &&
|
||||||
|
( fabs(p1.y() - p2.y()) < FG_COURSE_EPSILON ) ) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _TG_NODES_HXX
|
Loading…
Reference in a new issue