/*! Visits a SFFieldContainerPtr (or more specific pointer type) during preWrite. It creates an element for the pointed to container and calls preWrite on it. If the pointed to container is not in the root's id set it is added and thus scheduled for writing. \param[in] fieldId Id of the field in the container of this element. */ void OSBCommonElement::preWritePtrSingleField(const UInt32 fieldId) { OSG_OSB_LOG(("OSBCommonElement::preWritePtrSingleField: " "fieldId: [%u]\n", fieldId)); OSBRootElement *root = editRoot(); FieldContainerPtrSFieldBase::GetHandlePtr sfPtrField = boost::dynamic_pointer_cast<FieldContainerPtrSFieldBase::GetHandle>( getContainer()->getField(fieldId)); if(sfPtrField == NULL || sfPtrField->isValid() == false) return; FieldContainer *refedFC = (*sfPtrField)->getValue(); if(refedFC == NULL) return; UInt32 refedId = refedFC->getId (); const std::string &typeName = refedFC->getType().getName(); // only schedule a container once if(root->getIdSet().count(refedId) == 0) { OSBElementBase *elem = OSBElementFactory::the()->acquire( typeName, root); root->editIdSet ().insert (refedId); root->editElementList().push_back(elem ); elem->setContainer(refedFC); elem->preWrite (refedFC); } }
/*! Reads a MFFieldContainerPtr (or a more specific pointer type) from the stream. It has the given \a fieldId in the container it belongs to. \param[in] fieldId Id of the field in the container it belongs to. \param[in] fieldSize field size \return Iterator that points to the PtrFieldInfo structure that was created for this field. */ OSBCommonElement::PtrFieldListIt OSBCommonElement::readPtrMultiField( const UInt32 fieldId, const UInt32 fieldSize) { OSG_OSB_LOG(("OSBCommonElement::readPtrMultiField: " "fieldId: [%u]\n", fieldId)); UInt32 ptrId; UInt32 numElements; OSBRootElement *root = editRoot(); BinaryReadHandler *rh = editRoot()->getReadHandler(); root->editPtrFieldList().push_back(PtrFieldInfo(getContainer(), fieldId)); PtrFieldInfo &pfi = root->editPtrFieldList().back(); rh->getValue(numElements); OSG_OSB_LOG(("OSBCommonElement::readPtrMultiField: ptrIds [")); for(UInt32 i = 0; i < numElements; ++i) { rh->getValue(ptrId); pfi.editIdStore().push_back(ptrId); OSG_OSB_PLOG(("%u ", ptrId)); } OSG_OSB_PLOG(("]\n")); return --(root->editPtrFieldList().end()); }
/*! Callback called for each element in an AttachmentMap (this is used by preWriteAttachmentMapField). */ void OSBCommonElement::handleAttachmentMapElementPreWrite( FieldContainer *refedFC) { OSG_OSB_LOG(("OSBCommonElement::handleAttachmentMapElementPreWrite\n")); if(refedFC == NULL) return; Attachment *refedAtt = dynamic_cast<Attachment *>(refedFC); // skip attachments marked as 'internal' if(refedAtt == NULL || refedAtt->getSFInternal()->getValue() == true ) { return; } OSBRootElement *root = editRoot(); UInt32 refedId = refedAtt->getId (); const std::string &typeName = refedAtt->getType().getName(); // only schedule a container once if(root->getIdSet().count(refedId) > 0) return; OSBElementBase *elem = OSBElementFactory::the()->acquire(typeName, root); root->editIdSet ().insert (refedId); root->editElementList().push_back(elem ); elem->setContainer(refedAtt); elem->preWrite (refedAtt); }
/*! Reads a SFFieldContainerPtr (or a more specific pointer type) from the stream. It has the given \a fieldId in the container it belongs to. \param[in] fieldId Id of the field in the container it belongs to. \return Iterator that points to the PtrFieldInfo structure that was created for this field. */ OSBCommonElement::PtrFieldListIt OSBCommonElement::readPtrSingleField(const UInt32 fieldId) { OSG_OSB_LOG(("OSBCommonElement::readPtrSingleField: " "fieldId: [%u]\n", fieldId)); OSBRootElement *root = editRoot(); UInt32 ptrId; root->getReadHandler()->getValue(ptrId); OSG_OSB_LOG(("OSBCommonElement::readPtrSingleField: ptrId [%u]\n", ptrId)); root->editPtrFieldList().push_back(PtrFieldInfo(getContainer(), fieldId)); root->editPtrFieldList().back().editIdStore().push_back(ptrId); return --(root->editPtrFieldList().end()); }
/*! Visits a MFFieldContainerPtr (or more specific pointer type) during preWrite. It creates elements for the pointed to containers and calls preWrite on them. If the pointed to containers are not in the root's id set they are added and thus scheduled for writing. \param[in] fieldId Id of the field in the container of this element. */ void OSBCommonElement::preWritePtrMultiField(const UInt32 fieldId) { OSG_OSB_LOG(("OSBCommonElement::preWritePtrMultiField: " "fieldId: [%u]\n", fieldId)); OSBRootElement *root = editRoot(); FieldContainerPtrMFieldBase::GetHandlePtr mfPtrField = boost::dynamic_pointer_cast<FieldContainerPtrMFieldBase::GetHandle>( getContainer()->getField(fieldId)); if(mfPtrField == NULL || mfPtrField->isValid() == false) return; FieldContainerPtrMFieldBase::const_iterator fieldIt = (*mfPtrField)->begin(); FieldContainerPtrMFieldBase::const_iterator fieldEnd = (*mfPtrField)->end (); for(; fieldIt != fieldEnd; ++fieldIt) { FieldContainer *refedFC = *fieldIt; if(refedFC == NULL) continue; UInt32 refedId = refedFC->getId (); const std::string &typeName = refedFC->getType().getName(); // only schedule a container once if(root->getIdSet().count(refedId) > 0) continue; OSBElementBase *elem = OSBElementFactory::the()->acquire( typeName, root); root->editIdSet ().insert (refedId); root->editElementList().push_back(elem ); elem->setContainer(refedFC); elem->preWrite (refedFC); } }
/*! Callback called for each element in a map field (this is used by preWriteMapField). */ void OSBCommonElement::handleMapElementPreWrite(FieldContainer *refedFC) { if(refedFC == NULL) return; OSBRootElement *root = editRoot(); UInt32 refedId = refedFC->getId (); const std::string &typeName = refedFC->getType().getName(); // only schedule a container once if(root->getIdSet().count(refedId) > 0) return; OSBElementBase *elem = OSBElementFactory::the()->acquire(typeName, root); root->editIdSet ().insert (refedId); root->editElementList().push_back(elem ); elem->setContainer(refedFC); elem->preWrite (refedFC); }
/*! Reads from \a inStream which must provide access to an ".osb" file. \param[in] inStream Stream to read data from. \param[in] optionStr String that holds the options for the read operation. \return On success a pointer to the container read from the file. NULL otherwise. */ FieldContainerTransitPtr OSBDriver::readFC( std::istream &inStream, const IOFileTypeBase::OptionSet &options ) { FieldContainerTransitPtr retVal; OSBRootElement *root = dynamic_cast<OSBRootElement *>( OSBElementFactory::the()->acquire("RootElement", 0)); root->initialiseRead(inStream); root->editOptions ( ).init(options); root->read (""); root->postRead( ); retVal = root->getContainer(); root->terminateRead(); OSBElementFactory::the()->release(root); return retVal; }
bool OSBDriver::writeFC( FieldContainer * const fc, std::ostream &outStream, const IOFileTypeBase::OptionSet &options ) { OSBRootElement *root = dynamic_cast<OSBRootElement *>( OSBElementFactory::the()->acquire("RootElement", 0)); root->initialiseWrite(outStream); root->editOptions ( ).init(options); root->preWrite(fc); root->write ( ); root->terminateWrite(); OSBElementFactory::the()->release(root); return true; }
void OSBTextureChunkElement::postRead(void) { OSG_OSB_LOG(("OSBTextureChunkElement::postRead:\n")); OSBRootElement *pRoot = editRoot(); // for the id remapping TexEnv needs an id that is not used in the file UInt32 texEnvIdFile = pRoot->getIdMap().rbegin()->first; while(pRoot->getIdMap().find(texEnvIdFile) != pRoot->getIdMap().end()) { ++texEnvIdFile; } // add mapping entry for TexEnv pRoot->editIdMap()[texEnvIdFile] = _pTexEnv->getId(); PtrFieldListIt ptrFieldIt = pRoot->editPtrFieldList().begin(); PtrFieldListIt ptrFieldEnd = pRoot->editPtrFieldList().end (); for(; ptrFieldIt != ptrFieldEnd; ++ptrFieldIt) { ChunkMaterial *chkMat = dynamic_cast<ChunkMaterial *>(ptrFieldIt->getContainer()); if(chkMat != NULL) { // OSBChunkMaterialElement takes care of handling the two chunks // replacing TextureChunk continue; } else { UInt32 numIds = ptrFieldIt->getIdStore ().size(); UInt32 numBind = ptrFieldIt->getBindingStore().size(); if(numBind > 0) { // TextureChunk is pointed to from an attachment map for(UInt32 i = 0; (i < numIds) && (i < numBind); ++i) { if(ptrFieldIt->getIdStore()[i] == getFCIdFile()) { // insert a pointer to TexEnv right after the TexObj ptrFieldIt->editIdStore().insert( ptrFieldIt->editIdStore().begin() + i + 1, texEnvIdFile ); // duplicate the binding of the TexObj ptrFieldIt->editBindingStore().insert( ptrFieldIt->editBindingStore().begin() + i + 1, ptrFieldIt->getBindingStore()[i] ); ++numIds; ++numBind; } } } else { for(UInt32 i = 0; i < numIds; ++i) { if(ptrFieldIt->getIdStore()[i] == getFCIdFile()) { // insert a pointer to TexEnv right after the TexObj ptrFieldIt->editIdStore().insert( ptrFieldIt->editIdStore().begin() + i + 1, texEnvIdFile ); ++numIds; } } } } } }
void OSBGeometryElement::postReadV100(void) { OSG_OSB_LOG(("OSBGeometryElement::postReadV100\n")); OSBRootElement *root = editRoot(); Geometry *geo = dynamic_cast<Geometry*>(getContainer()); UInt32 indexMappingSize = UInt32(_indexMapping.size()); if(indexMappingSize <= 1) { OSG_OSB_LOG(("OSBGeometryElement::postReadV100: " "Converting single index.\n" )); if(_indicesPacked) { OSG_OSB_LOG(("OSBGeometryElement::postReadV100: " "Converting packed indices.\n" )); geo->setIndices(_indices); } else { OSG_OSB_LOG(("OSBGeometryElement::postReadV100: " "Converting non-packed indices.\n" )); // indices stored in container with id _indicesId // create PtrFieldInfo structure to set all entries of field // "propIndices" to the container with id _indicesId FieldDescriptionBase *indFieldDesc = geo->getFieldDescription("propIndices"); UInt32 indFieldId = indFieldDesc->getFieldId(); root->editPtrFieldList().push_back(PtrFieldInfo(geo, indFieldId)); PtrFieldInfo &indFieldPFI = root->editPtrFieldList().back(); for(UInt32 i = 0; i < Geometry::MaxAttribs; ++i) { indFieldPFI.editIdStore().push_back(_indicesId); } } } else { OSG_OSB_LOG(("OSBGeometryElement::postReadV100: " "Converting multi index.\n" )); OSBGeometryHelper gh; if(_indicesPacked) { OSG_OSB_LOG(("OSBGeometryElement::postReadV100: " "Converting packed indices.\n" )); // create 16 bit or 32 bit indices if(_indices16Bit) { GeoUInt16Property *ui16Indices = dynamic_pointer_cast<GeoUInt16Property>(_indices); gh.splitMultiIndex<GeoUInt16Property *>( _indexMapping, ui16Indices, geo); } else { GeoUInt32Property *ui32Indices = dynamic_pointer_cast<GeoUInt32Property>(_indices); gh.splitMultiIndex<GeoUInt32Property *>( _indexMapping, ui32Indices, geo); } } else { OSG_OSB_LOG(("OSBGeometryElement::postReadV100: " "Converting non-packed indices.\n" )); FieldContainerIdMapConstIt mapIt = root->getIdMap().find(_indicesId); if(mapIt != root->getIdMap().end()) { _indices = dynamic_cast<GeoIntegralProperty *>( FieldContainerFactory::the()->getContainer(mapIt->second)); } else { FWARNING(("OSBGeometryElement::postReadV100: " "Could not find indices property.\n")); return; } if(_indices->getFormatSize() == sizeof(UInt16)) { GeoUInt16Property *ui16Indices = dynamic_pointer_cast<GeoUInt16Property>(_indices); gh.splitMultiIndex<GeoUInt16Property *>( _indexMapping, ui16Indices, geo); } else if(_indices->getFormatSize() == sizeof(UInt32)) { GeoUInt32Property *ui32Indices = dynamic_pointer_cast<GeoUInt32Property>(_indices); gh.splitMultiIndex<GeoUInt32Property *>( _indexMapping, ui32Indices, geo); } } } }
void OSBGeometryElement::readV100(void) { OSG_OSB_LOG(("OSBGeometryElement::readV100:\n")); OSBRootElement *root = editRoot(); BinaryReadHandler *rh = editRoot()->getReadHandler(); OSBGeometryHelper gh; GeometryUnrecPtr geo = Geometry::create(); setContainer(geo); // The "properties" mfield can be thought of the unification of the // "positions", "normals", etc sfields of the 1.x Geometry. // For the conversion the PtrFieldInfo structure for the "properties" // mfield is filled with the corresponding ids of the sfields from the // file. The remapping after postRead will fill in the right pointers. FieldDescriptionBase *propFieldDesc = geo->getFieldDescription("properties"); UInt32 propFieldId = propFieldDesc->getFieldId(); root->editPtrFieldList().push_back(PtrFieldInfo(geo, propFieldId)); PtrFieldInfo &propFieldPFI = root->editPtrFieldList().back(); propFieldPFI.editIdStore().resize(Geometry::MaxAttribs); while(true) { std::string fieldName; std::string fieldTypeName; UInt32 fieldSize; PtrFieldListIt ptrFieldIt; if(!readFieldHeader("", fieldName, fieldTypeName, fieldSize)) { OSG_OSB_LOG(("OSBGeometryElement::readV100: " "Reading stopped at field: [%s].\n", fieldName.c_str())); break; } if(fieldName == "indexMapping") { // read into temporary field MField<UInt16> indexMappingField; indexMappingField.copyFromBin(*rh); // copy to member for use in postRead indexMappingField.getValues().swap(_indexMapping); } else if(fieldName == "indices") { // read container id of indices property // postRead will handle the conversion of multi indices rh->getValue(_indicesId); } else if(fieldName == "positions") { UInt32 positionsId; rh->getValue(positionsId); propFieldPFI.editIdStore()[Geometry::PositionsIndex] = positionsId; } else if(fieldName == "normals") { UInt32 normalsId; rh->getValue(normalsId); propFieldPFI.editIdStore()[Geometry::NormalsIndex] = normalsId; } else if(fieldName == "colors") { UInt32 colorsId; rh->getValue(colorsId); propFieldPFI.editIdStore()[Geometry::ColorsIndex] = colorsId; } else if(fieldName == "secondaryColors") { UInt32 secondaryColorsId; rh->getValue(secondaryColorsId); propFieldPFI.editIdStore()[Geometry::SecondaryColorsIndex] = secondaryColorsId; } else if(fieldName == "texCoords") { UInt32 texCoordsId; rh->getValue(texCoordsId); propFieldPFI.editIdStore()[Geometry::TexCoordsIndex] = texCoordsId; } else if(fieldName == "texCoords1") { UInt32 texCoordsId1; rh->getValue(texCoordsId1); propFieldPFI.editIdStore()[Geometry::TexCoords1Index] = texCoordsId1; } else if(fieldName == "texCoords2") { UInt32 texCoordsId2; rh->getValue(texCoordsId2); propFieldPFI.editIdStore()[Geometry::TexCoords2Index] = texCoordsId2; } else if(fieldName == "texCoords3") { UInt32 texCoordsId3; rh->getValue(texCoordsId3); propFieldPFI.editIdStore()[Geometry::TexCoords3Index] = texCoordsId3; } else if(fieldName == "texCoords4") { UInt32 texCoordsId4; rh->getValue(texCoordsId4); propFieldPFI.editIdStore()[Geometry::TexCoords4Index] = texCoordsId4; } else if(fieldName == "texCoords5") { UInt32 texCoordsId5; rh->getValue(texCoordsId5); propFieldPFI.editIdStore()[Geometry::TexCoords5Index] = texCoordsId5; } else if(fieldName == "texCoords6") { UInt32 texCoordsId6; rh->getValue(texCoordsId6); propFieldPFI.editIdStore()[Geometry::TexCoords6Index] = texCoordsId6; } else if(fieldName == "texCoords7") { UInt32 texCoordsId7; rh->getValue(texCoordsId7); propFieldPFI.editIdStore()[Geometry::TexCoords7Index] = texCoordsId7; } else if(fieldName == "pindices") { UInt32 maxValue; UInt32 propSize; UInt32 byteSize; _indicesPacked = true; gh.readPackedIntegralPropertyHeader(rh, maxValue, propSize, byteSize); if(root->getOptions().unpack16BitIndices()) { if(maxValue > TypeTraits<UInt16>::getMax()) { GeoUInt32PropertyUnrecPtr ui32Indices = GeoUInt32Property::create(); gh.readPackedIntegralProperty(rh, ui32Indices, maxValue, propSize, byteSize ); _indices16Bit = false; _indices = ui32Indices; } else { GeoUInt16PropertyUnrecPtr ui16Indices = GeoUInt16Property::create(); gh.readPackedIntegralProperty(rh, ui16Indices, maxValue, propSize, byteSize ); _indices16Bit = true; _indices = ui16Indices; } } else { GeoUInt32PropertyUnrecPtr ui32Indices = GeoUInt32Property::create(); gh.readPackedIntegralProperty(rh, ui32Indices, maxValue, propSize, byteSize ); _indices16Bit = false; _indices = ui32Indices; } } else if(fieldName == "qpositions") { // Quantized positions are stored inside the geometry object, not // in the geo-property. They are always of type Pnt3f. GeoPnt3fPropertyUnrecPtr propPos = GeoPnt3fProperty::create(); UInt8 resolution; Real32 minValue; Real32 maxValue; UInt32 propSize; gh.readQuantizedVectorPropertyHeader(rh, resolution, minValue, maxValue, propSize ); gh.readQuantizedVectorProperty(rh, propPos, fieldSize, resolution, minValue, maxValue, propSize ); geo->setProperty(propPos, Geometry::PositionsIndex); } else if(fieldName == "qnormals") { // Quantized normals are stored inside the geometry object, not // in the geo-property. They are always of type Vec3f. GeoVec3fPropertyUnrecPtr propNorm = GeoVec3fProperty::create(); UInt8 resolution; Real32 minValue; Real32 maxValue; UInt32 propSize; gh.readQuantizedVectorPropertyHeader( rh, resolution, minValue, maxValue, propSize); gh.readQuantizedVectorProperty( rh, propNorm, fieldSize, resolution, minValue, maxValue, propSize ); geo->setProperty(propNorm, Geometry::NormalsIndex); } else if(fieldName == "qtexCoords") { // Quantized texCoords are stored inside the geometry object, not // in the geo-property. They are always of type Vec2f. GeoVec2fPropertyUnrecPtr propTexCoords = GeoVec2fProperty::create(); UInt8 resolution; Real32 minValue; Real32 maxValue; UInt32 propSize; gh.readQuantizedVectorPropertyHeader( rh, resolution, minValue, maxValue, propSize); gh.readQuantizedVectorProperty( rh, propTexCoords, fieldSize, resolution, minValue, maxValue, propSize ); geo->setProperty(propTexCoords, Geometry::NormalsIndex); } else { // 1.x Geometry has _sfVbo, it can be skipped readFieldContent(fieldName, fieldTypeName, fieldSize, "'vbo'", ptrFieldIt ); } } }
void OSBGeometryElement::preWrite(FieldContainer * const fc) { OSG_OSB_LOG(("OSBGeometryElement::preWrite\n")); OSBRootElement *root = editRoot(); UInt32 fieldCount = fc->getType().getNumFieldDescs(); UInt8 quanResPositions = root->getOptions().quantizePositions(); UInt8 quanResNormals = root->getOptions().quantizeNormals (); UInt8 quanResTexCoords = root->getOptions().quantizeTexCoords(); bool packIndices = root->getOptions().packIndices (); // go through all fields and find those refering to other FCs for(UInt32 fieldId = 1; fieldId <= fieldCount; ++fieldId) { const FieldDescriptionBase *fieldDesc = fc->getFieldDescription(fieldId); const FieldType &fieldType = fieldDesc->getFieldType(); const std::string &fieldName = fieldDesc->getName (); // skip internal fields if(fieldDesc->isInternal()) { OSG_OSB_LOG(("OSBGeometryElement::preWrite: " "Skipping internal field: [%s]\n", fieldName.c_str())); continue; } if(fieldName == "properties") { // "properties" might be quantized FieldContainerPtrMFieldBase::GetHandlePtr fP = boost::dynamic_pointer_cast< FieldContainerPtrMFieldBase::GetHandle>( getContainer()->getField(fieldId)); if(fP == NULL || fP->isValid() == false) continue; FieldContainerPtrMFieldBase::const_iterator fieldIt = (*fP)->begin(); FieldContainerPtrMFieldBase::const_iterator fieldEnd = (*fP)->end (); for(UInt32 i = 0; fieldIt != fieldEnd; ++fieldIt, ++i) { FieldContainer *refedFC = *fieldIt; if(refedFC == NULL) continue; UInt32 refedId = refedFC->getId (); const std::string typeName = refedFC->getType().getName(); // only schedule a container once if(root->getIdSet().count(refedId) > 0) continue; OSBElementBase *elem = OSBElementFactory::the()->acquire(typeName, root); OSBGeoVectorPropertyElement *propElem = dynamic_cast<OSBGeoVectorPropertyElement *>(elem); if((propElem != 0) && (i == Geometry::PositionsIndex)) { propElem->setQuantizeResolution(quanResPositions); } else if((propElem != 0) && (i == Geometry::NormalsIndex)) { propElem->setQuantizeResolution(quanResNormals); } else if((propElem != 0) && (i >= Geometry::TexCoordsIndex) && (i <= Geometry::TexCoords7Index) ) { propElem->setQuantizeResolution(quanResTexCoords); } root->editIdSet ().insert (refedId); root->editElementList().push_back(elem ); elem->setContainer(refedFC); elem->preWrite (refedFC); } } else if(fieldName == "propIndices") { // "propIndices" might be packed FieldContainerPtrMFieldBase::GetHandlePtr fP = boost::dynamic_pointer_cast< FieldContainerPtrMFieldBase::GetHandle>( getContainer()->getField(fieldId)); if(fP == NULL || fP->isValid() == false) continue; FieldContainerPtrMFieldBase::const_iterator fieldIt = (*fP)->begin(); FieldContainerPtrMFieldBase::const_iterator fieldEnd = (*fP)->end (); for(UInt32 i = 0; fieldIt != fieldEnd; ++fieldIt, ++i) { FieldContainer *refedFC = *fieldIt; if(refedFC == NULL) continue; UInt32 refedId = refedFC->getId (); const std::string typeName = refedFC->getType().getName(); // only schedule a container once if(root->getIdSet().count(refedId) > 0) continue; OSBElementBase *elem = OSBElementFactory::the()->acquire(typeName, root); OSBGeoIntegralPropertyElement *propElem = dynamic_cast<OSBGeoIntegralPropertyElement *>(elem); if((propElem != 0) && (packIndices == true)) { propElem->setPackData(true); } root->editIdSet ().insert (refedId); root->editElementList().push_back(elem ); elem->setContainer(refedFC); elem->preWrite (refedFC); } } else if(fieldName == "attachments") { preWriteAttachmentMapField(fieldId); } else { // check if field refers to another FC, i.e. its a field holding // FieldContainerPtr or an FieldContainerAttachmentMap if(fieldType.getContentType().isDerivedFrom( FieldTraits<FieldContainer *>::getType()) == true) { if(fieldType.getCardinality() == FieldType::SingleField) { preWritePtrSingleField(fieldId); } else if(fieldType.getCardinality() == FieldType::MultiField) { preWritePtrMultiField(fieldId); } } } } }
/*! Reads a SFFieldContainerAttachmentPtrMap from the stream. It has the given \a fieldId in the container it belongs to and size \a fieldSize. \param[in] fieldId Id of the field in the container it belongs to. \param[in] fieldSize Size in byte of the field. \return Iterator that points to the PtrFieldInfo structure that was created for this field. */ OSBCommonElement::PtrFieldListIt OSBCommonElement::readAttachmentMapField( const UInt32 fieldId, const UInt32 fieldSize) { OSG_OSB_LOG(("OSBCommonElement::readAttachmentMapField: " "fieldId: [%u]\n", fieldId)); bool hasBindingInfo = false; UInt32 ptrId; UInt32 numElements; OSBRootElement *root = editRoot(); BinaryReadHandler *rh = editRoot()->getReadHandler(); root->editPtrFieldList().push_back(PtrFieldInfo(getContainer(), fieldId)); PtrFieldInfo &pfi = root->editPtrFieldList().back(); rh->getValue(numElements); // keep these ordered from highest to lowest version if(root->getHeaderVersion() >= OSGOSBHeaderVersion200) { if(root->getHeaderVersion() > OSGOSBHeaderVersion200) { FINFO(("OSBCommonElement::readAttachmentMapField: " "Unknown header version, trying to read as latest.\n")); } hasBindingInfo = true; } else if(root->getHeaderVersion() >= OSGOSBHeaderVersion100) { // distinguish format with or without binding info if(fieldSize == (sizeof(UInt32) + numElements * sizeof(UInt32))) { hasBindingInfo = false; } else { hasBindingInfo = true; } } if(hasBindingInfo == true) { OSG_OSB_LOG(("OSBCommonElement::readAttachmentMapField: " "reading [%u] attachments with binding info.\n", numElements)); EditMapFieldHandlePtr sfMapField = boost::dynamic_pointer_cast<EditMapFieldHandle>( getContainer()->editField(fieldId)); if(sfMapField == NULL || sfMapField->isValid() == false) return --(root->editPtrFieldList().end()); pfi.setHandledField(sfMapField->loadFromBin(rh, numElements, hasBindingInfo, pfi.editBindingStore(), pfi.editIdStore ())); #if 0 for(UInt32 i = 0; i < numElements; ++i) { rh->getValue(binding); rh->getValue(ptrId ); OSG_OSB_LOG(("OSBCommonElement::readAttachmentMapField: " "attachment [%u], binding [%u], id [%u].\n", i, binding, ptrId)); pfi.editBindingStore().push_back(binding); pfi.editIdStore ().push_back(ptrId ); } #endif } else { OSG_OSB_LOG(("OSBCommonElement::readAttachmentMapField: " "reading [%u] attachments without binding info.\n", numElements)); for(UInt32 i = 0; i < numElements; ++i) { rh->getValue(ptrId); OSG_OSB_LOG(("OSBCommonElement::readAttachmentMapField: " "attachment [%u], id [%u].\n", i, ptrId)); pfi.editBindingStore().push_back(0 ); pfi.editIdStore ().push_back(ptrId); } } return --(root->editPtrFieldList().end()); }