port: CMapOutdoor + PythonBackground + minimap (1:1 40250)

GameLib map/area/terrain units, PRTerrainLib Terrain/TextureSet,
PythonBackground(+Module) and ColorTransitionHelper ported verbatim;
pending stand-ins and background module stubs removed. Hand edits:
BeginEnvironment's pointer tag via uintptr_t, LoadWaterMap reads the
file's 32-bit longs. Terrain draw passes stay platform no-ops (Godot
draws the terrain). RecordingDevice gains textures, buffers and render
targets; orthographic draws become UI commands so CPythonMiniMap's
masked tiles show through minimap_image_filter in python_ui_surface.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
shenlei
2026-09-24 03:50:09 +09:00
co-authored by Claude Opus 5.5
parent b69116992c
commit 2ead95756e
100 changed files with 17679 additions and 1514 deletions
+30
View File
@@ -0,0 +1,30 @@
#ifndef __ETER_FILE_DIR__
#define __ETER_FILE_DIR__
#include <windows.h>
class CDir
{
public:
CDir();
virtual ~CDir();
void Destroy();
bool Create(const char* c_szFilter, const char* c_szPath="", BOOL bCheckedExtension = FALSE);
protected:
virtual bool OnFolder(const char* c_szFilter, const char* c_szPath, const char* c_szName) = 0;
virtual bool OnFile(const char* c_szPath, const char* c_szName) = 0;
protected:
bool IsFolder();
void Initialize();
protected:
WIN32_FIND_DATA m_wfd;
HANDLE m_hFind;
};
#endif
+16
View File
@@ -0,0 +1,16 @@
#ifndef __INC_ETERBASE_TEMPFILE_H__
#define __INC_ETERBASE_TEMPFILE_H__
#include "FileBase.h"
class CTempFile : public CFileBase
{
public:
CTempFile(const char * c_pszPrefix = NULL);
virtual ~CTempFile();
protected:
char m_szFileName[MAX_PATH+1];
};
#endif
@@ -0,0 +1,104 @@
#include "StdAfx.h"
#include "ColorTransitionHelper.h"
void CColorTransitionHelper::Clear(const float & c_rfRed,
const float & c_rfGreen,
const float & c_rfBlue,
const float & c_rfAlpha)
{
m_fSrcRed = c_rfRed;
m_fSrcGreen = c_rfGreen;
m_fSrcBlue = c_rfBlue;
m_fSrcAlpha = c_rfAlpha;
m_fDstRed = c_rfRed;
m_fDstGreen = c_rfGreen;
m_fDstBlue = c_rfBlue;
m_fDstAlpha = c_rfAlpha;
m_dwCurColor = 0x00000000;
m_dwStartTime = m_dwDuration = 0;
}
void CColorTransitionHelper::SetSrcColor(const float & c_rfRed,
const float & c_rfGreen,
const float & c_rfBlue,
const float & c_rfAlpha)
{
m_fSrcRed = c_rfRed;
m_fSrcGreen = c_rfGreen;
m_fSrcBlue = c_rfBlue;
m_fSrcAlpha = c_rfAlpha;
}
void CColorTransitionHelper::SetTransition(const float & c_rfRed,
const float & c_rfGreen,
const float & c_rfBlue,
const float & c_rfAlpha,
const DWORD & dwDuration)
{
m_fDstRed = c_rfRed;
m_fDstGreen = c_rfGreen;
m_fDstBlue = c_rfBlue;
m_fDstAlpha = c_rfAlpha;
m_dwDuration = dwDuration;
}
void CColorTransitionHelper::StartTransition()
{
m_bTransitionStarted = true;
m_dwStartTime = GetCurrentTime();
}
bool CColorTransitionHelper::Update()
{
// if (!m_bTransitionStarted)
// return false;
DWORD dwCurTime = GetCurrentTime();
DWORD dwElapsedTime = dwCurTime - m_dwStartTime;
float fpercent = (float)(dwElapsedTime) / (float)(m_dwDuration);
if (fpercent <= 0.0f)
fpercent = 0.0f;
if (fpercent >= 1.0f)
fpercent = 1.0f;
float fCurRed, fCurGreen, fCurBlue, fCurAlpha;
fCurRed = m_fSrcRed + (m_fDstRed - m_fSrcRed) * fpercent;
fCurGreen = m_fSrcGreen + (m_fDstGreen - m_fSrcGreen) * fpercent;
fCurBlue = m_fSrcBlue + (m_fDstBlue - m_fSrcBlue) * fpercent;
fCurAlpha = m_fSrcAlpha + (m_fDstAlpha - m_fSrcAlpha) * fpercent;
// Tracef("%f, %f, %f, %f\n", fCurRed, fCurGreen, fCurBlue, fCurAlpha);
m_dwCurColor = (((DWORD)(fCurAlpha * 255.0f)&0xff)<< 24) |
(((DWORD)(fCurRed * 255.0f)&0xff) << 16) |
(((DWORD)(fCurGreen * 255.0f)&0xff) << 8) |
((DWORD)(fCurBlue * 255.0f)&0xff);
if ( (1.0f == fpercent) && (fCurAlpha == m_fDstAlpha) && (fCurRed == m_fDstRed) && (fCurGreen == m_fDstGreen) && (fCurBlue == m_fDstBlue) )
{
m_bTransitionStarted = false;
return false;
}
return true;
}
const D3DCOLOR & CColorTransitionHelper::GetCurColor()
{
return m_dwCurColor;
}
CColorTransitionHelper::CColorTransitionHelper():m_bTransitionStarted(false)
{
Clear(0.0f, 0.0f, 0.0f, 0.0f);
}
CColorTransitionHelper::~CColorTransitionHelper()
{
Clear(0.0f, 0.0f, 0.0f, 0.0f);
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+265
View File
@@ -0,0 +1,265 @@
#include "StdAfx.h"
#include "DungeonBlock.h"
#include "../EterLib/StateManager.h"
class CDungeonModelInstance : public CGrannyModelInstance
{
public:
CDungeonModelInstance() {}
virtual ~CDungeonModelInstance() {}
void RenderDungeonBlock()
{
if (IsEmpty())
return;
STATEMANAGER.SetVertexShader(ms_pnt2VS);
LPDIRECT3DVERTEXBUFFER8 lpd3dRigidPNTVtxBuf = m_pModel->GetPNTD3DVertexBuffer();
if (lpd3dRigidPNTVtxBuf)
{
STATEMANAGER.SetStreamSource(0, lpd3dRigidPNTVtxBuf, sizeof(TPNT2Vertex));
RenderMeshNodeListWithTwoTexture(CGrannyMesh::TYPE_RIGID, CGrannyMaterial::TYPE_BLEND_PNT);
}
}
void RenderDungeonBlockShadow()
{
if (IsEmpty())
return;
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, 0xffffffff);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCCOLOR);
STATEMANAGER.SetVertexShader(ms_pnt2VS);
LPDIRECT3DVERTEXBUFFER8 lpd3dRigidPNTVtxBuf = m_pModel->GetPNTD3DVertexBuffer();
if (lpd3dRigidPNTVtxBuf)
{
STATEMANAGER.SetStreamSource(0, lpd3dRigidPNTVtxBuf, sizeof(TPNT2Vertex));
RenderMeshNodeListWithoutTexture(CGrannyMesh::TYPE_RIGID, CGrannyMaterial::TYPE_BLEND_PNT);
}
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1);
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP);
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAOP);
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND);
STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND);
}
};
struct FUpdate
{
float fElapsedTime;
D3DXMATRIX * pmatWorld;
void operator() (CGrannyModelInstance * pInstance)
{
pInstance->Update(CGrannyModelInstance::ANIFPS_MIN);
pInstance->UpdateLocalTime(fElapsedTime);
pInstance->Deform(pmatWorld);
}
};
void CDungeonBlock::Update()
{
Transform();
FUpdate Update;
Update.fElapsedTime = 0.0f;
Update.pmatWorld = &m_worldMatrix;
for_each(m_ModelInstanceContainer.begin(), m_ModelInstanceContainer.end(), Update);
}
struct FRender
{
void operator() (CDungeonModelInstance * pInstance)
{
pInstance->RenderDungeonBlock();
}
};
void CDungeonBlock::Render()
{
// if (!isShow())
// return;
for_each(m_ModelInstanceContainer.begin(), m_ModelInstanceContainer.end(), FRender());
}
struct FRenderShadow
{
void operator() (CDungeonModelInstance * pInstance)
{
pInstance->RenderDungeonBlockShadow();
}
};
void CDungeonBlock::OnRenderShadow()
{
for_each(m_ModelInstanceContainer.begin(), m_ModelInstanceContainer.end(), FRenderShadow());
}
struct FBoundBox
{
D3DXVECTOR3 * m_pv3Min;
D3DXVECTOR3 * m_pv3Max;
FBoundBox(D3DXVECTOR3 * pv3Min, D3DXVECTOR3 * pv3Max)
{
m_pv3Min = pv3Min;
m_pv3Max = pv3Max;
}
void operator() (CGrannyModelInstance * pInstance)
{
pInstance->GetBoundBox(m_pv3Min, m_pv3Max);
}
};
bool CDungeonBlock::GetBoundingSphere(D3DXVECTOR3 & v3Center, float & fRadius)
{
v3Center = m_v3Center;
fRadius = m_fRadius;
D3DXVec3TransformCoord(&v3Center, &v3Center, &GetTransform());
return true;
}
void CDungeonBlock::OnUpdateCollisionData(const CStaticCollisionDataVector * pscdVector)
{
assert(pscdVector);
CStaticCollisionDataVector::const_iterator it;
for(it = pscdVector->begin();it!=pscdVector->end();++it)
{
AddCollision(&(*it),&GetTransform());
}
}
void CDungeonBlock::OnUpdateHeighInstance(CAttributeInstance * pAttributeInstance)
{
assert(pAttributeInstance);
SetHeightInstance(pAttributeInstance);
}
bool CDungeonBlock::OnGetObjectHeight(float fX, float fY, float * pfHeight)
{
if (m_pHeightAttributeInstance && m_pHeightAttributeInstance->GetHeight(fX, fY, pfHeight))
return true;
return false;
}
void CDungeonBlock::BuildBoundingSphere()
{
D3DXVECTOR3 v3Min, v3Max;
for_each(m_ModelInstanceContainer.begin(), m_ModelInstanceContainer.end(), FBoundBox(&v3Min, &v3Max));
m_v3Center = (v3Min+v3Max) * 0.5f;
const auto vv = (v3Max - v3Min);
m_fRadius = D3DXVec3Length(&vv)*0.5f + 150.0f; // extra length for attached objects
}
bool CDungeonBlock::Intersect(float * pfu, float * pfv, float * pft)
{
TModelInstanceContainer::iterator itor = m_ModelInstanceContainer.begin();
for (; itor != m_ModelInstanceContainer.end(); ++itor)
{
CDungeonModelInstance * pInstance = *itor;
if (pInstance->Intersect(&CGraphicObjectInstance::GetTransform(), pfu, pfv, pft))
return true;
}
return false;
}
void CDungeonBlock::GetBoundBox(D3DXVECTOR3 * pv3Min, D3DXVECTOR3 * pv3Max)
{
pv3Min->x = +10000000.0f;
pv3Min->y = +10000000.0f;
pv3Min->z = +10000000.0f;
pv3Max->x = -10000000.0f;
pv3Max->y = -10000000.0f;
pv3Max->z = -10000000.0f;
TModelInstanceContainer::iterator itor = m_ModelInstanceContainer.begin();
for (; itor != m_ModelInstanceContainer.end(); ++itor)
{
CDungeonModelInstance * pInstance = *itor;
D3DXVECTOR3 v3Min;
D3DXVECTOR3 v3Max;
pInstance->GetBoundBox(&v3Min, &v3Max);
pv3Min->x = min(v3Min.x, pv3Min->x);
pv3Min->y = min(v3Min.x, pv3Min->y);
pv3Min->z = min(v3Min.x, pv3Min->z);
pv3Max->x = max(v3Max.x, pv3Max->x);
pv3Max->y = max(v3Max.x, pv3Max->y);
pv3Max->z = max(v3Max.x, pv3Max->z);
}
}
bool CDungeonBlock::Load(const char * c_szFileName)
{
Destroy();
m_pThing = (CGraphicThing *)CResourceManager::Instance().GetResourcePointer(c_szFileName);
m_pThing->AddReference();
if (m_pThing->GetModelCount() <= 0)
{
TraceError("CDungeonBlock::Load(filename=%s) - model count is %d\n", c_szFileName, m_pThing->GetModelCount());
return false;
}
m_ModelInstanceContainer.reserve(m_pThing->GetModelCount());
for (int i = 0; i < m_pThing->GetModelCount(); ++i)
{
CDungeonModelInstance * pModelInstance = new CDungeonModelInstance;
pModelInstance->SetMainModelPointer(m_pThing->GetModelPointer(i), &m_kDeformableVertexBuffer);
DWORD dwVertexCount = pModelInstance->GetVertexCount();
m_kDeformableVertexBuffer.Destroy();
m_kDeformableVertexBuffer.Create(
dwVertexCount,
D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1,
D3DUSAGE_WRITEONLY,
D3DPOOL_MANAGED);
m_ModelInstanceContainer.push_back(pModelInstance);
}
return true;
}
void CDungeonBlock::__Initialize()
{
m_v3Center = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
m_fRadius = 0.0f;
m_pThing = NULL;
}
void CDungeonBlock::Destroy()
{
if (m_pThing)
{
m_pThing->Release();
m_pThing = NULL;
}
stl_wipe(m_ModelInstanceContainer);
__Initialize();
}
CDungeonBlock::CDungeonBlock()
{
__Initialize();
}
CDungeonBlock::~CDungeonBlock()
{
Destroy();
}
+101
View File
@@ -0,0 +1,101 @@
#include "StdAfx.h"
#include "MapBase.h"
CMapBase::CMapBase()
{
Clear();
}
CMapBase::~CMapBase()
{
Clear();
}
void CMapBase::Clear()
{
m_strName = "";
m_eType = MAPTYPE_INVALID;
mc_pEnvironmentData = NULL;
Leave();
}
bool CMapBase::Enter()
{
m_bReady = true;
return true;
}
bool CMapBase::Leave()
{
m_bReady = false;
return true;
}
void CMapBase::SetEnvironmentDataPtr(const TEnvironmentData * c_pEnvironmentData)
{
mc_pEnvironmentData = c_pEnvironmentData;
OnSetEnvironmentDataPtr();
}
void CMapBase::ResetEnvironmentDataPtr(const TEnvironmentData * c_pEnvironmentData)
{
mc_pEnvironmentData = c_pEnvironmentData;
OnResetEnvironmentDataPtr();
}
void CMapBase::Render()
{
if (IsReady())
OnRender();
}
bool CMapBase::LoadProperty()
{
std::string strFileName = GetName() + "\\MapProperty.txt";
CTokenVectorMap stTokenVectorMap;
if (!LoadMultipleTextData(strFileName.c_str(), stTokenVectorMap))
{
TraceError("CMapBase::LoadProperty(FileName=%s) - LoadMultipleTextData ERROR \306\304\300\317\300\314 \276\370\300\273 \260\241\264\311\274\272\300\314 \270\271\275\300\264\317\264\331.", strFileName.c_str());
return false;
}
if (stTokenVectorMap.end() == stTokenVectorMap.find("scripttype"))
{
TraceError("CMapBase::LoadProperty(FileName=%s) - FIND 'scripttype' - FAILED", strFileName.c_str());
return false;
}
if (stTokenVectorMap.end() == stTokenVectorMap.find("maptype"))
{
TraceError("CMapBase::LoadProperty(FileName=%s) - FIND 'maptype' - FAILED", strFileName.c_str());
return false;
}
// NOTE: 이미 존재하는 맵 데이터와 동일한 데이터를 사용하는 맵을 새로 추가할 때, 맵 배포 용량을 줄이기 위한 작업.
// MapProperty.txt 파일에 ParentMapName 값이 설정되어 있다면, 실제 모든 데이터는 ParentMap에서 읽어온다.
// 데이터의 부분공유(부분 오버라이트?) 기능은 필요 없대서, Parent Map에서 모든 데이터를 읽어옴.
if (stTokenVectorMap.end() != stTokenVectorMap.find("parentmapname"))
{
m_strParentMapName = stTokenVectorMap["parentmapname"][0];
}
const std::string & c_rstrType = stTokenVectorMap["scripttype"][0];
const std::string & c_rstrMapType = stTokenVectorMap["maptype"][0];
if (0 != c_rstrType.compare("MapProperty"))
{
TraceError("CMapBase::LoadProperty(FileName=%s) - Resourse Type ERROR", strFileName.c_str());
return false;
}
if (0 == c_rstrMapType.compare("Indoor"))
SetType(MAPTYPE_INDOOR);
else if (0 == c_rstrMapType.compare("Outdoor"))
SetType(MAPTYPE_OUTDOOR);
else if (0 == c_rstrMapType.compare("Invalid"))
SetType(MAPTYPE_OUTDOOR);
return true;
}
+638
View File
@@ -0,0 +1,638 @@
#include "StdAfx.h"
#include "../EterLib/StateManager.h"
#include "../EterPack/EterPackManager.h"
#include "MapManager.h"
#include "MapOutdoor.h"
#include "PropertyLoader.h"
//////////////////////////////////////////////////////////////////////////
// 기본 함수
//////////////////////////////////////////////////////////////////////////
bool CMapManager::IsMapOutdoor()
{
if (m_pkMap)
return true;
return false;
}
CMapOutdoor& CMapManager::GetMapOutdoorRef()
{
assert(NULL!=m_pkMap);
return *m_pkMap;
}
CMapManager::CMapManager() : mc_pcurEnvironmentData(NULL)
{
m_pkMap = NULL;
m_isSoftwareTilingEnableReserved=false;
// Initialize();
}
CMapManager::~CMapManager()
{
Destroy();
}
bool CMapManager::IsSoftwareTilingEnable()
{
return CTerrainPatch::SOFTWARE_TRANSFORM_PATCH_ENABLE;
}
void CMapManager::ReserveSoftwareTilingEnable(bool isEnable)
{
m_isSoftwareTilingEnableReserved=isEnable;
}
void CMapManager::Initialize()
{
mc_pcurEnvironmentData = NULL;
__LoadMapInfoVector();
}
void CMapManager::Create()
{
assert(NULL==m_pkMap && "CMapManager::Create");
if (m_pkMap)
{
Clear();
return;
}
CTerrainPatch::SOFTWARE_TRANSFORM_PATCH_ENABLE=m_isSoftwareTilingEnableReserved;
m_pkMap = (CMapOutdoor*)AllocMap();
assert(NULL!=m_pkMap && "CMapManager::Create MAP is NULL");
}
void CMapManager::Destroy()
{
stl_wipe_second(m_EnvironmentDataMap);
if (m_pkMap)
{
m_pkMap->Clear();
delete m_pkMap;
m_pkMap = NULL;
}
}
void CMapManager::Clear()
{
if (m_pkMap)
m_pkMap->Clear();
}
CMapBase * CMapManager::AllocMap()
{
return new CMapOutdoor;
}
//////////////////////////////////////////////////////////////////////////
// Map
//////////////////////////////////////////////////////////////////////////
void CMapManager::LoadProperty()
{
CPropertyLoader PropertyLoader;
PropertyLoader.SetPropertyManager(&m_PropertyManager);
PropertyLoader.Create("*.*", "Property");
}
bool CMapManager::LoadMap(const std::string & c_rstrMapName, float x, float y, float z)
{
CMapOutdoor& rkMap = GetMapOutdoorRef();
rkMap.Leave();
rkMap.SetName(c_rstrMapName);
rkMap.LoadProperty();
if ( CMapBase::MAPTYPE_INDOOR == rkMap.GetType())
{
TraceError("CMapManager::LoadMap() Indoor Map Load Failed");
return false;
}
else if (CMapBase::MAPTYPE_OUTDOOR == rkMap.GetType())
{
if (!rkMap.Load(x, y, z))
{
TraceError("CMapManager::LoadMap() Outdoor Map Load Failed");
return false;
}
RegisterEnvironmentData(0, rkMap.GetEnvironmentDataName().c_str());
SetEnvironmentData(0);
}
else
{
TraceError("CMapManager::LoadMap() Invalid Map Type");
return false;
}
rkMap.Enter();
return true;
}
bool CMapManager::IsMapReady()
{
if (!m_pkMap)
return false;
return m_pkMap->IsReady();
}
bool CMapManager::UnloadMap(const std::string c_strMapName)
{
CMapOutdoor& rkMap=GetMapOutdoorRef();
if (c_strMapName != rkMap.GetName() && "" != rkMap.GetName())
{
LogBoxf("%s: Unload Map Failed", c_strMapName.c_str());
return false;
}
Clear();
return true;
}
bool CMapManager::UpdateMap(float fx, float fy, float fz)
{
if (!m_pkMap)
return false;
CMapOutdoor& rkMap=GetMapOutdoorRef();
return rkMap.Update(fx, -fy, fz);
}
void CMapManager::UpdateAroundAmbience(float fx, float fy, float fz)
{
if (!m_pkMap)
return;
CMapOutdoor& rkMap=GetMapOutdoorRef();
rkMap.UpdateAroundAmbience(fx, -fy, fz);
}
float CMapManager::GetHeight(float fx, float fy)
{
if (!m_pkMap)
{
TraceError("CMapManager::GetHeight(%f, %f) - \270\312\300\314 \273\375\274\272\265\307\301\366 \276\312\300\272 \273\363\305\302\277\241\274\255 \301\242\261\331", fx, fy);
return 0.0f;
}
CMapOutdoor& rkMap=GetMapOutdoorRef();
return rkMap.GetHeight(fx, fy);
}
float CMapManager::GetTerrainHeight(float fx, float fy)
{
if (!m_pkMap)
{
TraceError("CMapManager::GetTerrainHeight(%f, %f) - \270\312\300\314 \273\375\274\272\265\307\301\366 \276\312\300\272 \273\363\305\302\277\241\274\255 \301\242\261\331", fx, fy);
return 0.0f;
}
CMapOutdoor& rkMap=GetMapOutdoorRef();
return rkMap.GetTerrainHeight(fx, fy);
}
bool CMapManager::GetWaterHeight(int iX, int iY, long * plWaterHeight)
{
if (!m_pkMap)
{
TraceError("CMapManager::GetTerrainHeight(%f, %f) - \270\312\300\314 \273\375\274\272\265\307\301\366 \276\312\300\272 \273\363\305\302\277\241\274\255 \301\242\261\331", iX, iY);
return false;
}
CMapOutdoor& rkMap=GetMapOutdoorRef();
return rkMap.GetWaterHeight(iX, iY, plWaterHeight);
}
//////////////////////////////////////////////////////////////////////////
// Environment
//////////////////////////////////////////////////////////////////////////
void CMapManager::BeginEnvironment()
{
if (!m_pkMap)
return;
if (!mc_pcurEnvironmentData)
return;
CMapOutdoor& rkMap=GetMapOutdoorRef();
// Light always on
STATEMANAGER.SaveRenderState(D3DRS_LIGHTING, TRUE);
// Fog
STATEMANAGER.SaveRenderState(D3DRS_FOGENABLE, mc_pcurEnvironmentData->bFogEnable);
// Material
STATEMANAGER.SetMaterial(&mc_pcurEnvironmentData->Material);
// Directional Light
if (mc_pcurEnvironmentData->bDirLightsEnable[ENV_DIRLIGHT_BACKGROUND])
{
ms_lpd3dDevice->LightEnable(0, TRUE);
rkMap.ApplyLight((DWORD)(uintptr_t)mc_pcurEnvironmentData, mc_pcurEnvironmentData->DirLights[ENV_DIRLIGHT_BACKGROUND]); // PORT: 64-bit pointer tag
}
else
ms_lpd3dDevice->LightEnable(0, FALSE);
if (mc_pcurEnvironmentData->bFogEnable)
{
DWORD dwFogColor = mc_pcurEnvironmentData->FogColor;
STATEMANAGER.SetRenderState(D3DRS_FOGCOLOR, dwFogColor);
if (mc_pcurEnvironmentData->bDensityFog)
{
float fDensity = 0.00015f;
STATEMANAGER.SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_EXP); // pixel fog
STATEMANAGER.SetRenderState(D3DRS_FOGDENSITY, *((DWORD *) &fDensity)); // vertex fog
}
else
{
CSpeedTreeForestDirectX8& rkForest=CSpeedTreeForestDirectX8::Instance();
rkForest.SetFog(
mc_pcurEnvironmentData->GetFogNearDistance(),
mc_pcurEnvironmentData->GetFogFarDistance()
);
float fFogNear=mc_pcurEnvironmentData->GetFogNearDistance();
float fFogFar=mc_pcurEnvironmentData->GetFogFarDistance();
STATEMANAGER.SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR); // vertex fox
STATEMANAGER.SetRenderState(D3DRS_RANGEFOGENABLE, TRUE); // vertex fox
STATEMANAGER.SetRenderState(D3DRS_FOGSTART, *((DWORD *) &fFogNear)); // USED BY D3DFOG_LINEAR
STATEMANAGER.SetRenderState(D3DRS_FOGEND, *((DWORD *) &fFogFar)); // USED BY D3DFOG_LINEAR
}
}
rkMap.OnBeginEnvironment();
}
void CMapManager::EndEnvironment()
{
if (!mc_pcurEnvironmentData)
return;
STATEMANAGER.RestoreRenderState(D3DRS_LIGHTING);
STATEMANAGER.RestoreRenderState(D3DRS_FOGENABLE);
}
void CMapManager::SetEnvironmentData(int nEnvDataIndex)
{
const TEnvironmentData * c_pEnvironmenData;
if (GetEnvironmentData(nEnvDataIndex, &c_pEnvironmenData))
SetEnvironmentDataPtr(c_pEnvironmenData);
}
void CMapManager::SetEnvironmentDataPtr(const TEnvironmentData * c_pEnvironmentData)
{
if (!m_pkMap)
return;
if (!c_pEnvironmentData)
{
assert(!"null environment data");
TraceError("null environment data");
return;
}
CMapOutdoor& rkMap=GetMapOutdoorRef();
mc_pcurEnvironmentData = c_pEnvironmentData;
rkMap.SetEnvironmentDataPtr(mc_pcurEnvironmentData);
}
void CMapManager::ResetEnvironmentDataPtr(const TEnvironmentData * c_pEnvironmentData)
{
if (!m_pkMap)
return;
if (!c_pEnvironmentData)
{
assert(!"null environment data");
TraceError("null environment data");
return;
}
CMapOutdoor& rkMap=GetMapOutdoorRef();
mc_pcurEnvironmentData = c_pEnvironmentData;
rkMap.ResetEnvironmentDataPtr(mc_pcurEnvironmentData);
}
void CMapManager::BlendEnvironmentData(const TEnvironmentData * c_pEnvironmentData, int iTransitionTime)
{
}
bool CMapManager::RegisterEnvironmentData(DWORD dwIndex, const char * c_szFileName)
{
TEnvironmentData * pEnvironmentData = AllocEnvironmentData();
if (!LoadEnvironmentData(c_szFileName, pEnvironmentData))
{
DeleteEnvironmentData(pEnvironmentData);
return false;
}
TEnvironmentDataMap::iterator f=m_EnvironmentDataMap.find(dwIndex);
if (m_EnvironmentDataMap.end()==f)
{
m_EnvironmentDataMap.insert(TEnvironmentDataMap::value_type(dwIndex, pEnvironmentData));
}
else
{
delete f->second;
f->second=pEnvironmentData;
}
return true;
}
void CMapManager::GetCurrentEnvironmentData(const TEnvironmentData ** c_ppEnvironmentData)
{
*c_ppEnvironmentData = mc_pcurEnvironmentData;
}
bool CMapManager::GetEnvironmentData(DWORD dwIndex, const TEnvironmentData ** c_ppEnvironmentData)
{
TEnvironmentDataMap::iterator itor = m_EnvironmentDataMap.find(dwIndex);
if (m_EnvironmentDataMap.end() == itor)
{
*c_ppEnvironmentData = NULL;
return false;
}
*c_ppEnvironmentData = itor->second;
return true;
}
void CMapManager::RefreshPortal()
{
if (!IsMapReady())
return;
CMapOutdoor & rMap = GetMapOutdoorRef();
for (int i = 0; i < AROUND_AREA_NUM; ++i)
{
CArea * pArea;
if (!rMap.GetAreaPointer(i, &pArea))
continue;
pArea->RefreshPortal();
}
}
void CMapManager::ClearPortal()
{
if (!IsMapReady())
return;
CMapOutdoor & rMap = GetMapOutdoorRef();
for (int i = 0; i < AROUND_AREA_NUM; ++i)
{
CArea * pArea;
if (!rMap.GetAreaPointer(i, &pArea))
continue;
pArea->ClearPortal();
}
}
void CMapManager::AddShowingPortalID(int iID)
{
if (!IsMapReady())
return;
CMapOutdoor & rMap = GetMapOutdoorRef();
for (int i = 0; i < AROUND_AREA_NUM; ++i)
{
CArea * pArea;
if (!rMap.GetAreaPointer(i, &pArea))
continue;
pArea->AddShowingPortalID(iID);
}
}
TEnvironmentData * CMapManager::AllocEnvironmentData()
{
TEnvironmentData * pEnvironmentData = new TEnvironmentData;
Environment_Init(*pEnvironmentData);
return pEnvironmentData;
}
void CMapManager::DeleteEnvironmentData(TEnvironmentData * pEnvironmentData)
{
delete pEnvironmentData;
pEnvironmentData = NULL;
}
BOOL CMapManager::LoadEnvironmentData(const char * c_szFileName, TEnvironmentData * pEnvironmentData)
{
if (!pEnvironmentData)
return FALSE;
return (BOOL)Environment_Load(*pEnvironmentData, c_szFileName);
}
DWORD CMapManager::GetShadowMapColor(float fx, float fy)
{
if (!IsMapReady())
return 0xFFFFFFFF;
CMapOutdoor& rkMap=GetMapOutdoorRef();
return rkMap.GetShadowMapColor(fx, fy);
}
std::vector<int> & CMapManager::GetRenderedSplatNum(int * piPatch, int * piSplat, float * pfSplatRatio)
{
if (!m_pkMap)
{
static std::vector<int> s_emptyVector;
*piPatch = 0;
*piSplat = 0;
return s_emptyVector;
}
CMapOutdoor& rkMap=GetMapOutdoorRef();
return rkMap.GetRenderedSplatNum(piPatch, piSplat, pfSplatRatio);
}
CArea::TCRCWithNumberVector & CMapManager::GetRenderedGraphicThingInstanceNum(DWORD * pdwGraphicThingInstanceNum, DWORD * pdwCRCNum)
{
if (!m_pkMap)
{
static CArea::TCRCWithNumberVector s_emptyVector;
*pdwGraphicThingInstanceNum = 0;
*pdwCRCNum = 0;
return s_emptyVector;
}
CMapOutdoor& rkMap=GetMapOutdoorRef();
return rkMap.GetRenderedGraphicThingInstanceNum(pdwGraphicThingInstanceNum, pdwCRCNum);
}
bool CMapManager::GetNormal(int ix, int iy, D3DXVECTOR3 * pv3Normal)
{
if (!IsMapReady())
return false;
CMapOutdoor& rkMap=GetMapOutdoorRef();
return rkMap.GetNormal(ix, iy, pv3Normal);
}
bool CMapManager::isPhysicalCollision(const D3DXVECTOR3 & c_rvCheckPosition)
{
if (!IsMapReady())
return false;
CMapOutdoor& rkMap=GetMapOutdoorRef();
return rkMap.isAttrOn(c_rvCheckPosition.x, -c_rvCheckPosition.y, CTerrainImpl::ATTRIBUTE_BLOCK);
}
bool CMapManager::isAttrOn(float fX, float fY, BYTE byAttr)
{
if (!IsMapReady())
return false;
CMapOutdoor& rkMap=GetMapOutdoorRef();
return rkMap.isAttrOn(fX, fY, byAttr);
}
bool CMapManager::GetAttr(float fX, float fY, BYTE * pbyAttr)
{
if (!IsMapReady())
return false;
CMapOutdoor& rkMap=GetMapOutdoorRef();
return rkMap.GetAttr(fX, fY, pbyAttr);
}
bool CMapManager::isAttrOn(int iX, int iY, BYTE byAttr)
{
if (!IsMapReady())
return false;
CMapOutdoor& rkMap=GetMapOutdoorRef();
return rkMap.isAttrOn(iX, iY, byAttr);
}
bool CMapManager::GetAttr(int iX, int iY, BYTE * pbyAttr)
{
if (!IsMapReady())
return false;
CMapOutdoor& rkMap=GetMapOutdoorRef();
return rkMap.GetAttr(iX, iY, pbyAttr);
}
// 2004.10.14.myevan.TEMP_CAreaLoaderThread
/*
bool CMapManager::BGLoadingEnable()
{
if (!IsMapReady())
return false;
return ((CMapOutdoor*)m_pMap)->BGLoadingEnable();
}
void CMapManager::BGLoadingEnable(bool bBGLoadingEnable)
{
if (!IsMapReady())
return;
((CMapOutdoor*)m_pMap)->BGLoadingEnable(bBGLoadingEnable);
}
*/
void CMapManager::SetTerrainRenderSort(CMapOutdoor::ETerrainRenderSort eTerrainRenderSort)
{
if (!IsMapReady())
return;
CMapOutdoor& rkMap=GetMapOutdoorRef();
rkMap.SetTerrainRenderSort(eTerrainRenderSort);
}
void CMapManager::SetTransparentTree(bool bTransparenTree)
{
if (!IsMapReady())
return;
CMapOutdoor& rkMap=GetMapOutdoorRef();
rkMap.SetTransparentTree(bTransparenTree);
}
CMapOutdoor::ETerrainRenderSort CMapManager::GetTerrainRenderSort()
{
if (!IsMapReady())
return CMapOutdoor::DISTANCE_SORT;
CMapOutdoor& rkMap=GetMapOutdoorRef();
return rkMap.GetTerrainRenderSort();
}
void CMapManager::GetBaseXY(DWORD * pdwBaseX, DWORD * pdwBaseY)
{
if (!IsMapReady())
{
*pdwBaseX = 0;
*pdwBaseY = 0;
}
CMapOutdoor& rkMap=GetMapOutdoorRef();
rkMap.GetBaseXY(pdwBaseX, pdwBaseY);
}
void CMapManager::__LoadMapInfoVector()
{
CMappedFile kFile;
LPCVOID pData;
if (!CEterPackManager::Instance().Get(kFile, m_stAtlasInfoFileName.c_str(), &pData))
if (!CEterPackManager::Instance().Get(kFile, "AtlasInfo.txt", &pData))
return;
CMemoryTextFileLoader textFileLoader;
textFileLoader.Bind(kFile.Size(), pData);
char szMapName[256];
int x, y;
int width, height;
for (UINT uLineIndex=0; uLineIndex<textFileLoader.GetLineCount(); ++uLineIndex)
{
const std::string& c_rstLine=textFileLoader.GetLineString(uLineIndex);
sscanf(c_rstLine.c_str(), "%s %d %d %d %d",
szMapName,
&x, &y, &width, &height);
if ('\0'==szMapName[0])
continue;
TMapInfo kMapInfo;
kMapInfo.m_strName = szMapName;
kMapInfo.m_dwBaseX = x;
kMapInfo.m_dwBaseY = y;
kMapInfo.m_dwSizeX = width;
kMapInfo.m_dwSizeY = height;
kMapInfo.m_dwEndX = kMapInfo.m_dwBaseX + kMapInfo.m_dwSizeX * CTerrainImpl::TERRAIN_XSIZE;
kMapInfo.m_dwEndY = kMapInfo.m_dwBaseY + kMapInfo.m_dwSizeY * CTerrainImpl::TERRAIN_YSIZE;
m_kVct_kMapInfo.push_back(kMapInfo);
}
return;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,529 @@
#include "StdAfx.h"
#include "MapOutdoor.h"
void CMapOutdoor::SetIndexBuffer()
{
void * pIndices;
long x, y;
DWORD dwIndexNum = TERRAIN_PATCHSIZE * TERRAIN_PATCHSIZE * 4;
#ifdef WORLD_EDITOR
m_pwIndices = new WORD[dwIndexNum];
if (!m_pwIndices)
TraceError("CMapOutdoor::SetIndexBuffer() IndexBuffer is NULL");
memset(m_pwIndices, 0, sizeof(WORD) * dwIndexNum);
if (!m_IndexBuffer.Create(dwIndexNum, D3DFMT_INDEX16))
TraceError("CMapOutdoor::SetIndexBuffer() IndexBuffer Create Error");
WORD count = 0;
WORD count2 = 0;
long ry = 0;
BYTE ucNumLineWarp = TERRAIN_PATCHSIZE + 1;
for (y = 0; y < TERRAIN_PATCHSIZE; y++)
{
if (ry % 2 == 0)
{
m_pwIndices[count++] = count2;
m_pwIndices[count++] = count2+ucNumLineWarp;
}
else
{
m_pwIndices[count++] = count2+ucNumLineWarp;
m_pwIndices[count++] = count2;
}
for (x = 0; x < TERRAIN_PATCHSIZE; x++)
{
if (ry % 2 == 1)
{
m_pwIndices[count++] = (WORD) (count2+ucNumLineWarp-1);
m_pwIndices[count++] = (WORD) (count2-1);
count2 -= (short) 1;
}
else
{
m_pwIndices[count++] = (WORD) (count2+1);
m_pwIndices[count++] = (WORD) (count2+ucNumLineWarp+1);
count2 += (short) 1;
}
}
if (y < TERRAIN_PATCHSIZE-1)
{
m_pwIndices[count++] = (WORD) (count2+ucNumLineWarp);
m_pwIndices[count++] = (WORD) (count2+ucNumLineWarp);
count2 += ucNumLineWarp;
}
ry++;
}
m_wNumIndices = count;
if (!m_IndexBuffer.Lock((void **) &pIndices))
TraceError("CMapOutdoor::SetIndexBuffer() IndexBuffer Unlock Error");
memcpy(pIndices, m_pwIndices, count * sizeof(WORD));
m_IndexBuffer.Unlock();
delete [] m_pwIndices;
m_pwIndices = NULL;
#else
WORD count[TERRAINPATCH_LODMAX], count2[TERRAINPATCH_LODMAX];
BYTE uci;
for (uci = 0; uci < TERRAINPATCH_LODMAX; ++uci)
{
m_pwaIndices[uci] = new WORD[dwIndexNum];
memset(m_pwaIndices[uci], 0, sizeof(WORD) * dwIndexNum);
count[uci] = 0;
count2[uci] = 0;
if ( !m_IndexBuffer[uci].Create(dwIndexNum, D3DFMT_INDEX16) )
TraceError("CMapOutdoor::SetIndexBuffer() IndexBuffer Create Error");
}
BYTE ucNumLineWarp = TERRAIN_PATCHSIZE + 1;
for (y = 0; y < TERRAIN_PATCHSIZE; y++)
{
if (y%2 == 0)
{
m_pwaIndices[0][(count[0])++] = count2[0];
m_pwaIndices[0][(count[0])++] = count2[0]+ucNumLineWarp;
}
else
{
m_pwaIndices[0][(count[0])++] = count2[0]+ucNumLineWarp;
m_pwaIndices[0][(count[0])++] = count2[0];
}
for (x = 0; x < TERRAIN_PATCHSIZE; x++)
{
if (y%2 == 0)
{
m_pwaIndices[0][(count[0])++] = (WORD) (count2[0]+1);
m_pwaIndices[0][(count[0])++] = (WORD) (count2[0]+ucNumLineWarp+1);
count2[0] += (short) 1;
}
else
{
m_pwaIndices[0][(count[0])++] = (WORD) (count2[0]+ucNumLineWarp-1);
m_pwaIndices[0][(count[0])++] = (WORD) (count2[0]-1);
count2[0] -= (short) 1;
}
if (0 == x%2)
{
if (0 == y)
{
if (0 == x)
ADDLvl1TL(m_pwaIndices[1], count[1], count2[1], ucNumLineWarp);
else if ((TERRAIN_PATCHSIZE - 2) == x)
ADDLvl1TR(m_pwaIndices[1], count[1], count2[1], ucNumLineWarp);
else
ADDLvl1T(m_pwaIndices[1], count[1], count2[1], ucNumLineWarp);
}
else if ((TERRAIN_PATCHSIZE - 2) == y)
{
if (0 == x)
ADDLvl1BL(m_pwaIndices[1], count[1], count2[1], ucNumLineWarp);
else if ((TERRAIN_PATCHSIZE - 2) == x)
ADDLvl1BR(m_pwaIndices[1], count[1], count2[1], ucNumLineWarp);
else
ADDLvl1B(m_pwaIndices[1], count[1], count2[1], ucNumLineWarp);
}
else if (0 == y%2)
{
if (0 == x)
ADDLvl1L(m_pwaIndices[1], count[1], count2[1], ucNumLineWarp);
else if ((TERRAIN_PATCHSIZE - 2) == x)
ADDLvl1R(m_pwaIndices[1], count[1], count2[1], ucNumLineWarp);
else
ADDLvl1M(m_pwaIndices[1], count[1], count2[1], ucNumLineWarp);
}
count2[1] += 2;
}
if (0 == x%4)
{
if (0 == y)
{
if (0 == x)
ADDLvl2TL(m_pwaIndices[2], count[2], count2[2], ucNumLineWarp);
else if ((TERRAIN_PATCHSIZE - 4) == x)
ADDLvl2TR(m_pwaIndices[2], count[2], count2[2], ucNumLineWarp);
else
ADDLvl2T(m_pwaIndices[2], count[2], count2[2], ucNumLineWarp);
}
else if ((TERRAIN_PATCHSIZE - 4) == y)
{
if (0 == x)
ADDLvl2BL(m_pwaIndices[2], count[2], count2[2], ucNumLineWarp);
else if ((TERRAIN_PATCHSIZE - 4) == x)
ADDLvl2BR(m_pwaIndices[2], count[2], count2[2], ucNumLineWarp);
else
ADDLvl2B(m_pwaIndices[2], count[2], count2[2], ucNumLineWarp);
}
else if (0 == y%4)
{
if (0 == x)
ADDLvl2L(m_pwaIndices[2], count[2], count2[2], ucNumLineWarp);
else if ((TERRAIN_PATCHSIZE - 4) == x)
ADDLvl2R(m_pwaIndices[2], count[2], count2[2], ucNumLineWarp);
else
ADDLvl2M(m_pwaIndices[2], count[2], count2[2], ucNumLineWarp);
}
count2[2] += 4;
}
}
if (y < TERRAIN_PATCHSIZE-1)
{
m_pwaIndices[0][(count[0])++] = (WORD) (count2[0]+ucNumLineWarp);
m_pwaIndices[0][(count[0])++] = (WORD) (count2[0]+ucNumLineWarp);
count2[0] += ucNumLineWarp;
if (0 == y%2)
count2[1] += 2;
if (0 == y%4)
count2[2] += 4;
}
}
for (uci = 0; uci < TERRAINPATCH_LODMAX; ++uci)
{
m_wNumIndices[uci] = count[uci];
if( !m_IndexBuffer[uci].Lock((void **) &pIndices) )
TraceError("CMapOutdoor::SetIndexBuffer() IndexBuffer Unlock Error");
memcpy(pIndices, m_pwaIndices[uci], count[uci] * sizeof(WORD));
m_IndexBuffer[uci].Unlock();
delete [] m_pwaIndices[uci];
m_pwaIndices[uci] = NULL;
}
#endif
}
void CMapOutdoor::ADDLvl1TL(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
{
pIndices[rwCount++] = c_rwCurCount;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
pIndices[rwCount++] = c_rwCurCount + 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
pIndices[rwCount++] = c_rwCurCount + 2;
pIndices[rwCount++] = c_rwCurCount + 1;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
pIndices[rwCount++] = c_rwCurCount + 1;
pIndices[rwCount++] = c_rwCurCount;
}
void CMapOutdoor::ADDLvl1T(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
{
pIndices[rwCount++] = c_rwCurCount;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
pIndices[rwCount++] = c_rwCurCount + 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
pIndices[rwCount++] = c_rwCurCount + 2;
pIndices[rwCount++] = c_rwCurCount + 1;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
pIndices[rwCount++] = c_rwCurCount + 1;
pIndices[rwCount++] = c_rwCurCount;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
}
void CMapOutdoor::ADDLvl1TR(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
{
pIndices[rwCount++] = c_rwCurCount;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 2;
pIndices[rwCount++] = c_rwCurCount + 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
pIndices[rwCount++] = c_rwCurCount + 2;
pIndices[rwCount++] = c_rwCurCount + 1;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
pIndices[rwCount++] = c_rwCurCount + 1;
pIndices[rwCount++] = c_rwCurCount;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
}
void CMapOutdoor::ADDLvl1L(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
{
pIndices[rwCount++] = c_rwCurCount;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
pIndices[rwCount++] = c_rwCurCount + 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
pIndices[rwCount++] = c_rwCurCount + 2;
pIndices[rwCount++] = c_rwCurCount;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
}
void CMapOutdoor::ADDLvl1R(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
{
pIndices[rwCount++] = c_rwCurCount;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 2;
pIndices[rwCount++] = c_rwCurCount + 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
pIndices[rwCount++] = c_rwCurCount + 2;
pIndices[rwCount++] = c_rwCurCount;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
}
void CMapOutdoor::ADDLvl1BL(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
{
pIndices[rwCount++] = c_rwCurCount;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 1;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 1;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
pIndices[rwCount++] = c_rwCurCount + 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
pIndices[rwCount++] = c_rwCurCount + 2;
pIndices[rwCount++] = c_rwCurCount;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
}
void CMapOutdoor::ADDLvl1B(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
{
pIndices[rwCount++] = c_rwCurCount;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 1;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 1;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
pIndices[rwCount++] = c_rwCurCount + 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
pIndices[rwCount++] = c_rwCurCount + 2;
pIndices[rwCount++] = c_rwCurCount;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
}
void CMapOutdoor::ADDLvl1BR(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
{
pIndices[rwCount++] = c_rwCurCount;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 1;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 1;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 2;
pIndices[rwCount++] = c_rwCurCount + 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
pIndices[rwCount++] = c_rwCurCount + 2;
pIndices[rwCount++] = c_rwCurCount;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp + 1;
}
void CMapOutdoor::ADDLvl1M(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
{
pIndices[rwCount++] = c_rwCurCount;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
pIndices[rwCount++] = c_rwCurCount + 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
pIndices[rwCount++] = c_rwCurCount + 2;
}
void CMapOutdoor::ADDLvl2TL(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
{
ADDLvl1TL(pIndices, rwCount, c_rwCurCount, c_rucNumLineWarp);
ADDLvl1T(pIndices, rwCount, c_rwCurCount + 2, c_rucNumLineWarp);
ADDLvl1L(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2, c_rucNumLineWarp);
ADDLvl1M(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2 + 2, c_rucNumLineWarp);
}
void CMapOutdoor::ADDLvl2T(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
{
ADDLvl1T(pIndices, rwCount, c_rwCurCount, c_rucNumLineWarp);
ADDLvl1T(pIndices, rwCount, c_rwCurCount + 2, c_rucNumLineWarp);
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4 + 4;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4 + 4;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 4;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
}
void CMapOutdoor::ADDLvl2TR(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
{
ADDLvl1T(pIndices, rwCount, c_rwCurCount, c_rucNumLineWarp);
ADDLvl1TR(pIndices, rwCount, c_rwCurCount + 2, c_rucNumLineWarp);
ADDLvl1M(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2, c_rucNumLineWarp);
ADDLvl1R(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2 + 2, c_rucNumLineWarp);
}
void CMapOutdoor::ADDLvl2L(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
{
ADDLvl1L(pIndices, rwCount, c_rwCurCount, c_rucNumLineWarp);
ADDLvl1L(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2, c_rucNumLineWarp);
pIndices[rwCount++] = c_rwCurCount + 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
pIndices[rwCount++] = c_rwCurCount + 4;
pIndices[rwCount++] = c_rwCurCount + 4;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4 + 4;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4 + 4;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4 + 2;
}
void CMapOutdoor::ADDLvl2R(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
{
ADDLvl1R(pIndices, rwCount, c_rwCurCount + 2, c_rucNumLineWarp);
ADDLvl1R(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2 + 2, c_rucNumLineWarp);
pIndices[rwCount++] = c_rwCurCount + 2;
pIndices[rwCount++] = c_rwCurCount;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
pIndices[rwCount++] = c_rwCurCount;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4 + 2;
}
void CMapOutdoor::ADDLvl2BL(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
{
ADDLvl1L(pIndices, rwCount, c_rwCurCount, c_rucNumLineWarp);
ADDLvl1M(pIndices, rwCount, c_rwCurCount + 2, c_rucNumLineWarp);
ADDLvl1BL(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2, c_rucNumLineWarp);
ADDLvl1B(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2 + 2, c_rucNumLineWarp);
}
void CMapOutdoor::ADDLvl2B(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
{
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
pIndices[rwCount++] = c_rwCurCount;
pIndices[rwCount++] = c_rwCurCount;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
pIndices[rwCount++] = c_rwCurCount + 4;
pIndices[rwCount++] = c_rwCurCount + 4;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 2;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 2 + 4;
ADDLvl1B(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2, c_rucNumLineWarp);
ADDLvl1B(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2 + 2, c_rucNumLineWarp);
}
void CMapOutdoor::ADDLvl2BR(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
{
ADDLvl1M(pIndices, rwCount, c_rwCurCount, c_rucNumLineWarp);
ADDLvl1R(pIndices, rwCount, c_rwCurCount + 2, c_rucNumLineWarp);
ADDLvl1B(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2, c_rucNumLineWarp);
ADDLvl1BR(pIndices, rwCount, c_rwCurCount + c_rucNumLineWarp * 2 + 2, c_rucNumLineWarp);
}
void CMapOutdoor::ADDLvl2M(WORD * pIndices, WORD & rwCount, const WORD & c_rwCurCount, const BYTE & c_rucNumLineWarp)
{
pIndices[rwCount++] = c_rwCurCount;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4;
pIndices[rwCount++] = c_rwCurCount + 4;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4;
pIndices[rwCount++] = c_rwCurCount + c_rucNumLineWarp * 4 + 4;
pIndices[rwCount++] = c_rwCurCount + 4;
}
@@ -0,0 +1,544 @@
#include "StdAfx.h"
#include "MapOutdoor.h"
#include "AreaTerrain.h"
#include "AreaLoaderThread.h"
#include "../EterLib/ResourceManager.h"
#include "../EterPack/EterPackManager.h"
//CAreaLoaderThread CMapOutdoor::ms_AreaLoaderThread;
bool CMapOutdoor::Load(float x, float y, float z)
{
Destroy();
CEterPackManager& rkPackMgr=CEterPackManager::Instance();
{
static std::string s_strOldPathName="";
// 2004.08.09.myevan.Pack파일을 찾을때.. 폴더명만으로는 그냥 리턴되는 부분이 있다
std::string c_rstrNewPathName=GetName()+"\\cache";
s_strOldPathName=c_rstrNewPathName;
}
std::string strFileName = GetMapDataDirectory() + "\\Setting.txt";
if (!LoadSetting(strFileName.c_str()))
TraceError("CMapOutdoor::Load : LoadSetting(%s) Failed", strFileName.c_str());
#ifdef WORLD_EDITOR
if (!LoadMonsterAreaInfo())
TraceError("CMapOutdoor::Load - LoadMonsterAreaInfo ERROR");
#endif
CreateTerrainPatchProxyList();
BuildQuadTree();
LoadWaterTexture();
CreateCharacterShadowTexture();
m_lOldReadX = -1;
// TODO: SetRenderingDevice에서 Environment로 부터 라이트 속성을 넘겨줘야 스태틱 라이트가 제대로 작동한다.
CSpeedTreeForestDirectX8::Instance().SetRenderingDevice(ms_lpd3dDevice);
Update(x, y, z);
__HeightCache_Init();
// LOCAL_ENVIRONMENT_DATA
std::string local_envDataName = GetMapDataDirectory() + "\\" + m_settings_envDataName;
if (rkPackMgr.isExist(local_envDataName.c_str()))
{
m_envDataName = local_envDataName;
}
else
{
const std::string& c_rstrEnvironmentRoot = "d:/ymir work/environment/";
const std::string& c_rstrMapName = GetName();
m_envDataName = c_rstrEnvironmentRoot + m_settings_envDataName;
if (0 == m_envDataName.compare(c_rstrEnvironmentRoot))
{
const std::string& strAppendName = c_rstrMapName.substr(c_rstrMapName.size() - 2, 2);
m_envDataName = c_rstrEnvironmentRoot + strAppendName + ".msenv";
}
}
// LOCAL_ENVIRONMENT_DATA_END
return true;
}
std::string& CMapOutdoor::GetEnvironmentDataName()
{
return m_envDataName;
}
bool CMapOutdoor::isTerrainLoaded(WORD wX, WORD wY)
{
for (DWORD i = 0; i < m_TerrainVector.size(); ++i)
{
CTerrain * pTerrain = m_TerrainVector[i];
WORD usCoordX, usCoordY;
pTerrain->GetCoordinate(&usCoordX, &usCoordY);
if (usCoordX == wX && usCoordY == wY)
return true;
}
return false;
}
bool CMapOutdoor::isAreaLoaded(WORD wX, WORD wY)
{
for (DWORD i = 0; i < m_AreaVector.size(); ++i)
{
CArea * pArea = m_AreaVector[i];
WORD usCoordX, usCoordY;
pArea->GetCoordinate(&usCoordX, &usCoordY);
if (usCoordX == wX && usCoordY == wY)
return true;
}
return false;
}
// 현재 좌표를 기반으로 주위(ex. 3x3)에 있는 Terrain과 Area포인터를
// m_pTerrain과 m_pArea에 연결한다.
void CMapOutdoor::AssignTerrainPtr()
{
// 월드에디터에서 화면을 죽죽죽 넘길 때 터레인을 저장해야 하기
// 때문에 이 virtual method를 호출 한다. 이 메소드는 CMapOutDoor에서는 아무 행동도
// 하지 않는다.
OnPreAssignTerrainPtr();
short sReferenceCoordMinX, sReferenceCoordMaxX, sReferenceCoordMinY, sReferenceCoordMaxY;
sReferenceCoordMinX = max(m_CurCoordinate.m_sTerrainCoordX - LOAD_SIZE_WIDTH, 0);
sReferenceCoordMaxX = min(m_CurCoordinate.m_sTerrainCoordX + LOAD_SIZE_WIDTH, m_sTerrainCountX - 1);
sReferenceCoordMinY = max(m_CurCoordinate.m_sTerrainCoordY - LOAD_SIZE_WIDTH, 0);
sReferenceCoordMaxY = min(m_CurCoordinate.m_sTerrainCoordY + LOAD_SIZE_WIDTH, m_sTerrainCountY - 1);
DWORD i;
for (i = 0; i < AROUND_AREA_NUM; ++i)
{
m_pArea[i] = NULL;
m_pTerrain[i] = NULL;
}
for (i = 0; i < m_TerrainVector.size(); ++i)
{
CTerrain * pTerrain = m_TerrainVector[i];
WORD usCoordX, usCoordY;
pTerrain->GetCoordinate(&usCoordX, &usCoordY);
if (usCoordX >= sReferenceCoordMinX &&
usCoordX <= sReferenceCoordMaxX &&
usCoordY >= sReferenceCoordMinY &&
usCoordY <= sReferenceCoordMaxY)
{
m_pTerrain[(usCoordY - m_CurCoordinate.m_sTerrainCoordY + LOAD_SIZE_WIDTH) * 3 +
(usCoordX - m_CurCoordinate.m_sTerrainCoordX + LOAD_SIZE_WIDTH) ] = pTerrain;
}
}
for (i = 0; i < m_AreaVector.size(); ++i)
{
CArea * pArea = m_AreaVector[i];
WORD usCoordX, usCoordY;
pArea->GetCoordinate(&usCoordX, &usCoordY);
if (usCoordX >= sReferenceCoordMinX &&
usCoordX <= sReferenceCoordMaxX &&
usCoordY >= sReferenceCoordMinY &&
usCoordY <= sReferenceCoordMaxY)
{
m_pArea[(usCoordY - m_CurCoordinate.m_sTerrainCoordY + LOAD_SIZE_WIDTH) * 3 +
(usCoordX - m_CurCoordinate.m_sTerrainCoordX + LOAD_SIZE_WIDTH) ] = pArea;
}
}
}
bool CMapOutdoor::LoadArea(WORD wAreaCoordX, WORD wAreaCoordY, WORD wCellCoordX, WORD wCellCoordY)
{
if (isAreaLoaded(wAreaCoordX, wAreaCoordY))
return true;
#ifdef _DEBUG
DWORD dwStartTime = ELTimer_GetMSec();
#endif
unsigned long ulID = (unsigned long) (wAreaCoordX) * 1000L + (unsigned long) (wAreaCoordY);
char szAreaPathName[64+1];
_snprintf(szAreaPathName, sizeof(szAreaPathName), "%s\\%06u\\", GetMapDataDirectory().c_str(), ulID);
CArea * pArea = CArea::New();
pArea->SetMapOutDoor(this);
#ifdef _DEBUG
Tracef("CMapOutdoor::LoadArea1 %d\n", ELTimer_GetMSec() - dwStartTime);
dwStartTime = ELTimer_GetMSec();
#endif
pArea->SetCoordinate(wAreaCoordX, wAreaCoordY);
if ( !pArea->Load(szAreaPathName) )
TraceError(" CMapOutdoor::LoadArea(%d, %d) LoadShadowMap ERROR", wAreaCoordX, wAreaCoordY);
#ifdef _DEBUG
Tracef("CMapOutdoor::LoadArea2 %d\n", ELTimer_GetMSec() - dwStartTime);
dwStartTime = ELTimer_GetMSec();
#endif
m_AreaVector.push_back(pArea);
pArea->EnablePortal(m_bEnablePortal);
#ifdef _DEBUG
Tracef("CMapOutdoor::LoadArea3 %d\n", ELTimer_GetMSec() - dwStartTime);
#endif
return true;
}
bool CMapOutdoor::LoadTerrain(WORD wTerrainCoordX, WORD wTerrainCoordY, WORD wCellCoordX, WORD wCellCoordY)
{
if (isTerrainLoaded(wTerrainCoordX, wTerrainCoordY))
return true;
//////////////////////////////////////////////////////////////////////////
DWORD dwStartTime = ELTimer_GetMSec();
unsigned long ulID = (unsigned long) (wTerrainCoordX) * 1000L + (unsigned long) (wTerrainCoordY);
char filename[256];
sprintf(filename, "%s\\%06u\\AreaProperty.txt", GetMapDataDirectory().c_str(), ulID);
CTokenVectorMap stTokenVectorMap;
if (!LoadMultipleTextData(filename, stTokenVectorMap))
{
TraceError("CMapOutdoor::LoadTerrain AreaProperty Read Error\n");
return false;
}
if (stTokenVectorMap.end() == stTokenVectorMap.find("scripttype"))
{
TraceError("CMapOutdoor::LoadTerrain AreaProperty FileFormat Error 1\n");
return false;
}
if (stTokenVectorMap.end() == stTokenVectorMap.find("areaname"))
{
TraceError("CMapOutdoor::LoadTerrain AreaProperty FileFormat Error 2\n");
return false;
}
const std::string & c_rstrType = stTokenVectorMap["scripttype"][0];
const std::string & c_rstrAreaName = stTokenVectorMap["areaname"][0];
if (c_rstrType != "AreaProperty")
{
TraceError("CMapOutdoor::LoadTerrain AreaProperty FileFormat Error 3\n");
return false;
}
CTerrain * pTerrain = CTerrain::New();
pTerrain->Clear();
pTerrain->SetMapOutDoor(this);
pTerrain->SetCoordinate(wTerrainCoordX, wTerrainCoordY);
pTerrain->CopySettingFromGlobalSetting();
char szRawHeightFieldname[64+1];
char szWaterMapName[64+1];
char szAttrMapName[64+1];
char szShadowTexName[64+1];
char szShadowMapName[64+1];
char szMiniMapTexName[64+1];
char szSplatName[64+1];
_snprintf(szRawHeightFieldname, sizeof(szRawHeightFieldname), "%s\\%06u\\height.raw", GetMapDataDirectory().c_str(), ulID);
_snprintf(szSplatName, sizeof(szSplatName), "%s\\%06u\\tile.raw", GetMapDataDirectory().c_str(), ulID);
_snprintf(szAttrMapName, sizeof(szAttrMapName), "%s\\%06u\\attr.atr", GetMapDataDirectory().c_str(), ulID);
_snprintf(szWaterMapName, sizeof(szWaterMapName), "%s\\%06u\\water.wtr", GetMapDataDirectory().c_str(), ulID);
_snprintf(szShadowTexName, sizeof(szShadowTexName), "%s\\%06u\\shadowmap.dds", GetMapDataDirectory().c_str(), ulID);
_snprintf(szShadowMapName, sizeof(szShadowMapName), "%s\\%06u\\shadowmap.raw", GetMapDataDirectory().c_str(), ulID);
_snprintf(szMiniMapTexName, sizeof(szMiniMapTexName), "%s\\%06u\\minimap.dds", GetMapDataDirectory().c_str(), ulID);
if(!pTerrain->LoadWaterMap(szWaterMapName))
TraceError(" CMapOutdoor::LoadTerrain(%d, %d) LoadWaterMap ERROR", wTerrainCoordX, wTerrainCoordY);
if (!pTerrain->LoadHeightMap(szRawHeightFieldname))
TraceError(" CMapOutdoor::LoadTerrain(%d, %d) LoadHeightMap ERROR", wTerrainCoordX, wTerrainCoordY);
if (!pTerrain->LoadAttrMap(szAttrMapName))
TraceError(" CMapOutdoor::LoadTerrain(%d, %d) LoadAttrMap ERROR", wTerrainCoordX, wTerrainCoordY);
if (!pTerrain->RAW_LoadTileMap(szSplatName))
TraceError(" CMapOutdoor::LoadTerrain(%d, %d) RAW_LoadTileMap ERROR", wTerrainCoordX, wTerrainCoordY);
pTerrain->LoadShadowTexture(szShadowTexName);
if (!pTerrain->LoadShadowMap(szShadowMapName))
TraceError(" CMapOutdoor::LoadTerrain(%d, %d) LoadShadowMap ERROR", wTerrainCoordX, wTerrainCoordY);
pTerrain->LoadMiniMapTexture(szMiniMapTexName);
pTerrain->SetName(c_rstrAreaName.c_str());
pTerrain->CalculateTerrainPatch();
pTerrain->SetReady();
Tracef("CMapOutdoor::LoadTerrain %d\n", ELTimer_GetMSec() - dwStartTime);
m_TerrainVector.push_back(pTerrain);
return true;
}
bool CMapOutdoor::LoadSetting(const char * c_szFileName)
{
NANOBEGIN
CTokenVectorMap stTokenVectorMap;
if (!LoadMultipleTextData(c_szFileName, stTokenVectorMap))
{
TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - LoadMultipleTextData", c_szFileName);
return false;
}
if (stTokenVectorMap.end() == stTokenVectorMap.find("scripttype"))
{
TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - FIND 'scripttype' - FAILED", c_szFileName);
return false;
}
if (stTokenVectorMap.end() == stTokenVectorMap.find("viewradius"))
{
TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - FIND 'viewradius' - FAILED", c_szFileName);
return false;
}
if (stTokenVectorMap.end() == stTokenVectorMap.find("cellscale"))
{
TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - FIND 'cellscale' - FAILED", c_szFileName);
return false;
}
if (stTokenVectorMap.end() == stTokenVectorMap.find("heightscale"))
{
TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - FIND 'heightscale' - FAILED", c_szFileName);
return false;
}
if (stTokenVectorMap.end() == stTokenVectorMap.find("mapsize"))
{
TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - FIND 'mapsize' - FAILED", c_szFileName);
return false;
}
if (stTokenVectorMap.end() == stTokenVectorMap.find("textureset"))
{
TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - FIND 'textureset' - FAILED", c_szFileName);
return false;
}
if (stTokenVectorMap.end() != stTokenVectorMap.find("terrainvisible"))
{
m_bSettingTerrainVisible = (bool) (atoi(stTokenVectorMap["terrainvisible"][0].c_str()) != 0);
}
else
{
m_bSettingTerrainVisible = true;
}
const std::string & c_rstrType = stTokenVectorMap["scripttype"][0];
const std::string & c_rstrViewRadius = stTokenVectorMap["viewradius"][0];
//const std::string & c_rstrCellScale = stTokenVectorMap["cellscale"][0];
const std::string & c_rstrHeightScale = stTokenVectorMap["heightscale"][0];
const std::string & c_rstrMapSizeX = stTokenVectorMap["mapsize"][0];
const std::string & c_rstrMapSizeY = stTokenVectorMap["mapsize"][1];
std::string strTextureSet;
TTokenVector & rkVec_strToken = stTokenVectorMap["textureset"];
if (!rkVec_strToken.empty())
{
strTextureSet = rkVec_strToken[0];
}
if (c_rstrType != "MapSetting")
{
TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - Resourse Type ERROR", c_szFileName);
return false;
}
m_lViewRadius = atol(c_rstrViewRadius.c_str());
#ifdef WORLD_EDITOR
m_lViewRadius <<= 1;
#endif
if (0L >= m_lViewRadius)
{
TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - VIEWRADIUS IS NOT GREATER THAN 0", c_szFileName);
return false;
}
m_fHeightScale = atof(c_rstrHeightScale.c_str());
SetTerrainCount(atoi(c_rstrMapSizeX.c_str()), atoi(c_rstrMapSizeY.c_str()));
m_fTerrainTexCoordBase = 1.0f / (float) (CTerrainImpl::PATCH_XSIZE * CTerrainImpl::CELLSCALE);
if (stTokenVectorMap.end() != stTokenVectorMap.find("baseposition"))
{
const std::string & c_rstrMapBaseX = stTokenVectorMap["baseposition"][0];
const std::string & c_rstrMapBaseY = stTokenVectorMap["baseposition"][1];
SetBaseXY((DWORD)atol(c_rstrMapBaseX.c_str()), (DWORD)atol(c_rstrMapBaseY.c_str()));
}
std::string stTextureSetFileName = strTextureSet;
// TextureSet 이 이미 붙어 있을 경우 안붙인다.
if (0 != stTextureSetFileName.find_first_of("textureset", 0))
stTextureSetFileName = "textureset\\"+strTextureSet;
if (!m_TextureSet.Load(stTextureSetFileName.c_str(), m_fTerrainTexCoordBase))
{
#ifdef WORLD_EDITOR
// TextureSet 이 적용되어 있지 않아도 진행
LogBox("TextureSet \300\314 \300\373\277\353\265\307\276\356\300\326\301\366 \276\312\300\272 \270\312 \300\324\264\317\264\331.\n\301\366\307\374 \305\330\275\272\303\347 \300\333\276\367\277\241 \301\326\300\307\307\317\275\303\261\342 \271\331\266\370\264\317\264\331.");
#else
TraceError("MapOutdoor::LoadSetting(c_szFileName=%s) - LOAD TEXTURE SET(%s) ERROR", c_szFileName, stTextureSetFileName.c_str());
return false;
#endif
}
CTerrain::SetTextureSet(&m_TextureSet);
if (stTokenVectorMap.end() != stTokenVectorMap.find("environment"))
{
const CTokenVector & c_rEnvironmentVector = stTokenVectorMap["environment"];
if (!c_rEnvironmentVector.empty())
m_settings_envDataName = c_rEnvironmentVector[0];
else
TraceError("CMapOutdoor::LoadSetting(c_szFileName=%s) - Failed to load environment data\n", c_szFileName);
}
m_fWaterTexCoordBase = 1.0f / (float)(CTerrainImpl::CELLSCALE * 4);
D3DXMatrixScaling(&m_matSplatAlpha,
+m_fTerrainTexCoordBase * 2.0f * (float)(CTerrainImpl::PATCH_XSIZE) / (float)(CTerrainImpl::SPLATALPHA_RAW_XSIZE-2),
-m_fTerrainTexCoordBase * 2.0f * (float)(CTerrainImpl::PATCH_YSIZE) / (float)(CTerrainImpl::SPLATALPHA_RAW_XSIZE-2),
0.0f);
m_matSplatAlpha._41 = m_fTerrainTexCoordBase * 4.6f;
m_matSplatAlpha._42 = m_fTerrainTexCoordBase * 4.6f;
D3DXMatrixScaling(&m_matStaticShadow,
+m_fTerrainTexCoordBase * ((float) CTerrainImpl::PATCH_XSIZE / static_cast<float>(CTerrainImpl::XSIZE)),
-m_fTerrainTexCoordBase * ((float) CTerrainImpl::PATCH_YSIZE / static_cast<float>(CTerrainImpl::XSIZE)),
0.0f);
m_matStaticShadow._41 = 0.0f;
m_matStaticShadow._42 = 0.0f;
D3DXMatrixScaling(&m_matDynamicShadowScale, 1.0f / 2550.0f, -1.0f / 2550.0f, 1.0f);
m_matDynamicShadowScale._41 = 0.5f;
m_matDynamicShadowScale._42 = 0.5f;
// Transform
D3DXMatrixScaling(&m_matBuildingTransparent, 1.0f / ((float)ms_iWidth), -1.0f / ((float)ms_iHeight), 1.0f);
m_matBuildingTransparent._41 = 0.5f;
m_matBuildingTransparent._42 = 0.5f;
NANOEND
return true;
}
bool CMapOutdoor::LoadMonsterAreaInfo()
{
RemoveAllMonsterAreaInfo();
char c_szFileName[256];
sprintf(c_szFileName, "%s\\regen.txt", GetMapDataDirectory().c_str());
LPCVOID pModelData;
CMappedFile File;
if (!CEterPackManager::Instance().Get(File, c_szFileName, &pModelData))
{
//TraceError(" CMapOutdoorAccessor::LoadMonsterAreaInfo Load File %s ERROR", c_szFileName);
return false;
}
CMemoryTextFileLoader textFileLoader;
CTokenVector stTokenVector;
textFileLoader.Bind(File.Size(), pModelData);
for (DWORD i = 0; i < textFileLoader.GetLineCount(); ++i)
{
if (!textFileLoader.SplitLine(i, &stTokenVector))
continue;
stl_lowers(stTokenVector[0]);
// Start or End
if (0 == stTokenVector[0].compare("m") || 0 == stTokenVector[0].compare("g"))
{
if (stTokenVector.size() < 11)
{
TraceError("CMapOutdoorAccessor::LoadMonsterAreaInfo Get MonsterInfo File Format ERROR! continue....");
continue;
}
CMonsterAreaInfo::EMonsterAreaInfoType eMonsterAreaInfoType;
if (0 == stTokenVector[0].compare("m"))
{
eMonsterAreaInfoType = CMonsterAreaInfo::MONSTERAREAINFOTYPE_MONSTER;
}
else if (0 == stTokenVector[0].compare("g"))
{
eMonsterAreaInfoType = CMonsterAreaInfo::MONSTERAREAINFOTYPE_GROUP;
}
else
{
TraceError("CMapOutdoorAccessor::LoadMonsterAreaInfo Get MonsterInfo Data ERROR! continue....");
continue;
}
const std::string & c_rstrOriginX = stTokenVector[1].c_str();
const std::string & c_rstrOriginY = stTokenVector[2].c_str();
const std::string & c_rstrSizeX = stTokenVector[3].c_str();
const std::string & c_rstrSizeY = stTokenVector[4].c_str();
const std::string & c_rstrZ = stTokenVector[5].c_str();
const std::string & c_rstrDir = stTokenVector[6].c_str();
const std::string & c_rstrTime = stTokenVector[7].c_str();
const std::string & c_rstrPercent = stTokenVector[8].c_str();
const std::string & c_rstrCount = stTokenVector[9].c_str();
const std::string & c_rstrVID = stTokenVector[10].c_str();
long lOriginX, lOriginY, lSizeX, lSizeY, lZ, lTime, lPercent;
CMonsterAreaInfo::EMonsterDir eMonsterDir;
DWORD dwMonsterCount;
DWORD dwMonsterVID;
lOriginX = atol(c_rstrOriginX.c_str());
lOriginY = atol(c_rstrOriginY.c_str());
lSizeX = atol(c_rstrSizeX.c_str());
lSizeY = atol(c_rstrSizeY.c_str());
lZ = atol(c_rstrZ.c_str());
eMonsterDir = (CMonsterAreaInfo::EMonsterDir) atoi(c_rstrDir.c_str());
lTime = atol(c_rstrTime.c_str());
lPercent = atol(c_rstrPercent.c_str());
dwMonsterCount = (DWORD) atoi(c_rstrCount.c_str());
dwMonsterVID = (DWORD) atoi(c_rstrVID.c_str());
// lOriginX -= m_dwBaseX / 100;
// lOriginY -= m_dwBaseY / 100;
CMonsterAreaInfo * pMonsterAreaInfo = AddMonsterAreaInfo(lOriginX, lOriginY, lSizeX, lSizeY);
pMonsterAreaInfo->SetMonsterAreaInfoType(eMonsterAreaInfoType);
if (CMonsterAreaInfo::MONSTERAREAINFOTYPE_MONSTER == eMonsterAreaInfoType)
pMonsterAreaInfo->SetMonsterVID(dwMonsterVID);
else if (CMonsterAreaInfo::MONSTERAREAINFOTYPE_GROUP == eMonsterAreaInfoType)
pMonsterAreaInfo->SetMonsterGroupID(dwMonsterVID);
pMonsterAreaInfo->SetMonsterCount(dwMonsterCount);
pMonsterAreaInfo->SetMonsterDirection(eMonsterDir);
}
}
return true;
}
@@ -0,0 +1,168 @@
#include "StdAfx.h"
#include "MapOutdoor.h"
#include "TerrainQuadtree.h"
//////////////////////////////////////////////////////////////////////////
// QuadTree
//////////////////////////////////////////////////////////////////////////
void CMapOutdoor::BuildQuadTree()
{
FreeQuadTree();
// m_wPatchCount는 ConvertPatchSplat에서도 정한다, 안전을 위해 여기서 체크한다.
if (0 == m_wPatchCount)
{
TraceError("MapOutdoor::BuildQuadTree : m_wPatchCount is zero, you must call ConvertPatchSplat before call this method.");
return;
}
m_pRootNode = AllocQuadTreeNode(0, 0, m_wPatchCount - 1, m_wPatchCount - 1);
if (!m_pRootNode)
TraceError("CMapOutdoor::BuildQuadTree() RootNode is NULL");
if (m_pRootNode->Size > 1)
SubDivideNode(m_pRootNode);
}
CTerrainQuadtreeNode * CMapOutdoor::AllocQuadTreeNode(long x0, long y0, long x1, long y1)
{
CTerrainQuadtreeNode * Node;
long xsize, ysize;
xsize = x1-x0+1;
ysize = y1-y0+1;
if ((xsize == 0) || (ysize == 0))
return NULL;
Node = new CTerrainQuadtreeNode;
Node->x0 = x0;
Node->y0 = y0;
Node->x1 = x1;
Node->y1 = y1;
if (ysize > xsize)
Node->Size = ysize;
else
Node->Size = xsize;
Node->PatchNum = y0 * m_wPatchCount + x0;
/*
const float fTerrainMin = -(float) (m_lViewRadius * m_lCellScale);
minx = fTerrainMin + x0 * c_byPatchSize * m_lCellScale;
maxx = fTerrainMin + (x1 + 1) * c_byPatchSize * m_lCellScale;
miny = fTerrainMin + y0 * c_byPatchSize * m_lCellScale;
maxy = fTerrainMin + (y1 + 1) * c_byPatchSize * m_lCellScale;
minz = 0.0f;
maxz = 0.0f;
/ * Set up 8 vertices that belong to the bounding box * /
Node->center.x = minx + (maxx - minx) * 0.5f;
Node->center.y = miny + (maxy - miny) * 0.5f;
Node->center.z = minz + (maxz - minz) * 0.5f;
Node->radius = sqrtf(
(maxx-minx)*(maxx-minx)+
(maxy-miny)*(maxy-miny)+
(maxz-minz)*(maxz-minz)
)/2.0f;
*/
Node->center.x = 0.0f;
Node->center.y = 0.0f;
Node->center.z = 0.0f;
Node->radius = 0.0f;
return Node;
}
void CMapOutdoor::SubDivideNode(CTerrainQuadtreeNode * Node)
{
long nw_size;
CTerrainQuadtreeNode * tempnode;
nw_size = Node->Size / 2;
Node->NW_Node = AllocQuadTreeNode (Node->x0, Node->y0, Node->x0 + nw_size-1, Node->y0 + nw_size-1);
Node->NE_Node = AllocQuadTreeNode (Node->x0 + nw_size, Node->y0, Node->x1, Node->y0 + nw_size-1);
Node->SW_Node = AllocQuadTreeNode (Node->x0, Node->y0 + nw_size, Node->x0 + nw_size-1, Node->y1);
Node->SE_Node = AllocQuadTreeNode (Node->x0 + nw_size, Node->y0 + nw_size, Node->x1, Node->y1);
tempnode = (CTerrainQuadtreeNode *) Node->NW_Node;
if ((tempnode != NULL) && (tempnode->Size > 1))
SubDivideNode (tempnode);
tempnode = (CTerrainQuadtreeNode *) Node->NE_Node;
if ((tempnode != NULL) && (tempnode->Size > 1))
SubDivideNode (tempnode);
tempnode = (CTerrainQuadtreeNode *) Node->SW_Node;
if ((tempnode != NULL) && (tempnode->Size > 1))
SubDivideNode (tempnode);
tempnode = (CTerrainQuadtreeNode *) Node->SE_Node;
if ((tempnode != NULL) && (tempnode->Size > 1))
SubDivideNode (tempnode);
}
/*
void CMapOutdoor::RecurseDeleteQuadTree(CTerrainQuadtreeNode *Node)
{
if (Node == NULL)
return;
if (Node->NW_Node != NULL)
{
RecurseDeleteQuadTree(Node->NW_Node);
Node->NW_Node = NULL;
}
if (Node->NE_Node != NULL)
{
RecurseDeleteQuadTree(Node->NE_Node);
Node->NE_Node = NULL;
}
if (Node->SW_Node != NULL)
{
RecurseDeleteQuadTree(Node->SW_Node);
Node->SW_Node = NULL;
}
if (Node->SE_Node != NULL)
{
RecurseDeleteQuadTree(Node->SE_Node);
Node->SE_Node = NULL;
}
free(Node);
}
*/
void CMapOutdoor::FreeQuadTree()
{
if (NULL == m_pRootNode)
return;
if (m_pRootNode->NW_Node)
{
delete m_pRootNode->NW_Node;
m_pRootNode->NW_Node = NULL;
}
if (m_pRootNode->NE_Node)
{
delete m_pRootNode->NE_Node;
m_pRootNode->NE_Node = NULL;
}
if (m_pRootNode->SW_Node)
{
delete m_pRootNode->SW_Node;
m_pRootNode->SW_Node = NULL;
}
if (m_pRootNode->SE_Node)
{
delete m_pRootNode->SE_Node;
m_pRootNode->SE_Node = NULL;
}
delete m_pRootNode;
m_pRootNode = NULL;
}
@@ -0,0 +1,964 @@
#include "StdAfx.h"
#include "MapOutdoor.h"
#include "TerrainPatch.h"
#include "AreaTerrain.h"
#include "TerrainQuadtree.h"
#include "../EterLib/Camera.h"
#include "../EterLib/StateManager.h"
#define MAX_RENDER_SPALT 150
CArea::TCRCWithNumberVector m_dwRenderedCRCWithNumberVector;
CMapOutdoor::TTerrainNumVector CMapOutdoor::FSortPatchDrawStructWithTerrainNum::m_TerrainNumVector;
void CMapOutdoor::RenderTerrain()
{
if (!IsVisiblePart(PART_TERRAIN))
return;
if (!m_bSettingTerrainVisible)
return;
// Inserted by levites
if (!m_pTerrainPatchProxyList)
return;
CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera();
if (!pCamera)
return;
auto vv = ms_matView * ms_matProj;
BuildViewFrustum(vv);
D3DXVECTOR3 v3Eye = pCamera->GetEye();
m_fXforDistanceCaculation = -v3Eye.x;
m_fYforDistanceCaculation = -v3Eye.y;
//////////////////////////////////////////////////////////////////////////
// Push
m_PatchVector.clear();
__RenderTerrain_RecurseRenderQuadTree(m_pRootNode);
// 거리순 정렬
std::sort(m_PatchVector.begin(),m_PatchVector.end());
// 그리기 위한 벡터 세팅
if (CTerrainPatch::SOFTWARE_TRANSFORM_PATCH_ENABLE)
__RenderTerrain_RenderSoftwareTransformPatch();
else
__RenderTerrain_RenderHardwareTransformPatch();
}
void CMapOutdoor::__RenderTerrain_RecurseRenderQuadTree(CTerrainQuadtreeNode *Node, bool bCullCheckNeed)
{
if (bCullCheckNeed)
{
switch (__RenderTerrain_RecurseRenderQuadTree_CheckBoundingCircle(Node->center, Node->radius))
{
case VIEW_ALL:
// all child nodes need not cull check
bCullCheckNeed = false;
break;
case VIEW_PART:
break;
case VIEW_NONE:
// no need to render
return;
}
// if no need cull check more
// -> bCullCheckNeed = false;
}
if (Node->Size == 1)
{
D3DXVECTOR3 v3Center = Node->center;
float fDistance = fMAX(fabs(v3Center.x + m_fXforDistanceCaculation), fabs(-v3Center.y + m_fYforDistanceCaculation));
__RenderTerrain_AppendPatch(v3Center, fDistance, Node->PatchNum);
}
else
{
if (Node->NW_Node != NULL)
__RenderTerrain_RecurseRenderQuadTree(Node->NW_Node, bCullCheckNeed);
if (Node->NE_Node != NULL)
__RenderTerrain_RecurseRenderQuadTree(Node->NE_Node, bCullCheckNeed);
if (Node->SW_Node != NULL)
__RenderTerrain_RecurseRenderQuadTree(Node->SW_Node, bCullCheckNeed);
if (Node->SE_Node != NULL)
__RenderTerrain_RecurseRenderQuadTree(Node->SE_Node, bCullCheckNeed);
}
}
int CMapOutdoor::__RenderTerrain_RecurseRenderQuadTree_CheckBoundingCircle(const D3DXVECTOR3 & c_v3Center, const float & c_fRadius)
{
const int count = 6;
D3DXVECTOR3 center = c_v3Center;
center.y = -center.y;
int i;
float distance[count];
for(i = 0; i < count; ++i)
{
distance[i] = D3DXPlaneDotCoord(&m_plane[i], &center);
if (distance[i] <= -c_fRadius)
return VIEW_NONE;
}
for(i = 0; i < count;++i)
{
if (distance[i] <= c_fRadius)
return VIEW_PART;
}
return VIEW_ALL;
}
void CMapOutdoor::__RenderTerrain_AppendPatch(const D3DXVECTOR3& c_rv3Center, float fDistance, long lPatchNum)
{
assert(NULL!=m_pTerrainPatchProxyList && "CMapOutdoor::__RenderTerrain_AppendPatch");
if (!m_pTerrainPatchProxyList[lPatchNum].isUsed())
return;
m_pTerrainPatchProxyList[lPatchNum].SetCenterPosition(c_rv3Center);
m_PatchVector.push_back(std::make_pair(fDistance, lPatchNum));
}
void CMapOutdoor::ApplyLight(DWORD dwVersion, const D3DLIGHT8& c_rkLight)
{
m_kSTPD.m_dwLightVersion=dwVersion;
STATEMANAGER.SetLight(0, &c_rkLight);
}
// 2004. 2. 17. myevan. 모든 부분을 보이게 초기화 한다
void CMapOutdoor::InitializeVisibleParts()
{
m_dwVisiblePartFlags=0xffffffff;
}
// 2004. 2. 17. myevan. 특정 부분을 보이게 하거나 감추는 함수
void CMapOutdoor::SetVisiblePart(int ePart, bool isVisible)
{
DWORD dwMask=(1<<ePart);
if (isVisible)
{
m_dwVisiblePartFlags|=dwMask;
}
else
{
DWORD dwReverseMask=~dwMask;
m_dwVisiblePartFlags&=dwReverseMask;
}
}
// 2004. 2. 17. myevan. 특정 부분이 보이는지 알아내는 함수
bool CMapOutdoor::IsVisiblePart(int ePart)
{
DWORD dwMask=(1<<ePart);
if (dwMask & m_dwVisiblePartFlags)
return true;
return false;
}
// Splat 개수 제한
void CMapOutdoor::SetSplatLimit(int iSplatNum)
{
m_iSplatLimit = iSplatNum;
}
std::vector<int> & CMapOutdoor::GetRenderedSplatNum(int * piPatch, int * piSplat, float * pfSplatRatio)
{
*piPatch = m_iRenderedPatchNum;
*piSplat = m_iRenderedSplatNum;
*pfSplatRatio = m_iRenderedSplatNumSqSum/float(m_iRenderedPatchNum);
return m_RenderedTextureNumVector;
}
CArea::TCRCWithNumberVector & CMapOutdoor::GetRenderedGraphicThingInstanceNum(DWORD * pdwGraphicThingInstanceNum, DWORD * pdwCRCNum)
{
*pdwGraphicThingInstanceNum = m_dwRenderedGraphicThingInstanceNum;
*pdwCRCNum = m_dwRenderedCRCNum;
return m_dwRenderedCRCWithNumberVector;
}
void CMapOutdoor::RenderBeforeLensFlare()
{
m_LensFlare.DrawBeforeFlare();
if (!mc_pEnvironmentData)
{
TraceError("CMapOutdoor::RenderBeforeLensFlare mc_pEnvironmentData is NULL");
return;
}
m_LensFlare.Compute(mc_pEnvironmentData->DirLights[ENV_DIRLIGHT_BACKGROUND].Direction);
}
void CMapOutdoor::RenderAfterLensFlare()
{
m_LensFlare.AdjustBrightness();
m_LensFlare.DrawFlare();
}
void CMapOutdoor::RenderCollision()
{
for (int i = 0; i < AROUND_AREA_NUM; ++i)
{
CArea * pArea;
if (GetAreaPointer(i, &pArea))
pArea->RenderCollision();
}
}
void CMapOutdoor::RenderScreenFiltering()
{
m_ScreenFilter.Render();
}
void CMapOutdoor::RenderSky()
{
if (IsVisiblePart(PART_SKY))
m_SkyBox.Render();
}
void CMapOutdoor::RenderCloud()
{
if (IsVisiblePart(PART_CLOUD))
m_SkyBox.RenderCloud();
}
void CMapOutdoor::RenderTree()
{
if (IsVisiblePart(PART_TREE))
CSpeedTreeForestDirectX8::Instance().Render();
}
void CMapOutdoor::SetInverseViewAndDynamicShaodwMatrices()
{
CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera();
if (!pCamera)
return;
m_matViewInverse = pCamera->GetInverseViewMatrix();
D3DXVECTOR3 v3Target = pCamera->GetTarget();
D3DXVECTOR3 v3LightEye(v3Target.x - 1.732f * 1250.0f,
v3Target.y - 1250.0f,
v3Target.z + 2.0f * 1.732f * 1250.0f);
const auto vv = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
D3DXMatrixLookAtRH(&m_matLightView, &v3LightEye, &v3Target, &vv);
m_matDynamicShadow = m_matViewInverse * m_matLightView * m_matDynamicShadowScale;
}
void CMapOutdoor::OnRender()
{
#ifdef __PERFORMANCE_CHECKER__
DWORD t1=ELTimer_GetMSec();
SetInverseViewAndDynamicShaodwMatrices();
SetBlendOperation();
DWORD t2=ELTimer_GetMSec();
RenderArea();
DWORD t3=ELTimer_GetMSec();
if (!m_bEnableTerrainOnlyForHeight)
RenderTerrain();
DWORD t4=ELTimer_GetMSec();
RenderTree();
DWORD t5=ELTimer_GetMSec();
DWORD tEnd=ELTimer_GetMSec();
if (tEnd-t1<7)
return;
static FILE* fp=fopen("perf_map_render.txt", "w");
fprintf(fp, "MAP.Total %d (Time %d)\n", tEnd-t1, ELTimer_GetMSec());
fprintf(fp, "MAP.ENV %d\n", t2-t1);
fprintf(fp, "MAP.OBJ %d\n", t3-t2);
fprintf(fp, "MAP.TRN %d\n", t4-t3);
fprintf(fp, "MAP.TRE %d\n", t5-t4);
#else
SetInverseViewAndDynamicShaodwMatrices();
SetBlendOperation();
RenderArea();
RenderTree();
if (!m_bEnableTerrainOnlyForHeight)
RenderTerrain();
RenderBlendArea();
#endif
}
struct FAreaRenderShadow
{
void operator () (CGraphicObjectInstance * pInstance)
{
pInstance->RenderShadow();
pInstance->Hide();
}
};
struct FPCBlockerHide
{
void operator () (CGraphicObjectInstance * pInstance)
{
pInstance->Hide();
}
};
struct FRenderPCBlocker
{
void operator () (CGraphicObjectInstance * pInstance)
{
pInstance->Show();
CGraphicThingInstance* pThingInstance = dynamic_cast <CGraphicThingInstance*> (pInstance);
if (pThingInstance != NULL)
{
if (pThingInstance->HaveBlendThing())
{
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
pThingInstance->BlendRender();
return;
}
}
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
pInstance->RenderPCBlocker();
}
};
void CMapOutdoor::RenderEffect()
{
if (!IsVisiblePart(PART_OBJECT))
return;
for (int i = 0; i < AROUND_AREA_NUM; ++i)
{
CArea * pArea;
if (GetAreaPointer(i, &pArea))
{
pArea->RenderEffect();
}
}
}
struct CMapOutdoor_LessThingInstancePtrRenderOrder
{
bool operator() (CGraphicThingInstance* pkLeft, CGraphicThingInstance* pkRight)
{
//TODO : Camera위치기반으로 소팅
CCamera * pCurrentCamera = CCameraManager::Instance().GetCurrentCamera();
const D3DXVECTOR3 & c_rv3CameraPos = pCurrentCamera->GetEye();
const D3DXVECTOR3 & c_v3LeftPos = pkLeft->GetPosition();
const D3DXVECTOR3 & c_v3RightPos = pkRight->GetPosition();
const auto vv = D3DXVECTOR3(c_rv3CameraPos - c_v3RightPos);
const auto vv2 = D3DXVECTOR3(c_rv3CameraPos - c_v3LeftPos);
return D3DXVec3LengthSq(&vv2) < D3DXVec3LengthSq(&vv);
}
};
struct CMapOutdoor_FOpaqueThingInstanceRender
{
inline void operator () (CGraphicThingInstance * pkThingInst)
{
pkThingInst->Render();
}
};
struct CMapOutdoor_FBlendThingInstanceRender
{
inline void operator () (CGraphicThingInstance * pkThingInst)
{
pkThingInst->BlendRender();
}
};
void CMapOutdoor::RenderArea(bool bRenderAmbience)
{
if (!IsVisiblePart(PART_OBJECT))
return;
m_dwRenderedCRCNum = 0;
m_dwRenderedGraphicThingInstanceNum = 0;
m_dwRenderedCRCWithNumberVector.clear();
// NOTE - 20041201.levites.던젼 그림자 추가
for (int j = 0; j < AROUND_AREA_NUM; ++j)
{
CArea * pArea;
if (GetAreaPointer(j, &pArea))
{
pArea->RenderDungeon();
}
}
#ifndef WORLD_EDITOR
// PCBlocker
std::for_each(m_PCBlockerVector.begin(), m_PCBlockerVector.end(), FPCBlockerHide());
// Shadow Receiver
if (m_bDrawShadow && m_bDrawChrShadow)
{
if (mc_pEnvironmentData != NULL)
STATEMANAGER.SetRenderState(D3DRS_FOGCOLOR, 0xFFFFFFFF);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
// Transform
STATEMANAGER.SaveTransform(D3DTS_TEXTURE1, &m_matDynamicShadow);
STATEMANAGER.SetTexture(1, m_lpCharacterShadowMapTexture);
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_BORDER);
STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_BORDER);
STATEMANAGER.SaveTextureStageState(1, D3DTSS_BORDERCOLOR, 0xFFFFFFFF);
std::for_each(m_ShadowReceiverVector.begin(), m_ShadowReceiverVector.end(), FAreaRenderShadow());
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXCOORDINDEX);
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS);
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSU);
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSV);
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_BORDERCOLOR);
STATEMANAGER.RestoreTransform(D3DTS_TEXTURE1);
if (mc_pEnvironmentData != NULL)
STATEMANAGER.SetRenderState(D3DRS_FOGCOLOR, mc_pEnvironmentData->FogColor);
}
#endif
STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE, TRUE);
bool m_isDisableSortRendering=false;
if (m_isDisableSortRendering)
{
for (int i = 0; i < AROUND_AREA_NUM; ++i)
{
CArea * pArea;
if (GetAreaPointer(i, &pArea))
{
pArea->Render();
m_dwRenderedCRCNum += pArea->DEBUG_GetRenderedCRCNum();
m_dwRenderedGraphicThingInstanceNum += pArea->DEBUG_GetRenderedGrapphicThingInstanceNum();
CArea::TCRCWithNumberVector & rCRCWithNumberVector = pArea->DEBUG_GetRenderedCRCWithNumVector();
CArea::TCRCWithNumberVector::iterator aIterator = rCRCWithNumberVector.begin();
while (aIterator != rCRCWithNumberVector.end())
{
DWORD dwCRC = (*aIterator++).dwCRC;
CArea::TCRCWithNumberVector::iterator aCRCWithNumberVectorIterator =
std::find_if(m_dwRenderedCRCWithNumberVector.begin(), m_dwRenderedCRCWithNumberVector.end(), CArea::FFindIfCRC(dwCRC));
if ( m_dwRenderedCRCWithNumberVector.end() == aCRCWithNumberVectorIterator)
{
CArea::TCRCWithNumber aCRCWithNumber;
aCRCWithNumber.dwCRC = dwCRC;
aCRCWithNumber.dwNumber = 1;
m_dwRenderedCRCWithNumberVector.push_back(aCRCWithNumber);
}
else
{
CArea::TCRCWithNumber & rCRCWithNumber = *aCRCWithNumberVectorIterator;
rCRCWithNumber.dwNumber += 1;
}
}
#ifdef WORLD_EDITOR
if (bRenderAmbience)
pArea->RenderAmbience();
#endif
}
}
std::sort(m_dwRenderedCRCWithNumberVector.begin(), m_dwRenderedCRCWithNumberVector.end(), CArea::CRCNumComp());
}
else
{
static std::vector<CGraphicThingInstance*> s_kVct_pkOpaqueThingInstSort;
s_kVct_pkOpaqueThingInstSort.clear();
for (int i = 0; i < AROUND_AREA_NUM; ++i)
{
CArea * pArea;
if (GetAreaPointer(i, &pArea))
{
pArea->CollectRenderingObject(s_kVct_pkOpaqueThingInstSort);
#ifdef WORLD_EDITOR
if (bRenderAmbience)
pArea->RenderAmbience();
#endif
}
}
std::sort(s_kVct_pkOpaqueThingInstSort.begin(), s_kVct_pkOpaqueThingInstSort.end(), CMapOutdoor_LessThingInstancePtrRenderOrder());
std::for_each(s_kVct_pkOpaqueThingInstSort.begin(), s_kVct_pkOpaqueThingInstSort.end(), CMapOutdoor_FOpaqueThingInstanceRender());
}
STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE);
#ifndef WORLD_EDITOR
// Shadow Receiver
if (m_bDrawShadow && m_bDrawChrShadow)
{
std::for_each(m_ShadowReceiverVector.begin(), m_ShadowReceiverVector.end(), std::mem_fn(&CGraphicObjectInstance::Show));
}
#endif
}
void CMapOutdoor::RenderBlendArea()
{
if (!IsVisiblePart(PART_OBJECT))
return;
static std::vector<CGraphicThingInstance*> s_kVct_pkBlendThingInstSort;
s_kVct_pkBlendThingInstSort.clear();
for (int i = 0; i < AROUND_AREA_NUM; ++i)
{
CArea * pArea;
if (GetAreaPointer(i, &pArea))
{
pArea->CollectBlendRenderingObject(s_kVct_pkBlendThingInstSort);
}
}
if (s_kVct_pkBlendThingInstSort.size() != 0)
{
//STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
//STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
//STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
//STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
//STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
//STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
//// Transform
//STATEMANAGER.SaveTransform(D3DTS_TEXTURE1, &m_matDynamicShadow);
//STATEMANAGER.SetTexture(1, m_lpCharacterShadowMapTexture);
//STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
//STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
//STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);
//STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
//STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_BORDER);
//STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_BORDER);
//STATEMANAGER.SaveTextureStageState(1, D3DTSS_BORDERCOLOR, 0xFFFFFFFF);
////std::for_each(m_ShadowReceiverVector.begin(), m_ShadowReceiverVector.end(), FAreaRenderShadow());
//STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXCOORDINDEX);
//STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS);
//STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSU);
//STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSV);
//STATEMANAGER.RestoreTextureStageState(1, D3DTSS_BORDERCOLOR);
//STATEMANAGER.RestoreTransform(D3DTS_TEXTURE1);
std::sort(s_kVct_pkBlendThingInstSort.begin(), s_kVct_pkBlendThingInstSort.end(), CMapOutdoor_LessThingInstancePtrRenderOrder());
STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE, TRUE);
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
std::for_each(s_kVct_pkBlendThingInstSort.begin(), s_kVct_pkBlendThingInstSort.end(), CMapOutdoor_FBlendThingInstanceRender());
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND);
STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND);
STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE);
}
}
void CMapOutdoor::RenderDungeon()
{
for (int i = 0; i < AROUND_AREA_NUM; ++i)
{
CArea * pArea;
if (!GetAreaPointer(i, &pArea))
continue;
pArea->RenderDungeon();
}
}
void CMapOutdoor::RenderPCBlocker()
{
#ifndef WORLD_EDITOR
// PCBlocker
if (m_PCBlockerVector.size() != 0)
{
STATEMANAGER.SetTexture(0, NULL);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
STATEMANAGER.SaveTransform(D3DTS_TEXTURE1, &m_matBuildingTransparent);
STATEMANAGER.SetTexture(1, m_BuildingTransparentImageInstance.GetTexturePointer()->GetD3DTexture());
std::for_each(m_PCBlockerVector.begin(), m_PCBlockerVector.end(), FRenderPCBlocker());
STATEMANAGER.SetTexture(1, NULL);
STATEMANAGER.RestoreTransform(D3DTS_TEXTURE1);
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXCOORDINDEX);
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS);
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSU);
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSV);
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
}
#endif
}
void CMapOutdoor::SelectIndexBuffer(BYTE byLODLevel, WORD * pwPrimitiveCount, D3DPRIMITIVETYPE * pePrimitiveType)
{
#ifdef WORLD_EDITOR
*pwPrimitiveCount = m_wNumIndices - 2;
*pePrimitiveType = D3DPT_TRIANGLESTRIP;
STATEMANAGER.SetIndices(m_IndexBuffer.GetD3DIndexBuffer(), 0);
#else
if (0 == byLODLevel)
{
*pwPrimitiveCount = m_wNumIndices[byLODLevel] - 2;
*pePrimitiveType = D3DPT_TRIANGLESTRIP;
}
else
{
*pwPrimitiveCount = m_wNumIndices[byLODLevel]/3;
*pePrimitiveType = D3DPT_TRIANGLELIST;
}
STATEMANAGER.SetIndices(m_IndexBuffer[byLODLevel].GetD3DIndexBuffer(), 0);
#endif
}
void CMapOutdoor::SetPatchDrawVector()
{
assert(NULL!=m_pTerrainPatchProxyList && "CMapOutdoor::__SetPatchDrawVector");
m_PatchDrawStructVector.clear();
std::vector<std::pair<float, long> >::iterator aDistancePatchVectorIterator;
TPatchDrawStruct aPatchDrawStruct;
aDistancePatchVectorIterator = m_PatchVector.begin();
while(aDistancePatchVectorIterator != m_PatchVector.end())
{
std::pair<float, long> adistancePatchPair = *aDistancePatchVectorIterator;
CTerrainPatchProxy * pTerrainPatchProxy = &m_pTerrainPatchProxyList[adistancePatchPair.second];
if (!pTerrainPatchProxy->isUsed())
{
++aDistancePatchVectorIterator;
continue;
}
long lPatchNum = pTerrainPatchProxy->GetPatchNum();
if (lPatchNum < 0)
{
++aDistancePatchVectorIterator;
continue;
}
BYTE byTerrainNum = pTerrainPatchProxy->GetTerrainNum();
if (0xFF == byTerrainNum)
{
++aDistancePatchVectorIterator;
continue;
}
CTerrain * pTerrain;
if (!GetTerrainPointer(byTerrainNum, &pTerrain))
{
++aDistancePatchVectorIterator;
continue;
}
aPatchDrawStruct.fDistance = adistancePatchPair.first;
aPatchDrawStruct.byTerrainNum = byTerrainNum;
aPatchDrawStruct.lPatchNum = lPatchNum;
aPatchDrawStruct.pTerrainPatchProxy = pTerrainPatchProxy;
m_PatchDrawStructVector.push_back(aPatchDrawStruct);
++aDistancePatchVectorIterator;
}
std::stable_sort(m_PatchDrawStructVector.begin(), m_PatchDrawStructVector.end(), FSortPatchDrawStructWithTerrainNum());
}
float CMapOutdoor::__GetNoFogDistance()
{
return (float)(CTerrainImpl::CELLSCALE * m_lViewRadius) * 0.5f;
}
float CMapOutdoor::__GetFogDistance()
{
return (float)(CTerrainImpl::CELLSCALE * m_lViewRadius) * 0.75f;
}
struct FPatchNumMatch
{
long m_lPatchNumToCheck;
FPatchNumMatch(long lPatchNum)
{
m_lPatchNumToCheck = lPatchNum;
}
bool operator() (std::pair<long, BYTE> aPair)
{
return m_lPatchNumToCheck == aPair.first;
}
};
void CMapOutdoor::NEW_DrawWireFrame(CTerrainPatchProxy * pTerrainPatchProxy, WORD wPrimitiveCount, D3DPRIMITIVETYPE ePrimitiveType)
{
DWORD dwFillMode = STATEMANAGER.GetRenderState(D3DRS_FILLMODE);
STATEMANAGER.SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
DWORD dwFogEnable = STATEMANAGER.GetRenderState(D3DRS_FOGENABLE);
STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, FALSE);
STATEMANAGER.SetTexture(0, NULL);
STATEMANAGER.SetTexture(1, NULL);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);
STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount);
STATEMANAGER.SetRenderState(D3DRS_FILLMODE, dwFillMode);
STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, dwFogEnable);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
}
void CMapOutdoor::DrawWireFrame(long patchnum, WORD wPrimitiveCount, D3DPRIMITIVETYPE ePrimitiveType)
{
assert(NULL!=m_pTerrainPatchProxyList && "CMapOutdoor::DrawWireFrame");
CTerrainPatchProxy * pTerrainPatchProxy= &m_pTerrainPatchProxyList[patchnum];
if (!pTerrainPatchProxy->isUsed())
return;
long sPatchNum = pTerrainPatchProxy->GetPatchNum();
if (sPatchNum < 0)
return;
BYTE ucTerrainNum = pTerrainPatchProxy->GetTerrainNum();
if (0xFF == ucTerrainNum)
return;
DWORD dwFillMode = STATEMANAGER.GetRenderState(D3DRS_FILLMODE);
STATEMANAGER.SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
DWORD dwFogEnable = STATEMANAGER.GetRenderState(D3DRS_FOGENABLE);
STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, FALSE);
STATEMANAGER.SetTexture(0, NULL);
STATEMANAGER.SetTexture(1, NULL);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);
STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount);
STATEMANAGER.SetRenderState(D3DRS_FILLMODE, dwFillMode);
STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, dwFogEnable);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
}
// Attr
void CMapOutdoor::RenderMarkedArea()
{
if (!m_pTerrainPatchProxyList)
return;
m_matWorldForCommonUse._41 = 0.0f;
m_matWorldForCommonUse._42 = 0.0f;
STATEMANAGER.SetTransform(D3DTS_WORLD, &m_matWorldForCommonUse);
WORD wPrimitiveCount;
D3DPRIMITIVETYPE eType;
SelectIndexBuffer(0, &wPrimitiveCount, &eType);
D3DXMATRIX matTexTransform, matTexTransformTemp;
D3DXMatrixScaling(&matTexTransform, m_fTerrainTexCoordBase * 32.0f, -m_fTerrainTexCoordBase * 32.0f, 0.0f);
D3DXMatrixMultiply(&matTexTransform, &m_matViewInverse, &matTexTransform);
STATEMANAGER.SaveTransform(D3DTS_TEXTURE0, &matTexTransform);
STATEMANAGER.SaveTransform(D3DTS_TEXTURE1, &matTexTransform);
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
static long lStartTime = timeGetTime();
float fTime = float((timeGetTime() - lStartTime)%3000) / 3000.0f;
float fAlpha = fabs(fTime - 0.5f) / 2.0f + 0.1f;
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, D3DXCOLOR(1.0f, 1.0f, 1.0f, fAlpha));
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TFACTOR);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
STATEMANAGER.SaveTextureStageState(1, D3DTSS_MINFILTER, D3DTEXF_POINT);
STATEMANAGER.SaveTextureStageState(1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
STATEMANAGER.SaveTextureStageState(1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
STATEMANAGER.SetTexture(0, m_attrImageInstance.GetTexturePointer()->GetD3DTexture());
RecurseRenderAttr(m_pRootNode);
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXCOORDINDEX);
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS);
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXCOORDINDEX);
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS);
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_MINFILTER);
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_MAGFILTER);
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_MIPFILTER);
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSU);
STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSV);
STATEMANAGER.RestoreTransform(D3DTS_TEXTURE0);
STATEMANAGER.RestoreTransform(D3DTS_TEXTURE1);
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND);
STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND);
}
void CMapOutdoor::RecurseRenderAttr(CTerrainQuadtreeNode *Node, bool bCullEnable)
{
if (bCullEnable)
{
if (__RenderTerrain_RecurseRenderQuadTree_CheckBoundingCircle(Node->center, Node->radius)==VIEW_NONE)
return;
}
{
if (Node->Size == 1)
{
DrawPatchAttr(Node->PatchNum);
}
else
{
if (Node->NW_Node != NULL)
RecurseRenderAttr(Node->NW_Node, bCullEnable);
if (Node->NE_Node != NULL)
RecurseRenderAttr(Node->NE_Node, bCullEnable);
if (Node->SW_Node != NULL)
RecurseRenderAttr(Node->SW_Node, bCullEnable);
if (Node->SE_Node != NULL)
RecurseRenderAttr(Node->SE_Node, bCullEnable);
}
}
}
void CMapOutdoor::DrawPatchAttr(long patchnum)
{
CTerrainPatchProxy * pTerrainPatchProxy = &m_pTerrainPatchProxyList[patchnum];
if (!pTerrainPatchProxy->isUsed())
return;
long sPatchNum = pTerrainPatchProxy->GetPatchNum();
if (sPatchNum < 0)
return;
BYTE ucTerrainNum = pTerrainPatchProxy->GetTerrainNum();
if (0xFF == ucTerrainNum)
return;
// Deal with this material buffer
CTerrain * pTerrain;
if (!GetTerrainPointer(ucTerrainNum, &pTerrain))
return;
if (!pTerrain->IsMarked())
return;
WORD wCoordX, wCoordY;
pTerrain->GetCoordinate(&wCoordX, &wCoordY);
m_matWorldForCommonUse._41 = -(float) (wCoordX * CTerrainImpl::XSIZE * CTerrainImpl::CELLSCALE);
m_matWorldForCommonUse._42 = (float) (wCoordY * CTerrainImpl::YSIZE * CTerrainImpl::CELLSCALE);
D3DXMATRIX matTexTransform, matTexTransformTemp;
D3DXMatrixMultiply(&matTexTransform, &m_matViewInverse, &m_matWorldForCommonUse);
D3DXMatrixMultiply(&matTexTransform, &matTexTransform, &m_matStaticShadow);
STATEMANAGER.SetTransform(D3DTS_TEXTURE1, &matTexTransform);
TTerrainSplatPatch & rAttrSplatPatch = pTerrain->GetMarkedSplatPatch();
STATEMANAGER.SetTexture(1, rAttrSplatPatch.Splats[0].pd3dTexture);
STATEMANAGER.SetVertexShader(D3DFVF_XYZ | D3DFVF_NORMAL);
STATEMANAGER.SetStreamSource(0, pTerrainPatchProxy->HardwareTransformPatch_GetVertexBufferPtr()->GetD3DVertexBuffer(), m_iPatchTerrainVertexSize);
#ifdef WORLD_EDITOR
STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0, m_iPatchTerrainVertexCount, 0, m_wNumIndices - 2);
#else
STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0, m_iPatchTerrainVertexCount, 0, m_wNumIndices[0] - 2);
#endif
}
File diff suppressed because it is too large Load Diff
+299
View File
@@ -0,0 +1,299 @@
#include "StdAfx.h"
#include "../EterBase/Filename.h"
#include "Property.h"
float SEnvironmentData::GetFogNearDistance() const
{
return m_fFogNearDistance;
}
float SEnvironmentData::GetFogFarDistance() const
{
return m_fFogFarDistance;
}
float SPixelPosition_CalculateDistanceSq3d(const TPixelPosition& c_rkPPosLeft, const TPixelPosition& c_rkPPosRight)
{
float dx=c_rkPPosLeft.x-c_rkPPosRight.x;
float dy=c_rkPPosLeft.y-c_rkPPosRight.y;
float dz=c_rkPPosLeft.z-c_rkPPosRight.z;
return dx*dx+dy*dy+dz*dz;
}
namespace prt
{
DWORD GetPropertyType(const char * c_szTypeName)
{
for (DWORD i = 0; i < PROPERTY_TYPE_MAX_NUM; ++i)
{
if (!strcmp(c_szPropertyTypeName[i], c_szTypeName))
return i;
}
return PROPERTY_TYPE_NONE;
}
const char * GetPropertyExtension(DWORD dwType)
{
if (dwType >= PROPERTY_TYPE_MAX_NUM)
return c_szPropertyExtension[0];
return c_szPropertyExtension[dwType];
}
const char * IntegerNumberToString(int iNumber)
{
static char szString[16+1];
_snprintf(szString, sizeof(szString), "%d", iNumber);
return szString;
}
const char * FloatNumberToString(float fNumber)
{
static char szString[16+1];
_snprintf(szString, sizeof(szString), "%f", fNumber);
return szString;
}
bool PropertyTreeDataToString(TPropertyTree * pData, CProperty * pProperty)
{
pProperty->Clear();
pProperty->PutString("PropertyType", "Tree");
pProperty->PutString("PropertyName", pData->strName.c_str());
pProperty->PutString("TreeFile", pData->strFileName.c_str());
pProperty->PutString("TreeSize", FloatNumberToString(pData->fSize));
pProperty->PutString("TreeVariance", FloatNumberToString(pData->fVariance));
return true;
}
bool PropertyTreeStringToData(CProperty * pProperty, TPropertyTree * pData)
{
const char * c_pszPropertyType;
const char * c_pszPropertyName;
if (!pProperty->GetString("PropertyType", &c_pszPropertyType))
return false;
if (!pProperty->GetString("PropertyName", &c_pszPropertyName))
return false;
if (strcmp(c_pszPropertyType, "Tree"))
return false;
pData->strName = c_pszPropertyName;
///////////////////////////////////////////////////////////////////////////////////
const char * c_pszTreeName;
const char * c_pszTreeSize;
const char * c_pszTreeVariance;
if (!pProperty->GetString("TreeFile", &c_pszTreeName))
return false;
if (!pProperty->GetString("TreeSize", &c_pszTreeSize))
return false;
if (!pProperty->GetString("TreeVariance", &c_pszTreeVariance))
return false;
pData->strFileName = c_pszTreeName;
pData->fSize = atof(c_pszTreeSize);
pData->fVariance = atof(c_pszTreeVariance);
return true;
}
bool PropertyBuildingDataToString(TPropertyBuilding * pData, CProperty * pProperty)
{
pProperty->Clear();
pProperty->PutString("PropertyType", "Building");
pProperty->PutString("PropertyName", pData->strName.c_str());
pProperty->PutString("BuildingFile", pData->strFileName.c_str());
pProperty->PutString("ShadowFlag", IntegerNumberToString(pData->isShadowFlag));
return true;
}
bool PropertyBuildingStringToData(CProperty * pProperty, TPropertyBuilding * pData)
{
const char * c_pszPropertyType;
const char * c_pszPropertyName;
if (!pProperty->GetString("PropertyType", &c_pszPropertyType))
return false;
if (!pProperty->GetString("PropertyName", &c_pszPropertyName))
return false;
if (strcmp(c_pszPropertyType, "Building"))
return false;
pData->strName = c_pszPropertyName;
///////////////////////////////////////////////////////////////////////////////////
const char * c_pszBuildingName;
if (!pProperty->GetString("BuildingFile", &c_pszBuildingName))
return false;
pData->strFileName = c_pszBuildingName;
pData->strAttributeDataFileName = CFileNameHelper::NoExtension(pData->strFileName) + ".mdatr";
const char * c_pszShadowFlag;
if (!pProperty->GetString("ShadowFlag", &c_pszShadowFlag))
{
pData->isShadowFlag = FALSE;
}
else
{
pData->isShadowFlag = atoi(c_pszShadowFlag);
}
return true;
}
bool PropertyEffectDataToString(TPropertyEffect * pData, CProperty * pProperty)
{
pProperty->Clear();
pProperty->PutString("PropertyType", "Effect");
pProperty->PutString("PropertyName", pData->strName.c_str());
pProperty->PutString("EffectFile", pData->strFileName.c_str());
return true;
}
bool PropertyEffectStringToData(CProperty * pProperty, TPropertyEffect * pData)
{
const char * c_pszPropertyType;
const char * c_pszPropertyName;
if (!pProperty->GetString("PropertyType", &c_pszPropertyType))
return false;
if (!pProperty->GetString("PropertyName", &c_pszPropertyName))
return false;
if (strcmp(c_pszPropertyType, "Effect"))
return false;
pData->strName = c_pszPropertyName;
///////////////////////////////////////////////////////////////////////////////////
const char * c_pszEffectName;
if (!pProperty->GetString("EffectFile", &c_pszEffectName))
return false;
pData->strFileName = c_pszEffectName;
return true;
}
bool PropertyAmbienceDataToString(TPropertyAmbience * pData, CProperty * pProperty)
{
pProperty->Clear();
pProperty->PutString("PropertyType", "Ambience");
pProperty->PutString("PropertyName", pData->strName.c_str());
pProperty->PutString("PlayType", pData->strPlayType.c_str());
pProperty->PutString("PlayInterval", FloatNumberToString(pData->fPlayInterval));
pProperty->PutString("PlayIntervalVariation", FloatNumberToString(pData->fPlayIntervalVariation));
pProperty->PutString("MaxVolumeAreaPercentage", FloatNumberToString(pData->fMaxVolumeAreaPercentage));
CTokenVector AmbienceSoundVector;
std::vector<std::string>::iterator itor = pData->AmbienceSoundVector.begin();
for (; itor != pData->AmbienceSoundVector.end(); ++itor)
{
std::string & rstrToken = *itor;
AmbienceSoundVector.push_back(rstrToken.c_str());
}
pProperty->PutVector("AmbienceSoundVector", AmbienceSoundVector);
return true;
}
bool PropertyAmbienceStringToData(CProperty * pProperty, TPropertyAmbience * pData)
{
const char * c_pszPropertyType;
const char * c_pszPropertyName;
if (!pProperty->GetString("PropertyType", &c_pszPropertyType))
return false;
if (!pProperty->GetString("PropertyName", &c_pszPropertyName))
return false;
if (strcmp(c_pszPropertyType, "Ambience"))
return false;
pData->strName = c_pszPropertyName;
///////////////////////////////////////////////////////////////////////////////////
const char * c_pszPlayType;
const char * c_pszPlayInterval;
const char * c_pszPlayIntervalVariation;
const char * c_pszMaxVolumeAreaPercentage = NULL;
CTokenVector AmbienceSoundVector;
if (!pProperty->GetString("PlayType", &c_pszPlayType))
return false;
if (!pProperty->GetString("PlayInterval", &c_pszPlayInterval))
return false;
if (!pProperty->GetString("PlayIntervalVariation", &c_pszPlayIntervalVariation))
return false;
if (!pProperty->GetString("MaxVolumeAreaPercentage", &c_pszMaxVolumeAreaPercentage))
{
pData->fMaxVolumeAreaPercentage = 0.0f;
}
if (!pProperty->GetVector("AmbienceSoundVector", AmbienceSoundVector))
return false;
pData->strPlayType = c_pszPlayType;
pData->fPlayInterval = atof(c_pszPlayInterval);
pData->fPlayIntervalVariation = atof(c_pszPlayIntervalVariation);
if (c_pszMaxVolumeAreaPercentage)
pData->fMaxVolumeAreaPercentage = atof(c_pszMaxVolumeAreaPercentage);
for (CTokenVector::iterator itor = AmbienceSoundVector.begin(); itor != AmbienceSoundVector.end(); ++itor)
pData->AmbienceSoundVector.push_back(*itor);
return true;
}
bool PropertyDungeonBlockDataToString(TPropertyDungeonBlock * pData, CProperty * pProperty)
{
pProperty->Clear();
pProperty->PutString("PropertyType", "DungeonBlock");
pProperty->PutString("PropertyName", pData->strName.c_str());
pProperty->PutString("DungeonBlockFile", pData->strFileName.c_str());
return true;
}
bool PropertyDungeonBlockStringToData(CProperty * pProperty, TPropertyDungeonBlock * pData)
{
const char * c_pszPropertyType;
const char * c_pszPropertyName;
if (!pProperty->GetString("PropertyType", &c_pszPropertyType))
return false;
if (!pProperty->GetString("PropertyName", &c_pszPropertyName))
return false;
if (strcmp(c_pszPropertyType, "DungeonBlock"))
return false;
pData->strName = c_pszPropertyName;
///////////////////////////////////////////////////////////////////////////////////
const char * c_pszDungeonBlockFileName = NULL;
if (!pProperty->GetString("dungeonblockfile", &c_pszDungeonBlockFileName))
return false;
pData->strFileName = c_pszDungeonBlockFileName;
pData->strAttributeDataFileName = CFileNameHelper::NoExtension(pData->strFileName) + std::string(".mdatr");
return true;
}
}; // namespace prt;
@@ -0,0 +1,148 @@
// MonsterAreaInfo.cpp: implementation of the CMonsterAreaInfo class.
//
//////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "MonsterAreaInfo.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMonsterAreaInfo::CMonsterAreaInfo()
{
Clear();
}
CMonsterAreaInfo::~CMonsterAreaInfo()
{
Clear();
}
void CMonsterAreaInfo::Clear()
{
SetOrigin(-1, -1);
SetSize(-1, -1);
RemoveAllMonsters();
}
void CMonsterAreaInfo::SetOrigin(long lOriginX, long lOriginY)
{
m_lOriginX = lOriginX;
m_lOriginY = lOriginY;
SetLRTB();
}
void CMonsterAreaInfo::SetSize(long lSizeX, long lSizeY)
{
m_lSizeX = lSizeX;
m_lSizeY = lSizeY;
SetLRTB();
}
void CMonsterAreaInfo::GetOrigin(long * plOriginX, long * plOriginY)
{
*plOriginX = m_lOriginX;
*plOriginY = m_lOriginY;
}
void CMonsterAreaInfo::GetSize(long * plSizeX, long * plSizeY)
{
*plSizeX = m_lSizeX;
*plSizeY = m_lSizeY;
}
void CMonsterAreaInfo::SetLRTB()
{
m_lLeft = m_lOriginX - m_lSizeX;
m_lTop = m_lOriginY - m_lSizeY;
m_lRight = m_lOriginX + m_lSizeX;
m_lBottom = m_lOriginY + m_lSizeY;
}
void CMonsterAreaInfo::SetMonsterCount(DWORD dwCount)
{
m_dwMonsterCount = dwCount;
if (m_TempMonsterPosVector.size() == dwCount)
return;
m_TempMonsterPosVector.clear();
m_TempMonsterPosVector.resize(dwCount);
for (DWORD dwI = 0; dwI < dwCount; ++dwI)
{
m_TempMonsterPosVector[dwI].x = (float)random_range(m_lLeft, m_lRight);
m_TempMonsterPosVector[dwI].y = (float)random_range(m_lTop, m_lBottom);
}
}
void CMonsterAreaInfo::SetMonsterDirection(EMonsterDir eMonsterDir)
{
m_eMonsterDir = eMonsterDir;
D3DXMATRIX matRotation;
D3DXVECTOR3 v3Direction(0.0f, 1.0f, 0.0f);
float fDegree = 0.0f;
switch(m_eMonsterDir)
{
case DIR_RANDOM:
fDegree = (float) random_range(0, 7) * 45.0f;
break;
case DIR_NORTH:
fDegree = 0.0f;
break;
case DIR_NORTHEAST:
fDegree = 45.0f;
break;
case DIR_EAST:
fDegree = 90.0f;
break;
case DIR_SOUTHEAST:
fDegree = 135.0f;
break;
case DIR_SOUTH:
fDegree = 180.0f;
break;
case DIR_SOUTHWEST:
fDegree = 225.0f;
break;
case DIR_WEST:
fDegree = 270.0f;
break;
case DIR_NORTHWEST:
fDegree = 315.0f;
break;
}
D3DXMatrixRotationZ(&matRotation, -D3DXToRadian(fDegree));
D3DXVec3TransformCoord(&v3Direction, &v3Direction, &matRotation);
m_v2Monsterdirection.x = v3Direction.x;
m_v2Monsterdirection.y = v3Direction.y;
D3DXVec2Normalize(&m_v2Monsterdirection, &m_v2Monsterdirection);
}
void CMonsterAreaInfo::RemoveAllMonsters()
{
SetMonsterAreaInfoType(MONSTERAREAINFOTYPE_INVALID);
SetMonsterGroupID(0);
m_strGroupName.assign("\300\314\270\247\276\370\300\275");
m_strLeaderName.assign("\300\314\270\247\276\370\300\275");
SetMonsterGroupFollowerCount(0);
SetMonsterVID(0);
m_strMonsterName.assign("\300\314\270\247\276\370\300\275");
SetMonsterCount(0);
SetMonsterDirection(DIR_NORTH);
m_TempMonsterPosVector.clear();
}
D3DXVECTOR2 CMonsterAreaInfo::GetTempMonsterPos(DWORD dwIndex)
{
if (dwIndex >= m_TempMonsterPosVector.size())
return D3DXVECTOR2(0.0f, 0.0f);
return m_TempMonsterPosVector[dwIndex];
}
+269
View File
@@ -0,0 +1,269 @@
#include "StdAfx.h"
#include <string.h>
#include "../EterBase/TempFile.h"
#include "PropertyManager.h"
#include "Property.h"
/*
* CProperty 파일 포맷
*
* 0 ~ 4 bytes: fourcc
* 5 ~ 6 bytes: \r\n
*
* 그 이후의 바이트들은 텍스트 파일 로더와 같은 구조
*/
CProperty::CProperty(const char * c_pszFileName) : mc_pFileName(NULL), m_dwCRC(0)
{
m_stFileName = c_pszFileName;
StringPath(m_stFileName);
mc_pFileName = strrchr(m_stFileName.c_str(), '/');
if (!mc_pFileName)
mc_pFileName = m_stFileName.c_str();
else
++mc_pFileName;
}
CProperty::~CProperty()
{
}
DWORD CProperty::GetCRC()
{
return m_dwCRC;
}
const char * CProperty::GetFileName()
{
return (m_stFileName.c_str());
}
bool CProperty::GetString(const char * c_pszKey, const char ** c_ppString)
{
std::string stTempKey = c_pszKey;
stl_lowers(stTempKey);
CTokenVectorMap::iterator it = m_stTokenMap.find(stTempKey.c_str());
// printf("GetString %s %d\n", stTempKey.c_str(), m_stTokenMap.size());
if (m_stTokenMap.end() == it)
return false;
*c_ppString = it->second[0].c_str();
return true;
}
DWORD CProperty::GetSize()
{
return m_stTokenMap.size();
}
bool CProperty::GetVector(const char * c_pszKey, CTokenVector & rTokenVector)
{
std::string stTempKey = c_pszKey;
stl_lowers(stTempKey);
CTokenVectorMap::iterator it = m_stTokenMap.find(stTempKey.c_str());
if (m_stTokenMap.end() == it)
return false;
// NOTE : 튕김 현상 발견
// std::copy(rTokenVector.begin(), it->second.begin(), it->second.end());
// NOTE : 레퍼런스에는 이런 식으로 하게끔 되어 있음
///////////////////////////////////////////////////////////////////////////////
// template <class InputIterator, class OutputIterator>
// OutputIterator copy(InputIterator first, InputIterator last,
// OutputIterator result);
//
// vector<int> V(5);
// iota(V.begin(), V.end(), 1);
// list<int> L(V.size());
// copy(V.begin(), V.end(), L.begin());
// assert(equal(V.begin(), V.end(), L.begin()));
///////////////////////////////////////////////////////////////////////////////
// 헌데 그래도 튕김. - [levites]
// std::copy(it->second.begin(), it->second.end(), rTokenVector.begin());
// 결국 이렇게.. - [levites]
// 현재 사용하는 곳 : WorldEditor/Dialog/MapObjectPropertyPageBuilding.cpp
CTokenVector & rSourceTokenVector = it->second;
CTokenVector::iterator itor = rSourceTokenVector.begin();
for (; itor != rSourceTokenVector.end(); ++itor)
{
rTokenVector.push_back(*itor);
}
return true;
}
void CProperty::PutString(const char * c_pszKey, const char * c_pszString)
{
std::string stTempKey = c_pszKey;
stl_lowers(stTempKey);
// 이미 있는걸 지움
CTokenVectorMap::iterator itor = m_stTokenMap.find(stTempKey);
if (itor != m_stTokenMap.end())
m_stTokenMap.erase(itor);
CTokenVector tokenVector;
tokenVector.push_back(c_pszString);
m_stTokenMap.insert(CTokenVectorMap::value_type(stTempKey, tokenVector));
}
void CProperty::PutVector(const char * c_pszKey, const CTokenVector & c_rTokenVector)
{
std::string stTempKey = c_pszKey;
stl_lowers(stTempKey);
m_stTokenMap.insert(CTokenVectorMap::value_type(stTempKey, c_rTokenVector));
}
void GetTimeString(char * str, time_t ct)
{
struct tm tm;
tm = *localtime(&ct);
_snprintf(str, 15, "%04d%02d%02d%02d%02d%02d",
tm.tm_year + 1900,
tm.tm_mon + 1,
tm.tm_mday,
tm.tm_hour,
tm.tm_min,
tm.tm_sec);
}
bool CProperty::Save(const char * c_pszFileName)
{
CTempFile file;
DWORD fourcc = MAKEFOURCC('Y', 'P', 'R', 'T');
file.Write(&fourcc, sizeof(DWORD));
file.Write("\r\n", 2);
if (0 == m_stCRC.length())
{
char szCRC[MAX_PATH + 16 + 1];
GetTimeString(szCRC, time(0));
strcpy(szCRC + strlen(szCRC), c_pszFileName);
m_dwCRC = CPropertyManager::Instance().GetUniqueCRC(szCRC);
_snprintf(szCRC, sizeof(szCRC), "%u", m_dwCRC);
m_stCRC.assign(szCRC);
}
file.Write(m_stCRC.c_str(), m_stCRC.length());
file.Write("\r\n", 2);
CTokenVectorMap::iterator itor = m_stTokenMap.begin();
char buf[4096 + 1];
while (itor != m_stTokenMap.end())
{
CTokenVector & tokenVector = itor->second;
int len = _snprintf(buf, sizeof(buf), "%s\t", itor->first.c_str());
file.Write(buf, len);
for (DWORD i = 0; i < tokenVector.size(); ++i)
{
len = _snprintf(buf, sizeof(buf), "\t\"%s\"", tokenVector[i].c_str());
file.Write(buf, len);
}
file.Write("\r\n", 2);
++itor;
}
file.Close();
return CPropertyManager::Instance().Put(c_pszFileName, file.GetFileName());
}
bool CProperty::ReadFromMemory(const void * c_pvData, int iLen, const char * c_pszFileName)
{
const char * pcData = (const char *) c_pvData;
if (*(DWORD *) pcData != MAKEFOURCC('Y', 'P', 'R', 'T'))
return false;
pcData += sizeof(DWORD);
if (*pcData != '\r' || *(pcData + 1) != '\n')
{
TraceError("CProperty::ReadFromMemory: File format error after FourCC: %s\n", c_pszFileName);
return false;
}
pcData += 2;
CTokenVector stTokenVector;
/*
char szTimeStamp[64];
memcpy(szTimeStamp, pcData, 14);
szTimeStamp[14] = '\0';
pcData += 14;
if (*pcData != '\r' || *(pcData + 1) != '\n')
{
TraceError("CProperty::ReadFromMemory: File format error after TimeStamp: %s\n", c_pszFileName);
return false;
}
std::string m_stTimeStamp;
m_stTimeStamp = szTimeStamp;
int iTimeStampLen = 14 + _snprintf(szTimeStamp + 14, 64 - 14, "%s", mc_pFileName);
m_dwCRC = GetCRC32(szTimeStamp, iTimeStampLen);
char tmp[64];
sprintf(tmp, "%u", m_dwCRC);
m_stCRC.assign(tmp);
CMemoryTextFileLoader textFileLoader;
textFileLoader.Bind(iLen - (sizeof(DWORD) + 2 + 14 + 2), pcData);
for (DWORD i = 0; i < textFileLoader.GetLineCount(); ++i)
{
if (!textFileLoader.SplitLine(i, &stTokenVector))
continue;
stl_lowers(stTokenVector[0]);
std::string stKey = stTokenVector[0];
stTokenVector.erase(stTokenVector.begin());
PutVector(stKey.c_str(), stTokenVector);
}
return true;
*/
CMemoryTextFileLoader textFileLoader;
textFileLoader.Bind(iLen - (sizeof(DWORD) + 2), pcData);
m_stCRC = textFileLoader.GetLineString(0);
m_dwCRC = atoi(m_stCRC.c_str());
for (DWORD i = 1; i < textFileLoader.GetLineCount(); ++i)
{
if (!textFileLoader.SplitLine(i, &stTokenVector))
continue;
stl_lowers(stTokenVector[0]);
std::string stKey = stTokenVector[0];
stTokenVector.erase(stTokenVector.begin());
PutVector(stKey.c_str(), stTokenVector);
}
//Tracef("Property: %s\n", c_pszFileName);
return true;
}
void CProperty::Clear()
{
m_stTokenMap.clear();
}
+34
View File
@@ -0,0 +1,34 @@
#pragma once
#include <string>
class CProperty
{
public:
CProperty(const char * c_pszFileName);
~CProperty();
void Clear();
bool ReadFromMemory(const void * c_pvData, int iLen, const char * c_pszFileName);
const char * GetFileName();
bool GetVector(const char * c_pszKey, CTokenVector & rTokenVector);
bool GetString(const char * c_pszKey, const char ** c_ppString);
void PutVector(const char * c_pszKey, const CTokenVector & c_rTokenVector);
void PutString(const char * c_pszKey, const char * c_pszString);
bool Save(const char * c_pszFileName);
DWORD GetSize();
DWORD GetCRC();
protected:
std::string m_stFileName;
std::string m_stCRC;
const char * mc_pFileName;
DWORD m_dwCRC;
CTokenVectorMap m_stTokenMap;
};
@@ -0,0 +1,68 @@
#include "StdAfx.h"
#include "PropertyLoader.h"
#include "PropertyManager.h"
#include "Property.h"
bool CPropertyLoader::OnFolder(const char* c_szFilter, const char* c_szPathName, const char* c_szFileName)
{
std::string stPathName = "";
stPathName += c_szPathName;
stPathName += c_szFileName;
CPropertyLoader PropertyLoader;
PropertyLoader.SetPropertyManager(m_pPropertyManager);
PropertyLoader.Create(c_szFilter, stPathName.c_str());
return true;
}
bool CPropertyLoader::OnFile(const char* c_szPathName, const char* c_szFileName)
{
RegisterFile(c_szPathName, c_szFileName);
return true;
}
DWORD CPropertyLoader::RegisterFile(const char * c_szPathName, const char * c_szFileName)
{
std::string strFileName = "";
strFileName += c_szPathName;
strFileName += c_szFileName;
std::string stExt;
GetFileExtension(strFileName.c_str(), strFileName.length(), &stExt);
stl_lowers(stExt);
stl_lowers(strFileName);
// 패스를 소문자로 만들고 \\ 는 / 로 바꾼다.
StringPath(strFileName);
// 예약된 CRC 처리 (지워진 CRC)
if (0 == strFileName.compare("property/reserve"))
{
m_pPropertyManager->LoadReservedCRC(strFileName.c_str());
return 1;
}
else
{
CProperty * pProperty;
if (m_pPropertyManager->Register(strFileName.c_str(), &pProperty))
return pProperty->GetCRC();
else
return 0;
}
}
void CPropertyLoader::SetPropertyManager(CPropertyManager * pPropertyManager)
{
m_pPropertyManager = pPropertyManager;
}
CPropertyLoader::CPropertyLoader()
{
m_pPropertyManager = NULL;
}
CPropertyLoader::~CPropertyLoader()
{
}
@@ -0,0 +1,21 @@
#pragma once
#include "../EterBase/FileDir.h"
class CPropertyManager;
class CPropertyLoader : public CDir
{
public:
CPropertyLoader();
virtual ~CPropertyLoader();
void SetPropertyManager(CPropertyManager * pPropertyManager);
DWORD RegisterFile(const char* c_szPathName, const char* c_szFileName);
virtual bool OnFolder(const char* c_szFilter, const char* c_szPathName, const char* c_szFileName);
virtual bool OnFile(const char* c_szPathName, const char* c_szFileName);
protected:
CPropertyManager * m_pPropertyManager;
};
@@ -0,0 +1,255 @@
#include "StdAfx.h"
#include "../EterPack/EterPackManager.h"
#include "PropertyManager.h"
#include "Property.h"
CPropertyManager::CPropertyManager() : m_isFileMode(true)
{
}
CPropertyManager::~CPropertyManager()
{
Clear();
}
bool CPropertyManager::Initialize(const char * c_pszPackFileName)
{
if (c_pszPackFileName)
{
if (!m_pack.Create(m_fileDict, c_pszPackFileName, "", true))
{
LogBoxf("Cannot open property pack file (filename %s)", c_pszPackFileName);
return false;
}
m_isFileMode = false;
TDataPositionMap & indexMap = m_pack.GetIndexMap();
TDataPositionMap::iterator itor = indexMap.begin();
typedef std::map<DWORD, TEterPackIndex *> TDataPositionMap;
int i = 0;
while (indexMap.end() != itor)
{
TEterPackIndex * pIndex = itor->second;
++itor;
if (!stricmp("property/reserve", pIndex->filename))
{
LoadReservedCRC(pIndex->filename);
continue;
}
if (!Register(pIndex->filename))
continue;
++i;
}
}
else
{
m_isFileMode = true;
// NOTE : 여기서 Property를 등록시키면 WorldEditor에서 이상이 생김 ;
// 또한, Property Tree List에도 등록을 시켜야 되기 때문에 바깥쪽에서.. - [levites]
}
return true;
}
bool CPropertyManager::BuildPack()
{
if (!m_pack.Create(m_fileDict, "property", ""))
return false;
WIN32_FIND_DATA fdata;
HANDLE hFind = FindFirstFile("property\\*", &fdata);
if (hFind == INVALID_HANDLE_VALUE)
return false;
do
{
if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
continue;
char szSourceFileName[256 + 1];
_snprintf(szSourceFileName, sizeof(szSourceFileName), "property\\%s", fdata.cFileName);
m_pack.Put(fdata.cFileName, szSourceFileName,COMPRESSED_TYPE_NONE,"");
}
while (FindNextFile(hFind, &fdata));
FindClose(hFind);
return true;
}
bool CPropertyManager::LoadReservedCRC(const char * c_pszFileName)
{
CMappedFile file;
LPCVOID c_pvData;
if (!CEterPackManager::Instance().Get(file, c_pszFileName, &c_pvData))
return false;
CMemoryTextFileLoader textFileLoader;
textFileLoader.Bind(file.Size(), c_pvData);
for (DWORD i = 0; i < textFileLoader.GetLineCount(); ++i)
{
const char * pszLine = textFileLoader.GetLineString(i).c_str();
if (!pszLine || !*pszLine)
continue;
ReserveCRC(atoi(pszLine));
}
return true;
}
void CPropertyManager::ReserveCRC(DWORD dwCRC)
{
m_ReservedCRCSet.insert(dwCRC);
}
DWORD CPropertyManager::GetUniqueCRC(const char * c_szSeed)
{
std::string stTmp = c_szSeed;
while (1)
{
DWORD dwCRC = GetCRC32(stTmp.c_str(), stTmp.length());
if (m_ReservedCRCSet.find(dwCRC) == m_ReservedCRCSet.end() &&
m_PropertyByCRCMap.find(dwCRC) == m_PropertyByCRCMap.end())
return dwCRC;
char szAdd[2];
_snprintf(szAdd, sizeof(szAdd), "%d", random() % 10);
stTmp += szAdd;
}
}
bool CPropertyManager::Register(const char * c_pszFileName, CProperty ** ppProperty)
{
CMappedFile file;
LPCVOID c_pvData;
if (!CEterPackManager::Instance().Get(file, c_pszFileName, &c_pvData))
return false;
CProperty * pProperty = new CProperty(c_pszFileName);
if (!pProperty->ReadFromMemory(c_pvData, file.Size(), c_pszFileName))
{
delete pProperty;
return false;
}
DWORD dwCRC = pProperty->GetCRC();
TPropertyCRCMap::iterator itor = m_PropertyByCRCMap.find(dwCRC);
if (m_PropertyByCRCMap.end() != itor)
{
Tracef("Property already registered, replace %s to %s\n",
itor->second->GetFileName(),
c_pszFileName);
delete itor->second;
itor->second = pProperty;
}
else
m_PropertyByCRCMap.insert(TPropertyCRCMap::value_type(dwCRC, pProperty));
if (ppProperty)
*ppProperty = pProperty;
return true;
}
bool CPropertyManager::Get(const char * c_pszFileName, CProperty ** ppProperty)
{
return Register(c_pszFileName, ppProperty);
}
bool CPropertyManager::Get(DWORD dwCRC, CProperty ** ppProperty)
{
TPropertyCRCMap::iterator itor = m_PropertyByCRCMap.find(dwCRC);
if (m_PropertyByCRCMap.end() == itor)
return false;
*ppProperty = itor->second;
return true;
}
bool CPropertyManager::Put(const char * c_pszFileName, const char * c_pszSourceFileName)
{
if (!CopyFile(c_pszSourceFileName, c_pszFileName, FALSE))
return false;
if (!m_isFileMode) // 팩 파일에도 넣음
{
if (!m_pack.Put(c_pszFileName, NULL, COMPRESSED_TYPE_NONE,""))
{
assert(!"CPropertyManager::Put cannot write to pack file");
return false;
}
}
Register(c_pszFileName);
return true;
}
bool CPropertyManager::Erase(DWORD dwCRC)
{
TPropertyCRCMap::iterator itor = m_PropertyByCRCMap.find(dwCRC);
if (m_PropertyByCRCMap.end() == itor)
return false;
CProperty * pProperty = itor->second;
m_PropertyByCRCMap.erase(itor);
DeleteFile(pProperty->GetFileName());
ReserveCRC(pProperty->GetCRC());
if (!m_isFileMode) // 파일 모드가 아니면 팩에서도 지움
m_pack.Delete(pProperty->GetFileName());
FILE * fp = fopen("property/reserve", "a+");
if (!fp)
LogBox("\277\271\276\340 CRC \306\304\300\317\300\273 \277\255 \274\366 \276\370\275\300\264\317\264\331.");
else
{
char szCRC[64 + 1];
_snprintf(szCRC, sizeof(szCRC), "%u\r\n", pProperty->GetCRC());
fputs(szCRC, fp);
fclose(fp);
}
delete pProperty;
return true;
}
bool CPropertyManager::Erase(const char * c_pszFileName)
{
CProperty * pProperty = NULL;
if (Get(c_pszFileName, &pProperty))
return Erase(pProperty->GetCRC());
return false;
}
void CPropertyManager::Clear()
{
stl_wipe_second(m_PropertyByCRCMap);
}
@@ -0,0 +1,353 @@
#include "StdAfx.h"
#include "SnowEnvironment.h"
#include "../EterLib/StateManager.h"
#include "../EterLib/Camera.h"
#include "../EterLib/ResourceManager.h"
#include "SnowParticle.h"
void CSnowEnvironment::Enable()
{
if (!m_bSnowEnable)
{
Create();
}
m_bSnowEnable = TRUE;
}
void CSnowEnvironment::Disable()
{
m_bSnowEnable = FALSE;
}
void CSnowEnvironment::Update(const D3DXVECTOR3 & c_rv3Pos)
{
if (!m_bSnowEnable)
{
if (m_kVct_pkParticleSnow.empty())
return;
}
m_v3Center=c_rv3Pos;
}
void CSnowEnvironment::Deform()
{
if (!m_bSnowEnable)
{
if (m_kVct_pkParticleSnow.empty())
return;
}
const D3DXVECTOR3 & c_rv3Pos=m_v3Center;
static long s_lLastTime = CTimer::Instance().GetCurrentMillisecond();
long lcurTime = CTimer::Instance().GetCurrentMillisecond();
float fElapsedTime = float(lcurTime - s_lLastTime) / 1000.0f;
s_lLastTime = lcurTime;
CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera();
if (!pCamera)
return;
const D3DXVECTOR3 & c_rv3View = pCamera->GetView();
D3DXVECTOR3 v3ChangedPos = c_rv3View * 3500.0f + c_rv3Pos;
v3ChangedPos.z = c_rv3Pos.z;
std::vector<CSnowParticle*>::iterator itor = m_kVct_pkParticleSnow.begin();
for (; itor != m_kVct_pkParticleSnow.end();)
{
CSnowParticle * pSnow = *itor;
pSnow->Update(fElapsedTime, v3ChangedPos);
if (!pSnow->IsActivate())
{
CSnowParticle::Delete(pSnow);
itor = m_kVct_pkParticleSnow.erase(itor);
}
else
{
++itor;
}
}
if (m_bSnowEnable)
{
for (int p = 0; p < min(10, m_dwParticleMaxNum - m_kVct_pkParticleSnow.size()); ++p)
{
CSnowParticle * pSnowParticle = CSnowParticle::New();
pSnowParticle->Init(v3ChangedPos);
m_kVct_pkParticleSnow.push_back(pSnowParticle);
}
}
}
void CSnowEnvironment::__BeginBlur()
{
if (!m_bBlurEnable)
return;
ms_lpd3dDevice->GetRenderTarget(&m_lpOldSurface);
ms_lpd3dDevice->GetDepthStencilSurface(&m_lpOldDepthStencilSurface);
ms_lpd3dDevice->SetRenderTarget(m_lpSnowRenderTargetSurface, m_lpSnowDepthSurface);
ms_lpd3dDevice->Clear(0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0L);
STATEMANAGER.SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
STATEMANAGER.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
STATEMANAGER.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_DESTALPHA);
}
void CSnowEnvironment::__ApplyBlur()
{
if (!m_bBlurEnable)
return;
// {
// STATEMANAGER.SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
// STATEMANAGER.SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
// STATEMANAGER.SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
// STATEMANAGER.SetRenderState( D3DRS_COLORVERTEX ,TRUE);
// STATEMANAGER.SetRenderState( D3DRS_DIFFUSEMATERIALSOURCE , D3DMCS_COLOR1 );
// STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
// STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
// STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
// STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
// STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
// STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
// DWORD alphaColor = 0xFFFFFF | ((DWORD)(0.6f*255.0f) << 24);
//
// BlurVertex V[4] = { BlurVertex(D3DXVECTOR3(0.0f,0.0f,0.0f),1.0f, alphaColor, 0,0) ,
// BlurVertex(D3DXVECTOR3(wTextureSize,0.0f,0.0f),1.0f, alphaColor, 1,0) ,
// BlurVertex(D3DXVECTOR3(0.0f,wTextureSize,0.0f),1.0f, alphaColor, 0,1) ,
// BlurVertex(D3DXVECTOR3(wTextureSize,wTextureSize,0.0f),1.0f, alphaColor, 1,1) };
// //누적 블러 텍스쳐를 찍는다.
// STATEMANAGER.SetTexture(0,m_lpAccumTexture);
// STATEMANAGER.SetVertexShader( D3DFVF_XYZRHW | D3DFVF_DIFFUSE|D3DFVF_TEX1 );
// STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,2,V,sizeof(BlurVertex));
// }
//
// {
// STATEMANAGER.SetRenderTarget(m_lpAccumRenderTargetSurface, m_lpAccumDepthSurface);
//
// BlurVertex V[4] = { BlurVertex(D3DXVECTOR3(0.0f,0.0f,0.0f),1.0f, 0xFFFFFF, 0,0) ,
// BlurVertex(D3DXVECTOR3(wTextureSize,0.0f,0.0f),1.0f, 0xFFFFFF, 1,0) ,
// BlurVertex(D3DXVECTOR3(0.0f,wTextureSize,0.0f),1.0f, 0xFFFFFF, 0,1) ,
// BlurVertex(D3DXVECTOR3(wTextureSize,wTextureSize,0.0f),1.0f, 0xFFFFFF, 1,1) };
//
// STATEMANAGER.SetTexture(0,m_lpSnowTexture);
// STATEMANAGER.SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE);
// STATEMANAGER.SetVertexShader( D3DFVF_XYZRHW | D3DFVF_DIFFUSE|D3DFVF_TEX1 );
// STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,2,V,sizeof(BlurVertex));
// }
///////////////
{
ms_lpd3dDevice->SetRenderTarget(m_lpOldSurface, m_lpOldDepthStencilSurface);
STATEMANAGER.SetTexture(0,m_lpSnowTexture);
STATEMANAGER.SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE);
D3DSURFACE_DESC desc;
m_lpOldSurface->GetDesc(&desc);
float sx = (float)desc.Width ;
float sy = (float)desc.Height;
SAFE_RELEASE( m_lpOldSurface );
SAFE_RELEASE( m_lpOldDepthStencilSurface );
BlurVertex V[4] = { BlurVertex(D3DXVECTOR3(0.0f,0.0f,0.0f),1.0f ,0xFFFFFF, 0,0) ,
BlurVertex(D3DXVECTOR3(sx,0.0f,0.0f),1.0f ,0xFFFFFF, 1,0) ,
BlurVertex(D3DXVECTOR3(0.0f,sy,0.0f),1.0f ,0xFFFFFF, 0,1) ,
BlurVertex(D3DXVECTOR3(sx,sy,0.0f),1.0f ,0xFFFFFF, 1,1) };
STATEMANAGER.SetVertexShader( D3DFVF_XYZRHW | D3DFVF_DIFFUSE|D3DFVF_TEX1 );
STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,2,V,sizeof(BlurVertex));
}
}
void CSnowEnvironment::Render()
{
if (!m_bSnowEnable)
{
if (m_kVct_pkParticleSnow.empty())
return;
}
__BeginBlur();
DWORD dwParticleCount = min(m_dwParticleMaxNum, m_kVct_pkParticleSnow.size());
CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera();
if (!pCamera)
return;
const D3DXVECTOR3 & c_rv3Up = pCamera->GetUp();
const D3DXVECTOR3 & c_rv3Cross = pCamera->GetCross();
SParticleVertex * pv3Verticies;
if (SUCCEEDED(m_pVB->Lock(0, sizeof(SParticleVertex)*dwParticleCount*4, (BYTE **) &pv3Verticies, D3DLOCK_DISCARD)))
{
int i = 0;
std::vector<CSnowParticle*>::iterator itor = m_kVct_pkParticleSnow.begin();
for (; i < dwParticleCount && itor != m_kVct_pkParticleSnow.end(); ++i, ++itor)
{
CSnowParticle * pSnow = *itor;
pSnow->SetCameraVertex(c_rv3Up, c_rv3Cross);
pSnow->GetVerticies(pv3Verticies[i*4+0],
pv3Verticies[i*4+1],
pv3Verticies[i*4+2],
pv3Verticies[i*4+3]);
}
m_pVB->Unlock();
}
STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE, FALSE);
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
STATEMANAGER.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
STATEMANAGER.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
STATEMANAGER.SetTexture(1, NULL);
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
m_pImageInstance->GetGraphicImagePointer()->GetTextureReference().SetTextureStage(0);
STATEMANAGER.SetIndices(m_pIB, 0);
STATEMANAGER.SetStreamSource(0, m_pVB, sizeof(SParticleVertex));
STATEMANAGER.SetVertexShader(D3DFVF_XYZ | D3DFVF_TEX1);
STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, dwParticleCount*4, 0, dwParticleCount*2);
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE);
STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE);
__ApplyBlur();
}
bool CSnowEnvironment::__CreateBlurTexture()
{
if (!m_bBlurEnable)
return true;
if (FAILED(ms_lpd3dDevice->CreateTexture(m_wBlurTextureSize, m_wBlurTextureSize, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &m_lpSnowTexture)))
return false;
if (FAILED(m_lpSnowTexture->GetSurfaceLevel(0, &m_lpSnowRenderTargetSurface)))
return false;
if (FAILED(ms_lpd3dDevice->CreateDepthStencilSurface(m_wBlurTextureSize, m_wBlurTextureSize, D3DFMT_D16, D3DMULTISAMPLE_NONE, &m_lpSnowDepthSurface)))
return false;
if (FAILED(ms_lpd3dDevice->CreateTexture(m_wBlurTextureSize, m_wBlurTextureSize, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &m_lpAccumTexture)))
return false;
if (FAILED(m_lpAccumTexture->GetSurfaceLevel(0, &m_lpAccumRenderTargetSurface)))
return false;
if (FAILED(ms_lpd3dDevice->CreateDepthStencilSurface(m_wBlurTextureSize, m_wBlurTextureSize, D3DFMT_D16, D3DMULTISAMPLE_NONE, &m_lpAccumDepthSurface)))
return false;
return true;
}
bool CSnowEnvironment::__CreateGeometry()
{
if (FAILED(ms_lpd3dDevice->CreateVertexBuffer(sizeof(SParticleVertex)*m_dwParticleMaxNum*4,
D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY,
D3DFVF_XYZ | D3DFVF_TEX1,
D3DPOOL_SYSTEMMEM,
&m_pVB)))
return false;
if (FAILED(ms_lpd3dDevice->CreateIndexBuffer(sizeof(WORD)*m_dwParticleMaxNum*6,
D3DUSAGE_WRITEONLY,
D3DFMT_INDEX16,
D3DPOOL_MANAGED,
&m_pIB)))
return false;
WORD* dstIndices;
if (FAILED(m_pIB->Lock(0, sizeof(WORD)*m_dwParticleMaxNum*6, (BYTE**)&dstIndices, 0)))
return false;
const WORD c_awFillRectIndices[6] = { 0, 2, 1, 2, 3, 1, };
for (int i = 0; i < m_dwParticleMaxNum; ++i)
{
for (int j = 0; j < 6; ++j)
{
dstIndices[i*6 + j] = i*4 + c_awFillRectIndices[j];
}
}
m_pIB->Unlock();
return true;
}
bool CSnowEnvironment::Create()
{
Destroy();
if (!__CreateBlurTexture())
return false;
if (!__CreateGeometry())
return false;
CGraphicImage * pImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer("d:/ymir work/special/snow.dds");
m_pImageInstance = CGraphicImageInstance::New();
m_pImageInstance->SetImagePointer(pImage);
return true;
}
void CSnowEnvironment::Destroy()
{
SAFE_RELEASE(m_lpSnowTexture);
SAFE_RELEASE(m_lpSnowRenderTargetSurface);
SAFE_RELEASE(m_lpSnowDepthSurface);
SAFE_RELEASE(m_lpAccumTexture);
SAFE_RELEASE(m_lpAccumRenderTargetSurface);
SAFE_RELEASE(m_lpAccumDepthSurface);
SAFE_RELEASE(m_pVB);
SAFE_RELEASE(m_pIB);
stl_wipe(m_kVct_pkParticleSnow);
CSnowParticle::DestroyPool();
if (m_pImageInstance)
{
CGraphicImageInstance::Delete(m_pImageInstance);
m_pImageInstance = NULL;
}
__Initialize();
}
void CSnowEnvironment::__Initialize()
{
m_bSnowEnable = FALSE;
m_lpSnowTexture = NULL;
m_lpSnowRenderTargetSurface = NULL;
m_lpSnowDepthSurface = NULL;
m_lpAccumTexture = NULL;
m_lpAccumRenderTargetSurface = NULL;
m_lpAccumDepthSurface = NULL;
m_pVB = NULL;
m_pIB = NULL;
m_pImageInstance = NULL;
m_kVct_pkParticleSnow.reserve(m_dwParticleMaxNum);
}
CSnowEnvironment::CSnowEnvironment()
{
m_bBlurEnable = FALSE;
m_dwParticleMaxNum = 3000;
m_wBlurTextureSize = 512;
__Initialize();
}
CSnowEnvironment::~CSnowEnvironment()
{
Destroy();
}
+103
View File
@@ -0,0 +1,103 @@
#include "StdAfx.h"
#include "SnowParticle.h"
const float c_fSnowDistance = 70000.0f;
std::vector<CSnowParticle*> CSnowParticle::ms_kVct_SnowParticlePool;
void CSnowParticle::SetCameraVertex(const D3DXVECTOR3 & rv3Up, const D3DXVECTOR3 & rv3Cross)
{
m_v3Up = rv3Up*m_fHalfWidth;
m_v3Cross = rv3Cross*m_fHalfHeight;
}
bool CSnowParticle::IsActivate()
{
return m_bActivate;
}
void CSnowParticle::Update(float fElapsedTime, const D3DXVECTOR3 & c_rv3Pos)
{
m_v3Position += m_v3Velocity * fElapsedTime;
m_v3Position.x += m_v3Cross.x * sin(m_fcurRadian) / 10.0f;
m_v3Position.y += m_v3Cross.y * sin(m_fcurRadian) / 10.0f;
m_fcurRadian += m_fPeriod * fElapsedTime;
if (m_v3Position.z < c_rv3Pos.z - 500.0f)
m_bActivate = false;
else if (abs(m_v3Position.x - c_rv3Pos.x) > c_fSnowDistance)
m_bActivate = false;
else if (abs(m_v3Position.y - c_rv3Pos.y) > c_fSnowDistance)
m_bActivate = false;
}
void CSnowParticle::GetVerticies(SParticleVertex & rv3Vertex1, SParticleVertex & rv3Vertex2,
SParticleVertex & rv3Vertex3, SParticleVertex & rv3Vertex4)
{
rv3Vertex1.v3Pos = m_v3Position - m_v3Cross - m_v3Up;
rv3Vertex1.u = 0.0f;
rv3Vertex1.v = 0.0f;
rv3Vertex2.v3Pos = m_v3Position + m_v3Cross - m_v3Up;
rv3Vertex2.u = 1.0f;
rv3Vertex2.v = 0.0f;
rv3Vertex3.v3Pos = m_v3Position - m_v3Cross + m_v3Up;
rv3Vertex3.u = 0.0f;
rv3Vertex3.v = 1.0f;
rv3Vertex4.v3Pos = m_v3Position + m_v3Cross + m_v3Up;
rv3Vertex4.u = 1.0f;
rv3Vertex4.v = 1.0f;
}
void CSnowParticle::Init(const D3DXVECTOR3 & c_rv3Pos)
{
float fRot = frandom(0.0f, 36000.0f) / 100.0f;
float fDistance = frandom(0.0f, c_fSnowDistance) / 10.0f;
m_v3Position.x = c_rv3Pos.x + fDistance*sin((double)D3DXToRadian(fRot));
m_v3Position.y = c_rv3Pos.y + fDistance*cos((double)D3DXToRadian(fRot));
m_v3Position.z = c_rv3Pos.z + frandom(1500.0f, 2000.0f);
m_v3Velocity.x = 0.0f;
m_v3Velocity.y = 0.0f;
m_v3Velocity.z = frandom(-50.0f, -200.0f);
m_fHalfWidth = frandom(2.0f, 7.0f);
m_fHalfHeight = m_fHalfWidth;
m_bActivate = true;
m_bChangedSize = false;
m_fPeriod = frandom(1.5f, 5.0f);
m_fcurRadian = frandom(-1.6f, 1.6f);
m_fAmplitude = frandom(1.0f, 3.0f);
}
CSnowParticle * CSnowParticle::New()
{
if (ms_kVct_SnowParticlePool.empty())
{
return new CSnowParticle;
}
CSnowParticle * pParticle = ms_kVct_SnowParticlePool.back();
ms_kVct_SnowParticlePool.pop_back();
return pParticle;
}
void CSnowParticle::Delete(CSnowParticle * pSnowParticle)
{
ms_kVct_SnowParticlePool.push_back(pSnowParticle);
}
void CSnowParticle::DestroyPool()
{
stl_wipe(ms_kVct_SnowParticlePool);
}
CSnowParticle::CSnowParticle()
{
}
CSnowParticle::~CSnowParticle()
{
}
+59
View File
@@ -0,0 +1,59 @@
#pragma once
struct SParticleVertex
{
D3DXVECTOR3 v3Pos;
float u, v;
};
struct BlurVertex
{
D3DXVECTOR3 pos;
FLOAT rhw;
DWORD color;
FLOAT tu, tv;
static const DWORD FVF;
BlurVertex(D3DXVECTOR3 p, float w,DWORD c,float u,float v):pos(p),rhw(w),color(c),tu(u),tv(v) {}
~BlurVertex(){};
};
class CSnowParticle
{
public:
CSnowParticle();
~CSnowParticle();
static CSnowParticle * New();
static void Delete(CSnowParticle * pSnowParticle);
static void DestroyPool();
void Init(const D3DXVECTOR3 & c_rv3Pos);
void SetCameraVertex(const D3DXVECTOR3 & rv3Up, const D3DXVECTOR3 & rv3Cross);
bool IsActivate();
void Update(float fElapsedTime, const D3DXVECTOR3 & c_rv3Pos);
void GetVerticies(SParticleVertex & rv3Vertex1, SParticleVertex & rv3Vertex2,
SParticleVertex & rv3Vertex3, SParticleVertex & rv3Vertex4);
protected:
bool m_bActivate;
bool m_bChangedSize;
float m_fHalfWidth;
float m_fHalfHeight;
D3DXVECTOR3 m_v3Velocity;
D3DXVECTOR3 m_v3Position;
D3DXVECTOR3 m_v3Up;
D3DXVECTOR3 m_v3Cross;
float m_fPeriod;
float m_fcurRadian;
float m_fAmplitude;
public:
static std::vector<CSnowParticle*> ms_kVct_SnowParticlePool;
};
+180
View File
@@ -0,0 +1,180 @@
// TerrainDecal.cpp: implementation of the CTerrainDecal class.
//
//////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "../EterLib/StateManager.h"
#include "../PRTerrainLib/StdAfx.h"
#include "TerrainDecal.h"
#include "MapOutdoor.h"
#include "AreaTerrain.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CTerrainDecal::CTerrainDecal(CMapOutdoor * pMapOutdoor):m_pMapOutdoor(pMapOutdoor)
{
}
CTerrainDecal::~CTerrainDecal()
{
CDecal::Clear();
}
void CTerrainDecal::Make(D3DXVECTOR3 v3Center, D3DXVECTOR3 v3Normal, D3DXVECTOR3 v3Tangent, float fWidth, float fHeight, float fDepth)
{
Clear();
m_v3Center = v3Center;
m_v3Normal = v3Normal;
D3DXVECTOR3 v3Binormal;
D3DXVec3Normalize(&v3Normal, &v3Normal);
D3DXVec3Normalize(&v3Tangent, &v3Tangent);
D3DXVec3Cross(&v3Binormal, &m_v3Normal, &v3Tangent);
D3DXVec3Normalize(&v3Binormal, &v3Binormal);
// Calculate boundary planes
float fd = D3DXVec3Dot(&m_v3Center, &v3Tangent);
m_v4LeftPlane = D3DXPLANE(v3Tangent.x, v3Tangent.y, v3Tangent.z, fWidth * 0.5f - fd);
m_v4RightPlane = D3DXPLANE(-v3Tangent.x, -v3Tangent.y, -v3Tangent.z, fWidth * 0.5f + fd);
fd = D3DXVec3Dot(&m_v3Center, &v3Binormal);
m_v4BottomPlane = D3DXPLANE(v3Binormal.x, v3Binormal.y, v3Binormal.z, fHeight * 0.5f - fd);
m_v4TopPlane = D3DXPLANE(-v3Binormal.x, -v3Binormal.y, -v3Binormal.z, fHeight * 0.5f + fd);
fd = D3DXVec3Dot(&m_v3Center, &m_v3Normal);
m_v4FrontPlane = D3DXPLANE(-m_v3Normal.x, -m_v3Normal.y, -m_v3Normal.z, fDepth + fd);
m_v4BackPlane = D3DXPLANE(m_v3Normal.x, m_v3Normal.y, m_v3Normal.z, fDepth - fd);
// Begin with empty mesh
m_dwVertexCount = 0;
m_dwPrimitiveCount = 0;
// Add this point, determine which surfaces may be affected by this decal and call ClipMesh().
float fSearchRadius = fMAX(fWidth, fHeight);// 0.75f >= sqrtf(2)/2;
float fMinX = v3Center.x - fSearchRadius;
float fMaxX = v3Center.x + fSearchRadius;
float fMinY = fabs(v3Center.y) - fSearchRadius;
float fMaxY = fabs(v3Center.y) + fSearchRadius;
DWORD dwAffectedPrimitiveCount = 0;
D3DXVECTOR3 v3AffectedVertex[MAX_SEARCH_VERTICES];
D3DXVECTOR3 v3AffectedNormal[MAX_SEARCH_VERTICES];
memset(v3AffectedVertex, 0, sizeof(v3AffectedVertex));
memset(v3AffectedNormal, 0, sizeof(v3AffectedNormal));
SearchAffectedTerrainMesh(fMinX, fMaxX, fMinY, fMaxY, &dwAffectedPrimitiveCount, v3AffectedVertex, v3AffectedNormal);
ClipMesh(dwAffectedPrimitiveCount, v3AffectedVertex, v3AffectedNormal);
// Assign texture mapping coordinates
float fOne_over_w = 1.0f / fWidth;
float fOne_over_h = 1.0f / fHeight;
for (DWORD dwi = 0; dwi < m_dwVertexCount; ++dwi)
{
D3DXVECTOR3 v3 = m_Vertices[dwi].position - m_v3Center;
float fu = -D3DXVec3Dot(&v3, &v3Binormal) * fOne_over_w + 0.5f;
float fv = -D3DXVec3Dot(&v3, &v3Tangent) * fOne_over_h + 0.5f;
m_Vertices[dwi].texCoord = D3DXVECTOR2(fu, fv);
}
}
/*
void CTerrainDecal::Update()
{
}
*/
void CTerrainDecal::Render()
{
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
CDecal::Render();
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXCOORDINDEX);
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS);
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ADDRESSU);
STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ADDRESSV);
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
}
void CTerrainDecal::SearchAffectedTerrainMesh(float fMinX,
float fMaxX,
float fMinY,
float fMaxY,
DWORD * pdwAffectedPrimitiveCount,
D3DXVECTOR3 * pv3AffectedVertex,
D3DXVECTOR3 * pv3AffectedNormal)
{
if (!m_pMapOutdoor)
return;
int iMinX, iMaxX, iMinY, iMaxY;
PR_FLOAT_TO_INT(fMinX, iMinX);
PR_FLOAT_TO_INT(fMaxX, iMaxX);
PR_FLOAT_TO_INT(fMinY, iMinY);
PR_FLOAT_TO_INT(fMaxY, iMaxY);
iMinX -= iMinX % CTerrainImpl::CELLSCALE;
iMaxX -= iMaxX % CTerrainImpl::CELLSCALE;
iMinY -= iMinY % CTerrainImpl::CELLSCALE;
iMaxY -= iMaxY % CTerrainImpl::CELLSCALE;
for(int iy = iMinY; iy <= iMaxY; iy += CTerrainImpl::CELLSCALE)
{
if (iy < 0)
continue;
WORD wTerrainNumY = iy / CTerrainImpl::TERRAIN_YSIZE;
for(int ix = iMinX; ix <= iMaxX; ix += CTerrainImpl::CELLSCALE)
{
if (ix < 0)
continue;
WORD wTerrainNumX = ix / CTerrainImpl::TERRAIN_YSIZE;
BYTE byTerrainNum;
if (!m_pMapOutdoor->GetTerrainNumFromCoord(wTerrainNumX, wTerrainNumY, &byTerrainNum))
continue;
CTerrain * pTerrain;
if (!m_pMapOutdoor->GetTerrainPointer(byTerrainNum, &pTerrain))
continue;
float fHeightLT = pTerrain->GetHeight(ix, iy) + m_cfDecalEpsilon;
float fHeightRT = pTerrain->GetHeight(ix + CTerrainImpl::CELLSCALE, iy) + m_cfDecalEpsilon;
float fHeightLB = pTerrain->GetHeight(ix, iy + CTerrainImpl::CELLSCALE) + m_cfDecalEpsilon;
float fHeightRB = pTerrain->GetHeight(ix + CTerrainImpl::CELLSCALE, iy + CTerrainImpl::CELLSCALE) + m_cfDecalEpsilon;
*pdwAffectedPrimitiveCount += 2;
*pv3AffectedVertex++ = D3DXVECTOR3((float)ix, (float)(-iy), fHeightLT);
*pv3AffectedVertex++ = D3DXVECTOR3((float)ix, (float)(-iy - CTerrainImpl::CELLSCALE), fHeightLB);
*pv3AffectedVertex++ = D3DXVECTOR3((float)(ix + CTerrainImpl::CELLSCALE), (float)(-iy), fHeightRT);
*pv3AffectedVertex++ = D3DXVECTOR3((float)(ix + CTerrainImpl::CELLSCALE), (float)(-iy), fHeightRT);
*pv3AffectedVertex++ = D3DXVECTOR3((float)ix, (float)(-iy - CTerrainImpl::CELLSCALE), fHeightLB);
*pv3AffectedVertex++ = D3DXVECTOR3((float)(ix + CTerrainImpl::CELLSCALE), (float)(-iy - CTerrainImpl::CELLSCALE), fHeightRB);
*pv3AffectedNormal++ = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
*pv3AffectedNormal++ = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
*pv3AffectedNormal++ = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
*pv3AffectedNormal++ = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
*pv3AffectedNormal++ = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
*pv3AffectedNormal++ = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
}
}
}
+240
View File
@@ -0,0 +1,240 @@
// TerrainPatch.cpp: implementation of the CTerrainPatch class.
//
//////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "TerrainPatch.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CTerrainPatch::SSoftwareTransformPatch::SSoftwareTransformPatch()
{
__Initialize();
}
CTerrainPatch::SSoftwareTransformPatch::~SSoftwareTransformPatch()
{
Destroy();
}
void CTerrainPatch::SSoftwareTransformPatch::Create()
{
assert(NULL==m_akTerrainVertex);
m_akTerrainVertex=new SoftwareTransformPatch_SSourceVertex[TERRAIN_VERTEX_COUNT];
}
void CTerrainPatch::SSoftwareTransformPatch::Destroy()
{
if (m_akTerrainVertex)
delete [] m_akTerrainVertex;
__Initialize();
}
void CTerrainPatch::SSoftwareTransformPatch::__Initialize()
{
m_akTerrainVertex=NULL;
}
bool CTerrainPatch::SOFTWARE_TRANSFORM_PATCH_ENABLE=TRUE;
void CTerrainPatch::Clear()
{
m_kHT.m_kVB.Destroy();
m_kST.Destroy();
m_WaterVertexBuffer.Destroy();
ClearID();
SetUse(false);
m_bWaterExist = false;
m_bNeedUpdate = true;
m_dwWaterPriCount = 0;
m_byType = PATCH_TYPE_PLAIN;
m_fMinX = m_fMaxX = m_fMinY = m_fMaxY = m_fMinZ = m_fMaxZ = 0.0f;
m_dwVersion=0;
}
void CTerrainPatch::BuildWaterVertexBuffer(SWaterVertex* akSrcVertex, UINT uWaterVertexCount)
{
CGraphicVertexBuffer& rkVB=m_WaterVertexBuffer;
if (!rkVB.Create(uWaterVertexCount, D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DUSAGE_WRITEONLY, D3DPOOL_MANAGED))
return;
SWaterVertex* akDstWaterVertex;
if (rkVB.Lock((void **) &akDstWaterVertex))
{
UINT uVBSize=sizeof(SWaterVertex)*uWaterVertexCount;
memcpy(akDstWaterVertex, akSrcVertex, uVBSize);
m_dwWaterPriCount=uWaterVertexCount/3;
rkVB.Unlock();
}
}
void CTerrainPatch::BuildTerrainVertexBuffer(HardwareTransformPatch_SSourceVertex* akSrcVertex)
{
if (SOFTWARE_TRANSFORM_PATCH_ENABLE)
__BuildSoftwareTerrainVertexBuffer(akSrcVertex);
else
__BuildHardwareTerrainVertexBuffer(akSrcVertex);
}
void CTerrainPatch::__BuildSoftwareTerrainVertexBuffer(HardwareTransformPatch_SSourceVertex* akSrcVertex)
{
//DWORD dwVBSize=sizeof(HardwareTransformPatch_SSourceVertex)*TERRAIN_VERTEX_COUNT;
m_kST.Create();
SoftwareTransformPatch_SSourceVertex* akDstVertex=SoftwareTransformPatch_GetTerrainVertexDataPtr();
for (UINT uIndex=0; uIndex!=TERRAIN_VERTEX_COUNT; ++uIndex)
{
*((HardwareTransformPatch_SSourceVertex*)(akDstVertex+uIndex))=*(akSrcVertex+uIndex);
akDstVertex[uIndex].dwDiffuse=0xFFFFFFFF;
}
}
void CTerrainPatch::__BuildHardwareTerrainVertexBuffer(HardwareTransformPatch_SSourceVertex* akSrcVertex)
{
CGraphicVertexBuffer& rkVB=m_kHT.m_kVB;
if (!rkVB.Create(TERRAIN_VERTEX_COUNT, D3DFVF_XYZ | D3DFVF_NORMAL, D3DUSAGE_WRITEONLY, D3DPOOL_MANAGED))
return;
HardwareTransformPatch_SSourceVertex* akDstVertex;
if (rkVB.Lock((void **) &akDstVertex))
{
UINT uVBSize=sizeof(HardwareTransformPatch_SSourceVertex)*TERRAIN_VERTEX_COUNT;
memcpy(akDstVertex, akSrcVertex, uVBSize);
rkVB.Unlock();
}
}
void CTerrainPatch::SoftwareTransformPatch_UpdateTerrainLighting(DWORD dwVersion, const D3DLIGHT8& c_rkLight, const D3DMATERIAL8& c_rkMtrl)
{
if (m_dwVersion==dwVersion)
return;
m_dwVersion=dwVersion;
SoftwareTransformPatch_SSourceVertex* akSrcVertex=SoftwareTransformPatch_GetTerrainVertexDataPtr();
if (!akSrcVertex)
return;
D3DXVECTOR3 kLightDir=c_rkLight.Direction;
DWORD dwDot;
DWORD dwAmbientR=(c_rkMtrl.Ambient.r*c_rkLight.Ambient.r+c_rkMtrl.Emissive.r)*255.0f;
DWORD dwAmbientG=(c_rkMtrl.Ambient.g*c_rkLight.Ambient.g+c_rkMtrl.Emissive.g)*255.0f;
DWORD dwAmbientB=(c_rkMtrl.Ambient.b*c_rkLight.Ambient.b+c_rkMtrl.Emissive.b)*255.0f;
DWORD dwDiffuseR=(c_rkMtrl.Diffuse.r*c_rkLight.Diffuse.r)*255.0f;
DWORD dwDiffuseG=(c_rkMtrl.Diffuse.g*c_rkLight.Diffuse.g)*255.0f;
DWORD dwDiffuseB=(c_rkMtrl.Diffuse.b*c_rkLight.Diffuse.b)*255.0f;
if (dwDiffuseR>255-dwAmbientR)
dwDiffuseR=255-dwAmbientR;
if (dwDiffuseG+dwAmbientG>255)
dwDiffuseG=255-dwAmbientG;
if (dwDiffuseB+dwAmbientB>255)
dwDiffuseB=255-dwAmbientB;
for (UINT uIndex=0; uIndex!=CTerrainPatch::TERRAIN_VERTEX_COUNT; ++uIndex)
{
float fDot=D3DXVec3Dot(&akSrcVertex[uIndex].kNormal, &kLightDir);
const float N=0xffffff;
const int S=24;
if (fDot<0.0f)
dwDot=(N*-fDot);
else
dwDot=(N*+fDot);
akSrcVertex[uIndex].dwDiffuse=(0xff000000)|
(((dwDiffuseR*dwDot>>S)+dwAmbientR)<<16)|
(((dwDiffuseG*dwDot>>S)+dwAmbientG)<<8)|
((dwDiffuseB*dwDot>>S)+dwAmbientB);
}
}
UINT CTerrainPatch::GetWaterFaceCount()
{
return m_dwWaterPriCount;
}
CTerrainPatchProxy::CTerrainPatchProxy()
{
Clear();
}
CTerrainPatchProxy::~CTerrainPatchProxy()
{
Clear();
}
void CTerrainPatchProxy::SetCenterPosition(const D3DXVECTOR3& c_rv3Center)
{
m_v3Center=c_rv3Center;
}
bool CTerrainPatchProxy::IsIn(const D3DXVECTOR3& c_rv3Target, float fRadius)
{
float dx=m_v3Center.x-c_rv3Target.x;
float dy=m_v3Center.y-c_rv3Target.y;
float fDist=dx*dx+dy*dy;
float fCheck=fRadius*fRadius;
if (fDist<fCheck)
return true;
return false;
}
void CTerrainPatchProxy::SoftwareTransformPatch_UpdateTerrainLighting(DWORD dwVersion, const D3DLIGHT8& c_rkLight, const D3DMATERIAL8& c_rkMtrl)
{
if (m_pTerrainPatch)
m_pTerrainPatch->SoftwareTransformPatch_UpdateTerrainLighting(dwVersion, c_rkLight, c_rkMtrl);
}
CGraphicVertexBuffer* CTerrainPatchProxy::HardwareTransformPatch_GetVertexBufferPtr()
{
if (m_pTerrainPatch)
return m_pTerrainPatch->HardwareTransformPatch_GetVertexBufferPtr();
return NULL;
}
SoftwareTransformPatch_SSourceVertex* CTerrainPatchProxy::SoftwareTransformPatch_GetTerrainVertexDataPtr()
{
if (m_pTerrainPatch)
return m_pTerrainPatch->SoftwareTransformPatch_GetTerrainVertexDataPtr();
return NULL;
}
UINT CTerrainPatchProxy::GetWaterFaceCount()
{
if (m_pTerrainPatch)
return m_pTerrainPatch->GetWaterFaceCount();
return 0;
}
void CTerrainPatchProxy::Clear()
{
m_bUsed = false;
m_sPatchNum = 0;
m_byTerrainNum = 0xFF;
m_pTerrainPatch = NULL;
}
@@ -0,0 +1,46 @@
// TerrainQuadtreeNode.cpp: implementation of the CTerrainQuadtreeNode class.
//
//////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "TerrainQuadtree.h"
//////////////////////////////////////////////////////////////////////
// CTerrainQuadtree
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// CTerrainQuadtreeNode
//////////////////////////////////////////////////////////////////////
CTerrainQuadtreeNode::CTerrainQuadtreeNode():NW_Node(NULL), NE_Node(NULL), SW_Node(NULL), SE_Node(NULL), center(-1.0f, -1.0f, -1.0f)
{
x0 = y0 = x1 = y1 = 0;
Size = 0;
PatchNum = 0;
radius = 0.0f;
m_byLODLevel = 0;
}
CTerrainQuadtreeNode::~CTerrainQuadtreeNode()
{
if (NW_Node)
{
delete NW_Node;
NW_Node = NULL;
}
if (NE_Node)
{
delete NE_Node;
NE_Node = NULL;
}
if (SW_Node)
{
delete SW_Node;
SW_Node = NULL;
}
if (SE_Node)
{
delete SE_Node;
SE_Node = NULL;
}
}
@@ -0,0 +1,32 @@
// TerrainQuadtreeNode.h: interface for the CTerrainQuadtreeNode class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_TERRAINQUADTREENODE_H__C788298F_1098_4CEE_B6F3_5975D618BBF3__INCLUDED_)
#define AFX_TERRAINQUADTREENODE_H__C788298F_1098_4CEE_B6F3_5975D618BBF3__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CTerrainQuadtreeNode
{
public:
CTerrainQuadtreeNode();
virtual ~CTerrainQuadtreeNode();
public:
long x0, y0, x1, y1;
CTerrainQuadtreeNode * NW_Node;
CTerrainQuadtreeNode * NE_Node;
CTerrainQuadtreeNode * SW_Node;
CTerrainQuadtreeNode * SE_Node;
long Size;
long PatchNum;
D3DXVECTOR3 center;
float radius;
BYTE m_byLODLevel;
};
#endif // !defined(AFX_TERRAINQUADTREENODE_H__C788298F_1098_4CEE_B6F3_5975D618BBF3__INCLUDED_)
+1 -2
View File
@@ -19,8 +19,7 @@
#include "../EterLib/StdAfx.h"
#include "../EterGrnLib/StdAfx.h"
// PORT: dropped #include "../ScriptLib/StdAfx.h": no PRTerrainLib file uses Python, and it would pull
// CPython headers into every terrain translation unit.
#include "../ScriptLib/StdAfx.h"
/* Fast Float<->Integer conversion */
extern float PR_FCNV;
+329
View File
@@ -0,0 +1,329 @@
#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(int32_t) * m_byNumWater; // PORT: the file's long is 32-bit
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)
for (int i = 0; i < m_byNumWater; ++i) // PORT: widen the file's 32-bit longs (LP64 long is 64-bit)
{
int32_t lHeight;
memcpy(&lHeight, abSrcWaterHeight + sizeof(int32_t) * i, sizeof(int32_t));
m_lWaterHeight[i] = lHeight;
}
}
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;
}
@@ -0,0 +1,275 @@
#include "StdAfx.h"
#include "TextureSet.h"
CTextureSet::CTextureSet()
{
Initialize();
}
CTextureSet::~CTextureSet()
{
Clear();
}
void CTextureSet::Initialize()
{
}
void CTextureSet::Create()
{
CResource * pResource = CResourceManager::Instance().GetResourcePointer("d:/ymir work/special/error.tga");
m_ErrorTexture.ImageInstance.SetImagePointer(static_cast<CGraphicImage *> (pResource));
AddEmptyTexture(); // 지우개 텍스춰를 처음에 추가 해야 함
}
bool CTextureSet::Load(const char * c_szTextureSetFileName, float fTerrainTexCoordBase)
{
NANOBEGIN
Clear();
CTokenVectorMap stTokenVectorMap;
if (!LoadMultipleTextData(c_szTextureSetFileName, stTokenVectorMap))
{
TraceError("TextureSet::Load : cannot load %s", c_szTextureSetFileName);
return false;
}
if (stTokenVectorMap.end() == stTokenVectorMap.find("textureset"))
{
TraceError("TextureSet::Load : syntax error, TextureSet (filename: %s)", c_szTextureSetFileName);
return false;
}
if (stTokenVectorMap.end() == stTokenVectorMap.find("texturecount"))
{
TraceError("TextureSet::Load : syntax error, TextureCount (filename: %s)", c_szTextureSetFileName);
return false;
}
Create();
const std::string & c_rstrCount = stTokenVectorMap["texturecount"][0];
long lCount = atol(c_rstrCount.c_str());
char szTextureName[32 + 1];
m_Textures.resize(lCount + 1);
for (long i = 0; i < lCount; ++i)
{
_snprintf(szTextureName, sizeof(szTextureName), "texture%03d", i + 1);
if (stTokenVectorMap.end() == stTokenVectorMap.find(szTextureName))
continue;
const CTokenVector & rVector = stTokenVectorMap[szTextureName];
const std::string & c_rstrFileName = rVector[0].c_str();
const std::string & c_rstrUScale = rVector[1].c_str();
const std::string & c_rstrVScale = rVector[2].c_str();
const std::string & c_rstrUOffset = rVector[3].c_str();
const std::string & c_rstrVOffset = rVector[4].c_str();
const std::string & c_rstrbSplat = rVector[5].c_str();
const std::string & c_rstrBegin = rVector[6].c_str();
const std::string & c_rstrEnd = rVector[7].c_str();
float fuScale, fvScale, fuOffset, fvOffset;
bool bSplat;
unsigned short usBegin, usEnd;
fuScale = atof(c_rstrUScale.c_str());
fvScale = atof(c_rstrVScale.c_str());
fuOffset = atof(c_rstrUOffset.c_str());
fvOffset = atof(c_rstrVOffset.c_str());
bSplat = 0 != atoi(c_rstrbSplat.c_str());
usBegin = static_cast<unsigned short>(atoi(c_rstrBegin.c_str()));
usEnd = static_cast<unsigned short>(atoi(c_rstrEnd.c_str()));
if (!SetTexture(i + 1, c_rstrFileName.c_str(), fuScale, fvScale, fuOffset, fvOffset, bSplat, usBegin, usEnd, fTerrainTexCoordBase))
TraceError("CTextureSet::Load : SetTexture failed : Filename: %s", c_rstrFileName.c_str());
}
m_stFileName.assign(c_szTextureSetFileName);
NANOEND
return true;
}
void CTextureSet::Clear()
{
m_ErrorTexture.ImageInstance.Destroy();
m_Textures.clear();
Initialize();
}
void CTextureSet::AddEmptyTexture()
{
TTerrainTexture eraser;
m_Textures.push_back(eraser);
}
unsigned long CTextureSet::GetTextureCount()
{
return m_Textures.size();
}
TTerrainTexture & CTextureSet::GetTexture(unsigned long ulIndex)
{
if (GetTextureCount() <= ulIndex)
return m_ErrorTexture;
return m_Textures[ulIndex];
}
bool CTextureSet::SetTexture(unsigned long ulIndex,
const char * c_szFileName,
float fuScale,
float fvScale,
float fuOffset,
float fvOffset,
bool bSplat,
unsigned short usBegin,
unsigned short usEnd,
float fTerrainTexCoordBase)
{
if (ulIndex >= m_Textures.size())
{
TraceError("CTextureSet::SetTexture : Index Error : Index(%d) is Larger than TextureSet Size(%d)", ulIndex, m_Textures.size());
return false;
}
CResource * pResource = CResourceManager::Instance().GetResourcePointer(c_szFileName);
if (!pResource->IsType(CGraphicImage::Type()))
{
TraceError("CTerrainImpl::GenerateTexture : %s is NOT Image File", pResource->GetFileName());
return false;
}
TTerrainTexture & tex = m_Textures[ulIndex];
tex.stFilename = c_szFileName;
tex.UScale = fuScale;
tex.VScale = fvScale;
tex.UOffset = fuOffset;
tex.VOffset = fvOffset;
tex.bSplat = bSplat;
tex.Begin = usBegin;
tex.End = usEnd;
tex.ImageInstance.SetImagePointer(static_cast<CGraphicImage *>(pResource));
tex.pd3dTexture = tex.ImageInstance.GetTexturePointer()->GetD3DTexture();
D3DXMatrixScaling(&tex.m_matTransform, fTerrainTexCoordBase * tex.UScale, -fTerrainTexCoordBase * tex.VScale, 0.0f);
tex.m_matTransform._41 = tex.UOffset;
tex.m_matTransform._42 = -tex.VOffset;
return true;
}
void CTextureSet::Reload(float fTerrainTexCoordBase)
{
for (DWORD dwIndex = 1; dwIndex < GetTextureCount(); ++dwIndex)
{
TTerrainTexture & tex = m_Textures[dwIndex];
tex.ImageInstance.ReloadImagePointer((CGraphicImage *) CResourceManager::Instance().GetResourcePointer(tex.stFilename.c_str()));
tex.pd3dTexture = tex.ImageInstance.GetTexturePointer()->GetD3DTexture();
D3DXMatrixScaling(&tex.m_matTransform, fTerrainTexCoordBase * tex.UScale, -fTerrainTexCoordBase * tex.VScale, 0.0f);
tex.m_matTransform._41 = tex.UOffset;
tex.m_matTransform._42 = -tex.VOffset;
}
}
bool CTextureSet::AddTexture(const char * c_szFileName,
float fuScale,
float fvScale,
float fuOffset,
float fvOffset,
bool bSplat,
unsigned short usBegin,
unsigned short usEnd,
float fTerrainTexCoordBase)
{
if (GetTextureCount() >= 256)
{
LogBox("\305\330\275\272\303\263\270\246 \264\365 \300\314\273\363 \303\337\260\241\307\322 \274\366 \276\370\275\300\264\317\264\331.", "\303\326\264\353 \305\330\275\272\303\263 \260\263\274\366 255\260\263");
return false;
}
for (unsigned long i = 1; i < GetTextureCount(); ++i)
{
if (0 == m_Textures[i].stFilename.compare(c_szFileName))
{
LogBox("\265\277\300\317\307\321 \300\314\270\247\300\307 \305\330\275\272\303\263\260\241 \300\314\271\314 \300\326\275\300\264\317\264\331.", "\301\337\272\271");
return false;
}
}
CResource * pResource = CResourceManager::Instance().GetResourcePointer(c_szFileName);
if (!pResource->IsType(CGraphicImage::Type()))
{
LogBox("CTerrainImpl::GenerateTexture : \300\314\271\314\301\366 \306\304\300\317\300\314 \276\306\264\325\264\317\264\331. %s", pResource->GetFileName());
return false;
}
m_Textures.reserve(m_Textures.size() + 1);
SetTexture(m_Textures.size() - 1,
c_szFileName,
fuScale,
fvScale,
fuOffset,
fvOffset,
bSplat,
usBegin,
usEnd,
fTerrainTexCoordBase);
return true;
}
bool CTextureSet::RemoveTexture(unsigned long ulIndex)
{
if (GetTextureCount() <= ulIndex)
return false;
TTextureVector::iterator itor = m_Textures.begin() + ulIndex;
m_Textures.erase(itor);
return true;
}
bool CTextureSet::Save(const char * c_pszFileName)
{
FILE * pFile = fopen(c_pszFileName, "w");
if (!pFile)
return false;
fprintf(pFile, "TextureSet\n");
fprintf(pFile, "\n");
fprintf(pFile, "TextureCount %ld\n", GetTextureCount() - 1); // -1 을 하는 이유는 지우개 때문임
fprintf(pFile, "\n");
for (DWORD i = 1; i < GetTextureCount(); ++i)
{
TTerrainTexture & rTex = m_Textures[i];
fprintf(pFile, "Start Texture%03d\n", i);
fprintf(pFile, " \"%s\"\n", rTex.stFilename.c_str());
fprintf(pFile, " %f\n", rTex.UScale);
fprintf(pFile, " %f\n", rTex.VScale);
fprintf(pFile, " %f\n", rTex.UOffset);
fprintf(pFile, " %f\n", rTex.VOffset);
fprintf(pFile, " %d\n", rTex.bSplat);
fprintf(pFile, " %hu\n", rTex.Begin);
fprintf(pFile, " %hu\n", rTex.End);
fprintf(pFile, "End Texture%03d\n", i);
}
fclose(pFile);
return true;
}
@@ -0,0 +1,921 @@
// PythonBackground.cpp: implementation of the CPythonBackground class.
//
//////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "../EterLib/CullingManager.h"
#include "../EterLib/Camera.h"
#include "../EterPack/EterPackManager.h"
#include "../GameLib/MapOutdoor.h"
#include "../GameLib/PropertyLoader.h"
#include "PythonBackground.h"
#include "PythonCharacterManager.h"
#include "PythonNetworkStream.h"
#include "PythonMiniMap.h"
#include "PythonSystem.h"
std::string g_strEffectName = "d:/ymir work/effect/etc/direction/direction_land.mse";
DWORD CPythonBackground::GetRenderShadowTime()
{
return m_dwRenderShadowTime;
}
bool CPythonBackground::SetVisiblePart(int eMapOutDoorPart, bool isVisible)
{
if (!m_pkMap)
return false;
CMapOutdoor& rkMap=GetMapOutdoorRef();
rkMap.SetVisiblePart(eMapOutDoorPart, isVisible);
return true;
}
void CPythonBackground::EnableTerrainOnlyForHeight()
{
if (!m_pkMap)
return;
CMapOutdoor& rkMap=GetMapOutdoorRef();
rkMap.EnableTerrainOnlyForHeight(TRUE);
}
bool CPythonBackground::SetSplatLimit(int iSplatNum)
{
if (!m_pkMap)
return false;
CMapOutdoor& rkMap = GetMapOutdoorRef();
rkMap.SetSplatLimit(iSplatNum);
return true;
}
void CPythonBackground::CreateCharacterShadowTexture()
{
if (!m_pkMap)
return;
CMapOutdoor& rkMap = GetMapOutdoorRef();
rkMap.CreateCharacterShadowTexture();
}
void CPythonBackground::ReleaseCharacterShadowTexture()
{
if (!m_pkMap)
return;
CMapOutdoor& rkMap = GetMapOutdoorRef();
rkMap.ReleaseCharacterShadowTexture();
}
void CPythonBackground::RefreshShadowLevel()
{
SetShadowLevel(CPythonSystem::Instance().GetShadowLevel());
}
bool CPythonBackground::SetShadowLevel(int eLevel)
{
if (!m_pkMap)
return false;
if (m_eShadowLevel == eLevel)
return true;
CMapOutdoor& rkMap = GetMapOutdoorRef();
m_eShadowLevel = eLevel;
switch (m_eShadowLevel)
{
case SHADOW_NONE:
rkMap.SetDrawShadow(false);
rkMap.SetShadowTextureSize(512);
break;
case SHADOW_GROUND:
rkMap.SetDrawShadow(true);
rkMap.SetDrawCharacterShadow(false);
rkMap.SetShadowTextureSize(512);
break;
case SHADOW_GROUND_AND_SOLO:
rkMap.SetDrawShadow(true);
rkMap.SetDrawCharacterShadow(true);
rkMap.SetShadowTextureSize(512);
break;
case SHADOW_ALL:
rkMap.SetDrawShadow(true);
rkMap.SetDrawCharacterShadow(true);
rkMap.SetShadowTextureSize(512);
break;
case SHADOW_ALL_HIGH:
rkMap.SetDrawShadow(true);
rkMap.SetDrawCharacterShadow(true);
rkMap.SetShadowTextureSize(1024);
break;
case SHADOW_ALL_MAX:
rkMap.SetDrawShadow(true);
rkMap.SetDrawCharacterShadow(true);
rkMap.SetShadowTextureSize(2048);
break;
}
return true;
}
void CPythonBackground::SelectViewDistanceNum(int eNum)
{
if (!m_pkMap)
return;
CMapOutdoor& rkMap=GetMapOutdoorRef();
if (!mc_pcurEnvironmentData)
{
TraceError("CPythonBackground::SelectViewDistanceNum(int eNum=%d) mc_pcurEnvironmentData is NULL", eNum);
return;
}
m_eViewDistanceNum = eNum;
TEnvironmentData * env = ((TEnvironmentData *) mc_pcurEnvironmentData);
// 게임 분위기를 바꿔놓을 수 있으므로 reserve로 되어있으면 고치지 않는다.
if (env->bReserve)
{
env->m_fFogNearDistance = m_ViewDistanceSet[m_eViewDistanceNum].m_fFogStart;
env->m_fFogFarDistance = m_ViewDistanceSet[m_eViewDistanceNum].m_fFogEnd;
env->v3SkyBoxScale = m_ViewDistanceSet[m_eViewDistanceNum].m_v3SkyBoxScale;
rkMap.SetEnvironmentSkyBox();
}
}
void CPythonBackground::SetViewDistanceSet(int eNum, float fFarClip)
{
if (!m_pkMap)
return;
m_ViewDistanceSet[eNum].m_fFogStart = fFarClip * 0.5f;//0.3333333f;
m_ViewDistanceSet[eNum].m_fFogEnd = fFarClip * 0.7f;//0.6666667f;
float fSkyBoxScale = fFarClip * 0.6f;//0.5773502f;
m_ViewDistanceSet[eNum].m_v3SkyBoxScale = D3DXVECTOR3(fSkyBoxScale, fSkyBoxScale, fSkyBoxScale);
m_ViewDistanceSet[eNum].m_fFarClip = fFarClip;
if (eNum == m_eViewDistanceNum)
SelectViewDistanceNum(eNum);
}
float CPythonBackground::GetFarClip()
{
if (!m_pkMap)
return 50000.0f;
if (m_ViewDistanceSet[m_eViewDistanceNum].m_fFarClip==0.0f)
{
TraceError("CPythonBackground::GetFarClip m_eViewDistanceNum=%d", m_eViewDistanceNum);
m_ViewDistanceSet[m_eViewDistanceNum].m_fFarClip=25600.0f;
}
return m_ViewDistanceSet[m_eViewDistanceNum].m_fFarClip;
}
void CPythonBackground::GetDistanceSetInfo(int * peNum, float * pfStart, float * pfEnd, float * pfFarClip)
{
if (!m_pkMap)
{
*peNum = 4;
*pfStart= 10000.0f;
*pfEnd= 15000.0f;
*pfFarClip = 50000.0f;
return;
}
*peNum = m_eViewDistanceNum;
*pfStart = m_ViewDistanceSet[m_eViewDistanceNum].m_fFogStart;
*pfEnd= m_ViewDistanceSet[m_eViewDistanceNum].m_fFogEnd;
*pfFarClip = m_ViewDistanceSet[m_eViewDistanceNum].m_fFarClip;
}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CPythonBackground::CPythonBackground()
{
m_dwRenderShadowTime=0;
m_eViewDistanceNum=0;
m_eViewDistanceNum=0;
m_eViewDistanceNum=0;
m_eShadowLevel=SHADOW_NONE;
m_dwBaseX=0;
m_dwBaseY=0;
m_strMapName="";
m_iDayMode = DAY_MODE_LIGHT;
m_iXMasTreeGrade = 0;
m_bVisibleGuildArea = FALSE;
SetViewDistanceSet(4, 25600.0f);
SetViewDistanceSet(3, 25600.0f);
SetViewDistanceSet(2, 25600.0f);
SetViewDistanceSet(1, 25600.0f);
SetViewDistanceSet(0, 25600.0f);
Initialize();
}
CPythonBackground::~CPythonBackground()
{
Tracen("CPythonBackground Clear");
}
void CPythonBackground::Initialize()
{
std::string stAtlasInfoFileName (LocaleService_GetLocalePath());
stAtlasInfoFileName += "/AtlasInfo.txt";
SetAtlasInfoFileName(stAtlasInfoFileName.c_str());
CMapManager::Initialize();
}
void CPythonBackground::__CreateProperty()
{
if (CEterPackManager::SEARCH_FILE_FIRST == CEterPackManager::Instance().GetSearchMode() &&
_access("property", 0) == 0)
{
m_PropertyManager.Initialize(NULL);
CPropertyLoader PropertyLoader;
PropertyLoader.SetPropertyManager(&m_PropertyManager);
PropertyLoader.Create("*.*", "Property");
}
else
{
m_PropertyManager.Initialize("pack/property");
}
}
//////////////////////////////////////////////////////////////////////
// Normal Functions
//////////////////////////////////////////////////////////////////////
bool CPythonBackground::GetPickingPoint(D3DXVECTOR3 * v3IntersectPt)
{
CMapOutdoor& rkMap=GetMapOutdoorRef();
return rkMap.GetPickingPoint(v3IntersectPt);
}
bool CPythonBackground::GetPickingPointWithRay(const CRay & rRay, D3DXVECTOR3 * v3IntersectPt)
{
CMapOutdoor& rkMap=GetMapOutdoorRef();
return rkMap.GetPickingPointWithRay(rRay, v3IntersectPt);
}
bool CPythonBackground::GetPickingPointWithRayOnlyTerrain(const CRay & rRay, D3DXVECTOR3 * v3IntersectPt)
{
CMapOutdoor& rkMap=GetMapOutdoorRef();
return rkMap.GetPickingPointWithRayOnlyTerrain(rRay, v3IntersectPt);
}
BOOL CPythonBackground::GetLightDirection(D3DXVECTOR3 & rv3LightDirection)
{
if (!mc_pcurEnvironmentData)
return FALSE;
rv3LightDirection.x = mc_pcurEnvironmentData->DirLights[ENV_DIRLIGHT_BACKGROUND].Direction.x;
rv3LightDirection.y = mc_pcurEnvironmentData->DirLights[ENV_DIRLIGHT_BACKGROUND].Direction.y;
rv3LightDirection.z = mc_pcurEnvironmentData->DirLights[ENV_DIRLIGHT_BACKGROUND].Direction.z;
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
void CPythonBackground::Destroy()
{
CMapManager::Destroy();
m_SnowEnvironment.Destroy();
m_bVisibleGuildArea = FALSE;
}
void CPythonBackground::Create()
{
static int s_isCreateProperty=false;
if (!s_isCreateProperty)
{
s_isCreateProperty=true;
__CreateProperty();
}
CMapManager::Create();
m_SnowEnvironment.Create();
}
struct FGetPortalID
{
float m_fRequestX, m_fRequestY;
std::set<int> m_kSet_iPortalID;
FGetPortalID(float fRequestX, float fRequestY)
{
m_fRequestX=fRequestX;
m_fRequestY=fRequestY;
}
void operator () (CGraphicObjectInstance * pObject)
{
for (int i = 0; i < PORTAL_ID_MAX_NUM; ++i)
{
int iID = pObject->GetPortal(i);
if (0 == iID)
break;
m_kSet_iPortalID.insert(iID);
}
}
};
void CPythonBackground::Update(float fCenterX, float fCenterY, float fCenterZ)
{
if (!IsMapReady())
return;
#ifdef __PERFORMANCE_CHECKER__
DWORD t1=ELTimer_GetMSec();
#endif
UpdateMap(fCenterX, fCenterY, fCenterZ);
#ifdef __PERFORMANCE_CHECKER__
DWORD t2=ELTimer_GetMSec();
#endif
UpdateAroundAmbience(fCenterX, fCenterY, fCenterZ);
#ifdef __PERFORMANCE_CHECKER__
DWORD t3=ELTimer_GetMSec();
#endif
m_SnowEnvironment.Update(D3DXVECTOR3(fCenterX, -fCenterY, fCenterZ));
#ifdef __PERFORMANCE_CHECKER__
{
static FILE* fp=fopen("perf_bg_update.txt", "w");
if (t3-t1>5)
{
fprintf(fp, "BG.Total %d (Time %f)\n", t3-t1, ELTimer_GetMSec()/1000.0f);
fprintf(fp, "BG.UpdateMap %d\n", t2-t1);
fprintf(fp, "BG.UpdateAmb %d\n", t3-t2);
fflush(fp);
}
}
#endif
// Portal Process
CMapOutdoor& rkMap=GetMapOutdoorRef();
if (rkMap.IsEnablePortal())
{
CCullingManager & rkCullingMgr = CCullingManager::Instance();
FGetPortalID kGetPortalID(fCenterX, -fCenterY);
Vector3d aVector3d;
aVector3d.Set(fCenterX, -fCenterY, fCenterZ);
Vector3d toTop;
toTop.Set(0, 0, 25000.0f);
rkCullingMgr.ForInRay(aVector3d, toTop, &kGetPortalID);
std::set<int>::iterator itor = kGetPortalID.m_kSet_iPortalID.begin();
if (!__IsSame(kGetPortalID.m_kSet_iPortalID, m_kSet_iShowingPortalID))
{
ClearPortal();
std::set<int>::iterator itor=kGetPortalID.m_kSet_iPortalID.begin();
for (; itor!=kGetPortalID.m_kSet_iPortalID.end(); ++itor)
{
AddShowingPortalID(*itor);
}
RefreshPortal();
m_kSet_iShowingPortalID = kGetPortalID.m_kSet_iPortalID;
}
}
// Target Effect Process
{
std::map<DWORD, DWORD>::iterator itor = m_kMap_dwTargetID_dwChrID.begin();
for (; itor != m_kMap_dwTargetID_dwChrID.end(); ++itor)
{
DWORD dwTargetID = itor->first;
DWORD dwChrID = itor->second;
CInstanceBase * pInstance = CPythonCharacterManager::Instance().GetInstancePtr(dwChrID);
if (!pInstance)
continue;
TPixelPosition kPixelPosition;
pInstance->NEW_GetPixelPosition(&kPixelPosition);
CreateSpecialEffect(dwTargetID,
+kPixelPosition.x,
-kPixelPosition.y,
+kPixelPosition.z,
g_strEffectName.c_str());
}
}
// Reserve Target Effect
{
std::map<DWORD, SReserveTargetEffect>::iterator itor = m_kMap_dwID_kReserveTargetEffect.begin();
for (; itor != m_kMap_dwID_kReserveTargetEffect.end();)
{
DWORD dwID = itor->first;
SReserveTargetEffect & rReserveTargetEffect = itor->second;
float ilx = float(rReserveTargetEffect.ilx);
float ily = float(rReserveTargetEffect.ily);
float fHeight = rkMap.GetHeight(ilx, ily);
if (0.0f == fHeight)
{
++itor;
continue;
}
CreateSpecialEffect(dwID, ilx, ily, fHeight, g_strEffectName.c_str());
itor = m_kMap_dwID_kReserveTargetEffect.erase(itor);
}
}
}
bool CPythonBackground::__IsSame(std::set<int> & rleft, std::set<int> & rright)
{
std::set<int>::iterator itor_l;
std::set<int>::iterator itor_r;
for (itor_l=rleft.begin(); itor_l!=rleft.end(); ++itor_l)
{
if (rright.end() == rright.find(*itor_l))
return false;
}
for (itor_r=rright.begin(); itor_r!=rright.end(); ++itor_r)
{
if (rleft.end() == rleft.find(*itor_r))
return false;
}
return true;
}
void CPythonBackground::Render()
{
if (!IsMapReady())
return;
m_SnowEnvironment.Deform();
CMapOutdoor& rkMap=GetMapOutdoorRef();
rkMap.Render();
if (m_bVisibleGuildArea)
rkMap.RenderMarkedArea();
}
void CPythonBackground::RenderSnow()
{
m_SnowEnvironment.Render();
}
void CPythonBackground::RenderPCBlocker()
{
if (!IsMapReady())
return;
CMapOutdoor& rkMap=GetMapOutdoorRef();
rkMap.RenderPCBlocker();
}
void CPythonBackground::RenderCollision()
{
if (!IsMapReady())
return;
CMapOutdoor& rkMap=GetMapOutdoorRef();
rkMap.RenderCollision();
}
void CPythonBackground::RenderCharacterShadowToTexture()
{
extern bool GRAPHICS_CAPS_CAN_NOT_DRAW_SHADOW;
if (GRAPHICS_CAPS_CAN_NOT_DRAW_SHADOW)
return;
if (!IsMapReady())
return;
CMapOutdoor& rkMap=GetMapOutdoorRef();
DWORD t1=ELTimer_GetMSec();
if (m_eShadowLevel == SHADOW_ALL ||
m_eShadowLevel == SHADOW_ALL_HIGH ||
m_eShadowLevel == SHADOW_ALL_MAX ||
m_eShadowLevel == SHADOW_GROUND_AND_SOLO)
{
D3DXMATRIX matWorld;
STATEMANAGER.GetTransform(D3DTS_WORLD, &matWorld);
bool canRender=rkMap.BeginRenderCharacterShadowToTexture();
if (canRender)
{
CPythonCharacterManager& rkChrMgr=CPythonCharacterManager::Instance();
if (m_eShadowLevel == SHADOW_GROUND_AND_SOLO)
rkChrMgr.RenderShadowMainInstance();
else
rkChrMgr.RenderShadowAllInstances();
}
rkMap.EndRenderCharacterShadowToTexture();
STATEMANAGER.SetTransform(D3DTS_WORLD, &matWorld);
}
DWORD t2=ELTimer_GetMSec();
m_dwRenderShadowTime=t2-t1;
}
inline float Interpolate(float fStart, float fEnd, float fPercent)
{
return fStart + (fEnd - fStart) * fPercent;
}
struct CollisionChecker
{
bool isBlocked;
CInstanceBase* pInstance;
CollisionChecker(CInstanceBase* pInstance) : pInstance(pInstance), isBlocked(false) {}
void operator () (CGraphicObjectInstance* pOpponent)
{
if (isBlocked)
return;
if (!pOpponent)
return;
if (pInstance->IsBlockObject(*pOpponent))
isBlocked=true;
}
};
struct CollisionAdjustChecker
{
bool isBlocked;
CInstanceBase* pInstance;
CollisionAdjustChecker(CInstanceBase* pInstance) : pInstance(pInstance), isBlocked(false) {}
void operator () (CGraphicObjectInstance* pOpponent)
{
if (!pOpponent)
return;
if (pInstance->AvoidObject(*pOpponent))
isBlocked=true;
}
};
bool CPythonBackground::CheckAdvancing(CInstanceBase * pInstance)
{
if (!IsMapReady())
return true;
Vector3d center;
float radius;
pInstance->GetGraphicThingInstanceRef().GetBoundingSphere(center,radius);
CCullingManager & rkCullingMgr = CCullingManager::Instance();
CollisionAdjustChecker kCollisionAdjustChecker(pInstance);
rkCullingMgr.ForInRange(center, radius, &kCollisionAdjustChecker);
if (kCollisionAdjustChecker.isBlocked)
{
CollisionChecker kCollisionChecker(pInstance);
rkCullingMgr.ForInRange(center, radius, &kCollisionChecker);
if (kCollisionChecker.isBlocked)
{
pInstance->BlockMovement();
return true;
}
else
{
pInstance->NEW_MoveToDestPixelPositionDirection(pInstance->NEW_GetDstPixelPositionRef());
}
return false;
}
return false;
}
void CPythonBackground::RenderSky()
{
if (!IsMapReady())
return;
CMapOutdoor& rkMap=GetMapOutdoorRef();
rkMap.RenderSky();
}
void CPythonBackground::RenderCloud()
{
if (!IsMapReady())
return;
CMapOutdoor& rkMap=GetMapOutdoorRef();
rkMap.RenderCloud();
}
void CPythonBackground::RenderWater()
{
if (!IsMapReady())
return;
CMapOutdoor& rkMap=GetMapOutdoorRef();
rkMap.RenderWater();
}
void CPythonBackground::RenderEffect()
{
if (!IsMapReady())
return;
CMapOutdoor& rkMap=GetMapOutdoorRef();
rkMap.RenderEffect();
}
void CPythonBackground::RenderBeforeLensFlare()
{
if (!IsMapReady())
return;
CMapOutdoor& rkMap=GetMapOutdoorRef();
rkMap.RenderBeforeLensFlare();
}
void CPythonBackground::RenderAfterLensFlare()
{
if (!IsMapReady())
return;
CMapOutdoor& rkMap=GetMapOutdoorRef();
rkMap.RenderAfterLensFlare();
}
void CPythonBackground::ClearGuildArea()
{
if (!IsMapReady())
return;
CMapOutdoor& rkMap=GetMapOutdoorRef();
rkMap.ClearGuildArea();
}
void CPythonBackground::RegisterGuildArea(int isx, int isy, int iex, int iey)
{
if (!IsMapReady())
return;
CMapOutdoor& rkMap=GetMapOutdoorRef();
rkMap.RegisterGuildArea(isx, isy, iex, iey);
}
void CPythonBackground::SetCharacterDirLight()
{
if (!IsMapReady())
return;
if (!mc_pcurEnvironmentData)
return;
STATEMANAGER.SetLight(0, &mc_pcurEnvironmentData->DirLights[ENV_DIRLIGHT_CHARACTER]);
}
void CPythonBackground::SetBackgroundDirLight()
{
if (!IsMapReady())
return;
if (!mc_pcurEnvironmentData)
return;
STATEMANAGER.SetLight(0, &mc_pcurEnvironmentData->DirLights[ENV_DIRLIGHT_BACKGROUND]);
}
void CPythonBackground::GlobalPositionToLocalPosition(LONG& rGlobalX, LONG& rGlobalY)
{
rGlobalX-=m_dwBaseX;
rGlobalY-=m_dwBaseY;
}
void CPythonBackground::LocalPositionToGlobalPosition(LONG& rLocalX, LONG& rLocalY)
{
rLocalX+=m_dwBaseX;
rLocalY+=m_dwBaseY;
}
void CPythonBackground::RegisterDungeonMapName(const char * c_szMapName)
{
m_kSet_strDungeonMapName.insert(c_szMapName);
}
CPythonBackground::TMapInfo* CPythonBackground::GlobalPositionToMapInfo(DWORD dwGlobalX, DWORD dwGlobalY)
{
TMapInfoVector::iterator f = std::find_if(m_kVct_kMapInfo.begin(), m_kVct_kMapInfo.end(), FFindWarpMapName(dwGlobalX, dwGlobalY));
if (f == m_kVct_kMapInfo.end())
return NULL;
return &(*f);
}
void CPythonBackground::Warp(DWORD dwX, DWORD dwY)
{
TMapInfo* pkMapInfo = GlobalPositionToMapInfo(dwX, dwY);
if (!pkMapInfo)
{
TraceError("NOT_FOUND_GLOBAL_POSITION(%d, %d)", dwX, dwY);
return;
}
RefreshShadowLevel();
TMapInfo & rMapInfo = *pkMapInfo;
assert( (dwX >= rMapInfo.m_dwBaseX) && (dwY >= rMapInfo.m_dwBaseY) );
if (!LoadMap(rMapInfo.m_strName, float(dwX - rMapInfo.m_dwBaseX), float(dwY - rMapInfo.m_dwBaseY), 0))
{
// LOAD_MAP_ERROR_HANDLING
PostQuitMessage(0);
// END_OF_LOAD_MAP_ERROR_HANDLING
return;
}
CPythonMiniMap::Instance().LoadAtlas();
m_dwBaseX=rMapInfo.m_dwBaseX;
m_dwBaseY=rMapInfo.m_dwBaseY;
m_strMapName = rMapInfo.m_strName;
SetXMaxTree(m_iXMasTreeGrade);
if (m_kSet_strDungeonMapName.end() != m_kSet_strDungeonMapName.find(m_strMapName))
{
EnableTerrainOnlyForHeight();
CMapOutdoor& rkMap=GetMapOutdoorRef();
rkMap.EnablePortal(TRUE);
}
m_kSet_iShowingPortalID.clear();
m_kMap_dwTargetID_dwChrID.clear();
m_kMap_dwID_kReserveTargetEffect.clear();
}
void CPythonBackground::VisibleGuildArea()
{
if (!IsMapReady())
return;
CMapOutdoor& rkMap=GetMapOutdoorRef();
rkMap.VisibleMarkedArea();
m_bVisibleGuildArea = TRUE;
}
void CPythonBackground::DisableGuildArea()
{
if (!IsMapReady())
return;
CMapOutdoor& rkMap=GetMapOutdoorRef();
rkMap.DisableMarkedArea();
m_bVisibleGuildArea = FALSE;
}
const char * CPythonBackground::GetWarpMapName()
{
return m_strMapName.c_str();
}
void CPythonBackground::ChangeToDay()
{
m_iDayMode = DAY_MODE_LIGHT;
}
void CPythonBackground::ChangeToNight()
{
m_iDayMode = DAY_MODE_DARK;
}
void CPythonBackground::EnableSnowEnvironment()
{
m_SnowEnvironment.Enable();
}
void CPythonBackground::DisableSnowEnvironment()
{
m_SnowEnvironment.Disable();
}
const D3DXVECTOR3 c_v3TreePos = D3DXVECTOR3(76500.0f, -60900.0f, 20215.0f);
void CPythonBackground::SetXMaxTree(int iGrade)
{
if (!m_pkMap)
return;
assert(iGrade >= 0 && iGrade <= 3);
m_iXMasTreeGrade = iGrade;
CMapOutdoor& rkMap=GetMapOutdoorRef();
if ("map_n_snowm_01" != m_strMapName)
{
rkMap.XMasTree_Destroy();
return;
}
if (0 == iGrade)
{
rkMap.XMasTree_Destroy();
return;
}
//////////////////////////////////////////////////////////////////////
iGrade -= 1;
iGrade = max(iGrade, 0);
iGrade = min(iGrade, 2);
static std::string s_strTreeName[3] = {
"d:/ymir work/tree/christmastree1.spt",
"d:/ymir work/tree/christmastree2.spt",
"d:/ymir work/tree/christmastree3.spt"
};
static std::string s_strEffectName[3] = {
"d:/ymir work/effect/etc/christmas_tree/tree_1s.mse",
"d:/ymir work/effect/etc/christmas_tree/tree_2s.mse",
"d:/ymir work/effect/etc/christmas_tree/tree_3s.mse",
};
rkMap.XMasTree_Set(c_v3TreePos.x, c_v3TreePos.y, c_v3TreePos.z, s_strTreeName[iGrade].c_str(), s_strEffectName[iGrade].c_str());
}
void CPythonBackground::CreateTargetEffect(DWORD dwID, DWORD dwChrVID)
{
m_kMap_dwTargetID_dwChrID.insert(std::make_pair(dwID, dwChrVID));
}
void CPythonBackground::CreateTargetEffect(DWORD dwID, long lx, long ly)
{
if (m_kMap_dwTargetID_dwChrID.end() != m_kMap_dwTargetID_dwChrID.find(dwID))
return;
CMapOutdoor& rkMap=GetMapOutdoorRef();
DWORD dwBaseX;
DWORD dwBaseY;
rkMap.GetBaseXY(&dwBaseX, &dwBaseY);
int ilx = +(lx-int(dwBaseX));
int ily = -(ly-int(dwBaseY));
float fHeight = rkMap.GetHeight(float(ilx), float(ily));
if (0.0f == fHeight)
{
SReserveTargetEffect ReserveTargetEffect;
ReserveTargetEffect.ilx = ilx;
ReserveTargetEffect.ily = ily;
m_kMap_dwID_kReserveTargetEffect.insert(std::make_pair(dwID, ReserveTargetEffect));
return;
}
CreateSpecialEffect(dwID, ilx, ily, fHeight, g_strEffectName.c_str());
}
void CPythonBackground::DeleteTargetEffect(DWORD dwID)
{
if (m_kMap_dwID_kReserveTargetEffect.end() != m_kMap_dwID_kReserveTargetEffect.find(dwID))
{
m_kMap_dwID_kReserveTargetEffect.erase(dwID);
}
if (m_kMap_dwTargetID_dwChrID.end() != m_kMap_dwTargetID_dwChrID.find(dwID))
{
m_kMap_dwTargetID_dwChrID.erase(dwID);
}
DeleteSpecialEffect(dwID);
}
void CPythonBackground::CreateSpecialEffect(DWORD dwID, float fx, float fy, float fz, const char * c_szFileName)
{
CMapOutdoor& rkMap=GetMapOutdoorRef();
rkMap.SpecialEffect_Create(dwID, fx, fy, fz, c_szFileName);
}
void CPythonBackground::DeleteSpecialEffect(DWORD dwID)
{
CMapOutdoor& rkMap=GetMapOutdoorRef();
rkMap.SpecialEffect_Delete(dwID);
}
@@ -0,0 +1,619 @@
#include "StdAfx.h"
#include "PythonSystem.h"
#include "PythonBackground.h"
#include "../EterLib/StateManager.h"
#include "../GameLib/MapOutdoor.h"
PyObject * backgroundIsSoftwareTiling(PyObject * poSelf, PyObject * poArgs)
{
CPythonBackground& rkBG=CPythonBackground::Instance();
return Py_BuildValue("i", rkBG.IsSoftwareTilingEnable());
}
PyObject * backgroundEnableSoftwareTiling(PyObject * poSelf, PyObject * poArgs)
{
int nIsEnable;
if (!PyTuple_GetInteger(poArgs, 0, &nIsEnable))
return Py_BadArgument();
bool isEnable=nIsEnable ? true : false;
CPythonBackground& rkBG=CPythonBackground::Instance();
rkBG.ReserveSoftwareTilingEnable(isEnable);
CPythonSystem& rkSystem=CPythonSystem::Instance();
rkSystem.SetSoftwareTiling(isEnable);
return Py_BuildNone();
}
PyObject * backgroundEnableSnow(PyObject * poSelf, PyObject * poArgs)
{
int nIsEnable;
if (!PyTuple_GetInteger(poArgs, 0, &nIsEnable))
return Py_BadArgument();
CPythonBackground& rkBG=CPythonBackground::Instance();
if (nIsEnable)
rkBG.EnableSnowEnvironment();
else
rkBG.DisableSnowEnvironment();
return Py_BuildNone();
}
PyObject * backgroundLoadMap(PyObject * poSelf, PyObject * poArgs)
{
char * pszMapPathName;
if (!PyTuple_GetString(poArgs, 0, &pszMapPathName))
return Py_BadArgument();
float x, y, z;
if (!PyTuple_GetFloat(poArgs, 1, &x))
return Py_BadArgument();
if (!PyTuple_GetFloat(poArgs, 2, &y))
return Py_BadArgument();
if (!PyTuple_GetFloat(poArgs, 3, &z))
return Py_BadArgument();
CPythonBackground& rkBG=CPythonBackground::Instance();
rkBG.LoadMap(pszMapPathName, x, y, z);
//#ifdef _DEBUG
// CMapOutdoor& rkMap=rkBG.GetMapOutdoorRef();
// rkMap.EnablePortal(TRUE);
// rkBG.EnableTerrainOnlyForHeight();
//#endif
return Py_BuildNone();
}
PyObject * backgroundDestroy(PyObject * poSelf, PyObject * poArgs)
{
CPythonBackground& rkBG=CPythonBackground::Instance();
rkBG.SetShadowLevel(CPythonBackground::SHADOW_NONE);
rkBG.Destroy();
return Py_BuildNone();
}
PyObject * backgroundRegisterEnvironmentData(PyObject * poSelf, PyObject * poArgs)
{
int iIndex;
if (!PyTuple_GetInteger(poArgs, 0, &iIndex))
return Py_BadArgument();
char * pszEnvironmentFileName;
if (!PyTuple_GetString(poArgs, 1, &pszEnvironmentFileName))
return Py_BadArgument();
CPythonBackground& rkBG=CPythonBackground::Instance();
if (!rkBG.RegisterEnvironmentData(iIndex, pszEnvironmentFileName))
{
TraceError("background.RegisterEnvironmentData(iIndex=%d, szEnvironmentFileName=%s)", iIndex, pszEnvironmentFileName);
// TODO:
// 디폴트 환경 설정 작업을 해주자
}
return Py_BuildNone();
}
PyObject * backgroundSetEnvironmentData(PyObject * poSelf, PyObject * poArgs)
{
int iIndex;
if (!PyTuple_GetInteger(poArgs, 0, &iIndex))
return Py_BadArgument();
const TEnvironmentData * c_pEnvironmenData;
CPythonBackground& rkBG=CPythonBackground::Instance();
if (rkBG.GetEnvironmentData(iIndex, &c_pEnvironmenData))
rkBG.ResetEnvironmentDataPtr(c_pEnvironmenData);
return Py_BuildNone();
}
PyObject * backgroundGetCurrentMapName(PyObject * poSelf, PyObject * poArgs)
{
CPythonBackground& rkBG=CPythonBackground::Instance();
return Py_BuildValue("s", rkBG.GetWarpMapName());
}
PyObject * backgroundGetPickingPoint(PyObject * poSelf, PyObject * poArgs)
{
CPythonBackground& rkBG=CPythonBackground::Instance();
TPixelPosition kPPosPicked(0.0f, 0.0f, 0.0f);
if (rkBG.GetPickingPoint(&kPPosPicked))
{
kPPosPicked.y=-kPPosPicked.y;
}
return Py_BuildValue("fff", kPPosPicked.x, kPPosPicked.y, kPPosPicked.z);
}
PyObject * backgroundBeginEnvironment(PyObject * poSelf, PyObject * poArgs)
{
CPythonBackground& rkBG=CPythonBackground::Instance();
rkBG.BeginEnvironment();
return Py_BuildNone();
}
PyObject * backgroundEndEnvironemt(PyObject * poSelf, PyObject * poArgs)
{
CPythonBackground& rkBG=CPythonBackground::Instance();
rkBG.EndEnvironment();
return Py_BuildNone();
}
PyObject * backgroundSetCharacterDirLight(PyObject * poSelf, PyObject * poArgs)
{
CPythonBackground& rkBG = CPythonBackground::Instance();
rkBG.SetCharacterDirLight();
return Py_BuildNone();
}
PyObject * backgroundSetBackgroundDirLight(PyObject * poSelf, PyObject * poArgs)
{
CPythonBackground& rkBG = CPythonBackground::Instance();
rkBG.SetBackgroundDirLight();
return Py_BuildNone();
}
PyObject * backgroundInitialize(PyObject * poSelf, PyObject * poArgs)
{
CPythonBackground& rkBG=CPythonBackground::Instance();
rkBG.Create();
return Py_BuildNone();
}
PyObject * backgroundUpdate(PyObject * poSelf, PyObject * poArgs)
{
float fCameraX;
if (!PyTuple_GetFloat(poArgs, 0, &fCameraX))
return Py_BadArgument();
float fCameraY;
if (!PyTuple_GetFloat(poArgs, 1, &fCameraY))
return Py_BadArgument();
float fCameraZ;
if (!PyTuple_GetFloat(poArgs, 2, &fCameraZ))
return Py_BadArgument();
CPythonBackground::Instance().Update(fCameraX, fCameraY, fCameraZ);
return Py_BuildNone();
}
PyObject * backgroundRender(PyObject * poSelf, PyObject * poArgs)
{
CPythonBackground::Instance().Render();
return Py_BuildNone();
}
PyObject * backgroundRenderPCBlocker(PyObject * poSelf, PyObject * poArgs)
{
CPythonBackground::Instance().RenderPCBlocker();
return Py_BuildNone();
}
PyObject * backgroundRenderCollision(PyObject * poSelf, PyObject * poArgs)
{
CPythonBackground::Instance().RenderCollision();
return Py_BuildNone();
}
PyObject * backgroundRenderSky(PyObject * poSelf, PyObject * poArgs)
{
CPythonBackground::Instance().RenderSky();
return Py_BuildNone();
}
PyObject * backgroundRenderCloud(PyObject * poSelf, PyObject * poArgs)
{
CPythonBackground::Instance().RenderCloud();
return Py_BuildNone();
}
PyObject * backgroundRenderWater(PyObject * poSelf, PyObject * poArgs)
{
CPythonBackground::Instance().RenderWater();
return Py_BuildNone();
}
PyObject * backgroundRenderEffect(PyObject * poSelf, PyObject * poArgs)
{
CPythonBackground::Instance().RenderEffect();
return Py_BuildNone();
}
PyObject * backgroundRenderBeforeLensFlare(PyObject * poSelf, PyObject * poArgs)
{
CPythonBackground::Instance().RenderBeforeLensFlare();
return Py_BuildNone();
}
PyObject * backgroundRenderAfterLensFlare(PyObject * poSelf, PyObject * poArgs)
{
CPythonBackground::Instance().RenderAfterLensFlare();
return Py_BuildNone();
}
PyObject * backgroundRenderCharacterShadowToTexture(PyObject * poSelf, PyObject * poArgs)
{
CPythonBackground::Instance().RenderCharacterShadowToTexture();
return Py_BuildNone();
}
PyObject * backgroundRenderDungeon(PyObject * poSelf, PyObject * poArgs)
{
assert(!"background.RenderDungeon() - \273\347\277\353\307\317\301\366 \276\312\264\302 \307\324\274\366\300\324\264\317\264\331 - [levites]");
return Py_BuildNone();
}
PyObject * backgroundGetHeight(PyObject * poSelf, PyObject * poArgs)
{
float fx;
if (!PyTuple_GetFloat(poArgs, 0, &fx))
return Py_BadArgument();
float fy;
if (!PyTuple_GetFloat(poArgs, 1, &fy))
return Py_BadArgument();
float fz = CPythonBackground::Instance().GetHeight(fx, fy);
return Py_BuildValue("f", fz);
}
PyObject * backgroundGetRenderedSplatNum(PyObject * poSelf, PyObject * poArgs)
{
int iPatch;
int iSplat;
float fSplatRatio;
std::vector<int> & aTextureNumVector = CPythonBackground::Instance().GetRenderedSplatNum(&iPatch, &iSplat, &fSplatRatio);
char szOutput[MAX_PATH] = "";
int iOutput = 0;
for( std::vector<int>::iterator it = aTextureNumVector.begin(); it != aTextureNumVector.end(); it++ ) {
iOutput += snprintf(szOutput + iOutput, sizeof(szOutput) - iOutput, "%d ", *it);
}
//std::copy(aTextureNumVector.begin(),aTextureNumVector.end(),std::ostream_iterator<int>(ostr," "));
return Py_BuildValue("iifs", iPatch, iSplat, fSplatRatio, szOutput);
}
PyObject * backgroundGetRenderedGTINum(PyObject * poSelf, PyObject * poArgs)
{
DWORD dwGraphicThingInstanceNum;
DWORD dwCRCNum;
/*CArea::TCRCWithNumberVector & rCRCWithNumberVector = */
CPythonBackground::Instance().GetRenderedGraphicThingInstanceNum(&dwGraphicThingInstanceNum, &dwCRCNum);
/*
std::ostringstream ostr;
std::for_each(rCRCWithNumberVector.begin(),rCRCWithNumberVector.end(),std::ostream_iterator<CArea::TCRCWithNumberVector>(ostr," "));
*/
return Py_BuildValue("ii", dwGraphicThingInstanceNum, dwCRCNum);
}
PyObject * backgroundGetRenderShadowTime(PyObject * poSelf, PyObject * poArgs)
{
CPythonBackground& rkBG=CPythonBackground::Instance();
return Py_BuildValue("i", rkBG.GetRenderShadowTime());
}
PyObject * backgroundGetShadowMapcolor(PyObject * poSelf, PyObject * poArgs)
{
float fx;
if (!PyTuple_GetFloat(poArgs, 0, &fx))
return Py_BadArgument();
float fy;
if (!PyTuple_GetFloat(poArgs, 1, &fy))
return Py_BadArgument();
DWORD dwColor = CPythonBackground::Instance().GetShadowMapColor(fx, fy);
return Py_BuildValue("i", dwColor);
}
PyObject * backgroundSetShadowLevel(PyObject * poSelf, PyObject * poArgs)
{
int iLevel;
if (!PyTuple_GetInteger(poArgs, 0, &iLevel))
return Py_BadArgument();
CPythonBackground& rkBG = CPythonBackground::Instance();
rkBG.SetShadowLevel(iLevel);
return Py_BuildNone();
}
PyObject * backgroundSetVisiblePart(PyObject * poSelf, PyObject * poArgs)
{
int ePart;
if (!PyTuple_GetInteger(poArgs, 0, &ePart))
return Py_BadArgument();
int isVisible;
if (!PyTuple_GetInteger(poArgs, 1, &isVisible))
return Py_BadArgument();
if (ePart>=CMapOutdoor::PART_NUM)
return Py_BuildException("ePart(%d)<background.PART_NUM(%d)", ePart, CMapOutdoor::PART_NUM);
CPythonBackground& rkBG=CPythonBackground::Instance();
rkBG.SetVisiblePart(ePart, isVisible ? true : false);
return Py_BuildNone();
}
PyObject * backgroundSetSpaltLimit(PyObject * poSelf, PyObject * poArgs)
{
int iSplatNum;
if (!PyTuple_GetInteger(poArgs, 0, &iSplatNum))
return Py_BadArgument();
if (iSplatNum<0)
return Py_BuildException("background.SetSplatLimit(iSplatNum(%d)>=0)", iSplatNum);
CPythonBackground& rkBG=CPythonBackground::Instance();
rkBG.SetSplatLimit(iSplatNum);
return Py_BuildNone();
}
PyObject * backgroundSelectViewDistanceNum(PyObject * poSelf, PyObject * poArgs)
{
int iNum;
if (!PyTuple_GetInteger(poArgs, 0, &iNum))
return Py_BadArgument();
CPythonBackground& rkBG=CPythonBackground::Instance();
rkBG.SelectViewDistanceNum(iNum);
return Py_BuildNone();
}
PyObject * backgroundSetViewDistanceSet(PyObject * poSelf, PyObject * poArgs)
{
int iNum;
if (!PyTuple_GetInteger(poArgs, 0, &iNum))
return Py_BadArgument();
float fFarClip;
if (!PyTuple_GetFloat(poArgs, 1, &fFarClip))
return Py_BadArgument();
CPythonBackground& rkBG=CPythonBackground::Instance();
rkBG.SetViewDistanceSet(iNum, fFarClip);
return Py_BuildNone();
}
PyObject * backgroundGetFarClip(PyObject * poSelf, PyObject * poArgs)
{
float fFarClip = CPythonBackground::Instance().GetFarClip();
return Py_BuildValue("f", fFarClip);
}
PyObject * backgroundGetDistanceSetInfo(PyObject * poSelf, PyObject * poArgs)
{
int iNum;
float fStart, fEnd, fFarClip;
CPythonBackground::Instance().GetDistanceSetInfo(&iNum, &fStart, &fEnd, &fFarClip);
return Py_BuildValue("ifff", iNum, fStart, fEnd, fFarClip);
}
PyObject * backgroundSetBGLoading(PyObject * poSelf, PyObject * poArgs)
{
bool bBGLoading;
if (!PyTuple_GetBoolean(poArgs, 0, &bBGLoading))
return Py_BadArgument();
//CPythonBackground::Instance().BGLoadingEnable(bBGLoading);
return Py_BuildNone();
}
PyObject * backgroundSetRenderSort(PyObject * poSelf, PyObject * poArgs)
{
int eSort;
if (!PyTuple_GetInteger(poArgs, 0, &eSort))
return Py_BadArgument();
CPythonBackground::Instance().SetTerrainRenderSort((CMapOutdoor::ETerrainRenderSort) eSort);
return Py_BuildNone();
}
PyObject * backgroundSetTransparentTree(PyObject * poSelf, PyObject * poArgs)
{
int bTransparent;
if (!PyTuple_GetInteger(poArgs, 0, &bTransparent))
return Py_BadArgument();
CPythonBackground::Instance().SetTransparentTree(bTransparent ? true : false);
return Py_BuildNone();
}
PyObject * backgroundGlobalPositionToLocalPosition(PyObject * poSelf, PyObject * poArgs)
{
int iX;
if (!PyTuple_GetInteger(poArgs, 0, &iX))
return Py_BadArgument();
int iY;
if (!PyTuple_GetInteger(poArgs, 1, &iY))
return Py_BadArgument();
LONG lX=iX;
LONG lY=iY;
CPythonBackground& rkBG=CPythonBackground::Instance();
rkBG.GlobalPositionToLocalPosition(lX, lY);
return Py_BuildValue("ii", lX, lY);
}
PyObject * backgroundGlobalPositionToMapInfo(PyObject * poSelf, PyObject * poArgs)
{
int iX;
if (!PyTuple_GetInteger(poArgs, 0, &iX))
return Py_BadArgument();
int iY;
if (!PyTuple_GetInteger(poArgs, 1, &iY))
return Py_BadArgument();
CPythonBackground& rkBG=CPythonBackground::Instance();
CPythonBackground::TMapInfo* pkMapInfo=rkBG.GlobalPositionToMapInfo(iX, iY);
if (pkMapInfo)
return Py_BuildValue("sii", pkMapInfo->m_strName.c_str(), pkMapInfo->m_dwBaseX, pkMapInfo->m_dwBaseY);
else
return Py_BuildValue("sii", "", 0, 0);
}
PyObject * backgroundWarpTest(PyObject * poSelf, PyObject * poArgs)
{
int iX;
if (!PyTuple_GetInteger(poArgs, 0, &iX))
return Py_BadArgument();
int iY;
if (!PyTuple_GetInteger(poArgs, 1, &iY))
return Py_BadArgument();
CPythonBackground::Instance().Warp((DWORD)iX * 100 , (DWORD)iY * 100);
return Py_BuildNone();
}
PyObject * backgroundSetXMasTree(PyObject * poSelf, PyObject * poArgs)
{
int iGrade;
if (!PyTuple_GetInteger(poArgs, 0, &iGrade))
return Py_BadArgument();
CPythonBackground::Instance().SetXMaxTree(iGrade);
return Py_BuildNone();
}
PyObject * backgroundRegisterDungeonMapName(PyObject * poSelf, PyObject * poArgs)
{
char * szName;
if (!PyTuple_GetString(poArgs, 0, &szName))
return Py_BadArgument();
CPythonBackground::Instance().RegisterDungeonMapName(szName);
return Py_BuildNone();
}
PyObject * backgroundVisibleGuildArea(PyObject * poSelf, PyObject * poArgs)
{
CPythonBackground::Instance().VisibleGuildArea();
return Py_BuildNone();
}
PyObject * backgroundDisableGuildArea(PyObject * poSelf, PyObject * poArgs)
{
CPythonBackground::Instance().DisableGuildArea();
return Py_BuildNone();
}
void initBackground()
{
static PyMethodDef s_methods[] =
{
{ "IsSoftwareTiling", backgroundIsSoftwareTiling, METH_VARARGS },
{ "EnableSoftwareTiling", backgroundEnableSoftwareTiling, METH_VARARGS },
{ "EnableSnow", backgroundEnableSnow, METH_VARARGS },
{ "GlobalPositionToLocalPosition", backgroundGlobalPositionToLocalPosition, METH_VARARGS },
{ "GlobalPositionToMapInfo", backgroundGlobalPositionToMapInfo, METH_VARARGS },
{ "GetRenderShadowTime", backgroundGetRenderShadowTime, METH_VARARGS },
{ "LoadMap", backgroundLoadMap, METH_VARARGS },
{ "Destroy", backgroundDestroy, METH_VARARGS },
{ "RegisterEnvironmentData", backgroundRegisterEnvironmentData, METH_VARARGS },
{ "SetEnvironmentData", backgroundSetEnvironmentData, METH_VARARGS },
{ "GetCurrentMapName", backgroundGetCurrentMapName, METH_VARARGS },
{ "GetPickingPoint", backgroundGetPickingPoint, METH_VARARGS },
{ "BeginEnvironment", backgroundBeginEnvironment, METH_VARARGS },
{ "EndEnvironment", backgroundEndEnvironemt, METH_VARARGS },
{ "SetCharacterDirLight", backgroundSetCharacterDirLight, METH_VARARGS },
{ "SetBackgroundDirLight", backgroundSetBackgroundDirLight, METH_VARARGS },
{ "Initialize", backgroundInitialize, METH_VARARGS },
{ "Update", backgroundUpdate, METH_VARARGS },
{ "Render", backgroundRender, METH_VARARGS },
{ "RenderPCBlocker", backgroundRenderPCBlocker, METH_VARARGS },
{ "RenderCollision", backgroundRenderCollision, METH_VARARGS },
{ "RenderSky", backgroundRenderSky, METH_VARARGS },
{ "RenderCloud", backgroundRenderCloud, METH_VARARGS },
{ "RenderWater", backgroundRenderWater, METH_VARARGS },
{ "RenderEffect", backgroundRenderEffect, METH_VARARGS },
{ "RenderBeforeLensFlare", backgroundRenderBeforeLensFlare, METH_VARARGS },
{ "RenderAfterLensFlare", backgroundRenderAfterLensFlare, METH_VARARGS },
{ "RenderCharacterShadowToTexture", backgroundRenderCharacterShadowToTexture, METH_VARARGS },
{ "RenderDungeon", backgroundRenderDungeon, METH_VARARGS },
{ "GetHeight", backgroundGetHeight, METH_VARARGS },
{ "SetShadowLevel", backgroundSetShadowLevel, METH_VARARGS },
{ "SetVisiblePart", backgroundSetVisiblePart, METH_VARARGS },
{ "GetShadowMapColor", backgroundGetShadowMapcolor, METH_VARARGS },
{ "SetSplatLimit", backgroundSetSpaltLimit, METH_VARARGS },
{ "GetRenderedSplatNum", backgroundGetRenderedSplatNum, METH_VARARGS },
{ "GetRenderedGraphicThingInstanceNum", backgroundGetRenderedGTINum, METH_VARARGS },
{ "SelectViewDistanceNum", backgroundSelectViewDistanceNum, METH_VARARGS },
{ "SetViewDistanceSet", backgroundSetViewDistanceSet, METH_VARARGS },
{ "GetFarClip", backgroundGetFarClip, METH_VARARGS },
{ "GetDistanceSetInfo", backgroundGetDistanceSetInfo, METH_VARARGS },
{ "SetBGLoading", backgroundSetBGLoading, METH_VARARGS },
{ "SetRenderSort", backgroundSetRenderSort, METH_VARARGS },
{ "SetTransparentTree", backgroundSetTransparentTree, METH_VARARGS },
{ "SetXMasTree", backgroundSetXMasTree, METH_VARARGS },
{ "RegisterDungeonMapName", backgroundRegisterDungeonMapName, METH_VARARGS },
{ "VisibleGuildArea", backgroundVisibleGuildArea, METH_VARARGS },
{ "DisableGuildArea", backgroundDisableGuildArea, METH_VARARGS },
{ "WarpTest", backgroundWarpTest, METH_VARARGS },
{ NULL, NULL, NULL },
};
PyObject * poModule = Py_InitModule("background", s_methods);
PyModule_AddIntConstant(poModule, "PART_SKY", CMapOutdoor::PART_SKY);
PyModule_AddIntConstant(poModule, "PART_TREE", CMapOutdoor::PART_TREE);
PyModule_AddIntConstant(poModule, "PART_CLOUD", CMapOutdoor::PART_CLOUD);
PyModule_AddIntConstant(poModule, "PART_WATER", CMapOutdoor::PART_WATER);
PyModule_AddIntConstant(poModule, "PART_OBJECT", CMapOutdoor::PART_OBJECT);
PyModule_AddIntConstant(poModule, "PART_TERRAIN", CMapOutdoor::PART_TERRAIN);
PyModule_AddIntConstant(poModule, "SKY_RENDER_MODE_DEFAULT", CSkyObject::SKY_RENDER_MODE_DEFAULT);
PyModule_AddIntConstant(poModule, "SKY_RENDER_MODE_DIFFUSE", CSkyObject::SKY_RENDER_MODE_DIFFUSE);
PyModule_AddIntConstant(poModule, "SKY_RENDER_MODE_TEXTURE", CSkyObject::SKY_RENDER_MODE_TEXTURE);
PyModule_AddIntConstant(poModule, "SKY_RENDER_MODE_MODULATE", CSkyObject::SKY_RENDER_MODE_MODULATE);
PyModule_AddIntConstant(poModule, "SKY_RENDER_MODE_MODULATE2X", CSkyObject::SKY_RENDER_MODE_MODULATE2X);
PyModule_AddIntConstant(poModule, "SKY_RENDER_MODE_MODULATE4X", CSkyObject::SKY_RENDER_MODE_MODULATE4X);
PyModule_AddIntConstant(poModule, "SHADOW_NONE", CPythonBackground::SHADOW_NONE);
PyModule_AddIntConstant(poModule, "SHADOW_GROUND", CPythonBackground::SHADOW_GROUND);
PyModule_AddIntConstant(poModule, "SHADOW_GROUND_AND_SOLO", CPythonBackground::SHADOW_GROUND_AND_SOLO);
PyModule_AddIntConstant(poModule, "SHADOW_ALL", CPythonBackground::SHADOW_ALL);
PyModule_AddIntConstant(poModule, "SHADOW_ALL_HIGH", CPythonBackground::SHADOW_ALL_HIGH);
PyModule_AddIntConstant(poModule, "SHADOW_ALL_MAX", CPythonBackground::SHADOW_ALL_MAX);
PyModule_AddIntConstant(poModule, "DISTANCE0", CPythonBackground::DISTANCE0);
PyModule_AddIntConstant(poModule, "DISTANCE1", CPythonBackground::DISTANCE1);
PyModule_AddIntConstant(poModule, "DISTANCE2", CPythonBackground::DISTANCE2);
PyModule_AddIntConstant(poModule, "DISTANCE3", CPythonBackground::DISTANCE3);
PyModule_AddIntConstant(poModule, "DISTANCE4", CPythonBackground::DISTANCE4);
PyModule_AddIntConstant(poModule, "DISTANCE_SORT", CMapOutdoor::DISTANCE_SORT);
PyModule_AddIntConstant(poModule, "TEXTURE_SORT", CMapOutdoor::TEXTURE_SORT);
}
@@ -58,6 +58,7 @@ void initnet();
void initeffect();
void initfly();
void initskill();
void initBackground();
void initServerStateChecker();
extern const std::string& ApplicationStringTable_GetString(DWORD dwID);
+74 -4
View File
@@ -662,10 +662,71 @@ typedef struct _D3DCAPS8
// upcasts 40250 relies on (texture -> base texture) compile; of the resources only the buffers carry
// methods (Lock/Unlock, platform/EterLib/CpuBuffer.h).
struct IDirect3D8;
struct IDirect3DResource8 {};
struct IDirect3DBaseTexture8 : IDirect3DResource8 {};
struct IDirect3DTexture8 : IDirect3DBaseTexture8 {};
struct IDirect3DSurface8 : IDirect3DResource8 {};
typedef enum _D3DRESOURCETYPE
{
D3DRTYPE_SURFACE = 1,
D3DRTYPE_VOLUME = 2,
D3DRTYPE_TEXTURE = 3,
D3DRTYPE_VOLUMETEXTURE = 4,
D3DRTYPE_CUBETEXTURE = 5,
D3DRTYPE_VERTEXBUFFER = 6,
D3DRTYPE_INDEXBUFFER = 7,
D3DRTYPE_FORCE_DWORD = 0x7fffffff
} D3DRESOURCETYPE;
typedef struct _D3DLOCKED_RECT
{
INT Pitch;
void* pBits;
} D3DLOCKED_RECT;
typedef struct _D3DSURFACE_DESC
{
D3DFORMAT Format;
D3DRESOURCETYPE Type;
DWORD Usage;
D3DPOOL Pool;
UINT Size;
D3DMULTISAMPLE_TYPE MultiSampleType;
UINT Width;
UINT Height;
} D3DSURFACE_DESC;
typedef struct _D3DRECT
{
LONG x1, y1, x2, y2;
} D3DRECT;
#define D3DCLEAR_TARGET 0x00000001l
#define D3DCLEAR_ZBUFFER 0x00000002l
#define D3DCLEAR_STENCIL 0x00000004l
// PORT: the resource interfaces carry virtual defaults so the platform's texture handles
// (GrpImageTexture's MemoryTexture/FileTexture, owned by their own registries) need not implement
// them; device-created resources (RecordingDevice CreateTexture/...) override AddRef/Release.
struct IDirect3DResource8
{
virtual ~IDirect3DResource8() = default;
virtual ULONG AddRef() { return 1; }
virtual ULONG Release() { return 1; }
};
struct IDirect3DSurface8 : IDirect3DResource8
{
virtual HRESULT GetDesc(D3DSURFACE_DESC* pDesc) { return E_FAIL; }
virtual HRESULT LockRect(D3DLOCKED_RECT* pLockedRect, const RECT* pRect, DWORD Flags) { return E_FAIL; }
virtual HRESULT UnlockRect() { return E_FAIL; }
};
struct IDirect3DBaseTexture8 : IDirect3DResource8
{
virtual DWORD GetLevelCount() { return 1; }
};
struct IDirect3DTexture8 : IDirect3DBaseTexture8
{
virtual HRESULT GetLevelDesc(UINT Level, D3DSURFACE_DESC* pDesc) { return E_FAIL; }
virtual HRESULT GetSurfaceLevel(UINT Level, IDirect3DSurface8** ppSurfaceLevel) { return E_FAIL; }
virtual HRESULT LockRect(UINT Level, D3DLOCKED_RECT* pLockedRect, const RECT* pRect, DWORD Flags) { return E_FAIL; }
virtual HRESULT UnlockRect(UINT Level) { return E_FAIL; }
};
struct IDirect3DVertexBuffer8 : IDirect3DResource8
{
virtual ~IDirect3DVertexBuffer8() = default;
@@ -695,6 +756,15 @@ struct IDirect3DDevice8
virtual HRESULT GetTransform(D3DTRANSFORMSTATETYPE State, D3DMATRIX* pMatrix) = 0;
virtual HRESULT SetMaterial(const D3DMATERIAL8* pMaterial) = 0;
virtual HRESULT SetLight(DWORD Index, const D3DLIGHT8* pLight) = 0;
virtual HRESULT LightEnable(DWORD Index, BOOL Enable) = 0;
virtual HRESULT CreateTexture(UINT Width, UINT Height, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DTexture8** ppTexture) = 0;
virtual HRESULT CreateVertexBuffer(UINT Length, DWORD Usage, DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer8** ppVertexBuffer) = 0;
virtual HRESULT CreateIndexBuffer(UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DIndexBuffer8** ppIndexBuffer) = 0;
virtual HRESULT CreateDepthStencilSurface(UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, IDirect3DSurface8** ppSurface) = 0;
virtual HRESULT GetRenderTarget(IDirect3DSurface8** ppRenderTarget) = 0;
virtual HRESULT GetDepthStencilSurface(IDirect3DSurface8** ppZStencilSurface) = 0;
virtual HRESULT SetRenderTarget(IDirect3DSurface8* pRenderTarget, IDirect3DSurface8* pNewZStencil) = 0;
virtual HRESULT Clear(DWORD Count, const D3DRECT* pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil) = 0;
virtual HRESULT SetRenderState(D3DRENDERSTATETYPE State, DWORD Value) = 0;
virtual HRESULT SetTexture(DWORD Stage, IDirect3DBaseTexture8* pTexture) = 0;
virtual HRESULT SetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value) = 0;
+10
View File
@@ -411,6 +411,16 @@ inline FLOAT D3DXPlaneDotCoord(const D3DXPLANE* pP, const D3DXVECTOR3* pV)
{
return pP->a * pV->x + pP->b * pV->y + pP->c * pV->z + pP->d;
}
inline D3DXPLANE* D3DXPlaneNormalize(D3DXPLANE* pOut, const D3DXPLANE* pP)
{
const FLOAT length = sqrtf(pP->a * pP->a + pP->b * pP->b + pP->c * pP->c);
const FLOAT inv = length > 0.0f ? 1.0f / length : 0.0f;
pOut->a = pP->a * inv;
pOut->b = pP->b * inv;
pOut->c = pP->c * inv;
pOut->d = pP->d * inv;
return pOut;
}
// --- ID3DXMatrixStack --- (the D3DX8 interface, as a plain class: the Local variants pre-multiply)
struct ID3DXMatrixStack
+28
View File
@@ -65,9 +65,37 @@ void fill_find_data(const std::string& path, WIN32_FIND_DATA* data)
const size_t slash = path.find_last_of('/');
const std::string name = path.substr(slash == std::string::npos ? 0 : slash + 1);
std::snprintf(data->cFileName, sizeof(data->cFileName), "%s", name.c_str());
struct stat st{};
data->dwFileAttributes = stat(path.c_str(), &st) == 0 && S_ISDIR(st.st_mode) ? FILE_ATTRIBUTE_DIRECTORY
: FILE_ATTRIBUTE_NORMAL;
}
}
BOOL CopyFile(LPCSTR existing_path, LPCSTR new_path, BOOL fail_if_exists)
{
if (!existing_path || !new_path)
return FALSE;
if (fail_if_exists && _access(new_path, 0) == 0)
return FALSE;
FILE* in = std::fopen(existing_path, "rb");
if (!in)
return FALSE;
FILE* out = std::fopen(new_path, "wb");
if (!out)
{
std::fclose(in);
return FALSE;
}
char buffer[65536];
size_t n;
bool ok = true;
while ((n = std::fread(buffer, 1, sizeof(buffer), in)) > 0)
ok = ok && std::fwrite(buffer, 1, n, out) == n;
std::fclose(in);
ok = std::fclose(out) == 0 && ok;
return ok ? TRUE : FALSE;
}
HANDLE FindFirstFile(const char* pattern, WIN32_FIND_DATA* data)
{
if (!pattern || !data)
+6 -1
View File
@@ -61,8 +61,11 @@ int _snprintf(char* buf, size_t count, const char* fmt, ...)
// the MSVC modes 0 (exists), 2 (write), 4 (read), 6 (read/write).
BOOL CreateDirectory(LPCSTR path, void* security_attributes);
BOOL DeleteFile(LPCSTR path);
BOOL CopyFile(LPCSTR existing_path, LPCSTR new_path, BOOL fail_if_exists);
int _access(const char* path, int mode);
struct WIN32_FIND_DATA { char cFileName[MAX_PATH]; };
#define FILE_ATTRIBUTE_DIRECTORY 0x00000010
#define FILE_ATTRIBUTE_NORMAL 0x00000080
struct WIN32_FIND_DATA { DWORD dwFileAttributes; char cFileName[MAX_PATH]; };
#define INVALID_HANDLE_VALUE (reinterpret_cast<HANDLE>(static_cast<intptr_t>(-1)))
HANDLE FindFirstFile(const char* pattern, WIN32_FIND_DATA* data);
BOOL FindNextFile(HANDLE handle, WIN32_FIND_DATA* data);
@@ -72,6 +75,8 @@ void Sleep(DWORD milliseconds);
// winmm `timeGetTime`: milliseconds since system start, wrapping at 2^32.
DWORD timeGetTime();
DWORD GetTickCount();
// winbase.h: #define GetCurrentTime() GetTickCount()
#define GetCurrentTime() GetTickCount()
// Recursive, like the Win32 critical section. Storage holds a std::recursive_mutex.
struct CRITICAL_SECTION