|
#include <osgViewer/Viewer>
#include <osgDB/ReadFile>
#include <osgGA/GUIEventAdapter>
#include <osgGA/GUIEventHandler>
#include <osgGA/CameraManipulator>
#include <osg/MatrixTransform>
#include <osg/ShapeDrawable>
class Follow: public osgGA::CameraManipulator
{
public:
Follow(osgViewer::Viewer *vv)
{
m_vPosition = osg::Vec3(0.0, 0.0, 3.0);
m_vRotation = osg::Vec3(osg:I_2, 0.0f, 0.0f);
m_fMoveSpeed = 2.0;
m_fAnglg = 2.5;
carPosition = osg::Vec3(0.0, 12.0, 0.0);
mt = CreateMT();
mt->setMatrix(osg::Matrixd::translate(osg::Vec3(0.0, 12.0, 0.0)));
viewer = vv;
if(viewer)
{
viewer->getSceneData()->asGroup()->addChild(mt);
}
}
virtual void setByMatrix(const osg::Matrixd& matrix)
{
}
virtual void setByInverseMatrix(const osg::Matrixd& matrix)
{
}
virtual osg::Matrixd getMatrix() const
{
osg::Matrixd mat;
mat.makeRotate(m_vRotation.x(), osg::Vec3(1.0, 0.0, 0.0),
m_vRotation.y(), osg::Vec3(0.0, 1.0, 0.0),
m_vRotation.z(), osg::Vec3(0.0, 0.0, 1.0));
return mat * osg::Matrixd::translate(m_vPosition);
}
virtual osg::Matrixd getInverseMatrix() const
{
osg::Matrixd mat;
mat.makeRotate(m_vRotation.x(), osg::Vec3(1.0, 0.0, 0.0),
m_vRotation.y(), osg::Vec3(0.0, 1.0, 0.0),
m_vRotation.z(), osg::Vec3(0.0, 0.0, 1.0));
return osg::Matrixd::inverse(mat * osg::Matrixd::translate(m_vPosition));
}
void ChangePosition(osg::Vec3 delta)
{
m_vPosition = osg::Vec3(m_vPosition.x(), m_vPosition.y(), 3.0);
m_vPosition += delta;
}
void ChangePositionCar(osg::Vec3 delta)
{
osg::Vec3 temp;
temp = osg::Vec3(m_vPosition.x(), m_vPosition.y(), 0.0);
mt->setMatrix(osg::Matrixd::translate(temp + delta));
carPosition = temp + delta;
}
void ChangePositionCarLeftRight(osg::Vec3 delta)
{
carPosition += delta;
mt->setMatrix(osg::Matrixd::translate(carPosition));
}
osg::Geode* CreateSphere()
{
osg::ref_ptr<osg::Geode> gnode = new osg::Geode;
gnode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0, 0.0, 1.0), 1)));
return gnode.release();
}
osg::MatrixTransform* CreateMT()
{
osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform;
mt->addChild(CreateSphere());
mt->setMatrix(osg::Matrix::translate(0.0, 0.0, 0.0));
return mt.release();
}
bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us)
{
switch(ea.getEventType())
{
case osgGA::GUIEventAdapter::KEYDOWN:
if(ea.getKey() == 'w' || ea.getKey() == 'W')
{
ChangePosition(osg::Vec3(m_fMoveSpeed * cosf(osg::PI_2 + m_vRotation[2]), m_fMoveSpeed*sinf(osg::PI_2 + m_vRotation[2]), 0));
ChangePositionCar(osg::Vec3(m_fMoveSpeed * 6 * cosf(osg::PI_2 + m_vRotation[2]), m_fMoveSpeed * 6 * sinf(osg::PI_2 + m_vRotation[2]), 0));
}
else if(ea.getKey() == 's' || ea.getKey() == 'S')
{
ChangePosition(osg::Vec3(-m_fMoveSpeed * cosf(osg::PI_2 + m_vRotation[2]), -m_fMoveSpeed*sinf(osg::PI_2 + m_vRotation[2]), 0));
ChangePositionCar(osg::Vec3(m_fMoveSpeed * 6 * cosf(osg::PI_2 + m_vRotation[2]), m_fMoveSpeed * 6 *sinf(osg::PI_2 + m_vRotation[2]), 0));
}
else if(ea.getKey() == 'a' || ea.getKey() == 'A')
{
ChangePosition(osg::Vec3(-m_fMoveSpeed * sinf(osg::PI_2 + m_vRotation[2]), m_fMoveSpeed * cosf(osg::PI_2 + m_vRotation[2]), 0));
ChangePositionCarLeftRight(osg::Vec3(-m_fMoveSpeed * sinf(osg::PI_2 + m_vRotation[2]), m_fMoveSpeed * cosf(osg::PI_2 + m_vRotation[2]), 0));
}
else if(ea.getKey() == 0xFF53) //右旋转
{
float temp = m_vRotation._v[2];
m_vRotation._v[2] -= osg:egreesToRadians(m_fAnglg);
ChangePosition(osg::Vec3(12*sin(m_vRotation._v[2]) - 12 * sin(temp), 12 * (1-cos(m_vRotation._v[2])) - 12*(1-cos(temp)), 0));
}
else if(ea.getKey() == 0xFF51) //左旋转
{
float temp = m_vRotation._v[2];
m_vRotation._v[2] += osg::DegreesToRadians(m_fAnglg);
ChangePosition(osg::Vec3(12*sin(m_vRotation._v[2]) - 12 * sin(temp), 12 * (1-cos(m_vRotation._v[2])) - 12*(1-cos(temp)), 0));
}
else
{
}
}
return false;
}
private:
osg::Vec3 m_vPosition;
osg::Vec3 m_vRotation;
float m_fMoveSpeed;
float m_fAnglg;
osg::Vec3 carPosition;
osg::MatrixTransform* mt;
osgViewer::Viewer *viewer;
};
int main()
{
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
viewer->setSceneData(osgDB::readNodeFile("zzu1.ive"));
viewer->setCameraManipulator(new Follow(viewer));
return viewer->run();
} |
|