⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mapnormaler.cpp

📁 使用stl技术,(还没看,是听说的)
💻 CPP
字号:
#include "MapUtil.h"
#include "MapNormaler.h"
#include "OgrePagingLandScapeOptions.h"

namespace Ogre
{

MapNormaler::MapNormaler()
{
    reset();
}
MapNormaler::~MapNormaler()
{
    delete[] Normals;
}

//----------------------------------------------------------------------
Image *MapNormaler::getNormalMap()
{ 
    if (mAlreadyComputed == false)
    {
        CalcNormalMap();
        mAlreadyComputed = true;
    }
    return &NormalMap;
}
//----------------------------------------------------------------------
void MapNormaler::reset()
{
    mAlreadyComputed = false;
}

//----------------------------------------------------------------------
const Vector3 MapNormaler::getNormalAt (const uint x, const uint z)
{      
    if (mAlreadyComputed == false)
    {
        CalcNormalMap();
        mAlreadyComputed = true;
    }
    return Normals[( z * mWidth) + x];
}
#define getHeight(A,B) (MapUtil::getSingleton().getHeight(A, B))
//----------------------------------------------------------------------
void MapNormaler::CalcNormalMap()
{
    uint  height = MapUtil::getSingleton().getMapHeight ();
    uint  width = MapUtil::getSingleton().getMapWidth ();
    mHeight = height;
    mWidth = width;
    DataChunk dc;
    dc.allocate(width * height * 3);
    uchar *NormalData = dc.getPtr();

    Normals = new Vector3 [width * height];

    std::cout << "normal Map Calc : ";

    // First General method : (9 adds and 6 muls + a normalization)
    //        *---v3--*
    //        |   |   |
    //        |   |   |
    //        v1--X--v2
    //        |   |   |
    //        |   |   |
    //        *---v4--*
    //
    //        U = v2 - v1;
    //        V = v4 - v3;
    //        N = Cross(U, V);
    //        N.normalise;
    //
    // BUT IN CASE OF A HEIGHTMAP : 
    //
    //   if you do some math by hand before you code, 
    //   you can see that N is immediately given by 
    //  Approximation (2 adds and a normalization)
    // 
    //        N = Vector3(z[x-1][y] - z[x+1][y], z[x][y-1] - z[x][y+1], 2); 
    //        N.normalise();
    //
    // or even using SOBEL operator VERY accurate! 
    // (14 adds and a normalization)
    //
    //       N = Vector3 (z[x-1][y-1] + z[x-1][y] + z[x-1][y] + z[x-1][y+1] - z[x+1][y-1] - z[x+1][y] - z[x+1][y] - z[x+1][y+1], 
    //                     z[x-1][y-1] + z[x][y-1] + z[x][y-1] + z[x+1][y-1] - z[x-1][y+1] - z[x][y+1] - z[x][y+1] - z[x+1][y+1], 
    //                     8);
    //       N.normalize();


    uint j = 0; 
    uint k = 0;
    for (uint z = 0; z < height; z++)
    {
        DEBUG_PROGRESS_OUTPUT(".")
        for (uint x = 0; x < width; x++)
        {
            // Fast SOBEL filter and mathematically correct
            Normals[k].x = getHeight(x-1,z-1) + getHeight (x-1, z) + getHeight (x-1, z) + getHeight (x-1, z+1) - getHeight (x+1, z-1) - getHeight (x+1, z) - getHeight (x+1, z) - getHeight (x+1, z+1); 
            Normals[k].z = getHeight (x-1, z-1) + getHeight (x, z-1) + getHeight (x, z-1) + getHeight (x+1, z-1) - getHeight (x-1, z+1) - getHeight (x, z+1) - getHeight (x, z+1) - getHeight (x+1, z+1);
            Normals[k].y = 8.0f; 

            // very Fast SOBEL filter
            // (not mathematically correct, approximation)
            // But gives same result as above 
            //Normals[k].x = getHeight (x - 1 , z)   - getHeight (x + 1, z);
            //Normals[k].z = getHeight (x,      z-1) - getHeight (x    , z + 1);
            //Normals[k].y = 2.0f; 

            
            Normals[k].normalise ();

            NormalData[j++] = (uchar)((Normals[k].x + 1.0f) * 127.5f);
            NormalData[j++] = (uchar)((Normals[k].y + 1.0f) * 127.5f);
            NormalData[j++] = (uchar)((Normals[k].z + 1.0f) * 127.5f);

            k++;
        }
    }
    NormalMap.loadRawData(dc, width, height, PF_R8G8B8);
    dc.clear();
    std::cout << "\n";
}

}//namespace Ogre

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -