|
楼主 |
发表于 2009-10-21 17:15:15
|
显示全部楼层
我想实现这样一个功能:
选择一个模型后,摄像机自动移动到该模型的 相对位置。(即从模型的正前方观察该模型)
在未选择任何模型时,摄像机是可以随意操作的(平移、旋转、缩放等)。
现在的问题是: 中心点的位置可以平滑的过度, 但眼睛的位置怎样实现平滑过度啊?
附上代码,不对的地敬请指正, 才接触osg。
这个MatrixManipulator派生类是别人写的,理解得不是很明白..
- bool CityManipulator::handle(const GUIEventAdapter& ea,GUIActionAdapter& us)
- {
- osgViewer::Viewer* viewer = dynamic_cast<osgViewer::Viewer*> (&us);
- if( !viewer )
- return false;
- osg::Vec3d dis( _center-_centerTo );
- if( m_IsQuery && dis.length() > m_fMoveSpeed )
- {
- _center = _center + _toDirection * m_fMoveSpeed;
- return false;
- }
- else if(m_IsQuery)
- {
- _center = _centerTo; // 校位
- m_IsQuery = false;
- _homeEye[2] = _center[2]+100.f; // 调整观察位置
- _homeEye[1] = _center[1]-300.f;
- _homeEye[0] = _center[0];
- computePosition(_homeEye, _center, _homeUp);
- }
- }
- void CityManipulator::computePosition(const osg::Vec3d& eye,const osg::Vec3d& center,const osg::Vec3d& up)
- {
- if (!_node)
- return;
- // compute rotation matrix
- osg::Vec3d lv(center-eye);
- _distance = lv.length();
- _center = center;
- osg::Matrixd rotation_matrix = osg::Matrixd::lookAt(eye,center,up);
- _rotation = rotation_matrix.getRotate().inverse();
- osg::Quat tmp(-osg::PI/4, osg::Vec3(1.0,0,0));
- _rotation = _rotation*tmp;
- CoordinateFrame coordinateFrame = getCoordinateFrame(_center);
- _previousUp = getUpVector(coordinateFrame);
- clampOrientation();
- }
- void CityManipulator::clampOrientation()
- {
- osg::Matrixd rotation_matrix;
- rotation_matrix.makeRotate(_rotation);
- osg::Vec3d lookVector = -getUpVector(rotation_matrix);
- osg::Vec3d upVector = getFrontVector(rotation_matrix);
- CoordinateFrame coordinateFrame = getCoordinateFrame(_center);
- osg::Vec3d localUp = getUpVector(coordinateFrame);
- //osg::Vec3d localUp = _previousUp;
- osg::Vec3d sideVector = lookVector ^ localUp;
- if (sideVector.length()<0.1)
- {
- osg::notify(osg::INFO)<<"Side vector short "<<sideVector.length()<<std::endl;
- sideVector = upVector^localUp;
- sideVector.normalize();
- }
- Vec3d newUpVector = sideVector^lookVector;
- newUpVector.normalize();
- osg::Quat rotate_roll;
- rotate_roll.makeRotate(upVector,newUpVector);
- if (!rotate_roll.zeroRotation())
- {
- _rotation = _rotation * rotate_roll;
- }
- }
- osg::Matrixd CityManipulator::getInverseMatrix() const
- {
- return osg::Matrixd::translate(-_center)*osg::Matrixd::rotate(_rotation.inverse())
- *osg::Matrixd::translate(0.0,0.0,-_distance);
- }
复制代码 |
|