查看: 3228|回复: 8

关于pagelod2

[复制链接]

该用户从未签到

发表于 2010-3-2 14:13:58 | 显示全部楼层 |阅读模式
使用vpb将tif文件转换为.ive的一堆pagelod文件后,应该如果将其实导进数据库,如果将每个文件作为一流块导进数据库后,应该如何将其导出,才能使得加载数据时机制和加载本地文件机制一样的。

该用户从未签到

发表于 2010-3-2 14:50:21 | 显示全部楼层
这个也是需要您自己去把握的。我曾经做过这样一个工作:把所有的pagedlod文件合并为一个大文件,然后用内存映射的策略,从大文件中搜索相对应的内存偏址并载入流数据。几个也许对您有用的提示是:
1、VPB不一定保存为ive文件,-o参数的扩展名决定了最终保存的格式。
2、您可以自己定义一个伪插件,例如osgdb_fakeive,它读取类同output_L0_x0_Y0.fakeive的文件名,并在其内部直接使用ive插件来进行真正的读操作。
3、当您的PagedLOD中保存的文件名均为xxx.fakeive时,DatabasePager的操作将只是调用osgdb_fakeive插件并给定xxx.fakeive这个文件名,而真正要做什么操作(例如内存映射,从数据库导出)则是由您自定义的插件代码来决定的!这就实现了不同的数据加载机制,而不用对OSG内部代码进行改动

该用户从未签到

 楼主| 发表于 2010-3-3 09:39:22 | 显示全部楼层
谢谢array的回复,不过,我技术有限还是不懂,因为对于内存偏址,内存映射等还很模糊,现在我想问在建立好的pagelod文件的最外层的那个文件(假设为file.osg)中,例如有一段如下的字符
  FileNameList 2 {
      ""
      RemoteLayer_root_L0_X0_Y0/RemoteLayer_L0_X0_Y0_subtile.osg
    }
那么程序是如何解析这字符的:
FileNameList 为什么是2,
如果是根据这个FileNameList去加载相关的文件,那么本身这个file.osg是不是就暂停加载,直到FileNameList中的文件加载完毕,还是相当于多线程一样的同步加载?

该用户从未签到

发表于 2010-3-3 09:44:05 | 显示全部楼层
文件的内存映射是我做的工作,这里只是给您一个提示,并非让您也这么去做。
FileNameList为2,是因为PagedLOD有两个子节点,第一个是空字符,因此第一个子节点不是动态加载的,而是直接使用addChild加入的最低级别的子节点;而第二个节点则是保存在外部文件中并可以进行动态调度。

如果是根据这个FileNameList去加载相关的文件,那么本身这个file.osg是不是就暂停加载
很显然,当程序读取到FileNameList时,file.osg已经加载完毕了

该用户从未签到

 楼主| 发表于 2010-3-3 14:41:30 | 显示全部楼层
感谢array的提示,结合伪插件的思想,我将“三维渲染引擎设计与实践”中的pagelod动态加载的数据(.trans)改为.DBtrans然后编写DBtrans伪插件,主要从数据库中读取流转换为节点,功能上算是达到目的了,但是我想这并不是一种很好的方法,因为频繁的操作数据库,其实应该会影响速度的。
伪插件代码如下:
#include <iostream>
#include <sstream>

#include <stdio.h>
#define OTL_STL
#define OTL_STREAM_READ_ITERATOR_ON
#define OTL_ODBC
#include "../Include/otlv4.h"
#define EXTENSION_NAME "DBtrans"
otl_connect m_db; // connect object
bool connet2Database(const std::string& Connectionstring)
{
otl_connect:tl_initialize(); // 单线程模式(默认)
bool sucess=true;
try
{
  m_db.rlogon(Connectionstring.c_str()); // connect to Oracle
}
catch(otl_exception& p){ // intercept OTL exceptions
  std::cerr<<p.msg<<std::endl; // print out error message
  std::cerr<<p.stm_text<<std::endl; // print out SQL that caused the error
  std::cerr<<p.var_info<<std::endl; // print out the variable that caused the error
  sucess=false;
}
return sucess;
}
bool IsOpen()
{
return m_db.connected;
}
void Close()
{
m_db.logoff();
}

static bool getFilenameAndParams(const std::string& input, std::string& filename, std::string& params)
{
// find the start of the params list, accounting for nesting of [] and () brackets,
// note, we are working backwards.
int noNestedBrackets = 0;
std::string::size_type pos = input.size();
for(; pos>0; )
{
  --pos;
  char c = input[pos];
  if (c==']') ++noNestedBrackets;
  else if (c=='[') --noNestedBrackets;
  else if (c==')') ++noNestedBrackets;
  else if (c=='(') --noNestedBrackets;
  else if (c=='.' && noNestedBrackets==0) break;
}
// get the next "extension", which actually contains the pseudo-loader parameters
params = input.substr(pos+1, std::string::npos );
if( params.empty() )
{
  osg::notify(osg::WARN) << "Missing parameters for " EXTENSION_NAME " pseudo-loader" << std::endl;
  return false;
}
// clear the params sting of any brackets.
std::string::size_type params_pos = params.size();
for(; params_pos>0; )
{
  --params_pos;
  char c = params[params_pos];
  if (c==']' || c=='[' || c==')' || c=='(')
  {
   params.erase(params_pos,1);
  }
}
// strip the "params extension", which must leave a sub-filename.
filename = input.substr(0, pos );
return true;
}

osg::Node* readNodeFileFromDB(const std::string& filename,const osgDB::ReaderWriter::Options* options )
{
if(!IsOpen())
  connet2Database("UID=saWD=sa;DSN=ExpoTd");
if (IsOpen())
{
  std::string sqlstr="select Geometry from Expo_Td where Name = '"+ filename+"'";
  otl_stream i;
  i.set_lob_stream_mode(true);
  i.open(1,sqlstr.c_str(),m_db);
  /*while (!i.eof())
  {*/
   otl_lob_stream lob;
   std::string outputstr;
   i>>lob;
   while (!lob.eof())
   {
    otl_long_string f2(3000);
    lob>>f2;
    for (int i=0;i<f2.len();i++)
     outputstr.push_back(f2[i]);
   }
   lob.close();
   std::istringstream istrstream(outputstr);
   osgDB::ReaderWriter* rw =osgDB::Registry::instance()->getReaderWriterForExtension("osg");
   osgDB::ReaderWriter::ReadResult rr = rw->readNode(istrstream);
   osg::Node* node=rr.takeNode();
   return node;
  //}
}
else
  return NULL;

}
///////////////////////////////////////////////////////////////////////////
/**
* An OSG reader plugin for the ".trans" pseudo-loader, which inserts a
* translation transform above the loaded geometry.
* This pseudo-loader make it simple to change the origin of a saved model
* by specifying a correcting translation as part of the filename.
*
* Usage: <modelfile.ext>.<tx>,<ty>,<tz>.globe
* where:
*      <modelfile.ext> = an model filename.
*      <tx> = translation along the X axis.
*      <ty> = translation along the Y axis.
*      <tz> = translation along the Z axis.
*
* example: osgviewer cow.osg.25,0,0.trans cessna.osg
*/
class ReaderWriterDBTRANS : public osgDB::ReaderWriter
{
public:
ReaderWriterDBTRANS()
{
  supportsExtension(EXTENSION_NAME,"DBTranslation Psuedo loader.");
}
virtual const char* className() const { return "dbtranslation pseudo-loader"; }
virtual ReadResult readNode(const std::string& fileName, const osgDB::ReaderWriter::Options* options) const
{
  std::string ext = osgDB::getLowerCaseFileExtension(fileName);
  if( !acceptsExtension(ext) )
   return ReadResult::FILE_NOT_HANDLED;
  osg::notify(osg::INFO) << "ReaderWriterDBTRANS( \"" << fileName << "\" )" << std::endl;
  // strip the pseudo-loader extension
  std::string tmpName = osgDB::getNameLessExtension( fileName );
  if (tmpName.empty())
   return ReadResult::FILE_NOT_HANDLED;
  std::string subFileName, params;
  if (!getFilenameAndParams(tmpName, subFileName, params))
  {
   return ReadResult::FILE_NOT_HANDLED;
  }
  if( subFileName.empty())
  {
   osg::notify(osg::WARN) << "Missing subfilename for " EXTENSION_NAME " pseudo-loader" << std::endl;
   return ReadResult::FILE_NOT_HANDLED;
  }
  osg::notify(osg::INFO) << " params = \"" << params << "\"" << std::endl;
  osg::notify(osg::INFO) << " subFileName = \"" << subFileName << "\"" << std::endl;
  float tx, ty, tz;
  int count = sscanf( params.c_str(), "%f,%f,%f", &tx, &ty, &tz );
  if( count != 3 )
  {
   osg::notify(osg::WARN) << "Bad parameters for " EXTENSION_NAME " pseudo-loader: \"" << params << "\"" << std::endl;
   return ReadResult::FILE_NOT_HANDLED;
  }
  // recursively load the subfile.
  //osg::Node *node = osgDB::readNodeFile( subFileName, options );
  osg::Node* node=readNodeFileFromDB(subFileName,options);
  if( !node )
  {
   // propagate the read failure upwards
   osg::notify(osg::WARN) << "Subfile \"" << subFileName << "\" could not be loaded" << std::endl;
   return ReadResult::FILE_NOT_HANDLED;
  }
  osg::MatrixTransform *xform = new osg::MatrixTransform;
  xform->setDataVariance( osg::Object::STATIC );
  xform->setMatrix( osg::Matrix::translate( tx, ty, tz ) );
  xform->addChild( node );
  return xform;
}
};

// Add ourself to the Registry to instantiate the reader/writer.
REGISTER_OSGPLUGIN(DBtrans, ReaderWriterDBTRANS)

请各位高手指点

该用户从未签到

发表于 2010-3-3 15:15:34 | 显示全部楼层
抱歉我不是很了解数据库的API调用流程,不过我认为频繁操作是完全可以避免的,除非您原本的意图就无法避免过多的数据库操作。

例如在ReaderWriter的构造函数中创建和引用数据库对象,并在析构函数中将它卸载,以及使用本地缓存来操作数据,等等。插件机制并不会影响相关的操作过程

该用户从未签到

 楼主| 发表于 2010-3-3 15:45:02 | 显示全部楼层
嗯,谢谢,估计也只能使用本地缓存的办法了

该用户从未签到

发表于 2019-8-7 10:51:23 | 显示全部楼层
您好,想问一下,如果模型文件中已经包含PageLOD节点,如果通过内存映射或者其他方式将文件Buffer通过下面这种方式加载
std::istringstream istrstream(outputstr);
   osgDB::ReaderWriter* rw =osgDB::Registry::instance()->getReaderWriterForExtension("osg");
   osgDB::ReaderWriter::ReadResult rr = rw->readNode(istrstream);
   osg::Node* node=rr.takeNode();
完成后Node没问题,但是PageLOD就没作用了,这种是什么问题
上面看到了这种需要计算偏移量,是这样吗?

该用户从未签到

发表于 2019-8-7 10:58:58 | 显示全部楼层
您好,想问一下,加入模型文件中已经包含PageLOD例如:
    FileNameList 2 {
      ""
     test.ive
    }
我通过内存映射或者其他方式将文件的内容通过
                        std::istream stream(&sb);
                        osgDB::ReaderWriter::ReadResult rr = rw->readObject(stream);
                        return rr.takeNode();
这种方式加载后,文件中包含的PageLOD并不会动态加载
这种是是什么原因,需要上面说的计算偏移量通过外部加载吗?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表