C++ 如何在OpenSceneGraph中通过指针而不是复制来访问阵列数据?

C++ 如何在OpenSceneGraph中通过指针而不是复制来访问阵列数据?,c++,openscenegraph,C++,Openscenegraph,我用OpenSceneGraph(osg)编写了一个小的动画程序。在每个帧中,我应该更新场景中的模型(顶点位置、法线、颜色和其他内容) 现在我应该在每个帧中将数据转换为osg。代码如下: cog_.vertex_->clear(); cog_.vertex_->push_back(osg::Vec3(1.0,1.0,1.0)); 然而,这些转换非常耗时。所以我想知道如何通过指针直接访问数据。我试过了,但失败了。以下是我所做的,希望有人能帮我找到问题,或者告诉我更好的解决方案: 首先

我用OpenSceneGraph(osg)编写了一个小的动画程序。在每个帧中,我应该更新场景中的模型(顶点位置、法线、颜色和其他内容)

现在我应该在每个帧中将数据转换为osg。代码如下:

cog_.vertex_->clear();
cog_.vertex_->push_back(osg::Vec3(1.0,1.0,1.0));
然而,这些转换非常耗时。所以我想知道如何通过指针直接访问数据。我试过了,但失败了。以下是我所做的,希望有人能帮我找到问题,或者告诉我更好的解决方案:

首先,我将指针包装为指向osg::Vec3的指针

class vec3_map : public osg::Vec3
{
public:
    typedef osg::Vec3::value_type value_type;
    osg::Vec3::value_type* p_;

    vec3_map() :p_(0) {}
    vec3_map(osg::Vec3::value_type*p, int offset = 0) :p_(p+offset){}

    inline value_type& x() { return *(p_+0); }
    inline value_type& y() { return *(p_+1); }
    inline value_type& z() { return *(p_+2); }

    // some other stuff
};
当我想构建一个vec3_映射数组时,我发现osg使用了一个tempalte来定义Vec3Array,但是指针没有任何类型,所以我选择了Closer类型(我知道指针是一个具有无符号长整型的变量):

typedef osg::TemplateArray Vec3\u map\u数组;
根据此定义,我可以将问题改写为以下内容:

#define BOOST_ALL_NO_LIB
#include <boost/shared_ptr.hpp>
#include <fstream>

#include <vector>
#include <osg/Group>
#include <osg/Geometry>
#include <osgViewer/Viewer>
#include <osg/Vec3>

class vec3_map : public osg::Vec3
{
public:
typedef osg::Vec3::value_type value_type;
osg::Vec3::value_type* p_;

vec3_map() :p_(0) {}
vec3_map(osg::Vec3::value_type*p, int offset = 0) :p_(p + offset) {}

inline value_type* ptr() { return p_; }
inline const value_type* ptr() const { return p_; }

inline value_type& operator [] (int i) { return *(p_ + i); }
inline value_type operator [] (int i) const { return *(p_ + i); }

inline value_type& x() { return *(p_ + 0); }
inline value_type& y() { return *(p_ + 1); }
inline value_type& z() { return *(p_ + 2); }

inline value_type x() const { return *(p_); }
inline value_type y() const { return *(p_ + 1); }
inline value_type z() const { return *(p_ + 2); }
};


typedef osg::TemplateArray<vec3_map, osg::Array::UIntArrayType, 1,     GL_UNSIGNED_INT> Vec3_map_Array;

struct point_data
{
 point_data(float xx, float yy, float zz) { x = xx; y = yy; z = zz; }
 float x;
 float y;
 float z;
};

osg::Geode* create_point_node(boost::shared_ptr<std::vector<point_data> > ptr)
{
 osg::Geode *geode_ = new osg::Geode;
 osg::Geometry* geometry_ = new osg::Geometry;
 Vec3_map_Array* vertex_ = new Vec3_map_Array;
 osg::DrawElementsUInt* point_idx_ = new osg::DrawElementsUInt;

 vertex_->reserve(ptr->size());
 point_idx_->reserve(ptr->size());

 vec3_map vm;
 std::vector<point_data> & pd = *ptr;
 for (size_t i = 0; i < ptr->size(); ++i)
 {
    vertex_->push_back(vec3_map(&(pd[i].x)));
    point_idx_->push_back(i);
 }

 geometry_->setVertexArray(vertex_);
 geometry_->addPrimitiveSet(point_idx_);
 geode_->addDrawable(geometry_);
 return geode_;
}

int main(int argc, char *argv[])
{
 boost::shared_ptr<std::vector<point_data> > pd(new std::vector<point_data>);
 pd->push_back(point_data(1.0, 1.0, 1.0));
 pd->push_back(point_data(2.0, 2.0, 2.0));

 osgViewer::Viewer viewer;
 osg::Node *node = create_point_node(pd);
 viewer.setSceneData(node);
 return viewer.run();
}
#定义BOOST\u ALL\u NO\u库
#包括
#包括
#包括
#包括
#包括
#包括
#包括
类vec3_映射:public osg::vec3
{
公众:
typedef osg::Vec3::value_type value_type;
osg::Vec3::值\类型*p;
vec3_映射():p_0{}
vec3_映射(osg::vec3::value_type*p,int offset=0):p_(p+offset){
内联值_type*ptr(){return p_;}
内联常量值_type*ptr()常量{返回p_;}
内联值类型和运算符[](int i){return*(p_u+i);}
内联值_类型运算符[](int i)常量{return*(p_u+i);}
内联值_type&x(){return*(p_u+0);}
内联值_type&y(){return*(p_+1);}
内联值_type&z(){return*(p_+2);}
内联值_typex()常量{return*(p)}
内联值_typey()常量{return*(p_u+1);}
内联值_type z()常量{return*(p_u2);}
};
typedef osg::TemplateArray Vec3_map_数组;
结构点数据
{
点_数据(浮点xx,浮点yy,浮点zz){x=xx;y=yy;z=zz;}
浮动x;
浮动y;
浮动z;
};
osg::Geode*创建点节点(boost::共享点节点)
{
osg::Geode*Geode_u2;=新osg::Geode;
osg::Geometry*Geometry=新osg::Geometry;
Vec3_映射数组*顶点=新的Vec3_映射数组;
osg::Dropelementsuint*point_idx_u=新osg::Dropelementsuint;
顶点->保留(ptr->大小());
点idx->保留(ptr->大小());
vec3_-map-vm;
std::vector&pd=*ptr;
对于(大小i=0;isize();++i)
{
顶点->推回(vec3_映射(&(pd[i].x));
点idx->推回(i);
}
几何体->设置顶点阵列(顶点);
几何体->添加基本体集(点\u idx\ux);
测地线->可添加绘图(几何图形);
返回测地线;
}
int main(int argc,char*argv[])
{
boost::shared_ptr pd(新std::vector);
pd->push_back(点_数据(1.0,1.0,1.0));
pd->push_back(点_数据(2.0,2.0,2.0));
osgViewer::查看器;
osg::Node*Node=创建点节点(pd);
viewer.setSceneData(节点);
返回viewer.run();
}

然而,这个问题崩溃了。我不确定我是否能做这样的事

请提供一个感谢您的回复@m.s。我已经上传了一个带有数据的最小测试到下面的链接,这到目前为止还不是最小的。尽量减少代码,然后将代码插入其中,而不是链接到非现场资源。@m.s.谢谢。但我认为这个例子是非常小的。为了演示我的情况,我构建了一个只有一个渲染节点的场景,该节点是从本地文件加载的。我认为减少它会使它不能执行。嗯,我不认为百行代码(以及更多)是最小的。
#define BOOST_ALL_NO_LIB
#include <boost/shared_ptr.hpp>
#include <fstream>

#include <vector>
#include <osg/Group>
#include <osg/Geometry>
#include <osgViewer/Viewer>
#include <osg/Vec3>

class vec3_map : public osg::Vec3
{
public:
typedef osg::Vec3::value_type value_type;
osg::Vec3::value_type* p_;

vec3_map() :p_(0) {}
vec3_map(osg::Vec3::value_type*p, int offset = 0) :p_(p + offset) {}

inline value_type* ptr() { return p_; }
inline const value_type* ptr() const { return p_; }

inline value_type& operator [] (int i) { return *(p_ + i); }
inline value_type operator [] (int i) const { return *(p_ + i); }

inline value_type& x() { return *(p_ + 0); }
inline value_type& y() { return *(p_ + 1); }
inline value_type& z() { return *(p_ + 2); }

inline value_type x() const { return *(p_); }
inline value_type y() const { return *(p_ + 1); }
inline value_type z() const { return *(p_ + 2); }
};


typedef osg::TemplateArray<vec3_map, osg::Array::UIntArrayType, 1,     GL_UNSIGNED_INT> Vec3_map_Array;

struct point_data
{
 point_data(float xx, float yy, float zz) { x = xx; y = yy; z = zz; }
 float x;
 float y;
 float z;
};

osg::Geode* create_point_node(boost::shared_ptr<std::vector<point_data> > ptr)
{
 osg::Geode *geode_ = new osg::Geode;
 osg::Geometry* geometry_ = new osg::Geometry;
 Vec3_map_Array* vertex_ = new Vec3_map_Array;
 osg::DrawElementsUInt* point_idx_ = new osg::DrawElementsUInt;

 vertex_->reserve(ptr->size());
 point_idx_->reserve(ptr->size());

 vec3_map vm;
 std::vector<point_data> & pd = *ptr;
 for (size_t i = 0; i < ptr->size(); ++i)
 {
    vertex_->push_back(vec3_map(&(pd[i].x)));
    point_idx_->push_back(i);
 }

 geometry_->setVertexArray(vertex_);
 geometry_->addPrimitiveSet(point_idx_);
 geode_->addDrawable(geometry_);
 return geode_;
}

int main(int argc, char *argv[])
{
 boost::shared_ptr<std::vector<point_data> > pd(new std::vector<point_data>);
 pd->push_back(point_data(1.0, 1.0, 1.0));
 pd->push_back(point_data(2.0, 2.0, 2.0));

 osgViewer::Viewer viewer;
 osg::Node *node = create_point_node(pd);
 viewer.setSceneData(node);
 return viewer.run();
}