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:
@@ -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)
|
||||
|
||||
@@ -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 );
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user