diff --git a/src/osgPlugins/dae/CMakeLists.txt b/src/osgPlugins/dae/CMakeLists.txt index 71a88303c..80252517b 100644 --- a/src/osgPlugins/dae/CMakeLists.txt +++ b/src/osgPlugins/dae/CMakeLists.txt @@ -52,6 +52,7 @@ IF(COLLADA_USE_STATIC) COLLADA_STATIC_LIBRARY COLLADA_LIBXML_LIBRARY COLLADA_PCRECPP_LIBRARY + COLLADA_PCRE_LIBRARY COLLADA_BOOST_FILESYSTEM_LIBRARY COLLADA_BOOST_SYSTEM_LIBRARY) ENDIF() @@ -63,7 +64,11 @@ ELSE() COLLADA_BOOST_SYSTEM_LIBRARY) ELSE() SET(TARGET_LIBRARIES_VARS - COLLADA_DYNAMIC_LIBRARY) + COLLADA_PCRECPP_LIBRARY + COLLADA_PCRE_LIBRARY + COLLADA_DYNAMIC_LIBRARY + COLLADA_BOOST_FILESYSTEM_LIBRARY + COLLADA_BOOST_SYSTEM_LIBRARY) ENDIF() ENDIF() diff --git a/src/osgPlugins/dae/daeRSceneObjects.cpp b/src/osgPlugins/dae/daeRSceneObjects.cpp index 2852c8b61..7f9d6820a 100644 --- a/src/osgPlugins/dae/daeRSceneObjects.cpp +++ b/src/osgPlugins/dae/daeRSceneObjects.cpp @@ -25,6 +25,7 @@ #include #include #include +#include using namespace osgdae; @@ -322,7 +323,10 @@ osg::Node* daeReader::processOsgLOD(domTechnique* teq) // 0..* osg::Node* daeReader::processLight( domLight *dlight ) { - osg::Node *node = new osg::Switch(); + if (m_numlights >= 7) + { + osg::notify( osg::WARN ) << "More than 8 lights may not be supported by OpenGL driver." << std::endl; + } //do light processing here. domLight::domTechnique_common::domAmbient *ambient; @@ -331,19 +335,30 @@ osg::Node* daeReader::processLight( domLight *dlight ) domLight::domTechnique_common::domSpot *spot; if ( dlight->getTechnique_common() == NULL || - dlight->getTechnique_common()->getContents().getCount() == 0 ) + dlight->getTechnique_common()->getContents().getCount() == 0 ) { osg::notify( osg::WARN ) << "Invalid content for light" << std::endl; return NULL; } osg::Light* light = new osg::Light(); + light->setPosition(osg::Vec4(0,0,0,1)); + light->setLightNum(m_numlights); + + // Enable OpenGL lighting + _rootStateSet->setMode(GL_LIGHTING, osg::StateAttribute::ON); + // Enable this OpenGL light + _rootStateSet->setMode(GL_LIGHT0 + m_numlights++, osg::StateAttribute::ON); + + // Set ambient of lightmodel to zero + // Ambient lights are added as separate lights with only an ambient term + osg::LightModel* lightmodel = new osg::LightModel; + lightmodel->setAmbientIntensity(osg::Vec4(0.0f,0.0f,0.0f,1.0f)); + _rootStateSet->setAttributeAndModes(lightmodel, osg::StateAttribute::ON); osg::LightSource* lightsource = new osg::LightSource(); - - lightsource->setLight( light ); - light->setPosition(osg::Vec4(0,0,0,1)); - light->setLightNum( m_numlights ); + lightsource->setLight(light); + lightsource->setName(dlight->getId()); daeElement *el = dlight->getTechnique_common()->getContents()[0]; ambient = daeSafeCast< domLight::domTechnique_common::domAmbient >( el ); @@ -357,34 +372,50 @@ osg::Node* daeReader::processLight( domLight *dlight ) osg::notify( osg::WARN ) << "Invalid content for ambient light" << std::endl; return NULL; } - light->setAmbient( osg::Vec4( ambient->getColor()->getValue()[0], ambient->getColor()->getValue()[1], - ambient->getColor()->getValue()[2], 1.0f ) ); + + light->setAmbient( osg::Vec4( ambient->getColor()->getValue()[0], + ambient->getColor()->getValue()[1], + ambient->getColor()->getValue()[2], 1.0f ) ); + light->setDiffuse( osg::Vec4( 0, 0, 0, 0)); + light->setSpecular( osg::Vec4( 0, 0, 0, 0)); + + // Tell OpenGL to make it a directional light (w=0) + light->setPosition( osg::Vec4(0,0,0,0)); } else if ( directional != NULL ) { if ( directional->getColor() == NULL ) { - osg::notify( osg::WARN ) << "Invalid content for ambient light" << std::endl; + osg::notify( osg::WARN ) << "Invalid content for directional light" << std::endl; return NULL; } - light->setDiffuse( osg::Vec4( directional->getColor()->getValue()[0], directional->getColor()->getValue()[1], - directional->getColor()->getValue()[2], 1.0f ) ); - light->setSpecular( osg::Vec4( directional->getColor()->getValue()[0], directional->getColor()->getValue()[1], - directional->getColor()->getValue()[2], 1.0f ) ); + light->setAmbient( osg::Vec4( 0, 0, 0, 0)); + light->setDiffuse( osg::Vec4( directional->getColor()->getValue()[0], + directional->getColor()->getValue()[1], + directional->getColor()->getValue()[2], 1.0f ) ); + light->setSpecular( osg::Vec4( directional->getColor()->getValue()[0], + directional->getColor()->getValue()[1], + directional->getColor()->getValue()[2], 1.0f ) ); - light->setDirection( osg::Vec3( 0, 0, -1 ) ); + light->setDirection(osg::Vec3(0,0,-1)); + + // Tell OpenGL it is a directional light (w=0) + light->setPosition( osg::Vec4(0,0,1,0)); } else if ( point != NULL ) { if ( point->getColor() == NULL ) { - osg::notify( osg::WARN ) << "Invalid content for ambient light" << std::endl; + osg::notify( osg::WARN ) << "Invalid content for point light" << std::endl; return NULL; } - light->setDiffuse( osg::Vec4( point->getColor()->getValue()[0], point->getColor()->getValue()[1], - point->getColor()->getValue()[2], 1.0f ) ); - light->setSpecular( osg::Vec4( point->getColor()->getValue()[0], point->getColor()->getValue()[1], - point->getColor()->getValue()[2], 1.0f ) ); + light->setAmbient( osg::Vec4( 0, 0, 0, 0)); + light->setDiffuse( osg::Vec4( point->getColor()->getValue()[0], + point->getColor()->getValue()[1], + point->getColor()->getValue()[2], 1.0f ) ); + light->setSpecular( osg::Vec4( point->getColor()->getValue()[0], + point->getColor()->getValue()[1], + point->getColor()->getValue()[2], 1.0f ) ); if ( point->getConstant_attenuation() != NULL ) { @@ -411,18 +442,23 @@ osg::Node* daeReader::processLight( domLight *dlight ) light->setQuadraticAttenuation( 0.0 ); } + // Tell OpenGL this is an omni directional light + light->setDirection(osg::Vec3(0, 0, 0)); } else if ( spot != NULL ) { if ( spot->getColor() == NULL ) { - osg::notify( osg::WARN ) << "Invalid content for ambient light" << std::endl; + osg::notify( osg::WARN ) << "Invalid content for spot light" << std::endl; return NULL; } - light->setDiffuse( osg::Vec4( spot->getColor()->getValue()[0], spot->getColor()->getValue()[1], - spot->getColor()->getValue()[2], 1.0f ) ); - light->setSpecular( osg::Vec4( spot->getColor()->getValue()[0], spot->getColor()->getValue()[1], - spot->getColor()->getValue()[2], 1.0f ) ); + light->setAmbient( osg::Vec4( 0, 0, 0, 0)); + light->setDiffuse( osg::Vec4( spot->getColor()->getValue()[0], + spot->getColor()->getValue()[1], + spot->getColor()->getValue()[2], 1.0f ) ); + light->setSpecular( osg::Vec4( spot->getColor()->getValue()[0], + spot->getColor()->getValue()[1], + spot->getColor()->getValue()[2], 1.0f ) ); if ( spot->getConstant_attenuation() != NULL ) { @@ -448,35 +484,35 @@ osg::Node* daeReader::processLight( domLight *dlight ) { light->setQuadraticAttenuation( 0.0f ); } - + // OpenGL range [0, 90] (degrees) or 180 (omni) if ( spot->getFalloff_angle() != NULL ) { - light->setSpotCutoff( spot->getFalloff_angle()->getValue() ); + float falloffAngle = spot->getFalloff_angle()->getValue(); + if (falloffAngle != 180) + { + falloffAngle = osg::clampTo(falloffAngle, 0, 90); + } + light->setSpotCutoff(falloffAngle); } else { light->setSpotCutoff( 180.0f ); } - + // OpenGL range [0, 128], where 0 means hard edge, and 128 means soft edge if ( spot->getFalloff_exponent() != NULL ) { - light->setSpotExponent( spot->getFalloff_exponent()->getValue() ); + float falloffExponent = spot->getFalloff_exponent()->getValue(); + falloffExponent = osg::clampTo(falloffExponent, 0, 128); + light->setSpotExponent(falloffExponent); } else { light->setSpotExponent( 0.0f ); } - + light->setDirection(osg::Vec3(0, 0, -1)); } - osg::Switch* svitch = static_cast(node); - - // Switched of by default to avoid excessively large scene bound - svitch->addChild(lightsource,false); - - m_numlights++; - - return node; + return lightsource; } // diff --git a/src/osgPlugins/dae/daeReader.cpp b/src/osgPlugins/dae/daeReader.cpp index 82082b2c1..f4615dffd 100644 --- a/src/osgPlugins/dae/daeReader.cpp +++ b/src/osgPlugins/dae/daeReader.cpp @@ -128,6 +128,7 @@ bool daeReader::convert( const std::string &fileURI ) osg::Node* daeReader::processVisualScene( domVisual_scene *scene ) { osg::Node *retVal; + _rootStateSet = new osg::StateSet(); unsigned int nbVisualSceneGroup=scene->getNode_array().getCount(); if (nbVisualSceneGroup==0) @@ -160,6 +161,8 @@ osg::Node* daeReader::processVisualScene( domVisual_scene *scene ) } } } + retVal->setStateSet(_rootStateSet); + return retVal; } diff --git a/src/osgPlugins/dae/daeReader.h b/src/osgPlugins/dae/daeReader.h index cf0f6b17c..ed5eac077 100644 --- a/src/osgPlugins/dae/daeReader.h +++ b/src/osgPlugins/dae/daeReader.h @@ -224,6 +224,7 @@ protected: protected: DAE *dae; osg::Node* rootNode; + osg::ref_ptr _rootStateSet; std::map _targetMap; diff --git a/src/osgPlugins/dae/daeWGeometry.cpp b/src/osgPlugins/dae/daeWGeometry.cpp index 00df0cb93..f4c8639f5 100644 --- a/src/osgPlugins/dae/daeWGeometry.cpp +++ b/src/osgPlugins/dae/daeWGeometry.cpp @@ -50,7 +50,7 @@ void daeWriter::apply( osg::Geode &node ) std::map< osg::Geometry*, domGeometry *>::iterator iter = geometryMap.find( g ); if ( iter != geometryMap.end() ) { - domInstance_geometry *ig = daeSafeCast< domInstance_geometry >( currentNode->add( "instance_geometry" ) ); + domInstance_geometry *ig = daeSafeCast< domInstance_geometry >( currentNode->add( COLLADA_ELEMENT_INSTANCE_GEOMETRY ) ); std::string url = "#" + std::string( iter->second->getId() ); ig->setUrl( url.c_str() ); @@ -76,7 +76,7 @@ void daeWriter::apply( osg::Geode &node ) continue; } - domInstance_geometry *ig = daeSafeCast< domInstance_geometry >( currentNode->add( "instance_geometry" ) ); + domInstance_geometry *ig = daeSafeCast< domInstance_geometry >( currentNode->add( COLLADA_ELEMENT_INSTANCE_GEOMETRY ) ); std::string url = "#" + name; ig->setUrl( url.c_str() ); @@ -218,8 +218,8 @@ bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const st vertices->setId( vName.c_str() ); //make a POSITION input in it - domInputLocal *il = daeSafeCast< domInputLocal >( vertices->add( "input" ) ); - il->setSemantic( "POSITION" ); + domInputLocal *il = daeSafeCast< domInputLocal >( vertices->add( COLLADA_ELEMENT_INPUT) ); + il->setSemantic(COMMON_PROFILE_INPUT_POSITION); std::string url = "#" + std::string( pos->getId() ); il->setSource( url.c_str() ); @@ -272,8 +272,8 @@ bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const st //if NORMAL shares same indices as POSITION put it in the vertices /*if ( normalInds == vertInds && vertInds != NULL ) { - il = daeSafeCast< domInputLocal >( vertices->add( "input" ) ); - il->setSemantic( "NORMAL" ); + il = daeSafeCast< domInputLocal >( vertices->add( COLLADA_ELEMENT_INPUT) ); + il->setSemantic(COMMON_PROFILE_INPUT_NORMAL); url = "#" + std::string(md->norm->getId()); il->setSource( url.c_str() ); }*/ @@ -323,8 +323,8 @@ bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const st } //if COLOR shares same indices as POSITION put it in the vertices /*if ( colorInds == vertInds && vertInds != NULL ) { - il = daeSafeCast< domInputLocal >( vertices->add( "input" ) ); - il->setSemantic( "COLOR" ); + il = daeSafeCast< domInputLocal >( vertices->add( COLLADA_ELEMENT_INPUT) ); + il->setSemantic(COMMON_PROFILE_INPUT_COLOR); url = "#" + std::string(md->color->getId()); il->setSource( url.c_str() ); }*/ @@ -1056,7 +1056,7 @@ domSource *daeWriter::createSource( daeElement *parent, const std::string &baseN std::string fName = baseName + "-array"; fa->setId( fName.c_str() ); - domSource::domTechnique_common *teq = daeSafeCast< domSource::domTechnique_common >( src->add( "technique_common" ) ); + domSource::domTechnique_common *teq = daeSafeCast< domSource::domTechnique_common >( src->add( COLLADA_ELEMENT_TECHNIQUE_COMMON ) ); domAccessor *acc = daeSafeCast< domAccessor >( teq->add( COLLADA_ELEMENT_ACCESSOR ) ); std::string url = "#" + fName; acc->setSource( url.c_str() ); @@ -1135,32 +1135,32 @@ Ty *daeWriter::createPrimGroup( daeString type, domMesh *mesh, domSource *norm, { unsigned int offset = 0; Ty *retVal = daeSafeCast< Ty >( mesh->add( type ) ); - domInputLocalOffset *ilo = daeSafeCast< domInputLocalOffset >( retVal->add( "input" ) ); + domInputLocalOffset *ilo = daeSafeCast< domInputLocalOffset >(retVal->add( COLLADA_ELEMENT_INPUT)); ilo->setOffset( offset++ ); - ilo->setSemantic( "VERTEX" ); + ilo->setSemantic(COMMON_PROFILE_INPUT_VERTEX); std::string url = "#" + std::string(mesh->getVertices()->getId()); ilo->setSource( url.c_str() ); if ( norm != NULL ) { - ilo = daeSafeCast< domInputLocalOffset >( retVal->add( "input" ) ); + ilo = daeSafeCast< domInputLocalOffset >( retVal->add(COLLADA_ELEMENT_INPUT)); ilo->setOffset( offset++ ); - ilo->setSemantic( "NORMAL" ); + ilo->setSemantic( COMMON_PROFILE_INPUT_NORMAL); url = "#" + std::string( norm->getId() ); ilo->setSource( url.c_str() ); } if ( color != NULL ) { - ilo = daeSafeCast< domInputLocalOffset >( retVal->add( "input" ) ); + ilo = daeSafeCast< domInputLocalOffset >( retVal->add(COLLADA_ELEMENT_INPUT)); ilo->setOffset( offset++ ); - ilo->setSemantic( "COLOR" ); + ilo->setSemantic(COMMON_PROFILE_INPUT_COLOR); url = "#" + std::string( color->getId() ); ilo->setSource( url.c_str() ); } for ( unsigned int i = 0; i < texcoord.size(); i++ ) { - ilo = daeSafeCast< domInputLocalOffset >( retVal->add( "input" ) ); + ilo = daeSafeCast< domInputLocalOffset >( retVal->add(COLLADA_ELEMENT_INPUT)); ilo->setOffset( offset++ ); - ilo->setSemantic( "TEXCOORD" ); + ilo->setSemantic(COMMON_PROFILE_INPUT_TEXCOORD); ilo->setSet( i ); url = "#" + std::string( texcoord[i]->getId() ); ilo->setSource( url.c_str() ); diff --git a/src/osgPlugins/dae/daeWMaterials.cpp b/src/osgPlugins/dae/daeWMaterials.cpp index 7880a76f1..048b745f0 100644 --- a/src/osgPlugins/dae/daeWMaterials.cpp +++ b/src/osgPlugins/dae/daeWMaterials.cpp @@ -34,7 +34,7 @@ void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, co { osg::ref_ptr ssClean = CleanStateSet(ss); // Need to hold a ref to this or the materialMap.find() will delete it domBind_material *bm = daeSafeCast< domBind_material >( ig->add( COLLADA_ELEMENT_BIND_MATERIAL ) ); - domBind_material::domTechnique_common *tc = daeSafeCast< domBind_material::domTechnique_common >( bm->add( "technique_common" ) ); + domBind_material::domTechnique_common *tc = daeSafeCast< domBind_material::domTechnique_common >( bm->add(COLLADA_ELEMENT_TECHNIQUE_COMMON)); domInstance_material *im = daeSafeCast< domInstance_material >( tc->add( COLLADA_ELEMENT_INSTANCE_MATERIAL ) ); std::string symbol = geoName + "_material"; im->setSymbol( symbol.c_str() ); @@ -65,7 +65,7 @@ void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, co std::string url = "#" + name; im->setTarget( url.c_str() ); - domInstance_effect *ie = daeSafeCast( mat->add( "instance_effect" ) ); + domInstance_effect *ie = daeSafeCast( mat->add( COLLADA_ELEMENT_INSTANCE_EFFECT ) ); if ( lib_effects == NULL ) { @@ -80,9 +80,9 @@ void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, co ie->setUrl( url.c_str() ); domProfile_COMMON *pc = daeSafeCast< domProfile_COMMON >( effect->add( COLLADA_ELEMENT_PROFILE_COMMON ) ); - domProfile_COMMON::domTechnique *pc_teq = daeSafeCast< domProfile_COMMON::domTechnique >( pc->add( "technique" ) ); + domProfile_COMMON::domTechnique *pc_teq = daeSafeCast< domProfile_COMMON::domTechnique >( pc->add( COLLADA_ELEMENT_TECHNIQUE ) ); pc_teq->setSid( "t0" ); - domProfile_COMMON::domTechnique::domPhong *phong = daeSafeCast< domProfile_COMMON::domTechnique::domPhong >( pc_teq->add( "phong" ) ); + domProfile_COMMON::domTechnique::domPhong *phong = daeSafeCast< domProfile_COMMON::domTechnique::domPhong >( pc_teq->add(COLLADA_ELEMENT_PHONG)); osg::Texture *tex = static_cast(ssClean->getTextureAttribute( 0, osg::StateAttribute::TEXTURE )); if ( ssClean->getTextureAttribute( 1, osg::StateAttribute::TEXTURE ) != NULL ) @@ -97,7 +97,7 @@ void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, co img->setId( iName.c_str() ); osg::Image *osgimg = tex->getImage( 0 ); - domImage::domInit_from *imgif = daeSafeCast< domImage::domInit_from >( img->add( "init_from" ) ); + domImage::domInit_from *imgif = daeSafeCast< domImage::domInit_from >( img->add(COLLADA_ELEMENT_INIT_FROM)); std::string fileURI = ReaderWriterDAE::ConvertFilePathToColladaCompatibleURI(osgDB::findDataFile(osgimg->getFileName())); daeURI dd(*dae, fileURI);//fileURI.c_str() ); imgif->setValue( dd ); @@ -105,23 +105,23 @@ void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, co imgif->getValue().makeRelativeTo(doc->getDocumentURI()); #ifndef EARTH_TEX - domCommon_newparam_type *np = daeSafeCast< domCommon_newparam_type >( pc->add( "newparam" ) ); + domCommon_newparam_type *np = daeSafeCast< domCommon_newparam_type >(pc->add(COLLADA_ELEMENT_NEWPARAM)); std::string surfName = efName + "-surface"; np->setSid( surfName.c_str() ); - domFx_surface_common *surface = daeSafeCast< domFx_surface_common >( np->add( "surface" ) ); - domFx_surface_init_from_common *sif = daeSafeCast< domFx_surface_init_from_common >( surface->add("init_from") ); + domFx_surface_common *surface = daeSafeCast< domFx_surface_common >(np->add(COLLADA_ELEMENT_SURFACE)); + domFx_surface_init_from_common *sif = daeSafeCast< domFx_surface_init_from_common >( surface->add(COLLADA_ELEMENT_INIT_FROM)); sif->setValue( iName.c_str() ); surface->setType( FX_SURFACE_TYPE_ENUM_2D ); - np = daeSafeCast< domCommon_newparam_type >( pc->add( "newparam" ) ); + np = daeSafeCast< domCommon_newparam_type >( pc->add(COLLADA_ELEMENT_NEWPARAM)); std::string sampName = efName + "-sampler"; np->setSid( sampName.c_str() ); - domFx_sampler2D_common *sampler = daeSafeCast< domFx_sampler2D_common >( np->add( "sampler2D" ) ); - domFx_sampler2D_common_complexType::domSource *source = daeSafeCast< domFx_sampler2D_common_complexType::domSource >( sampler->add( "source" ) ); + domFx_sampler2D_common *sampler = daeSafeCast< domFx_sampler2D_common >( np->add(COLLADA_ELEMENT_SAMPLER2D) ); + domFx_sampler2D_common_complexType::domSource *source = daeSafeCast< domFx_sampler2D_common_complexType::domSource >(sampler->add(COLLADA_ELEMENT_SOURCE)); source->setValue( surfName.c_str() ); //set sampler state - domFx_sampler2D_common_complexType::domWrap_s *wrap_s = daeSafeCast< domFx_sampler2D_common_complexType::domWrap_s >( sampler->add( "wrap_s" ) ); + domFx_sampler2D_common_complexType::domWrap_s *wrap_s = daeSafeCast< domFx_sampler2D_common_complexType::domWrap_s >(sampler->add(COLLADA_ELEMENT_WRAP_S)); osg::Texture::WrapMode wrap = tex->getWrap( osg::Texture::WRAP_S ); switch( wrap ) { @@ -143,7 +143,7 @@ void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, co break; } - domFx_sampler2D_common_complexType::domWrap_t *wrap_t = daeSafeCast< domFx_sampler2D_common_complexType::domWrap_t >( sampler->add( "wrap_t" ) ); + domFx_sampler2D_common_complexType::domWrap_t *wrap_t = daeSafeCast< domFx_sampler2D_common_complexType::domWrap_t >(sampler->add( COLLADA_ELEMENT_WRAP_T)); wrap = tex->getWrap( osg::Texture::WRAP_T ); switch( wrap ) { @@ -166,13 +166,13 @@ void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, co } const osg::Vec4 &bcol = tex->getBorderColor(); - domFx_sampler2D_common_complexType::domBorder_color *dbcol = daeSafeCast< domFx_sampler2D_common_complexType::domBorder_color >( sampler->add( "border_color" ) ); + domFx_sampler2D_common_complexType::domBorder_color *dbcol = daeSafeCast< domFx_sampler2D_common_complexType::domBorder_color >(sampler->add(COLLADA_ELEMENT_BORDER_COLOR)); dbcol->getValue().append( bcol.r() ); dbcol->getValue().append( bcol.g() ); dbcol->getValue().append( bcol.b() ); dbcol->getValue().append( bcol.a() ); - domFx_sampler2D_common_complexType::domMinfilter *minfilter = daeSafeCast< domFx_sampler2D_common_complexType::domMinfilter >( sampler->add( "minfilter" ) ); + domFx_sampler2D_common_complexType::domMinfilter *minfilter = daeSafeCast< domFx_sampler2D_common_complexType::domMinfilter >(sampler->add(COLLADA_ELEMENT_MINFILTER)); osg::Texture::FilterMode mode = tex->getFilter( osg::Texture::MIN_FILTER ); switch( mode ) { @@ -196,7 +196,7 @@ void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, co break; } - domFx_sampler2D_common_complexType::domMagfilter *magfilter = daeSafeCast< domFx_sampler2D_common_complexType::domMagfilter >( sampler->add( "magfilter" ) ); + domFx_sampler2D_common_complexType::domMagfilter *magfilter = daeSafeCast< domFx_sampler2D_common_complexType::domMagfilter >(sampler->add(COLLADA_ELEMENT_MAGFILTER)); mode = tex->getFilter( osg::Texture::MAG_FILTER ); switch( mode ) { @@ -221,18 +221,18 @@ void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, co } - domCommon_color_or_texture_type *cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add( "diffuse" ) ); - domCommon_color_or_texture_type_complexType::domTexture *dtex = daeSafeCast< domCommon_color_or_texture_type_complexType::domTexture >( cot->add( "texture" ) ); + domCommon_color_or_texture_type *cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add(COLLADA_ELEMENT_DIFFUSE) ); + domCommon_color_or_texture_type_complexType::domTexture *dtex = daeSafeCast< domCommon_color_or_texture_type_complexType::domTexture >(cot->add(COLLADA_ELEMENT_TEXTURE)); dtex->setTexture( sampName.c_str() ); dtex->setTexcoord( "texcoord0" ); #else - domCommon_color_or_texture_type *cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add( "diffuse" ) ); - domCommon_color_or_texture_type_complexType::domTexture *dtex = daeSafeCast< domCommon_color_or_texture_type_complexType::domTexture >( cot->add( "texture" ) ); + domCommon_color_or_texture_type *cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add(COLLADA_ELEMENT_DIFFUSE) ); + domCommon_color_or_texture_type_complexType::domTexture *dtex = daeSafeCast< domCommon_color_or_texture_type_complexType::domTexture >( cot->add(COLLADA_ELEMENT_TEXTURE)); dtex->setTexture( iName.c_str() ); dtex->setTexcoord( "texcoord0" ); #endif - domInstance_material::domBind_vertex_input *bvi = daeSafeCast< domInstance_material::domBind_vertex_input >( im->add( "bind_vertex_input" ) ); + domInstance_material::domBind_vertex_input *bvi = daeSafeCast< domInstance_material::domBind_vertex_input >(im->add(COLLADA_ELEMENT_BIND_VERTEX_INPUT)); bvi->setSemantic( "texcoord0" ); bvi->setInput_semantic( "TEXCOORD" ); bvi->setInput_set( 0 ); @@ -246,15 +246,15 @@ void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, co const osg::Vec4 &sCol = osgmat->getSpecularFrontAndBack()?osgmat->getSpecular( osg::Material::FRONT_AND_BACK ):osgmat->getSpecular( osg::Material::FRONT ); float shininess = osgmat->getShininessFrontAndBack()?osgmat->getShininess( osg::Material::FRONT_AND_BACK ):osgmat->getShininess( osg::Material::FRONT ); - domCommon_color_or_texture_type *cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add( "emission" ) ); - domCommon_color_or_texture_type_complexType::domColor *col = daeSafeCast< domCommon_color_or_texture_type_complexType::domColor >( cot->add( "color" ) ); + domCommon_color_or_texture_type *cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add(COLLADA_ELEMENT_EMISSION)); + domCommon_color_or_texture_type_complexType::domColor *col = daeSafeCast< domCommon_color_or_texture_type_complexType::domColor >( cot->add(COLLADA_ELEMENT_COLOR)); col->getValue().append( eCol.r() ); col->getValue().append( eCol.g() ); col->getValue().append( eCol.b() ); col->getValue().append( eCol.a() ); - cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add( "ambient" ) ); - col = daeSafeCast< domCommon_color_or_texture_type_complexType::domColor >( cot->add( "color" ) ); + cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add(COLLADA_ELEMENT_AMBIENT)); + col = daeSafeCast< domCommon_color_or_texture_type_complexType::domColor >(cot->add(COLLADA_ELEMENT_COLOR)); col->getValue().append( aCol.r() ); col->getValue().append( aCol.g() ); col->getValue().append( aCol.b() ); @@ -264,8 +264,8 @@ void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, co //### check if we really have a texture if ( phong->getDiffuse() == NULL ) { - cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add( "diffuse" ) ); - col = daeSafeCast< domCommon_color_or_texture_type_complexType::domColor >( cot->add( "color" ) ); + cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add(COLLADA_ELEMENT_DIFFUSE)); + col = daeSafeCast< domCommon_color_or_texture_type_complexType::domColor >( cot->add(COLLADA_ELEMENT_COLOR)); col->getValue().append( dCol.r() ); col->getValue().append( dCol.g() ); col->getValue().append( dCol.b() ); @@ -290,7 +290,7 @@ void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, co extra->setType( "color" ); domTechnique *teq = daeSafeCast< domTechnique >( extra->add( COLLADA_ELEMENT_TECHNIQUE ) ); teq->setProfile( "SCEI" ); - domAny *any = (domAny*)(daeElement*)teq->add( "color" ); + domAny *any = (domAny*)(daeElement*)teq->add(COLLADA_ELEMENT_COLOR); std::ostringstream colVal; colVal << dCol.r() << " " << dCol.g() << " " << dCol.b() << " " << dCol.a(); @@ -298,15 +298,15 @@ void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, co } } - cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add( "specular" ) ); - col = daeSafeCast< domCommon_color_or_texture_type_complexType::domColor >( cot->add( "color" ) ); + cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add(COLLADA_ELEMENT_SPECULAR)); + col = daeSafeCast< domCommon_color_or_texture_type_complexType::domColor >( cot->add(COLLADA_ELEMENT_COLOR)); col->getValue().append( sCol.r() ); col->getValue().append( sCol.g() ); col->getValue().append( sCol.b() ); col->getValue().append( sCol.a() ); - domCommon_float_or_param_type *fop = daeSafeCast< domCommon_float_or_param_type >( phong->add( "shininess" ) ); - domCommon_float_or_param_type_complexType::domFloat *f = daeSafeCast< domCommon_float_or_param_type_complexType::domFloat >( fop->add( "float" ) ); + domCommon_float_or_param_type *fop = daeSafeCast< domCommon_float_or_param_type >( phong->add(COLLADA_ELEMENT_SHININESS)); + domCommon_float_or_param_type_complexType::domFloat *f = daeSafeCast< domCommon_float_or_param_type_complexType::domFloat >( fop->add(COLLADA_ELEMENT_FLOAT)); f->setValue( shininess ); } @@ -323,11 +323,11 @@ void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, co if ((GL_CONSTANT_ALPHA == pBlendFunc->getSource()) && (GL_ONE_MINUS_CONSTANT_ALPHA == pBlendFunc->getDestination())) { // A_ONE opaque mode - domCommon_transparent_type *pTransparent = daeSafeCast(phong->add("transparent")); + domCommon_transparent_type *pTransparent = daeSafeCast(phong->add(COLLADA_ELEMENT_TRANSPARENT)); pTransparent->setOpaque(FX_OPAQUE_ENUM_A_ONE); - domCommon_color_or_texture_type_complexType::domColor *pColor = daeSafeCast(pTransparent->add("color")); - domCommon_float_or_param_type *pFop = daeSafeCast(phong->add( "transparency")); - domCommon_float_or_param_type_complexType::domFloat *pTransparency = daeSafeCast(pFop->add("float")); + domCommon_color_or_texture_type_complexType::domColor *pColor = daeSafeCast(pTransparent->add(COLLADA_ELEMENT_COLOR)); + domCommon_float_or_param_type *pFop = daeSafeCast(phong->add(COLLADA_ELEMENT_TRANSPARENCY)); + domCommon_float_or_param_type_complexType::domFloat *pTransparency = daeSafeCast(pFop->add(COLLADA_ELEMENT_FLOAT)); if (m_GoogleMode) { pColor->getValue().append(1.0); @@ -348,15 +348,15 @@ void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, co else if ((GL_ONE_MINUS_CONSTANT_COLOR == pBlendFunc->getSource()) && (GL_CONSTANT_COLOR == pBlendFunc->getDestination())) { // RGB_ZERO opaque mode - domCommon_transparent_type *pTransparent = daeSafeCast(phong->add("transparent")); + domCommon_transparent_type *pTransparent = daeSafeCast(phong->add(COLLADA_ELEMENT_TRANSPARENT)); pTransparent->setOpaque(FX_OPAQUE_ENUM_RGB_ZERO); - domCommon_color_or_texture_type_complexType::domColor *pColor = daeSafeCast(pTransparent->add("color")); + domCommon_color_or_texture_type_complexType::domColor *pColor = daeSafeCast(pTransparent->add(COLLADA_ELEMENT_COLOR)); pColor->getValue().append(pBlendColor->getConstantColor().r()); pColor->getValue().append(pBlendColor->getConstantColor().g()); pColor->getValue().append(pBlendColor->getConstantColor().b()); pColor->getValue().append(pBlendColor->getConstantColor().a()); - domCommon_float_or_param_type *pFop = daeSafeCast(phong->add( "transparency")); - domCommon_float_or_param_type_complexType::domFloat *pTransparency = daeSafeCast(pFop->add("float")); + domCommon_float_or_param_type *pFop = daeSafeCast(phong->add(COLLADA_ELEMENT_TRANSPARENCY)); + domCommon_float_or_param_type_complexType::domFloat *pTransparency = daeSafeCast(pFop->add(COLLADA_ELEMENT_FLOAT)); pTransparency->setValue(1.0); } else @@ -364,9 +364,9 @@ void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, co } else if (tex != NULL && tex->getImage( 0 ) != NULL) { - domCommon_transparent_type *ctt = daeSafeCast< domCommon_transparent_type >( phong->add( "transparent" ) ); + domCommon_transparent_type *ctt = daeSafeCast< domCommon_transparent_type >( phong->add(COLLADA_ELEMENT_TRANSPARENT)); ctt->setOpaque( FX_OPAQUE_ENUM_A_ONE ); - domCommon_color_or_texture_type_complexType::domTexture * dtex = daeSafeCast< domCommon_color_or_texture_type_complexType::domTexture >( ctt->add( "texture" ) ); + domCommon_color_or_texture_type_complexType::domTexture * dtex = daeSafeCast< domCommon_color_or_texture_type_complexType::domTexture >( ctt->add(COLLADA_ELEMENT_TEXTURE)); #ifndef EARTH_TEX std::string sampName = efName + "-sampler"; diff --git a/src/osgPlugins/dae/daeWSceneObjects.cpp b/src/osgPlugins/dae/daeWSceneObjects.cpp index f42395a84..a52230f6d 100644 --- a/src/osgPlugins/dae/daeWSceneObjects.cpp +++ b/src/osgPlugins/dae/daeWSceneObjects.cpp @@ -353,22 +353,129 @@ void daeWriter::apply( osg::LightSource &node ) { debugPrint( node ); - domInstance_light *il = daeSafeCast< domInstance_light >( currentNode->add( "instance_light" ) ); + domInstance_light *pDomInstanceLight = daeSafeCast< domInstance_light >( currentNode->add(COLLADA_ELEMENT_INSTANCE_LIGHT)); std::string name = node.getName(); if ( name.empty() ) { name = uniquify( "light" ); } std::string url = "#" + name; - il->setUrl( url.c_str() ); + pDomInstanceLight->setUrl( url.c_str() ); if ( lib_lights == NULL ) { lib_lights = daeSafeCast< domLibrary_lights >( dom->add( COLLADA_ELEMENT_LIBRARY_LIGHTS ) ); } - domLight *light = daeSafeCast< domLight >( lib_lights->add( COLLADA_ELEMENT_LIGHT ) ); - light->setId( name.c_str() ); + osg::Light* pOsgLight = node.getLight(); + + domLight *pDomLight = daeSafeCast< domLight >( lib_lights->add( COLLADA_ELEMENT_LIGHT ) ); + pDomLight->setId( name.c_str() ); + + domLight::domTechnique_common *domTechniqueCommon = daeSafeCast(pDomLight->add(COLLADA_ELEMENT_TECHNIQUE_COMMON)); + + osg::Vec4 position = pOsgLight->getPosition(); + osg::Vec3 direction = pOsgLight->getDirection(); + osg::Vec4 ambientColor = pOsgLight->getAmbient(); + osg::Vec4 diffuseColor = pOsgLight->getDiffuse(); + osg::Vec4 specularColor = pOsgLight->getSpecular(); + + if (position.w() == 0) + { + // Directional light + domLight::domTechnique_common::domDirectional *domDirectional = daeSafeCast(domTechniqueCommon->add(COLLADA_ELEMENT_DIRECTIONAL)); + + if ((position.x() != 0) || (position.y() != 0) || (position.z() != 0)) + { + osg::Vec3 dir(-position.x(), -position.y(), -position.z()); + // TODO wrap instance_light in a rotating node to translate default light [0,0,-1] into proper direction + } + + domFloat3 color; + color.append3(diffuseColor.r(), diffuseColor.g(), diffuseColor.b()); + domDirectional->add(COLLADA_ELEMENT_COLOR); + domDirectional->getColor()->setValue(color); + } + else if (direction.length() == 0) + { + // Omni/point light + domLight::domTechnique_common::domPoint *domPoint = daeSafeCast(domTechniqueCommon->add(COLLADA_ELEMENT_POINT)); + domPoint->add(COLLADA_ELEMENT_CONSTANT_ATTENUATION); + domPoint->getConstant_attenuation()->setValue(pOsgLight->getConstantAttenuation()); + domPoint->add(COLLADA_ELEMENT_LINEAR_ATTENUATION); + domPoint->getLinear_attenuation()->setValue(pOsgLight->getLinearAttenuation()); + domPoint->add(COLLADA_ELEMENT_QUADRATIC_ATTENUATION); + domPoint->getQuadratic_attenuation()->setValue(pOsgLight->getQuadraticAttenuation()); + + if ((position.x() != 0) || (position.y() != 0) || (position.z() != 0)) + { + // TODO wrap instance_light in a transforming node to translate default light [0,0,0] into proper position + } + + domFloat3 color; + color.append3(diffuseColor.r(), diffuseColor.g(), diffuseColor.b()); + domPoint->add(COLLADA_ELEMENT_COLOR); + domPoint->getColor()->setValue(color); + } + else + { + // Spot light + domLight::domTechnique_common::domSpot *domSpot = daeSafeCast(domTechniqueCommon->add(COLLADA_ELEMENT_SPOT)); + domSpot->add(COLLADA_ELEMENT_CONSTANT_ATTENUATION); + domSpot->getConstant_attenuation()->setValue(pOsgLight->getConstantAttenuation()); + domSpot->add(COLLADA_ELEMENT_LINEAR_ATTENUATION); + domSpot->getLinear_attenuation()->setValue(pOsgLight->getLinearAttenuation()); + domSpot->add(COLLADA_ELEMENT_QUADRATIC_ATTENUATION); + domSpot->getQuadratic_attenuation()->setValue(pOsgLight->getQuadraticAttenuation()); + + if ((position.x() != 0) || (position.y() != 0) || (position.z() != 0)) + { + // TODO wrap instance_light in a transforming node to translate default light [0,0,0] into proper position + // and rotate default direction [0,0,-1] into proper dir + } + + domFloat3 color; + color.append3(diffuseColor.r(), diffuseColor.g(), diffuseColor.b()); + domSpot->add(COLLADA_ELEMENT_COLOR); + domSpot->getColor()->setValue(color); + + domSpot->add(COLLADA_ELEMENT_FALLOFF_ANGLE); + domSpot->getFalloff_angle()->setValue(pOsgLight->getSpotCutoff()); + + domSpot->add(COLLADA_ELEMENT_FALLOFF_EXPONENT); + domSpot->getFalloff_exponent()->setValue(pOsgLight->getSpotExponent()); + } + + // Write ambient as a separate Collada light + if ((ambientColor.r() != 0) || (ambientColor.g() != 0) || (ambientColor.b() != 0)) + { + domInstance_light *ambientDomInstanceLight = daeSafeCast< domInstance_light >(currentNode->add( COLLADA_ELEMENT_INSTANCE_LIGHT )); + std::string name = node.getName(); + if (name.empty()) + { + name = uniquify( "light-ambient" ); + } + else + { + name += "-ambient"; + } + std::string url = "#" + name; + ambientDomInstanceLight->setUrl( url.c_str() ); + + domLight *ambientDomLight = daeSafeCast< domLight >( lib_lights->add( COLLADA_ELEMENT_LIGHT ) ); + ambientDomLight->setId(name.c_str()); + + domLight::domTechnique_common *ambientDomTechniqueCommon = daeSafeCast(ambientDomLight->add(COLLADA_ELEMENT_TECHNIQUE_COMMON)); + + // Ambient light + domLight::domTechnique_common::domAmbient *domAmbient = daeSafeCast(ambientDomTechniqueCommon->add(COLLADA_ELEMENT_AMBIENT)); + + domFloat3 color; + color.append3(ambientColor.r(), ambientColor.g(), ambientColor.b()); + domAmbient->add(COLLADA_ELEMENT_COLOR); + domAmbient->getColor()->setValue(color); + } + traverse( node ); } @@ -376,7 +483,7 @@ void daeWriter::apply( osg::Camera &node ) { debugPrint( node ); - domInstance_camera *ic = daeSafeCast< domInstance_camera >( currentNode->add( "instance_camera" ) ); + domInstance_camera *ic = daeSafeCast< domInstance_camera >( currentNode->add( COLLADA_ELEMENT_INSTANCE_CAMERA ) ); std::string name = node.getName(); if ( name.empty() ) { @@ -399,7 +506,7 @@ void daeWriter::apply( osg::CameraView &node) { debugPrint( node ); - domInstance_camera *ic = daeSafeCast< domInstance_camera >( currentNode->add( "instance_camera" ) ); + domInstance_camera *ic = daeSafeCast< domInstance_camera >( currentNode->add(COLLADA_ELEMENT_INSTANCE_CAMERA)); std::string name = node.getName(); if ( name.empty() ) { diff --git a/src/osgPlugins/dae/daeWriter.cpp b/src/osgPlugins/dae/daeWriter.cpp index a86e662ad..0aa382d9c 100644 --- a/src/osgPlugins/dae/daeWriter.cpp +++ b/src/osgPlugins/dae/daeWriter.cpp @@ -57,12 +57,12 @@ daeWriter::daeWriter( DAE *dae_, const std::string &fileURI, bool _usePolygons, dae->getDatabase()->createDocument( fileURI.c_str(), &doc ); dom = (domCOLLADA*)doc->getDomRoot(); //create scene and instance visual scene - domCOLLADA::domScene *scene = daeSafeCast< domCOLLADA::domScene >( dom->add( COLLADA_ELEMENT_SCENE ) ); - domInstanceWithExtra *ivs = daeSafeCast< domInstanceWithExtra >( scene->add( "instance_visual_scene" ) ); + domCOLLADA::domScene *scene = daeSafeCast< domCOLLADA::domScene >( dom->add(COLLADA_ELEMENT_SCENE)); + domInstanceWithExtra *ivs = daeSafeCast< domInstanceWithExtra >( scene->add(COLLADA_ELEMENT_INSTANCE_VISUAL_SCENE)); ivs->setUrl( "#defaultScene" ); //create library visual scenes and a visual scene and the root node - lib_vis_scenes = daeSafeCast( dom->add( COLLADA_ELEMENT_LIBRARY_VISUAL_SCENES ) ); - vs = daeSafeCast< domVisual_scene >( lib_vis_scenes->add( COLLADA_ELEMENT_VISUAL_SCENE ) ); + lib_vis_scenes = daeSafeCast( dom->add(COLLADA_ELEMENT_LIBRARY_VISUAL_SCENES)); + vs = daeSafeCast< domVisual_scene >( lib_vis_scenes->add(COLLADA_ELEMENT_VISUAL_SCENE)); vs->setId( "defaultScene" ); currentNode = daeSafeCast< domNode >( vs->add( COLLADA_ELEMENT_NODE ) ); currentNode->setId( "sceneRoot" ); @@ -156,9 +156,9 @@ std::string daeWriter::uniquify( const std::string &name ) void daeWriter::createAssetTag() { domAsset *asset = daeSafeCast< domAsset >(dom->add( COLLADA_ELEMENT_ASSET ) ); - domAsset::domCreated *c = daeSafeCast< domAsset::domCreated >(asset->add("created" )); - domAsset::domModified *m = daeSafeCast< domAsset::domModified >(asset->add("modified" )); - domAsset::domUnit *u = daeSafeCast< domAsset::domUnit >(asset->add("unit")); + domAsset::domCreated *c = daeSafeCast< domAsset::domCreated >(asset->add(COLLADA_ELEMENT_CREATED)); + domAsset::domModified *m = daeSafeCast< domAsset::domModified >(asset->add(COLLADA_ELEMENT_MODIFIED)); + domAsset::domUnit *u = daeSafeCast< domAsset::domUnit >(asset->add(COLLADA_ELEMENT_UNIT)); //TODO : set date and time c->setValue( "2006-07-25T00:00:00Z" );