查看: 1262|回复: 3

求提高该段代码效率

[复制链接]

该用户从未签到

发表于 2012-12-3 23:52:59 | 显示全部楼层 |阅读模式
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秒,项目要求是动态进行的
考虑用多线程,求问有没有什么好的解决方案

该用户从未签到

发表于 2012-12-4 08:05:16 | 显示全部楼层
这么多操作 估计会卡,封装到operation中,在thread中操作,然后保存父节点就行了,在主线程apply时将处理好的节点添加进来

该用户从未签到

 楼主| 发表于 2012-12-4 10:48:16 | 显示全部楼层
再问,怎么能把NodeVisitor和多线程结合起来

该用户从未签到

发表于 2012-12-5 07:57:37 | 显示全部楼层
最经典的结合方式就是DataBasePager了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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