diff --git a/simgear/canvas/elements/CanvasImage.cxx b/simgear/canvas/elements/CanvasImage.cxx index 3964653b..09e09edf 100644 --- a/simgear/canvas/elements/CanvasImage.cxx +++ b/simgear/canvas/elements/CanvasImage.cxx @@ -866,6 +866,11 @@ SGRect intersectRect(const SGRect& a, const SGRect& b) void Image::fillRect(const SGRect& rect, const osg::Vec4& color) { osg::ref_ptr image = _texture->getImage(); + if (!image) { + allocateImage(); + image = _texture->getImage(); + } + const auto format = image->getInternalTextureFormat(); auto clippedRect = intersectRect(rect, SGRect(0, 0, image->s(), image->t())); @@ -881,6 +886,7 @@ SGRect intersectRect(const SGRect& a, const SGRect& b) switch (format) { case GL_RGBA8: + case GL_RGBA: rowByteSize = pixelWidth * 4; rowData = static_cast(alloca(rowByteSize)); @@ -892,6 +898,7 @@ SGRect intersectRect(const SGRect& a, const SGRect& b) break; case GL_RGB8: + case GL_RGB: rowByteSize = pixelWidth * 3; rowData = static_cast(alloca(rowByteSize)); pixel = color.asABGR(); @@ -908,8 +915,8 @@ SGRect intersectRect(const SGRect& a, const SGRect& b) GLubyte* imageData = image->data(clippedRect.l(), row); memcpy(imageData, rowData, rowByteSize); } - - setImage(image); + + image->dirty(); } void Image::setPixel(int x, int y, const std::string& c) @@ -924,12 +931,30 @@ SGRect intersectRect(const SGRect& a, const SGRect& b) void Image::setPixel(int x, int y, const osg::Vec4& color) { osg::ref_ptr image = _texture->getImage(); + if (!image) { + allocateImage(); + image = _texture->getImage(); + } + image->setColor(color, x, y); - - // is this needed, or does OSG track modifications to the data - // automatically? - setImage(image); } + void Image::allocateImage() + { + osg::Image* image = new osg::Image; + // default to RGBA + image->allocateImage(_node->getIntValue("size[0]"), _node->getIntValue("size[1]"), 1, GL_RGBA, GL_UNSIGNED_BYTE); + image->setInternalTextureFormat(GL_RGBA); + _texture->setImage(image); + } + + +osg::ref_ptr Image::getImage() const +{ + if (!_texture) + return {}; + return _texture->getImage(); +} + } // namespace canvas } // namespace simgear diff --git a/simgear/canvas/elements/CanvasImage.hxx b/simgear/canvas/elements/CanvasImage.hxx index dedcaf01..a1aeed2f 100644 --- a/simgear/canvas/elements/CanvasImage.hxx +++ b/simgear/canvas/elements/CanvasImage.hxx @@ -115,6 +115,7 @@ namespace canvas void setPixel(int x, int y, const osg::Vec4& color); + osg::ref_ptr getImage() const; // void setRow(int row, int offset, ) protected: @@ -141,6 +142,8 @@ namespace canvas HTTP::Request& request, const std::string& type ); + void allocateImage(); + osg::ref_ptr _texture; // TODO optionally forward events to canvas CanvasWeakPtr _src_canvas; diff --git a/simgear/debug/logstream.cxx b/simgear/debug/logstream.cxx index d99b0dc2..c06f5c5f 100644 --- a/simgear/debug/logstream.cxx +++ b/simgear/debug/logstream.cxx @@ -564,7 +564,7 @@ public: } if (in == SG_DEV_ALERT) { - return m_developerMode ? SG_POPUP : SG_WARN; + return m_developerMode ? SG_ALERT : SG_WARN; } return in; diff --git a/simgear/ephemeris/ephemeris.cxx b/simgear/ephemeris/ephemeris.cxx index a05481bd..f918c3f7 100644 --- a/simgear/ephemeris/ephemeris.cxx +++ b/simgear/ephemeris/ephemeris.cxx @@ -31,7 +31,7 @@ // Constructor -SGEphemeris::SGEphemeris( const std::string &path ) { +SGEphemeris::SGEphemeris( const SGPath& path ) { our_sun = new Star; moon = new MoonPos; mercury = new Mercury; @@ -44,7 +44,7 @@ SGEphemeris::SGEphemeris( const std::string &path ) { nplanets = 7; for ( int i = 0; i < nplanets; ++i ) planets[i] = SGVec3d::zeros(); - stars = new SGStarData( SGPath(path) ); + stars = new SGStarData(path); } diff --git a/simgear/ephemeris/ephemeris.hxx b/simgear/ephemeris/ephemeris.hxx index 398eb3ef..abe5a8a0 100644 --- a/simgear/ephemeris/ephemeris.hxx +++ b/simgear/ephemeris/ephemeris.hxx @@ -97,7 +97,7 @@ public: * calling the constructor you need to provide a path pointing to * your star database file. * @param path path to your star database */ - SGEphemeris( const std::string &path ); + SGEphemeris( const SGPath &path ); /** Destructor */ ~SGEphemeris( void ); diff --git a/simgear/io/iostreams/gzcontainerfile.cxx b/simgear/io/iostreams/gzcontainerfile.cxx index c60650a8..d5dd4afd 100644 --- a/simgear/io/iostreams/gzcontainerfile.cxx +++ b/simgear/io/iostreams/gzcontainerfile.cxx @@ -71,10 +71,10 @@ static const uint32_t EndianMagic = 0x11223344; * gzContainerWriter **************************************************************************/ -gzContainerWriter::gzContainerWriter(const std::string& name, +gzContainerWriter::gzContainerWriter(const SGPath& name, const std::string& fileMagic) : sg_gzofstream(name, ios_out | ios_binary), - filename(name) + filename(name.utf8Str()) { /* write byte-order marker **************************************/ write((char*)&EndianMagic, sizeof(EndianMagic)); @@ -138,10 +138,10 @@ gzContainerWriter::writeContainer(ContainerType Type, SGPropertyNode* root) * gzContainerReader **************************************************************************/ -gzContainerReader::gzContainerReader(const std::string& name, +gzContainerReader::gzContainerReader(const SGPath& name, const std::string& fileMagic) : sg_gzifstream(SGPath(name), ios_in | ios_binary), - filename(name) + filename(name.utf8Str()) { bool ok = (good() && !eof()); diff --git a/simgear/io/iostreams/gzcontainerfile.hxx b/simgear/io/iostreams/gzcontainerfile.hxx index 79c5563a..40af7a13 100644 --- a/simgear/io/iostreams/gzcontainerfile.hxx +++ b/simgear/io/iostreams/gzcontainerfile.hxx @@ -35,7 +35,7 @@ typedef int ContainerType; class gzContainerReader : public sg_gzifstream { public: - gzContainerReader( const std::string& name, + gzContainerReader( const SGPath& name, const std::string& fileMagic); bool readContainerHeader(ContainerType* pType, size_t* pSize); @@ -48,7 +48,7 @@ private: class gzContainerWriter : public sg_gzofstream { public: - gzContainerWriter( const std::string& name, + gzContainerWriter( const SGPath& name, const std::string& fileMagic); bool writeContainerHeader(ContainerType Type, size_t Size); diff --git a/simgear/io/iostreams/sgstream.cxx b/simgear/io/iostreams/sgstream.cxx index 77c30f1f..fc20e73a 100644 --- a/simgear/io/iostreams/sgstream.cxx +++ b/simgear/io/iostreams/sgstream.cxx @@ -212,7 +212,7 @@ sg_ifstream::sg_ifstream(const SGPath& path, ios_openmode io_mode) #if defined(SG_WINDOWS) std::wstring ps = path.wstr(); #else - std::string ps = path.local8BitStr(); + std::string ps = path.utf8Str(); #endif std::ifstream::open(ps.c_str(), io_mode); } @@ -222,7 +222,7 @@ void sg_ifstream::open( const SGPath& name, ios_openmode io_mode ) #if defined(SG_WINDOWS) std::wstring ps = name.wstr(); #else - std::string ps = name.local8BitStr(); + std::string ps = name.utf8Str(); #endif std::ifstream::open(ps.c_str(), io_mode); } @@ -232,7 +232,7 @@ sg_ofstream::sg_ofstream(const SGPath& path, ios_openmode io_mode) #if defined(SG_WINDOWS) std::wstring ps = path.wstr(); #else - std::string ps = path.local8BitStr(); + std::string ps = path.utf8Str(); #endif std::ofstream::open(ps.c_str(), io_mode); } @@ -242,7 +242,7 @@ void sg_ofstream::open( const SGPath& name, ios_openmode io_mode ) #if defined(SG_WINDOWS) std::wstring ps = name.wstr(); #else - std::string ps = name.local8BitStr(); + std::string ps = name.utf8Str(); #endif std::ofstream::open(ps.c_str(), io_mode); } diff --git a/simgear/misc/path_test.cxx b/simgear/misc/path_test.cxx old mode 100644 new mode 100755 index dac7c0d2..9ae36245 --- a/simgear/misc/path_test.cxx +++ b/simgear/misc/path_test.cxx @@ -333,6 +333,12 @@ void test_hash_function() SG_CHECK_NE(std::hash{}(p), std::hash{}(p / "foobar")); } +void test_null_path() +{ + const SGPath nullPath; + SG_VERIFY(!nullPath.exists()); +} + int main(int argc, char* argv[]) { SGPath pa; @@ -441,6 +447,7 @@ int main(int argc, char* argv[]) test_update_dir(); test_comparisons(); test_hash_function(); + test_null_path(); cout << "all tests passed OK" << endl; return 0; // passed diff --git a/simgear/misc/sg_dir.cxx b/simgear/misc/sg_dir.cxx index 9430e1b2..0836a49b 100644 --- a/simgear/misc/sg_dir.cxx +++ b/simgear/misc/sg_dir.cxx @@ -115,7 +115,7 @@ Dir Dir::tempDir(const std::string& templ) // Mac OS-X / BSD manual says any number of 'X's, but GLibc manual // says exactly six, so that's what I'm going with p.concat("-XXXXXX"); - std::string s = p.local8BitStr(); + std::string s = p.utf8Str(); ::snprintf(buf, 1024, "%s", s.c_str()); if (!mkdtemp(buf)) { SG_LOG(SG_IO, SG_WARN, @@ -206,7 +206,7 @@ PathList Dir::children(int types, const std::string& nameFilter) const FindClose(find); #else - std::string ps = _path.local8BitStr(); + std::string ps = _path.utf8Str(); DIR* dp = opendir(ps.c_str()); if (!dp) { SG_LOG(SG_GENERAL, SG_WARN, "Dir::children: opendir failed:" << _path); @@ -290,7 +290,7 @@ bool Dir::isEmpty() const std::wstring ps = _path.wstr(); return PathIsDirectoryEmptyW( ps.c_str() ); #else - std::string ps = _path.local8BitStr(); + std::string ps = _path.utf8Str(); DIR* dp = opendir( ps.c_str() ); if (!dp) return true; @@ -339,7 +339,7 @@ bool Dir::create(mode_t mode) std::wstring ps = _path.wstr(); int err = _wmkdir(ps.c_str()); #else - std::string ps = _path.local8BitStr(); + std::string ps = _path.utf8Str(); int err = mkdir(ps.c_str(), mode); #endif if (err) { @@ -394,7 +394,7 @@ bool Dir::remove(bool recursive) std::wstring ps = _path.wstr(); int err = _wrmdir(ps.c_str()); #else - std::string ps = _path.local8BitStr(); + std::string ps = _path.utf8Str(); int err = rmdir(ps.c_str()); #endif if (err) { diff --git a/simgear/misc/sg_path.cxx b/simgear/misc/sg_path.cxx index 3d0e41b1..a252480f 100644 --- a/simgear/misc/sg_path.cxx +++ b/simgear/misc/sg_path.cxx @@ -786,8 +786,8 @@ bool SGPath::rename(const SGPath& newName) std::wstring np = newName.wstr(); if (_wrename(p.c_str(), np.c_str()) != 0) #else - std::string p = local8BitStr(); - std::string np = newName.local8BitStr(); + std::string p = utf8Str(); + std::string np = newName.utf8Str(); if( ::rename(p.c_str(), np.c_str()) != 0 ) #endif diff --git a/simgear/misc/strutils.cxx b/simgear/misc/strutils.cxx index 5062e242..208f422c 100644 --- a/simgear/misc/strutils.cxx +++ b/simgear/misc/strutils.cxx @@ -672,8 +672,7 @@ static std::string convertWStringToMultiByte(DWORD encoding, const std::wstring& std::wstring convertUtf8ToWString(const std::string& a) { #if defined(SG_WINDOWS) - std::wstring_convert, wchar_t> ucs2conv; - return ucs2conv.from_bytes(a); + return convertMultiByteToWString(CP_UTF8, a); #else assert(sizeof(wchar_t) == 4); std::wstring result; @@ -723,8 +722,7 @@ std::wstring convertUtf8ToWString(const std::string& a) std::string convertWStringToUtf8(const std::wstring& w) { #if defined(SG_WINDOWS) - std::wstring_convert, wchar_t> ucs2conv; - return ucs2conv.to_bytes(w); + return convertWStringToMultiByte(CP_UTF8, w); #else assert(sizeof(wchar_t) == 4); std::string result; diff --git a/simgear/misc/strutils_test.cxx b/simgear/misc/strutils_test.cxx index b78b9a63..cb371c47 100644 --- a/simgear/misc/strutils_test.cxx +++ b/simgear/misc/strutils_test.cxx @@ -458,7 +458,7 @@ void test_escape() " ab\\nc \\\\def\\t\\r \\\\ ghi\\\\"); // U+0152 is LATIN CAPITAL LIGATURE OE. The last word is Egg translated in // French and encoded in UTF-8 ('Œuf' if you can read UTF-8). - SG_CHECK_EQUAL(strutils::escape("Un \"Bel\" '\u0152uf'"), + SG_CHECK_EQUAL(strutils::escape(u8"Un \"Bel\" '\u0152uf'"), "Un \\\"Bel\\\" '\\305\\222uf'"); SG_CHECK_EQUAL(strutils::escape("\a\b\f\n\r\t\v"), "\\a\\b\\f\\n\\r\\t\\v"); @@ -628,6 +628,11 @@ void test_utf8Convert() std::wstring aRoundTrip = strutils::convertUtf8ToWString(utf8A); SG_VERIFY(a == aRoundTrip); + + + const auto wide2(L"\U0001f6eb\u2708\ufe0f\u2764\ufe0f"); + std::string utf8_2 = strutils::convertWStringToUtf8(wide2); + SG_VERIFY(utf8_2 == std::string("\xf0\x9f\x9b\xab\xe2\x9c\x88\xef\xb8\x8f\xe2\x9d\xa4\xef\xb8\x8f")); } void test_parseGeod() diff --git a/simgear/scene/material/Effect.cxx b/simgear/scene/material/Effect.cxx index 44f15a7f..57f6ac29 100644 --- a/simgear/scene/material/Effect.cxx +++ b/simgear/scene/material/Effect.cxx @@ -81,6 +81,8 @@ #include #include +#include + namespace simgear { using namespace std; @@ -97,6 +99,25 @@ void UniformFactoryImpl::reset() uniformCache.clear(); } +// work around the fact osg::Shader::loadShaderFromSourceFile does not +// respect UTF8 paths, even when OSG_USE_UTF8_FILENAME is set :( +bool loadShaderFromUTF8File(osg::Shader* shader, const std::string& fileName) +{ + sg_ifstream inStream(SGPath::fromUtf8(fileName), std::ios::in | std::ios::binary); + if (!inStream.is_open()) + return false; + + string shaderSource; + while (!inStream.eof()) { + char bytes[8192]; + inStream.read(bytes, 8192); + shaderSource.append(bytes, inStream.gcount()); + } + inStream.close(); + shader->setShaderSource(shaderSource); + return true; +} + ref_ptr UniformFactoryImpl::getUniform( Effect * effect, const string & name, Uniform::Type uniformType, @@ -829,7 +850,7 @@ void reload_shaders() Shader *shader = sitr->second.get(); string fileName = SGModelLib::findDataFile(sitr->first.first); if (!fileName.empty()) { - shader->loadShaderSourceFromFile(fileName); + loadShaderFromUTF8File(shader, fileName); } else SG_LOG(SG_INPUT, SG_ALERT, "Could not locate shader: " << fileName); @@ -953,7 +974,7 @@ void ShaderProgramBuilder::buildAttribute(Effect* effect, Pass* pass, } else { ref_ptr shader = new Shader(stype); shader->setName(fileName); - if (shader->loadShaderSourceFromFile(fileName)) { + if (loadShaderFromUTF8File(shader, fileName)) { program->addShader(shader.get()); shaderMap.insert(ShaderMap::value_type(skey, shader)); } diff --git a/simgear/scene/material/mat.cxx b/simgear/scene/material/mat.cxx index 1ebb86b1..6bedbdcd 100644 --- a/simgear/scene/material/mat.cxx +++ b/simgear/scene/material/mat.cxx @@ -149,7 +149,7 @@ SGMaterial::read_properties(const SGReaderWriterOptions* options, SGPath tpath("Textures"); tpath.append(tname); - std::string fullTexPath = SGModelLib::findDataFile(tpath.local8BitStr(), options); + std::string fullTexPath = SGModelLib::findDataFile(tpath, options); if (fullTexPath.empty()) { SG_LOG(SG_GENERAL, SG_ALERT, "Cannot find texture \"" << tname << "\" in Textures folders."); @@ -181,7 +181,7 @@ SGMaterial::read_properties(const SGReaderWriterOptions* options, SGPath tpath("Textures"); tpath.append(tname); - std::string fullTexPath = SGModelLib::findDataFile(tpath.local8BitStr(), options); + std::string fullTexPath = SGModelLib::findDataFile(tpath, options); if (fullTexPath.empty()) { SG_LOG(SG_GENERAL, SG_ALERT, "Cannot find texture \"" << tname << "\" in Textures folders."); @@ -207,7 +207,7 @@ SGMaterial::read_properties(const SGReaderWriterOptions* options, SGPath tpath("Textures"); tpath.append("Terrain"); tpath.append("unknown.rgb"); - _internal_state st( NULL, tpath.local8BitStr(), true, options ); + _internal_state st( NULL, tpath.utf8Str(), true, options ); _status.push_back( st ); } @@ -219,7 +219,7 @@ SGMaterial::read_properties(const SGReaderWriterOptions* options, if (! omname.empty()) { SGPath ompath("Textures"); ompath.append(omname); - std::string fullMaskPath = SGModelLib::findDataFile(ompath.local8BitStr(), options); + std::string fullMaskPath = SGModelLib::findDataFile(ompath, options); if (fullMaskPath.empty()) { SG_LOG(SG_GENERAL, SG_ALERT, "Cannot find texture \"" @@ -358,7 +358,7 @@ SGMaterial::read_properties(const SGReaderWriterOptions* options, if (! treeTexPath.empty()) { SGPath treePath("Textures"); treePath.append(treeTexPath); - tree_texture = SGModelLib::findDataFile(treePath.local8BitStr(), options); + tree_texture = SGModelLib::findDataFile(treePath, options); if (tree_texture.empty()) { SG_LOG(SG_GENERAL, SG_ALERT, "Cannot find texture \"" diff --git a/simgear/scene/material/matlib.cxx b/simgear/scene/material/matlib.cxx index 0b40869d..3459d7e0 100644 --- a/simgear/scene/material/matlib.cxx +++ b/simgear/scene/material/matlib.cxx @@ -65,7 +65,7 @@ SGMaterialLib::SGMaterialLib ( void ) : } // Load a library of material properties -bool SGMaterialLib::load( const string &fg_root, const string& mpath, +bool SGMaterialLib::load( const SGPath &fg_root, const SGPath& mpath, SGPropertyNode *prop_root ) { SGPropertyNode materialblocks; @@ -81,7 +81,7 @@ bool SGMaterialLib::load( const string &fg_root, const string& mpath, osg::ref_ptr options = new osgDB::Options; options->setObjectCacheHint(osgDB::Options::CACHE_ALL); - options->setDatabasePath(fg_root); + options->setDatabasePath(fg_root.utf8Str()); simgear::PropertyList blocks = materialblocks.getChildren("region"); simgear::PropertyList::const_iterator block_iter = blocks.begin(); diff --git a/simgear/scene/material/matlib.hxx b/simgear/scene/material/matlib.hxx index 90fb273c..ff80d795 100644 --- a/simgear/scene/material/matlib.hxx +++ b/simgear/scene/material/matlib.hxx @@ -38,6 +38,7 @@ class SGMaterial; class SGPropertyNode; +class SGPath; namespace simgear { class Effect; } namespace osg { class Geode; } @@ -87,7 +88,7 @@ public: SGMaterialLib ( void ); // Load a library of material properties - bool load( const std::string &fg_root, const std::string& mpath, + bool load( const SGPath &fg_root, const SGPath& mpath, SGPropertyNode *prop_root ); // find a material record by material name SGMaterial *find( const std::string& material, SGVec2f center ) const; diff --git a/simgear/scene/model/ModelRegistry.cxx b/simgear/scene/model/ModelRegistry.cxx index a1e6d32b..3178d206 100644 --- a/simgear/scene/model/ModelRegistry.cxx +++ b/simgear/scene/model/ModelRegistry.cxx @@ -285,16 +285,17 @@ ModelRegistry::readImage(const string& fileName, string absFileName = SGModelLib::findDataFile(fileName, opt); string originalFileName = absFileName; if (!fileExists(absFileName)) { - SG_LOG(SG_IO, SG_ALERT, "Cannot find image file \"" + SG_LOG(SG_IO, SG_DEV_ALERT, "Cannot find image file \"" << fileName << "\""); return ReaderWriter::ReadResult::FILE_NOT_FOUND; } Registry* registry = Registry::instance(); ReaderWriter::ReadResult res; - if (cache_active) { + const SGReaderWriterOptions* sgoptC = dynamic_cast(opt); + + if (cache_active && (!sgoptC || sgoptC->getLoadOriginHint() != SGReaderWriterOptions::LoadOriginHint::ORIGIN_SPLASH_SCREEN)) { if (fileExtension != "dds" && fileExtension != "gz") { - const SGReaderWriterOptions* sgoptC = dynamic_cast(opt); std::string root = getPathRoot(absFileName); std::string prr = getPathRelative(root, absFileName); @@ -328,7 +329,7 @@ ModelRegistry::readImage(const string& fileName, hash = f.computeHash(); } catch (sg_io_exception &e) { - SG_LOG(SG_INPUT, SG_ALERT, "Modelregistry::failed to compute filehash '" << absFileName << "' " << e.getFormattedMessage()); + SG_LOG(SG_IO, SG_DEV_ALERT, "Modelregistry::failed to compute filehash '" << absFileName << "' " << e.getFormattedMessage()); hash = std::string(); } } @@ -406,12 +407,12 @@ ModelRegistry::readImage(const string& fileName, } if (pot_message.size()) - SG_LOG(SG_IO, SG_WARN, pot_message << " " << absFileName); + SG_LOG(SG_IO, SG_DEV_WARN, pot_message << " " << absFileName); // unlikely that after resizing in height the width will still be outside of the max texture size. if (height > max_texture_size) { - SG_LOG(SG_IO, SG_WARN, "Image texture too high (max " << max_texture_size << ") " << width << "," << height << " " << absFileName); + SG_LOG(SG_IO, SG_DEV_WARN, "Image texture too high (max " << max_texture_size << ") " << width << "," << height << " " << absFileName); int factor = height / max_texture_size; height /= factor; width /= factor; @@ -419,7 +420,7 @@ ModelRegistry::readImage(const string& fileName, } if (width > max_texture_size) { - SG_LOG(SG_IO, SG_WARN, "Image texture too wide (max " << max_texture_size << ") " << width << "," << height << " " << absFileName); + SG_LOG(SG_IO, SG_DEV_WARN, "Image texture too wide (max " << max_texture_size << ") " << width << "," << height << " " << absFileName); int factor = width / max_texture_size; height /= factor; width /= factor; @@ -487,7 +488,7 @@ ModelRegistry::readImage(const string& fileName, if (processor) { - SG_LOG(SG_IO, SG_ALERT, "Creating " << targetFormat << " for " + absFileName); + SG_LOG(SG_IO, SG_DEV_ALERT, "Creating " << targetFormat << " for " + absFileName); // normal maps: // nvdxt.exe - quality_highest - rescaleKaiser - Kaiser - dxt5nm - norm processor->compress(*srcImage, targetFormat, true, true, osgDB::ImageProcessor::USE_CPU, osgDB::ImageProcessor::PRODUCTION); @@ -527,11 +528,11 @@ ModelRegistry::readImage(const string& fileName, absFileName = newName; } catch (...) { - SG_LOG(SG_IO, SG_ALERT, "Exception processing " << absFileName << " may be corrupted"); + SG_LOG(SG_IO, SG_DEV_ALERT, "Exception processing " << absFileName << " may be corrupted"); } } else - SG_LOG(SG_IO, SG_WARN, absFileName + " too small " << width << "," << height); + SG_LOG(SG_IO, SG_DEV_WARN, absFileName + " too small " << width << "," << height); } } } @@ -545,7 +546,7 @@ ModelRegistry::readImage(const string& fileName, res = registry->readImageImplementation(absFileName, opt); if (!res.success()) { - SG_LOG(SG_IO, SG_WARN, "Image loading failed:" << res.message()); + SG_LOG(SG_IO, SG_DEV_WARN, "Image loading failed:" << res.message()); return res; } diff --git a/simgear/scene/model/SGMaterialAnimation.cxx b/simgear/scene/model/SGMaterialAnimation.cxx index 065631e2..c380d9e6 100644 --- a/simgear/scene/model/SGMaterialAnimation.cxx +++ b/simgear/scene/model/SGMaterialAnimation.cxx @@ -381,9 +381,9 @@ public: osg::StateAttribute::ON); } } else { - SG_LOG(SG_IO, SG_WARN, "texture animation: requested texture : " << textureName << " not found. Searched paths:" ); + SG_LOG(SG_IO, SG_DEV_WARN, "texture animation: requested texture : " << textureName << " not found. Searched paths:" ); for( osgDB::FilePathList::iterator it = _texturePathList.begin(); it != _texturePathList.end(); ++it ) { - SG_LOG(SG_IO, SG_WARN, " - " << *it ); + SG_LOG(SG_IO, SG_DEV_WARN, " - " << *it ); } } } @@ -420,7 +420,7 @@ SGMaterialAnimation::SGMaterialAnimation(simgear::SGTransientModelData &modelDat SGAnimation(modelData), texturePathList(modelData.getOptions()->getDatabasePathList()) { if (modelData.getConfigNode()->hasChild("global")) - SG_LOG(SG_IO, SG_ALERT, modelData.getPath() << + SG_LOG(SG_IO, SG_DEV_ALERT, modelData.getPath() << ": Use of in material animation is " "no longer supported."); } diff --git a/simgear/scene/model/SGPickAnimation.cxx b/simgear/scene/model/SGPickAnimation.cxx index 9f2a9eac..943c021a 100644 --- a/simgear/scene/model/SGPickAnimation.cxx +++ b/simgear/scene/model/SGPickAnimation.cxx @@ -186,7 +186,7 @@ osg::Vec2d eventToWindowCoords(const osgGA::GUIEventAdapter& ea) osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), _texX(x), _texY(y), _mask(mask), _done(false) { - SG_LOG(SG_INPUT, SG_DEBUG, "VncVisitor constructor " + SG_LOG(SG_IO, SG_DEBUG, "VncVisitor constructor " << x << "," << y << " mask " << mask); } @@ -240,7 +240,7 @@ osg::Vec2d eventToWindowCoords(const osgGA::GUIEventAdapter& ea) int pixX = _texX * img->s(); int pixY = _texY * img->t(); _done = img->sendPointerEvent(pixX, pixY, _mask); - SG_LOG(SG_INPUT, SG_DEBUG, "VncVisitor image said " << _done + SG_LOG(SG_IO, SG_DEBUG, "VncVisitor image said " << _done << " to coord " << pixX << "," << pixY); } } @@ -267,7 +267,7 @@ public: : _condition(condition) , _node(node) { - SG_LOG(SG_INPUT, SG_DEBUG, "Configuring VNC callback"); + SG_LOG(SG_IO, SG_DEBUG, "Configuring VNC callback"); const char *cornernames[3] = {"top-left", "top-right", "bottom-left"}; SGVec3d *cornercoords[3] = {&_topLeft, &_toRight, &_toDown}; for (int c =0; c < 3; c++) { @@ -289,7 +289,7 @@ public: { if (!_condition || _condition->test()) { SGVec3d loc(info.local); - SG_LOG(SG_INPUT, SG_DEBUG, "VNC pressed " << button << ": " << loc); + SG_LOG(SG_IO, SG_DEBUG, "VNC pressed " << button << ": " << loc); loc -= _topLeft; _x = dot(loc, _toRight) / _squaredRight; _y = dot(loc, _toDown) / _squaredDown; @@ -307,7 +307,7 @@ public: { if (!_condition || _condition->test()) { SG_UNUSED(keyModState); - SG_LOG(SG_INPUT, SG_DEBUG, "VNC release"); + SG_LOG(SG_IO, SG_DEBUG, "VNC release"); VncVisitor vv(_x, _y, 0); _node->accept(vv); } diff --git a/simgear/scene/model/SGReaderWriterXML.cxx b/simgear/scene/model/SGReaderWriterXML.cxx index b6fc37e9..7084c3a3 100644 --- a/simgear/scene/model/SGReaderWriterXML.cxx +++ b/simgear/scene/model/SGReaderWriterXML.cxx @@ -95,7 +95,7 @@ SGReaderWriterXML::readNode(const std::string& name, int num_anims; std::tie(num_anims, result) = sgLoad3DModel_internal(p, options); } catch (const sg_exception &t) { - SG_LOG(SG_INPUT, SG_ALERT, "Failed to load model: " << t.getFormattedMessage() + SG_LOG(SG_IO, SG_DEV_ALERT, "Failed to load model: " << t.getFormattedMessage() << "\n\tfrom:" << fileName); result=new osg::Node; } @@ -264,7 +264,7 @@ sgLoad3DModel_internal(const SGPath& path, SGPropertyNode *overlay) { if (!path.exists()) { - SG_LOG(SG_INPUT, SG_ALERT, "Failed to load file: \"" << path << "\""); + SG_LOG(SG_IO, SG_DEV_ALERT, "Failed to load file: \"" << path << "\""); return std::make_tuple(0, (osg::Node *) NULL); } @@ -293,7 +293,7 @@ sgLoad3DModel_internal(const SGPath& path, try { readProperties(modelpath, props); } catch (const sg_exception &t) { - SG_LOG(SG_INPUT, SG_ALERT, "Failed to load xml: " + SG_LOG(SG_IO, SG_DEV_ALERT, "Failed to load xml: " << t.getFormattedMessage()); throw; } @@ -338,12 +338,12 @@ sgLoad3DModel_internal(const SGPath& path, if (!texturepath.extension().empty()) texturepath = texturepath.dir(); - options->setDatabasePath(texturepath.local8BitStr()); + options->setDatabasePath(texturepath.utf8Str()); osgDB::ReaderWriter::ReadResult modelResult; #if OSG_VERSION_LESS_THAN(3,4,1) - modelResult = osgDB::readNodeFile(modelpath.local8BitStr(), options.get()); + modelResult = osgDB::readNodeFile(modelpath.utf8Str(), options.get()); #else - modelResult = osgDB::readRefNodeFile(modelpath.local8BitStr(), options.get()); + modelResult = osgDB::readRefNodeFile(modelpath.utf8Str(), options.get()); #endif if (!modelResult.validNode()) throw sg_io_exception("Failed to load 3D model:" + modelResult.message(), @@ -414,7 +414,7 @@ sgLoad3DModel_internal(const SGPath& path, NULL, modelDir); if (submodelPath.isNull()) { - SG_LOG(SG_INPUT, SG_ALERT, "Failed to load file: \"" << subPathStr << "\""); + SG_LOG(SG_IO, SG_DEV_ALERT, "Failed to load file: \"" << subPathStr << "\""); continue; } @@ -433,7 +433,7 @@ sgLoad3DModel_internal(const SGPath& path, sub_props->getNode("overlay")); animationcount += num_anims; } catch (const sg_exception &t) { - SG_LOG(SG_INPUT, SG_ALERT, "Failed to load submodel: " << t.getFormattedMessage() + SG_LOG(SG_IO, SG_DEV_ALERT, "Failed to load submodel: " << t.getFormattedMessage() << "\n\tfrom:" << t.getOrigin()); continue; } @@ -484,7 +484,7 @@ sgLoad3DModel_internal(const SGPath& path, // Load panels vector panel_nodes = props->getChildren("panel"); for (unsigned i = 0; i < panel_nodes.size(); i++) { - SG_LOG(SG_INPUT, SG_DEBUG, "Loading a panel"); + SG_LOG(SG_IO, SG_DEBUG, "Loading a panel"); osg::ref_ptr panel = load_panel(panel_nodes[i]); if (panel_nodes[i]->hasValue("name")) panel->setName(panel_nodes[i]->getStringValue("name")); @@ -503,7 +503,7 @@ sgLoad3DModel_internal(const SGPath& path, if (!texturepath.extension().empty()) texturepath = texturepath.dir(); - options2->setDatabasePath(texturepath.local8BitStr()); + options2->setDatabasePath(texturepath.utf8Str()); } group->addChild(Particles::appendParticles(particle_nodes[i], prop_root, @@ -544,7 +544,7 @@ sgLoad3DModel_internal(const SGPath& path, group = static_cast(modelWithEffects.get()); } - simgear::SGTransientModelData modelData(group.get(), prop_root, options.get(), path.local8BitStr()); + simgear::SGTransientModelData modelData(group.get(), prop_root, options.get(), path.utf8Str()); for (unsigned i = 0; i < animation_nodes.size(); ++i) { if (previewMode && animation_nodes[i]->hasChild("nopreview")) { diff --git a/simgear/scene/model/SGText.cxx b/simgear/scene/model/SGText.cxx index 62081f13..d47b5337 100644 --- a/simgear/scene/model/SGText.cxx +++ b/simgear/scene/model/SGText.cxx @@ -97,7 +97,7 @@ osg::Node * SGText::appendText(const SGPropertyNode* configNode, SGPath path("Fonts" ); path.append( configNode->getStringValue( "font", "Helvetica" )); - text->setFont( path.local8BitStr() ); + text->setFont( path.utf8Str() ); text->setCharacterSize(configNode->getDoubleValue("character-size", 1.0 ), configNode->getDoubleValue("character-aspect-ratio", 1.0 )); diff --git a/simgear/scene/model/SGTrackToAnimation.cxx b/simgear/scene/model/SGTrackToAnimation.cxx index 2705a566..e4f4e47b 100644 --- a/simgear/scene/model/SGTrackToAnimation.cxx +++ b/simgear/scene/model/SGTrackToAnimation.cxx @@ -69,7 +69,7 @@ class FindGroupVisitor: _group(0) { if( name.empty() ) - SG_LOG(SG_IO, SG_WARN, "FindGroupVisitor: empty name provided"); + SG_LOG(SG_IO, SG_DEV_WARN, "FindGroupVisitor: empty name provided"); } osg::Group* getGroup() const @@ -91,7 +91,7 @@ class FindGroupVisitor: SG_LOG ( SG_IO, - SG_WARN, + SG_DEV_WARN, "FindGroupVisitor: name not unique '" << _name << "'" ); } @@ -154,7 +154,7 @@ class SGTrackToAnimation::UpdateCallback: if( _lock_axis.normalize() == 0.0 ) { - anim->log(SG_WARN, "invalid lock-axis"); + anim->log(SG_DEV_WARN, "invalid lock-axis"); _lock_axis.set(0, 1, 0); } @@ -184,7 +184,7 @@ class SGTrackToAnimation::UpdateCallback: if( _slave_dof < 2 ) // Without slave_dof >= 2, can not rotate out of plane normal to // lock axis. - anim->log(SG_WARN, "track-axis not perpendicular to lock-axis"); + anim->log(SG_DEV_WARN, "track-axis not perpendicular to lock-axis"); // Make tracking axis perpendicular to locked axis _track_axis -= _lock_axis * proj; @@ -192,7 +192,7 @@ class SGTrackToAnimation::UpdateCallback: if( _track_axis.normalize() == 0.0 ) { - anim->log(SG_WARN, "invalid track-axis"); + anim->log(SG_DEV_WARN, "invalid track-axis"); if( std::fabs(_lock_axis.x()) < 0.1 ) _track_axis.set(1, 0, 0); else @@ -383,7 +383,7 @@ SGTrackToAnimation::SGTrackToAnimation(simgear::SGTransientModelData &modelData) modelData.getNode()->accept(target_finder); if( !(_target_group = target_finder.getGroup()) ) - log(SG_ALERT, "target not found: '" + target + '\''); + log(SG_DEV_ALERT, "target not found: '" + target + '\''); std::string slave = modelData.getConfigNode()->getStringValue("slave-name"); if( !slave.empty() ) diff --git a/simgear/scene/model/animation.cxx b/simgear/scene/model/animation.cxx index ebe38ca6..e1d8ba70 100644 --- a/simgear/scene/model/animation.cxx +++ b/simgear/scene/model/animation.cxx @@ -426,6 +426,7 @@ struct DoDrawArraysVisitor : public osg::NodeVisitor { SGAnimation::SGAnimation(simgear::SGTransientModelData &modelData) : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), + _modelData(modelData), _found(false), _configNode(modelData.getConfigNode()), _modelRoot(modelData.getModelRoot()) @@ -454,8 +455,8 @@ SGAnimation::~SGAnimation() } if (!info.empty()) { - SG_LOG(SG_IO, SG_ALERT, "Could not find at least one of the following" - " objects for animation: " << info); + SG_LOG(SG_IO, SG_DEV_ALERT, "Could not find at least one of the following" + " objects for animation: " << info << " in file: " << _modelData.getPath()); } } } @@ -671,7 +672,7 @@ public: _group(0) { if (name.empty()) - SG_LOG(SG_IO, SG_WARN, "FindGroupVisitor: empty name provided"); + SG_LOG(SG_IO, SG_DEV_WARN, "FindGroupVisitor: empty name provided"); } osg::Group* getGroup() const @@ -693,7 +694,7 @@ public: SG_LOG ( SG_IO, - SG_WARN, + SG_DEV_WARN, "FindGroupVisitor: name not unique '" << _name << "'" ); } @@ -771,11 +772,13 @@ bool SGAnimation::setCenterAndAxisFromObject(osg::Node *rootNode, SGVec3d& cente */ object_group->setNodeMask(0); } - else - SG_LOG(SG_INPUT, SG_ALERT, "Could not find a valid line segment for animation: " << axis_object_name); + else { + SG_LOG(SG_IO, SG_DEV_ALERT, "Could not find a valid line segment for animation: " << axis_object_name << " in file: " << _modelData.getPath()); + } + } + else if (can_warn) { + SG_LOG(SG_IO, SG_DEV_ALERT, "Could not find at least one of the following objects for axis animation: " << axis_object_name << " in file: " << _modelData.getPath()); } - else if (can_warn) - SG_LOG(SG_INPUT, SG_ALERT, "Could not find at least one of the following objects for axis animation: " << axis_object_name); } if (axisSegment) { @@ -2391,12 +2394,13 @@ SGTexTransformAnimation::createAnimationGroup(osg::Group& parent) appendTexRotate(*transformConfigs[i], updateCallback); else if (subtype == "textrapezoid") appendTexTrapezoid(*transformConfigs[i], updateCallback); - else - SG_LOG(SG_INPUT, SG_ALERT, - "Ignoring unknown texture transform subtype"); + else { + SG_LOG(SG_IO, SG_DEV_ALERT, + "Ignoring unknown texture transform subtype in file: " << _modelData.getPath()); + } } } else { - SG_LOG(SG_INPUT, SG_ALERT, "Ignoring unknown texture transform type"); + SG_LOG(SG_IO, SG_DEV_ALERT, "Ignoring unknown texture transform type in file: " << _modelData.getPath()); } texMat->setUpdateCallback(updateCallback); diff --git a/simgear/scene/model/animation.hxx b/simgear/scene/model/animation.hxx index e00db1ad..2a4897ab 100644 --- a/simgear/scene/model/animation.hxx +++ b/simgear/scene/model/animation.hxx @@ -100,6 +100,7 @@ protected: const SGCondition* getCondition() const; + simgear::SGTransientModelData &_modelData; std::list _objectNames; private: void installInGroup(const std::string& name, osg::Group& group, diff --git a/simgear/scene/model/model.hxx b/simgear/scene/model/model.hxx index 956d329b..4e719527 100644 --- a/simgear/scene/model/model.hxx +++ b/simgear/scene/model/model.hxx @@ -47,7 +47,7 @@ SGLoadTexture2D(const SGPath& path, bool wrapu = true, bool wrapv = true, int mipmaplevels = -1) { - return SGLoadTexture2D(true, path.local8BitStr(), options, wrapu, wrapv, + return SGLoadTexture2D(true, path.utf8Str(), options, wrapu, wrapv, mipmaplevels); } @@ -57,7 +57,7 @@ SGLoadTexture2D(bool staticTexture, const SGPath& path, bool wrapu = true, bool wrapv = true, int mipmaplevels = -1) { - return SGLoadTexture2D(staticTexture, path.local8BitStr(), options, wrapu, wrapv, + return SGLoadTexture2D(staticTexture, path.utf8Str(), options, wrapu, wrapv, mipmaplevels); } diff --git a/simgear/scene/model/modellib.cxx b/simgear/scene/model/modellib.cxx index 92b19196..1dd32459 100644 --- a/simgear/scene/model/modellib.cxx +++ b/simgear/scene/model/modellib.cxx @@ -77,13 +77,27 @@ std::string SGModelLib::findDataFile(const std::string& file, return file; SGPath p = ResourceManager::instance()->findPath(file, currentPath); if (p.exists()) { - return p.local8BitStr(); + return p.utf8Str(); } // finally hand on to standard OSG behaviour return osgDB::findDataFile(file, opts); } +std::string SGModelLib::findDataFile(const SGPath& file, + const osgDB::Options* opts, + SGPath currentPath) +{ + SGPath p = ResourceManager::instance()->findPath(file.utf8Str(), currentPath); + if (p.exists()) { + return p.utf8Str(); + } + + // finally hand on to standard OSG behaviour + return osgDB::findDataFile(file.utf8Str(), opts); +} + + SGModelLib::SGModelLib() { } diff --git a/simgear/scene/model/modellib.hxx b/simgear/scene/model/modellib.hxx index b9be0311..6032bb1e 100644 --- a/simgear/scene/model/modellib.hxx +++ b/simgear/scene/model/modellib.hxx @@ -85,7 +85,11 @@ public: SGModelData *data=0); static std::string findDataFile(const std::string& file, - const osgDB::Options* opts = NULL, + const osgDB::Options* opts = nullptr, + SGPath currentDir = SGPath()); + + static std::string findDataFile(const SGPath& file, + const osgDB::Options* opts = nullptr, SGPath currentDir = SGPath()); protected: SGModelLib(); diff --git a/simgear/scene/sky/cloud.cxx b/simgear/scene/sky/cloud.cxx index 89a964b7..08649e1e 100644 --- a/simgear/scene/sky/cloud.cxx +++ b/simgear/scene/sky/cloud.cxx @@ -78,7 +78,7 @@ SGMakeState(const SGPath &path, const char* colorTexture, osg::StateSet *stateSet = new osg::StateSet; osg::ref_ptr options; - options = SGReaderWriterOptions::fromPath(path.local8BitStr()); + options = SGReaderWriterOptions::fromPath(path); stateSet->setTextureAttribute(0, SGLoadTexture2D(colorTexture, options.get())); stateSet->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON); @@ -93,7 +93,7 @@ SGMakeState(const SGPath &path, const char* colorTexture, } // Constructor -SGCloudLayer::SGCloudLayer( const string &tex_path ) : +SGCloudLayer::SGCloudLayer( const SGPath &tex_path ) : cloud_root(new osg::Switch), layer_root(new osg::Switch), group_top(new osg::Group), diff --git a/simgear/scene/sky/cloud.hxx b/simgear/scene/sky/cloud.hxx index fb4cf3c5..65b525fa 100644 --- a/simgear/scene/sky/cloud.hxx +++ b/simgear/scene/sky/cloud.hxx @@ -42,6 +42,7 @@ #include class SGCloudField; +class SGPath; /** * A class layer to model a single cloud layer @@ -73,7 +74,7 @@ public: * Constructor * @param tex_path the path to the set of cloud textures */ - SGCloudLayer( const std::string &tex_path ); + SGCloudLayer( const SGPath &tex_path ); /** * Destructor diff --git a/simgear/scene/sky/moon.cxx b/simgear/scene/sky/moon.cxx index 7f7412d1..d9a1e39c 100644 --- a/simgear/scene/sky/moon.cxx +++ b/simgear/scene/sky/moon.cxx @@ -76,7 +76,7 @@ SGMoon::build( SGPath path, double moon_size ) { // set up the orb state osg::ref_ptr options; - options = SGReaderWriterOptions::fromPath(path.local8BitStr()); + options = SGReaderWriterOptions::fromPath(path); osg::Texture2D* texture = SGLoadTexture2D("moon.png", options.get()); stateSet->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON); diff --git a/simgear/scene/sky/newcloud.cxx b/simgear/scene/sky/newcloud.cxx index 8e9eb714..96437427 100644 --- a/simgear/scene/sky/newcloud.cxx +++ b/simgear/scene/sky/newcloud.cxx @@ -118,7 +118,7 @@ SGNewCloud::SGNewCloud(const SGPath &texture_root, const SGPropertyNode *cld_def "image"), texture); ref_ptr options; - options = SGReaderWriterOptions::fromPath(texture_root.local8BitStr()); + options = SGReaderWriterOptions::fromPath(texture_root); effect = makeEffect(pcloudEffect, true, options.get()); if (effect.valid()) { diff --git a/simgear/scene/sky/oursun.cxx b/simgear/scene/sky/oursun.cxx index 1e856f64..43d3e3b2 100644 --- a/simgear/scene/sky/oursun.cxx +++ b/simgear/scene/sky/oursun.cxx @@ -70,7 +70,7 @@ SGSun::build( SGPath path, double sun_size, SGPropertyNode *property_tree_Node ) env_node = property_tree_Node; osg::ref_ptr options; - options = SGReaderWriterOptions::fromPath(path.local8BitStr()); + options = SGReaderWriterOptions::fromPath(path); // build the ssg scene graph sub tree for the sky and connected // into the provide scene graph branch sun_transform = new osg::MatrixTransform; diff --git a/simgear/scene/sky/sky.cxx b/simgear/scene/sky/sky.cxx index 25df35d7..796b1522 100644 --- a/simgear/scene/sky/sky.cxx +++ b/simgear/scene/sky/sky.cxx @@ -296,8 +296,9 @@ void SGSky::set_3dCloudUseImpostors(bool imp) SGCloudField::setUseImpostors(imp); } -void SGSky::texture_path( const std::string& path ) { - tex_path = SGPath( path ); +void SGSky::set_texture_path( const SGPath& path ) +{ + tex_path = path; } // modify the current visibility based on cloud layers, thickness, diff --git a/simgear/scene/sky/sky.hxx b/simgear/scene/sky/sky.hxx index a824b74a..a07d9d0c 100644 --- a/simgear/scene/sky/sky.hxx +++ b/simgear/scene/sky/sky.hxx @@ -326,7 +326,7 @@ public: * * @param path Base path to texture locations */ - void texture_path( const std::string& path ); + void set_texture_path( const SGPath& path ); /** * Get the current sun color diff --git a/simgear/scene/tgdb/ReaderWriterSTG.cxx b/simgear/scene/tgdb/ReaderWriterSTG.cxx index 73fc9da0..9aff6737 100644 --- a/simgear/scene/tgdb/ReaderWriterSTG.cxx +++ b/simgear/scene/tgdb/ReaderWriterSTG.cxx @@ -276,7 +276,7 @@ struct ReaderWriterSTG::_ModelBin { SGPath path = filePath; path.append(".."); path.append(".."); path.append(".."); - sharedOptions->getDatabasePathList().push_back(path.local8BitStr()); + sharedOptions->getDatabasePathList().push_back(path.utf8Str()); // ensure Models directory synced via TerraSync is searched before the copy in // FG_ROOT, so that updated models can be used. @@ -372,7 +372,7 @@ struct ReaderWriterSTG::_ModelBin { SG_LOG(SG_TERRAIN, SG_INFO, "Loading stg file " << absoluteFileName); - std::string filePath = osgDB::getFilePath(absoluteFileName.local8BitStr()); + std::string filePath = osgDB::getFilePath(absoluteFileName.utf8Str()); // Bucket provides a consistent seed // so we have consistent set of pseudo-random numbers for each STG file @@ -420,7 +420,7 @@ struct ReaderWriterSTG::_ModelBin { _Object obj; obj._errorLocation = absoluteFileName; obj._token = token; - obj._name = path.local8BitStr(); + obj._name = path.utf8Str(); obj._options = staticOptions(filePath, options); _objectList.push_back(obj); } @@ -430,7 +430,7 @@ struct ReaderWriterSTG::_ModelBin { _Object obj; obj._errorLocation = absoluteFileName; obj._token = token; - obj._name = path.local8BitStr(); + obj._name = path.utf8Str(); obj._options = staticOptions(filePath, options); _objectList.push_back(obj); } @@ -537,7 +537,7 @@ struct ReaderWriterSTG::_ModelBin { _objectStaticList.push_back(obj); } else if (token == BUILDING_LIST) { _BuildingList buildinglist; - buildinglist._filename = path.local8BitStr(); + buildinglist._filename = path.utf8Str(); in >> buildinglist._material_name >> buildinglist._lon >> buildinglist._lat >> buildinglist._elev; checkInsideBucket(absoluteFileName, buildinglist._lon, buildinglist._lat); _buildingListList.push_back(buildinglist); diff --git a/simgear/scene/util/SGReaderWriterOptions.cxx b/simgear/scene/util/SGReaderWriterOptions.cxx index 12e32128..8937bd42 100644 --- a/simgear/scene/util/SGReaderWriterOptions.cxx +++ b/simgear/scene/util/SGReaderWriterOptions.cxx @@ -47,10 +47,10 @@ SGReaderWriterOptions::copyOrCreate(const osgDB::Options* options) } SGReaderWriterOptions* -SGReaderWriterOptions::fromPath(const std::string& path) +SGReaderWriterOptions::fromPath(const SGPath& path) { - SGReaderWriterOptions* options = copyOrCreate(0); - options->setDatabasePath(path); + SGReaderWriterOptions* options = copyOrCreate(nullptr); + options->setDatabasePath(path.utf8Str()); return options; } diff --git a/simgear/scene/util/SGReaderWriterOptions.hxx b/simgear/scene/util/SGReaderWriterOptions.hxx index 17183944..e22648f0 100644 --- a/simgear/scene/util/SGReaderWriterOptions.hxx +++ b/simgear/scene/util/SGReaderWriterOptions.hxx @@ -31,6 +31,8 @@ #endif class SGPropertyNode; +class SGPath; + typedef std::vector < std::string > string_list; namespace simgear @@ -43,6 +45,7 @@ public: ORIGIN_MODEL, ORIGIN_EFFECTS, ORIGIN_EFFECTS_NORMALIZED, + ORIGIN_SPLASH_SCREEN, }; //SGReaderWriterOptions* cloneOptions(const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY) const { return static_cast(clone(copyop)); } @@ -50,7 +53,6 @@ public: SGReaderWriterOptions() : _materialLib(0), _load_panel(0), - _model_data(0), _instantiateEffects(false), _instantiateMaterialEffects(false), _LoadOriginHint(ORIGIN_MODEL) @@ -59,7 +61,6 @@ public: osgDB::Options(str), _materialLib(0), _load_panel(0), - _model_data(0), _instantiateEffects(false), _instantiateMaterialEffects(false), _LoadOriginHint(ORIGIN_MODEL) @@ -69,7 +70,6 @@ public: osgDB::Options(options, copyop), _materialLib(0), _load_panel(0), - _model_data(0), _instantiateEffects(false), _instantiateMaterialEffects(false), _LoadOriginHint(ORIGIN_MODEL) @@ -144,7 +144,7 @@ public: { _sceneryPathSuffixes = suffixes; } static SGReaderWriterOptions* copyOrCreate(const osgDB::Options* options); - static SGReaderWriterOptions* fromPath(const std::string& path); + static SGReaderWriterOptions* fromPath(const SGPath& path); void setLocation(double lon, double lat) { _geod = SGGeod::fromDeg(lon, lat); } diff --git a/simgear/timing/lowleveltime.cxx b/simgear/timing/lowleveltime.cxx index ae994f31..903877c4 100644 --- a/simgear/timing/lowleveltime.cxx +++ b/simgear/timing/lowleveltime.cxx @@ -42,6 +42,7 @@ #include #include +#include #include "lowleveltime.h" @@ -857,7 +858,12 @@ void fgtzfile_read (const char *file) // file = _new; // } - f = fopen (file, "rb"); +#if defined(SG_WINDOWS) + const std::wstring wfile = simgear::strutils::convertUtf8ToWString(file); + f = _wfopen(wfile.c_str(), L"rb"); +#else + f = fopen(file, "rb"); +#endif if (f == NULL) { perror( "fgtzfile_read(): " ); diff --git a/simgear/timing/sg_time.cxx b/simgear/timing/sg_time.cxx index 83b22aec..bbabd1a4 100644 --- a/simgear/timing/sg_time.cxx +++ b/simgear/timing/sg_time.cxx @@ -86,7 +86,7 @@ void SGTime::init( const SGGeod& location, const SGPath& root, time_t init_time SGPath zone( root ); zone.append( "zone.tab" ); SG_LOG( SG_EVENT, SG_INFO, "Reading timezone info from: " << zone ); - std::string zs = zone.local8BitStr(); + std::string zs = zone.utf8Str(); static_tzContainer.reset(new SGTimeZoneContainer( zs.c_str() )); } @@ -222,7 +222,7 @@ void SGTime::update( const SGGeod& location, time_t ct, long int warp ) // Given lon/lat, update timezone information and local_offset -void SGTime::updateLocal( const SGGeod& aLocation, const string& root ) { +void SGTime::updateLocal( const SGGeod& aLocation, const SGPath& root ) { SGGeod location(aLocation); if (!aLocation.isValid()) { location = SGGeod(); @@ -243,7 +243,7 @@ void SGTime::updateLocal( const SGGeod& aLocation, const string& root ) { } currGMT = sgTimeGetGMT( gmtime(&cur_time) ); - std::string zs = zone.local8BitStr(); + std::string zs = zone.utf8Str(); aircraftLocalTime = sgTimeGetGMT( (fgLocaltime(&cur_time, zs.c_str())) ); local_offset = aircraftLocalTime - currGMT; // cout << "Using " << local_offset << " as local time offset Timezone is " diff --git a/simgear/timing/sg_time.hxx b/simgear/timing/sg_time.hxx index 00c058af..0990d0e2 100644 --- a/simgear/timing/sg_time.hxx +++ b/simgear/timing/sg_time.hxx @@ -162,7 +162,7 @@ public: * @param location Current geodetic location * @param root Bbase path containing time zone directory */ - void updateLocal( const SGGeod& location, const std::string& root ); + void updateLocal( const SGGeod& location, const SGPath& root ); /** @return current system/unix time in seconds */ inline time_t get_cur_time() const { return cur_time; }; diff --git a/simgear/timing/timezone.cxx b/simgear/timing/timezone.cxx old mode 100644 new mode 100755 index 4fa6746c..b1fc6344 --- a/simgear/timing/timezone.cxx +++ b/simgear/timing/timezone.cxx @@ -36,6 +36,7 @@ #include #include +#include #include "timezone.h" @@ -134,7 +135,12 @@ SGTimeZone::SGTimeZone(const SGTimeZone& other) SGTimeZoneContainer::SGTimeZoneContainer(const char *filename) { char buffer[256]; - FILE* infile = fopen(filename, "rb"); +#if defined(SG_WINDOWS) + const std::wstring wfile = simgear::strutils::convertUtf8ToWString(filename); + FILE* infile = _wfopen(wfile.c_str(), L"rb"); +#else + FILE* infile = fopen(filename, "rb"); +#endif if (!(infile)) { std::string e = "Unable to open time zone file '"; throw sg_exception(e + filename + '\'');