From Mattias Linde, "Have made the updates now. Added a std::map for easy lookup if a visual node

is targeted by a rigid body which is the reason why the .h-file was changed too.
So now there'll be Group as often as possible, otherwise PostitionAttitudeTransform."
This commit is contained in:
Robert Osfield
2007-09-07 09:49:31 +00:00
parent 14b0ef597b
commit b13a1957b0
2 changed files with 111 additions and 24 deletions

View File

@@ -15,6 +15,7 @@
#include <dae.h>
#include <dom/domCOLLADA.h>
#include <dom/domInstanceWithExtra.h>
#include <dom/domConstants.h>
using namespace osgdae;
@@ -34,6 +35,12 @@ daeReader::~daeReader()
bool daeReader::convert( const std::string &fileURI )
{
daeElement *colladaElement;
domInstance_rigid_body *irb;
daeInt count, result;
std::string fURI;
if ( fileURI[1] == ':' )
{
@@ -76,6 +83,25 @@ bool daeReader::convert( const std::string &fileURI )
}
}
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++) {
result = dae->getDatabase()->getElement(&colladaElement, i, NULL, COLLADA_TYPE_INSTANCE_RIGID_BODY);
if (result == DAE_OK) {
irb = daeSafeCast<domInstance_rigid_body>(colladaElement);
if (irb) {
domNode *node = daeSafeCast<domNode>(irb->getTarget().getElement());
if (node && node->getId()) {
_targetMap[ std::string(node->getId()) ] = true;
}
}
}
}
}
domInstanceWithExtra *ivs = document->getScene()->getInstance_visual_scene();
domVisual_scene *vs = daeSafeCast< domVisual_scene >( getElementFromURI( ivs->getUrl() ) );
@@ -130,11 +156,92 @@ osg::Node* daeReader::processVisualScene( domVisual_scene *scene )
osg::Node* daeReader::processNode( domNode *node )
{
osg::Node *retVal = new osg::Group();
osg::Node *retVal;
osg::PositionAttitudeTransform *pat;
int patcount = node->getRotate_array().getCount() +
node->getScale_array().getCount() +
node->getTranslate_array().getCount();
bool targeted = false;
if (node->getId()) {
targeted = _targetMap[std::string(node->getId())];
}
if (patcount > 0 || targeted )
{
pat = new osg::PositionAttitudeTransform();
retVal = pat;
}
else
{
retVal = new osg::Group();
}
osg::Node *current = retVal;
retVal->setName( node->getId() ? node->getId() : "" );
// Handle rotate, translate and scale first..
// will make the hierarchy less deep
// <rotate>
osg::Quat osgRot;
for (int i=0; i<node->getRotate_array().getCount(); i++)
{
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 (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 (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++ )
{
@@ -142,41 +249,19 @@ osg::Node* daeReader::processNode( domNode *node )
//I'm using daeSafeCast to check type because the pointer comparisons are a lot faster
//than a strcmp
//TODO: I am doing transforms wrong. A Transform is itself a group node. They need to be
//consolodated and then the children of the collada node need to be the children of the
//transform node.
domTranslate * t = daeSafeCast< domTranslate >( node->getContents()[i] );
if ( t != NULL )
{
trans = processTranslate( t );
if ( trans != NULL )
{
current->asGroup()->addChild( trans );
current = trans;
}
continue;
}
domRotate * r = daeSafeCast< domRotate >( node->getContents()[i] );
if ( r != NULL ) {
trans = processRotate( r );
if ( trans != NULL )
{
current->asGroup()->addChild( trans );
current = trans;
}
continue;
}
domScale * s = daeSafeCast< domScale >( node->getContents()[i] );
if ( s != NULL ) {
trans = processScale( s );
if ( trans != NULL )
{
current->asGroup()->addChild( trans );
current = trans;
}
continue;
}
@@ -202,7 +287,7 @@ osg::Node* daeReader::processNode( domNode *node )
continue;
}
domInstance_geometry *ig = daeSafeCast< domInstance_geometry >( node->getContents()[i] );
domInstance_geometry *ig = daeSafeCast< domInstance_geometry >( node->getContents()[i] );
if ( ig != NULL )
{
trans = processInstance_geometry( ig );

View File

@@ -160,6 +160,8 @@ protected:
DAE *dae;
osg::Node* rootNode;
std::map<std::string,bool> _targetMap;
int m_numlights;
domEffect *currentEffect;