查看: 2359|回复: 7

世界坐标转为屏幕坐标

[复制链接]

该用户从未签到

发表于 2009-7-29 21:02:13 | 显示全部楼层 |阅读模式
本帖最后由 dlhuaan 于 2009-7-29 23:30 编辑

osg::Vec3 objectPosition=osg::Vec3(0.,0.,0.);
osg::ref_ptr<osgUtil::SceneView> sv = new  osgUtil::SceneView();
sv->projectObjectIntoWindow( objectPosition, windowPos );

std::cout<< "Viewer Position X: "<<windowPos.x()<<" "<<windowPos.y()<<std::endl;

也就是projectObjectIntoWindow如何使用?现在求世界坐标0,0,0点在屏幕上的x,y坐标。

我用鼠标在屏幕上转动,平移(控制器是trackball),得出的结果windowPos.x()一直不变?按道理来说世界坐标的原点相对于屏幕也会动的啊?

上面的方法不知道什么地方不对。错在哪里呢?

该用户从未签到

 楼主| 发表于 2009-7-29 23:30:31 | 显示全部楼层
自己顶一下.

该用户从未签到

发表于 2009-7-30 00:52:23 | 显示全部楼层
坐标的转换请使用MVPW矩阵,即
V' = V * ModelView * Projection * WindowMatrix

的方式,世界坐标转屏幕坐标则是它的逆运算,我记得以前的帖子里回答过不止一次这个问题了。请您自行搜索一下

该用户从未签到

 楼主| 发表于 2009-7-30 23:14:07 | 显示全部楼层
本帖最后由 dlhuaan 于 2009-7-30 23:31 编辑

我查了以前论坛里的资料:windowCoord = worldCoord * VM * PM * WM

---------------------------------------------------------------------------------
原点世界坐标osg::Vec3(0.,0.,0.),以下代码:
osg::Vec3 winPos =osg::Vec3(0.,0.,0.)*(viewer->getCamera()->getViewMatrix() )* (viewer->getCamera()->getProjectionMatrix() )* (viewer->getCamera()->getViewport()->computeWindowMatrix());
std::cout <<"Windows Position X:"<<winPos.x()<<" Y: "<<winPos.y()<<" Z: "<<winPos.z()<<":::\n";

答案怎么不对呢?调了半天,没找出原因。
结果是:Windows Position X: -1.#IND Y: -1.#IND Z: -1.#IND

----------------------------------------------------------------
使用projectObjectIntoWindow方法,
世界坐标点osg::Vec3(0.,0.,0.)的Windows Position X: 400 Y:300,好像是正确的。

但是,世界坐标点osg::Vec3(-6.,0.,0.)的结果是:Windows Position X: -2000 Y:300
这个好像不对,我的屏幕分辨率是600x480,怎么会出来-2000呢?

我是新手,呵呵,概念有点混乱,查了一些网上的代码,不理解,困扰中~恳请版主或者大侠们解释一下。

该用户从未签到

 楼主| 发表于 2009-7-30 23:23:37 | 显示全部楼层
头像加上了,顶一个。呵呵。

该用户从未签到

发表于 2009-7-31 17:55:13 | 显示全部楼层
计算最好在仿真循环过程中完成,不然OSG可能还没有正确计算和生成某个矩阵的内容。
至于(-6.,0.,0.)为什么对应X: -2000 Y:300,这取决于您的观察矩阵和投影矩阵设置。当然有可能出现屏幕坐标超出窗口范围的情形,因为这个坐标点本身就在窗口之外了

该用户从未签到

 楼主| 发表于 2009-7-31 21:47:58 | 显示全部楼层
O了,谢谢array.还得是在循环中才行。我加了个camera callback,多日愁眉苦脸烟消云散~

class CameraCB : public osg::NodeCallback
{
public:
    CameraCB() : _angle( 0. ) {}

    virtual void operator()( osg::Node* node,
            osg::NodeVisitor* nv )
    {
        // Normally, check to make sure we have an update
        //   visitor, not necessary in this simple example.
                osg::Camera* cam =                dynamic_cast<osg::Camera*>( node );
   osg::Vec3 winPos =osg::Vec3(0.,0.,0.)*(cam->getViewMatrix() )* (cam->getProjectionMatrix() )* (cam->getViewport()->computeWindowMatrix());

        std::cout <<"Windows Position ::::"<<winPos.x()<<"::::"<<winPos.y()<<"::::"<<winPos.z()<<":::\n";
        traverse( node, nv );
    }


};

//////////////////以下是main()中///////////////////////////////////////////
viewer->getCamera()->setUpdateCallback( new CameraCB );

该用户从未签到

发表于 2009-9-12 18:12:27 | 显示全部楼层
楼上的,为什么生成的屏幕坐标点不是很精确?
还有就是另外一个问题,从全屏模式切换到窗口模式, 生成的屏幕坐标就一点也不对了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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