279 lines
8.5 KiB
C++
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;
|
|
}
|