From Sukender, "I found the bug I was chasing! Here is my "twin" submission, from latest trunk rev: 12124.
1. DAE submission: DAE plugin now correctly writes images URI in Collada file, when images are used twice. I also greatly improved readability and maintenability of geometry reading (mainly daeRGeometry.cpp), by factorizing code, templatizing it (for double/single precision), and removing ugly macros. 2. osgDB submission: I updated osgDB::getPathRelative(): it is now far more readable, it handles more cases (especially when you want to relativise "a/c" from "a/b", which results in "../c"), and I added comments to make it clearer to maintain."
This commit is contained in:
@@ -31,9 +31,13 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
static const char * const PATH_SEPARATORS = "/\\";
|
||||
static unsigned int PATH_SEPARATORS_LEN = 2;
|
||||
|
||||
|
||||
std::string osgDB::getFilePath(const std::string& fileName)
|
||||
{
|
||||
std::string::size_type slash = fileName.find_last_of("/\\");
|
||||
std::string::size_type slash = fileName.find_last_of(PATH_SEPARATORS);
|
||||
if (slash==std::string::npos) return std::string();
|
||||
else return std::string(fileName, 0, slash);
|
||||
}
|
||||
@@ -41,7 +45,7 @@ std::string osgDB::getFilePath(const std::string& fileName)
|
||||
|
||||
std::string osgDB::getSimpleFileName(const std::string& fileName)
|
||||
{
|
||||
std::string::size_type slash = fileName.find_last_of("/\\");
|
||||
std::string::size_type slash = fileName.find_last_of(PATH_SEPARATORS);
|
||||
if (slash==std::string::npos) return fileName;
|
||||
else return std::string(fileName.begin()+slash+1,fileName.end());
|
||||
}
|
||||
@@ -50,7 +54,7 @@ std::string osgDB::getSimpleFileName(const std::string& fileName)
|
||||
std::string osgDB::getFileExtension(const std::string& fileName)
|
||||
{
|
||||
std::string::size_type dot = fileName.find_last_of('.');
|
||||
std::string::size_type slash = fileName.find_last_of("/\\");
|
||||
std::string::size_type slash = fileName.find_last_of(PATH_SEPARATORS);
|
||||
if (dot==std::string::npos || (slash!=std::string::npos && dot<slash)) return std::string("");
|
||||
return std::string(fileName.begin()+dot+1,fileName.end());
|
||||
}
|
||||
@@ -58,7 +62,7 @@ std::string osgDB::getFileExtension(const std::string& fileName)
|
||||
std::string osgDB::getFileExtensionIncludingDot(const std::string& fileName)
|
||||
{
|
||||
std::string::size_type dot = fileName.find_last_of('.');
|
||||
std::string::size_type slash = fileName.find_last_of("/\\");
|
||||
std::string::size_type slash = fileName.find_last_of(PATH_SEPARATORS);
|
||||
if (dot==std::string::npos || (slash!=std::string::npos && dot<slash)) return std::string("");
|
||||
return std::string(fileName.begin()+dot,fileName.end());
|
||||
}
|
||||
@@ -138,7 +142,7 @@ std::string osgDB::convertToLowerCase(const std::string& str)
|
||||
std::string osgDB::getNameLessExtension(const std::string& fileName)
|
||||
{
|
||||
std::string::size_type dot = fileName.find_last_of('.');
|
||||
std::string::size_type slash = fileName.find_last_of("/\\"); // Finds forward slash *or* back slash
|
||||
std::string::size_type slash = fileName.find_last_of(PATH_SEPARATORS); // Finds forward slash *or* back slash
|
||||
if (dot==std::string::npos || (slash!=std::string::npos && dot<slash)) return fileName;
|
||||
return std::string(fileName.begin(),fileName.begin()+dot);
|
||||
}
|
||||
@@ -148,7 +152,7 @@ std::string osgDB::getNameLessExtension(const std::string& fileName)
|
||||
std::string osgDB::getNameLessAllExtensions(const std::string& fileName)
|
||||
{
|
||||
// Finds start serach position: from last slash, or the begining of the string if none found
|
||||
std::string::size_type startPos = fileName.find_last_of("/\\"); // Finds forward slash *or* back slash
|
||||
std::string::size_type startPos = fileName.find_last_of(PATH_SEPARATORS); // Finds forward slash *or* back slash
|
||||
if (startPos == std::string::npos) startPos = 0;
|
||||
std::string::size_type dot = fileName.find_first_of('.', startPos); // Finds *FIRST* dot from start pos
|
||||
if (dot==std::string::npos) return fileName;
|
||||
@@ -321,45 +325,101 @@ std::string osgDB::getRealPath(const std::string& path)
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string osgDB::getPathRelative(const std::string& from, const std::string& to)
|
||||
{
|
||||
std::string::size_type slash = to.find_last_of('/');
|
||||
std::string::size_type backslash = to.find_last_of('\\');
|
||||
if (slash == std::string::npos)
|
||||
|
||||
/// Helper to iterate over elements of a path (including Windows' root, if any).
|
||||
class PathIterator {
|
||||
public:
|
||||
PathIterator(const std::string & v) : end(v.end()), start(v.begin()), stop(v.begin()) { operator++(); }
|
||||
bool valid() const { return start!=end; }
|
||||
PathIterator & operator++()
|
||||
{
|
||||
if (backslash == std::string::npos) return to;
|
||||
slash = backslash;
|
||||
if (!valid()) return *this;
|
||||
start = skipSeparators(stop);
|
||||
if (start != end) stop = next(start);
|
||||
return *this;
|
||||
}
|
||||
else if (backslash != std::string::npos && backslash > slash)
|
||||
std::string operator*()
|
||||
{
|
||||
slash = backslash;
|
||||
if (!valid()) return std::string();
|
||||
return std::string(start, stop);
|
||||
}
|
||||
|
||||
if (from.empty() || from.length() > to.length())
|
||||
return osgDB::getSimpleFileName(to);
|
||||
protected:
|
||||
std::string::const_iterator end; ///< End of path string
|
||||
std::string::const_iterator start; ///< Points to the first char of an element, or ==end() if no more
|
||||
std::string::const_iterator stop; ///< Points to the separator after 'start', or ==end()
|
||||
|
||||
std::string::const_iterator itTo = to.begin();
|
||||
for (std::string::const_iterator itFrom = from.begin();
|
||||
itFrom != from.end(); ++itFrom, ++itTo)
|
||||
/// Iterate until 'it' points to something different from a separator
|
||||
std::string::const_iterator skipSeparators(std::string::const_iterator it)
|
||||
{
|
||||
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);
|
||||
}
|
||||
for (; it!=end && std::find_first_of(it, it+1, PATH_SEPARATORS, PATH_SEPARATORS+PATH_SEPARATORS_LEN) != it+1; ++it) {}
|
||||
return it;
|
||||
}
|
||||
|
||||
while (itTo != to.end() && (*itTo == '\\' || *itTo == '/'))
|
||||
std::string::const_iterator next(std::string::const_iterator it)
|
||||
{
|
||||
++itTo;
|
||||
return std::find_first_of(it, end, PATH_SEPARATORS, PATH_SEPARATORS+PATH_SEPARATORS_LEN);
|
||||
}
|
||||
};
|
||||
|
||||
return std::string(itTo, to.end());
|
||||
/// Gets root part of a path, or an empty string if none found
|
||||
std::string getPathRoot(const std::string& path) {
|
||||
// Test for unix root
|
||||
if (path.empty()) return "";
|
||||
if (path[0] == '/') return "/";
|
||||
// Now test for Windows root
|
||||
if (path.length()<2) return "";
|
||||
if (path[1] == ':') return path.substr(0, 2); // We should check that path[0] is a letter, but as ':' is invalid in paths in other cases, that's not a problem.
|
||||
return "";
|
||||
}
|
||||
|
||||
//std::string testA = getPathRelative("C:\\a\\b", "C:\\a/b/d/f");
|
||||
//std::string testB = getPathRelative("C:\\a\\d", "C:\\a/b/d/f");
|
||||
//std::string testC = getPathRelative("C:\\ab", "C:\\a/b/d/f");
|
||||
//std::string testD = getPathRelative("a/d", "a/d");
|
||||
std::string osgDB::getPathRelative(const std::string& from, const std::string& to)
|
||||
{
|
||||
// This implementation is not 100% robust, and should be replaced with C++0x "std::path" as soon as possible.
|
||||
|
||||
// Definition: an "element" is a part between slashes. Ex: "/a/b" has two elements ("a" and "b").
|
||||
// Algorithm:
|
||||
// 1. If paths are neither both absolute nor both relative, then we cannot do anything (we need to make them absolute, but need additionnal info on how to make it). Return.
|
||||
// 2. If both paths are absolute and root isn't the same (for Windows only, as roots are of the type "C:", "D:"), then the operation is impossible. Return.
|
||||
// 3. Iterate over two paths elements until elements are equal
|
||||
// 4. For each remaining element in "from", add ".." to result
|
||||
// 5. For each remaining element in "to", add this element to result
|
||||
|
||||
// 1 & 2
|
||||
const std::string root = getPathRoot(from);
|
||||
if (root != getPathRoot(to)) {
|
||||
OSG_INFO << "Cannot relativise paths. From=" << from << ", To=" << to << ". Returning 'to' unchanged." << std::endl;
|
||||
//return to;
|
||||
return osgDB::getSimpleFileName(to);
|
||||
}
|
||||
|
||||
// 3
|
||||
PathIterator itFrom(from), itTo(to);
|
||||
// Iterators may point to Windows roots. As we tested they are equal, there is no need to ++itFrom and ++itTo.
|
||||
// However, if we got an Unix root, we must add it to the result.
|
||||
std::string res(root == "/" ? "/" : "");
|
||||
for(; itFrom.valid() && itTo.valid() && *itFrom==*itTo; ++itFrom, ++itTo) {}
|
||||
|
||||
// 4
|
||||
for(; itFrom.valid(); ++itFrom) res += "../";
|
||||
|
||||
// 5
|
||||
for(; itTo.valid(); ++itTo) res += *itTo + "/";
|
||||
|
||||
// Remove trailing slash before returning
|
||||
if (!res.empty() && std::find_first_of(res.rbegin(), res.rbegin()+1, PATH_SEPARATORS, PATH_SEPARATORS+PATH_SEPARATORS_LEN) != res.rbegin()+1)
|
||||
{
|
||||
return res.substr(0, res.length()-1);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//using namespace osgDB;
|
||||
//std::string testA = getPathRelative("C:\\a\\b", "C:\\a/b/d/f"); // d/f
|
||||
//std::string testB = getPathRelative("C:\\a\\d", "C:\\a/b/d/f"); // ../b/d/f
|
||||
//std::string testC = getPathRelative("C:\\ab", "C:\\a/b/d/f"); // ../a/b/d/f
|
||||
//std::string testD = getPathRelative("a/d", "a/d"); // ""
|
||||
//std::string testE = getPathRelative("a", "a/d"); // ../d
|
||||
//std::string testF = getPathRelative("C:/a/b", "a/d"); // Precondition fail. Returns d.
|
||||
//std::string testG = getPathRelative("/a/b", "a/d"); // Precondition fail. Returns d.
|
||||
//std::string testH = getPathRelative("a/b", "/a/d"); // Precondition fail. Returns d.
|
||||
|
||||
@@ -577,7 +577,7 @@ daeReader::ChannelPart* daeReader::processSampler(domChannel* pDomChannel, Sourc
|
||||
{
|
||||
if (!strcmp("TIME", domParams[0]->getName()))
|
||||
{
|
||||
pOsgTimesArray = sources[input_source].getFloatArray();
|
||||
pOsgTimesArray = sources[input_source].getArray<osg::FloatArray>();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -688,58 +688,58 @@ daeReader::ChannelPart* daeReader::processSampler(domChannel* pDomChannel, Sourc
|
||||
{
|
||||
case domSourceReader::Float:
|
||||
keyframes = makeKeyframes<float>(pOsgTimesArray,
|
||||
sources[output_source].getFloatArray(),
|
||||
sources[output_intangent_source].getFloatArray(),
|
||||
sources[output_outtangent_source].getFloatArray(),
|
||||
sources[output_source].getArray<osg::FloatArray>(),
|
||||
sources[output_intangent_source].getArray<osg::FloatArray>(),
|
||||
sources[output_outtangent_source].getArray<osg::FloatArray>(),
|
||||
interpolationType);
|
||||
break;
|
||||
case domSourceReader::Vec2:
|
||||
keyframes = makeKeyframes<osg::Vec2>(pOsgTimesArray,
|
||||
sources[output_source].getVec2Array(),
|
||||
sources[output_intangent_source].getVec2Array(),
|
||||
sources[output_outtangent_source].getVec2Array(),
|
||||
sources[output_source].getArray<osg::Vec2Array>(),
|
||||
sources[output_intangent_source].getArray<osg::Vec2Array>(),
|
||||
sources[output_outtangent_source].getArray<osg::Vec2Array>(),
|
||||
interpolationType);
|
||||
break;
|
||||
case domSourceReader::Vec3:
|
||||
keyframes = makeKeyframes<osg::Vec3>(pOsgTimesArray,
|
||||
sources[output_source].getVec3Array(),
|
||||
sources[output_intangent_source].getVec3Array(),
|
||||
sources[output_outtangent_source].getVec3Array(),
|
||||
sources[output_source].getArray<osg::Vec3Array>(),
|
||||
sources[output_intangent_source].getArray<osg::Vec3Array>(),
|
||||
sources[output_outtangent_source].getArray<osg::Vec3Array>(),
|
||||
interpolationType);
|
||||
break;
|
||||
case domSourceReader::Vec4:
|
||||
keyframes = makeKeyframes<osg::Vec4>(pOsgTimesArray,
|
||||
sources[output_source].getVec4Array(),
|
||||
sources[output_intangent_source].getVec4Array(),
|
||||
sources[output_outtangent_source].getVec4Array(),
|
||||
sources[output_source].getArray<osg::Vec4Array>(),
|
||||
sources[output_intangent_source].getArray<osg::Vec4Array>(),
|
||||
sources[output_outtangent_source].getArray<osg::Vec4Array>(),
|
||||
interpolationType);
|
||||
break;
|
||||
case domSourceReader::Vec2d:
|
||||
keyframes = makeKeyframes<osg::Vec2d>(pOsgTimesArray,
|
||||
sources[output_source].getVec2dArray(),
|
||||
sources[output_intangent_source].getVec2dArray(),
|
||||
sources[output_outtangent_source].getVec2dArray(),
|
||||
sources[output_source].getArray<osg::Vec2dArray>(),
|
||||
sources[output_intangent_source].getArray<osg::Vec2dArray>(),
|
||||
sources[output_outtangent_source].getArray<osg::Vec2dArray>(),
|
||||
interpolationType);
|
||||
break;
|
||||
case domSourceReader::Vec3d:
|
||||
keyframes = makeKeyframes<osg::Vec3d>(pOsgTimesArray,
|
||||
sources[output_source].getVec3dArray(),
|
||||
sources[output_intangent_source].getVec3dArray(),
|
||||
sources[output_outtangent_source].getVec3dArray(),
|
||||
sources[output_source].getArray<osg::Vec3dArray>(),
|
||||
sources[output_intangent_source].getArray<osg::Vec3dArray>(),
|
||||
sources[output_outtangent_source].getArray<osg::Vec3dArray>(),
|
||||
interpolationType);
|
||||
break;
|
||||
case domSourceReader::Vec4d:
|
||||
keyframes = makeKeyframes<osg::Vec4d>(pOsgTimesArray,
|
||||
sources[output_source].getVec4dArray(),
|
||||
sources[output_intangent_source].getVec4dArray(),
|
||||
sources[output_outtangent_source].getVec4dArray(),
|
||||
sources[output_source].getArray<osg::Vec4dArray>(),
|
||||
sources[output_intangent_source].getArray<osg::Vec4dArray>(),
|
||||
sources[output_outtangent_source].getArray<osg::Vec4dArray>(),
|
||||
interpolationType);
|
||||
break;
|
||||
case domSourceReader::Matrix:
|
||||
keyframes = makeKeyframes<osg::Matrixf>(pOsgTimesArray,
|
||||
sources[output_source].getMatrixArray(),
|
||||
sources[output_intangent_source].getMatrixArray(),
|
||||
sources[output_outtangent_source].getMatrixArray(),
|
||||
sources[output_source].getArray<osg::MatrixfArray>(),
|
||||
sources[output_intangent_source].getArray<osg::MatrixfArray>(),
|
||||
sources[output_outtangent_source].getArray<osg::MatrixfArray>(),
|
||||
interpolationType);
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -701,9 +701,56 @@ struct VertexIndices
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Templated getter for memebers, used for createGeometryData()
|
||||
enum ValueType { POSITION, COLOR, NORMAL, TEXCOORD };
|
||||
template <int Value>
|
||||
inline int get() const;
|
||||
|
||||
int position_index, color_index, normal_index, texcoord_indices[MAX_TEXTURE_COORDINATE_SETS];
|
||||
};
|
||||
|
||||
template<>
|
||||
inline int VertexIndices::get<VertexIndices::POSITION>() const { return position_index; }
|
||||
template<>
|
||||
inline int VertexIndices::get<VertexIndices::COLOR>() const { return color_index; }
|
||||
template<>
|
||||
inline int VertexIndices::get<VertexIndices::NORMAL>() const { return normal_index; }
|
||||
template<int Value>
|
||||
inline int VertexIndices::get() const {
|
||||
// TEXCOORD has not to be implemented here as we need compile-time constants for texcoord number
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
typedef std::map<VertexIndices, GLuint> VertexIndicesIndexMap;
|
||||
|
||||
/// Creates a value array, packed in a osg::Geometry::ArrayData, corresponding to indexed values.
|
||||
template <class ArrayType, int Value>
|
||||
osg::Geometry::ArrayData createGeometryData(domSourceReader & sourceReader, const VertexIndicesIndexMap & vertexIndicesIndexMap, int texcoordNum=-1) {
|
||||
const ArrayType * source = sourceReader.getArray<ArrayType>();
|
||||
if (!source) return osg::Geometry::ArrayData();
|
||||
ArrayType * pArray = new ArrayType;
|
||||
for (VertexIndicesIndexMap::const_iterator it = vertexIndicesIndexMap.begin(), end = vertexIndicesIndexMap.end(); it != end; ++it) {
|
||||
int index = texcoordNum>=0 ? it->first.texcoord_indices[texcoordNum] : it->first.get<Value>();
|
||||
if (index>=0 && static_cast<unsigned int>(index)<source->size()) pArray->push_back(source->at(index));
|
||||
else {
|
||||
// Invalid data (index out of bounds)
|
||||
//LOG_WARN << ...
|
||||
//pArray->push_back(0);
|
||||
return osg::Geometry::ArrayData();
|
||||
}
|
||||
}
|
||||
return osg::Geometry::ArrayData(pArray, osg::Geometry::BIND_PER_VERTEX);
|
||||
}
|
||||
|
||||
|
||||
template <class ArrayTypeSingle, class ArrayTypeDouble, int Value>
|
||||
inline osg::Geometry::ArrayData createGeometryData(domSourceReader & sourceReader, const VertexIndicesIndexMap & vertexIndicesIndexMap, bool useDoublePrecision, int texcoordNum=-1) {
|
||||
if (useDoublePrecision) return createGeometryData<ArrayTypeDouble, Value>(sourceReader, vertexIndicesIndexMap);
|
||||
else return createGeometryData<ArrayTypeSingle, Value>(sourceReader, vertexIndicesIndexMap);
|
||||
}
|
||||
|
||||
|
||||
void daeReader::resolveMeshArrays(const domP_Array& domPArray,
|
||||
const domInputLocalOffset_Array& inputs, const domMesh* pDomMesh,
|
||||
osg::Geometry* geometry, SourceMap &sources,
|
||||
@@ -735,7 +782,6 @@ void daeReader::resolveMeshArrays(const domP_Array& domPArray,
|
||||
}
|
||||
++stride;
|
||||
|
||||
typedef std::map<VertexIndices, GLuint> VertexIndicesIndexMap;
|
||||
VertexIndicesIndexMap vertexIndicesIndexMap;
|
||||
|
||||
for (size_t j = 0; j < domPArray.getCount(); ++j)
|
||||
@@ -794,99 +840,35 @@ void daeReader::resolveMeshArrays(const domP_Array& domPArray,
|
||||
}
|
||||
}
|
||||
|
||||
// Local defines to make te code a bit more readable
|
||||
// Sukender: This is not a very clean way to code, I know, but else the code is unmaintanable.
|
||||
#define FOREACH_INDEX for (VertexIndicesIndexMap::const_iterator it = vertexIndicesIndexMap.begin(), end = vertexIndicesIndexMap.end(); it != end; ++it)
|
||||
//#define FOREACH_INDEX for (VertexIndicesIndexMap::const_iterator it = vertexIndicesIndexMap.begin(); it != vertexIndicesIndexMap.end(); ++it)
|
||||
#define ENSURE_VECTOR_SIZE(arrayName, text) if (arrayName) { \
|
||||
if (arrayName->size() > nbVertices) OSG_NOTIFY(osg::NOTICE) << "More " #text " coordinates than vertices found. Result may not be what expected." << std::endl; \
|
||||
if (arrayName->size() < nbVertices) { \
|
||||
OSG_NOTIFY(osg::WARN) << "Less " #text " coordinates than vertices found. Skipping " #text " components." << std::endl; \
|
||||
arrayName = NULL; \
|
||||
} \
|
||||
} \
|
||||
/**/
|
||||
const bool readDoubleVertices = (_precisionHint & osgDB::Options::DOUBLE_PRECISION_VERTEX) != 0;
|
||||
const bool readDoubleColors = (_precisionHint & osgDB::Options::DOUBLE_PRECISION_COLOR) != 0;
|
||||
const bool readDoubleNormals = (_precisionHint & osgDB::Options::DOUBLE_PRECISION_NORMAL) != 0;
|
||||
const bool readDoubleTexcoords = (_precisionHint & osgDB::Options::DOUBLE_PRECISION_TEX_COORD) != 0;
|
||||
|
||||
unsigned int nbVertices(0);
|
||||
// TODO Factorize code below!
|
||||
// Vertices
|
||||
{
|
||||
if (!readDoubleVertices)
|
||||
osg::Geometry::ArrayData arrayData( createGeometryData<osg::Vec3Array, osg::Vec3dArray, VertexIndices::POSITION>(sources[position_source], vertexIndicesIndexMap, readDoubleVertices) );
|
||||
if (arrayData.array.valid())
|
||||
{
|
||||
const osg::Vec3Array * source = sources[position_source].getVec3Array();
|
||||
if (source)
|
||||
{
|
||||
nbVertices = source->size();
|
||||
osg::Vec3Array* pArray = new osg::Vec3Array;
|
||||
FOREACH_INDEX pArray->push_back(source->at(it->first.position_index));
|
||||
geometry->setVertexData(osg::Geometry::ArrayData(pArray, osg::Geometry::BIND_PER_VERTEX));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const osg::Vec3dArray* source = sources[position_source].getVec3dArray();
|
||||
if (source)
|
||||
{
|
||||
nbVertices = source->size();
|
||||
osg::Vec3dArray* pArray = new osg::Vec3dArray;
|
||||
FOREACH_INDEX pArray->push_back(source->at(it->first.position_index));
|
||||
geometry->setVertexData(osg::Geometry::ArrayData(pArray, osg::Geometry::BIND_PER_VERTEX));
|
||||
}
|
||||
geometry->setVertexData(arrayData);
|
||||
}
|
||||
}
|
||||
|
||||
if (color_source)
|
||||
{
|
||||
if (!readDoubleColors)
|
||||
osg::Geometry::ArrayData arrayData( createGeometryData<osg::Vec4Array, osg::Vec4dArray, VertexIndices::COLOR>(sources[color_source], vertexIndicesIndexMap, readDoubleColors) );
|
||||
if (arrayData.array.valid())
|
||||
{
|
||||
const osg::Vec4Array * colorSource = sources[color_source].getVec4Array();
|
||||
ENSURE_VECTOR_SIZE(colorSource, color)
|
||||
if (colorSource)
|
||||
{
|
||||
osg::Vec4Array* pArray = new osg::Vec4Array;
|
||||
FOREACH_INDEX pArray->push_back(colorSource->at(it->first.color_index));
|
||||
geometry->setColorData(osg::Geometry::ArrayData(pArray, osg::Geometry::BIND_PER_VERTEX));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const osg::Vec4dArray* colorSource = sources[color_source].getVec4dArray();
|
||||
ENSURE_VECTOR_SIZE(colorSource, color)
|
||||
if (colorSource)
|
||||
{
|
||||
osg::Vec4dArray* pArray = new osg::Vec4dArray;
|
||||
FOREACH_INDEX pArray->push_back(colorSource->at(it->first.color_index));
|
||||
geometry->setColorData(osg::Geometry::ArrayData(pArray, osg::Geometry::BIND_PER_VERTEX));
|
||||
}
|
||||
geometry->setColorData(arrayData);
|
||||
}
|
||||
}
|
||||
|
||||
if (normal_source)
|
||||
{
|
||||
if (!readDoubleNormals)
|
||||
osg::Geometry::ArrayData arrayData( createGeometryData<osg::Vec3Array, osg::Vec3dArray, VertexIndices::NORMAL>(sources[normal_source], vertexIndicesIndexMap, readDoubleNormals) );
|
||||
if (arrayData.array.valid())
|
||||
{
|
||||
const osg::Vec3Array * normalSource = sources[normal_source].getVec3Array();
|
||||
ENSURE_VECTOR_SIZE(normalSource, normal)
|
||||
if (normalSource)
|
||||
{
|
||||
osg::Vec3Array* pArray = new osg::Vec3Array;
|
||||
FOREACH_INDEX pArray->push_back(normalSource->at(it->first.normal_index));
|
||||
geometry->setNormalData(osg::Geometry::ArrayData(pArray, osg::Geometry::BIND_PER_VERTEX));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const osg::Vec3dArray* normalSource = sources[normal_source].getVec3dArray();
|
||||
ENSURE_VECTOR_SIZE(normalSource, normal)
|
||||
if (normalSource)
|
||||
{
|
||||
osg::Vec3dArray* pArray = new osg::Vec3dArray;
|
||||
FOREACH_INDEX pArray->push_back(normalSource->at(it->first.normal_index));
|
||||
geometry->setNormalData(osg::Geometry::ArrayData(pArray, osg::Geometry::BIND_PER_VERTEX));
|
||||
}
|
||||
geometry->setNormalData(arrayData);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -894,57 +876,20 @@ void daeReader::resolveMeshArrays(const domP_Array& domPArray,
|
||||
{
|
||||
if (daeElement* texcoord_source = texcoord_sources[texcoord_set])
|
||||
{
|
||||
osg::Array* pArray = NULL;
|
||||
if (!readDoubleTexcoords)
|
||||
// 2D Texcoords
|
||||
osg::Geometry::ArrayData arrayData( createGeometryData<osg::Vec2Array, osg::Vec2dArray, VertexIndices::TEXCOORD>(sources[texcoord_source], vertexIndicesIndexMap, readDoubleTexcoords, texcoord_set) );
|
||||
if (arrayData.array.valid())
|
||||
{
|
||||
const osg::Vec2Array * tcSource2f = sources[texcoord_source].getVec2Array();
|
||||
const osg::Vec3Array * tcSource3f = sources[texcoord_source].getVec3Array();
|
||||
if (tcSource2f)
|
||||
{
|
||||
ENSURE_VECTOR_SIZE(tcSource2f, texture)
|
||||
if (tcSource2f)
|
||||
{
|
||||
osg::Vec2Array* pVec2Array = new osg::Vec2Array;
|
||||
pArray = pVec2Array;
|
||||
FOREACH_INDEX pVec2Array->push_back(tcSource2f->at(it->first.texcoord_indices[texcoord_set]));
|
||||
}
|
||||
}
|
||||
else if (tcSource3f)
|
||||
{
|
||||
ENSURE_VECTOR_SIZE(tcSource3f, texture)
|
||||
if (tcSource3f) {
|
||||
osg::Vec3Array* pVec3Array = new osg::Vec3Array;
|
||||
pArray = pVec3Array;
|
||||
FOREACH_INDEX pVec3Array->push_back(tcSource3f->at(it->first.texcoord_indices[texcoord_set]));
|
||||
}
|
||||
}
|
||||
geometry->setTexCoordData(texcoord_set, arrayData);
|
||||
}
|
||||
else
|
||||
{
|
||||
const osg::Vec2dArray* tcSource2d = sources[texcoord_source].getVec2dArray();
|
||||
const osg::Vec3dArray* tcSource3d = sources[texcoord_source].getVec3dArray();
|
||||
if (tcSource2d)
|
||||
// 3D Textcoords
|
||||
osg::Geometry::ArrayData arrayData( createGeometryData<osg::Vec3Array, osg::Vec3dArray, VertexIndices::TEXCOORD>(sources[texcoord_source], vertexIndicesIndexMap, readDoubleTexcoords, texcoord_set) );
|
||||
if (arrayData.array.valid())
|
||||
{
|
||||
ENSURE_VECTOR_SIZE(tcSource2d, texture)
|
||||
if (tcSource2d) {
|
||||
osg::Vec2dArray* pVec2Array = new osg::Vec2dArray;
|
||||
pArray = pVec2Array;
|
||||
FOREACH_INDEX pVec2Array->push_back(tcSource2d->at(it->first.texcoord_indices[texcoord_set]));
|
||||
}
|
||||
geometry->setTexCoordData(texcoord_set, arrayData);
|
||||
}
|
||||
else if (tcSource3d)
|
||||
{
|
||||
ENSURE_VECTOR_SIZE(tcSource3d, texture)
|
||||
if (tcSource3d) {
|
||||
osg::Vec3dArray* pVec3Array = new osg::Vec3dArray;
|
||||
pArray = pVec3Array;
|
||||
FOREACH_INDEX pVec3Array->push_back(tcSource3d->at(it->first.texcoord_indices[texcoord_set]));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pArray)
|
||||
{
|
||||
geometry->setTexCoordData(texcoord_set, osg::Geometry::ArrayData(pArray, osg::Geometry::BIND_PER_VERTEX));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -556,7 +556,7 @@ bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const st
|
||||
|
||||
// RS BUG
|
||||
// getNumTexCoordArrays may return larger number
|
||||
// where getTexCoordArray(0) may have a BIND_OFF and an empty arrat
|
||||
// where getTexCoordArray(0) may have a BIND_OFF and an empty array
|
||||
std::vector<ArrayNIndices> texcoords;
|
||||
for ( unsigned int i = 0; i < geom->getNumTexCoordArrays(); i++ )
|
||||
{
|
||||
|
||||
@@ -106,7 +106,7 @@ void daeWriter::processMaterial( osg::StateSet *ss, domBind_material *pDomBindMa
|
||||
std::string fileURI;
|
||||
if (m_linkOrignialTextures)
|
||||
{
|
||||
// We link to orignial images.
|
||||
// We link to orignial images (not the ones in memory).
|
||||
fileURI = osgDB::findDataFile(osgimg->getFileName());
|
||||
if (fileURI=="" && m_ForceTexture)
|
||||
{
|
||||
@@ -115,10 +115,14 @@ void daeWriter::processMaterial( osg::StateSet *ss, domBind_material *pDomBindMa
|
||||
}
|
||||
else
|
||||
{
|
||||
// We do not link to orignial images. Then must ensure to write the image.
|
||||
// We do not link to orignial images but to the ones in memory. Then must ensure to write the images.
|
||||
// Following code block is borrowed from FBX's WriterNodeVisitor::Material::Material().
|
||||
ImageSet::iterator it = _imageSet.find(osgimg);
|
||||
if (it == _imageSet.end())
|
||||
if (it != _imageSet.end())
|
||||
{
|
||||
fileURI = it->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
fileURI = osgDB::getRealPath(osgDB::convertFileNameToNativeStyle(osgimg->getFileName()));
|
||||
std::string destPath;
|
||||
@@ -155,7 +159,7 @@ void daeWriter::processMaterial( osg::StateSet *ss, domBind_material *pDomBindMa
|
||||
assert(!destPath.empty()); // Else the implementation is to be fixed
|
||||
assert(!relativePath.empty()); // ditto
|
||||
fileURI = relativePath;
|
||||
it = _imageSet.insert(ImageSet::value_type(osgimg, relativePath)).first;
|
||||
it = _imageSet.insert(ImageSet::value_type(osgimg, fileURI)).first;
|
||||
_imageFilenameSet.insert(destPath);
|
||||
}
|
||||
// (end of code borrowed from FBX)
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace osgDAE {
|
||||
|
||||
/**
|
||||
@class domSourceReader
|
||||
Converts a source to an OSG vector array as soon as you call a getter, so calling simple precision version \c getVec3Array() will force getVec3dArray() to return NULL, and vice-versa (for a Vec3 array in the example).
|
||||
Converts a source to an OSG vector array as soon as you call a getter, so calling simple precision version \c getArray<osg::Vec3Array>() will force getArray<osg::Vec3dArray>() to return NULL, and vice-versa (for a Vec3 array in the example).
|
||||
@brief Convert sources from DAE to OSG arrays
|
||||
*/
|
||||
class domSourceReader
|
||||
@@ -38,21 +38,24 @@ public:
|
||||
|
||||
ArrayType getArrayType(bool enableDoublePrecision) const { if (srcInit) const_cast<domSourceReader*>(this)->convert(enableDoublePrecision); return m_array_type; };
|
||||
|
||||
osg::FloatArray* getFloatArray() { if (srcInit) convert(false); return m_float_array.get(); };
|
||||
|
||||
osg::Vec2Array* getVec2Array() { if (srcInit) convert(false); return m_vec2_array.get(); };
|
||||
|
||||
osg::Vec3Array* getVec3Array() { if (srcInit) convert(false); return m_vec3_array.get(); };
|
||||
|
||||
osg::Vec4Array* getVec4Array() { if (srcInit) convert(false); return m_vec4_array.get(); };
|
||||
|
||||
osg::Vec2dArray* getVec2dArray() { if (srcInit) convert(true); return m_vec2d_array.get(); };
|
||||
|
||||
osg::Vec3dArray* getVec3dArray() { if (srcInit) convert(true); return m_vec3d_array.get(); };
|
||||
|
||||
osg::Vec4dArray* getVec4dArray() { if (srcInit) convert(true); return m_vec4d_array.get(); };
|
||||
|
||||
osg::MatrixfArray* getMatrixArray() { if (srcInit) convert(false); return m_matrix_array.get(); };
|
||||
template <class OsgArrayType>
|
||||
inline OsgArrayType * getArray();
|
||||
template <>
|
||||
inline osg::FloatArray* domSourceReader::getArray<osg::FloatArray>() { if (srcInit) convert(false); return m_float_array.get(); };
|
||||
template <>
|
||||
inline osg::Vec2Array* domSourceReader::getArray<osg::Vec2Array>() { if (srcInit) convert(false); return m_vec2_array.get(); };
|
||||
template <>
|
||||
inline osg::Vec3Array* domSourceReader::getArray<osg::Vec3Array>() { if (srcInit) convert(false); return m_vec3_array.get(); };
|
||||
template <>
|
||||
inline osg::Vec4Array* domSourceReader::getArray<osg::Vec4Array>() { if (srcInit) convert(false); return m_vec4_array.get(); };
|
||||
template <>
|
||||
inline osg::Vec2dArray* domSourceReader::getArray<osg::Vec2dArray>() { if (srcInit) convert(true); return m_vec2d_array.get(); };
|
||||
template <>
|
||||
inline osg::Vec3dArray* domSourceReader::getArray<osg::Vec3dArray>() { if (srcInit) convert(true); return m_vec3d_array.get(); };
|
||||
template <>
|
||||
inline osg::Vec4dArray* domSourceReader::getArray<osg::Vec4dArray>() { if (srcInit) convert(true); return m_vec4d_array.get(); };
|
||||
template <>
|
||||
inline osg::MatrixfArray* domSourceReader::getArray<osg::MatrixfArray>() { if (srcInit) convert(false); return m_matrix_array.get(); };
|
||||
|
||||
int getCount(bool enableDoublePrecision) const { if (srcInit) const_cast<domSourceReader*>(this)->convert(enableDoublePrecision); return m_count; };
|
||||
|
||||
|
||||
Reference in New Issue
Block a user