- Point nodes are now generated. Testing Madeira with tranisition shader enbled shows rocky cliffs, so I think thy are correct.
- some small optimizations made by storing triangle nodes in addition to triangle coordinates in TGSuperpoly. More can be done, here. - Brute force methos of generating alist of faces for each nodes that the face has is completely brute force. Looking at original method, I think I can make it work, which should be a significant speedup.
This commit is contained in:
parent
80ac1b38f5
commit
30573aa811
5 changed files with 513 additions and 144 deletions
|
@ -587,7 +587,7 @@ void TGConstruct::add_intermediate_nodes( ) {
|
|||
after = current.total_size();
|
||||
|
||||
if (before != after) {
|
||||
SG_LOG( SG_CLIPPER, SG_INFO, "Fixed t-juntions in " << get_area_name( (AreaType)i ) << ":" << j+1 << " of " << (int)polys_clipped.superpolys[i].size() << " nodes increased from " << before << " to " << after );
|
||||
SG_LOG( SG_CLIPPER, SG_INFO, "Fixed t-junctions in " << get_area_name( (AreaType)i ) << ":" << j+1 << " of " << (int)polys_clipped.superpolys[i].size() << " nodes increased from " << before << " to " << after );
|
||||
}
|
||||
|
||||
/* Save it back */
|
||||
|
@ -626,7 +626,8 @@ double TGConstruct::distanceSphere( const Point3D p1, const Point3D p2 ) {
|
|||
// hopefully, this will get better when we have the area lookup via superpoly...
|
||||
void TGConstruct::fix_point_heights()
|
||||
{
|
||||
TGPolygon tri_poly;
|
||||
//TGPolygon tri_poly;
|
||||
TGPolyNodes tri_nodes;
|
||||
double e1, e2, e3, min;
|
||||
int n1, n2, n3;
|
||||
Point3D p;
|
||||
|
@ -649,22 +650,27 @@ void TGConstruct::fix_point_heights()
|
|||
for (int j = 0; j < (int)polys_clipped.superpolys[i].size(); ++j ) {
|
||||
SG_LOG( SG_CLIPPER, SG_INFO, "Flattening " << get_area_name( (AreaType)i ) << ":" << j+1 << " of " << (int)polys_clipped.superpolys[i].size() );
|
||||
|
||||
tri_poly.erase();
|
||||
tri_poly = polys_clipped.superpolys[i][j].get_tris();
|
||||
// tri_poly = polys_clipped.superpolys[i][j].get_tris();
|
||||
tri_nodes = polys_clipped.superpolys[i][j].get_tri_idxs();
|
||||
|
||||
for (int k=0; k< tri_poly.contours(); k++) {
|
||||
if (tri_poly.contour_size(k) != 3) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "triangle doesnt have 3 nodes" << tri_poly.contour_size(k) );
|
||||
// for (int k=0; k< tri_poly.contours(); k++) {
|
||||
for (int k=0; k< tri_nodes.contours(); k++) {
|
||||
// if (tri_poly.contour_size(k) != 3) {
|
||||
if (tri_nodes.contour_size(k) != 3) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "triangle doesnt have 3 nodes" << tri_nodes.contour_size(k) );
|
||||
exit(0);
|
||||
}
|
||||
|
||||
n1 = nodes.find( tri_poly.get_pt( k, 0 ) );
|
||||
// n1 = nodes.find( tri_poly.get_pt( k, 0 ) );
|
||||
n1 = tri_nodes.get_pt( k, 0 );
|
||||
e1 = nodes.get_node(n1).GetPosition().z();
|
||||
|
||||
n2 = nodes.find( tri_poly.get_pt( k, 1 ) );
|
||||
// n2 = nodes.find( tri_poly.get_pt( k, 1 ) );
|
||||
n2 = tri_nodes.get_pt( k, 1 );
|
||||
e2 = nodes.get_node(n2).GetPosition().z();
|
||||
|
||||
n3 = nodes.find( tri_poly.get_pt( k, 2 ) );
|
||||
// n3 = nodes.find( tri_poly.get_pt( k, 2 ) );
|
||||
n3 = tri_nodes.get_pt( k, 2 );
|
||||
e3 = nodes.get_node(n3).GetPosition().z();
|
||||
|
||||
min = e1;
|
||||
|
@ -688,22 +694,29 @@ void TGConstruct::fix_point_heights()
|
|||
for (int j = 0; j < (int)polys_clipped.superpolys[i].size(); ++j ) {
|
||||
SG_LOG( SG_CLIPPER, SG_INFO, "Flattening " << get_area_name( (AreaType)i ) << ":" << j+1 << " of " << (int)polys_clipped.superpolys[i].size() );
|
||||
|
||||
TGPolygon tri_poly = polys_clipped.superpolys[i][j].get_tris();
|
||||
for (int k=0; k< tri_poly.contours(); k++) {
|
||||
if (tri_poly.contour_size(k) != 3) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "triangle doesnt have 3 nodes" << tri_poly.contour_size(k) );
|
||||
// tri_poly = polys_clipped.superpolys[i][j].get_tris();
|
||||
tri_nodes = polys_clipped.superpolys[i][j].get_tri_idxs();
|
||||
|
||||
// for (int k=0; k< tri_poly.contours(); k++) {
|
||||
for (int k=0; k< tri_nodes.contours(); k++) {
|
||||
// if (tri_poly.contour_size(k) != 3) {
|
||||
if (tri_nodes.contour_size(k) != 3) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "triangle doesnt have 3 nodes" << tri_nodes.contour_size(k) );
|
||||
exit(0);
|
||||
}
|
||||
|
||||
point_list raw_nodes = nodes.get_geod_nodes();
|
||||
|
||||
n1 = nodes.find( tri_poly.get_pt( k, 0 ) );
|
||||
// n1 = nodes.find( tri_poly.get_pt( k, 0 ) );
|
||||
n1 = tri_nodes.get_pt( k, 0 );
|
||||
e1 = nodes.get_node(n1).GetPosition().z();
|
||||
|
||||
n2 = nodes.find( tri_poly.get_pt( k, 1 ) );
|
||||
// n2 = nodes.find( tri_poly.get_pt( k, 1 ) );
|
||||
n2 = tri_nodes.get_pt( k, 1 );
|
||||
e2 = nodes.get_node(n2).GetPosition().z();
|
||||
|
||||
n3 = nodes.find( tri_poly.get_pt( k, 2 ) );
|
||||
// n3 = nodes.find( tri_poly.get_pt( k, 2 ) );
|
||||
n3 = tri_nodes.get_pt( k, 2 );
|
||||
e3 = nodes.get_node(n3).GetPosition().z();
|
||||
|
||||
min = e1;
|
||||
|
@ -731,22 +744,29 @@ void TGConstruct::fix_point_heights()
|
|||
for (int j = 0; j < (int)polys_clipped.superpolys[i].size(); ++j ) {
|
||||
SG_LOG( SG_CLIPPER, SG_INFO, "Flattening " << get_area_name( (AreaType)i ) << ":" << j+1 << " of " << (int)polys_clipped.superpolys[i].size() );
|
||||
|
||||
TGPolygon tri_poly = polys_clipped.superpolys[i][j].get_tris();
|
||||
for (int k=0; k< tri_poly.contours(); k++) {
|
||||
if (tri_poly.contour_size(k) != 3) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "triangle doesnt have 3 nodes" << tri_poly.contour_size(k) );
|
||||
// tri_poly = polys_clipped.superpolys[i][j].get_tris();
|
||||
tri_nodes = polys_clipped.superpolys[i][j].get_tri_idxs();
|
||||
|
||||
// for (int k=0; k< tri_poly.contours(); k++) {
|
||||
for (int k=0; k< tri_nodes.contours(); k++) {
|
||||
// if (tri_poly.contour_size(k) != 3) {
|
||||
if (tri_nodes.contour_size(k) != 3) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "triangle doesnt have 3 nodes" << tri_nodes.contour_size(k) );
|
||||
exit(0);
|
||||
}
|
||||
|
||||
point_list raw_nodes = nodes.get_geod_nodes();
|
||||
|
||||
n1 = nodes.find( tri_poly.get_pt( k, 0 ) );
|
||||
// n1 = nodes.find( tri_poly.get_pt( k, 0 ) );
|
||||
n1 = tri_nodes.get_pt( k, 0 );
|
||||
e1 = nodes.get_node(n1).GetPosition().z();
|
||||
|
||||
n2 = nodes.find( tri_poly.get_pt( k, 1 ) );
|
||||
// n2 = nodes.find( tri_poly.get_pt( k, 1 ) );
|
||||
n2 = tri_nodes.get_pt( k, 1 );
|
||||
e2 = nodes.get_node(n2).GetPosition().z();
|
||||
|
||||
n3 = nodes.find( tri_poly.get_pt( k, 2 ) );
|
||||
// n3 = nodes.find( tri_poly.get_pt( k, 2 ) );
|
||||
n3 = tri_nodes.get_pt( k, 2 );
|
||||
e3 = nodes.get_node(n3).GetPosition().z();
|
||||
|
||||
min = e1;
|
||||
|
@ -772,19 +792,26 @@ void TGConstruct::fix_point_heights()
|
|||
|
||||
if ( is_ocean_area( (AreaType)i ) ) {
|
||||
for (int j = 0; j < (int)polys_clipped.superpolys[i].size(); ++j ) {
|
||||
TGPolygon tri_poly = polys_clipped.superpolys[i][j].get_tris();
|
||||
|
||||
// tri_poly = polys_clipped.superpolys[i][j].get_tris();
|
||||
tri_nodes = polys_clipped.superpolys[i][j].get_tri_idxs();
|
||||
|
||||
SG_LOG( SG_CLIPPER, SG_INFO, "Flattening " << get_area_name( (AreaType)i ) << ":" << j+1 << " of " << (int)polys_clipped.superpolys[i].size() );
|
||||
|
||||
for (int k=0; k< tri_poly.contours(); k++) {
|
||||
if (tri_poly.contour_size(k) != 3) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "triangle doesnt have 3 nodes" << tri_poly.contour_size(k) );
|
||||
// for (int k=0; k< tri_poly.contours(); k++) {
|
||||
for (int k=0; k< tri_nodes.contours(); k++) {
|
||||
// if (tri_poly.contour_size(k) != 3) {
|
||||
if (tri_nodes.contour_size(k) != 3) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "triangle doesnt have 3 nodes" << tri_nodes.contour_size(k) );
|
||||
exit(0);
|
||||
}
|
||||
|
||||
n1 = nodes.find( tri_poly.get_pt( k, 0 ) );
|
||||
n2 = nodes.find( tri_poly.get_pt( k, 1 ) );
|
||||
n3 = nodes.find( tri_poly.get_pt( k, 2 ) );
|
||||
// n1 = nodes.find( tri_poly.get_pt( k, 0 ) );
|
||||
n1 = tri_nodes.get_pt( k, 0 );
|
||||
// n2 = nodes.find( tri_poly.get_pt( k, 1 ) );
|
||||
n2 = tri_nodes.get_pt( k, 1 );
|
||||
// n3 = nodes.find( tri_poly.get_pt( k, 2 ) );
|
||||
n3 = tri_nodes.get_pt( k, 2 );
|
||||
|
||||
nodes.SetElevation( n1, 0.0 );
|
||||
nodes.SetElevation( n2, 0.0 );
|
||||
|
@ -1253,20 +1280,8 @@ bool TGNodesSortByLon( const TGNode& n1, const TGNode& n2 )
|
|||
return ( n1.GetPosition().x() < n2.GetPosition().x() );
|
||||
}
|
||||
|
||||
static void dump_nodes( TGNodes* nodes ) {
|
||||
for (unsigned int i=0; i<nodes->size(); i++) {
|
||||
TGNode node = nodes->get_node( i );
|
||||
string fixed;
|
||||
|
||||
if ( node.GetFixedPosition() ) {
|
||||
fixed = " z is fixed elevation ";
|
||||
} else {
|
||||
fixed = " z is interpolated elevation ";
|
||||
}
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "Point[" << i << "] is " << node.GetPosition() << fixed );
|
||||
}
|
||||
}
|
||||
// TODO : Add to TGNodes class
|
||||
#if 0
|
||||
|
||||
static void dump_lat_nodes( TGConstruct& c, double lat ) {
|
||||
node_list all_nodes = c.get_nodes()->get_node_list();
|
||||
|
@ -1291,11 +1306,217 @@ static void dump_lat_nodes( TGConstruct& c, double lat ) {
|
|||
SG_LOG(SG_GENERAL, SG_ALERT, "Point[" << i << "] is " << sorted_nodes[i].GetPosition() << fixed );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// This function populates the Superpoly tri_idx polygon.
|
||||
// This polygon is a mirror of tris, except the verticies are
|
||||
// indexes into the node array (cast as unsigned long)
|
||||
void TGConstruct::LookupNodesPerVertex( void )
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "LookupNodexPerVertex");
|
||||
|
||||
// for each node, traverse all the triangles - and create face lists
|
||||
for ( unsigned int area = 0; area < TG_MAX_AREA_TYPES; ++area ) {
|
||||
|
||||
for( unsigned int p = 0; p < polys_clipped.superpolys[area].size(); ++p ) {
|
||||
TGPolygon tris = polys_clipped.superpolys[area][p].get_tris();
|
||||
TGPolyNodes tri_nodes;
|
||||
int idx;
|
||||
|
||||
for (int tri=0; tri < tris.contours(); tri++) {
|
||||
|
||||
for (int vertex = 0; vertex < tris.contour_size(tri); vertex++) {
|
||||
idx = nodes.find( tris.get_pt( tri, vertex ) );
|
||||
if (idx >= 0) {
|
||||
tri_nodes.add_node( tri, idx );
|
||||
} else {
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
polys_clipped.superpolys[area][p].set_tri_idxs(tri_nodes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TGConstruct::LookupFacesPerNode( void )
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "LookupFacesPerNode");
|
||||
int five_percent = nodes.size()/20;
|
||||
|
||||
for (unsigned int n=0; n<nodes.size(); n++) {
|
||||
// for each node, traverse all the triangles - and create face lists
|
||||
for ( unsigned int area = 0; area < TG_MAX_AREA_TYPES; ++area ) {
|
||||
|
||||
for( unsigned int p = 0; p < polys_clipped.superpolys[area].size(); ++p ) {
|
||||
TGPolyNodes tri_nodes = polys_clipped.superpolys[area][p].get_tri_idxs();
|
||||
|
||||
for (int tri=0; tri < tri_nodes.contours(); tri++) {
|
||||
|
||||
for (int sub = 0; sub < tri_nodes.contour_size(tri); sub++) {
|
||||
|
||||
if ( n == (unsigned int)tri_nodes.get_pt( tri, sub ) ) {
|
||||
nodes.AddFace( n, area, p, tri );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (n % five_percent == 0) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, " " << n*5 / five_percent << "% complete" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double TGConstruct::calc_tri_area( int_list& triangle_nodes ) {
|
||||
Point3D p1 = nodes.get_node( triangle_nodes[0] ).GetPosition();
|
||||
Point3D p2 = nodes.get_node( triangle_nodes[1] ).GetPosition();
|
||||
Point3D p3 = nodes.get_node( triangle_nodes[2] ).GetPosition();
|
||||
|
||||
return triangle_area( p1, p2, p3 );
|
||||
}
|
||||
|
||||
void TGConstruct::calc_normals( point_list& wgs84_nodes, TGSuperPoly& sp ) {
|
||||
// for each face in the superpoly, calculate a face normal
|
||||
SGVec3d v1, v2, normal;
|
||||
TGPolyNodes tri_nodes = sp.get_tri_idxs();
|
||||
int_list face_nodes;
|
||||
point_list face_normals;
|
||||
|
||||
face_normals.clear();
|
||||
|
||||
for (int i=0; i<tri_nodes.contours(); i++) {
|
||||
face_nodes = tri_nodes.get_contour(i);
|
||||
|
||||
Point3D p1 = wgs84_nodes[ face_nodes[0] ];
|
||||
Point3D p2 = wgs84_nodes[ face_nodes[1] ];
|
||||
Point3D p3 = wgs84_nodes[ face_nodes[2] ];
|
||||
|
||||
// do some sanity checking. With the introduction of landuse
|
||||
// areas, we can get some long skinny triangles that blow up our
|
||||
// "normal" calculations here. Let's check for really small
|
||||
// triangle areas and check if one dimension of the triangle
|
||||
// coordinates is nearly coincident. If so, assign the "default"
|
||||
// normal of straight up.
|
||||
|
||||
bool degenerate = false;
|
||||
const double area_eps = 1.0e-12;
|
||||
double area = calc_tri_area( face_nodes );
|
||||
// cout << " area = " << area << endl;
|
||||
if ( area < area_eps ) {
|
||||
degenerate = true;
|
||||
}
|
||||
|
||||
// cout << " " << p1 << endl;
|
||||
// cout << " " << p2 << endl;
|
||||
// cout << " " << p3 << endl;
|
||||
if ( fabs(p1.x() - p2.x()) < SG_EPSILON && fabs(p1.x() - p3.x()) < SG_EPSILON ) {
|
||||
degenerate = true;
|
||||
}
|
||||
if ( fabs(p1.y() - p2.y()) < SG_EPSILON && fabs(p1.y() - p3.y()) < SG_EPSILON ) {
|
||||
degenerate = true;
|
||||
}
|
||||
if ( fabs(p1.z() - p2.z()) < SG_EPSILON && fabs(p1.z() - p3.z()) < SG_EPSILON ) {
|
||||
degenerate = true;
|
||||
}
|
||||
|
||||
if ( degenerate ) {
|
||||
normal = normalize(SGVec3d(p1.x(), p1.y(), p1.z()));
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "Degenerate tri!");
|
||||
} else {
|
||||
v1[0] = p2.x() - p1.x();
|
||||
v1[1] = p2.y() - p1.y();
|
||||
v1[2] = p2.z() - p1.z();
|
||||
v2[0] = p3.x() - p1.x();
|
||||
v2[1] = p3.y() - p1.y();
|
||||
v2[2] = p3.z() - p1.z();
|
||||
normal = normalize(cross(v1, v2));
|
||||
}
|
||||
|
||||
|
||||
face_normals.push_back( Point3D::fromSGVec3( normal ) );
|
||||
}
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "calculated " << face_normals.size() << " face normals ");
|
||||
|
||||
sp.set_face_normals( face_normals );
|
||||
}
|
||||
|
||||
void TGConstruct::CalcFaceNormals( void )
|
||||
{
|
||||
// traverse the superpols, and calc normals for each tri within
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "Calculating face normals");
|
||||
|
||||
point_list wgs84_nodes = nodes.get_wgs84_nodes_as_Point3d();
|
||||
|
||||
for (int i = 0; i < TG_MAX_AREA_TYPES; i++) {
|
||||
for (int j = 0; j < (int)polys_clipped.superpolys[i].size(); ++j ) {
|
||||
SG_LOG( SG_CLIPPER, SG_INFO, "Calculating face normals for " << get_area_name( (AreaType)i ) << ":" << j+1 << " of " << (int)polys_in.superpolys[i].size() );
|
||||
|
||||
calc_normals( wgs84_nodes, polys_clipped.superpolys[i][j] );
|
||||
point_list fns = polys_clipped.superpolys[i][j].get_face_normals();
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "SP " << i << "," << j << " has " << fns.size() << " face normals ");
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < TG_MAX_AREA_TYPES; i++) {
|
||||
for (int j = 0; j < (int)polys_clipped.superpolys[i].size(); ++j ) {
|
||||
point_list fns = polys_clipped.superpolys[i][j].get_face_normals();
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "SP " << i << "," << j << " has " << fns.size() << " face normals ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TGConstruct::CalcPointNormals( void )
|
||||
{
|
||||
// traverse triangle structure building the face normal table
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "Calculating point normals");
|
||||
|
||||
Point3D normal;
|
||||
point_list wgs84_nodes = nodes.get_wgs84_nodes_as_Point3d();
|
||||
|
||||
for ( unsigned int i = 0; i<nodes.size(); i++ ) {
|
||||
TGNode node = nodes.get_node( i );
|
||||
TGFaceList faces = node.GetFaces();
|
||||
double total_area = 0.0;
|
||||
|
||||
Point3D average( 0.0 );
|
||||
|
||||
// for each triangle that shares this node
|
||||
for ( unsigned int j = 0; j < faces.size(); ++j ) {
|
||||
unsigned int at = faces[j].area;
|
||||
unsigned int poly = faces[j].poly;
|
||||
unsigned int tri = faces[j].tri;
|
||||
int_list face_nodes;
|
||||
|
||||
normal = polys_clipped.superpolys[at][poly].get_face_normal( tri );
|
||||
face_nodes = polys_clipped.superpolys[at][poly].get_tri_idxs().get_contour( tri ) ;
|
||||
|
||||
double area = calc_tri_area( face_nodes );
|
||||
normal *= area; // scale normal weight relative to area
|
||||
total_area += area;
|
||||
average += normal;
|
||||
// cout << normal << endl;
|
||||
}
|
||||
|
||||
average /= total_area;
|
||||
//cout << "average = " << average << endl;
|
||||
|
||||
nodes.SetNormal( i, average );
|
||||
}
|
||||
}
|
||||
|
||||
// master construction routine
|
||||
// TODO : Split each step into its own function, and move
|
||||
// into seperate files by major functionality
|
||||
// loading, clipping, tesselating, normals, and output
|
||||
// Also, we are still calculating some thing more than one
|
||||
// (like face area - need to move this into superpoly )
|
||||
void TGConstruct::construct_bucket( SGBucket b ) {
|
||||
|
||||
sprintf(ds_name, "./construct_debug_%d", b.gen_index() );
|
||||
sprintf(ds_name, "./construct_debug_%ld", b.gen_index() );
|
||||
ds_id = tgShapefileOpenDatasource( ds_name );
|
||||
|
||||
bucket = b;
|
||||
|
@ -1326,18 +1547,16 @@ void TGConstruct::construct_bucket( SGBucket b ) {
|
|||
|
||||
// do clipping
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "clipping polygons");
|
||||
|
||||
clip_all(min, max);
|
||||
|
||||
// SG_LOG(SG_GENERAL, SG_ALERT, "NODE LIST AFTER CLIPPING" );
|
||||
// dump_nodes( c );
|
||||
// nodes.Dump();
|
||||
|
||||
// Make sure we have the elavation nodes in the main node database
|
||||
// I'd like to do this first, but we get initial tgnodes from clipper
|
||||
point_list corner_list = array.get_corner_list();
|
||||
if ( corner_list.size() == 0 ) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "corner list is 0 " );
|
||||
// exit(0);
|
||||
}
|
||||
|
||||
for (unsigned int i=0; i<corner_list.size(); i++) {
|
||||
|
@ -1366,7 +1585,7 @@ void TGConstruct::construct_bucket( SGBucket b ) {
|
|||
m.add_shared_nodes( this );
|
||||
|
||||
// SG_LOG(SG_GENERAL, SG_ALERT, "NODE LIST AFTER ADDING SHARED EDGES" );
|
||||
// dump_nodes( c );
|
||||
// nodes.Dump();
|
||||
|
||||
for (int i = 0; i < TG_MAX_AREA_TYPES; i++) {
|
||||
for (int j = 0; j < (int)polys_clipped.superpolys[i].size(); ++j ) {
|
||||
|
@ -1391,7 +1610,7 @@ void TGConstruct::construct_bucket( SGBucket b ) {
|
|||
clean_clipped_polys();
|
||||
|
||||
// SG_LOG(SG_GENERAL, SG_ALERT, "NODE LIST AFTER ADDING CLIPPED POLYS" );
|
||||
// dump_nodes( c );
|
||||
// nodes.Dump();
|
||||
|
||||
// tesselate the polygons and prepair them for final output
|
||||
point_list extra = nodes.get_geod_nodes();
|
||||
|
@ -1401,6 +1620,7 @@ void TGConstruct::construct_bucket( SGBucket b ) {
|
|||
|
||||
SG_LOG( SG_CLIPPER, SG_INFO, "Tesselating " << get_area_name( (AreaType)i ) << "(" << i << ") :" << j+1 << " of " << (int)polys_clipped.superpolys[i].size() << " : flag = " << polys_clipped.superpolys[i][j].get_flag());
|
||||
|
||||
#if 0
|
||||
if ( (i == 3) && (j == 137) ) {
|
||||
SG_LOG( SG_CLIPPER, SG_INFO, "Error Poly\n" << poly );
|
||||
|
||||
|
@ -1413,21 +1633,10 @@ void TGConstruct::construct_bucket( SGBucket b ) {
|
|||
// close befoe the crash
|
||||
tgShapefileCloseDatasource( ds_id );
|
||||
}
|
||||
#endif
|
||||
|
||||
TGPolygon tri = polygon_tesselate_alt_with_extra( poly, extra, false );
|
||||
TGPolygon tc;
|
||||
|
||||
if ( polys_clipped.superpolys[i][j].get_flag() == "textured" ) {
|
||||
// SG_LOG(SG_GENERAL, SG_DEBUG, "USE TEXTURE PARAMS for tex coord calculations" );
|
||||
// tc = linear_tex_coords( tri, clipped_polys.texparams[i][j] );
|
||||
tc = area_tex_coords( tri );
|
||||
} else {
|
||||
// SG_LOG(SG_GENERAL, SG_DEBUG, "USE SIMGEAR for tex coord calculations" );
|
||||
tc = area_tex_coords( tri );
|
||||
}
|
||||
|
||||
polys_clipped.superpolys[i][j].set_tris( tri );
|
||||
polys_clipped.superpolys[i][j].set_texcoords( tc );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1444,33 +1653,30 @@ void TGConstruct::construct_bucket( SGBucket b ) {
|
|||
}
|
||||
}
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "NODE LIST BEFORE FLATTEN" );
|
||||
dump_nodes( get_nodes() );
|
||||
// SG_LOG(SG_GENERAL, SG_ALERT, "NODE LIST BEFORE FLATTEN" );
|
||||
// nodes.Dump();
|
||||
|
||||
// Step 7) Flatten
|
||||
// Step 7 : Generate triangle vertex to node index lists
|
||||
LookupNodesPerVertex();
|
||||
|
||||
// Step 8) Flatten
|
||||
fix_point_heights();
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "NODE LIST AFTER FLATTEN" );
|
||||
dump_nodes( get_nodes() );
|
||||
// SG_LOG(SG_GENERAL, SG_ALERT, "NODE LIST AFTER FLATTEN" );
|
||||
// nodes.Dump();
|
||||
|
||||
// Step 8) Generate face_connected list
|
||||
LookupFacesPerNode();
|
||||
nodes.Dump();
|
||||
|
||||
// Step 9 - Calculate Face Normals
|
||||
CalcFaceNormals();
|
||||
|
||||
// Step 10 - Calculate Point Normals
|
||||
CalcPointNormals();
|
||||
|
||||
#if 0
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "REVERSE ELE LOOKUP ");
|
||||
|
||||
// Step 9) Generate face_connected list
|
||||
// build the node -> element (triangle) reverse lookup table
|
||||
c.set_reverse_ele_lookup( gen_node_ele_lookup_table( c ) );
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "FACE NORMALS ");
|
||||
|
||||
// Step 10) Generate Face normals
|
||||
// build the face normal list
|
||||
c.set_face_normals( gen_face_normals( c ) );
|
||||
|
||||
// Step 11) Generate node normals
|
||||
// calculate the normals for each point in wgs84_nodes
|
||||
c.set_point_normals( gen_point_normals( c ) );
|
||||
|
||||
if ( c.get_cover().size() > 0 ) {
|
||||
// Now for all the remaining "default" land cover polygons, assign
|
||||
// each one it's proper type from the land use/land cover
|
||||
|
@ -1483,6 +1689,28 @@ void TGConstruct::construct_bucket( SGBucket b ) {
|
|||
// Step 13) Sort the triangle list by material (optional)
|
||||
#endif
|
||||
|
||||
// Calc texture coordinates
|
||||
for (int i = 0; i < TG_MAX_AREA_TYPES; i++) {
|
||||
for (int j = 0; j < (int)polys_clipped.superpolys[i].size(); ++j ) {
|
||||
TGPolygon poly = polys_clipped.superpolys[i][j].get_poly();
|
||||
|
||||
SG_LOG( SG_CLIPPER, SG_INFO, "Texturing " << get_area_name( (AreaType)i ) << "(" << i << ") :" << j+1 << " of " << (int)polys_clipped.superpolys[i].size() << " : flag = " << polys_clipped.superpolys[i][j].get_flag());
|
||||
|
||||
TGPolygon tri = polys_clipped.superpolys[i][j].get_tris();
|
||||
TGPolygon tc;
|
||||
|
||||
if ( polys_clipped.superpolys[i][j].get_flag() == "textured" ) {
|
||||
// SG_LOG(SG_GENERAL, SG_DEBUG, "USE TEXTURE PARAMS for tex coord calculations" );
|
||||
// tc = linear_tex_coords( tri, clipped_polys.texparams[i][j] );
|
||||
tc = area_tex_coords( tri );
|
||||
} else {
|
||||
// SG_LOG(SG_GENERAL, SG_DEBUG, "USE SIMGEAR for tex coord calculations" );
|
||||
tc = area_tex_coords( tri );
|
||||
}
|
||||
polys_clipped.superpolys[i][j].set_texcoords( tc );
|
||||
}
|
||||
}
|
||||
|
||||
// write shared data
|
||||
m.split_tile( bucket, this );
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "Tile Split");
|
||||
|
@ -1520,48 +1748,28 @@ void TGConstruct::construct_bucket( SGBucket b ) {
|
|||
int_list pt_n, tri_n, strip_n;
|
||||
int_list tri_tc, strip_tc;
|
||||
|
||||
// calculate "the" normal for this tile
|
||||
// temporary - generate a single normal
|
||||
Point3D p;
|
||||
p.setx( bucket.get_center_lon() * SGD_DEGREES_TO_RADIANS );
|
||||
p.sety( bucket.get_center_lat() * SGD_DEGREES_TO_RADIANS );
|
||||
p.setz( 0 );
|
||||
Point3D vnt = sgGeodToCart( p );
|
||||
|
||||
SGVec3d tmp( vnt.x(), vnt.y(), vnt.z() );
|
||||
tmp = normalize(tmp);
|
||||
Point3D vn( tmp.x(), tmp.y(), tmp.z() );
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "found normal for this airport = " << tmp);
|
||||
|
||||
for (int i = 0; i < TG_MAX_AREA_TYPES; i++) {
|
||||
// only tesselate non holes
|
||||
if ( !is_hole_area( i ) ) {
|
||||
for (int j = 0; j < (int)polys_clipped.superpolys[i].size(); ++j ) {
|
||||
SG_LOG( SG_CLIPPER, SG_INFO, "Ouput nodes for " << get_area_name( (AreaType)i ) << ":" << j+1 << " of " << (int)polys_clipped.superpolys[i].size() );
|
||||
|
||||
TGPolygon tri_poly = polys_clipped.superpolys[i][j].get_tris();
|
||||
TGPolygon tri_txs = polys_clipped.superpolys[i][j].get_texcoords();
|
||||
string material = polys_clipped.superpolys[i][j].get_material();
|
||||
TGPolyNodes tri_nodes = polys_clipped.superpolys[i][j].get_tri_idxs();
|
||||
TGPolygon tri_txs = polys_clipped.superpolys[i][j].get_texcoords();
|
||||
string material = polys_clipped.superpolys[i][j].get_material();
|
||||
|
||||
for (int k = 0; k < tri_poly.contours(); ++k)
|
||||
for (int k = 0; k < tri_nodes.contours(); ++k)
|
||||
{
|
||||
tri_v.clear();
|
||||
tri_n.clear();
|
||||
tri_tc.clear();
|
||||
for (int l = 0; l < tri_poly.contour_size(k); ++l)
|
||||
for (int l = 0; l < tri_nodes.contour_size(k); ++l)
|
||||
{
|
||||
p = tri_poly.get_pt( k, l );
|
||||
index = nodes.find( p );
|
||||
if (index < 0) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "NODE NOT FOUND " << p);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
index = tri_nodes.get_pt( k, l );
|
||||
tri_v.push_back( index );
|
||||
|
||||
// use 'the' normal
|
||||
index = normals.unique_add( vn );
|
||||
// add the node's normal
|
||||
index = normals.unique_add( nodes.GetNormal( index ) );
|
||||
tri_n.push_back( index );
|
||||
|
||||
Point3D tc = tri_txs.get_pt( k, l );
|
||||
|
@ -1652,15 +1860,6 @@ void TGConstruct::construct_bucket( SGBucket b ) {
|
|||
throw sg_exception("error writing file. :-(");
|
||||
}
|
||||
|
||||
// TEMP TEMP TEMP TEMP
|
||||
|
||||
#if 0
|
||||
// Step 14) Generate the output
|
||||
// generate the output
|
||||
TGGenOutput output;
|
||||
do_output( c, output );
|
||||
#endif
|
||||
|
||||
// Step 15) Adding custome objects to the .stg file
|
||||
// collect custom objects and move to scenery area
|
||||
do_custom_objects();
|
||||
|
|
|
@ -130,6 +130,18 @@ private:
|
|||
// face normal list (for flat shading)
|
||||
point_list face_normals;
|
||||
|
||||
private:
|
||||
void LookupNodesPerVertex( void );
|
||||
void LookupFacesPerNode( void );
|
||||
void CalcFaceNormals( void );
|
||||
void CalcPointNormals( void );
|
||||
|
||||
// Should be in superpoly?
|
||||
void calc_normals( point_list& wgs84_nodes, TGSuperPoly& sp );
|
||||
|
||||
// Where should this be? Geometry library, I think...
|
||||
double calc_tri_area( int_list& triangle_nodes );
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
|
|
|
@ -97,40 +97,29 @@ point_list TGNodes::get_geod_nodes( void ) const {
|
|||
}
|
||||
|
||||
std::vector< SGVec3d > TGNodes::get_wgs84_nodes_as_SGVec3d( void ) const {
|
||||
std::vector< SGVec3d > points;
|
||||
Point3D pos;
|
||||
const_node_list_iterator current, last;
|
||||
std::vector< SGVec3d > points;
|
||||
|
||||
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 );
|
||||
points.push_back( (*current).GetWgs84AsSGVec3d() );
|
||||
}
|
||||
|
||||
return points;
|
||||
}
|
||||
|
||||
|
||||
point_list TGNodes::get_wgs84_nodes_as_Point3d( void ) const {
|
||||
point_list points;
|
||||
Point3D pos;
|
||||
const_node_list_iterator current, last;
|
||||
point_list points;
|
||||
|
||||
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 ) );
|
||||
points.push_back( (*current).GetWgs84AsPoint3D() );
|
||||
}
|
||||
|
||||
return points;
|
||||
|
@ -168,6 +157,27 @@ point_list TGNodes::get_normals( void ) const {
|
|||
return points;
|
||||
}
|
||||
|
||||
void TGNodes::Dump( void ) {
|
||||
for (unsigned int i=0; i<tg_node_list.size(); i++) {
|
||||
TGNode node = tg_node_list[ i ];
|
||||
std::string fixed;
|
||||
|
||||
if ( node.GetFixedPosition() ) {
|
||||
fixed = " z is fixed elevation ";
|
||||
} else {
|
||||
fixed = " z is interpolated elevation ";
|
||||
}
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "Point[" << i << "] is " << node.GetPosition() << fixed );
|
||||
if ( node.GetFaces().size() ) {
|
||||
TGFaceList faces = node.GetFaces();
|
||||
for (unsigned int j=0; j<faces.size(); j++) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "\tface " << faces[j].area << "," << faces[j].poly << "," << faces[j].tri );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
bool TGNodes::LookupFixedElevation( Point3D p, double* z )
|
||||
{
|
||||
|
|
|
@ -13,20 +13,27 @@
|
|||
#define FG_PROXIMITY_EPSILON 0.000001
|
||||
#define FG_COURSE_EPSILON 0.0001
|
||||
|
||||
typedef std::vector < unsigned int > TGIdxList;
|
||||
// for each node, we'll need a vector to lookup all triangles the node
|
||||
// is a member of.
|
||||
struct TGFaceLookup {
|
||||
unsigned int area;
|
||||
unsigned int poly;
|
||||
unsigned int tri;
|
||||
};
|
||||
typedef std::vector < TGFaceLookup > TGFaceList;
|
||||
|
||||
|
||||
class TGNode {
|
||||
public:
|
||||
TGNode( Point3D p ) {
|
||||
position = p;
|
||||
normal = Point3D();
|
||||
CalcWgs84();
|
||||
|
||||
|
||||
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 )
|
||||
|
@ -36,21 +43,42 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
inline void CalcWgs84()
|
||||
{
|
||||
SGGeod geod = SGGeod::fromDegM( position.x(), position.y(), position.z() );
|
||||
wgs84 = SGVec3d::fromGeod(geod);
|
||||
}
|
||||
|
||||
inline void AddFace( unsigned int area, unsigned int poly, unsigned int tri )
|
||||
{
|
||||
TGFaceLookup face;
|
||||
face.area = area;
|
||||
face.poly = poly;
|
||||
face.tri = tri;
|
||||
|
||||
faces.push_back( face );
|
||||
}
|
||||
|
||||
inline TGFaceList GetFaces( void ) const { return faces; }
|
||||
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 SGVec3d GetWgs84AsSGVec3d( void ) const { return wgs84; }
|
||||
inline Point3D GetWgs84AsPoint3D( void ) const { return Point3D::fromSGVec3( wgs84 ); }
|
||||
|
||||
inline void SetPosition( const Point3D& p )
|
||||
{
|
||||
if (!fixed_position) {
|
||||
position = p;
|
||||
CalcWgs84();
|
||||
}
|
||||
}
|
||||
|
||||
inline void SetElevation( double z )
|
||||
{
|
||||
if (!fixed_position) {
|
||||
position.setelev( z );
|
||||
position.setelev( z );
|
||||
CalcWgs84();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,12 +89,12 @@ public:
|
|||
private:
|
||||
Point3D position;
|
||||
Point3D normal;
|
||||
SGVec3d wgs84;
|
||||
|
||||
bool fixed_position;
|
||||
bool fixed_normal;
|
||||
|
||||
TGIdxList faces;
|
||||
TGIdxList neighbors;
|
||||
TGFaceList faces;
|
||||
};
|
||||
typedef std::vector < TGNode > node_list;
|
||||
typedef node_list::iterator node_list_iterator;
|
||||
|
@ -95,7 +123,6 @@ public:
|
|||
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 );
|
||||
|
||||
|
@ -111,6 +138,9 @@ public:
|
|||
// bool LookupFixedElevation( Point3D p, double* z );
|
||||
void SetElevation( int idx, double z ) { tg_node_list[idx].SetElevation( z ); }
|
||||
|
||||
Point3D GetNormal( int idx ) const { return tg_node_list[idx].GetNormal(); }
|
||||
void SetNormal( int idx, Point3D n ) { tg_node_list[idx].SetNormal( n ); }
|
||||
|
||||
// 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; }
|
||||
|
@ -128,9 +158,16 @@ public:
|
|||
// return the ith point
|
||||
inline TGNode get_node( int i ) const { return tg_node_list[i]; }
|
||||
|
||||
inline void AddFace( int i, unsigned int area, unsigned int poly, unsigned int tri )
|
||||
{
|
||||
tg_node_list[i].AddFace( area, poly, tri );
|
||||
}
|
||||
|
||||
// return the size of the node list
|
||||
inline size_t size() const { return tg_node_list.size(); }
|
||||
|
||||
void Dump( void );
|
||||
|
||||
private:
|
||||
node_list tg_node_list;
|
||||
|
||||
|
|
|
@ -38,6 +38,91 @@
|
|||
|
||||
#include "polygon.hxx"
|
||||
|
||||
// TODO : Needs to be its own class
|
||||
typedef std::vector < int > int_list;
|
||||
typedef std::vector < int_list > idx_list;
|
||||
typedef idx_list::iterator idx_list_iterator;
|
||||
typedef idx_list::const_iterator const_idx_list_iterator;
|
||||
|
||||
class TGPolyNodes {
|
||||
|
||||
private:
|
||||
|
||||
idx_list poly; // polygon node indexes
|
||||
|
||||
public:
|
||||
|
||||
// Constructor and destructor
|
||||
TGPolyNodes( void ) {}
|
||||
~TGPolyNodes( void ) {}
|
||||
|
||||
// Add a contour
|
||||
inline void add_contour( const int_list contour )
|
||||
{
|
||||
poly.push_back( contour );
|
||||
}
|
||||
|
||||
// Get a contour
|
||||
inline int_list get_contour( const int i ) const
|
||||
{
|
||||
return poly[i];
|
||||
}
|
||||
|
||||
// Delete a contour
|
||||
inline void delete_contour( const int i )
|
||||
{
|
||||
idx_list_iterator start_poly = poly.begin();
|
||||
poly.erase( start_poly + i );
|
||||
}
|
||||
|
||||
// Add the specified node (index) to the polygon
|
||||
inline void add_node( int contour, int n )
|
||||
{
|
||||
if ( contour >= (int)poly.size() ) {
|
||||
// extend polygon
|
||||
int_list empty_contour;
|
||||
empty_contour.clear();
|
||||
for ( int i = 0; i < contour - (int)poly.size() + 1; ++i ) {
|
||||
poly.push_back( empty_contour );
|
||||
}
|
||||
}
|
||||
poly[contour].push_back( n );
|
||||
}
|
||||
|
||||
// return size
|
||||
inline int contours() const
|
||||
{
|
||||
return poly.size();
|
||||
}
|
||||
inline int contour_size( int contour ) const
|
||||
{
|
||||
return poly[contour].size();
|
||||
}
|
||||
inline int total_size() const
|
||||
{
|
||||
int size = 0;
|
||||
|
||||
for ( int i = 0; i < contours(); ++i )
|
||||
size += poly[i].size();
|
||||
return size;
|
||||
}
|
||||
|
||||
// return the ith point from the specified contour
|
||||
inline int get_pt( int contour, int i ) const
|
||||
{
|
||||
return poly[contour][i];
|
||||
}
|
||||
|
||||
// update the value of a point
|
||||
inline void set_pt( int contour, int i, const int n )
|
||||
{
|
||||
poly[contour][i] = n;
|
||||
}
|
||||
};
|
||||
// END TODO
|
||||
|
||||
|
||||
|
||||
class TGSuperPoly {
|
||||
|
||||
private:
|
||||
|
@ -46,7 +131,10 @@ std::string material; // material/texture name
|
|||
TGPolygon poly; // master polygon
|
||||
TGPolygon normals; // corresponding normals
|
||||
TGPolygon texcoords; // corresponding texture coordinates
|
||||
|
||||
TGPolygon tris; // triangulation
|
||||
TGPolyNodes tri_idxs; // triangle node indexes
|
||||
|
||||
point_list face_normals; // triangle normals
|
||||
std::string flag; // For various potential record keeping needs
|
||||
|
||||
|
@ -101,6 +189,29 @@ inline void set_tris( const TGPolygon &p )
|
|||
tris = p;
|
||||
}
|
||||
|
||||
inline TGPolyNodes get_tri_idxs() const
|
||||
{
|
||||
return tri_idxs;
|
||||
}
|
||||
inline void set_tri_idxs( const TGPolyNodes &p )
|
||||
{
|
||||
tri_idxs = p;
|
||||
}
|
||||
|
||||
inline Point3D get_face_normal( int tri ) const
|
||||
{
|
||||
return face_normals[tri];
|
||||
}
|
||||
|
||||
inline point_list get_face_normals() const
|
||||
{
|
||||
return face_normals;
|
||||
}
|
||||
inline void set_face_normals( const point_list &fns )
|
||||
{
|
||||
face_normals = fns;
|
||||
}
|
||||
|
||||
inline std::string get_flag() const
|
||||
{
|
||||
return flag;
|
||||
|
|
Loading…
Reference in a new issue