Checkpoint : Linear features build their own superpoly_list on Finish() with
correct texture and heading for each quad. Still need to clip them against their own accum during build btg
This commit is contained in:
parent
7d729633c1
commit
47b1b05ac7
6 changed files with 645 additions and 518 deletions
|
@ -189,7 +189,6 @@ static point_list calc_elevations( TGAptSurface &surf,
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
// Determine node elevations of each node of a TGPolygon based on the
|
||||
// provided TGAptSurface. Offset is added to the final elevation
|
||||
static TGPolygon calc_elevations( TGAptSurface &surf,
|
||||
|
@ -211,11 +210,24 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
{
|
||||
TGPolygon apt_base;
|
||||
TGPolygon apt_clearing;
|
||||
|
||||
TGPolygon accum;
|
||||
accum.erase();
|
||||
TGPolygon line_accum;
|
||||
line_accum.erase();
|
||||
|
||||
// runways
|
||||
superpoly_list rwy_polys;
|
||||
texparams_list texparams;
|
||||
texparams_list rwy_tps;
|
||||
|
||||
// pavements
|
||||
superpoly_list pvmt_polys;
|
||||
texparams_list pvmt_tps;
|
||||
|
||||
// linear features
|
||||
superpoly_list line_polys;
|
||||
texparams_list line_tps;
|
||||
|
||||
int i, j, k;
|
||||
char buf[120]; // For debugging output
|
||||
Point3D p;
|
||||
|
@ -225,9 +237,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
int rwy_count = 0;
|
||||
|
||||
// Find the average of all the runway long / lats
|
||||
// TODO : Need runway object...
|
||||
|
||||
|
||||
// TODO : Need runway object...
|
||||
for (i=0; i<runways.size(); i++)
|
||||
{
|
||||
printf("runway %d from (%lf,%lf) to (%lf,%lf) : midpoint is (%lf,%lf)\n",
|
||||
|
@ -253,32 +263,42 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
{
|
||||
if ( runways[i]->IsPrecision() )
|
||||
{
|
||||
runways[i]->BuildBtg( altitude, &rwy_polys, &texparams, &accum, &apt_base, &apt_clearing );
|
||||
runways[i]->BuildBtg( altitude, &rwy_polys, &rwy_tps, &accum, &apt_base, &apt_clearing );
|
||||
}
|
||||
}
|
||||
|
||||
// Now generate pavements
|
||||
// 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]->BuildBtg( altitude, &rwy_polys, &texparams, &accum, &apt_base, &apt_clearing );
|
||||
pavements[i]->BuildBtg( altitude, &pvmt_polys, &pvmt_tps, &accum, &apt_base, &apt_clearing );
|
||||
AddFeatures( pavements[i]->GetFeatures() );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "no pavements");
|
||||
}
|
||||
|
||||
// wipe out the pavements to save memory
|
||||
pavements.clear();
|
||||
|
||||
// Then the linear features
|
||||
for ( i=0; i< 1; i++ )
|
||||
if (features.size())
|
||||
{
|
||||
// not yet...
|
||||
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 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "no pavements");
|
||||
}
|
||||
// wipe out the pavements to save memory
|
||||
features.clear();
|
||||
|
||||
if ( apt_base.total_size() == 0 )
|
||||
{
|
||||
|
@ -294,59 +314,11 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
TGPolygon divided_base = tgPolygonSplitLongEdges( filled_base, 200.0 );
|
||||
TGPolygon base_poly = tgPolygonDiff( divided_base, accum );
|
||||
|
||||
// do this when generating the polys themselves...
|
||||
#if 0
|
||||
for ( k = 0; k < (int)rwy_polys.size(); ++k )
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "add nodes/remove dups section = " << k << " " << rwy_polys[k].get_material());
|
||||
TGPolygon poly = rwy_polys[k].get_poly();
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "total size before = " << poly.total_size());
|
||||
for ( i = 0; i < poly.contours(); ++i )
|
||||
{
|
||||
for ( j = 0; j < poly.contour_size(i); ++j )
|
||||
{
|
||||
Point3D tmp = poly.get_pt(i, j);
|
||||
snprintf(buf, 119, " %.7f %.7f %.7f\n", tmp.x(), tmp.y(), tmp.z() );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, buf);
|
||||
}
|
||||
}
|
||||
|
||||
poly = remove_dups( poly );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after remove_dups() = " << poly.total_size());
|
||||
|
||||
for ( i = 0; i < poly.contours(); ++i )
|
||||
{
|
||||
for ( j = 0; j < poly.contour_size(i); ++j )
|
||||
{
|
||||
Point3D tmp = poly.get_pt(i, j);
|
||||
snprintf(buf, 119, " %.7f %.7f %.7f\n", tmp.x(), tmp.y(), tmp.z() );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, buf);
|
||||
}
|
||||
}
|
||||
|
||||
poly = reduce_degeneracy( poly );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after reduce_degeneracy() = " << poly.total_size());
|
||||
|
||||
for ( i = 0; i < poly.contours(); ++i )
|
||||
{
|
||||
for ( j = 0; j < poly.contour_size(i); ++j )
|
||||
{
|
||||
Point3D tmp = poly.get_pt(i, j);
|
||||
snprintf(buf, 119, " %.7f %.7f %.7f\n", tmp.x(), tmp.y(), tmp.z() );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, buf);
|
||||
}
|
||||
}
|
||||
|
||||
rwy_polys[k].set_poly( poly );
|
||||
}
|
||||
// END do this when generating polys
|
||||
#endif
|
||||
|
||||
// add segments to polygons to remove any possible "T"
|
||||
// intersections
|
||||
TGTriNodes tmp_nodes;
|
||||
|
||||
// build temporary node list
|
||||
// build temporary node list from runways...
|
||||
for ( k = 0; k < (int)rwy_polys.size(); ++k )
|
||||
{
|
||||
TGPolygon poly = rwy_polys[k].get_poly();
|
||||
|
@ -358,6 +330,34 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// and pavements
|
||||
for ( k = 0; k < (int)pvmt_polys.size(); ++k )
|
||||
{
|
||||
TGPolygon poly = pvmt_polys[k].get_poly();
|
||||
for ( i = 0; i < poly.contours(); ++i )
|
||||
{
|
||||
for ( j = 0; j < poly.contour_size( i ); ++j )
|
||||
{
|
||||
tmp_nodes.unique_add( poly.get_pt(i, j) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// and linear features
|
||||
for ( k = 0; k < (int)line_polys.size(); ++k )
|
||||
{
|
||||
TGPolygon poly = line_polys[k].get_poly();
|
||||
for ( i = 0; i < poly.contours(); ++i )
|
||||
{
|
||||
for ( j = 0; j < poly.contour_size( i ); ++j )
|
||||
{
|
||||
tmp_nodes.unique_add( poly.get_pt(i, j) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// and the base
|
||||
for ( i = 0; i < base_poly.contours(); ++i )
|
||||
{
|
||||
for ( j = 0; j < base_poly.contour_size( i ); ++j )
|
||||
|
@ -376,6 +376,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
}
|
||||
}
|
||||
|
||||
// second pass : runways
|
||||
for ( k = 0; k < (int)rwy_polys.size(); ++k )
|
||||
{
|
||||
TGPolygon poly = rwy_polys[k].get_poly();
|
||||
|
@ -385,6 +386,27 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
rwy_polys[k].set_poly( poly );
|
||||
}
|
||||
|
||||
// second pass : and pavements
|
||||
for ( k = 0; k < (int)pvmt_polys.size(); ++k )
|
||||
{
|
||||
TGPolygon poly = pvmt_polys[k].get_poly();
|
||||
poly = add_nodes_to_poly( poly, tmp_nodes );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after add nodes = " << poly.total_size());
|
||||
|
||||
pvmt_polys[k].set_poly( poly );
|
||||
}
|
||||
|
||||
// second pass : and lines
|
||||
for ( k = 0; k < (int)line_polys.size(); ++k )
|
||||
{
|
||||
TGPolygon poly = line_polys[k].get_poly();
|
||||
poly = add_nodes_to_poly( poly, tmp_nodes );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after add nodes = " << poly.total_size());
|
||||
|
||||
line_polys[k].set_poly( poly );
|
||||
}
|
||||
|
||||
|
||||
// One more pass to try to get rid of other yukky stuff
|
||||
for ( k = 0; k < (int)rwy_polys.size(); ++k )
|
||||
{
|
||||
|
@ -402,6 +424,39 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
rwy_polys[k].set_poly( poly );
|
||||
}
|
||||
|
||||
for ( k = 0; k < (int)pvmt_polys.size(); ++k )
|
||||
{
|
||||
TGPolygon poly = pvmt_polys[k].get_poly();
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "total size of section " << k << " before =" << poly.total_size());
|
||||
|
||||
poly = remove_dups( poly );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after remove_dups() = " << poly.total_size());
|
||||
poly = remove_bad_contours( poly );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after remove_bad() = " << poly.total_size());
|
||||
poly = remove_tiny_contours( poly );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after remove_tiny_contours() = " << poly.total_size());
|
||||
|
||||
pvmt_polys[k].set_poly( poly );
|
||||
}
|
||||
|
||||
for ( k = 0; k < (int)line_polys.size(); ++k )
|
||||
{
|
||||
TGPolygon poly = line_polys[k].get_poly();
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "total size of section " << k << " before =" << poly.total_size());
|
||||
|
||||
poly = remove_dups( poly );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after remove_dups() = " << poly.total_size());
|
||||
poly = remove_bad_contours( poly );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after remove_bad() = " << poly.total_size());
|
||||
poly = remove_tiny_contours( poly );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after remove_tiny_contours() = " << poly.total_size());
|
||||
|
||||
line_polys[k].set_poly( poly );
|
||||
}
|
||||
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "add nodes base ");
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, " before: " << base_poly);
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, " tmp_nodes size = " << tmp_nodes.get_node_list().size());
|
||||
|
@ -430,20 +485,48 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after = " << tri.total_size());
|
||||
|
||||
TGPolygon tc;
|
||||
if ( rwy_polys[i].get_flag() == "taxi" )
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "taxiway, no clip");
|
||||
tc = rwy_section_tex_coords( tri, texparams[i], false );
|
||||
}
|
||||
else
|
||||
{
|
||||
tc = rwy_section_tex_coords( tri, texparams[i], true );
|
||||
}
|
||||
tc = rwy_section_tex_coords( tri, rwy_tps[i], true );
|
||||
|
||||
rwy_polys[i].set_tris( tri );
|
||||
rwy_polys[i].set_texcoords( tc );
|
||||
}
|
||||
|
||||
// tesselate the polygons and prepair them for final output
|
||||
for ( i = 0; i < (int)pvmt_polys.size(); ++i )
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Tesselating section = " << i << " flag = " << pvmt_polys[i].get_flag());
|
||||
|
||||
TGPolygon poly = pvmt_polys[i].get_poly();
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "contours before " << poly.contours() << " total points before = " << poly.total_size());
|
||||
TGPolygon tri = polygon_tesselate_alt( poly );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after = " << tri.total_size());
|
||||
|
||||
TGPolygon tc;
|
||||
tc = rwy_section_tex_coords( tri, pvmt_tps[i], false );
|
||||
|
||||
pvmt_polys[i].set_tris( tri );
|
||||
pvmt_polys[i].set_texcoords( tc );
|
||||
pvmt_polys[i].set_tri_mode( GL_TRIANGLES );
|
||||
}
|
||||
|
||||
// tesselate the polygons and prepair them for final output
|
||||
for ( i = 0; i < (int)line_polys.size(); ++i )
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Tesselating section = " << i << " flag = " << pvmt_polys[i].get_flag());
|
||||
|
||||
TGPolygon poly = line_polys[i].get_poly();
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "contours before " << poly.contours() << " total points before = " << poly.total_size());
|
||||
TGPolygon tri = polygon_tesselate_alt( poly );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after = " << tri.total_size());
|
||||
|
||||
TGPolygon tc;
|
||||
tc = rwy_section_tex_coords( tri, line_tps[i], false );
|
||||
|
||||
line_polys[i].set_tris( tri );
|
||||
line_polys[i].set_texcoords( tc );
|
||||
line_polys[i].set_tri_mode( GL_TRIANGLES );
|
||||
}
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Tesselating base");
|
||||
TGPolygon base_tris = polygon_tesselate_alt( base_poly );
|
||||
|
||||
|
@ -534,6 +617,78 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
|
|||
}
|
||||
}
|
||||
|
||||
for ( k = 0; k < (int)pvmt_polys.size(); ++k )
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "tri " << k);
|
||||
// TGPolygon tri_poly = rwy_tris[k];
|
||||
TGPolygon tri_poly = pvmt_polys[k].get_tris();
|
||||
TGPolygon tri_txs = pvmt_polys[k].get_texcoords();
|
||||
string material = pvmt_polys[k].get_material();
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "material = " << material);
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "poly size = " << tri_poly.contours());
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "texs size = " << tri_txs.contours());
|
||||
for ( i = 0; i < tri_poly.contours(); ++i )
|
||||
{
|
||||
tri_v.clear();
|
||||
tri_n.clear();
|
||||
tri_tc.clear();
|
||||
for ( j = 0; j < tri_poly.contour_size(i); ++j )
|
||||
{
|
||||
p = tri_poly.get_pt( i, j );
|
||||
index = nodes.unique_add( p );
|
||||
tri_v.push_back( index );
|
||||
|
||||
// use 'the' normal
|
||||
index = normals.unique_add( vn );
|
||||
tri_n.push_back( index );
|
||||
|
||||
Point3D tc = tri_txs.get_pt( i, j );
|
||||
index = texcoords.unique_add( tc );
|
||||
tri_tc.push_back( index );
|
||||
}
|
||||
tris_v.push_back( tri_v );
|
||||
tris_n.push_back( tri_n );
|
||||
tris_tc.push_back( tri_tc );
|
||||
tri_materials.push_back( material );
|
||||
}
|
||||
}
|
||||
|
||||
for ( k = 0; k < (int)line_polys.size(); ++k )
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "tri " << k);
|
||||
// TGPolygon tri_poly = rwy_tris[k];
|
||||
TGPolygon tri_poly = line_polys[k].get_tris();
|
||||
TGPolygon tri_txs = line_polys[k].get_texcoords();
|
||||
string material = line_polys[k].get_material();
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "material = " << material);
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "poly size = " << tri_poly.contours());
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "texs size = " << tri_txs.contours());
|
||||
for ( i = 0; i < tri_poly.contours(); ++i )
|
||||
{
|
||||
tri_v.clear();
|
||||
tri_n.clear();
|
||||
tri_tc.clear();
|
||||
for ( j = 0; j < tri_poly.contour_size(i); ++j )
|
||||
{
|
||||
p = tri_poly.get_pt( i, j );
|
||||
index = nodes.unique_add( p );
|
||||
tri_v.push_back( index );
|
||||
|
||||
// use 'the' normal
|
||||
index = normals.unique_add( vn );
|
||||
tri_n.push_back( index );
|
||||
|
||||
Point3D tc = tri_txs.get_pt( i, j );
|
||||
index = texcoords.unique_add( tc );
|
||||
tri_tc.push_back( index );
|
||||
}
|
||||
tris_v.push_back( tri_v );
|
||||
tris_n.push_back( tri_n );
|
||||
tris_tc.push_back( tri_tc );
|
||||
tri_materials.push_back( material );
|
||||
}
|
||||
}
|
||||
|
||||
// add base points
|
||||
std::vector< SGVec2f > base_txs;
|
||||
int_list base_tc;
|
||||
|
|
|
@ -30,6 +30,14 @@ public:
|
|||
features.push_back( feature );
|
||||
}
|
||||
|
||||
void AddFeatures( FeatureList* feature_list )
|
||||
{
|
||||
for (int i=0; i<feature_list->size(); i++)
|
||||
{
|
||||
features.push_back( feature_list->at(i) );
|
||||
}
|
||||
}
|
||||
|
||||
void BuildOsg( osg::Group* airport );
|
||||
void BuildBtg( const string& root, const string_list& elev_src );
|
||||
|
||||
|
|
|
@ -45,6 +45,10 @@ void ClosedPoly::AddNode( BezNode* node )
|
|||
cur_contour->push_back( node );
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "CLOSEDPOLY::ADDNODE : (" << node->GetLoc().x() << "," << node->GetLoc().y() << ")");
|
||||
|
||||
|
||||
// TODO: Create ONE linear feature for each contour.
|
||||
// Parse the polys in linear feature
|
||||
// if recording a linear feature on the pavement, add this node
|
||||
// to it as well
|
||||
// TODO: just doing marking now, need lighting as well
|
||||
|
@ -71,7 +75,7 @@ void ClosedPoly::AddNode( BezNode* node )
|
|||
// 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(NULL);
|
||||
cur_feat = new LinearFeature( (char*)"none" );
|
||||
cur_feat->AddNode( node );
|
||||
cur_marking = node->GetMarking();
|
||||
}
|
||||
|
@ -129,7 +133,7 @@ int ClosedPoly::CloseCurContour()
|
|||
}
|
||||
}
|
||||
|
||||
void ClosedPoly::ConvertContour( BezContour* src, point_list *dst, bool reverse )
|
||||
void ClosedPoly::ConvertContour( BezContour* src, point_list *dst )
|
||||
{
|
||||
BezNode* prevNode;
|
||||
BezNode* curNode;
|
||||
|
@ -151,19 +155,6 @@ void ClosedPoly::ConvertContour( BezContour* src, point_list *dst, bool reverse
|
|||
// clear anything in this point list
|
||||
dst->empty();
|
||||
|
||||
if (reverse)
|
||||
{
|
||||
start = src->size()-1;
|
||||
end = -1;
|
||||
inc = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
start = 0;
|
||||
end = src->size();
|
||||
inc = 1;
|
||||
}
|
||||
|
||||
// iterate through each bezier node in the contour
|
||||
for (i=0; i <= src->size()-1; i++)
|
||||
{
|
||||
|
@ -486,7 +477,7 @@ int ClosedPoly::Finish()
|
|||
if (boundary != NULL)
|
||||
{
|
||||
// create the boundary
|
||||
ConvertContour( boundary, &dst_contour, false );
|
||||
ConvertContour( boundary, &dst_contour );
|
||||
|
||||
// and add it to the geometry
|
||||
pre_tess.add_contour( dst_contour, 0 );
|
||||
|
@ -495,7 +486,7 @@ int ClosedPoly::Finish()
|
|||
for (int i=0; i<holes.size(); i++)
|
||||
{
|
||||
dst_contour.clear();
|
||||
ConvertContour( holes[i], &dst_contour, false );
|
||||
ConvertContour( holes[i], &dst_contour );
|
||||
pre_tess.add_contour( dst_contour, 1 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,12 +25,17 @@ public:
|
|||
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()
|
||||
{
|
||||
return &features;
|
||||
}
|
||||
|
||||
private:
|
||||
//osg::DrawArrays* CreatePrimitive( BezContour* contour, osg::Vec3Array* v_pave );
|
||||
// convert the BezierPoly to a normal Poly (adding nodes for the curves)
|
||||
void CreateConvexHull( void );
|
||||
void ConvertContour( BezContour* src, point_list *dst, bool reverse );
|
||||
void ConvertContour( BezContour* src, point_list *dst );
|
||||
osg::DrawArrays* CreateOsgPrimitive( point_list contour, osg::Vec3Array* vpave );
|
||||
void ExpandContour( point_list& src, TGPolygon& dst, double dist );
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
#include "beznode.hxx"
|
||||
#include "linearfeature.hxx"
|
||||
#include "math.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <simgear/math/sg_geodesy.hxx>
|
||||
#include <simgear/math/SGVec3.hxx>
|
||||
|
@ -12,375 +10,254 @@
|
|||
#include <osg/PolygonMode>
|
||||
#include <osg/PolygonOffset>
|
||||
|
||||
int LinearFeature::Finish( osg::Group* airport )
|
||||
#include <Geometry/poly_support.hxx>
|
||||
|
||||
#include "beznode.hxx"
|
||||
#include "linearfeature.hxx"
|
||||
#include "math.h"
|
||||
|
||||
void LinearFeature::ConvertContour( BezContour* src )
|
||||
{
|
||||
BezNode* node;
|
||||
int i, j;
|
||||
int prev_dir = 0;
|
||||
double direction;
|
||||
double dist1, dist2;
|
||||
|
||||
printf("Finish a %s Linear Feature with %d verticies\n", closed ? "closed" : "open", contour.size());
|
||||
|
||||
BezNode* prevNode;
|
||||
BezNode* curNode;
|
||||
BezNode* nextNode;
|
||||
|
||||
BezNode* prevNode;
|
||||
BezNode* curNode;
|
||||
BezNode* nextNode;
|
||||
|
||||
Point3D prevLoc;
|
||||
Point3D curLoc;
|
||||
Point3D nextLoc;
|
||||
Point3D cp1;
|
||||
Point3D cp2;
|
||||
|
||||
Point3D st_cur1;
|
||||
Point3D st_cur2;
|
||||
double st_curx, st_cury, az2;
|
||||
int curve_type = CURVE_LINEAR;
|
||||
Marking* cur_mark = NULL;
|
||||
int i;
|
||||
|
||||
// create a DrawElement for the stripe triangle strip
|
||||
int stripe_idx = 0;
|
||||
int cur_marking = 0;
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Creating a contour with " << src->size() << " nodes");
|
||||
|
||||
osg::Vec3dArray* v_stripe = new osg::Vec3dArray;
|
||||
// clear anything in the point list
|
||||
points.empty();
|
||||
|
||||
for (i=0; i<contour.size(); i++)
|
||||
// iterate through each bezier node in the contour
|
||||
for (i=0; i <= src->size()-1; i++)
|
||||
{
|
||||
printf("\nHandling Node %d\n\n", i );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "\nHandling Node " << i << "\n\n");
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
// if closed, set prev node to last in the contour
|
||||
if (closed)
|
||||
{
|
||||
prevNode = contour.at( contour.size()-1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
prevNode = NULL;
|
||||
}
|
||||
// set prev node to last in the contour, as all contours must be closed
|
||||
prevNode = src->at( src->size()-1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
prevNode = contour.at( i-1 );
|
||||
// otherwise, it's just the previous index
|
||||
prevNode = src->at( i-1 );
|
||||
}
|
||||
|
||||
curNode = contour.at(i);
|
||||
curNode = src->at(i);
|
||||
|
||||
if (i<contour.size()-1)
|
||||
if (i < src->size() - 1)
|
||||
{
|
||||
nextNode = contour.at(i+1);
|
||||
nextNode = src->at(i+1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// if closed, set next node to the first in the contour
|
||||
if (closed)
|
||||
// for the last node, next is the first. as all contours are closed
|
||||
nextNode = src->at(0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// remember the index for the starting stopping of marks on the converted contour
|
||||
|
||||
// are we watching a mark for the end?
|
||||
if (cur_mark)
|
||||
{
|
||||
if (curNode->GetMarking() != cur_mark->type)
|
||||
{
|
||||
nextNode = contour.at(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
nextNode = NULL;
|
||||
// amrking has ended, or changed
|
||||
cur_mark->end_idx = points.size();
|
||||
marks.push_back(cur_mark);
|
||||
cur_mark = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// should we start a new mark?
|
||||
if (cur_mark == NULL)
|
||||
{
|
||||
if (curNode->GetMarking())
|
||||
{
|
||||
// we aren't watching a mark, and this node has one
|
||||
cur_mark = new Marking;
|
||||
cur_mark->type = curNode->GetMarking();
|
||||
cur_mark->start_idx = points.size();
|
||||
}
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// determine the type of curve from prev (just to get correct prev location)
|
||||
// once we start drawing the curve from cur to next, we can just remember the prev loc
|
||||
if (prevNode)
|
||||
{
|
||||
if (prevNode->HasNextCp())
|
||||
{
|
||||
// curve from prev is cubic or quadratic
|
||||
if(curNode->HasPrevCp())
|
||||
{
|
||||
// curve from prev is cubic : calculate the last location on the curve
|
||||
prevLoc = CalculateCubicLocation( prevNode->GetLoc(), prevNode->GetNextCp(), curNode->GetPrevCp(), curNode->GetLoc(), (1.0f/BEZIER_DETAIL) * (BEZIER_DETAIL-1) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// curve from prev is quadratic : use prev node next cp
|
||||
prevLoc = CalculateQuadraticLocation( prevNode->GetLoc(), prevNode->GetNextCp(), curNode->GetLoc(), (1.0f/BEZIER_DETAIL) * (BEZIER_DETAIL-1) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// curve from prev is quadratic or linear
|
||||
if( curNode->HasPrevCp() )
|
||||
{
|
||||
// curve from prev is quadratic : calculate the last location on the curve
|
||||
prevLoc = CalculateQuadraticLocation( prevNode->GetLoc(), curNode->GetPrevCp(), curNode->GetLoc(), (1.0f/BEZIER_DETAIL) * (BEZIER_DETAIL-1) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// curve from prev is linear : just use prev node location
|
||||
prevLoc = prevNode->GetLoc();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (prevNode->HasNextCp())
|
||||
{
|
||||
prevLoc = Point3D(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
int curve_type = CURVE_LINEAR;
|
||||
Point3D cp1;
|
||||
Point3D cp2;
|
||||
|
||||
if ( nextNode)
|
||||
{
|
||||
// now determine how we will iterate through cur node to next node
|
||||
if( curNode->HasNextCp() )
|
||||
// curve from prev is cubic or quadratic
|
||||
if(curNode->HasPrevCp())
|
||||
{
|
||||
// next curve is cubic or quadratic
|
||||
if( nextNode->HasPrevCp() )
|
||||
{
|
||||
// curve is cubic : need both control points
|
||||
curve_type = CURVE_CUBIC;
|
||||
cp1 = curNode->GetNextCp();
|
||||
cp2 = nextNode->GetPrevCp();
|
||||
}
|
||||
else
|
||||
{
|
||||
// curve is quadratic using current nodes cp as the cp
|
||||
curve_type = CURVE_QUADRATIC;
|
||||
cp1 = curNode->GetNextCp();
|
||||
}
|
||||
// curve from prev is cubic : calculate the last location on the curve
|
||||
prevLoc = CalculateCubicLocation( prevNode->GetLoc(), prevNode->GetNextCp(), curNode->GetPrevCp(), curNode->GetLoc(), (1.0f/BEZIER_DETAIL) * (BEZIER_DETAIL-1) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// next curve is quadratic or linear
|
||||
if( nextNode->HasPrevCp() )
|
||||
{
|
||||
// curve is quadratic using next nodes cp as the cp
|
||||
curve_type = CURVE_QUADRATIC;
|
||||
cp1 = nextNode->GetPrevCp();
|
||||
}
|
||||
else
|
||||
{
|
||||
// curve is linear
|
||||
curve_type = CURVE_LINEAR;
|
||||
}
|
||||
// curve from prev is quadratic : use prev node next cp
|
||||
prevLoc = CalculateQuadraticLocation( prevNode->GetLoc(), prevNode->GetNextCp(), curNode->GetLoc(), (1.0f/BEZIER_DETAIL) * (BEZIER_DETAIL-1) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// curve from prev is quadratic or linear
|
||||
if( curNode->HasPrevCp() )
|
||||
{
|
||||
// curve from prev is quadratic : calculate the last location on the curve
|
||||
prevLoc = CalculateQuadraticLocation( prevNode->GetLoc(), curNode->GetPrevCp(), curNode->GetLoc(), (1.0f/BEZIER_DETAIL) * (BEZIER_DETAIL-1) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// curve from prev is linear : just use prev node location
|
||||
prevLoc = prevNode->GetLoc();
|
||||
}
|
||||
}
|
||||
|
||||
// now determine how we will iterate from current node to next node
|
||||
if( curNode->HasNextCp() )
|
||||
{
|
||||
// next curve is cubic or quadratic
|
||||
if( nextNode->HasPrevCp() )
|
||||
{
|
||||
// curve is cubic : need both control points
|
||||
curve_type = CURVE_CUBIC;
|
||||
cp1 = curNode->GetNextCp();
|
||||
cp2 = nextNode->GetPrevCp();
|
||||
}
|
||||
else
|
||||
{
|
||||
// curve is quadratic using current nodes cp as the cp
|
||||
curve_type = CURVE_QUADRATIC;
|
||||
cp1 = curNode->GetNextCp();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
curve_type = CURVE_NONE;
|
||||
// next curve is quadratic or linear
|
||||
if( nextNode->HasPrevCp() )
|
||||
{
|
||||
// curve is quadratic using next nodes cp as the cp
|
||||
curve_type = CURVE_QUADRATIC;
|
||||
cp1 = nextNode->GetPrevCp();
|
||||
}
|
||||
else
|
||||
{
|
||||
// curve is linear
|
||||
curve_type = CURVE_LINEAR;
|
||||
}
|
||||
}
|
||||
|
||||
// initialize current location
|
||||
curLoc = curNode->GetLoc();
|
||||
switch( curve_type )
|
||||
if (curve_type != CURVE_LINEAR)
|
||||
{
|
||||
case CURVE_QUADRATIC:
|
||||
case CURVE_CUBIC:
|
||||
for (int p=0; p<BEZIER_DETAIL; p++)
|
||||
for (int p=0; p<BEZIER_DETAIL; p++)
|
||||
{
|
||||
// calculate next location
|
||||
if (curve_type == CURVE_QUADRATIC)
|
||||
{
|
||||
// calculate next location
|
||||
if (curve_type == CURVE_QUADRATIC)
|
||||
{
|
||||
nextLoc = CalculateQuadraticLocation( curNode->GetLoc(), cp1, nextNode->GetLoc(), (1.0f/BEZIER_DETAIL) * (p+1) );
|
||||
}
|
||||
else
|
||||
{
|
||||
nextLoc = CalculateCubicLocation( curNode->GetLoc(), cp1, cp2, nextNode->GetLoc(), (1.0f/BEZIER_DETAIL) * (p+1) );
|
||||
}
|
||||
|
||||
// set the verticies
|
||||
// convert from lat/lon to geodisc
|
||||
// (maybe later) - check some simgear objects...
|
||||
// printf("Added vertex at %lf,%lf\n",
|
||||
// add the pavement vertex
|
||||
if (p==0)
|
||||
{
|
||||
printf("adding Curve Anchor node (type %d) at (%lf,%lf)\n", curve_type, curLoc.x(), curLoc.y());
|
||||
}
|
||||
else
|
||||
{
|
||||
printf(" add bezier node (type %d) at (%lf,%lf)\n", curve_type, curLoc.x(), curLoc.y());
|
||||
}
|
||||
|
||||
// find the average direction at this vertex...
|
||||
direction = CalcMarkingVerticies( &prevLoc, &curLoc, &nextLoc, -1, &prev_dir, &dist1, &dist2 );
|
||||
|
||||
printf("got dir for bezier : prev_dir %d, dist1 %lf, dist2 %lf\n", prev_dir, dist1, dist2);
|
||||
|
||||
// distance can't be constant - it's the hypotenous of a right triangler with a constant offset from the outer rim.
|
||||
geo_direct_wgs_84( curLoc.x(), curLoc.y(), direction, dist1, &st_curx, &st_cury, &az2 );
|
||||
st_cur1 = Point3D( st_curx, st_cury, 0.0f );
|
||||
v_stripe->push_back( SGPoint3DtoOSGVec3d(st_cur1) );
|
||||
|
||||
geo_direct_wgs_84( curLoc.x(), curLoc.y(), direction, dist2, &st_curx, &st_cury, &az2 );
|
||||
st_cur2 = Point3D( st_curx, st_cury, 0.0f );
|
||||
v_stripe->push_back( SGPoint3DtoOSGVec3d(st_cur2) );
|
||||
|
||||
printf("node at (%lf,%lf) has stripe verticies (%lf,%lf) and (%lf,%lf)\n",
|
||||
curLoc.x(), curLoc.y(),
|
||||
st_cur1.x(), st_cur1.y(),
|
||||
st_cur2.x(), st_cur2.y()
|
||||
);
|
||||
|
||||
// now set set prev and cur locations for the next iteration
|
||||
prevLoc = curLoc;
|
||||
curLoc = nextLoc;
|
||||
nextLoc = CalculateQuadraticLocation( curNode->GetLoc(), cp1, nextNode->GetLoc(), (1.0f/BEZIER_DETAIL) * (p+1) );
|
||||
}
|
||||
else
|
||||
{
|
||||
nextLoc = CalculateCubicLocation( curNode->GetLoc(), cp1, cp2, nextNode->GetLoc(), (1.0f/BEZIER_DETAIL) * (p+1) );
|
||||
}
|
||||
break;
|
||||
|
||||
case CURVE_LINEAR:
|
||||
nextLoc = nextNode->GetLoc();
|
||||
// add the feature vertex
|
||||
points.push_back( curLoc );
|
||||
|
||||
printf("adding Linear Anchor node at (%lf,%lf)\n", curLoc.x(), curLoc.y());
|
||||
if (p==0)
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "adding Curve Anchor node (type " << curve_type << ") at (" << curLoc.x() << "," << curLoc.y() << ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, " add bezier node (type " << curve_type << ") at (" << curLoc.x() << "," << curLoc.y() << ")");
|
||||
}
|
||||
|
||||
// find the average direction at this vertex...
|
||||
direction = CalcMarkingVerticies( &prevLoc, &curLoc, &nextLoc, -1, &prev_dir, &dist1, &dist2 );
|
||||
// now set set prev and cur locations for the next iteration
|
||||
prevLoc = curLoc;
|
||||
curLoc = nextLoc;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nextLoc = nextNode->GetLoc();
|
||||
|
||||
printf("got dir for linear : prev_dir %d, dist1 %lf, dist2 %lf\n", prev_dir, dist1, dist2);
|
||||
// just add the one vertex - linear
|
||||
points.push_back( curLoc );
|
||||
|
||||
// distance can't be constant - it's the hypotenous of a right triangler with a constant offset from the outer rim.
|
||||
printf("calc direct: curLoc is (%lf,%lf), direction is %lf, dist is %lf\n", curLoc.x(), curLoc.y(), direction, dist1);
|
||||
|
||||
geo_direct_wgs_84( curLoc.x(), curLoc.y(), direction, dist1, &st_curx, &st_cury, &az2 );
|
||||
st_cur1 = Point3D( st_curx, st_cury, 0.0f );
|
||||
|
||||
v_stripe->push_back( SGPoint3DtoOSGVec3d(st_cur1) );
|
||||
|
||||
geo_direct_wgs_84( curLoc.x(), curLoc.y(), direction, dist2, &st_curx, &st_cury, &az2 );
|
||||
st_cur2 = Point3D( st_curx, st_cury, 0.0f );
|
||||
v_stripe->push_back( SGPoint3DtoOSGVec3d(st_cur2) );
|
||||
|
||||
printf("node at (%lf,%lf) has stripe verticies (%lf,%lf) and (%lf,%lf)\n",
|
||||
curLoc.x(), curLoc.y(),
|
||||
st_cur1.x(), st_cur1.y(),
|
||||
st_cur2.x(), st_cur2.y()
|
||||
);
|
||||
break;
|
||||
|
||||
case CURVE_NONE:
|
||||
nextLoc = Point3D(0.0f, 0.0f, 0.0f);
|
||||
|
||||
// we need to add the last verticies based on cur and prev position.
|
||||
// find the average direction at this vertex...
|
||||
direction = CalcMarkingVerticies( &prevLoc, &curLoc, &nextLoc, -1, &prev_dir, &dist1, &dist2 );
|
||||
|
||||
printf("got dir for term points : prev_dir %lf, dist1 %lf, dist2 %lf\n", prev_dir, dist1, dist2);
|
||||
|
||||
// distance can't be constant - it's the hypotenous of a right triangler with a constant offset from the outer rim.
|
||||
geo_direct_wgs_84( curLoc.x(), curLoc.y(), direction, dist1, &st_curx, &st_cury, &az2 );
|
||||
st_cur1 = Point3D( st_curx, st_cury, 0.0f );
|
||||
v_stripe->push_back( SGPoint3DtoOSGVec3d(st_cur1) );
|
||||
|
||||
geo_direct_wgs_84( curLoc.x(), curLoc.y(), direction, dist2, &st_curx, &st_cury, &az2 );
|
||||
st_cur2 = Point3D( st_curx, st_cury, 0.0f );
|
||||
v_stripe->push_back( SGPoint3DtoOSGVec3d(st_cur2) );
|
||||
|
||||
printf("node at (%lf,%lf) has stripe verticies (%lf,%lf) and (%lf,%lf)\n",
|
||||
curLoc.x(), curLoc.y(),
|
||||
st_cur1.x(), st_cur1.y(),
|
||||
st_cur2.x(), st_cur2.y()
|
||||
);
|
||||
break;
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "adding Linear Anchor node at (" << curLoc.x() << "," << curLoc.y() << ")");
|
||||
}
|
||||
}
|
||||
|
||||
printf("End feature %d \n", v_stripe->size() );
|
||||
airport->addChild(FinishMarking( v_stripe ) );
|
||||
}
|
||||
|
||||
int LinearFeature::BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list* texparams, TGPolygon* accum, TGPolygon* apt_base, TGPolygon* apt_clearing )
|
||||
{
|
||||
string material;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// this should be in the class
|
||||
// TODO: Should Be AddMidMarkingVerticies - and handle offset (used in LinearFeature::Finish only)
|
||||
double CalcMiddleMarkingVerticies( Point3D *prev, Point3D *cur, Point3D *next, int wind, int *prev_dir, double *dist1, double *dist2 )
|
||||
Point3D LinearFeature::OffsetPointMiddle( Point3D *prev, Point3D *cur, Point3D *next, double offset_by )
|
||||
{
|
||||
int turn_direction;
|
||||
bool reverse_dir = false;
|
||||
double offset_dir;
|
||||
double next_dir;
|
||||
double az1, az2;
|
||||
double dist;
|
||||
double pt_x, pt_y;
|
||||
|
||||
printf("Find averate angle for mark: prev (%lf,%lf), cur(%lf,%lf), next(%lf,%lf)\n", prev->x(), prev->y(), cur->x(), cur->y(), next->x(), next->y());
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Find average angle for contour: prev (" << *prev << "), "
|
||||
"cur (" << *cur << "), "
|
||||
"next (" << *next << ")" );
|
||||
|
||||
// first, find if the line turns left or right ar src
|
||||
// for this, take the cross product of the vectors from prev to src, and src to next.
|
||||
// if the cross product is negetive, we've turned to the left
|
||||
// if the cross product is positive, we've turned to the right
|
||||
// if the cross product is 0, then we need to use the direction passed in
|
||||
SGVec3d dir1 = cur->toSGVec3d() - prev->toSGVec3d();
|
||||
SGVec3d dir1 = prev->toSGVec3d() - cur->toSGVec3d();
|
||||
dir1 = normalize(dir1);
|
||||
|
||||
printf("normalized dir1 is (%lf,%lf)\n", dir1.x(), dir1.y());
|
||||
|
||||
SGVec3d dir2 = next->toSGVec3d() - cur->toSGVec3d();
|
||||
dir2 = normalize(dir2);
|
||||
|
||||
printf("normalized dir2 is (%lf,%lf)\n", dir2.x(), dir2.y());
|
||||
|
||||
SGVec3d cp = cross(dir1,dir2);
|
||||
if (cp.z() < 0.0)
|
||||
{
|
||||
turn_direction = -1;
|
||||
}
|
||||
else if (cp.z() > 0.0)
|
||||
{
|
||||
turn_direction = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
turn_direction = 0;
|
||||
}
|
||||
|
||||
printf("turn direction is %d\n", turn_direction);
|
||||
|
||||
// Now find the average
|
||||
SGVec3d avg = -dir1 + dir2;
|
||||
|
||||
printf("avg is (%lf,%lf)\n", avg.x(), avg.y());
|
||||
|
||||
// now determine which way the direction needs to point
|
||||
if ((wind == -1) && (turn_direction == 1))
|
||||
{
|
||||
reverse_dir = true;
|
||||
}
|
||||
if ((wind == 1) && (turn_direction == -1))
|
||||
{
|
||||
reverse_dir = true;
|
||||
}
|
||||
|
||||
printf("reverse dir is %d\n", reverse_dir);
|
||||
SGVec3d avg = dir1 + dir2;
|
||||
avg = normalize(avg);
|
||||
|
||||
// find the offset angle
|
||||
geo_inverse_wgs_84( 0.0f, 0.0f, avg.x(), avg.y(), &offset_dir, &az2, &dist);
|
||||
if (reverse_dir)
|
||||
{
|
||||
offset_dir += 180;
|
||||
while (offset_dir >= 360.0)
|
||||
{
|
||||
offset_dir -= 360.0;
|
||||
}
|
||||
}
|
||||
printf("offset direction is %lf\n", offset_dir);
|
||||
geo_inverse_wgs_84( 0.0f, 0.0f, avg.y(), avg.x(), &offset_dir, &az2, &dist);
|
||||
|
||||
// find the direction to the next point
|
||||
geo_inverse_wgs_84( cur->x(), cur->y(), next->x(), next->y(), &next_dir, &az2, &dist);
|
||||
printf("next direction is %lf\n", next_dir);
|
||||
geo_inverse_wgs_84( cur->y(), cur->x(), next->y(), next->x(), &next_dir, &az2, &dist);
|
||||
|
||||
// calculate correct distance for the offset point
|
||||
*dist1 = (-LINE_WIDTH)/sin(SGMiscd::deg2rad(next_dir-offset_dir));
|
||||
*dist2 = (LINE_WIDTH)/sin(SGMiscd::deg2rad(next_dir-offset_dir));
|
||||
dist = (offset_by)/sin(SGMiscd::deg2rad(offset_dir-next_dir));
|
||||
|
||||
return offset_dir;
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "heading 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 );
|
||||
|
||||
return Point3D(pt_x, pt_y, 0.0f);
|
||||
}
|
||||
|
||||
// TODO: Should Be AddStartMarkingVerticies - and handle offset (used in LinearFeature::Finish only)
|
||||
double CalcStartMarkingVerticies( Point3D *cur, Point3D *next, int wind, int *prev_dir, double *dist1, double *dist2 )
|
||||
Point3D LinearFeature::OffsetPointFirst( Point3D *cur, Point3D *next, double offset_by )
|
||||
{
|
||||
double offset_dir;
|
||||
double az1, az2;
|
||||
double dist;
|
||||
double pt_x, pt_y;
|
||||
|
||||
printf("Find start angle for mark: cur(%lf,%lf), next(%lf,%lf)\n", cur->x(), cur->y(), next->x(), next->y());
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "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);
|
||||
|
@ -390,23 +267,24 @@ double CalcStartMarkingVerticies( Point3D *cur, Point3D *next, int wind, int *pr
|
|||
offset_dir += 360;
|
||||
}
|
||||
|
||||
printf("offset direction is %lf\n", offset_dir);
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "heading is " << offset_dir << " distance is " << offset_by );
|
||||
|
||||
// calculate correct distance for the offset point
|
||||
*dist1 = (-LINE_WIDTH);
|
||||
*dist2 = (LINE_WIDTH);
|
||||
// calculate the point from cur
|
||||
geo_direct_wgs_84( cur->y(), cur->x(), offset_dir, offset_by, &pt_y, &pt_x, &az2 );
|
||||
|
||||
return offset_dir;
|
||||
return Point3D(pt_x, pt_y, 0.0f);
|
||||
}
|
||||
|
||||
// TODO: Should Be AddEndMarkingVerticies - and handle offset (used in LinearFeature::Finish only)
|
||||
double CalcEndMarkingVerticies( Point3D *prev, Point3D *cur, int wind, int *prev_dir, double *dist1, double *dist2 )
|
||||
Point3D LinearFeature::OffsetPointLast( Point3D *prev, Point3D *cur, double offset_by )
|
||||
{
|
||||
double offset_dir;
|
||||
double az1, az2;
|
||||
double dist;
|
||||
double pt_x, pt_y;
|
||||
|
||||
printf("Find end angle for mark: prev(%lf,%lf), cur(%lf,%lf)\n", prev->x(), prev->y(), cur->x(), cur->y());
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "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);
|
||||
|
@ -416,135 +294,177 @@ double CalcEndMarkingVerticies( Point3D *prev, Point3D *cur, int wind, int *prev
|
|||
offset_dir += 360;
|
||||
}
|
||||
|
||||
printf("offset direction is %lf\n", offset_dir);
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "heading is " << offset_dir << " distance is " << offset_by );
|
||||
|
||||
// calculate correct distance for the offset point
|
||||
*dist1 = (-LINE_WIDTH);
|
||||
*dist2 = (LINE_WIDTH);
|
||||
// calculate the point from cur
|
||||
geo_direct_wgs_84( cur->y(), cur->x(), offset_dir, offset_by, &pt_y, &pt_x, &az2 );
|
||||
|
||||
return offset_dir;
|
||||
return Point3D(pt_x, pt_y, 0.0f);
|
||||
}
|
||||
|
||||
// TODO: Should Be AddMarkingVerticies - and handle offset (used in LinearFeature::Finish only)
|
||||
double CalcMarkingVerticies( Point3D *prev, Point3D *cur, Point3D *next, int wind, int *prev_dir, double *dist1, double *dist2 )
|
||||
|
||||
|
||||
int LinearFeature::Finish()
|
||||
{
|
||||
double offset_dir;
|
||||
|
||||
// first, we need to see if we want to average the directions (we have both prev, and next)
|
||||
if ( (prev->x() == 0.0f) && (prev->y() == 0.0f) )
|
||||
TGPolygon poly;
|
||||
TGSuperPoly sp;
|
||||
TGTexParams tp;
|
||||
Point3D prev_inner, prev_outer;
|
||||
Point3D cur_inner, cur_outer;
|
||||
double heading;
|
||||
double dist;
|
||||
double az2;
|
||||
int i, j;
|
||||
string material;
|
||||
|
||||
|
||||
// create the inner and outer boundaries to generate polys
|
||||
// this generates 2 point lists for the contours, and remembers
|
||||
// the start stop points for markings
|
||||
ConvertContour( &contour );
|
||||
|
||||
// now generate the supoerpoly and texparams list
|
||||
for (i=0; i<marks.size(); i++)
|
||||
{
|
||||
// direction is 90 degrees less than from current to next
|
||||
offset_dir = CalcStartMarkingVerticies( cur, next, wind, prev_dir, dist1, dist2 );
|
||||
printf("got dist 1: %lf, dist2: %lf\n", *dist1, *dist2);
|
||||
}
|
||||
else if ( (next->x() == 0.0f) && (next->y() == 0.0f) )
|
||||
{
|
||||
// direction is 90 degrees less than from current to next
|
||||
offset_dir = CalcEndMarkingVerticies( prev, cur, wind, prev_dir, dist1, dist2 );
|
||||
printf("got dist 1: %lf, dist2: %lf\n", *dist1, *dist2);
|
||||
}
|
||||
else
|
||||
{
|
||||
offset_dir = CalcMiddleMarkingVerticies( prev, cur, next, wind, prev_dir, dist1, dist2 );
|
||||
printf("got dist 1: %lf, dist2: %lf\n", *dist1, *dist2);
|
||||
}
|
||||
prev_inner = Point3D(0.0f, 0.0f, 0.0f);
|
||||
prev_outer = Point3D(0.0f, 0.0f, 0.0f);
|
||||
|
||||
printf("return from CalcMarkingVerticies: dirst1: %lf, dist2: %lf\n", *dist1, *dist2);
|
||||
|
||||
return offset_dir;
|
||||
}
|
||||
|
||||
// need to refactor this stuff.
|
||||
osg::Geode* FinishMarking( osg::Vec3dArray* verticies )
|
||||
{
|
||||
osg::Geometry* stripe = NULL;
|
||||
osg::Geode* geode_stripe = NULL;
|
||||
osg::StateSet* ss_stripe = NULL;
|
||||
osg::PolygonMode* polymode = NULL;
|
||||
osg::Vec4Array* col_stripe = NULL;
|
||||
int j;
|
||||
|
||||
// set up polygon offset
|
||||
osg::PolygonOffset* polyoffset = new osg::PolygonOffset;
|
||||
polyoffset->setFactor(-1.00f);
|
||||
polyoffset->setUnits(-1.00f);
|
||||
|
||||
polymode = new osg::PolygonMode;
|
||||
polymode->setMode( osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE );
|
||||
|
||||
col_stripe = new osg::Vec4Array;
|
||||
col_stripe->push_back(osg::Vec4(1.0f,1.0f,0.0f,1.0f));
|
||||
|
||||
// Create a new stripe geometry
|
||||
stripe = new osg::Geometry;
|
||||
stripe->setColorArray(col_stripe);
|
||||
stripe->setColorBinding(osg::Geometry::BIND_OVERALL);
|
||||
|
||||
ss_stripe = new osg::StateSet();
|
||||
ss_stripe->setAttributeAndModes(polyoffset,osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);
|
||||
#if WIREFRAME
|
||||
ss_stripe->setAttributeAndModes(polymode,osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);
|
||||
#endif
|
||||
geode_stripe = new osg::Geode();
|
||||
geode_stripe->setStateSet(ss_stripe);
|
||||
|
||||
stripe->setVertexArray(verticies);
|
||||
|
||||
// create the index array for the stripe
|
||||
osg::DrawElementsUShort& drawElements = *(new osg::DrawElementsUShort(GL_TRIANGLE_STRIP,verticies->size()));
|
||||
|
||||
for (j=0; j<verticies->size(); j++)
|
||||
{
|
||||
drawElements[j] = j;
|
||||
}
|
||||
|
||||
for (int k=0; k<j; k++)
|
||||
{
|
||||
printf("index %d is %d\n", k, drawElements[k]);
|
||||
}
|
||||
|
||||
stripe->addPrimitiveSet(&drawElements);
|
||||
|
||||
geode_stripe->addDrawable(stripe);
|
||||
|
||||
return geode_stripe;
|
||||
}
|
||||
|
||||
// TODO: Add this into Linear Feature
|
||||
osg::Vec3dArray* StartMarking()
|
||||
{
|
||||
osg::Vec3dArray* v_marking = new osg::Vec3dArray;
|
||||
|
||||
return v_marking;
|
||||
}
|
||||
|
||||
// TODO: move this into LinearFeature
|
||||
osg::Vec3dArray* CheckMarking(int cur_marking, int new_marking, osg::Vec3dArray* v_marking, osg::Group* airport)
|
||||
{
|
||||
// check if we need to finish a marking
|
||||
printf("Check Marking : current is %d, new is %d\n", cur_marking, new_marking);
|
||||
|
||||
if ( (v_marking != NULL) && (cur_marking != new_marking) )
|
||||
{
|
||||
printf("End current marking %d and start new marking %d : mark poly has %d verticies\n", cur_marking, new_marking, v_marking->size() );
|
||||
for (int k=0; k<v_marking->size(); k++)
|
||||
// which material for this mark?
|
||||
switch( marks[i]->type )
|
||||
{
|
||||
printf("vertex %d is (%lf, %lf)\n", k, v_marking->at(k).x(), v_marking->at(k).y());
|
||||
case LF_NONE:
|
||||
case LF_SOLID_YELLOW:
|
||||
case LF_BROKEN_YELLOW:
|
||||
case LF_SOLID_DBL_YELLOW:
|
||||
case LF_RUNWAY_HOLD:
|
||||
case LF_OTHER_HOLD:
|
||||
case LF_ILS_HOLD:
|
||||
case LF_SAFETYZONE_CENTERLINE:
|
||||
case LF_SINGLE_LANE_QUEUE:
|
||||
case LF_DOUBLE_LANE_QUEUE:
|
||||
|
||||
case LF_B_SOLID_YELLOW:
|
||||
case LF_B_BROKEN_YELLOW:
|
||||
case LF_B_SOLID_DBL_YELLOW:
|
||||
case LF_B_RUNWAY_HOLD:
|
||||
case LF_B_OTHER_HOLD:
|
||||
case LF_B_ILS_HOLD:
|
||||
case LF_B_SAFETYZONE_CENTERLINE:
|
||||
case LF_B_SINGLE_LANE_QUEUE:
|
||||
case LF_B_DOUBLE_LANE_QUEUE:
|
||||
|
||||
case LF_SOLID_WHITE:
|
||||
case LF_CHECKERBOARD_WHITE:
|
||||
case LF_BROKEN_WHITE:
|
||||
|
||||
case LF_BIDIR_GREEN:
|
||||
case LF_OMNIDIR_BLUE:
|
||||
case LF_UNIDIR_CLOSE_AMBER:
|
||||
case LF_UNIDIR_CLOSE_AMBER_PULSE:
|
||||
case LF_BIDIR_GREEN_AMBER:
|
||||
case LF_OMNIDIR_RED:
|
||||
material = "gloff_lf_b_solid_yellow";
|
||||
break;
|
||||
|
||||
default:
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "ClosedPoly::BuildBtg: unknown material " << marks[i]->type );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// END THE CURRENT MARKING
|
||||
airport->addChild(FinishMarking( v_marking ) );
|
||||
v_marking = NULL;
|
||||
}
|
||||
|
||||
// Start recording a new marking
|
||||
if ( (v_marking == NULL) && (new_marking != 0) )
|
||||
{
|
||||
// start a new marking
|
||||
printf("Start new marking %d\n", new_marking);
|
||||
|
||||
v_marking = StartMarking();
|
||||
}
|
||||
for (j = marks[i]->start_idx; j < marks[i]->end_idx; j++)
|
||||
{
|
||||
// for each point on the PointsList, generate a quad from
|
||||
// start to next, offset by 2 distnaces from the edge
|
||||
|
||||
return v_marking;
|
||||
if (j == 0)
|
||||
{
|
||||
// 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 );
|
||||
}
|
||||
else if (j == points.size()-1)
|
||||
{
|
||||
// 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 );
|
||||
}
|
||||
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 );
|
||||
}
|
||||
|
||||
if ( (prev_inner.x() != 0.0f) && (prev_inner.y() != 0.0f) )
|
||||
{
|
||||
geo_inverse_wgs_84( prev_outer.y(), prev_outer.x(), cur_outer.y(), cur_outer.x(), &heading, &az2, &dist);
|
||||
|
||||
poly.erase();
|
||||
poly.add_node( 0, prev_outer );
|
||||
poly.add_node( 0, prev_inner );
|
||||
poly.add_node( 0, cur_inner );
|
||||
poly.add_node( 0, cur_outer );
|
||||
|
||||
sp.erase();
|
||||
sp.set_poly( poly );
|
||||
sp.set_material( material );
|
||||
feature_polys.push_back(sp);
|
||||
|
||||
tp = TGTexParams( prev_inner, 0.1, 1.0, heading );
|
||||
feature_tps.push_back(tp);
|
||||
}
|
||||
|
||||
prev_outer = cur_outer;
|
||||
prev_inner = cur_inner;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int LinearFeature::BuildBtg(float alt_m, superpoly_list* line_polys, texparams_list* line_tps, TGPolygon* line_accum )
|
||||
{
|
||||
string material;
|
||||
int j, k;
|
||||
|
||||
#if 0
|
||||
|
||||
// verify the poly has been generated
|
||||
if ( pre_tess.contours() )
|
||||
{
|
||||
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 );
|
||||
|
||||
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");
|
||||
|
||||
TGPolygon split = tgPolygonSplitLongEdges( clipped, 400.0 );
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "BuildBtg: split poly has " << split.contours() << " contours");
|
||||
|
||||
sp.erase();
|
||||
sp.set_poly( split );
|
||||
sp.set_material( material );
|
||||
sp.set_flag("taxi");
|
||||
|
||||
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 );
|
||||
}
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,49 @@
|
|||
|
||||
using std::string;
|
||||
|
||||
|
||||
#define LF_NONE (0)
|
||||
#define LF_SOLID_YELLOW (1)
|
||||
#define LF_BROKEN_YELLOW (2)
|
||||
#define LF_SOLID_DBL_YELLOW (3)
|
||||
#define LF_RUNWAY_HOLD (4)
|
||||
#define LF_OTHER_HOLD (5)
|
||||
#define LF_ILS_HOLD (6)
|
||||
#define LF_SAFETYZONE_CENTERLINE (7)
|
||||
#define LF_SINGLE_LANE_QUEUE (8)
|
||||
#define LF_DOUBLE_LANE_QUEUE (9)
|
||||
|
||||
#define LF_B_SOLID_YELLOW (51)
|
||||
#define LF_B_BROKEN_YELLOW (52)
|
||||
#define LF_B_SOLID_DBL_YELLOW (53)
|
||||
#define LF_B_RUNWAY_HOLD (54)
|
||||
#define LF_B_OTHER_HOLD (55)
|
||||
#define LF_B_ILS_HOLD (56)
|
||||
#define LF_B_SAFETYZONE_CENTERLINE (57)
|
||||
#define LF_B_SINGLE_LANE_QUEUE (58)
|
||||
#define LF_B_DOUBLE_LANE_QUEUE (59)
|
||||
|
||||
#define LF_SOLID_WHITE (20)
|
||||
#define LF_CHECKERBOARD_WHITE (21)
|
||||
#define LF_BROKEN_WHITE (22)
|
||||
|
||||
#define LF_BIDIR_GREEN (101)
|
||||
#define LF_OMNIDIR_BLUE (102)
|
||||
#define LF_UNIDIR_CLOSE_AMBER (103)
|
||||
#define LF_UNIDIR_CLOSE_AMBER_PULSE (104)
|
||||
#define LF_BIDIR_GREEN_AMBER (105)
|
||||
#define LF_OMNIDIR_RED (106)
|
||||
|
||||
struct Marking
|
||||
{
|
||||
public:
|
||||
int type;
|
||||
int start_idx;
|
||||
int end_idx;
|
||||
};
|
||||
typedef std::vector <Marking*> MarkingList;
|
||||
|
||||
|
||||
class LinearFeature
|
||||
{
|
||||
public:
|
||||
|
@ -24,40 +67,45 @@ public:
|
|||
{
|
||||
strcpy( description, "none" );
|
||||
}
|
||||
|
||||
offset = 0.0f;
|
||||
closed = false;
|
||||
}
|
||||
|
||||
|
||||
void AddNode( BezNode* b )
|
||||
{
|
||||
contour.push_back( b );
|
||||
}
|
||||
|
||||
void SetClosed()
|
||||
{
|
||||
closed = true;
|
||||
}
|
||||
int Finish();
|
||||
int BuildOsg( osg::Group* airport );
|
||||
int BuildBtg( float alt_m, superpoly_list* line_polys, texparams_list* line_tps, TGPolygon* line_accum );
|
||||
|
||||
int Finish( osg::Group* airport );
|
||||
int BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list* texparams, TGPolygon* accum, TGPolygon* apt_base, TGPolygon* apt_clearing );
|
||||
|
||||
private:
|
||||
Point3D OffsetPointFirst( Point3D *cur, Point3D *next, double offset_by );
|
||||
Point3D OffsetPointMiddle( Point3D *prev, Point3D *cur, Point3D *next, double offset_by );
|
||||
Point3D OffsetPointLast( Point3D *prev, Point3D *cur, double offset_by );
|
||||
|
||||
MarkingList marks;
|
||||
Marking* cur_mark;
|
||||
|
||||
void ConvertContour( BezContour* src );
|
||||
|
||||
// text description
|
||||
char description[256];
|
||||
|
||||
// contour definition
|
||||
// contour definition (each beznode has marking type)
|
||||
BezContour contour;
|
||||
|
||||
// TODO : Implement offset
|
||||
double offset;
|
||||
|
||||
bool closed;
|
||||
// contour definition after bezier interpolation
|
||||
point_list points;
|
||||
|
||||
superpoly_list feature_polys;
|
||||
texparams_list feature_tps;
|
||||
};
|
||||
|
||||
typedef std::vector <LinearFeature *> FeatureList;
|
||||
|
||||
// add this to the class
|
||||
extern double CalcMarkingVerticies( Point3D *prev, Point3D *cur, Point3D *next, int wind, int *prev_dir, double *dist1, double *dist2 );
|
||||
|
||||
extern double CalcMarkingVerticies( Point3D *prev, Point3D *cur, Point3D *next, double *dist1, double *dist2 );
|
||||
|
||||
// don't know what to do with these
|
||||
extern osg::Geode* FinishMarking( osg::Vec3dArray* verticies );
|
||||
|
|
Loading…
Reference in a new issue