Changeset 11129

Show
Ignore:
Timestamp:
02/26/10 15:41:50 (6 years ago)
Author:
robert
Message:

From Michael Platings, "Here's the all-new, all-dancing DAE plugin, with support for reading
osgAnimation. It's been tested with the majority of the samples in the
COLLADA test repository and works with all of them either as well as, or
better than, the version of the plugin currently in SVN.

Known issue: vertex animation (AKA morphing) doesn't work at present,
but that's a relatively unpopular method of animating so it's not high
on my priority list."

Follow up email:
"I've been informed that the previous DAE submission didn't build on
unix, so here's the submission again with the fixes. Thanks to Gregory Potdevin and Benjamin Bozou.
Also, my apologies to Roland for not crediting his part in making DAE
animation happen, my work was indeed built on top of his work. Thanks
also to Marius Heise and of course Cedric Pinson."

Changes by Robert Osfield, fixed compile issues when compile without C* automatic conversion enabled in ref_ptr<>
and constructor initialization fixes to address some warnings under gcc.

Location:
OpenSceneGraph/trunk
Files:
3 added
19 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/include/osg/Array

    r10650 r11129  
    3030#include <osg/Vec3b> 
    3131#include <osg/Vec4b> 
     32#include <osg/Matrix> 
    3233 
    3334#include <osg/BufferObject> 
     
    7273            Vec2dArrayType    = 19, 
    7374            Vec3dArrayType    = 20, 
    74             Vec4dArrayType    = 21 
     75            Vec4dArrayType    = 21, 
     76            MatrixArrayType   = 22             
    7577        }; 
    7678 
     
    309311typedef TemplateArray<Vec3d,Array::Vec3dArrayType,3,GL_DOUBLE>                   Vec3dArray; 
    310312typedef TemplateArray<Vec4d,Array::Vec4dArrayType,4,GL_DOUBLE>                   Vec4dArray; 
     313 
     314typedef TemplateArray<Matrixf,Array::MatrixArrayType,16,GL_FLOAT>                MatrixfArray; 
    311315 
    312316 
     
    344348        virtual void apply(Vec3dArray&) {} 
    345349        virtual void apply(Vec4dArray&) {} 
     350         
     351        virtual void apply(MatrixfArray&) {} 
    346352}; 
    347353 
     
    379385        virtual void apply(const Vec3dArray&) {} 
    380386        virtual void apply(const Vec4dArray&) {} 
     387         
     388        virtual void apply(const MatrixfArray&) {} 
    381389}; 
    382390 
     
    415423        virtual void apply(Vec3d&) {} 
    416424        virtual void apply(Vec4d&) {} 
     425         
     426        virtual void apply(Matrixf&) {} 
    417427}; 
    418428 
     
    449459        virtual void apply(const Vec3d&) {} 
    450460        virtual void apply(const Vec4d&) {} 
     461         
     462        virtual void apply(const Matrixf&) {} 
    451463}; 
    452464 
  • OpenSceneGraph/trunk/include/osg/Matrixf

    r8868 r11129  
    384384        } 
    385385 
     386        /** Multiply by scalar. */ 
     387        inline Matrixf operator * (value_type rhs) const 
     388        { 
     389            return Matrixf( 
     390                _mat[0][0]*rhs, _mat[0][1]*rhs, _mat[0][2]*rhs, _mat[0][3]*rhs, 
     391                _mat[1][0]*rhs, _mat[1][1]*rhs, _mat[1][2]*rhs, _mat[1][3]*rhs, 
     392                _mat[2][0]*rhs, _mat[2][1]*rhs, _mat[2][2]*rhs, _mat[2][3]*rhs, 
     393                _mat[3][0]*rhs, _mat[3][1]*rhs, _mat[3][2]*rhs, _mat[3][3]*rhs); 
     394        } 
     395 
     396        /** Unary multiply by scalar. */ 
     397        inline Matrixf& operator *= (value_type rhs) 
     398        { 
     399            _mat[0][0]*=rhs; 
     400            _mat[0][1]*=rhs; 
     401            _mat[0][2]*=rhs; 
     402            _mat[0][3]*=rhs; 
     403            _mat[1][0]*=rhs; 
     404            _mat[1][1]*=rhs; 
     405            _mat[1][2]*=rhs; 
     406            _mat[1][3]*=rhs; 
     407            _mat[2][0]*=rhs; 
     408            _mat[2][1]*=rhs; 
     409            _mat[2][2]*=rhs; 
     410            _mat[2][3]*=rhs; 
     411            _mat[3][0]*=rhs; 
     412            _mat[3][1]*=rhs; 
     413            _mat[3][2]*=rhs; 
     414            _mat[3][3]*=rhs; 
     415            return *this; 
     416        }   
     417 
     418        /** Divide by scalar. */ 
     419        inline Matrixf operator / (value_type rhs) const 
     420        { 
     421            return Matrixf( 
     422                _mat[0][0]/rhs, _mat[0][1]/rhs, _mat[0][2]/rhs, _mat[0][3]/rhs, 
     423                _mat[1][0]/rhs, _mat[1][1]/rhs, _mat[1][2]/rhs, _mat[1][3]/rhs, 
     424                _mat[2][0]/rhs, _mat[2][1]/rhs, _mat[2][2]/rhs, _mat[2][3]/rhs, 
     425                _mat[3][0]/rhs, _mat[3][1]/rhs, _mat[3][2]/rhs, _mat[3][3]/rhs); 
     426        } 
     427 
     428        /** Unary divide by scalar. */ 
     429        inline Matrixf& operator /= (value_type rhs) 
     430        { 
     431            _mat[0][0]/=rhs; 
     432            _mat[0][1]/=rhs; 
     433            _mat[0][2]/=rhs; 
     434            _mat[0][3]/=rhs; 
     435            _mat[1][0]/=rhs; 
     436            _mat[1][1]/=rhs; 
     437            _mat[1][2]/=rhs; 
     438            _mat[1][3]/=rhs; 
     439            _mat[2][0]/=rhs; 
     440            _mat[2][1]/=rhs; 
     441            _mat[2][2]/=rhs; 
     442            _mat[2][3]/=rhs; 
     443            _mat[3][0]/=rhs; 
     444            _mat[3][1]/=rhs; 
     445            _mat[3][2]/=rhs; 
     446            _mat[3][3]/=rhs; 
     447            return *this; 
     448        }           
     449 
     450        /** Binary vector add. */ 
     451        inline Matrixf operator + (const Matrixf& rhs) const 
     452        { 
     453            return Matrixf( 
     454                _mat[0][0] + rhs._mat[0][0], 
     455                _mat[0][1] + rhs._mat[0][1], 
     456                _mat[0][2] + rhs._mat[0][2], 
     457                _mat[0][3] + rhs._mat[0][3], 
     458                _mat[1][0] + rhs._mat[1][0], 
     459                _mat[1][1] + rhs._mat[1][1], 
     460                _mat[1][2] + rhs._mat[1][2], 
     461                _mat[1][3] + rhs._mat[1][3], 
     462                _mat[2][0] + rhs._mat[2][0], 
     463                _mat[2][1] + rhs._mat[2][1], 
     464                _mat[2][2] + rhs._mat[2][2], 
     465                _mat[2][3] + rhs._mat[2][3], 
     466                _mat[3][0] + rhs._mat[3][0], 
     467                _mat[3][1] + rhs._mat[3][1], 
     468                _mat[3][2] + rhs._mat[3][2], 
     469                _mat[3][3] + rhs._mat[3][3]);                          
     470        } 
     471 
     472        /** Unary vector add. Slightly more efficient because no temporary 
     473        * intermediate object. 
     474        */ 
     475        inline Matrixf& operator += (const Matrixf& rhs) 
     476        { 
     477            _mat[0][0] += rhs._mat[0][0]; 
     478            _mat[0][1] += rhs._mat[0][1]; 
     479            _mat[0][2] += rhs._mat[0][2]; 
     480            _mat[0][3] += rhs._mat[0][3]; 
     481            _mat[1][0] += rhs._mat[1][0]; 
     482            _mat[1][1] += rhs._mat[1][1]; 
     483            _mat[1][2] += rhs._mat[1][2]; 
     484            _mat[1][3] += rhs._mat[1][3]; 
     485            _mat[2][0] += rhs._mat[2][0]; 
     486            _mat[2][1] += rhs._mat[2][1]; 
     487            _mat[2][2] += rhs._mat[2][2]; 
     488            _mat[2][3] += rhs._mat[2][3]; 
     489            _mat[3][0] += rhs._mat[3][0]; 
     490            _mat[3][1] += rhs._mat[3][1]; 
     491            _mat[3][2] += rhs._mat[3][2]; 
     492            _mat[3][3] += rhs._mat[3][3]; 
     493            return *this; 
     494        }             
     495 
    386496    protected: 
    387497        value_type _mat[4][4]; 
  • OpenSceneGraph/trunk/src/osgPlugins/dae/CMakeLists.txt

    r10336 r11129  
    33SET(TARGET_SRC 
    44    daeReader.cpp 
     5    daeRAnimations.cpp 
    56    daeRGeometry.cpp 
    67    daeRMaterials.cpp 
    78    daeRSceneObjects.cpp 
     9    daeRSkinning.cpp 
    810    daeRTransforms.cpp 
     11    daeWAnimations.cpp 
    912    daeWGeometry.cpp 
    1013    daeWMaterials.cpp 
     
    6770ENDIF() 
    6871  
    69 SET(TARGET_ADDED_LIBRARIES osgSim )  
     72SET(TARGET_ADDED_LIBRARIES osgSim osgAnimation)  
    7073 
    7174#### end var setup  ### 
  • OpenSceneGraph/trunk/src/osgPlugins/dae/ReaderWriterDAE.cpp

    r9529 r11129  
    5858    } 
    5959 
    60     osgdae::daeReader daeReader(pDAE, options && options->getOptionString().find("StrictTransparency") != std::string::npos ) ; 
     60    osgDAE::daeReader daeReader(pDAE, options && options->getOptionString().find("StrictTransparency") != std::string::npos ) ; 
    6161 
    6262    // Convert file name to URI 
     
    7676        // Return some additional information about the document 
    7777        if (options->getPluginData("DAE-AssetUnitName")) 
    78              *(std::string*)options->getPluginData("DAE-AssetUnitName") = daeReader.m_AssetUnitName; 
     78             *(std::string*)options->getPluginData("DAE-AssetUnitName") = daeReader.getAssetUnitName(); 
    7979        if (options->getPluginData("DAE-AssetUnitMeter")) 
    80             *(float*)options->getPluginData("DAE-AssetUnitMeter") = daeReader.m_AssetUnitMeter; 
     80            *(float*)options->getPluginData("DAE-AssetUnitMeter") = daeReader.getAssetUnitMeter(); 
    8181        if (options->getPluginData("DAE-AssetUp_axis")) 
    82             *(domUpAxisType*)options->getPluginData("DAE-AssetUp_axis") = daeReader.m_AssetUp_axis; 
     82            *(domUpAxisType*)options->getPluginData("DAE-AssetUp_axis") = daeReader.getAssetUpAxis(); 
    8383   } 
    8484 
     
    142142    osg::NodeVisitor::TraversalMode traversalMode = writeExtras ? osg::NodeVisitor::TRAVERSE_ALL_CHILDREN : osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN; 
    143143     
    144     osgdae::daeWriter daeWriter(pDAE, fileURI, usePolygon, GoogleMode, traversalMode, writeExtras); 
     144    osgDAE::daeWriter daeWriter(pDAE, fileURI, usePolygon, GoogleMode, traversalMode, writeExtras); 
    145145    daeWriter.setRootNode( node ); 
    146146    const_cast<osg::Node*>(&node)->accept( daeWriter ); 
     
    149149    if ( daeWriter.isSuccess() ) 
    150150    { 
    151         if ( daeWriter.writeFile() ) 
     151        if (pDAE->write(fileURI)) 
    152152            retVal = WriteResult::FILE_SAVED; 
    153153    } 
  • OpenSceneGraph/trunk/src/osgPlugins/dae/ReaderWriterDAE.h

    r8578 r11129  
    99// See http://collada.org/ and http://khronos.org/collada/ 
    1010 
    11 #define EXTENSION_NAME "dae" 
    12  
    1311class ReaderWriterDAE : public osgDB::ReaderWriter 
    1412{ 
     
    1614    ReaderWriterDAE() 
    1715    { 
    18         supportsExtension(EXTENSION_NAME,"COLLADA 1.4.x DAE format"); 
     16        // Collada document 
     17        supportsExtension("dae","COLLADA 1.4.x DAE format"); 
     18        // Collada zip archive (contains one or more dae files and a manifest.xml) 
     19        supportsExtension("zae","COLLADA 1.4.x ZAE format"); 
    1920    } 
    2021 
  • OpenSceneGraph/trunk/src/osgPlugins/dae/daeRGeometry.cpp

    r10901 r11129  
    22 * Copyright 2006 Sony Computer Entertainment Inc. 
    33 * 
    4  * Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this  
     4 * Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this 
    55 * file except in compliance with the License. You may obtain a copy of the License at: 
    66 * http://research.scea.com/scea_shared_source_license.html 
    77 * 
    8  * Unless required by applicable law or agreed to in writing, software distributed under the License  
    9  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or  
    10  * implied. See the License for the specific language governing permissions and limitations under the  
    11  * License.  
     8 * Unless required by applicable law or agreed to in writing, software distributed under the License 
     9 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
     10 * implied. See the License for the specific language governing permissions and limitations under the 
     11 * License. 
    1212 */ 
    1313 
     
    1919#include <dom/domInstance_controller.h> 
    2020#include <dom/domController.h> 
     21#include <dom/domConstants.h> 
    2122#include <osg/StateSet> 
    22  
     23#include <osg/ShapeDrawable> 
    2324#include <osg/Geometry> 
    2425 
    25 using namespace osgdae; 
    26  
    27 osg::Geode* daeReader::processInstanceGeometry( domInstance_geometry *ig ) 
    28 { 
    29     daeElement *el = getElementFromURI( ig->getUrl() ); 
    30     domGeometry *geom = daeSafeCast< domGeometry >( el ); 
    31     if ( geom == NULL ) 
    32     { 
    33         osg::notify( osg::WARN ) << "Failed to locate geometry " << ig->getUrl().getURI() << std::endl; 
     26#include <osgAnimation/MorphGeometry> 
     27#include <osgAnimation/RigGeometry> 
     28#include <osgAnimation/UpdateBone> 
     29 
     30using namespace osgDAE; 
     31 
     32osg::Geode* daeReader::getOrCreateGeometry(domGeometry *pDomGeometry, domBind_material* pDomBindMaterial, const osg::Geode** ppOriginalGeode) 
     33{ 
     34    // Check cache if geometry already exists 
     35    osg::Geode* pOsgGeode; 
     36 
     37    domGeometryGeodeMap::iterator iter = _geometryMap.find( pDomGeometry ); 
     38    if ( iter != _geometryMap.end() ) 
     39    { 
     40        pOsgGeode = iter->second.get(); 
     41    } 
     42    else 
     43    { 
     44        pOsgGeode = processGeometry( pDomGeometry ); 
     45        _geometryMap.insert( std::make_pair( pDomGeometry, pOsgGeode ) ); 
     46    } 
     47 
     48    if (ppOriginalGeode) 
     49    { 
     50        *ppOriginalGeode = pOsgGeode; 
     51    } 
     52 
     53    if (!pOsgGeode) 
    3454        return NULL; 
    35     } 
    36      
    37     // Check cache if geometry already exists 
    38     osg::Geode* cachedGeode; 
    39  
    40     domGeometryGeodeMap::iterator iter = geometryMap.find( geom ); 
    41     if ( iter != geometryMap.end() ) 
    42     { 
    43         cachedGeode = iter->second.get(); 
    44     } 
    45     else 
    46     { 
    47         cachedGeode = processGeometry( geom ); 
    48         geometryMap.insert( std::make_pair( geom, cachedGeode ) ); 
    49     } 
    5055 
    5156    // Create a copy of the cached Geode with a copy of the drawables, 
    5257    // because we may be using a different material or texture unit bindings. 
    53     osg::Geode *geode = static_cast<osg::Geode*>(cachedGeode->clone(osg::CopyOp::DEEP_COPY_DRAWABLES)); 
    54     if ( geode == NULL ) 
    55     { 
    56         osg::notify( osg::WARN ) << "Failed to load geometry " << ig->getUrl().getURI() << std::endl; 
     58    osg::Geode *pCopiedOsgGeode = static_cast<osg::Geode*>(pOsgGeode->clone(osg::CopyOp::DEEP_COPY_DRAWABLES)); 
     59    if ( pCopiedOsgGeode == NULL ) 
     60    { 
     61        osg::notify( osg::WARN ) << "Failed to load geometry " << pDomGeometry->getName() << std::endl; 
    5762        return NULL; 
    5863    } 
    5964 
    60     // process material bindings 
    61     if ( ig->getBind_material() != NULL ) 
    62     { 
    63         processBindMaterial( ig->getBind_material(), geom, geode, cachedGeode ); 
    64     } 
    65  
    66     return geode; 
    67 } 
    68  
    69 // <controller> 
    70 // attributes: 
    71 // id, name 
    72 // elements: 
     65    // Compute optimized geometry by expanding all indexed arrays so we are no longer rendering with the slow path 
     66    for(unsigned int i=0;i < pCopiedOsgGeode->getNumDrawables();++i) 
     67    { 
     68        osg::Geometry* geom = pCopiedOsgGeode->getDrawable(i)->asGeometry(); 
     69        if (geom) 
     70        { 
     71            if (!geom->areFastPathsUsed() && !geom->getInternalOptimizedGeometry()) 
     72            { 
     73                //geom->computeInternalOptimizedGeometry(); 
     74            } 
     75        } 
     76    } 
     77 
     78    if (pDomBindMaterial) 
     79    { 
     80        processBindMaterial( pDomBindMaterial, pDomGeometry, pCopiedOsgGeode, pOsgGeode ); 
     81    } 
     82 
     83    return pCopiedOsgGeode; 
     84} 
     85 
     86osgAnimation::Bone* daeReader::getOrCreateBone(domNode *pDomNode) 
     87{ 
     88    // Check cache if bone already exists 
     89    osgAnimation::Bone *pOsgBone = NULL; 
     90 
     91    domNodeOsgBoneMap::iterator iterBone = _jointMap.find( pDomNode ); 
     92    if ( iterBone != _jointMap.end() ) 
     93        return iterBone->second.get(); 
     94 
     95    std::string name; 
     96    if (pDomNode->getId()) 
     97        name = pDomNode->getId(); 
     98    if (name.empty() && pDomNode->getSid()) 
     99        name = pDomNode->getSid(); 
     100    if (name.empty() && pDomNode->getName()) 
     101        name = pDomNode->getName(); 
     102    pOsgBone = new osgAnimation::Bone(name); 
     103    pOsgBone->setDataVariance(osg::Object::DYNAMIC); 
     104 
     105    pOsgBone->setUpdateCallback(new osgAnimation::UpdateBone(name)); 
     106 
     107    _jointMap.insert( std::make_pair( pDomNode, pOsgBone ) ); 
     108 
     109    return pOsgBone; 
     110} 
     111 
     112osgAnimation::Skeleton* daeReader::getOrCreateSkeleton(domNode *pDomNode) 
     113{ 
     114    // Check cache if skeleton already exists 
     115    osgAnimation::Skeleton *pOsgSkeleton = NULL; 
     116 
     117    domNodeOsgSkeletonMap::iterator iter = _skeletonMap.find( pDomNode ); 
     118    if ( iter != _skeletonMap.end() ) 
     119        return iter->second.get(); 
     120 
     121    pOsgSkeleton = new osgAnimation::Skeleton; 
     122    pOsgSkeleton->setDefaultUpdateCallback(); 
     123    pOsgSkeleton->setDataVariance(osg::Object::DYNAMIC); 
     124 
     125    _skeletonMap.insert( std::make_pair( pDomNode, pOsgSkeleton ) ); 
     126 
     127    return pOsgSkeleton; 
     128} 
     129 
     130 
     131 
     132osg::Geode* daeReader::processInstanceGeometry( domInstance_geometry *pDomInstanceGeometry ) 
     133{ 
     134    domGeometry *pDomGeometry = daeSafeCast< domGeometry >(getElementFromURI(pDomInstanceGeometry->getUrl())); 
     135    if (!pDomGeometry) 
     136    { 
     137        osg::notify( osg::WARN ) << "Failed to locate geometry " << pDomInstanceGeometry->getUrl().getURI() << std::endl; 
     138        return NULL; 
     139    } 
     140 
     141    return getOrCreateGeometry(pDomGeometry, pDomInstanceGeometry->getBind_material()); 
     142} 
     143 
     144// <morph source (method)> 
     145// 2..*    <source> 
     146// 1    <targets> 
     147//        2..*    <input semantic source> 
     148//        0..*    <extra> 
     149// 0..* <extra> 
     150osg::Node* daeReader::processMorph(domMorph* pDomMorph, domBind_material* pDomBindMaterial) 
     151{ 
     152    domGeometry* pDomGeometry = daeSafeCast< domGeometry >(getElementFromURI( pDomMorph->getSource())); 
     153 
     154    if (!pDomGeometry) 
     155    { 
     156        osg::notify( osg::WARN ) << "Failed to locate geometry " << pDomMorph->getSource().getURI() << std::endl; 
     157        return NULL; 
     158    } 
     159 
     160    // Base mesh 
     161    osg::Geode* pOsgGeode = getOrCreateGeometry(pDomGeometry, pDomBindMaterial); 
     162    if (!pOsgGeode) 
     163        return NULL; 
     164 
     165    // Expects a single geometry inside the geode, should change this 
     166    osg::Geometry* pOsgGeometry = dynamic_cast<osg::Geometry*>(pOsgGeode->getDrawable(0)); 
     167    if (!pOsgGeometry) 
     168        return NULL; 
     169 
     170    osgAnimation::MorphGeometry* pOsgMorphGeometry = new osgAnimation::MorphGeometry(*pOsgGeometry); 
     171    pOsgGeode->removeDrawables(0); 
     172    pOsgGeode->addDrawable(pOsgMorphGeometry); 
     173 
     174    domMorphMethodType morphMethod = pDomMorph->getMethod(); 
     175 
     176    //Files exported by the FBX converter always seem to say they're relative 
     177    //when in fact they should be normalized. 
     178    if (_authoringTool == FBX_CONVERTER) 
     179    { 
     180        morphMethod = MORPHMETHODTYPE_NORMALIZED; 
     181    } 
     182 
     183    switch (morphMethod) 
     184    { 
     185    case MORPHMETHODTYPE_RELATIVE: 
     186        pOsgMorphGeometry->setMethod(osgAnimation::MorphGeometry::RELATIVE); 
     187        break; 
     188    case MORPHMETHODTYPE_NORMALIZED: 
     189        pOsgMorphGeometry->setMethod(osgAnimation::MorphGeometry::NORMALIZED); 
     190        break; 
     191    default: 
     192        osg::notify( osg::WARN ) << "Unknown morph method method type " << std::endl; 
     193    } 
     194 
     195    // 1    <targets> 
     196    domMorph::domTargets* pDomMorhpTargets = pDomMorph->getTargets(); 
     197    domInputLocal_Array domInputs = pDomMorhpTargets->getInput_array(); 
     198 
     199    // TODO how to handle multiple pairs of morph inputs? 
     200    if (domInputs.getCount() > 2) 
     201    { 
     202        osg::notify( osg::WARN ) << "Only a single pair of morph inputs is supported." << std::endl; 
     203    } 
     204 
     205    for (size_t i=0; i < 2; i++) 
     206    { 
     207        if (!strcmp(domInputs[i]->getSemantic(), COMMON_PROFILE_INPUT_MORPH_TARGET)) 
     208        { 
     209            domSource* pDomSource = daeSafeCast<domSource>(getElementFromURI(domInputs[i]->getSource())); 
     210            if (pDomSource) 
     211            { 
     212                if (const domName_array* pDomNames = pDomSource->getName_array()) 
     213                { 
     214                    const domListOfNames& names = pDomNames->getValue(); 
     215                    for (size_t j=0; j < names.getCount(); j++) 
     216                    { 
     217                        daeSIDResolver resolver(_visualScene, names.get(j)); 
     218                        pDomGeometry = daeSafeCast< domGeometry >(resolver.getElement()); 
     219 
     220                        if (pDomGeometry) 
     221                        { 
     222                            osg::Geode* targetgeode = getOrCreateGeometry(pDomGeometry, NULL); 
     223 
     224                            // Expects a single geometry inside the geode, should change this 
     225                            osg::Geometry* pOsgGeometry = dynamic_cast<osg::Geometry*>(targetgeode->getDrawable(0)); 
     226                            if (pOsgGeometry) 
     227                            { 
     228                                pOsgMorphGeometry->addMorphTarget(pOsgGeometry); 
     229                            } 
     230                        } 
     231                        else 
     232                        { 
     233                            osg::notify( osg::WARN ) << "Failed to locate morph geometry '" << names.get(j) << "'" << std::endl; 
     234                        } 
     235                    } 
     236                } 
     237                else if (domIDREF_array* pDomIDREFs = pDomSource->getIDREF_array()) 
     238                { 
     239                    xsIDREFS* pIDREFS = &(pDomIDREFs->getValue()); 
     240                    for (size_t j=0; j < pIDREFS->getCount(); j++) 
     241                    { 
     242                        pDomGeometry = daeSafeCast< domGeometry >(getElementFromIDRef(pIDREFS->get(j))); 
     243 
     244                        if (pDomGeometry) 
     245                        { 
     246                            osg::Geode* targetgeode = getOrCreateGeometry(pDomGeometry, NULL); 
     247 
     248                            // Expects a single geometry inside the geode, should change this 
     249                            osg::Geometry* pOsgGeometry = dynamic_cast<osg::Geometry*>(targetgeode->getDrawable(0)); 
     250                            if (pOsgGeometry) 
     251                            { 
     252                                pOsgMorphGeometry->addMorphTarget(pOsgGeometry); 
     253                            } 
     254                        } 
     255                        else 
     256                        { 
     257                            osg::notify( osg::WARN ) << "Failed to locate morph geometry '" << pIDREFS->get(j).getID() << "'" << std::endl; 
     258                        } 
     259                    } 
     260                } 
     261            } 
     262            else 
     263            { 
     264                osg::notify( osg::WARN ) << "Could not find morph source '" << domInputs[i]->getSource().getURI() << "'" <<std::endl; 
     265                return NULL; 
     266            } 
     267        } 
     268        else if (!strcmp(domInputs[i]->getSemantic(), COMMON_PROFILE_INPUT_MORPH_WEIGHT)) 
     269        { 
     270            domSource* pDomSource = daeSafeCast<domSource>(getElementFromURI(domInputs[i]->getSource())); 
     271            if (pDomSource) 
     272            { 
     273                domFloat_array* pDomFloatArray = pDomSource->getFloat_array(); 
     274                domListOfFloats weights = pDomFloatArray->getValue(); 
     275                for (size_t j=0; j < pDomFloatArray->getCount(); j++) 
     276                { 
     277                    pOsgMorphGeometry->setWeight(j, weights.get(j)); 
     278                } 
     279 
     280                // See if morph weights are targetted by animations 
     281                daeElementDomChannelMap::iterator iter = _daeElementDomChannelMap.find(pDomSource); 
     282                if (iter != _daeElementDomChannelMap.end()) 
     283                { 
     284                    std::string name = pDomSource->getId() ? pDomSource->getId() : ""; 
     285                    osgAnimation::UpdateMorph* pUpdateCallback = new osgAnimation::UpdateMorph(name); 
     286                    pOsgGeode->setUpdateCallback(pUpdateCallback); 
     287                    pOsgGeode->setDataVariance(osg::Object::DYNAMIC); 
     288 
     289                    // Associate all animation channels with this update callback 
     290                    do 
     291                    { 
     292                        _domChannelOsgAnimationUpdateCallbackMap[iter->second] = pUpdateCallback; 
     293                        ++iter; 
     294                    } 
     295                    while (iter != _daeElementDomChannelMap.upper_bound(pDomSource)); 
     296                } 
     297            } 
     298            else 
     299            { 
     300                osg::notify( osg::WARN ) << "Could not find morph source '" << domInputs[i]->getSource().getURI() << "'" <<std::endl; 
     301                return NULL; 
     302            } 
     303        } 
     304    } 
     305 
     306    return pOsgGeode; 
     307} 
     308 
     309// <controller (id) (name)> 
    73310// 0..1 <asset> 
    74311// 1    <skin>, <morph> 
    75312// 0..* <extra> 
    76 osg::Geode* daeReader::processInstanceController( domInstance_controller *ictrl ) 
    77 { 
    78     //TODO: support skinning 
    79     daeElement *el = getElementFromURI( ictrl->getUrl()); 
    80     domController *ctrl = daeSafeCast< domController >( el ); 
    81     if ( ctrl == NULL ) 
    82     { 
    83         osg::notify( osg::WARN ) << "Failed to locate conroller " << ictrl->getUrl().getURI() << std::endl; 
     313osg::Node* daeReader::processInstanceController( domInstance_controller *pDomInstanceController ) 
     314{ 
     315    domController *pDomController = daeSafeCast< domController >(getElementFromURI(pDomInstanceController->getUrl())); 
     316    if (!pDomController) 
     317    { 
     318        osg::notify( osg::WARN ) << "Failed to locate controller " << pDomInstanceController->getUrl().getURI() << std::endl; 
    84319        return NULL; 
    85320    } 
    86321 
    87     osg::notify( osg::WARN ) << "Processing <controller>. There is not skinning support but will display the base mesh." << std::endl; 
    88  
    89     el = NULL; 
    90     //## non init 
    91     daeURI *src=NULL; 
    92     if ( ctrl->getSkin() != NULL ) 
    93     { 
    94         src = &ctrl->getSkin()->getSource(); 
    95         el = getElementFromURI( ctrl->getSkin()->getSource() ); 
    96     } 
    97     else if ( ctrl->getMorph() != NULL ) 
    98     { 
    99         src = &ctrl->getSkin()->getSource(); 
    100         el = getElementFromURI( ctrl->getMorph()->getSource() ); 
    101     } 
    102      
    103     //non init case 
    104     if ( !src ) 
    105     { 
    106         osg::notify( osg::WARN ) << "Failed to locate geometry : URI is NULL" << std::endl; 
     322    if (pDomController->getSkin()) 
     323    { 
     324        _skinInstanceControllers.push_back(pDomInstanceController); 
    107325        return NULL; 
    108326    } 
    109          
    110     domGeometry *geom = daeSafeCast< domGeometry >( el ); 
    111     if ( geom == NULL ) 
    112     { 
    113         osg::notify( osg::WARN ) << "Failed to locate geometry " << src->getURI() << std::endl; 
    114         return NULL; 
    115     } 
    116  
    117     // Check cache if geometry already exists 
    118     osg::Geode* cachedGeode; 
    119     domGeometryGeodeMap::iterator iter = geometryMap.find( geom ); 
    120     if ( iter != geometryMap.end() ) 
    121     { 
    122         cachedGeode = iter->second.get(); 
    123     } 
    124     else 
    125     { 
    126         cachedGeode = processGeometry( geom ); 
    127         geometryMap.insert( std::make_pair( geom, cachedGeode ) ); 
    128     } 
    129  
    130     // Create a copy of the cached Geode with a copy of the drawables, 
    131     // because we may be using a different material or texture unit bindings. 
    132     osg::Geode *geode = static_cast<osg::Geode*>(cachedGeode->clone(osg::CopyOp::DEEP_COPY_DRAWABLES)); 
    133     if ( geode == NULL ) 
    134     { 
    135         osg::notify( osg::WARN ) << "Failed to load geometry " << src->getURI() << std::endl; 
    136         return NULL; 
    137     } 
    138     //process material bindings 
    139     if ( ictrl->getBind_material() != NULL ) 
    140     { 
    141         processBindMaterial( ictrl->getBind_material(), geom, geode, cachedGeode ); 
    142     } 
    143  
    144     return geode; 
    145 } 
    146  
    147 // <geometry> 
    148 // attributes: 
    149 // id, name 
    150 // elements: 
     327    else if (pDomController->getMorph()) 
     328    { 
     329        return processMorph(pDomController->getMorph(), pDomInstanceController->getBind_material()); 
     330    } 
     331 
     332    osg::notify( osg::WARN ) << "Expected skin or morph element in controller '" << pDomController->getName() << "'" << std::endl; 
     333 
     334    return NULL; 
     335} 
     336 
     337// <mesh> 
     338// 1..* <source> 
     339// 1    <vertices> 
     340// 0..*    <lines>, <linestrips>, <polygons>, <polylist>, <triangles>, <trifans>, <tristrips> 
     341// 0..* <extra> 
     342osg::Geode *daeReader::processMesh(domMesh* pDomMesh) 
     343{ 
     344    osg::Geode* pOsgGeode = new osg::Geode; 
     345//    if (pDomMesh->getId() != NULL ) 
     346    { 
     347//        pOsgGeode->setName( pDomMesh->getId() ); 
     348    } 
     349 
     350    // size_t count = mesh->getContents().getCount(); 
     351 
     352    // 1..* <source> 
     353    SourceMap sources; 
     354    domSource_Array sourceArray = pDomMesh->getSource_array(); 
     355    for ( size_t i = 0; i < sourceArray.getCount(); i++) 
     356    { 
     357        sources.insert(std::make_pair((daeElement*)sourceArray[i], domSourceReader(sourceArray[i]))); 
     358    } 
     359 
     360    // 0..*    <lines> 
     361    domLines_Array linesArray = pDomMesh->getLines_array(); 
     362    for ( size_t i = 0; i < linesArray.getCount(); i++) 
     363    { 
     364        processSinglePPrimitive<domLines>(pOsgGeode, pDomMesh, linesArray[i], sources, GL_LINES); 
     365    } 
     366 
     367    // 0..*    <linestrips> 
     368    domLinestrips_Array linestripsArray = pDomMesh->getLinestrips_array(); 
     369    for ( size_t i = 0; i < linestripsArray.getCount(); i++) 
     370    { 
     371        processMultiPPrimitive<domLinestrips>(pOsgGeode, pDomMesh, linestripsArray[i], sources, GL_LINE_STRIP); 
     372    } 
     373 
     374    // 0..* <polygons> 
     375    domPolygons_Array polygonsArray = pDomMesh->getPolygons_array(); 
     376    for ( size_t i = 0; i < polygonsArray.getCount(); i++) 
     377    { 
     378        processPolygons<domPolygons>(pOsgGeode, pDomMesh, polygonsArray[i], sources); 
     379    } 
     380 
     381    // 0..* <polylist> 
     382    domPolylist_Array polylistArray = pDomMesh->getPolylist_array(); 
     383    for ( size_t i = 0; i < polylistArray.getCount(); i++) 
     384    { 
     385        processPolylist(pOsgGeode, pDomMesh, polylistArray[i], sources); 
     386    } 
     387 
     388    // 0..* <triangles> 
     389    domTriangles_Array trianglesArray = pDomMesh->getTriangles_array(); 
     390    for ( size_t i = 0; i < trianglesArray.getCount(); i++) 
     391    { 
     392        processSinglePPrimitive<domTriangles>(pOsgGeode, pDomMesh, trianglesArray[i], sources, GL_TRIANGLES); 
     393    } 
     394 
     395    // 0..* <trifans> 
     396    domTrifans_Array trifansArray = pDomMesh->getTrifans_array(); 
     397    for ( size_t i = 0; i < trifansArray.getCount(); i++) 
     398    { 
     399        processPolygons<domTrifans>(pOsgGeode, pDomMesh, trifansArray[i], sources); 
     400    } 
     401 
     402    // 0..* <tristrips> 
     403    domTristrips_Array tristripsArray = pDomMesh->getTristrips_array(); 
     404    for ( size_t i = 0; i < tristripsArray.getCount(); i++) 
     405    { 
     406        processMultiPPrimitive<domTristrips>(pOsgGeode, pDomMesh, tristripsArray[i], sources, GL_TRIANGLE_STRIP); 
     407    } 
     408 
     409    return pOsgGeode; 
     410} 
     411 
     412// <convexmesh> 
     413osg::Geode *daeReader::processConvexMesh(domConvex_mesh* pDomConvexMesh) 
     414{ 
     415//    osg::notify( osg::WARN ) << "Unsupported geometry convex mesh '" << pDomConvexMesh->getId() << "'" << std::endl; 
     416    return NULL; 
     417} 
     418 
     419// <spline> 
     420osg::Geode *daeReader::processSpline(domSpline* pDomSpline) 
     421{ 
     422//    osg::notify( osg::WARN ) << "Unsupported geometry type spline '" << pDomSpline->getId() << "'" << std::endl; 
     423    return NULL; 
     424} 
     425 
     426// <geometry (id) (name)> 
    151427// 0..1 <asset> 
    152428// 1    <convex_mesh>, <mesh>, <spline> 
    153429// 0..* <extra> 
    154 osg::Geode *daeReader::processGeometry( domGeometry *geo ) 
    155 { 
    156     domMesh *mesh = geo->getMesh(); 
    157     if ( mesh == NULL ) 
    158     { 
    159         osg::notify( osg::WARN ) << "Unsupported Geometry type loading " << geo->getId() << std::endl; 
    160         return NULL; 
    161     } 
    162  
    163     osg::Geode* geode = new osg::Geode; 
    164     if (geo->getId() != NULL ) 
    165     { 
    166         geode->setName( geo->getId() ); 
    167     } 
    168  
    169     // <mesh> 
    170     // elements: 
    171     // 1..* <source> 
    172     // 1    <vertices> 
    173     // 0..*    <lines>, <linestrips>, <polygons>, <polylist>, <triangles>, <trifans>, <tristrips> 
    174     // 0..* <extra> 
    175  
    176     // size_t count = mesh->getContents().getCount(); 
    177      
    178     // 1..* <source> 
    179     SourceMap sources; 
    180     domSource_Array sourceArray = mesh->getSource_array(); 
    181     for ( size_t i = 0; i < sourceArray.getCount(); i++) 
    182     { 
    183         sources.insert( std::make_pair((daeElement*)sourceArray[i], domSourceReader( sourceArray[i] ) ) );  
    184     } 
    185  
    186     // 0..*    <lines> 
    187     domLines_Array linesArray = mesh->getLines_array(); 
    188     for ( size_t i = 0; i < linesArray.getCount(); i++) 
    189     { 
    190         processSinglePPrimitive<domLines>(geode, linesArray[i], sources, GL_LINES ); 
    191     } 
    192  
    193     // 0..*    <linestrips> 
    194     domLinestrips_Array linestripsArray = mesh->getLinestrips_array(); 
    195     for ( size_t i = 0; i < linestripsArray.getCount(); i++) 
    196     { 
    197         processMultiPPrimitive<domLinestrips>(geode, linestripsArray[i], sources, GL_LINE_STRIP ); 
    198     } 
    199  
    200     // 0..* <polygons> 
    201     domPolygons_Array polygonsArray = mesh->getPolygons_array(); 
    202     for ( size_t i = 0; i < polygonsArray.getCount(); i++) 
    203     { 
    204         processMultiPPrimitive<domPolygons>(geode, polygonsArray[i], sources, GL_POLYGON ); 
    205     } 
    206  
    207     // 0..* <polylist> 
    208     domPolylist_Array polylistArray = mesh->getPolylist_array(); 
    209     for ( size_t i = 0; i < polylistArray.getCount(); i++) 
    210     { 
    211         processPolylist(geode, polylistArray[i], sources ); 
    212     } 
    213  
    214     // 0..* <triangles> 
    215     domTriangles_Array trianglesArray = mesh->getTriangles_array(); 
    216     for ( size_t i = 0; i < trianglesArray.getCount(); i++) 
    217     { 
    218         processSinglePPrimitive<domTriangles>(geode, trianglesArray[i], sources, GL_TRIANGLES ); 
    219     } 
    220  
    221     // 0..* <trifans> 
    222     domTrifans_Array trifansArray = mesh->getTrifans_array(); 
    223     for ( size_t i = 0; i < trifansArray.getCount(); i++) 
    224     { 
    225         processMultiPPrimitive<domTrifans>(geode, trifansArray[i], sources, GL_TRIANGLE_FAN ); 
    226     } 
    227  
    228     // 0..* <tristrips> 
    229     domTristrips_Array tristripsArray = mesh->getTristrips_array(); 
    230     for ( size_t i = 0; i < tristripsArray.getCount(); i++) 
    231     { 
    232         processMultiPPrimitive<domTristrips>(geode, tristripsArray[i], sources, GL_TRIANGLE_STRIP ); 
    233     } 
    234  
    235     return geode; 
     430osg::Geode *daeReader::processGeometry(domGeometry *pDomGeometry) 
     431{ 
     432    if (pDomGeometry->getMesh()) 
     433    { 
     434        return processMesh(pDomGeometry->getMesh()); 
     435    } 
     436    else if (pDomGeometry->getConvex_mesh()) 
     437    { 
     438        return processConvexMesh(pDomGeometry->getConvex_mesh()); 
     439    } 
     440    else if (pDomGeometry->getSpline()) 
     441    { 
     442        return processSpline(pDomGeometry->getSpline()); 
     443    } 
     444#ifdef COLLADA15 
     445    else if (pDomGeometry->getBRep()) 
     446    { 
     447        return processBRep(pDomGeometry->getBRep()); 
     448    } 
     449#endif 
     450 
     451    osg::notify( osg::WARN ) << "Unexpected geometry type in geometry '" << pDomGeometry->getId() << "'" << std::endl; 
     452    return NULL; 
    236453} 
    237454 
    238455 
    239456template< typename T > 
    240 void daeReader::processSinglePPrimitive(osg::Geode* geode, T *group, SourceMap &sources, GLenum mode ) 
    241 { 
    242     osg::Geometry *geometry = new ReaderGeometry(); 
    243     if (group->getMaterial() != NULL ) 
    244     { 
    245         geometry->setName(group->getMaterial()); 
    246     } 
    247  
    248     IndexMap index_map; 
    249     resolveArrays( group->getInput_array(), geometry, sources, index_map ); 
    250  
    251     osg::DrawArrayLengths* dal = new osg::DrawArrayLengths( mode ); 
    252     processP( group->getP(), geometry, index_map, dal/*mode*/ ); 
    253     geometry->addPrimitiveSet( dal ); 
    254      
     457void daeReader::processSinglePPrimitive(osg::Geode* geode, 
     458    const domMesh* pDomMesh, const T* group, SourceMap& sources, GLenum mode) 
     459{ 
     460    osg::Geometry *geometry = new osg::Geometry(); 
     461    geometry->setName(group->getMaterial()); 
    255462    geode->addDrawable( geometry ); 
     463 
     464    osg::DrawElementsUInt* pDrawElements = new osg::DrawElementsUInt(mode); 
     465    geometry->addPrimitiveSet(pDrawElements); 
     466 
     467    domP_Array domPArray; 
     468    domPArray.append(group->getP()); 
     469    std::vector<std::vector<GLuint> > indexLists; 
     470    resolveMeshArrays(domPArray, group->getInput_array(), pDomMesh, 
     471        geometry, sources, indexLists); 
     472    pDrawElements->asVector().swap(indexLists.front()); 
    256473} 
    257474 
    258475template< typename T > 
    259 void daeReader::processMultiPPrimitive(osg::Geode* geode, T *group, SourceMap &sources, GLenum mode ) 
    260 { 
    261     osg::Geometry *geometry = new ReaderGeometry(); 
    262     if (group->getMaterial() != NULL ) 
    263     { 
    264         geometry->setName(group->getMaterial()); 
    265     } 
    266  
    267     IndexMap index_map; 
    268     resolveArrays( group->getInput_array(), geometry, sources, index_map ); 
    269  
    270     osg::DrawArrayLengths* dal = new osg::DrawArrayLengths( mode ); 
    271  
    272     for ( size_t i = 0; i < group->getP_array().getCount(); i++ ) 
    273     { 
    274         processP( group->getP_array()[i], geometry, index_map, dal/*mode*/ ); 
    275     } 
    276     geometry->addPrimitiveSet( dal ); 
    277  
     476void daeReader::processMultiPPrimitive(osg::Geode* geode, 
     477    const domMesh* pDomMesh, const T* group, SourceMap &sources, GLenum mode) 
     478{ 
     479    osg::Geometry *geometry = new osg::Geometry(); 
     480    geometry->setName(group->getMaterial()); 
    278481    geode->addDrawable( geometry ); 
    279 } 
    280  
    281 void daeReader::processPolylist(osg::Geode* geode, domPolylist *group, SourceMap &sources ) 
    282 { 
    283     osg::Geometry *geometry = new ReaderGeometry(); 
    284     if (group->getMaterial() != NULL ) 
    285     { 
    286         geometry->setName(group->getMaterial()); 
    287     } 
    288  
    289     IndexMap index_map; 
    290     resolveArrays( group->getInput_array(), geometry, sources, index_map ); 
    291  
    292     osg::DrawArrayLengths* dal = new osg::DrawArrayLengths( GL_POLYGON ); 
    293      
    294     //domPRef p = (domP*)(daeElement*)domP::_Meta->create(); //I don't condone creating elements like this but I don't care 
    295     domPRef p = (domP*)domP::registerElement(*dae)->create().cast(); 
    296     //if it created properly because I never want it as part of the document. Its just a temporary 
    297     //element to trick the importer into loading polylists easier. 
    298     unsigned int maxOffset = 0; 
    299     for ( unsigned int i = 0; i < group->getInput_array().getCount(); i++ ) 
    300     { 
    301         if ( group->getInput_array()[i]->getOffset() > maxOffset ) 
    302         { 
    303             maxOffset = group->getInput_array()[i]->getOffset(); 
    304         } 
    305     } 
    306     maxOffset++; 
    307     unsigned int pOffset = 0; 
    308     for ( unsigned int i = 0; i < group->getCount(); i++ ) 
    309     { 
    310         p->getValue().clear(); 
    311         for ( unsigned int x = 0; x < group->getVcount()->getValue()[i]; x++ ) 
    312         { 
    313             for ( unsigned int y = 0; y < maxOffset; y++ ) 
    314             { 
    315                 p->getValue().append( group->getP()->getValue()[ pOffset + x*maxOffset + y ] ); 
    316             } 
    317         } 
    318         pOffset += group->getVcount()->getValue()[i] * maxOffset; 
    319         processP( p, geometry, index_map, dal/*mode*/ ); 
    320     } 
    321      
    322     geometry->addPrimitiveSet( dal ); 
    323      
    324     geode->addDrawable( geometry ); 
    325 } 
    326  
    327 void daeReader::processP( domP *p, osg::Geometry *&/*geom*/, IndexMap &index_map, osg::DrawArrayLengths* dal /*GLenum mode*/ ) 
    328 { 
    329     int idxcount = index_map.size(); 
    330     int count = p->getValue().getCount(); 
    331     count = (count/idxcount)*idxcount; 
    332     dal->push_back(count/idxcount); 
    333  
    334     int j = 0; 
    335     while ( j < count ) { 
    336         for ( IndexMap::iterator k = index_map.begin(); k != index_map.end(); k++,j++ ) { 
    337             int tmp = p->getValue()[j]; 
    338             k->second->push_back(tmp); 
    339         } 
    340     } 
    341 } 
    342  
    343 void daeReader::resolveArrays( domInputLocalOffset_Array &inputs, osg::Geometry *geom,  
    344                                     SourceMap &sources, IndexMap &index_map ) 
    345 { 
    346     domVertices* vertices = NULL; 
     482 
     483    std::vector<std::vector<GLuint> > indexLists; 
     484    resolveMeshArrays(group->getP_array(), group->getInput_array(), pDomMesh, 
     485        geometry, sources, indexLists); 
     486 
     487    for (size_t i = 0; i < indexLists.size(); ++i) 
     488    { 
     489        osg::DrawElementsUInt* pDrawElements = new osg::DrawElementsUInt(mode); 
     490        geometry->addPrimitiveSet(pDrawElements); 
     491        pDrawElements->asVector().swap(indexLists[i]); 
     492    } 
     493} 
     494 
     495void daeReader::processPolylist(osg::Geode* geode, const domMesh* pDomMesh, const domPolylist *group, SourceMap &sources) 
     496{ 
     497    const domPolylist::domVcount* pDomVcount = group->getVcount(); 
     498    if (!pDomVcount) 
     499    { 
     500        osg::notify(osg::WARN) << "Index counts not found." << std::endl; 
     501        return; 
     502    } 
     503 
     504    osg::Geometry* geometry = new osg::Geometry(); 
     505    geometry->setName(group->getMaterial()); 
     506    geode->addDrawable(geometry); 
     507 
     508    std::vector<std::vector<GLuint> > vertexLists; 
     509    domP_Array domPArray; 
     510    domPArray.append(group->getP()); 
     511    resolveMeshArrays(domPArray, group->getInput_array(), pDomMesh, geometry, sources, vertexLists); 
     512 
     513    const std::vector<GLuint>& vertexList = vertexLists.front(); 
     514 
     515    osg::DrawElementsUInt* pDrawTriangles = new osg::DrawElementsUInt(GL_TRIANGLES); 
     516    geometry->addPrimitiveSet(pDrawTriangles); 
     517 
     518    const domListOfUInts& vCount = pDomVcount->getValue(); 
     519    for (size_t i = 0, j = 0; i < vCount.getCount(); ++i) 
     520    { 
     521        size_t primitiveLength = vCount[i]; 
     522        if (j + primitiveLength > vertexList.size()) 
     523        { 
     524            osg::notify(osg::WARN) << "Error: vertex counts are greater than the number of indices." << std::endl; 
     525            return; 
     526        } 
     527        for (size_t k = 2; k < primitiveLength; ++k) 
     528        { 
     529            pDrawTriangles->push_back(vertexList[j]); 
     530            pDrawTriangles->push_back(vertexList[j+k-1]); 
     531            pDrawTriangles->push_back(vertexList[j+k]); 
     532        } 
     533        j += primitiveLength; 
     534    } 
     535} 
     536 
     537template <typename T> 
     538void daeReader::processPolygons(osg::Geode* geode, 
     539    const domMesh* pDomMesh, const T *group, SourceMap& sources) 
     540{ 
     541    osg::Geometry *geometry = new osg::Geometry(); 
     542    geometry->setName(group->getMaterial()); 
     543    geode->addDrawable(geometry); 
     544 
     545    osg::DrawElementsUInt* pDrawElements = new osg::DrawElementsUInt(GL_TRIANGLES); 
     546    geometry->addPrimitiveSet(pDrawElements); 
     547 
     548    std::vector<std::vector<GLuint> > indexLists; 
     549    resolveMeshArrays(group->getP_array(), group->getInput_array(), pDomMesh, 
     550        geometry, sources, indexLists); 
     551 
     552    for ( size_t i = 0; i < indexLists.size(); ++i) 
     553    { 
     554        const std::vector<GLuint>& indices = indexLists[i]; 
     555 
     556        for (size_t j = 2; j < indices.size(); ++j) 
     557        { 
     558            pDrawElements->push_back(indices.front()); 
     559            pDrawElements->push_back(indices[j - 1]); 
     560            pDrawElements->push_back(indices[j]); 
     561        } 
     562    } 
     563} 
     564 
     565void processVertices( 
     566    domVertices* vertices, 
     567    daeElement*& position_source, 
     568    daeElement*& color_source, 
     569    daeElement*& normal_source, 
     570    daeElement*& texcoord_source) 
     571{ 
     572    const domInputLocal_Array& inputs = vertices->getInput_array(); 
     573 
     574    // Process input elements within the vertices element. These are of the unshared type 
     575    // and therefore cannot have set and offset attributes 
     576 
     577    for (size_t i = 0; i < inputs.getCount(); ++i) 
     578    { 
     579        xsNMTOKEN semantic = inputs[i]->getSemantic(); 
     580        daeElement* pDaeElement = getElementFromURI(inputs[i]->getSource()); 
     581        if (strcmp(COMMON_PROFILE_INPUT_POSITION, semantic) == 0) 
     582        { 
     583            position_source = pDaeElement; 
     584        } 
     585        else if (strcmp(COMMON_PROFILE_INPUT_COLOR, semantic) == 0) 
     586        { 
     587            color_source = pDaeElement; 
     588        } 
     589        else if (strcmp(COMMON_PROFILE_INPUT_NORMAL, semantic) == 0) 
     590        { 
     591            normal_source = pDaeElement; 
     592        } 
     593        else if (strcmp(COMMON_PROFILE_INPUT_TEXCOORD, semantic) == 0) 
     594        { 
     595            texcoord_source = pDaeElement; 
     596        } 
     597    } 
     598} 
     599 
     600// I've never seen more than 2 used so this should be enough. If you find that 
     601// a greater number is needed then increase it accordingly and submit the change 
     602// to OpenSceneGraph. 
     603// Why not use a vector? Because a large map of VertexIndices is used and 
     604// allocating vectors for each element would make it a lot slower. 
     605const int MAX_TEXTURE_COORDINATE_SETS = 4; 
     606 
     607void resolveMeshInputs( 
     608    const domInputLocalOffset_Array &inputs, 
     609    daeElement*& position_source, 
     610    daeElement*& color_source, 
     611    daeElement*& normal_source, 
     612    daeElement* texcoord_sources[MAX_TEXTURE_COORDINATE_SETS], 
     613    int& position_offset, 
     614    int& color_offset, 
     615    int& normal_offset, 
     616    int texcoord_offsets[MAX_TEXTURE_COORDINATE_SETS]) 
     617{ 
     618    position_source = color_source = normal_source = NULL; 
     619    position_offset = color_offset = normal_offset = 0; 
     620    for (int i = 0; i < MAX_TEXTURE_COORDINATE_SETS; ++i) 
     621    { 
     622        texcoord_sources[i] = NULL; 
     623        texcoord_offsets[i] = NULL; 
     624    } 
     625 
     626    for ( size_t i = 0; i < inputs.getCount(); i++ ) 
     627    { 
     628        if (strcmp(COMMON_PROFILE_INPUT_VERTEX, inputs[i]->getSemantic()) == 0) 
     629        { 
     630            daeElement* pDaeElement = getElementFromURI(inputs[i]->getSource()); 
     631            if (domVertices* vertices = daeSafeCast<domVertices>(pDaeElement)) 
     632            { 
     633                processVertices(vertices, position_source, color_source, normal_source, texcoord_sources[0]); 
     634                position_offset = inputs[i]->getOffset(); 
     635 
     636                if (color_source) color_offset = position_offset; 
     637                if (normal_source) normal_offset = position_offset; 
     638                if (texcoord_sources[0]) texcoord_offsets[0] = position_offset; 
     639            } 
     640            break; 
     641        } 
     642    } 
     643 
     644    for ( size_t i = 0; i < inputs.getCount(); i++ ) 
     645    { 
     646        xsNMTOKEN semantic = inputs[i]->getSemantic(); 
     647        daeElement* pDaeElement = getElementFromURI(inputs[i]->getSource()); 
     648        int offset = inputs[i]->getOffset(); 
     649 
     650        if (strcmp(COMMON_PROFILE_INPUT_COLOR, semantic) == 0) 
     651        { 
     652            if (color_source != NULL) 
     653                osg::notify( osg::WARN )<<"Overwriting vertices input(COLOR) with input from primitive"<<std::endl; 
     654            color_source = pDaeElement; 
     655            color_offset = offset; 
     656        } 
     657        else if (strcmp(COMMON_PROFILE_INPUT_NORMAL, semantic) == 0) 
     658        { 
     659            if (normal_source != NULL) 
     660                osg::notify( osg::WARN )<<"Overwriting vertices input(NORMAL) with input from primitive"<<std::endl; 
     661            normal_source = pDaeElement; 
     662            normal_offset = offset; 
     663        } 
     664        else if (strcmp(COMMON_PROFILE_INPUT_TEXCOORD, semantic) == 0) 
     665        { 
     666            unsigned set = inputs[i]->getSet(); 
     667            if (set >= MAX_TEXTURE_COORDINATE_SETS) 
     668            { 
     669                osg::notify( osg::WARN )<<"Texture coordinate set "<< set << 
     670                    "was requested, the maximum allowed is " << MAX_TEXTURE_COORDINATE_SETS - 1 << "." << std::endl; 
     671                continue; 
     672            } 
     673            if (texcoord_sources[set]) 
     674                osg::notify( osg::WARN )<<"Overwriting vertices input(TEXCOORD) with input from primitive"<<std::endl; 
     675 
     676            texcoord_sources[set] = pDaeElement; 
     677            texcoord_offsets[set] = offset; 
     678        } 
     679    } 
     680} 
     681 
     682struct VertexIndices 
     683{ 
     684    VertexIndices(int p, int c, int n, const int t[MAX_TEXTURE_COORDINATE_SETS]) 
     685        : position_index(p), color_index(c), normal_index(n) 
     686    { 
     687        for (int i = 0; i < MAX_TEXTURE_COORDINATE_SETS; ++i) texcoord_indices[i] = t[i]; 
     688    } 
     689    bool operator < (const VertexIndices& rhs) const 
     690    { 
     691        if (position_index != rhs.position_index) return position_index < rhs.position_index; 
     692        if (color_index != rhs.color_index) return color_index < rhs.color_index; 
     693        if (normal_index != rhs.normal_index) return normal_index < rhs.normal_index; 
     694        for (int i = 0; i < MAX_TEXTURE_COORDINATE_SETS; ++i) 
     695        { 
     696            if (texcoord_indices[i] != rhs.texcoord_indices[i]) return texcoord_indices[i] < rhs.texcoord_indices[i]; 
     697        } 
     698        return false; 
     699    } 
     700 
     701    int position_index, color_index, normal_index, texcoord_indices[MAX_TEXTURE_COORDINATE_SETS]; 
     702}; 
     703 
     704void daeReader::resolveMeshArrays(const domP_Array& domPArray, 
     705    const domInputLocalOffset_Array& inputs, const domMesh* pDomMesh, 
     706    osg::Geometry* geometry, SourceMap &sources, 
     707    std::vector<std::vector<GLuint> >& vertexLists) 
     708{ 
    347709    daeElement* position_source = NULL; 
    348710    daeElement* color_source = NULL; 
    349711    daeElement* normal_source = NULL; 
    350     daeElement* texcoord_source = NULL; 
    351  
    352     daeElement *tmp_el; 
    353     domInputLocalOffset *tmp_input; 
    354     ReaderGeometry* GeometryWrapper = dynamic_cast<ReaderGeometry*>(geom); 
    355  
    356     int TexCoordSetsUsed = 0; 
    357  
    358     if ( findInputSourceBySemantic( inputs, "VERTEX", tmp_el, &tmp_input ) )  
    359     { 
    360         vertices = daeSafeCast< domVertices >( tmp_el ); 
    361         if ( vertices == NULL )  
    362         { 
    363             osg::notify( osg::WARN )<<"Could not get vertices"<<std::endl; 
    364             return; 
    365         } 
    366  
    367         // Process mandatory offset attribute 
    368         int offset = tmp_input->getOffset(); 
    369         if ( index_map[offset] == NULL )  
    370             index_map[offset] = new osg::IntArray(); 
    371         geom->setVertexIndices( index_map[offset] ); 
    372  
    373         // Process input elements within the vertices element. These are of the unshared type 
    374         // and therefore cannot have set and offset attributes 
    375  
    376         // The vertices POSITION semantic input element is mandatory 
    377         domInputLocal *tmp; 
    378         findInputSourceBySemantic( vertices->getInput_array(), "POSITION", position_source, &tmp ); 
    379         if ( position_source != NULL ) 
    380         { 
    381             geom->setVertexArray( sources[position_source].getVec3Array() ); 
    382         } 
    383         else 
    384         { 
    385             osg::notify( osg::FATAL )<<"Mandatory POSITION semantic missing"<<std::endl; 
    386             return; 
    387         } 
    388  
    389         // Process additional vertices input elements 
    390         findInputSourceBySemantic( vertices->getInput_array(), "COLOR", color_source, &tmp ); 
    391         findInputSourceBySemantic( vertices->getInput_array(), "NORMAL", normal_source, &tmp ); 
    392         findInputSourceBySemantic( vertices->getInput_array(), "TEXCOORD", texcoord_source, &tmp ); 
    393  
    394  
    395         int VertexCount = sources[position_source].getCount(); 
    396         if ( color_source != NULL )  
    397         { 
    398             // Check matching arrays 
    399             if ( sources[color_source].getCount() >= VertexCount ) 
    400             { 
    401                 geom->setColorArray( sources[color_source].getVec4Array() ); 
    402                 geom->setColorBinding( osg::Geometry::BIND_PER_VERTEX ); 
    403                 geom->setColorIndices( index_map[offset] ); // Use the vertex indices 
    404             } 
    405             else 
    406             { 
    407                 osg::notify( osg::WARN )<<"Not enough entries in color array"<<std::endl; 
    408             } 
    409         } 
    410         if ( normal_source != NULL ) 
    411         { 
    412             // Check matching arrays 
    413             if ( sources[normal_source].getCount() >= VertexCount ) 
    414             { 
    415                 geom->setNormalArray( sources[normal_source].getVec3Array() ); 
    416                 geom->setNormalBinding( osg::Geometry::BIND_PER_VERTEX ); 
    417                 geom->setNormalIndices( index_map[offset] ); // Use the vertex indices 
    418             } 
    419             else 
    420             { 
    421                 osg::notify( osg::WARN )<<"Not enough entries in normal array"<<std::endl; 
    422             } 
    423         } 
    424         // It seems sensible to only process the first input found here with a TEXCOORD semantic. 
    425         // as offsets are not allowed here. 
    426         // I assume that this belongs to set zero as the DOM returns 0 for the set attribute on shared 
    427         // input elements even if the attribute is absent. 
    428         if ( texcoord_source != NULL ) 
    429         { 
    430             domSourceReader *sc = &sources[texcoord_source]; 
    431             if ( sc->getCount() >= VertexCount ) 
    432             { 
    433                 if (NULL != GeometryWrapper) 
    434                     GeometryWrapper->_TexcoordSetMap[0] = TexCoordSetsUsed; 
    435                 switch( sc->getArrayType() ) 
     712    daeElement* texcoord_sources[MAX_TEXTURE_COORDINATE_SETS] = {NULL}; 
     713    int position_offset = 0; 
     714    int color_offset = 0; 
     715    int normal_offset = 0; 
     716    int texcoord_offsets[MAX_TEXTURE_COORDINATE_SETS] = {0}; 
     717 
     718    resolveMeshInputs(inputs, 
     719        position_source, 
     720        color_source, 
     721        normal_source, 
     722        texcoord_sources, 
     723        position_offset, 
     724        color_offset, 
     725        normal_offset, 
     726        texcoord_offsets); 
     727 
     728    unsigned stride = 0; 
     729    for (size_t i = 0; i < inputs.getCount(); ++i) 
     730    { 
     731        stride = osg::maximum<unsigned>(stride, inputs[i]->getOffset()); 
     732    } 
     733    ++stride; 
     734 
     735    typedef std::map<VertexIndices, GLuint> VertexIndicesIndexMap; 
     736    VertexIndicesIndexMap vertexIndicesIndexMap; 
     737 
     738    for (size_t j = 0; j < domPArray.getCount(); ++j) 
     739    { 
     740        const domListOfUInts& p = domPArray[j]->getValue(); 
     741 
     742        for (size_t i = 0; i < p.getCount(); i += stride) 
     743        { 
     744            int texcoord_indices[MAX_TEXTURE_COORDINATE_SETS]; 
     745            for (int t = 0; t < MAX_TEXTURE_COORDINATE_SETS; ++t) 
     746            { 
     747                texcoord_indices[t] = p.get(i + texcoord_offsets[t]); 
     748            } 
     749            VertexIndices v( 
     750                p.get(i + position_offset), 
     751                p.get(i + color_offset), 
     752                p.get(i + normal_offset), 
     753                texcoord_indices); 
     754            vertexIndicesIndexMap.insert(VertexIndicesIndexMap::value_type(v, 0)); 
     755        } 
     756    } 
     757 
     758    { 
     759        VertexIndicesIndexMap::iterator it = vertexIndicesIndexMap.begin(), end = vertexIndicesIndexMap.end(); 
     760        for (GLuint i = 0; it != end; ++it, ++i) 
     761        { 
     762            it->second = i; 
     763        } 
     764    } 
     765 
     766    vertexLists.resize(domPArray.getCount()); 
     767 
     768    for (size_t j = 0; j < domPArray.getCount(); ++j) 
     769    { 
     770        const domListOfUInts& p = domPArray[j]->getValue(); 
     771 
     772        for (size_t i = 0; i < p.getCount(); i += stride) 
     773        { 
     774            int texcoord_indices[MAX_TEXTURE_COORDINATE_SETS]; 
     775            for (int t = 0; t < MAX_TEXTURE_COORDINATE_SETS; ++t) 
     776            { 
     777                texcoord_indices[t] = p.get(i + texcoord_offsets[t]); 
     778            } 
     779            VertexIndices v( 
     780                p.get(i + position_offset), 
     781                p.get(i + color_offset), 
     782                p.get(i + normal_offset), 
     783                texcoord_indices); 
     784 
     785            GLuint index = vertexIndicesIndexMap.find(v)->second; 
     786 
     787            _oldToNewIndexMap.insert(OldToNewIndexMap::value_type( 
     788                OldToNewIndexMap::key_type(pDomMesh, v.position_index), 
     789                OldToNewIndexMap::mapped_type(geometry, index))); 
     790            vertexLists[j].push_back(index); 
     791        } 
     792    } 
     793 
     794    if (const osg::Vec3Array* source = sources[position_source].getVec3Array()) 
     795    { 
     796        osg::Vec3Array* pArray = new osg::Vec3Array; 
     797 
     798        for (VertexIndicesIndexMap::const_iterator it = vertexIndicesIndexMap.begin(), 
     799            end = vertexIndicesIndexMap.end(); it != end; ++it) 
     800        { 
     801            pArray->push_back(source->at(it->first.position_index)); 
     802        } 
     803 
     804        geometry->setVertexData(osg::Geometry::ArrayData(pArray, osg::Geometry::BIND_PER_VERTEX)); 
     805    } 
     806 
     807    if (color_source) 
     808    { 
     809        if (const osg::Vec4Array* source = sources[color_source].getVec4Array()) 
     810        { 
     811            osg::Vec4Array* pArray = new osg::Vec4Array; 
     812 
     813            for (VertexIndicesIndexMap::const_iterator it = vertexIndicesIndexMap.begin(), 
     814                end = vertexIndicesIndexMap.end(); it != end; ++it) 
     815            { 
     816                pArray->push_back(source->at(it->first.color_index)); 
     817            } 
     818 
     819            geometry->setColorData(osg::Geometry::ArrayData(pArray, osg::Geometry::BIND_PER_VERTEX)); 
     820        } 
     821    } 
     822 
     823    if (normal_source) 
     824    { 
     825        if (const osg::Vec3Array* source = sources[normal_source].getVec3Array()) 
     826        { 
     827            osg::Vec3Array* pArray = new osg::Vec3Array; 
     828 
     829            for (VertexIndicesIndexMap::const_iterator it = vertexIndicesIndexMap.begin(), 
     830                end = vertexIndicesIndexMap.end(); it != end; ++it) 
     831            { 
     832                pArray->push_back(source->at(it->first.normal_index)); 
     833            } 
     834 
     835            geometry->setNormalData(osg::Geometry::ArrayData(pArray, osg::Geometry::BIND_PER_VERTEX)); 
     836        } 
     837    } 
     838 
     839    for (int texcoord_set = 0; texcoord_set < MAX_TEXTURE_COORDINATE_SETS; ++texcoord_set) 
     840    { 
     841        if (daeElement* texcoord_source = texcoord_sources[texcoord_set]) 
     842        { 
     843            osg::Array* pArray = NULL; 
     844 
     845            if (const osg::Vec2Array* source = sources[texcoord_source].getVec2Array()) 
     846            { 
     847                osg::Vec2Array* pVec2Array = new osg::Vec2Array; 
     848                pArray = pVec2Array; 
     849 
     850                for (VertexIndicesIndexMap::const_iterator it = vertexIndicesIndexMap.begin(), 
     851                    end = vertexIndicesIndexMap.end(); it != end; ++it) 
    436852                { 
    437                     case domSourceReader::Vec2: 
    438                         geom->setTexCoordArray( TexCoordSetsUsed, sc->getVec2Array() ); 
    439                         break; 
    440                     case domSourceReader::Vec3: 
    441                         geom->setTexCoordArray( TexCoordSetsUsed, sc->getVec3Array() ); 
    442                         break; 
    443                     default: 
    444                         osg::notify( osg::WARN )<<"Unsupported array type: "<< sc->getArrayType() <<std::endl; 
    445                         break; 
     853                    pVec2Array->push_back(source->at(it->first.texcoord_indices[texcoord_set])); 
    446854                } 
    447                 TexCoordSetsUsed++; 
    448             } 
    449             else 
    450             { 
    451                 osg::notify( osg::WARN )<<"Not enough entries in texcoord array"<<std::endl; 
    452             } 
    453         } 
    454         if ( findInputSourceBySemantic( inputs, "TEXCOORD", texcoord_source, &tmp_input, 1 ) ) 
    455         { 
    456             osg::notify( osg::WARN )<<"More than one input element with TEXCOORD semantic found in vertices element"<<std::endl; 
    457         } 
    458     } 
    459     else  
    460     { 
    461         osg::notify( osg::WARN )<<"Vertex data not found"<<std::endl; 
    462         return; 
    463     } 
    464  
    465     if ( findInputSourceBySemantic( inputs, "COLOR", tmp_el, &tmp_input ))  
    466     { 
    467         if (color_source != NULL) 
    468             osg::notify( osg::WARN )<<"Overwriting vertices input(COLOR) with input from primitive"<<std::endl; 
    469         else 
    470             geom->setColorBinding( osg::Geometry::BIND_PER_VERTEX ); 
    471  
    472         int offset = tmp_input->getOffset(); 
    473         if ( index_map[offset] == NULL ) 
    474             index_map[offset] = new osg::IntArray(); 
    475         geom->setColorIndices( index_map[offset] ); 
    476         geom->setColorArray( sources[tmp_el].getVec4Array() ); 
    477     } 
    478  
    479     if ( findInputSourceBySemantic( inputs, "NORMAL", tmp_el, &tmp_input ) )  
    480     { 
    481         if (normal_source != NULL) 
    482             osg::notify( osg::WARN )<<"Overwriting vertices input(NORMAL) with input from primitive"<<std::endl; 
    483         else 
    484             geom->setNormalBinding( osg::Geometry::BIND_PER_VERTEX ); 
    485  
    486         int offset = tmp_input->getOffset(); 
    487         if ( index_map[offset] == NULL ) 
    488             index_map[offset] = new osg::IntArray(); 
    489         geom->setNormalIndices( index_map[offset] ); 
    490         geom->setNormalArray( sources[tmp_el].getVec3Array() ); 
    491     } 
    492  
    493     int inputNumber = 0; 
    494     while ( findInputSourceBySemantic( inputs, "TEXCOORD", texcoord_source, &tmp_input, inputNumber ) ) 
    495     { 
    496         int offset = tmp_input->getOffset(); 
    497         int set = tmp_input->getSet(); 
    498         if (NULL != GeometryWrapper) 
    499         { 
    500             if (GeometryWrapper->_TexcoordSetMap.find(set) != GeometryWrapper->_TexcoordSetMap.end()) 
    501                     osg::notify( osg::WARN )<<"Duplicate texcoord set: "<< set <<std::endl; 
    502             GeometryWrapper->_TexcoordSetMap[set] = TexCoordSetsUsed; 
    503         } 
    504  
    505         if ( index_map[offset] == NULL )  
    506         { 
    507             index_map[offset] = new osg::IntArray(); 
    508         } 
    509         geom->setTexCoordIndices( TexCoordSetsUsed, index_map[offset] ); 
    510  
    511         if ( texcoord_source != NULL ) 
    512         { 
    513             domSourceReader &sc = sources[texcoord_source]; 
    514             switch( sc.getArrayType() ) { 
    515                 case domSourceReader::Vec2: 
    516                     geom->setTexCoordArray( TexCoordSetsUsed, sc.getVec2Array() ); 
    517                     break; 
    518                 case domSourceReader::Vec3: 
    519                     geom->setTexCoordArray( TexCoordSetsUsed, sc.getVec3Array() ); 
    520                     break; 
    521                 default: 
    522                     osg::notify( osg::WARN )<<"Unsupported array type: "<< sc.getArrayType() <<std::endl; 
    523                     break; 
    524             } 
    525         } 
    526         TexCoordSetsUsed++; 
    527         inputNumber++; 
    528     } 
    529 } 
    530  
     855            } 
     856            else if (const osg::Vec3Array* source = sources[texcoord_source].getVec3Array()) 
     857            { 
     858                osg::Vec3Array* pVec3Array = new osg::Vec3Array; 
     859                pArray = pVec3Array; 
     860 
     861                for (VertexIndicesIndexMap::const_iterator it = vertexIndicesIndexMap.begin(), 
     862                    end = vertexIndicesIndexMap.end(); it != end; ++it) 
     863                { 
     864                    pVec3Array->push_back(source->at(it->first.texcoord_indices[texcoord_set])); 
     865                } 
     866            } 
     867 
     868            if (pArray) 
     869            { 
     870                geometry->setTexCoordData(texcoord_set, osg::Geometry::ArrayData(pArray, osg::Geometry::BIND_PER_VERTEX)); 
     871            } 
     872        } 
     873    } 
     874} 
  • OpenSceneGraph/trunk/src/osgPlugins/dae/daeRMaterials.cpp

    r9956 r11129  
    1919#include <dom/domCOLLADA.h> 
    2020#include <dom/domProfile_COMMON.h> 
     21#include <dom/domConstants.h> 
    2122 
    2223#include <osg/BlendColor> 
     
    3031#include <sstream> 
    3132 
    32 using namespace osgdae; 
    33  
     33using namespace osgDAE; 
     34 
     35template <typename T> 
     36void daeReader::getTransparencyCounts(daeDatabase* database, int& zero, int& one) const 
     37{ 
     38    std::vector<T*> constantVec; 
     39    database->typeLookup(constantVec); 
     40 
     41    for (size_t i = 0; i < constantVec.size(); ++i) 
     42    { 
     43        if (const domCommon_transparent_type* pTransparent = constantVec[i]->getTransparent()) 
     44        { 
     45            domFx_opaque_enum opaque = pTransparent->getOpaque(); 
     46            if (opaque == FX_OPAQUE_ENUM_RGB_ZERO) 
     47            { 
     48                ++one; 
     49                continue; 
     50            } 
     51        } 
     52 
     53        if (const domCommon_float_or_param_type* pTransparency = constantVec[i]->getTransparency()) 
     54        { 
     55            float transparency; 
     56 
     57            domFloat transparencyParam = 1.0; 
     58            if (pTransparency->getFloat()) 
     59            { 
     60                transparency = pTransparency->getFloat()->getValue(); 
     61            } 
     62            else if (pTransparency->getParam() && 
     63                GetFloatParam(pTransparency->getParam()->getRef(), transparencyParam)) 
     64            { 
     65                transparency = transparencyParam; 
     66            } 
     67            else 
     68            { 
     69                continue; 
     70            } 
     71 
     72            if (transparency < 0.01f) 
     73            { 
     74                ++zero; 
     75            } 
     76            else if (transparency > 0.99f) 
     77            { 
     78                ++one; 
     79            } 
     80        } 
     81 
     82    } 
     83 
     84} 
     85 
     86bool daeReader::findInvertTransparency(daeDatabase* database) const 
     87{ 
     88    int zero = 0, one = 0; 
     89    getTransparencyCounts<domProfile_COMMON::domTechnique::domConstant>(database, zero, one); 
     90    getTransparencyCounts<domProfile_COMMON::domTechnique::domLambert>(database, zero, one); 
     91    getTransparencyCounts<domProfile_COMMON::domTechnique::domPhong>(database, zero, one); 
     92    getTransparencyCounts<domProfile_COMMON::domTechnique::domBlinn>(database, zero, one); 
     93 
     94    return zero > one; 
     95} 
    3496 
    3597// <bind_material> 
     
    64126        osg::Drawable* drawable = geode->getDrawable(i); 
    65127        std::string materialName = drawable->getName(); 
    66         ReaderGeometry *cachedGeometry = dynamic_cast<ReaderGeometry*>(cachedGeode->getDrawable(i)->asGeometry()); 
     128        osg::Geometry *cachedGeometry = dynamic_cast<osg::Geometry*>(cachedGeode->getDrawable(i)->asGeometry()); 
    67129         
    68130        domInstance_material_Array &ima = bm->getTechnique_common()->getInstance_material_array(); 
     
    80142                    // Check material cache if this material already exists 
    81143                    osg::StateSet* ss; 
    82                     domMaterialStateSetMap::iterator iter = materialMap.find( mat ); 
    83                     if ( iter != materialMap.end() ) 
     144                    domMaterialStateSetMap::iterator iter = _materialMap.find( mat ); 
     145                    if (iter != _materialMap.end() ) 
    84146                    { 
    85147                        // Reuse material 
     
    91153                        ss = new osg::StateSet; 
    92154                        processMaterial(ss, mat); 
    93                         materialMap.insert(std::make_pair(mat, ss)); 
     155                        _materialMap.insert(std::make_pair(mat, ss)); 
    94156                    } 
    95157                    drawable->setStateSet(ss); 
    96158                    // Need to process bind_vertex_inputs here 
    97                     // This all feels like a horrible kludge to me 
    98                     // I wish somebody with a better knowledge of Collada and OSG than me would have a go at it! 
    99159                    // 1. Clear the texcoord arrays and associated texcoord vertex indices 
    100160                    // from the current (cloned) drawable. 
     
    106166                    } 
    107167                    clonedGeometry->getTexCoordArrayList().clear(); 
     168 
    108169                    // 2. For each possible texture unit find the correct texcoord array and  
    109                     // indices from the original (uncloned) drawable and place in the cloned drawable 
     170                    // indices from the cached drawable and place in the cloned drawable 
    110171                    // in the correct texture unit slot 
    111                     std::string TransparencyMapTexcoordName; 
    112                     osg::Texture2D *Texture; 
    113                     if (NULL != (Texture = dynamic_cast<osg::Texture2D*>(ss->getTextureAttribute(AMBIENT_OCCLUSION_UNIT, osg::StateAttribute::TEXTURE)))) 
    114                     { 
    115                         std::string AmbientOcclusionTexcoordName = Texture->getName(); 
    116                         if (!AmbientOcclusionTexcoordName.empty()) 
    117                         { 
    118                             domInstance_material::domBind_vertex_input_Array &bvia = ima[j]->getBind_vertex_input_array(); 
    119                             size_t k; 
    120                             for ( k = 0; k < bvia.getCount(); k++) 
    121                             { 
    122                                 if (!strcmp(bvia[k]->getSemantic(), AmbientOcclusionTexcoordName.c_str()) && !strcmp(bvia[k]->getInput_semantic(), "TEXCOORD")) 
    123                                 { 
    124                                     // OK - found the effect name, now see if I can find a matching set in the cachedGeometry 
    125                                     if (NULL != cachedGeometry) 
    126                                     { 
    127                                         std::map<int, int>::iterator iTr; 
    128                                         if (cachedGeometry->_TexcoordSetMap.end() != (iTr = cachedGeometry->_TexcoordSetMap.find(bvia[k]->getInput_set()))) 
    129                                         { 
    130                                             // Copy the texture cordinates and indices (if any) into the cloned geometry 
    131                                             clonedGeometry->setTexCoordData(AMBIENT_OCCLUSION_UNIT, cachedGeometry->getTexCoordData(iTr->second)); 
    132                                         } 
    133                                     } 
    134                                     break; 
    135                                 } 
    136                             } 
    137                             if (k == bvia.getCount()) 
    138                                 osg::notify( osg::WARN ) << "Failed to find matching <bind_vertex_input> for " << AmbientOcclusionTexcoordName << std::endl; 
    139                         } 
    140                     } 
    141                     if (NULL != (Texture = dynamic_cast<osg::Texture2D*>(ss->getTextureAttribute(MAIN_TEXTURE_UNIT, osg::StateAttribute::TEXTURE)))) 
    142                     { 
    143                         std::string MainTextureTexcoordName = Texture->getName(); 
    144                         if (!MainTextureTexcoordName.empty()) 
    145                         { 
    146                             domInstance_material::domBind_vertex_input_Array &bvia = ima[j]->getBind_vertex_input_array(); 
    147                             size_t k; 
    148                             for ( k = 0; k < bvia.getCount(); k++) 
    149                             { 
    150                                 if (!strcmp(bvia[k]->getSemantic(), MainTextureTexcoordName.c_str()) && !strcmp(bvia[k]->getInput_semantic(), "TEXCOORD")) 
    151                                 { 
    152                                     // OK - found the effect name, now see if I can find a matching set in the cachedGeometry 
    153                                     if (NULL != cachedGeometry) 
    154                                     { 
    155                                         std::map<int, int>::iterator iTr; 
    156                                         if (cachedGeometry->_TexcoordSetMap.end() != (iTr = cachedGeometry->_TexcoordSetMap.find(bvia[k]->getInput_set()))) 
    157                                         { 
    158                                             // Copy the texture cordinates and indices (if any) into the cloned geometry 
    159                                             clonedGeometry->setTexCoordData(MAIN_TEXTURE_UNIT, cachedGeometry->getTexCoordData(iTr->second)); 
    160                                         } 
    161                                     } 
    162                                     break; 
    163                                 } 
    164                             } 
    165                             if (k == bvia.getCount()) 
    166                             { 
    167                                 osg::notify( osg::WARN ) << "Failed to find matching <bind_vertex_input> for " << MainTextureTexcoordName << std::endl; 
    168                                 // This may be a departure from the spec. For the time being I am only going to do this 
    169                                 // for the MAIN_TEXTURE_UNIT. 
    170                                 // Not found so just use the first TEXCOORD we have if any. 
    171                                 if (cachedGeometry->_TexcoordSetMap.size() > 0) 
    172                                     clonedGeometry->setTexCoordData(MAIN_TEXTURE_UNIT, cachedGeometry->getTexCoordData(cachedGeometry->_TexcoordSetMap.begin()->second)); 
    173                             } 
    174                         } 
    175                     } 
    176                     if (NULL != (Texture = dynamic_cast<osg::Texture2D*>(ss->getTextureAttribute(TRANSPARENCY_MAP_UNIT, osg::StateAttribute::TEXTURE)))) 
    177                     { 
    178                         std::string TransparencyMapTexcoordName = Texture->getName(); 
    179                         if (!TransparencyMapTexcoordName.empty()) 
    180                         { 
    181                             domInstance_material::domBind_vertex_input_Array &bvia = ima[j]->getBind_vertex_input_array(); 
    182                             size_t k; 
    183                             for ( k = 0; k < bvia.getCount(); k++) 
    184                             { 
    185                                 if (!strcmp(bvia[k]->getSemantic(), TransparencyMapTexcoordName.c_str()) && !strcmp(bvia[k]->getInput_semantic(), "TEXCOORD")) 
    186                                 { 
    187                                     // OK - found the effect name, now see if I can find a matching set in the cachedGeometry 
    188                                     if (NULL != cachedGeometry) 
    189                                     { 
    190                                         std::map<int, int>::iterator iTr; 
    191                                         if (cachedGeometry->_TexcoordSetMap.end() != (iTr = cachedGeometry->_TexcoordSetMap.find(bvia[k]->getInput_set()))) 
    192                                         { 
    193                                             // Copy the texture cordinates and indices (if any) into the cloned geometry 
    194                                             clonedGeometry->setTexCoordData(TRANSPARENCY_MAP_UNIT, cachedGeometry->getTexCoordData(iTr->second)); 
    195                                         } 
    196                                     } 
    197                                     break; 
    198                                 } 
    199                             } 
    200                             if (k == bvia.getCount()) 
    201                                 osg::notify( osg::WARN ) << "Failed to find matching <bind_vertex_input> for " << TransparencyMapTexcoordName << std::endl; 
    202                         } 
    203                     } 
     172                    copyTextureCoordinateSet(ss, cachedGeometry, clonedGeometry, ima[j], AMBIENT_OCCLUSION_UNIT); 
     173                    copyTextureCoordinateSet(ss, cachedGeometry, clonedGeometry, ima[j], MAIN_TEXTURE_UNIT); 
     174                    copyTextureCoordinateSet(ss, cachedGeometry, clonedGeometry, ima[j], TRANSPARENCY_MAP_UNIT); 
    204175                } 
    205176                else 
     
    228199void    daeReader::processMaterial(osg::StateSet *ss, domMaterial *mat ) 
    229200{ 
    230     currentInstance_effect = mat->getInstance_effect(); 
    231     domEffect *effect = daeSafeCast< domEffect >( getElementFromURI( currentInstance_effect->getUrl() ) ); 
     201    _currentInstance_effect = mat->getInstance_effect(); 
     202    domEffect *effect = daeSafeCast< domEffect >( getElementFromURI( _currentInstance_effect->getUrl() ) ); 
    232203    if (effect) 
    233204    { 
     
    260231    { 
    261232        domProfile_COMMON *pc = daeSafeCast< domProfile_COMMON >( effect->getFx_profile_abstract_array()[i] ); 
    262         if ( pc != NULL ) 
    263         { 
    264             if ( hasCOMMON ) 
     233        if (pc != NULL ) 
     234        { 
     235            if (hasCOMMON ) 
    265236            { 
    266237                osg::notify( osg::WARN ) << "Effect already has a profile_COMMON. Skipping this one" << std::endl; 
    267238                continue; 
    268239            } 
    269             currentEffect = effect; 
     240            _currentEffect = effect; 
    270241            processProfileCOMMON(ss, pc); 
    271242            hasCOMMON = true; 
     
    346317    // 0..1 <transparency> 
    347318    // 0..1 <index_of_refraction> 
    348     if ( b != NULL ) 
    349     { 
    350         osg::StateAttribute *EmissionStateAttribute = NULL; 
    351         osg::StateAttribute *AmbientStateAttribute = NULL; 
    352         osg::StateAttribute *DiffuseStateAttribute = NULL; 
    353         processColorOrTextureType( b->getEmission(), osg::Material::EMISSION, mat.get(), NULL, &EmissionStateAttribute ); 
     319    if (b != NULL ) 
     320    { 
     321        osg::Texture2D *EmissionStateAttribute = NULL; 
     322        osg::Texture2D *AmbientStateAttribute = NULL; 
     323        osg::Texture2D *DiffuseStateAttribute = NULL; 
     324        processColorOrTextureType(ss, b->getEmission(), osg::Material::EMISSION, mat.get(), NULL, &EmissionStateAttribute ); 
    354325        if (NULL != EmissionStateAttribute) 
    355326            osg::notify( osg::WARN ) << "Currently no support for <texture> in Emission channel " << std::endl; 
    356327 
    357         processColorOrTextureType( b->getAmbient(), osg::Material::AMBIENT, mat.get(), NULL,  &AmbientStateAttribute ); 
     328        processColorOrTextureType(ss, b->getAmbient(), osg::Material::AMBIENT, mat.get(), NULL,  &AmbientStateAttribute ); 
    358329         
    359         processColorOrTextureType( b->getDiffuse(), osg::Material::DIFFUSE, mat.get(), NULL, &DiffuseStateAttribute ); 
    360         if ( DiffuseStateAttribute != NULL )  
    361         { 
    362             if ( AmbientStateAttribute != NULL )  
     330        processColorOrTextureType(ss, b->getDiffuse(), osg::Material::DIFFUSE, mat.get(), NULL, &DiffuseStateAttribute ); 
     331        if (DiffuseStateAttribute != NULL )  
     332        { 
     333            if (AmbientStateAttribute != NULL )  
    363334            { 
    364335                // Set the ambient and diffuse colour white so that the incoming fragment colour ends up as a 
     
    392363        else 
    393364        { 
    394             if ( NULL != AmbientStateAttribute  )  
     365            if (NULL != AmbientStateAttribute  )  
    395366                osg::notify( osg::WARN ) << "Ambient occlusion map only supported when diffuse texture also specified" << std::endl; 
    396367        } 
    397368 
    398         if(processColorOrTextureType( b->getSpecular(), osg::Material::SPECULAR, mat.get(), b->getShininess() ) && (NULL != DiffuseStateAttribute) ) 
     369        if (processColorOrTextureType(ss, b->getSpecular(), osg::Material::SPECULAR, mat.get(), b->getShininess() ) && (NULL != DiffuseStateAttribute) ) 
    399370        { 
    400371            // Diffuse texture will defeat specular highlighting 
     
    420391    // 0..1 <transparency> 
    421392    // 0..1 <index_of_refraction> 
    422     else if ( p != NULL ) 
    423     { 
    424         osg::StateAttribute *EmissionStateAttribute = NULL; 
    425         osg::StateAttribute *AmbientStateAttribute = NULL; 
    426         osg::StateAttribute *DiffuseStateAttribute = NULL; 
    427         processColorOrTextureType( p->getEmission(), osg::Material::EMISSION, mat.get(), NULL, &EmissionStateAttribute ); 
     393    else if (p != NULL ) 
     394    { 
     395        osg::Texture2D *EmissionStateAttribute = NULL; 
     396        osg::Texture2D *AmbientStateAttribute = NULL; 
     397        osg::Texture2D *DiffuseStateAttribute = NULL; 
     398        processColorOrTextureType(ss, p->getEmission(), osg::Material::EMISSION, mat.get(), NULL, &EmissionStateAttribute ); 
    428399        if (NULL != EmissionStateAttribute) 
    429400            osg::notify( osg::WARN ) << "Currently no support for <texture> in Emission channel " << std::endl; 
    430401         
    431         processColorOrTextureType( p->getAmbient(), osg::Material::AMBIENT, mat.get(), NULL,  &AmbientStateAttribute ); 
     402        processColorOrTextureType(ss, p->getAmbient(), osg::Material::AMBIENT, mat.get(), NULL,  &AmbientStateAttribute ); 
    432403         
    433         processColorOrTextureType( p->getDiffuse(), osg::Material::DIFFUSE, mat.get(), NULL, &DiffuseStateAttribute ); 
    434         if ( DiffuseStateAttribute != NULL )  
    435         { 
    436             if ( AmbientStateAttribute != NULL )  
     404        processColorOrTextureType(ss, p->getDiffuse(), osg::Material::DIFFUSE, mat.get(), NULL, &DiffuseStateAttribute ); 
     405        if (DiffuseStateAttribute != NULL )  
     406        { 
     407            if (AmbientStateAttribute != NULL )  
    437408            { 
    438409                // Set the ambient and diffuse colour white so that the incoming fragment colour ends up as a 
     
    466437        else 
    467438        { 
    468             if ( NULL != AmbientStateAttribute  )  
     439            if (NULL != AmbientStateAttribute  )  
    469440                osg::notify( osg::WARN ) << "Ambient occlusion map only supported when diffuse texture also specified" << std::endl; 
    470441        } 
    471442         
    472         if(processColorOrTextureType( p->getSpecular(), osg::Material::SPECULAR, mat.get(), p->getShininess() ) && (NULL != DiffuseStateAttribute) ) 
     443        if (processColorOrTextureType(ss, p->getSpecular(), osg::Material::SPECULAR, mat.get(), p->getShininess() ) && (NULL != DiffuseStateAttribute) ) 
    473444        { 
    474445            // Diffuse texture will defeat specular highlighting 
     
    492463    // 0..1 <transparency> 
    493464    // 0..1 <index_of_refraction> 
    494     else if ( l != NULL ) 
    495     { 
    496         osg::StateAttribute *EmissionStateAttribute = NULL; 
    497         osg::StateAttribute *AmbientStateAttribute = NULL; 
    498         osg::StateAttribute *DiffuseStateAttribute = NULL; 
    499         processColorOrTextureType( l->getEmission(), osg::Material::EMISSION, mat.get(), NULL, &EmissionStateAttribute ); 
     465    else if (l != NULL ) 
     466    { 
     467        osg::Texture2D *EmissionStateAttribute = NULL; 
     468        osg::Texture2D *AmbientStateAttribute = NULL; 
     469        osg::Texture2D *DiffuseStateAttribute = NULL; 
     470        processColorOrTextureType(ss, l->getEmission(), osg::Material::EMISSION, mat.get(), NULL, &EmissionStateAttribute ); 
    500471        if (NULL != EmissionStateAttribute) 
    501472            osg::notify( osg::WARN ) << "Currently no support for <texture> in Emission channel " << std::endl; 
    502473         
    503         processColorOrTextureType( l->getAmbient(), osg::Material::AMBIENT, mat.get(), NULL,  &AmbientStateAttribute); 
    504  
    505         processColorOrTextureType( l->getDiffuse(), osg::Material::DIFFUSE, mat.get(), NULL, &DiffuseStateAttribute ); 
    506         if ( DiffuseStateAttribute != NULL )  
    507         { 
    508             if ( AmbientStateAttribute != NULL )  
     474        processColorOrTextureType(ss, l->getAmbient(), osg::Material::AMBIENT, mat.get(), NULL,  &AmbientStateAttribute); 
     475 
     476        processColorOrTextureType(ss, l->getDiffuse(), osg::Material::DIFFUSE, mat.get(), NULL, &DiffuseStateAttribute ); 
     477        if (DiffuseStateAttribute != NULL )  
     478        { 
     479            if (AmbientStateAttribute != NULL )  
    509480            { 
    510481                // Set the ambient and diffuse colour white so that the incoming fragment colour ends up as a 
     
    538509        else 
    539510        { 
    540             if ( NULL != AmbientStateAttribute  )  
     511            if (NULL != AmbientStateAttribute  )  
    541512                osg::notify( osg::WARN ) << "Ambient occlusion map only supported when diffuse texture also specified" << std::endl; 
    542513        } 
     
    552523    // 0..1 <transparency> 
    553524    // 0..1 <index_of_refraction> 
    554     else if ( c != NULL ) 
    555     { 
    556         osg::StateAttribute *sa = NULL; 
    557         processColorOrTextureType( c->getEmission(), osg::Material::EMISSION, mat.get(), NULL, &sa ); 
    558         if ( sa != NULL )  
     525    else if (c != NULL ) 
     526    { 
     527        osg::Texture2D *sa = NULL; 
     528        processColorOrTextureType(ss, c->getEmission(), osg::Material::EMISSION, mat.get(), NULL, &sa ); 
     529        if (sa != NULL )  
    559530        { 
    560531            ss->setTextureMode( MAIN_TEXTURE_UNIT, GL_TEXTURE_2D, GL_TRUE ); 
     
    586557//        1        texcoord 
    587558//        0..*    extra 
    588 bool daeReader::processColorOrTextureType(    domCommon_color_or_texture_type *cot,  
    589                                             osg::Material::ColorMode channel, 
    590                                             osg::Material *mat, 
    591                                             domCommon_float_or_param_type *fop, 
    592                                             osg::StateAttribute **sa, 
    593                                             bool blinn) 
    594 { 
    595     if ( cot == NULL ) 
     559bool daeReader::processColorOrTextureType(const osg::StateSet* ss, 
     560                                          domCommon_color_or_texture_type *cot,  
     561                                          osg::Material::ColorMode channel, 
     562                                          osg::Material *mat, 
     563                                          domCommon_float_or_param_type *fop, 
     564                                          osg::Texture2D **sa, 
     565                                          bool blinn) 
     566{ 
     567    if (cot == NULL ) 
    596568    { 
    597569        return false; 
    598570    } 
    599571    bool retVal = false; 
     572 
     573    std::string texCoordSet; 
    600574 
    601575    //osg::StateAttribute *sa = NULL; 
    602576    //TODO: Make all channels process <param ref=""> type of value 
    603     if ( channel == osg::Material::EMISSION ) 
    604     { 
    605         if ( cot->getColor() != NULL ) 
     577    if (channel == osg::Material::EMISSION ) 
     578    { 
     579        if (cot->getColor() != NULL ) 
    606580        { 
    607581            domFloat4 &f4 = cot->getColor()->getValue(); 
     
    622596            if (sa != NULL) 
    623597            { 
    624                 *sa = processTexture( cot->getTexture() ); 
     598                *sa = processTexture( cot->getTexture(), ss, MAIN_TEXTURE_UNIT); 
    625599                retVal = true; 
    626600            } 
     
    633607        } 
    634608    } 
    635     else if ( channel == osg::Material::AMBIENT ) 
    636     { 
    637         if ( cot->getColor() != NULL ) 
     609    else if (channel == osg::Material::AMBIENT ) 
     610    { 
     611        if (cot->getColor() != NULL ) 
    638612        { 
    639613            domFloat4 &f4 = cot->getColor()->getValue(); 
     
    653627        { 
    654628            if (sa != NULL) 
    655                 *sa = processTexture( cot->getTexture() ); 
     629                *sa = processTexture( cot->getTexture(), ss, AMBIENT_OCCLUSION_UNIT); 
    656630            else 
    657631            { 
     
    666640        } 
    667641    } 
    668     else if ( channel == osg::Material::DIFFUSE ) 
    669     { 
    670         if ( cot->getColor() != NULL ) 
     642    else if (channel == osg::Material::DIFFUSE ) 
     643    { 
     644        if (cot->getColor() != NULL ) 
    671645        { 
    672646            domFloat4 &f4 = cot->getColor()->getValue(); 
     
    674648            retVal = true; 
    675649        } 
    676         else if ( cot->getTexture() != NULL) 
     650        else if (cot->getTexture() != NULL) 
    677651        { 
    678652            if (sa != NULL) 
    679                 *sa = processTexture( cot->getTexture() ); 
     653                *sa = processTexture( cot->getTexture(), ss, MAIN_TEXTURE_UNIT); 
    680654            else 
    681655            { 
     
    684658            } 
    685659            domExtra *extra = cot->getTexture()->getExtra(); 
    686             if ( extra != NULL && extra->getType() != NULL && strcmp( extra->getType(), "color" ) == 0 ) 
     660            if (extra != NULL && extra->getType() != NULL && strcmp( extra->getType(), "color" ) == 0 ) 
    687661            { 
    688662                //the extra data for osg. Diffuse color can happen with a texture. 
     
    690664                { 
    691665                    domTechnique *teq = extra->getTechnique_array()[i]; 
    692                     if ( strcmp( teq->getProfile(), "SCEI" ) == 0 ) 
     666                    if (strcmp( teq->getProfile(), "SCEI" ) == 0 ) 
    693667                    { 
    694668                        osg::Vec4 col; 
     
    717691        } 
    718692    } 
    719     else if ( channel == osg::Material::SPECULAR ) 
    720     { 
    721         if ( cot->getColor() != NULL ) 
     693    else if (channel == osg::Material::SPECULAR ) 
     694    { 
     695        if (cot->getColor() != NULL ) 
    722696        { 
    723697            domFloat4 &f4 = cot->getColor()->getValue(); 
     
    743717        } 
    744718 
    745         if ( fop != NULL && fop->getFloat() != NULL ) 
     719        if (fop != NULL && fop->getFloat() != NULL ) 
    746720        { 
    747721            float shininess = fop->getFloat()->getValue(); 
     
    759733} 
    760734 
    761 bool daeReader::GetFloat4Param(xsNCName Reference, domFloat4 &f4) 
     735bool daeReader::GetFloat4Param(xsNCName Reference, domFloat4 &f4) const 
    762736{ 
    763737    std::string MyReference = Reference; 
    764738 
    765739    MyReference.insert(0, "./"); 
    766     daeSIDResolver Resolver(currentEffect, MyReference.c_str()); 
     740    daeSIDResolver Resolver(_currentEffect, MyReference.c_str()); 
    767741    daeElement *el = Resolver.getElement(); 
    768742    if (NULL == el) 
    769743            return false; 
    770744 
    771     if (NULL != currentInstance_effect) 
     745    if (NULL != _currentInstance_effect) 
    772746    { 
    773747        // look here first for setparams 
    774748        // I am sure there must be a better way of doing this 
    775749        // Maybe the Collada DAE guys can give us a parameter management mechanism ! 
    776         const domInstance_effect::domSetparam_Array& SetParamArray = currentInstance_effect->getSetparam_array(); 
     750        const domInstance_effect::domSetparam_Array& SetParamArray = _currentInstance_effect->getSetparam_array(); 
    777751        size_t NumberOfSetParams = SetParamArray.getCount(); 
    778752        for (size_t i = 0; i < NumberOfSetParams; i++) 
     
    806780} 
    807781 
    808 bool daeReader::GetFloatParam(xsNCName Reference, domFloat &f) 
     782bool daeReader::GetFloatParam(xsNCName Reference, domFloat &f) const 
    809783{ 
    810784    std::string MyReference = Reference; 
    811785 
    812786    MyReference.insert(0, "./"); 
    813     daeSIDResolver Resolver(currentEffect, MyReference.c_str()); 
     787    daeSIDResolver Resolver(_currentEffect, MyReference.c_str()); 
    814788    daeElement *el = Resolver.getElement(); 
    815789    if (NULL == el) 
    816790        return false; 
    817791 
    818     if (NULL != currentInstance_effect) 
     792    if (NULL != _currentInstance_effect) 
    819793    { 
    820794        // look here first for setparams 
    821795        // I am sure there must be a better way of doing this 
    822796        // Maybe the Collada DAE guys can give us a parameter management mechanism ! 
    823         const domInstance_effect::domSetparam_Array& SetParamArray = currentInstance_effect->getSetparam_array(); 
     797        const domInstance_effect::domSetparam_Array& SetParamArray = _currentInstance_effect->getSetparam_array(); 
    824798        size_t NumberOfSetParams = SetParamArray.getCount(); 
    825799        for (size_t i = 0; i < NumberOfSetParams; i++) 
     
    853827} 
    854828 
    855 osg::StateAttribute *daeReader::processTexture( domCommon_color_or_texture_type_complexType::domTexture *tex ) 
    856 { 
     829osg::Texture::WrapMode getWrapMode(domFx_sampler_wrap_common domWrap) 
     830{ 
     831    switch (domWrap) 
     832    { 
     833    case FX_SAMPLER_WRAP_COMMON_WRAP: 
     834        return osg::Texture::REPEAT; 
     835    case FX_SAMPLER_WRAP_COMMON_MIRROR: 
     836        return osg::Texture::MIRROR; 
     837    case FX_SAMPLER_WRAP_COMMON_CLAMP: 
     838        return osg::Texture::CLAMP_TO_EDGE; 
     839    case FX_SAMPLER_WRAP_COMMON_NONE: 
     840    case FX_SAMPLER_WRAP_COMMON_BORDER: 
     841        return osg::Texture::CLAMP_TO_BORDER; 
     842    } 
     843 
     844    return osg::Texture::CLAMP; 
     845} 
     846 
     847osg::Texture::FilterMode getFilterMode(domFx_sampler_filter_common domFilter, bool allowMipMap) 
     848{ 
     849    switch (domFilter) 
     850    { 
     851    case FX_SAMPLER_FILTER_COMMON_NEAREST: 
     852        return osg::Texture::NEAREST; 
     853    case FX_SAMPLER_FILTER_COMMON_LINEAR: 
     854        return osg::Texture::LINEAR; 
     855    } 
     856 
     857    if (allowMipMap) 
     858    { 
     859        switch (domFilter) 
     860        { 
     861        case FX_SAMPLER_FILTER_COMMON_NEAREST_MIPMAP_NEAREST: 
     862            return osg::Texture::NEAREST_MIPMAP_NEAREST; 
     863        case FX_SAMPLER_FILTER_COMMON_LINEAR_MIPMAP_NEAREST: 
     864            return osg::Texture::LINEAR_MIPMAP_NEAREST; 
     865        case FX_SAMPLER_FILTER_COMMON_NEAREST_MIPMAP_LINEAR: 
     866            return osg::Texture::NEAREST_MIPMAP_LINEAR; 
     867        case FX_SAMPLER_FILTER_COMMON_NONE: 
     868        case FX_SAMPLER_FILTER_COMMON_LINEAR_MIPMAP_LINEAR: 
     869            return osg::Texture::LINEAR_MIPMAP_LINEAR; 
     870        } 
     871    } 
     872 
     873    return osg::Texture::LINEAR; 
     874} 
     875 
     876std::string daeReader::processImagePath(const domImage* pDomImage) const 
     877{ 
     878    if (pDomImage == NULL) 
     879    { 
     880        osg::notify( osg::WARN ) << "Could not locate image for texture" << std::endl; 
     881        return std::string(); 
     882    } 
     883 
     884    //Got a sampler and a surface and an imaged. Time to create the texture stuff for osg 
     885    if (pDomImage->getInit_from()) 
     886    { 
     887        pDomImage->getInit_from()->getValue().validate(); 
     888        if (strcmp(pDomImage->getInit_from()->getValue().getProtocol(), "file") == 0) 
     889        { 
     890            std::string path = pDomImage->getInit_from()->getValue().pathDir() + 
     891                pDomImage->getInit_from()->getValue().pathFile(); 
     892            path = cdom::uriToNativePath(path); 
     893            if (path.empty()) 
     894            { 
     895                osg::notify( osg::WARN ) << "Unable to get path from URI." << std::endl; 
     896                return std::string(); 
     897            } 
     898#ifdef WIN32 
     899            // If the path has a drive specifier or a UNC name then strip the leading / 
     900            const char* szFilename = path.c_str(); 
     901            if (path.size() > 2 && (path[2] == ':' || (path[1] == '/' && path[2] == '/'))) 
     902                return szFilename + 1; 
     903#endif 
     904            return path; 
     905        } 
     906        else 
     907        { 
     908            osg::notify( osg::WARN ) << "Only images with a \"file\" scheme URI are supported in this version." << std::endl; 
     909        } 
     910    } 
     911    else 
     912    { 
     913        osg::notify( osg::WARN ) << "Embedded image data is not supported in this version." << std::endl; 
     914    } 
     915    return std::string(); 
     916} 
     917 
     918float luminance(const osg::Vec4& color) 
     919{ 
     920    return 
     921        color.r() * 0.212671f + 
     922        color.g() * 0.715160f + 
     923        color.b() * 0.072169f; 
     924} 
     925 
     926osg::Image* daeReader::processImageTransparency(const osg::Image* srcImg, domFx_opaque_enum opaque, float transparency) const 
     927{ 
     928    int s = srcImg->s(); 
     929    int t = srcImg->t(); 
     930    unsigned char* pixels = new unsigned char [s * t]; 
     931 
     932    if (opaque == FX_OPAQUE_ENUM_RGB_ZERO) 
     933    { 
     934        for (int i = 0; i < t; ++i) 
     935        { 
     936            for (int j = 0; j < s; ++j) 
     937            { 
     938                osg::Vec4 color(srcImg->getColor(j, i)); 
     939 
     940                pixels[i * s + j] = static_cast<unsigned char>( 
     941                    (1.0f - luminance(color) * transparency) * 255.0f); 
     942            } 
     943        } 
     944    } 
     945    else 
     946    { 
     947        bool texHasAlpha = false; 
     948        switch (srcImg->getPixelFormat()) 
     949        { 
     950        case GL_ALPHA: 
     951        case GL_LUMINANCE_ALPHA: 
     952        case GL_RGBA: 
     953        case GL_BGRA: 
     954            texHasAlpha = true; 
     955        } 
     956 
     957        if (texHasAlpha) 
     958        { 
     959            for (int i = 0; i < t; ++i) 
     960            { 
     961                for (int j = 0; j < s; ++j) 
     962                { 
     963                    osg::Vec4 color(srcImg->getColor(j, i)); 
     964 
     965                    pixels[i * s + j] = static_cast<unsigned char>( 
     966                        color.a() * transparency * 255.0f); 
     967                } 
     968            } 
     969        } 
     970        else 
     971        { 
     972            for (int i = 0; i < t; ++i) 
     973            { 
     974                for (int j = 0; j < s; ++j) 
     975                { 
     976                    osg::Vec4 color(srcImg->getColor(j, i)); 
     977 
     978                    pixels[i * s + j] = static_cast<unsigned char>( 
     979                        luminance(color) * transparency * 255.0f); 
     980                } 
     981            } 
     982        } 
     983    } 
     984 
     985    osg::Image* transparentImage = new osg::Image; 
     986    transparentImage->setWriteHint(osg::Image::STORE_INLINE); 
     987    transparentImage->setImage(s, t, 1, GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, pixels, osg::Image::USE_NEW_DELETE); 
     988 
     989    return transparentImage; 
     990} 
     991 
     992osg::Texture2D* daeReader::processTexture( 
     993    domCommon_color_or_texture_type_complexType::domTexture *tex, 
     994    const osg::StateSet* ss, TextureUnitUsage tuu, 
     995    domFx_opaque_enum opaque, float transparency) 
     996{ 
     997    TextureParameters parameters; 
     998    parameters.transparent = tuu == TRANSPARENCY_MAP_UNIT; 
     999    parameters.opaque = opaque; 
     1000    parameters.transparency = transparency; 
     1001 
    8571002    //find the newparam for the sampler based on the texture attribute 
    8581003    domFx_sampler2D_common *sampler = NULL; 
     
    8631008    osg::notify(osg::NOTICE)<<"processTexture("<<target<<")"<<std::endl; 
    8641009     
    865     daeSIDResolver res1( currentEffect, target.c_str() ); 
     1010    daeSIDResolver res1( _currentEffect, target.c_str() ); 
    8661011    daeElement *el = res1.getElement(); 
    8671012 
    868     if ( el == NULL ) 
    869     { 
    870         osg::notify( osg::WARN ) << "Could not locate newparam for texture sampler2D" << tex->getTexture() << std::endl; 
    871         osg::notify( osg::WARN ) << "Checking if data does incorrect linking straight to the image" << std::endl; 
    872         dae->getDatabase()->getElement( (daeElement**)&dImg, 0, tex->getTexture(), "image" ); 
    873         if ( dImg != NULL ) 
     1013    if (el == NULL ) 
     1014    { 
     1015        osg::notify( osg::WARN ) << "Could not locate newparam for texture sampler2D \"" << tex->getTexture() << 
     1016            "\". Checking if data does incorrect linking straight to the image" << std::endl; 
     1017        _dae->getDatabase()->getElement( (daeElement**)&dImg, 0, tex->getTexture(), "image" ); 
     1018        if (dImg != NULL ) 
    8741019        { 
    8751020            osg::notify( osg::WARN ) << "Direct image link found. Data is incorrect but will continue to load texture" << std::endl; 
     
    8811026        domFx_newparam_common *npc = daeSafeCast< domFx_newparam_common >( el ); 
    8821027 
    883         if ( cnp != NULL ) 
     1028        if (cnp != NULL ) 
    8841029        { 
    8851030            sampler = cnp->getSampler2D(); 
    8861031        } 
    887         else if ( npc != NULL ) 
     1032        else if (npc != NULL ) 
    8881033        { 
    8891034            sampler = npc->getFx_basic_type_common()->getSampler2D(); 
    8901035        } 
    8911036 
    892         if ( sampler == NULL ) 
     1037        if (sampler == NULL ) 
    8931038        { 
    8941039            osg::notify( osg::WARN ) << "Wrong newparam type. Expected sampler2D" << std::endl; 
     
    8981043        //find the newparam for the surface based on the sampler2D->source value 
    8991044        target = std::string("./") + std::string( sampler->getSource()->getValue() ); 
    900         daeSIDResolver res2( currentEffect, target.c_str() ); 
     1045        daeSIDResolver res2( _currentEffect, target.c_str() ); 
    9011046        el = res2.getElement(); 
    902         if ( el == NULL ) 
     1047        if (el == NULL ) 
    9031048        { 
    9041049            osg::notify( osg::WARN ) << "Could not locate newparam for source " << sampler->getSource()->getValue() << std::endl; 
     
    9081053        npc = daeSafeCast< domFx_newparam_common >( el ); 
    9091054 
    910         if ( cnp != NULL ) 
     1055        if (cnp != NULL ) 
    9111056        { 
    9121057            surface = cnp->getSurface(); 
    9131058        } 
    914         else if ( npc != NULL ) 
     1059        else if (npc != NULL ) 
    9151060        { 
    9161061            surface = npc->getFx_basic_type_common()->getSurface(); 
    9171062        } 
    9181063 
    919         if ( surface == NULL ) 
     1064        if (surface == NULL ) 
    9201065        { 
    9211066            osg::notify( osg::WARN ) << "Wrong newparam type. Expected surface" << std::endl; 
     
    9271072        dImg = daeSafeCast< domImage >( getElementFromIDRef( ref ) ); 
    9281073    } 
    929     if ( dImg == NULL ) 
    930     { 
    931         osg::notify( osg::WARN ) << "Could not locate image for texture" << std::endl; 
     1074 
     1075    parameters.filename = processImagePath(dImg); 
     1076    if (parameters.filename.empty()) 
     1077    { 
    9321078        return NULL; 
    9331079    } 
    934     //Got a sampler and a surface and an imaged. Time to create the texture stuff for osg 
    935     osg::ref_ptr<osg::Image> img = NULL; 
    936     if ( dImg->getInit_from() != NULL ) 
    937     { 
    938         // daeURI uri = dImg->getInit_from()->getValue(); 
    939         dImg->getInit_from()->getValue().validate(); 
    940         if ( std::string( dImg->getInit_from()->getValue().getProtocol() ) == std::string( "file" ) ) 
    941         { 
    942             //unsigned int bufSize = 1; //for the null char 
    943             //bufSize += dImg->getInit_from()->getValue().pathDir().size(); 
    944             //bufSize += dImg->getInit_from()->getValue().pathFile().size(); 
    945            std::string path =  dImg->getInit_from()->getValue().pathDir()+ 
    946                                   dImg->getInit_from()->getValue().pathFile(); 
    947               // remove space encodings 
    948               // 
    949               path = cdom::uriToNativePath(path); 
    950            if(path.empty()) 
    951            { 
    952               osg::notify( osg::WARN ) << "Unable to get path from URI." << std::endl; 
    953               return NULL; 
    954            } 
    955 #ifdef WIN32 
    956             // If the path has a drive specifier or a UNC name then strip the leading / 
    957             const char* filename =path.c_str(); 
    958             if ((path[2] == ':') || ((path[1] == '/') && (path[2] == '/'))) 
    959                ++filename;// = path+1; 
    960 //            else 
    961 //                filename = path; 
    962 #else 
    963             const char* filename = path.c_str(); 
    964 #endif 
    965             img = osgDB::readRefImageFile( filename ); 
    966  
    967             osg::notify(osg::INFO)<<"  processTexture(..) - readImage("<<filename<<")"<<std::endl; 
    968              
    969             //Moved this below the osg::notify - Parag, 24/7/2007 
    970             //delete [] path; 
    971  
    972              
    973         } 
    974         else 
    975         { 
    976             osg::notify( osg::WARN ) << "Only images with a \"file\" scheme URI are supported in this version." << std::endl; 
     1080 
     1081    //set texture parameters 
     1082    if (sampler) 
     1083    { 
     1084        if (sampler->getWrap_s()) 
     1085        { 
     1086            parameters.wrap_s = getWrapMode(sampler->getWrap_s()->getValue()); 
     1087        } 
     1088        if (sampler->getWrap_t()) 
     1089        { 
     1090            parameters.wrap_t = getWrapMode(sampler->getWrap_s()->getValue()); 
     1091        } 
     1092 
     1093        if (sampler->getMinfilter()) 
     1094        { 
     1095            parameters.filter_min = getFilterMode(sampler->getMinfilter()->getValue(), true); 
     1096        } 
     1097        if (sampler->getMagfilter()) 
     1098        { 
     1099            parameters.filter_min = getFilterMode(sampler->getMagfilter()->getValue(), false); 
     1100        } 
     1101 
     1102        if (sampler->getBorder_color() != NULL ) 
     1103        { 
     1104            const domFloat4& col = sampler->getBorder_color()->getValue(); 
     1105            parameters.border.set(col[0], col[1], col[2], col[3]); 
     1106        } 
     1107    } 
     1108 
     1109    osg::Texture2D* t2D = NULL; 
     1110    TextureParametersMap::const_iterator mapIt = _textureParamMap.find(parameters); 
     1111    if (mapIt != _textureParamMap.end()) 
     1112    { 
     1113        t2D = mapIt->second.get(); 
     1114    } 
     1115    else 
     1116    { 
     1117        osg::ref_ptr<osg::Image> img = osgDB::readRefImageFile(parameters.filename); 
     1118 
     1119        if (!img.valid()) 
     1120        { 
     1121            _textureParamMap[parameters] = NULL; 
    9771122            return NULL; 
    9781123        } 
    979     } 
    980     else 
    981     { 
    982         osg::notify( osg::WARN ) << "Embedded image data is not supported in this version." << std::endl; 
    983             return NULL; 
    984     } 
    985  
    986     osg::Texture2D *t2D = new osg::Texture2D( img.get() ); 
    987     //set texture parameters 
    988     if ( sampler != NULL ) 
    989     { 
    990         if ( sampler->getWrap_s() != NULL ) 
    991         { 
    992             osg::Texture::WrapMode wrap; 
    993             switch( sampler->getWrap_s()->getValue() ) 
    994             { 
    995             case FX_SAMPLER_WRAP_COMMON_WRAP: 
    996                 wrap = osg::Texture::REPEAT; 
    997                 break; 
    998             case FX_SAMPLER_WRAP_COMMON_MIRROR: 
    999                 wrap = osg::Texture::MIRROR; 
    1000                 break; 
    1001             case FX_SAMPLER_WRAP_COMMON_CLAMP: 
    1002                 wrap = osg::Texture::CLAMP_TO_EDGE; 
    1003                 break; 
    1004             case FX_SAMPLER_WRAP_COMMON_NONE: 
    1005             case FX_SAMPLER_WRAP_COMMON_BORDER: 
    1006                 wrap = osg::Texture::CLAMP_TO_BORDER; 
    1007                 break; 
    1008             default: 
    1009                 wrap = osg::Texture::CLAMP; 
    1010                 break; 
    1011             } 
    1012             t2D->setWrap( osg::Texture::WRAP_S, wrap ); 
    1013         } 
    1014         else 
    1015         { 
    1016             t2D->setWrap( osg::Texture::WRAP_S, osg::Texture::REPEAT ); 
    1017         } 
    1018         if ( sampler->getWrap_t() != NULL ) 
    1019         { 
    1020             osg::Texture::WrapMode wrap; 
    1021             switch( sampler->getWrap_t()->getValue() ) 
    1022             { 
    1023             case FX_SAMPLER_WRAP_COMMON_WRAP: 
    1024                 wrap = osg::Texture::REPEAT; 
    1025                 break; 
    1026             case FX_SAMPLER_WRAP_COMMON_MIRROR: 
    1027                 wrap = osg::Texture::MIRROR; 
    1028                 break; 
    1029             case FX_SAMPLER_WRAP_COMMON_CLAMP: 
    1030                 wrap = osg::Texture::CLAMP_TO_EDGE; 
    1031                 break; 
    1032             case FX_SAMPLER_WRAP_COMMON_NONE: 
    1033             case FX_SAMPLER_WRAP_COMMON_BORDER: 
    1034                 wrap = osg::Texture::CLAMP_TO_BORDER; 
    1035                 break; 
    1036             default: 
    1037                 wrap = osg::Texture::CLAMP; 
    1038                 break; 
    1039             } 
    1040             t2D->setWrap( osg::Texture::WRAP_T, wrap ); 
    1041         } 
    1042         else 
    1043         { 
    1044             t2D->setWrap( osg::Texture::WRAP_T, osg::Texture::REPEAT ); 
    1045         } 
    1046         if ( sampler->getMinfilter() != NULL ) 
    1047         { 
    1048             osg::Texture::FilterMode mode; 
    1049             switch( sampler->getMinfilter()->getValue() ) 
    1050             { 
    1051             case FX_SAMPLER_FILTER_COMMON_NEAREST: 
    1052                 mode = osg::Texture::NEAREST; 
    1053                 break; 
    1054             case FX_SAMPLER_FILTER_COMMON_LINEAR: 
    1055                 mode = osg::Texture::LINEAR; 
    1056                 break; 
    1057             case FX_SAMPLER_FILTER_COMMON_NEAREST_MIPMAP_NEAREST: 
    1058                 mode = osg::Texture::NEAREST_MIPMAP_NEAREST; 
    1059                 break; 
    1060             case FX_SAMPLER_FILTER_COMMON_LINEAR_MIPMAP_NEAREST: 
    1061                 mode = osg::Texture::LINEAR_MIPMAP_NEAREST; 
    1062                 break; 
    1063             case FX_SAMPLER_FILTER_COMMON_NONE: 
    1064             case FX_SAMPLER_FILTER_COMMON_NEAREST_MIPMAP_LINEAR: 
    1065                 mode = osg::Texture::NEAREST_MIPMAP_LINEAR; 
    1066                 break; 
    1067             case FX_SAMPLER_FILTER_COMMON_LINEAR_MIPMAP_LINEAR: 
    1068                 mode = osg::Texture::LINEAR_MIPMAP_LINEAR; 
    1069                 break; 
    1070             default: 
    1071                 mode = osg::Texture::LINEAR; 
    1072                 break; 
    1073             } 
    1074             t2D->setFilter( osg::Texture::MIN_FILTER, mode ); 
    1075         } 
    1076         else 
    1077         { 
    1078             t2D->setFilter( osg::Texture::MIN_FILTER, osg::Texture::NEAREST_MIPMAP_LINEAR ); 
    1079         } 
    1080         if ( sampler->getMagfilter() != NULL ) 
    1081         { 
    1082             osg::Texture::FilterMode mode; 
    1083             switch( sampler->getMagfilter()->getValue() ) 
    1084             { 
    1085             case FX_SAMPLER_FILTER_COMMON_NEAREST: 
    1086                 mode = osg::Texture::NEAREST; 
    1087                 break; 
    1088             case FX_SAMPLER_FILTER_COMMON_NONE: 
    1089             case FX_SAMPLER_FILTER_COMMON_LINEAR: 
    1090                 mode = osg::Texture::LINEAR; 
    1091                 break; 
    1092             case FX_SAMPLER_FILTER_COMMON_NEAREST_MIPMAP_NEAREST: 
    1093                 mode = osg::Texture::NEAREST_MIPMAP_NEAREST; 
    1094                 break; 
    1095             case FX_SAMPLER_FILTER_COMMON_LINEAR_MIPMAP_NEAREST: 
    1096                 mode = osg::Texture::LINEAR_MIPMAP_NEAREST; 
    1097                 break; 
    1098             case FX_SAMPLER_FILTER_COMMON_NEAREST_MIPMAP_LINEAR: 
    1099                 mode = osg::Texture::NEAREST_MIPMAP_LINEAR; 
    1100                 break; 
    1101             case FX_SAMPLER_FILTER_COMMON_LINEAR_MIPMAP_LINEAR: 
    1102                 mode = osg::Texture::LINEAR_MIPMAP_LINEAR; 
    1103                 break; 
    1104             default: 
    1105                 mode = osg::Texture::LINEAR; 
    1106                 break; 
    1107             } 
    1108             t2D->setFilter( osg::Texture::MAG_FILTER, mode ); 
    1109         } 
    1110         else 
    1111         { 
    1112             t2D->setFilter( osg::Texture::MAG_FILTER, osg::Texture::LINEAR ); 
    1113         } 
    1114         if ( sampler->getBorder_color() != NULL ) 
    1115         { 
    1116             const domFloat4 &col = sampler->getBorder_color()->getValue(); 
    1117             t2D->setBorderColor( osg::Vec4( col[0], col[1], col[2], col[3] ) ); 
    1118         } 
    1119     } 
    1120     else  
    1121     { 
    1122         t2D->setWrap( osg::Texture::WRAP_S, osg::Texture::REPEAT ); 
    1123         t2D->setWrap( osg::Texture::WRAP_T, osg::Texture::REPEAT ); 
    1124         t2D->setFilter( osg::Texture::MIN_FILTER, osg::Texture::NEAREST_MIPMAP_LINEAR ); 
    1125         t2D->setFilter( osg::Texture::MAG_FILTER, osg::Texture::LINEAR ); 
    1126     } 
    1127  
    1128     // Store the texcoord name in the texture object 
    1129     t2D->setName(tex->getTexcoord()); 
     1124 
     1125        osg::notify(osg::INFO)<<"  processTexture(..) - readImage("<<parameters.filename<<")"<<std::endl; 
     1126 
     1127        if (tuu == TRANSPARENCY_MAP_UNIT) 
     1128        { 
     1129            img = processImageTransparency(img.get(), opaque, transparency); 
     1130        } 
     1131 
     1132        t2D = new osg::Texture2D(img.get()); 
     1133 
     1134        t2D->setWrap( osg::Texture::WRAP_S, parameters.wrap_s); 
     1135        t2D->setWrap( osg::Texture::WRAP_T, parameters.wrap_t); 
     1136        t2D->setFilter( osg::Texture::MIN_FILTER, parameters.filter_min); 
     1137        t2D->setFilter( osg::Texture::MAG_FILTER, parameters.filter_mag); 
     1138        t2D->setBorderColor(parameters.border); 
     1139 
     1140        _textureParamMap[parameters] = t2D; 
     1141    } 
     1142 
     1143    _texCoordSetMap[TextureToCoordSetMap::key_type(ss, tuu)] = tex->getTexcoord(); 
     1144 
    11301145    return t2D; 
    11311146} 
     
    11601175                                            xsNCName diffuseTextureName  ) 
    11611176{ 
     1177    if (ss == NULL) 
     1178        return; 
     1179 
    11621180    if (NULL == ctt && NULL == pTransparency) 
    11631181        return; 
    11641182 
    1165     if (ctt && ctt->getTexture() != NULL) 
    1166     { 
    1167         if (!diffuseTextureName || (strcmp( ctt->getTexture()->getTexture(), diffuseTextureName))) 
    1168         { 
    1169             osg::notify( osg::WARN ) << "Currently no support for different textures in diffuse and transparent channels." << std::endl; 
    1170             return; 
    1171         } 
    1172     } 
    1173      
    1174     // Fix up defaults according to 1.4.1 release notes 
    1175     domFloat4 f4; 
    1176     domFx_opaque_enum Opaque = FX_OPAQUE_ENUM_A_ONE; 
    1177     if (NULL == ctt) 
    1178     { 
    1179         f4.append(0.0f); 
    1180         f4.append(0.0f); 
    1181         f4.append(0.0f); 
    1182         f4.append(1.0f); 
     1183    float transparency = 1.0f; 
     1184    if (pTransparency) 
     1185    { 
     1186        if (pTransparency->getFloat()) 
     1187        { 
     1188            transparency = pTransparency->getFloat()->getValue(); 
     1189        } 
     1190        else if (pTransparency->getParam()) 
     1191        { 
     1192            domFloat transparencyParam; 
     1193            if (GetFloatParam(pTransparency->getParam()->getRef(), transparencyParam)) 
     1194            { 
     1195                transparency = transparencyParam; 
     1196            } 
     1197        } 
     1198 
     1199        if (_invertTransparency) 
     1200        { 
     1201            transparency = 1.0f - transparency; 
     1202        } 
     1203    } 
     1204 
     1205    osg::Texture2D* pTransparentTexture = NULL; 
     1206    osg::Vec4 transparentColor(transparency, transparency, transparency, transparency); 
     1207 
     1208    // Fix up defaults according to "Determining Transparency" chapter of 1.4.1 spec 
     1209    domFx_opaque_enum opaque = FX_OPAQUE_ENUM_A_ONE; 
     1210    if (ctt) 
     1211    { 
     1212        opaque = ctt->getOpaque(); 
     1213        if (ctt->getColor()) 
     1214        { 
     1215            const domFx_color_common& domColorValue = ctt->getColor()->getValue(); 
     1216            transparentColor.set( 
     1217                domColorValue.get(0), 
     1218                domColorValue.get(1), 
     1219                domColorValue.get(2), 
     1220                domColorValue.get(3)); 
     1221 
     1222            if (opaque == FX_OPAQUE_ENUM_RGB_ZERO) 
     1223            { 
     1224                transparentColor.set( 
     1225                    1.0f - transparentColor.r() * transparency, 
     1226                    1.0f - transparentColor.g() * transparency, 
     1227                    1.0f - transparentColor.b() * transparency, 
     1228                    1.0f - luminance(transparentColor) * transparency); 
     1229            } 
     1230            else 
     1231            { 
     1232                float a = transparentColor.a() * transparency; 
     1233                transparentColor.set(a, a, a, a); 
     1234            } 
     1235        } 
     1236        else if (ctt->getTexture()) 
     1237        { 
     1238            pTransparentTexture = processTexture(ctt->getTexture(), ss, TRANSPARENCY_MAP_UNIT, opaque, transparency); 
     1239        } 
     1240    } 
     1241 
     1242    if (pTransparentTexture) 
     1243    { 
     1244        ss->setTextureAttributeAndModes(TRANSPARENCY_MAP_UNIT, pTransparentTexture); 
     1245        ss->setAttributeAndModes(new osg::BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); 
    11831246    } 
    11841247    else 
    11851248    { 
    1186         Opaque = ctt->getOpaque(); 
    1187         if (NULL != ctt->getColor()) 
    1188         { 
    1189             f4 = ctt->getColor()->getValue(); 
    1190         } 
    1191         else if ((NULL == ctt->getParam()) || !GetFloat4Param(ctt->getParam()->getRef(), f4)) 
    1192         { 
    1193             f4.append(0.0f); 
    1194             f4.append(0.0f); 
    1195             f4.append(0.0f); 
    1196             f4.append(1.0f); 
    1197         } 
    1198     } 
    1199  
    1200     domFloat Transparency = 1.0f; 
    1201     if (NULL != pTransparency) 
    1202     { 
    1203         if (NULL != pTransparency->getFloat()) 
    1204         { 
    1205             Transparency = pTransparency->getFloat()->getValue(); 
    1206             if (m_AuthoringTool == GOOGLE_SKETCHUP) // Google back to front support 
    1207                 Transparency = 1.0f - Transparency; 
    1208         } 
    1209         else if (NULL != pTransparency->getParam()) 
    1210         { 
    1211             if (GetFloatParam(pTransparency->getParam()->getRef(), Transparency)) 
    1212             { 
    1213                 if (m_AuthoringTool == GOOGLE_SKETCHUP) // Google back to front support 
    1214                     Transparency = 1.0f - Transparency; 
    1215             } 
    1216             else 
    1217                 Transparency = 1.0f; 
    1218         } 
    1219     } 
    1220  
    1221     if (NULL != ctt || NULL != pTransparency) 
    1222     { 
    1223         int SourceBlendFactor; 
    1224         int DestBlendFactor; 
    1225         bool SwitchOnTheBlender = false; 
    1226         if (m_StrictTransparency) 
    1227         { 
    1228             // Process transparent and transparency settings accroding to a strict interpretation of the spec 
    1229             // See https://collada.org/public_forum/viewtopic.php?f=12&t=1210 
    1230             SwitchOnTheBlender = true; 
    1231             switch(Opaque) 
    1232             { 
    1233     /* 
    1234                 case FX_OPAQUE_ENUM_RGB_ONE: 
    1235                     if (ctt->getTexture() != NULL) 
    1236                     { 
    1237                         SourceBlendFactor = GL_SRC_COLOR; 
    1238                         DestBlendFactor = GL_ONE_MINUS_SRC_COLOR; 
    1239                     } 
    1240                     else 
    1241                     { 
    1242                         SourceBlendFactor = GL_CONSTANT_COLOR; 
    1243                         DestBlendFactor = GL_ONE_MINUS_CONSTANT_COLOR; 
    1244                     } 
    1245                     break; 
    1246                 case FX_OPAQUE_ALPHA_ZERO: 
    1247                     if (ctt->getTexture() != NULL) 
    1248                     { 
    1249                         SourceBlendFactor = GL_ONE_MINUS_SRC_ALPHA; 
    1250                         DestBlendFactor = GL_SRC_ALPHA; 
    1251                     } 
    1252                     else 
    1253                     { 
    1254                         SourceBlendFactor = GL_ONE_MINUS_CONSTANT_ALPHA; 
    1255                         DestBlendFactor = GL_CONSTANT_ALPHA; 
    1256                     } 
    1257                     break; 
    1258     */ 
    1259                 case FX_OPAQUE_ENUM_RGB_ZERO: 
    1260                     if (ctt->getTexture() != NULL) 
    1261                     { 
    1262                         SourceBlendFactor = GL_ONE_MINUS_SRC_COLOR; 
    1263                         DestBlendFactor = GL_SRC_COLOR; 
    1264                     } 
    1265                     else 
    1266                     { 
    1267                         SourceBlendFactor = GL_ONE_MINUS_CONSTANT_COLOR; 
    1268                         DestBlendFactor = GL_CONSTANT_COLOR; 
    1269                     } 
    1270                     break; 
    1271                 default: 
    1272                     if (ctt->getTexture() != NULL) 
    1273                     { 
    1274                         SourceBlendFactor = GL_SRC_ALPHA; 
    1275                         DestBlendFactor = GL_ONE_MINUS_SRC_ALPHA; 
    1276                     } 
    1277                     else 
    1278                     { 
    1279                         SourceBlendFactor = GL_CONSTANT_ALPHA; 
    1280                         DestBlendFactor = GL_ONE_MINUS_CONSTANT_ALPHA; 
    1281                     } 
    1282                     break; 
    1283             } 
     1249        bool strictTransparency = _strictTransparency; 
     1250        if (!strictTransparency) 
     1251        { 
     1252            const osg::Texture* pMainTexture = dynamic_cast<osg::Texture*>( 
     1253                ss->getTextureAttribute(MAIN_TEXTURE_UNIT, osg::StateAttribute::TEXTURE)); 
     1254            bool haveTranslucentTexture = pMainTexture && 
     1255                pMainTexture->getImage(0) && pMainTexture->getImage(0)->isImageTranslucent(); 
     1256            strictTransparency = !haveTranslucentTexture; 
     1257        } 
     1258 
     1259        if (strictTransparency) 
     1260        { 
     1261            if (transparentColor == osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f)) 
     1262            { 
     1263                return; 
     1264            } 
     1265 
     1266            ss->setAttributeAndModes(new osg::BlendColor(transparentColor)); 
     1267            ss->setAttributeAndModes(new osg::BlendFunc(GL_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR)); 
    12841268        } 
    12851269        else 
    12861270        { 
    1287             // Jump through various hoops to accomodate the multiplicity of different ways 
    1288             // that various people have interpreted the specification 
    1289             // I assume that the presence of either a <tansparent> or a <transparency> element 
    1290             // means that the user may want some kind of alpha blending 
    1291             bool HaveDiffuseTexture = false; 
    1292             bool HaveTranslucentDiffuseTexture = false; 
    1293             // Unfortunately isImageTransparent only works for  A_ONE_OPAQUE 
    1294             if ((NULL != ss) && 
    1295                     (HaveDiffuseTexture = (GL_TRUE == ss->getTextureMode(MAIN_TEXTURE_UNIT, GL_TEXTURE_2D))) && 
    1296                     (NULL != dynamic_cast<osg::Texture2D*>(ss->getTextureAttribute(MAIN_TEXTURE_UNIT, osg::StateAttribute::TEXTURE))) && 
    1297                     (NULL != dynamic_cast<osg::Texture2D*>(ss->getTextureAttribute(MAIN_TEXTURE_UNIT, osg::StateAttribute::TEXTURE))->getImage()) && 
    1298                     (dynamic_cast<osg::Texture2D*>(ss->getTextureAttribute(MAIN_TEXTURE_UNIT, osg::StateAttribute::TEXTURE))->getImage()->isImageTranslucent())) 
    1299                 HaveTranslucentDiffuseTexture = true; 
    1300             osg::Vec4 Diffuse; 
    1301             if (material) 
    1302                 Diffuse = material->getDiffuse(osg::Material::FRONT_AND_BACK); 
    1303  
    1304             // Determine whether or not to switch on the blender and which blending factors to use. 
    1305             // I switch the blender on if the supplied (or default) <transparent> and <transparency> elements work out as non opaque, 
    1306             // or if they work out opaque and I have a translucent texture in the MAIN_TEXTURE_UNIT or a non opaque value in the diffuse colour 
    1307             switch(Opaque) 
    1308             { 
    1309     /* 
    1310                 case FX_OPAQUE_ENUM_RGB_ONE: 
    1311                     if ((Transparency  * f4[0] > 0.99f) && 
    1312                         (Transparency  * f4[1] > 0.99f) && 
    1313                         (Transparency  * f4[2] > 0.99f)) 
    1314                     { 
    1315                         SourceBlendFactor = GL_SRC_COLOR; 
    1316                         DestBlendFactor = GL_ONE_MINUS_SRC_COLOR; 
    1317                         // It would be nice to check for a translucent texture here as well 
    1318                         if (!HaveDiffuseTexture && (Diffuse.r() < 0.99f) && (Diffuse.g() < 0.99f) && (Diffuse.b() < 0.99f)) 
    1319                             SwitchOnTheBlender = true; 
    1320                     } 
    1321                     else 
    1322                     { 
    1323                         SourceBlendFactor = GL_CONSTANT_COLOR; 
    1324                         DestBlendFactor = GL_ONE_MINUS_CONSTANT_COLOR; 
    1325                         SwitchOnTheBlender = true; 
    1326                     } 
    1327                     break; 
    1328                 case FX_OPAQUE_ALPHA_ZERO: 
    1329                     if (Transparency  * f4[3] < 0.01f) 
    1330                     { 
    1331                         SourceBlendFactor = GL_ONE_MINUS_SRC_ALPHA; 
    1332                         DestBlendFactor = GL_SRC_ALPHA; 
    1333                         // It would be nice to check for a translucent texture here as well 
    1334                         if (Diffuse.a() > 0.01f) 
    1335                             SwitchOnTheBlender = true; 
    1336                     } 
    1337                     else 
    1338                     { 
    1339                         SourceBlendFactor = GL_ONE_MINUS_CONSTANT_ALPHA; 
    1340                         DestBlendFactor = GL_CONSTANT_ALPHA; 
    1341                         SwitchOnTheBlender = true; 
    1342                     } 
    1343                     break; 
    1344     */ 
    1345                 case FX_OPAQUE_ENUM_RGB_ZERO: 
    1346                     if ((Transparency  * f4[0] < 0.01f) && 
    1347                         (Transparency  * f4[1] < 0.01f) && 
    1348                         (Transparency  * f4[2] < 0.01f)) 
    1349                     { 
    1350                         SourceBlendFactor = GL_ONE_MINUS_SRC_COLOR; 
    1351                         DestBlendFactor = GL_SRC_COLOR; 
    1352                         // It would be nice to check for a translucent texture here as well 
    1353     //                    if (!HaveDiffuseTexture && (Diffuse.r() > 0.01f) && (Diffuse.g() > 0.01f) && (Diffuse.b() > 0.01f)) 
    1354     //                        SwitchOnTheBlender = true; 
    1355                     } 
    1356                     else 
    1357                     { 
    1358                         SourceBlendFactor = GL_ONE_MINUS_CONSTANT_COLOR; 
    1359                         DestBlendFactor = GL_CONSTANT_COLOR; 
    1360                         SwitchOnTheBlender = true; 
    1361                     } 
    1362                     break; 
    1363                 default: 
    1364                     if (Transparency  * f4[3] > 0.99f) 
    1365                     { 
    1366                         SourceBlendFactor = GL_SRC_ALPHA; 
    1367                         DestBlendFactor = GL_ONE_MINUS_SRC_ALPHA; 
    1368                         if (HaveTranslucentDiffuseTexture || (Diffuse.a() < 0.99f)) 
    1369                             SwitchOnTheBlender = true; 
    1370                     } 
    1371                     else 
    1372                     { 
    1373                         SourceBlendFactor = GL_CONSTANT_ALPHA; 
    1374                         DestBlendFactor = GL_ONE_MINUS_CONSTANT_ALPHA; 
    1375                         SwitchOnTheBlender = true; 
    1376                     } 
    1377                     break; 
    1378             } 
    1379         } 
    1380         if (SwitchOnTheBlender) 
    1381         { 
    1382             if ((SourceBlendFactor == GL_CONSTANT_COLOR) || 
    1383                 (SourceBlendFactor == GL_ONE_MINUS_CONSTANT_COLOR) || 
    1384                 (SourceBlendFactor == GL_CONSTANT_ALPHA) || 
    1385                 (SourceBlendFactor == GL_ONE_MINUS_CONSTANT_ALPHA)) 
    1386             { 
    1387                 osg::BlendColor *bc = new osg::BlendColor(); 
    1388                 bc->setConstantColor(osg::Vec4( f4[0] * Transparency, f4[1] * Transparency, f4[2] * Transparency, f4[3] * Transparency )); 
    1389                 ss->setAttribute( bc ); 
    1390             } 
    1391             osg::BlendFunc *bf = new osg::BlendFunc(SourceBlendFactor, DestBlendFactor); 
    1392             ss->setAttribute( bf ); 
    1393             ss->setMode( GL_BLEND, osg::StateAttribute::ON ); 
    1394  
    1395             ss->setRenderingHint( osg::StateSet::TRANSPARENT_BIN ); 
    1396         } 
    1397     } 
    1398 } 
     1271            ss->setAttributeAndModes(new osg::BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); 
     1272        } 
     1273    } 
     1274 
     1275    ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); 
     1276} 
     1277 
     1278void daeReader::copyTextureCoordinateSet(const osg::StateSet* ss, const osg::Geometry* cachedGeometry, osg::Geometry* clonedGeometry, const domInstance_material* im, TextureUnitUsage tuu) 
     1279{ 
     1280    if (!ss->getTextureAttribute(tuu, osg::StateAttribute::TEXTURE)) 
     1281        return; 
     1282 
     1283    const std::string& texCoordSetName = _texCoordSetMap 
     1284        [TextureToCoordSetMap::key_type(ss, tuu)]; 
     1285    if (!texCoordSetName.empty()) 
     1286    { 
     1287        const domInstance_material::domBind_vertex_input_Array &bvia = im->getBind_vertex_input_array(); 
     1288        size_t k; 
     1289        for (k = 0; k < bvia.getCount(); k++) 
     1290        { 
     1291            if (!strcmp(bvia[k]->getSemantic(), texCoordSetName.c_str()) && !strcmp(bvia[k]->getInput_semantic(), COMMON_PROFILE_INPUT_TEXCOORD)) 
     1292            { 
     1293                unsigned set = bvia[k]->getInput_set(); 
     1294                if (set < cachedGeometry->getNumTexCoordArrays()) 
     1295                { 
     1296                    clonedGeometry->setTexCoordData(tuu, cachedGeometry->getTexCoordData(set)); 
     1297                } 
     1298                else 
     1299                { 
     1300                    osg::notify(osg::WARN) << "Texture coordinate set " << set << " not found." << std::endl; 
     1301                } 
     1302                break; 
     1303            } 
     1304        } 
     1305        if (k == bvia.getCount()) 
     1306        { 
     1307            osg::notify( osg::WARN ) << "Failed to find matching <bind_vertex_input> for " << texCoordSetName << std::endl; 
     1308            if (cachedGeometry->getNumTexCoordArrays()) 
     1309            { 
     1310                clonedGeometry->setTexCoordData(tuu, cachedGeometry->getTexCoordData(0)); 
     1311            } 
     1312        } 
     1313    } 
     1314} 
  • OpenSceneGraph/trunk/src/osgPlugins/dae/daeRSceneObjects.cpp

    r10234 r11129  
    2828#include <osg/LightModel> 
    2929 
    30 using namespace osgdae; 
    31  
    32 osg::Node* daeReader::processOsgMultiSwitch(domTechnique* teq) 
     30using namespace osgDAE; 
     31 
     32osg::Group* daeReader::processOsgMultiSwitch(domTechnique* teq) 
    3333{ 
    3434    osgSim::MultiSwitch* msw = new osgSim::MultiSwitch; 
     
    8787} 
    8888 
    89 osg::Node* daeReader::processOsgSwitch(domTechnique* teq) 
     89osg::Group* daeReader::processOsgSwitch(domTechnique* teq) 
    9090{ 
    9191    osg::Switch* sw = new osg::Switch; 
     
    113113} 
    114114 
    115 osg::Node* daeReader::processOsgSequence(domTechnique* teq) 
     115osg::Group* daeReader::processOsgSequence(domTechnique* teq) 
    116116{ 
    117117    osg::Sequence* sq = new osg::Sequence; 
     
    220220 
    221221 
    222 osg::Node* daeReader::processOsgLOD(domTechnique* teq) 
     222osg::Group* daeReader::processOsgLOD(domTechnique* teq) 
    223223{ 
    224224    osg::LOD* lod = new osg::LOD; 
     
    324324osg::Node* daeReader::processLight( domLight *dlight ) 
    325325{ 
    326     if (m_numlights >= 7) 
     326    if (_numlights >= 7) 
    327327    { 
    328328        osg::notify( osg::WARN ) << "More than 8 lights may not be supported by OpenGL driver." << std::endl; 
     
    344344    osg::Light* light = new osg::Light(); 
    345345    light->setPosition(osg::Vec4(0,0,0,1)); 
    346     light->setLightNum(m_numlights); 
     346    light->setLightNum(_numlights); 
    347347 
    348348    // Enable OpenGL lighting 
    349349    _rootStateSet->setMode(GL_LIGHTING, osg::StateAttribute::ON); 
    350350    // Enable this OpenGL light 
    351     _rootStateSet->setMode(GL_LIGHT0 + m_numlights++, osg::StateAttribute::ON); 
     351    _rootStateSet->setMode(GL_LIGHT0 + _numlights++, osg::StateAttribute::ON); 
    352352     
    353353    // Set ambient of lightmodel to zero 
  • OpenSceneGraph/trunk/src/osgPlugins/dae/daeRTransforms.cpp

    r9228 r11129  
    22 * Copyright 2006 Sony Computer Entertainment Inc. 
    33 * 
    4  * Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this  
     4 * Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this 
    55 * file except in compliance with the License. You may obtain a copy of the License at: 
    66 * http://research.scea.com/scea_shared_source_license.html 
    77 * 
    8  * Unless required by applicable law or agreed to in writing, software distributed under the License  
    9  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or  
    10  * implied. See the License for the specific language governing permissions and limitations under the  
    11  * License.  
     8 * Unless required by applicable law or agreed to in writing, software distributed under the License 
     9 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
     10 * implied. See the License for the specific language governing permissions and limitations under the 
     11 * License. 
    1212 */ 
    1313 
     
    1717#include <dom/domCOLLADA.h> 
    1818 
     19#include <osgAnimation/UpdateMatrixTransform> 
     20#include <osgAnimation/StackedMatrixElement> 
     21#include <osgAnimation/StackedRotateAxisElement> 
     22#include <osgAnimation/StackedScaleElement> 
     23#include <osgAnimation/StackedTranslateElement> 
    1924#include <osg/MatrixTransform> 
    2025#include <osgSim/DOFTransform> 
    2126 
    22 using namespace osgdae; 
     27using namespace osgDAE; 
    2328 
    2429// Note <lookat>, <matrix>, <rotate>, <scale>, <skew> and <translate> may appear in any order 
    2530// These transformations can be combined in any number and ordering to produce the desired 
    26 // coordinate systemfor the parent <node> element. The COLLADA specificatin requires that the 
    27 // transformation elements are processed in order and accumulate the result as if they were  
     31// coordinate system for the parent <node> element. The COLLADA specificatin requires that the 
     32// transformation elements are processed in order and accumulate the result as if they were 
    2833// converted to column-order matrices and concatenated using matrix post-multiplication. 
    29 osg::Node* daeReader::processOsgMatrixTransform( domNode *node ) 
     34osg::Transform* daeReader::processOsgMatrixTransform(domNode *node, bool isBone) 
    3035{ 
    31     osg::MatrixTransform* matNode = new osg::MatrixTransform; 
    32     osg::Matrix matrix; 
     36    osg::MatrixTransform* resultNode = NULL; 
     37 
     38    if (isBone) 
     39    { 
     40        resultNode = getOrCreateBone(node); 
     41    } 
     42    else 
     43    { 
     44        resultNode = new osg::MatrixTransform; 
     45    } 
     46 
     47    osg::NodeCallback* pNodeCallback = resultNode->getUpdateCallback(); 
     48    std::vector<osg::ref_ptr<osgAnimation::StackedTransformElement> > transformElements; 
     49    osg::ref_ptr<osgAnimation::StackedTransformElement> pLastStaticTransformElement; 
    3350 
    3451    // Process all coordinate system contributing elements in order! 
    3552    size_t count = node->getContents().getCount(); 
    36     for (size_t i = 0; i < count; i++ )  
    37     { 
    38         domRotate * rot = daeSafeCast< domRotate >( node->getContents()[i] ); 
    39         if (rot) 
    40         { 
    41             domFloat4& r = rot->getValue(); 
    42             if (r.getCount() != 4 )  
    43             { 
    44                 osg::notify(osg::WARN)<<"Data is wrong size for rotate"<<std::endl; 
    45                 continue; 
    46             } 
    47  
    48             // Build rotation matrix 
    49             osg::Matrix rotMat; 
    50             rotMat.makeRotate(osg::DegreesToRadians(r[3]), r[0], r[1], r[2]); 
    51  
    52             matrix = rotMat * matrix; 
    53             continue; 
    54         } 
    55  
    56         domTranslate * trans = daeSafeCast< domTranslate >( node->getContents()[i] ); 
    57         if (trans != NULL) 
    58         { 
    59             domFloat3& t = trans->getValue(); 
    60             if (t.getCount() != 3 )  
     53    for (size_t i = 0; i < count; i++ ) 
     54    { 
     55        daeElement* pDaeElement = node->getContents()[i]; 
     56        osg::ref_ptr<osgAnimation::StackedTransformElement> pTransformElement = NULL; 
     57 
     58        if (domRotate * pDomRotate = daeSafeCast< domRotate >( pDaeElement )) 
     59        { 
     60            const domFloat4& r = pDomRotate->getValue(); 
     61            if (r.getCount() != 4 ) 
     62            { 
     63                osg::notify(osg::WARN) << "Data is wrong size for rotate" << std::endl; 
     64                continue; 
     65            } 
     66 
     67            pTransformElement = new osgAnimation::StackedRotateAxisElement(pDomRotate->getSid() ? pDomRotate->getSid() : "", osg::Vec3(r[0], r[1], r[2]), osg::DegreesToRadians(r[3])); 
     68        } 
     69        else if (domTranslate * pDomTranslate = daeSafeCast< domTranslate >( pDaeElement )) 
     70        { 
     71            const domFloat3& t = pDomTranslate->getValue(); 
     72            if (t.getCount() != 3 ) 
    6173            { 
    6274                osg::notify(osg::WARN)<<"Data is wrong size for translate"<<std::endl; 
     
    6476            } 
    6577 
    66             // Build translation matrix 
    67             osg::Matrix transMat; 
    68             transMat.makeTranslate(t[0], t[1], t[2]); 
    69  
    70             matrix = transMat * matrix; 
    71             continue; 
    72         } 
    73  
    74         domScale * scale = daeSafeCast< domScale >( node->getContents()[i] ); 
    75         if (scale != NULL) 
    76         { 
    77             domFloat3& s = scale->getValue(); 
    78             if (s.getCount() != 3 )  
     78            pTransformElement = new osgAnimation::StackedTranslateElement(pDomTranslate->getSid() ?  pDomTranslate->getSid() : "", osg::Vec3(t[0], t[1], t[2])); 
     79        } 
     80        else if (domScale * pDomScale = daeSafeCast< domScale >( pDaeElement )) 
     81        { 
     82            const domFloat3& s = pDomScale->getValue(); 
     83            if (s.getCount() != 3 ) 
    7984            { 
    8085                osg::notify(osg::WARN)<<"Data is wrong size for scale"<<std::endl; 
     
    8287            } 
    8388 
    84             // Build scale matrix 
    85             osg::Matrix scaleMat; 
    86             scaleMat.makeScale(s[0], s[1], s[2]); 
    87  
    88             matrix = scaleMat * matrix; 
    89             continue; 
    90         } 
    91  
    92         domMatrix * mat = daeSafeCast< domMatrix >( node->getContents()[i] ); 
    93         if (mat != NULL) 
    94         { 
    95             if (mat->getValue().getCount() != 16 )  
     89            pTransformElement = new osgAnimation::StackedScaleElement(pDomScale->getSid() ? pDomScale->getSid() : "", osg::Vec3(s[0], s[1], s[2])); 
     90        } 
     91        else if (domMatrix * pDomMatrix = daeSafeCast< domMatrix >( pDaeElement )) 
     92        { 
     93            if (pDomMatrix->getValue().getCount() != 16 ) 
    9694            { 
    9795                osg::notify(osg::WARN)<<"Data is wrong size for matrix"<<std::endl; 
     
    9997            } 
    10098 
    101             // Build matrix 
    102             osg::Matrix mMat(    mat->getValue()[0], mat->getValue()[4], mat->getValue()[8], mat->getValue()[12], 
    103                                 mat->getValue()[1], mat->getValue()[5], mat->getValue()[9], mat->getValue()[13], 
    104                                 mat->getValue()[2], mat->getValue()[6], mat->getValue()[10], mat->getValue()[14], 
    105                                 mat->getValue()[3], mat->getValue()[7], mat->getValue()[11], mat->getValue()[15] ); 
    106  
    107             matrix = mMat * matrix; 
    108             continue; 
    109         } 
    110  
    111         domLookat * la = daeSafeCast< domLookat >( node->getContents()[i] ); 
    112         if (la != NULL) 
    113         { 
    114             if (la->getValue().getCount() != 9 )  
     99            pTransformElement = new osgAnimation::StackedMatrixElement(pDomMatrix->getSid() ? pDomMatrix->getSid() : "", 
     100                osg::Matrix(    pDomMatrix->getValue()[0], pDomMatrix->getValue()[4], pDomMatrix->getValue()[8], pDomMatrix->getValue()[12], 
     101                pDomMatrix->getValue()[1], pDomMatrix->getValue()[5], pDomMatrix->getValue()[9], pDomMatrix->getValue()[13], 
     102                pDomMatrix->getValue()[2], pDomMatrix->getValue()[6], pDomMatrix->getValue()[10], pDomMatrix->getValue()[14], 
     103                pDomMatrix->getValue()[3], pDomMatrix->getValue()[7], pDomMatrix->getValue()[11], pDomMatrix->getValue()[15])); 
     104        } 
     105        else if (domLookat * pDomLookat = daeSafeCast< domLookat >( pDaeElement )) 
     106        { 
     107            if (pDomLookat->getValue().getCount() != 9 ) 
    115108            { 
    116109                osg::notify(osg::WARN)<<"Data is wrong size for lookat"<<std::endl; 
     
    118111            } 
    119112 
    120             // Build lookat matrix 
    121             osg::Matrix lookatMat; 
    122             osg::Vec3 eye(la->getValue()[0], la->getValue()[1], la->getValue()[2]); 
    123             osg::Vec3 center(la->getValue()[3], la->getValue()[4], la->getValue()[5] ); 
    124             osg::Vec3 up( la->getValue()[6], la->getValue()[7], la->getValue()[8] ); 
    125             lookatMat.makeLookAt( eye, center, up ); 
    126              
    127             matrix = lookatMat * matrix; 
    128             continue; 
    129         } 
    130  
    131         domSkew * skew = daeSafeCast< domSkew >( node->getContents()[i] ); 
    132         if (skew != NULL) 
    133         { 
    134             if (skew->getValue().getCount() != 7 )  
     113            pTransformElement = new osgAnimation::StackedMatrixElement(pDomLookat->getSid() ? pDomLookat->getSid() : "", 
     114                osg::Matrix::lookAt( 
     115                osg::Vec3(pDomLookat->getValue()[0], pDomLookat->getValue()[1], pDomLookat->getValue()[2]), 
     116                osg::Vec3(pDomLookat->getValue()[3], pDomLookat->getValue()[4], pDomLookat->getValue()[5]), 
     117                osg::Vec3(pDomLookat->getValue()[6], pDomLookat->getValue()[7], pDomLookat->getValue()[8]))); 
     118        } 
     119        else if (domSkew * pDomSkew = daeSafeCast< domSkew >( pDaeElement )) 
     120        { 
     121            if (pDomSkew->getValue().getCount() != 7 ) 
    135122            { 
    136123                osg::notify(osg::WARN)<<"Data is wrong size for skew"<<std::endl; 
     
    138125            } 
    139126 
    140             // Skew matrix building derived from GNURealistic ShaderMan GMANMatrix4 (LGPL) matrix class 
    141  
    142             // Build skew matrix 
    143             domFloat7& s = skew->getValue(); 
     127            const domFloat7& s = pDomSkew->getValue(); 
    144128 
    145129            float shear = sin(osg::DegreesToRadians(s[0])); 
     
    149133            osg::Vec3f along(s[4],s[5],s[6]); 
    150134 
    151             along.normalize(); 
    152             osg::Vec3f a = around - (along * (around * along)); 
    153             a.normalize(); 
    154              
    155             float an1 = around * a; 
    156             float an2 = around * along; 
    157              
    158             float rx = an1 * cos(shear) - an2 * sin(shear); 
    159             float ry = an1 * sin(shear) + an2 * cos(shear); 
    160  
    161             if (rx <= 0.0)  
    162             { 
    163                 osg::notify(osg::WARN)<<"skew angle too large"<<std::endl; 
    164                 continue; 
    165             } 
    166              
    167             float alpha; 
    168             // A parallel to B?? 
    169             if (an1==0)  
    170             { 
    171                 alpha=0; 
    172             }  
    173             else  
    174             { 
    175                 alpha=ry/rx-an2/an1; 
    176             } 
    177  
    178  
    179             osg::Matrix skewMat(a.x()*along.x()*alpha+1.0,    a.x()*along.y()*alpha,        a.x()*along.z()*alpha,        0, 
    180                                 a.y()*along.x()*alpha,        a.y()*along.y()*alpha+1.0,    a.y()*along.z()*alpha,        0, 
    181                                 a.z()*along.x()*alpha,        a.z()*along.y()*alpha,        a.z()*along.z()*alpha+1.0,    0, 
    182                                 0,                            0,                            0,                            1); 
    183  
    184  
    185             matrix = skewMat * matrix; 
    186             continue; 
    187         } 
    188     } 
    189  
    190     matNode->setMatrix(matrix); 
     135            //This maths is untested so may be transposed or negated or just completely wrong. 
     136            osg::Vec3f normal = along ^ around; 
     137            normal.normalize(); 
     138            around.normalize(); 
     139            along *= shear / along.length(); 
     140 
     141            pTransformElement = new osgAnimation::StackedMatrixElement(pDomLookat->getSid() ? pDomLookat->getSid() : "", 
     142                osg::Matrix( 
     143                normal.x() * along.x() + 1.0f, normal.x() * along.y(), normal.x() * along.z(), 0.0f, 
     144                normal.y() * along.x(), normal.y() * along.y() + 1.0f, normal.y() * along.z(), 0.0f, 
     145                normal.z() * along.x(), normal.z() * along.y(), normal.z() * along.z() + 1.0f, 0.0f, 
     146                0.0f, 0.0f, 0.0f, 1.0f)); 
     147        } 
     148 
     149        if (pTransformElement) 
     150        { 
     151            daeElementDomChannelMap::iterator iter = _daeElementDomChannelMap.find(pDaeElement); 
     152            if (iter != _daeElementDomChannelMap.end()) 
     153            { 
     154                // The element is animated 
     155 
     156                // First add single or collapsed transform element if any 
     157                if (pLastStaticTransformElement) 
     158                { 
     159                    transformElements.push_back(pLastStaticTransformElement); 
     160                    pLastStaticTransformElement = NULL; 
     161                } 
     162                transformElements.push_back(pTransformElement); 
     163 
     164                // Animated element so we need an AnimationUpdateCallback 
     165                if (!pNodeCallback) 
     166                { 
     167                    std::string name = node->getId() ? node->getId() : node->getSid() ? node->getSid() : ""; 
     168                    resultNode->setDataVariance(osg::Object::DYNAMIC); 
     169 
     170                    pNodeCallback = new osgAnimation::UpdateMatrixTransform(name); 
     171                    resultNode->setUpdateCallback(pNodeCallback); 
     172                } 
     173 
     174                do 
     175                { 
     176                    _domChannelOsgAnimationUpdateCallbackMap[iter->second] = pNodeCallback; 
     177                    ++iter; 
     178                } while (iter != _daeElementDomChannelMap.end() && iter->first == pDaeElement); 
     179            } 
     180            else if (pLastStaticTransformElement) 
     181            { 
     182                // Add transform element only if not identity 
     183                if (!pTransformElement->isIdentity()) 
     184                { 
     185                    // Collapse static transform elements 
     186                    osg::Matrix matrix = pLastStaticTransformElement->getAsMatrix(); 
     187                    pTransformElement->applyToMatrix(matrix); 
     188                    pLastStaticTransformElement = new osgAnimation::StackedMatrixElement("collapsed", matrix); 
     189                } 
     190            } 
     191            else if (!pTransformElement->isIdentity()) 
     192            { 
     193                // Store single static transform element only if not identity 
     194                pLastStaticTransformElement = pTransformElement; 
     195            } 
     196        } 
     197    } 
     198 
     199    // Add final collapsed element (if any) 
     200    if (pLastStaticTransformElement) 
     201    { 
     202        transformElements.push_back(pLastStaticTransformElement); 
     203    } 
     204 
     205    // Build a matrix for the MatrixTransform and add the elements to the updateCallback 
     206    osg::Matrix matrix; 
     207 
     208    osgAnimation::UpdateMatrixTransform* pUpdateStackedTransform = 
     209        dynamic_cast<osgAnimation::UpdateMatrixTransform*>(pNodeCallback); 
     210 
     211    for (size_t i=0; i < transformElements.size(); i++) 
     212    { 
     213        transformElements[i]->applyToMatrix(matrix); 
     214        if (pUpdateStackedTransform) 
     215        { 
     216            pUpdateStackedTransform->getStackedTransforms().push_back(transformElements[i].get()); 
     217        } 
     218    } 
     219 
     220    resultNode->setMatrix(matrix); 
    191221 
    192222    osg::Vec3 scale = matrix.getScale(); 
    193223    if ((scale.x() != 1) || (scale.y() != 1) || (scale.z() != 1)) 
    194224    { 
    195         osg::StateSet* ss = matNode->getOrCreateStateSet(); 
     225        osg::StateSet* ss = resultNode->getOrCreateStateSet(); 
    196226        ss->setMode(GL_RESCALE_NORMAL, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); 
    197227    } 
    198228 
    199     return matNode; 
     229    return resultNode; 
    200230} 
    201231 
    202 osg::Node* daeReader::processOsgDOFTransform(domTechnique* teq) 
     232osg::Group* daeReader::processOsgDOFTransform(domTechnique* teq) 
    203233{ 
    204234    osgSim::DOFTransform* dof = new osgSim::DOFTransform; 
  • OpenSceneGraph/trunk/src/osgPlugins/dae/daeReader.cpp

    r10351 r11129  
    1919#include <dom/domConstants.h> 
    2020#include <osg/MatrixTransform> 
    21  
    22 using namespace osgdae; 
    23  
    24 daeReader::daeReader(DAE *dae_, bool strictTransparency) : 
    25                   m_AssetUnitName("meter"), 
    26                   m_AssetUnitMeter(1.0), 
    27                   m_AssetUp_axis(UPAXISTYPE_Y_UP), 
    28                   dae(dae_), 
    29                   rootNode(NULL), 
    30                   m_numlights(0), 
    31                   currentInstance_effect(NULL), 
    32                   currentEffect(NULL), 
    33                   m_AuthoringTool(UNKNOWN), 
    34                   m_StrictTransparency(strictTransparency) 
     21#include <osg/PositionAttitudeTransform> 
     22 
     23using namespace osgDAE; 
     24 
     25daeReader::daeReader(DAE *dae_, bool strictTransparency) :  
     26                  _dae(dae_), 
     27                  _rootNode(NULL), 
     28                  _visualScene(NULL), 
     29                  _numlights(0), 
     30                  _currentInstance_effect(NULL), 
     31                  _currentEffect(NULL), 
     32                  _authoringTool(UNKNOWN), 
     33                  _strictTransparency(strictTransparency), 
     34                  _invertTransparency(false), 
     35                  _assetUnitName("meter"), 
     36                  _assetUnitMeter(1.0), 
     37                  _assetUp_axis(UPAXISTYPE_Y_UP) 
    3538{ 
    3639} 
     
    4245bool daeReader::convert( const std::string &fileURI )  
    4346{ 
     47    // Clear caches 
     48    _geometryMap.clear(); 
     49    _materialMap.clear(); 
     50    _materialMap2.clear(); 
     51 
    4452    daeElement *colladaElement; 
    45     domInstance_rigid_body *irb; 
     53     
    4654 
    4755    daeInt count, result; 
    4856 
    49     daeInt res = dae->load( fileURI.c_str() ); 
     57    _document = _dae->open(fileURI); 
    5058     
    51     if( res != DAE_OK && res != DAE_ERR_COLLECTION_ALREADY_EXISTS)  
     59    if (!_document)  
    5260    { 
    5361        osg::notify( osg::WARN ) << "Load failed in COLLADA DOM" << std::endl; 
     
    5664    osg::notify( osg::INFO ) << "URI loaded: " << fileURI << std::endl; 
    5765 
    58     domCOLLADA* document = dae->getDom( fileURI.c_str() ); 
    59  
    60     if ( !document->getScene() || !document->getScene()->getInstance_visual_scene() )  
     66    if ( !_document->getScene() || !_document->getScene()->getInstance_visual_scene() )  
    6167    { 
    6268        osg::notify( osg::WARN ) << "No scene found!" << std::endl; 
     
    6470    } 
    6571 
    66     if (document->getAsset()) 
    67     { 
    68         const domAsset::domContributor_Array& ContributorArray = document->getAsset()->getContributor_array(); 
     72    if (_document->getAsset()) 
     73    { 
     74        const domAsset::domContributor_Array& ContributorArray = _document->getAsset()->getContributor_array(); 
    6975        size_t NumberOfContributors = ContributorArray.getCount(); 
    7076        size_t CurrentContributor; 
     
    7379            if (ContributorArray[CurrentContributor]->getAuthoring_tool()) 
    7480            { 
     81                const char szBlender[] = "Blender"; 
     82                const char szDazStudio[] = "DAZ|Studio"; 
     83                const char szSketchup[] = "Google SketchUp"; 
     84                const char szFbx[] = "FBX"; 
     85                const char szMaya[] = "Maya"; 
     86 
    7587                xsString Tool = ContributorArray[CurrentContributor]->getAuthoring_tool()->getValue(); 
    76                 if (strncmp(Tool, "Google SketchUp", 15) == 0) 
    77                     m_AuthoringTool = GOOGLE_SKETCHUP; 
    78             } 
    79         } 
    80         if (document->getAsset()->getUnit()) 
    81         { 
    82             if (NULL != document->getAsset()->getUnit()->getName()) 
    83                 m_AssetUnitName = std::string(document->getAsset()->getUnit()->getName()); 
    84             if (0 != document->getAsset()->getUnit()->getMeter()) 
    85                 m_AssetUnitMeter = document->getAsset()->getUnit()->getMeter(); 
    86         } 
    87         if (document->getAsset()->getUp_axis()) 
    88             m_AssetUp_axis = document->getAsset()->getUp_axis()->getValue(); 
    89     } 
    90  
    91     if (dae->getDatabase())  
    92     { 
    93         count = dae->getDatabase()->getElementCount(NULL, COLLADA_TYPE_INSTANCE_RIGID_BODY, NULL); 
     88 
     89                if (strncmp(Tool, szBlender, strlen(szBlender)) == 0) 
     90                    _authoringTool = BLENDER; 
     91                else if (strncmp(Tool, szDazStudio, strlen(szDazStudio)) == 0) 
     92                    _authoringTool = DAZ_STUDIO; 
     93                else if (strncmp(Tool, szFbx, strlen(szFbx)) == 0) 
     94                    _authoringTool = FBX_CONVERTER; 
     95                else if (strncmp(Tool, szSketchup, strlen(szSketchup)) == 0) 
     96                    _authoringTool = GOOGLE_SKETCHUP; 
     97                else if (strncmp(Tool, szMaya, strlen(szMaya)) == 0) 
     98                    _authoringTool = MAYA; 
     99            } 
     100        } 
     101        if (_document->getAsset()->getUnit()) 
     102        { 
     103            if (NULL != _document->getAsset()->getUnit()->getName()) 
     104                _assetUnitName = std::string(_document->getAsset()->getUnit()->getName()); 
     105            if (0 != _document->getAsset()->getUnit()->getMeter()) 
     106                _assetUnitMeter = _document->getAsset()->getUnit()->getMeter(); 
     107        } 
     108        if (_document->getAsset()->getUp_axis()) 
     109            _assetUp_axis = _document->getAsset()->getUp_axis()->getValue(); 
     110    } 
     111 
     112    domInstanceWithExtra *ivs = _document->getScene()->getInstance_visual_scene(); 
     113    _visualScene = daeSafeCast< domVisual_scene >( getElementFromURI( ivs->getUrl() ) ); 
     114    if ( _visualScene == NULL )  
     115    { 
     116        osg::notify( osg::WARN ) << "Unable to locate visual scene!" << std::endl; 
     117        return false; 
     118    } 
     119 
     120    if (daeDatabase* database = _dae->getDatabase())  
     121    { 
     122        _invertTransparency = findInvertTransparency(database); 
    94123 
    95124        // build a std::map for lookup if Group or PositionAttitudeTransform should be created,  
    96125        // i.e, make it easy to check if a instance_rigid_body targets a visual node 
     126        domInstance_rigid_body *pDomInstanceRigidBody; 
     127        count = database->getElementCount(NULL, COLLADA_TYPE_INSTANCE_RIGID_BODY, NULL); 
    97128        for (int i=0; i<count; i++)  
    98129        { 
    99             result = dae->getDatabase()->getElement(&colladaElement, i, NULL, COLLADA_TYPE_INSTANCE_RIGID_BODY); 
     130            result = database->getElement(&colladaElement, i, NULL, COLLADA_TYPE_INSTANCE_RIGID_BODY); 
    100131 
    101132            if (result == DAE_OK)  
    102133            { 
    103                 irb = daeSafeCast<domInstance_rigid_body>(colladaElement); 
    104                 if (irb)  
    105                 { 
    106                     domNode *node = daeSafeCast<domNode>(irb->getTarget().getElement()); 
     134                pDomInstanceRigidBody = daeSafeCast<domInstance_rigid_body>(colladaElement); 
     135                if (pDomInstanceRigidBody)  
     136                { 
     137                    domNode *node = daeSafeCast<domNode>(pDomInstanceRigidBody->getTarget().getElement()); 
    107138                    if (node && node->getId())  
    108139                    { 
     
    112143            } 
    113144        } 
    114     } 
    115  
    116     domInstanceWithExtra *ivs = document->getScene()->getInstance_visual_scene(); 
    117     domVisual_scene *vs = daeSafeCast< domVisual_scene >( getElementFromURI( ivs->getUrl() ) ); 
    118     if ( vs == NULL )  
    119     { 
    120         osg::notify( osg::WARN ) << "Unable to locate visual scene!" << std::endl; 
    121         return false; 
    122     } 
    123     rootNode = processVisualScene( vs ); 
    124  
     145 
     146        // Build a map of elements that are targetted by animations 
     147        count = database->getElementCount(NULL, COLLADA_TYPE_CHANNEL, NULL); 
     148        for (int i=0; i<count; i++)  
     149        { 
     150            result = database->getElement(&colladaElement, i, NULL, COLLADA_TYPE_CHANNEL); 
     151 
     152            if (result == DAE_OK)  
     153            { 
     154                domChannel* pDomChannel = daeSafeCast<domChannel>(colladaElement); 
     155                if (pDomChannel)  
     156                { 
     157                    std::string target = pDomChannel->getTarget(); 
     158                    size_t openparenthesis = target.find_first_of('('); 
     159                    if (openparenthesis != std::string::npos) target.erase(openparenthesis); 
     160                    daeSIDResolver resolver(pDomChannel, target.c_str()); 
     161                    daeElement *pDaeElement = resolver.getElement(); 
     162                    if (pDaeElement) 
     163                    { 
     164                        _daeElementDomChannelMap.insert(daeElementDomChannelMap::value_type(pDaeElement, pDomChannel)); 
     165                    } 
     166                    else 
     167                    { 
     168                        osg::notify( osg::WARN ) << "Could not locate <channel> target "  << pDomChannel->getTarget()<< std::endl; 
     169                    } 
     170                } 
     171            } 
     172        } 
     173 
     174        // Find all nodes that are used as bones. Note that while many files 
     175        // identify nodes with type="JOINT", some don't do this, while others 
     176        // identify every node as a joint, making it meaningless. 
     177        std::vector<domInstance_controller*> instanceControllers; 
     178        database->typeLookup(instanceControllers); 
     179        for (size_t i = 0; i < instanceControllers.size(); ++i)  
     180        { 
     181            domInstance_controller* pInstanceController = instanceControllers[i]; 
     182 
     183            domController *pDomController = daeSafeCast<domController>(getElementFromURI(pInstanceController->getUrl())); 
     184            if (!pDomController) 
     185            { 
     186                osg::notify( osg::WARN ) << "Failed to locate controller " << pInstanceController->getUrl().getURI() << std::endl; 
     187                continue; 
     188            } 
     189 
     190            const domInstance_controller::domSkeleton_Array& domSkeletonURIs = pInstanceController->getSkeleton_array(); 
     191            std::vector<daeElement*> searchIn; 
     192 
     193            for (size_t i = 0; i < domSkeletonURIs.getCount(); ++i) 
     194            { 
     195                if (daeElement* el = getElementFromURI(domSkeletonURIs[i]->getValue())) 
     196                { 
     197                    searchIn.push_back(el); 
     198                    if (domNode* pJoint = daeSafeCast<domNode>(el)) 
     199                    { 
     200                        _jointSet.insert(pJoint); 
     201                    } 
     202                } 
     203            } 
     204 
     205            if (searchIn.empty()) 
     206            { 
     207                searchIn.push_back(_visualScene); 
     208            } 
     209 
     210            const domSkin* pSkin = pDomController->getSkin(); 
     211            if (!pSkin) continue; 
     212            const domSkin::domJoints* pJoints = pSkin->getJoints(); 
     213            if (!pJoints) continue; 
     214            const domInputLocal_Array& inputURIs = pJoints->getInput_array(); 
     215 
     216            domSource* pDomJointsSource = NULL;  
     217            for (size_t i=0; i < inputURIs.getCount(); i++) 
     218            { 
     219                if (!strcmp(inputURIs[i]->getSemantic(), COMMON_PROFILE_INPUT_JOINT)) 
     220                { 
     221                    pDomJointsSource = daeSafeCast<domSource>(getElementFromURI(inputURIs[i]->getSource())); 
     222                    if (!pDomJointsSource) 
     223                    { 
     224                        osg::notify( osg::WARN ) << "Could not find skin joints source '" << inputURIs[i]->getSource().getURI() << "'" <<std::endl; 
     225                    } 
     226                } 
     227            } 
     228 
     229            if (!pDomJointsSource) 
     230            { 
     231            } 
     232            else if (domIDREF_array* pDomIDREFs = pDomJointsSource->getIDREF_array()) 
     233            { 
     234                for (size_t i = 0; i < pDomIDREFs->getCount(); ++i) 
     235                { 
     236                    if (domNode* pJoint = daeSafeCast<domNode>(getElementFromIDRef(pDomIDREFs->getValue().get(i)))) 
     237                    { 
     238                        _jointSet.insert(pJoint); 
     239                    } 
     240                } 
     241            } 
     242            else if (domName_array* pDomNames = pDomJointsSource->getName_array()) 
     243            { 
     244                for (size_t i = 0; i < pDomNames->getCount(); ++i) 
     245                { 
     246                    daeString target = pDomNames->getValue().get(i); 
     247                    for (size_t j = 0; j < searchIn.size(); ++j) 
     248                    { 
     249                        daeSIDResolver resolver(searchIn[j], target); 
     250                        if (domNode* pJoint = daeSafeCast<domNode>(resolver.getElement())) 
     251                        { 
     252                            _jointSet.insert(pJoint); 
     253                        } 
     254                    } 
     255                } 
     256            } 
     257        } 
     258    } 
     259 
     260    // Build the actual scene graph based on the visual scene 
     261    _rootNode = processVisualScene( _visualScene ); 
     262 
     263    osgAnimation::BasicAnimationManager* pOsgAnimationManager = processAnimationLibraries(_document); 
     264    if (pOsgAnimationManager) 
     265    { 
     266        _rootNode->addUpdateCallback(pOsgAnimationManager); 
     267    } 
     268     
    125269    return true; 
    126270} 
    127271 
    128 osg::Node* daeReader::processVisualScene( domVisual_scene *scene ) 
    129 { 
    130     osg::Node *retVal;  
     272void daeReader::addChild(osg::Group* group, osg::Node* node) 
     273{ 
     274    if (dynamic_cast<osgAnimation::Bone*>(node)) 
     275    { 
     276        unsigned index = 0; 
     277        while (index < group->getNumChildren() && 
     278            dynamic_cast<osgAnimation::Bone*>(group->getChild(index))) 
     279        { 
     280            ++index; 
     281        } 
     282        group->insertChild(index, node); 
     283    } 
     284    else 
     285    { 
     286        group->addChild(node); 
     287    } 
     288} 
     289 
     290osg::Group* daeReader::turnZUp() 
     291{ 
     292    osg::PositionAttitudeTransform* pat = NULL; 
     293     
     294    // If not Z axis up we need to rotate scene to bring the Z axis up 
     295    if (_assetUp_axis != UPAXISTYPE_Z_UP) 
     296    { 
     297        pat = new osg::PositionAttitudeTransform(); 
     298        if (_assetUp_axis == UPAXISTYPE_Y_UP) 
     299        { 
     300            pat->setAttitude(osg::Quat(osg::inDegrees(90.0f), osg::Vec3(1.0f,0.0f,0.0f))); 
     301        } 
     302        else //(m_AssetUp_axis == UPAXISTYPE_X_UP) 
     303        { 
     304            pat->setAttitude(osg::Quat(osg::inDegrees(90.0f), osg::Vec3(0.0f,1.0f,0.0f))); 
     305        } 
     306    } 
     307 
     308    _assetUp_axis = UPAXISTYPE_Z_UP; 
     309    return pat; 
     310} 
     311 
     312osg::Group* daeReader::processVisualScene( domVisual_scene *scene ) 
     313{ 
     314    osg::Group *retVal;  
    131315    _rootStateSet = new osg::StateSet(); 
    132316 
     
    138322        retVal->setName("Empty Collada scene"); 
    139323    } 
    140     else if (nbVisualSceneGroup==1) 
    141     { 
    142         osg::Node *node = processNode( scene->getNode_array()[0] ); 
    143         if ( node != NULL ) 
    144            retVal = node; 
    145         else 
    146         { 
    147            retVal = new osg::Group(); 
    148            retVal->setName("Empty Collada scene (import failure)"); 
    149         } 
    150     } 
    151324    else 
    152     {  
    153        retVal = new osg::Group(); 
    154        retVal->setName("Collada visual scene group"); 
    155        for ( size_t i = 0; i < scene->getNode_array().getCount(); i++ ) 
    156        { 
    157           osg::Node *node = processNode( scene->getNode_array()[i] ); 
    158           if ( node != NULL ) 
    159           { 
    160               retVal->asGroup()->addChild( node ); 
    161           } 
    162        } 
     325    { 
     326        retVal = turnZUp();  
     327 
     328        if (!retVal) 
     329        { 
     330            retVal = new osg::Group; 
     331        } 
     332 
     333        _skinInstanceControllers.clear(); 
     334 
     335        const domNode_Array& node_array = scene->getNode_array(); 
     336        for (size_t i = 0; i < node_array.getCount(); i++) 
     337        { 
     338            if (osg::Node* node = processNode(node_array[i], false)) 
     339            { 
     340                addChild(retVal, node); 
     341            } 
     342        } 
     343 
     344        processSkins(); 
     345 
     346        if (retVal->getName().empty()) 
     347        { 
     348            if (retVal->getNumChildren()) 
     349            { 
     350                retVal->setName("Collada visual scene group"); 
     351            } 
     352            else 
     353            { 
     354                retVal->setName("Empty Collada scene (import failure)"); 
     355            } 
     356        } 
    163357    } 
    164358    retVal->setStateSet(_rootStateSet.get()); 
     
    167361} 
    168362 
    169 osg::Node* daeReader::processExtras(domNode *node) 
     363 
     364 
     365osg::Group* daeReader::processExtras(domNode *node) 
    170366{ 
    171367    // See if one of the extras contains OpenSceneGraph specific information 
     
    304500// 0..* <node> 
    305501// 0..* <extra> 
    306 osg::Node* daeReader::processNode( domNode *node ) 
     502osg::Node* daeReader::processNode( domNode *node, bool skeleton) 
    307503{ 
    308504    // First we need to determine what kind of OSG node we need 
     
    316512                        node->getSkew_array().getCount(); 
    317513 
    318     // See if it is targeted 
     514    // See if it is targeted by an animation 
    319515    bool targeted = false; 
    320516    if (node->getId())  
     
    323519    } 
    324520 
    325     osg::Node *resultNode; 
    326     if (coordcount > 0 || targeted )  
    327     { 
    328         resultNode = processOsgMatrixTransform(node); 
     521 
     522    osg::Group *resultNode = NULL; 
     523 
     524    bool isBone = skeleton || isJoint(node); 
     525 
     526    if (coordcount > 0 || targeted || isBone)  
     527    { 
     528        // TODO 
     529        // single matrix -> MatrixTransform 
     530        // scale, euler, translate -> PositionAttitudeTransform 
     531        // if targeted -> StackedTransform 
     532        // otherwise a flattened -> MatrixTransform 
     533        resultNode = processOsgMatrixTransform(node, isBone); 
    329534    } 
    330535    else 
     
    337542    processNodeExtra(resultNode, node); 
    338543 
    339     resultNode->setName( node->getId() ? node->getId() : "" ); 
    340  
    341     osg::Group* groupNode = resultNode->asGroup(); 
    342  
    343     if (groupNode) 
    344     { 
    345         // 0..* <instance_camera> 
    346         domInstance_camera_Array cameraInstanceArray = node->getInstance_camera_array(); 
    347         for ( size_t i = 0; i < cameraInstanceArray.getCount(); i++ )  
    348         { 
    349             daeElement *el = getElementFromURI( cameraInstanceArray[i]->getUrl()); 
    350             domCamera *c = daeSafeCast< domCamera >( el ); 
    351  
    352             if (c) 
    353                 groupNode->addChild( processCamera( c )); 
    354             else 
    355                 osg::notify( osg::WARN ) << "Failed to locate camera " << cameraInstanceArray[i]->getUrl().getURI() << std::endl; 
    356         } 
    357  
    358         // 0..* <instance_controller> 
    359         domInstance_controller_Array controllerInstanceArray = node->getInstance_controller_array(); 
    360         for ( size_t i = 0; i < controllerInstanceArray.getCount(); i++ )  
    361         { 
    362             groupNode->addChild( processInstanceController( controllerInstanceArray[i] )); 
    363         } 
    364  
    365         // 0..* <instance_geometry> 
    366         domInstance_geometry_Array geometryInstanceArray = node->getInstance_geometry_array(); 
    367         for ( size_t i = 0; i < geometryInstanceArray.getCount(); i++ )  
    368         { 
    369             groupNode->addChild( processInstanceGeometry( geometryInstanceArray[i] )); 
    370         } 
    371  
    372         // 0..* <instance_light> 
    373         domInstance_light_Array lightInstanceArray = node->getInstance_light_array(); 
    374         for ( size_t i = 0; i < lightInstanceArray.getCount(); i++ )  
    375         { 
    376             daeElement *el = getElementFromURI( lightInstanceArray[i]->getUrl()); 
    377             domLight *l = daeSafeCast< domLight >( el ); 
    378              
    379             if (l) 
    380                 groupNode->addChild( processLight( l )); 
    381             else 
    382                 osg::notify( osg::WARN ) << "Failed to locate light " << lightInstanceArray[i]->getUrl().getURI() << std::endl; 
    383         } 
    384  
    385         // 0..* <instance_node> 
    386         domInstance_node_Array nodeInstanceArray = node->getInstance_node_array(); 
    387         for ( size_t i = 0; i < nodeInstanceArray.getCount(); i++ )  
    388         { 
    389             daeElement *el = getElementFromURI( nodeInstanceArray[i]->getUrl()); 
    390             domNode *n = daeSafeCast< domNode >( el ); 
    391  
    392             if (n) 
    393                 // Recursive call 
    394                 groupNode->addChild( processNode( n )); 
    395             else 
    396                 osg::notify( osg::WARN ) << "Failed to locate node " << nodeInstanceArray[i]->getUrl().getURI() << std::endl; 
    397         } 
    398  
    399         // 0..* <node> 
    400         domNode_Array nodeArray = node->getNode_array(); 
    401         for ( size_t i = 0; i < nodeArray.getCount(); i++ )  
    402         { 
     544    if (resultNode->getName().empty()) 
     545    { 
     546        resultNode->setName( node->getId() ? node->getId() : "" ); 
     547    } 
     548 
     549    osg::Group* attachTo = resultNode; 
     550 
     551    if (!skeleton && isJoint(node)) 
     552    { 
     553        skeleton = true; 
     554        osgAnimation::Skeleton* pOsgSkeleton = getOrCreateSkeleton(node); 
     555        pOsgSkeleton->addChild(resultNode); 
     556        attachTo = resultNode; 
     557        resultNode = pOsgSkeleton; 
     558    } 
     559 
     560    // 0..* <instance_camera> 
     561    const domInstance_camera_Array& cameraInstanceArray = node->getInstance_camera_array(); 
     562    for ( size_t i = 0; i < cameraInstanceArray.getCount(); i++ )  
     563    { 
     564        daeElement *el = getElementFromURI( cameraInstanceArray[i]->getUrl()); 
     565        domCamera *c = daeSafeCast< domCamera >( el ); 
     566 
     567        if (c) 
     568            addChild(attachTo, processCamera( c )); 
     569        else 
     570            osg::notify( osg::WARN ) << "Failed to locate camera " << cameraInstanceArray[i]->getUrl().getURI() << std::endl; 
     571    } 
     572 
     573    // 0..* <instance_controller> 
     574    const domInstance_controller_Array& controllerInstanceArray = node->getInstance_controller_array(); 
     575    for ( size_t i = 0; i < controllerInstanceArray.getCount(); i++ )  
     576    { 
     577        osg::Node* pOsgNode = processInstanceController( controllerInstanceArray[i]); 
     578         
     579        // A skin controller may return NULL,  since the RigGeometry is added as  
     580        // child of the skeleton and the skeleton already is added to the scenegraph 
     581        if (pOsgNode) 
     582        { 
     583            addChild(attachTo, pOsgNode); 
     584        } 
     585    } 
     586 
     587    // 0..* <instance_geometry> 
     588    const domInstance_geometry_Array& geometryInstanceArray = node->getInstance_geometry_array(); 
     589    for ( size_t i = 0; i < geometryInstanceArray.getCount(); i++ )  
     590    { 
     591        addChild(attachTo, processInstanceGeometry( geometryInstanceArray[i] )); 
     592    } 
     593 
     594    // 0..* <instance_light> 
     595    const domInstance_light_Array& lightInstanceArray = node->getInstance_light_array(); 
     596    for ( size_t i = 0; i < lightInstanceArray.getCount(); i++ )  
     597    { 
     598        daeElement *el = getElementFromURI( lightInstanceArray[i]->getUrl()); 
     599        domLight *pDomLight = daeSafeCast< domLight >( el ); 
     600         
     601        if (pDomLight) 
     602            addChild(attachTo, processLight(pDomLight)); 
     603        else 
     604            osg::notify( osg::WARN ) << "Failed to locate light " << lightInstanceArray[i]->getUrl().getURI() << std::endl; 
     605    } 
     606 
     607    // 0..* <instance_node> 
     608    const domInstance_node_Array& nodeInstanceArray = node->getInstance_node_array(); 
     609    for ( size_t i = 0; i < nodeInstanceArray.getCount(); i++ )  
     610    { 
     611        daeElement *el = getElementFromURI( nodeInstanceArray[i]->getUrl()); 
     612        domNode *n = daeSafeCast< domNode >( el ); 
     613 
     614        if (n) 
    403615            // Recursive call 
    404             groupNode->addChild( processNode( nodeArray[i] )); 
    405         } 
     616            addChild(attachTo, processNode( n, skeleton )); 
     617        else 
     618            osg::notify( osg::WARN ) << "Failed to locate node " << nodeInstanceArray[i]->getUrl().getURI() << std::endl; 
     619    } 
     620 
     621    // 0..* <node> 
     622    const domNode_Array& nodeArray = node->getNode_array(); 
     623    for ( size_t i = 0; i < nodeArray.getCount(); i++ )  
     624    { 
     625        // Recursive call 
     626        addChild(attachTo, processNode( nodeArray[i], skeleton )); 
    406627    } 
    407628 
  • OpenSceneGraph/trunk/src/osgPlugins/dae/daeReader.h

    r10234 r11129  
    2121#include <dae/daeElement.h> 
    2222#include <dom/domCommon_color_or_texture_type.h> 
     23#include <dom/domInputLocalOffset.h> 
     24#include <dom/domInstance_controller.h> 
    2325 
    2426#include <osg/Node> 
    25 #include <osg/Transform> 
    2627#include <osg/Notify> 
    27 #include <osg/PositionAttitudeTransform> 
    2828#include <osgDB/ReaderWriter> 
    2929#include <osgDB/FileNameUtils> 
     
    3131#include <osgDB/Registry> 
    3232#include <osg/Material> 
    33  
     33#include <osg/Texture2D> 
     34#include <osgAnimation/BasicAnimationManager> 
     35#include <osgAnimation/Bone> 
     36#include <osgAnimation/Skeleton> 
    3437 
    3538class domBind_material; 
     
    5356class domVisual_scene; 
    5457 
    55 #include <dom/domInputLocalOffset.h> 
    56  
    57 namespace osgdae { 
     58namespace osgDAE 
     59{ 
    5860 
    5961class domSourceReader; 
     
    137139    bool convert( const std::string &fileURI ); 
    138140     
    139     osg::Node* getRootNode()    { return rootNode; } 
    140  
    141     // Additional Information 
    142     std::string m_AssetUnitName; 
    143     float m_AssetUnitMeter; 
    144     domUpAxisType m_AssetUp_axis; 
    145  
    146     // Texture unit useage 
    147     enum 
     141    osg::Node* getRootNode()    { return _rootNode; } 
     142 
     143    const std::string& getAssetUnitName() const {return _assetUnitName;} 
     144    float getAssetUnitMeter() const {return _assetUnitMeter;} 
     145    domUpAxisType getAssetUpAxis() const {return _assetUp_axis;} 
     146 
     147    enum TextureUnitUsage 
    148148    { 
    149149        AMBIENT_OCCLUSION_UNIT = 0, 
     
    152152    }; 
    153153 
    154 protected: 
    155     //scene processing 
    156     osg::Node*    processVisualScene( domVisual_scene *scene ); 
    157     osg::Node*    processNode( domNode *node ); 
    158     osg::Node*    processOsgMatrixTransform( domNode *node ); 
    159     //osg::Node* processInstance( domInstanceWithExtra *iwe ); 
     154    enum InterpolationType  
     155    {  
     156        INTERPOLATION_UNKNOWN,  
     157        INTERPOLATION_STEP,  
     158        INTERPOLATION_LINEAR,  
     159        INTERPOLATION_BEZIER,  
     160        INTERPOLATION_HERMITE,  
     161        INTERPOLATION_CARDINAL,  
     162        INTERPOLATION_BSPLINE, 
     163 
     164        //COLLADA spec states that if interpolation is not specified then 
     165        //interpolation is application defined. Linear is a sensible default. 
     166        INTERPOLATION_DEFAULT = INTERPOLATION_LINEAR 
     167    }; 
     168 
     169    enum AuthoringTool 
     170    { 
     171        UNKNOWN, 
     172        BLENDER, 
     173        DAZ_STUDIO, 
     174        FBX_CONVERTER, 
     175        AUTODESK_3DS_MAX = FBX_CONVERTER,//3ds Max exports to DAE via Autodesk's FBX converter 
     176        GOOGLE_SKETCHUP, 
     177        MAYA 
     178    }; 
     179 
     180    class TextureParameters 
     181    { 
     182    public: 
     183        TextureParameters() 
     184            : wrap_s(osg::Texture::REPEAT), wrap_t(osg::Texture::REPEAT), 
     185            filter_min(osg::Texture::LINEAR_MIPMAP_LINEAR), filter_mag(osg::Texture::LINEAR), 
     186            transparent(false), opaque(FX_OPAQUE_ENUM_A_ONE), transparency(1.0f) 
     187        {} 
     188 
     189        bool operator < (const TextureParameters& rhs) const 
     190        { 
     191            int diffStr = filename.compare(rhs.filename); 
     192            if (diffStr) return diffStr < 0; 
     193            if (wrap_s != rhs.wrap_s) return wrap_s < rhs.wrap_s; 
     194            if (wrap_t != rhs.wrap_t) return wrap_t < rhs.wrap_t; 
     195            if (filter_min != rhs.filter_min) return filter_min < rhs.filter_min; 
     196            if (filter_mag != rhs.filter_mag) return filter_mag < rhs.filter_mag; 
     197            if (transparency != rhs.transparency) return transparency < rhs.transparency; 
     198            if (opaque != rhs.opaque) return opaque < rhs.opaque; 
     199            if (transparent != rhs.transparent) return transparent < rhs.transparent; 
     200            return border < rhs.border; 
     201        } 
     202 
     203        std::string filename; 
     204        osg::Texture::WrapMode wrap_s, wrap_t; 
     205        osg::Texture::FilterMode filter_min, filter_mag; 
     206        osg::Vec4 border; 
     207 
     208        //The following parameters are for transparency textures, to handle 
     209        //COLLADA's horrible transparency spec. 
     210        bool transparent; 
     211        domFx_opaque_enum opaque; 
     212        float transparency; 
     213    }; 
     214 
     215    class ChannelPart : public osg::Referenced 
     216    { 
     217    public: 
     218        std::string name; 
     219        osg::ref_ptr<osgAnimation::KeyframeContainer> keyframes; 
     220        InterpolationType interpolation; 
     221    }; 
     222 
     223    typedef std::map<domGeometry*, osg::ref_ptr<osg::Geode> >    domGeometryGeodeMap; 
     224    typedef std::map<domMaterial*, osg::ref_ptr<osg::StateSet> > domMaterialStateSetMap; 
     225    typedef std::map<std::string, osg::ref_ptr<osg::StateSet> >    MaterialStateSetMap; 
     226    typedef std::multimap< daeElement*, domChannel*> daeElementDomChannelMap; 
     227    typedef std::map<domChannel*, osg::ref_ptr<osg::NodeCallback> > domChannelOsgAnimationUpdateCallbackMap; 
     228    typedef std::map<domNode*, osg::ref_ptr<osgAnimation::Bone> > domNodeOsgBoneMap; 
     229    typedef std::map<domNode*, osg::ref_ptr<osgAnimation::Skeleton> > domNodeOsgSkeletonMap; 
     230    typedef std::map<TextureParameters, osg::ref_ptr<osg::Texture2D> > TextureParametersMap; 
     231    typedef std::map<std::pair<const osg::StateSet*, TextureUnitUsage>, std::string> TextureToCoordSetMap; 
     232 
     233    typedef std::map< daeElement*, domSourceReader > SourceMap; 
     234    typedef std::map< int, osg::IntArray*, std::less<int> > IndexMap; 
     235    typedef std::map< int, osg::Array*, std::less<int> > ArrayMap; 
     236 
     237    typedef std::multimap< osgAnimation::Target*, osg::ref_ptr<ChannelPart> > TargetChannelPartMap; 
     238    typedef std::multimap<std::pair<const domMesh*, unsigned>, std::pair<osg::ref_ptr<osg::Geometry>, GLuint> > OldToNewIndexMap; 
     239 
     240private: 
     241    // If the node is a bone then it should be added before any other types of 
     242    // node, this function makes that happen. 
     243    static void addChild(osg::Group*, osg::Node*); 
     244 
     245     //scene processing 
     246    osg::Group* turnZUp(); 
     247    osg::Group*    processVisualScene( domVisual_scene *scene ); 
     248    osg::Node*    processNode( domNode *node, bool skeleton ); 
     249    osg::Transform*    processOsgMatrixTransform( domNode *node, bool isBone); 
     250 
     251    template <typename T> 
     252    inline void getTransparencyCounts(daeDatabase*, int& zero, int& one) const; 
     253 
     254    /** Earlier versions of the COLLADA 1.4 spec state that transparency values 
     255    of 0 mean 100% opacity, but this has been changed in later versions to state 
     256    that transparency values of 1 mean 100% opacity. Documents created by 
     257    different tools at different times adhere to different versions of the 
     258    standard. This function looks at all transparency values in the database and 
     259    heuristically decides which way the values should be interpreted.*/ 
     260    bool findInvertTransparency(daeDatabase*) const; 
     261     
     262    osgAnimation::BasicAnimationManager* processAnimationLibraries(domCOLLADA* document); 
     263    void processAnimationClip(osgAnimation::BasicAnimationManager* pOsgAnimationManager, domAnimation_clip* pDomAnimationClip); 
     264    void processAnimation(domAnimation* pDomAnimation, osgAnimation::Animation* pOsgAnimation); 
     265    ChannelPart* processSampler(domChannel* pDomChannel, SourceMap &sources); 
     266    void processAnimationChannels(domAnimation* pDomAnimation, TargetChannelPartMap& tcm); 
     267    void processChannel(domChannel* pDomChannel, SourceMap &sources, TargetChannelPartMap& tcm); 
     268    void extractTargetName(const std::string&, std::string&, std::string&, std::string&); 
    160269 
    161270    // Processing of OSG specific info stored in node extras 
    162     osg::Node* processExtras(domNode *node); 
     271    osg::Group* processExtras(domNode *node); 
    163272    void processNodeExtra(osg::Node* osgNode, domNode *node); 
    164273    domTechnique* getOpenSceneGraphProfile(domExtra* extra); 
    165274    void processAsset( domAsset *node ); 
    166275 
    167     osg::Node* processOsgSwitch(domTechnique* teq); 
    168     osg::Node* processOsgMultiSwitch(domTechnique* teq); 
    169     osg::Node* processOsgLOD(domTechnique* teq); 
    170     osg::Node* processOsgDOFTransform(domTechnique* teq); 
    171     osg::Node* processOsgSequence(domTechnique* teq); 
    172  
    173     //geometry processing 
    174     class ReaderGeometry : public osg::Geometry 
    175     { 
    176     public: 
    177         std::map<int, int> _TexcoordSetMap; 
    178     }; 
     276    osg::Group* processOsgSwitch(domTechnique* teq); 
     277    osg::Group* processOsgMultiSwitch(domTechnique* teq); 
     278    osg::Group* processOsgLOD(domTechnique* teq); 
     279    osg::Group* processOsgDOFTransform(domTechnique* teq); 
     280    osg::Group* processOsgSequence(domTechnique* teq); 
     281 
     282    // geometry processing 
     283    osg::Geode* getOrCreateGeometry(domGeometry *geom, domBind_material* pDomBindMaterial, const osg::Geode** ppOriginalGeode = NULL); 
     284    osgAnimation::Bone* getOrCreateBone(domNode *pDomNode); 
     285    osgAnimation::Skeleton* getOrCreateSkeleton(domNode *pDomNode); 
    179286    osg::Geode* processInstanceGeometry( domInstance_geometry *ig ); 
    180     osg::Geode* processGeometry( domGeometry *geo ); 
    181     osg::Geode* processInstanceController( domInstance_controller *ictrl ); 
    182  
    183     typedef std::map< daeElement*, domSourceReader > SourceMap; 
    184     typedef std::map< int, osg::IntArray*, std::less<int> > IndexMap; 
     287 
     288    osg::Geode* processMesh(domMesh* pDomMesh); 
     289    osg::Geode* processConvexMesh(domConvex_mesh* pDomConvexMesh); 
     290    osg::Geode* processSpline(domSpline* pDomSpline); 
     291    osg::Geode* processGeometry(domGeometry *pDomGeometry); 
     292 
     293    typedef std::vector<domInstance_controller*> domInstance_controllerList; 
     294 
     295    void processSkins(); 
     296    //Process skins attached to one skeleton 
     297    void processSkeletonSkins(domNode* skeletonRoot, const domInstance_controllerList&); 
     298    void processSkin(domSkin* pDomSkin, domNode* skeletonRoot, osgAnimation::Skeleton*, domBind_material* pDomBindMaterial); 
     299    osg::Node* processMorph(domMorph* pDomMorph, domBind_material* pDomBindMaterial); 
     300    osg::Node* processInstanceController( domInstance_controller *ictrl ); 
    185301 
    186302    template< typename T > 
    187     void processSinglePPrimitive(osg::Geode* geode, T *group, SourceMap &sources, GLenum mode ); 
     303    void processSinglePPrimitive(osg::Geode* geode, const domMesh* pDomMesh, const T* group, SourceMap& sources, GLenum mode); 
    188304     
    189305    template< typename T > 
    190     void processMultiPPrimitive(osg::Geode* geode, T *group, SourceMap &sources, GLenum mode ); 
    191  
    192     void processPolylist(osg::Geode* geode, domPolylist *group, SourceMap &sources ); 
    193  
    194     void resolveArrays( domInputLocalOffset_Array &inputs, osg::Geometry *geom,  
    195                         SourceMap &sources, IndexMap &index_map ); 
    196  
    197     void processP( domP *p, osg::Geometry *&geom, IndexMap &index_map, osg::DrawArrayLengths* dal/*GLenum mode*/ ); 
     306    void processMultiPPrimitive(osg::Geode* geode, const domMesh* pDomMesh, const T* group, SourceMap& sources, GLenum mode); 
     307 
     308    template <typename T> 
     309    void processPolygons(osg::Geode* geode, const domMesh* pDomMesh, const T *group, SourceMap& sources); 
     310 
     311    void processPolylist(osg::Geode* geode, const domMesh* pDomMesh, const domPolylist *group, SourceMap &sources); 
     312    void processPolygons(osg::Geode* geode, const domMesh* pDomMesh, const domPolygons *group, SourceMap &sources); 
     313 
     314    void resolveMeshArrays(const domP_Array&, 
     315        const domInputLocalOffset_Array& inputs, const domMesh* pDomMesh, 
     316        osg::Geometry* geometry, SourceMap &sources, 
     317        std::vector<std::vector<GLuint> >& vertexLists); 
    198318 
    199319    //material/effect processing 
     
    202322    void processEffect(osg::StateSet *ss, domEffect *effect ); 
    203323    void processProfileCOMMON(osg::StateSet *ss, domProfile_COMMON *pc ); 
    204     bool processColorOrTextureType( domCommon_color_or_texture_type *cot,  
     324    bool processColorOrTextureType(const osg::StateSet*, 
     325                                    domCommon_color_or_texture_type *cot,  
    205326                                    osg::Material::ColorMode channel,  
    206327                                    osg::Material *mat,  
    207328                                    domCommon_float_or_param_type *fop = NULL,  
    208                                     osg::StateAttribute **sa = NULL, 
     329                                    osg::Texture2D **sa = NULL, 
    209330                                    bool normalizeShininess=false); 
    210331    void processTransparencySettings( domCommon_transparent_type *ctt, 
    211332                                        domCommon_float_or_param_type *pTransparency,  
    212                                         osg::StateSet *ss, 
     333                                        osg::StateSet*, 
    213334                                        osg::Material *material, 
    214335                                        xsNCName diffuseTextureName ); 
    215     bool GetFloat4Param(xsNCName Reference, domFloat4 &f4); 
    216     bool GetFloatParam(xsNCName Reference, domFloat &f); 
    217  
    218     osg::StateAttribute *processTexture( domCommon_color_or_texture_type_complexType::domTexture *tex ); 
     336    bool GetFloat4Param(xsNCName Reference, domFloat4 &f4) const; 
     337    bool GetFloatParam(xsNCName Reference, domFloat &f) const; 
     338 
     339    std::string processImagePath(const domImage*) const; 
     340    osg::Image* processImageTransparency(const osg::Image*, domFx_opaque_enum, float transparency) const; 
     341    osg::Texture2D* processTexture( domCommon_color_or_texture_type_complexType::domTexture *tex, const osg::StateSet*, TextureUnitUsage, domFx_opaque_enum = FX_OPAQUE_ENUM_A_ONE, float transparency = 1.0f); 
     342    void copyTextureCoordinateSet(const osg::StateSet* ss, const osg::Geometry* cachedGeometry, osg::Geometry* clonedGeometry, const domInstance_material* im, TextureUnitUsage); 
    219343 
    220344    //scene objects 
     
    222346    osg::Node* processCamera( domCamera *dcamera ); 
    223347 
    224 protected: 
    225     DAE *dae; 
    226     osg::Node* rootNode; 
     348    domNode* getRootJoint(domNode*) const; 
     349    domNode* findJointNode(daeElement* searchFrom, domInstance_controller*) const; 
     350    domNode* findSkeletonNode(daeElement* searchFrom, domInstance_controller*) const; 
     351 
     352    /// Return whether the node is used as a bone. Note that while many files 
     353    /// identify joints with type="JOINT", some don't do this, while others 
     354    /// incorrectly identify every node as a joint. 
     355    bool isJoint(const domNode* node) const {return _jointSet.find(node) != _jointSet.end();} 
     356 
     357private: 
     358 
     359    DAE *_dae; 
     360    osg::Node* _rootNode; 
    227361    osg::ref_ptr<osg::StateSet> _rootStateSet; 
     362    domCOLLADA* _document; 
     363    domVisual_scene* _visualScene; 
    228364 
    229365    std::map<std::string,bool> _targetMap; 
    230366 
    231     int m_numlights; 
    232  
    233     domInstance_effect *currentInstance_effect; 
    234     domEffect *currentEffect; 
    235  
    236     typedef std::map< domGeometry*, osg::ref_ptr<osg::Geode> >    domGeometryGeodeMap; 
    237     typedef std::map< domMaterial*, osg::ref_ptr<osg::StateSet> > domMaterialStateSetMap; 
    238     typedef std::map< std::string, osg::ref_ptr<osg::StateSet> >    MaterialStateSetMap; 
    239  
     367    int _numlights; 
     368 
     369    domInstance_effect *_currentInstance_effect; 
     370    domEffect *_currentEffect; 
     371 
     372    /// Maps an animated element to a domchannel to quickly find which animation influence this element 
     373    // TODO a single element can be animated by multiple channels (with different members like translate.x or morphweights(2) ) 
     374    daeElementDomChannelMap _daeElementDomChannelMap; 
     375    /// Maps a domchannel to an animationupdatecallback 
     376    domChannelOsgAnimationUpdateCallbackMap _domChannelOsgAnimationUpdateCallbackMap; 
    240377    /// Maps geometry to a Geode 
    241     domGeometryGeodeMap     geometryMap; 
     378    domGeometryGeodeMap _geometryMap; 
     379    /// All nodes in the document that are used as joints. 
     380    std::set<const domNode*> _jointSet; 
     381    /// Maps a node (of type joint) to a osgAnimation::Bone 
     382    domNodeOsgBoneMap _jointMap; 
     383    /// Maps a node (of type joint) to a osgAnimation::Skeleton 
     384    domNodeOsgSkeletonMap _skeletonMap; 
    242385    // Maps material target to stateset 
    243     domMaterialStateSetMap  materialMap; 
     386    domMaterialStateSetMap _materialMap; 
    244387    // Maps material symbol to stateset 
    245     MaterialStateSetMap     materialMap2; 
    246  
    247     enum AuthoringTool 
    248     { 
    249         UNKNOWN, 
    250         GOOGLE_SKETCHUP 
    251     }; 
    252     AuthoringTool m_AuthoringTool; 
    253     bool m_StrictTransparency; 
     388    MaterialStateSetMap _materialMap2; 
     389    TextureParametersMap _textureParamMap; 
     390    TextureToCoordSetMap _texCoordSetMap; 
     391    domInstance_controllerList _skinInstanceControllers; 
     392    OldToNewIndexMap _oldToNewIndexMap; 
     393 
     394    AuthoringTool _authoringTool; 
     395    bool _strictTransparency, _invertTransparency; 
     396 
     397    // Additional Information 
     398    std::string _assetUnitName; 
     399    float _assetUnitMeter; 
     400    domUpAxisType _assetUp_axis; 
    254401}; 
    255402 
  • OpenSceneGraph/trunk/src/osgPlugins/dae/daeWGeometry.cpp

    r10234 r11129  
    1313 
    1414#include "daeWriter.h" 
     15#include <osgAnimation/RigGeometry> 
    1516 
    1617#include <dom/domCOLLADA.h> 
     
    2021#include <dom/domGeometry.h> 
    2122#include <dom/domConstants.h> 
     23//#include <dom/domSkin.h> 
    2224 
    2325#include <sstream> 
    2426 
    25 using namespace osgdae; 
     27using namespace osgDAE; 
     28 
     29domGeometry* daeWriter::getOrCreateDomGeometry(osg::Geometry* pOsgGeometry) 
     30{ 
     31    // See if geometry exists in cache 
     32    OsgGeometryDomGeometryMap::iterator iter = geometryMap.find( pOsgGeometry ); 
     33    if ( iter != geometryMap.end() ) 
     34    { 
     35        return iter->second; 
     36    } 
     37    else 
     38    { 
     39        if (!lib_geoms) 
     40        { 
     41            lib_geoms = daeSafeCast< domLibrary_geometries >( dom->add( COLLADA_ELEMENT_LIBRARY_GEOMETRIES ) ); 
     42        } 
     43        domGeometry* pDomGeometry = daeSafeCast< domGeometry >( lib_geoms->add( COLLADA_ELEMENT_GEOMETRY ) ); 
     44 
     45        std::string name = pOsgGeometry->getName(); 
     46        if (name.empty()) 
     47            name = uniquify("geometry"); 
     48        else 
     49            name = uniquify(name); 
     50        pDomGeometry->setId( name.c_str() ); 
     51    #ifndef EARTH_GEO 
     52        geometryMap.insert( std::make_pair( pOsgGeometry, pDomGeometry ) ); 
     53    #endif 
     54 
     55        if ( !processGeometry( pOsgGeometry, pDomGeometry, name ) ) 
     56        { 
     57            daeElement::removeFromParent( pDomGeometry ); 
     58            return NULL; 
     59        } 
     60        return pDomGeometry; 
     61    } 
     62} 
     63 
     64void daeWriter::writeRigGeometry(osgAnimation::RigGeometry *pOsgRigGeometry) 
     65{ 
     66    // See if controller exists in cache 
     67    OsgRigGeometryDomControllerMap::iterator iter = _osgRigGeometryDomControllerMap.find(pOsgRigGeometry); 
     68    domController* pDomController = NULL; 
     69    if ( iter != _osgRigGeometryDomControllerMap.end() ) 
     70    { 
     71        pDomController = iter->second; 
     72    } 
     73    else 
     74    { 
     75        domGeometry* pDomGeometry = getOrCreateDomGeometry(pOsgRigGeometry); 
     76        if (pDomGeometry) 
     77        { 
     78            if (!lib_controllers) 
     79            { 
     80                lib_controllers = daeSafeCast< domLibrary_controllers >( dom->add( COLLADA_ELEMENT_LIBRARY_CONTROLLERS ) ); 
     81            } 
     82 
     83            // <controller> 
     84            // 1 <skin> 
     85            //   source 
     86            //   0..1    <bind_shape_matrix> 
     87            //   3..*    <source> 
     88            //   1        <joints> 
     89            //   1      <vertex_weights> 
     90            //   0..1    <extra> 
     91            pDomController = daeSafeCast< domController >( lib_controllers->add( COLLADA_ELEMENT_CONTROLLER) ); 
     92            std::string name = pOsgRigGeometry->getName(); 
     93            if (name.empty()) 
     94                name = uniquify("skincontroller"); 
     95            else  
     96                name = uniquify(name); 
     97            pDomController->setId( name.c_str() ); 
     98            _osgRigGeometryDomControllerMap.insert( std::make_pair( pOsgRigGeometry, pDomController ) ); 
     99 
     100            // Link <skin> to cache hit or created <geometry> 
     101            domSkin* pDomSkin = daeSafeCast< domSkin >(pDomController->add( COLLADA_ELEMENT_SKIN )); 
     102            std::string url = "#" + std::string(pDomGeometry->getId()); 
     103            pDomSkin->setSource(url.c_str()); 
     104 
     105            domSkin::domBind_shape_matrix* pDomBindShapeMatrix = daeSafeCast< domSkin::domBind_shape_matrix >(pDomSkin->add( COLLADA_ELEMENT_BIND_SHAPE_MATRIX )); 
     106 
     107            domSource* pDomJointsSource = daeSafeCast< domSource >(pDomSkin->add( COLLADA_ELEMENT_SOURCE )); 
     108            std::string skinJointsName = name + "_skin_joints"; 
     109            pDomJointsSource->setId(skinJointsName.c_str()); 
     110 
     111            domListOfNames jointNames; // TODO fill with joint ids 
     112            int size = 0; // TODO number of animated joints 
     113 
     114            osgAnimation::VertexInfluenceMap* vim = pOsgRigGeometry->getInfluenceMap(); 
     115            osgAnimation::VertexInfluenceMap::iterator iter =    vim->begin(); 
     116            while (iter != vim->end()) 
     117            { 
     118                jointNames.append(iter->first.c_str()); 
     119                //iter->second.getn 
     120                ++iter; 
     121            } 
     122 
     123            domName_array* pDomJointsNameArray = daeSafeCast< domName_array >(pDomJointsSource->add(COLLADA_ELEMENT_NAME_ARRAY)); 
     124            std::string jointsNameArrayName = name + "_joints_array"; 
     125            pDomJointsNameArray->setId(jointsNameArrayName.c_str()); 
     126            pDomJointsNameArray->setCount(size); 
     127            pDomJointsNameArray->setValue(jointNames); 
     128            { 
     129                domSource::domTechnique_common* pDomSourceTechniqueCommon = daeSafeCast< domSource::domTechnique_common >(pDomJointsSource->add(COLLADA_ELEMENT_TECHNIQUE_COMMON)); 
     130                 
     131                domAccessor* pDomAccessor = daeSafeCast< domAccessor >(pDomSourceTechniqueCommon->add(COLLADA_ELEMENT_ACCESSOR)); 
     132                std::string url = "#" + jointsNameArrayName; 
     133                pDomAccessor->setSource(url.c_str()); 
     134                pDomAccessor->setCount(size); 
     135 
     136                domParam* pDomParam = daeSafeCast< domParam >(pDomAccessor->add(COLLADA_ELEMENT_PARAM)); 
     137                pDomParam->setType(COLLADA_TYPE_NAME); 
     138            } 
     139 
     140            domSource* pDomSkinBindPoseSource = daeSafeCast< domSource >(pDomSkin->add( COLLADA_ELEMENT_SOURCE )); 
     141            std::string skinBindPoseName = name + "_skin_bind_pose"; 
     142            pDomSkinBindPoseSource->setId(skinBindPoseName.c_str()); 
     143 
     144            domListOfFloats matrices; // TODO fill with bind matrices 
     145            int numMatrices = 0; // TODO number of bind matrices 
     146            domFloat_array* pDomMatricesArray = daeSafeCast< domFloat_array >(pDomSkinBindPoseSource->add(COLLADA_ELEMENT_FLOAT_ARRAY)); 
     147            std::string matricesArrayName = name + "_matrices_array"; 
     148            pDomMatricesArray->setId(matricesArrayName.c_str()); 
     149            pDomMatricesArray->setCount(numMatrices); 
     150            pDomMatricesArray->setValue(matrices); 
     151            { 
     152                domSource::domTechnique_common* pDomSourceTechniqueCommon = daeSafeCast< domSource::domTechnique_common >(pDomSkinBindPoseSource->add(COLLADA_ELEMENT_TECHNIQUE_COMMON)); 
     153                 
     154                domAccessor* pDomAccessor = daeSafeCast< domAccessor >(pDomSourceTechniqueCommon->add(COLLADA_ELEMENT_ACCESSOR)); 
     155                std::string url = "#" + matricesArrayName; 
     156                pDomAccessor->setSource(url.c_str()); 
     157                pDomAccessor->setCount(size); 
     158                pDomAccessor->setStride(16); 
     159 
     160                domParam* pDomParam = daeSafeCast< domParam >(pDomAccessor->add(COLLADA_ELEMENT_PARAM)); 
     161                pDomParam->setType(COLLADA_TYPE_FLOAT4X4); 
     162            } 
     163 
     164            domSource* pDomSkinWeightsSource = daeSafeCast< domSource >(pDomSkin->add( COLLADA_ELEMENT_SOURCE )); 
     165            std::string skinWeightsName = name + "_skin_weights"; 
     166            pDomSkinWeightsSource->setId(skinWeightsName.c_str()); 
     167 
     168            domListOfFloats weights; // TODO fill with vertex weights 
     169            int numWeights = 0; // TODO number of vertices vertex weights 
     170            domFloat_array* pDomWeightsArray = daeSafeCast< domFloat_array >(pDomSkinWeightsSource->add(COLLADA_ELEMENT_FLOAT_ARRAY)); 
     171            std::string weightsArrayName = name + "_weights_array"; 
     172            pDomWeightsArray->setId(weightsArrayName.c_str()); 
     173            pDomWeightsArray->setCount(numWeights); 
     174            pDomWeightsArray->setValue(weights); 
     175            { 
     176                domSource::domTechnique_common* pDomSourceTechniqueCommon = daeSafeCast< domSource::domTechnique_common >(pDomSkinWeightsSource->add(COLLADA_ELEMENT_TECHNIQUE_COMMON)); 
     177                 
     178                domAccessor* pDomAccessor = daeSafeCast< domAccessor >(pDomSourceTechniqueCommon->add(COLLADA_ELEMENT_ACCESSOR)); 
     179                std::string url = "#" + weightsArrayName; 
     180                pDomAccessor->setSource(url.c_str()); 
     181                pDomAccessor->setCount(size); 
     182 
     183                domParam* pDomParam = daeSafeCast< domParam >(pDomAccessor->add(COLLADA_ELEMENT_PARAM)); 
     184                pDomParam->setType(COLLADA_TYPE_FLOAT); 
     185            } 
     186 
     187            domSkin::domJoints* pDomJoints = daeSafeCast< domSkin::domJoints >(pDomSkin->add( COLLADA_ELEMENT_JOINTS )); 
     188             
     189            domInputLocal* pDomInput = daeSafeCast< domInputLocal >(pDomJoints->add(COLLADA_ELEMENT_INPUT)); 
     190            pDomInput->setSemantic(COMMON_PROFILE_INPUT_JOINT); 
     191            url = "#" + skinJointsName; 
     192            pDomInput->setSource(url.c_str()); 
     193 
     194            pDomInput = daeSafeCast< domInputLocal >(pDomJoints->add(COLLADA_ELEMENT_INPUT)); 
     195            pDomInput->setSemantic(COMMON_PROFILE_INPUT_INV_BIND_MATRIX); 
     196            url = "#" + skinBindPoseName; 
     197            pDomInput->setSource(url.c_str()); 
     198 
     199            domSkin::domVertex_weights* pDomVertexWeights = daeSafeCast< domSkin::domVertex_weights >(pDomSkin->add( COLLADA_ELEMENT_VERTEX_WEIGHTS )); 
     200            pDomVertexWeights->setCount(0);// TODO set number of vertex weights 
     201 
     202            domInputLocalOffset* pDomInputLocalOffset = daeSafeCast< domInputLocalOffset >(pDomVertexWeights->add(COLLADA_ELEMENT_INPUT)); 
     203            pDomInputLocalOffset->setSemantic(COMMON_PROFILE_INPUT_JOINT); 
     204            url = "#" + skinJointsName; 
     205            pDomInputLocalOffset->setSource(url.c_str()); 
     206            pDomInputLocalOffset->setOffset(0); 
     207 
     208            pDomInputLocalOffset = daeSafeCast< domInputLocalOffset >(pDomVertexWeights->add(COLLADA_ELEMENT_INPUT)); 
     209            pDomInputLocalOffset->setSemantic(COMMON_PROFILE_INPUT_WEIGHT); 
     210            url = "#" + weightsArrayName; 
     211            pDomInputLocalOffset->setSource(url.c_str()); 
     212            pDomInputLocalOffset->setOffset(1); 
     213 
     214            domSkin::domVertex_weights::domVcount* pDomVcount = daeSafeCast< domSkin::domVertex_weights::domVcount >(pDomVertexWeights->add(COLLADA_ELEMENT_VCOUNT)); 
     215            domListOfUInts valueCounts; 
     216            // TODO 
     217            pDomVcount->setValue(valueCounts); 
     218            domSkin::domVertex_weights::domV* pDomV = daeSafeCast< domSkin::domVertex_weights::domV >(pDomVertexWeights->add(COLLADA_ELEMENT_V)); 
     219            domListOfInts values; 
     220            //TODO 
     221            pDomV->setValue(values); 
     222        } 
     223    } 
     224 
     225    if (pDomController) 
     226    { 
     227        // Link <instance_controller> to cache hit or created <controller> 
     228        domInstance_controller* pDomInstanceController = daeSafeCast< domInstance_controller >( currentNode->add( COLLADA_ELEMENT_INSTANCE_CONTROLLER ) ); 
     229        std::string url = "#" + std::string(pDomController->getId()); 
     230        pDomInstanceController->setUrl( url.c_str() ); 
     231    } 
     232} 
     233 
     234void daeWriter::writeMorphGeometry(osgAnimation::MorphGeometry *pOsgMorphGeometry) 
     235{ 
     236    // See if controller exists in cache 
     237    OsgMorphGeometryDomControllerMap::iterator iter = _osgMorphGeometryDomControllerMap.find(pOsgMorphGeometry); 
     238    domController* pDomController = NULL; 
     239    if ( iter != _osgMorphGeometryDomControllerMap.end() ) 
     240    { 
     241        pDomController = iter->second; 
     242    } 
     243    else 
     244    { 
     245        domGeometry* pDomGeometry = getOrCreateDomGeometry(pOsgMorphGeometry); 
     246        if (pDomGeometry) 
     247        { 
     248            if (!lib_controllers) 
     249            { 
     250                lib_controllers = daeSafeCast< domLibrary_controllers >( dom->add( COLLADA_ELEMENT_LIBRARY_CONTROLLERS ) ); 
     251            } 
     252 
     253            // <controller> 
     254            // 1 <morph source (method)> 
     255            //     2..*    <source> 
     256            //   1        <targets> 
     257            //        2..*    <input semantic source> 
     258            //        0..*    <extra> 
     259            //   0..* <extra> 
     260            pDomController = daeSafeCast< domController >( lib_controllers->add( COLLADA_ELEMENT_CONTROLLER) ); 
     261            std::string name = pOsgMorphGeometry->getName(); 
     262            if (name.empty()) 
     263                name = uniquify("morphcontroller"); 
     264            else  
     265                name = uniquify(name); 
     266            pDomController->setId( name.c_str() ); 
     267            _osgMorphGeometryDomControllerMap.insert( std::make_pair( pOsgMorphGeometry, pDomController ) ); 
     268 
     269            // Link <morph> to cache hit or created <geometry> 
     270            domMorph* pDomMorph = daeSafeCast< domMorph >(pDomController->add( COLLADA_ELEMENT_MORPH )); 
     271            std::string url = "#" + std::string(pDomGeometry->getId()); 
     272            pDomMorph->setSource(url.c_str()); 
     273            pDomMorph->setMethod(MORPHMETHODTYPE_NORMALIZED); 
     274            //pDomMorph->setMethod(MORPHMETHODTYPE_RELATIVE); 
     275 
     276            domSource* pDomTargetsSource = daeSafeCast< domSource >(pDomMorph->add( COLLADA_ELEMENT_SOURCE )); 
     277            std::string targetsName = name + "_morph_targets"; 
     278            pDomTargetsSource->setId(targetsName.c_str()); 
     279 
     280            domIDREF_array* pDomIDREFArray = daeSafeCast< domIDREF_array >(pDomTargetsSource->add(COLLADA_ELEMENT_IDREF_ARRAY)); 
     281            xsIDREFS idrefs; 
     282            osgAnimation::MorphGeometry::MorphTargetList morphTargetList = pOsgMorphGeometry->getMorphTargetList(); 
     283            for (unsigned int i=0; i < morphTargetList.size(); i++) 
     284            { 
     285                domGeometry* pDomGeometry = getOrCreateDomGeometry(morphTargetList[i].getGeometry()); 
     286                idrefs.append(pDomGeometry->getId()); 
     287            } 
     288            pDomIDREFArray->setValue(idrefs); 
     289            std::string targetsArrayName = targetsName + "_array"; 
     290            pDomIDREFArray->setId(targetsArrayName.c_str()); 
     291            pDomIDREFArray->setCount(morphTargetList.size()); 
     292 
     293            domSource::domTechnique_common* pDomTechniqueCommon = daeSafeCast< domSource::domTechnique_common >(pDomTargetsSource->add(COLLADA_ELEMENT_TECHNIQUE_COMMON)); 
     294            domAccessor* pDomAccessor = daeSafeCast< domAccessor >(pDomTechniqueCommon->add(COLLADA_ELEMENT_ACCESSOR)); 
     295            pDomAccessor->setCount(morphTargetList.size()); 
     296            url = "#" + targetsArrayName; 
     297            pDomAccessor->setSource(url.c_str()); 
     298 
     299            domParam* pDomParam = daeSafeCast< domParam >(pDomAccessor->add(COLLADA_ELEMENT_PARAM)); 
     300            pDomParam->setName(COMMON_PROFILE_INPUT_MORPH_TARGET); 
     301            pDomParam->setType("IDREF"); // COLLADA_TYPE_IDREF does not exist 
     302 
     303            domSource* pDomWeightsSource = daeSafeCast< domSource >(pDomMorph->add( COLLADA_ELEMENT_SOURCE )); 
     304            std::string weightsName = name + "_morph_weights"; 
     305            pDomWeightsSource->setId(weightsName.c_str()); 
     306 
     307            domFloat_array* pDomFloatArray = daeSafeCast< domFloat_array >(pDomWeightsSource->add(COLLADA_ELEMENT_FLOAT_ARRAY)); 
     308            domListOfFloats weights; 
     309            for (unsigned int i=0; i < morphTargetList.size(); i++) 
     310            { 
     311                weights.append(morphTargetList[i].getWeight()); 
     312            } 
     313            pDomFloatArray->setValue(weights); 
     314            std::string weigthsArrayName = weightsName + "_array"; 
     315            pDomFloatArray->setId(weigthsArrayName.c_str()); 
     316            pDomFloatArray->setCount(morphTargetList.size()); 
     317 
     318            pDomTechniqueCommon = daeSafeCast< domSource::domTechnique_common >(pDomWeightsSource->add(COLLADA_ELEMENT_TECHNIQUE_COMMON)); 
     319            pDomAccessor = daeSafeCast< domAccessor >(pDomTechniqueCommon->add(COLLADA_ELEMENT_ACCESSOR)); 
     320            pDomAccessor->setCount(morphTargetList.size()); 
     321            url = "#" + weightsName; 
     322            pDomAccessor->setSource(url.c_str()); 
     323 
     324            pDomParam = daeSafeCast< domParam >(pDomAccessor->add(COLLADA_ELEMENT_PARAM)); 
     325            pDomParam->setName(COMMON_PROFILE_INPUT_MORPH_WEIGHT); 
     326            pDomParam->setType(COLLADA_TYPE_FLOAT); 
     327 
     328            domMorph::domTargets* pDomTargets = daeSafeCast< domMorph::domTargets >(pDomMorph->add( COLLADA_ELEMENT_TARGETS )); 
     329 
     330            domInputLocal* pDomTargetsInput = daeSafeCast< domInputLocal >(pDomTargets->add( COLLADA_ELEMENT_INPUT )); 
     331            pDomTargetsInput->setSemantic(COMMON_PROFILE_INPUT_MORPH_TARGET); 
     332            url = "#" + targetsName; 
     333            pDomTargetsInput->setSource(url.c_str()); 
     334 
     335            domInputLocal* pDomWeightsInput = daeSafeCast< domInputLocal >(pDomTargets->add( COLLADA_ELEMENT_INPUT )); 
     336            pDomWeightsInput->setSemantic(COMMON_PROFILE_INPUT_MORPH_WEIGHT); 
     337            url = "#" + weightsName; 
     338            pDomWeightsInput->setSource(url.c_str()); 
     339        } 
     340    } 
     341 
     342    if (pDomController) 
     343    { 
     344        // Transparency at drawable level 
     345        if (pOsgMorphGeometry->getStateSet()) 
     346            m_CurrentRenderingHint = pOsgMorphGeometry->getStateSet()->getRenderingHint(); 
     347 
     348        pushStateSet(pOsgMorphGeometry->getStateSet()); 
     349 
     350        // Link <instance_controller> to cache hit or created <controller> 
     351        domInstance_controller* pDomInstanceController = daeSafeCast< domInstance_controller >( currentNode->add( COLLADA_ELEMENT_INSTANCE_CONTROLLER ) ); 
     352        std::string url = "#" + std::string(pDomController->getId()); 
     353        pDomInstanceController->setUrl( url.c_str() ); 
     354 
     355        if (!stateSetStack.empty()) 
     356        { 
     357            domBind_material *pDomBindMaterial = daeSafeCast< domBind_material >( pDomInstanceController->add( COLLADA_ELEMENT_BIND_MATERIAL ) ); 
     358            processMaterial( currentStateSet.get(), pDomBindMaterial, pOsgMorphGeometry->getName() ); 
     359        } 
     360 
     361        popStateSet(pOsgMorphGeometry->getStateSet()); 
     362    } 
     363} 
    26364 
    27365void daeWriter::apply( osg::Geode &node ) 
     
    43381        if ( g != NULL ) 
    44382        { 
    45             // Transparency at drawable level 
    46             if (NULL != g->getStateSet()) 
    47                 m_CurrentRenderingHint = g->getStateSet()->getRenderingHint(); 
    48  
    49             pushStateSet(g->getStateSet()); 
    50             std::map< osg::Geometry*, domGeometry *>::iterator iter = geometryMap.find( g ); 
    51             if ( iter != geometryMap.end() ) 
    52             { 
    53                 domInstance_geometry *ig = daeSafeCast< domInstance_geometry >( currentNode->add( COLLADA_ELEMENT_INSTANCE_GEOMETRY ) ); 
     383            osgAnimation::RigGeometry *pOsgRigGeometry = dynamic_cast<osgAnimation::RigGeometry*>(g); 
     384            if (pOsgRigGeometry) 
     385            { 
     386                writeRigGeometry(pOsgRigGeometry); 
     387            } 
     388            else 
     389            { 
     390                osgAnimation::MorphGeometry *pOsgMorphGeometry = dynamic_cast<osgAnimation::MorphGeometry*>(g); 
     391                if (pOsgMorphGeometry) 
     392                { 
     393                    writeMorphGeometry(pOsgMorphGeometry); 
     394                } 
     395                else 
     396                { 
     397                    // Write a default osg::Geometry 
     398 
     399                    // Transparency at drawable level 
     400                    if (NULL != g->getStateSet()) 
     401                        m_CurrentRenderingHint = g->getStateSet()->getRenderingHint(); 
     402 
     403                    pushStateSet(g->getStateSet()); 
    54404                     
    55                 std::string url = "#" + std::string( iter->second->getId() ); 
    56                 ig->setUrl( url.c_str() ); 
    57                 if (!stateSetStack.empty()) 
    58                     processMaterial( currentStateSet.get(), ig, iter->second->getId() ); 
    59             } 
    60             else 
    61             { 
    62                 if ( lib_geoms == NULL ) 
    63                 { 
    64                     lib_geoms = daeSafeCast< domLibrary_geometries >( dom->add( COLLADA_ELEMENT_LIBRARY_GEOMETRIES ) ); 
    65                 } 
    66                 std::string name = node.getName(); 
    67                 if ( name.empty() ) name = "geometry"; 
    68                 name = uniquify( name ); 
    69  
    70                 domGeometryRef geo = daeSafeCast< domGeometry >( lib_geoms->add( COLLADA_ELEMENT_GEOMETRY ) ); 
    71                 geo->setId( name.c_str() ); 
    72  
    73                 if ( !processGeometry( g, geo, name ) ) 
    74                 { 
    75                     daeElement::removeFromParent( geo ); 
    76                     continue; 
    77                 } 
    78  
    79                 domInstance_geometry *ig = daeSafeCast< domInstance_geometry >( currentNode->add( COLLADA_ELEMENT_INSTANCE_GEOMETRY ) ); 
    80                      
    81                 std::string url = "#" + name; 
    82                 ig->setUrl( url.c_str() ); 
    83  
    84 #ifndef EARTH_GEO 
    85                 geometryMap.insert( std::make_pair( g, geo ) ); 
    86 #endif 
    87  
    88                 if (!stateSetStack.empty()) 
    89                     processMaterial( currentStateSet.get(), ig, name ); 
    90             } 
    91             popStateSet(g->getStateSet()); 
     405                    domGeometry* pDomGeometry = getOrCreateDomGeometry(g); 
     406                    if (pDomGeometry) 
     407                    { 
     408                        // Link <instance_geometry> to cache hit or created <geometry> 
     409                        domInstance_geometry *pDomInstanceGeometry = daeSafeCast< domInstance_geometry >( currentNode->add( COLLADA_ELEMENT_INSTANCE_GEOMETRY ) ); 
     410                        std::string url = "#" + std::string(pDomGeometry->getId()); 
     411                        pDomInstanceGeometry->setUrl( url.c_str() ); 
     412 
     413                        if (!stateSetStack.empty()) 
     414                        { 
     415                            domBind_material *pDomBindMaterial = daeSafeCast< domBind_material >( pDomInstanceGeometry->add( COLLADA_ELEMENT_BIND_MATERIAL ) ); 
     416                            processMaterial( currentStateSet.get(), pDomBindMaterial, pDomGeometry->getId() ); 
     417                        } 
     418                    } 
     419 
     420                    popStateSet(g->getStateSet()); 
     421                } 
     422            } 
     423        } 
     424        else 
     425        { 
     426            osg::notify( osg::WARN ) << "Non-geometry drawables are not supported" << std::endl; 
    92427        } 
    93428    } 
     
    143478    domSource *color = NULL; 
    144479    std::vector< domSource * >texcoord; 
     480    std::vector< domSource * > vertexAttribute; 
    145481    domLines *lines = NULL; 
    146482    domLinestrips *linestrips = NULL; 
     
    149485    domTrifans *trifans = NULL; 
    150486    domPolygons *polys = NULL; 
    151         domPolylist *polylist = NULL; 
     487    domPolylist *polylist = NULL; 
    152488     
    153     //TODO: Make sure the assumptions about arrays is correct. 
    154     // Probably not so I should make each thing more flexible so arrays can be different sizes. 
    155  
    156     /*osg::Vec3Array *verts = (osg::Vec3Array *)geom->getVertexArray(); 
    157     osg::IndexArray *vertInds = geom->getVertexIndices(); 
    158  
    159     osg::Vec3Array *normals = (osg::Vec3Array *)geom->getNormalArray(); 
    160     osg::IndexArray *normalInds = geom->getNormalIndices(); 
    161  
    162     osg::Vec4Array *colors = (osg::Vec4Array *)geom->getColorArray(); 
    163     osg::IndexArray *colorInds = geom->getColorIndices();*/ 
    164  
    165489    ArrayNIndices verts( geom->getVertexArray(), geom->getVertexIndices() ); 
    166490    ArrayNIndices normals( geom->getNormalArray(), geom->getNormalIndices() ); 
    167491    ArrayNIndices colors( geom->getColorArray(), geom->getColorIndices() ); 
     492 
     493    // RS BUG 
     494    // getNumTexCoordArrays may return larger number 
     495    // where getTexCoordArray(0) may have a BIND_OFF and an empty arrat 
    168496    std::vector<ArrayNIndices> texcoords; 
    169497    for ( unsigned int i = 0; i < geom->getNumTexCoordArrays(); i++ ) 
    170498    { 
    171         texcoords.push_back( ArrayNIndices( geom->getTexCoordArray( i ), geom->getTexCoordIndices( i ) ) ); 
    172     } 
    173          
    174     //process POSITION 
     499        if (geom->getTexCoordArray(i)) 
     500        { 
     501            texcoords.push_back( ArrayNIndices( geom->getTexCoordArray( i ), geom->getTexCoordIndices( i ) ) ); 
     502        } 
     503    } 
     504    std::vector<ArrayNIndices> vertexAttributes; 
     505    for ( unsigned int i = 0; i < geom->getNumVertexAttribArrays(); i++ ) 
     506    { 
     507        if (geom->getVertexAttribArray(i)) 
     508        { 
     509            vertexAttributes.push_back(ArrayNIndices( geom->getVertexAttribArray( i ), geom->getVertexAttribIndices(i))); 
     510        } 
     511    } 
     512        
     513    // process POSITION 
    175514    std::string sName = name + "-positions"; 
    176515    pos = createSource( mesh, sName, verts.mode ); 
     
    219558 
    220559    //make a POSITION input in it 
    221     domInputLocal *il = daeSafeCast< domInputLocal >( vertices->add( COLLADA_ELEMENT_INPUT) ); 
    222     il->setSemantic(COMMON_PROFILE_INPUT_POSITION); 
     560    domInputLocal *il = daeSafeCast< domInputLocal >( vertices->add( COLLADA_ELEMENT_INPUT ) ); 
     561    il->setSemantic( COMMON_PROFILE_INPUT_POSITION ); 
    223562    std::string url = "#" + std::string( pos->getId() ); 
    224563    il->setSource( url.c_str() ); 
     
    273612        //if NORMAL shares same indices as POSITION put it in the vertices 
    274613        /*if ( normalInds == vertInds && vertInds != NULL ) { 
    275             il = daeSafeCast< domInputLocal >( vertices->add( COLLADA_ELEMENT_INPUT) ); 
    276             il->setSemantic(COMMON_PROFILE_INPUT_NORMAL); 
     614            il = daeSafeCast< domInputLocal >( vertices->add( COLLADA_ELEMENT_INPUT ) ); 
     615            il->setSemantic( COMMON_PROFILE_INPUT_NORMAL ); 
    277616            url = "#" + std::string(md->norm->getId()); 
    278617            il->setSource( url.c_str() ); 
     
    324663        //if COLOR shares same indices as POSITION put it in the vertices 
    325664        /*if ( colorInds == vertInds && vertInds != NULL ) { 
    326             il = daeSafeCast< domInputLocal >( vertices->add( COLLADA_ELEMENT_INPUT) ); 
    327             il->setSemantic(COMMON_PROFILE_INPUT_COLOR); 
     665            il = daeSafeCast< domInputLocal >( vertices->add( COLLADA_ELEMENT_INPUT ) ); 
     666            il->setSemantic( COMMON_PROFILE_INPUT_COLOR ); 
    328667            url = "#" + std::string(md->color->getId()); 
    329668            il->setSource( url.c_str() ); 
     
    366705            for ( unsigned int i = 0; i < texcoords[ti].vec4->size(); i++ ) 
    367706            { 
    368                 t->getFloat_array()->getValue().append( (*texcoords[i].vec4)[ti].x() ); 
    369                 t->getFloat_array()->getValue().append( (*texcoords[i].vec4)[ti].y() ); 
    370                 t->getFloat_array()->getValue().append( (*texcoords[i].vec4)[ti].z() ); 
    371                 t->getFloat_array()->getValue().append( (*texcoords[i].vec4)[ti].w() ); 
     707                t->getFloat_array()->getValue().append( (*texcoords[ti].vec4)[i].x() ); 
     708                t->getFloat_array()->getValue().append( (*texcoords[ti].vec4)[i].y() ); 
     709                t->getFloat_array()->getValue().append( (*texcoords[ti].vec4)[i].z() ); 
     710                t->getFloat_array()->getValue().append( (*texcoords[ti].vec4)[i].w() ); 
    372711            } 
    373712            break; 
     
    378717        } 
    379718        texcoord.push_back( t ); 
     719    } 
     720 
     721    //RS 
     722    //process TEXCOORD 
     723    //TODO: Do the same as normal and colors for texcoods. But in a loop since you can have many 
     724    for ( unsigned int ti = 0; ti < vertexAttributes.size(); ti++ ) 
     725    { 
     726        if (vertexAttributes[ti].mode != ArrayNIndices::NONE) 
     727        { 
     728            std::ostringstream intstr; 
     729            intstr << std::dec << ti; 
     730            sName = name + "-vertexAttribute_" + intstr.str(); 
     731 
     732            domSource *t = createSource( mesh, sName, vertexAttributes[ti].mode, false, true ); 
     733            switch( vertexAttributes[ti].mode ) 
     734            { 
     735            case ArrayNIndices::VEC2: 
     736                t->getFloat_array()->setCount( vertexAttributes[ti].vec2->size() *2 ); 
     737                t->getTechnique_common()->getAccessor()->setCount( vertexAttributes[ti].vec2->size() ); 
     738                for ( unsigned int i = 0; i < vertexAttributes[ti].vec2->size(); i++ ) 
     739                { 
     740                    t->getFloat_array()->getValue().append( (*vertexAttributes[ti].vec2)[i].x() ); 
     741                    t->getFloat_array()->getValue().append( (*vertexAttributes[ti].vec2)[i].y() ); 
     742                } 
     743                break; 
     744            case ArrayNIndices::VEC3: 
     745                t->getFloat_array()->setCount( vertexAttributes[ti].vec3->size() *3 ); 
     746                t->getTechnique_common()->getAccessor()->setCount( vertexAttributes[ti].vec3->size() ); 
     747                for ( unsigned int i = 0; i < vertexAttributes[ti].vec3->size(); i++ ) 
     748                { 
     749                    t->getFloat_array()->getValue().append( (*vertexAttributes[ti].vec3)[i].x() ); 
     750                    t->getFloat_array()->getValue().append( (*vertexAttributes[ti].vec3)[i].y() ); 
     751                    t->getFloat_array()->getValue().append( (*vertexAttributes[ti].vec3)[i].z() ); 
     752                } 
     753                break; 
     754            case ArrayNIndices::VEC4: 
     755                t->getFloat_array()->setCount( vertexAttributes[ti].vec4->size() *4 ); 
     756                t->getTechnique_common()->getAccessor()->setCount( vertexAttributes[ti].vec4->size() ); 
     757                for ( unsigned int i = 0; i < vertexAttributes[ti].vec4->size(); i++ ) 
     758                { 
     759                    t->getFloat_array()->getValue().append( (*vertexAttributes[ti].vec4)[i].x() ); 
     760                    t->getFloat_array()->getValue().append( (*vertexAttributes[ti].vec4)[i].y() ); 
     761                    t->getFloat_array()->getValue().append( (*vertexAttributes[ti].vec4)[i].z() ); 
     762                    t->getFloat_array()->getValue().append( (*vertexAttributes[ti].vec4)[i].w() ); 
     763                } 
     764                break; 
     765            default: 
     766              //##ti and not i 
     767                osg::notify( osg::WARN ) << "Invalid array type for vertex attribute" << ti << std::endl; 
     768                break; 
     769            } 
     770            vertexAttribute.push_back( t ); 
     771        } 
     772        else 
     773        { 
     774            osg::notify( osg::WARN ) << "Invalid array type for vertex attribute" << ti << std::endl; 
     775        } 
    380776    } 
    381777 
     
    11361532    unsigned int offset = 0; 
    11371533    Ty *retVal = daeSafeCast< Ty >( mesh->add( type ) ); 
    1138     domInputLocalOffset *ilo = daeSafeCast< domInputLocalOffset >(retVal->add( COLLADA_ELEMENT_INPUT)); 
     1534    domInputLocalOffset *ilo = daeSafeCast< domInputLocalOffset >( retVal->add( COLLADA_ELEMENT_INPUT ) ); 
    11391535    ilo->setOffset( offset++ ); 
    1140     ilo->setSemantic(COMMON_PROFILE_INPUT_VERTEX); 
     1536    ilo->setSemantic( COMMON_PROFILE_INPUT_VERTEX ); 
    11411537    std::string url = "#" + std::string(mesh->getVertices()->getId()); 
    11421538    ilo->setSource( url.c_str() ); 
    11431539    if ( norm != NULL ) 
    11441540    { 
    1145         ilo = daeSafeCast< domInputLocalOffset >( retVal->add(COLLADA_ELEMENT_INPUT)); 
     1541        ilo = daeSafeCast< domInputLocalOffset >( retVal->add( COLLADA_ELEMENT_INPUT ) ); 
    11461542        ilo->setOffset( offset++ ); 
    1147         ilo->setSemantic( COMMON_PROFILE_INPUT_NORMAL); 
     1543        ilo->setSemantic( COMMON_PROFILE_INPUT_NORMAL ); 
    11481544        url = "#" + std::string( norm->getId() ); 
    11491545        ilo->setSource( url.c_str() ); 
     
    11511547    if ( color != NULL ) 
    11521548    { 
    1153         ilo = daeSafeCast< domInputLocalOffset >( retVal->add(COLLADA_ELEMENT_INPUT)); 
     1549        ilo = daeSafeCast< domInputLocalOffset >( retVal->add( COLLADA_ELEMENT_INPUT ) ); 
    11541550        ilo->setOffset( offset++ ); 
    1155         ilo->setSemantic(COMMON_PROFILE_INPUT_COLOR); 
     1551        ilo->setSemantic( COMMON_PROFILE_INPUT_COLOR ); 
    11561552        url = "#" + std::string( color->getId() ); 
    11571553        ilo->setSource( url.c_str() ); 
     
    11591555    for ( unsigned int i = 0; i < texcoord.size(); i++ ) 
    11601556    { 
    1161         ilo = daeSafeCast< domInputLocalOffset >( retVal->add(COLLADA_ELEMENT_INPUT)); 
     1557        ilo = daeSafeCast< domInputLocalOffset >( retVal->add( COLLADA_ELEMENT_INPUT ) ); 
    11621558        ilo->setOffset( offset++ ); 
    1163         ilo->setSemantic(COMMON_PROFILE_INPUT_TEXCOORD); 
     1559        ilo->setSemantic( COMMON_PROFILE_INPUT_TEXCOORD ); 
    11641560        ilo->setSet( i ); 
    11651561        url = "#" + std::string( texcoord[i]->getId() ); 
  • OpenSceneGraph/trunk/src/osgPlugins/dae/daeWMaterials.cpp

    r10234 r11129  
    2929#endif 
    3030 
    31 using namespace osgdae; 
    32  
    33 void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, const std::string &geoName ) 
     31using namespace osgDAE; 
     32 
     33void daeWriter::processMaterial( osg::StateSet *ss, domBind_material *pDomBindMaterial, const std::string &geoName ) 
    3434{ 
    3535    osg::ref_ptr<osg::StateSet> ssClean = CleanStateSet(ss); // Need to hold a ref to this or the materialMap.find() will delete it 
    36     domBind_material *bm = daeSafeCast< domBind_material >( ig->add( COLLADA_ELEMENT_BIND_MATERIAL ) ); 
    37     domBind_material::domTechnique_common *tc = daeSafeCast< domBind_material::domTechnique_common >( bm->add(COLLADA_ELEMENT_TECHNIQUE_COMMON)); 
    38     domInstance_material *im = daeSafeCast< domInstance_material >( tc->add( COLLADA_ELEMENT_INSTANCE_MATERIAL ) ); 
     36    domBind_material::domTechnique_common *tc = daeSafeCast< domBind_material::domTechnique_common >( pDomBindMaterial->add( COLLADA_ELEMENT_TECHNIQUE_COMMON ) ); 
     37    domInstance_material *pDomInstanceMaterial = daeSafeCast< domInstance_material >( tc->add( COLLADA_ELEMENT_INSTANCE_MATERIAL ) ); 
    3938    std::string symbol = geoName + "_material"; 
    40     im->setSymbol( symbol.c_str() ); 
    41  
     39    pDomInstanceMaterial->setSymbol( symbol.c_str() ); 
     40 
     41    // See if material already exists in cache 
    4242    MaterialMap::iterator iter = materialMap.find( ssClean ); 
    4343    if ( iter != materialMap.end() ) 
    4444    { 
    4545        std::string url = "#" + std::string( iter->second->getId() ); 
    46         im->setTarget( url.c_str() ); 
     46        pDomInstanceMaterial->setTarget( url.c_str() ); 
    4747        return; 
    4848    } 
     
    6464 
    6565    std::string url = "#" + name; 
    66     im->setTarget( url.c_str() ); 
     66    pDomInstanceMaterial->setTarget( url.c_str() ); 
    6767 
    6868    domInstance_effect *ie = daeSafeCast<domInstance_effect>( mat->add( COLLADA_ELEMENT_INSTANCE_EFFECT ) ); 
     
    8383    domProfile_COMMON::domTechnique *pc_teq = daeSafeCast< domProfile_COMMON::domTechnique >( pc->add( COLLADA_ELEMENT_TECHNIQUE ) ); 
    8484    pc_teq->setSid( "t0" ); 
    85     domProfile_COMMON::domTechnique::domPhong *phong = daeSafeCast< domProfile_COMMON::domTechnique::domPhong >( pc_teq->add(COLLADA_ELEMENT_PHONG)); 
     85    domProfile_COMMON::domTechnique::domPhong *phong = daeSafeCast< domProfile_COMMON::domTechnique::domPhong >( pc_teq->add( COLLADA_ELEMENT_PHONG ) ); 
    8686 
    8787    osg::Texture *tex = static_cast<osg::Texture*>(ssClean->getTextureAttribute( 0, osg::StateAttribute::TEXTURE )); 
     
    9898 
    9999        osg::Image *osgimg = tex->getImage( 0 ); 
    100         domImage::domInit_from *imgif = daeSafeCast< domImage::domInit_from >( img->add(COLLADA_ELEMENT_INIT_FROM)); 
     100 
     101        domImage::domInit_from *imgif = daeSafeCast< domImage::domInit_from >( img->add( COLLADA_ELEMENT_INIT_FROM ) ); 
    101102        std::string fileURI = ReaderWriterDAE::ConvertFilePathToColladaCompatibleURI(osgDB::findDataFile(osgimg->getFileName())); 
    102        daeURI dd(*dae, fileURI);//fileURI.c_str() ); 
     103        daeURI dd(*dae, fileURI); 
    103104        imgif->setValue( dd ); 
    104105        // The document URI should contain the canonical path it was created with 
    105106        imgif->getValue().makeRelativeTo(doc->getDocumentURI()); 
    106107 
     108 
    107109#ifndef EARTH_TEX 
    108         domCommon_newparam_type *np = daeSafeCast< domCommon_newparam_type >(pc->add(COLLADA_ELEMENT_NEWPARAM)); 
     110        domCommon_newparam_type *np = daeSafeCast< domCommon_newparam_type >( pc->add(COLLADA_ELEMENT_NEWPARAM) ); 
    109111        std::string surfName = efName + "-surface"; 
    110112        np->setSid( surfName.c_str() ); 
    111         domFx_surface_common *surface = daeSafeCast< domFx_surface_common >(np->add(COLLADA_ELEMENT_SURFACE)); 
    112         domFx_surface_init_from_common *sif = daeSafeCast< domFx_surface_init_from_common >( surface->add(COLLADA_ELEMENT_INIT_FROM)); 
     113        domFx_surface_common *surface = daeSafeCast< domFx_surface_common >( np->add(COLLADA_ELEMENT_SURFACE) ); 
     114        domFx_surface_init_from_common *sif = daeSafeCast< domFx_surface_init_from_common >( surface->add(COLLADA_ELEMENT_INIT_FROM) ); 
    113115        sif->setValue( iName.c_str() ); 
    114116        surface->setType( FX_SURFACE_TYPE_ENUM_2D ); 
    115117 
    116         np = daeSafeCast< domCommon_newparam_type >( pc->add(COLLADA_ELEMENT_NEWPARAM)); 
     118        np = daeSafeCast< domCommon_newparam_type >( pc->add( COLLADA_ELEMENT_NEWPARAM ) ); 
    117119        std::string sampName = efName + "-sampler"; 
    118120        np->setSid( sampName.c_str() ); 
    119         domFx_sampler2D_common *sampler = daeSafeCast< domFx_sampler2D_common >( np->add(COLLADA_ELEMENT_SAMPLER2D) ); 
    120         domFx_sampler2D_common_complexType::domSource *source = daeSafeCast< domFx_sampler2D_common_complexType::domSource >(sampler->add(COLLADA_ELEMENT_SOURCE)); 
     121        domFx_sampler2D_common *sampler = daeSafeCast< domFx_sampler2D_common >( np->add( COLLADA_ELEMENT_SAMPLER2D ) ); 
     122        domFx_sampler2D_common_complexType::domSource *source = daeSafeCast< domFx_sampler2D_common_complexType::domSource >( sampler->add( COLLADA_ELEMENT_SOURCE ) ); 
    121123        source->setValue( surfName.c_str() );  
    122124 
    123125        //set sampler state 
    124         domFx_sampler2D_common_complexType::domWrap_s *wrap_s = daeSafeCast< domFx_sampler2D_common_complexType::domWrap_s >(sampler->add(COLLADA_ELEMENT_WRAP_S)); 
     126        domFx_sampler2D_common_complexType::domWrap_s *wrap_s = daeSafeCast< domFx_sampler2D_common_complexType::domWrap_s >( sampler->add( COLLADA_ELEMENT_WRAP_S ) ); 
    125127        osg::Texture::WrapMode wrap = tex->getWrap( osg::Texture::WRAP_S ); 
    126128        switch( wrap )  
     
    144146        } 
    145147 
    146         domFx_sampler2D_common_complexType::domWrap_t *wrap_t = daeSafeCast< domFx_sampler2D_common_complexType::domWrap_t >(sampler->add( COLLADA_ELEMENT_WRAP_T)); 
     148        domFx_sampler2D_common_complexType::domWrap_t *wrap_t = daeSafeCast< domFx_sampler2D_common_complexType::domWrap_t >( sampler->add( COLLADA_ELEMENT_WRAP_T ) ); 
    147149        wrap = tex->getWrap( osg::Texture::WRAP_T ); 
    148150        switch( wrap )  
     
    167169 
    168170        const osg::Vec4 &bcol = tex->getBorderColor(); 
    169         domFx_sampler2D_common_complexType::domBorder_color *dbcol = daeSafeCast< domFx_sampler2D_common_complexType::domBorder_color >(sampler->add(COLLADA_ELEMENT_BORDER_COLOR)); 
     171        domFx_sampler2D_common_complexType::domBorder_color *dbcol = daeSafeCast< domFx_sampler2D_common_complexType::domBorder_color >( sampler->add( COLLADA_ELEMENT_BORDER_COLOR ) ); 
    170172        dbcol->getValue().append( bcol.r() ); 
    171173        dbcol->getValue().append( bcol.g() ); 
     
    173175        dbcol->getValue().append( bcol.a() ); 
    174176 
    175         domFx_sampler2D_common_complexType::domMinfilter *minfilter = daeSafeCast< domFx_sampler2D_common_complexType::domMinfilter >(sampler->add(COLLADA_ELEMENT_MINFILTER)); 
     177        domFx_sampler2D_common_complexType::domMinfilter *minfilter = daeSafeCast< domFx_sampler2D_common_complexType::domMinfilter >( sampler->add( COLLADA_ELEMENT_MINFILTER ) ); 
    176178        osg::Texture::FilterMode mode = tex->getFilter( osg::Texture::MIN_FILTER ); 
    177179        switch( mode ) 
     
    197199        } 
    198200 
    199         domFx_sampler2D_common_complexType::domMagfilter *magfilter = daeSafeCast< domFx_sampler2D_common_complexType::domMagfilter >(sampler->add(COLLADA_ELEMENT_MAGFILTER)); 
     201        domFx_sampler2D_common_complexType::domMagfilter *magfilter = daeSafeCast< domFx_sampler2D_common_complexType::domMagfilter >( sampler->add( COLLADA_ELEMENT_MAGFILTER ) ); 
    200202        mode = tex->getFilter( osg::Texture::MAG_FILTER ); 
    201203        switch( mode ) 
     
    222224 
    223225 
    224         domCommon_color_or_texture_type *cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add(COLLADA_ELEMENT_DIFFUSE) ); 
    225         domCommon_color_or_texture_type_complexType::domTexture *dtex = daeSafeCast< domCommon_color_or_texture_type_complexType::domTexture >(cot->add(COLLADA_ELEMENT_TEXTURE)); 
     226        domCommon_color_or_texture_type *cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add( COLLADA_ELEMENT_DIFFUSE ) ); 
     227        domCommon_color_or_texture_type_complexType::domTexture *dtex = daeSafeCast< domCommon_color_or_texture_type_complexType::domTexture >( cot->add( COLLADA_ELEMENT_TEXTURE ) ); 
    226228        dtex->setTexture( sampName.c_str() ); 
    227229        dtex->setTexcoord( "texcoord0" ); 
    228230#else 
    229         domCommon_color_or_texture_type *cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add(COLLADA_ELEMENT_DIFFUSE) ); 
    230         domCommon_color_or_texture_type_complexType::domTexture *dtex = daeSafeCast< domCommon_color_or_texture_type_complexType::domTexture >( cot->add(COLLADA_ELEMENT_TEXTURE)); 
     231        domCommon_color_or_texture_type *cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add( COLLADA_ELEMENT_DIFFUSE ) ); 
     232        domCommon_color_or_texture_type_complexType::domTexture *dtex = daeSafeCast< domCommon_color_or_texture_type_complexType::domTexture >( cot->add( COLLADA_ELEMENT_TEXTURE ) ); 
    231233        dtex->setTexture( iName.c_str() ); 
    232234        dtex->setTexcoord( "texcoord0" ); 
    233235#endif 
    234236 
    235         domInstance_material::domBind_vertex_input *bvi = daeSafeCast< domInstance_material::domBind_vertex_input >(im->add(COLLADA_ELEMENT_BIND_VERTEX_INPUT)); 
     237        domInstance_material::domBind_vertex_input *bvi = daeSafeCast< domInstance_material::domBind_vertex_input >( pDomInstanceMaterial->add( COLLADA_ELEMENT_BIND_VERTEX_INPUT ) ); 
    236238        bvi->setSemantic( "texcoord0" ); 
    237         bvi->setInput_semantic( "TEXCOORD" ); 
     239        bvi->setInput_semantic( COMMON_PROFILE_INPUT_TEXCOORD ); 
    238240        bvi->setInput_set( 0 ); 
    239241    } 
     
    247249        float shininess = osgmat->getShininessFrontAndBack()?osgmat->getShininess( osg::Material::FRONT_AND_BACK ):osgmat->getShininess( osg::Material::FRONT ); 
    248250         
    249         domCommon_color_or_texture_type *cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add(COLLADA_ELEMENT_EMISSION)); 
    250         domCommon_color_or_texture_type_complexType::domColor *col = daeSafeCast< domCommon_color_or_texture_type_complexType::domColor >( cot->add(COLLADA_ELEMENT_COLOR)); 
     251        domCommon_color_or_texture_type *cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add( COLLADA_ELEMENT_EMISSION ) ); 
     252        domCommon_color_or_texture_type_complexType::domColor *col = daeSafeCast< domCommon_color_or_texture_type_complexType::domColor >( cot->add( COLLADA_ELEMENT_COLOR ) ); 
    251253        col->getValue().append( eCol.r() ); 
    252254        col->getValue().append( eCol.g() ); 
     
    254256        col->getValue().append( eCol.a() ); 
    255257 
    256         cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add(COLLADA_ELEMENT_AMBIENT)); 
    257         col = daeSafeCast< domCommon_color_or_texture_type_complexType::domColor >(cot->add(COLLADA_ELEMENT_COLOR)); 
     258        cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add( COLLADA_ELEMENT_AMBIENT ) ); 
     259        col = daeSafeCast< domCommon_color_or_texture_type_complexType::domColor >( cot->add( COLLADA_ELEMENT_COLOR ) ); 
    258260        col->getValue().append( aCol.r() ); 
    259261        col->getValue().append( aCol.g() ); 
     
    265267        if ( phong->getDiffuse() == NULL ) 
    266268        { 
    267             cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add(COLLADA_ELEMENT_DIFFUSE)); 
    268             col = daeSafeCast< domCommon_color_or_texture_type_complexType::domColor >( cot->add(COLLADA_ELEMENT_COLOR)); 
     269            cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add( COLLADA_ELEMENT_DIFFUSE ) ); 
     270            col = daeSafeCast< domCommon_color_or_texture_type_complexType::domColor >( cot->add( COLLADA_ELEMENT_COLOR ) ); 
    269271            col->getValue().append( dCol.r() ); 
    270272            col->getValue().append( dCol.g() ); 
     
    291293                domTechnique *teq = daeSafeCast< domTechnique >( extra->add( COLLADA_ELEMENT_TECHNIQUE ) ); 
    292294                teq->setProfile( "SCEI" ); 
    293                 domAny *any = (domAny*)(daeElement*)teq->add(COLLADA_ELEMENT_COLOR); 
     295                domAny *any = (domAny*)(daeElement*)teq->add( COLLADA_ELEMENT_COLOR ); 
    294296 
    295297                std::ostringstream colVal; 
     
    299301        } 
    300302 
    301         cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add(COLLADA_ELEMENT_SPECULAR)); 
    302         col = daeSafeCast< domCommon_color_or_texture_type_complexType::domColor >( cot->add(COLLADA_ELEMENT_COLOR)); 
     303        cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add( COLLADA_ELEMENT_SPECULAR ) ); 
     304        col = daeSafeCast< domCommon_color_or_texture_type_complexType::domColor >( cot->add( COLLADA_ELEMENT_COLOR ) ); 
    303305        col->getValue().append( sCol.r() ); 
    304306        col->getValue().append( sCol.g() ); 
     
    306308        col->getValue().append( sCol.a() ); 
    307309 
    308         domCommon_float_or_param_type *fop = daeSafeCast< domCommon_float_or_param_type >( phong->add(COLLADA_ELEMENT_SHININESS)); 
    309         domCommon_float_or_param_type_complexType::domFloat *f = daeSafeCast< domCommon_float_or_param_type_complexType::domFloat >( fop->add(COLLADA_ELEMENT_FLOAT)); 
     310        domCommon_float_or_param_type *fop = daeSafeCast< domCommon_float_or_param_type >( phong->add( COLLADA_ELEMENT_SHININESS ) ); 
     311        domCommon_float_or_param_type_complexType::domFloat *f = daeSafeCast< domCommon_float_or_param_type_complexType::domFloat >( fop->add(COLLADA_ELEMENT_FLOAT) ); 
    310312        f->setValue( shininess ); 
    311313    } 
     
    365367            else if (tex != NULL && tex->getImage( 0 ) != NULL) 
    366368            { 
    367                 domCommon_transparent_type *ctt = daeSafeCast< domCommon_transparent_type >( phong->add(COLLADA_ELEMENT_TRANSPARENT)); 
     369                domCommon_transparent_type *ctt = daeSafeCast< domCommon_transparent_type >( phong->add(COLLADA_ELEMENT_TRANSPARENT) ); 
    368370                ctt->setOpaque( FX_OPAQUE_ENUM_A_ONE ); 
    369                 domCommon_color_or_texture_type_complexType::domTexture * dtex = daeSafeCast< domCommon_color_or_texture_type_complexType::domTexture >( ctt->add(COLLADA_ELEMENT_TEXTURE)); 
     371                domCommon_color_or_texture_type_complexType::domTexture * dtex = daeSafeCast< domCommon_color_or_texture_type_complexType::domTexture >( ctt->add(COLLADA_ELEMENT_TEXTURE) ); 
    370372                 
    371373    #ifndef EARTH_TEX 
  • OpenSceneGraph/trunk/src/osgPlugins/dae/daeWSceneObjects.cpp

    r10234 r11129  
    2929#include <osg/CameraView> 
    3030 
    31 using namespace osgdae; 
     31using namespace osgDAE; 
    3232 
    3333// Write non-standard node data as extra of type "Node" with "OpenSceneGraph" technique 
     
    129129    else 
    130130    { 
     131        writeAnimations(node); 
     132 
    131133        currentNode->setId(getNodeName(node,"group").c_str()); 
    132134    } 
     
    354356    debugPrint( node ); 
    355357 
    356     domInstance_light *pDomInstanceLight = daeSafeCast< domInstance_light >( currentNode->add(COLLADA_ELEMENT_INSTANCE_LIGHT)); 
     358    domInstance_light *il = daeSafeCast< domInstance_light >( currentNode->add( COLLADA_ELEMENT_INSTANCE_LIGHT ) ); 
    357359    std::string name = node.getName(); 
    358360    if ( name.empty() ) 
     
    361363    } 
    362364    std::string url = "#" + name; 
    363     pDomInstanceLight->setUrl( url.c_str() ); 
     365    il->setUrl( url.c_str() ); 
    364366 
    365367    if ( lib_lights == NULL ) 
     
    367369        lib_lights = daeSafeCast< domLibrary_lights >( dom->add( COLLADA_ELEMENT_LIBRARY_LIGHTS ) ); 
    368370    } 
     371    domLight *light = daeSafeCast< domLight >( lib_lights->add( COLLADA_ELEMENT_LIGHT ) ); 
     372    light->setId( name.c_str() ); 
    369373     
    370374    osg::Light* pOsgLight = node.getLight(); 
  • OpenSceneGraph/trunk/src/osgPlugins/dae/daeWTransforms.cpp

    r9476 r11129  
    22 * Copyright 2006 Sony Computer Entertainment Inc. 
    33 * 
    4  * Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this  
     4 * Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this 
    55