Files
OpenSceneGraph/src/osgPlugins/dae/daeReader.cpp

279 lines
8.5 KiB
C++

/*
* Copyright 2006 Sony Computer Entertainment Inc.
*
* Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this
* file except in compliance with the License. You may obtain a copy of the License at:
* http://research.scea.com/scea_shared_source_license.html
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing permissions and limitations under the
* License.
*/
#include "daeReader.h"
#include <dae.h>
#include <dom/domCOLLADA.h>
#include <dom/domInstanceWithExtra.h>
using namespace osgdae;
daeReader::daeReader(DAE *dae_) : dae(dae_),
rootNode(NULL),
m_numlights(0),
currentEffect(NULL),
geometryMap(),
materialMap()
{
}
daeReader::~daeReader()
{
}
bool daeReader::convert( const std::string &fileURI )
{
std::string fURI;
if ( fileURI[1] == ':' )
{
fURI = "/" + fileURI;
}
else
{
fURI = fileURI;
}
daeInt res = dae->load( fURI.c_str() );
if( res != DAE_OK && res != DAE_ERR_COLLECTION_ALREADY_EXISTS)
{
osg::notify( osg::WARN ) << "Load failed in COLLADA DOM" << std::endl;
return false;
}
osg::notify( osg::INFO ) << "URI loaded: " << fURI << std::endl;
domCOLLADA* document = dae->getDom( fURI.c_str() );
if ( !document->getScene() || !document->getScene()->getInstance_visual_scene() )
{
osg::notify( osg::WARN ) << "No scene found!" << std::endl;
return false;
}
domInstanceWithExtra *ivs = document->getScene()->getInstance_visual_scene();
domVisual_scene *vs = daeSafeCast< domVisual_scene >( getElementFromURI( ivs->getUrl() ) );
if ( vs == NULL )
{
osg::notify( osg::WARN ) << "Unable to locate visual scene!" << std::endl;
return false;
}
rootNode = processVisualScene( vs );
return true;
}
osg::Node* daeReader::processVisualScene( domVisual_scene *scene )
{
osg::Node *retVal;
//### do not add an empty group if there is only one
unsigned int nbVisualSceneGroup=scene->getNode_array().getCount();
if (nbVisualSceneGroup==0)
{
osg::notify( osg::WARN ) << "No visual scene group found !" << std::endl;
retVal = new osg::Group();
retVal->setName("Empty Collada scene");
}
else if (nbVisualSceneGroup==1)
{
osg::Node *node = processNode( scene->getNode_array()[0] );
if ( node != NULL )
retVal = node;
else
{
retVal = new osg::Group();
retVal->setName("Empty Collada scene (import failure)");
}
}
else
{
retVal = new osg::Group();
retVal->setName("Collada visual scene group");
for ( size_t i = 0; i < scene->getNode_array().getCount(); i++ )
{
osg::Node *node = processNode( scene->getNode_array()[i] );
if ( node != NULL )
{
retVal->asGroup()->addChild( node );
}
}
}
return retVal;
}
osg::Node* daeReader::processNode( domNode *node )
{
osg::Node *retVal = new osg::Group();
osg::Node *current = retVal;
retVal->setName( node->getId() ? node->getId() : "" );
size_t count = node->getContents().getCount();
for ( size_t i = 0; i < count; i++ )
{
osg::Node *trans = NULL;
//I'm using daeSafeCast to check type because the pointer comparisons are a lot faster
//than a strcmp
//TODO: I am doing transforms wrong. A Transform is itself a group node. They need to be
//consolodated and then the children of the collada node need to be the children of the
//transform node.
domTranslate * t = daeSafeCast< domTranslate >( node->getContents()[i] );
if ( t != NULL )
{
trans = processTranslate( t );
if ( trans != NULL )
{
current->asGroup()->addChild( trans );
current = trans;
}
continue;
}
domRotate * r = daeSafeCast< domRotate >( node->getContents()[i] );
if ( r != NULL ) {
trans = processRotate( r );
if ( trans != NULL )
{
current->asGroup()->addChild( trans );
current = trans;
}
continue;
}
domScale * s = daeSafeCast< domScale >( node->getContents()[i] );
if ( s != NULL ) {
trans = processScale( s );
if ( trans != NULL )
{
current->asGroup()->addChild( trans );
current = trans;
}
continue;
}
domMatrix * m = daeSafeCast< domMatrix >( node->getContents()[i] );
if ( m != NULL ) {
trans = processMatrix( m );
if ( trans != NULL )
{
current->asGroup()->addChild( trans );
current = trans;
}
continue;
}
domSkew *sk = daeSafeCast< domSkew >( node->getContents()[i] );
if ( sk != NULL ) {
trans = processSkew( sk );
if ( trans != NULL )
{
current->asGroup()->addChild( trans );
current = trans;
}
continue;
}
domInstance_geometry *ig = daeSafeCast< domInstance_geometry >( node->getContents()[i] );
if ( ig != NULL )
{
trans = processInstance_geometry( ig );
if ( trans != NULL )
{
current->asGroup()->addChild( trans );
}
continue;
}
domInstance_controller *ictrl = daeSafeCast< domInstance_controller >( node->getContents()[i] );
if ( ictrl != NULL )
{
trans = processInstance_controller( ictrl );
if ( trans != NULL )
{
current->asGroup()->addChild( trans );
}
continue;
}
domInstance_camera *ic = daeSafeCast< domInstance_camera >( node->getContents()[i] );
if ( ic != NULL )
{
daeElement *el = getElementFromURI( ic->getUrl() );
domCamera *c = daeSafeCast< domCamera >( el );
if ( c == NULL )
{
osg::notify( osg::WARN ) << "Failed to locate camera " << ic->getUrl().getURI() << std::endl;
}
trans = processCamera( c );
if ( trans != NULL )
{
current->asGroup()->addChild( trans );
}
continue;
}
domInstance_light *il = daeSafeCast< domInstance_light >( node->getContents()[i] );
if ( il != NULL )
{
daeElement *el = getElementFromURI( il->getUrl() );
domLight *l = daeSafeCast< domLight >( el );
if ( l == NULL )
{
osg::notify( osg::WARN ) << "Failed to locate light " << il->getUrl().getURI() << std::endl;
}
trans = processLight( l );
if ( trans != NULL )
{
current->asGroup()->addChild( trans );
}
continue;
}
domInstance_node *instn = daeSafeCast< domInstance_node >( node->getContents()[i] );
if ( instn != NULL )
{
daeElement *el = getElementFromURI( instn->getUrl() );
domNode *n = daeSafeCast< domNode >( el );
if ( n == NULL )
{
osg::notify( osg::WARN ) << "Failed to locate camera " << ic->getUrl().getURI() << std::endl;
}
trans = processNode( n );
if ( trans != NULL )
{
current->asGroup()->addChild( trans );
}
continue;
}
domNode *n = daeSafeCast< domNode >( node->getContents()[i] );
if ( n != NULL )
{
trans = processNode( n );
if ( trans != NULL )
{
current->asGroup()->addChild( trans );
}
continue;
}
const char *name = node->getContents()[i]->getElementName();
if ( name == NULL ) name = node->getContents()[i]->getTypeName();
osg::notify( osg::WARN ) << "Unsupported element type: " << name << " in COLLADA scene!" << std::endl;
}
return retVal;
}