|
本帖最后由 zhoujiajun2010 于 2010-12-30 11:41 编辑
#include <osgViewer/Viewer>
#include <osgViewer/View>
#include <osgViewer/ViewerEventHandlers>
#include <osg/Node>
#include <osg/Geode>
#include <osg/Group>
#include <osg/Geometry>
#include <osg/MatrixTransform>
#include <osg/PositionAttitudeTransform>
#include <osg/Camera>
#include <osgViewer/CompositeViewer>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <osgUtil/Optimizer>
#include <osgGA/TrackballManipulator>
#include <iostream>
struct updateAccumlatedMatrix : 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();
bool attachToGroup(osg::Group* g);
osg::Matrix getMatrix();
protected:
osg::ref_ptr<osg::Group> parent;
osg::Node* node;
updateAccumlatedMatrix* mpcb;
};
// 类的实现代码如下所示:
transformAccumulator::transformAccumulator()
{
parent = NULL;
node = new osg::Node;
mpcb = new updateAccumlatedMatrix();
node->setUpdateCallback(mpcb);
}
osg::Matrix transformAccumulator::getMatrix()
{
return mpcb->matrix;
}
bool transformAccumulator::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;
};
class followNodeMatrixManipulator : public osgGA::MatrixManipulator
{
public:
followNodeMatrixManipulator( transformAccumulator* ta);
bool handle (const osgGA::GUIEventAdapter&ea, osgGA::GUIActionAdapter&aa);
void updateTheMatrix();
virtual void setByMatrix(const osg::Matrixd& mat) {theMatrix = mat;}
virtual void setByInverseMatrix(const osg::Matrixd&mat) {}
virtual osg::Matrixd getInverseMatrix() const;
virtual osg::Matrixd getMatrix() const;
protected:
~followNodeMatrixManipulator() {}
transformAccumulator* worldCoordinatesOfNode;
osg::Matrixd theMatrix;
};
followNodeMatrixManipulator::followNodeMatrixManipulator( transformAccumulator* ta)
{
worldCoordinatesOfNode = ta; theMatrix = osg::Matrixd::identity();
}
void followNodeMatrixManipulator::updateTheMatrix()
{
theMatrix = worldCoordinatesOfNode->getMatrix();
}
osg::Matrixd followNodeMatrixManipulator::getMatrix() const
{
return theMatrix;
}
osg::Matrixd followNodeMatrixManipulator::getInverseMatrix() const
{
// 将矩阵从 Y轴向上旋转到Z 轴向上
osg::Matrixd m;
m = theMatrix * osg::Matrixd::rotate(-3.1415926/2.0, osg::Vec3(1,0,0) );
return m;
}
bool followNodeMatrixManipulator::handle
(const osgGA::GUIEventAdapter&ea, osgGA::GUIActionAdapter&aa)
{
switch(ea.getEventType())
{
case (osgGA::GUIEventAdapter::FRAME):
{
updateTheMatrix();
return false;
}
}
return false;
}
void createView (osgViewer::CompositeViewer *viewer,
osg::ref_ptr<osg::Group> scene,
osg::ref_ptr<osg::GraphicsContext> gc,
osgGA::TrackballManipulator* Tman,
int x, int y, int width, int height)
{
double left,right,top,bottom,near,far, aspectratio;
double frusht, fruswid, fudge;
bool gotfrustum = true;
// 向最终的组合视口添加一个新的视口,并设置其操控方式。
osgViewer::View* view = new osgViewer::View;
viewer->addView(view);
view->setCameraManipulator(Tman);
// 设置视口的场景数据,并设置摄像机的截锥坐标。
view->setSceneData(scene.get());
view->getCamera()->setViewport(new osg::Viewport(x,y, width,height));
view->getCamera()-> getProjectionMatrixAsFrustum(left,right,
bottom,top,
near,far);
if (gotfrustum)
{
aspectratio = (double) width/ (double) height;
frusht = top - bottom;
fruswid = right - left;
fudge = frusht*aspectratio/fruswid;
right = right*fudge;
left = left*fudge;
view->getCamera()-> setProjectionMatrixAsFrustum(left,right,bottom,top,near,far);
}
view->getCamera()->setGraphicsContext(gc.get());
// 添加渲染状态控制器
osg::ref_ptr<osg::StateSet> statesetManipulator = new osg::StateSet();
statesetManipulator=view->getCamera()->getOrCreateStateSet();
// statesetManipulator->setStateSet(view->getCamera()->getOrCreateStateSet());
//view->addEventHandler( statesetManipulator.get() );
}
int main( int argc, char **argv )
{
// 场景根节点和坦克模型节点指针。
osg::ref_ptr<osg::Group> rootNode;
osg::ref_ptr<osg::Group> ownTank;
osgGA::TrackballManipulator *Tman1 = new osgGA::TrackballManipulator();
osgGA::TrackballManipulator *Tman2 = new osgGA::TrackballManipulator();
// 建立场景和坦克。
// if (!setupScene(rootNode, ownTank))
// {
// std::cout<< "problem setting up scene" << std::endl;
// return -1;
// }
// 声明一个位于坦克偏后上方的位移变换节点。将其添加到坦克节点。
osg:ositionAttitudeTransform * followerOffset = new osg::PositionAttitudeTransform();
followerOffset->setPosition( osg::Vec3(0.0,-25.0,10) );
followerOffset->setAttitude( osg:uat( osg:egreesToRadians(-15.0), osg::Vec3(1,0,0) ) );
ownTank.get()->addChild(followerOffset);
// 声明一个自定义的位移累加器类,以便放置相机。将其关联给上面的变换节点。
//
transformAccumulator*tankFollowerWorldCoords = new transformAccumulator();
tankFollowerWorldCoords->attachToGroup(followerOffset);
// 构建视口类,以及与其相关的图形设备类。
osgViewer::CompositeViewer viewer;
osg::GraphicsContext::WindowingSystemInterface* wsi =osg::GraphicsContext::getWindowingSystemInterface();
if (!wsi)
{
osg::notify(osg::NOTICE)
<<"Error, no WindowSystemInterface available, cannot create windows."<<std::endl;
return 1;
}
unsigned int width, height;
wsi->getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0), width, height);
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
traits->x = 100;
traits->y = 100;
traits->width = width;
traits->height = height;
traits->windowDecoration = true;
traits->doubleBuffer = true;
traits->sharedContext = 0;
osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());
if (gc.valid())
{
osg::notify(osg::INFO)<<"GraphicsWindow has been created successfully."<<std::endl;
gc->setClearColor(osg::Vec4f(0.2f,0.2f,0.6f,1.0f));
gc->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
else
{
osg::notify(osg::NOTICE)<<" GraphicsWindow has not been created successfully."<<std::endl;
}
// 第一个视口
createView (&viewer,rootNode,gc,Tman1,0, 0, traits->width/2, traits->height);
// 第二个视口
createView (&viewer,rootNode,gc,Tman2,traits->width/2, 0, traits->width/2, traits->height);
viewer.setThreadingModel(osgViewer::CompositeViewer::SingleThreaded);
while( !viewer.done() )
//{
// 获取跟踪摄像机的句柄。使用相应的方法设置坦克跟踪相机的世界坐标位置矩阵。
// 注意该矩阵需要从 Y轴向上旋转到Z 轴向上的坐标系。
Tman2->setByInverseMatrix(tankFollowerWorldCoords->getMatrix() *osg::Matrix::rotate( osg::PI_2*3, osg::Vec3(1.0, 0.0, 0.0 )));
viewer.frame();
//}
return 0;
}
不知什么原因,编译可以,但是老是执行不了,请高手指点,非常感谢 |
|