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>
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::string;
|
||||
|
||||
|
||||
#define MASK_CLIP 1
|
||||
|
||||
|
||||
|
@ -65,9 +62,9 @@ TGClipper::~TGClipper() {
|
|||
// Initialize the clipper (empty all the polygon buckets.)
|
||||
bool TGClipper::init() {
|
||||
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;
|
||||
}
|
||||
|
@ -109,21 +106,19 @@ bool TGClipper::load_polys(const string& path) {
|
|||
poly3d = false;
|
||||
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 );
|
||||
cout << "poly type (int) = " << (int)poly_type << endl;
|
||||
SG_LOG( SG_CLIPPER, SG_INFO, "poly type (int) = " << (int)poly_type);
|
||||
in >> contours;
|
||||
cout << "num contours = " << contours << endl;
|
||||
SG_LOG( SG_CLIPPER, SG_INFO, "num contours = " << contours);
|
||||
|
||||
poly.erase();
|
||||
|
||||
for ( i = 0; i < contours; ++i ) {
|
||||
in >> count;
|
||||
// cout << "Contour = " << i << " size = " << count << endl;
|
||||
|
||||
if ( count < 3 ) {
|
||||
SG_LOG( SG_CLIPPER, SG_ALERT,
|
||||
"Polygon with less than 3 data points." );
|
||||
SG_LOG( SG_CLIPPER, SG_ALERT, "Polygon with less than 3 data points." );
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
@ -138,8 +133,11 @@ bool TGClipper::load_polys(const string& path) {
|
|||
}
|
||||
p = Point3D(startx+nudge, starty+nudge, startz);
|
||||
poly.add_node( i, p );
|
||||
|
||||
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 ) {
|
||||
|
@ -153,7 +151,9 @@ bool TGClipper::load_polys(const string& path) {
|
|||
p = Point3D( x+nudge, y+nudge, z );
|
||||
poly.add_node( i, p );
|
||||
if ( poly3d ) {
|
||||
fixed_elevations.unique_add( p );
|
||||
nodes.unique_add_fixed_elevation( p );
|
||||
} else {
|
||||
nodes.unique_add( p );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -165,25 +165,25 @@ bool TGClipper::load_polys(const string& path) {
|
|||
lastz = -9999.0;
|
||||
}
|
||||
|
||||
if ( (fabs(startx - lastx) < SG_EPSILON)
|
||||
&& (fabs(starty - lasty) < SG_EPSILON)
|
||||
&& (fabs(startz - lastz) < SG_EPSILON) ) {
|
||||
if ( (fabs(startx - lastx) < SG_EPSILON) &&
|
||||
(fabs(starty - lasty) < SG_EPSILON) &&
|
||||
(fabs(startz - lastz) < SG_EPSILON) ) {
|
||||
// last point same as first, discard
|
||||
} else {
|
||||
p = Point3D( lastx+nudge, lasty+nudge, lastz );
|
||||
poly.add_node( i, p );
|
||||
if ( poly3d ) {
|
||||
fixed_elevations.unique_add( p );
|
||||
nodes.unique_add_fixed_elevation( p );
|
||||
} else {
|
||||
nodes.unique_add( p );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int area = (int)poly_type;
|
||||
string material = get_area_name( area );
|
||||
|
||||
add_poly(area, poly);
|
||||
|
||||
// FILE *ofp= fopen("outfile", "w");
|
||||
// gpc_write_polygon(ofp, &polys.landuse);
|
||||
add_poly(area, poly, material);
|
||||
|
||||
in >> skipcomment;
|
||||
}
|
||||
|
@ -195,7 +195,6 @@ bool TGClipper::load_polys(const string& path) {
|
|||
// Load a polygon definition file containing osgb36 Eastings and Northings
|
||||
// and convert them to WGS84 Latitude and Longitude
|
||||
bool TGClipper::load_osgb36_polys(const string& path) {
|
||||
// cout << "Loading osgb36 poly\n";
|
||||
string poly_name;
|
||||
AreaType poly_type;
|
||||
int contours, count, i, j;
|
||||
|
@ -211,9 +210,6 @@ bool TGClipper::load_osgb36_polys(const string& path) {
|
|||
exit(-1);
|
||||
}
|
||||
|
||||
// gpc_polygon *poly = new gpc_polygon;
|
||||
// poly->num_contours = 0;
|
||||
// poly->contour = NULL;
|
||||
TGPolygon poly;
|
||||
|
||||
Point3D p;
|
||||
|
@ -221,11 +217,11 @@ bool TGClipper::load_osgb36_polys(const string& path) {
|
|||
in >> skipcomment;
|
||||
while ( !in.eof() ) {
|
||||
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 );
|
||||
cout << "poly type (int) = " << (int)poly_type << endl;
|
||||
SG_LOG( SG_CLIPPER, SG_INFO, "poly type (int) = " << (int)poly_type);
|
||||
in >> contours;
|
||||
cout << "num contours = " << contours << endl;
|
||||
SG_LOG( SG_CLIPPER, SG_INFO, "num contours = " << contours);
|
||||
|
||||
poly.erase();
|
||||
|
||||
|
@ -233,8 +229,7 @@ bool TGClipper::load_osgb36_polys(const string& path) {
|
|||
in >> count;
|
||||
|
||||
if ( count < 3 ) {
|
||||
SG_LOG( SG_CLIPPER, SG_ALERT,
|
||||
"Polygon with less than 3 data points." );
|
||||
SG_LOG( SG_CLIPPER, SG_ALERT, "Polygon with less than 3 data points." );
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
@ -249,8 +244,9 @@ bool TGClipper::load_osgb36_polys(const string& path) {
|
|||
p = OSGB36ToWGS84(OSRef);
|
||||
|
||||
poly.add_node( i, p );
|
||||
SG_LOG( SG_CLIPPER, SG_BULK, "0 = "
|
||||
<< startx << ", " << starty );
|
||||
nodes.unique_add( p );
|
||||
|
||||
SG_LOG( SG_CLIPPER, SG_BULK, "0 = " << startx << ", " << starty );
|
||||
|
||||
for ( j = 1; j < count - 1; ++j ) {
|
||||
in >> x;
|
||||
|
@ -259,33 +255,30 @@ bool TGClipper::load_osgb36_polys(const string& path) {
|
|||
p = OSGB36ToWGS84(OSRef);
|
||||
|
||||
poly.add_node( i, p );
|
||||
nodes.unique_add( p );
|
||||
SG_LOG( SG_CLIPPER, SG_BULK, j << " = " << x << ", " << y );
|
||||
}
|
||||
|
||||
in >> lastx;
|
||||
in >> lasty;
|
||||
|
||||
if ( (fabs(startx - lastx) < SG_EPSILON)
|
||||
&& (fabs(starty - lasty) < SG_EPSILON) ) {
|
||||
if ( (fabs(startx - lastx) < SG_EPSILON) &&
|
||||
(fabs(starty - lasty) < SG_EPSILON) ) {
|
||||
// last point same as first, discard
|
||||
} else {
|
||||
OSRef = Point3D( lastx, lasty, -9999.0 );
|
||||
p = OSGB36ToWGS84(OSRef);
|
||||
|
||||
poly.add_node( i, p );
|
||||
SG_LOG( SG_CLIPPER, SG_BULK, count - 1 << " = "
|
||||
<< lastx << ", " << lasty );
|
||||
nodes.unique_add( p );
|
||||
SG_LOG( SG_CLIPPER, SG_BULK, count - 1 << " = " << lastx << ", " << lasty );
|
||||
}
|
||||
|
||||
// gpc_add_contour( poly, &v_list, hole_flag );
|
||||
}
|
||||
|
||||
int area = (int)poly_type;
|
||||
string material = get_area_name( area );
|
||||
|
||||
add_poly( area, poly);
|
||||
|
||||
// FILE *ofp= fopen("outfile", "w");
|
||||
// gpc_write_polygon(ofp, &polys.landuse);
|
||||
add_poly(area, poly, material);
|
||||
|
||||
in >> skipcomment;
|
||||
}
|
||||
|
@ -294,13 +287,17 @@ bool TGClipper::load_osgb36_polys(const string& path) {
|
|||
}
|
||||
|
||||
// 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 ) {
|
||||
polys_in.polys[area].push_back(poly);
|
||||
sp.set_poly( poly );
|
||||
sp.set_material( material );
|
||||
|
||||
polys_in.superpolys[area].push_back(sp);
|
||||
} else {
|
||||
SG_LOG( SG_CLIPPER, SG_ALERT, "Polygon type out of range = "
|
||||
<< area);
|
||||
SG_LOG( SG_CLIPPER, SG_ALERT, "Polygon type out of range = " << area);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
@ -310,9 +307,6 @@ void TGClipper::add_poly( int area, const TGPolygon &poly )
|
|||
void TGClipper::move_slivers( TGPolygon& in, TGPolygon& out ) {
|
||||
// traverse each contour of the polygon and attempt to identify
|
||||
// likely slivers
|
||||
|
||||
// cout << "Begin move slivers" << endl;
|
||||
|
||||
int i;
|
||||
|
||||
out.erase();
|
||||
|
@ -328,20 +322,11 @@ void TGClipper::move_slivers( TGPolygon& in, TGPolygon& out ) {
|
|||
// process contours in reverse order so deleting a contour doesn't
|
||||
// foul up our sequence
|
||||
for ( i = in.contours() - 1; i >= 0; --i ) {
|
||||
// cout << "contour " << i << endl;
|
||||
|
||||
min_angle = in.minangle_contour( i );
|
||||
area = in.area_contour( i );
|
||||
|
||||
/* cout << " min_angle (rad) = "
|
||||
<< min_angle << endl;
|
||||
cout << " min_angle (deg) = "
|
||||
<< min_angle * 180.0 / SGD_PI << endl;
|
||||
cout << " area = " << area << endl; */
|
||||
|
||||
if ( ((min_angle < angle_cutoff) && (area < area_cutoff)) ||
|
||||
( area < area_cutoff / 10.0) )
|
||||
{
|
||||
( area < area_cutoff / 10.0) ) {
|
||||
// cout << " WE THINK IT'S A SLIVER!" << endl;
|
||||
|
||||
// check if this is a hole
|
||||
|
@ -373,7 +358,7 @@ void TGClipper::merge_slivers( TGPolyList& clipped, TGPolygon& slivers ) {
|
|||
point_list contour;
|
||||
int original_contours, result_contours;
|
||||
bool done;
|
||||
int area, i, j, k;
|
||||
int area, i, j;
|
||||
|
||||
for ( i = 0; i < slivers.contours(); ++i ) {
|
||||
// cout << "Merging sliver = " << i << endl;
|
||||
|
@ -393,39 +378,21 @@ void TGClipper::merge_slivers( TGPolyList& clipped, TGPolygon& slivers ) {
|
|||
|
||||
// cout << " testing area = " << area << " with "
|
||||
// << clipped.polys[area].size() << " polys" << endl;
|
||||
for ( j = 0;
|
||||
j < (int)clipped.polys[area].size() && !done;
|
||||
++j )
|
||||
{
|
||||
for ( j = 0; j < (int)clipped.superpolys[area].size() && !done; ++j ) {
|
||||
// cout << " polygon = " << j << endl;
|
||||
|
||||
poly = clipped.polys[area][j];
|
||||
poly = clipped.superpolys[area][j].get_poly();
|
||||
original_contours = poly.contours();
|
||||
result = tgPolygonUnion( poly, sliver );
|
||||
result_contours = result.contours();
|
||||
|
||||
if ( original_contours == result_contours ) {
|
||||
// cout << " FOUND a poly to merge the sliver with" << endl;
|
||||
clipped.polys[area][j] = result;
|
||||
clipped.superpolys[area][j].set_poly( 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 slivers, remains;
|
||||
int i, j;
|
||||
|
||||
// gpcpoly_iterator current, last;
|
||||
Point3D p;
|
||||
|
||||
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();
|
||||
|
||||
cout << " (" << min.x << "," << min.y << ") ("
|
||||
<< max.x << "," << max.y << ")" << endl;
|
||||
|
||||
// set up clipping tile
|
||||
// set up clipping tile : and remember to add the nodes!
|
||||
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) );
|
||||
polys_in.safety_base.add_node( 0, Point3D(max.x, max.y, -9999.0) );
|
||||
polys_in.safety_base.add_node( 0, Point3D(min.x, max.y, -9999.0) );
|
||||
|
||||
p = Point3D(min.x, min.y, -9999.0);
|
||||
polys_in.safety_base.add_node( 0, p );
|
||||
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
|
||||
// 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();
|
||||
for ( i = 0; i < TG_MAX_AREA_TYPES; i++ ) {
|
||||
if ( is_landmass_area( i ) && !m_ignore_landmass ) {
|
||||
for ( unsigned j = 0; j < (int)polys_in.polys[i].size(); ++j ) {
|
||||
land_mask =
|
||||
tgPolygonUnion( land_mask, polys_in.polys[i][j] );
|
||||
for ( unsigned int j = 0; j < polys_in.superpolys[i].size(); ++j ) {
|
||||
land_mask = tgPolygonUnion( land_mask, polys_in.superpolys[i][j].get_poly() );
|
||||
}
|
||||
} else if ( is_water_area( i ) ) {
|
||||
for (unsigned int j = 0; j < polys_in.polys[i].size(); j++) {
|
||||
water_mask =
|
||||
tgPolygonUnion( water_mask, polys_in.polys[i][j] );
|
||||
for (unsigned int j = 0; j < polys_in.superpolys[i].size(); j++) {
|
||||
water_mask = tgPolygonUnion( water_mask, polys_in.superpolys[i][j].get_poly() );
|
||||
}
|
||||
} else if ( is_island_area( i ) ) {
|
||||
for (unsigned int j = 0; j < polys_in.polys[i].size(); j++) {
|
||||
island_mask =
|
||||
tgPolygonUnion( island_mask, polys_in.polys[i][j] );
|
||||
for (unsigned int j = 0; j < polys_in.superpolys[i].size(); j++) {
|
||||
island_mask = tgPolygonUnion( island_mask, polys_in.superpolys[i][j].get_poly() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// process polygons in priority order
|
||||
for ( i = 0; i < TG_MAX_AREA_TYPES; ++i ) {
|
||||
cout << "num polys of type (" << i << ") = "
|
||||
<< polys_in.polys[i].size() << endl;
|
||||
for( j = 0; j < (int)polys_in.polys[i].size(); ++j ) {
|
||||
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, "num polys of type (" << i << ") = " << polys_in.superpolys[i].size() );
|
||||
for( j = 0; j < (int)polys_in.superpolys[i].size(); ++j ) {
|
||||
TGPolygon current = polys_in.superpolys[i][j].get_poly();
|
||||
SG_LOG( SG_CLIPPER, SG_INFO, get_area_name( (AreaType)i ) << " = " << current.contours() );
|
||||
|
||||
tmp = current;
|
||||
|
||||
|
@ -545,14 +516,12 @@ bool TGClipper::clip_all(const point2d& min, const point2d& max) {
|
|||
// add the sliverless result polygon (from after the
|
||||
// move_slivers) to the clipped polys list
|
||||
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;
|
||||
// cout << "Writing clipped polygon to next-result" << count
|
||||
// << endl;
|
||||
// char filename[256];
|
||||
// sprintf(filename, "next-result-%02d-%02d", i, count++);
|
||||
// result_diff.write(filename);
|
||||
sp.set_material( material );
|
||||
sp.set_poly( result_diff );
|
||||
polys_clipped.superpolys[i].push_back( sp );
|
||||
}
|
||||
}
|
||||
accum = result_union;
|
||||
|
@ -582,31 +551,17 @@ bool TGClipper::clip_all(const point2d& min, const point2d& max) {
|
|||
}
|
||||
|
||||
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());
|
||||
|
||||
#if 0
|
||||
FILE *ofp;
|
||||
sp.set_material( material );
|
||||
sp.set_poly( remains );
|
||||
|
||||
// tmp output accum
|
||||
if ( accum.num_contours ) {
|
||||
ofp = fopen("accum", "w");
|
||||
gpc_write_polygon(ofp, 1, &accum);
|
||||
fclose(ofp);
|
||||
polys_clipped.superpolys[(int)get_sliver_target_area_type()].push_back(sp);
|
||||
}
|
||||
|
||||
// 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." );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -35,8 +35,10 @@
|
|||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <Geometry/trinodes.hxx>
|
||||
#include <Polygon/polygon.hxx>
|
||||
//#include <Geometry/trinodes.hxx>
|
||||
#include <Geometry/tg_nodes.hxx>
|
||||
#include <Polygon/superpoly.hxx>
|
||||
#include <Polygon/texparams.hxx>
|
||||
#include <Polygon/point2d.hxx>
|
||||
|
||||
#include <string>
|
||||
|
@ -49,18 +51,21 @@
|
|||
class TGPolyList
|
||||
{
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class TGClipper
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
TGPolyList polys_in, polys_clipped;
|
||||
TGTriNodes fixed_elevations;
|
||||
//TGTriNodes fixed_elevations;
|
||||
TGNodes nodes;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -80,7 +85,7 @@ public:
|
|||
bool load_osgb36_polys(const std::string& path);
|
||||
|
||||
// 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
|
||||
// polygon.
|
||||
|
@ -99,7 +104,9 @@ public:
|
|||
inline TGPolyList get_polys_clipped() const { return polys_clipped; }
|
||||
|
||||
// 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;
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <simgear/io/sg_binobj.hxx>
|
||||
#include <simgear/math/SGGeometry.hxx>
|
||||
#include <simgear/misc/texcoord.hxx>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
#include <Output/output.hxx>
|
||||
#include <Clipper/priorities.hxx>
|
||||
|
@ -49,7 +50,7 @@ void TGGenOutput::calc_gbs( TGConstruct& c ) {
|
|||
gbs_center = SGVec3d::fromGeod( c.get_bucket().get_center() );
|
||||
|
||||
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());
|
||||
if ( dist_squared > radius_squared ) {
|
||||
radius_squared = dist_squared;
|
||||
|
@ -58,126 +59,44 @@ void TGGenOutput::calc_gbs( TGConstruct& c ) {
|
|||
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
|
||||
// data
|
||||
int TGGenOutput::build( TGConstruct& c ) {
|
||||
int i, j, k;
|
||||
int TGGenOutput::build_fans( TGConstruct& c ) {
|
||||
// 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
|
||||
geod_nodes = trinodes.get_node_list();
|
||||
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;
|
||||
|
||||
TGGenFans f;
|
||||
for ( i = 0; i < TG_MAX_AREA_TYPES; ++i ) {
|
||||
|
||||
// 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 ( (int)t_current->get_attribute() == i ) {
|
||||
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;
|
||||
fans[i] = f.greedy_build( area_tris );
|
||||
primitives[i] = f.greedy_build( area_tris );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -187,16 +106,16 @@ int TGGenOutput::build( TGConstruct& c ) {
|
|||
cout << "c.get_useUKGrid() = " << c.get_useUKGrid() << endl;
|
||||
tex_coords.clear();
|
||||
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];
|
||||
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;
|
||||
for ( j = 0; j < (int)fans[i].size(); ++j ) {
|
||||
// int_list t_list = calc_tex_coords( c, geod_nodes, fans[i][j] );
|
||||
// cout << fans[i][j].size() << " === "
|
||||
// << t_list.size() << 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;
|
||||
|
||||
|
@ -205,19 +124,20 @@ int TGGenOutput::build( TGConstruct& c ) {
|
|||
|
||||
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, fans[i][j], 1.0 );
|
||||
for ( k = 0; k < (int)tp_list.size(); ++k ) {
|
||||
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, fans[i][j] );
|
||||
for ( k = 0; k < (int)tp_list.size(); ++k ) {
|
||||
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 ) );
|
||||
|
@ -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
|
||||
void TGGenOutput::calc_group_bounding_sphere( TGConstruct& c,
|
||||
const opt_list& fans,
|
||||
const opt_list& primitives,
|
||||
Point3D *center, double *radius )
|
||||
{
|
||||
cout << "calculate group bounding sphere for " << fans.size() << " fans."
|
||||
<< endl;
|
||||
cout << "calculate group bounding sphere for " << primitives.size() << " primitives." << endl;
|
||||
|
||||
point_list wgs84_nodes = c.get_wgs84_nodes();
|
||||
|
||||
// generate a list of unique points from the triangle list
|
||||
TGTriNodes nodes;
|
||||
|
||||
const_opt_list_iterator f_current = fans.begin();
|
||||
const_opt_list_iterator f_last = fans.end();
|
||||
const_opt_list_iterator f_current = primitives.begin();
|
||||
const_opt_list_iterator f_last = primitives.end();
|
||||
for ( ; f_current != f_last; ++f_current ) {
|
||||
const_int_list_iterator i_current = f_current->begin();
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
// 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;
|
||||
|
||||
// write out the fgfs scenery file (using fans)
|
||||
int TGGenOutput::write_fans( TGConstruct &c ) {
|
||||
// Assemble all the data into the final format
|
||||
|
||||
SGBucket b = c.get_bucket();
|
||||
|
@ -457,12 +366,12 @@ int TGGenOutput::write( TGConstruct &c ) {
|
|||
name += ".btg";
|
||||
|
||||
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];
|
||||
wgs84_nodes.push_back( node.toSGVec3d() );
|
||||
}
|
||||
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];
|
||||
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());
|
||||
} */
|
||||
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];
|
||||
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;
|
||||
fans_v.clear(); fans_tc.clear(); fan_materials.clear();
|
||||
|
||||
for ( i = 0; i < TG_MAX_AREA_TYPES; ++i ) {
|
||||
if ( (int)fans[i].size() > 0 ) {
|
||||
cout << "creating " << fans[i].size() << " fans of type "
|
||||
<< i << endl;
|
||||
for ( unsigned int i = 0; i < TG_MAX_AREA_TYPES; ++i ) {
|
||||
if ( primitives[i].size() > 0 ) {
|
||||
cout << "creating " << primitives[i].size() << " fans of type " << i << endl;
|
||||
string attr_name = get_area_name( (AreaType)i );
|
||||
|
||||
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();
|
||||
for ( int k = 0; k < (int)fans[i][j].size(); ++k ) {
|
||||
vs.push_back( fans[i][j][k] );
|
||||
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] );
|
||||
}
|
||||
fans_v.push_back( vs );
|
||||
|
@ -529,4 +437,83 @@ int TGGenOutput::write( TGConstruct &c ) {
|
|||
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
|
||||
TGTriNodes tex_coords;
|
||||
|
||||
// fan list
|
||||
opt_list fans[TG_MAX_AREA_TYPES];
|
||||
// fan / triangle list
|
||||
opt_list primitives[TG_MAX_AREA_TYPES];
|
||||
|
||||
// textures pointer list
|
||||
tex_list textures[TG_MAX_AREA_TYPES];
|
||||
|
@ -93,10 +93,12 @@ public:
|
|||
|
||||
// build the necessary output structures based on the
|
||||
// triangulation data
|
||||
int build( TGConstruct& c );
|
||||
int build_fans( TGConstruct& c );
|
||||
int build_tris( TGConstruct& c );
|
||||
|
||||
// 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
|
||||
// pre-specified)
|
||||
TGTriNodes fixed_elevations;
|
||||
node_list fixed_elevations;
|
||||
|
||||
// raw node list (after triangulation)
|
||||
TGTriNodes tri_nodes;
|
||||
TGNodes nodes;
|
||||
|
||||
// node list in geodetic coords (with fixed elevation)
|
||||
point_list geod_nodes;
|
||||
|
@ -115,10 +116,6 @@ private:
|
|||
// face normal list (for flat shading)
|
||||
point_list face_normals;
|
||||
|
||||
// normal list (for each point) in cart coords (for smooth
|
||||
// shading)
|
||||
point_list point_normals;
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
|
@ -167,33 +164,32 @@ public:
|
|||
inline TGPolyList get_clipped_polys() const { return clipped_polys; }
|
||||
inline void set_clipped_polys( TGPolyList p ) { clipped_polys = p; }
|
||||
|
||||
// Fixed elevations (from polygon input data with z values
|
||||
// pre-specified)
|
||||
inline TGTriNodes get_fixed_elevations() const { return fixed_elevations; }
|
||||
inline void set_fixed_elevations( TGTriNodes n ) { fixed_elevations = n; }
|
||||
// Fixed elevations (from polygon input data with z values pre-specified)
|
||||
inline node_list get_fixed_elevations() const { return nodes.get_fixed_elevation_nodes(); }
|
||||
|
||||
// node list (after triangulation)
|
||||
inline TGTriNodes get_tri_nodes() const { return tri_nodes; }
|
||||
inline void set_tri_nodes( TGTriNodes n ) { tri_nodes = n; }
|
||||
// node list (after triangulation) : No need - we won't add nodes....
|
||||
// inline TGTriNodes get_tri_nodes() const { return tri_nodes; }
|
||||
// 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 void set_tri_elements( triele_list e ) { tri_elements = e; }
|
||||
inline void set_tri_attribute( int num, AreaType a ) {
|
||||
tri_elements[num].set_attribute( a );
|
||||
}
|
||||
inline void set_tri_attribute( int num, AreaType 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 void set_tri_segs( TGTriSegments s ) { tri_segs = s; }
|
||||
|
||||
// node list in geodetic coords (with fixed elevation)
|
||||
inline point_list get_geod_nodes() const { return geod_nodes; }
|
||||
inline void set_geod_nodes( point_list n ) { geod_nodes = n; }
|
||||
inline point_list get_geod_nodes() const { return nodes.get_geod_nodes(); }
|
||||
// inline void set_geod_nodes( point_list n ) { geod_nodes = n; }
|
||||
|
||||
// node list in cartesian coords (wgs84 model)
|
||||
inline point_list get_wgs84_nodes() const { return wgs84_nodes; }
|
||||
inline void set_wgs84_nodes( point_list n ) { wgs84_nodes = n; }
|
||||
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; }
|
||||
|
||||
// for each node, a list of triangle indices that contain this node
|
||||
inline belongs_to_list get_reverse_ele_lookup() const {
|
||||
|
@ -209,8 +205,7 @@ public:
|
|||
|
||||
// normal list (for each point) in cart coords (for smooth
|
||||
// shading)
|
||||
inline point_list get_point_normals() const { return point_normals; }
|
||||
inline void set_point_normals( point_list n ) { point_normals = n; }
|
||||
inline point_list get_point_normals() const { return nodes.get_normals(); }
|
||||
};
|
||||
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -27,9 +27,11 @@
|
|||
|
||||
#include <simgear/compiler.h>
|
||||
#include <Geometry/point3d.hxx>
|
||||
#include <Geometry/tg_nodes.hxx>
|
||||
#include <simgear/math/sg_geodesy.hxx>
|
||||
#include <simgear/misc/sgstream.hxx>
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
#include "match.hxx"
|
||||
|
||||
|
@ -369,6 +371,9 @@ void TGMatch::split_tile( TGConstruct& c ) {
|
|||
point_list nodes = c.get_geod_nodes();
|
||||
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 ) {
|
||||
Point3D node = nodes[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
|
||||
cout << " extracting (shared) area edge segments" << endl;
|
||||
|
||||
|
@ -494,6 +500,10 @@ void TGMatch::split_tile( TGConstruct& c ) {
|
|||
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;
|
||||
}
|
||||
|
||||
// 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
|
||||
// data)
|
||||
|
@ -805,6 +864,7 @@ void TGMatch::assemble_tile( TGConstruct& c ) {
|
|||
TGTriSeg(n1, n2, marker) );
|
||||
}
|
||||
|
||||
#if 0 // UNUSED
|
||||
c.set_tri_nodes( new_nodes );
|
||||
c.set_point_normals( new_normals );
|
||||
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 << " new_nodes = " << new_nodes.size() << endl;
|
||||
cout << " new normals = " << new_normals.size() << endl;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
|
|
@ -95,6 +95,10 @@ public:
|
|||
// try to find info for the specified shared component
|
||||
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
|
||||
// segments and the body. This must be done after calling
|
||||
// load_neighbor_data() and will ignore any shared data from the
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include <Geometry/poly_support.hxx>
|
||||
#include <Polygon/polygon.hxx>
|
||||
#include <Polygon/superpoly.hxx>
|
||||
#include <TriangleJRS/tri_support.h>
|
||||
|
||||
#include "triangle.hxx"
|
||||
|
@ -75,8 +76,9 @@ TGTriangle::build( const point_list& corner_list,
|
|||
}
|
||||
|
||||
// next process the polygons
|
||||
TGSuperPoly sp;
|
||||
TGPolygon gpc_poly;
|
||||
const_poly_list_iterator current, last;
|
||||
const_superpoly_list_iterator current, last;
|
||||
|
||||
// process polygons in priority order
|
||||
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 ) {
|
||||
polylist[i].clear();
|
||||
|
||||
cout << "area type = " << i << " polys = " << gpc_polys.polys[i].size()
|
||||
<< endl;
|
||||
cout << "area type = " << i << " polys = " << gpc_polys.superpolys[i].size() << endl;
|
||||
debug_counter = 0;
|
||||
current = gpc_polys.polys[i].begin();
|
||||
last = gpc_polys.polys[i].end();
|
||||
current = gpc_polys.superpolys[i].begin();
|
||||
last = gpc_polys.superpolys[i].end();
|
||||
for ( ; current != last; ++current ) {
|
||||
gpc_poly = *current;
|
||||
sp = *current;
|
||||
gpc_poly = sp.get_poly();
|
||||
|
||||
cout << "processing a polygon, contours = "
|
||||
<< gpc_poly.contours() << endl;
|
||||
// cout << "processing a polygon, contours = " << gpc_poly.contours() << endl;
|
||||
|
||||
if (gpc_poly.contours() <= 0 ) {
|
||||
cout << "FATAL ERROR! no contours in this polygon" << endl;
|
||||
|
@ -102,9 +103,7 @@ TGTriangle::build( const point_list& corner_list,
|
|||
|
||||
int j;
|
||||
for ( j = 0; j < gpc_poly.contours(); ++j ) {
|
||||
cout << " processing contour = " << j << ", nodes = "
|
||||
<< gpc_poly.contour_size( j ) << ", hole = "
|
||||
<< gpc_poly.get_hole_flag( j ) << endl;
|
||||
// cout << " processing contour = " << j << ", nodes = " << gpc_poly.contour_size( j ) << ", hole = " << gpc_poly.get_hole_flag( j ) << endl;
|
||||
|
||||
/*
|
||||
char junkn[256];
|
||||
|
@ -149,8 +148,7 @@ TGTriangle::build( const point_list& corner_list,
|
|||
gpc_poly = remove_bad_contours( gpc_poly );
|
||||
gpc_poly = remove_cycles( gpc_poly );
|
||||
|
||||
cout << "after sanity checks, contours = "
|
||||
<< gpc_poly.contours() << endl;
|
||||
// cout << "after sanity checks, contours = " << gpc_poly.contours() << endl;
|
||||
|
||||
/*
|
||||
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 );
|
||||
cout << "after calc_points_inside()" << endl;
|
||||
// cout << "after calc_points_inside()" << endl;
|
||||
|
||||
#if 0
|
||||
// old way
|
||||
|
@ -240,8 +238,7 @@ TGTriangle::build( const point_list& corner_list,
|
|||
// process each polygon in list
|
||||
for ( ; tp_current != tp_last; ++tp_current ) {
|
||||
poly = *tp_current;
|
||||
cout << " processing a polygon with contours = "
|
||||
<< poly.contours() << endl;
|
||||
// cout << " processing a polygon with contours = " << poly.contours() << endl;
|
||||
for ( int j = 0; j < (int)poly.contours(); ++j) {
|
||||
for ( int k = 0; k < (int)(poly.contour_size(j) - 1); ++k ) {
|
||||
p1 = poly.get_pt( j, k );
|
||||
|
@ -280,14 +277,15 @@ TGTriangle::build( const point_list& corner_list,
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// populate this class based on the specified gpc_polys list
|
||||
int TGTriangle::rebuild( TGConstruct& c ) {
|
||||
in_nodes.clear();
|
||||
in_segs.clear();
|
||||
|
||||
#if 0
|
||||
in_nodes = c.get_tri_nodes();
|
||||
in_segs = c.get_tri_segs();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -307,8 +305,12 @@ int TGTriangle::run_triangulate( double angle, const int pass ) {
|
|||
int counter;
|
||||
int i, j;
|
||||
|
||||
|
||||
// point 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.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
|
||||
// triangle angles less than 10 degrees
|
||||
// tri_options = "pczAen";
|
||||
#if 0
|
||||
if ( angle < 0.00001 ) {
|
||||
tri_options = "pczAen";
|
||||
} else {
|
||||
|
@ -474,6 +477,13 @@ int TGTriangle::run_triangulate( double angle, const int pass ) {
|
|||
tri_options += angle_str;
|
||||
tri_options += "Aen";
|
||||
}
|
||||
#else
|
||||
|
||||
// TEST TEST TEST : NO ADDING POINTS
|
||||
tri_options = "pzenYYQ";
|
||||
|
||||
#endif
|
||||
|
||||
// // string tri_options = "pzAen";
|
||||
// // string tri_options = "pczq15S400Aen";
|
||||
} 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
|
||||
// structures
|
||||
|
||||
cout << "TRIANGULATE : NUMBER OF OUTPUT NODES: " << out.numberofpoints << endl;
|
||||
|
||||
// nodes
|
||||
out_nodes.clear();
|
||||
for ( i = 0; i < out.numberofpoints; ++i ) {
|
||||
|
|
|
@ -8,6 +8,7 @@ add_library(Geometry STATIC
|
|||
poly_support.cxx
|
||||
poly_extra.cxx
|
||||
rectangle.cxx
|
||||
tg_nodes.cxx
|
||||
trinodes.cxx
|
||||
trisegs.cxx
|
||||
util.cxx
|
||||
|
@ -17,6 +18,7 @@ add_library(Geometry STATIC
|
|||
poly_support.hxx
|
||||
poly_extra.hxx
|
||||
rectangle.hxx
|
||||
tg_nodes.hxx
|
||||
trinodes.hxx
|
||||
trisegs.hxx
|
||||
util.hxx
|
||||
|
|
|
@ -114,4 +114,67 @@ TGPolygon add_nodes_to_poly( const TGPolygon& poly,
|
|||
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/trinodes.hxx>
|
||||
#include <Geometry/tg_nodes.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,
|
||||
const TGTriNodes& tmp_nodes );
|
||||
|
||||
TGPolygon add_tgnodes_to_poly( const TGPolygon& poly,
|
||||
const TGNodes* nodes );
|
||||
|
||||
|
||||
#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