1
0
Fork 0

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:
PSadrozinski 2011-09-21 20:00:11 -04:00 committed by Christian Schmitt
parent 7d729633c1
commit 47b1b05ac7
6 changed files with 645 additions and 518 deletions

View file

@ -189,7 +189,6 @@ static point_list calc_elevations( TGAptSurface &surf,
return result; return result;
} }
// Determine node elevations of each node of a TGPolygon based on the // Determine node elevations of each node of a TGPolygon based on the
// provided TGAptSurface. Offset is added to the final elevation // provided TGAptSurface. Offset is added to the final elevation
static TGPolygon calc_elevations( TGAptSurface &surf, 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_base;
TGPolygon apt_clearing; TGPolygon apt_clearing;
TGPolygon accum; TGPolygon accum;
accum.erase(); accum.erase();
TGPolygon line_accum;
line_accum.erase();
// runways
superpoly_list rwy_polys; 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; int i, j, k;
char buf[120]; // For debugging output char buf[120]; // For debugging output
Point3D p; Point3D p;
@ -226,8 +238,6 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
// Find the average of all the runway long / lats // Find the average of all the runway long / lats
// TODO : Need runway object... // TODO : Need runway object...
for (i=0; i<runways.size(); i++) for (i=0; i<runways.size(); i++)
{ {
printf("runway %d from (%lf,%lf) to (%lf,%lf) : midpoint is (%lf,%lf)\n", 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() ) 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()) if (pavements.size())
{ {
for ( i=0; i<pavements.size(); i++ ) for ( i=0; i<pavements.size(); i++ )
{ {
SG_LOG(SG_GENERAL, SG_ALERT, "Build Pavement Poly " << 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 else
{ {
SG_LOG(SG_GENERAL, SG_ALERT, "no pavements"); SG_LOG(SG_GENERAL, SG_ALERT, "no pavements");
} }
// wipe out the pavements to save memory // wipe out the pavements to save memory
pavements.clear(); pavements.clear();
// Then the linear features // 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 ) 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 divided_base = tgPolygonSplitLongEdges( filled_base, 200.0 );
TGPolygon base_poly = tgPolygonDiff( divided_base, accum ); 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" // add segments to polygons to remove any possible "T"
// intersections // intersections
TGTriNodes tmp_nodes; TGTriNodes tmp_nodes;
// build temporary node list // build temporary node list from runways...
for ( k = 0; k < (int)rwy_polys.size(); ++k ) for ( k = 0; k < (int)rwy_polys.size(); ++k )
{ {
TGPolygon poly = rwy_polys[k].get_poly(); 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 ( i = 0; i < base_poly.contours(); ++i )
{ {
for ( j = 0; j < base_poly.contour_size( i ); ++j ) 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 ) for ( k = 0; k < (int)rwy_polys.size(); ++k )
{ {
TGPolygon poly = rwy_polys[k].get_poly(); 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 ); 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 // One more pass to try to get rid of other yukky stuff
for ( k = 0; k < (int)rwy_polys.size(); ++k ) 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 ); 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, "add nodes base ");
SG_LOG(SG_GENERAL, SG_DEBUG, " before: " << base_poly); SG_LOG(SG_GENERAL, SG_DEBUG, " before: " << base_poly);
SG_LOG(SG_GENERAL, SG_DEBUG, " tmp_nodes size = " << tmp_nodes.get_node_list().size()); 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()); SG_LOG(SG_GENERAL, SG_DEBUG, "total size after = " << tri.total_size());
TGPolygon tc; TGPolygon tc;
if ( rwy_polys[i].get_flag() == "taxi" ) tc = rwy_section_tex_coords( tri, rwy_tps[i], true );
{
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 );
}
rwy_polys[i].set_tris( tri ); rwy_polys[i].set_tris( tri );
rwy_polys[i].set_texcoords( tc ); 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"); SG_LOG(SG_GENERAL, SG_DEBUG, "Tesselating base");
TGPolygon base_tris = polygon_tesselate_alt( base_poly ); 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 // add base points
std::vector< SGVec2f > base_txs; std::vector< SGVec2f > base_txs;
int_list base_tc; int_list base_tc;

View file

@ -30,6 +30,14 @@ public:
features.push_back( feature ); 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 BuildOsg( osg::Group* airport );
void BuildBtg( const string& root, const string_list& elev_src ); void BuildBtg( const string& root, const string_list& elev_src );

View file

@ -45,6 +45,10 @@ void ClosedPoly::AddNode( BezNode* node )
cur_contour->push_back( node ); cur_contour->push_back( node );
SG_LOG(SG_GENERAL, SG_DEBUG, "CLOSEDPOLY::ADDNODE : (" << node->GetLoc().x() << "," << node->GetLoc().y() << ")"); 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 // if recording a linear feature on the pavement, add this node
// to it as well // to it as well
// TODO: just doing marking now, need lighting 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 // TODO: With offset, as all pavement markings should be
// a bit in from the edge // a bit in from the edge
SG_LOG(SG_GENERAL, SG_DEBUG, " Starting a new linear feature"); 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_feat->AddNode( node );
cur_marking = node->GetMarking(); 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* prevNode;
BezNode* curNode; BezNode* curNode;
@ -151,19 +155,6 @@ void ClosedPoly::ConvertContour( BezContour* src, point_list *dst, bool reverse
// clear anything in this point list // clear anything in this point list
dst->empty(); 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 // iterate through each bezier node in the contour
for (i=0; i <= src->size()-1; i++) for (i=0; i <= src->size()-1; i++)
{ {
@ -486,7 +477,7 @@ int ClosedPoly::Finish()
if (boundary != NULL) if (boundary != NULL)
{ {
// create the boundary // create the boundary
ConvertContour( boundary, &dst_contour, false ); ConvertContour( boundary, &dst_contour );
// and add it to the geometry // and add it to the geometry
pre_tess.add_contour( dst_contour, 0 ); pre_tess.add_contour( dst_contour, 0 );
@ -495,7 +486,7 @@ int ClosedPoly::Finish()
for (int i=0; i<holes.size(); i++) for (int i=0; i<holes.size(); i++)
{ {
dst_contour.clear(); dst_contour.clear();
ConvertContour( holes[i], &dst_contour, false ); ConvertContour( holes[i], &dst_contour );
pre_tess.add_contour( dst_contour, 1 ); pre_tess.add_contour( dst_contour, 1 );
} }
} }

View file

@ -26,11 +26,16 @@ public:
int BuildOsg( osg::Group* airport ); 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 ); 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: private:
//osg::DrawArrays* CreatePrimitive( BezContour* contour, osg::Vec3Array* v_pave ); //osg::DrawArrays* CreatePrimitive( BezContour* contour, osg::Vec3Array* v_pave );
// convert the BezierPoly to a normal Poly (adding nodes for the curves) // convert the BezierPoly to a normal Poly (adding nodes for the curves)
void CreateConvexHull( void ); 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 ); osg::DrawArrays* CreateOsgPrimitive( point_list contour, osg::Vec3Array* vpave );
void ExpandContour( point_list& src, TGPolygon& dst, double dist ); void ExpandContour( point_list& src, TGPolygon& dst, double dist );

View file

@ -1,6 +1,4 @@
#include "beznode.hxx" #include <stdlib.h>
#include "linearfeature.hxx"
#include "math.h"
#include <simgear/math/sg_geodesy.hxx> #include <simgear/math/sg_geodesy.hxx>
#include <simgear/math/SGVec3.hxx> #include <simgear/math/SGVec3.hxx>
@ -12,375 +10,254 @@
#include <osg/PolygonMode> #include <osg/PolygonMode>
#include <osg/PolygonOffset> #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; BezNode* prevNode;
int i, j; BezNode* curNode;
int prev_dir = 0; BezNode* nextNode;
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;
Point3D prevLoc; Point3D prevLoc;
Point3D curLoc; Point3D curLoc;
Point3D nextLoc; Point3D nextLoc;
Point3D cp1;
Point3D cp2;
Point3D st_cur1; int curve_type = CURVE_LINEAR;
Point3D st_cur2; Marking* cur_mark = NULL;
double st_curx, st_cury, az2; int i;
// create a DrawElement for the stripe triangle strip SG_LOG(SG_GENERAL, SG_DEBUG, "Creating a contour with " << src->size() << " nodes");
int stripe_idx = 0;
int cur_marking = 0;
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 (i == 0)
{ {
// if closed, set prev node to last in the contour // set prev node to last in the contour, as all contours must be closed
if (closed) prevNode = src->at( src->size()-1 );
{
prevNode = contour.at( contour.size()-1 );
}
else
{
prevNode = NULL;
}
} }
else 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 else
{ {
// if closed, set next node to the first in the contour // for the last node, next is the first. as all contours are closed
if (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); // amrking has ended, or changed
} cur_mark->end_idx = points.size();
else marks.push_back(cur_mark);
{ cur_mark = NULL;
nextNode = 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) // 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 // once we start drawing the curve from cur to next, we can just remember the prev loc
if (prevNode) if (prevNode->HasNextCp())
{ {
if (prevNode->HasNextCp()) // curve from prev is cubic or quadratic
if(curNode->HasPrevCp())
{ {
// curve from prev is cubic or quadratic // curve from prev is cubic : calculate the last location on the curve
if(curNode->HasPrevCp()) prevLoc = CalculateCubicLocation( prevNode->GetLoc(), prevNode->GetNextCp(), curNode->GetPrevCp(), curNode->GetLoc(), (1.0f/BEZIER_DETAIL) * (BEZIER_DETAIL-1) );
{
// 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 else
{ {
// curve from prev is quadratic or linear // curve from prev is quadratic : use prev node next cp
if( curNode->HasPrevCp() ) prevLoc = CalculateQuadraticLocation( prevNode->GetLoc(), prevNode->GetNextCp(), curNode->GetLoc(), (1.0f/BEZIER_DETAIL) * (BEZIER_DETAIL-1) );
{
// 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 else
{ {
prevLoc = Point3D(0.0f, 0.0f, 0.0f); // curve from prev is quadratic or linear
} if( curNode->HasPrevCp() )
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() )
{ {
// next curve is cubic or quadratic // curve from prev is quadratic : calculate the last location on the curve
if( nextNode->HasPrevCp() ) prevLoc = CalculateQuadraticLocation( prevNode->GetLoc(), curNode->GetPrevCp(), curNode->GetLoc(), (1.0f/BEZIER_DETAIL) * (BEZIER_DETAIL-1) );
{
// 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 else
{ {
// next curve is quadratic or linear // curve from prev is linear : just use prev node location
if( nextNode->HasPrevCp() ) prevLoc = prevNode->GetLoc();
{ }
// curve is quadratic using next nodes cp as the cp }
curve_type = CURVE_QUADRATIC;
cp1 = nextNode->GetPrevCp(); // now determine how we will iterate from current node to next node
} if( curNode->HasNextCp() )
else {
{ // next curve is cubic or quadratic
// curve is linear if( nextNode->HasPrevCp() )
curve_type = CURVE_LINEAR; {
} // 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 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 // initialize current location
curLoc = curNode->GetLoc(); curLoc = curNode->GetLoc();
switch( curve_type ) if (curve_type != CURVE_LINEAR)
{ {
case CURVE_QUADRATIC: for (int p=0; p<BEZIER_DETAIL; p++)
case CURVE_CUBIC: {
for (int p=0; p<BEZIER_DETAIL; p++) // calculate next location
if (curve_type == CURVE_QUADRATIC)
{ {
// calculate next location nextLoc = CalculateQuadraticLocation( curNode->GetLoc(), cp1, nextNode->GetLoc(), (1.0f/BEZIER_DETAIL) * (p+1) );
if (curve_type == CURVE_QUADRATIC) }
{ else
nextLoc = CalculateQuadraticLocation( curNode->GetLoc(), cp1, nextNode->GetLoc(), (1.0f/BEZIER_DETAIL) * (p+1) ); {
} nextLoc = CalculateCubicLocation( curNode->GetLoc(), cp1, cp2, 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;
} }
break;
case CURVE_LINEAR: // add the feature vertex
nextLoc = nextNode->GetLoc(); 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... // now set set prev and cur locations for the next iteration
direction = CalcMarkingVerticies( &prevLoc, &curLoc, &nextLoc, -1, &prev_dir, &dist1, &dist2 ); 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. SG_LOG(SG_GENERAL, SG_DEBUG, "adding Linear Anchor node at (" << curLoc.x() << "," << curLoc.y() << ")");
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;
} }
} }
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 Point3D LinearFeature::OffsetPointMiddle( Point3D *prev, Point3D *cur, Point3D *next, double offset_by )
// 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 )
{ {
int turn_direction;
bool reverse_dir = false;
double offset_dir; double offset_dir;
double next_dir; double next_dir;
double az1, az2; double az1, az2;
double dist; 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 // 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. // 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 negetive, we've turned to the left
// if the cross product is positive, we've turned to the right // 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 // 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); dir1 = normalize(dir1);
printf("normalized dir1 is (%lf,%lf)\n", dir1.x(), dir1.y());
SGVec3d dir2 = next->toSGVec3d() - cur->toSGVec3d(); SGVec3d dir2 = next->toSGVec3d() - cur->toSGVec3d();
dir2 = normalize(dir2); 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 // Now find the average
SGVec3d avg = -dir1 + dir2; SGVec3d avg = dir1 + dir2;
avg = normalize(avg);
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);
// find the offset angle // find the offset angle
geo_inverse_wgs_84( 0.0f, 0.0f, avg.x(), avg.y(), &offset_dir, &az2, &dist); geo_inverse_wgs_84( 0.0f, 0.0f, avg.y(), avg.x(), &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);
// find the direction to the next point // find the direction to the next point
geo_inverse_wgs_84( cur->x(), cur->y(), next->x(), next->y(), &next_dir, &az2, &dist); geo_inverse_wgs_84( cur->y(), cur->x(), next->y(), next->x(), &next_dir, &az2, &dist);
printf("next direction is %lf\n", next_dir);
// calculate correct distance for the offset point // calculate correct distance for the offset point
*dist1 = (-LINE_WIDTH)/sin(SGMiscd::deg2rad(next_dir-offset_dir)); dist = (offset_by)/sin(SGMiscd::deg2rad(offset_dir-next_dir));
*dist2 = (LINE_WIDTH)/sin(SGMiscd::deg2rad(next_dir-offset_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) Point3D LinearFeature::OffsetPointFirst( Point3D *cur, Point3D *next, double offset_by )
double CalcStartMarkingVerticies( Point3D *cur, Point3D *next, int wind, int *prev_dir, double *dist1, double *dist2 )
{ {
double offset_dir; double offset_dir;
double az1, az2; double az1, az2;
double dist; 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 // 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->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; 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 // calculate the point from cur
*dist1 = (-LINE_WIDTH); geo_direct_wgs_84( cur->y(), cur->x(), offset_dir, offset_by, &pt_y, &pt_x, &az2 );
*dist2 = (LINE_WIDTH);
return offset_dir; return Point3D(pt_x, pt_y, 0.0f);
} }
// TODO: Should Be AddEndMarkingVerticies - and handle offset (used in LinearFeature::Finish only) // 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 offset_dir;
double az1, az2; double az1, az2;
double dist; 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 // 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->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; 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 // calculate the point from cur
*dist1 = (-LINE_WIDTH); geo_direct_wgs_84( cur->y(), cur->x(), offset_dir, offset_by, &pt_y, &pt_x, &az2 );
*dist2 = (LINE_WIDTH);
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; 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;
// 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) ) // 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 prev_inner = Point3D(0.0f, 0.0f, 0.0f);
offset_dir = CalcStartMarkingVerticies( cur, next, wind, prev_dir, dist1, dist2 ); prev_outer = Point3D(0.0f, 0.0f, 0.0f);
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);
}
printf("return from CalcMarkingVerticies: dirst1: %lf, dist2: %lf\n", *dist1, *dist2); // which material for this mark?
switch( marks[i]->type )
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++)
{ {
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 for (j = marks[i]->start_idx; j < marks[i]->end_idx; j++)
airport->addChild(FinishMarking( v_marking ) ); {
v_marking = NULL; // for each point on the PointsList, generate a quad from
// start to next, offset by 2 distnaces from the edge
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;
}
} }
}
// Start recording a new marking
if ( (v_marking == NULL) && (new_marking != 0) ) int LinearFeature::BuildBtg(float alt_m, superpoly_list* line_polys, texparams_list* line_tps, TGPolygon* line_accum )
{ {
// start a new marking string material;
printf("Start new marking %d\n", new_marking); int j, k;
v_marking = StartMarking(); #if 0
}
// verify the poly has been generated
return v_marking; 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;
} }

View file

@ -11,6 +11,49 @@
using std::string; 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 class LinearFeature
{ {
public: public:
@ -24,9 +67,6 @@ public:
{ {
strcpy( description, "none" ); strcpy( description, "none" );
} }
offset = 0.0f;
closed = false;
} }
void AddNode( BezNode* b ) void AddNode( BezNode* b )
@ -34,30 +74,38 @@ public:
contour.push_back( b ); contour.push_back( b );
} }
void SetClosed() int Finish();
{ int BuildOsg( osg::Group* airport );
closed = true; 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: 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]; char description[256];
// contour definition // contour definition (each beznode has marking type)
BezContour contour; BezContour contour;
// TODO : Implement offset // contour definition after bezier interpolation
double offset; point_list points;
bool closed; superpoly_list feature_polys;
texparams_list feature_tps;
}; };
typedef std::vector <LinearFeature *> FeatureList; typedef std::vector <LinearFeature *> FeatureList;
// add this to the class // 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 // don't know what to do with these
extern osg::Geode* FinishMarking( osg::Vec3dArray* verticies ); extern osg::Geode* FinishMarking( osg::Vec3dArray* verticies );