📄 mapsplitter.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
MapSplitter.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 "MapSplitter.h"
#include <iostream>
#include <fstream>
#include <vector>
#include "OgreImageCodec.h"
#include "OgreILCodecs.h"
#include "fileutils.h"
namespace Ogre
{
//-----------------------------------------------------------------------
MapSplitter::MapSplitter()
{
}
//-----------------------------------------------------------------------
MapSplitter::~MapSplitter()
{
}
//-----------------------------------------------------------------------
void MapSplitter::ComputeTileSize()
{
uint tileh = MapUtil::getSingleton().getMapHeight() /
PagingLandScapeOptions::getSingleton().world_height;
uint tilew = MapUtil::getSingleton().getMapWidth() /
PagingLandScapeOptions::getSingleton().world_width;
int TileSize = (tilew < tileh)? tilew : tileh;
int i = 0;
while ( i < 256 )
{
if ( TileSize < ( 1 << i ))
{
break;
}
i++;
}
mTileSize = ( 1 << (i - 1));
}
//-----------------------------------------------------------------------
void MapSplitter::init ()
{
if (PagingLandScapeOptions::getSingleton().Paged)
{
mTileSpacing = 1;
b_SaveBigFile = false;
ComputeTileSize ();
}
else
{
b_SaveBigFile = true;
mTileSize = 0;
mTileSpacing = 0;
}
if (PagingLandScapeOptions::getSingleton().landscape_extension == "Raw")
{
b_SaveAsRaw = true;
b_SaveAsExt = false;
}
else
{
b_SaveAsRaw = false;
b_SaveAsExt = true;
}
OutDirectory = PagingLandScapeOptions::getSingleton().OutDirectory;
// make sure directory exists before adding it to archive manager
char *olddir = ChangeToDir (const_cast< char * > (OutDirectory.c_str ()));
RetablishDir (olddir);
ArchiveManager::getSingleton ().addCommonSearchPath(OutDirectory);
}
//-----------------------------------------------------------------------
void MapSplitter::saveAndSplitMap (String filename, Image *newImage)
{
char *olddir = ChangeToDir (const_cast< char * > (OutDirectory.c_str ()));
setCurrentMap (newImage);
if (b_SaveBigFile)
saveCurrentMap (filename);
else
SplitCurrentMap (filename, mTileSize);
RetablishDir (olddir);
}
//-----------------------------------------------------------------------
void MapSplitter::saveAndSpaceAndSplitMap (String filename, Image *newImage)
{
char *olddir = ChangeToDir (const_cast< char * > (OutDirectory.c_str ()));
setCurrentMap (newImage);
if (b_SaveBigFile)
saveCurrentMap (filename);
else
SplitAndSpaceCurrentMap (filename, mTileSpacing, mTileSize);
RetablishDir (olddir);
}
//-----------------------------------------------------------------------
void MapSplitter::setCurrentMap(Image *newImage)
{
mCurrentMap = newImage;
}
//-----------------------------------------------------------------------
const bool MapSplitter::save(String filename, uchar* data,
uint width, uint height,
uint NumBytesPP)
{
bool Okraw = false;
bool Okpng = false;
bool local_SaveAsRaw = false;
String pure_file_name;
String ext_name;
// Get codec according to filename extension
size_t pos = filename.find_last_of(".");
pure_file_name = filename.substr(0, pos + 1);
ext_name = filename.substr(pos + 1);
if (ext_name.length() == 0)
ext_name = PagingLandScapeOptions::getSingleton().landscape_extension;
else
if (StringUtil::startsWith (ext_name, "raw", false))
local_SaveAsRaw = true;
if (b_SaveAsRaw || local_SaveAsRaw)
Okraw = saveRaw(filename, data,
width, height,
NumBytesPP);
else if (b_SaveAsExt)
Okpng = saveExt(filename, data,
width, height,
NumBytesPP);
return Okpng && Okraw;
}
//-----------------------------------------------------------------------
const bool MapSplitter::saveCurrentMap (String filename)
{
bool Okraw = false;
bool Okpng = false;
bool local_SaveAsRaw = false;
String pure_file_name;
String ext_name;
// Get codec according to filename extension
size_t pos = filename.find_last_of(".");
pure_file_name = filename.substr(0, pos + 1);
ext_name = filename.substr(pos + 1);
if (ext_name.length() == 0)
ext_name = PagingLandScapeOptions::getSingleton().landscape_extension;
else
if (StringUtil::startsWith (ext_name, "raw", false))
local_SaveAsRaw = true;
if (b_SaveAsRaw || local_SaveAsRaw)
Okraw = saveCurrentMapAsRaw(filename);
else if (b_SaveAsExt)
Okpng = saveCurrentMapAsExt(filename);
return Okpng && Okraw;
}
//-----------------------------------------------------------------------
const bool MapSplitter::saveCurrentMapAsRaw(String filename)
{
return saveRaw(filename,
mCurrentMap->getData(),
(uint) mCurrentMap->getWidth(),
(uint) mCurrentMap->getHeight(),
(uint) mCurrentMap->getNumElemBytes(mCurrentMap->getFormat ()));
}
//-----------------------------------------------------------------------
const bool MapSplitter::saveRaw(String filename, uchar* data,
uint width, uint height,
uint NumBytesPP)
{
DataChunk image_chunk(data, width*height*NumBytesPP);
std::ofstream outfile;
String FileNameRaw;
// Get codec according to filename extension
std::vector< String > partofname = StringUtil::split (filename, ".");
if (partofname.size () == 0)
FileNameRaw = filename + ".raw";
else
{
for (uint i = 0; i < partofname.size () - 1; i++)
FileNameRaw += partofname[i] + ".";
FileNameRaw += "raw";
}
outfile.open (const_cast< char * > (FileNameRaw.c_str()),
std::ios::binary);
// Write out
outfile << image_chunk.getAsString ();
outfile.close ();
return true;
}
//-----------------------------------------------------------------------
const bool MapSplitter::saveExt(String filename, uchar* data,
uint width, uint height,
uint NumBytesPP)
{
ImageCodec::ImageData imgData;
imgData.width = width;
imgData.height = height;
imgData.size = width*height*NumBytesPP;
if (NumBytesPP == 1)
imgData.format = PF_A8;
if (NumBytesPP == 2)
imgData.format = PF_L16;
else if (NumBytesPP == 3)
imgData.format = PF_R8G8B8;
else if (NumBytesPP == 4)
imgData.format = PF_A8R8G8B8;
imgData.depth = 1;
// Get codec according to filename extension
std::vector<String> partofname = StringUtil::split (filename, ".");
if (partofname.size() == 0 )
{
Except(
Exception::ERR_INVALIDPARAMS,
"Unable to determine image type for '" + filename + "' - invalid extension.",
"MapSplitter::save" );
}
// Get the codec
Codec * pCodec = Codec::getCodec (partofname[partofname.size() - 1]);
DataChunk image_chunk(data, imgData.size);
// Write out
pCodec->codeToFile(image_chunk, filename, &imgData);
return true;
}
//-----------------------------------------------------------------------
const bool MapSplitter::saveCurrentMapAsExt(String filename)
{
return saveExt(filename,
mCurrentMap->getData(),
(uint) mCurrentMap->getWidth(),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -