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:
Robert Osfield
2011-01-27 17:12:23 +00:00
parent 67ae23f2cf
commit 278203240b
6 changed files with 212 additions and 200 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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