我要发帖 回复

高级会员

109

主题

1267

积分

0

专家分

OSG-VR-GIS

忠于职守杰出贡献

:

私信
发表时间 : 2007-12-21 14:19:18 | 浏览 : 1905    评论 : 0
Navy16 - 交集测试 (2)
下面将获取地形模型在给定X,Y位置的高度值,并放置坦克模型

   double tankXPosition = -10.0;
   double tankYPosition = -10.0;

   osg::LineSegment* tankLocationSegment = new osg::LineSegment();
   tankLocationSegment->set(
      osg::Vec3(tankXPosition, tankYPosition, 999) ,
      osg::Vec3(tankXPosition, tankYPosition, -999) );

   osgUtil::IntersectVisitor findTankElevationVisitor;
   findTankElevationVisitor.addLineSegment(tankLocationSegment);
   terrainNode->accept(findTankElevationVisitor);

   osgUtil::IntersectVisitor::HitList tankElevationLocatorHits;
   tankElevationLocatorHits =
      findTankElevationVisitor.getHitList(tankLocationSegment);
   osgUtil::Hit heightTestResults;
   if ( tankElevationLocatorHits.empty() )
   {
      std::cout << " couldn't place tank on terrain" << std::endl;
      return -1;
   }
   heightTestResults = tankElevationLocatorHits.front();
   osg::Vec3d terrainHeight = heightTestResults.getWorldIntersectPoint();

   tankXform->setPosition( terrainHeight );
   tankXform->setAttitude(
      osg::Quat(osg::DegreesToRadians(-45.0), osg::Vec3(0,0,1) ) );

下面的代码将设置视口,告示牌节点,以及渲染状态。

   viewer.setCameraManipulator(new osgGA::TrackballManipulator());
   viewer.setSceneData(rootNode);
   viewer.realize();

   osg::Billboard* shrubBillBoard = new osg::Billboard();
   rootNode->addChild(shrubBillBoard);

   shrubBillBoard->setMode(osg::Billboard::AXIAL_ROT);
   shrubBillBoard->setAxis(osg::Vec3(0.0f,0.0f,1.0f));
   shrubBillBoard->setNormal(osg::Vec3(0.0f,-1.0f,0.0f));

   osg::Texture2D *ocotilloTexture = new osg::Texture2D;
   ocotilloTexture->setImage(osgDB::readImageFile("images\\ocotillo.png"));

   osg::StateSet* billBoardStateSet = new osg::StateSet;

   billBoardStateSet->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
   billBoardStateSet->setTextureAttributeAndModes(0, ocotilloTexture, osg::StateAttribute::ON );
   billBoardStateSet->setAttributeAndModes( new osg::BlendFunc, osg::StateAttribute::ON );

   osg::AlphaFunc* alphaFunction = new osg::AlphaFunc;
   alphaFunction->setFunction(osg::AlphaFunc::GEQUAL,0.05f);
   billBoardStateSet->setAttributeAndModes( alphaFunction, osg::StateAttribute::ON );

按照上面所述的检测射线和地形模型碰撞交点的基本步骤,现在我们将向IntersectVisitor添加多个LineSegment实例。每条射线的交集测试结果(交点位置)将用于放置相应的告示牌。

   srand(time(0)); // 初始化随机数生成器。

   osgUtil::IntersectVisitor isectVisitor;
   osg::LineSegment* terrainIsect[NUMBER_O_SHRUBS];

   int randomX, randomY;

   for (int i=0; i< NUMBER_O_SHRUBS; i++ )
   {
      randomX = (rand() % 100) + 1;
      randomY = (rand() % 100) + 1;
      terrainIsect = new osg::LineSegment(
         osg::Vec3(randomX, randomY, 999) ,
         osg::Vec3(randomX, randomY, -999) );
      isectVisitor.addLineSegment(terrainIsect);
   }
   terrainNode->accept(isectVisitor);

   osg::Drawable* shrubDrawable[NUMBER_O_SHRUBS];

   for (int j = 0 ; j < NUMBER_O_SHRUBS; j ++)
   {
      float randomScale = ((rand() % 15) + 1 ) / 10.0;
      shrubDrawable[j] = createShrub( randomScale, billBoardStateSet);
      osgUtil::IntersectVisitor::HitList hitList = isectVisitor.getHitList(terrainIsect[j]);
      if (! hitList.empty() )
      {
         osgUtil::Hit firstHit = hitList.front();
         osg::Vec3d shrubPosition = firstHit.getWorldIntersectPoint();

         // osg::Vec3d shrubPosition =
         // isectVisitor.getHitList(terrainIsect[j]).front().getWorldIntersectPoint();

         shrubBillBoard->addDrawable( shrubDrawable[j] , shrubPosition );
      }
   }

   while( !viewer.done() )
   {
      viewer.frame();
   }
   return 0;
}

编程愉快!

最近VR访客


OSG中国官方网站:http://www.osgChina.org
OSG中国官方讨论区:http://bbs.osgChina.org

OSG专业群-OSG地形研究者 49668412
      OSG地形专业研究 45763709

手机版|VR开发网 统计 津ICP备18009691号
网安备12019202000257

GMT+8, 2021-10-29 01:48 AM

返回顶部