菜鸟学习OGRE和天龙八部之十七: 修正部分地图载入的通用性问题,附源码

本文探讨如何针对非标准地图尺寸和缺失碰撞文件等问题,优化地形生成过程,包括调整地形大小、创建光照图和碰撞文件,以及使用ManualObject生成地形mesh。通过改进函数参数、调整tile大小和优化资源加载流程,提升性能并确保地图完整加载。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有的地图不是tile的整数倍,有的地图没有WCollision文件,有的地图有centre等

有的地图没有光照图等等

 

比如武当的地图不是tile的整数倍,那么就需要调整tile大小,其实只需要稍微改动

源码没有经过优化的,比如不需要更改的函数参数可以全部改成const引用,提高效率的

自己去优化了,


  1. void
     TLBBTerrain::createTerrain()  
  2. {  
  3.     // 生成材质, 看是否有光照图  
  4.   
  5.     if(mHasLightMap){  
  6.         createLightMaterial();  
  7.     }else{  
  8.         createMaterial();  
  9.     }  
  10.       
  11.     // 判断地图大小是否能被tile(32)整除,不能整除的就矫正tile大小  
  12.     bool isAdjustCol = false;  // 是否矫正tile的大小  
  13.     bool isAdjustRow = false;  
  14.     if(mXSize%mTileSize != 0){  
  15.         isAdjustCol = true;  
  16.     }  
  17.     if(mZSize%mTileSize != 0){  
  18.         isAdjustRow = true;  
  19.     }  
  20.   
  21.     // tile的行数和列数,不管能否被整除都适用  
  22.     mTileCol = mXSize/mTileSize;  
  23.     mTileRow = mZSize/mTileSize;  
  24.   
  25.     // WCollision  
  26.     createWCollision();  
  27.   
  28.     // 地形mesh  
  29.     for(size_t matIndex = 0; matIndex < mMaterialNum; ++ matIndex){  
  30.         // 同材质的mesh按tile区域生成  
  31.         for(int tileIndex =0; tileIndex < mTileCol*mTileRow; ++ tileIndex){  
  32.             if(createTileMesh(tileIndex, matIndex, isAdjustCol, isAdjustRow)){  
  33.                 Entity* entity = mSceneMgr->createEntity("tile"+StringConverter::toString(tileIndex + matIndex*mTileCol*mTileRow), "GridMesh" + StringConverter::toString(tileIndex + matIndex*mTileCol*mTileRow));  
  34.                 entity->setCastShadows(false);  
  35.                 mSceneMgr->getRootSceneNode()->createChildSceneNode(mCentre)->attachObject(entity);  
  36.             }  
  37.         }  
  38.     }  
  39.   
  40. }  

  1. // 分别用mesh和ManualObject生成地形  
  2. bool TLBBTerrain::createTileMesh(int tileIndex, int materialIndex, bool isAdjustCol, bool isAdjustRow)  
  3. {  
  4.     // 方法1, ManualObject  
  5.     const Real width = 1;  
  6.     ManualObject mo("GridObject" + StringConverter::toString(tileIndex + materialIndex*mMaterialNum));        
  7.     mo.begin("material"+StringConverter::toString(materialIndex), RenderOperation::OT_TRIANGLE_LIST);  
  8.   
  9.     int k = 0;  
  10.     bool hasMesh = false;  
  11.     int tileSizeX = mTileSize;  
  12.     int tileSizeZ = mTileSize;  
  13.     int tileIndex_x = tileIndex%(mXSize/mTileSize);  
  14.     int tileIndex_z = tileIndex/(mXSize/mTileSize);  
  15.   
  16.     // 如果地图大小不能被tile整除,就需要矫正  
  17.     if(isAdjustCol && tileIndex_x == mXSize/mTileSize - 1){  
  18.         tileSizeX = mTileSize + mXSize%mTileSize;  
  19.     }  
  20.     if(isAdjustRow && tileIndex_z == mZSize/mTileSize - 1){  
  21.         tileSizeZ = mTileSize + mZSize%mTileSize;  
  22.     }  
  23.   
  24.     // 地图可以被tile整除  
  25.     for(int j = 0; j < tileSizeX*tileSizeZ; ++ j){  
  26.         // 把每个tile的坐标转换成全图坐标  
  27.         int row = j/tileSizeX + tileIndex_z*mTileSize;  
  28.         int col = j%tileSizeX + tileIndex_x*mTileSize;  
  29.         int mapIndex = col + row*mXSize;  
  30.   
  31.         Ogre::String str;  
  32.         if(mHasLightMap){  
  33.             str = mLightMaterialData[mapIndex];  
  34.         }else{  
  35.             str = mMaterialData[mapIndex];  
  36.         }  
  37.   
  38.         if(str == "material"+StringConverter::toString(materialIndex) && mGridData[mapIndex].nFirstLayer >= 0){  
  39.             // 此tile含有此材质的mesh  
  40.             hasMesh = true;  
  41.             // 高度图坐标转换  
  42.             int heightMapIndex = mapIndex + mapIndex/mXSize;  
  43.   
  44.             // 第一层纹理坐标  
  45.             Real left1 = mPixMapData[mGridData[mapIndex].nFirstLayer].left;  
  46.             Real right1 = mPixMapData[mGridData[mapIndex].nFirstLayer].right;  
  47.             Real top1 = mPixMapData[mGridData[mapIndex].nFirstLayer].top;  
  48.             Real bottom1 = mPixMapData[mGridData[mapIndex].nFirstLayer].bottom;  
  49.             Vector2 left_top_1(left1, top1);  
  50.             Vector2 right_top_1(right1, top1);  
  51.             Vector2 right_bottom_1(right1, bottom1);  
  52.             Vector2 left_bottom_1(left1, bottom1);  
  53.             // 图片翻转等操作  
  54.             flipPicture(mGridData[mapIndex].nFirstLayerOp, left_top_1, right_top_1, left_bottom_1, right_bottom_1, mGridData[mapIndex].IndexOrder);  
  55.   
  56.   
  57.             // 第二层纹理坐标  
  58.             Vector2 left_top_2 = Vector2::ZERO;  
  59.             Vector2 right_top_2 = Vector2::ZERO;  
  60.             Vector2 right_bottom_2 = Vector2::ZERO;  
  61.             Vector2 left_bottom_2 = Vector2::ZERO;  
  62.             if(mGridData[mapIndex].nSecondLayer >= 0){  
  63.                 Real left2 = mPixMapData[mGridData[mapIndex].nSecondLayer].left;  
  64.                 Real right2 = mPixMapData[mGridData[mapIndex].nSecondLayer].right;  
  65.                 Real top2 = mPixMapData[mGridData[mapIndex].nSecondLayer].top;  
  66.                 Real bottom2 = mPixMapData[mGridData[mapIndex].nSecondLayer].bottom;  
  67.                 left_top_2 = Vector2(left2, top2);  
  68.                 right_top_2 = Vector2(right2, top2);  
  69.                 right_bottom_2 = Vector2(right2, bottom2);  
  70.                 left_bottom_2 = Vector2(left2, bottom2);  
  71.                 flipPicture(mGridData[mapIndex].nSecondLayerOp, left_top_2, right_top_2, left_bottom_2, right_bottom_2, mGridData[mapIndex].IndexOrder);  
  72.             }  
  73.   
  74.             // 光照图纹理坐标  
  75.             Vector2 left_top_3 = Vector2::ZERO;  
  76.             Vector2 right_top_3 = Vector2::ZERO;  
  77.             Vector2 right_bottom_3 = Vector2::ZERO;  
  78.             Vector2 left_bottom_3 = Vector2::ZERO;  
  79.             if(mHasLightMap){  
  80.                 Real left3 = (mapIndex%mXSize)/(Real)mXSize;     
  81.                 Real right3 = left3 + 1/(Real)mXSize;  
  82.                 Real top3 = (mapIndex/mXSize)/(Real)mZSize;  
  83.                 Real bottom3 = top3 + 1/(Real)mZSize;  
  84.                 left_top_3 = Vector2(left3, top3);  
  85.                 right_top_3 = Vector2(right3, top3);  
  86.                 right_bottom_3 = Vector2(right3, bottom3);  
  87.                 left_bottom_3 = Vector2(left3, bottom3);  
  88.             }  
  89.   
  90.             // 点0  
  91.             mo.position((mapIndex%mXSize)*mScaleX, mHeightMapData[heightMapIndex]*mScaleY, (mapIndex/mXSize)*mScaleZ);  
  92.             mo.normal(getNormalAt(mapIndex%mXSize, mapIndex/mXSize));  
  93.             mo.textureCoord(left_top_1);  
  94.             if(mGridData[mapIndex].nSecondLayer >= 0){  
  95.                 mo.textureCoord(left_top_2);  
  96.             }  
  97.             if(mHasLightMap){  
  98.                 mo.textureCoord(left_top_3);     // 光照图纹理坐标  
  99.             }  
  100.   
  101.             // 点1  
  102.             mo.position((mapIndex%mXSize+width)*mScaleX, mHeightMapData[heightMapIndex+1]*mScaleY, (mapIndex/mXSize)*mScaleZ);  
  103.             mo.normal(getNormalAt(mapIndex%mXSize+width, mapIndex/mXSize));  
  104.             mo.textureCoord(right_top_1);  
  105.             if(mGridData[mapIndex].nSecondLayer >= 0){  
  106.                 mo.textureCoord(right_top_2);  
  107.             }  
  108.             if(mHasLightMap){  
  109.                 mo.textureCoord(right_top_3);   // 光照图纹理坐标  
  110.             }  
  111.   
  112.             // 点2  
  113.             mo.position((mapIndex%mXSize+width)*mScaleX, mHeightMapData[heightMapIndex+mXSize+2]*mScaleY, (width+mapIndex/mXSize)*mScaleZ);  
  114.             mo.normal(getNormalAt(mapIndex%mXSize+width, mapIndex/mXSize+width));  
  115.             mo.textureCoord(right_bottom_1);  
  116.             if(mGridData[mapIndex].nSecondLayer >= 0){  
  117.                 mo.textureCoord(right_bottom_2);  
  118.             }  
  119.             if(mHasLightMap){  
  120.                 mo.textureCoord(right_bottom_3);  // 光照图纹理坐标  
  121.             }  
  122.   
  123.   
  124.             // 点3  
  125.             mo.position((mapIndex%mXSize)*mScaleX, mHeightMapData[heightMapIndex+mXSize+1]*mScaleY, (width+mapIndex/mXSize)*mScaleZ);  
  126.             mo.normal(getNormalAt(mapIndex%mXSize, mapIndex/mXSize+width));  
  127.             mo.textureCoord(left_bottom_1);  
  128.             if(mGridData[mapIndex].nSecondLayer >= 0){  
  129.                 mo.textureCoord(left_bottom_2);  
  130.             }  
  131.             if(mHasLightMap){  
  132.                 mo.textureCoord(left_bottom_3);   // 光照图纹理坐标  
  133.             }  
  134.   
  135.             // 三角形索引顺序  
  136.             int offset = k * 4;  
  137.             if(mGridData[mapIndex].IndexOrder == 0){ // 正常顺序  
  138.                 mo.triangle(offset+1, offset, offset+3);  
  139.                 mo.triangle(offset+1, offset+3, offset+2);  
  140.             }else{  
  141.                 mo.triangle(offset, offset+3, offset+2);  
  142.                 mo.triangle(offset, offset+2, offset+1);  
  143.             }  
  144.   
  145.             ++ k;  
  146.         }  
  147.     }  
  148.   
  149.     mo.end();  
  150.     if(hasMesh){  
  151.         mo.convertToMesh("GridMesh" + StringConverter::toString(tileIndex + materialIndex*mTileCol*mTileRow));  
  152.         return true;  
  153.     }  
  154.     return false;  
  155. }  

 

如图,武当正确载入

老是看峨眉那图,都看烦了!换几个新鲜的








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值