|
楼主 |
发表于 2012-8-29 11:25:21
|
显示全部楼层
smash 发表于 2012-8-29 10:24
ive模型跟osg模型读到内存里都是一样的,怎么会osg能简化ive不能简化?
我也奇怪呢,我设化简参数是0.1,读cow.osg化简前顶点数是7772,化简后是三百多,读一个ive文件,化简前后顶点数没有变化
[code
//节点纹理访问器
class TextureVisitor : public osg::NodeVisitor
{
public:
osg::ref_ptr<osg::Vec3Array> extracted_verts;
//构造函数,遍历所有子节点
TextureVisitor( ):
osg::NodeVisitor( osg::NodeVisitor::TRAVERSE_ALL_CHILDREN )
{
//
extracted_verts=new osg::Vec3Array;
}
//重载apply方法
virtual void apply( osg::Node& node )
{
if( node.getStateSet() )
{
apply( node.getStateSet() );
//node.setStateSet(NULL);
}
//实现继续遍历节点
traverse(node);
}
//重载apply方法
virtual void apply( osg::Geode& geode )
{
if( geode.getStateSet() )
{
apply( geode.getStateSet() );
// geode.setStateSet(NULL);
}
unsigned int cnt = geode.getNumDrawables();
for( unsigned int i = 0; i < cnt; i++ )
{
apply(geode.getDrawable(i)->getStateSet());
//geode.getDrawable(i)->setStateSet(NULL);
//得到绘制体
osg::Geometry * geom=dynamic_cast<osg::Geometry*>(geode.getDrawable(i));
if (!geom)
{
continue;
}
//得到顶点
osg::Vec3Array *verts= dynamic_cast<osg::Vec3Array*>(geom->getVertexArray());
if (!verts)
{
continue;
}
//将顶点插入到顶点列表
extracted_verts->insert(extracted_verts->end(),verts->begin(),verts->end());
}
traverse(geode);
}
//得到贴图列表
void apply( osg::StateSet* state )
{
//得到纹理属性列表
osg::StateSet::TextureAttributeList& texAttribList = state->getTextureAttributeList();
for( unsigned int i = 0; i < texAttribList.size(); i++ )
{
//得到纹理
osg::Texture2D* tex2D = NULL;
if( tex2D = dynamic_cast<osg::Texture2D*>(state->getTextureAttribute(i, osg::StateAttribute::TEXTURE)) )
{
//得到贴图
if( tex2D->getImage() )
{
//简化贴图
scale(tex2D->getImage(),minimage);
}
}
}
}
void setminimage(float m)
{
minimage=m;
}
protected:
float minimage;//贴图简化大小
};
void SimplifierTexture(osg::Node* node,float minverts,float minimage)
{
//样本比率越小,简化越多
float sampleRatio = 0.1f;
//设置点的最大误差
float maxError = 4.0f;
//计算顶点数
unsigned int num;
//深拷贝模型到nodedeep节点
osg::ref_ptr<osg::Node> nodedeep = (osg::Node*)node->clone(osg::CopyOp:EEP_COPY_ALL);
//创建纹理访问器
TextureVisitor textureTV;
textureTV.setminimage(minimage);
//启动访问器,执行遍历
nodedeep->accept( textureTV );
//得到模型的顶点数
num=textureTV.extracted_verts->size();
//得到化简样本比率
sampleRatio=minverts/(float)num;
std::cout<<num;
//创建简化对象
osgUtil::Simplifier simplifier(sampleRatio, maxError);
//利用simplifier简化nodedeep
nodedeep->accept(simplifier);
return ;
}
int main()
{
//创建Viewer对象,场景浏览器
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
osg::ref_ptr<osg::Group> root = new osg::Group();
//创建一个节点并读取模型
osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("cow.osg");
float minverts=1000;
float minimage=256;
SimplifierTexture(node,minverts,minimage);
root->addChild(node.get());
////优化场景数据
//osgUtil::Optimizer optimizer ;
//optimizer.optimize(root.get()) ;
viewer->setSceneData(root.get());
viewer->realize();
viewer->run();
return 0 ;
}[/code]
|
|