模型貼花

地形貼花,CreateMeshDecal()只創建一次,之後每次調用SetMeshDecal()。

/**
* @Function: CreateMeshDecal
* @Description: 創建模型貼花Mesh,此Mesh只被創建一次
*/
void CMap::CreateMeshDecal(void)
{
      m_pMeshDecal = new Ogre::ManualObject("MeshDecal");
      m_pSceneManager->getRootSceneNode()->attachObject(m_pMeshDecal); // 掛在根節點

      int x_size = 4;                  // 在X方向的多邊形數量
      int z_size = 4;                  // 在Z方向的多邊形數量

      // 此Mesh所使用的材質,用三角形帶創建Mesh
      m_pMeshDecal->begin("Crosshairs", Ogre::RenderOperation::OT_TRIANGLE_LIST);
      for (int i = 0; i <= x_size; i++)
      {
            for (int j = 0; j <= z_size; j++)
            {
                  // 添加一個頂點
                  m_pMeshDecal->position(Ogre::Vector3(i, 0, j));
                  // 爲這個頂點定義紋理座標
                  m_pMeshDecal->textureCoord((float)i / (float)x_size, (float)j / (float)z_size);
            }
       }

      for (int i = 0; i < x_size; i++)
      {
            for (int j = 0; j < z_size; j++)
            {
                  // 通過頂點索引建立四邊形(4*4),(x_size + 1)是一行上的頂點數
                  // quad只用於三角形帶
                  m_pMeshDecal->quad(
                  i * (x_size + 1) + j,                  // 左上
                  i * (x_size + 1) + j + 1,            // 右上
                  (i + 1) * (x_size + 1) + j + 1,    // 右下
                  (i + 1) * (x_size + 1) + j           // 左下
                  );
            }
      }
      m_pMeshDecal->end();
}

============================================================================


/**
* @Function: SetMeshDecal
* @Description: 設置模型貼花到指定位置
* @Param x: 座標
* @Param z:
* @Param rad: 半徑
*/
void CMap::SetMeshDecal(Ogre::Real x, Ogre::Real z, Ogre::Real rad)
{
      Ogre::Real x1 = x - rad;            // 左下角座標
      Ogre::Real z1 = z - rad;

      int x_size = 4;                             // 在X方向的多邊形數量
      int z_size = 4;

      Ogre::Real x_step = (rad * 2) / x_size;            // 每個四邊形的寬、高
      Ogre::Real z_step = (rad * 2) / z_size;

      // 更新地形貼花Mesh
      m_pMeshDecal->beginUpdate(0);
      for (int i = 0; i <= x_size; i++)
      {
            for (int j = 0; j <= z_size; j++)
            {
                  // 根據地形高度更新頂點位置
                  m_pMeshDecal->position(Ogre::Vector3(x1, GetTerrainHeight(x1, z1) + 1, z1));
                  m_pMeshDecal->textureCoord((float)i / (float)x_size, (float)j / (float)z_size);
                  z1 += z_step;            // 列中每行
            }
            x1 += x_step;                  // 行中每列
            z1 = z - rad;
      }

      // 更新四邊形
      for (int i = 0; i < x_size; i++)
      {
            for (int j = 0; j < z_size; j++)
            {
                  m_pMeshDecal->quad(
                        i * (x_size + 1) + j,                  // 左下
                        i * (x_size + 1) + j + 1,            // 左上
                        (i + 1) * (x_size + 1) + j + 1,   // 右上
                        (i + 1) * (x_size + 1) + j);        // 右下
            }
      }
      m_pMeshDecal->end();
}

============================================================================


/**
* @Function: GetTerrainHeight
* @Description: 獲得地形高度
* @Param x: 座標
* @Param z:
* @Return: 高度
*/
Real CMap::GetTerrainHeight(Real x, Real z)
{
      // 設置光線的起始位置爲人物上方5000高度
      m_UpdateRay.setOrigin(Vector3(x, 5000.0f, z));
      // 設置光線的方向爲Y軸負方向
      m_UpdateRay.setDirection(Vector3::NEGATIVE_UNIT_Y);
      m_pRaySceneQuery->setRay(m_UpdateRay);                                    // 設置用於光線追蹤的光線

      RaySceneQueryResult& result = m_pRaySceneQuery->execute();      // 獲得搜索結果
      RaySceneQueryResult::iterator itr;

      for(itr = result.begin(); itr != result.end(); itr++)
      {
            if (itr->worldFragment)   // 如果是地形
            {
                  return itr->worldFragment->singleIntersection.y;
            }
      }
      return 0;
}
 

 

發佈了13 篇原創文章 · 獲贊 0 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章