|
void VertexVisitor_mt::apply(osg::Geode& geode)
{
osg::ref_ptr<osg::MatrixTransform> matrix = new osg::MatrixTransform(); //for each geode
osg::Matrix* wcMatrix = new osg::Matrixd();
wcMatrix->set( osg::computeLocalToWorld(this->getNodePath()) );
matrix->setMatrix(*wcMatrix);
//得到每一个drawables
for (unsigned int i=0; i<geode.getNumDrawables(); ++i)
{
osg::ref_ptr<osg::Vec3Array> extracted_verts = new osg::Vec3Array(); //保存顶点数据
//得到几何体
osg::ref_ptr<osg::Geometry> geom = dynamic_cast<osg::Geometry*>(geode.getDrawable(i));
if(!geom)
{
std::cout<<"几何体错误!"<<std::endl;
continue;
}
//得到顶点数组
osg::ref_ptr<osg::Vec3Array> verts = dynamic_cast<osg::Vec3Array*>(geom->getVertexArray());
if(!verts)
{
std::cout<<"顶点数组错误!"<<std::endl;
continue;
}
//添加到extracted_verts
extracted_verts->insert(extracted_verts->end(), verts->begin(), verts->end());
int size_t = extracted_verts->size();
std::vector<osg::Vec3>::iterator iter = extracted_verts->begin();
float **fir_array = new float *[size_t]; //the top array
for (int i=0; i<size_t; i++)
{
fir_array[i] = new float[3];
}
for (int i=0; i<size_t; i++)
{
fir_array[i][0] = iter->x();
fir_array[i][1] = iter->y();
fir_array[i][2] = iter->z();
iter++;
}
//the following code is divided
float min_x = fir_array[0][0];
float max_x = fir_array[0][0];
float min_y = fir_array[0][1];
float max_y = fir_array[0][1];
for (int i=0; i<size_t; i++)
{
if( min_x > fir_array[i][0] ) min_x = fir_array[i][0];
if( max_x < fir_array[i][0] ) max_x = fir_array[i][0];
if( min_y > fir_array[i][1] ) min_y = fir_array[i][1];
if( max_y < fir_array[i][1] ) max_y = fir_array[i][1];
}
float x_add = ( max_x - min_x ) / 15;
float y_add = ( max_y - min_y ) / 15;
int block[256] = {0};
for( int i=0; i<size_t; i++)
{
int ii = (int)((fir_array[i][0] - min_x) / x_add); //该值落在第几行
int jj = (int)((fir_array[i][1] - min_y) / y_add); //该值在第几列
block[ii * 16 + jj]++; //根据行列确定其块数
}
float ***blockArray = new float**[256]; //第一维保存块数
for (int i=0; i<256; i++)
{
blockArray[i] = new float*[block[i]];
for(int j=0; j<block[i]; j++)
blockArray[i][j] = new float[3]; //第三维保存x,y,z值
}
int b_t[256] = {0}; //临时变量
for (int i=0; i<size_t; i++)
{
int ii = (int)((fir_array[i][0] - min_x) / x_add); //该值落在第几行
int jj = (int)((fir_array[i][1] - min_y) / y_add); //该值在第几列
blockArray[ii * 16 + jj][(b_t[ii * 16 + jj])][0] = fir_array[i][0]; //对应赋值
blockArray[ii * 16 + jj][(b_t[ii * 16 + jj])][1] = fir_array[i][1];
blockArray[ii * 16 + jj][(b_t[ii * 16 + jj])][2] = fir_array[i][2];
b_t[ii * 16 + jj]++; //指向下一位置
}
osg::ref_ptr<osg::Geode> point[256];
osg::ref_ptr<osg::Geode> trigeode[256];
osg::ref_ptr<osg::Geode> threeBox[256];
osg::ref_ptr<osg::Geode> fourSphere[256];
for(int i=0; i<256; i++)
{
point[i] = new osg::Geode();
trigeode[i] = new osg::Geode();
threeBox[i] = new osg::Geode();
fourSphere[i] = new osg::Geode();
}
for( int i=0; i<256; i++)
{
osg::ref_ptr<osg::Vec3Array> pointArray = new osg::Vec3Array();
for( int j=0; j<block[i]; j++ )
{
pointArray->push_back(osg::Vec3(blockArray[i][j][0],blockArray[i][j][1],blockArray[i][j][2]));
}
osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry();
geometry->setVertexArray(pointArray.get());
geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POINTS,0,block[i]));
osg::ref_ptr<osg::Vec4Array> vc = new osg::Vec4Array(); //添加颜色
vc->push_back(osg::Vec4(0.0f,1.0f,0.0f,1.0f));
geometry->setColorArray(vc.get());
geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
geometry->setUseDisplayList(false);
geometry->setUseVertexBufferObjects(true);
point[i]->addDrawable(geometry.get());
osg::ref_ptr<osg::Vec3Array> triArray = new osg::Vec3Array();
for( int j=0; j<block[i]; j++ )
{
triArray->push_back(osg::Vec3(blockArray[i][j][0],blockArray[i][j][1],blockArray[i][j][2]));
triArray->push_back(osg::Vec3(blockArray[i][j][0],blockArray[i][j][1]-150.0f,blockArray[i][j][2]+300.0f));
triArray->push_back(osg::Vec3(blockArray[i][j][0],blockArray[i][j][1]+150.0f,blockArray[i][j][2]+300.0f));
}
osg::ref_ptr<osg::Geometry> geometryTri = new osg::Geometry();
geometryTri->setVertexArray(triArray.get());
geometryTri->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES,0,block[i]*3));
osg::ref_ptr<osg::Vec4Array> vcTri = new osg::Vec4Array(); //添加颜色
vcTri->push_back(osg::Vec4(1.0f,0.0f,1.0f,0.0f));
geometryTri->setColorArray(vcTri.get());
geometryTri->setColorBinding(osg::Geometry::BIND_OVERALL);
geometryTri->setUseDisplayList(false);
geometryTri->setUseVertexBufferObjects(true);
trigeode[i]->addDrawable(geometryTri.get());
for(int j=0; j<block[i]; j++) //
{
threeBox[i]->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(blockArray[i][j][0],blockArray[i][j][1],blockArray[i][j][2]+100.0f),100.0f)));
fourSphere[i]->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(blockArray[i][j][0],blockArray[i][j][1],blockArray[i][j][2]+200.0f),200.0f)));
}
osg::ref_ptr<osg::LOD> lode = new osg::LOD();
lode->addChild(point[i].get(),100000, 840000);
lode->addChild(trigeode[i].get(),10000, 100000);
lode->addChild(threeBox[i].get(),5000, 10000);
lode->addChild(fourSphere[i].get(),0, 5000);
matrix->addChild(lode.get());
}
delete fir_array;
delete blockArray;
}
mt->addChild(matrix);
}
先获取顶点,然后显示,因为地形上有很多个drawable,所以时间是线性增加的
100万个结点差不多要200秒,项目要求是动态进行的
考虑用多线程,求问有没有什么好的解决方案 |
|