Changeset 12126

Show
Ignore:
Timestamp:
01/27/11 18:12:23 (3 years ago)
Author:
robert
Message:

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

Location:
OpenSceneGraph/trunk/src
Files:
6 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/src/osgDB/FileNameUtils.cpp

    r12108 r12126  
    3232using namespace std; 
    3333 
     34static const char * const PATH_SEPARATORS = "/\\"; 
     35static unsigned int PATH_SEPARATORS_LEN = 2; 
     36 
     37 
    3438std::string osgDB::getFilePath(const std::string& fileName) 
    3539{ 
    36     std::string::size_type slash = fileName.find_last_of("/\\"); 
     40    std::string::size_type slash = fileName.find_last_of(PATH_SEPARATORS); 
    3741    if (slash==std::string::npos) return std::string(); 
    3842    else return std::string(fileName, 0, slash); 
     
    4246std::string osgDB::getSimpleFileName(const std::string& fileName) 
    4347{ 
    44     std::string::size_type slash = fileName.find_last_of("/\\"); 
     48    std::string::size_type slash = fileName.find_last_of(PATH_SEPARATORS); 
    4549    if (slash==std::string::npos) return fileName; 
    4650    else return std::string(fileName.begin()+slash+1,fileName.end()); 
     
    5155{ 
    5256    std::string::size_type dot = fileName.find_last_of('.'); 
    53     std::string::size_type slash = fileName.find_last_of("/\\"); 
     57    std::string::size_type slash = fileName.find_last_of(PATH_SEPARATORS); 
    5458    if (dot==std::string::npos || (slash!=std::string::npos && dot<slash)) return std::string(""); 
    5559    return std::string(fileName.begin()+dot+1,fileName.end()); 
     
    5963{ 
    6064    std::string::size_type dot = fileName.find_last_of('.'); 
    61     std::string::size_type slash = fileName.find_last_of("/\\"); 
     65    std::string::size_type slash = fileName.find_last_of(PATH_SEPARATORS); 
    6266    if (dot==std::string::npos || (slash!=std::string::npos && dot<slash)) return std::string(""); 
    6367    return std::string(fileName.begin()+dot,fileName.end()); 
     
    139143{ 
    140144    std::string::size_type dot = fileName.find_last_of('.'); 
    141     std::string::size_type slash = fileName.find_last_of("/\\");        // Finds forward slash *or* back slash 
     145    std::string::size_type slash = fileName.find_last_of(PATH_SEPARATORS);        // Finds forward slash *or* back slash 
    142146    if (dot==std::string::npos || (slash!=std::string::npos && dot<slash)) return fileName; 
    143147    return std::string(fileName.begin(),fileName.begin()+dot); 
     
    149153{ 
    150154    // Finds start serach position: from last slash, or the begining of the string if none found 
    151     std::string::size_type startPos = fileName.find_last_of("/\\");            // Finds forward slash *or* back slash 
     155    std::string::size_type startPos = fileName.find_last_of(PATH_SEPARATORS);            // Finds forward slash *or* back slash 
    152156    if (startPos == std::string::npos) startPos = 0; 
    153157    std::string::size_type dot = fileName.find_first_of('.', startPos);        // Finds *FIRST* dot from start pos 
     
    322326} 
    323327 
     328 
     329/// Helper to iterate over elements of a path (including Windows' root, if any). 
     330class PathIterator { 
     331public: 
     332    PathIterator(const std::string & v) : end(v.end()), start(v.begin()), stop(v.begin()) { operator++(); } 
     333    bool valid() const { return start!=end; } 
     334    PathIterator & operator++() 
     335    { 
     336        if (!valid()) return *this; 
     337        start = skipSeparators(stop); 
     338        if (start != end) stop = next(start); 
     339        return *this; 
     340    } 
     341    std::string operator*() 
     342    { 
     343        if (!valid()) return std::string(); 
     344        return std::string(start, stop); 
     345    } 
     346 
     347protected: 
     348    std::string::const_iterator end;     ///< End of path string 
     349    std::string::const_iterator start;   ///< Points to the first char of an element, or ==end() if no more 
     350    std::string::const_iterator stop;    ///< Points to the separator after 'start', or ==end() 
     351 
     352    /// Iterate until 'it' points to something different from a separator 
     353    std::string::const_iterator skipSeparators(std::string::const_iterator it) 
     354    { 
     355        for (; it!=end && std::find_first_of(it, it+1, PATH_SEPARATORS, PATH_SEPARATORS+PATH_SEPARATORS_LEN) != it+1; ++it) {} 
     356        return it; 
     357    } 
     358 
     359    std::string::const_iterator next(std::string::const_iterator it) 
     360    { 
     361        return std::find_first_of(it, end, PATH_SEPARATORS, PATH_SEPARATORS+PATH_SEPARATORS_LEN); 
     362    } 
     363}; 
     364 
     365/// Gets root part of a path, or an empty string if none found 
     366std::string getPathRoot(const std::string& path) { 
     367    // Test for unix root 
     368    if (path.empty()) return ""; 
     369    if (path[0] == '/') return "/"; 
     370    // Now test for Windows root 
     371    if (path.length()<2) return ""; 
     372    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. 
     373    return ""; 
     374} 
     375 
    324376std::string osgDB::getPathRelative(const std::string& from, const std::string& to) 
    325377{ 
    326     std::string::size_type slash = to.find_last_of('/'); 
    327     std::string::size_type backslash = to.find_last_of('\\'); 
    328     if (slash == std::string::npos)  
    329     { 
    330         if (backslash == std::string::npos) return to; 
    331         slash = backslash; 
    332     } 
    333     else if (backslash != std::string::npos && backslash > slash) 
    334     { 
    335         slash = backslash; 
    336     } 
    337  
    338     if (from.empty() || from.length() > to.length()) 
     378    // This implementation is not 100% robust, and should be replaced with C++0x "std::path" as soon as possible. 
     379 
     380    // Definition: an "element" is a part between slashes. Ex: "/a/b" has two elements ("a" and "b"). 
     381    // Algorithm: 
     382    // 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. 
     383    // 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. 
     384    // 3. Iterate over two paths elements until elements are equal 
     385    // 4. For each remaining element in "from", add ".." to result 
     386    // 5. For each remaining element in "to", add this element to result 
     387 
     388    // 1 & 2 
     389    const std::string root = getPathRoot(from); 
     390    if (root != getPathRoot(to)) { 
     391        OSG_INFO << "Cannot relativise paths. From=" << from << ", To=" << to << ". Returning 'to' unchanged." << std::endl; 
     392        //return to; 
    339393        return osgDB::getSimpleFileName(to); 
    340  
    341     std::string::const_iterator itTo = to.begin(); 
    342     for (std::string::const_iterator itFrom = from.begin(); 
    343         itFrom != from.end(); ++itFrom, ++itTo) 
    344     { 
    345         char a = tolower(*itFrom), b = tolower(*itTo); 
    346         if (a == '\\') a = '/'; 
    347         if (b == '\\') b = '/'; 
    348         if (a != b || itTo == to.begin() + slash + 1) 
    349         { 
    350             return osgDB::getSimpleFileName(to); 
    351         } 
    352     } 
    353  
    354     while (itTo != to.end() && (*itTo == '\\' || *itTo == '/')) 
    355     { 
    356         ++itTo; 
    357     } 
    358  
    359     return std::string(itTo, to.end()); 
    360 } 
    361  
    362 //std::string testA = getPathRelative("C:\\a\\b", "C:\\a/b/d/f"); 
    363 //std::string testB = getPathRelative("C:\\a\\d", "C:\\a/b/d/f"); 
    364 //std::string testC = getPathRelative("C:\\ab", "C:\\a/b/d/f"); 
    365 //std::string testD = getPathRelative("a/d", "a/d"); 
     394    } 
     395 
     396    // 3 
     397    PathIterator itFrom(from), itTo(to); 
     398    // Iterators may point to Windows roots. As we tested they are equal, there is no need to ++itFrom and ++itTo. 
     399    // However, if we got an Unix root, we must add it to the result. 
     400    std::string res(root == "/" ? "/" : ""); 
     401    for(; itFrom.valid() && itTo.valid() && *itFrom==*itTo; ++itFrom, ++itTo) {} 
     402 
     403    // 4 
     404    for(; itFrom.valid(); ++itFrom) res += "../"; 
     405 
     406    // 5 
     407    for(; itTo.valid(); ++itTo) res += *itTo + "/"; 
     408 
     409    // Remove trailing slash before returning 
     410    if (!res.empty() && std::find_first_of(res.rbegin(), res.rbegin()+1, PATH_SEPARATORS, PATH_SEPARATORS+PATH_SEPARATORS_LEN) != res.rbegin()+1) 
     411    { 
     412        return res.substr(0, res.length()-1); 
     413    } 
     414    return res; 
     415} 
     416 
     417//using namespace osgDB; 
     418//std::string testA = getPathRelative("C:\\a\\b", "C:\\a/b/d/f");       // d/f 
     419//std::string testB = getPathRelative("C:\\a\\d", "C:\\a/b/d/f");       // ../b/d/f 
     420//std::string testC = getPathRelative("C:\\ab", "C:\\a/b/d/f");         // ../a/b/d/f 
     421//std::string testD = getPathRelative("a/d", "a/d");                    // "" 
     422//std::string testE = getPathRelative("a", "a/d");                      // ../d 
     423//std::string testF = getPathRelative("C:/a/b", "a/d");                 // Precondition fail. Returns d. 
     424//std::string testG = getPathRelative("/a/b", "a/d");                   // Precondition fail. Returns d. 
     425//std::string testH = getPathRelative("a/b", "/a/d");                   // Precondition fail. Returns d. 
  • OpenSceneGraph/trunk/src/osgPlugins/dae/daeRAnimations.cpp

    r12101 r12126  
    578578                    if (!strcmp("TIME", domParams[0]->getName())) 
    579579                    { 
    580                         pOsgTimesArray = sources[input_source].getFloatArray(); 
     580                        pOsgTimesArray = sources[input_source].getArray<osg::FloatArray>(); 
    581581                    } 
    582582                    else 
     
    689689    case domSourceReader::Float: 
    690690        keyframes = makeKeyframes<float>(pOsgTimesArray, 
    691             sources[output_source].getFloatArray(), 
    692             sources[output_intangent_source].getFloatArray(), 
    693             sources[output_outtangent_source].getFloatArray(), 
     691            sources[output_source].getArray<osg::FloatArray>(), 
     692            sources[output_intangent_source].getArray<osg::FloatArray>(), 
     693            sources[output_outtangent_source].getArray<osg::FloatArray>(), 
    694694            interpolationType); 
    695695        break; 
    696696    case domSourceReader::Vec2: 
    697697        keyframes = makeKeyframes<osg::Vec2>(pOsgTimesArray, 
    698             sources[output_source].getVec2Array(), 
    699             sources[output_intangent_source].getVec2Array(), 
    700             sources[output_outtangent_source].getVec2Array(), 
     698            sources[output_source].getArray<osg::Vec2Array>(), 
     699            sources[output_intangent_source].getArray<osg::Vec2Array>(), 
     700            sources[output_outtangent_source].getArray<osg::Vec2Array>(), 
    701701            interpolationType); 
    702702        break; 
    703703    case domSourceReader::Vec3: 
    704704        keyframes = makeKeyframes<osg::Vec3>(pOsgTimesArray, 
    705             sources[output_source].getVec3Array(), 
    706             sources[output_intangent_source].getVec3Array(), 
    707             sources[output_outtangent_source].getVec3Array(), 
     705            sources[output_source].getArray<osg::Vec3Array>(), 
     706            sources[output_intangent_source].getArray<osg::Vec3Array>(), 
     707            sources[output_outtangent_source].getArray<osg::Vec3Array>(), 
    708708            interpolationType); 
    709709        break; 
    710710    case domSourceReader::Vec4: 
    711711        keyframes = makeKeyframes<osg::Vec4>(pOsgTimesArray, 
    712             sources[output_source].getVec4Array(), 
    713             sources[output_intangent_source].getVec4Array(), 
    714             sources[output_outtangent_source].getVec4Array(), 
     712            sources[output_source].getArray<osg::Vec4Array>(), 
     713            sources[output_intangent_source].getArray<osg::Vec4Array>(), 
     714            sources[output_outtangent_source].getArray<osg::Vec4Array>(), 
    715715            interpolationType); 
    716716        break; 
    717717    case domSourceReader::Vec2d: 
    718718        keyframes = makeKeyframes<osg::Vec2d>(pOsgTimesArray, 
    719             sources[output_source].getVec2dArray(), 
    720             sources[output_intangent_source].getVec2dArray(), 
    721             sources[output_outtangent_source].getVec2dArray(), 
     719            sources[output_source].getArray<osg::Vec2dArray>(), 
     720            sources[output_intangent_source].getArray<osg::Vec2dArray>(), 
     721            sources[output_outtangent_source].getArray<osg::Vec2dArray>(), 
    722722            interpolationType); 
    723723        break; 
    724724    case domSourceReader::Vec3d: 
    725725        keyframes = makeKeyframes<osg::Vec3d>(pOsgTimesArray, 
    726             sources[output_source].getVec3dArray(), 
    727             sources[output_intangent_source].getVec3dArray(), 
    728             sources[output_outtangent_source].getVec3dArray(), 
     726            sources[output_source].getArray<osg::Vec3dArray>(), 
     727            sources[output_intangent_source].getArray<osg::Vec3dArray>(), 
     728            sources[output_outtangent_source].getArray<osg::Vec3dArray>(), 
    729729            interpolationType); 
    730730        break; 
    731731    case domSourceReader::Vec4d: 
    732732        keyframes = makeKeyframes<osg::Vec4d>(pOsgTimesArray, 
    733             sources[output_source].getVec4dArray(), 
    734             sources[output_intangent_source].getVec4dArray(), 
    735             sources[output_outtangent_source].getVec4dArray(), 
     733            sources[output_source].getArray<osg::Vec4dArray>(), 
     734            sources[output_intangent_source].getArray<osg::Vec4dArray>(), 
     735            sources[output_outtangent_source].getArray<osg::Vec4dArray>(), 
    736736            interpolationType); 
    737737        break; 
    738738    case domSourceReader::Matrix: 
    739739        keyframes = makeKeyframes<osg::Matrixf>(pOsgTimesArray, 
    740             sources[output_source].getMatrixArray(), 
    741             sources[output_intangent_source].getMatrixArray(), 
    742             sources[output_outtangent_source].getMatrixArray(), 
     740            sources[output_source].getArray<osg::MatrixfArray>(), 
     741            sources[output_intangent_source].getArray<osg::MatrixfArray>(), 
     742            sources[output_outtangent_source].getArray<osg::MatrixfArray>(), 
    743743            interpolationType); 
    744744        break; 
  • OpenSceneGraph/trunk/src/osgPlugins/dae/daeRGeometry.cpp

    r12101 r12126  
    702702    } 
    703703 
     704    /// Templated getter for memebers, used for createGeometryData() 
     705    enum ValueType { POSITION, COLOR, NORMAL, TEXCOORD }; 
     706    template <int Value> 
     707    inline int get() const; 
     708 
    704709    int position_index, color_index, normal_index, texcoord_indices[MAX_TEXTURE_COORDINATE_SETS]; 
    705710}; 
     711 
     712template<> 
     713inline int VertexIndices::get<VertexIndices::POSITION>() const { return position_index; } 
     714template<> 
     715inline int VertexIndices::get<VertexIndices::COLOR>() const { return color_index; } 
     716template<> 
     717inline int VertexIndices::get<VertexIndices::NORMAL>() const { return normal_index; } 
     718template<int Value> 
     719inline int VertexIndices::get() const { 
     720    // TEXCOORD has not to be implemented here as we need compile-time constants for texcoord number 
     721    return -1; 
     722} 
     723 
     724 
     725typedef std::map<VertexIndices, GLuint> VertexIndicesIndexMap; 
     726 
     727/// Creates a value array, packed in a osg::Geometry::ArrayData, corresponding to indexed values. 
     728template <class ArrayType, int Value> 
     729osg::Geometry::ArrayData createGeometryData(domSourceReader & sourceReader, const VertexIndicesIndexMap & vertexIndicesIndexMap, int texcoordNum=-1) { 
     730    const ArrayType * source = sourceReader.getArray<ArrayType>(); 
     731    if (!source) return osg::Geometry::ArrayData(); 
     732    ArrayType * pArray = new ArrayType; 
     733    for (VertexIndicesIndexMap::const_iterator it = vertexIndicesIndexMap.begin(), end = vertexIndicesIndexMap.end(); it != end; ++it) { 
     734        int index = texcoordNum>=0 ? it->first.texcoord_indices[texcoordNum] : it->first.get<Value>(); 
     735        if (index>=0 && static_cast<unsigned int>(index)<source->size()) pArray->push_back(source->at(index)); 
     736        else { 
     737            // Invalid data (index out of bounds) 
     738            //LOG_WARN << ... 
     739            //pArray->push_back(0); 
     740            return osg::Geometry::ArrayData(); 
     741        } 
     742    } 
     743    return osg::Geometry::ArrayData(pArray, osg::Geometry::BIND_PER_VERTEX); 
     744} 
     745 
     746 
     747template <class ArrayTypeSingle, class ArrayTypeDouble, int Value> 
     748inline osg::Geometry::ArrayData createGeometryData(domSourceReader & sourceReader, const VertexIndicesIndexMap & vertexIndicesIndexMap, bool useDoublePrecision, int texcoordNum=-1) { 
     749    if (useDoublePrecision) return createGeometryData<ArrayTypeDouble, Value>(sourceReader, vertexIndicesIndexMap); 
     750    else                    return createGeometryData<ArrayTypeSingle, Value>(sourceReader, vertexIndicesIndexMap); 
     751} 
     752 
    706753 
    707754void daeReader::resolveMeshArrays(const domP_Array& domPArray, 
     
    736783    ++stride; 
    737784 
    738     typedef std::map<VertexIndices, GLuint> VertexIndicesIndexMap; 
    739785    VertexIndicesIndexMap vertexIndicesIndexMap; 
    740786 
     
    795841    } 
    796842 
    797 // Local defines to make te code a bit more readable 
    798 // Sukender: This is not a very clean way to code, I know, but else the code is unmaintanable. 
    799 #define FOREACH_INDEX for (VertexIndicesIndexMap::const_iterator it = vertexIndicesIndexMap.begin(), end = vertexIndicesIndexMap.end(); it != end; ++it) 
    800 //#define FOREACH_INDEX for (VertexIndicesIndexMap::const_iterator it = vertexIndicesIndexMap.begin(); it != vertexIndicesIndexMap.end(); ++it) 
    801 #define ENSURE_VECTOR_SIZE(arrayName, text) if (arrayName) { \ 
    802     if (arrayName->size() > nbVertices) OSG_NOTIFY(osg::NOTICE) << "More " #text " coordinates than vertices found. Result may not be what expected." << std::endl; \ 
    803         if (arrayName->size() < nbVertices) { \ 
    804             OSG_NOTIFY(osg::WARN) << "Less " #text " coordinates than vertices found. Skipping " #text " components." << std::endl; \ 
    805             arrayName = NULL; \ 
    806         } \ 
    807     } \ 
    808 /**/ 
    809843    const bool readDoubleVertices  = (_precisionHint & osgDB::Options::DOUBLE_PRECISION_VERTEX) != 0; 
    810844    const bool readDoubleColors    = (_precisionHint & osgDB::Options::DOUBLE_PRECISION_COLOR) != 0; 
     
    812846    const bool readDoubleTexcoords = (_precisionHint & osgDB::Options::DOUBLE_PRECISION_TEX_COORD) != 0; 
    813847 
    814     unsigned int nbVertices(0); 
    815     // TODO Factorize code below! 
    816     { 
    817         if (!readDoubleVertices) 
    818         { 
    819             const osg::Vec3Array * source = sources[position_source].getVec3Array(); 
    820             if (source) 
    821             { 
    822                 nbVertices = source->size(); 
    823                 osg::Vec3Array* pArray = new osg::Vec3Array; 
    824                 FOREACH_INDEX pArray->push_back(source->at(it->first.position_index)); 
    825                 geometry->setVertexData(osg::Geometry::ArrayData(pArray, osg::Geometry::BIND_PER_VERTEX)); 
    826             } 
    827         } 
    828         else 
    829         { 
    830             const osg::Vec3dArray* source = sources[position_source].getVec3dArray(); 
    831             if (source) 
    832             { 
    833                 nbVertices = source->size(); 
    834                 osg::Vec3dArray* pArray = new osg::Vec3dArray; 
    835                 FOREACH_INDEX pArray->push_back(source->at(it->first.position_index)); 
    836                 geometry->setVertexData(osg::Geometry::ArrayData(pArray, osg::Geometry::BIND_PER_VERTEX)); 
    837             } 
     848    // Vertices 
     849    { 
     850        osg::Geometry::ArrayData arrayData( createGeometryData<osg::Vec3Array, osg::Vec3dArray, VertexIndices::POSITION>(sources[position_source], vertexIndicesIndexMap, readDoubleVertices) ); 
     851        if (arrayData.array.valid()) 
     852        { 
     853            geometry->setVertexData(arrayData); 
    838854        } 
    839855    } 
     
    841857    if (color_source) 
    842858    { 
    843         if (!readDoubleColors) 
    844         { 
    845             const osg::Vec4Array * colorSource = sources[color_source].getVec4Array(); 
    846             ENSURE_VECTOR_SIZE(colorSource, color) 
    847             if (colorSource) 
    848             { 
    849                 osg::Vec4Array* pArray = new osg::Vec4Array; 
    850                 FOREACH_INDEX pArray->push_back(colorSource->at(it->first.color_index)); 
    851                 geometry->setColorData(osg::Geometry::ArrayData(pArray, osg::Geometry::BIND_PER_VERTEX)); 
    852             } 
    853         } 
    854         else 
    855         { 
    856             const osg::Vec4dArray* colorSource = sources[color_source].getVec4dArray(); 
    857             ENSURE_VECTOR_SIZE(colorSource, color) 
    858             if (colorSource) 
    859             { 
    860                 osg::Vec4dArray* pArray = new osg::Vec4dArray; 
    861                 FOREACH_INDEX pArray->push_back(colorSource->at(it->first.color_index)); 
    862                 geometry->setColorData(osg::Geometry::ArrayData(pArray, osg::Geometry::BIND_PER_VERTEX)); 
    863             } 
     859        osg::Geometry::ArrayData arrayData( createGeometryData<osg::Vec4Array, osg::Vec4dArray, VertexIndices::COLOR>(sources[color_source], vertexIndicesIndexMap, readDoubleColors) ); 
     860        if (arrayData.array.valid()) 
     861        { 
     862            geometry->setColorData(arrayData); 
    864863        } 
    865864    } 
     
    867866    if (normal_source) 
    868867    { 
    869         if (!readDoubleNormals) 
    870         { 
    871             const osg::Vec3Array * normalSource = sources[normal_source].getVec3Array(); 
    872             ENSURE_VECTOR_SIZE(normalSource, normal) 
    873             if (normalSource) 
    874             { 
    875                 osg::Vec3Array* pArray = new osg::Vec3Array; 
    876                 FOREACH_INDEX pArray->push_back(normalSource->at(it->first.normal_index)); 
    877                 geometry->setNormalData(osg::Geometry::ArrayData(pArray, osg::Geometry::BIND_PER_VERTEX)); 
    878             } 
    879         } 
    880         else 
    881         { 
    882             const osg::Vec3dArray* normalSource = sources[normal_source].getVec3dArray(); 
    883             ENSURE_VECTOR_SIZE(normalSource, normal) 
    884             if (normalSource) 
    885             { 
    886                 osg::Vec3dArray* pArray = new osg::Vec3dArray; 
    887                 FOREACH_INDEX pArray->push_back(normalSource->at(it->first.normal_index)); 
    888                 geometry->setNormalData(osg::Geometry::ArrayData(pArray, osg::Geometry::BIND_PER_VERTEX)); 
    889             } 
     868        osg::Geometry::ArrayData arrayData( createGeometryData<osg::Vec3Array, osg::Vec3dArray, VertexIndices::NORMAL>(sources[normal_source], vertexIndicesIndexMap, readDoubleNormals) ); 
     869        if (arrayData.array.valid()) 
     870        { 
     871            geometry->setNormalData(arrayData); 
    890872        } 
    891873    } 
     
    895877        if (daeElement* texcoord_source = texcoord_sources[texcoord_set]) 
    896878        { 
    897             osg::Array* pArray = NULL; 
    898             if (!readDoubleTexcoords) 
    899             { 
    900                 const osg::Vec2Array * tcSource2f = sources[texcoord_source].getVec2Array(); 
    901                 const osg::Vec3Array * tcSource3f = sources[texcoord_source].getVec3Array(); 
    902                 if (tcSource2f) 
     879            // 2D Texcoords 
     880            osg::Geometry::ArrayData arrayData( createGeometryData<osg::Vec2Array, osg::Vec2dArray, VertexIndices::TEXCOORD>(sources[texcoord_source], vertexIndicesIndexMap, readDoubleTexcoords, texcoord_set) ); 
     881            if (arrayData.array.valid()) 
     882            { 
     883                geometry->setTexCoordData(texcoord_set, arrayData); 
     884            } 
     885            else 
     886            { 
     887                // 3D Textcoords 
     888                osg::Geometry::ArrayData arrayData( createGeometryData<osg::Vec3Array, osg::Vec3dArray, VertexIndices::TEXCOORD>(sources[texcoord_source], vertexIndicesIndexMap, readDoubleTexcoords, texcoord_set) ); 
     889                if (arrayData.array.valid()) 
    903890                { 
    904                     ENSURE_VECTOR_SIZE(tcSource2f, texture) 
    905                     if (tcSource2f) 
    906                     { 
    907                         osg::Vec2Array* pVec2Array = new osg::Vec2Array; 
    908                         pArray = pVec2Array; 
    909                         FOREACH_INDEX pVec2Array->push_back(tcSource2f->at(it->first.texcoord_indices[texcoord_set])); 
    910                     } 
     891                    geometry->setTexCoordData(texcoord_set, arrayData); 
    911892                } 
    912                 else if (tcSource3f) 
    913                 { 
    914                     ENSURE_VECTOR_SIZE(tcSource3f, texture) 
    915                     if (tcSource3f) { 
    916                         osg::Vec3Array* pVec3Array = new osg::Vec3Array; 
    917                         pArray = pVec3Array; 
    918                         FOREACH_INDEX pVec3Array->push_back(tcSource3f->at(it->first.texcoord_indices[texcoord_set])); 
    919                     } 
    920                 } 
    921             } 
    922             else 
    923             { 
    924                 const osg::Vec2dArray* tcSource2d = sources[texcoord_source].getVec2dArray(); 
    925                 const osg::Vec3dArray* tcSource3d = sources[texcoord_source].getVec3dArray(); 
    926                 if (tcSource2d) 
    927                 { 
    928                     ENSURE_VECTOR_SIZE(tcSource2d, texture) 
    929                     if (tcSource2d) { 
    930                         osg::Vec2dArray* pVec2Array = new osg::Vec2dArray; 
    931                         pArray = pVec2Array; 
    932                         FOREACH_INDEX pVec2Array->push_back(tcSource2d->at(it->first.texcoord_indices[texcoord_set])); 
    933                     } 
    934                 } 
    935                 else if (tcSource3d) 
    936                 { 
    937                     ENSURE_VECTOR_SIZE(tcSource3d, texture) 
    938                     if (tcSource3d) { 
    939                         osg::Vec3dArray* pVec3Array = new osg::Vec3dArray; 
    940                         pArray = pVec3Array; 
    941                         FOREACH_INDEX pVec3Array->push_back(tcSource3d->at(it->first.texcoord_indices[texcoord_set])); 
    942                     } 
    943                 } 
    944             } 
    945             if (pArray) 
    946             { 
    947                 geometry->setTexCoordData(texcoord_set, osg::Geometry::ArrayData(pArray, osg::Geometry::BIND_PER_VERTEX)); 
    948893            } 
    949894        } 
  • OpenSceneGraph/trunk/src/osgPlugins/dae/daeWGeometry.cpp

    r12101 r12126  
    557557    // RS BUG 
    558558    // getNumTexCoordArrays may return larger number 
    559     // where getTexCoordArray(0) may have a BIND_OFF and an empty arrat 
     559    // where getTexCoordArray(0) may have a BIND_OFF and an empty array 
    560560    std::vector<ArrayNIndices> texcoords; 
    561561    for ( unsigned int i = 0; i < geom->getNumTexCoordArrays(); i++ ) 
  • OpenSceneGraph/trunk/src/osgPlugins/dae/daeWMaterials.cpp

    r12110 r12126  
    107107        if (m_linkOrignialTextures) 
    108108        { 
    109             // We link to orignial images. 
     109            // We link to orignial images (not the ones in memory). 
    110110            fileURI = osgDB::findDataFile(osgimg->getFileName()); 
    111111            if (fileURI=="" && m_ForceTexture) 
     
    116116        else 
    117117        { 
    118             // We do not link to orignial images. Then must ensure to write the image. 
     118            // We do not link to orignial images but to the ones in memory. Then must ensure to write the images. 
    119119            // Following code block is borrowed from FBX's WriterNodeVisitor::Material::Material(). 
    120120            ImageSet::iterator it = _imageSet.find(osgimg); 
    121             if (it == _imageSet.end()) 
     121            if (it != _imageSet.end()) 
     122            { 
     123                fileURI = it->second; 
     124            } 
     125            else 
    122126            { 
    123127                fileURI = osgDB::getRealPath(osgDB::convertFileNameToNativeStyle(osgimg->getFileName())); 
     
    156160                assert(!relativePath.empty());    // ditto 
    157161                fileURI = relativePath; 
    158                 it = _imageSet.insert(ImageSet::value_type(osgimg, relativePath)).first; 
     162                it = _imageSet.insert(ImageSet::value_type(osgimg, fileURI)).first; 
    159163                _imageFilenameSet.insert(destPath); 
    160164            } 
  • OpenSceneGraph/trunk/src/osgPlugins/dae/domSourceReader.h

    r12101 r12126  
    2424/** 
    2525@class domSourceReader 
    26 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). 
     26Converts 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). 
    2727@brief Convert sources from DAE to OSG arrays 
    2828*/  
     
    3939    ArrayType getArrayType(bool enableDoublePrecision) const { if (srcInit) const_cast<domSourceReader*>(this)->convert(enableDoublePrecision); return m_array_type; }; 
    4040 
    41     osg::FloatArray* getFloatArray() { if (srcInit) convert(false); return m_float_array.get(); }; 
    42      
    43     osg::Vec2Array* getVec2Array() { if (srcInit) convert(false); return m_vec2_array.get(); }; 
    44  
    45     osg::Vec3Array* getVec3Array() { if (srcInit) convert(false); return m_vec3_array.get(); }; 
    46  
    47     osg::Vec4Array* getVec4Array() { if (srcInit) convert(false); return m_vec4_array.get(); }; 
    48  
    49     osg::Vec2dArray* getVec2dArray() { if (srcInit) convert(true); return m_vec2d_array.get(); }; 
    50  
    51     osg::Vec3dArray* getVec3dArray() { if (srcInit) convert(true); return m_vec3d_array.get(); }; 
    52  
    53     osg::Vec4dArray* getVec4dArray() { if (srcInit) convert(true); return m_vec4d_array.get(); }; 
    54  
    55     osg::MatrixfArray* getMatrixArray() { if (srcInit) convert(false); return m_matrix_array.get(); }; 
     41    template <class OsgArrayType> 
     42    inline OsgArrayType * getArray(); 
     43    template <> 
     44    inline osg::FloatArray* domSourceReader::getArray<osg::FloatArray>() { if (srcInit) convert(false); return m_float_array.get(); }; 
     45    template <> 
     46    inline osg::Vec2Array* domSourceReader::getArray<osg::Vec2Array>() { if (srcInit) convert(false); return m_vec2_array.get(); }; 
     47    template <> 
     48    inline osg::Vec3Array* domSourceReader::getArray<osg::Vec3Array>() { if (srcInit) convert(false); return m_vec3_array.get(); }; 
     49    template <> 
     50    inline osg::Vec4Array* domSourceReader::getArray<osg::Vec4Array>() { if (srcInit) convert(false); return m_vec4_array.get(); }; 
     51    template <> 
     52    inline osg::Vec2dArray* domSourceReader::getArray<osg::Vec2dArray>() { if (srcInit) convert(true); return m_vec2d_array.get(); }; 
     53    template <> 
     54    inline osg::Vec3dArray* domSourceReader::getArray<osg::Vec3dArray>() { if (srcInit) convert(true); return m_vec3d_array.get(); }; 
     55    template <> 
     56    inline osg::Vec4dArray* domSourceReader::getArray<osg::Vec4dArray>() { if (srcInit) convert(true); return m_vec4d_array.get(); }; 
     57    template <> 
     58    inline osg::MatrixfArray* domSourceReader::getArray<osg::MatrixfArray>() { if (srcInit) convert(false); return m_matrix_array.get(); }; 
    5659 
    5760    int getCount(bool enableDoublePrecision) const { if (srcInit) const_cast<domSourceReader*>(this)->convert(enableDoublePrecision); return m_count; };