From Roland Smeenk, "Overview of the Collada/dae plugin changes

New features
+Read and write of osg::LOD, osg::Switch, osgSim::Sequence, osgim::MultiSwitch and osgSim::DOFTransform data in <extra>
+Read and write of osg::Node description data in <extra>
+Plugin option "NoExtras" to prevent writing of <extra> data and only traverse the active children when saving
 
Changes/additions
+instanced_geometry and instanced_controller are now loaded in a single Geode with multiple Geometries instead of multiple geodes with a single Geometry
+Changed all calls to the deprecated createAndPlace() to the new add() methods
+All transformation elements <scale>, <rotate>, <translate>, <lookat>, <matrix>, <skew> are now concatenated properly in to a single MatrixTransform.
 Previously this was not done in order as required by Collada and and not all elements were included.
+Complete skew matrix creation
+Automatically add GL_RESCALE_NORMAL if scale is non-identity
+Blinn shininess remapping to [0,128] when in range [0,1]
+Changes to CMake file to make it compile on Windows
+Coding style and code documentation
 
Bug fixes
+Transparent texture writing fixed
+Fixed bug in using osg node name as collada node ID
+Fixed usage of double sided faces in GOOGLEEARTH extra
+Not adding blendfunc and blendcolor when opaque
 
TODO/Wishlist
-solve differences in drawables, DAE reader should place multiple collation elements into multiple primitivesets in a single geometry where possible (only when same material)
-solve differences in matrices
-multitexture support
-skinned mesh and generic animations using osgAnimation
-profile_GLSL based on COLLADA OpenGL Effects Viewer http://ati.amd.com/developer/rendermonkey/downloads.html
-handling more <extra> to more closely mimic the intended lighting"
This commit is contained in:
Robert Osfield
2008-11-24 14:26:04 +00:00
parent d25de5e92e
commit 6bdd83413d
14 changed files with 2047 additions and 971 deletions

View File

@@ -27,9 +27,10 @@ OPTION(COLLADA_USE_STATIC "Set to ON to build OpenSceneGraph with static Collada
IF (WIN32)
IF (COLLADA_USE_STATIC)
SET(TARGET_EXTERNAL_LIBRARIES libcollada_dom libcollada_dae libcollada_STLDatabase libcollada_LIBXMLPlugin libcollada_stdErrPlugin libxml2 )
SET(TARGET_EXTERNAL_LIBRARIES libxml2 pcrecpp-d pcre-d)
ELSE (COLLADA_USE_STATIC)
ADD_DEFINITIONS(-DDOM_DYNAMIC)
# ADD_DEFINITIONS(-DDOM_DYNAMIC)
SET(TARGET_EXTERNAL_LIBRARIES libxml2 pcrecpp-d pcre-d)
ENDIF(COLLADA_USE_STATIC)
ELSE (WIN32)
@@ -53,6 +54,7 @@ ELSE (WIN32)
ENDIF(WIN32)
SET(TARGET_LIBRARIES_VARS COLLADA_LIBRARY)
SET(TARGET_ADDED_LIBRARIES osgSim )
#### end var setup ###
SETUP_PLUGIN(dae)

View File

@@ -14,6 +14,7 @@
#include <memory>
#include <osg/Notify>
#include <osg/NodeVisitor>
#include <osgDB/ReaderWriter>
#include <osgDB/FileNameUtils>
#include <osgDB/Registry>
@@ -40,7 +41,7 @@ ReaderWriterDAE::readNode(const std::string& fname,
DAE* pDAE = NULL;
if ( options )
pDAE = (DAE*) options->getPluginData("DAE");
pDAE = (DAE*)options->getPluginData("DAE");
std::string ext( osgDB::getLowerCaseFileExtension(fname) );
if( ! acceptsExtension(ext) ) return ReadResult::FILE_NOT_HANDLED;
@@ -103,31 +104,32 @@ ReaderWriterDAE::writeNode( const osg::Node& node,
if( ! acceptsExtension(ext) ) return WriteResult::FILE_NOT_HANDLED;
// Process options
bool usePolygon(false);
bool GoogleMode(false);
bool usePolygon(false); // Use plugin option "polygon" to enable
bool GoogleMode(false); // Use plugin option "GoogleMode" to enable
bool writeExtras(true); // Use plugin option "NoExtras" to disable
if( options )
{
pDAE = (DAE*) options->getPluginData("DAE");
pDAE = (DAE*)options->getPluginData("DAE");
std::istringstream iss( options->getOptionString() );
std::string opt;
while( std::getline( iss, opt, ',' ) )
{
if( opt == "polygon") usePolygon = true;
else if (opt == "GoogleMode") GoogleMode = true;
else
while( std::getline( iss, opt, ',' ) )
{
osg::notify(osg::WARN)
<< "\n" "COLLADA dae plugin: unrecognized option \"" << opt << "\"\n"
<< "comma-delimited options:\n"
<< "\tpolygon = use polygons instead of polylists for element\n"
<< "\tGoogleMode = write files suitable for use by Google products\n"
<< "example: osgviewer -O polygon bar.dae" "\n"
<< std::endl;
if( opt == "polygon") usePolygon = true;
else if (opt == "GoogleMode") GoogleMode = true;
else if (opt == "NoExtras") writeExtras = false;
else
{
osg::notify(osg::WARN)
<< std::endl << "COLLADA dae plugin: unrecognized option \"" << opt << std::endl
<< "comma-delimited options:" << std::endl << std::endl
<< "\tpolygon = use polygons instead of polylists for element" << std::endl
<< "\tGoogleMode = write files suitable for use by Google products" << std::endl
<< "example: osgviewer -O polygon bar.dae" << std::endl << std::endl;
}
}
}
}
if (NULL == pDAE)
{
bOwnDAE = true;
@@ -137,7 +139,9 @@ ReaderWriterDAE::writeNode( const osg::Node& node,
// Convert file name to URI
std::string fileURI = ConvertFilePathToColladaCompatibleURI(fname);
osgdae::daeWriter daeWriter(pDAE, fileURI, usePolygon, GoogleMode );
osg::NodeVisitor::TraversalMode traversalMode = writeExtras ? osg::NodeVisitor::TRAVERSE_ALL_CHILDREN : osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN;
osgdae::daeWriter daeWriter(pDAE, fileURI, usePolygon, GoogleMode, traversalMode, writeExtras);
daeWriter.setRootNode( node );
const_cast<osg::Node*>(&node)->accept( daeWriter );

View File

@@ -18,17 +18,14 @@
#include <dom/domInstance_geometry.h>
#include <dom/domInstance_controller.h>
#include <dom/domController.h>
#include <osg/StateSet>
#include <osg/Geometry>
using namespace osgdae;
osg::Node* daeReader::processInstance_geometry( domInstance_geometry *ig )
osg::Geode* daeReader::processInstanceGeometry( domInstance_geometry *ig )
{
//TODO: cache geometries so they don't get processed mulitple times.
//TODO: after cached need to check geometries and materials. both have to be the same for it
// to be the same instance.
daeElement *el = getElementFromURI( ig->getUrl() );
domGeometry *geom = daeSafeCast< domGeometry >( el );
if ( geom == NULL )
@@ -36,50 +33,65 @@ osg::Node* daeReader::processInstance_geometry( domInstance_geometry *ig )
osg::notify( osg::WARN ) << "Failed to locate geometry " << ig->getUrl().getURI() << std::endl;
return NULL;
}
//check cache if geometry already exists
osg::Node *geo;
// Check cache if geometry already exists
osg::Geode *geode;
std::map< domGeometry*, osg::Node* >::iterator iter = geometryMap.find( geom );
domGeometryGeodeMap::iterator iter = geometryMap.find( geom );
if ( iter != geometryMap.end() )
{
geo = iter->second;
osg::Geode* cachedGeode = iter->second;
// Create a copy of the cached Geode with a copy of the drawables,
// because the may be using a different material.
// TODO Cloning is not necessary if the material layouts are exactly the same.
// To check this we need to compare the material bindings used by the cached Geode
// and this new instance_geometry material bindings.
geode = static_cast<osg::Geode*>(cachedGeode->clone(osg::CopyOp::DEEP_COPY_DRAWABLES));
}
else
{
geo = processGeometry( geom );
geometryMap.insert( std::make_pair( geom, geo ) );
geode = processGeometry( geom );
geometryMap.insert( std::make_pair( geom, geode ) );
}
if ( geo == NULL )
if ( geode == NULL )
{
osg::notify( osg::WARN ) << "Failed to load geometry " << ig->getUrl().getURI() << std::endl;
return NULL;
}
//process material bindings
// process material bindings
if ( ig->getBind_material() != NULL )
{
processBindMaterial( ig->getBind_material(), geo );
processBindMaterial( ig->getBind_material(), geom, geode );
}
return geo;
return geode;
}
osg::Node* daeReader::processInstance_controller( domInstance_controller *ictrl )
// <controller>
// attributes:
// id, name
// elements:
// 0..1 <asset>
// 1 <skin>, <morph>
// 0..* <extra>
osg::Geode* daeReader::processInstanceController( domInstance_controller *ictrl )
{
//TODO: cache geometries so they don't get processed mulitple times.
//TODO: after cached need to check geometries and materials. both have to be the same for it
// to be the same instance.
//TODO: support skinning
osg::notify( osg::WARN ) << "Processing <instance_controller>. There is not skinning support but will display the base mesh." << std::endl;
daeElement *el = getElementFromURI( ictrl->getUrl() );
daeElement *el = getElementFromURI( ictrl->getUrl());
domController *ctrl = daeSafeCast< domController >( el );
if ( ctrl == NULL )
{
osg::notify( osg::WARN ) << "Failed to locate controller " << ictrl->getUrl().getURI() << std::endl;
osg::notify( osg::WARN ) << "Failed to locate conroller " << ictrl->getUrl().getURI() << std::endl;
return NULL;
}
osg::notify( osg::WARN ) << "Processing <controller>. There is not skinning support but will display the base mesh." << std::endl;
el = NULL;
//## non init
//## non init
daeURI *src=NULL;
if ( ctrl->getSkin() != NULL )
{
@@ -91,12 +103,13 @@ osg::Node* daeReader::processInstance_controller( domInstance_controller *ictrl
src = &ctrl->getSkin()->getSource();
el = getElementFromURI( ctrl->getMorph()->getSource() );
}
//non init case
if ( !src )
{
osg::notify( osg::WARN ) << "Failed to locate geometry : URI is NULL" << std::endl;
return NULL;
}
//non init case
if ( !src )
{
osg::notify( osg::WARN ) << "Failed to locate geometry : URI is NULL" << std::endl;
return NULL;
}
domGeometry *geom = daeSafeCast< domGeometry >( el );
if ( geom == NULL )
@@ -104,19 +117,29 @@ osg::Node* daeReader::processInstance_controller( domInstance_controller *ictrl
osg::notify( osg::WARN ) << "Failed to locate geometry " << src->getURI() << std::endl;
return NULL;
}
osg::Node *geo;
std::map< domGeometry*, osg::Node* >::iterator iter = geometryMap.find( geom );
// Check cache if geometry already exists
osg::Geode *geode;
domGeometryGeodeMap::iterator iter = geometryMap.find( geom );
if ( iter != geometryMap.end() )
{
geo = iter->second;
osg::Geode* cachedGeode = iter->second;
// Create a copy of the cached Geode with a copy of the drawables,
// because the may be using a different material.
// TODO Cloning is not necessary if the material layouts are exactly the same.
// To check this we need to compare the material bindings used by the cached Geode
// and this new instance_geometry material bindings.
geode = static_cast<osg::Geode*>(cachedGeode->clone(osg::CopyOp::DEEP_COPY_DRAWABLES));
}
else
{
geo = processGeometry( geom );
geometryMap.insert( std::make_pair( geom, geo ) );
geode = processGeometry( geom );
geometryMap.insert( std::make_pair( geom, geode ) );
}
if ( geo == NULL )
if ( geode == NULL )
{
osg::notify( osg::WARN ) << "Failed to load geometry " << src->getURI() << std::endl;
return NULL;
@@ -124,13 +147,20 @@ osg::Node* daeReader::processInstance_controller( domInstance_controller *ictrl
//process material bindings
if ( ictrl->getBind_material() != NULL )
{
processBindMaterial( ictrl->getBind_material(), geo );
processBindMaterial( ictrl->getBind_material(), geom, geode );
}
return geo;
return geode;
}
osg::Node *daeReader::processGeometry( domGeometry *geo )
// <geometry>
// attributes:
// id, name
// elements:
// 0..1 <asset>
// 1 <convex_mesh>, <mesh>, <spline>
// 0..* <extra>
osg::Geode *daeReader::processGeometry( domGeometry *geo )
{
domMesh *mesh = geo->getMesh();
if ( mesh == NULL )
@@ -138,124 +168,87 @@ osg::Node *daeReader::processGeometry( domGeometry *geo )
osg::notify( osg::WARN ) << "Unsupported Geometry type loading " << geo->getId() << std::endl;
return NULL;
}
osg::Node *node = new osg::Group();
if ( geo->getId() != NULL )
osg::Geode* geode = new osg::Geode;
if (geo->getId() != NULL )
{
node->setName( geo->getId() );
geode->setName( geo->getId() );
}
SourceMap sources;
// <mesh>
// elements:
// 1..* <source>
// 1 <vertices>
// 0..* <lines>, <linestrips>, <polygons>, <polylist>, <triangles>, <trifans>, <tristrips>
// 0..* <extra>
size_t count = mesh->getContents().getCount();
for ( size_t i = 0; i < count; i++ )
// 1..* <source>
SourceMap sources;
domSource_Array sourceArray = mesh->getSource_array();
for ( size_t i = 0; i < sourceArray.getCount(); i++)
{
if ( daeSafeCast< domVertices >( mesh->getContents()[i] ) != NULL ) continue;
domSource *s = daeSafeCast< domSource >( mesh->getContents()[i] );
if ( s != NULL )
{
sources.insert( std::make_pair( (daeElement*)mesh->getContents()[i],
domSourceReader( s ) ) );
continue;
}
osg::Node *n = NULL;
domTriangles *t = daeSafeCast< domTriangles >( mesh->getContents()[i] );
if ( t != NULL )
{
n = processSinglePPrimitive( t, sources, GL_TRIANGLES );
if ( n != NULL )
{
node->asGroup()->addChild( n );
}
continue;
}
domTristrips *ts = daeSafeCast< domTristrips >( mesh->getContents()[i] );
if ( ts != NULL )
{
n = processMultiPPrimitive( ts, sources, GL_TRIANGLE_STRIP );
if ( n != NULL )
{
node->asGroup()->addChild( n );
}
continue;
}
domTrifans *tf = daeSafeCast< domTrifans >( mesh->getContents()[i] );
if ( tf != NULL )
{
n = processMultiPPrimitive( tf, sources, GL_TRIANGLE_FAN );
if ( n != NULL )
{
node->asGroup()->addChild( n );
}
continue;
}
domLines *l = daeSafeCast< domLines >( mesh->getContents()[i] );
if ( l != NULL )
{
n = processSinglePPrimitive( l, sources, GL_LINES );
if ( n != NULL )
{
node->asGroup()->addChild( n );
}
continue;
}
domLinestrips *ls = daeSafeCast< domLinestrips >( mesh->getContents()[i] );
if ( ls != NULL )
{
n = processMultiPPrimitive( ls, sources, GL_LINE_STRIP );
if ( n != NULL )
{
node->asGroup()->addChild( n );
}
continue;
}
domPolygons *p = daeSafeCast< domPolygons >( mesh->getContents()[i] );
if ( p != NULL )
{
n = processMultiPPrimitive( p, sources, GL_POLYGON );
if ( n != NULL )
{
node->asGroup()->addChild( n );
}
continue;
}
domPolylist *pl = daeSafeCast< domPolylist >( mesh->getContents()[i] );
if ( pl != NULL )
{
n = processPolylist( pl, sources );
if ( n != NULL )
{
node->asGroup()->addChild( n );
}
continue;
}
osg::notify( osg::WARN ) << "Unsupported primitive type " << mesh->getContents()[i]->getTypeName() << " in geometry " << geo->getId() << std::endl;
sources.insert( std::make_pair((daeElement*)sourceArray[i], domSourceReader( sourceArray[i] ) ) );
}
return node;
// 0..* <lines>
domLines_Array linesArray = mesh->getLines_array();
for ( size_t i = 0; i < linesArray.getCount(); i++)
{
processSinglePPrimitive<domLines>(geode, linesArray[i], sources, GL_LINES );
}
// 0..* <linestrips>
domLinestrips_Array linestripsArray = mesh->getLinestrips_array();
for ( size_t i = 0; i < linestripsArray.getCount(); i++)
{
processMultiPPrimitive<domLinestrips>(geode, linestripsArray[i], sources, GL_LINE_STRIP );
}
// 0..* <polygons>
domPolygons_Array polygonsArray = mesh->getPolygons_array();
for ( size_t i = 0; i < polygonsArray.getCount(); i++)
{
processMultiPPrimitive<domPolygons>(geode, polygonsArray[i], sources, GL_POLYGON );
}
// 0..* <polylist>
domPolylist_Array polylistArray = mesh->getPolylist_array();
for ( size_t i = 0; i < polylistArray.getCount(); i++)
{
processPolylist(geode, polylistArray[i], sources );
}
// 0..* <triangles>
domTriangles_Array trianglesArray = mesh->getTriangles_array();
for ( size_t i = 0; i < trianglesArray.getCount(); i++)
{
processSinglePPrimitive<domTriangles>(geode, trianglesArray[i], sources, GL_TRIANGLES );
}
// 0..* <trifans>
domTrifans_Array trifansArray = mesh->getTrifans_array();
for ( size_t i = 0; i < trifansArray.getCount(); i++)
{
processMultiPPrimitive<domTrifans>(geode, trifansArray[i], sources, GL_TRIANGLE_FAN );
}
// 0..* <tristrips>
domTristrips_Array tristripsArray = mesh->getTristrips_array();
for ( size_t i = 0; i < tristripsArray.getCount(); i++)
{
processMultiPPrimitive<domTristrips>(geode, tristripsArray[i], sources, GL_TRIANGLE_STRIP );
}
return geode;
}
template< typename T >
osg::Node* daeReader::processSinglePPrimitive( T *group, SourceMap &sources, GLenum mode )
{
osg::Geode* geode = new osg::Geode();
osg::Geometry *geometry = new osg::Geometry();
//Setting the name of the geode to the material symbol for easy binding later
if ( group->getMaterial() != NULL )
{
geode->setName( group->getMaterial() );
}
template< typename T >
void daeReader::processSinglePPrimitive(osg::Geode* geode, T *group, SourceMap &sources, GLenum mode )
{
osg::Geometry *geometry = new osg::Geometry();
geometry->setName(group->getMaterial());
IndexMap index_map;
resolveArrays( group->getInput_array(), geometry, sources, index_map );
@@ -265,20 +258,13 @@ osg::Node* daeReader::processSinglePPrimitive( T *group, SourceMap &sources, GLe
geometry->addPrimitiveSet( dal );
geode->addDrawable( geometry );
return geode;
}
template< typename T >
osg::Node* daeReader::processMultiPPrimitive( T *group, SourceMap &sources, GLenum mode )
void daeReader::processMultiPPrimitive(osg::Geode* geode, T *group, SourceMap &sources, GLenum mode )
{
osg::Geode* geode = new osg::Geode();
osg::Geometry *geometry = new osg::Geometry();
//Setting the name of the geode to the material symbol for easy binding later
if ( group->getMaterial() != NULL )
{
geode->setName( group->getMaterial() );
}
geometry->setName(group->getMaterial());
IndexMap index_map;
resolveArrays( group->getInput_array(), geometry, sources, index_map );
@@ -292,19 +278,12 @@ template< typename T >
geometry->addPrimitiveSet( dal );
geode->addDrawable( geometry );
return geode;
}
osg::Node* daeReader::processPolylist( domPolylist *group, SourceMap &sources )
void daeReader::processPolylist(osg::Geode* geode, domPolylist *group, SourceMap &sources )
{
osg::Geode* geode = new osg::Geode();
osg::Geometry *geometry = new osg::Geometry();
//Setting the name of the geode to the material symbol for easy binding later
if ( group->getMaterial() != NULL )
{
geode->setName( group->getMaterial() );
}
geometry->setName(group->getMaterial());
IndexMap index_map;
resolveArrays( group->getInput_array(), geometry, sources, index_map );
@@ -342,12 +321,10 @@ osg::Node* daeReader::processPolylist( domPolylist *group, SourceMap &sources )
geometry->addPrimitiveSet( dal );
geode->addDrawable( geometry );
return geode;
}
void daeReader::processP( domP *p, osg::Geometry *&/*geom*/, IndexMap &index_map, osg::DrawArrayLengths* dal /*GLenum mode*/ )
{
//osg::DrawArrayLengths* dal = new osg::DrawArrayLengths( mode );
int idxcount = index_map.size();
int count = p->getValue().getCount();
count = (count/idxcount)*idxcount;
@@ -360,7 +337,6 @@ void daeReader::processP( domP *p, osg::Geometry *&/*geom*/, IndexMap &index_map
k->second->push_back(tmp);
}
}
//geom->addPrimitiveSet( dal );
}
void daeReader::resolveArrays( domInputLocalOffset_Array &inputs, osg::Geometry *&geom,
@@ -377,9 +353,11 @@ void daeReader::resolveArrays( domInputLocalOffset_Array &inputs, osg::Geometry
daeElement *tmp_el;
domInputLocalOffset *tmp_input;
if ( findInputSourceBySemantic( inputs, "VERTEX", tmp_el, &tmp_input ) ) {
if ( findInputSourceBySemantic( inputs, "VERTEX", tmp_el, &tmp_input ) )
{
vertices = daeSafeCast< domVertices >( tmp_el );
if ( vertices == NULL ) {
if ( vertices == NULL )
{
osg::notify( osg::WARN )<<"Could not get vertices"<<std::endl;
return;
}
@@ -393,7 +371,8 @@ void daeReader::resolveArrays( domInputLocalOffset_Array &inputs, osg::Geometry
findInputSourceBySemantic( vertices->getInput_array(), "NORMAL", normal_source, &tmp );
findInputSourceBySemantic( vertices->getInput_array(), "TEXCOORD", texcoord_source, &tmp );
if ( index_map[offset] == NULL ) {
if ( index_map[offset] == NULL )
{
index_map[offset] = new osg::IntArray();
}
geom->setVertexIndices( index_map[offset] );
@@ -436,9 +415,8 @@ void daeReader::resolveArrays( domInputLocalOffset_Array &inputs, osg::Geometry
return;
}
if ( findInputSourceBySemantic( inputs, "COLOR", color_source, &tmp_input ) ) {
if ( findInputSourceBySemantic( inputs, "COLOR", color_source, &tmp_input ))
{
offset = tmp_input->getOffset();
if ( index_map[offset] == NULL ) {
index_map[offset] = new osg::IntArray();
@@ -446,32 +424,36 @@ void daeReader::resolveArrays( domInputLocalOffset_Array &inputs, osg::Geometry
geom->setColorIndices( index_map[offset] );
}
if ( color_source != NULL ) {
if ( color_source != NULL )
{
geom->setColorArray( sources[color_source].getVec4Array() );
geom->setColorBinding( osg::Geometry::BIND_PER_VERTEX );
}
if ( findInputSourceBySemantic( inputs, "NORMAL", normal_source, &tmp_input ) ) {
if ( findInputSourceBySemantic( inputs, "NORMAL", normal_source, &tmp_input ) )
{
offset = tmp_input->getOffset();
if ( index_map[offset] == NULL ) {
if ( index_map[offset] == NULL )
{
index_map[offset] = new osg::IntArray();
}
geom->setNormalIndices( index_map[offset] );
}
if ( normal_source ) {
if ( normal_source )
{
geom->setNormalArray( sources[normal_source].getVec3Array() );
geom->setNormalBinding( osg::Geometry::BIND_PER_VERTEX );
}
int unit = 0;
while ( findInputSourceBySemantic( inputs, "TEXCOORD", texcoord_source, &tmp_input, unit ) ) {
while ( findInputSourceBySemantic( inputs, "TEXCOORD", texcoord_source, &tmp_input, unit ) )
{
offset = tmp_input->getOffset();
set = tmp_input->getSet();
if ( index_map[offset] == NULL ) {
if ( index_map[offset] == NULL )
{
index_map[offset] = new osg::IntArray();
}
//this should really be set. Then when you bind_vertex_input you can adjust accordingly for the

View File

@@ -29,84 +29,120 @@
using namespace osgdae;
void daeReader::processBindMaterial( domBind_material *bm, osg::Node *geo )
// <bind_material>
// elements:
// 0..* <param>
// name
// sid
// semantic
// type
// 1 <technique_common>
// 0..* <instance_material>
// symbol
// target
// sid
// name
// 0..* <technique>
// profile
// 0..* <extra>
// id
// name
// type
void daeReader::processBindMaterial( domBind_material *bm, domGeometry *geom, osg::Geode *geode )
{
if ( bm->getTechnique_common() == NULL )
if (bm->getTechnique_common() == NULL )
{
osg::notify( osg::WARN ) << "No COMMON technique for bind_material" << std::endl;
return;
}
osg::Group *group = geo->asGroup();
if ( group == NULL )
{
//this shouldn't happen unless something is terribly wrong
return;
}
domInstance_material_Array &ima = bm->getTechnique_common()->getInstance_material_array();
size_t count = ima.getCount();
for ( size_t i = 0; i < count; i++ )
{
std::string symbol = ima[i]->getSymbol();
domMaterial *mat = daeSafeCast< domMaterial >( getElementFromURI( ima[i]->getTarget() ) );
if ( mat == NULL )
{
osg::notify( osg::WARN ) << "Failed to locate material " << ima[i]->getTarget().getURI() << std::endl;
continue;
}
osg::StateSet *ss;
//check material cache if this material already exists
std::map< domMaterial*, osg::StateSet*>::iterator iter = materialMap.find( mat );
if ( iter != materialMap.end() )
{
ss = iter->second;
}
else
{
ss = processMaterial( mat );
materialMap.insert( std::make_pair( mat, ss ) );
}
if ( ss == NULL )
{
continue;
}
//TODO: process all of the <bind>s and <bind_vertex_input>s that are here in the instance_material.
for ( unsigned int x = 0; x < group->getNumChildren(); x++ )
for (size_t i =0; i < geode->getNumDrawables(); i++)
{
osg::Drawable* drawable = geode->getDrawable(i);
std::string materialName = drawable->getName();
domInstance_material_Array &ima = bm->getTechnique_common()->getInstance_material_array();
std::string symbol;
bool found = false;
for ( size_t j = 0; j < ima.getCount(); j++)
{
//I named the geode with the material symbol so I can do this check for binding
if ( group->getChild( x )->getName() == symbol )
{
/*if ( group->getChild( x )->getStateSet() != NULL )
symbol = ima[j]->getSymbol();
if (symbol.compare(materialName) == 0)
{
found = true;
domMaterial *mat = daeSafeCast< domMaterial >(getElementFromURI( ima[j]->getTarget()));
if (mat)
{
//already have a stateSet this means I am an instance so clone me.
group->replaceChild( group->getChild( x ), (osg::Node*)group->getChild( x )->cloneType() );
}*/
group->getChild( x )->setStateSet( ss );
// Check material cache if this material already exists
domMaterialStateSetMap::iterator iter = materialMap.find( mat );
if ( iter != materialMap.end() )
{
// Reuse material
drawable->setStateSet(iter->second);
}
else
{
// Create new material
osg::StateSet* ss = new osg::StateSet;
processMaterial(ss, mat);
drawable->setStateSet(ss);
materialMap.insert(std::make_pair(mat, ss));
}
}
else
{
osg::notify( osg::WARN ) << "Failed to locate <material> wit id " << ima[i]->getTarget().getURI() << std::endl;
}
break;
}
}
if (!found)
{
osg::notify( osg::WARN ) << "Failed to locate <instance_material> with symbol " << materialName << std::endl;
}
}
}
osg::StateSet *daeReader::processMaterial( domMaterial *mat )
// <material>
// attributes:
// 0..1 id
// 0..1 name
// elements:
// 0..1 <asset>
// 1 <instance_effect>
// 0..* <extra>
void daeReader::processMaterial(osg::StateSet *ss, domMaterial *mat )
{
currentInstance_effect = mat->getInstance_effect();
domEffect *effect = daeSafeCast< domEffect >( getElementFromURI( currentInstance_effect->getUrl() ) );
if ( effect == NULL )
if (effect)
{
processEffect(ss, effect);
//TODO: process all of the setParams that could happen here in the material. ESP. the textures
}
else
{
osg::notify( osg::WARN ) << "Failed to locate effect " << mat->getInstance_effect()->getUrl().getURI() << std::endl;
return NULL;
}
osg::StateSet *ss = processEffect( effect );
//TODO: process all of the setParams that could happen here in the material. ESP. the textures
return ss;
}
osg::StateSet *daeReader::processEffect( domEffect *effect )
// <effect>
// attributes:
// 1 id
// 0..1 name
// elements:
// 0..1 <asset>
// 0..* <annotate>
// 0..* <image>
// 0..* <newparam>
// 1..* <fx_profile_abstract>
// 0..* <extra>
void daeReader::processEffect(osg::StateSet *ss, domEffect *effect )
{
bool hasCOMMON = false;
osg::StateSet *ss = NULL;
for ( size_t i = 0; i < effect->getFx_profile_abstract_array().getCount(); i++ )
{
@@ -119,21 +155,28 @@ osg::StateSet *daeReader::processEffect( domEffect *effect )
continue;
}
currentEffect = effect;
ss = processProfileCOMMON( pc );
processProfileCOMMON(ss, pc);
hasCOMMON = true;
continue;
}
osg::notify( osg::WARN ) << "unsupported effect profile " << effect->getFx_profile_abstract_array()[i]->getTypeName() << std::endl;
}
return ss;
}
osg::StateSet *daeReader::processProfileCOMMON( domProfile_COMMON *pc )
// <profile_COMMON>
// elements:
// 0..* <image>, <newparam>
// 1 <technique>
// attributes:
// elements:
// 0..1 <asset>
// 0..* <image>, <newparam>
// 1 <constant>, <lambert>, <phong>, <blinn>
// 0..* <extra>
// 0..* <extra>
void daeReader::processProfileCOMMON(osg::StateSet *ss, domProfile_COMMON *pc )
{
osg::StateSet *ss = new osg::StateSet();
domProfile_COMMON::domTechnique *teq = pc->getTechnique();
domProfile_COMMON::domTechnique::domConstant *c = teq->getConstant();
@@ -143,42 +186,53 @@ osg::StateSet *daeReader::processProfileCOMMON( domProfile_COMMON *pc )
ss->setMode( GL_CULL_FACE, GL_TRUE );
if (m_AuthoringTool == GOOGLE_SKETCHUP)
// See if there are any extra's that are supported by OpenSceneGraph
const domExtra_Array& ExtraArray = pc->getExtra_array();
size_t NumberOfExtras = ExtraArray.getCount();
size_t CurrentExtra;
for (CurrentExtra = 0; CurrentExtra < NumberOfExtras; CurrentExtra++)
{
const domExtra_Array& ExtraArray = pc->getExtra_array();
size_t NumberOfExtras = ExtraArray.getCount();
size_t CurrentExtra;
for (CurrentExtra = 0; CurrentExtra < NumberOfExtras; CurrentExtra++)
const domTechnique_Array& TechniqueArray = ExtraArray[CurrentExtra]->getTechnique_array();
size_t NumberOfTechniques = TechniqueArray.getCount();
size_t CurrentTechnique;
for (CurrentTechnique = 0; CurrentTechnique < NumberOfTechniques; CurrentTechnique++)
{
const domTechnique_Array& TechniqueArray = ExtraArray[CurrentExtra]->getTechnique_array();
size_t NumberOfTechniques = TechniqueArray.getCount();
size_t CurrentTechnique;
for (CurrentTechnique = 0; CurrentTechnique < NumberOfTechniques; CurrentTechnique++)
// <technique profile="GOOGLEEARTH">
// <double_sided>0</double_sided>
// </technique>
if (strcmp(TechniqueArray[CurrentTechnique]->getProfile(), "GOOGLEEARTH") == 0)
{
if (strcmp(TechniqueArray[CurrentTechnique]->getProfile(), "GOOGLEEARTH") == 0)
const daeElementRefArray& ElementArray = TechniqueArray[CurrentTechnique]->getContents();
size_t NumberOfElements = ElementArray.getCount();
size_t CurrentElement;
for (CurrentElement = 0; CurrentElement < NumberOfElements; CurrentElement++)
{
const daeElementRefArray& ElementArray = TechniqueArray[CurrentTechnique]->getContents();
size_t NumberOfElements = ElementArray.getCount();
size_t CurrentElement;
for (CurrentElement = 0; CurrentElement < NumberOfElements; CurrentElement++)
domAny* pAny = (domAny*)ElementArray[CurrentElement].cast();
if (strcmp(pAny->getElementName(), "double_sided") == 0)
{
domAny* pAny = (domAny*)ElementArray[CurrentElement].cast();
if (strcmp(pAny->getElementName(), "double_sided") == 0)
{
daeString Value = pAny->getValue();
if (strcmp(Value, "1") == 0)
ss->setMode( GL_CULL_FACE, GL_FALSE );
}
daeString Value = pAny->getValue();
if (strcmp(Value, "1") == 0)
ss->setMode( GL_CULL_FACE, GL_FALSE );
}
}
}
}
}
//ss->setMode( GL_LIGHTING, GL_FALSE );
osg::ref_ptr< osg::Material > mat = new osg::Material();
bool insertMat = false;
// <blinn>
// elements:
// 0..1 <emission>
// 0..1 <ambient>
// 0..1 <diffuse>
// 0..1 <specular>
// 0..1 <shininess>
// 0..1 <reflective>
// 0..1 <reflectivity>
// 0..1 <transparent>
// 0..1 <transparency>
// 0..1 <index_of_refraction>
if ( b != NULL )
{
bool tmp;
@@ -197,7 +251,7 @@ osg::StateSet *daeReader::processProfileCOMMON( domProfile_COMMON *pc )
ss->setTextureAttribute( 0, sa );
}
tmp = processColorOrTextureType( b->getSpecular(), osg::Material::SPECULAR, mat.get(), b->getShininess() );
tmp = processColorOrTextureType( b->getSpecular(), osg::Material::SPECULAR, mat.get(), b->getShininess(), NULL, true );
insertMat = insertMat || tmp;
osg::StateAttribute *sa2 = NULL;
@@ -214,16 +268,33 @@ osg::StateSet *daeReader::processProfileCOMMON( domProfile_COMMON *pc )
osg::notify( osg::WARN ) << "Already have a texture in the diffuse channel" << std::endl;
}
}
}
// <phong>
// elements:
// 0..1 <emission>
// 0..1 <ambient>
// 0..1 <diffuse>
// 0..1 <specular>
// 0..1 <shininess>
// 0..1 <reflective>
// 0..1 <reflectivity>
// 0..1 <transparent>
// 0..1 <transparency>
// 0..1 <index_of_refraction>
else if ( p != NULL )
{
bool tmp;
tmp = processColorOrTextureType( p->getEmission(), osg::Material::EMISSION, mat.get() );
insertMat = insertMat || tmp;
tmp = processColorOrTextureType( p->getAmbient(), osg::Material::AMBIENT, mat.get() );
osg::StateAttribute *sa1 = NULL;
tmp = processColorOrTextureType( p->getAmbient(), osg::Material::AMBIENT, mat.get(), NULL, &sa1 );
insertMat = insertMat || tmp;
if ( sa1 != NULL )
{
ss->setTextureMode( 1, GL_TEXTURE_2D, GL_TRUE );
ss->setTextureAttribute( 0, sa1 );
}
osg::StateAttribute *sa = NULL;
tmp = processColorOrTextureType( p->getDiffuse(), osg::Material::DIFFUSE, mat.get(), NULL, &sa );
@@ -253,6 +324,16 @@ osg::StateSet *daeReader::processProfileCOMMON( domProfile_COMMON *pc )
}
}
// <lambert>
// elements:
// 0..1 <emission>
// 0..1 <ambient>
// 0..1 <diffuse>
// 0..1 <reflective>
// 0..1 <reflectivity>
// 0..1 <transparent>
// 0..1 <transparency>
// 0..1 <index_of_refraction>
else if ( l != NULL )
{
bool tmp;
@@ -287,6 +368,14 @@ osg::StateSet *daeReader::processProfileCOMMON( domProfile_COMMON *pc )
}
}
// <constant>
// elements:
// 0..1 <emission>
// 0..1 <reflective>
// 0..1 <reflectivity>
// 0..1 <transparent>
// 0..1 <transparency>
// 0..1 <index_of_refraction>
else if ( c != NULL )
{
insertMat = processColorOrTextureType( c->getEmission(), osg::Material::EMISSION, mat.get() );
@@ -303,21 +392,32 @@ osg::StateSet *daeReader::processProfileCOMMON( domProfile_COMMON *pc )
{
ss->setAttribute( mat.get() );
}
return ss;
}
bool daeReader::processColorOrTextureType( domCommon_color_or_texture_type *cot,
osg::Material::ColorMode channel,
osg::Material *mat,
domCommon_float_or_param_type *fop,
osg::StateAttribute **sa )
// colorOrTexture
// 1 of
// <color>
// <param>
// attributes:
// 1 ref
// <texture>
// attributes:
// 1 texture
// 1 texcoord
// 0..* extra
bool daeReader::processColorOrTextureType( domCommon_color_or_texture_type *cot,
osg::Material::ColorMode channel,
osg::Material *mat,
domCommon_float_or_param_type *fop,
osg::StateAttribute **sa,
bool blinn)
{
if ( cot == NULL )
{
return false;
}
bool retVal = false;
//osg::StateAttribute *sa = NULL;
//TODO: Make all channels process <param ref=""> type of value
if ( channel == osg::Material::EMISSION )
@@ -328,7 +428,6 @@ osg::StateAttribute **sa )
mat->setEmission( osg::Material::FRONT_AND_BACK, osg::Vec4( f4[0], f4[1], f4[2], f4[3] ) );
retVal = true;
}
else if (cot->getParam() != NULL)
{
domFloat4 f4;
@@ -338,10 +437,14 @@ osg::StateAttribute **sa )
retVal = true;
}
}
else
else if (cot->getTexture() != NULL)
{
osg::notify( osg::WARN ) << "Currently no support for <texture> in Emission channel " << std::endl;
}
else
{
osg::notify( osg::WARN ) << "Missing <color>, <param> or <texture> in Emission channel " << std::endl;
}
}
else if ( channel == osg::Material::AMBIENT )
{
@@ -360,9 +463,14 @@ osg::StateAttribute **sa )
retVal = true;
}
}
else if (cot->getTexture() != NULL && sa != NULL)
{
*sa = processTexture( cot->getTexture() );
//osg::notify( osg::WARN ) << "Currently no support for <texture> in Ambient channel " << std::endl;
}
else
{
osg::notify( osg::WARN ) << "Currently no support for <texture> in Ambient channel " << std::endl;
osg::notify( osg::WARN ) << "Missing <color>, <param> or <texture> in Ambient channel " << std::endl;
}
}
else if ( channel == osg::Material::DIFFUSE )
@@ -377,8 +485,7 @@ osg::StateAttribute **sa )
{
*sa = processTexture( cot->getTexture() );
domExtra *extra = cot->getTexture()->getExtra();
if ( extra != NULL && extra->getType() != NULL &&
strcmp( extra->getType(), "color" ) == 0 )
if ( extra != NULL && extra->getType() != NULL && strcmp( extra->getType(), "color" ) == 0 )
{
//the extra data for osg. Diffuse color can happen with a texture.
for ( unsigned int i = 0; i < extra->getTechnique_array().getCount(); i++ )
@@ -406,6 +513,10 @@ osg::StateAttribute **sa )
retVal = true;
}
}
else
{
osg::notify( osg::WARN ) << "Missing <color>, <param> or <texture> in Diffuse channel " << std::endl;
}
}
else if ( channel == osg::Material::SPECULAR )
{
@@ -415,7 +526,7 @@ osg::StateAttribute **sa )
mat->setSpecular( osg::Material::FRONT_AND_BACK, osg::Vec4( f4[0], f4[1], f4[2], f4[3] ) );
retVal = true;
}
else if (cot->getParam() != NULL)
else if (cot->getParam() != NULL)
{
domFloat4 f4;
if (GetFloat4Param(cot->getParam()->getRef(), f4))
@@ -424,13 +535,25 @@ osg::StateAttribute **sa )
retVal = true;
}
}
else
else if (cot->getTexture() != NULL)
{
osg::notify( osg::WARN ) << "Currently no support for <texture> in Specular channel " << std::endl;
}
else
{
osg::notify( osg::WARN ) << "Missing <color>, <param> or <texture> in Specular channel " << std::endl;
}
if ( fop != NULL && fop->getFloat() != NULL )
{
mat->setShininess( osg::Material::FRONT_AND_BACK, fop->getFloat()->getValue() );
float shininess = fop->getFloat()->getValue();
if (blinn)
{
// If the blinn mode is in the range [0,1] rescale it to [0,128]
if (shininess < 1)
shininess *= 128.0f;
}
mat->setShininess( osg::Material::FRONT_AND_BACK, shininess );
retVal = true;
}
}
@@ -808,6 +931,28 @@ osg::StateAttribute *daeReader::processTexture( domCommon_color_or_texture_type_
return t2D;
}
/*
Collada 1.4.1 Specification (2nd Edition) Patch Release Notes: Revision C Release notes
In <blinn>, <constant>, <lambert>, and <phong>, the child element <transparent> now has an
optional opaque attribute whose valid values are:
<EFBFBD> A_ONE (the default): Takes the transparency information from the color<6F>s alpha channel, where the value 1.0 is opaque.
<EFBFBD> RGB_ZERO: Takes the transparency information from the color<6F>s red, green, and blue channels, where the value 0.0 is opaque,
with each channel modulated independently.
In the Specification, this is described in the <20>FX Reference<63> chapter in the
common_color_or_texture_type entry, along with a description of how transparency works in the
<EFBFBD>Getting Started with COLLADA FX<46> chapter in the <20>Determining Transparency<63> section.
Collada Digital Asset Schema Release 1.5.0 Release Notes
The <transparent> element<6E>s opaque attribute now allows, in addition to A_ONE and RGB_ZERO, the following values:
<EFBFBD> A_ZERO (the default): Takes the transparency information from the color<6F>s alpha channel, where the value 0.0 is opaque.
<EFBFBD> RGB_ONE: Takes the transparency information from the color<6F>s red, green, and blue channels, where the value 1.0 is opaque,
with each channel modulated independently.
*/
osg::StateAttribute *daeReader::processTransparencySettings( domCommon_transparent_type *ctt, domCommon_float_or_param_type *pTransparency, osg::StateSet *ss )
{
if (NULL == ctt && NULL == pTransparency)
@@ -881,17 +1026,6 @@ osg::StateAttribute *daeReader::processTransparencySettings( domCommon_transpare
}
}
osg::BlendColor *bc = new osg::BlendColor();
bc->setConstantColor(osg::Vec4( f4[0] * Transparency, f4[1] * Transparency, f4[2] * Transparency, f4[3] * Transparency ));
ss->setAttribute( bc );
osg::BlendFunc *bf;
if (FX_OPAQUE_ENUM_A_ONE == Opaque)
bf = new osg::BlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA);
else
bf = new osg::BlendFunc(GL_ONE_MINUS_CONSTANT_COLOR, GL_CONSTANT_COLOR);
ss->setAttribute( bf );
ss->setMode( GL_BLEND, GL_TRUE );
if (FX_OPAQUE_ENUM_A_ONE == Opaque)
{
if (Transparency * f4[3] > 0.99f)
@@ -908,7 +1042,20 @@ osg::StateAttribute *daeReader::processTransparencySettings( domCommon_transpare
return NULL;
}
osg::BlendColor *bc = new osg::BlendColor();
bc->setConstantColor(osg::Vec4( f4[0] * Transparency, f4[1] * Transparency, f4[2] * Transparency, f4[3] * Transparency ));
ss->setAttribute( bc );
osg::BlendFunc *bf;
if (FX_OPAQUE_ENUM_A_ONE == Opaque)
bf = new osg::BlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA);
else
bf = new osg::BlendFunc(GL_ONE_MINUS_CONSTANT_COLOR, GL_CONSTANT_COLOR);
ss->setAttribute( bf );
ss->setMode( GL_BLEND, GL_TRUE );
ss->setRenderingHint( osg::StateSet::TRANSPARENT_BIN );
ss->setRenderBinDetails( 10, "DepthSortedBin" );
return NULL;
}
// 0..* <extra>

View File

@@ -13,18 +13,316 @@
#include "daeReader.h"
#include <dae.h>
#include <dae/domAny.h>
#include <dom/domCOLLADA.h>
#include <osg/Switch>
#include <osg/LightSource>
#include <osg/Geode>
#include <osg/Switch>
#include <osg/ShapeDrawable>
#include <osg/LOD>
#include <osg/Billboard>
#include <osgSim/MultiSwitch>
#include <osg/Sequence>
using namespace osgdae;
osg::Node* daeReader::processOsgMultiSwitch(domTechnique* teq)
{
osgSim::MultiSwitch* msw = new osgSim::MultiSwitch;
domAny* any = daeSafeCast<domAny>(teq->getChild("ActiveSwitchSet"));
if (any)
{
msw->setActiveSwitchSet(parseString<unsigned int>(any->getValue()));
}
else
{
osg::notify(osg::WARN) << "Expected element 'ActiveSwitchSet' not found" << std::endl;
}
any = daeSafeCast<domAny>(teq->getChild("ValueLists"));
if (any)
{
unsigned int numChildren = any->getChildren().getCount();
for (unsigned int currChild = 0; currChild < numChildren; currChild++)
{
domAny* child = daeSafeCast<domAny>(any->getChildren()[currChild]);
if (child)
{
if (strcmp(child->getElementName(), "ValueList" ) == 0 )
{
std::list<std::string> stringValues;
osgSim::MultiSwitch::ValueList values;
cdom::tokenize(child->getValue(), " ", stringValues);
cdom::tokenIter iter = stringValues.begin();
while (iter != stringValues.end())
{
values.push_back(parseString<bool>(*iter));
++iter;
}
msw->setValueList(currChild, values);
}
else
{
osg::notify(osg::WARN) << "Child of element 'ValueLists' is not of type 'ValueList'" << std::endl;
}
}
else
{
osg::notify(osg::WARN) << "Element 'ValueLists' does not contain expected elements." << std::endl;
}
}
}
else
{
osg::notify(osg::WARN) << "Expected element 'ValueLists' not found" << std::endl;
}
return msw;
}
osg::Node* daeReader::processOsgSwitch(domTechnique* teq)
{
osg::Switch* sw = new osg::Switch;
domAny* any = daeSafeCast< domAny >(teq->getChild("ValueList"));
if (any)
{
std::list<std::string> stringValues;
cdom::tokenize(any->getValue(), " ", stringValues);
cdom::tokenIter iter = stringValues.begin();
int pos = 0;
while (iter != stringValues.end())
{
sw->setValue(pos++, parseString<bool>(*iter));
++iter;
}
}
else
{
osg::notify(osg::WARN) << "Expected element 'ValueList' not found" << std::endl;
}
return sw;
}
osg::Node* daeReader::processOsgSequence(domTechnique* teq)
{
osg::Sequence* sq = new osg::Sequence;
domAny* any = daeSafeCast< domAny >(teq->getChild("FrameTime"));
if (any)
{
std::list<std::string> stringValues;
cdom::tokenize(any->getValue(), " ", stringValues);
cdom::tokenIter iter = stringValues.begin();
int frame = 0;
while (iter != stringValues.end())
{
sq->setTime(frame++, parseString<double>(*iter));
++iter;
}
}
else
{
osg::notify(osg::WARN) << "Expected element 'FrameTime' not found" << std::endl;
}
any = daeSafeCast< domAny >(teq->getChild("LastFrameTime"));
if (any)
{
sq->setLastFrameTime(parseString<double>(any->getValue()));
}
else
{
osg::notify(osg::WARN) << "Expected element 'LastFrameTime' not found" << std::endl;
}
osg::Sequence::LoopMode loopmode;
any = daeSafeCast< domAny >(teq->getChild("LoopMode"));
if (any)
{
loopmode = (osg::Sequence::LoopMode)parseString<int>(any->getValue());
}
else
{
osg::notify(osg::WARN) << "Expected element 'LoopMode' not found" << std::endl;
}
int begin=0;
any = daeSafeCast< domAny >(teq->getChild("IntervalBegin"));
if (any)
{
begin = parseString<int>(any->getValue());
}
else
{
osg::notify(osg::WARN) << "Expected element 'IntervalBegin' not found" << std::endl;
}
int end=-1;
any = daeSafeCast< domAny >(teq->getChild("IntervalEnd"));
if (any)
{
end = parseString<int>(any->getValue());
}
else
{
osg::notify(osg::WARN) << "Expected element 'IntervalEnd' not found" << std::endl;
}
sq->setInterval(loopmode, begin, end);
float speed = 0;
any = daeSafeCast< domAny >(teq->getChild("DurationSpeed"));
if (any)
{
speed = parseString<float>(any->getValue());
}
else
{
osg::notify(osg::WARN) << "Expected element 'DurationSpeed' not found" << std::endl;
}
int nreps = -1;
any = daeSafeCast< domAny >(teq->getChild("DurationNReps"));
if (any)
{
nreps = parseString<int>(any->getValue());
}
else
{
osg::notify(osg::WARN) << "Expected element 'DurationNReps' not found" << std::endl;
}
sq->setDuration(speed, nreps);
any = daeSafeCast< domAny >(teq->getChild("SequenceMode"));
if (any)
{
sq->setMode((osg::Sequence::SequenceMode)parseString<int>(any->getValue()));
}
else
{
osg::notify(osg::WARN) << "Expected element 'SequenceMode' not found" << std::endl;
}
return sq;
}
osg::Node* daeReader::processOsgLOD(domTechnique* teq)
{
osg::LOD* lod = new osg::LOD;
domAny* any = daeSafeCast< domAny >(teq->getChild("Center"));
if (any)
{
// If a center is specified
lod->setCenterMode(osg::LOD::USER_DEFINED_CENTER);
lod->setCenter(parseVec3String(any->getValue()));
any = daeSafeCast< domAny >(teq->getChild("Radius"));
if (any)
{
lod->setRadius(parseString<osg::LOD::value_type>(any->getValue()));
}
else
{
osg::notify(osg::WARN) << "Expected element 'Radius' not found" << std::endl;
}
}
any = daeSafeCast< domAny >(teq->getChild("RangeMode"));
if (any)
{
lod->setRangeMode((osg::LOD::RangeMode)parseString<int>(any->getValue()));
}
else
{
osg::notify(osg::WARN) << "Expected element 'RangeMode' not found" << std::endl;
}
any = daeSafeCast< domAny >(teq->getChild("RangeList"));
if (any)
{
osg::LOD::RangeList rangelist;
unsigned int numChildren = any->getChildren().getCount();
for (unsigned int currChild = 0; currChild < numChildren; currChild++)
{
domAny* child = daeSafeCast<domAny>(any->getChildren()[currChild]);
if (child)
{
if (strcmp(child->getElementName(), "MinMax" ) == 0 )
{
std::list<std::string> stringValues;
osg::LOD::MinMaxPair minMaxPair;
cdom::tokenize(child->getValue(), " ", stringValues);
cdom::tokenIter iter = stringValues.begin();
if (iter != stringValues.end())
{
minMaxPair.first = parseString<float>(*iter);
++iter;
}
else
{
osg::notify(osg::WARN) << "'MinMax' does not contain a valid minimum value" << std::endl;
}
if (iter != stringValues.end())
{
minMaxPair.second = parseString<float>(*iter);
}
else
{
osg::notify(osg::WARN) << "'MinMax' does not contain a valid maximum value" << std::endl;
}
rangelist.push_back(minMaxPair);
}
else
{
osg::notify(osg::WARN) << "Child of element 'RangeList' is not of type 'MinMax'" << std::endl;
}
}
else
{
osg::notify(osg::WARN) << "Element 'RangeList' does not contain expected elements." << std::endl;
}
}
lod->setRangeList(rangelist);
}
else
{
osg::notify(osg::WARN) << "Expected element 'RangeList' not found" << std::endl;
}
return lod;
}
// <light>
// attributes:
// id, name
// elements:
// 0..1 <asset>
// 1 <technique_common>
// 1 <ambient>, <directional>, <point>, <spot>
// 0..* <technique>
// 0..* <extra>
osg::Node* daeReader::processLight( domLight *dlight )
{
osg::Node *node = new osg::Switch();
//do light processing here.
domLight::domTechnique_common::domAmbient *ambient;
domLight::domTechnique_common::domDirectional *directional;
@@ -38,8 +336,6 @@ osg::Node* daeReader::processLight( domLight *dlight )
return NULL;
}
osg::Node* node = new osg::Switch();
osg::Light* light = new osg::Light();
osg::LightSource* lightsource = new osg::LightSource();
@@ -182,11 +478,25 @@ osg::Node* daeReader::processLight( domLight *dlight )
return node;
}
osg::Node* daeReader::processCamera( domCamera* /*dcamera*/ )
// <camera>
// attributes:
// id, name
// elements:
// 0..1 <asset>
// 1 <optics>
// 1 <technique_common>
// 1 <orthographic>, <perspective>
// 0..* <technique>
// 0..* <extra>
// 0..* <imager>
// 1 <technique>
// 0..* <extra>
// 0..* <extra>
osg::Node* daeReader::processCamera( domCamera * dcamera )
{
//TODO: Make the camera actually make a camera to view from. Not just draw a cone.
osg::Node *node = new osg::Switch();
//TODO: Make the camera actually make a camera to view from. Not just draw a cone.
osg::Cone* cone = new osg::Cone();
osg::ShapeDrawable* sd = new osg::ShapeDrawable(cone);

View File

@@ -13,185 +13,357 @@
#include "daeReader.h"
#include <dae.h>
#include <dae/domAny.h>
#include <dom/domCOLLADA.h>
#include <osg/PositionAttitudeTransform>
#include <osg/MatrixTransform>
#include <osgSim/DOFTransform>
using namespace osgdae;
osg::Transform* daeReader::processMatrix( domMatrix *mat )
// Note <lookat>, <matrix>, <rotate>, <scale>, <skew> and <translate> may appear in any order
// These transformations can be combined in any number and ordering to produce the desired
// coordinate systemfor the parent <node> element. The COLLADA specificatin requires that the
// transformation elements are processed in order and accumulate the result as if they were
// converted to column-order matrices and concatenated using matrix post-multiplication.
osg::Node* daeReader::processOsgMatrixTransform( domNode *node )
{
osg::Transform* xform = new osg::MatrixTransform();
xform->setDataVariance(osg::Object::STATIC);
osg::MatrixTransform* matNode = new osg::MatrixTransform;
osg::Matrix matrix;
xform->setName( mat->getSid() ? mat->getSid() : "" );
osg::Matrix m;
if (mat->getValue().getCount() != 16 ) {
osg::notify(osg::WARN)<<"Data is wrong size for matrix"<<std::endl;
return NULL;
}
//m.set((daeDouble*)mat->getValue().getRawData());
m.set( mat->getValue()[0], mat->getValue()[4], mat->getValue()[8], mat->getValue()[12],
mat->getValue()[1], mat->getValue()[5], mat->getValue()[9], mat->getValue()[13],
mat->getValue()[2], mat->getValue()[6], mat->getValue()[10], mat->getValue()[14],
mat->getValue()[3], mat->getValue()[7], mat->getValue()[11], mat->getValue()[15] );
xform->asMatrixTransform()->setMatrix(m);
return xform;
}
osg::Transform* daeReader::processTranslate( domTranslate *trans )
{
osg::Transform* xform = new osg::PositionAttitudeTransform();
//xform->setDataVariance(osg::Object::STATIC);
xform->setName( trans->getSid() ? trans->getSid() : "" );
if (trans->getValue().getCount() != 3 ) {
osg::notify(osg::WARN)<<"Data is wrong size for translate"<<std::endl;
return NULL;
}
domFloat3& t = trans->getValue();
xform->asPositionAttitudeTransform()->setPosition(
osg::Vec3(t[0],t[1],t[2]));
return xform;
}
osg::Transform* daeReader::processRotate( domRotate *rot )
{
osg::Transform* xform = new osg::PositionAttitudeTransform();
//xform->setDataVariance(osg::Object::STATIC);
xform->setName( rot->getSid() ? rot->getSid() : "" );
if (rot->getValue().getCount() != 4 ) {
osg::notify(osg::WARN)<<"Data is wrong size for rotate"<<std::endl;
return NULL;
}
domFloat4& r = rot->getValue();
osg::Vec3 axis;
axis.set(r[0],r[1],r[2]);
xform->asPositionAttitudeTransform()->setAttitude(
osg::Quat(osg::DegreesToRadians(r[3]),axis));
return xform;
}
osg::Transform* daeReader::processScale( domScale *scale )
{
osg::Transform* xform = new osg::PositionAttitudeTransform();
//xform->setDataVariance(osg::Object::STATIC);
xform->setName( scale->getSid() ? scale->getSid() : "" );
if (scale->getValue().getCount() != 3 ) {
osg::notify(osg::WARN)<<"Data is wrong size for scale"<<std::endl;
return NULL;
}
domFloat3& s = scale->getValue();
xform->asPositionAttitudeTransform()->setScale(
osg::Vec3(s[0],s[1],s[2]));
return xform;
}
osg::Transform* daeReader::processLookat( domLookat *la )
{
osg::Transform* xform = new osg::MatrixTransform();
xform->setDataVariance(osg::Object::STATIC);
xform->setName( la->getSid() ? la->getSid() : "" );
if (la->getValue().getCount() != 9 ) {
osg::notify(osg::WARN)<<"Data is wrong size for lookat"<<std::endl;
return NULL;
}
osg::Matrix m;
osg::Vec3 eye;
osg::Vec3 center;
osg::Vec3 up;
eye.set( la->getValue()[0], la->getValue()[1], la->getValue()[2] );
center.set( la->getValue()[3], la->getValue()[4], la->getValue()[5] );
up.set( la->getValue()[6], la->getValue()[7], la->getValue()[8] );
m.makeLookAt( eye, center, up );
xform->asMatrixTransform()->setMatrix(m);
return xform;
}
osg::Transform* daeReader::processSkew( domSkew *skew )
{
osg::Transform* xform = new osg::MatrixTransform();
xform->setDataVariance(osg::Object::STATIC);
xform->setName( skew->getSid() ? skew->getSid() : "" );
if (skew->getValue().getCount() != 9 ) {
osg::notify(osg::WARN)<<"Data is wrong size for skew"<<std::endl;
return NULL;
}
domFloat7& s = skew->getValue();
float angle = s[0];
float shear = sin(osg::DegreesToRadians(angle));
osg::Vec3 around(s[1],s[2],s[3]);
osg::Vec3 along(s[4],s[5],s[6]);
osg::Vec3 const x(1,0,0);
osg::Vec3 const y(0,1,0);
osg::Vec3 const z(0,0,1);
osg::Matrix m;
if ( along == x ) {
if ( around == y ) {
m(2,0) = shear;
} else if ( around == z ) {
m(1,0) = -shear;
} else {
//osg::notify(osg::WARN)<<"Unsupported skew around "<<around<<std::endl;
}
} else if ( along == y ) {
if ( around == x ) {
m(2,1) = -shear;
} else if ( around == z ) {
m(0,1) = shear;
} else {
//osg::notify(osg::WARN)<<"Unsupported skew around "<<around<<std::endl;
// Process all coordinate system contributing elements in order!
size_t count = node->getContents().getCount();
for (size_t i = 0; i < count; i++ )
{
domRotate * rot = daeSafeCast< domRotate >( node->getContents()[i] );
if (rot)
{
domFloat4& r = rot->getValue();
if (r.getCount() != 4 )
{
osg::notify(osg::WARN)<<"Data is wrong size for rotate"<<std::endl;
continue;
}
} else if ( along == z ) {
if ( around == x ) {
m(1,2) = shear;
} else if ( around == y ) {
m(0,2) = -shear;
} else {
//osg::notify(osg::WARN)<<"Unsupported skew around "<<around<<std::endl;
// Build rotation matrix
osg::Matrix rotMat;
rotMat.makeRotate(osg::DegreesToRadians(r[3]), r[0], r[1], r[2]);
matrix = rotMat * matrix;
continue;
}
domTranslate * trans = daeSafeCast< domTranslate >( node->getContents()[i] );
if (trans != NULL)
{
domFloat3& t = trans->getValue();
if (t.getCount() != 3 )
{
osg::notify(osg::WARN)<<"Data is wrong size for translate"<<std::endl;
continue;
}
// Build translation matrix
osg::Matrix transMat;
transMat.makeTranslate(t[0], t[1], t[2]);
matrix = transMat * matrix;
continue;
}
domScale * scale = daeSafeCast< domScale >( node->getContents()[i] );
if (scale != NULL)
{
domFloat3& s = scale->getValue();
if (s.getCount() != 3 )
{
osg::notify(osg::WARN)<<"Data is wrong size for scale"<<std::endl;
continue;
}
// Build scale matrix
osg::Matrix scaleMat;
scaleMat.makeScale(s[0], s[1], s[2]);
matrix = scaleMat * matrix;
continue;
}
domMatrix * mat = daeSafeCast< domMatrix >( node->getContents()[i] );
if (mat != NULL)
{
if (mat->getValue().getCount() != 16 )
{
osg::notify(osg::WARN)<<"Data is wrong size for matrix"<<std::endl;
continue;
}
// Build matrix
osg::Matrix mMat( mat->getValue()[0], mat->getValue()[4], mat->getValue()[8], mat->getValue()[12],
mat->getValue()[1], mat->getValue()[5], mat->getValue()[9], mat->getValue()[13],
mat->getValue()[2], mat->getValue()[6], mat->getValue()[10], mat->getValue()[14],
mat->getValue()[3], mat->getValue()[7], mat->getValue()[11], mat->getValue()[15] );
matrix = mMat * matrix;
continue;
}
domLookat * la = daeSafeCast< domLookat >( node->getContents()[i] );
if (la != NULL)
{
if (la->getValue().getCount() != 9 )
{
osg::notify(osg::WARN)<<"Data is wrong size for lookat"<<std::endl;
continue;
}
// Build lookat matrix
osg::Matrix lookatMat;
osg::Vec3 eye(la->getValue()[0], la->getValue()[1], la->getValue()[2]);
osg::Vec3 center(la->getValue()[3], la->getValue()[4], la->getValue()[5] );
osg::Vec3 up( la->getValue()[6], la->getValue()[7], la->getValue()[8] );
lookatMat.makeLookAt( eye, center, up );
matrix = lookatMat * matrix;
continue;
}
domSkew * skew = daeSafeCast< domSkew >( node->getContents()[i] );
if (skew != NULL)
{
if (skew->getValue().getCount() != 7 )
{
osg::notify(osg::WARN)<<"Data is wrong size for skew"<<std::endl;
continue;
}
// Skew matrix building derived from GNURealistic ShaderMan GMANMatrix4 (LGPL) matrix class
// Build skew matrix
domFloat7& s = skew->getValue();
float shear = sin(osg::DegreesToRadians(s[0]));
// axis of rotation
osg::Vec3f around(s[1],s[2],s[3]);
// axis of translation
osg::Vec3f along(s[4],s[5],s[6]);
along.normalize();
osg::Vec3f a = around - (along * (around * along));
a.normalize();
float an1 = around * a;
float an2 = around * along;
float rx = an1 * cos(shear) - an2 * sin(shear);
float ry = an1 * sin(shear) + an2 * cos(shear);
if (rx <= 0.0)
{
osg::notify(osg::WARN)<<"skew angle too large"<<std::endl;
continue;
}
float alpha;
// A parallel to B??
if (an1==0)
{
alpha=0;
}
else
{
alpha=ry/rx-an2/an1;
}
osg::Matrix skewMat(a.x()*along.x()*alpha+1.0, a.x()*along.y()*alpha, a.x()*along.z()*alpha, 0,
a.y()*along.x()*alpha, a.y()*along.y()*alpha+1.0, a.y()*along.z()*alpha, 0,
a.z()*along.x()*alpha, a.z()*along.y()*alpha, a.z()*along.z()*alpha+1.0, 0,
0, 0, 0, 1);
matrix = skewMat * matrix;
continue;
}
} else {
//osg::notify(osg::WARN)<<"Unsupported skew along "<<along<<std::endl;
}
matNode->setMatrix(matrix);
if (angle > 0) {
//osg::notify(osg::NOTICE)<<"Skew: angle("<<angle<<") around("<<around<<") along("<<along<<")"<<std::endl;
osg::Vec3 scale = matrix.getScale();
if ((scale.x() != 1) || (scale.y() != 1) || (scale.z() != 1))
{
osg::StateSet* ss = matNode->getOrCreateStateSet();
ss->setMode(GL_RESCALE_NORMAL, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
}
xform->asMatrixTransform()->setMatrix(m);
return xform;
return matNode;
}
osg::Node* daeReader::processOsgDOFTransform(domTechnique* teq)
{
osgSim::DOFTransform* dof = new osgSim::DOFTransform;
domAny* any = daeSafeCast< domAny >(teq->getChild("MinHPR"));
if (any)
{
dof->setMinHPR(parseVec3String(any->getValue()));
}
else
{
osg::notify(osg::WARN) << "Expected element 'MinHPR' not found" << std::endl;
}
any = daeSafeCast< domAny >(teq->getChild("MaxHPR"));
if (any)
{
dof->setMaxHPR(parseVec3String(any->getValue()));
}
else
{
osg::notify(osg::WARN) << "Expected element 'MaxHPR' not found" << std::endl;
}
any = daeSafeCast< domAny >(teq->getChild("IncrementHPR"));
if (any)
{
dof->setIncrementHPR(parseVec3String(any->getValue()));
}
else
{
osg::notify(osg::WARN) << "Expected element 'IncrementHPR' not found" << std::endl;
}
any = daeSafeCast< domAny >(teq->getChild("CurrentHPR"));
if (any)
{
dof->setCurrentHPR(parseVec3String(any->getValue()));
}
else
{
osg::notify(osg::WARN) << "Expected element 'CurrentHPR' not found" << std::endl;
}
any = daeSafeCast< domAny >(teq->getChild("MinTranslate"));
if (any)
{
dof->setMinTranslate(parseVec3String(any->getValue()));
}
else
{
osg::notify(osg::WARN) << "Expected element 'MinTranslate' not found" << std::endl;
}
any = daeSafeCast< domAny >(teq->getChild("MaxTranslate"));
if (any)
{
dof->setMaxTranslate(parseVec3String(any->getValue()));
}
else
{
osg::notify(osg::WARN) << "Expected element 'MaxTranslate' not found" << std::endl;
}
any = daeSafeCast< domAny >(teq->getChild("IncrementTranslate"));
if (any)
{
dof->setIncrementTranslate(parseVec3String(any->getValue()));
}
else
{
osg::notify(osg::WARN) << "Expected element 'IncrementTranslate' not found" << std::endl;
}
any = daeSafeCast< domAny >(teq->getChild("CurrentTranslate"));
if (any)
{
dof->setCurrentTranslate(parseVec3String(any->getValue()));
}
else
{
osg::notify(osg::WARN) << "Expected element 'CurrentTranslate' not found" << std::endl;
}
any = daeSafeCast< domAny >(teq->getChild("MinScale"));
if (any)
{
dof->setMinScale(parseVec3String(any->getValue()));
}
else
{
osg::notify(osg::WARN) << "Expected element 'MinScale' not found" << std::endl;
}
any = daeSafeCast< domAny >(teq->getChild("MaxScale"));
if (any)
{
dof->setMaxScale(parseVec3String(any->getValue()));
}
else
{
osg::notify(osg::WARN) << "Expected element 'MaxScale' not found" << std::endl;
}
any = daeSafeCast< domAny >(teq->getChild("IncrementScale"));
if (any)
{
dof->setIncrementScale(parseVec3String(any->getValue()));
}
else
{
osg::notify(osg::WARN) << "Expected element 'IncrementScale' not found" << std::endl;
}
any = daeSafeCast< domAny >(teq->getChild("CurrentScale"));
if (any)
{
dof->setCurrentScale(parseVec3String(any->getValue()));
}
else
{
osg::notify(osg::WARN) << "Expected element 'CurrentScale' not found" << std::endl;
}
any = daeSafeCast< domAny >(teq->getChild("MultOrder"));
if (any)
{
dof->setHPRMultOrder((osgSim::DOFTransform::MultOrder)parseString<int>(any->getValue()));
}
else
{
osg::notify(osg::WARN) << "Expected element 'MultOrder' not found" << std::endl;
}
any = daeSafeCast< domAny >(teq->getChild("LimitationFlags"));
if (any)
{
dof->setLimitationFlags(parseString<unsigned long>(any->getValue()));
}
else
{
osg::notify(osg::WARN) << "Expected element 'LimitationFlags' not found" << std::endl;
}
any = daeSafeCast< domAny >(teq->getChild("AnimationOn"));
if (any)
{
dof->setAnimationOn(parseString<bool>(any->getValue()));
}
else
{
osg::notify(osg::WARN) << "Expected element 'AnimationOn' not found" << std::endl;
}
any = daeSafeCast< domAny >(teq->getChild("PutMatrix"));
if (any)
{
osg::Matrix mat = parseMatrixString(any->getValue());
dof->setPutMatrix(mat);
dof->setInversePutMatrix( osg::Matrixd::inverse( mat ) );
}
else
{
osg::notify(osg::WARN) << "Expected element 'PutMatrix' not found" << std::endl;
}
return dof;
}

View File

@@ -13,9 +13,11 @@
#include "daeReader.h"
#include <dae.h>
#include <dae/domAny.h>
#include <dom/domCOLLADA.h>
#include <dom/domInstanceWithExtra.h>
#include <dom/domConstants.h>
#include <osg/MatrixTransform>
using namespace osgdae;
@@ -86,19 +88,24 @@ bool daeReader::convert( const std::string &fileURI )
m_AssetUp_axis = document->getAsset()->getUp_axis()->getValue();
}
if (dae->getDatabase()) {
if (dae->getDatabase())
{
count = dae->getDatabase()->getElementCount(NULL, COLLADA_TYPE_INSTANCE_RIGID_BODY, NULL);
// build a std::map for lookup if Group or PositionAttitudeTransform should be created,
// i.e, make it easy to check if a instance_rigid_body targets a visual node
for (int i=0; i<count; i++) {
for (int i=0; i<count; i++)
{
result = dae->getDatabase()->getElement(&colladaElement, i, NULL, COLLADA_TYPE_INSTANCE_RIGID_BODY);
if (result == DAE_OK) {
if (result == DAE_OK)
{
irb = daeSafeCast<domInstance_rigid_body>(colladaElement);
if (irb) {
domNode *node = daeSafeCast<domNode>(irb->getTarget().getElement());
if (node && node->getId()) {
if (irb)
{
domNode *node = daeSafeCast<domNode>(irb->getTarget().getElement());
if (node && node->getId())
{
_targetMap[ std::string(node->getId()) ] = true;
}
}
@@ -121,7 +128,7 @@ bool daeReader::convert( const std::string &fileURI )
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)
{
@@ -154,231 +161,246 @@ osg::Node* daeReader::processVisualScene( domVisual_scene *scene )
}
}
return retVal;
}
osg::Node* daeReader::processExtras(domNode *node)
{
// See if one of the extras contains OpenSceneGraph specific information
unsigned int numExtras = node->getExtra_array().getCount();
for (unsigned int currExtra=0; currExtra < numExtras; currExtra++)
{
domExtra* extra = node->getExtra_array()[currExtra];
domTechnique* teq = NULL;
daeString extraType = extra->getType();
if (extraType)
{
if (strcmp(extraType, "Switch") == 0)
{
teq = getOpenSceneGraphProfile(extra);
if (teq)
{
return processOsgSwitch(teq);
}
}
else if (strcmp(extraType, "MultiSwitch") == 0)
{
teq = getOpenSceneGraphProfile(extra);
if (teq)
{
return processOsgMultiSwitch(teq);
}
}
else if (strcmp(extraType, "LOD") == 0)
{
teq = getOpenSceneGraphProfile(extra);
if (teq)
{
return processOsgLOD(teq);
}
}
else if (strcmp(extraType, "DOFTransform") == 0)
{
teq = getOpenSceneGraphProfile(extra);
if (teq)
{
return processOsgDOFTransform(teq);
}
}
else if (strcmp(extraType, "Sequence") == 0)
{
teq = getOpenSceneGraphProfile(extra);
if (teq)
{
return processOsgSequence(teq);
}
}
}
}
return new osg::Group;
}
void daeReader::processNodeExtra(osg::Node* osgNode, domNode *node)
{
// See if one of the extras contains OpenSceneGraph specific information
unsigned int numExtras = node->getExtra_array().getCount();
for (unsigned int currExtra=0; currExtra < numExtras; currExtra++)
{
domExtra* extra = node->getExtra_array()[currExtra];
daeString extraType = extra->getType();
if (extraType && (strcmp(extraType, "Node") == 0))
{
domTechnique* teq = getOpenSceneGraphProfile(extra);
if (teq)
{
domAny* any = daeSafeCast< domAny >(teq->getChild("Descriptions"));
if (any)
{
osg::Node::DescriptionList descriptions;
unsigned int numChildren = any->getChildren().getCount();
for (unsigned int currChild = 0; currChild < numChildren; currChild++)
{
domAny* child = daeSafeCast<domAny>(any->getChildren()[currChild]);
if (child)
{
if (strcmp(child->getElementName(), "Description" ) == 0 )
{
std::string value = child->getValue();
descriptions.push_back(value);
}
else
{
osg::notify(osg::WARN) << "Child of element 'Descriptions' is not of type 'Description'" << std::endl;
}
}
else
{
osg::notify(osg::WARN) << "Element 'Descriptions' does not contain expected elements." << std::endl;
}
}
osgNode->setDescriptions(descriptions);
}
else
{
osg::notify(osg::WARN) << "Expected element 'Descriptions' not found" << std::endl;
}
}
}
}
}
domTechnique* daeReader::getOpenSceneGraphProfile(domExtra* extra)
{
unsigned int numTeqs = extra->getTechnique_array().getCount();
for ( unsigned int currTeq = 0; currTeq < numTeqs; ++currTeq )
{
// Only interested in OpenSceneGraph technique
if (strcmp( extra->getTechnique_array()[currTeq]->getProfile(), "OpenSceneGraph" ) == 0 )
{
return extra->getTechnique_array()[currTeq];
}
}
return NULL;
}
// <node>
// attributes:
// id, name, sid, type, layer
// child elements:
// 0..1 <asset>
// 0..* <lookat>, <matrix>, <rotate>, <scale>, <skew>, <translate>
// 0..* <instance_camera>
// 0..* <instance_controller>
// 0..* <instance_geometry>
// 0..* <instance_light>
// 0..* <instance_node>
// 0..* <node>
// 0..* <extra>
osg::Node* daeReader::processNode( domNode *node )
{
osg::Node *retVal;
osg::PositionAttitudeTransform *pat;
int patcount = node->getRotate_array().getCount() +
node->getScale_array().getCount() +
node->getTranslate_array().getCount();
// First we need to determine what kind of OSG node we need
// If there exist any of the <lookat>, <matrix>, <rotate>, <scale>, <skew>, <translate> elements
// or if a COLLADA_TYPE_INSTANCE_RIGID_BODY targets this node we need a MatrixTransform
int coordcount = node->getRotate_array().getCount() +
node->getScale_array().getCount() +
node->getTranslate_array().getCount() +
node->getLookat_array().getCount() +
node->getMatrix_array().getCount() +
node->getSkew_array().getCount();
// See if it is targeted
bool targeted = false;
if (node->getId()) {
if (node->getId())
{
targeted = _targetMap[std::string(node->getId())];
}
if (patcount > 0 || targeted )
osg::Node *resultNode;
if (coordcount > 0 || targeted )
{
pat = new osg::PositionAttitudeTransform();
retVal = pat;
}
else
resultNode = processOsgMatrixTransform(node);
}
else
{
retVal = new osg::Group();
// No transform data, determine node type based on it's available extra data
resultNode = processExtras(node);
}
osg::Node *current = retVal;
// See if there is generic node info attached as extra
processNodeExtra(resultNode, node);
retVal->setName( node->getId() ? node->getId() : "" );
resultNode->setName( node->getId() ? node->getId() : "" );
osg::Group* groupNode = resultNode->asGroup();
// Handle rotate, translate and scale first..
// will make the hierarchy less deep
// <rotate>
osg::Quat osgRot;
for (unsigned int i=0; i<node->getRotate_array().getCount(); i++)
if (groupNode)
{
daeSmartRef<domRotate> rot = node->getRotate_array().get(i);
if (rot->getValue().getCount() != 4 ) {
osg::notify(osg::WARN)<<"Data is wrong size for rotate"<<std::endl;
continue;
}
domFloat4& r = rot->getValue();
osg::Vec3 axis;
axis.set(r[0],r[1],r[2]);
osgRot = osg::Quat(osg::DegreesToRadians(r[3]),axis) * osgRot;
pat->setAttitude(osgRot);
}
// <scale>
osg::Vec3 osgScale = osg::Vec3(1.0, 1.0, 1.0);
for (unsigned int i=0; i<node->getScale_array().getCount(); i++)
{
daeSmartRef<domScale> scale = node->getScale_array().get(i);
if (scale->getValue().getCount() != 3 ) {
osg::notify(osg::WARN)<<"Data is wrong size for scale"<<std::endl;
continue;
}
domFloat3& s = scale->getValue();
osgScale[0] *= s[0];
osgScale[1] *= s[1];
osgScale[2] *= s[2];
pat->setScale(osgScale);
}
// <translate>
osg::Vec3 osgTrans = osg::Vec3(0.0, 0.0, 0.0);
for (unsigned int i=0; i<node->getTranslate_array().getCount(); i++)
{
daeSmartRef<domTranslate> trans = node->getTranslate_array().get(i);
if (trans->getValue().getCount() != 3 ) {
osg::notify(osg::WARN)<<"Data is wrong size for translate"<<std::endl;
continue;
}
domFloat3& t = trans->getValue();
osgTrans += osg::Vec3(t[0],t[1],t[2]);
pat->setPosition(osgTrans);
}
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
domTranslate * t = daeSafeCast< domTranslate >( node->getContents()[i] );
if ( t != NULL )
// 0..* <instance_camera>
domInstance_camera_Array cameraInstanceArray = node->getInstance_camera_array();
for ( size_t i = 0; i < cameraInstanceArray.getCount(); i++ )
{
continue;
}
domRotate * r = daeSafeCast< domRotate >( node->getContents()[i] );
if ( r != NULL ) {
continue;
}
domScale * s = daeSafeCast< domScale >( node->getContents()[i] );
if ( s != NULL ) {
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() );
daeElement *el = getElementFromURI( cameraInstanceArray[i]->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;
if (c)
groupNode->addChild( processCamera( c ));
else
osg::notify( osg::WARN ) << "Failed to locate camera " << cameraInstanceArray[i]->getUrl().getURI() << std::endl;
}
domInstance_light *il = daeSafeCast< domInstance_light >( node->getContents()[i] );
if ( il != NULL )
// 0..* <instance_controller>
domInstance_controller_Array controllerInstanceArray = node->getInstance_controller_array();
for ( size_t i = 0; i < controllerInstanceArray.getCount(); i++ )
{
daeElement *el = getElementFromURI( il->getUrl() );
groupNode->addChild( processInstanceController( controllerInstanceArray[i] ));
}
// 0..* <instance_geometry>
domInstance_geometry_Array geometryInstanceArray = node->getInstance_geometry_array();
for ( size_t i = 0; i < geometryInstanceArray.getCount(); i++ )
{
groupNode->addChild( processInstanceGeometry( geometryInstanceArray[i] ));
}
// 0..* <instance_light>
domInstance_light_Array lightInstanceArray = node->getInstance_light_array();
for ( size_t i = 0; i < lightInstanceArray.getCount(); i++ )
{
daeElement *el = getElementFromURI( lightInstanceArray[i]->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;
if (l)
groupNode->addChild( processLight( l ));
else
osg::notify( osg::WARN ) << "Failed to locate light " << lightInstanceArray[i]->getUrl().getURI() << std::endl;
}
domInstance_node *instn = daeSafeCast< domInstance_node >( node->getContents()[i] );
if ( instn != NULL )
// 0..* <instance_node>
domInstance_node_Array nodeInstanceArray = node->getInstance_node_array();
for ( size_t i = 0; i < nodeInstanceArray.getCount(); i++ )
{
daeElement *el = getElementFromURI( instn->getUrl() );
daeElement *el = getElementFromURI( nodeInstanceArray[i]->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;
if (n)
// Recursive call
groupNode->addChild( processNode( n ));
else
osg::notify( osg::WARN ) << "Failed to locate node " << nodeInstanceArray[i]->getUrl().getURI() << std::endl;
}
domNode *n = daeSafeCast< domNode >( node->getContents()[i] );
if ( n != NULL )
// 0..* <node>
domNode_Array nodeArray = node->getNode_array();
for ( size_t i = 0; i < nodeArray.getCount(); i++ )
{
trans = processNode( n );
if ( trans != NULL )
{
current->asGroup()->addChild( trans );
}
continue;
// Recursive call
groupNode->addChild( processNode( nodeArray[i] ));
}
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;
return resultNode;
}

View File

@@ -93,6 +93,38 @@ bool findInputSourceBySemantic( TInputArray& inputs, const char* semantic, daeEl
return false;
}
/// Convert string to value using it's stream operator
template <typename T>
T parseString(const std::string& valueAsString) {
std::stringstream str;
str << valueAsString;
T result;
str >> result;
return result;
}
inline osg::Vec3 parseVec3String(const std::string& valueAsString)
{
std::stringstream str;
str << valueAsString;
osg::Vec3 result;
str >> result.x() >> result.y() >> result.z();
return result;
}
inline osg::Matrix parseMatrixString(const std::string& valueAsString)
{
std::stringstream str;
str << valueAsString;
osg::Matrix result;
str >> result(0,0) >> result(1,0) >> result(2,0) >> result(3,0)
>> result(0,1) >> result(1,1) >> result(2,1) >> result(3,1)
>> result(0,2) >> result(1,2) >> result(2,2) >> result(3,2)
>> result(0,3) >> result(1,3) >> result(2,3) >> result(3,3);
return result;
}
/**
@class daeReader
@brief Read a OSG scene from a DAE file
@@ -113,33 +145,38 @@ public:
protected:
//scene processing
osg::Node* processVisualScene( domVisual_scene *scene );
osg::Node* processNode( domNode *node );
osg::Node* processVisualScene( domVisual_scene *scene );
osg::Node* processNode( domNode *node );
osg::Node* processOsgMatrixTransform( domNode *node );
//osg::Node* processInstance( domInstanceWithExtra *iwe );
//transform processing
osg::Transform* processMatrix( domMatrix *mat );
osg::Transform* processTranslate( domTranslate *trans );
osg::Transform* processRotate( domRotate *rot );
osg::Transform* processScale( domScale *scale );
osg::Transform* processLookat( domLookat *la );
osg::Transform* processSkew( domSkew *skew );
// Processing of OSG specific info stored in node extras
osg::Node* processExtras(domNode *node);
void processNodeExtra(osg::Node* osgNode, domNode *node);
domTechnique* getOpenSceneGraphProfile(domExtra* extra);
void processAsset( domAsset *node );
osg::Node* processOsgSwitch(domTechnique* teq);
osg::Node* processOsgMultiSwitch(domTechnique* teq);
osg::Node* processOsgLOD(domTechnique* teq);
osg::Node* processOsgDOFTransform(domTechnique* teq);
osg::Node* processOsgSequence(domTechnique* teq);
//geometry processing
osg::Node* processInstance_geometry( domInstance_geometry *ig );
osg::Node* processGeometry( domGeometry *geo );
osg::Node* processInstance_controller( domInstance_controller *ictrl );
osg::Geode* processInstanceGeometry( domInstance_geometry *ig );
osg::Geode* processGeometry( domGeometry *geo );
osg::Geode* processInstanceController( domInstance_controller *ictrl );
typedef std::map< daeElement*, domSourceReader > SourceMap;
typedef std::map< int, osg::IntArray*, std::less<int> > IndexMap;
template< typename T >
osg::Node* processSinglePPrimitive( T *group, SourceMap &sources, GLenum mode );
void processSinglePPrimitive(osg::Geode* geode, T *group, SourceMap &sources, GLenum mode );
template< typename T >
osg::Node* processMultiPPrimitive( T *group, SourceMap &sources, GLenum mode );
void processMultiPPrimitive(osg::Geode* geode, T *group, SourceMap &sources, GLenum mode );
osg::Node* processPolylist( domPolylist *group, SourceMap &sources );
void processPolylist(osg::Geode* geode, domPolylist *group, SourceMap &sources );
void resolveArrays( domInputLocalOffset_Array &inputs, osg::Geometry *&geom,
SourceMap &sources, IndexMap &index_map );
@@ -147,12 +184,16 @@ protected:
void processP( domP *p, osg::Geometry *&geom, IndexMap &index_map, osg::DrawArrayLengths* dal/*GLenum mode*/ );
//material/effect processing
void processBindMaterial( domBind_material *bm, osg::Node *geo );
osg::StateSet *processMaterial( domMaterial *mat );
osg::StateSet *processEffect( domEffect *effect );
osg::StateSet *processProfileCOMMON( domProfile_COMMON *pc );
void processBindMaterial( domBind_material *bm, domGeometry *geom, osg::Geode *geode );
void processMaterial(osg::StateSet *ss, domMaterial *mat );
void processEffect(osg::StateSet *ss, domEffect *effect );
void processProfileCOMMON(osg::StateSet *ss, domProfile_COMMON *pc );
bool processColorOrTextureType( domCommon_color_or_texture_type *cot,
osg::Material::ColorMode channel, osg::Material *mat, domCommon_float_or_param_type *fop = NULL, osg::StateAttribute **sa = NULL );
osg::Material::ColorMode channel,
osg::Material *mat,
domCommon_float_or_param_type *fop = NULL,
osg::StateAttribute **sa = NULL,
bool normalizeShininess=false);
osg::StateAttribute *processTransparencySettings( domCommon_transparent_type *ctt, domCommon_float_or_param_type *pTransparency, osg::StateSet *ss );
bool GetFloat4Param(xsNCName Reference, domFloat4 &f4);
bool GetFloatParam(xsNCName Reference, domFloat &f);
@@ -174,8 +215,17 @@ protected:
domInstance_effect *currentInstance_effect;
domEffect *currentEffect;
std::map< domGeometry*, osg::Node* > geometryMap;
std::map< domMaterial*, osg::StateSet* > materialMap;
typedef std::map< domGeometry*, osg::Geode*> domGeometryGeodeMap;
typedef std::map< domMaterial*, osg::StateSet*> domMaterialStateSetMap;
typedef std::map< std::string, osg::StateSet*> MaterialStateSetMap;
/// Maps geometry to a Geode
domGeometryGeodeMap geometryMap;
// Maps material target to stateset
domMaterialStateSetMap materialMap;
// Maps material symbol to stateset
MaterialStateSetMap materialMap2;
enum AuthoringTool
{
UNKNOWN,

View File

@@ -24,28 +24,33 @@
using namespace osgdae;
//GEODE
void daeWriter::apply( osg::Geode &node )
{
#ifdef _DEBUG
debugPrint( node );
#endif
pushStateSet(node.getStateSet());
if (NULL != node.getStateSet())
m_CurrentRenderingHint = node.getStateSet()->getRenderingHint();
// TODO
// Write a Geode as a single instance_geometry if all drawables use the same vertex streams
// Reuse an existing Geode if only statesets differ
unsigned int count = node.getNumDrawables();
for ( unsigned int i = 0; i < count; i++ )
{
osg::Geometry *g = node.getDrawable( i )->asGeometry();
if ( g != NULL )
{
// Transparency at drawable level
if (NULL != g->getStateSet())
m_CurrentRenderingHint = g->getStateSet()->getRenderingHint();
pushStateSet(g->getStateSet());
std::map< osg::Geometry*, domGeometry *>::iterator iter = geometryMap.find( g );
if ( iter != geometryMap.end() )
{
domInstance_geometry *ig = daeSafeCast< domInstance_geometry >( currentNode->createAndPlace( "instance_geometry" ) );
domInstance_geometry *ig = daeSafeCast< domInstance_geometry >( currentNode->add( "instance_geometry" ) );
std::string url = "#" + std::string( iter->second->getId() );
ig->setUrl( url.c_str() );
@@ -56,13 +61,13 @@ void daeWriter::apply( osg::Geode &node )
{
if ( lib_geoms == NULL )
{
lib_geoms = daeSafeCast< domLibrary_geometries >( dom->createAndPlace( COLLADA_ELEMENT_LIBRARY_GEOMETRIES ) );
lib_geoms = daeSafeCast< domLibrary_geometries >( dom->add( COLLADA_ELEMENT_LIBRARY_GEOMETRIES ) );
}
std::string name = node.getName();
if ( name.empty() ) name = "geometry";
name = uniquify( name );
domGeometryRef geo = daeSafeCast< domGeometry >( lib_geoms->createAndPlace( COLLADA_ELEMENT_GEOMETRY ) );
domGeometryRef geo = daeSafeCast< domGeometry >( lib_geoms->add( COLLADA_ELEMENT_GEOMETRY ) );
geo->setId( name.c_str() );
if ( !processGeometry( g, geo, name ) )
@@ -71,7 +76,7 @@ void daeWriter::apply( osg::Geode &node )
continue;
}
domInstance_geometry *ig = daeSafeCast< domInstance_geometry >( currentNode->createAndPlace( "instance_geometry" ) );
domInstance_geometry *ig = daeSafeCast< domInstance_geometry >( currentNode->add( "instance_geometry" ) );
std::string url = "#" + name;
ig->setUrl( url.c_str() );
@@ -87,8 +92,6 @@ void daeWriter::apply( osg::Geode &node )
}
}
lastVisited = GEODE;
popStateSet(node.getStateSet());
}
@@ -130,7 +133,7 @@ void daeWriter::appendGeometryIndices(osg::Geometry *geom,
bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const std::string &name )
{
domMesh *mesh = daeSafeCast< domMesh >( geo->createAndPlace( COLLADA_ELEMENT_MESH ) );
domMesh *mesh = daeSafeCast< domMesh >( geo->add( COLLADA_ELEMENT_MESH ) );
domSource *pos = NULL;
domSource *norm = NULL;
domSource *color = NULL;
@@ -206,12 +209,12 @@ bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const st
}
//create a vertices element
domVertices *vertices = daeSafeCast< domVertices >( mesh->createAndPlace( COLLADA_ELEMENT_VERTICES ) );
domVertices *vertices = daeSafeCast< domVertices >( mesh->add( COLLADA_ELEMENT_VERTICES ) );
std::string vName = name + "-vertices";
vertices->setId( vName.c_str() );
//make a POSITION input in it
domInputLocal *il = daeSafeCast< domInputLocal >( vertices->createAndPlace( "input" ) );
domInputLocal *il = daeSafeCast< domInputLocal >( vertices->add( "input" ) );
il->setSemantic( "POSITION" );
std::string url = "#" + std::string( pos->getId() );
il->setSource( url.c_str() );
@@ -265,7 +268,7 @@ 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->createAndPlace( "input" ) );
il = daeSafeCast< domInputLocal >( vertices->add( "input" ) );
il->setSemantic( "NORMAL" );
url = "#" + std::string(md->norm->getId());
il->setSource( url.c_str() );
@@ -316,7 +319,7 @@ 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->createAndPlace( "input" ) );
il = daeSafeCast< domInputLocal >( vertices->add( "input" ) );
il->setSemantic( "COLOR" );
url = "#" + std::string(md->color->getId());
il->setSource( url.c_str() );
@@ -403,7 +406,7 @@ bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const st
if ( lines == NULL )
{
lines = createPrimGroup<domLines>( COLLADA_ELEMENT_LINES, mesh, norm, color, texcoord );
lines->createAndPlace( COLLADA_ELEMENT_P );
lines->add( COLLADA_ELEMENT_P );
std::string mat = name + "_material";
lines->setMaterial( mat.c_str() );
}
@@ -416,7 +419,7 @@ bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const st
if ( tris == NULL )
{
tris = createPrimGroup<domTriangles>( COLLADA_ELEMENT_TRIANGLES, mesh, norm, color, texcoord );
tris->createAndPlace( COLLADA_ELEMENT_P );
tris->add( COLLADA_ELEMENT_P );
std::string mat = name + "_material";
tris->setMaterial( mat.c_str() );
}
@@ -431,7 +434,7 @@ bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const st
if (usePolygons)
{
polys = createPrimGroup<domPolygons>( COLLADA_ELEMENT_POLYGONS, mesh, norm, color, texcoord );
polys->createAndPlace( COLLADA_ELEMENT_P );
polys->add( COLLADA_ELEMENT_P );
std::string mat = name + "_material";
polys->setMaterial( mat.c_str() );
}
@@ -439,8 +442,8 @@ bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const st
{
polylist = createPrimGroup<domPolylist>( COLLADA_ELEMENT_POLYLIST, mesh, norm, color, texcoord );
polylist->createAndPlace( COLLADA_ELEMENT_VCOUNT );
polylist->createAndPlace( COLLADA_ELEMENT_P );
polylist->add( COLLADA_ELEMENT_VCOUNT );
polylist->add( COLLADA_ELEMENT_P );
std::string mat = name + "_material";
polylist->setMaterial( mat.c_str() );
}
@@ -492,7 +495,7 @@ bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const st
if (usePolygons)
{
polys = createPrimGroup<domPolygons>( COLLADA_ELEMENT_POLYGONS, mesh, norm, color, texcoord );
polys->createAndPlace( COLLADA_ELEMENT_P );
polys->add( COLLADA_ELEMENT_P );
std::string mat = name + "_material";
polys->setMaterial( mat.c_str() );
}
@@ -500,8 +503,8 @@ bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const st
{
polylist = createPrimGroup<domPolylist>( COLLADA_ELEMENT_POLYLIST, mesh, norm, color, texcoord );
polylist->createAndPlace( COLLADA_ELEMENT_VCOUNT );
polylist->createAndPlace( COLLADA_ELEMENT_P );
polylist->add( COLLADA_ELEMENT_VCOUNT );
polylist->add( COLLADA_ELEMENT_P );
std::string mat = name + "_material";
polylist->setMaterial( mat.c_str() );
}
@@ -549,19 +552,19 @@ bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const st
}
case GL_LINE_STRIP:
{
p.push_back(daeSafeCast<domP>( linestrips->createAndPlace( COLLADA_ELEMENT_P ) ));
p.push_back(daeSafeCast<domP>( linestrips->add( COLLADA_ELEMENT_P ) ));
linestrips->setCount( linestrips->getCount() + 1 );
break;
}
case GL_TRIANGLE_STRIP:
{
p.push_back(daeSafeCast<domP>( tristrips->createAndPlace( COLLADA_ELEMENT_P ) ));
p.push_back(daeSafeCast<domP>( tristrips->add( COLLADA_ELEMENT_P ) ));
tristrips->setCount( tristrips->getCount() + 1 );
break;
}
case GL_TRIANGLE_FAN:
{
p.push_back(daeSafeCast<domP>( trifans->createAndPlace( COLLADA_ELEMENT_P ) ));
p.push_back(daeSafeCast<domP>( trifans->add( COLLADA_ELEMENT_P ) ));
trifans->setCount( trifans->getCount() + 1 );
break;
}
@@ -650,19 +653,19 @@ bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const st
}
case GL_LINE_STRIP:
{
p.push_back(daeSafeCast<domP>( linestrips->createAndPlace( COLLADA_ELEMENT_P ) ));
p.push_back(daeSafeCast<domP>( linestrips->add( COLLADA_ELEMENT_P ) ));
linestrips->setCount( linestrips->getCount() + 1 );
break;
}
case GL_TRIANGLE_STRIP:
{
p.push_back(daeSafeCast<domP>( tristrips->createAndPlace( COLLADA_ELEMENT_P ) ));
p.push_back(daeSafeCast<domP>( tristrips->add( COLLADA_ELEMENT_P ) ));
tristrips->setCount( tristrips->getCount() + 1 );
break;
}
case GL_TRIANGLE_FAN:
{
p.push_back(daeSafeCast<domP>( trifans->createAndPlace( COLLADA_ELEMENT_P ) ));
p.push_back(daeSafeCast<domP>( trifans->add( COLLADA_ELEMENT_P ) ));
trifans->setCount( trifans->getCount() + 1 );
break;
}
@@ -744,19 +747,19 @@ bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const st
}
case GL_LINE_STRIP:
{
p.push_back(daeSafeCast<domP>( linestrips->createAndPlace( COLLADA_ELEMENT_P ) ));
p.push_back(daeSafeCast<domP>( linestrips->add( COLLADA_ELEMENT_P ) ));
linestrips->setCount( linestrips->getCount() + 1 );
break;
}
case GL_TRIANGLE_STRIP:
{
p.push_back(daeSafeCast<domP>( tristrips->createAndPlace( COLLADA_ELEMENT_P ) ));
p.push_back(daeSafeCast<domP>( tristrips->add( COLLADA_ELEMENT_P ) ));
tristrips->setCount( tristrips->getCount() + 1 );
break;
}
case GL_TRIANGLE_FAN:
{
p.push_back(daeSafeCast<domP>( trifans->createAndPlace( COLLADA_ELEMENT_P ) ));
p.push_back(daeSafeCast<domP>( trifans->add( COLLADA_ELEMENT_P ) ));
trifans->setCount( trifans->getCount() + 1 );
break;
}
@@ -843,19 +846,19 @@ bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const st
}
case GL_LINE_STRIP:
{
p.push_back(daeSafeCast<domP>( linestrips->createAndPlace( COLLADA_ELEMENT_P ) ));
p.push_back(daeSafeCast<domP>( linestrips->add( COLLADA_ELEMENT_P ) ));
linestrips->setCount( linestrips->getCount() + 1 );
break;
}
case GL_TRIANGLE_STRIP:
{
p.push_back(daeSafeCast<domP>( tristrips->createAndPlace( COLLADA_ELEMENT_P ) ));
p.push_back(daeSafeCast<domP>( tristrips->add( COLLADA_ELEMENT_P ) ));
tristrips->setCount( tristrips->getCount() + 1 );
break;
}
case GL_TRIANGLE_FAN:
{
p.push_back(daeSafeCast<domP>( trifans->createAndPlace( COLLADA_ELEMENT_P ) ));
p.push_back(daeSafeCast<domP>( trifans->add( COLLADA_ELEMENT_P ) ));
trifans->setCount( trifans->getCount() + 1 );
break;
}
@@ -944,19 +947,19 @@ bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const st
}
case GL_LINE_STRIP:
{
p.push_back(daeSafeCast<domP>( linestrips->createAndPlace( COLLADA_ELEMENT_P ) ));
p.push_back(daeSafeCast<domP>( linestrips->add( COLLADA_ELEMENT_P ) ));
linestrips->setCount( linestrips->getCount() + 1 );
break;
}
case GL_TRIANGLE_STRIP:
{
p.push_back(daeSafeCast<domP>( tristrips->createAndPlace( COLLADA_ELEMENT_P ) ));
p.push_back(daeSafeCast<domP>( tristrips->add( COLLADA_ELEMENT_P ) ));
tristrips->setCount( tristrips->getCount() + 1 );
break;
}
case GL_TRIANGLE_FAN:
{
p.push_back(daeSafeCast<domP>( trifans->createAndPlace( COLLADA_ELEMENT_P ) ));
p.push_back(daeSafeCast<domP>( trifans->add( COLLADA_ELEMENT_P ) ));
trifans->setCount( trifans->getCount() + 1 );
break;
}
@@ -1038,39 +1041,39 @@ bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const st
domSource *daeWriter::createSource( daeElement *parent, const std::string &baseName, int size, bool color, bool uv )
{
domSource *src = daeSafeCast< domSource >( parent->createAndPlace( COLLADA_ELEMENT_SOURCE ) );
domSource *src = daeSafeCast< domSource >( parent->add( COLLADA_ELEMENT_SOURCE ) );
if ( src == NULL )
{
return NULL;
}
src->setId( baseName.c_str() );
domFloat_array *fa = daeSafeCast< domFloat_array >( src->createAndPlace( COLLADA_ELEMENT_FLOAT_ARRAY ) );
domFloat_array *fa = daeSafeCast< domFloat_array >( src->add( COLLADA_ELEMENT_FLOAT_ARRAY ) );
std::string fName = baseName + "-array";
fa->setId( fName.c_str() );
domSource::domTechnique_common *teq = daeSafeCast< domSource::domTechnique_common >( src->createAndPlace( "technique_common" ) );
domAccessor *acc = daeSafeCast< domAccessor >( teq->createAndPlace( COLLADA_ELEMENT_ACCESSOR ) );
domSource::domTechnique_common *teq = daeSafeCast< domSource::domTechnique_common >( src->add( "technique_common" ) );
domAccessor *acc = daeSafeCast< domAccessor >( teq->add( COLLADA_ELEMENT_ACCESSOR ) );
std::string url = "#" + fName;
acc->setSource( url.c_str() );
domParam *param;
if ( color )
{
acc->setStride( size );
param = daeSafeCast< domParam >( acc->createAndPlace( COLLADA_ELEMENT_PARAM ) );
param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) );
param->setName( "R" );
param->setType( "float" );
param = daeSafeCast< domParam >( acc->createAndPlace( COLLADA_ELEMENT_PARAM ) );
param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) );
param->setName( "G" );
param->setType( "float" );
param = daeSafeCast< domParam >( acc->createAndPlace( COLLADA_ELEMENT_PARAM ) );
param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) );
param->setName( "B" );
param->setType( "float" );
if ( size == 4 ) {
param = daeSafeCast< domParam >( acc->createAndPlace( COLLADA_ELEMENT_PARAM ) );
param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) );
param->setName( "A" );
param->setType( "float" );
}
@@ -1079,17 +1082,17 @@ domSource *daeWriter::createSource( daeElement *parent, const std::string &baseN
else if ( uv )
{
acc->setStride( size );
param = daeSafeCast< domParam >( acc->createAndPlace( COLLADA_ELEMENT_PARAM ) );
param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) );
param->setName( "S" );
param->setType( "float" );
param = daeSafeCast< domParam >( acc->createAndPlace( COLLADA_ELEMENT_PARAM ) );
param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) );
param->setName( "T" );
param->setType( "float" );
if ( size >=3 )
{
param = daeSafeCast< domParam >( acc->createAndPlace( COLLADA_ELEMENT_PARAM ) );
param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) );
param->setName( "P" );
param->setType( "float" );
}
@@ -1097,23 +1100,23 @@ domSource *daeWriter::createSource( daeElement *parent, const std::string &baseN
else
{
acc->setStride( size );
param = daeSafeCast< domParam >( acc->createAndPlace( COLLADA_ELEMENT_PARAM ) );
param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) );
param->setName( "X" );
param->setType( "float" );
param = daeSafeCast< domParam >( acc->createAndPlace( COLLADA_ELEMENT_PARAM ) );
param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) );
param->setName( "Y" );
param->setType( "float" );
if ( size >=3 )
{
param = daeSafeCast< domParam >( acc->createAndPlace( COLLADA_ELEMENT_PARAM ) );
param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) );
param->setName( "Z" );
param->setType( "float" );
if ( size == 4 )
{
param = daeSafeCast< domParam >( acc->createAndPlace( COLLADA_ELEMENT_PARAM ) );
param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) );
param->setName( "W" );
param->setType( "float" );
}
@@ -1127,15 +1130,15 @@ template < typename Ty >
Ty *daeWriter::createPrimGroup( daeString type, domMesh *mesh, domSource *norm, domSource *color, const std::vector< domSource* > &texcoord )
{
unsigned int offset = 0;
Ty *retVal = daeSafeCast< Ty >( mesh->createAndPlace( type ) );
domInputLocalOffset *ilo = daeSafeCast< domInputLocalOffset >( retVal->createAndPlace( "input" ) );
Ty *retVal = daeSafeCast< Ty >( mesh->add( type ) );
domInputLocalOffset *ilo = daeSafeCast< domInputLocalOffset >( retVal->add( "input" ) );
ilo->setOffset( offset++ );
ilo->setSemantic( "VERTEX" );
std::string url = "#" + std::string(mesh->getVertices()->getId());
ilo->setSource( url.c_str() );
if ( norm != NULL )
{
ilo = daeSafeCast< domInputLocalOffset >( retVal->createAndPlace( "input" ) );
ilo = daeSafeCast< domInputLocalOffset >( retVal->add( "input" ) );
ilo->setOffset( offset++ );
ilo->setSemantic( "NORMAL" );
url = "#" + std::string( norm->getId() );
@@ -1143,7 +1146,7 @@ Ty *daeWriter::createPrimGroup( daeString type, domMesh *mesh, domSource *norm,
}
if ( color != NULL )
{
ilo = daeSafeCast< domInputLocalOffset >( retVal->createAndPlace( "input" ) );
ilo = daeSafeCast< domInputLocalOffset >( retVal->add( "input" ) );
ilo->setOffset( offset++ );
ilo->setSemantic( "COLOR" );
url = "#" + std::string( color->getId() );
@@ -1151,7 +1154,7 @@ Ty *daeWriter::createPrimGroup( daeString type, domMesh *mesh, domSource *norm,
}
for ( unsigned int i = 0; i < texcoord.size(); i++ )
{
ilo = daeSafeCast< domInputLocalOffset >( retVal->createAndPlace( "input" ) );
ilo = daeSafeCast< domInputLocalOffset >( retVal->add( "input" ) );
ilo->setOffset( offset++ );
ilo->setSemantic( "TEXCOORD" );
ilo->setSet( i );

View File

@@ -33,9 +33,9 @@ using namespace osgdae;
void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, const std::string &geoName )
{
osg::ref_ptr<osg::StateSet> ssClean = CleanStateSet(ss); // Need to hold a ref to this or the materialMap.find() will delete it
domBind_material *bm = daeSafeCast< domBind_material >( ig->createAndPlace( COLLADA_ELEMENT_BIND_MATERIAL ) );
domBind_material::domTechnique_common *tc = daeSafeCast< domBind_material::domTechnique_common >( bm->createAndPlace( "technique_common" ) );
domInstance_material *im = daeSafeCast< domInstance_material >( tc->createAndPlace( COLLADA_ELEMENT_INSTANCE_MATERIAL ) );
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" ) );
domInstance_material *im = daeSafeCast< domInstance_material >( tc->add( COLLADA_ELEMENT_INSTANCE_MATERIAL ) );
std::string symbol = geoName + "_material";
im->setSymbol( symbol.c_str() );
@@ -49,10 +49,10 @@ void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, co
if ( lib_mats == NULL )
{
lib_mats = daeSafeCast< domLibrary_materials >( dom->createAndPlace( COLLADA_ELEMENT_LIBRARY_MATERIALS ) );
lib_mats = daeSafeCast< domLibrary_materials >( dom->add( COLLADA_ELEMENT_LIBRARY_MATERIALS ) );
}
domMaterial *mat = daeSafeCast< domMaterial >( lib_mats->createAndPlace( COLLADA_ELEMENT_MATERIAL ) );
domMaterial *mat = daeSafeCast< domMaterial >( lib_mats->add( COLLADA_ELEMENT_MATERIAL ) );
std::string name = ssClean->getName();
if ( name.empty() )
{
@@ -65,13 +65,13 @@ void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, co
std::string url = "#" + name;
im->setTarget( url.c_str() );
domInstance_effect *ie = daeSafeCast<domInstance_effect>( mat->createAndPlace( "instance_effect" ) );
domInstance_effect *ie = daeSafeCast<domInstance_effect>( mat->add( "instance_effect" ) );
if ( lib_effects == NULL )
{
lib_effects = daeSafeCast< domLibrary_effects >( dom->createAndPlace( COLLADA_ELEMENT_LIBRARY_EFFECTS ) );
lib_effects = daeSafeCast< domLibrary_effects >( dom->add( COLLADA_ELEMENT_LIBRARY_EFFECTS ) );
}
domEffect *effect = daeSafeCast< domEffect >( lib_effects->createAndPlace( COLLADA_ELEMENT_EFFECT ) );
domEffect *effect = daeSafeCast< domEffect >( lib_effects->add( COLLADA_ELEMENT_EFFECT ) );
std::string efName = name + "_effect";
effect->setId( efName.c_str() );
@@ -79,10 +79,10 @@ void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, co
url = "#" + efName;
ie->setUrl( url.c_str() );
domProfile_COMMON *pc = daeSafeCast< domProfile_COMMON >( effect->createAndPlace( COLLADA_ELEMENT_PROFILE_COMMON ) );
domProfile_COMMON::domTechnique *pc_teq = daeSafeCast< domProfile_COMMON::domTechnique >( pc->createAndPlace( "technique" ) );
domProfile_COMMON *pc = daeSafeCast< domProfile_COMMON >( effect->add( COLLADA_ELEMENT_PROFILE_COMMON ) );
domProfile_COMMON::domTechnique *pc_teq = daeSafeCast< domProfile_COMMON::domTechnique >( pc->add( "technique" ) );
pc_teq->setSid( "t0" );
domProfile_COMMON::domTechnique::domPhong *phong = daeSafeCast< domProfile_COMMON::domTechnique::domPhong >( pc_teq->createAndPlace( "phong" ) );
domProfile_COMMON::domTechnique::domPhong *phong = daeSafeCast< domProfile_COMMON::domTechnique::domPhong >( pc_teq->add( "phong" ) );
osg::Texture *tex = static_cast<osg::Texture*>(ssClean->getTextureAttribute( 0, osg::StateAttribute::TEXTURE ));
if ( ssClean->getTextureAttribute( 1, osg::StateAttribute::TEXTURE ) != NULL )
@@ -92,12 +92,12 @@ void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, co
if ( tex != NULL && tex->getImage( 0 ) != NULL )
{
//TODO: Export all of the texture Attributes like wrap mode and all that jazz
domImage *img = daeSafeCast< domImage >( pc->createAndPlace( COLLADA_ELEMENT_IMAGE ) );
domImage *img = daeSafeCast< domImage >( pc->add( COLLADA_ELEMENT_IMAGE ) );
std::string iName = efName + "-image";
img->setId( iName.c_str() );
osg::Image *osgimg = tex->getImage( 0 );
domImage::domInit_from *imgif = daeSafeCast< domImage::domInit_from >( img->createAndPlace( "init_from" ) );
domImage::domInit_from *imgif = daeSafeCast< domImage::domInit_from >( img->add( "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->createAndPlace( "newparam" ) );
domCommon_newparam_type *np = daeSafeCast< domCommon_newparam_type >( pc->add( "newparam" ) );
std::string surfName = efName + "-surface";
np->setSid( surfName.c_str() );
domFx_surface_common *surface = daeSafeCast< domFx_surface_common >( np->createAndPlace( "surface" ) );
domFx_surface_init_from_common *sif = daeSafeCast< domFx_surface_init_from_common >( surface->createAndPlace("init_from") );
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") );
sif->setValue( iName.c_str() );
surface->setType( FX_SURFACE_TYPE_ENUM_2D );
np = daeSafeCast< domCommon_newparam_type >( pc->createAndPlace( "newparam" ) );
np = daeSafeCast< domCommon_newparam_type >( pc->add( "newparam" ) );
std::string sampName = efName + "-sampler";
np->setSid( sampName.c_str() );
domFx_sampler2D_common *sampler = daeSafeCast< domFx_sampler2D_common >( np->createAndPlace( "sampler2D" ) );
domFx_sampler2D_common_complexType::domSource *source = daeSafeCast< domFx_sampler2D_common_complexType::domSource >( sampler->createAndPlace( "source" ) );
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" ) );
source->setValue( surfName.c_str() );
//set sampler state
domFx_sampler2D_common_complexType::domWrap_s *wrap_s = daeSafeCast< domFx_sampler2D_common_complexType::domWrap_s >( sampler->createAndPlace( "wrap_s" ) );
domFx_sampler2D_common_complexType::domWrap_s *wrap_s = daeSafeCast< domFx_sampler2D_common_complexType::domWrap_s >( sampler->add( "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->createAndPlace( "wrap_t" ) );
domFx_sampler2D_common_complexType::domWrap_t *wrap_t = daeSafeCast< domFx_sampler2D_common_complexType::domWrap_t >( sampler->add( "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->createAndPlace( "border_color" ) );
domFx_sampler2D_common_complexType::domBorder_color *dbcol = daeSafeCast< domFx_sampler2D_common_complexType::domBorder_color >( sampler->add( "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->createAndPlace( "minfilter" ) );
domFx_sampler2D_common_complexType::domMinfilter *minfilter = daeSafeCast< domFx_sampler2D_common_complexType::domMinfilter >( sampler->add( "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->createAndPlace( "magfilter" ) );
domFx_sampler2D_common_complexType::domMagfilter *magfilter = daeSafeCast< domFx_sampler2D_common_complexType::domMagfilter >( sampler->add( "magfilter" ) );
mode = tex->getFilter( osg::Texture::MAG_FILTER );
switch( mode )
{
@@ -221,49 +221,21 @@ void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, co
}
domCommon_color_or_texture_type *cot = daeSafeCast< domCommon_color_or_texture_type >( phong->createAndPlace( "diffuse" ) );
domCommon_color_or_texture_type_complexType::domTexture *dtex = daeSafeCast< domCommon_color_or_texture_type_complexType::domTexture >( cot->createAndPlace( "texture" ) );
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" ) );
dtex->setTexture( sampName.c_str() );
dtex->setTexcoord( "texcoord0" );
#else
domCommon_color_or_texture_type *cot = daeSafeCast< domCommon_color_or_texture_type >( phong->createAndPlace( "diffuse" ) );
domCommon_color_or_texture_type_complexType::domTexture *dtex = daeSafeCast< domCommon_color_or_texture_type_complexType::domTexture >( cot->createAndPlace( "texture" ) );
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" ) );
dtex->setTexture( iName.c_str() );
dtex->setTexcoord( "texcoord0" );
#endif
domInstance_material::domBind_vertex_input *bvi = daeSafeCast< domInstance_material::domBind_vertex_input >( im->createAndPlace( "bind_vertex_input" ) );
domInstance_material::domBind_vertex_input *bvi = daeSafeCast< domInstance_material::domBind_vertex_input >( im->add( "bind_vertex_input" ) );
bvi->setSemantic( "texcoord0" );
bvi->setInput_semantic( "TEXCOORD" );
bvi->setInput_set( 0 );
/* I dont think this belongs here RFJ
//take care of blending if any
osg::BlendFunc *bf = static_cast< osg::BlendFunc * >( ssClean->getAttribute( osg::StateAttribute::BLENDFUNC ) );
osg::BlendColor *bc = static_cast< osg::BlendColor * >( ssClean->getAttribute( osg::StateAttribute::BLENDCOLOR ) );
if ( bc != NULL )
{
domCommon_transparent_type *ctt = daeSafeCast< domCommon_transparent_type >( phong->createAndPlace( "transparent" ) );
ctt->setOpaque( FX_OPAQUE_ENUM_RGB_ZERO );
domCommon_color_or_texture_type_complexType::domColor *tcol = daeSafeCast< domCommon_color_or_texture_type_complexType::domColor >( ctt->createAndPlace( "color" ) );
tcol->getValue().append( bc->getConstantColor().r() );
tcol->getValue().append( bc->getConstantColor().r() );
tcol->getValue().append( bc->getConstantColor().r() );
tcol->getValue().append( bc->getConstantColor().r() );
}
else if ( bf != NULL )
{
domCommon_transparent_type *ctt = daeSafeCast< domCommon_transparent_type >( phong->createAndPlace( "transparent" ) );
ctt->setOpaque( FX_OPAQUE_ENUM_A_ONE );
dtex = daeSafeCast< domCommon_color_or_texture_type_complexType::domTexture >( ctt->createAndPlace( "texture" ) );
#ifndef EARTH_TEX
dtex->setTexture( sampName.c_str() );
#else
dtex->setTexture( iName.c_str() );
#endif
dtex->setTexcoord( "texcoord0" );
}
*/
}
osg::Material *osgmat = static_cast<osg::Material*>(ssClean->getAttribute( osg::StateAttribute::MATERIAL ));
if ( osgmat != NULL )
@@ -274,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->createAndPlace( "emission" ) );
domCommon_color_or_texture_type_complexType::domColor *col = daeSafeCast< domCommon_color_or_texture_type_complexType::domColor >( cot->createAndPlace( "color" ) );
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" ) );
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->createAndPlace( "ambient" ) );
col = daeSafeCast< domCommon_color_or_texture_type_complexType::domColor >( cot->createAndPlace( "color" ) );
cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add( "ambient" ) );
col = daeSafeCast< domCommon_color_or_texture_type_complexType::domColor >( cot->add( "color" ) );
col->getValue().append( aCol.r() );
col->getValue().append( aCol.g() );
col->getValue().append( aCol.b() );
@@ -292,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->createAndPlace( "diffuse" ) );
col = daeSafeCast< domCommon_color_or_texture_type_complexType::domColor >( cot->createAndPlace( "color" ) );
cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add( "diffuse" ) );
col = daeSafeCast< domCommon_color_or_texture_type_complexType::domColor >( cot->add( "color" ) );
col->getValue().append( dCol.r() );
col->getValue().append( dCol.g() );
col->getValue().append( dCol.b() );
@@ -303,27 +275,38 @@ void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, co
{
cot = phong->getDiffuse();
domCommon_color_or_texture_type_complexType::domTexture *dtex = cot->getTexture();
domExtra *extra = daeSafeCast< domExtra >( dtex->createAndPlace( COLLADA_ELEMENT_EXTRA ) );
extra->setType( "color" );
domTechnique *teq = daeSafeCast< domTechnique >( extra->createAndPlace( COLLADA_ELEMENT_TECHNIQUE ) );
teq->setProfile( "SCEI" );
domAny *any = (domAny*)(daeElement*)teq->createAndPlace( "color" );
if (writeExtras)
{
// Adds the following to a texture element
std::ostringstream colVal;
colVal << dCol.r() << " " << dCol.g() << " " << dCol.b() << " " << dCol.a();
any->setValue( colVal.str().c_str() );
//<extra type="color">
// <technique profile="SCEI">
// <color>1.0 1.0 1.0 1.0</color>
// </technique>
//</extra>
domCommon_color_or_texture_type_complexType::domTexture *dtex = cot->getTexture();
domExtra *extra = daeSafeCast< domExtra >( dtex->add( COLLADA_ELEMENT_EXTRA ) );
extra->setType( "color" );
domTechnique *teq = daeSafeCast< domTechnique >( extra->add( COLLADA_ELEMENT_TECHNIQUE ) );
teq->setProfile( "SCEI" );
domAny *any = (domAny*)(daeElement*)teq->add( "color" );
std::ostringstream colVal;
colVal << dCol.r() << " " << dCol.g() << " " << dCol.b() << " " << dCol.a();
any->setValue( colVal.str().c_str() );
}
}
cot = daeSafeCast< domCommon_color_or_texture_type >( phong->createAndPlace( "specular" ) );
col = daeSafeCast< domCommon_color_or_texture_type_complexType::domColor >( cot->createAndPlace( "color" ) );
cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add( "specular" ) );
col = daeSafeCast< domCommon_color_or_texture_type_complexType::domColor >( cot->add( "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->createAndPlace( "shininess" ) );
domCommon_float_or_param_type_complexType::domFloat *f = daeSafeCast< domCommon_float_or_param_type_complexType::domFloat >( fop->createAndPlace( "float" ) );
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" ) );
f->setValue( shininess );
}
@@ -333,65 +316,100 @@ void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, co
{
osg::BlendFunc *pBlendFunc = static_cast< osg::BlendFunc * >( ssClean->getAttribute( osg::StateAttribute::BLENDFUNC ) );
osg::BlendColor *pBlendColor = static_cast< osg::BlendColor * >( ssClean->getAttribute( osg::StateAttribute::BLENDCOLOR ) );
if ((NULL != pBlendFunc) && (NULL != pBlendColor))
if (pBlendFunc != NULL)
{
if ((GL_CONSTANT_ALPHA == pBlendFunc->getSource()) && (GL_ONE_MINUS_CONSTANT_ALPHA == pBlendFunc->getDestination()))
if (pBlendColor != NULL)
{
// A_ONE opaque mode
domCommon_transparent_type *pTransparent = daeSafeCast<domCommon_transparent_type>(phong->createAndPlace("transparent"));
pTransparent->setOpaque(FX_OPAQUE_ENUM_A_ONE);
domCommon_color_or_texture_type_complexType::domColor *pColor = daeSafeCast<domCommon_color_or_texture_type_complexType::domColor>(pTransparent->createAndPlace("color"));
domCommon_float_or_param_type *pFop = daeSafeCast<domCommon_float_or_param_type>(phong->createAndPlace( "transparency"));
domCommon_float_or_param_type_complexType::domFloat *pTransparency = daeSafeCast<domCommon_float_or_param_type_complexType::domFloat>(pFop->createAndPlace("float"));
if (m_GoogleMode)
if ((GL_CONSTANT_ALPHA == pBlendFunc->getSource()) && (GL_ONE_MINUS_CONSTANT_ALPHA == pBlendFunc->getDestination()))
{
pColor->getValue().append(1.0);
pColor->getValue().append(1.0);
pColor->getValue().append(1.0);
pColor->getValue().append(1.0);
pTransparency->setValue(1.0 - pBlendColor->getConstantColor().a());
// A_ONE opaque mode
domCommon_transparent_type *pTransparent = daeSafeCast<domCommon_transparent_type>(phong->add("transparent"));
pTransparent->setOpaque(FX_OPAQUE_ENUM_A_ONE);
domCommon_color_or_texture_type_complexType::domColor *pColor = daeSafeCast<domCommon_color_or_texture_type_complexType::domColor>(pTransparent->add("color"));
domCommon_float_or_param_type *pFop = daeSafeCast<domCommon_float_or_param_type>(phong->add( "transparency"));
domCommon_float_or_param_type_complexType::domFloat *pTransparency = daeSafeCast<domCommon_float_or_param_type_complexType::domFloat>(pFop->add("float"));
if (m_GoogleMode)
{
pColor->getValue().append(1.0);
pColor->getValue().append(1.0);
pColor->getValue().append(1.0);
pColor->getValue().append(1.0);
pTransparency->setValue(1.0 - pBlendColor->getConstantColor().a());
}
else
{
pColor->getValue().append(pBlendColor->getConstantColor().r());
pColor->getValue().append(pBlendColor->getConstantColor().g());
pColor->getValue().append(pBlendColor->getConstantColor().b());
pColor->getValue().append(pBlendColor->getConstantColor().a());
pTransparency->setValue(1.0);
}
}
else
else if ((GL_ONE_MINUS_CONSTANT_COLOR == pBlendFunc->getSource()) && (GL_CONSTANT_COLOR == pBlendFunc->getDestination()))
{
// RGB_ZERO opaque mode
domCommon_transparent_type *pTransparent = daeSafeCast<domCommon_transparent_type>(phong->add("transparent"));
pTransparent->setOpaque(FX_OPAQUE_ENUM_RGB_ZERO);
domCommon_color_or_texture_type_complexType::domColor *pColor = daeSafeCast<domCommon_color_or_texture_type_complexType::domColor>(pTransparent->add("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<domCommon_float_or_param_type>(phong->add( "transparency"));
domCommon_float_or_param_type_complexType::domFloat *pTransparency = daeSafeCast<domCommon_float_or_param_type_complexType::domFloat>(pFop->add("float"));
pTransparency->setValue(1.0);
}
else
osg::notify( osg::WARN ) << "Unsupported BlendFunction parameters in transparency processing." << std::endl;
}
else if ((GL_ONE_MINUS_CONSTANT_COLOR == pBlendFunc->getSource()) && (GL_CONSTANT_COLOR == pBlendFunc->getDestination()))
else if (tex != NULL && tex->getImage( 0 ) != NULL)
{
// RGB_ZERO opaque mode
domCommon_transparent_type *pTransparent = daeSafeCast<domCommon_transparent_type>(phong->createAndPlace("transparent"));
pTransparent->setOpaque(FX_OPAQUE_ENUM_RGB_ZERO);
domCommon_color_or_texture_type_complexType::domColor *pColor = daeSafeCast<domCommon_color_or_texture_type_complexType::domColor>(pTransparent->createAndPlace("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<domCommon_float_or_param_type>(phong->createAndPlace( "transparency"));
domCommon_float_or_param_type_complexType::domFloat *pTransparency = daeSafeCast<domCommon_float_or_param_type_complexType::domFloat>(pFop->createAndPlace("float"));
pTransparency->setValue(1.0);
domCommon_transparent_type *ctt = daeSafeCast< domCommon_transparent_type >( phong->add( "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" ) );
#ifndef EARTH_TEX
std::string sampName = efName + "-sampler";
dtex->setTexture( sampName.c_str() );
#else
std::string iName = efName + "-image";
dtex->setTexture( iName.c_str() );
#endif
dtex->setTexcoord( "texcoord0" );
}
else
osg::notify( osg::WARN ) << "Unsupported BlendFunction parameters in transparency processing." << std::endl;
{
osg::notify( osg::WARN ) << "Transparency processing - No texture or BlendColor." << std::endl;
}
}
else
osg::notify( osg::WARN ) << "Transparency processing - BlendFunction or BlendColor not found." << std::endl;
{
osg::notify( osg::WARN ) << "Transparency processing - BlendFunction not found." << std::endl;
}
}
// Process GOOGLE one sided stuff here
if (osg::StateAttribute::INHERIT != ssClean->getMode(GL_CULL_FACE))
if (writeExtras)
{
domExtra *pExtra = daeSafeCast<domExtra>(pc->createAndPlace(COLLADA_ELEMENT_EXTRA));
domTechnique *pTechnique = daeSafeCast<domTechnique>(pExtra->createAndPlace( COLLADA_ELEMENT_TECHNIQUE ) );
pTechnique->setProfile("GOOGLEEARTH");
domAny *pAny = (domAny*)(daeElement*)pTechnique->createAndPlace("double_sided");
if (GL_FALSE == ssClean->getMode(GL_CULL_FACE))
pAny->setValue("1");
else
pAny->setValue("0");
// Adds the following to a Profile_COMMON element
//<extra>
// <technique profile="GOOGLEEARTH">
// <double_sided>0</double_sided>
// </technique>
//</extra>
// Process GOOGLE one sided stuff here
if (osg::StateAttribute::INHERIT != ssClean->getMode(GL_CULL_FACE))
{
domExtra *pExtra = daeSafeCast<domExtra>(pc->add(COLLADA_ELEMENT_EXTRA));
domTechnique *pTechnique = daeSafeCast<domTechnique>(pExtra->add( COLLADA_ELEMENT_TECHNIQUE ) );
pTechnique->setProfile("GOOGLEEARTH");
domAny *pAny = (domAny*)(daeElement*)pTechnique->add("double_sided");
if (GL_FALSE == ssClean->getMode(GL_CULL_FACE))
pAny->setValue("1");
else
pAny->setValue("0");
}
}
materialMap.insert( std::make_pair( ssClean, mat ) );
@@ -409,7 +427,7 @@ osg::StateSet* daeWriter::CleanStateSet(osg::StateSet* pStateSet) const
if (NULL != pStateSet->getAttribute(osg::StateAttribute::MATERIAL))
pCleanedStateSet->setAttribute(pStateSet->getAttribute(osg::StateAttribute::MATERIAL));
// pCleanedStateSet->setRenderingHint(pStateSet->getRenderingHint()); does not work at the moment due to stateSet::merge
if (osg::StateAttribute::INHERIT != pStateSet->getMode(GL_CULL_FACE))
if (osg::StateAttribute::ON != pStateSet->getMode(GL_CULL_FACE))
pCleanedStateSet->setMode(GL_CULL_FACE, pStateSet->getMode(GL_CULL_FACE));
return pCleanedStateSet;
}

View File

@@ -19,19 +19,54 @@
#include <dom/domConstants.h>
#include <dom/domLibrary_cameras.h>
#include <dom/domLibrary_lights.h>
#include <dae/domAny.h>
//#include <dom/domVisual_scene.h>
//#include <dom/domLibrary_visual_scenes.h>
#include <osgSim/MultiSwitch>
#include <osg/Sequence>
#include <osg/Billboard>
using namespace osgdae;
// Write non-standard node data as extra of type "Node" with "OpenSceneGraph" technique
void daeWriter::writeNodeExtra(osg::Node &node)
{
unsigned int numDesc = node.getDescriptions().size();
// Only create extra if descriptions are filled in
if (writeExtras && (numDesc > 0))
{
// Adds the following to a node
//<extra type="Node">
// <technique profile="OpenSceneGraph">
// <Descriptions>
// <Description>Some info</Description>
// </Descriptions>
// </technique>
//</extra>
domExtra *extra = daeSafeCast<domExtra>(currentNode->add( COLLADA_ELEMENT_EXTRA ));
extra->setType("Node");
domTechnique *teq = daeSafeCast<domTechnique>(extra->add( COLLADA_ELEMENT_TECHNIQUE ) );
teq->setProfile( "OpenSceneGraph" );
domAny *descriptions = (domAny*)teq->add( "Descriptions" );
for (unsigned int currDesc = 0; currDesc < numDesc; currDesc++)
{
std::string value = node.getDescription(currDesc);
if (!value.empty())
{
domAny *description = (domAny*)descriptions->add( "Description" );
description->setValue(value.c_str());
}
}
}
}
//GROUP
void daeWriter::apply( osg::Group &node )
{
#ifdef _DEBUG
debugPrint( node );
#endif
while ( lastDepth >= _nodePath.size() )
{
@@ -39,23 +74,73 @@ void daeWriter::apply( osg::Group &node )
currentNode = daeSafeCast< domNode >( currentNode->getParentElement() );
lastDepth--;
}
currentNode = daeSafeCast< domNode >(currentNode->createAndPlace( COLLADA_ELEMENT_NODE ) );
currentNode = daeSafeCast< domNode >(currentNode->add( COLLADA_ELEMENT_NODE ) );
// If a multiswitch node, store it's data as extra "MultiSwitch" data in the "OpenSceneGraph" technique
osgSim::MultiSwitch* multiswitch = dynamic_cast<osgSim::MultiSwitch*>(&node);
if (writeExtras && multiswitch)
{
// Adds the following to a node
//<extra type="MultiSwitch">
// <technique profile="OpenSceneGraph">
// <ActiveSwitchSet>0</ActiveSwitchSet>
// <ValueLists>
// <ValueList>1 0</ValueList>
// <ValueList>0 1</ValueList>
// </ValueLists>
// </technique>
//</extra>
domExtra *extra = daeSafeCast<domExtra>(currentNode->add( COLLADA_ELEMENT_EXTRA ));
extra->setType("MultiSwitch");
domTechnique *teq = daeSafeCast<domTechnique>(extra->add( COLLADA_ELEMENT_TECHNIQUE ) );
teq->setProfile( "OpenSceneGraph" );
domAny *activeSwitchSet = (domAny*)teq->add("ActiveSwitchSet" );
activeSwitchSet->setValue(toString<unsigned int>(multiswitch->getActiveSwitchSet()).c_str());
domAny *valueLists = (domAny*)teq->add( "ValueLists" );
unsigned int pos = 0;
const osgSim::MultiSwitch::SwitchSetList& switchset = multiswitch->getSwitchSetList();
for(osgSim::MultiSwitch::SwitchSetList::const_iterator sitr=switchset.begin();
sitr!=switchset.end();
++sitr,++pos)
{
domAny *valueList = (domAny*)valueLists->add( "ValueList" );
std::stringstream fw;
const osgSim::MultiSwitch::ValueList& values = *sitr;
for(osgSim::MultiSwitch::ValueList::const_iterator itr=values.begin();
itr!=values.end();
++itr)
{
if (itr != values.begin())
{
fw << " ";
}
fw << *itr;
}
valueList->setValue(fw.str().c_str());
}
currentNode->setId(getNodeName(node,"multiswitch").c_str());
}
else
{
currentNode->setId(getNodeName(node,"group").c_str());
}
writeNodeExtra(node);
lastDepth = _nodePath.size();
lastVisited = GROUP;
traverse( node );
}
//SWITCH
void daeWriter::apply( osg::Switch &node )
{
#ifdef _DEBUG
debugPrint( node );
#endif
while ( lastDepth >= _nodePath.size() )
{
@@ -63,29 +148,52 @@ void daeWriter::apply( osg::Switch &node )
currentNode = daeSafeCast< domNode >( currentNode->getParentElement() );
lastDepth--;
}
currentNode = daeSafeCast< domNode >(currentNode->createAndPlace( COLLADA_ELEMENT_NODE ) );
currentNode = daeSafeCast< domNode >(currentNode->add( COLLADA_ELEMENT_NODE ) );
currentNode->setId(getNodeName(node,"switch").c_str());
if (writeExtras)
{
// Adds the following to a node
//<extra type="Switch">
// <technique profile="OpenSceneGraph">
// <ValueList>1 0</ValueList>
// </technique>
//</extra>
domExtra *extra = daeSafeCast<domExtra>(currentNode->add( COLLADA_ELEMENT_EXTRA ));
extra->setType("Switch");
domTechnique *teq = daeSafeCast<domTechnique>(extra->add( COLLADA_ELEMENT_TECHNIQUE ) );
teq->setProfile( "OpenSceneGraph" );
domAny *valueList = (domAny*)teq->add( "ValueList" );
std::stringstream fw;
const osg::Switch::ValueList& values = node.getValueList();
for(osg::Switch::ValueList::const_iterator itr=values.begin();
itr!=values.end();
++itr)
{
if (itr != values.begin())
{
fw << " ";
}
fw << *itr;
}
valueList->setValue(fw.str().c_str());
}
writeNodeExtra(node);
lastDepth = _nodePath.size();
lastVisited = SWITCH;
unsigned int cnt = node.getNumChildren();
for ( unsigned int i = 0; i < cnt; i++ )
{
if ( node.getValue( i ) )
{
node.getChild( i )->accept( *this );
}
}
// Process all children
traverse( node );
}
//LOD
void daeWriter::apply( osg::LOD &node )
void daeWriter::apply( osg::Sequence &node )
{
#ifdef _DEBUG
debugPrint( node );
#endif
while ( lastDepth >= _nodePath.size() )
{
@@ -93,40 +201,158 @@ void daeWriter::apply( osg::LOD &node )
currentNode = daeSafeCast< domNode >( currentNode->getParentElement() );
lastDepth--;
}
currentNode = daeSafeCast< domNode >(currentNode->createAndPlace( COLLADA_ELEMENT_NODE ) );
currentNode = daeSafeCast< domNode >(currentNode->add( COLLADA_ELEMENT_NODE ) );
currentNode->setId(getNodeName(node,"sequence").c_str());
// If a sequence node, store it's data as extra "Sequence" data in the "OpenSceneGraph" technique
if (writeExtras)
{
// Adds the following to a node
//<extra type="Sequence">
// <technique profile="OpenSceneGraph">
// <FrameTime>0 0</FrameTime>
// <LastFrameTime>0</LastFrameTime>
// <LoopMode>0</LoopMode>
// <IntervalBegin>0</IntervalBegin>
// <IntervalEnd>-1</IntervalEnd>
// <DurationSpeed>1</DurationSpeed>
// <DurationNReps>-1</DurationNReps>
// <SequenceMode>0</SequenceMode>
// </technique>
//</extra>
domExtra *extra = daeSafeCast<domExtra>(currentNode->add( COLLADA_ELEMENT_EXTRA ));
extra->setType("Sequence");
domTechnique *teq = daeSafeCast<domTechnique>(extra->add( COLLADA_ELEMENT_TECHNIQUE ) );
teq->setProfile( "OpenSceneGraph" );
domAny *frameTime = (domAny*)teq->add("FrameTime");
std::stringstream fw;
for (unsigned int i = 0; i < node.getNumChildren(); i++)
{
if (i > 0)
{
fw << " ";
}
fw << node.getTime(i);
}
frameTime->setValue(fw.str().c_str());
domAny *lastFrameTime = (domAny*)teq->add("LastFrameTime");
lastFrameTime->setValue(toString<double>(node.getLastFrameTime()).c_str());
// loop mode & interval
osg::Sequence::LoopMode mode;
int begin, end;
node.getInterval(mode, begin, end);
domAny *loopMode = (domAny*)teq->add("LoopMode");
loopMode->setValue(toString<osg::Sequence::LoopMode>(mode).c_str());
domAny *intervalBegin = (domAny*)teq->add("IntervalBegin");
intervalBegin->setValue(toString<int>(begin).c_str());
domAny *intervalEnd = (domAny*)teq->add("IntervalEnd");
intervalEnd->setValue(toString<int>(end).c_str());
// duration
float speed;
int nreps;
node.getDuration(speed, nreps);
domAny *durationSpeed = (domAny*)teq->add("DurationSpeed");
durationSpeed->setValue(toString<float>(speed).c_str());
domAny *durationNReps = (domAny*)teq->add("DurationNReps");
durationNReps->setValue(toString<int>(nreps).c_str());
// sequence mode
domAny *sequenceMode = (domAny*)teq->add("SequenceMode");
sequenceMode->setValue(toString<osg::Sequence::SequenceMode>(node.getMode()).c_str());
}
writeNodeExtra(node);
lastDepth = _nodePath.size();
traverse( node );
}
void daeWriter::apply( osg::LOD &node )
{
debugPrint( node );
while ( lastDepth >= _nodePath.size() )
{
//We are not a child of previous node
currentNode = daeSafeCast< domNode >( currentNode->getParentElement() );
lastDepth--;
}
currentNode = daeSafeCast< domNode >(currentNode->add( COLLADA_ELEMENT_NODE ) );
lastDepth = _nodePath.size();
currentNode->setId(getNodeName(node,"LOD").c_str());
lastVisited = LOD;
//TODO : get the most or less detailed node, not only the first one
/*for ( unsigned int i = 0; i < node.getNumChildren(); i++ )
if (writeExtras)
{
if ( node.getChild( i ) != NULL )
// Store LOD data as extra "LOD" data in the "OpenSceneGraph" technique
// Adds the following to a node
//<extra type="LOD">
// <technique profile="OpenSceneGraph">
// <Center>1 2 3</Center> (optional )
// <Radius>-1</Radius> (required if Center is available)
// <RangeMode>0</RangeMode>
// <RangeList>
// <MinMax>0 300</MinMax>
// <MinMax>300 600</MinMax>
// </RangeList>
// </technique>
//</extra>
domExtra *extra = daeSafeCast<domExtra>(currentNode->add( COLLADA_ELEMENT_EXTRA ));
extra->setType("LOD");
domTechnique *teq = daeSafeCast<domTechnique>(extra->add( COLLADA_ELEMENT_TECHNIQUE ) );
teq->setProfile( "OpenSceneGraph" );
if (node.getCenterMode()==osg::LOD::USER_DEFINED_CENTER)
{
node.getChild( i )->accept( *this );
break;
domAny *center = (domAny*)teq->add("Center");
center->setValue(toString(node.getCenter()).c_str());
domAny *radius = (domAny*)teq->add("Radius");
radius->setValue(toString<osg::LOD::value_type>(node.getRadius()).c_str());
}
}*/
//unsigned int cnt = node.getNumChildren();
node.getChild( 0 )->accept( *this );
domAny *rangeMode = (domAny*)teq->add("RangeMode");
rangeMode->setValue(toString<osg::LOD::RangeMode>(node.getRangeMode()).c_str());
domAny *valueLists = (domAny*)teq->add("RangeList");
unsigned int pos = 0;
const osg::LOD::RangeList& rangelist = node.getRangeList();
for(osg::LOD::RangeList::const_iterator sitr=rangelist.begin();
sitr!=rangelist.end();
++sitr,++pos)
{
domAny *valueList = (domAny*)valueLists->add("MinMax");
std::stringstream fw;
fw << sitr->first << " " << sitr->second;
valueList->setValue(fw.str().c_str());
}
}
writeNodeExtra(node);
// Process all children
traverse( node );
}
void daeWriter::apply( osg::ProxyNode &node )
{
osg::notify( osg::WARN ) << "ProxyNode. Missing " << node.getNumChildren() << " children\n";
osg::notify( osg::WARN ) << "ProxyNode. Missing " << node.getNumChildren() << " children" << std::endl;
}
//LIGHT
void daeWriter::apply( osg::LightSource &node )
{
#ifdef _DEBUG
debugPrint( node );
#endif
domInstance_light *il = daeSafeCast< domInstance_light >( currentNode->createAndPlace( "instance_light" ) );
domInstance_light *il = daeSafeCast< domInstance_light >( currentNode->add( "instance_light" ) );
std::string name = node.getName();
if ( name.empty() )
{
@@ -137,24 +363,19 @@ void daeWriter::apply( osg::LightSource &node )
if ( lib_lights == NULL )
{
lib_lights = daeSafeCast< domLibrary_lights >( dom->createAndPlace( COLLADA_ELEMENT_LIBRARY_LIGHTS ) );
lib_lights = daeSafeCast< domLibrary_lights >( dom->add( COLLADA_ELEMENT_LIBRARY_LIGHTS ) );
}
domLight *light = daeSafeCast< domLight >( lib_lights->createAndPlace( COLLADA_ELEMENT_LIGHT ) );
domLight *light = daeSafeCast< domLight >( lib_lights->add( COLLADA_ELEMENT_LIGHT ) );
light->setId( name.c_str() );
lastVisited = LIGHT;
traverse( node );
}
//CAMERA
void daeWriter::apply( osg::Camera &node )
{
#ifdef _DEBUG
debugPrint( node );
#endif
domInstance_camera *ic = daeSafeCast< domInstance_camera >( currentNode->createAndPlace( "instance_camera" ) );
domInstance_camera *ic = daeSafeCast< domInstance_camera >( currentNode->add( "instance_camera" ) );
std::string name = node.getName();
if ( name.empty() )
{
@@ -165,12 +386,10 @@ void daeWriter::apply( osg::Camera &node )
if ( lib_cameras == NULL )
{
lib_cameras = daeSafeCast< domLibrary_cameras >( dom->createAndPlace( COLLADA_ELEMENT_LIBRARY_CAMERAS ) );
lib_cameras = daeSafeCast< domLibrary_cameras >( dom->add( COLLADA_ELEMENT_LIBRARY_CAMERAS ) );
}
domCamera *cam = daeSafeCast< domCamera >( lib_cameras->createAndPlace( COLLADA_ELEMENT_CAMERA ) );
domCamera *cam = daeSafeCast< domCamera >( lib_cameras->add( COLLADA_ELEMENT_CAMERA ) );
cam->setId( name.c_str() );
lastVisited = CAMERA;
traverse( node );
}

View File

@@ -17,6 +17,9 @@
#include <dom/domNode.h>
#include <dom/domConstants.h>
#include <dae/domAny.h>
#include <osgSim/DOFTransform>
using namespace osgdae;
@@ -34,10 +37,10 @@ void daeWriter::apply( osg::MatrixTransform &node )
lastDepth--;
}
currentNode = daeSafeCast< domNode >(currentNode->createAndPlace( COLLADA_ELEMENT_NODE ) );
currentNode = daeSafeCast< domNode >(currentNode->add( COLLADA_ELEMENT_NODE ) );
currentNode->setId(getNodeName(node,"matrixTransform").c_str());
domMatrix *mat = daeSafeCast< domMatrix >(currentNode->createAndPlace( COLLADA_ELEMENT_MATRIX ) );
domMatrix *mat = daeSafeCast< domMatrix >(currentNode->add( COLLADA_ELEMENT_MATRIX ) );
const osg::Matrix::value_type *mat_vals = node.getMatrix().ptr();
//for ( int i = 0; i < 16; i++ )
//{
@@ -60,9 +63,10 @@ void daeWriter::apply( osg::MatrixTransform &node )
mat->getValue().append( mat_vals[11] );
mat->getValue().append( mat_vals[15] );
lastVisited = MATRIX;
lastDepth = _nodePath.size();
writeNodeExtra(node);
traverse( node );
}
@@ -79,7 +83,7 @@ void daeWriter::apply( osg::PositionAttitudeTransform &node )
currentNode = daeSafeCast< domNode >( currentNode->getParentElement() );
lastDepth--;
}
currentNode = daeSafeCast< domNode >(currentNode->createAndPlace( COLLADA_ELEMENT_NODE ) );
currentNode = daeSafeCast< domNode >(currentNode->add( COLLADA_ELEMENT_NODE ) );
currentNode->setId(getNodeName(node,"positionAttitudeTransform").c_str());
const osg::Vec3 &pos = node.getPosition();
@@ -89,7 +93,7 @@ void daeWriter::apply( osg::PositionAttitudeTransform &node )
if ( s.x() != 1 || s.y() != 1 || s.z() != 1 )
{
//make a scale
domScale *scale = daeSafeCast< domScale >( currentNode->createAndPlace( COLLADA_ELEMENT_SCALE ) );
domScale *scale = daeSafeCast< domScale >( currentNode->add( COLLADA_ELEMENT_SCALE ) );
scale->getValue().append( s.x() );
scale->getValue().append( s.y() );
scale->getValue().append( s.z() );
@@ -101,7 +105,7 @@ void daeWriter::apply( osg::PositionAttitudeTransform &node )
if ( angle != 0 )
{
//make a rotate
domRotate *rot = daeSafeCast< domRotate >( currentNode->createAndPlace( COLLADA_ELEMENT_ROTATE ) );
domRotate *rot = daeSafeCast< domRotate >( currentNode->add( COLLADA_ELEMENT_ROTATE ) );
rot->getValue().append( axis.x() );
rot->getValue().append( axis.y() );
rot->getValue().append( axis.z() );
@@ -111,13 +115,14 @@ void daeWriter::apply( osg::PositionAttitudeTransform &node )
if ( pos.x() != 0 || pos.y() != 0 || pos.z() != 0 )
{
//make a translate
domTranslate *trans = daeSafeCast< domTranslate >( currentNode->createAndPlace( COLLADA_ELEMENT_TRANSLATE ) );
domTranslate *trans = daeSafeCast< domTranslate >( currentNode->add( COLLADA_ELEMENT_TRANSLATE ) );
trans->getValue().append( pos.x() );
trans->getValue().append( pos.y() );
trans->getValue().append( pos.z() );
}
lastVisited = POSATT;
writeNodeExtra(node);
lastDepth = _nodePath.size();
traverse( node );
@@ -125,10 +130,117 @@ void daeWriter::apply( osg::PositionAttitudeTransform &node )
void daeWriter::apply( osg::Transform &node )
{
osg::notify( osg::WARN ) << "some other transform type. Missing " << node.getNumChildren() << " children\n";
debugPrint( node );
while ( lastDepth >= _nodePath.size() )
{
// We are not a child of previous node
currentNode = daeSafeCast< domNode >( currentNode->getParentElement() );
lastDepth--;
}
currentNode = daeSafeCast< domNode >(currentNode->add( COLLADA_ELEMENT_NODE ) );
// If a DOFTransform node store it's data as extra "DOFTransform" data in the "OpenSceneGraph" technique
osgSim::DOFTransform* dof = dynamic_cast<osgSim::DOFTransform*>(&node);
if (writeExtras && dof)
{
// Adds the following to a node
//<extra type="DOFTransform">
// <technique profile="OpenSceneGraph">
// <MinHPR>0 -0.174533 0</MinHPR>
// <MaxHPR>0 0.872665 0</MaxHPR>
// <IncrementHPR>0 0.0174533 0</IncrementHPR>
// <CurrentHPR>0 0 0</CurrentHPR>
// <MinTranslate>0 0 0</MinTranslate>
// <MaxTranslate>0 0 0</MaxTranslate>
// <IncrementTranslate>0 0 0</IncrementTranslate>
// <CurrentTranslate>0 0 0</CurrentTranslate>
// <MinScale>0 0 0</MinScale>
// <MaxScale>1 1 1</MaxScale>
// <IncrementScale>0 0 0</IncrementScale>
// <CurrentScale>1 1 1</CurrentScale>
// <MultOrder>0</MultOrder>
// <LimitationFlags>269964960</LimitationFlags>
// <AnimationOn>0</AnimationOn>
// <PutMatrix>
// 1 0 0 0
// 0 1 0 0
// 0 0 1 0
// 0 0 0 1
// </PutMatrix>
// </technique>
//</extra>
domExtra *extra = daeSafeCast<domExtra>(currentNode->add( COLLADA_ELEMENT_EXTRA ));
extra->setType("DOFTransform");
domTechnique *teq = daeSafeCast<domTechnique>(extra->add( COLLADA_ELEMENT_TECHNIQUE ) );
teq->setProfile( "OpenSceneGraph" );
domAny *minHPR = (domAny*)teq->add("MinHPR" );
minHPR->setValue(toString(dof->getMinHPR()).c_str());
domAny *maxHPR = (domAny*)teq->add("MaxHPR" );
maxHPR->setValue(toString(dof->getMaxHPR()).c_str());
domAny *incrementHPR = (domAny*)teq->add("IncrementHPR" );
incrementHPR->setValue(toString(dof->getIncrementHPR()).c_str());
domAny *currentHPR = (domAny*)teq->add("CurrentHPR" );
currentHPR->setValue(toString(dof->getCurrentHPR()).c_str());
domAny *minTranslate = (domAny*)teq->add("MinTranslate" );
minTranslate->setValue(toString(dof->getMinTranslate()).c_str());
domAny *maxTranslate = (domAny*)teq->add("MaxTranslate" );
maxTranslate->setValue(toString(dof->getMaxTranslate()).c_str());
domAny *incrementTranslate = (domAny*)teq->add("IncrementTranslate" );
incrementTranslate->setValue(toString(dof->getIncrementTranslate()).c_str());
domAny *currentTranslate = (domAny*)teq->add("CurrentTranslate" );
currentTranslate->setValue(toString(dof->getCurrentTranslate()).c_str());
domAny *minScale = (domAny*)teq->add("MinScale" );
minScale->setValue(toString(dof->getMinScale()).c_str());
domAny *maxScale = (domAny*)teq->add("MaxScale" );
maxScale->setValue(toString(dof->getMaxScale()).c_str());
domAny *incrementScale = (domAny*)teq->add("IncrementScale" );
incrementScale->setValue(toString(dof->getIncrementScale()).c_str());
domAny *currentScale = (domAny*)teq->add("CurrentScale" );
currentScale->setValue(toString(dof->getCurrentScale()).c_str());
domAny *multOrder = (domAny*)teq->add("MultOrder" );
multOrder->setValue(toString<int>(dof->getHPRMultOrder()).c_str());
domAny *limitationFlags = (domAny*)teq->add("LimitationFlags" );
limitationFlags->setValue(toString<unsigned long>(dof->getLimitationFlags()).c_str());
domAny *animationOn = (domAny*)teq->add("AnimationOn" );
animationOn->setValue(toString<bool>(dof->getAnimationOn()).c_str());
domAny *putMatrix = (domAny*)teq->add("PutMatrix" );
putMatrix->setValue(toString(dof->getPutMatrix()).c_str());
currentNode->setId(getNodeName(node, "doftransform").c_str());
}
else
{
currentNode->setId(getNodeName(node, "transform").c_str());
osg::notify( osg::WARN ) << "some other transform type. Missing " << node.getNumChildren() << " children" << std::endl;
}
writeNodeExtra(node);
lastDepth = _nodePath.size();
traverse( node );
}
void daeWriter::apply( osg::CoordinateSystemNode &node )
{
osg::notify( osg::WARN ) << "CoordinateSystemNode. Missing " << node.getNumChildren() << " children\n";
osg::notify( osg::WARN ) << "CoordinateSystemNode. Missing " << node.getNumChildren() << " children" << std::endl;
}

View File

@@ -20,13 +20,33 @@
#include <sstream>
using namespace osgdae;
daeWriter::daeWriter( DAE *dae_, const std::string &fileURI, bool _usePolygons, bool GoogleMode ) : osg::NodeVisitor( TRAVERSE_ALL_CHILDREN ),
namespace osgdae {
std::string toString(osg::Vec3 value)
{
std::stringstream str;
str << value.x() << " " << value.y() << " " << value.z();
return str.str();
}
std::string toString(osg::Matrix value)
{
std::stringstream str;
str << value(0,0) << " " << value(1,0) << " " << value(2,0) << " " << value(3,0) << " "
<< value(0,1) << " " << value(1,1) << " " << value(2,1) << " " << value(3,1) << " "
<< value(0,2) << " " << value(1,2) << " " << value(2,2) << " " << value(3,2) << " "
<< value(0,3) << " " << value(1,3) << " " << value(2,3) << " " << value(3,3);
return str.str();
}
daeWriter::daeWriter( DAE *dae_, const std::string &fileURI, bool _usePolygons, bool GoogleMode, TraversalMode tm, bool _writeExtras) : osg::NodeVisitor( tm ),
dae(dae_),
rootName(*dae_),
usePolygons (_usePolygons),
m_GoogleMode(GoogleMode)
m_GoogleMode(GoogleMode),
writeExtras(_writeExtras)
{
success = true;
@@ -36,14 +56,14 @@ 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->createAndPlace( COLLADA_ELEMENT_SCENE ) );
domInstanceWithExtra *ivs = daeSafeCast< domInstanceWithExtra >( scene->createAndPlace( "instance_visual_scene" ) );
domCOLLADA::domScene *scene = daeSafeCast< domCOLLADA::domScene >( dom->add( COLLADA_ELEMENT_SCENE ) );
domInstanceWithExtra *ivs = daeSafeCast< domInstanceWithExtra >( scene->add( "instance_visual_scene" ) );
ivs->setUrl( "#defaultScene" );
//create library visual scenes and a visual scene and the root node
lib_vis_scenes = daeSafeCast<domLibrary_visual_scenes>( dom->createAndPlace( COLLADA_ELEMENT_LIBRARY_VISUAL_SCENES ) );
vs = daeSafeCast< domVisual_scene >( lib_vis_scenes->createAndPlace( COLLADA_ELEMENT_VISUAL_SCENE ) );
lib_vis_scenes = daeSafeCast<domLibrary_visual_scenes>( 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->createAndPlace( COLLADA_ELEMENT_NODE ) );
currentNode = daeSafeCast< domNode >( vs->add( COLLADA_ELEMENT_NODE ) );
currentNode->setId( "sceneRoot" );
//create Asset
@@ -66,12 +86,14 @@ daeWriter::~daeWriter()
void daeWriter::debugPrint( osg::Node &node )
{
#ifdef _DEBUG
std::string indent = "";
for ( unsigned int i = 0; i < _nodePath.size(); i++ )
{
indent += " ";
}
osg::notify( osg::INFO ) << indent << node.className() << std::endl;
#endif
}
bool daeWriter::writeFile()
@@ -94,7 +116,7 @@ void daeWriter::setRootNode( const osg::Node &node )
std::string daeWriter::getNodeName(const osg::Node & node,const std::string & defaultName)
{
std::string nodeName;
if ((node.getName().empty()) || (node.getName()!=""))
if (node.getName().empty())
nodeName=uniquify(defaultName);
else
nodeName=node.getName();
@@ -104,12 +126,9 @@ std::string daeWriter::getNodeName(const osg::Node & node,const std::string & de
//NODE
void daeWriter::apply( osg::Node &node )
{
#ifdef _DEBUG
debugPrint( node );
#endif
osg::notify( osg::INFO ) << "generic node\n";
lastVisited = NODE;
writeNodeExtra(node);
traverse( node );
}
@@ -135,10 +154,10 @@ std::string daeWriter::uniquify( const std::string &name )
void daeWriter::createAssetTag()
{
domAsset *asset = daeSafeCast< domAsset >(dom->createAndPlace( COLLADA_ELEMENT_ASSET ) );
domAsset::domCreated *c = daeSafeCast< domAsset::domCreated >( asset->createAndPlace( "created" ) );
domAsset::domModified *m = daeSafeCast< domAsset::domModified >( asset->createAndPlace( "modified" ) );
domAsset::domUnit *u = daeSafeCast< domAsset::domUnit >( asset->createAndPlace( "unit" ) );
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"));
//TODO : set date and time
c->setValue( "2006-07-25T00:00:00Z" );
@@ -179,3 +198,4 @@ void daeWriter::popStateSet(osg::StateSet* ss)
}
}
} // namespace osgdae

View File

@@ -39,6 +39,7 @@
#include <osgDB/FileNameUtils>
#include <osgDB/FileUtils>
#include <osgDB/Registry>
#include <osgSim/MultiSwitch>
#include <dae.h>
#include <dae/daeDocument.h>
@@ -61,6 +62,17 @@ class domVisual_scene;
class domP;
namespace osgdae {
/// Convert value to string using it's stream operator
template <typename T>
std::string toString(T value) {
std::stringstream str;
str << value;
return str.str();
}
std::string toString(osg::Vec3 value);
std::string toString(osg::Matrix value);
/**
@class daeWriter
@@ -71,9 +83,7 @@ class daeWriter : public osg::NodeVisitor
protected:
class ArrayNIndices;
public:
enum NodeType { NODE, GEODE, GROUP, LIGHT, CAMERA, MATRIX, POSATT, SWITCH, LOD };
daeWriter( DAE *dae_, const std::string &fileURI, bool usePolygons=false, bool GoogleMode = false );
daeWriter( DAE *dae_, const std::string &fileURI, bool usePolygons=false, bool GoogleMode = false,TraversalMode tm=TRAVERSE_ALL_CHILDREN, bool writeExtras = true);
virtual ~daeWriter();
void setRootNode( const osg::Node &node );
@@ -90,9 +100,10 @@ public:
virtual void apply( osg::MatrixTransform &node );
virtual void apply( osg::PositionAttitudeTransform &node );
virtual void apply( osg::Switch &node );
virtual void apply( osg::Sequence &node );
virtual void apply( osg::LOD &node );
//virtual void apply( osg::Billboard &node);
//virtual void apply( osg::Billboard &node);
virtual void apply( osg::ProxyNode &node );
//virtual void apply( osg::Projection &node)
virtual void apply( osg::CoordinateSystemNode &node );
@@ -100,11 +111,14 @@ public:
//virtual void apply( osg::TexGenNode &node)
virtual void apply( osg::Transform &node );
//virtual void apply( osg::CameraView &node)
//virtual void apply( osg::Sequence &node)
//virtual void apply( osg::PagedLOD &node)
//virtual void apply( osg::ClearNode &node)
//virtual void apply( osg::OccluderNode &node)
void writeNodeExtra(osg::Node &node);
void traverse (osg::Node &node);
/*protected:
@@ -148,8 +162,9 @@ protected: //members
domNode *currentNode;
domVisual_scene *vs;
/// Write OSG specific data as extra data
bool writeExtras;
bool success;
NodeType lastVisited;
unsigned int lastDepth;
struct CompareStateSet