This commit is contained in:
gallaert
2020-03-15 21:32:42 +00:00
42 changed files with 220 additions and 122 deletions

View File

@@ -866,6 +866,11 @@ SGRect<int> intersectRect(const SGRect<int>& a, const SGRect<int>& b)
void Image::fillRect(const SGRect<int>& rect, const osg::Vec4& color)
{
osg::ref_ptr<osg::Image> image = _texture->getImage();
if (!image) {
allocateImage();
image = _texture->getImage();
}
const auto format = image->getInternalTextureFormat();
auto clippedRect = intersectRect(rect, SGRect<int>(0, 0, image->s(), image->t()));
@@ -881,6 +886,7 @@ SGRect<int> intersectRect(const SGRect<int>& a, const SGRect<int>& b)
switch (format) {
case GL_RGBA8:
case GL_RGBA:
rowByteSize = pixelWidth * 4;
rowData = static_cast<GLubyte*>(alloca(rowByteSize));
@@ -892,6 +898,7 @@ SGRect<int> intersectRect(const SGRect<int>& a, const SGRect<int>& b)
break;
case GL_RGB8:
case GL_RGB:
rowByteSize = pixelWidth * 3;
rowData = static_cast<GLubyte*>(alloca(rowByteSize));
pixel = color.asABGR();
@@ -908,8 +915,8 @@ SGRect<int> intersectRect(const SGRect<int>& a, const SGRect<int>& 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<int> intersectRect(const SGRect<int>& a, const SGRect<int>& b)
void Image::setPixel(int x, int y, const osg::Vec4& color)
{
osg::ref_ptr<osg::Image> 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<osg::Image> Image::getImage() const
{
if (!_texture)
return {};
return _texture->getImage();
}
} // namespace canvas
} // namespace simgear

View File

@@ -115,6 +115,7 @@ namespace canvas
void setPixel(int x, int y, const osg::Vec4& color);
osg::ref_ptr<osg::Image> 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<osg::Texture2D> _texture;
// TODO optionally forward events to canvas
CanvasWeakPtr _src_canvas;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

7
simgear/misc/path_test.cxx Normal file → Executable file
View File

@@ -333,6 +333,12 @@ void test_hash_function()
SG_CHECK_NE(std::hash<SGPath>{}(p), std::hash<SGPath>{}(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

View File

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

View File

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

View File

@@ -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<std::codecvt_utf8<wchar_t>, 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<std::codecvt_utf8<wchar_t>, wchar_t> ucs2conv;
return ucs2conv.to_bytes(w);
return convertWStringToMultiByte(CP_UTF8, w);
#else
assert(sizeof(wchar_t) == 4);
std::string result;

View File

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

View File

@@ -81,6 +81,8 @@
#include <simgear/props/props_io.hxx>
#include <simgear/props/vectorPropTemplates.hxx>
#include <simgear/io/iostreams/sgstream.hxx>
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<Uniform> 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> 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));
}

View File

@@ -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 \""

View File

@@ -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<osgDB::Options> 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();

View File

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

View File

@@ -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<const SGReaderWriterOptions*>(opt);
if (cache_active && (!sgoptC || sgoptC->getLoadOriginHint() != SGReaderWriterOptions::LoadOriginHint::ORIGIN_SPLASH_SCREEN)) {
if (fileExtension != "dds" && fileExtension != "gz") {
const SGReaderWriterOptions* sgoptC = dynamic_cast<const SGReaderWriterOptions*>(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;
}

View File

@@ -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 <global> in material animation is "
"no longer supported.");
}

View File

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

View File

@@ -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<SGPropertyNode_ptr> 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<osg::Node> 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<Group*>(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")) {

View File

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

View File

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

View File

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

View File

@@ -100,6 +100,7 @@ protected:
const SGCondition* getCondition() const;
simgear::SGTransientModelData &_modelData;
std::list<std::string> _objectNames;
private:
void installInGroup(const std::string& name, osg::Group& group,

View File

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

View File

@@ -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()
{
}

View File

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

View File

@@ -78,7 +78,7 @@ SGMakeState(const SGPath &path, const char* colorTexture,
osg::StateSet *stateSet = new osg::StateSet;
osg::ref_ptr<SGReaderWriterOptions> 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),

View File

@@ -42,6 +42,7 @@
#include <osg/Switch>
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

View File

@@ -76,7 +76,7 @@ SGMoon::build( SGPath path, double moon_size ) {
// set up the orb state
osg::ref_ptr<SGReaderWriterOptions> 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);

View File

@@ -118,7 +118,7 @@ SGNewCloud::SGNewCloud(const SGPath &texture_root, const SGPropertyNode *cld_def
"image"),
texture);
ref_ptr<SGReaderWriterOptions> options;
options = SGReaderWriterOptions::fromPath(texture_root.local8BitStr());
options = SGReaderWriterOptions::fromPath(texture_root);
effect = makeEffect(pcloudEffect, true, options.get());
if (effect.valid())
{

View File

@@ -70,7 +70,7 @@ SGSun::build( SGPath path, double sun_size, SGPropertyNode *property_tree_Node )
env_node = property_tree_Node;
osg::ref_ptr<SGReaderWriterOptions> 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;

View File

@@ -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,

View File

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

View File

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

View File

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

View File

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

View File

@@ -42,6 +42,7 @@
#include <limits.h>
#include <simgear/structure/exception.hxx>
#include <simgear/misc/strutils.hxx>
#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(): " );

View File

@@ -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 "

View File

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

8
simgear/timing/timezone.cxx Normal file → Executable file
View File

@@ -36,6 +36,7 @@
#include <cstdlib>
#include <simgear/structure/exception.hxx>
#include <simgear/misc/strutils.hxx>
#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 + '\'');