查看: 1477|回复: 5

osg菜鸟求大侠帮忙~~

[复制链接]

该用户从未签到

发表于 2010-3-25 10:51:04 | 显示全部楼层 |阅读模式
小弟初学osg遇到一问题,请各位大侠出手相助,小弟不胜感激~~
我用书上的示例合成了一个程序,我想让视图三中的摄影机作为姿态摄影机,在飞机的侧上方显示飞机的实时姿态,但摄影机不是不随动,就是不显示,应该如何修改?源代码如下:
#include<osgViewer/Viewer>
#include<osgViewer/ViewerEventHandlers>
#include<osgViewer/CompositeViewer>
#include<osg/Node>
#include<osg/Geode>
#include<osg/Geometry>
#include<osg/Group>
#include<osg/Math>
#include<osg/AnimationPath>
#include<osg/PositionAttitudeTransform>
#include<osg/MatrixTransform>
#include<osg/Camera>
#include<osgGA/TrackballManipulator>
#include<osgDB/ReadFile>
#include<osgDB/WriteFile>
#include<osgUtil/Optimizer>
#include<iostream>

osg::ref_ptr<osg::AnimationPath>createAnimationPath(osg::Vec3&center,float radius,float looptime)
{
osg::ref_ptr<osg::AnimationPath>animationPath=new osg::AnimationPath();
animationPath->setLoopMode(osg::AnimationPath:OOP);
int numPoint=60;
float yaw=0.0f;
float yaw_delta=2.0f*osg:I/((float)(numPoint-1.0f));
float roll=osg::inDegrees(45.0f);
float time=0.0f;
float time_delta=looptime/((float)numPoint);

for(int i=0;i<numPoint;i++)
{
  osg::Vec3 position(center+osg::Vec3(sinf(yaw)*radius,cosf(yaw)*radius,0.0f));
  osg:uat rotation(osg::Quat(roll,osg::Vec3(0.0,1.0,0.0))*osg::Quat(-(yaw+osg::inDegrees(90.0f)),osg::Vec3(0.0,0.0,1.0)));
  animationPath->insert(time,osg::AnimationPath::ControlPoint(position,rotation));
  yaw+=yaw_delta;
  time+=time_delta;
}
return animationPath.get();
}
int main()
{
osg::ref_ptr<osg::Group>root=new osg::Group();
osg::ref_ptr<osg::Node>ss=osgDB::readNodeFile("cessna.osg");
osg::ref_ptr<osg::Node>node=osgDB::readNodeFile("lz.osg");
const osg::BoundingSphere&nk=node->getBound();
const osg::BoundingSphere&bs=ss->getBound();
osg::Vec3 position=bs.center()+osg::Vec3(0.0f,0.0f,200.0f);
float size=100.0f/bs.radius()*0.3f;
osg::ref_ptr<osg::AnimationPath>animationPath=new osg::AnimationPath();
animationPath=createAnimationPath(position,200.0f,10.0f);
std::string fileName("animation.path");
std:fstream out(fileName.c_str());
animationPath->write(out);
osg::ref_ptr<osg::MatrixTransform>mt=new osg::MatrixTransform();
mt->setDataVariance(osg::Object::STATIC);
mt->setMatrix(osg::Matrix::translate(-bs.center())*osg::Matrix::scale(size,size,size)*osg::Matrix::rotate(osg::inDegrees(-180.0f),(0.0f),0.0f,1.0f));
mt->addChild(ss.get());

osg::ref_ptr<osg::PositionAttitudeTransform>pat=new osg::PositionAttitudeTransform();
pat->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0f,1.0f));
pat->addChild(mt);
const osg::BoundingSphere&ps=pat->getBound();
root->addChild(pat.get());
root->addChild(node.get());
osgUtil::Optimizer op;
op.optimize(root.get());
op.optimize(pat.get());

osg::ref_ptr<osgViewer::CompositeViewer>viewer=new osgViewer::CompositeViewer();
osg::ref_ptr<osg::GraphicsContext::Traits>ts=new osg::GraphicsContext::Traits();
ts->x=100;
ts->y=100;
ts->width=900;
ts->height=700;
ts->windowDecoration=true;
ts->doubleBuffer=true;
ts->sharedContext=0;
osg::ref_ptr<osg::GraphicsContext>gc=osg::GraphicsContext::createGraphicsContext(ts.get());
if(gc->valid())
{
  osg::notify(osg::INFO)<<"GraphicsWindow has been createa 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::INFO)<<"GraphicsWindow has not been createa successfully."<<std::endl;
}
//视图一
{
  osg::ref_ptr<osgViewer::View>view=new osgViewer::View;
  viewer->addView(view.get());
  view->setSceneData(root.get());
  double fovy,aspectRatio,zNear,zFar;
  view->getCamera()->getProjectionMatrixAsPerspective(fovy,aspectRatio,zNear,zFar);
  double newAspectRatio=double(ts->width*2/3)/double(ts->height);
  double aspectRatioChange=newAspectRatio/aspectRatio;
  if(aspectRatioChange!=1.0)
  {
   view->getCamera()->getProjectionMatrix()*=osg::Matrix::scale(1./aspectRatioChange,1.0,1.0);
  }
  view->getCamera()->setViewport(new osg::Viewport(0,0,ts->width*2/3,ts->height));
  view->getCamera()->setGraphicsContext(gc.get());
  view->setCameraManipulator(new osgGA::TrackballManipulator);
  view->addEventHandler(new osgViewer::StatsHandler);
  view->addEventHandler(new osgViewer::WindowSizeHandler);
  view->addEventHandler(new osgViewer::ThreadingHandler);
  view->addEventHandler(new osgViewer::RecordCameraPathHandler);
}
//视图二
{
  osg::ref_ptr<osgViewer::View>view=new osgViewer::View;
  viewer->addView(view.get());
  osg::ref_ptr<osg::Camera>camera=new osg::Camera();
  camera->setViewMatrixAsLookAt(nk.center()+osg::Vec3f(400.0,0.0,0.0),nk.center(),osg::Vec3f(0.0,0.0,-1.0));
  camera->addChild(root.get());
  view->setSceneData(camera);
  double fovy,aspectRatio,zNear,zFar;
  view->getCamera()->getProjectionMatrixAsPerspective(fovy,aspectRatio,zNear,zFar);
  double newAspectRatio=double(ts->width/3)/double(ts->height/2);
  double aspectRatioChange=newAspectRatio/aspectRatio;
  if(aspectRatioChange!=1.0)
  {
   view->getCamera()->getProjectionMatrix()*=osg::Matrix::scale(1./aspectRatioChange,1.0,1.0);
  }
  view->getCamera()->setViewport(new osg::Viewport(ts->width*2/3,ts->height/2,ts->width/3,ts->height/2));
  view->getCamera()->setGraphicsContext(gc.get());
  view->setCameraManipulator(new osgGA::TrackballManipulator);
}
//视图三
{
  osg::ref_ptr<osgViewer::View>view=new osgViewer::View;
  viewer->addView(view.get());
  osg::ref_ptr<osg::Camera>camera=new osg::Camera();
  camera->setViewMatrixAsLookAt(bs.center()+osg::Vec3f(0.0,0.0,2*bs.radius()),bs.center(),osg::Vec3f(0.0,1.0,0.0));
  camera->setProjectionMatrixAsOrtho(-bs.radius(),bs.radius(),-bs.radius(),bs.radius(),2*bs.radius(),300);
  camera->addChild(root.get());
  view->setSceneData(camera);
  double fovy,aspectRatio,zNear,zFar;
  view->getCamera()->getProjectionMatrixAsPerspective(fovy,aspectRatio,zNear,zFar);
  double newAspectRatio=double(ts->width/3)/double(ts->height/2);
  double aspectRatioChange=newAspectRatio/aspectRatio;
  if(aspectRatioChange!=1.0)
  {
   view->getCamera()->getProjectionMatrix()*=osg::Matrix::scale(1./aspectRatioChange,1.0,1.0);
  }
  view->getCamera()->setViewport(new osg::Viewport(ts->width*2/3,0,ts->width/3,ts->height/2));
  view->getCamera()->setGraphicsContext(gc.get());
  view->setCameraManipulator(new osgGA::TrackballManipulator);
}
viewer->realize();
viewer->run();
return 0;
}

该用户从未签到

 楼主| 发表于 2010-3-25 10:55:33 | 显示全部楼层
由于帖子出现乱码,我重新上传了一份附件

osg.rar

1.69 KB, 下载次数: 112, 下载积分: 威望 1

该用户从未签到

发表于 2010-3-25 12:40:05 | 显示全部楼层
首先第一个建议是:既然您已经可以显示另外两个视图,那么就说明第三个视图的问题只会出在您的观察和投影矩阵设置上,因此您完全可以将自己的代码改写到30行以内,而不用让大家费力去看那么大段的程序——事实上很多时候,我个人也不得不忽略这类大段的代码,把它留给其他有闲暇的朋友去解答。

确定了问题的原因之后,只需要检查您的投影矩阵设置,注意您使用setProjectionMatrixAsOrtho设置了一个正交投影阵,但是紧接着又使用透视投影的方法去处理它,显然这是不合理的,您需要自己改写那些代码以适应aspectRatioChange的改变。

第三就是投影矩阵中远近平面的设定,2*bs.radius()到300这个距离似乎很难保证场景在您的视锥体之内,您需要再仔细斟酌您的算法实现。

最后,如果您是试图观察一个运动中的模型的话,需要使用回调来随时调整相机的观察矩阵,以保证与模型的运动一致

该用户从未签到

 楼主| 发表于 2010-3-25 20:03:16 | 显示全部楼层
3# array
不好意思,第一次发帖没有经验,下次一定注意~~
关于回调函数,我确实没搞清楚,能请您举一个关于位置坐标回调的简单的小例子来说明一下吗?

该用户从未签到

发表于 2010-3-26 08:15:54 | 显示全部楼层
也就是setUpdateCallback,您可以参看教程区精华的《快速入门指导》,或者登陆我的书《OSG三维渲染引擎设计与实践》的资源网站下载实例代码,其中都有回调的使用方法演示。当然做法不会和您的需求完全一致,不过原理都是相通的

该用户从未签到

 楼主| 发表于 2010-4-1 19:04:26 | 显示全部楼层
5# array
谢谢array~~
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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