|
发表于 2015-12-19 10:37:01
|
显示全部楼层
您好!我问一下:做相机跟随的时候,跟随物的矩阵我这样获得osg::Matrix mat=osg::computeLocalToWorld(nv->getNodePath()); ,绑定船后相机方向与船头运动方向垂直,不知道怎么修改,麻烦您帮我看一下,谢谢!
整个跟随物运动类定义如下
//船舶运动回调
class BoatPcsitionCallback:public osg::NodeCallback
{
public:
BoatPcsitionCallback(osgOcean::OceanScene *oceanScene,boatDeviceStateType* boatDevState)
{
_oceanScene=oceanScene;
boatInputDeviceSta=boatDevState;
m_fMoveSpeed=0.8;
}
virtual void operator()(osg::Node* node,osg::NodeVisitor * nv)
{
if (nv->getVisitorType()==osg::NodeVisitor::UPDATE_VISITOR)
{
osg::MatrixTransform* mt=dynamic_cast<osg::MatrixTransform*>(node);
if (!mt ||! _oceanScene) return;
osg::Matrix mat=osg::computeLocalToWorld(nv->getNodePath());
osg::Vec3d pos=mat.getTrans();
osg::Vec3f normal;
float height=_oceanScene->getOceanSurfaceHeightAt(pos.x(),pos.y(),&normal);
float m_x=0.0;
float m_y=0.0;
static float m_Turn=0.0000;
if (boatInputDeviceSta->moveFwdOrBack==1)//前进
{
m_x=m_fMoveSpeed*cosf(m_Turn);
m_y=m_fMoveSpeed*sinf(m_Turn);
}
else if (boatInputDeviceSta->moveFwdOrBack==-1)//后退
{
m_x=-m_fMoveSpeed*cosf(m_Turn);
m_y=-m_fMoveSpeed*sinf(m_Turn);
}
else if (boatInputDeviceSta->moveFwdOrBack==0)//停止前进
{
m_x=0.0;
m_y=0.0;
}
if (boatInputDeviceSta->moveTurnLeftOrRight==1)//左转弯
{
m_Turn+=0.01;
}
else if (boatInputDeviceSta->moveTurnLeftOrRight==-1)//右转弯
{
m_Turn-=0.01;
}
mat.makeTranslate(osg::Vec3f(pos.x()+m_x,pos.y()+m_y,height));
osg::Matrix rot;
rot.makeIdentity();
rot.makeRotate(normal.x()/5,osg::Vec3f(1.0f,0.0f,0.0f),normal.y()/5,osg::Vec3f(0.0f,1.0f,0.0f),
m_Turn,osg::Vec3f(0.0f,0.0f,1.0f));
mat=rot*mat;
mat=mat;
mt->setMatrix(mat);
}
traverse(node, nv);
}
private:
osgOcean::OceanScene *_oceanScene;
boatDeviceStateType* boatInputDeviceSta;
/**船舶移动速度*/
float m_fMoveSpeed;
};
相机绑定类使用场景图形的方法computeWorldToLocal( osg::NodePath)来获取表达节点世界坐标的矩阵,整个相机类表达如下:
struct updateAccumulatoredMatrix:public osg::NodeCallback
{
virtual void operator()(osg::Node* node,osg::NodeVisitor* nv)
{
_matrix=osg::computeWorldToLocal(nv->getNodePath());
traverse(node,nv);
}
osg::Matrix _matrix;
};
struct transformAccumulator
{
public:
transformAccumulator()
{
_parent=NULL;
node=new osg::Node;
mpcb=new updateAccumulatoredMatrix;
node->setUpdateCallback(mpcb);
}
bool attachToGroup(osg::Group* g)
{
bool _success=false;
if (_parent!=NULL)
{
int n=_parent->getNumChildren();
for (int i=0;i<n;i++)
{
if (node==_parent->getChild(i))
{
_parent->removeChild(i,1);
_success=true;
}
}
if (!_success)
{
return _success;
}
}
g->addChild(node);
return true;
}
osg::Matrix getMatrix()
{
return mpcb->_matrix;
}
protected:
osg::ref_ptr<osg::Group> _parent;
osg::Node* node;
updateAccumulatoredMatrix* mpcb;
};
class followNodeMatrixManipulator:
public osgGA::CameraManipulator
{
public:
followNodeMatrixManipulator(transformAccumulator* ta)
{
worldCoordinatesOfNode=ta;
theMatrix=osg::Matrixd::identity();
}
//~followNodeMatrixManipulator();
virtual void setByMatrix(const osg::Matrixd& matrix)
{
theMatrix=matrix;
}
virtual void setByInverseMatrix(const osg::Matrixd& matrix)
{
theMatrix=osg::Matrix::inverse(matrix);
}
virtual osg::Matrixd getMatrix() const
{
return theMatrix;
}
virtual osg::Matrixd getInverseMatrix() const
{
//将矩阵从Y轴向上旋转到Z轴向上
osg::Matrixd _mat;
osg::Matrix rot;
rot.makeIdentity();
rot.makeRotate(-osg:I_2,osg::Vec3(0.0,0.0,1.0));
_mat=theMatrix* osg::Matrixd::rotate(-osg::PI_2,osg::Vec3(1.0,0,0));
return _mat;
}
void updateTheMatrix()
{
osg::Matrixd _mat1;
_mat1=osg::Matrixd::rotate(-osg::PI_2,osg::Vec3(0.0,0,1.0));
theMatrix=worldCoordinatesOfNode->getMatrix();
}
bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa)
{
switch(ea.getEventType())
{
case (osgGA::GUIEventAdapter::FRAME):
{
updateTheMatrix();
return false;
}
}
return false;
}
protected:
transformAccumulator* worldCoordinatesOfNode;
osg::Matrixd theMatrix;
};
|
|