查看: 5226|回复: 31

PositionAttitudeTransform的问题

[复制链接]

该用户从未签到

发表于 2009-9-1 20:45:02 | 显示全部楼层 |阅读模式
我在程序里用PositionAttitudeTransform节点addchild(),然后回调,回调的时候再addchild(),是不是回调的时候PositionAttitudeTransform的坐标原点会变化的?具体程序代码如下:
osg::ref_ptr<osg::Group> root = new osg::Group;
        osg::ref_ptr<osg:ositionAttitudeTransform> pat2 = new osg::PositionAttitudeTransform();       
osg::ref_ptr<osg::Node> tanknode = new osg::Node;
        tanknode = osgDB::readNodeFile("T72-tank/t72-tank_des.flt");
        if(tanknode.get())
        {
                osg::StateSet *set = tanknode->getOrCreateStateSet();
                osg::Texture2D* tex = new osg::Texture2D;
                tex->setImage(osgDB::readImageFile("T72-tank/textures/t72-tank_des02.rgb"));
                set->setTextureAttributeAndModes( 0, tex, osg::StateAttribute::ON );
                pat2->setPosition(osg::Vec3(2985.f,0.f,230.f));
                pat2->addChild(tanknode.get());
                pat2->setScale(osg::Vec3(5,5,5));
                pat2->setUpdateCallback(new tubcallback());
                osgUtil::SmoothingVisitor smooth;
                tanknode->accept(smooth);
        }
root->addChild(pat2.get());

class tubcallback : public osg::NodeCallback
{
public:
        tubcallback():_weizhi(false),_chushi(362972.6,1114926.26,2000.f)
        {
                _oldposition = osg::Vec3(367772.6f,1108746.26f,2236.0f);
        }
        void updateparament()
        {
                ///读 入txt赋值给newposition
                std::vector<double> ch;
                std::vector<double>::iterator iter;
                double ival;
                std::ifstream infile("../virtual/debug/out.txt");
                if(!infile.is_open())
                {
                        std::cerr <<"Error! can not open file!" <<std::endl;
//                        exit(EXIT_FAILURE);
                }
                else
                {
                         while(infile>>ival)
                         {
                                ch.push_back(ival);
                         }
//                         int i=0,j=0;
                         std::cout<<"ch.size():"<<ch.size()<<std::endl;
                         for(iter=ch.begin();iter!=ch.end();)
                         {
//                                 std::cout<<"*iter:"<<*iter<<std::endl;
                                 _newposition.x() = *iter;
                                 _newposition.y() = *(++iter);
//                                 std::cout<<"*iter:"<<*iter<<std::endl;
                                 _newposition.z() = *(++iter);
                                 _speed = *(++iter);
                                 (iter++)++;
                         }
                }
                if(_newposition != _oldposition)
                {
                        _weizhi = true;
                }
               
                infile.close();

        }

        virtual void operator()(osg::Node* node,osg::NodeVisitor* nv)
        {
                updateparament();               
                if(_weizhi)
                {
osg::PositionAttitudeTransform* pat =dynamic_cast<osg::PositionAttitudeTransform*>(node);

if (pat)
{
        osg::Vec3d scale(_newposition.x()-_chushi.x(),_newposition.y()-_chushi.y(),_chushi.z());
        osg::Vec3d oldscale(_oldposition.x()-_chushi.x(),_oldposition.y()-_chushi.y(),_chushi.z());
        _speed = _speed/5;
for(int i = 0;i<10;i++)
{
        osgUtil::IntersectVisitor ivXY;
osg::ref_ptr<osg:ineSegment> lineXY = new osg::LineSegment( scale,oldscale);                                                  
osg::ref_ptr<osg::LineSegment> lineZ = new osg::LineSegment( scale+osg::Vec3(0.0f,0.0f,1.0f),scale+osg::Vec3(0.0f,0.0f,-1.0f));
        ivXY.addLineSegment(lineZ.get());
        ivXY.addLineSegment(lineXY.get());
        node->accept(ivXY);
                                 
        if(!ivXY.hits())
        {
                coords = new osg::Vec3Array;
                geom = new osg::Geometry;
                geode = new osg::Geode;
                colors = new osg::Vec4Array;
                normals = new osg::Vec3Array;
coords->push_back(osg::Vec3(fabs(oldscale.x()),fabs(oldscale.y()),oldscale.z()));
coords->push_back(osg::Vec3(fabs(scale.x()),fabs(scale.y()),scale.z()));
                                               
        geom->setVertexArray(coords.get());
geom->addPrimitiveSet(new osg:rawArrays(osg::PrimitiveSet::LINES,0,2));
colors->push_back(osg::Vec4(1.0,0.0,0.0,1.0));
geom->setColorArray(colors.get());
geom->setColorBinding(osg::Geometry::BIND_OVERALL);
normals->push_back(osg::Vec3(0.0f,1.0f,1.0f));
geom->setNormalArray(normals.get());
geom->setNormalBinding(osg::Geometry::BIND_OVERALL);

geode->addDrawable(geom.get());
pat->addChild(geode.get());
                                               
pat->setPosition(osg::Vec3d(fabs(scale.x()),fabs(scale.y()),scale.z()));
}
oldscale = scale;

if(_newposition.x()!=_oldposition.x()&&_newposition.y()==_oldposition.y())
        scale = osg::Vec3(scale.x(),scale.y()+_speed,scale.z());                                               
else if(_newposition.x()==_oldposition.x()&&_newposition.y() != _oldposition.y())
        scale = osg::Vec3(scale.x()+_speed,scale.y(),scale.z());
else
        scale = osg::Vec3(scale.x()+_speed,scale.y()+_speed,scale.z());
                                       
}
                                               
}
        _oldposition = _newposition;
}
        traverse(node,nv);
               
}
                       
               
private:
        osg::ref_ptr<osg::Geometry> geom ;
        osg::ref_ptr<osg::Geode> geode;
        osg::ref_ptr<osg::Vec3Array> coords;
        osg::ref_ptr<osg::Vec4Array> colors;
        osg::ref_ptr<osg::Vec3Array> normals;
        osg::Vec3d _newposition;
        double _speed;
        osg::Vec3d _oldposition;
        osg::Vec3d _chushi;
        bool _weizhi;

};

该用户从未签到

 楼主| 发表于 2009-9-1 20:57:44 | 显示全部楼层
是不是观察矩阵的问题?如果是的话该怎么解决呢?谢谢。漫游器的话用的就是osgviewer的。

该用户从未签到

 楼主| 发表于 2009-9-1 21:10:06 | 显示全部楼层
其实就是想画出模型移动后的轨迹,不知道还有没有其他的方法来做呢?谢谢

该用户从未签到

发表于 2009-9-1 21:16:31 | 显示全部楼层
抱歉我暂时没有时间看这么长的代码。也许您可以精炼一下自己的问题和代码段

该用户从未签到

 楼主| 发表于 2009-9-1 21:19:50 | 显示全部楼层
我想说的是我在程序里用positionattitudetransform对模型进行了回调,我现在想把模型在回调后运动的轨迹给用线给画出来,不知道如何来做?谢谢

该用户从未签到

发表于 2009-9-1 22:52:16 | 显示全部楼层
用一个Geometry对象,然后每次都给它新增顶点和更新PrimitiveSet,顶点数最好有个上限,这样就可以了。不要总是新增节点,那样很恐怖的

该用户从未签到

 楼主| 发表于 2009-9-2 08:12:25 | 显示全部楼层
每次回调时,都把新生成的节点作为孩子节点放到positionattitudetransform下面,但是显示的时候不在正确的位置,是不是更新回调后坐标系给变化的?

该用户从未签到

发表于 2009-9-2 08:43:25 | 显示全部楼层
您把轨迹节点作为PAT的子节点放置的话,它是处于PAT的局部坐标系下的,当然要考虑PAT的变换矩阵

该用户从未签到

 楼主| 发表于 2009-9-2 08:47:48 | 显示全部楼层
pat的变换矩阵如何来求得呢?谢谢!

该用户从未签到

发表于 2009-9-2 12:22:25 | 显示全部楼层
参考computeLocalToWorldMatrix的代码吧
不过我个人不知道为什么一定要取得PAT的变换矩阵;我做过实时轨迹的绘制,不需要这么麻烦

该用户从未签到

 楼主| 发表于 2009-9-2 13:09:08 | 显示全部楼层
哦,那您有什么方便的方法吗?谢谢

该用户从未签到

发表于 2009-9-3 12:39:38 | 显示全部楼层
10# array

像Array说使用一个Geometry 每次增加顶点。 不要将Geometry附到pat下就行了。
我曾使用这个做过一个实现动态绘制最短路径的。

该用户从未签到

 楼主| 发表于 2009-9-3 14:08:04 | 显示全部楼层
[b] [url=http://bbs.osgchina.org/redirect.php?goto=findpost&pid=12889&ptid=2171]12#
那新生成的顶点如何加到场景下面呢?如果不添加新的节点的话?望指导。谢谢

该用户从未签到

发表于 2009-9-3 17:20:34 | 显示全部楼层
更新已有的节点和Geometry对象就可以了

该用户从未签到

 楼主| 发表于 2009-9-3 17:48:02 | 显示全部楼层
如何更新呢?我是直接把顶点加到geoetry下面啦。谢谢。

该用户从未签到

 楼主| 发表于 2009-9-3 20:42:17 | 显示全部楼层
老大帮帮忙吧,这个问题困扰了我三天啦,谢谢。我的程序里是模型移动的时候用了pat来放置位置,轨迹节点放在了pat节点下面。如果轨迹节点不放在pat下面的话,那有什么方法来显示轨迹节点呢?在线等

该用户从未签到

发表于 2009-9-3 21:35:33 | 显示全部楼层
本帖最后由 口口广大 于 2009-9-3 21:36 编辑

节点如果挂在pat下,那么就要采用pat的局部坐标系,比如pat从100运动到200,你如果将pat-〉getPosition()的位置付给了Geometry,相当于让Geometry在pat的当前位置又偏移了100~200,那么在世界坐标系下就偏的多了。有一个方法是将Geometry和pat同时挂在一个group下,采用同一个group的局部坐标系,那么这时只要不断的将pat的位置付给了Geometry就行。

该用户从未签到

 楼主| 发表于 2009-9-3 21:45:27 | 显示全部楼层
如果按您所说的方法,那geometry的顶点如何进行更新呢?它是模型移动后生成的轨迹,谢谢

该用户从未签到

发表于 2009-9-3 21:46:10 | 显示全部楼层
pat-〉getPosition()的位置付给了Geometry的VertexArray->push_back()

该用户从未签到

 楼主| 发表于 2009-9-3 21:57:38 | 显示全部楼层
嗯,我是这样设置的,但是显示的时候还是出错的。我是在main函数里,把pat的getposition给了geometry的顶点。模型回调的时候是每帧都会刷新的,但是相应的这个geometry的顶点数组无法进行更新了?请指点,谢谢

该用户从未签到

发表于 2009-9-3 22:44:15 | 显示全部楼层
更新顶点数组的同时,还要重新设置PrimitiveSet,除此之外没有什么特殊技巧可言

该用户从未签到

 楼主| 发表于 2009-9-4 10:00:30 | 显示全部楼层
那这个geometry如何添加到场景中呢?谢谢。

该用户从未签到

发表于 2009-9-4 21:32:42 | 显示全部楼层
添加给一个Geode不就可以了……

该用户从未签到

 楼主| 发表于 2009-9-5 15:59:52 | 显示全部楼层
呵呵,我是想问的是这个geode加在哪个节点下面呢?场景结点还是pat节点?谢谢

该用户从未签到

发表于 2009-9-5 19:52:20 | 显示全部楼层
都可以,这取决于您的需求。不过加在不同的节点下,就要遵从相应的局部坐标系,这一点要注意

该用户从未签到

 楼主| 发表于 2009-9-5 21:34:34 | 显示全部楼层
那加入场景根结点下的话,这个geometry的顶点信息如何更新呢?模型在移动,是用pat来进行每帧回调的,如何把pat的位置来实时的传给geometry呢?谢谢。

该用户从未签到

发表于 2009-9-6 09:43:28 | 显示全部楼层
方法很多……传递指针也好,用数据池也好,取决于您的需求,没有一定之规

该用户从未签到

 楼主| 发表于 2009-9-7 21:53:12 | 显示全部楼层
说实话我还是不知道如何去更新顶点属性?我在程序里是这样的
        while(!viewer->done())
        {       
                geom->setVertexArray( movecoords.get());
                geom->addPrimitiveSet(new  osg:rawArrays(osg:rimitiveSet:INES,0,movecoords->getNumElements()));       
                viewer->frame();
        }
movecoords是一个全局的vec3array,在模型更新回调nodecallback的时候给赋值的,然后geometry是加在场景的总结点下面的,请指点,谢谢

该用户从未签到

发表于 2009-9-7 23:29:21 | 显示全部楼层
您的程序逻辑上似乎存在比较严重的问题,在程序运行过程中不断addPrimitiveSet?我个人认为这是一个很疯狂的行为。麻烦您再整理一下自己的思路。

该用户从未签到

 楼主| 发表于 2009-9-8 10:46:20 | 显示全部楼层
是这样的,我用一个movecoords设为一个全局的vec3array,它的赋值是在节点回调的时候来进行的。主程序里设置了一个geometry,movecoords作为它的顶点数组,geode也是主程序里的一个节点,然后把geometry给加到geode里。主程序的根节点root->addChild(geode)。像您说的每次要进行顶点的更新,所以我用了上面的方法来进行更新,但是出问题的。所以我想请教一下您,如何对顶点进行每帧都更新呢?谢谢。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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