地形平滑算法

地形平滑算法

  2486人阅读  评论(0)  收藏  举报
  分类:
 

拉出来的地下不平滑怎么办,笨办法就是美工一个顶点一个顶点的调整,而且效果还不好。实际上程序只要实现一个完美平滑算法,随便一刷,地形就平滑了。

平滑算法最重要的就是不能改变原来的地形的大概结构,

基本思路,就是和相邻的点取一个混合值。混合公式和alpha混合公式一样。



海滩边岩石的平滑效果非常好。

[cpp]  view plain  copy
  1. #include "SmoothHeightAction.h"  
  2. #include "SceneManipulator.h"  
  3. #include "HitIndicator.h"  
  4. namespace WX {  
  5.   
  6.     //  
  7.   
  8.     SmoothHeightAction::SmoothHeightAction(SceneManipulator* sceneManipulator)  
  9.         : TimeBasedHeightAction(sceneManipulator)  
  10.     {  
  11.     }  
  12.   
  13.     const String& SmoothHeightAction::getName(voidconst  
  14.     {  
  15.         static const String name = "SmoothHeightAction";  
  16.         return name;  
  17.     }  
  18.   
  19.     void SmoothHeightAction::_onBegin(const Point& pt)  
  20.     {  
  21.         TimeBasedHeightAction::_onBegin(pt);  
  22.   
  23.         //computeAverageHeight();  
  24.     }  
  25.   
  26.     void SmoothHeightAction::_onDrag(const Point& pt)  
  27.     {  
  28.         TimeBasedHeightAction::_onDrag(pt);  
  29.   
  30.         //computeAverageHeight();  
  31.     }  
  32.   
  33.     void SmoothHeightAction::computeAverageHeight(void)  
  34.     {  
  35.         //Real totalHeight = 0;  
  36.         //Real totalWeight = 0;  
  37.         //JunctionSelection* selection = static_cast<JunctionSelection*>(  
  38.         //    getSceneManipulator()->_getSelection("JunctionSelection"));  
  39.         //const JunctionSelection::JunctionMap& junctions = selection->getJunctions();  
  40.         //JunctionSelection::JunctionMap::const_iterator it;  
  41.         //for (it = junctions.begin(); it != junctions.end(); ++it)  
  42.         //{  
  43.         //    const JunctionSelection::Junction& junction = it->second;  
  44.         //    totalWeight += junction.weight;  
  45.         //    totalHeight += getTerrainData()->getHeight(junction.x, junction.z) * junction.weight;  
  46.         //}  
  47.         //mAverageHeight = totalWeight ? totalHeight / totalWeight : 0;  
  48.     }  
  49.   
  50.     Real SmoothHeightAction::_computeHeight(const JunctionSelection::Junction& junction, Real seconds)  
  51.     {  
  52.         //Real height = getTerrainData()->getHeight(junction.x, junction.z);  
  53.         //Real diff = mAverageHeight - height;  
  54.         //Real secondsRequest = Ogre::Math::Abs(diff * junction.weight / getSceneManipulator()->_getHeightAdjustSpeed());  
  55.         //if (secondsRequest < seconds)  
  56.         //    return mAverageHeight;  
  57.         //else  
  58.         //    return height + diff * seconds / secondsRequest;  
  59.         return 0;  
  60.     }  
  61.   
  62.     void SmoothHeightAction::_onUpdate(const Point& pt, Real seconds)  
  63.     {  
  64.         // 控制每秒平滑的次数  
  65.         static Real time = 0;  
  66.         time += seconds;  
  67.         if (time > 0.1)  
  68.         {  
  69.             smooth();  
  70.             time = 0;  
  71.         }  
  72.   
  73.         getSceneManipulator()->getHitIndicator("JunctionPoints")->refresh();  
  74.         getSceneManipulator()->getHitIndicator("IntersectPoint")->setHitPoint(pt);  
  75.     }  
  76.   
  77.     void SmoothHeightAction::smooth(void)  
  78.     {  
  79.         // 2012.9.16 luoyinan 实现新的平滑算法,基本思路是和相邻的点取  
  80.         // 一个混合值.再通过多次采样实现完美平滑效果  
  81.   
  82.         JunctionSelection* selection = static_cast<JunctionSelection*>(  
  83.             getSceneManipulator()->_getSelection("JunctionSelection"));  
  84.         //_prepareUpdate(*selection, seconds);  
  85.   
  86.         const JunctionSelection::JunctionMap& junctions = selection->getJunctions();  
  87.         JunctionSelection::JunctionMap::const_iterator it;  
  88.         std::vector<TerrainInfo> terrainInfo;  
  89.   
  90.         float k = 0.98;  
  91.   
  92.         // 从左到右  
  93.         for (it = junctions.begin(); it != junctions.end(); ++it)  
  94.         {  
  95.             const JunctionSelection::Junction& junction = it->second;  
  96.             mModifiedJunctions->add(junction.x, junction.z, 1);  
  97.   
  98.             //  
  99.             if (getTerrainData()->isValidJunction(junction.x-1,junction.z))  
  100.             {  
  101.                 float oldHeight = getTerrainData()->getHeight(junction.x,junction.z);  
  102.                 float newHeight = getTerrainData()->getHeight(junction.x-1,junction.z) * (1-k) + oldHeight * k;  
  103.   
  104.                 TerrainInfo terrInfo;  
  105.                 terrInfo.x = junction.x;  
  106.                 terrInfo.z = junction.z;  
  107.                 terrInfo.oldHeight = junction.height;  
  108.                 terrInfo.nowHeight = newHeight;  
  109.                 terrainInfo.push_back(terrInfo);  
  110.   
  111.                 getTerrainData()->setHeight(junction.x, junction.z, newHeight);  
  112.             }  
  113.         }     
  114.         // 从右到左  
  115.         for (it = junctions.begin(); it != junctions.end(); ++it)  
  116.         {  
  117.             const JunctionSelection::Junction& junction = it->second;  
  118.             mModifiedJunctions->add(junction.x, junction.z, 1);  
  119.   
  120.             //  
  121.             if (getTerrainData()->isValidJunction(junction.x+1,junction.z))  
  122.             {  
  123.                 float oldHeight = getTerrainData()->getHeight(junction.x,junction.z);  
  124.                 float newHeight = getTerrainData()->getHeight(junction.x+1,junction.z) * (1-k) + oldHeight * k;  
  125.   
  126.                 TerrainInfo terrInfo;  
  127.                 terrInfo.x = junction.x;  
  128.                 terrInfo.z = junction.z;  
  129.                 terrInfo.oldHeight = junction.height;  
  130.                 terrInfo.nowHeight = newHeight;  
  131.                 terrainInfo.push_back(terrInfo);  
  132.   
  133.                 getTerrainData()->setHeight(junction.x, junction.z, newHeight);  
  134.             }  
  135.         }     
  136.         // 从上到下  
  137.         for (it = junctions.begin(); it != junctions.end(); ++it)  
  138.         {  
  139.             const JunctionSelection::Junction& junction = it->second;  
  140.             mModifiedJunctions->add(junction.x, junction.z, 1);  
  141.   
  142.             //  
  143.             if (getTerrainData()->isValidJunction(junction.x,junction.z+1))  
  144.             {  
  145.                 float oldHeight = getTerrainData()->getHeight(junction.x,junction.z);  
  146.                 float newHeight = getTerrainData()->getHeight(junction.x,junction.z+1) * (1-k) + oldHeight * k;  
  147.   
  148.                 TerrainInfo terrInfo;  
  149.                 terrInfo.x = junction.x;  
  150.                 terrInfo.z = junction.z;  
  151.                 terrInfo.oldHeight = junction.height;  
  152.                 terrInfo.nowHeight = newHeight;  
  153.                 terrainInfo.push_back(terrInfo);  
  154.   
  155.                 getTerrainData()->setHeight(junction.x, junction.z, newHeight);  
  156.             }  
  157.         }     
  158.         // 从下到上  
  159.         for (it = junctions.begin(); it != junctions.end(); ++it)  
  160.         {  
  161.             const JunctionSelection::Junction& junction = it->second;  
  162.             mModifiedJunctions->add(junction.x, junction.z, 1);  
  163.   
  164.             //  
  165.             if (getTerrainData()->isValidJunction(junction.x,junction.z-1))  
  166.             {  
  167.                 float oldHeight = getTerrainData()->getHeight(junction.x,junction.z);  
  168.                 float newHeight = getTerrainData()->getHeight(junction.x,junction.z-1) * (1-k) + oldHeight * k;  
  169.   
  170.                 TerrainInfo terrInfo;  
  171.                 terrInfo.x = junction.x;  
  172.                 terrInfo.z = junction.z;  
  173.                 terrInfo.oldHeight = junction.height;  
  174.                 terrInfo.nowHeight = newHeight;  
  175.                 terrainInfo.push_back(terrInfo);  
  176.   
  177.                 getTerrainData()->setHeight(junction.x, junction.z, newHeight);  
  178.             }  
  179.         }     
  180.   
  181.         getSceneManipulator()->_fireTerrainHeightChanged(terrainInfo);  
  182.         selection->notifyModified();  
  183.     }  
  184.   
  185. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值