diff --git a/src/Airports/GenAirports850/airport.cxx b/src/Airports/GenAirports850/airport.cxx index 19f14590..4a0fdca2 100644 --- a/src/Airports/GenAirports850/airport.cxx +++ b/src/Airports/GenAirports850/airport.cxx @@ -268,29 +268,28 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src ) } // Now generate pavements, and gather the linear features and lights from them + SG_LOG(SG_GENERAL, SG_ALERT, "Features before pavement add " << features.size() ); + if (pavements.size()) { for ( i=0; iBuildBtg( altitude, &pvmt_polys, &pvmt_tps, &accum, &apt_base, &apt_clearing ); - AddFeatures( pavements[i]->GetFeatures() ); + AddFeatures( pavements[i]->GetMarkings() ); } } - else - { - SG_LOG(SG_GENERAL, SG_ALERT, "no pavements"); - } - // wipe out the pavements to save memory - pavements.clear(); + + SG_LOG(SG_GENERAL, SG_ALERT, "Features after pavement add " << features.size() ); // Then the linear features if (features.size()) { for ( i=0; iBuildBtg( altitude, &line_polys, &line_tps, &line_accum ); + SG_LOG(SG_GENERAL, SG_ALERT, "Build feature Poly " << i << ": " << features[i]->GetDescription() ); + + // cut the linear feature in until we get the geometry right... + // features[i]->BuildBtg( altitude, &line_polys, &line_tps, &line_accum ); + features[i]->BuildBtg( altitude, &pvmt_polys, &pvmt_tps, &accum ); } } else @@ -300,6 +299,23 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src ) // wipe out the pavements to save memory features.clear(); + // Now generate pavements, and gather the linear features and lights from them + if (pavements.size()) + { + for ( i=0; iGetDescription()); + pavements[i]->BuildBtg( altitude, &pvmt_polys, &pvmt_tps, &accum, &apt_base, &apt_clearing ); + AddFeatures( pavements[i]->GetMarkings() ); + } + } + else + { + SG_LOG(SG_GENERAL, SG_ALERT, "no pavements"); + } + // wipe out the pavements to save memory + pavements.clear(); + if ( apt_base.total_size() == 0 ) { SG_LOG(SG_GENERAL, SG_ALERT, "no airport points generated"); @@ -1088,6 +1104,8 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src ) SGBinObject obj; + SG_LOG(SG_GENERAL, SG_ALERT, "number of NODES is " << wgs84_nodes.size() ); + obj.set_gbs_center( gbs_center ); obj.set_gbs_radius( gbs_radius ); obj.set_wgs84_nodes( wgs84_nodes ); diff --git a/src/Airports/GenAirports850/airport.hxx b/src/Airports/GenAirports850/airport.hxx index 81d5555c..a8375808 100644 --- a/src/Airports/GenAirports850/airport.hxx +++ b/src/Airports/GenAirports850/airport.hxx @@ -27,6 +27,7 @@ public: void AddFeature( LinearFeature* feature ) { + SG_LOG(SG_GENERAL, SG_ALERT, "Adding Feature"); features.push_back( feature ); } diff --git a/src/Airports/GenAirports850/apt_surface.cxx b/src/Airports/GenAirports850/apt_surface.cxx index 470aefb2..664e3e40 100644 --- a/src/Airports/GenAirports850/apt_surface.cxx +++ b/src/Airports/GenAirports850/apt_surface.cxx @@ -350,6 +350,7 @@ static ColumnVector qr_method( Real* y, // Get diagonals of Hat matrix DiagonalMatrix Hat; Hat << X1 * X1.t(); +#ifdef DEBUG cout << "A vector = " << A << endl; cout << "A rows = " << A.nrows() << endl; @@ -362,6 +363,7 @@ static ColumnVector qr_method( Real* y, cout << setw(9) << setprecision(3) << (X.columns(2,4) | Y | Fitted | Y1 | Hat.as_column()); cout << "\n\n"; +#endif return A; } @@ -471,7 +473,7 @@ double TGAptSurface::query( double lon_deg, double lat_deg ) { + A(16)*x*x*y*y*y; result += offset.z(); - printf("result = %.6f %.6f %.2f\n", lon_deg, lat_deg, result); + // printf("result = %.6f %.6f %.2f\n", lon_deg, lat_deg, result); return result; } diff --git a/src/Airports/GenAirports850/closedpoly.cxx b/src/Airports/GenAirports850/closedpoly.cxx index 36c8ff1d..ca16d3cd 100644 --- a/src/Airports/GenAirports850/closedpoly.cxx +++ b/src/Airports/GenAirports850/closedpoly.cxx @@ -22,17 +22,16 @@ ClosedPoly::ClosedPoly( int st, float s, float th, char* desc ) texture_heading = th; if ( desc ) { - strcpy( description, desc ); + description = desc; } else { - strcpy( description, "none" ); + description = "none"; } boundary = NULL; cur_contour = NULL; - cur_feat = NULL; - cur_marking = 0; + cur_marking = NULL; } void ClosedPoly::AddNode( BezNode* node ) @@ -44,6 +43,7 @@ void ClosedPoly::AddNode( BezNode* node ) } cur_contour->push_back( node ); + SG_LOG(SG_GENERAL, SG_DEBUG, "CLOSEDPOLY::ADDNODE : (" << node->GetLoc().x() << "," << node->GetLoc().y() << ")"); @@ -52,33 +52,22 @@ void ClosedPoly::AddNode( BezNode* node ) // if recording a linear feature on the pavement, add this node // to it as well // TODO: just doing marking now, need lighting as well - if (cur_feat) + if (!cur_marking) { - SG_LOG(SG_GENERAL, SG_DEBUG, " Adding node (" << node->GetLoc().x() << "," << node->GetLoc().y() << ") to current linear feature " << cur_marking); - cur_feat->AddNode( node ); - - // if it should end, end it, and add to feature list - if (cur_marking != node->GetMarking()) + string marking_desc = description + ":"; + if (boundary) { - SG_LOG(SG_GENERAL, SG_DEBUG, " Node has marking " << node->GetMarking() << " end it"); - features.push_back( cur_feat ); - cur_feat = NULL; - cur_marking = 0; + marking_desc += "hole"; + } + else + { + marking_desc += "boundary"; } - } - // should we start a new feature here? - SG_LOG(SG_GENERAL, SG_DEBUG, " Node has marking " << node->GetMarking() << " cur marking is " << cur_marking); - if ( (cur_marking == 0) && (node->GetMarking())) - { - // Yes - create a new linear feature - // TODO: With offset, as all pavement markings should be - // a bit in from the edge - SG_LOG(SG_GENERAL, SG_DEBUG, " Starting a new linear feature"); - cur_feat = new LinearFeature( (char*)"none" ); - cur_feat->AddNode( node ); - cur_marking = node->GetMarking(); - } + SG_LOG(SG_GENERAL, SG_DEBUG, " Adding node (" << node->GetLoc().x() << "," << node->GetLoc().y() << ") to current linear feature " << cur_marking); + cur_marking = new LinearFeature(marking_desc /* TODO offset */ ); + } + cur_marking->AddNode( node ); } void ClosedPoly::CreateConvexHull( void ) @@ -104,15 +93,14 @@ int ClosedPoly::CloseCurContour() // if we are recording a pavement marking - it must be closed - // add the first node of the poly - if (cur_feat) + if (cur_marking) { SG_LOG(SG_GENERAL, SG_DEBUG, "We still have an active linear feature - add the first node to close it"); + // cur_marking->Close(); + cur_marking->Finish(); - cur_feat->AddNode( cur_contour->at(0) ); - - features.push_back( cur_feat ); - cur_feat = NULL; - cur_marking = 0; + markings.push_back(cur_marking); + cur_marking = NULL; } // add the contour to the poly - first one is the outer boundary diff --git a/src/Airports/GenAirports850/closedpoly.hxx b/src/Airports/GenAirports850/closedpoly.hxx index b9990dd3..ec98dd19 100644 --- a/src/Airports/GenAirports850/closedpoly.hxx +++ b/src/Airports/GenAirports850/closedpoly.hxx @@ -19,16 +19,17 @@ class ClosedPoly { public: ClosedPoly( int st, float s, float th, char* desc ); - + + inline string GetDescription() { return description; } void AddNode( BezNode* node ); int CloseCurContour(); int Finish(); int BuildOsg( osg::Group* airport ); int BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list* texparams, TGPolygon* accum, TGPolygon* apt_base, TGPolygon* apt_clearing ); - FeatureList* GetFeatures() + FeatureList* GetMarkings() { - return &features; + return &markings; } private: @@ -39,10 +40,10 @@ private: osg::DrawArrays* CreateOsgPrimitive( point_list contour, osg::Vec3Array* vpave ); void ExpandContour( point_list& src, TGPolygon& dst, double dist ); - int surface_type; - float smoothness; - float texture_heading; - char description[64]; + int surface_type; + float smoothness; + float texture_heading; + string description; // outer boundary definition as bezier nodes BezContour* boundary; @@ -53,17 +54,15 @@ private: // contour that nodes will be added until done BezContour* cur_contour; - // outer boundary as convex hull point_list hull; // Converted polygon after parsing complete TGPolygon pre_tess; - // pavement definitions can have multiple linear features (markings) - LinearFeature* cur_feat; - FeatureList features; - int cur_marking; + // pavement definitions have multiple linear features (markings and lights for each contour) + LinearFeature* cur_marking; + FeatureList markings; }; typedef std::vector PavementList; diff --git a/src/Airports/GenAirports850/linearfeature.cxx b/src/Airports/GenAirports850/linearfeature.cxx index 1b67b87b..b94d79d7 100644 --- a/src/Airports/GenAirports850/linearfeature.cxx +++ b/src/Airports/GenAirports850/linearfeature.cxx @@ -32,7 +32,7 @@ void LinearFeature::ConvertContour( BezContour* src ) Marking* cur_mark = NULL; int i; - SG_LOG(SG_GENERAL, SG_DEBUG, "Creating a contour with " << src->size() << " nodes"); + SG_LOG(SG_GENERAL, SG_ALERT, " LinearFeature::ConvertContour - Creating a contour with " << src->size() << " nodes"); // clear anything in the point list points.empty(); @@ -40,7 +40,7 @@ void LinearFeature::ConvertContour( BezContour* src ) // iterate through each bezier node in the contour for (i=0; i <= src->size()-1; i++) { - SG_LOG(SG_GENERAL, SG_DEBUG, "\nHandling Node " << i << "\n\n"); + SG_LOG(SG_GENERAL, SG_ALERT, " LinearFeature::ConvertContour: Handling Node " << i << "\n\n"); if (i == 0) { @@ -73,11 +73,17 @@ void LinearFeature::ConvertContour( BezContour* src ) { if (curNode->GetMarking() != cur_mark->type) { - // amrking has ended, or changed + SG_LOG(SG_GENERAL, SG_ALERT, "LinearFeature::ConvertContour Marking has changed from " << cur_mark->type << " to " << curNode->GetMarking() << " save mark from " << cur_mark->start_idx << " to " << points.size() ); + + // marking has ended, or changed cur_mark->end_idx = points.size(); marks.push_back(cur_mark); cur_mark = NULL; } + else + { + SG_LOG(SG_GENERAL, SG_ALERT, "LinearFeature::ConvertContour Continue Marking from " << cur_mark->start_idx << " with type " << cur_mark->type ); + } } // should we start a new mark? @@ -85,6 +91,8 @@ void LinearFeature::ConvertContour( BezContour* src ) { if (curNode->GetMarking()) { + SG_LOG(SG_GENERAL, SG_ALERT, "LinearFeature::ConvertContour Start Marking from " << points.size() << " with type " << curNode->GetMarking() ); + // we aren't watching a mark, and this node has one cur_mark = new Marking; cur_mark->type = curNode->GetMarking(); @@ -202,6 +210,16 @@ void LinearFeature::ConvertContour( BezContour* src ) SG_LOG(SG_GENERAL, SG_DEBUG, "adding Linear Anchor node at (" << curLoc.x() << "," << curLoc.y() << ")"); } } + + // check for marking that goes all the way to the end... + if (cur_mark) + { + SG_LOG(SG_GENERAL, SG_ALERT, "LinearFeature::ConvertContour Marking from " << cur_mark->start_idx << " with type " << cur_mark->type << " ends at the end of the contour: " << points.size() ); + + cur_mark->end_idx = points.size()-1; + marks.push_back(cur_mark); + cur_mark = NULL; + } } @@ -213,7 +231,7 @@ Point3D LinearFeature::OffsetPointMiddle( Point3D *prev, Point3D *cur, Point3D * double dist; double pt_x, pt_y; - SG_LOG(SG_GENERAL, SG_DEBUG, "Find average angle for contour: prev (" << *prev << "), " + SG_LOG(SG_GENERAL, SG_ALERT, "Find average angle for contour: prev (" << *prev << "), " "cur (" << *cur << "), " "next (" << *next << ")" ); @@ -232,20 +250,36 @@ Point3D LinearFeature::OffsetPointMiddle( Point3D *prev, Point3D *cur, Point3D * SGVec3d avg = dir1 + dir2; avg = normalize(avg); + // check the turn direction + SGVec3d cp = cross( dir1, dir2 ); + SG_LOG(SG_GENERAL, SG_ALERT, "\tcross product of dir1: " << dir1 << " and dir2: " << dir2 << " is " << cp ); + // find the offset angle - geo_inverse_wgs_84( 0.0f, 0.0f, avg.y(), avg.x(), &offset_dir, &az2, &dist); + geo_inverse_wgs_84( avg.y(), avg.x(), 0.0f, 0.0f, &offset_dir, &az2, &dist); + + // if we turned right, reverse the heading + if (cp.z() < 0.0f) + { + offset_dir += 180.0; + } + while (offset_dir >= 360.0) + { + offset_dir -= 360.0; + } // find the direction to the next point geo_inverse_wgs_84( cur->y(), cur->x(), next->y(), next->x(), &next_dir, &az2, &dist); // calculate correct distance for the offset point - dist = (offset_by)/sin(SGMiscd::deg2rad(offset_dir-next_dir)); + dist = (offset_by)/sin(SGMiscd::deg2rad(next_dir-offset_dir)); - SG_LOG(SG_GENERAL, SG_DEBUG, "heading is " << offset_dir << " distance is " << dist ); + SG_LOG(SG_GENERAL, SG_ALERT, "\theading is " << offset_dir << " distance is " << dist ); // calculate the point from cur geo_direct_wgs_84( cur->y(), cur->x(), offset_dir, dist, &pt_y, &pt_x, &az2 ); + SG_LOG(SG_GENERAL, SG_ALERT, "\tpoint is (" << pt_x << "," << pt_y << ")" ); + return Point3D(pt_x, pt_y, 0.0f); } @@ -256,22 +290,24 @@ Point3D LinearFeature::OffsetPointFirst( Point3D *cur, Point3D *next, double off double dist; double pt_x, pt_y; - SG_LOG(SG_GENERAL, SG_DEBUG, "Find OffsetPoint at Start : cur (" << *cur << "), " + SG_LOG(SG_GENERAL, SG_ALERT, "Find OffsetPoint at Start : cur (" << *cur << "), " "next (" << *next << ")" ); // find the offset angle - geo_inverse_wgs_84( cur->x(), cur->y(), next->x(), next->y(), &offset_dir, &az2, &dist); + geo_inverse_wgs_84( cur->y(), cur->x(), next->y(), next->x(), &offset_dir, &az2, &dist); offset_dir -= 90; if (offset_dir < 0) { offset_dir += 360; } - SG_LOG(SG_GENERAL, SG_DEBUG, "heading is " << offset_dir << " distance is " << offset_by ); + SG_LOG(SG_GENERAL, SG_ALERT, "\theading is " << offset_dir << " distance is " << offset_by ); // calculate the point from cur geo_direct_wgs_84( cur->y(), cur->x(), offset_dir, offset_by, &pt_y, &pt_x, &az2 ); + SG_LOG(SG_GENERAL, SG_ALERT, "\tpoint is (" << pt_x << "," << pt_y << ")" ); + return Point3D(pt_x, pt_y, 0.0f); } @@ -283,27 +319,27 @@ Point3D LinearFeature::OffsetPointLast( Point3D *prev, Point3D *cur, double offs double dist; double pt_x, pt_y; - SG_LOG(SG_GENERAL, SG_DEBUG, "Find OffsetPoint at End : prev (" << *prev << "), " + SG_LOG(SG_GENERAL, SG_ALERT, "Find OffsetPoint at End : prev (" << *prev << "), " "cur (" << *cur << ")" ); // find the offset angle - geo_inverse_wgs_84( prev->x(), prev->y(), cur->x(), cur->y(), &offset_dir, &az2, &dist); + geo_inverse_wgs_84( prev->y(), prev->x(), cur->y(), cur->x(), &offset_dir, &az2, &dist); offset_dir -= 90; if (offset_dir < 0) { offset_dir += 360; } - SG_LOG(SG_GENERAL, SG_DEBUG, "heading is " << offset_dir << " distance is " << offset_by ); + SG_LOG(SG_GENERAL, SG_ALERT, "\theading is " << offset_dir << " distance is " << offset_by ); // calculate the point from cur geo_direct_wgs_84( cur->y(), cur->x(), offset_dir, offset_by, &pt_y, &pt_x, &az2 ); + SG_LOG(SG_GENERAL, SG_ALERT, "\tpoint is (" << pt_x << "," << pt_y << ")" ); + return Point3D(pt_x, pt_y, 0.0f); } - - int LinearFeature::Finish() { TGPolygon poly; @@ -363,7 +399,9 @@ int LinearFeature::Finish() case LF_UNIDIR_CLOSE_AMBER_PULSE: case LF_BIDIR_GREEN_AMBER: case LF_OMNIDIR_RED: - material = "gloff_lf_b_solid_yellow"; + //material = "gloff_lf_b_solid_yellow"; + // material = "pa_lftest"; + material = "pa_tiedown"; break; default: @@ -371,27 +409,29 @@ int LinearFeature::Finish() exit(1); } - for (j = marks[i]->start_idx; j < marks[i]->end_idx; j++) + for (j = marks[i]->start_idx; j <= marks[i]->end_idx; j++) { + SG_LOG(SG_GENERAL, SG_ALERT, "LinearFeature::Finish: calculating offsets for mark " << i << " whose start idx is " << marks[i]->start_idx << " and end idx is " << marks[i]->end_idx << " cur idx is " << j ); + // for each point on the PointsList, generate a quad from // start to next, offset by 2 distnaces from the edge - if (j == 0) + if (j == marks[i]->start_idx) { - // first point on the contour - offset heading is 90deg - cur_outer = OffsetPointFirst( &points[j], &points[j+1], 0.4 ); - cur_inner = OffsetPointFirst( &points[j], &points[j+1], 0.5 ); + // first point on the mark - offset heading is 90deg + cur_outer = OffsetPointFirst( &points[j], &points[j+1], 1.0 ); + cur_inner = OffsetPointFirst( &points[j], &points[j+1], 2.0 ); } - else if (j == points.size()-1) + else if (j == marks[i]->end_idx) { - // last point on the contour - offset heading is 90deg - cur_outer = OffsetPointFirst( &points[j-1], &points[j], 0.4 ); - cur_inner = OffsetPointFirst( &points[j-1], &points[j], 0.5 ); + // last point on the mark - offset heading is 90deg + cur_outer = OffsetPointLast( &points[j-1], &points[j], 1.0 ); + cur_inner = OffsetPointLast( &points[j-1], &points[j], 2.0 ); } else { - cur_outer = OffsetPointMiddle( &points[j-1], &points[j], &points[j+1], 0.4 ); - cur_inner = OffsetPointMiddle( &points[j-1], &points[j], &points[j+1], 0.5 ); + cur_outer = OffsetPointMiddle( &points[j-1], &points[j], &points[j+1], 1.0 ); + cur_inner = OffsetPointMiddle( &points[j-1], &points[j], &points[j+1], 2.0 ); } if ( (prev_inner.x() != 0.0f) && (prev_inner.y() != 0.0f) ) @@ -421,50 +461,27 @@ int LinearFeature::Finish() int LinearFeature::BuildBtg(float alt_m, superpoly_list* line_polys, texparams_list* line_tps, TGPolygon* line_accum ) { - string material; - int j, k; + TGPolygon poly; + TGPolygon clipped; + TGPolygon split; + int i; -#if 0 - - // verify the poly has been generated - if ( pre_tess.contours() ) + for (i=0; ipush_back( feature_polys[i] ); - line_polys->push_back( sp ); - SG_LOG(SG_GENERAL, SG_DEBUG, "clipped = " << clipped.contours()); - *line_accum = tgPolygonUnion( pre_tess, *line_accum ); - tp = TGTexParams( pre_tess.get_pt(0,0), 0.2 /* TODO poly width */, 1.0 /* TODO poly length */, texture_heading ); - texparams->push_back( tp ); + *line_accum = tgPolygonUnion( poly, *line_accum ); + line_tps->push_back( feature_tps[i] ); } -#endif return 1; } diff --git a/src/Airports/GenAirports850/linearfeature.hxx b/src/Airports/GenAirports850/linearfeature.hxx index 19b9e6c8..f046bf05 100644 --- a/src/Airports/GenAirports850/linearfeature.hxx +++ b/src/Airports/GenAirports850/linearfeature.hxx @@ -61,14 +61,21 @@ public: { if ( desc ) { - strcpy( description, desc ); + description = desc; } else { - strcpy( description, "none" ); + description = "none"; } } + LinearFeature( string desc ) + { + description = desc; + } + + inline string GetDescription() { return description; } + void AddNode( BezNode* b ) { contour.push_back( b ); @@ -89,7 +96,7 @@ private: void ConvertContour( BezContour* src ); // text description - char description[256]; + string description; // contour definition (each beznode has marking type) BezContour contour; diff --git a/src/Airports/GenAirports850/main.cxx b/src/Airports/GenAirports850/main.cxx index 3f3403fd..305b7332 100644 --- a/src/Airports/GenAirports850/main.cxx +++ b/src/Airports/GenAirports850/main.cxx @@ -124,8 +124,8 @@ int main(int argc, char **argv) setup_default_elevation_sources(elev_src); // Set verbose - sglog().setLogLevels( SG_GENERAL, SG_BULK ); -// sglog().setLogLevels( SG_GENERAL, SG_INFO ); +// sglog().setLogLevels( SG_GENERAL, SG_BULK ); + sglog().setLogLevels( SG_GENERAL, SG_INFO ); SG_LOG(SG_GENERAL, SG_INFO, "Run genapt"); diff --git a/src/Airports/GenAirports850/parser.cxx b/src/Airports/GenAirports850/parser.cxx index 13214a50..99898d7b 100644 --- a/src/Airports/GenAirports850/parser.cxx +++ b/src/Airports/GenAirports850/parser.cxx @@ -169,7 +169,7 @@ LinearFeature* Parser::ParseFeature( char* line ) feature = new LinearFeature(NULL); } - SG_LOG(SG_GENERAL, SG_DEBUG, "Creating Linear Feature with desription \"" << line << "\""); + SG_LOG(SG_GENERAL, SG_ALERT, "Creating Linear Feature with desription \"" << line << "\""); return feature; } @@ -329,6 +329,7 @@ int Parser::ParseLine(char* line) } if (cur_airport) { + cur_feat->Finish(); cur_airport->AddFeature( cur_feat ); } SetState( STATE_NONE ); @@ -355,6 +356,7 @@ int Parser::ParseLine(char* line) } if (cur_airport) { + cur_feat->Finish(); cur_airport->AddFeature( cur_feat ); } SetState( STATE_NONE );