查看: 1838|回复: 11

请教模型消失的问题

[复制链接]

该用户从未签到

发表于 2010-4-12 22:46:08 | 显示全部楼层 |阅读模式
基于FreeSouth的MFC框架做了一个飞行仿真程序,两台摄影机分别跟踪目标和导弹,在未加入地球之前,模型在外部数据的驱动下飞行正常,摄影机跟踪正常。但当我加入地球模型后,摄影机仍能正常飞行,但目标和导弹却看不见了。摄影机与模型共享同一数据源,数据不存在问题。模型与摄影机的相对距离恒定100m,在摄影机已在地球外很高的情况下,模型不可能在地球内部。但当人为调高模型高度时出现了非常奇怪的现象:模型位置(0,0,9000000),即在北极上空2700km处,摄影机从模型一侧观察时,模型重新出现;从模型上方俯视时,能看见地球,但模型又消失了。当高度降低到北极上方1700km时,从何角度都看不到模型,但在适当角度地球正常出现。这是怎么回事?
PS:地球模型使用《OSG三维渲染引擎编程指南》P72类似做法,就是球体外贴了张图,数据量并不大。

该用户从未签到

 楼主| 发表于 2010-4-12 22:50:34 | 显示全部楼层
摄影机使用setMatrixAsLookAt,参考点位置选取模型位置,模型应该始终出现在视野中心,在不加地球的飞行试验中也证明了这点。

该用户从未签到

发表于 2010-4-12 23:40:24 | 显示全部楼层
我不能从您的叙述中获取足够的信息。您详细描述了现象,却没有给出自己的实现过程,而我并非这个程序的开发者,因此也就无从判断您的问题可能在哪里

该用户从未签到

发表于 2010-4-13 01:26:17 | 显示全部楼层
1# skywarrior
以前锐哥回答过相似的问题,我已经通过QQ把他的方法发给你了,你也可以根据我给的连接看一下原帖

该用户从未签到

发表于 2010-4-13 01:32:12 | 显示全部楼层

该用户从未签到

发表于 2010-4-13 08:21:55 | 显示全部楼层
如果是远近平面计算的问题的话,尽量不要设置DO_NOT_COMPUTE_NEAR_FAR,除非您很明确地知道自己每帧要设置的投影矩阵是什么。可以用setNearFarRatio来设置自动计算的比率

该用户从未签到

 楼主| 发表于 2010-4-15 00:24:51 | 显示全部楼层
我将模型各方向尺度放大100倍并将相机调远后,模型可以出现了,但我不明白,我明明用lookat矩阵锁定了模型与相机的相对距离,为什么在将地球加入主节点后(相机直接读取主节点),模型在相机中会变得很小(或者是由于相机离模型远了),总之,加入模型后视野中的模型小的看不见了~~,这是为什么? 6# array

该用户从未签到

 楼主| 发表于 2010-4-15 00:26:00 | 显示全部楼层
谢谢,不过,好像原因不太一样 4# wangfan3240

该用户从未签到

 楼主| 发表于 2010-4-15 00:32:57 | 显示全部楼层
3# array
程序还在实验室,而且太大无法上传,等我明天拷一下相关部分给您看一下

该用户从未签到

发表于 2010-4-15 09:03:11 | 显示全部楼层
总之,加入模型后视野中的模型小的看不见了
依然,对于这样笼统的描述,抱歉我判断不了什么,也许您可以考虑一下自己的lookat矩阵是否设置正确;此外,您是如何保证“锁定了模型与相机的相对距离”的?您确信自己屏蔽了场景漫游器(比如TrackballManipulator)
如果您要发给我程序,请不要直接把mfc程序都拷贝给我。我希望看到的只是在控制台下能够顺利调试的代码片段

该用户从未签到

 楼主| 发表于 2010-4-18 22:15:44 | 显示全部楼层
10# array
对不起,最近没有上网,上次说的问题:
osg::ref_ptr<osg::Node>CCoreOSG::createEarth()
{
osg::ref_ptr<osg::ShapeDrawable>sd=new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0f,0.0f,0.0f),osg::WGS_84_RADIUS_POLAR));
osg::ref_ptr<osg::Geode>geode=new osg::Geode();
geode->addDrawable(sd.get());
std::string filename("Images/land_shallow_topo_2048.jpg");
geode->getOrCreateStateSet()->setTextureAttributeAndModes(0,new osg::Texture2D(osgDB::readImageFile(filename)));
return geode.get();
}

void CCoreOSG::InitSceneGraph(void)
{
mRoot->addChild(missilePAT.get());
mRoot->addChild(createEarth());
}

void CCoreOSG::InitCameraConfig(void)
{
viewer->addView(view.get());
view->addSlave(camera.get());
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
camera->addChild(mRoot.get());
}

void CCoreOSG:reFrameUpdate()
{
missilePAT->setPosition(position_missile);
missilePAT->setAttitude(rotation_missile);
missilePAT->setScale(osg::Vec3(100.0f,100.0f,100.0f));
camera->setViewMatrixAsLookAt(position_missile+osg::Vec3(50000.0,-50000.0,20000.0),position_missile,osg::Vec3(0.0,0.0,1.0));
position=position_missile;
}
通过外部程序更新PreFrameUpdate()的数据实现模型运动,在加入地球前程序为:

missilePAT->setScale(osg::Vec3(1.0f,1.0f,1.0f));
camera->setViewMatrixAsLookAt(position_missile+osg::Vec3(500.0,-500.0,200.0),position_missile,osg::Vec3(0.0,0.0,1.0));
在加入createEarth()后就必须调大上面的参数才能看见模型,为什么?

该用户从未签到

发表于 2010-4-19 08:54:08 | 显示全部楼层
一个已经多次提过的事情是,不要在PreFrameUpdate()和PostFrameUpdate()里面写任何内容,它们只是OSG早期版本的一个遗留物而已;现在的多线程渲染机制使得这两个函数根本不是它们的名称所对应的意思,并且其中的内容很可能会造成系统不稳定

至于您所说的“必须调大上面的参数才能看见模型”,我个人认为是您自己代码中的弊病;问题的原因可能出在别的地方。

此外请注意您的CameraManipulator,它会每帧自动计算和设置观察矩阵,不知这是否会对您的策略产生什么影响
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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