查看: 1153|回复: 6

Array等版主们在吗?这个问题我和小伙伴们都解决不了了,

[复制链接]

该用户从未签到

发表于 2014-5-10 10:27:38 | 显示全部楼层 |阅读模式
本帖最后由 wpsperson 于 2014-5-15 10:42 编辑

CameraManipulator中X轴转角初始化...
在一些派生自MatrixManipulator(或者高版本的CameraManipulator)的类的初始构造函数中,为什么总要将绕着X轴的转角初始化为Pi/2?这样确实能够显示,但如果我初始化为0,通过之后的键盘操作将其改为Pi/2,却不显示场景了?这是怎么回事,原理上说不通啊?

该用户从未签到

发表于 2014-5-10 16:31:18 | 显示全部楼层
按你的描述的确说不通。
贴代码鉴定吧。

相机默认姿态是 Z轴负向为正前方。绕X轴转90度是为了水平看,一般把XY面作为水平面。


该用户从未签到

 楼主| 发表于 2014-5-10 21:04:45 | 显示全部楼层
cenfer 发表于 2014-5-10 16:31
按你的描述的确说不通。
贴代码鉴定吧。

在a.cpp文件中,构造函数如果xrot= osg:I_2;漫游正常(漫游交互按键注释中有),但如果xrot= 0;即便用F11和F12改变xrot的值并在控制台显示出xrot的值,也不能显示这个场景。
这是a.h的代码:
/*
程序功能:
·············利用键盘交互实现场景漫游··········
F1        沿着当前方向前行
F2        沿着当前方向后行
F3        沿着当前方向左移
F4        沿着当前方向右移
F5        向上平移
F6        向下平移


F7        沿着Z轴逆时针旋转
F8        沿着Z轴顺时针旋转
F9        沿着Y轴逆时针旋转
F10        沿着Y轴顺时针旋转
F11        沿着X轴逆时针旋转
F12        沿着X轴顺时针旋转


*/


#include <iostream>
#include <osgGA/GUIEventHandler>
#include <osgGA/CameraManipulator>
#include <osgGA/TrackballManipulator>
#include <osgViewer/Viewer>

class WPSCameraManipulator : public osgGA::CameraManipulator
{
public:
        WPSCameraManipulator(void);
        ~WPSCameraManipulator(void);
private:
        osg::Matrixd translateMatrix;
        osg::Matrixd rotateMatrix;
        osg::Vec3 pos;
        osg::Vec3 angle;
        float xtrans, ytrans, ztrans, xrot, yrot, zrot;
        float steplength, stepangle;//分别设置相机移动的位移基准长度,旋转基准角度。

public:
        // 虚函数
        virtual void setByMatrix(const osg::Matrixd& matrix);
        // 虚函数
        virtual void setByInverseMatrix(const osg::Matrixd& matrix);

        virtual osg::Matrixd getMatrix(void) const;
        // 得到逆矩阵
        virtual osg::Matrixd getInverseMatrix(void)const;
        // 主要事件控制器
        virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);
       
        void refresh(void);


};



这是a.cpp的代码:
#include "a.h"
#include <osg/Node>
#include <osgGA/GUIEventHandler>
#include <iostream>



WPSCameraManipulator::WPSCameraManipulator()

{
        xtrans = 0;
        ytrans = 0;
        ztrans= 0;
        //xrot= 0;
        xrot= osg::PI_2;
        yrot= 0;
        zrot= 0;
        steplength = 0.5;
        stepangle = osg::PI/20;

        pos.set(xtrans, ytrans, ztrans);
        angle.set(xrot, yrot, zrot);
        translateMatrix.makeIdentity();
        rotateMatrix.makeIdentity();

        translateMatrix = translateMatrix * osg::Matrixd::translate(pos);

        rotateMatrix.makeRotate(angle._v[0],osg::Vec3(1.0f, 0.0f, 0.0f),
                                                        angle._v[1],osg::Vec3(0.0f, 1.0f, 0.0f),
                                                        angle._v[2],osg::Vec3(0.0f, 0.0f, 1.0f));

       

}
//------------------------//------------------------------
WPSCameraManipulator::~WPSCameraManipulator()
{
}
//------------------------//------------------------------
void WPSCameraManipulator::setByMatrix(const osg::Matrixd& matrix)
{
}
//------------------------//------------------------------
void WPSCameraManipulator::setByInverseMatrix(const osg::Matrixd &matrix)
{
}
//------------------------//------------------------------
osg::Matrixd WPSCameraManipulator::getMatrix(void) const
{       
        return rotateMatrix * translateMatrix;
}
//------------------------//------------------------------
osg::Matrixd WPSCameraManipulator::getInverseMatrix (void) const
{
        return osg::Matrixd::inverse(rotateMatrix * translateMatrix);
}
       
        // 主要事件控制器
bool WPSCameraManipulator::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us)
{
        switch(ea.getEventType())
        {
        case(osgGA::GUIEventAdapter::KEYDOWN):
                {
                        if(ea.getKey()==0xFFBE)//F1
                        {
                                //!!!这里我解释一下,zrot是绕着Z轴的角度,初始时是0,也就是面向X轴正向,
                                //但osg的视图现实中,默认是面向Y轴正向,所以加了osg::PI_2使得面向x转为面向y
                                xtrans += steplength * cosf(zrot+osg::PI_2);
                                ytrans += steplength * sinf(zrot+osg::PI_2);
                                refresh();
                               
                        }
                        if(ea.getKey()==0xFFBF)
                        {
                                xtrans -= steplength * cosf(zrot+osg::PI_2);
                                ytrans -= steplength * sinf(zrot+osg::PI_2);
                                refresh();
                        }
                        if(ea.getKey()==0xFFC0)//F3
                        {
                                xtrans -= steplength * sinf(zrot+osg::PI_2);
                                ytrans += steplength * cosf(zrot+osg::PI_2);
                                refresh();
                               
                        }
                        if(ea.getKey()==0xFFC1)
                        {
                                xtrans += steplength * sinf(zrot+osg::PI_2);
                                ytrans -= steplength * cosf(zrot+osg::PI_2);
                                refresh();                               
                        }
                        if(ea.getKey()==0xFFC2)//F5
                        {
                                ztrans += steplength;
                                refresh();
                               
                        }
                        if(ea.getKey()==0xFFC3)
                        {
                                ztrans -= steplength;
                                refresh();                               
                        }               
                //------------------------//------------------------------
                        if(ea.getKey()==0xFFC4)//F7
                        {
                                zrot += stepangle;
                                refresh();
                               
                        }
                        if(ea.getKey()==0xFFC5)//F8
                        {
                                zrot -= stepangle;
                                refresh();                               
                        }
                        if(ea.getKey()==0xFFC6)
                        {
                                yrot += stepangle;
                                refresh();
                               
                        }
                        if(ea.getKey()==0xFFC7)
                        {
                                yrot -= stepangle;
                                refresh();               
                               
                        }
                        if(ea.getKey()==0xFFC8)
                        {
                                xrot += stepangle;
                                refresh();
                                std::cout<<"绕着X轴的角度是"<<xrot<<std::endl;
                               
                               
                        }
                        if(ea.getKey()==0xFFC9)
                        {                               
                               
                                xrot -= stepangle;
                                refresh();                               
                                std::cout<<"绕着X轴的角度是"<<xrot<<std::endl;
                               
                        }
               
                }
                break;
        case(osgGA::GUIEventAdapter:OUBLECLICK):
                {
               
                }
                break;
        default:break;
        }

        return false;
}

void WPSCameraManipulator::refresh()
{
        pos.set(xtrans, ytrans, ztrans);
        angle.set(xrot, yrot, zrot);
        translateMatrix.makeTranslate(pos);

        rotateMatrix.makeRotate(angle._v[0],osg::Vec3(1.0f, 0.0f, 0.0f),
                                                        angle._v[1],osg::Vec3(0.0f, 1.0f, 0.0f),
                                                        angle._v[2],osg::Vec3(0.0f, 0.0f, 1.0f));


}




主函数就比较简单了:
#include <osg/Node>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osgGA/TrackballManipulator>
#include <osg/MatrixTransform>
#include <iostream>
#include "a.h"


void main()
{
        osgViewer::Viewer viewer;
        osg::ref_ptr<osg::Group> root = new osg::Group();
        osg::ref_ptr<osg::Node> buildingnode = osgDB::readNodeFile("ceep.ive");
        root->addChild(buildingnode.get());
       
        viewer.setSceneData(root.get());
        WPSCameraManipulator* myCameramanipulator = new WPSCameraManipulator;
        viewer.setCameraManipulator(myCameramanipulator);
        viewer.setUpViewInWindow(700,500,500,500);
        viewer.realize();
        viewer.run();
}


这里的文件 ceep.ive可以再FreeSouth的群文件下到。二十多M附件放不下。
cenfer哥帮看看是什么情况?

a.cpp

3.71 KB, 下载次数: 1, 下载积分: 威望 1

漫游类实现

a.h

1.26 KB, 下载次数: 1, 下载积分: 威望 1

漫游类的定义

wps.cpp

641 Bytes, 下载次数: 0, 下载积分: 威望 1

主函数

该用户从未签到

发表于 2014-5-11 16:25:44 | 显示全部楼层
本帖最后由 cenfer 于 2014-5-11 16:35 编辑
wpsperson 发表于 2014-5-10 21:04
在a.cpp文件中,构造函数如果xrot= osg:I_2;漫游正常(漫游交互按键注释中有),但如果xrot= 0;即便用F ...


这个可能是个裁剪的Bug

用你的代码测试
我在XY添加了一个很大网格平面。


测试一
xtrans = 0;ytrans = 0;ztrans = 0;
xrot= 0;yrot= 0;zrot= 0;
初始场景不可见;
绕x轴正向或反向旋转任意角度,场景也不可见。

测试二
xtrans = 0;ytrans = 0;ztrans = 1000;
xrot= 0;yrot= 0;zrot= 0;
初始场景可见
绕x轴正向或反向旋转超过一定角度,场景不可见,返回,场景也不可见。

测试三
xtrans = 0;ytrans = 0;ztrans = 0;
xrot= osg:I_2;yrot= 0;zrot= 0;
初始场景可见
绕x轴正向或反向旋转超过一定角度,场景不可见,再返回场景可见。

测试四
xtrans = 0;ytrans = 0;ztrans = 1000;
xrot= osg::PI_2;yrot= 0;zrot= 0;
初始场景可见
绕x轴正向或反向旋转超过一定角度,场景不可见,返回,场景也不可见。


结论
1. 初始不可见的场景,即便相机调整到可见视野,也不可见
2. 场景和视点不相交,或者说和相机不相交,背离视野一定角度,永远不再可见。
3. 场景和视点相交,初始可见,只要场景在视野内就可见。

我怀疑 背离视野一定角度的场景 裁剪做了一定处理。
怎么让它们再次被绘制。
我是不知道有什么自动设置。

看来需要array老师了!!!

该用户从未签到

发表于 2014-5-11 16:28:36 | 显示全部楼层
本帖最后由 cenfer 于 2014-5-11 16:42 编辑

写错原来能编辑啊 楼上已编辑

该用户从未签到

发表于 2014-5-11 16:30:18 | 显示全部楼层
本帖最后由 cenfer 于 2014-5-11 16:42 编辑

周末被这样问题折磨,不好受啊!
array老师快来救救我们把!

该用户从未签到

 楼主| 发表于 2014-5-14 10:27:07 | 显示全部楼层
像我这样的新手遇到这种问题就得干瞪眼了,多谢cenfer的指点~
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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