From b10a40ff8d598930eedebb9e5b4b04f993f738ad Mon Sep 17 00:00:00 2001 From: Christian Schmitt Date: Sat, 12 May 2012 22:55:06 +0200 Subject: [PATCH] Taxiway signs: support all variants from the apt.dat 850 spec and read size values from the optional stg column --- simgear/scene/tgdb/ReaderWriterSTG.cxx | 7 ++- simgear/scene/tgdb/apt_signs.cxx | 66 ++++++++++++++++++-------- simgear/scene/tgdb/apt_signs.hxx | 2 +- 3 files changed, 53 insertions(+), 22 deletions(-) diff --git a/simgear/scene/tgdb/ReaderWriterSTG.cxx b/simgear/scene/tgdb/ReaderWriterSTG.cxx index 14318bcf..386a3f6a 100644 --- a/simgear/scene/tgdb/ReaderWriterSTG.cxx +++ b/simgear/scene/tgdb/ReaderWriterSTG.cxx @@ -288,7 +288,12 @@ ReaderWriterSTG::readStgFile(const std::string& absoluteFileName, } } else if ( token == "OBJECT_SIGN" ) { - signBuilder.addSign(SGGeod::fromDegM(lon, lat, elev), hdg, name); + int size(-1); + + if ( hasOptionalValue(in) ){ + in >> size; + } + signBuilder.addSign(SGGeod::fromDegM(lon, lat, elev), hdg, name, size); } else { SG_LOG( SG_TERRAIN, SG_ALERT, absoluteFileName << ": Unknown token '" << token << "'" ); diff --git a/simgear/scene/tgdb/apt_signs.cxx b/simgear/scene/tgdb/apt_signs.cxx index 8dc4a737..837096b2 100644 --- a/simgear/scene/tgdb/apt_signs.cxx +++ b/simgear/scene/tgdb/apt_signs.cxx @@ -66,7 +66,10 @@ struct element_info { typedef std::vector ElementVec; -const double HT[5] = {0.460, 0.610, 0.760, 1.220, 0.760}; // standard panel height sizes +// Standard panel height sizes. The first value is unused to +// make sure the size value equals 1:1 the value from the apt.dat file: +const double HT[6] = {0.1, 0.460, 0.610, 0.760, 1.220, 0.760}; + const double grounddist = 0.2; // hard-code sign distance from surface for now const double thick = 0.1; // half the thickness of the 3D sign @@ -80,14 +83,13 @@ struct pair { {"@d", "^d"}, {"@l", "^l"}, {"@lu", "^lu"}, - {"@ul", "^lu"}, {"@ld", "^ld"}, - {"@dl", "^ld"}, {"@r", "^r"}, {"@ru", "^ru"}, - {"@ur", "^ru"}, {"@rd", "^rd"}, - {"@dr", "^rd"}, + {"r1", "^I1"}, + {"r2", "^I2"}, + {"r3", "^I3"}, {0, 0}, }; @@ -274,7 +276,7 @@ AirportSignBuilder::~AirportSignBuilder() } } -void AirportSignBuilder::addSign(const SGGeod& pos, double heading, const std::string& content) +void AirportSignBuilder::addSign(const SGGeod& pos, double heading, const std::string& content, int size) { double sign_height = 1.0; // meter string newmat = "BlackSign"; @@ -285,10 +287,14 @@ void AirportSignBuilder::addSign(const SGGeod& pos, double heading, const std::s double total_width2 = 0.0; bool cmd = false; bool isBackside = false; - int size = -1; char oldtype = 0, newtype = 0; SGMaterial *material = 0; + if (size < -1 || size > 5){ + SG_LOG(SG_TERRAIN, SG_ALERT, SIGN "Found illegal sign size value of '" << size << "' for " << content << "."); + size = -1; + } + // Part I: parse & measure for (const char *s = content.data(); *s; s++) { string name; @@ -315,9 +321,10 @@ void AirportSignBuilder::addSign(const SGGeod& pos, double heading, const std::s for (; *s; s++) { name += *s; - if (s[1] == ',' || s[1] == '}' || s[1] == '=') + if (s[1] == ',' || s[1] == '}' ) break; } + if (!*s) { SG_LOG(SG_TERRAIN, SG_ALERT, SIGN "unclosed { in sign contents"); } else if (s[1] == '=') { @@ -330,25 +337,44 @@ void AirportSignBuilder::addSign(const SGGeod& pos, double heading, const std::s SG_LOG(SG_TERRAIN, SG_ALERT, SIGN "unclosed { in sign contents"); } - if (name == "@@") { - isBackside = true; - continue; + if (name == "no-entry") { + sign_height = HT[size < 0 ? 3 : size]; + newmat = "RedSign"; + newtype = 'R'; + } + + else if (name == "critical") { + sign_height = HT[size < 0 ? 3 : size]; + newmat = "SpecialSign"; + newtype = 'S'; + } + + else if (name == "safety") { + sign_height = HT[size < 0 ? 3 : size]; + newmat = "SpecialSign"; + newtype = 'S'; } - if (name == "@size") { - sign_height = strtod(value.data(), 0); + else if (name == "hazard") { + sign_height = HT[size < 0 ? 3 : size]; + newmat = "SpecialSign"; + newtype = 'S'; + } + + if (name == "@@") { + isBackside = true; continue; } if (name.size() == 2 || name.size() == 3) { string n = name; if (n.size() == 3 && n[2] >= '1' && n[2] <= '5') { - size = n[2] - '1'; + size = n[2]; n = n.substr(0, 2); } if (n == "@Y") { if (size < 3) { - sign_height = HT[size < 0 ? 2 : size]; + sign_height = HT[size < 0 ? 3 : size]; newmat = "YellowSign"; newtype = 'Y'; continue; @@ -356,7 +382,7 @@ void AirportSignBuilder::addSign(const SGGeod& pos, double heading, const std::s } else if (n == "@R") { if (size < 3) { - sign_height = HT[size < 0 ? 2 : size]; + sign_height = HT[size < 0 ? 3 : size]; newmat = "RedSign"; newtype = 'R'; continue; @@ -364,15 +390,15 @@ void AirportSignBuilder::addSign(const SGGeod& pos, double heading, const std::s } else if (n == "@L") { if (size < 3) { - sign_height = HT[size < 0 ? 2 : size]; + sign_height = HT[size < 0 ? 3 : size]; newmat = "FramedSign"; newtype = 'L'; continue; } } else if (n == "@B") { - if (size < 0 || size == 3 || size == 4) { - sign_height = HT[size < 0 ? 3 : size]; + if (size < 0 || size == 4 || size == 5) { + sign_height = HT[size < 0 ? 4 : size]; newmat = "BlackSign"; newtype = 'B'; continue; @@ -397,7 +423,7 @@ void AirportSignBuilder::addSign(const SGGeod& pos, double heading, const std::s material = d->materials->find(newmat); newmat.clear(); } - + SGMaterialGlyph *glyph = material->get_glyph(name); if (!glyph) { SG_LOG( SG_TERRAIN, SG_ALERT, SIGN "unsupported glyph '" << *s << '\''); diff --git a/simgear/scene/tgdb/apt_signs.hxx b/simgear/scene/tgdb/apt_signs.hxx index 31334e4a..b0fd9169 100644 --- a/simgear/scene/tgdb/apt_signs.hxx +++ b/simgear/scene/tgdb/apt_signs.hxx @@ -46,7 +46,7 @@ public: AirportSignBuilder(SGMaterialLib* mats, const SGGeod& center); ~AirportSignBuilder(); - void addSign(const SGGeod& pos, double heading, const std::string& content); + void addSign(const SGGeod& pos, double heading, const std::string& content, int size); osg::Node* getSignsGroup(); private: -- 2.39.5