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