From Sukender, "1. Made code a bit more readable/cleaner.

2. Removed unecessary code. Also made sure the images names are not truncated in the middle of an UTF8 character. You'll find there a function called utf8TruncateBytes(), which may be moved in core OSG (osgDB/ConvertUTF I guess). Feel free to do it if you feel it that way.
"
This commit is contained in:
Robert Osfield
2011-03-09 14:44:14 +00:00
parent d3d0859b4c
commit 7640e9535d
2 changed files with 45 additions and 60 deletions

View File

@@ -268,9 +268,9 @@ ReaderWriter3DS::ReaderObject::ReaderObject(const osgDB::ReaderWriter::Options*
{
if (opt == "noMatrixTransforms")
noMatrixTransforms = true;
if (opt == "checkForEspilonIdentityMatrices")
else if (opt == "checkForEspilonIdentityMatrices")
checkForEspilonIdentityMatrices = true;
if (opt == "restoreMatrixTransformsNoMeshes")
else if (opt == "restoreMatrixTransformsNoMeshes")
restoreMatrixTransformsNoMeshes = true;
}
}
@@ -487,13 +487,14 @@ osg::Node* ReaderWriter3DS::ReaderObject::processNode(StateSetMap drawStateMap,L
// Retreive LOCAL transform
static const osg::Matrix::value_type MATRIX_EPSILON = 1e-10;
osg::Matrix osgNodeMatrix( copyLib3dsMatrixToOsgMatrix(node->matrix) );
osg::Matrix osgWorldToNodeMatrix( copyLib3dsMatrixToOsgMatrix(node->matrix) );
osg::Matrix osgWorldToParentNodeMatrix;
if (node->parent)
{
// Matrices evaluated by lib3DS are multiplied by parents' ones
osgNodeMatrix *= osg::Matrix::inverse( copyLib3dsMatrixToOsgMatrix(node->parent->matrix) );
osgWorldToParentNodeMatrix = copyLib3dsMatrixToOsgMatrix(node->parent->matrix);
}
osg::Matrix osgNodeMatrix( osgWorldToNodeMatrix * osg::Matrix::inverse(osgWorldToParentNodeMatrix) );
// Test if we should create an intermediate Group (or MatrixTransform) and which matrix we should apply to the vertices
osg::Group* group = NULL;
@@ -505,20 +506,20 @@ osg::Node* ReaderWriter3DS::ReaderObject::processNode(StateSetMap drawStateMap,L
osg::Matrix meshMat;
if (mesh)
{
if (!noMatrixTransforms)
{
if (!noMatrixTransforms)
{
// There can be a transform directly on a mesh instance (= as if a osg::MatrixTransform and a osg::Geode were merged together) in object->pos/rot/scl
if (!pivoted) {
meshMat = osg::Matrix::inverse(copyLib3dsMatrixToOsgMatrix(mesh->matrix));
} else {
if (pivoted) {
meshMat = osg::Matrix::inverse(copyLib3dsMatrixToOsgMatrix(mesh->matrix)) * osg::Matrix::translate(-pivot);
} else {
meshMat = osg::Matrix::inverse(copyLib3dsMatrixToOsgMatrix(mesh->matrix));
}
}
else {
if (pivoted) {
meshMat = osg::Matrix::inverse(copyLib3dsMatrixToOsgMatrix(mesh->matrix)) * osg::Matrix::translate(-pivot) * copyLib3dsMatrixToOsgMatrix(node->matrix);
meshMat = osg::Matrix::inverse(copyLib3dsMatrixToOsgMatrix(mesh->matrix)) * osg::Matrix::translate(-pivot) * osgWorldToNodeMatrix;
} else {
meshMat = osg::Matrix::inverse(copyLib3dsMatrixToOsgMatrix(mesh->matrix)) * copyLib3dsMatrixToOsgMatrix(node->matrix);
meshMat = osg::Matrix::inverse(copyLib3dsMatrixToOsgMatrix(mesh->matrix)) * osgWorldToNodeMatrix; // ==Identity when not pivoted?
}
osgNodeMatrix = osg::Matrix::identity(); // Not sure it's useful, but it's harmless ;)
}

View File

@@ -91,6 +91,7 @@ std::string getFileName(const std::string & path)
/// Checks if a filename (\b not path) is 8.3 (an empty name is never 8.3, and a path is never 8.3).
/// Please note the '8' and '3' limitations are in \b bytes, not in characters (which is different when using UTF8).
bool is83(const std::string & s)
{
// 012345678901
@@ -441,49 +442,6 @@ WriterNodeVisitor::Material::Material(WriterNodeVisitor & writerNodeVisitor, osg
}
// If 'to' is in a subdirectory of 'from' then this function returns the
// subpath. Otherwise it just returns the file name.
// (Same as in FBX plugin)
std::string getPathRelative(const std::string& from/*directory*/,
const std::string& to/*file path*/)
{
std::string::size_type slash = to.find_last_of('/');
std::string::size_type backslash = to.find_last_of('\\');
if (slash == std::string::npos)
{
if (backslash == std::string::npos) return to;
slash = backslash;
}
else if (backslash != std::string::npos && backslash > slash)
{
slash = backslash;
}
if (from.empty() || from.length() > to.length())
return osgDB::getSimpleFileName(to);
std::string::const_iterator itTo = to.begin();
for (std::string::const_iterator itFrom = from.begin();
itFrom != from.end(); ++itFrom, ++itTo)
{
char a = tolower(*itFrom), b = tolower(*itTo);
if (a == '\\') a = '/';
if (b == '\\') b = '/';
if (a != b || itTo == to.begin() + slash + 1)
{
return osgDB::getSimpleFileName(to);
}
}
while (itTo != to.end() && (*itTo == '\\' || *itTo == '/'))
{
++itTo;
}
return std::string(itTo, to.end());
}
/// Converts an extension to a 3-letters long one equivalent.
std::string convertExt(const std::string & path, bool extendedFilePaths)
{
@@ -562,7 +520,7 @@ void WriterNodeVisitor::writeMaterials()
}
else
{
path = getPathRelative(_srcDirectory, mat.image->getFileName());
path = osgDB::getPathRelative(_srcDirectory, mat.image->getFileName());
}
path = convertExt(path, _extendedFilePaths);
@@ -597,6 +555,31 @@ void WriterNodeVisitor::writeMaterials()
}
}
/// Truncates an UTF8 string so that it does not takes more than a given \b bytes amount (\b excluding the potential NULL end character).
/// The function assumes the UTF8 string is valid.
///\return A valid UTF8 string which size is less or equal to \c byteLimit.
// May be moved in osgDB/ConvertUTF?
std::string utf8TruncateBytes(const std::string & s, std::string::size_type byteLimit) {
// Untruncated strings
if (s.size() <= byteLimit) return s;
// Truncated strings
std::string::const_iterator it=s.begin(), itEnd=s.begin()+byteLimit;
std::string::const_iterator itStop=it;
// Note: itEnd is < s.end(), so that we can always write "it+1"
for(; it!=itEnd; ++it) {
unsigned char c = static_cast<unsigned char>(*it);
if ((c & 0x80) == 0) itStop=it+1; // 7 bits ANSI. itStop must then point after that character.
else if ((c & 0x40) != 0) itStop=it; // UTF8 sequence start: this is also past-the-end for the previous character (ANSI or UTF8)
}
return std::string(s.begin(), itStop);
}
#ifdef OSG_USE_UTF8_FILENAME
# define truncateFilenameBytes(str, size) utf8TruncateBytes(str, size)
#else
# define truncateFilenameBytes(str, size) std::string(str, 0, size)
#endif
std::string WriterNodeVisitor::getUniqueName(const std::string& _defaultValue, const std::string & _defaultPrefix, bool nameIsPath)
{
@@ -615,7 +598,8 @@ std::string WriterNodeVisitor::getUniqueName(const std::string& _defaultValue, c
// Handling of paths is not well done yet. Defaulting to something very simple.
// We should actually ensure each component is 8 chars long, and final filename is 8.3, and total is <64 chars, or simply ensure total length for extended 3DS paths.
std::string defaultValue(nameIsPath ? osgDB::getSimpleFileName(_defaultValue) : _defaultValue);
std::string ext(nameIsPath ? osgDB::getFileExtensionIncludingDot(_defaultValue).substr(0, std::min<unsigned int>(_defaultValue.size(), 4)) : ""); // 4 chars = dot + 3 chars
std::string ext(nameIsPath ? osgDB::getFileExtensionIncludingDot(_defaultValue) : "");
ext = truncateFilenameBytes(ext, std::min<unsigned int>(_defaultValue.size(), 4)); // 4 chars = dot + 3 chars
if (ext == ".") ext = "";
std::string defaultPrefix(_defaultPrefix.empty() ? "_" : _defaultPrefix);
@@ -626,12 +610,12 @@ std::string WriterNodeVisitor::getUniqueName(const std::string& _defaultValue, c
{
if (defaultValue[i] == '.')
{
truncDefaultValue = defaultValue.substr(0, i);
truncDefaultValue = truncateFilenameBytes(defaultValue, i);
break;
}
}
if (truncDefaultValue.empty())
truncDefaultValue = defaultValue.substr(0, std::min<unsigned int>(defaultValue.size(), MAX_PREFIX_LEGNTH));
truncDefaultValue = truncateFilenameBytes(defaultValue, std::min<unsigned int>(defaultValue.size(), MAX_PREFIX_LEGNTH));
assert(truncDefaultValue.size() <= MAX_PREFIX_LEGNTH);
std::map<std::string, unsigned int>::iterator pairPrefix;
@@ -680,7 +664,7 @@ std::string WriterNodeVisitor::getUniqueName(const std::string& _defaultValue, c
// Failed finding a name
// Try with a shorter prefix if possible
if (defaultPrefix.length()>1) return getUniqueName(_defaultValue, defaultPrefix.substr(0, defaultPrefix.length()-1), nameIsPath);
if (defaultPrefix.length()>1) return getUniqueName(_defaultValue, truncateFilenameBytes(defaultPrefix, defaultPrefix.length()-1), nameIsPath);
// Try with default prefix if not arleady done
if (defaultPrefix != std::string("_")) return getUniqueName(_defaultValue, "_", nameIsPath);