1
0
Fork 0

near feature checkpoint 1

- cut in to the terrain
- using asphalt texture, need a test texture to check texcoords
- need offset - it's hardcoded for pavement features, so centerlines are off
This commit is contained in:
PSadrozinski 2011-09-23 13:19:26 -04:00 committed by Christian Schmitt
parent 47b1b05ac7
commit a547a9ba00
9 changed files with 160 additions and 126 deletions

View file

@ -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; i<pavements.size(); i++ )
{
SG_LOG(SG_GENERAL, SG_ALERT, "Build Pavement Poly " << i);
pavements[i]->BuildBtg( 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; i<features.size(); i++ )
{
SG_LOG(SG_GENERAL, SG_ALERT, "Build feature Poly " << i);
features[i]->BuildBtg( 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; i<pavements.size(); i++ )
{
SG_LOG(SG_GENERAL, SG_ALERT, "Build Pavement Poly " << i << ": " << pavements[i]->GetDescription());
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 );

View file

@ -27,6 +27,7 @@ public:
void AddFeature( LinearFeature* feature )
{
SG_LOG(SG_GENERAL, SG_ALERT, "Adding Feature");
features.push_back( feature );
}

View file

@ -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;
}

View file

@ -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

View file

@ -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 <ClosedPoly *> PavementList;

View file

@ -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; i<feature_polys.size(); i++)
{
SG_LOG(SG_GENERAL, SG_DEBUG, "LinearFeature::BuildBtg: original poly has " << pre_tess.contours() << " contours");
// do this before clipping and generating the base
pre_tess = remove_dups( pre_tess );
pre_tess = reduce_degeneracy( pre_tess );
poly = feature_polys[i].get_poly();
clipped = tgPolygonDiff( poly, *line_accum );
for (int c=0; c<pre_tess.contours(); c++)
{
for (int pt=0; pt<pre_tess.contour_size(c); pt++)
{
SG_LOG(SG_GENERAL, SG_DEBUG, "BuildBtg: contour " << c << " pt " << pt << ": (" << pre_tess.get_pt(c, pt).x() << "," << pre_tess.get_pt(c, pt).y() << ")" );
}
}
TGSuperPoly sp;
TGTexParams tp;
TGPolygon clipped = tgPolygonDiff( pre_tess, *line_accum );
SG_LOG(SG_GENERAL, SG_DEBUG, "BuildBtg: clipped poly has " << clipped.contours() << " contours");
SG_LOG(SG_GENERAL, SG_ALERT, "BuildBtg: clipped poly has " << clipped.contours() << " contours");
TGPolygon split = tgPolygonSplitLongEdges( clipped, 400.0 );
SG_LOG(SG_GENERAL, SG_DEBUG, "BuildBtg: split poly has " << split.contours() << " contours");
SG_LOG(SG_GENERAL, SG_ALERT, "BuildBtg: split poly has " << split.contours() << " contours");
sp.erase();
sp.set_poly( split );
sp.set_material( material );
sp.set_flag("taxi");
feature_polys[i].set_poly( split );
line_polys->push_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;
}

View file

@ -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;

View file

@ -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");

View file

@ -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 );