我要发帖 回复

高级会员

6

主题

1761

积分

0

专家分

兴趣点(最多三项):

视景仿真

私信
发表时间 : 2014-1-12 16:54:28 | 浏览 : 2874    评论 : 7
Vega Prime的DOF程序设计


1 引言
        在视景仿真应用中,使用DOF(Degree of Freedom,即自由度)技术可以使模型对象具有活动的能力,DOF节点可以控制它的所有子节点按照设置的自由度范围进行位移或者旋转。比如,为一个门的模型设置一个绕门轴转动的自由度,为一个窗户模型设置一个沿窗沿滑动的自由度,可以使门和窗按照符合逻辑的方式运动,这样可以大大增强模型数据库的真实性。又比如,我们想要场景里的某个物体绕着其自身的原点而不是整个场景的原点旋转,只需要为这个物体设置一个自由度节点即可。
        在下文中通过一个实例讲解DOF节点的程序设计方法,实例开发运行环境为:Windows XP SP3、Creator3.2、Vega Prime2.2.1、VS2005。

2 vsDOF类

        vsDOF类派生自vsNode类,用来定义和控制一个自由度节点,其在场景图里提供一种转换矩阵,典型地应用于关节模型中。与vsTransform类不同,vsDOF类实际上封装了两个矩阵,而不是一个。第一个矩阵是相对于父节点的本地矩阵(或称局部矩阵),第二个矩阵是相对于本地矩阵的转换矩阵。vsDOF节点允许在场景里相对于本地坐标系(或称局部坐标系)的任意一点进行位移和旋转,提供API用来指定本地坐标系和相对于本地坐标系的转换,该转换包含若干自由度和施加在这些自由度上的最大最小值限制。这些自由度包括:X、Y、Z轴上的位移,H、P、R上的旋转,沿X、Y、Z轴上的缩放因子。六自由度X、Y、Z、H、P、R的定义如图1坐标系所示,符合笛卡尔坐标系中的右手定则。
1.jpg

图1 坐标系

        在这个坐标系中,假设我们站在负Y轴上,面向正Y轴,那么X、Y、Z、H、P、R定义如下:
        ▲  +X指向右,-X指向左;
        ▲  +Y指向前,-Y指向后;
        ▲  +Z指向上,-Z指向下;
        ▲  朝向角Heading是指绕Z轴的旋转,+H指向左旋转,-H指向右旋转;
        ▲  倾斜角Pitch是指绕X轴的旋转,+P指向上旋转,-P指向下旋转;
        ▲  滚转角Roll是指绕Y轴的旋转,+R指向右旋转,-R指向左旋转。
        
vsDOF类的主要成员函数如下:
        ●  void   setTranslate (double x, double y, double z, bool incr=false)
          void   getTranslate (double *x, double *y, double *z) const
        功能:设置/获取X、Y、Z轴上的位移。

        ●  void   setTranslateX (double x, bool incr=false)
        double getTranslateX () const
        功能:设置/获取X轴上的位移。

        ●  void   setTranslateY (double y, bool incr=false)
        double getTranslateY () const
        功能:设置/获取Y轴上的位移。

        ●  void   setTranslateZ (double z, bool incr=false)
        double getTranslateZ () const
        功能:设置/获取Z轴上的位移。

        ●  void   setRotate (double h, double p, double r, bool incr=false)
        void   getRotate (double *h, double *p, double *r) const
        功能:设置/获取H、P、R姿态。

        ●  void   setRotateH (double h, bool incr=false)
        double getRotateH () const
        功能:设置/获取朝向角H。

        ●  void   setRotateP (double p, bool incr=false)
        double getRotateP () const
        功能:设置/获取倾斜角P。

        ●  void   setRotateR (double r, bool incr=false)
        double getRotateR () const
        功能:设置/获取滚转角R。

        ●  void   setScale (double x, double y, double z, bool incr=false)
        void   getScale (double *x, double *y, double *z) const
        功能:设置/获取X、Y、Z轴上的缩放因子。

        ●  void   setScaleX (double x, bool incr=false)
        double getScaleX () const
        功能:设置/获取X轴上的缩放因子。

        ●  void   setScaleY (double y, bool incr=false)
        double getScaleY () const
        功能:设置/获取Y轴上的缩放因子。

        ●  void   setScaleZ (double z, bool incr=false)
        double getScaleZ () const
        功能:设置/获取Z轴上的缩放因子。

        ●  void   setConstraint (Component component, const Constraint &c)
        const  Constraint & getConstraint (Component component) const
        功能:设置/获取某个自由度的范围。其中,第一个参数Component定义如下:
  1. enum Component
  2. {
  3.   COMPONENT_TRANSLATE_X,  //Translation along the x axis.
  4.   COMPONENT_TRANSLATE_Y,  //Translation along the y axis.
  5.   COMPONENT_TRANSLATE_Z,  //Translation along the z axis.
  6.   COMPONENT_ROTATE_H,     //Rotation around the z axis.
  7.   COMPONENT_ROTATE_P,     //Rotation around the x axis.
  8.   COMPONENT_ROTATE_R,     //Rotation around the y axis.
  9.   COMPONENT_SCALE_X,      //Scale along the x axis.
  10.   COMPONENT_SCALE_Y,      //Scale along the y axis.
  11.   COMPONENT_SCALE_Z       //Scale along the z axis.
  12. }
复制代码
3 DOF程序设计

       在Vega Prime应用程序中使用DOF技术,包括如下几个步骤:
              ⑴ 创建DOF节点;
               ⑵ 设置DOF节点的子节点;
              ⑶ 设置DOF节点的本地坐标系;
              ⑷ 设置DOF节点的自由度范围;
              ⑸ 控制DOF节点。

3.1创建DOF节点

       在实时可视化三维建模软件Creator中,DOF节点跟组节点级别相同,所以必须用组节点或其它同等级别的节点(如LOD节点)作为DOF节点的父节点。用户可以使用Creator提供的创建工具箱中的创建DOF工具在模型数据库的层级视图中创建DOF节点。

3.2设置DOF节点的子节点

       将需要设置自由度的模型对象的对应节点设置为DOF节点的子节点。DOF节点可以控制层级视图中它的所有子节点,包括子DOF节点,且DOF节点属性具有继承性,以保证所有的子节点都能符合逻辑的运动。


3.3设置DOF节点的本地坐标系
       为模型对象定义自由度,必须设置相应的本地坐标系,因为模型对象的所有自由度运动都是相对于本地坐标系进行的。创建DOF节点后,Creator会在模型数据库的原点上设置一个默认的本地坐标系,通常需要对其重新定位。定位方法是选择DOF节点,选择菜单命令“Local-DOF”-“Position DOF”,打开对话框如图2所示,按照对话框提示,在图形视图中依次确定DOF节点的本地坐标系原点、X轴和Y轴。
2.jpg

图2 DOF本地坐标系

3.4设置DOF节点的自由度范围
       DOF节点的自由度属性都是相对于本地坐标系而言的,默认值均为0,需要对其重新设置。设置方法是选择DOF节点,选择菜单命令“Local-DOF”-“Set DOF Limits”,打开对话框如图3所示,在此对话框中,对DOF节点的位移和旋转范围进行设置。
3.jpg

图3 DOF自由度范围


3.5控制DOF节点
       在Vega Prime应用程序中,使用vsDOF类实例控制模型对象中的DOF节点。下面结合一个基于MFC单文档框架的Vega Prime应用实例,给出主要编程步骤如下:
       ⑴ 在视图类头文件中添加vsDOF类的头文件
       #include "vsDOF.h"
       ⑵ 在视图类头文件中添加相关变量定义
       // 属性
       public:
               vpObject        *m_OBJ;                //指向模型对象类的指针
               vsDOF                *m_DOF;                //指向vsDOF类的指针
               CString                str1OBJ;        //模型对象的名字
               CString                str2DOF;        //DOF节点的名字


       ⑶ 在视图类实现文件中初始化DOF节点
  1. //初始化DOF节点
  2. void Cvp_sdiView::OnDOFInit()
  3. {
  4.         // TODO: 在此添加命令处理程序代码
  5.         CDOFdlg dlg;
  6.         dlg.ObjectName=str1OBJ;
  7.         dlg.DOFName=str2DOF;
  8.         if(dlg.DoModal()==IDOK)
  9.         {
  10.                 //模型对象的名字
  11.                 str1OBJ=dlg.ObjectName;
  12.                 //DOF节点的名字
  13.                 str2DOF=dlg.DOFName;
  14.                 //获取模型对象的指针
  15.                 m_OBJ=vpObject::find((LPCTSTR)str1OBJ);
  16.                 if(m_OBJ==NULL) return;
  17.                 m_OBJ->ref();
  18.                 //获取模型对象上DOF节点的指针
  19.                 m_DOF=static_cast<vsDOF*>(m_OBJ->find_named((LPCTSTR)str2DOF));
  20.                 if(m_DOF==NULL) return;
  21.                 m_DOF->ref();
  22.                 //设置自由度范围,此处可以根据具体情况修改
  23.                 //如果用模型本身定义的值,此处代码可以省略
  24.                 vsDOF::Constraint constraint;
  25.                 constraint.m_enable=TRUE;
  26.                 constraint.m_min=0.0;
  27.                 constraint.m_max=360.0;
  28.                 m_DOF->setConstraint(vsDOF::COMPONENT_ROTATE_H,constraint);
  29.                 constraint.m_enable=TRUE;
  30.                 constraint.m_min=0.0;
  31.                 constraint.m_max=360.0;
  32.                 m_DOF->setConstraint(vsDOF::COMPONENT_ROTATE_P,constraint);
  33.                 constraint.m_enable=TRUE;
  34.                 constraint.m_min=0.0;
  35.                 constraint.m_max=360.0;
  36.                 m_DOF->setConstraint(vsDOF::COMPONENT_ROTATE_R,constraint);
  37.         }
  38. }
复制代码
⑷ 在视图类实现文件中调整DOF节点
  1. //键盘响应消息处理
  2. void Cvp_sdiView::onKeyInput(vrWindow::Key key, int mod)
  3. {
  4.         switch (key)
  5.         {
  6.                 ……
  7.         case vrWindow::KEY_q:                //调整朝向角H++
  8.                 if(m_DOF)
  9.                 {
  10.                         m_DOF->setRotateH(1.0,true);
  11.                 }
  12.                 break;
  13.         case vrWindow::KEY_w:                //调整朝向角H--
  14.                 if(m_DOF)
  15.                 {
  16.                         m_DOF->setRotateH(-1.0,true);
  17.                 }
  18.                 break;
  19.                 //////////////////////////////
  20.         case vrWindow::KEY_e:                //调整倾斜角P++
  21.                 if(m_DOF)
  22.                 {
  23.                         m_DOF->setRotateP(1.0,true);
  24.                 }
  25.                 break;
  26.         case vrWindow::KEY_r:                //调整倾斜角P--
  27.                 if(m_DOF)
  28.                 {
  29.                         m_DOF->setRotateP(-1.0,true);
  30.                 }
  31.                 break;
  32.                 /////////////////////////////////
  33.         case vrWindow::KEY_t:                //调整滚转角R++
  34.                 if(m_DOF)
  35.                 {
  36.                         m_DOF->setRotateR(1.0,true);
  37.                 }
  38.                 break;
  39.         case vrWindow::KEY_y:                //调整滚转角R--
  40.                 if(m_DOF)
  41.                 {
  42.                         m_DOF->setRotateR(-1.0,true);
  43.                 }
  44.                 break;
  45.         }
  46. }
复制代码
在程序实例中,通过ACF文件加载一个坦克模型对象tank,在坦克模型里定义3个DOF节点,分别是tankDOF控制坦克整体运动,turretDOF控制炮塔运动和barrelDOF控制炮管运动,程序运行界面截图如图4所示:
4.jpg

5.jpg   


图4 控制DOF节点



4 结语

          在视景仿真应用中,使用DOF技术可以使模型对象具有活动的能力,自由度节点用于为模型对象设置一定的可运动范围,从而为其增加动态效果。通过实例讲解了DOF节点的程序设计方法,在此基础上可以在视景仿真中开发具体的DOF应用。

评分

参与人数 2积分 +50 VR币 +50 收起 理由
汽车站 + 50 很给力!
obuil + 50 赞一个!

查看全部评分

最近VR访客查看更多↓

哼哈嘣吧 评论于2014-1-12 17:11:48
不错不错,写的很详细。
jia2563422 评论于2014-1-12 22:13:31
虽然对程序部分还看不太懂,本来c c++  vc都是一知半解,
希望能早日看懂,早日编出自己的程序。
谢谢楼主分享!!
sichuanwww 评论于2014-1-13 09:15:47
写得非常好,
下一篇可以写写利用DOF进行精确组装的东西。
努力挣钱,快乐生活!
first001 评论于2014-1-14 08:24:11
受益匪浅,谢谢楼主
iamdela 评论于2015-1-6 16:03:20
楼主好厉害
zhaopan1682003专家组 评论于2015-6-3 20:32:15
谢谢学习了!
sowinwong 评论于2017-12-23 20:57:52

不错不错,写的很详细。

手机版|VR开发网 统计 津ICP备18009691号
网安备12019202000257

GMT+8, 2021-5-13 11:13 AM

返回顶部