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,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);