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

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

View File

@@ -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;
}