📄 mapinfinitizer.cpp
字号:
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation; either version 2 of the *
* License, or (at your option) any later version. *
* *
***************************************************************************/
/**
@file
MapInfinitizer.cpp
@brief
Utility that split big map in tiles, pre-calculate splatting by
pre-calculating coverage map and pre-calculate normals.
*/
#include "MapUtil.h"
#include "MapInfinitizer.h"
namespace Ogre
{
//-----------------------------------------------------------------------
MapInfinitizer::MapInfinitizer()
{
}
//-----------------------------------------------------------------------
MapInfinitizer::~MapInfinitizer()
{
}
//-----------------------------------------------------------------------
bool MapInfinitizer::colorsAreDifferrent (uchar *DataA, uchar *DataB)
{
for (uint curr_bpp = 0; curr_bpp < mBpp; curr_bpp++)
{
if (DataA[curr_bpp] - DataB[curr_bpp] > 3)
return true;
}
return false;
}
//-----------------------------------------------------------------------
bool MapInfinitizer::checkForNeed()
{
uint row_count_down = (mheight - mBorderSize) * mImage_width_size;
uint row_count_up = 0;
for (uint y = 0; y < mBorderSize; y++)
{
uint col_count_down = row_count_down;
uint col_count_up = row_count_up;
for (uint x = 0; x < mwidth; x++)
{
uchar* TargetColorUp = &mData[x * mBpp];
uchar* TargetColorDown = &mData[mheight * (mwidth - 1) * mBpp + x * mBpp];
if (colorsAreDifferrent(TargetColorUp, TargetColorDown))
{
return true;
}
col_count_up += mBpp;
col_count_down += mBpp;
}
row_count_up += mImage_width_size;
row_count_down += mImage_width_size;
}
uint row_count = 0;
for (uint y = 0; y < mheight; y++)
{
uchar* TargetColorRight = &mData[row_count + mImage_width_size];
uchar* TargetColorLeft = &mData[row_count];
if (colorsAreDifferrent(TargetColorRight, TargetColorLeft))
{
return true;
}
row_count += mImage_width_size;
}
std::cout << "no need for Infinitizing, your Map is already infinite\n";
return false;
}
//-----------------------------------------------------------------------
void MapInfinitizer::lerpColor (uchar *DataDest, uchar *DataA, uchar *DataB,
Real Factor)
{
for (uint curr_bpp = 0; curr_bpp < mBpp; curr_bpp++)
{
DataDest[curr_bpp] = uchar (((uint) DataA[curr_bpp]) * (1.0f - Factor) +
((uint) DataB[curr_bpp]) * Factor);
}
}
//-----------------------------------------------------------------------
void MapInfinitizer::lerpCorners ()
{
}
//-----------------------------------------------------------------------
void MapInfinitizer::lerpUpAndDown ()
{
uint row_count_down = (mheight - mBorderSize) * mImage_width_size;
uint row_count_up = 0;
for (uint y = 0; y < mBorderSize; y++)
{
uint col_count_down = row_count_down;
uint col_count_up = row_count_up;
Real factor1 = (Real) y / mBorderSize; // from 0 to 1
Real factor2 = 1.0f - factor1; // from 1 to 0
for (uint x = 0; x < mwidth; x++)
{
uchar* TargetColorUp = &mData[x * mBpp];
uchar* TargetColorDown = &mData[mheight * (mwidth - 1) * mBpp + x * mBpp];
// blend on the down side
lerpColor (&mData[col_count_down], &mData[col_count_down],
TargetColorUp, factor1);// from 0 to 1
// blend on the up side
lerpColor (&mData[col_count_up], &mData[col_count_up],
TargetColorDown, factor2); // from 1 to 0
col_count_up += mBpp;
col_count_down += mBpp;
}
row_count_up += mImage_width_size;
row_count_down += mImage_width_size;
}
}
//-----------------------------------------------------------------------
void MapInfinitizer::LerpLeftAndRight ()
{
uint row_count = 0;
for (uint y = 0; y < mheight; y++)
{
uint col_count_left = row_count;
uint col_count_right = row_count + (mwidth - mBorderSize) * mBpp;
//uint col_count_left_inv = row_count + mBorderSize * mBpp;
//uint col_count_right_inv = row_count + mImage_width_size;
uchar* TargetColorRight = &mData[row_count + mImage_width_size];
uchar* TargetColorLeft = &mData[row_count];
for (uint x = 0; x < mBorderSize; x++)
{
// from 1 to 0
Real factor1 = (Real) (mBorderSize - x) / mBorderSize;
// from 0 to 1
Real factor2 = 1.0f - factor1;
// lerp on the left side
lerpColor (&mData[col_count_left],
&mData[col_count_left],
TargetColorRight,
factor1); // from 0 to 1
// lerp on the right side
lerpColor (&mData[col_count_right],
&mData[col_count_right],
TargetColorLeft,
factor2); // from 1 to 0
col_count_left += mBpp;
col_count_right += mBpp;
//col_count_left_inv -= mBpp;
//col_count_right_inv -= mBpp;
}
row_count += mImage_width_size;
}
}
//-----------------------------------------------------------------------
void MapInfinitizer::blendColor (uchar *DataDest, uchar *DataA, Real FactorA,
uchar *DataB, Real FactorB)
{
for (uint curr_bpp = 0; curr_bpp < mBpp; curr_bpp++)
{
DataDest[curr_bpp] = uchar (((uint) DataA[curr_bpp]) * FactorA +
((uint) DataB[curr_bpp]) * FactorB);
}
}
//-----------------------------------------------------------------------
void MapInfinitizer::BlendCorners ()
{
}
//-----------------------------------------------------------------------
void MapInfinitizer::BlendUpAndDown ()
{
// example with mBordersize = 5
//
// Direction of copying : up to down
//
// ||
// ||
//
// UP storing DOWN storing
//
// ------- -------
// Border Border
// ------- -------
// 0.5 0.5 0.0 1.0
// 0.6 0.4 0.1 0.9
// 0.7 0.3 0.2 0.8
// 0.8 0.2 0.3 0.7
// 0.9 0.1 0.4 0.6
// 1.0 0.0 0.5 0.5
// ------- ------
// Border Border
// ------- ------
// Up down Up down
//
//
uint row_count_down = (mheight - mBorderSize) * mImage_width_size;
uint row_count_up = 0;
for (uint y = 0; y < mBorderSize; y++)
{
uint col_count_down = row_count_down;
uint col_count_up = row_count_up;
Real factor1 = (Real) y / mBorderSize2; // from 0 to 0.5
Real factor2 = 1.0f - factor1; // from 1 to 0.5
Real factor3 = (Real) (mBorderSize - y) / mBorderSize2; // from 0.5 to 0
Real factor4 = 1.0f - factor3 ;// from 0.5 to 1
for (uint x = 0; x < mwidth; x++)
{
// blend on the up side
blendColor (&mData[col_count_down],
&mData[col_count_down], factor2, // from 1 to 0.5
&mData[col_count_up], factor1);// from 0 to 0.5
// blend on the up side
blendColor (&mData[col_count_up],
&mData[col_count_down], factor3, // from 0.5 to 0
&mData[col_count_up], factor4); // from 0.5 to 1
col_count_up += mBpp;
col_count_down += mBpp;
}
row_count_up += mImage_width_size;
row_count_down += mImage_width_size;
}
}
//-----------------------------------------------------------------------
void MapInfinitizer::BlendLeftAndRight ()
{
// example with mBordersize = 5
//
// Direction of the copying : left to right
// ===>
//
// LEFT storing
// --0.5--0.4--0.3--0.2--0.1--0.0||Border|| right factor
// ||Border||0.5--0.6--0.7--0.8--0.9--1.0 left factor
//
//
//
// RIGHT storing
// --1.0--0.9--0.8--0.7--0.6--0.5||Border|| right factor
// ||Border||0.0--0.1--0.2--0.3--0.4--0.5 left factor
uint row_count = 0;
for (uint y = 0; y < mheight; y++)
{
uint col_count_left = row_count;
uint col_count_right = row_count + (mwidth - mBorderSize) * mBpp;
//uint col_count_left_inv = row_count + mBorderSize * mBpp;
//uint col_count_right_inv = row_count + mImage_width_size;
for (uint x = 0; x < mBorderSize; x++)
{
// from 0.5 to 0
Real factor1 = (Real) (mBorderSize - x) / mBorderSize2;
// from 0.5 to 1
Real factor2 = 1.0f - factor1;
// from 0 to 0.5
Real factor3 = (Real) x / mBorderSize2;
// from 1 to 0.5
Real factor4 = 1.0f - factor3;
// blend on the left side
blendColor (&mData[col_count_left],
//&mData[col_count_right_inv], factor1, // from 0.5 to 0
&mData[col_count_left], factor3, // from 0 to 0.5
&mData[col_count_left], factor2); // from 0.5 to 1
// blend on the right side
blendColor (&mData[col_count_right],
//&mData[col_count_left_inv], factor3, // from 0 to 0.5
&mData[col_count_left], factor3, // from 0 to 0.5
&mData[col_count_right], factor4); // from 1 to 0.5
col_count_left += mBpp;
col_count_right += mBpp;
//col_count_left_inv -= mBpp;
//col_count_right_inv -= mBpp;
}
row_count += mImage_width_size;
}
}
//-----------------------------------------------------------------------
bool MapInfinitizer::Infinitize (Image *BigImage, uint BorderSize,
Real RandFactor, uint BlurFactor)
{
mData = BigImage->getData();
mwidth = BigImage->getWidth ();
mheight = BigImage->getHeight ();
mBpp = BigImage->getNumElemBytes (BigImage->getFormat ());
mImage_width_size = mwidth * mBpp;
mBorderSize = BorderSize;
mBorderSize2 = mBorderSize * 2;
mBlurFactor = BlurFactor;
mRandFactor = RandFactor;
if (checkForNeed ())
{
std::cout << "Infinitizing.\n";
lerpUpAndDown ();
LerpLeftAndRight ();
//lerpCorners ();
//BlendUpAndDown ();
//BlendLeftAndRight ();
//BlendCorners ();
return true;
}
return false;
}
}//namespace Ogre
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -