WS3.0 AirportBuilder update to use Effects.
This commit is contained in:
parent
c71fc5ae73
commit
2bb15866b8
2 changed files with 139 additions and 94 deletions
|
@ -26,21 +26,27 @@
|
||||||
#include <osgDB/Registry>
|
#include <osgDB/Registry>
|
||||||
#include <osgUtil/Tessellator>
|
#include <osgUtil/Tessellator>
|
||||||
#include <osgUtil/DelaunayTriangulator>
|
#include <osgUtil/DelaunayTriangulator>
|
||||||
#include "AirportBuilder.hxx"
|
|
||||||
|
|
||||||
#include <osg/Geode>
|
#include <osg/Geode>
|
||||||
#include <osg/Geometry>
|
#include <osg/Geometry>
|
||||||
|
|
||||||
#include <simgear/scene/material/Effect.hxx>
|
#include <simgear/scene/material/Effect.hxx>
|
||||||
#include <simgear/scene/material/EffectGeode.hxx>
|
#include <simgear/scene/material/EffectGeode.hxx>
|
||||||
#include "simgear/scene/model/ModelRegistry.hxx"
|
#include <simgear/scene/model/ModelRegistry.hxx>
|
||||||
#include "simgear/scene/util/OsgMath.hxx"
|
#include <simgear/scene/util/OsgMath.hxx>
|
||||||
#include "simgear/math/SGGeodesy.hxx"
|
#include <simgear/scene/util/SGReaderWriterOptions.hxx>
|
||||||
#include "airport.hxx"
|
#include <simgear/math/SGGeodesy.hxx>
|
||||||
|
|
||||||
#include <Airports/apt_loader.hxx>
|
#include <Airports/apt_loader.hxx>
|
||||||
|
#include "airport.hxx"
|
||||||
#include "runways.hxx"
|
#include "runways.hxx"
|
||||||
#include "pavement.hxx"
|
#include "pavement.hxx"
|
||||||
|
|
||||||
|
#include "AirportBuilder.hxx"
|
||||||
|
|
||||||
|
using namespace osg;
|
||||||
|
using namespace simgear;
|
||||||
|
|
||||||
namespace flightgear
|
namespace flightgear
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -58,66 +64,76 @@ const char* AirportBuilder::className() const
|
||||||
return "Airport Builder";
|
return "Airport Builder";
|
||||||
}
|
}
|
||||||
|
|
||||||
osgDB::ReaderWriter::ReadResult
|
osgDB::ReaderWriter::ReadResult AirportBuilder::readNode(const std::string& fileName,
|
||||||
AirportBuilder::readNode(const std::string& fileName,
|
const osgDB::Options* options) const
|
||||||
const osgDB::Options* options) const
|
|
||||||
{
|
{
|
||||||
const SGPath aptFile = SGPath(fileName);
|
SGPath aptFile = SGPath(fileName);
|
||||||
const string airportId = aptFile.file_base();
|
|
||||||
|
|
||||||
|
if (! aptFile.isFile()) {
|
||||||
|
// Search for the file if we don't have a full path.
|
||||||
|
auto pathList = options->getDatabasePathList();
|
||||||
|
for(auto itr = pathList.begin(); itr != pathList.end(); ++itr) {
|
||||||
|
aptFile = SGPath(*itr, fileName);
|
||||||
|
if (aptFile.isFile()) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! aptFile.isFile()) return ReadResult::FILE_NOT_HANDLED;;
|
||||||
|
|
||||||
|
const string airportId = aptFile.file_base();
|
||||||
APTLoader aptLoader;
|
APTLoader aptLoader;
|
||||||
|
|
||||||
const FGAirport* airport = aptLoader.loadAirportFromFile(airportId, aptFile);
|
const FGAirport* airport = aptLoader.loadAirportFromFile(airportId, aptFile);
|
||||||
if (! airport) return ReadResult::FILE_NOT_HANDLED;;
|
if (! airport) return ReadResult::FILE_NOT_HANDLED;
|
||||||
|
|
||||||
std::cout << "AirportBuilder, building airport : " << airportId << " " << airport->getName() << "\n";
|
SG_LOG( SG_GENERAL, SG_DEBUG, "Building airport : " << airportId << " " << airport->getName());
|
||||||
std::cout << "Elevation : " << airport->getElevation() << "ft\n";
|
SG_LOG( SG_GENERAL, SG_DEBUG, "Lat/Lon : " << airport->getLatitude() << ", " << airport->getLongitude());
|
||||||
std::cout << "Latitude : " << airport->getLatitude() << "ft\n";
|
SG_LOG( SG_GENERAL, SG_DEBUG, "Elevation : " << airport->getElevation());
|
||||||
std::cout << "Longitude : " << airport->getLongitude() << "ft\n";
|
SG_LOG( SG_GENERAL, SG_DEBUG, "Runways : " << airport->numRunways());
|
||||||
|
SG_LOG( SG_GENERAL, SG_DEBUG, "Helipads : " << airport->numHelipads());
|
||||||
std::cout << "Runways : " << airport->numRunways() << "\n";
|
SG_LOG( SG_GENERAL, SG_DEBUG, "Taxiways : " << airport->numTaxiways());
|
||||||
std::cout << "Helipads : " << airport->numHelipads() << "\n";
|
SG_LOG( SG_GENERAL, SG_DEBUG, "Pavements : " << airport->numPavements());
|
||||||
std::cout << "Taxiways : " << airport->numTaxiways() << "\n";
|
SG_LOG( SG_GENERAL, SG_DEBUG, "Line Features : " << airport->numLineFeatures());
|
||||||
std::cout << "Pavements : " << airport->numPavements() << "\n";
|
|
||||||
std::cout << "Line Features : " << airport->numLineFeatures() << "\n";
|
|
||||||
|
|
||||||
const SGVec3f center = SGVec3f::fromGeod(airport->geod());
|
const SGVec3f center = SGVec3f::fromGeod(airport->geod());
|
||||||
const SGVec3f offset = SGVec3f::fromGeod(SGGeod::fromGeodM(airport->geod(), airport->geod().getElevationM() + 1.0));
|
|
||||||
const osg::Vec3f up = osg::Vec3f(toOsg(offset - center));
|
|
||||||
|
|
||||||
|
// Create a matrix operation that will center the airport facing the z axis
|
||||||
|
// We cannot also perform the translate to the center of the airport as we
|
||||||
|
// hit floating point precision issues, so we do that separately.
|
||||||
|
osg::Matrixd mat = osg::Matrix(toOsg(SGQuatd::fromLonLat(airport->geod())));
|
||||||
|
mat.preMultRotate(osg::Quat(0.0, 1.0, 0.0, 0.0));
|
||||||
|
|
||||||
std::vector<osg::Node*> nodeList;
|
std::vector<osg::Node*> nodeList;
|
||||||
osg::Group* group = new osg::Group();
|
osg::Group* group = new osg::Group();
|
||||||
|
|
||||||
// Build the various components
|
|
||||||
auto runwaylist = airport->getRunways();
|
|
||||||
std::for_each( runwaylist.begin(),
|
|
||||||
runwaylist.end(),
|
|
||||||
[&, center] (FGRunwayRef p) { group->addChild(this->createRunway(center, up, p)); } );
|
|
||||||
|
|
||||||
|
|
||||||
// Build the pavements
|
|
||||||
auto pavementlist = airport->getPavements();
|
|
||||||
std::for_each( pavementlist.begin(),
|
|
||||||
pavementlist.end(),
|
|
||||||
[&, center, up] (FGPavementRef p) { group->addChild(this->createPavement(center, up, p)); } );
|
|
||||||
|
|
||||||
// Build the boundary
|
// Build the boundary
|
||||||
auto boundaryList = airport->getBoundary();
|
auto boundaryList = airport->getBoundary();
|
||||||
std::for_each( boundaryList.begin(),
|
std::for_each( boundaryList.begin(),
|
||||||
boundaryList.end(),
|
boundaryList.end(),
|
||||||
[&, center] (FGPavementRef p) { group->addChild(this->createBoundary(center, up, p)); } );
|
[&, mat, center, options] (FGPavementRef p) { group->addChild(this->createBoundary(mat, center, p, options)); } );
|
||||||
|
|
||||||
|
// Build the pavements
|
||||||
|
auto pavementlist = airport->getPavements();
|
||||||
|
std::for_each( pavementlist.begin(),
|
||||||
|
pavementlist.end(),
|
||||||
|
[&, mat, center, options] (FGPavementRef p) { group->addChild(this->createPavement(mat, center, p, options)); } );
|
||||||
|
|
||||||
|
// Build the runways
|
||||||
|
auto runwaylist = airport->getRunways();
|
||||||
|
std::for_each( runwaylist.begin(),
|
||||||
|
runwaylist.end(),
|
||||||
|
[&, mat, center, options] (FGRunwayRef p) { group->addChild(this->createRunway(mat, center, p, options)); } );
|
||||||
|
|
||||||
// Build line features
|
// Build line features
|
||||||
auto lineList = airport->getLineFeatures();
|
auto lineList = airport->getLineFeatures();
|
||||||
std::for_each( lineList.begin(),
|
std::for_each( lineList.begin(),
|
||||||
lineList.end(),
|
lineList.end(),
|
||||||
[&, center] (FGPavementRef p) { group->addChild(this->createLine(center, up, p)); } );
|
[&, mat, center, options] (FGPavementRef p) { group->addChild(this->createLine(mat, center, p, options)); } );
|
||||||
|
|
||||||
return group;
|
return group;
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::Node* AirportBuilder::createRunway(const SGVec3f center, const osg::Vec3f up, const FGRunwayRef runway) const
|
osg::Node* AirportBuilder::createRunway(const osg::Matrixd mat, const SGVec3f center, const FGRunwayRef runway, const osgDB::Options* options) const
|
||||||
{
|
{
|
||||||
std::vector<SGGeod> nodes;
|
std::vector<SGGeod> nodes;
|
||||||
nodes.push_back(runway->pointOffCenterline(0.0, -0.5 * runway->widthM()));
|
nodes.push_back(runway->pointOffCenterline(0.0, -0.5 * runway->widthM()));
|
||||||
|
@ -130,7 +146,9 @@ osg::Node* AirportBuilder::createRunway(const SGVec3f center, const osg::Vec3f u
|
||||||
std::transform( nodes.begin(),
|
std::transform( nodes.begin(),
|
||||||
nodes.end(),
|
nodes.end(),
|
||||||
std::back_inserter(*points),
|
std::back_inserter(*points),
|
||||||
[center](SGGeod n) { return toOsg(SGVec3f::fromGeod(SGGeod::fromGeodM(n, n.getElevationM() + RUNWAY_OFFSET)) - center); }
|
[mat, center](SGGeod n) {
|
||||||
|
return mat * toOsg(SGVec3f::fromGeod(n) - center) + osg::Vec3f(0,0, RUNWAY_OFFSET);
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
osg::ref_ptr<osgUtil::DelaunayTriangulator> triangulator = new osgUtil::DelaunayTriangulator;
|
osg::ref_ptr<osgUtil::DelaunayTriangulator> triangulator = new osgUtil::DelaunayTriangulator;
|
||||||
|
@ -142,26 +160,26 @@ osg::Node* AirportBuilder::createRunway(const SGVec3f center, const osg::Vec3f u
|
||||||
geometry->addPrimitiveSet(triangulator->getTriangles()); // triangles with constraint cut
|
geometry->addPrimitiveSet(triangulator->getTriangles()); // triangles with constraint cut
|
||||||
|
|
||||||
osg::Vec3Array* n = new osg::Vec3Array;
|
osg::Vec3Array* n = new osg::Vec3Array;
|
||||||
n->push_back(up);
|
n->push_back(osg::Vec3f(0.0f, 0.0f, 1.0f));
|
||||||
|
|
||||||
osg::Vec4Array* c = new osg::Vec4Array;
|
osg::Vec4Array* c = new osg::Vec4Array;
|
||||||
c->push_back(osg::Vec4f(0.2f,0.2f,0.2f,1.0f));
|
c->push_back(osg::Vec4f(1.0f, 1.0f, 1.0f, 1.0f));
|
||||||
|
|
||||||
geometry->setColorArray(c, osg::Array::BIND_OVERALL);
|
geometry->setColorArray(c, osg::Array::BIND_OVERALL);
|
||||||
geometry->setNormalArray(n, osg::Array::BIND_OVERALL);
|
geometry->setNormalArray(n, osg::Array::BIND_OVERALL);
|
||||||
|
|
||||||
simgear::EffectGeode* geode = new simgear::EffectGeode;
|
EffectGeode* geode = new EffectGeode;
|
||||||
|
ref_ptr<Effect> effect = getMaterialEffect("pa_rest", options);
|
||||||
|
geode->setEffect(effect.get());
|
||||||
geode->addDrawable(geometry);
|
geode->addDrawable(geometry);
|
||||||
//geode->setEffect(_effect.get());
|
|
||||||
|
|
||||||
return geode;
|
return geode;
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::Node* AirportBuilder::createPavement(const SGVec3f center, const osg::Vec3f up, const FGPavementRef pavement) const
|
osg::Node* AirportBuilder::createPavement(const osg::Matrixd mat, const SGVec3f center, const FGPavementRef pavement, const osgDB::Options* options) const
|
||||||
{
|
{
|
||||||
const FGPavement::NodeList nodes = pavement->getNodeList();
|
const FGPavement::NodeList nodes = pavement->getNodeList();
|
||||||
|
if (nodes.size() < 2) return NULL;
|
||||||
if (nodes.size() == 0) return NULL;
|
|
||||||
|
|
||||||
osg::ref_ptr<osgUtil::Tessellator> tessellator = new osgUtil::Tessellator;
|
osg::ref_ptr<osgUtil::Tessellator> tessellator = new osgUtil::Tessellator;
|
||||||
tessellator->setBoundaryOnly(false);
|
tessellator->setBoundaryOnly(false);
|
||||||
|
@ -169,7 +187,7 @@ osg::Node* AirportBuilder::createPavement(const SGVec3f center, const osg::Vec3f
|
||||||
tessellator->beginContour();
|
tessellator->beginContour();
|
||||||
|
|
||||||
// Track the previous vertex for bezier curve generation.
|
// Track the previous vertex for bezier curve generation.
|
||||||
osg::Vec3f* previous;
|
osg::Vec3f* previous = NULL;
|
||||||
|
|
||||||
// Bezier control. Bezier curve is node n-1 -> n -> n+1 so need to store for
|
// Bezier control. Bezier curve is node n-1 -> n -> n+1 so need to store for
|
||||||
// handling the next node in addition to generating for the BezierNode itself.
|
// handling the next node in addition to generating for the BezierNode itself.
|
||||||
|
@ -180,19 +198,18 @@ osg::Node* AirportBuilder::createPavement(const SGVec3f center, const osg::Vec3f
|
||||||
for (; itr < nodes.end(); ++itr) {
|
for (; itr < nodes.end(); ++itr) {
|
||||||
FGPavement::NodeBase* node = *itr;
|
FGPavement::NodeBase* node = *itr;
|
||||||
|
|
||||||
// Create an offset so we can easily layer the boundary, pavement, lights and runways
|
osg::Vec3f* v = new osg::Vec3f(mat * toOsg(SGVec3f::fromGeod(node->mPos) - center) + osg::Vec3f(0,0, PAVEMENT_OFFSET));
|
||||||
SGGeod offset = SGGeod::fromGeodM(node->mPos, node->mPos.getElevationM() + PAVEMENT_OFFSET);
|
|
||||||
osg::Vec3f* v = new osg::Vec3f(toOsg(SGVec3f::fromGeod(offset) - center));
|
|
||||||
|
|
||||||
if (FGPavement::BezierNode *bez = dynamic_cast<FGPavement::BezierNode*>(node)) {
|
if (FGPavement::BezierNode *bez = dynamic_cast<FGPavement::BezierNode*>(node)) {
|
||||||
// Store the bezier control node for generation when we know the next node.
|
// Store the bezier control node for generation when we know the next node.
|
||||||
SGGeod controlGeod = SGGeod::fromGeodM(bez->mControl, bez->mControl.getElevationM() + PAVEMENT_OFFSET);
|
control = mat * toOsg(SGVec3f::fromGeod(bez->mControl) - center) + osg::Vec3f(0,0, PAVEMENT_OFFSET);
|
||||||
control = osg::Vec3f(toOsg(SGVec3f::fromGeod(controlGeod) - center));
|
|
||||||
bezier = true;
|
bezier = true;
|
||||||
|
|
||||||
// Generate from the last node to this one, reflecting the control point
|
// Generate from the last node to this one, reflecting the control point
|
||||||
for (float t = 0.05f; t < 0.95f; t += 0.05f ) {
|
for (float t = 0.05f; t < 0.95f; t += 0.05f ) {
|
||||||
osg::Vec3f p0 = *previous;
|
|
||||||
|
osg::Vec3f p0 = osg::Vec3f();
|
||||||
|
if (previous != NULL) p0 = *previous;
|
||||||
osg::Vec3f p1 = *v + *v - control;
|
osg::Vec3f p1 = *v + *v - control;
|
||||||
osg::Vec3f p2 = *v;
|
osg::Vec3f p2 = *v;
|
||||||
|
|
||||||
|
@ -225,8 +242,6 @@ osg::Node* AirportBuilder::createPavement(const SGVec3f center, const osg::Vec3f
|
||||||
// SimpleNode
|
// SimpleNode
|
||||||
tessellator->addVertex(v);
|
tessellator->addVertex(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
previous = v;
|
previous = v;
|
||||||
if (node->mClose) {
|
if (node->mClose) {
|
||||||
tessellator->endContour();
|
tessellator->endContour();
|
||||||
|
@ -242,6 +257,8 @@ osg::Node* AirportBuilder::createPavement(const SGVec3f center, const osg::Vec3f
|
||||||
osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry;
|
osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry;
|
||||||
auto primList = tessellator->getPrimList();
|
auto primList = tessellator->getPrimList();
|
||||||
osg::Vec3Array* points = new osg::Vec3Array();
|
osg::Vec3Array* points = new osg::Vec3Array();
|
||||||
|
osg::Vec3Array* normals = new osg::Vec3Array();
|
||||||
|
osg::Vec2Array* texCoords = new osg::Vec2Array();
|
||||||
geometry->setVertexArray(points);
|
geometry->setVertexArray(points);
|
||||||
unsigned int idx = 0;
|
unsigned int idx = 0;
|
||||||
auto primItr = primList.begin();
|
auto primItr = primList.begin();
|
||||||
|
@ -249,30 +266,33 @@ osg::Node* AirportBuilder::createPavement(const SGVec3f center, const osg::Vec3f
|
||||||
auto vertices = (*primItr)->_vertices;
|
auto vertices = (*primItr)->_vertices;
|
||||||
std::for_each( vertices.begin(),
|
std::for_each( vertices.begin(),
|
||||||
vertices.end(),
|
vertices.end(),
|
||||||
[points](auto v) { points->push_back(*v); }
|
[points, texCoords, normals](auto v) {
|
||||||
|
points->push_back(*v);
|
||||||
|
texCoords->push_back(osg::Vec2f(v->x(), v->y()));
|
||||||
|
normals->push_back(osg::Vec3f(0.0, 0.0, 1.0));
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
geometry->addPrimitiveSet(new osg::DrawArrays((*primItr)->_mode, idx, vertices.size()));
|
geometry->addPrimitiveSet(new osg::DrawArrays((*primItr)->_mode, idx, vertices.size()));
|
||||||
idx += vertices.size();
|
idx += vertices.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::Vec3Array* n = new osg::Vec3Array;
|
|
||||||
n->push_back(up);
|
|
||||||
|
|
||||||
osg::Vec4Array* c = new osg::Vec4Array;
|
osg::Vec4Array* c = new osg::Vec4Array;
|
||||||
c->push_back(osg::Vec4f(0.5f, 0.5f, 0.5f, 1.0f));
|
c->push_back(osg::Vec4f(1.0f, 1.0f, 1.0f, 1.0f));
|
||||||
|
|
||||||
geometry->setColorArray(c, osg::Array::BIND_OVERALL);
|
geometry->setColorArray(c, osg::Array::BIND_OVERALL);
|
||||||
geometry->setNormalArray(n, osg::Array::BIND_OVERALL);
|
geometry->setNormalArray(normals, osg::Array::BIND_PER_VERTEX);
|
||||||
|
geometry->setTexCoordArray(0, texCoords, osg::Array::BIND_PER_VERTEX);
|
||||||
|
|
||||||
simgear::EffectGeode* geode = new simgear::EffectGeode;
|
EffectGeode* geode = new EffectGeode;
|
||||||
|
ref_ptr<Effect> effect = getMaterialEffect("Asphalt", options);
|
||||||
|
geode->setEffect(effect.get());
|
||||||
geode->addDrawable(geometry);
|
geode->addDrawable(geometry);
|
||||||
//geode->setEffect(_effect.get());
|
|
||||||
|
|
||||||
return geode;
|
return geode;
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::Node* AirportBuilder::createBoundary(const SGVec3f center, const osg::Vec3f up, const FGPavementRef pavement) const
|
osg::Node* AirportBuilder::createBoundary(const osg::Matrixd mat, const SGVec3f center, const FGPavementRef pavement, const osgDB::Options* options) const
|
||||||
{
|
{
|
||||||
const FGPavement::NodeList nodes = pavement->getNodeList();
|
const FGPavement::NodeList nodes = pavement->getNodeList();
|
||||||
|
|
||||||
|
@ -284,31 +304,28 @@ osg::Node* AirportBuilder::createBoundary(const SGVec3f center, const osg::Vec3f
|
||||||
tessellator->beginContour();
|
tessellator->beginContour();
|
||||||
|
|
||||||
// Track the previous vertex for bezier curve generation.
|
// Track the previous vertex for bezier curve generation.
|
||||||
osg::Vec3f* previous;
|
osg::Vec3f* previous = NULL;
|
||||||
|
|
||||||
// Bezier control. Bezier curve is node n-1 -> n -> n+1 so need to store for
|
// Bezier control. Bezier curve is node n-1 -> n -> n+1 so need to store for
|
||||||
// handling the next node in addition to generating for the BezierNode itself.
|
// handling the next node in addition to generating for the BezierNode itself.
|
||||||
bool bezier = false;
|
bool bezier = false;
|
||||||
osg::Vec3f control;
|
osg::Vec3f control;
|
||||||
|
|
||||||
|
|
||||||
auto itr = nodes.begin();
|
auto itr = nodes.begin();
|
||||||
for (; itr < nodes.end(); ++itr) {
|
for (; itr < nodes.end(); ++itr) {
|
||||||
FGPavement::NodeBase* node = *itr;
|
FGPavement::NodeBase* node = *itr;
|
||||||
|
|
||||||
// Create an offset so we can easily layer the boundary, pavement, lights and runways
|
osg::Vec3f* v = new osg::Vec3f(mat * toOsg(SGVec3f::fromGeod(node->mPos) - center) + osg::Vec3f(0,0, BOUNDARY_OFFSET));
|
||||||
SGGeod offset = SGGeod::fromGeodM(node->mPos, node->mPos.getElevationM() + BOUNDARY_OFFSET);
|
|
||||||
osg::Vec3f* v = new osg::Vec3f(toOsg(SGVec3f::fromGeod(offset) - center));
|
|
||||||
|
|
||||||
if (FGPavement::BezierNode *bez = dynamic_cast<FGPavement::BezierNode*>(node)) {
|
if (FGPavement::BezierNode *bez = dynamic_cast<FGPavement::BezierNode*>(node)) {
|
||||||
// Store the bezier control node for generation when we know the next node.
|
// Store the bezier control node for generation when we know the next node.
|
||||||
SGGeod controlGeod = SGGeod::fromGeodM(bez->mControl, bez->mControl.getElevationM() + BOUNDARY_OFFSET);
|
control = osg::Vec3f(mat * toOsg(SGVec3f::fromGeod(bez->mControl) - center) + osg::Vec3f(0,0, BOUNDARY_OFFSET));
|
||||||
control = osg::Vec3f(toOsg(SGVec3f::fromGeod(controlGeod) - center));
|
|
||||||
bezier = true;
|
bezier = true;
|
||||||
|
|
||||||
// Generate from the last node to this one, reflecting the control point
|
// Generate from the last node to this one, reflecting the control point
|
||||||
for (float t = 0.05f; t < 0.95f; t += 0.05f ) {
|
for (float t = 0.05f; t < 0.95f; t += 0.05f ) {
|
||||||
osg::Vec3f p0 = *previous;
|
osg::Vec3f p0 = osg::Vec3f();
|
||||||
|
if (previous != NULL) p0 = *previous;
|
||||||
osg::Vec3f p1 = *v + *v - control;
|
osg::Vec3f p1 = *v + *v - control;
|
||||||
osg::Vec3f p2 = *v;
|
osg::Vec3f p2 = *v;
|
||||||
|
|
||||||
|
@ -371,22 +388,23 @@ osg::Node* AirportBuilder::createBoundary(const SGVec3f center, const osg::Vec3f
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::Vec3Array* n = new osg::Vec3Array;
|
osg::Vec3Array* n = new osg::Vec3Array;
|
||||||
n->push_back(up);
|
n->push_back(osg::Vec3f(0.0, 0.0, 1.0));
|
||||||
|
|
||||||
osg::Vec4Array* c = new osg::Vec4Array;
|
osg::Vec4Array* c = new osg::Vec4Array;
|
||||||
c->push_back(osg::Vec4f(0.3f, 0.7f, 0.3f, 1.0f));
|
c->push_back(osg::Vec4f(1.0f, 1.0f, 1.0f, 1.0f));
|
||||||
|
|
||||||
geometry->setColorArray(c, osg::Array::BIND_OVERALL);
|
geometry->setColorArray(c, osg::Array::BIND_OVERALL);
|
||||||
geometry->setNormalArray(n, osg::Array::BIND_OVERALL);
|
geometry->setNormalArray(n, osg::Array::BIND_OVERALL);
|
||||||
|
|
||||||
simgear::EffectGeode* geode = new simgear::EffectGeode;
|
EffectGeode* geode = new EffectGeode;
|
||||||
|
ref_ptr<Effect> effect = getMaterialEffect("Default", options);
|
||||||
|
geode->setEffect(effect.get());
|
||||||
geode->addDrawable(geometry);
|
geode->addDrawable(geometry);
|
||||||
//geode->setEffect(_effect.get());
|
|
||||||
|
|
||||||
return geode;
|
return geode;
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::Node* AirportBuilder::createLine(const SGVec3f center, const osg::Vec3f up, const FGPavementRef line) const
|
osg::Node* AirportBuilder::createLine(const osg::Matrixd mat, const SGVec3f center, const FGPavementRef line, const osgDB::Options* options) const
|
||||||
{
|
{
|
||||||
const FGPavement::NodeList nodes = line->getNodeList();
|
const FGPavement::NodeList nodes = line->getNodeList();
|
||||||
|
|
||||||
|
@ -414,7 +432,7 @@ osg::Node* AirportBuilder::createLine(const SGVec3f center, const osg::Vec3f up,
|
||||||
geometry->setVertexArray(points);
|
geometry->setVertexArray(points);
|
||||||
|
|
||||||
osg::Vec3Array* n = new osg::Vec3Array;
|
osg::Vec3Array* n = new osg::Vec3Array;
|
||||||
n->push_back(up);
|
n->push_back(osg::Vec3f(0.0, 0.0, 1.0));
|
||||||
geometry->setNormalArray(n, osg::Array::BIND_OVERALL);
|
geometry->setNormalArray(n, osg::Array::BIND_OVERALL);
|
||||||
|
|
||||||
osg::Vec4Array* c = new osg::Vec4Array;
|
osg::Vec4Array* c = new osg::Vec4Array;
|
||||||
|
@ -423,17 +441,13 @@ osg::Node* AirportBuilder::createLine(const SGVec3f center, const osg::Vec3f up,
|
||||||
auto itr = nodes.begin();
|
auto itr = nodes.begin();
|
||||||
for (; itr < nodes.end(); ++itr) {
|
for (; itr < nodes.end(); ++itr) {
|
||||||
FGPavement::NodeBase* node = *itr;
|
FGPavement::NodeBase* node = *itr;
|
||||||
|
osg::Vec3f v = osg::Vec3f(mat * toOsg(SGVec3f::fromGeod(node->mPos) - center) + osg::Vec3f(0,0, MARKING_OFFSET));
|
||||||
// Create an offset so we can easily layer the boundary, pavement, lights and runways
|
|
||||||
SGGeod offset = SGGeod::fromGeodM(node->mPos, node->mPos.getElevationM() + MARKING_OFFSET);
|
|
||||||
osg::Vec3f v = osg::Vec3f(toOsg(SGVec3f::fromGeod(offset) - center));
|
|
||||||
|
|
||||||
if (node->mPaintCode != 0) paintCode = node->mPaintCode;
|
if (node->mPaintCode != 0) paintCode = node->mPaintCode;
|
||||||
|
|
||||||
if (FGPavement::BezierNode *bez = dynamic_cast<FGPavement::BezierNode*>(node)) {
|
if (FGPavement::BezierNode *bez = dynamic_cast<FGPavement::BezierNode*>(node)) {
|
||||||
// Store the bezier control node for generation when we know the next node.
|
// Store the bezier control node for generation when we know the next node.
|
||||||
SGGeod controlGeod = SGGeod::fromGeodM(bez->mControl, bez->mControl.getElevationM() + MARKING_OFFSET);
|
control = osg::Vec3f(mat * toOsg(SGVec3f::fromGeod(bez->mControl) - center) + osg::Vec3f(0,0, MARKING_OFFSET));
|
||||||
control = osg::Vec3f(toOsg(SGVec3f::fromGeod(controlGeod) - center));
|
|
||||||
bezier = true;
|
bezier = true;
|
||||||
|
|
||||||
// Generate from the last node to this one, reflecting the control point
|
// Generate from the last node to this one, reflecting the control point
|
||||||
|
@ -517,14 +531,20 @@ osg::Node* AirportBuilder::createLine(const SGVec3f center, const osg::Vec3f up,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
simgear::EffectGeode* geode = new simgear::EffectGeode;
|
// We should be using different Effects for different lines, and/or
|
||||||
|
// parameterizing a single Effect to encode some line type information so
|
||||||
|
// we can use a single Effect for all lines.
|
||||||
|
EffectGeode* geode = new EffectGeode;
|
||||||
|
ref_ptr<Effect> effect = getMaterialEffect("lf_sng_solid_yellow", options);
|
||||||
|
geode->setEffect(effect.get());
|
||||||
geode->addDrawable(geometry);
|
geode->addDrawable(geometry);
|
||||||
//geode->setEffect(_effect.get());
|
|
||||||
|
|
||||||
return geode;
|
return geode;
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::Vec4f AirportBuilder::getLineColor(const int aPaintCode) const {
|
osg::Vec4f AirportBuilder::getLineColor(const int aPaintCode) const
|
||||||
|
{
|
||||||
if (aPaintCode == 1) return osg::Vec4f(0.7f, 0.7f, 0.3f, 1.0f); // Solid yellow
|
if (aPaintCode == 1) return osg::Vec4f(0.7f, 0.7f, 0.3f, 1.0f); // Solid yellow
|
||||||
if (aPaintCode == 2) return osg::Vec4f(0.7f, 0.7f, 0.3f, 1.0f); // Broken yellow
|
if (aPaintCode == 2) return osg::Vec4f(0.7f, 0.7f, 0.3f, 1.0f); // Broken yellow
|
||||||
if (aPaintCode == 3) return osg::Vec4f(0.9f, 0.9f, 0.3f, 1.0f); // Double yellow
|
if (aPaintCode == 3) return osg::Vec4f(0.9f, 0.9f, 0.3f, 1.0f); // Double yellow
|
||||||
|
@ -550,9 +570,32 @@ osg::Vec4f AirportBuilder::getLineColor(const int aPaintCode) const {
|
||||||
if (aPaintCode == 21) return osg::Vec4f(0.7f, 0.7f, 0.7f, 1.0f); // White chequerboard
|
if (aPaintCode == 21) return osg::Vec4f(0.7f, 0.7f, 0.7f, 1.0f); // White chequerboard
|
||||||
if (aPaintCode == 22) return osg::Vec4f(0.6f, 0.6f, 0.6f, 1.0f); // Broken white line
|
if (aPaintCode == 22) return osg::Vec4f(0.6f, 0.6f, 0.6f, 1.0f); // Broken white line
|
||||||
|
|
||||||
//std::cout << "Unknown line colour " << aPaintCode << "\n";
|
|
||||||
return osg::Vec4f(0.7f, 0.7f, 0.3f, 1.0f); // Default (probably an error), so red
|
return osg::Vec4f(0.7f, 0.7f, 0.3f, 1.0f); // Default (probably an error), so red
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::ref_ptr<Effect> AirportBuilder::getMaterialEffect(std::string material, const osgDB::Options* options) const
|
||||||
|
{
|
||||||
|
ref_ptr<Effect> effect;
|
||||||
|
SGPropertyNode_ptr effectProp = new SGPropertyNode();
|
||||||
|
|
||||||
|
osg::ref_ptr<SGReaderWriterOptions> sgOpts(SGReaderWriterOptions::copyOrCreate(options));
|
||||||
|
|
||||||
|
if (sgOpts->getMaterialLib()) {
|
||||||
|
const SGGeod loc = SGGeod(sgOpts->getLocation());
|
||||||
|
SGMaterialCache* matcache = sgOpts->getMaterialLib()->generateMatCache(loc);
|
||||||
|
SGMaterial* mat = matcache->find(material);
|
||||||
|
delete matcache;
|
||||||
|
|
||||||
|
if (mat) {
|
||||||
|
return mat->get_effect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SG_LOG( SG_TERRAIN, SG_ALERT, "Unable to get effect for " << material);
|
||||||
|
makeChild(effectProp, "inherits-from")->setStringValue("Effects/model-default");
|
||||||
|
effectProp->addChild("default")->setBoolValue(true);
|
||||||
|
effect = makeEffect(effectProp, true, sgOpts);
|
||||||
|
return effect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
// $Id$
|
// $Id$
|
||||||
#include <osgDB/Registry>
|
#include <osgDB/Registry>
|
||||||
#include "airport.hxx"
|
#include "airport.hxx"
|
||||||
|
#include <simgear/scene/material/Effect.hxx>
|
||||||
|
#include <simgear/scene/material/EffectGeode.hxx>
|
||||||
|
|
||||||
namespace flightgear
|
namespace flightgear
|
||||||
{
|
{
|
||||||
|
@ -48,12 +50,12 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
osg::Node* createAirport(const std::string airportId) const;
|
osg::Node* createAirport(const std::string airportId) const;
|
||||||
osg::Node* createRunway(const SGVec3f center, const osg::Vec3f up, const FGRunwayRef runway) const;
|
osg::Node* createRunway(const osg::Matrixd mat, const SGVec3f center, const FGRunwayRef runway, const osgDB::Options* options) const;
|
||||||
osg::Node* createPavement(const SGVec3f center, const osg::Vec3f up, const FGPavementRef pavement) const;
|
osg::Node* createPavement(const osg::Matrixd mat, const SGVec3f center, const FGPavementRef pavement, const osgDB::Options* options) const;
|
||||||
osg::Node* createBoundary(const SGVec3f center, const osg::Vec3f up, const FGPavementRef pavement) const;
|
osg::Node* createBoundary(const osg::Matrixd mat, const SGVec3f center, const FGPavementRef pavement, const osgDB::Options* options) const;
|
||||||
osg::Node* createLine(const SGVec3f center, const osg::Vec3f up, const FGPavementRef pavement) const;
|
osg::Node* createLine(const osg::Matrixd mat, const SGVec3f center, const FGPavementRef pavement, const osgDB::Options* options) const;
|
||||||
osg::Vec4f getLineColor(const int aPaintCode) const;
|
osg::Vec4f getLineColor(const int aPaintCode) const;
|
||||||
|
osg::ref_ptr<simgear::Effect> getMaterialEffect(std::string material, const osgDB::Options* options) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue