client/PRTerrainLib/Terrain.cpp

325 lines
8.2 KiB
C++

#include "Stdafx.h"
#include "../eterPack/EterPackManager.h"
#include "terrain.h"
#include <math.h>
//////////////////////////////////////////////////////////////////////////
// Texture Set
//////////////////////////////////////////////////////////////////////////
CTextureSet * CTerrainImpl::ms_pTextureSet = NULL;
void CTerrainImpl::SetTextureSet(CTextureSet * pTextureSet)
{
static CTextureSet s_EmptyTextureSet;
if (!pTextureSet)
ms_pTextureSet = &s_EmptyTextureSet;
else
ms_pTextureSet = pTextureSet;
}
CTextureSet * CTerrainImpl::GetTextureSet()
{
if (!ms_pTextureSet)
SetTextureSet(NULL);
return ms_pTextureSet;
}
CTerrainImpl::CTerrainImpl()
{
Initialize();
}
CTerrainImpl::~CTerrainImpl()
{
Clear();
}
void CTerrainImpl::Initialize()
{
memset(m_lWaterHeight, -1, sizeof(m_lWaterHeight));
m_byNumWater = 0;
memset(&m_HeightMapHeader, 0, sizeof(TGA_HEADER));
memset(&m_awShadowMap, 0xFFFF, sizeof(m_awShadowMap));
memset(&m_lpAlphaTexture, NULL, sizeof(m_lpAlphaTexture));
m_lViewRadius = 0;
m_wTileMapVersion = 8976;
m_fHeightScale = 0.0f;
m_lpShadowTexture = NULL;
m_lSplatTilesX = 0;
m_lSplatTilesY = 0;
}
void CTerrainImpl::Clear()
{
for (DWORD i = 0; i < GetTextureSet()->GetTextureCount(); ++i)
{
if (m_lpAlphaTexture[i])
{
m_lpAlphaTexture[i]->Release();
m_lpAlphaTexture[i] = NULL;
}
}
Initialize();
}
bool CTerrainImpl::LoadHeightMap(const char*c_szFileName)
{
Tracef("LoadRawHeightMapFile %s ", c_szFileName);
CMappedFile kMappedFile;
LPCVOID lpcvFileData;
if (!CEterPackManager::Instance().Get(kMappedFile, c_szFileName, &lpcvFileData))
{
Tracen("Error");
TraceError("CTerrainImpl::LoadHeightMap - %s OPEN ERROR", c_szFileName);
return false;
}
memcpy(m_awRawHeightMap, lpcvFileData, sizeof(WORD)*HEIGHTMAP_RAW_XSIZE*HEIGHTMAP_RAW_YSIZE);
return true;
}
bool CTerrainImpl::LoadAttrMap(const char *c_szFileName)
{
DWORD dwStart = ELTimer_GetMSec();
Tracef("LoadAttrMapFile %s ", c_szFileName);
CMappedFile kMappedFile;
LPCVOID lpcvFileData;
if (!CEterPackManager::Instance().Get(kMappedFile, c_szFileName, &lpcvFileData))
{
TraceError("CTerrainImpl::LoadAttrMap - %s OPEN ERROR", c_szFileName);
return false;
}
DWORD dwFileSize = kMappedFile.Size();
BYTE * abFileData = (BYTE *) lpcvFileData;
// LoadAttrMap
{
#pragma pack(push)
#pragma pack(1)
struct SAttrMapHeader
{
WORD m_wMagic;
WORD m_wWidth;
WORD m_wHeight;
};
#pragma pack(pop)
if (dwFileSize < sizeof(SAttrMapHeader))
{
TraceError(" CTerrainImpl::LoadAttrMap - %s FILE SIZE ERROR", c_szFileName);
return false;
}
SAttrMapHeader kAttrMapHeader;
memcpy(&kAttrMapHeader, abFileData, sizeof(kAttrMapHeader));
const WORD c_wAttrMapMagic = 2634;
if (c_wAttrMapMagic != kAttrMapHeader.m_wMagic)
{
TraceError("CTerrainImpl::LoadAttrMap - %s MAGIC NUMBER(%d!=MAGIC[%d]) ERROR", c_szFileName, kAttrMapHeader.m_wMagic, kAttrMapHeader.m_wMagic);
return false;
}
if (ATTRMAP_XSIZE != kAttrMapHeader.m_wWidth)
{
TraceError("CTerrainImpl::LoadAttrMap - kAttrMapHeader(%s).m_width(%d)!=ATTRMAP_XSIZE(%d)", c_szFileName, kAttrMapHeader.m_wWidth, ATTRMAP_XSIZE);
return false;
}
if (ATTRMAP_YSIZE != kAttrMapHeader.m_wHeight)
{
TraceError("CTerrainImpl::LoadAttrMap - kAttrMapHeader(%s).m_height(%d)!=ATTRMAP_YSIZE(%d)", c_szFileName, kAttrMapHeader.m_wHeight, ATTRMAP_YSIZE);
return false;
}
DWORD dwFileRestSize=dwFileSize-sizeof(kAttrMapHeader);
DWORD dwFileNeedSize=sizeof(m_abyAttrMap);
if (dwFileRestSize != dwFileNeedSize)
{
TraceError("CTerrainImpl::LoadAttrMap - %s FILE DATA SIZE(rest %d != need %d) ERROR", c_szFileName, dwFileRestSize, dwFileNeedSize);
return false;
}
BYTE* abSrcAttrData= abFileData+sizeof(kAttrMapHeader);
memcpy(m_abyAttrMap, abSrcAttrData, sizeof(m_abyAttrMap));
}
Tracef("%d\n", ELTimer_GetMSec() - dwStart);
return true;
}
bool CTerrainImpl::RAW_LoadTileMap(const char * c_szFileName)
{
Tracef("LoadSplatFile %s ", c_szFileName);
CMappedFile kMappedFile;
LPCVOID lpcvFileData;
if (!CEterPackManager::Instance().Get(kMappedFile, c_szFileName, &lpcvFileData))
{
Tracen("Error");
TraceError("CTerrainImpl::RAW_LoadTileMap - %s OPEN ERROR", c_szFileName);
return false;
}
memcpy(m_abyTileMap, lpcvFileData, sizeof(BYTE)*(TILEMAP_RAW_XSIZE)*(TILEMAP_RAW_YSIZE));
return true;
}
bool CTerrainImpl::LoadWaterMap(const char * c_szFileName)
{
DWORD dwStart = ELTimer_GetMSec();
if (!LoadWaterMapFile(c_szFileName))
{
memset(m_abyWaterMap, 0xFF, sizeof(m_abyWaterMap));
m_byNumWater = 0;
memset(m_lWaterHeight, -1, sizeof(m_lWaterHeight));
TraceError("CMapOutdoor::LoadWaterMap LoadWaterMapFile(%s) Failed", c_szFileName);
return false;
}
Tracef("LoadWaterMapFile %s %d\n", c_szFileName, ELTimer_GetMSec() - dwStart);
return true;
}
bool CTerrainImpl::LoadWaterMapFile(const char * c_szFileName)
{
CMappedFile kMappedFile;
LPCVOID lpcvFileData;
if (!CEterPackManager::Instance().Get(kMappedFile, c_szFileName, &lpcvFileData))
{
Tracen("Error");
TraceError("CTerrainImpl::LoadWaterMap - %s OPEN ERROR", c_szFileName);
return false;
}
DWORD dwFileSize = kMappedFile.Size();
BYTE* abFileData = (BYTE*)lpcvFileData;
{
#pragma pack(push)
#pragma pack(1)
struct SWaterMapHeader
{
WORD m_wMagic;
WORD m_wWidth;
WORD m_wHeight;
BYTE m_byLayerCount;
};
#pragma pack(pop)
if (dwFileSize < sizeof(SWaterMapHeader))
{
TraceError("CTerrainImpl::LoadWaterMap - %s FILE SIZE ERROR", c_szFileName);
return false;
}
SWaterMapHeader kWaterMapHeader;
memcpy(&kWaterMapHeader, abFileData, sizeof(kWaterMapHeader));
const WORD c_wWaterMapMagic = 5426;
if (c_wWaterMapMagic != kWaterMapHeader.m_wMagic)
{
TraceError("CTerrainImpl::LoadWaterMap - %s MAGIC NUMBER(%d!=MAGIC[%d]) ERROR", c_szFileName, kWaterMapHeader.m_wMagic, c_wWaterMapMagic);
return false;
}
if (WATERMAP_XSIZE != kWaterMapHeader.m_wWidth)
{
TraceError("CTerrainImpl::LoadWaterMap - kWaterMapHeader(%s).m_width(%d)!=WATERMAP_XSIZE(%d)", c_szFileName, kWaterMapHeader.m_wWidth, WATERMAP_XSIZE);
return false;
}
if (WATERMAP_YSIZE != kWaterMapHeader.m_wHeight)
{
TraceError("CTerrainImpl::LoadWaterMap - kWaterMapHeader(%s).m_height(%d)!=WATERMAP_YSIZE(%d)", c_szFileName, kWaterMapHeader.m_wHeight, WATERMAP_YSIZE);
return false;
}
m_byNumWater = kWaterMapHeader.m_byLayerCount;
DWORD dwFileRestSize = dwFileSize - sizeof(kWaterMapHeader);
DWORD dwFileNeedSize = sizeof(m_abyWaterMap) + sizeof(long) * m_byNumWater;
DWORD dwFileNeedSize2 = sizeof(m_abyWaterMap) + sizeof(WORD) * m_byNumWater;
if (dwFileRestSize == dwFileNeedSize2)
{
WORD wWaterHeight[MAX_WATER_NUM + 1];
BYTE * abSrcWaterData = abFileData + sizeof(kWaterMapHeader);
memcpy(m_abyWaterMap, abSrcWaterData, sizeof(m_abyWaterMap));
BYTE * abSrcWaterHeight = abSrcWaterData + sizeof(m_abyWaterMap);
m_byNumWater = MIN(MAX_WATER_NUM, m_byNumWater);
if (m_byNumWater)
{
memcpy(wWaterHeight, abSrcWaterHeight, sizeof(WORD) * m_byNumWater);
for (int i = 0; i < m_byNumWater; ++i)
m_lWaterHeight[i] = wWaterHeight[i];
}
}
else if (dwFileRestSize != dwFileNeedSize)
{
TraceError("CTerrainImpl::LoadWaterMap - %s FILE DATA SIZE(rest %d != need %d) ERROR", c_szFileName, dwFileRestSize, dwFileNeedSize);
return false;
}
BYTE * abSrcWaterData = abFileData + sizeof(kWaterMapHeader);
memcpy(m_abyWaterMap, abSrcWaterData, sizeof(m_abyWaterMap));
BYTE * abSrcWaterHeight = abSrcWaterData + sizeof(m_abyWaterMap);
if (m_byNumWater)
memcpy(m_lWaterHeight, abSrcWaterHeight, sizeof(long) * m_byNumWater);
}
return true;
}
DWORD CTerrainImpl::GetShadowMapColor(float fx, float fy)
{
float fMapSize = (float)(TERRAIN_XSIZE);
float fooMapSize = 1.0f / fMapSize;
if (fx < 0 || fy < 0 || fx >= fMapSize || fy >= fMapSize)
return 0xFFFFFFFF;
fx = fx * fooMapSize * (float)(SHADOWMAP_XSIZE - 1);
fy = fy * fooMapSize * (float)(SHADOWMAP_YSIZE - 1);
int ix, iy;
PR_FLOAT_TO_INT(fx, ix);
PR_FLOAT_TO_INT(fy, iy);
WORD w = *(m_awShadowMap + (iy * SHADOWMAP_XSIZE) + ix);
int b = w & 0x1f; w >>= 5; b <<= 3;
int g = w & 0x1f; w >>= 5; g <<= 3;
int r = w & 0x1f; r <<= 3;
return (DWORD) (0xff << 24) | (g << 16) | (g << 8) | r;
}