您的位置:首页 > 其它

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

2011-09-04 16:47 585 查看
有的地图不是tile的整数倍,有的地图没有WCollision文件,有的地图有centre等

有的地图没有光照图等等

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

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

自己去优化了,

void TLBBTerrain::createTerrain()

{

// 生成材质, 看是否有光照图

if(mHasLightMap){

createLightMaterial();

}else{

createMaterial();

}

// 判断地图大小是否能被tile(32)整除,不能整除的就矫正tile大小

bool isAdjustCol = false; // 是否矫正tile的大小

bool isAdjustRow = false;

if(mXSize%mTileSize != 0){

isAdjustCol = true;

}

if(mZSize%mTileSize != 0){

isAdjustRow = true;

}

// tile的行数和列数,不管能否被整除都适用

mTileCol = mXSize/mTileSize;

mTileRow = mZSize/mTileSize;

// WCollision

createWCollision();

// 地形mesh

for(size_t matIndex = 0; matIndex < mMaterialNum; ++ matIndex){

// 同材质的mesh按tile区域生成

for(int tileIndex =0; tileIndex < mTileCol*mTileRow; ++ tileIndex){

if(createTileMesh(tileIndex, matIndex, isAdjustCol, isAdjustRow)){

Entity* entity = mSceneMgr->createEntity("tile"+StringConverter::toString(tileIndex + matIndex*mTileCol*mTileRow), "GridMesh" + StringConverter::toString(tileIndex + matIndex*mTileCol*mTileRow));

entity->setCastShadows(false);

mSceneMgr->getRootSceneNode()->createChildSceneNode(mCentre)->attachObject(entity);

}

}

}

}

view
plain

// 分别用mesh和ManualObject生成地形

bool TLBBTerrain::createTileMesh(int tileIndex, int materialIndex, bool isAdjustCol, bool isAdjustRow)

{

// 方法1, ManualObject

const Real width = 1;

ManualObject mo("GridObject" + StringConverter::toString(tileIndex + materialIndex*mMaterialNum));

mo.begin("material"+StringConverter::toString(materialIndex), RenderOperation::OT_TRIANGLE_LIST);

int k = 0;

bool hasMesh = false;

int tileSizeX = mTileSize;

int tileSizeZ = mTileSize;

int tileIndex_x = tileIndex%(mXSize/mTileSize);

int tileIndex_z = tileIndex/(mXSize/mTileSize);

// 如果地图大小不能被tile整除,就需要矫正

if(isAdjustCol && tileIndex_x == mXSize/mTileSize - 1){

tileSizeX = mTileSize + mXSize%mTileSize;

}

if(isAdjustRow && tileIndex_z == mZSize/mTileSize - 1){

tileSizeZ = mTileSize + mZSize%mTileSize;

}

// 地图可以被tile整除

for(int j = 0; j < tileSizeX*tileSizeZ; ++ j){

// 把每个tile的坐标转换成全图坐标

int row = j/tileSizeX + tileIndex_z*mTileSize;

int col = j%tileSizeX + tileIndex_x*mTileSize;

int mapIndex = col + row*mXSize;

Ogre::String str;

if(mHasLightMap){

str = mLightMaterialData[mapIndex];

}else{

str = mMaterialData[mapIndex];

}

if(str == "material"+StringConverter::toString(materialIndex) && mGridData[mapIndex].nFirstLayer >= 0){

// 此tile含有此材质的mesh

hasMesh = true;

// 高度图坐标转换

int heightMapIndex = mapIndex + mapIndex/mXSize;

// 第一层纹理坐标

Real left1 = mPixMapData[mGridData[mapIndex].nFirstLayer].left;

Real right1 = mPixMapData[mGridData[mapIndex].nFirstLayer].right;

Real top1 = mPixMapData[mGridData[mapIndex].nFirstLayer].top;

Real bottom1 = mPixMapData[mGridData[mapIndex].nFirstLayer].bottom;

Vector2 left_top_1(left1, top1);

Vector2 right_top_1(right1, top1);

Vector2 right_bottom_1(right1, bottom1);

Vector2 left_bottom_1(left1, bottom1);

// 图片翻转等操作

flipPicture(mGridData[mapIndex].nFirstLayerOp, left_top_1, right_top_1, left_bottom_1, right_bottom_1, mGridData[mapIndex].IndexOrder);

// 第二层纹理坐标

Vector2 left_top_2 = Vector2::ZERO;

Vector2 right_top_2 = Vector2::ZERO;

Vector2 right_bottom_2 = Vector2::ZERO;

Vector2 left_bottom_2 = Vector2::ZERO;

if(mGridData[mapIndex].nSecondLayer >= 0){

Real left2 = mPixMapData[mGridData[mapIndex].nSecondLayer].left;

Real right2 = mPixMapData[mGridData[mapIndex].nSecondLayer].right;

Real top2 = mPixMapData[mGridData[mapIndex].nSecondLayer].top;

Real bottom2 = mPixMapData[mGridData[mapIndex].nSecondLayer].bottom;

left_top_2 = Vector2(left2, top2);

right_top_2 = Vector2(right2, top2);

right_bottom_2 = Vector2(right2, bottom2);

left_bottom_2 = Vector2(left2, bottom2);

flipPicture(mGridData[mapIndex].nSecondLayerOp, left_top_2, right_top_2, left_bottom_2, right_bottom_2, mGridData[mapIndex].IndexOrder);

}

// 光照图纹理坐标

Vector2 left_top_3 = Vector2::ZERO;

Vector2 right_top_3 = Vector2::ZERO;

Vector2 right_bottom_3 = Vector2::ZERO;

Vector2 left_bottom_3 = Vector2::ZERO;

if(mHasLightMap){

Real left3 = (mapIndex%mXSize)/(Real)mXSize;

Real right3 = left3 + 1/(Real)mXSize;

Real top3 = (mapIndex/mXSize)/(Real)mZSize;

Real bottom3 = top3 + 1/(Real)mZSize;

left_top_3 = Vector2(left3, top3);

right_top_3 = Vector2(right3, top3);

right_bottom_3 = Vector2(right3, bottom3);

left_bottom_3 = Vector2(left3, bottom3);

}

// 点0

mo.position((mapIndex%mXSize)*mScaleX, mHeightMapData[heightMapIndex]*mScaleY, (mapIndex/mXSize)*mScaleZ);

mo.normal(getNormalAt(mapIndex%mXSize, mapIndex/mXSize));

mo.textureCoord(left_top_1);

if(mGridData[mapIndex].nSecondLayer >= 0){

mo.textureCoord(left_top_2);

}

if(mHasLightMap){

mo.textureCoord(left_top_3); // 光照图纹理坐标

}

// 点1

mo.position((mapIndex%mXSize+width)*mScaleX, mHeightMapData[heightMapIndex+1]*mScaleY, (mapIndex/mXSize)*mScaleZ);

mo.normal(getNormalAt(mapIndex%mXSize+width, mapIndex/mXSize));

mo.textureCoord(right_top_1);

if(mGridData[mapIndex].nSecondLayer >= 0){

mo.textureCoord(right_top_2);

}

if(mHasLightMap){

mo.textureCoord(right_top_3); // 光照图纹理坐标

}

// 点2

mo.position((mapIndex%mXSize+width)*mScaleX, mHeightMapData[heightMapIndex+mXSize+2]*mScaleY, (width+mapIndex/mXSize)*mScaleZ);

mo.normal(getNormalAt(mapIndex%mXSize+width, mapIndex/mXSize+width));

mo.textureCoord(right_bottom_1);

if(mGridData[mapIndex].nSecondLayer >= 0){

mo.textureCoord(right_bottom_2);

}

if(mHasLightMap){

mo.textureCoord(right_bottom_3); // 光照图纹理坐标

}

// 点3

mo.position((mapIndex%mXSize)*mScaleX, mHeightMapData[heightMapIndex+mXSize+1]*mScaleY, (width+mapIndex/mXSize)*mScaleZ);

mo.normal(getNormalAt(mapIndex%mXSize, mapIndex/mXSize+width));

mo.textureCoord(left_bottom_1);

if(mGridData[mapIndex].nSecondLayer >= 0){

mo.textureCoord(left_bottom_2);

}

if(mHasLightMap){

mo.textureCoord(left_bottom_3); // 光照图纹理坐标

}

// 三角形索引顺序

int offset = k * 4;

if(mGridData[mapIndex].IndexOrder == 0){ // 正常顺序

mo.triangle(offset+1, offset, offset+3);

mo.triangle(offset+1, offset+3, offset+2);

}else{

mo.triangle(offset, offset+3, offset+2);

mo.triangle(offset, offset+2, offset+1);

}

++ k;

}

}

mo.end();

if(hasMesh){

mo.convertToMesh("GridMesh" + StringConverter::toString(tileIndex + materialIndex*mTileCol*mTileRow));

return true;

}

return false;

}

如图,武当正确载入

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











内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  vector 优化 list
相关文章推荐