From Brede Johansen, support for contiuation records.

This commit is contained in:
Robert Osfield 2008-01-04 11:26:21 +00:00
parent 6231c3a5a4
commit 8d5d543600
9 changed files with 168 additions and 167 deletions

View File

@ -38,7 +38,7 @@ class PushLevel : public Record
META_Record(PushLevel)
virtual void read(RecordInputStream& /*in*/, Document& document)
virtual void readRecord(RecordInputStream& /*in*/, Document& document)
{
document.pushLevel();
}
@ -63,6 +63,13 @@ class PopLevel : public Record
virtual void read(RecordInputStream& /*in*/, Document& document)
{
// Finally call dispose() for primary with push, pop level pair.
PrimaryRecord* primary = document.getTopOfLevelStack();
if (primary)
{
primary->dispose(document);
}
document.popLevel();
}
@ -181,9 +188,6 @@ class PushAttribute : public Record
virtual void read(RecordInputStream& in, Document& document)
{
readRecord(in,document);
// in().seekg(in.getEndOfRecord(), std::ios_base::beg);
// loop until PopAttribute
}
protected:

View File

@ -46,45 +46,37 @@ Document::Document() :
{
}
Document::~Document()
{
}
void Document::pushLevel()
{
_levelStack.push_back(_currentPrimaryRecord.get());
_levelStack.back()->pushLevel(*this);
_level++;
}
void Document::popLevel()
{
_levelStack.back()->popLevel(*this);
_levelStack.pop_back();
if (!_levelStack.empty())
_currentPrimaryRecord = _levelStack.back().get();
_currentPrimaryRecord = _levelStack.back();
if (--_level<=0)
_done = true;
}
void Document::pushSubface()
{
_subfaceLevel++;
}
void Document::popSubface()
{
_subfaceLevel--;
}
void Document::pushExtension()
{
if (!_currentPrimaryRecord.valid())
@ -96,7 +88,6 @@ void Document::pushExtension()
_extensionStack.push_back(_currentPrimaryRecord.get());
}
void Document::popExtension()
{
_currentPrimaryRecord=_extensionStack.back().get();
@ -109,7 +100,6 @@ void Document::popExtension()
_extensionStack.pop_back();
}
osg::Node* Document::getInstanceDefinition(int no)
{
InstanceDefinitionMap::iterator itr = _instanceDefinitionMap.find(no);
@ -119,7 +109,6 @@ osg::Node* Document::getInstanceDefinition(int no)
return NULL;
}
double flt::unitsToMeters(CoordUnits unit)
{
switch (unit)

View File

@ -96,7 +96,7 @@ class Document
const osgDB::ReaderWriter::Options* getOptions() const { return _options.get(); }
// Current primar record
void setCurrentPrimaryRecord(PrimaryRecord* record) {_currentPrimaryRecord=record; }
void setCurrentPrimaryRecord(PrimaryRecord* record) { _currentPrimaryRecord=record; }
PrimaryRecord* getCurrentPrimaryRecord() { return _currentPrimaryRecord.get(); }
const PrimaryRecord* getCurrentPrimaryRecord() const { return _currentPrimaryRecord.get(); }
@ -113,7 +113,6 @@ class Document
void pushExtension();
void popExtension();
void setHeaderNode(osg::Node* node) { _osgHeader = node; }
osg::Node* getHeaderNode() { return _osgHeader.get(); }

View File

@ -72,7 +72,6 @@ public:
META_setID(_geode)
META_setComment(_geode)
META_setMatrix(_geode)
META_setMultitexture(_geode)
// draw mode
@ -434,10 +433,17 @@ protected:
return osg::PrimitiveSet::POLYGON;
}
virtual void popLevel(Document& document)
virtual void dispose(Document& document)
{
if (_geode.valid())
{
// Insert transform(s)
if (_matrix.valid())
{
insertMatrixTransform(*_geode,*_matrix,_numberOfReplications);
}
// Add primitives, set bindings etc.
for (unsigned int i=0; i<_geode->getNumDrawables(); ++i)
{
osg::Geometry* geometry = dynamic_cast<osg::Geometry*>(_geode->getDrawable(i));
@ -728,7 +734,6 @@ public:
META_setID(_geode)
META_setComment(_geode)
META_setMatrix(_geode)
META_setMultitexture(_geode)
// draw mode
@ -964,10 +969,16 @@ protected:
_parent->addChild(*_geode);
}
virtual void popLevel(Document& document)
virtual void dispose(Document& document)
{
if (_geode.valid())
{
// Insert transform(s)
if (_matrix.valid())
{
insertMatrixTransform(*_geode,*_matrix,_numberOfReplications);
}
osg::StateSet* stateset = _geode->getOrCreateStateSet();
// Translucent image?

View File

@ -113,7 +113,7 @@ public:
META_setID(_lpn)
META_setComment(_lpn)
META_setMatrix(_lpn)
META_dispose(_lpn)
// Add lightpoint, add two if bidirectional.
virtual void addVertex(Vertex& vertex)
@ -263,7 +263,7 @@ public:
META_setID(_lpn)
META_setComment(_lpn)
META_setMatrix(_lpn)
META_dispose(_lpn)
// Add lightpoint, add two if bidirectional.
virtual void addVertex(Vertex& vertex)
@ -481,8 +481,16 @@ protected:
_parent->addChild(*((osg::Group*)_switch.get()));
}
virtual void popLevel(Document& document)
virtual void dispose(Document& document)
{
if (!_switch.valid()) return;
// Insert transform(s)
if (_matrix.valid())
{
insertMatrixTransform(*_switch,*_matrix,_numberOfReplications);
}
// Set default sets: 0 for all off, 1 for all on
_switch->setAllChildrenOff( 0 );
_switch->setAllChildrenOn( 1 );

View File

@ -54,7 +54,6 @@ public:
META_setID(_header)
META_setComment(_header)
// META_setMatrix(_header)
META_setMultitexture(_header)
META_addChild(_header)
@ -132,7 +131,7 @@ protected:
document.setHeaderNode(_header.get());
}
virtual void popLevel(Document& document)
virtual void dispose(Document& document)
{
if (_header.valid())
{
@ -186,7 +185,6 @@ public:
META_setID(_group)
META_setComment(_group)
META_setMatrix(_group)
META_setMultitexture(_group)
META_addChild(_group)
@ -236,8 +234,16 @@ protected:
_parent->addChild(*_group);
}
virtual void popLevel(Document& document)
virtual void dispose(Document& document)
{
if (!_group.valid()) return;
// Insert transform(s)
if (_matrix.valid())
{
insertMatrixTransform(*_group,*_matrix,_numberOfReplications);
}
// Children are added!
osg::Sequence* sequence = dynamic_cast<osg::Sequence*>(_group.get());
if (sequence && sequence->getNumChildren() > 0)
@ -318,14 +324,13 @@ public:
META_setID(_dof)
META_setComment(_dof)
META_setMatrix(_dof)
META_setMultitexture(_dof)
META_addChild(_dof)
META_dispose(_dof)
protected:
virtual ~DegreeOfFreedom() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
std::string id = in.readString(8);
@ -453,14 +458,13 @@ public:
META_setID(_lod)
META_setComment(_lod)
META_setMatrix(_lod)
META_setMultitexture(_lod)
META_addChild(_impChild0)
META_dispose(_lod)
protected:
virtual ~LevelOfDetail() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
std::string id = in.readString(8);
@ -509,14 +513,13 @@ public:
META_setID(_lod)
META_setComment(_lod)
META_setMatrix(_lod)
META_setMultitexture(_lod)
META_addChild(_impChild0)
META_dispose(_lod)
protected:
virtual ~OldLevelOfDetail() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
std::string id = in.readString(8);
@ -570,8 +573,8 @@ public:
META_setID(_multiSwitch)
META_setComment(_multiSwitch)
META_setMatrix(_multiSwitch)
META_setMultitexture(_multiSwitch)
META_dispose(_multiSwitch)
virtual void addChild(osg::Node& child)
{
@ -593,7 +596,6 @@ public:
protected:
virtual ~Switch() {}
virtual void readRecord(RecordInputStream& in, Document& /*document*/)
{
std::string id = in.readString(8);
@ -652,14 +654,13 @@ public:
META_setID(_external)
META_setComment(_external)
META_setMatrix(_external)
META_setMultitexture(_external)
META_addChild(_external)
META_dispose(_external)
protected:
virtual ~ExternalReference() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
std::string strFile = in.readString(200);
@ -717,11 +718,12 @@ RegisterRecordProxy<ExternalReference> g_ExternalReference(EXTERNAL_REFERENCE_OP
*/
class InstanceDefinition : public PrimaryRecord
{
int _number;
osg::ref_ptr<osg::Group> _instanceDefinition;
public:
InstanceDefinition() {}
InstanceDefinition():_number(0) {}
META_Record(InstanceDefinition)
@ -730,28 +732,32 @@ public:
META_setMultitexture(_instanceDefinition)
META_addChild(_instanceDefinition)
virtual void setMatrix(osg::Matrix& matrix)
{
osg::ref_ptr<osg::MatrixTransform> transform = new osg::MatrixTransform(matrix);
transform->setDataVariance(osg::Object::STATIC);
transform->addChild(_instanceDefinition.get());
_instanceDefinition = transform.get();
}
protected:
virtual ~InstanceDefinition() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
in.forward(2);
uint16 number = in.readUInt16();
_number = (int)in.readUInt16();
_instanceDefinition = new osg::Group;
}
virtual void dispose(Document& document)
{
// Insert transform(s)
if (_matrix.valid())
{
osg::ref_ptr<osg::MatrixTransform> transform = new osg::MatrixTransform(*_matrix);
transform->setDataVariance(osg::Object::STATIC);
transform->addChild(_instanceDefinition.get());
_instanceDefinition = transform.get();
}
// Add to instance definition table.
document.setInstanceDefinition(number,_instanceDefinition.get());
document.setInstanceDefinition(_number,_instanceDefinition.get());
}
};
RegisterRecordProxy<InstanceDefinition> g_InstanceDefinition(INSTANCE_DEFINITION_OP);
@ -771,7 +777,6 @@ public:
protected:
virtual ~InstanceReference() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
in.forward(2);
@ -781,7 +786,7 @@ protected:
osg::Node* instance = document.getInstanceDefinition(number);
// Add this implementation to parent implementation.
if (_parent.valid())
if (_parent.valid() && instance)
_parent->addChild(*instance);
}
};
@ -803,14 +808,13 @@ public:
META_setID(_extension)
META_setComment(_extension)
META_setMatrix(_extension)
META_setMultitexture(_extension)
META_addChild(_extension)
META_dispose(_extension)
protected:
virtual ~Extension() {}
virtual void readRecord(RecordInputStream& in, Document& /*document*/)
{
std::string id = in.readString(8);
@ -850,85 +854,68 @@ public:
META_setID(_object)
META_setComment(_object)
virtual void setMatrix(osg::Matrix& matrix)
{
if (_object.valid())
insertMatrixTransform(*_object,matrix);
else
{
_object = new osg::MatrixTransform(matrix);
_object->setDataVariance(osg::Object::STATIC);
if (_parent.valid())
_parent->addChild(*_object);
}
}
virtual void addChild(osg::Node& child)
{
// If object excists it means it is preserved.
if (_object.valid())
_object->addChild(&child);
// If no object add child to parent.
else if (_parent.valid())
_parent->addChild(child);
}
META_addChild(_object)
protected:
virtual ~Object() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
// Is it safe to remove the object?
if (!document.getPreserveObject())
{
// The following tests need a valid parent.
if (!_parent.valid())
return;
std::string id = in.readString(8);
/*uint32 flags =*/ in.readUInt32();
_object = new osg::Group;
_object->setName(id);
// Postpone add-to-parent until we know a bit more.
}
virtual void dispose(Document& document)
{
if (!_parent.valid() || !_object.valid()) return;
// Is it safe to remove _object?
if (!document.getPreserveObject() && isSafeToRemoveObject() && !_matrix.valid())
{
// Add children of _object to parent.
// _object will not be added to graph.
for (unsigned int i=0; i<_object->getNumChildren(); ++i)
{
_parent->addChild(*(_object->getChild(i)));
}
}
else
{
_parent->addChild(*_object);
}
// Insert transform(s)
if (_matrix.valid())
{
insertMatrixTransform(*_object,*_matrix,_numberOfReplications);
}
}
bool isSafeToRemoveObject() const
{
// The following tests need a valid parent.
if (_parent.valid())
{
// LODs adds an empty child group so it is safe to remove this object record.
if (typeid(*_parent)==typeid(flt::LevelOfDetail))
return;
return true;
if (typeid(*_parent)==typeid(flt::OldLevelOfDetail))
return;
return true;
// If parent is a Group record we have to check for animation.
Group* parentGroup = dynamic_cast<flt::Group*>(_parent.get());
if (parentGroup && !parentGroup->hasAnimation())
return;
return true;
}
std::string id = in.readString(8);
_object = new osg::Group;
_object->setName(id);
#if 1
/*uint32 flags =*/ in.readUInt32();
#else
// The Object "Flat Shaded" checkbox in Creator is used by the "Calculate Shading" operation,
// it is not a flat shaded state attribute.
uint32 flags = in.readUInt32();
// Flat shaded?
if (flags & FLAT_SHADED)
{
static osg::ref_ptr<osg::ShadeModel> shademodel;
if (!shademodel.valid())
{
shademodel = new osg::ShadeModel;
shademodel->setMode(osg::ShadeModel::FLAT);
}
_object->getOrCreateStateSet()->setAttribute(shademodel.get());
}
#endif
if (_parent.valid())
_parent->addChild(*_object);
return false;
}
};
RegisterRecordProxy<Object> g_Object(OBJECT_OP);
@ -952,12 +939,11 @@ public:
META_setID(_lightSource)
META_setComment(_lightSource)
META_setMatrix(_lightSource)
META_dispose(_lightSource)
protected:
virtual ~LightSource() {}
virtual void readRecord(RecordInputStream& in, Document& document)
{
std::string id = in.readString(8);

View File

@ -30,51 +30,39 @@ Record::Record()
{
}
Record::~Record()
{
}
void Record::setParent(PrimaryRecord* parent)
{
_parent = parent;
}
//PrimaryRecord& Record::parent()
//{
// if (!_parent)
// throw std::runtime_error("Record::parent(): invalid pointer to parent exception.");
//
// return *_parent;
//}
void Record::read(RecordInputStream& in, Document& document)
{
setParent(document.getCurrentPrimaryRecord());
_parent = document.getCurrentPrimaryRecord();
// Read record body.
readRecord(in,document);
}
void Record::readRecord(RecordInputStream& /*in*/, Document& /*document*/)
{
}
PrimaryRecord::PrimaryRecord() :
_numberOfReplications(0)
{
}
void PrimaryRecord::read(RecordInputStream& in, Document& document)
{
setParent(document.getTopOfLevelStack());
PrimaryRecord* parentPrimary = document.getTopOfLevelStack();
PrimaryRecord* currentPrimary = document.getCurrentPrimaryRecord();
// Update primary record.
// Finally call dispose() for primary without push, pop level pair.
if (currentPrimary && currentPrimary!=parentPrimary)
{
currentPrimary->dispose(document);
}
// Update current primary record.
document.setCurrentPrimaryRecord(this);
_parent = parentPrimary;
// Read record body.
readRecord(in,document);
}
@ -82,27 +70,47 @@ void PrimaryRecord::read(RecordInputStream& in, Document& document)
///////////////////////////////////////////////////////////////////////////////////
// Helper methods
// Insert matrix-tranform above node.
// Return transform.
osg::ref_ptr<osg::MatrixTransform> flt::insertMatrixTransform(osg::Node& node, const osg::Matrix& matrix)
// Insert matrix-tranform(s)
//
// node: node to apply transform
// matrix: transformation matrix
// numberOfReplications: zero for regular transform, number of copies if replication is used.
void flt::insertMatrixTransform(osg::Node& node, const osg::Matrix& matrix, int numberOfReplications)
{
osg::ref_ptr<osg::Node> ref = &node;
osg::ref_ptr<osg::MatrixTransform> transform = new osg::MatrixTransform(matrix);
transform->setDataVariance(osg::Object::STATIC);
// Replace parent
osg::Node::ParentList parents = node.getParents();
// Disconnect node from parents.
for (osg::Node::ParentList::iterator itr=parents.begin();
itr!=parents.end();
++itr)
{
(*itr)->replaceChild(&node,transform.get());
(*itr)->removeChild(&node);
}
// Make primary a child of matrix transform.
transform->addChild(&node);
// Start without transformation if replication.
osg::Matrix accumulatedMatrix = (numberOfReplications > 0)? osg::Matrix::identity() : matrix;
return transform;
for (int n=0; n<=numberOfReplications; n++)
{
// Accumulate transformation for each replication.
osg::ref_ptr<osg::MatrixTransform> transform = new osg::MatrixTransform(accumulatedMatrix);
transform->setDataVariance(osg::Object::STATIC);
// Add transform to parents
for (osg::Node::ParentList::iterator itr=parents.begin();
itr!=parents.end();
++itr)
{
(*itr)->addChild(transform.get());
}
// Make primary a child of matrix transform.
transform->addChild(&node);
// Accumulate transform if multiple replications.
accumulatedMatrix *= matrix;
}
}

View File

@ -42,10 +42,9 @@ class Matrix;
virtual bool isSameKindAs(const flt::Record* rec) const { return dynamic_cast<const name *>(rec)!=NULL; }
#define META_setID(imp) virtual void setID(const std::string& id) { if (imp.valid()) imp->setName(id); }
#define META_setComment(imp) virtual void setComment(const std::string& id) { if (imp.valid()) imp->addDescription(id); }
#define META_setMatrix(imp) virtual void setMatrix(osg::Matrix& matrix) { if (imp.valid()) insertMatrixTransform(*imp,matrix); }
#define META_setMultitexture(imp) virtual void setMultitexture(osg::StateSet& multitexture) { if (imp.valid()) imp->getOrCreateStateSet()->merge(multitexture); }
#define META_addChild(imp) virtual void addChild(osg::Node& child) { if (imp.valid()) imp->addChild(&child); }
#define META_dispose(imp) virtual void dispose(Document&) { if (imp.valid() && _matrix.valid()) insertMatrixTransform(*imp,*_matrix,_numberOfReplications); }
// pure virtual base class
class Record : public osg::Referenced
@ -62,7 +61,7 @@ public:
protected:
virtual ~Record();
virtual ~Record() {}
virtual void readRecord(RecordInputStream& in, Document& document);
@ -77,13 +76,11 @@ public:
PrimaryRecord();
virtual void read(RecordInputStream& in, Document& document);
virtual void pushLevel(Document& /*document*/) {}
virtual void popLevel(Document& /*document*/) {}
virtual void dispose(Document& /*document*/) {}
// Ancillary operations
virtual void setID(const std::string& /*id*/) {}
virtual void setComment(const std::string& /*comment*/) {}
virtual void setMatrix(osg::Matrix& /*matrix*/) {}
virtual void setMultitexture(osg::StateSet& /*multitexture*/) {}
virtual void addChild(osg::Node& /*child*/) {}
virtual void addVertex(Vertex& /*vertex*/) {}
@ -91,6 +88,7 @@ public:
virtual void addMorphVertex(Vertex& /*vertex0*/, Vertex& /*vertex100*/) {}
void setNumberOfReplications(int num) { _numberOfReplications = num; }
void setMatrix(const osg::Matrix& matrix) { _matrix = new osg::RefMatrix(matrix); }
void setLocalVertexPool(VertexList* pool) { _localVertexPool = pool; }
VertexList* getLocalVertexPool() { return _localVertexPool.get(); }
@ -100,6 +98,7 @@ protected:
virtual ~PrimaryRecord() {}
int _numberOfReplications;
osg::ref_ptr<osg::RefMatrix> _matrix;
osg::ref_ptr<VertexList> _localVertexPool;
};
@ -120,7 +119,7 @@ class DummyRecord : public Record
};
osg::ref_ptr<osg::MatrixTransform> insertMatrixTransform(osg::Node& node, const osg::Matrix& matrix);
void insertMatrixTransform(osg::Node& node, const osg::Matrix& matrix, int numberOfReplications);
osg::Vec3Array* getOrCreateVertexArray(osg::Geometry& geometry);
osg::Vec3Array* getOrCreateNormalArray(osg::Geometry& geometry);

View File

@ -40,14 +40,13 @@ class RoadSegment : public PrimaryRecord
META_setID(_roadSegment)
META_setComment(_roadSegment)
META_setMatrix(_roadSegment)
META_setMultitexture(_roadSegment)
META_addChild(_roadSegment)
META_dispose(_roadSegment)
protected:
virtual ~RoadSegment() {}
virtual void readRecord(RecordInputStream& in, Document& /*document*/)
{
_roadSegment = new osg::Group;
@ -78,14 +77,13 @@ class RoadConstruction : public PrimaryRecord
META_setID(_roadConstruction)
META_setComment(_roadConstruction)
META_setMatrix(_roadConstruction)
META_setMultitexture(_roadConstruction)
META_addChild(_roadConstruction)
META_dispose(_roadConstruction)
protected:
virtual ~RoadConstruction() {}
virtual void readRecord(RecordInputStream& in, Document& /*document*/)
{
_roadConstruction = new osg::Group;
@ -117,14 +115,13 @@ class RoadPath : public PrimaryRecord
META_setID(_roadPath)
META_setComment(_roadPath)
META_setMatrix(_roadPath)
META_setMultitexture(_roadPath)
META_addChild(_roadPath)
META_dispose(_roadPath)
protected:
virtual ~RoadPath() {}
virtual void readRecord(RecordInputStream& /*in*/, Document& /*document*/)
{
_roadPath = new osg::Group;