查看: 2160|回复: 5

【求助】OSG中拖拽器的约束器Constraint使用问题

[复制链接]

该用户从未签到

发表于 2012-9-17 14:39:45 | 显示全部楼层 |阅读模式
本帖最后由 xulin_2005 于 2012-9-17 15:09 编辑

问题描述:
    在制作自定义的拖拽器时,想继承其自带的Constraint类来实现对模型拖拽的约束,但发现在VS2005下的STLvector下,因为类型的强制转换,导致了在调用拖拽器时,对象的类型被强制改成了父类型,导致无法使用继承后的Constraint类,想问下谁有什么好的办法可以改进?
相关代码和描述:
Dragger.cpp中的代码:
(*itr)->constrain(command); // 关键这里的强制转换把指针的真实类型给截断掉了
  1. void Dragger::dispatch(MotionCommand& command)
  2. {
  3. // apply any constraints
  4. for(Constraints::iterator itr = _constraints.begin();
  5. itr != _constraints.end();
  6. ++itr)
  7. {
  8. (*itr)->constrain(command); // 关键这里的强制转换把指针的真实类型给截断掉了
  9. }

  10. // move self
  11. getParentDragger()->receive(command);


  12. for(DraggerCallbacks::iterator itr = getParentDragger()->getDraggerCallbacks().begin();
  13. itr != getParentDragger()->getDraggerCallbacks().end();
  14. ++itr)
  15. {
  16. (*itr)->receive(command);
  17. }
  18. }
复制代码

Constraint中的代码
virtual bool constrain(MotionCommand&) const { return false; } // 永远只会调用这一句
  1. class OSGMANIPULATOR_EXPORT Constraint : public osg::Referenced
  2. {
  3. public:

  4. virtual bool constrain(MotionCommand&) const { return false; } // 永远只会调用这一句
  5. virtual bool constrain(TranslateInLineCommand& command) const { return constrain((MotionCommand&)command); }
  6. virtual bool constrain(TranslateInPlaneCommand& command) const { return constrain((MotionCommand&)command); }
  7. virtual bool constrain(Scale1DCommand& command) const { return constrain((MotionCommand&)command); }
  8. virtual bool constrain(Scale2DCommand& command) const { return constrain((MotionCommand&)command); }
  9. virtual bool constrain(ScaleUniformCommand& command) const { return constrain((MotionCommand&)command); }


复制代码

Vector中的代码
return ((reference)**(_Mybase *)this);     // 这里的_Mybase类型和reference类型转换把原先的类型给截断了

  1. reference operator*() const
  2. { // return designated object
  3.      return ((reference)**(_Mybase *)this);     // 这里的_Mybase类型和reference类型转换把原先的类型给截断了
  4. }
复制代码

验证vector中的示例代码:
在下面的例子中我用了一个 vector 存放 ref_ptr<CDoParent> 的指针列表,在 OutInfo() 中,用迭代器重新遍历获取出来,再调用,发现此时调用的全都是 CDoParent:o(CCmd & cmd),其他的已经无法调用了。
  1. class CCmd;

  2. class CDoParent : public osg::Referenced
  3. {
  4. public:
  5. void Do( CCmd & cmd ) { cout << "CDoParent::Do(CCmd & cmd);" << endl; }
  6. };

  7. class CADo : public CDoParent
  8. {
  9. public:
  10. void Do( CCmd & cmd ) { cout << "CADo::Do(CCmd & cmd);" << endl; }
  11. };

  12. class CBDo : public CDoParent
  13. {
  14. public:
  15. void Do( CCmd & cmd ) { cout << "CBDo::Do(CCmd & cmd);" << endl; }
  16. };

  17. class CCmd : public osg::Referenced
  18. {
  19. protected:
  20. virtual ~CCmd() {};
  21. std::vector<osg::ref_ptr<CDoParent>> m_doList;
  22. std::vector<osg::ref_ptr<CDoParent>>::iterator m_doListIter;
  23. public:
  24. CCmd() {};

  25. void addDo(CDoParent & todo) { m_doList.push_back(&todo); }

  26. virtual void f( CDoParent & todo ) { todo.Do(*this); }
  27. virtual void f( CADo & todo ) { todo.Do(*this); }
  28. virtual void f( CBDo & todo ) { f((CDoParent&)todo); }

  29. void OutInfo()
  30. {
  31. for ( m_doListIter = m_doList.begin(); m_doListIter != m_doList.end(); ++m_doListIter )
  32. {
  33. CDoParent doParent;
  34. CADo Ado;
  35. CBDo Bdo;

  36. //f(*(m_doListIter->get()));
  37. if ( typeid(CDoParent) == typeid(m_doListIter->get()) )
  38. f( doParent );
  39. else if ( typeid(CADo) == typeid(m_doListIter->get()) )
  40. f( Ado );
  41. else if ( typeid(CBDo) == typeid(m_doListIter->get()) )
  42. f( Bdo );
  43. else
  44. cout << "can't find the type" << endl;
  45. }
  46. }
  47. };

  48. class CMotionCmd : public CCmd
  49. {
  50. protected:
  51. virtual ~CMotionCmd() {};
  52. public:
  53. CMotionCmd() {};

  54. virtual void f( CDoParent & todo ) { cout << "CMotionCmd::f() {" << endl; todo.Do(*this); cout << "}" << endl; }
  55. virtual void f( CADo & todo ) { cout << "CMotionCmd::f() {" << endl; todo.Do(*this); cout << "}" << endl; }
  56. virtual void f( CBDo & todo ) { cout << "CMotionCmd::f() {" << endl; f((CDoParent &)todo); cout << "}" << endl; }
  57. };

  58. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  59. void test()
  60. {
  61. std::vector< osg::ref_ptr<CCmd>> cmdList;
  62. std::vector< osg::ref_ptr<CCmd>>::iterator cmdListIter;

  63. osg::ref_ptr<CDoParent> todo = NULL;
  64. osg::ref_ptr<CCmd> cmd = NULL;
  65. cmd = new CCmd;
  66. todo = new CDoParent;
  67. cmd->addDo(*(todo.release()));
  68. todo = new CADo;
  69. cmd->addDo(*(todo.release()));
  70. todo = new CBDo;
  71. cmd->addDo(*(todo.release()));
  72. cmdList.push_back(cmd.release());
  73. cmd = new CMotionCmd;
  74. todo = new CDoParent;
  75. cmd->addDo(*(todo.release()));
  76. todo = new CADo;
  77. cmd->addDo(*(todo.release()));
  78. todo = new CBDo;
  79. cmd->addDo(*(todo.release()));
  80. cmdList.push_back( cmd.release());

  81. for ( cmdListIter = cmdList.begin(); cmdListIter != cmdList.end(); ++cmdListIter )
  82. {
  83. (*cmdListIter)->OutInfo();
  84. }

  85. }
复制代码

该用户从未签到

发表于 2012-9-17 14:45:01 | 显示全部楼层
虚函数 您不知道是什么意思么?

该用户从未签到

 楼主| 发表于 2012-9-17 14:53:48 | 显示全部楼层
liuzhiyu123 发表于 2012-9-17 14:45
虚函数 您不知道是什么意思么?

抱歉,烦请再看下贴,刚才把代码重新整理了下,不是虚函数怎么用的问题,而是OSG的那部分代码由于使用了vector导致虚函数无法起到任何作用,对于这个问题,想问下如果不改动OSG的源码,是否有好的办法解决~~

该用户从未签到

发表于 2012-9-17 15:43:43 | 显示全部楼层
xulin_2005 发表于 2012-9-17 14:53
抱歉,烦请再看下贴,刚才把代码重新整理了下,不是虚函数怎么用的问题,而是OSG的那部分代码由于使用了v ...

没有发现您的问题,Constraint用起来没有什么问题,从写Constraint()就可以了

该用户从未签到

 楼主| 发表于 2012-9-17 15:49:58 | 显示全部楼层
liuzhiyu123 发表于 2012-9-17 15:43
没有发现您的问题,Constraint用起来没有什么问题,从写Constraint()就可以了

我在代码里只是调用了下GridConstraint,发现最终只能执行Constraint::constrain(MotionCommand&)。
您说重写Constraint,那就是修改OSG的这部分代码么~~

该用户从未签到

发表于 2012-9-17 16:43:36 | 显示全部楼层
从新实现一个您自己的Constraint类,这回说的够明白了吧
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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