菜鸟学习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;
}
如图,武当正确载入
老是看峨眉那图,都看烦了!换几个新鲜的
有的地图没有光照图等等
比如武当的地图不是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;
}
如图,武当正确载入
老是看峨眉那图,都看烦了!换几个新鲜的
相关文章推荐
- 菜鸟学习OGRE和天龙八部之十七: 修正部分地图载入的通用性问题,附源码
- 菜鸟学习OGRE和天龙八部之十四: 修正水面算法的一些BUG
- 菜鸟学习OGRE和天龙八部之七: frame帧动画数据格式搞定,已修正关键帧
- 菜鸟学习OGRE和天龙八部之七: frame帧动画数据格式搞定,已修正关键帧
- 菜鸟学习OGRE和天龙八部之八: 水面方格效果和光照BUG的修正
- 菜鸟学习OGRE和天龙八部之八: 水面方格效果和光照BUG的修正
- 菜鸟学习OGRE和天龙八部之十: frame动画基本搞定,遇到点问题
- 菜鸟学习OGRE和天龙八部之十四: 修正水面算法的一些BUG
- 菜鸟学习OGRE和天龙八部之十: frame动画基本搞定,遇到点问题
- 菜鸟学习OGRE和天龙八部之七: frame帧动画数据格式搞定,已修正关键帧
- 菜鸟学习OGRE和天龙八部之二: 天龙八部AXP数据格式搞定
- 菜鸟学习OGRE和天龙八部之二: 天龙八部AXP数据格式搞定(2009.10.19)
- 修改ETM,用Ogre实现《天龙八部》地形与部分场景详解(附源码)
- 修改ETM,用Ogre实现《天龙八部》地形与部分场景详解(附源码)
- 菜鸟学习OGRE和天龙八部之三: GridInfo和HeightMap文件的数据格式(已更正)
- 菜鸟学习OGRE和天龙八部之四: 地表贴图的实现
- 菜鸟学习OGRE和天龙八部之一:OGRE+MFC+OIS
- 菜鸟学习OGRE和天龙八部之五: 水面TerrainLiquid基本搞定
- 菜鸟学习OGRE和天龙八部之三: GridInfo和HeightMap文件的数据格式(已更正)
- 菜鸟学习OGRE和天龙八部之六: 地表和水面的normal搞定,光照正常了