From Roger James, "The changes are as follows:-
1. DAE object no longer held onto by plugin. 2. Filename to URI conversion now handled internally by plugin. 2. User can supply an external DAE object for use by the plugin. 3. User can supply a std:string object for the plugin to return the URI of the document just processed. 4. User can supply a std::string to receive the unit name information from the document just read in. (e.g. meters, inches, etc.) 5. User can supply a float to receive the metric conversion factor from the document just read in. 6. User can supply an enum to receive the up axis orientation information from the document just read in. 7. Material transparency can be both read and written. 8. User can supply an experimental GoogleMode option on output. The plugin will try to emulate the way Sketchup specifies transparency (i.e. the inverse of what it should be!). I am still struggling to get GE to understand transparency, anyone know what it expects? 9. Rudimentary support for Collada effect parameters (newparam, setparam, param) on input. Basic nVidia FX Composer dae documents can now be read. "
This commit is contained in:
@@ -22,7 +22,7 @@ SET(TARGET_H
|
||||
)
|
||||
|
||||
OPTION(COLLADA_USE_STATIC "Set to ON to build OpenSceneGraph with static Collada support." OFF)
|
||||
MARK_AS_ADVANCED(COLLADA_USE_STATIC)
|
||||
#MARK_AS_ADVANCED(COLLADA_USE_STATIC)
|
||||
|
||||
IF (WIN32)
|
||||
|
||||
|
||||
@@ -19,67 +19,29 @@
|
||||
#include <osgDB/Registry>
|
||||
|
||||
#include <OpenThreads/ScopedLock>
|
||||
#include <OpenThreads/ReentrantMutex>
|
||||
|
||||
#include "ReaderWriterDAE.h"
|
||||
#include "daeReader.h"
|
||||
#include "daeWriter.h"
|
||||
|
||||
#define EXTENSION_NAME "dae"
|
||||
#ifdef WIN32
|
||||
#include "windows.h"
|
||||
#endif
|
||||
|
||||
#define SERIALIZER() OpenThreads::ScopedLock<OpenThreads::ReentrantMutex> lock(_serializerMutex)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// OSG reader/writer plugin for the COLLADA 1.4.x ".dae" format.
|
||||
// See http://collada.org/ and http://khronos.org/collada/
|
||||
|
||||
class ReaderWriterDAE : public osgDB::ReaderWriter
|
||||
{
|
||||
public:
|
||||
ReaderWriterDAE() : _dae(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
~ReaderWriterDAE()
|
||||
{
|
||||
if(_dae != NULL){
|
||||
delete _dae;
|
||||
DAE::cleanup();
|
||||
_dae = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const char* className() const { return "COLLADA 1.4.x DAE reader/writer"; }
|
||||
|
||||
bool acceptsExtension(const std::string& extension) const
|
||||
{
|
||||
return osgDB::equalCaseInsensitive( extension, EXTENSION_NAME );
|
||||
}
|
||||
|
||||
ReadResult readNode(const std::string&, const Options*) const;
|
||||
|
||||
WriteResult writeNode(const osg::Node&, const std::string&, const Options*) const;
|
||||
|
||||
private:
|
||||
|
||||
mutable DAE *_dae;
|
||||
mutable OpenThreads::ReentrantMutex _serializerMutex;
|
||||
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
osgDB::ReaderWriter::ReadResult
|
||||
ReaderWriterDAE::readNode(const std::string& fname,
|
||||
const osgDB::ReaderWriter::Options* options) const
|
||||
{
|
||||
SERIALIZER();
|
||||
|
||||
DAE* daeptr = 0L;
|
||||
|
||||
if ( options ) {
|
||||
daeptr = (DAE*) options->getPluginData("DAE");
|
||||
}
|
||||
|
||||
bool bOwnDAE = false;
|
||||
DAE* pDAE = NULL;
|
||||
|
||||
if ( options )
|
||||
pDAE = (DAE*) options->getPluginData("DAE");
|
||||
|
||||
std::string ext( osgDB::getLowerCaseFileExtension(fname) );
|
||||
if( ! acceptsExtension(ext) ) return ReadResult::FILE_NOT_HANDLED;
|
||||
|
||||
@@ -88,31 +50,39 @@ ReaderWriterDAE::readNode(const std::string& fname,
|
||||
|
||||
osg::notify(osg::INFO) << "ReaderWriterDAE( \"" << fileName << "\" )" << std::endl;
|
||||
|
||||
|
||||
if (daeptr == NULL) {
|
||||
if (_dae == NULL)
|
||||
_dae = new DAE();
|
||||
daeptr = _dae;
|
||||
if (NULL == pDAE)
|
||||
{
|
||||
bOwnDAE = true;
|
||||
pDAE = new DAE;
|
||||
}
|
||||
|
||||
osgdae::daeReader daeReader(daeptr) ;
|
||||
std::string fileURI( osgDB::convertFileNameToUnixStyle(fileName) );
|
||||
osgdae::daeReader daeReader(pDAE) ;
|
||||
|
||||
// Convert file name to URI
|
||||
std::string fileURI = ConvertFilePathToColladaCompatibleURI(fileName);
|
||||
|
||||
if ( ! daeReader.convert( fileURI ) )
|
||||
{
|
||||
osg::notify( osg::WARN ) << "Load failed in COLLADA DOM conversion" << std::endl;
|
||||
return ReadResult::ERROR_IN_READING_FILE;
|
||||
}
|
||||
|
||||
if ( options ) {
|
||||
// return DAE* used
|
||||
options->setPluginData("DAE", daeptr);
|
||||
// and filename document was stored as in database, does not have to be
|
||||
// the same as fname
|
||||
options->setPluginData("DAE-DocumentFileName", ( fileURI[1] == ':' ?
|
||||
(void*) new std::auto_ptr<std::string>(new std::string('/'+fileURI)) :
|
||||
(void*) new std::auto_ptr<std::string>(new std::string(fileURI)) )
|
||||
);
|
||||
}
|
||||
if ( options )
|
||||
{
|
||||
// Return the document URI
|
||||
if (options->getPluginData("DAE-DocumentURI"))
|
||||
*(std::string*)options->getPluginData("DAE-DocumentURI") = fileURI;
|
||||
// Return some additional information about the document
|
||||
if (options->getPluginData("DAE-AssetUnitName"))
|
||||
*(std::string*)options->getPluginData("DAE-AssetUnitName") = daeReader.m_AssetUnitName;
|
||||
if (options->getPluginData("DAE-AssetUnitMeter"))
|
||||
*(float*)options->getPluginData("DAE-AssetUnitMeter") = daeReader.m_AssetUnitMeter;
|
||||
if (options->getPluginData("DAE-AssetUp_axis"))
|
||||
*(domUpAxisType*)options->getPluginData("DAE-AssetUp_axis") = daeReader.m_AssetUp_axis;
|
||||
}
|
||||
|
||||
if (bOwnDAE)
|
||||
delete pDAE;
|
||||
|
||||
osg::Node* rootNode( daeReader.getRootNode() );
|
||||
return rootNode;
|
||||
@@ -126,44 +96,48 @@ ReaderWriterDAE::writeNode( const osg::Node& node,
|
||||
{
|
||||
SERIALIZER();
|
||||
|
||||
DAE* daeptr = 0L;
|
||||
bool bOwnDAE = false;
|
||||
DAE* pDAE = NULL;
|
||||
|
||||
std::string ext( osgDB::getLowerCaseFileExtension(fname) );
|
||||
if( ! acceptsExtension(ext) ) return WriteResult::FILE_NOT_HANDLED;
|
||||
|
||||
if ( options ) {
|
||||
daeptr = (DAE*) options->getPluginData("DAE");
|
||||
}
|
||||
|
||||
// Process options
|
||||
bool usePolygon(false);
|
||||
bool GoogleMode(false);
|
||||
if( options )
|
||||
{
|
||||
std::istringstream iss( options->getOptionString() );
|
||||
std::string opt;
|
||||
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
|
||||
{
|
||||
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 (daeptr == NULL) {
|
||||
if (_dae == NULL)
|
||||
_dae = new DAE();
|
||||
daeptr = _dae;
|
||||
if (NULL == pDAE)
|
||||
{
|
||||
bOwnDAE = true;
|
||||
pDAE = new DAE;
|
||||
}
|
||||
|
||||
osgdae::daeWriter daeWriter(daeptr, fname, usePolygon );
|
||||
// Convert file name to URI
|
||||
std::string fileURI = ConvertFilePathToColladaCompatibleURI(fname);
|
||||
|
||||
osgdae::daeWriter daeWriter(pDAE, fileURI, usePolygon, GoogleMode );
|
||||
daeWriter.setRootNode( node );
|
||||
const_cast<osg::Node*>(&node)->accept( daeWriter );
|
||||
|
||||
@@ -171,25 +145,40 @@ ReaderWriterDAE::writeNode( const osg::Node& node,
|
||||
if ( daeWriter.isSuccess() )
|
||||
{
|
||||
if ( daeWriter.writeFile() )
|
||||
{
|
||||
retVal = WriteResult::FILE_SAVED;
|
||||
}
|
||||
}
|
||||
|
||||
if ( options ) {
|
||||
// return DAE* used
|
||||
options->setPluginData("DAE", daeptr);
|
||||
|
||||
// saving filename so read and write work the same way,
|
||||
// this could be skipped since write does not currently modify the
|
||||
// filename which load might do (under windows for example)
|
||||
options->setPluginData("DAE-DocumentFileName", (void*) new
|
||||
std::auto_ptr<std::string>(new std::string(fname)));
|
||||
if ( options )
|
||||
{
|
||||
if (!bOwnDAE)
|
||||
{
|
||||
// Return the document URI used so that users of an external DAE object
|
||||
// can locate the correct database
|
||||
if (options->getPluginData("DAE-DocumentURI"))
|
||||
*(std::string*)options->getPluginData("DAE-DocumentURI") = fileURI;
|
||||
}
|
||||
}
|
||||
|
||||
if (bOwnDAE)
|
||||
delete pDAE;
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
std::string ReaderWriterDAE::ConvertFilePathToColladaCompatibleURI(const std::string& FilePath)
|
||||
{
|
||||
std::string fileURI = osgDB::convertFileNameToUnixStyle(osgDB::getRealPath(FilePath));
|
||||
// fileURI should now contain a canonical absolute path name with UNIX style component separators
|
||||
#if defined(WIN32) && !defined(__CYGWIN__)
|
||||
// Check for windows drive designator or UNC path
|
||||
if ((fileURI[1] == ':') || ((fileURI[0] == '/') && (fileURI[1] == '/')))
|
||||
fileURI.insert(0, 1, '/');
|
||||
#endif
|
||||
fileURI.insert(0, "file://");
|
||||
return fileURI;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Add ourself to the Registry to instantiate the reader/writer.
|
||||
|
||||
|
||||
40
src/osgPlugins/dae/ReaderWriterDAE.h
Normal file
40
src/osgPlugins/dae/ReaderWriterDAE.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#ifndef _READERWRITERDAE_H_
|
||||
#define _READERWRITERDAE_H_
|
||||
|
||||
|
||||
#include <OpenThreads/ReentrantMutex>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// OSG reader/writer plugin for the COLLADA 1.4.x ".dae" format.
|
||||
// See http://collada.org/ and http://khronos.org/collada/
|
||||
|
||||
#define EXTENSION_NAME "dae"
|
||||
|
||||
class ReaderWriterDAE : public osgDB::ReaderWriter
|
||||
{
|
||||
public:
|
||||
ReaderWriterDAE()
|
||||
{
|
||||
}
|
||||
|
||||
const char* className() const { return "COLLADA 1.4.x DAE reader/writer"; }
|
||||
|
||||
bool acceptsExtension(const std::string& extension) const
|
||||
{
|
||||
return osgDB::equalCaseInsensitive( extension, EXTENSION_NAME );
|
||||
}
|
||||
|
||||
ReadResult readNode(const std::string&, const Options*) const;
|
||||
|
||||
WriteResult writeNode(const osg::Node&, const std::string&, const Options*) const;
|
||||
|
||||
static std::string ConvertFilePathToColladaCompatibleURI(const std::string& FilePath);
|
||||
|
||||
private:
|
||||
mutable OpenThreads::ReentrantMutex _serializerMutex;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif
|
||||
|
||||
@@ -89,7 +89,8 @@ void daeReader::processBindMaterial( domBind_material *bm, osg::Node *geo )
|
||||
|
||||
osg::StateSet *daeReader::processMaterial( domMaterial *mat )
|
||||
{
|
||||
domEffect *effect = daeSafeCast< domEffect >( getElementFromURI( mat->getInstance_effect()->getUrl() ) );
|
||||
currentInstance_effect = mat->getInstance_effect();
|
||||
domEffect *effect = daeSafeCast< domEffect >( getElementFromURI( currentInstance_effect->getUrl() ) );
|
||||
if ( effect == NULL )
|
||||
{
|
||||
osg::notify( osg::WARN ) << "Failed to locate effect " << mat->getInstance_effect()->getUrl().getURI() << std::endl;
|
||||
@@ -327,9 +328,19 @@ 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;
|
||||
if (GetFloat4Param(cot->getParam()->getRef(), f4))
|
||||
{
|
||||
mat->setEmission( osg::Material::FRONT_AND_BACK, osg::Vec4( f4[0], f4[1], f4[2], f4[3] ) );
|
||||
retVal = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::notify( osg::WARN ) << "Currently no support for <param> or <texture> in Emission channel " << std::endl;
|
||||
osg::notify( osg::WARN ) << "Currently no support for <texture> in Emission channel " << std::endl;
|
||||
}
|
||||
}
|
||||
else if ( channel == osg::Material::AMBIENT )
|
||||
@@ -340,9 +351,18 @@ osg::StateAttribute **sa )
|
||||
mat->setAmbient( osg::Material::FRONT_AND_BACK, osg::Vec4( f4[0], f4[1], f4[2], f4[3] ) );
|
||||
retVal = true;
|
||||
}
|
||||
else if (cot->getParam() != NULL)
|
||||
{
|
||||
domFloat4 f4;
|
||||
if (GetFloat4Param(cot->getParam()->getRef(), f4))
|
||||
{
|
||||
mat->setAmbient( osg::Material::FRONT_AND_BACK, osg::Vec4( f4[0], f4[1], f4[2], f4[3] ) );
|
||||
retVal = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::notify( osg::WARN ) << "Currently no support for <param> or <texture> in Ambient channel " << std::endl;
|
||||
osg::notify( osg::WARN ) << "Currently no support for <texture> in Ambient channel " << std::endl;
|
||||
}
|
||||
}
|
||||
else if ( channel == osg::Material::DIFFUSE )
|
||||
@@ -377,9 +397,14 @@ osg::StateAttribute **sa )
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (cot->getParam() != NULL)
|
||||
{
|
||||
osg::notify( osg::WARN ) << "Currently no support for <param> in Diffuse channel " << std::endl;
|
||||
domFloat4 f4;
|
||||
if (GetFloat4Param(cot->getParam()->getRef(), f4))
|
||||
{
|
||||
mat->setDiffuse( osg::Material::FRONT_AND_BACK, osg::Vec4( f4[0], f4[1], f4[2], f4[3] ) );
|
||||
retVal = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( channel == osg::Material::SPECULAR )
|
||||
@@ -390,9 +415,18 @@ osg::StateAttribute **sa )
|
||||
mat->setSpecular( osg::Material::FRONT_AND_BACK, osg::Vec4( f4[0], f4[1], f4[2], f4[3] ) );
|
||||
retVal = true;
|
||||
}
|
||||
else
|
||||
else if (cot->getParam() != NULL)
|
||||
{
|
||||
osg::notify( osg::WARN ) << "Currently no support for <param> or <texture> in Specular channel " << std::endl;
|
||||
domFloat4 f4;
|
||||
if (GetFloat4Param(cot->getParam()->getRef(), f4))
|
||||
{
|
||||
mat->setSpecular( osg::Material::FRONT_AND_BACK, osg::Vec4( f4[0], f4[1], f4[2], f4[3] ) );
|
||||
retVal = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::notify( osg::WARN ) << "Currently no support for <texture> in Specular channel " << std::endl;
|
||||
}
|
||||
if ( fop != NULL && fop->getFloat() != NULL )
|
||||
{
|
||||
@@ -404,6 +438,100 @@ osg::StateAttribute **sa )
|
||||
return retVal;
|
||||
}
|
||||
|
||||
bool daeReader::GetFloat4Param(xsNCName Reference, domFloat4 &f4)
|
||||
{
|
||||
std::string MyReference = Reference;
|
||||
|
||||
MyReference.insert(0, "./");
|
||||
daeSIDResolver Resolver(currentEffect, MyReference.c_str());
|
||||
daeElement *el = Resolver.getElement();
|
||||
if (NULL == el)
|
||||
return false;
|
||||
|
||||
if (NULL != currentInstance_effect)
|
||||
{
|
||||
// look here first for setparams
|
||||
// I am sure there must be a better way of doing this
|
||||
// Maybe the Collada DAE guys can give us a parameter management mechanism !
|
||||
const domInstance_effect::domSetparam_Array& SetParamArray = currentInstance_effect->getSetparam_array();
|
||||
size_t NumberOfSetParams = SetParamArray.getCount();
|
||||
for (size_t i = 0; i < NumberOfSetParams; i++)
|
||||
{
|
||||
// Just do a simple comaprison of the ref strings for the time being
|
||||
if (0 == strcmp(SetParamArray[i]->getRef(), Reference))
|
||||
{
|
||||
if (NULL != SetParamArray[i]->getFx_basic_type_common() && (NULL != SetParamArray[i]->getFx_basic_type_common()->getFloat4()))
|
||||
{
|
||||
f4 = SetParamArray[i]->getFx_basic_type_common()->getFloat4()->getValue();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
domCommon_newparam_type *cnp = daeSafeCast< domCommon_newparam_type >( el );
|
||||
domFx_newparam_common *npc = daeSafeCast< domFx_newparam_common >( el );
|
||||
if ((cnp != NULL) && (NULL != cnp->getFloat4()))
|
||||
{
|
||||
f4 = cnp->getFloat4()->getValue();
|
||||
return true;
|
||||
}
|
||||
else if ((npc != NULL) && (NULL != npc->getFx_basic_type_common()) && (NULL != npc->getFx_basic_type_common()->getFloat4()))
|
||||
{
|
||||
f4 = npc->getFx_basic_type_common()->getFloat4()->getValue();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool daeReader::GetFloatParam(xsNCName Reference, domFloat &f)
|
||||
{
|
||||
std::string MyReference = Reference;
|
||||
|
||||
MyReference.insert(0, "./");
|
||||
daeSIDResolver Resolver(currentEffect, MyReference.c_str());
|
||||
daeElement *el = Resolver.getElement();
|
||||
if (NULL == el)
|
||||
return false;
|
||||
|
||||
if (NULL != currentInstance_effect)
|
||||
{
|
||||
// look here first for setparams
|
||||
// I am sure there must be a better way of doing this
|
||||
// Maybe the Collada DAE guys can give us a parameter management mechanism !
|
||||
const domInstance_effect::domSetparam_Array& SetParamArray = currentInstance_effect->getSetparam_array();
|
||||
size_t NumberOfSetParams = SetParamArray.getCount();
|
||||
for (size_t i = 0; i < NumberOfSetParams; i++)
|
||||
{
|
||||
// Just do a simple comaprison of the ref strings for the time being
|
||||
if (0 == strcmp(SetParamArray[i]->getRef(), Reference))
|
||||
{
|
||||
if (NULL != SetParamArray[i]->getFx_basic_type_common() && (NULL != SetParamArray[i]->getFx_basic_type_common()->getFloat()))
|
||||
{
|
||||
f = SetParamArray[i]->getFx_basic_type_common()->getFloat()->getValue();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
domCommon_newparam_type *cnp = daeSafeCast< domCommon_newparam_type >( el );
|
||||
domFx_newparam_common *npc = daeSafeCast< domFx_newparam_common >( el );
|
||||
if ((cnp != NULL) && (NULL != cnp->getFloat()))
|
||||
{
|
||||
f = cnp->getFloat()->getValue();
|
||||
return true;
|
||||
}
|
||||
else if ((npc != NULL) && (NULL != npc->getFx_basic_type_common()) && (NULL != npc->getFx_basic_type_common()->getFloat()))
|
||||
{
|
||||
f = npc->getFx_basic_type_common()->getFloat()->getValue();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
osg::StateAttribute *daeReader::processTexture( domCommon_color_or_texture_type_complexType::domTexture *tex )
|
||||
{
|
||||
//find the newparam for the sampler based on the texture attribute
|
||||
@@ -508,8 +636,12 @@ osg::StateAttribute *daeReader::processTexture( domCommon_color_or_texture_type_
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
// under windows the URI passed back from the dom includes a / i.e. /c:/path/file, so we need to jump over the leading /
|
||||
char* filename = path+1;
|
||||
// If the path has a drive specifier or a UNC name then strip the leading /
|
||||
char* filename;
|
||||
if ((path[2] == ':') || ((path[1] == '/') && (path[2] == '/')))
|
||||
filename = path+1;
|
||||
else
|
||||
filename = path;
|
||||
#else
|
||||
char* filename = path;
|
||||
#endif
|
||||
@@ -717,18 +849,17 @@ osg::StateAttribute *daeReader::processTransparencySettings( domCommon_transpare
|
||||
else
|
||||
{
|
||||
Opaque = ctt->getOpaque();
|
||||
if (NULL == ctt->getColor().cast())
|
||||
if (NULL != ctt->getColor())
|
||||
{
|
||||
f4 = ctt->getColor()->getValue();
|
||||
}
|
||||
else if ((NULL == ctt->getParam()) || !GetFloat4Param(ctt->getParam()->getRef(), f4))
|
||||
{
|
||||
// I test for a texture in the ctt above
|
||||
// but there could still be a param rather than a color
|
||||
// I don't know what to do with a param (Can anyone help here?)
|
||||
// So I will just assume a default
|
||||
f4.append(0.0f);
|
||||
f4.append(0.0f);
|
||||
f4.append(0.0f);
|
||||
f4.append(1.0f);
|
||||
}
|
||||
f4 = ctt->getColor()->getValue();
|
||||
}
|
||||
|
||||
domFloat Transparency;
|
||||
@@ -736,9 +867,22 @@ osg::StateAttribute *daeReader::processTransparencySettings( domCommon_transpare
|
||||
Transparency = 1.0f;
|
||||
else
|
||||
{
|
||||
Transparency = pTransparency->getFloat()->getValue();
|
||||
if (m_AuthoringTool == GOOGLE_SKETCHUP) // Google back to front support
|
||||
Transparency = 1.0f - Transparency;
|
||||
if (NULL != pTransparency->getFloat())
|
||||
{
|
||||
Transparency = pTransparency->getFloat()->getValue();
|
||||
if (m_AuthoringTool == GOOGLE_SKETCHUP) // Google back to front support
|
||||
Transparency = 1.0f - Transparency;
|
||||
}
|
||||
else if (NULL != pTransparency->getParam())
|
||||
{
|
||||
if (GetFloatParam(pTransparency->getParam()->getRef(), Transparency))
|
||||
{
|
||||
if (m_AuthoringTool == GOOGLE_SKETCHUP) // Google back to front support
|
||||
Transparency = 1.0f - Transparency;
|
||||
}
|
||||
else
|
||||
Transparency = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
osg::BlendColor *bc = new osg::BlendColor();
|
||||
|
||||
@@ -23,9 +23,13 @@ daeReader::daeReader(DAE *dae_) : dae(dae_),
|
||||
rootNode(NULL),
|
||||
m_numlights(0),
|
||||
currentEffect(NULL),
|
||||
currentInstance_effect(NULL),
|
||||
geometryMap(),
|
||||
materialMap(),
|
||||
m_AuthoringTool(UNKNOWN)
|
||||
m_AuthoringTool(UNKNOWN),
|
||||
m_AssetUnitName("meter"),
|
||||
m_AssetUnitMeter(1.0),
|
||||
m_AssetUp_axis(UPAXISTYPE_Y_UP)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -40,26 +44,16 @@ bool daeReader::convert( const std::string &fileURI )
|
||||
|
||||
daeInt count, result;
|
||||
|
||||
|
||||
std::string fURI;
|
||||
if ( fileURI[1] == ':' )
|
||||
{
|
||||
fURI = "/" + fileURI;
|
||||
}
|
||||
else
|
||||
{
|
||||
fURI = fileURI;
|
||||
}
|
||||
daeInt res = dae->load( fURI.c_str() );
|
||||
daeInt res = dae->load( fileURI.c_str() );
|
||||
|
||||
if( res != DAE_OK && res != DAE_ERR_COLLECTION_ALREADY_EXISTS)
|
||||
{
|
||||
osg::notify( osg::WARN ) << "Load failed in COLLADA DOM" << std::endl;
|
||||
return false;
|
||||
}
|
||||
osg::notify( osg::INFO ) << "URI loaded: " << fURI << std::endl;
|
||||
osg::notify( osg::INFO ) << "URI loaded: " << fileURI << std::endl;
|
||||
|
||||
domCOLLADA* document = dae->getDom( fURI.c_str() );
|
||||
domCOLLADA* document = dae->getDom( fileURI.c_str() );
|
||||
|
||||
if ( !document->getScene() || !document->getScene()->getInstance_visual_scene() )
|
||||
{
|
||||
@@ -81,6 +75,15 @@ bool daeReader::convert( const std::string &fileURI )
|
||||
m_AuthoringTool = GOOGLE_SKETCHUP;
|
||||
}
|
||||
}
|
||||
if (document->getAsset()->getUnit())
|
||||
{
|
||||
if (NULL != document->getAsset()->getUnit()->getName())
|
||||
m_AssetUnitName = std::string(document->getAsset()->getUnit()->getName());
|
||||
if (0 != document->getAsset()->getUnit()->getMeter())
|
||||
m_AssetUnitMeter = document->getAsset()->getUnit()->getMeter();
|
||||
}
|
||||
if (document->getAsset()->getUp_axis())
|
||||
m_AssetUp_axis = document->getAsset()->getUp_axis()->getValue();
|
||||
}
|
||||
|
||||
if (dae->getDatabase()) {
|
||||
@@ -190,7 +193,7 @@ osg::Node* daeReader::processNode( domNode *node )
|
||||
|
||||
// <rotate>
|
||||
osg::Quat osgRot;
|
||||
for (int i=0; i<node->getRotate_array().getCount(); i++)
|
||||
for (unsigned int i=0; i<node->getRotate_array().getCount(); i++)
|
||||
{
|
||||
daeSmartRef<domRotate> rot = node->getRotate_array().get(i);
|
||||
if (rot->getValue().getCount() != 4 ) {
|
||||
@@ -208,7 +211,7 @@ osg::Node* daeReader::processNode( domNode *node )
|
||||
|
||||
// <scale>
|
||||
osg::Vec3 osgScale = osg::Vec3(1.0, 1.0, 1.0);
|
||||
for (int i=0; i<node->getScale_array().getCount(); i++)
|
||||
for (unsigned int i=0; i<node->getScale_array().getCount(); i++)
|
||||
{
|
||||
daeSmartRef<domScale> scale = node->getScale_array().get(i);
|
||||
|
||||
@@ -226,7 +229,7 @@ osg::Node* daeReader::processNode( domNode *node )
|
||||
|
||||
// <translate>
|
||||
osg::Vec3 osgTrans = osg::Vec3(0.0, 0.0, 0.0);
|
||||
for (int i=0; i<node->getTranslate_array().getCount(); i++)
|
||||
for (unsigned int i=0; i<node->getTranslate_array().getCount(); i++)
|
||||
{
|
||||
daeSmartRef<domTranslate> trans = node->getTranslate_array().get(i);
|
||||
|
||||
|
||||
@@ -106,6 +106,11 @@ public:
|
||||
|
||||
osg::Node* getRootNode() { return rootNode; }
|
||||
|
||||
// Additional Information
|
||||
std::string m_AssetUnitName;
|
||||
float m_AssetUnitMeter;
|
||||
domUpAxisType m_AssetUp_axis;
|
||||
|
||||
protected:
|
||||
//scene processing
|
||||
osg::Node* processVisualScene( domVisual_scene *scene );
|
||||
@@ -149,6 +154,8 @@ protected:
|
||||
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::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);
|
||||
|
||||
osg::StateAttribute *processTexture( domCommon_color_or_texture_type_complexType::domTexture *tex );
|
||||
|
||||
@@ -164,6 +171,7 @@ protected:
|
||||
|
||||
int m_numlights;
|
||||
|
||||
domInstance_effect *currentInstance_effect;
|
||||
domEffect *currentEffect;
|
||||
|
||||
std::map< domGeometry*, osg::Node* > geometryMap;
|
||||
|
||||
@@ -32,6 +32,8 @@ void daeWriter::apply( osg::Geode &node )
|
||||
#endif
|
||||
|
||||
pushStateSet(node.getStateSet());
|
||||
if (NULL != node.getStateSet())
|
||||
m_CurrentRenderingHint = node.getStateSet()->getRenderingHint();
|
||||
|
||||
unsigned int count = node.getNumDrawables();
|
||||
for ( unsigned int i = 0; i < count; i++ )
|
||||
@@ -810,6 +812,9 @@ bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const st
|
||||
}
|
||||
|
||||
primItrBegin+=nbVerticesPerPoly;
|
||||
#if ( _SECURE_SCL == 1 )
|
||||
if (primItrBegin != drawElements->end())
|
||||
#endif
|
||||
primItrEnd+=nbVerticesPerPoly;
|
||||
}
|
||||
break;
|
||||
@@ -906,6 +911,9 @@ bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const st
|
||||
|
||||
}
|
||||
primItrBegin+=nbVerticesPerPoly;
|
||||
#if ( _SECURE_SCL == 1 )
|
||||
if (primItrBegin != drawElements->end())
|
||||
#endif
|
||||
primItrEnd+=nbVerticesPerPoly;
|
||||
}
|
||||
|
||||
@@ -1004,6 +1012,9 @@ bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const st
|
||||
}
|
||||
}
|
||||
primItrBegin+=nbVerticesPerPoly;
|
||||
#if ( _SECURE_SCL == 1 )
|
||||
if (primItrBegin != drawElements->end())
|
||||
#endif
|
||||
primItrEnd+=nbVerticesPerPoly;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
*/
|
||||
|
||||
#include "daeWriter.h"
|
||||
#include "ReaderWriterDAE.h"
|
||||
|
||||
#include <dae/domAny.h>
|
||||
#include <dom/domCOLLADA.h>
|
||||
@@ -97,49 +98,10 @@ void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, co
|
||||
|
||||
osg::Image *osgimg = tex->getImage( 0 );
|
||||
domImage::domInit_from *imgif = daeSafeCast< domImage::domInit_from >( img->createAndPlace( "init_from" ) );
|
||||
#ifdef WIN32
|
||||
char path1[ MAX_PATH + 1 ];
|
||||
char path2[ MAX_PATH + 1 ];
|
||||
LPTSTR pFileName;
|
||||
std::string imageFileName = osgDB::findDataFile( osgimg->getFileName() );
|
||||
GetFullPathName( imageFileName.c_str(), MAX_PATH + 1, path1, &pFileName );
|
||||
GetShortPathName( path1, path2, MAX_PATH + 1 );
|
||||
GetLongPathName( path2, path1, MAX_PATH + 1 );
|
||||
imageFileName = osgDB::convertFileNameToUnixStyle(path1);
|
||||
if ((imageFileName.length() > 3) && (isalpha(imageFileName[0])) && (imageFileName[1] == ':') && (imageFileName[2] == '/'))
|
||||
{
|
||||
if (islower(imageFileName[0]))
|
||||
imageFileName[0] = (char)_toupper(imageFileName[0]);
|
||||
imageFileName = '/' + imageFileName;
|
||||
}
|
||||
daeURI imageFileUri( imageFileName.c_str() );
|
||||
imageFileUri.validate();
|
||||
std::string docFileName = doc->getDocumentURI()->getFilepath();
|
||||
docFileName += doc->getDocumentURI()->getFile();
|
||||
if ((docFileName.length() > 3) && (docFileName[0] == '/') && (isalpha(docFileName[1])) && (docFileName[2] == ':') && (docFileName[3] == '/'))
|
||||
GetFullPathName( docFileName.c_str() + 1, MAX_PATH + 1, path1, &pFileName );
|
||||
else
|
||||
GetFullPathName( docFileName.c_str(), MAX_PATH + 1, path1, &pFileName );
|
||||
GetShortPathName( path1, path2, MAX_PATH + 1 );
|
||||
GetLongPathName( path2, path1, MAX_PATH + 1 );
|
||||
docFileName = osgDB::convertFileNameToUnixStyle(path1);
|
||||
if ((docFileName.length() > 3) && (isalpha(docFileName[0])) && (docFileName[1] == ':') && (docFileName[2] == '/'))
|
||||
{
|
||||
if (islower(docFileName[0]))
|
||||
docFileName[0] = (char)_toupper(docFileName[0]);
|
||||
docFileName = '/' + docFileName;
|
||||
}
|
||||
daeURI docFileUri( docFileName.c_str() );
|
||||
docFileUri.validate();
|
||||
imgif->setValue( imageFileUri.getURI() );
|
||||
imgif->getValue().makeRelativeTo( &docFileUri );
|
||||
#else
|
||||
std::string imgstr = osgDB::convertFileNameToUnixStyle( osgDB::findDataFile( osgimg->getFileName() ) );
|
||||
daeURI uri( imgstr.c_str() );
|
||||
uri.validate(); // This returns an absolute URI
|
||||
imgif->setValue( uri.getURI() );
|
||||
imgif->getValue().makeRelativeTo( doc->getDocumentURI() );
|
||||
#endif
|
||||
std::string fileURI = ReaderWriterDAE::ConvertFilePathToColladaCompatibleURI(osgDB::findDataFile(osgimg->getFileName()));
|
||||
imgif->setValue(daeURI(fileURI.c_str()));
|
||||
// The document URI should contain the canonical path it was created with
|
||||
imgif->getValue().makeRelativeTo(doc->getDocumentURI());
|
||||
|
||||
#ifndef EARTH_TEX
|
||||
domCommon_newparam_type *np = daeSafeCast< domCommon_newparam_type >( pc->createAndPlace( "newparam" ) );
|
||||
@@ -274,6 +236,7 @@ void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, co
|
||||
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 ) );
|
||||
@@ -299,7 +262,7 @@ void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, co
|
||||
#endif
|
||||
dtex->setTexcoord( "texcoord0" );
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
||||
osg::Material *osgmat = static_cast<osg::Material*>(ssClean->getAttribute( osg::StateAttribute::MATERIAL ));
|
||||
if ( osgmat != NULL )
|
||||
@@ -363,6 +326,73 @@ void daeWriter::processMaterial( osg::StateSet *ss, domInstance_geometry *ig, co
|
||||
f->setValue( shininess );
|
||||
}
|
||||
|
||||
// Do common transparency stuff here
|
||||
// if (osg::StateSet::TRANSPARENT_BIN == ssClean->getRenderingHint()) cannot do this at the moment because stateSet::merge does does not handle the hints
|
||||
if (osg::StateSet::TRANSPARENT_BIN == m_CurrentRenderingHint)
|
||||
{
|
||||
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 ((GL_CONSTANT_ALPHA == pBlendFunc->getSource()) && (GL_ONE_MINUS_CONSTANT_ALPHA == pBlendFunc->getDestination()))
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
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 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->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);
|
||||
}
|
||||
else
|
||||
osg::notify( osg::WARN ) << "Unsupported BlendFunction parameters in transparency processing." << std::endl;
|
||||
}
|
||||
else
|
||||
osg::notify( osg::WARN ) << "Transparency processing - BlendFunction or BlendColor not found." << std::endl;
|
||||
}
|
||||
|
||||
// Process GOOGLE one sided stuff here
|
||||
if (osg::StateAttribute::INHERIT != ssClean->getMode(GL_CULL_FACE))
|
||||
{
|
||||
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");
|
||||
}
|
||||
|
||||
materialMap.insert( std::make_pair( ssClean, mat ) );
|
||||
}
|
||||
|
||||
@@ -377,7 +407,9 @@ osg::StateSet* daeWriter::CleanStateSet(osg::StateSet* pStateSet) const
|
||||
pCleanedStateSet->setAttribute(pStateSet->getAttribute(osg::StateAttribute::BLENDCOLOR));
|
||||
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))
|
||||
pCleanedStateSet->setMode(GL_CULL_FACE, pStateSet->getMode(GL_CULL_FACE));
|
||||
return pCleanedStateSet;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,16 +22,17 @@
|
||||
|
||||
using namespace osgdae;
|
||||
|
||||
daeWriter::daeWriter( DAE *dae_, const std::string &fname,bool _usePolygons ) : osg::NodeVisitor( TRAVERSE_ALL_CHILDREN ),
|
||||
daeWriter::daeWriter( DAE *dae_, const std::string &fileURI, bool _usePolygons, bool GoogleMode ) : osg::NodeVisitor( TRAVERSE_ALL_CHILDREN ),
|
||||
dae(dae_),
|
||||
usePolygons (_usePolygons)
|
||||
usePolygons (_usePolygons),
|
||||
m_GoogleMode(GoogleMode)
|
||||
{
|
||||
success = true;
|
||||
|
||||
dae->setDatabase( NULL );
|
||||
dae->setIOPlugin( NULL );
|
||||
//create document
|
||||
dae->getDatabase()->createDocument( fname.c_str(), &doc );
|
||||
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 ) );
|
||||
|
||||
@@ -73,7 +73,7 @@ protected:
|
||||
public:
|
||||
enum NodeType { NODE, GEODE, GROUP, LIGHT, CAMERA, MATRIX, POSATT, SWITCH, LOD };
|
||||
|
||||
daeWriter( DAE *dae_, const std::string &fname, bool usePolygons=false );
|
||||
daeWriter( DAE *dae_, const std::string &fileURI, bool usePolygons=false, bool GoogleMode = false );
|
||||
virtual ~daeWriter();
|
||||
|
||||
void setRootNode( const osg::Node &node );
|
||||
@@ -240,6 +240,13 @@ private: //members
|
||||
|
||||
/** provide an unique name */
|
||||
std::string uniquify( const std::string &name );
|
||||
|
||||
/** work in Google compatibility mode */
|
||||
bool m_GoogleMode;
|
||||
|
||||
/** Current RenderingHint */
|
||||
/** This are needed because the stateSet merge code currently does not handle it */
|
||||
int m_CurrentRenderingHint;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user