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

View file

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

View file

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

View file

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

View file

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

View file

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