forked from metin2/client
1594 lines
42 KiB
C++
1594 lines
42 KiB
C++
|
#include "StdAfx.h"
|
|||
|
#include "../eterlib/StateManager.h"
|
|||
|
#include "../eterlib/Camera.h"
|
|||
|
#include "../PRTerrainLib/StdAfx.h"
|
|||
|
#include "../EffectLib/EffectManager.h"
|
|||
|
|
|||
|
#include "MapOutdoor.h"
|
|||
|
#include "TerrainPatch.h"
|
|||
|
#include "AreaTerrain.h"
|
|||
|
|
|||
|
//#define USE_LEVEL
|
|||
|
// unsigned int uiNumSplat;
|
|||
|
|
|||
|
struct FGetObjectHeight
|
|||
|
{
|
|||
|
bool m_bHeightFound;
|
|||
|
float m_fReturnHeight;
|
|||
|
float m_fRequestX, m_fRequestY;
|
|||
|
FGetObjectHeight(float fRequestX, float fRequestY)
|
|||
|
{
|
|||
|
m_fRequestX=fRequestX;
|
|||
|
m_fRequestY=fRequestY;
|
|||
|
m_bHeightFound=false;
|
|||
|
m_fReturnHeight=0.0f;
|
|||
|
}
|
|||
|
void operator () (CGraphicObjectInstance * pObject)
|
|||
|
{
|
|||
|
if (pObject->GetObjectHeight(m_fRequestX, m_fRequestY, &m_fReturnHeight))
|
|||
|
{
|
|||
|
#ifdef SPHERELIB_STRICT
|
|||
|
printf("FIND %f\n", m_fReturnHeight);
|
|||
|
#endif
|
|||
|
m_bHeightFound = true;
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
struct FGetPickingPoint
|
|||
|
{
|
|||
|
D3DXVECTOR3 m_v3Start;
|
|||
|
D3DXVECTOR3 m_v3Dir;
|
|||
|
D3DXVECTOR3 m_v3PickingPoint;
|
|||
|
bool m_bPicked;
|
|||
|
|
|||
|
FGetPickingPoint(D3DXVECTOR3 & v3Start, D3DXVECTOR3 & v3Dir) : m_v3Start(v3Start), m_v3Dir(v3Dir), m_bPicked(false) {}
|
|||
|
void operator() (CGraphicObjectInstance * pInstance)
|
|||
|
{
|
|||
|
if( pInstance && pInstance->GetType() == CGraphicThingInstance::ID )
|
|||
|
{
|
|||
|
CGraphicThingInstance * pThing = (CGraphicThingInstance *)pInstance;
|
|||
|
if (!pThing->IsObjectHeight())
|
|||
|
return;
|
|||
|
|
|||
|
float fX, fY, fZ;
|
|||
|
if (pThing->Picking(m_v3Start, m_v3Dir, fX, fY))
|
|||
|
{
|
|||
|
if (pThing->GetObjectHeight(fX, -fY, &fZ))
|
|||
|
{
|
|||
|
m_v3PickingPoint.x = fX;
|
|||
|
m_v3PickingPoint.y = fY;
|
|||
|
m_v3PickingPoint.z = fZ;
|
|||
|
m_bPicked = true;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
CMapOutdoor::CMapOutdoor()
|
|||
|
{
|
|||
|
CGraphicImage * pAlphaFogImage = (CGraphicImage *) CResourceManager::Instance().GetResourcePointer("D:/ymir work/special/fog.tga");
|
|||
|
CGraphicImage * pAttrImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer("d:/ymir work/special/white.dds");
|
|||
|
CGraphicImage * pBuildTransparentImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer("d:/ymir Work/special/PCBlockerAlpha.dds");
|
|||
|
m_AlphaFogImageInstance.SetImagePointer(pAlphaFogImage);
|
|||
|
m_attrImageInstance.SetImagePointer(pAttrImage);
|
|||
|
m_BuildingTransparentImageInstance.SetImagePointer(pBuildTransparentImage);
|
|||
|
|
|||
|
Initialize();
|
|||
|
|
|||
|
__SoftwareTransformPatch_Initialize();
|
|||
|
__SoftwareTransformPatch_Create();
|
|||
|
}
|
|||
|
|
|||
|
CMapOutdoor::~CMapOutdoor()
|
|||
|
{
|
|||
|
__SoftwareTransformPatch_Destroy();
|
|||
|
|
|||
|
// 2004.10.14.myevan.TEMP_CAreaLoaderThread
|
|||
|
//ms_AreaLoaderThread.Shutdown();
|
|||
|
Destroy();
|
|||
|
}
|
|||
|
|
|||
|
bool CMapOutdoor::Initialize()
|
|||
|
{
|
|||
|
BYTE i;
|
|||
|
for (i = 0; i < AROUND_AREA_NUM; ++i)
|
|||
|
{
|
|||
|
m_pArea[i] = NULL;
|
|||
|
m_pTerrain[i] = NULL;
|
|||
|
}
|
|||
|
|
|||
|
m_pTerrainPatchProxyList = NULL;
|
|||
|
|
|||
|
m_lViewRadius = 0L;
|
|||
|
m_fHeightScale = 0.0f;
|
|||
|
|
|||
|
m_sTerrainCountX = m_sTerrainCountY = 0;
|
|||
|
|
|||
|
m_CurCoordinate.m_sTerrainCoordX = -1;
|
|||
|
m_CurCoordinate.m_sTerrainCoordY = -1;
|
|||
|
m_PrevCoordinate.m_sTerrainCoordX = -1;
|
|||
|
m_PrevCoordinate.m_sTerrainCoordY = -1;
|
|||
|
|
|||
|
m_EntryPointMap.clear();
|
|||
|
|
|||
|
m_lCenterX = m_lCenterY = 0;
|
|||
|
m_lOldReadX = m_lOldReadY = -1;
|
|||
|
|
|||
|
#ifdef WORLD_EDITOR
|
|||
|
m_pwIndices = NULL;
|
|||
|
#else
|
|||
|
memset(m_pwaIndices, 0, sizeof(m_pwaIndices));
|
|||
|
for (i = 0; i < TERRAINPATCH_LODMAX; ++i)
|
|||
|
m_IndexBuffer[i].Destroy();
|
|||
|
#endif
|
|||
|
|
|||
|
m_bSettingTerrainVisible = false;
|
|||
|
m_bDrawWireFrame = false;
|
|||
|
m_bDrawShadow = false;
|
|||
|
m_bDrawChrShadow = false;
|
|||
|
|
|||
|
m_iSplatLimit = 50000;
|
|||
|
|
|||
|
m_wPatchCount = 0;
|
|||
|
|
|||
|
m_pRootNode = NULL;
|
|||
|
|
|||
|
//////////////////////////////////////////////////////////////////////////
|
|||
|
// Character Shadow
|
|||
|
m_lpCharacterShadowMapTexture = NULL;
|
|||
|
m_lpCharacterShadowMapRenderTargetSurface = NULL;
|
|||
|
m_lpCharacterShadowMapDepthSurface = NULL;
|
|||
|
|
|||
|
m_lpBackupRenderTargetSurface = NULL;
|
|||
|
m_lpBackupDepthSurface = NULL;
|
|||
|
// Character Shadow
|
|||
|
//////////////////////////////////////////////////////////////////////////
|
|||
|
|
|||
|
m_iRenderedPatchNum = 0;
|
|||
|
m_iRenderedSplatNum = 0;
|
|||
|
|
|||
|
//////////////////////////////////////////////////////////////////////////
|
|||
|
m_fOpaqueWaterDepth = 400.0f;
|
|||
|
|
|||
|
//////////////////////////////////////////////////////////////////////////
|
|||
|
m_TerrainVector.clear();
|
|||
|
m_TerrainDeleteVector.clear();
|
|||
|
m_TerrainLoadRequestVector.clear();
|
|||
|
m_TerrainLoadWaitVector.clear();
|
|||
|
|
|||
|
m_AreaVector.clear();
|
|||
|
m_AreaDeleteVector.clear();
|
|||
|
m_AreaLoadRequestVector.clear();
|
|||
|
m_AreaLoadWaitVector.clear();
|
|||
|
//////////////////////////////////////////////////////////////////////////
|
|||
|
|
|||
|
m_PatchVector.clear();
|
|||
|
|
|||
|
// 2004.10.14.myevan.TEMP_CAreaLoaderThread
|
|||
|
//m_bBGLoadingEnable = false;
|
|||
|
m_eTerrainRenderSort = DISTANCE_SORT;
|
|||
|
|
|||
|
D3DXMatrixIdentity(&m_matWorldForCommonUse);
|
|||
|
|
|||
|
InitializeFog();
|
|||
|
InitializeVisibleParts();
|
|||
|
|
|||
|
m_dwBaseX = 0;
|
|||
|
m_dwBaseY = 0;
|
|||
|
|
|||
|
m_settings_envDataName = "";
|
|||
|
m_bShowEntirePatchTextureCount = false;
|
|||
|
m_bTransparentTree = true;
|
|||
|
|
|||
|
CMapBase::Clear();
|
|||
|
|
|||
|
__XMasTree_Initialize();
|
|||
|
SpecialEffect_Destroy();
|
|||
|
|
|||
|
m_bEnableTerrainOnlyForHeight = FALSE;
|
|||
|
m_bEnablePortal = FALSE;
|
|||
|
|
|||
|
m_wShadowMapSize = 512;
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
bool CMapOutdoor::Destroy()
|
|||
|
{
|
|||
|
m_bEnableTerrainOnlyForHeight = FALSE;
|
|||
|
m_bEnablePortal = FALSE;
|
|||
|
|
|||
|
XMasTree_Destroy();
|
|||
|
|
|||
|
DestroyTerrain();
|
|||
|
DestroyArea();
|
|||
|
DestroyTerrainPatchProxyList();
|
|||
|
|
|||
|
FreeQuadTree();
|
|||
|
ReleaseCharacterShadowTexture();
|
|||
|
|
|||
|
CTerrain::DestroySystem();
|
|||
|
CArea::DestroySystem();
|
|||
|
|
|||
|
RemoveAllMonsterAreaInfo();
|
|||
|
|
|||
|
m_rkList_kGuildArea.clear();
|
|||
|
m_kPool_kMonsterAreaInfo.Destroy();
|
|||
|
m_AlphaFogImageInstance.Destroy();
|
|||
|
|
|||
|
CSpeedTreeForestDirectX8::Instance().Clear();
|
|||
|
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
void CMapOutdoor::Clear()
|
|||
|
{
|
|||
|
UnloadWaterTexture();
|
|||
|
Destroy(); // <20><><EFBFBD><EFBFBD>
|
|||
|
Initialize(); // <20>ʱ<EFBFBD>ȭ
|
|||
|
}
|
|||
|
|
|||
|
bool CMapOutdoor::SetTerrainCount(short sTerrainCountX, short sTerrainCountY)
|
|||
|
{
|
|||
|
if (0 == sTerrainCountX || MAX_MAPSIZE < sTerrainCountX)
|
|||
|
return false;
|
|||
|
|
|||
|
if (0 == sTerrainCountY || MAX_MAPSIZE < sTerrainCountY)
|
|||
|
return false;
|
|||
|
|
|||
|
m_sTerrainCountX = sTerrainCountX;
|
|||
|
m_sTerrainCountY = sTerrainCountY;
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
void CMapOutdoor::OnBeginEnvironment()
|
|||
|
{
|
|||
|
if (!mc_pEnvironmentData)
|
|||
|
return;
|
|||
|
|
|||
|
CSpeedTreeForestDirectX8& rkForest=CSpeedTreeForestDirectX8::Instance();
|
|||
|
rkForest.SetFog(
|
|||
|
mc_pEnvironmentData->GetFogNearDistance(),
|
|||
|
mc_pEnvironmentData->GetFogFarDistance()
|
|||
|
);
|
|||
|
|
|||
|
const D3DLIGHT8& c_rkLight = mc_pEnvironmentData->DirLights[ENV_DIRLIGHT_CHARACTER];
|
|||
|
rkForest.SetLight(
|
|||
|
(const float *)&c_rkLight.Direction,
|
|||
|
(const float *)&c_rkLight.Ambient,
|
|||
|
(const float *)&c_rkLight.Diffuse);
|
|||
|
|
|||
|
rkForest.SetWindStrength(mc_pEnvironmentData->fWindStrength);
|
|||
|
}
|
|||
|
|
|||
|
void CMapOutdoor::OnSetEnvironmentDataPtr()
|
|||
|
{
|
|||
|
SetEnvironmentScreenFilter();
|
|||
|
SetEnvironmentSkyBox();
|
|||
|
SetEnvironmentLensFlare();
|
|||
|
}
|
|||
|
|
|||
|
void CMapOutdoor::OnResetEnvironmentDataPtr()
|
|||
|
{
|
|||
|
m_SkyBox.Unload();
|
|||
|
SetEnvironmentScreenFilter();
|
|||
|
SetEnvironmentSkyBox();
|
|||
|
SetEnvironmentLensFlare();
|
|||
|
}
|
|||
|
|
|||
|
void CMapOutdoor::SetEnvironmentScreenFilter()
|
|||
|
{
|
|||
|
if (!mc_pEnvironmentData)
|
|||
|
return;
|
|||
|
|
|||
|
m_ScreenFilter.SetEnable(mc_pEnvironmentData->bFilteringEnable);
|
|||
|
m_ScreenFilter.SetBlendType(mc_pEnvironmentData->byFilteringAlphaSrc, mc_pEnvironmentData->byFilteringAlphaDest);
|
|||
|
m_ScreenFilter.SetColor(mc_pEnvironmentData->FilteringColor);
|
|||
|
}
|
|||
|
|
|||
|
void CMapOutdoor::SetEnvironmentSkyBox()
|
|||
|
{
|
|||
|
if (!mc_pEnvironmentData)
|
|||
|
return;
|
|||
|
|
|||
|
m_SkyBox.SetSkyBoxScale(mc_pEnvironmentData->v3SkyBoxScale);
|
|||
|
m_SkyBox.SetGradientLevel(mc_pEnvironmentData->bySkyBoxGradientLevelUpper, mc_pEnvironmentData->bySkyBoxGradientLevelLower);
|
|||
|
m_SkyBox.SetRenderMode( (mc_pEnvironmentData->bSkyBoxTextureRenderMode == TRUE) ? CSkyObject::SKY_RENDER_MODE_TEXTURE : CSkyObject::SKY_RENDER_MODE_DIFFUSE);
|
|||
|
|
|||
|
for( int i = 0; i < 6; ++i )
|
|||
|
{
|
|||
|
if (!mc_pEnvironmentData->strSkyBoxFaceFileName[i].empty())
|
|||
|
m_SkyBox.SetFaceTexture( mc_pEnvironmentData->strSkyBoxFaceFileName[i].c_str(), i );
|
|||
|
}
|
|||
|
|
|||
|
if (!mc_pEnvironmentData->strCloudTextureFileName.empty())
|
|||
|
m_SkyBox.SetCloudTexture(mc_pEnvironmentData->strCloudTextureFileName.c_str());
|
|||
|
|
|||
|
m_SkyBox.SetCloudScale(mc_pEnvironmentData->v2CloudScale);
|
|||
|
m_SkyBox.SetCloudHeight(mc_pEnvironmentData->fCloudHeight);
|
|||
|
m_SkyBox.SetCloudTextureScale(mc_pEnvironmentData->v2CloudTextureScale);
|
|||
|
m_SkyBox.SetCloudScrollSpeed(mc_pEnvironmentData->v2CloudSpeed);
|
|||
|
m_SkyBox.Refresh();
|
|||
|
|
|||
|
// Temporary
|
|||
|
m_SkyBox.SetCloudColor(mc_pEnvironmentData->CloudGradientColor, mc_pEnvironmentData->CloudGradientColor, 1);
|
|||
|
|
|||
|
if (!mc_pEnvironmentData->SkyBoxGradientColorVector.empty())
|
|||
|
m_SkyBox.SetSkyColor(mc_pEnvironmentData->SkyBoxGradientColorVector, mc_pEnvironmentData->SkyBoxGradientColorVector, 1);
|
|||
|
// Temporary
|
|||
|
|
|||
|
m_SkyBox.StartTransition();
|
|||
|
}
|
|||
|
|
|||
|
void CMapOutdoor::SetEnvironmentLensFlare()
|
|||
|
{
|
|||
|
if (!mc_pEnvironmentData)
|
|||
|
return;
|
|||
|
|
|||
|
m_LensFlare.CharacterizeFlare(mc_pEnvironmentData->bLensFlareEnable == 1 ? true : false,
|
|||
|
mc_pEnvironmentData->bMainFlareEnable == 1 ? true : false,
|
|||
|
mc_pEnvironmentData->fLensFlareMaxBrightness,
|
|||
|
mc_pEnvironmentData->LensFlareBrightnessColor);
|
|||
|
|
|||
|
m_LensFlare.Initialize("d:/ymir work/environment");
|
|||
|
|
|||
|
if (!mc_pEnvironmentData->strMainFlareTextureFileName.empty())
|
|||
|
m_LensFlare.SetMainFlare(mc_pEnvironmentData->strMainFlareTextureFileName.c_str(),
|
|||
|
mc_pEnvironmentData->fMainFlareSize);
|
|||
|
}
|
|||
|
|
|||
|
void CMapOutdoor::SetWireframe(bool bWireFrame)
|
|||
|
{
|
|||
|
m_bDrawWireFrame = bWireFrame;
|
|||
|
}
|
|||
|
|
|||
|
bool CMapOutdoor::IsWireframe()
|
|||
|
{
|
|||
|
return m_bDrawWireFrame;
|
|||
|
}
|
|||
|
|
|||
|
//////////////////////////////////////////////////////////////////////////
|
|||
|
// TerrainPatchList
|
|||
|
//////////////////////////////////////////////////////////////////////////
|
|||
|
void CMapOutdoor::CreateTerrainPatchProxyList()
|
|||
|
{
|
|||
|
m_wPatchCount = ((m_lViewRadius * 2) / TERRAIN_PATCHSIZE) + 2;
|
|||
|
|
|||
|
m_pTerrainPatchProxyList = new CTerrainPatchProxy[m_wPatchCount * m_wPatchCount];
|
|||
|
|
|||
|
m_iPatchTerrainVertexCount = (TERRAIN_PATCHSIZE+1)*(TERRAIN_PATCHSIZE+1);
|
|||
|
m_iPatchWaterVertexCount = TERRAIN_PATCHSIZE * TERRAIN_PATCHSIZE * 6;
|
|||
|
m_iPatchTerrainVertexSize = 24;
|
|||
|
m_iPatchWaterVertexSize = 16;
|
|||
|
|
|||
|
SetIndexBuffer();
|
|||
|
}
|
|||
|
|
|||
|
void CMapOutdoor::DestroyTerrainPatchProxyList()
|
|||
|
{
|
|||
|
if (m_pTerrainPatchProxyList)
|
|||
|
{
|
|||
|
delete [] m_pTerrainPatchProxyList;
|
|||
|
m_pTerrainPatchProxyList = NULL;
|
|||
|
}
|
|||
|
|
|||
|
#ifdef WORLD_EDITOR
|
|||
|
m_IndexBuffer.Destroy();
|
|||
|
#else
|
|||
|
for (int i = 0; i < TERRAINPATCH_LODMAX; ++i)
|
|||
|
m_IndexBuffer[i].Destroy();
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
//////////////////////////////////////////////////////////////////////////
|
|||
|
// Area
|
|||
|
//////////////////////////////////////////////////////////////////////////
|
|||
|
|
|||
|
void CMapOutdoor::EnablePortal(bool bFlag)
|
|||
|
{
|
|||
|
m_bEnablePortal = bFlag;
|
|||
|
|
|||
|
for (int i = 0; i < AROUND_AREA_NUM; ++i)
|
|||
|
if (m_pArea[i])
|
|||
|
m_pArea[i]->EnablePortal(bFlag);
|
|||
|
}
|
|||
|
|
|||
|
void CMapOutdoor::DestroyArea()
|
|||
|
{
|
|||
|
m_AreaVector.clear();
|
|||
|
m_AreaDeleteVector.clear();
|
|||
|
|
|||
|
CArea::ms_kPool.FreeAll();
|
|||
|
|
|||
|
for (int i = 0; i < AROUND_AREA_NUM; ++i)
|
|||
|
m_pArea[i] = NULL;
|
|||
|
}
|
|||
|
|
|||
|
//////////////////////////////////////////////////////////////////////////
|
|||
|
// Terrain
|
|||
|
//////////////////////////////////////////////////////////////////////////
|
|||
|
|
|||
|
void CMapOutdoor::DestroyTerrain()
|
|||
|
{
|
|||
|
m_TerrainVector.clear();
|
|||
|
m_TerrainDeleteVector.clear();
|
|||
|
|
|||
|
CTerrain::ms_kPool.FreeAll();
|
|||
|
for (int i=0; i < AROUND_AREA_NUM; ++i)
|
|||
|
m_pTerrain[i] = NULL;
|
|||
|
}
|
|||
|
|
|||
|
//////////////////////////////////////////////////////////////////////////
|
|||
|
// New
|
|||
|
//////////////////////////////////////////////////////////////////////////
|
|||
|
|
|||
|
bool CMapOutdoor::GetTerrainNum(float fx, float fy, BYTE * pbyTerrainNum)
|
|||
|
{
|
|||
|
if (fy < 0)
|
|||
|
fy = -fy;
|
|||
|
|
|||
|
int ix, iy;
|
|||
|
|
|||
|
PR_FLOAT_TO_INT(fx, ix);
|
|||
|
PR_FLOAT_TO_INT(fy, iy);
|
|||
|
|
|||
|
WORD wTerrainNumX = ix / (CTerrainImpl::TERRAIN_XSIZE);
|
|||
|
WORD wTerrainNumY = iy / (CTerrainImpl::TERRAIN_YSIZE);
|
|||
|
|
|||
|
return GetTerrainNumFromCoord(wTerrainNumX, wTerrainNumY, pbyTerrainNum);
|
|||
|
}
|
|||
|
|
|||
|
bool CMapOutdoor::GetPickingPoint(D3DXVECTOR3 * v3IntersectPt)
|
|||
|
{
|
|||
|
return GetPickingPointWithRay(ms_Ray, v3IntersectPt);
|
|||
|
}
|
|||
|
|
|||
|
bool CMapOutdoor::__PickTerrainHeight(float& fPos, const D3DXVECTOR3& v3Start, const D3DXVECTOR3& v3End, float fStep, float fRayRange, float fLimitRange, D3DXVECTOR3* pv3Pick)
|
|||
|
{
|
|||
|
CTerrain * pTerrain;
|
|||
|
|
|||
|
D3DXVECTOR3 v3CurPos;
|
|||
|
|
|||
|
float fRayRangeInv=1.0f/fRayRange;
|
|||
|
while (fPos < fRayRange && fPos<fLimitRange)
|
|||
|
{
|
|||
|
D3DXVec3Lerp(&v3CurPos, &v3Start, &v3End, fPos*fRayRangeInv);
|
|||
|
BYTE byTerrainNum;
|
|||
|
float fMultiplier = 1.0f;
|
|||
|
if (GetTerrainNum(v3CurPos.x, v3CurPos.y, &byTerrainNum))
|
|||
|
{
|
|||
|
if (GetTerrainPointer(byTerrainNum, &pTerrain))
|
|||
|
{
|
|||
|
int ix, iy;
|
|||
|
PR_FLOAT_TO_INT(v3CurPos.x, ix);
|
|||
|
PR_FLOAT_TO_INT(fabs(v3CurPos.y), iy);
|
|||
|
float fMapHeight = pTerrain->GetHeight(ix, iy);
|
|||
|
if ( fMapHeight >= v3CurPos.z)
|
|||
|
{
|
|||
|
*pv3Pick = v3CurPos;
|
|||
|
return true;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
fMultiplier = fMAX(1.0f, 0.01f * ( v3CurPos.z - fMapHeight ) );
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
fPos += fStep * fMultiplier;
|
|||
|
}
|
|||
|
|
|||
|
return false;
|
|||
|
}
|
|||
|
bool CMapOutdoor::GetPickingPointWithRay(const CRay & rRay, D3DXVECTOR3 * v3IntersectPt)
|
|||
|
{
|
|||
|
bool bObjectPick = false;
|
|||
|
bool bTerrainPick = false;
|
|||
|
D3DXVECTOR3 v3ObjectPick, v3TerrainPick;
|
|||
|
|
|||
|
D3DXVECTOR3 v3Start, v3End, v3Dir, v3CurPos;
|
|||
|
float fRayRange;
|
|||
|
rRay.GetStartPoint(&v3Start);
|
|||
|
rRay.GetDirection(&v3Dir, &fRayRange);
|
|||
|
rRay.GetEndPoint(&v3End);
|
|||
|
|
|||
|
Vector3d v3dStart, v3dEnd;
|
|||
|
v3dStart.Set(v3Start.x, v3Start.y, v3Start.z);
|
|||
|
v3dEnd.Set(v3End.x - v3Start.x, v3End.y - v3Start.y, v3End.z - v3Start.z);
|
|||
|
|
|||
|
if (!m_bEnableTerrainOnlyForHeight)
|
|||
|
{
|
|||
|
//DWORD baseTime = timeGetTime();
|
|||
|
CCullingManager & rkCullingMgr = CCullingManager::Instance();
|
|||
|
FGetPickingPoint kGetPickingPoint(v3Start, v3Dir);
|
|||
|
rkCullingMgr.ForInRange2d(v3dStart, &kGetPickingPoint);
|
|||
|
|
|||
|
if (kGetPickingPoint.m_bPicked)
|
|||
|
{
|
|||
|
bObjectPick = true;
|
|||
|
v3ObjectPick = kGetPickingPoint.m_v3PickingPoint;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
float fPos = 0.0f;
|
|||
|
//float fStep = 1.0f;
|
|||
|
//float fRayRangeInv=1.0f/fRayRange;
|
|||
|
|
|||
|
bTerrainPick=true;
|
|||
|
if (!__PickTerrainHeight(fPos, v3Start, v3End, 5.0f, fRayRange, 5000.0f, &v3TerrainPick))
|
|||
|
if (!__PickTerrainHeight(fPos, v3Start, v3End, 10.0f, fRayRange, 10000.0f, &v3TerrainPick))
|
|||
|
if (!__PickTerrainHeight(fPos, v3Start, v3End, 100.0f, fRayRange, 100000.0f, &v3TerrainPick))
|
|||
|
bTerrainPick=false;
|
|||
|
|
|||
|
|
|||
|
if (bObjectPick && bTerrainPick)
|
|||
|
{
|
|||
|
if ( D3DXVec3Length( &(v3ObjectPick - v3Start) ) >= D3DXVec3Length( &(v3TerrainPick - v3Start) ) )
|
|||
|
*v3IntersectPt = v3TerrainPick;
|
|||
|
else
|
|||
|
*v3IntersectPt = v3ObjectPick;
|
|||
|
return true;
|
|||
|
}
|
|||
|
else if (bObjectPick)
|
|||
|
{
|
|||
|
*v3IntersectPt = v3ObjectPick;
|
|||
|
return true;
|
|||
|
}
|
|||
|
else if (bTerrainPick)
|
|||
|
{
|
|||
|
*v3IntersectPt = v3TerrainPick;
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
bool CMapOutdoor::GetPickingPointWithRayOnlyTerrain(const CRay & rRay, D3DXVECTOR3 * v3IntersectPt)
|
|||
|
{
|
|||
|
bool bTerrainPick = false;
|
|||
|
D3DXVECTOR3 v3TerrainPick;
|
|||
|
|
|||
|
D3DXVECTOR3 v3Start, v3End, v3Dir, v3CurPos;
|
|||
|
float fRayRange;
|
|||
|
rRay.GetStartPoint(&v3Start);
|
|||
|
rRay.GetDirection(&v3Dir, &fRayRange);
|
|||
|
rRay.GetEndPoint(&v3End);
|
|||
|
|
|||
|
Vector3d v3dStart, v3dEnd;
|
|||
|
v3dStart.Set(v3Start.x, v3Start.y, v3Start.z);
|
|||
|
v3dEnd.Set(v3End.x - v3Start.x, v3End.y - v3Start.y, v3End.z - v3Start.z);
|
|||
|
|
|||
|
|
|||
|
|
|||
|
float fPos = 0.0f;
|
|||
|
bTerrainPick=true;
|
|||
|
if (!__PickTerrainHeight(fPos, v3Start, v3End, 5.0f, fRayRange, 5000.0f, &v3TerrainPick))
|
|||
|
if (!__PickTerrainHeight(fPos, v3Start, v3End, 10.0f, fRayRange, 10000.0f, &v3TerrainPick))
|
|||
|
if (!__PickTerrainHeight(fPos, v3Start, v3End, 100.0f, fRayRange, 100000.0f, &v3TerrainPick))
|
|||
|
bTerrainPick=false;
|
|||
|
|
|||
|
if (bTerrainPick)
|
|||
|
{
|
|||
|
*v3IntersectPt = v3TerrainPick;
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
return false;
|
|||
|
}
|
|||
|
/*
|
|||
|
{
|
|||
|
bool bTerrainPick = false;
|
|||
|
D3DXVECTOR3 v3TerrainPick;
|
|||
|
|
|||
|
CTerrain * pTerrain;
|
|||
|
|
|||
|
D3DXVECTOR3 v3Start, v3End, v3Dir, v3CurPos;
|
|||
|
float fRayRange;
|
|||
|
rRay.GetStartPoint(&v3Start);
|
|||
|
rRay.GetDirection(&v3Dir, &fRayRange);
|
|||
|
rRay.GetEndPoint(&v3End);
|
|||
|
|
|||
|
Vector3d v3dStart, v3dEnd;
|
|||
|
v3dStart.Set(v3Start.x, v3Start.y, v3Start.z);
|
|||
|
v3dEnd.Set(v3End.x - v3Start.x, v3End.y - v3Start.y, v3End.z - v3Start.z);
|
|||
|
|
|||
|
float fAdd = 1.0f / fRayRange;
|
|||
|
|
|||
|
float ft = 0.0f;
|
|||
|
while (ft < 1.0f)
|
|||
|
{
|
|||
|
D3DXVec3Lerp(&v3CurPos, &v3Start, &v3End, ft);
|
|||
|
BYTE byTerrainNum;
|
|||
|
float fMultiplier = 1.0f;
|
|||
|
if (GetTerrainNum(v3CurPos.x, v3CurPos.y, &byTerrainNum))
|
|||
|
{
|
|||
|
if (GetTerrainPointer(byTerrainNum, &pTerrain))
|
|||
|
{
|
|||
|
int ix, iy;
|
|||
|
PR_FLOAT_TO_INT(v3CurPos.x, ix);
|
|||
|
PR_FLOAT_TO_INT(fabs(v3CurPos.y), iy);
|
|||
|
float fMapHeight = pTerrain->GetHeight(ix, iy);
|
|||
|
if ( fMapHeight >= v3CurPos.z)
|
|||
|
{
|
|||
|
bTerrainPick = true;
|
|||
|
v3TerrainPick = v3CurPos;
|
|||
|
break;
|
|||
|
}
|
|||
|
else
|
|||
|
fMultiplier = fMAX(1.0f, 0.01f * ( v3CurPos.z - fMapHeight ) );
|
|||
|
}
|
|||
|
}
|
|||
|
ft += fAdd * fMultiplier;
|
|||
|
}
|
|||
|
|
|||
|
if (bTerrainPick)
|
|||
|
{
|
|||
|
*v3IntersectPt = v3TerrainPick;
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
return false;
|
|||
|
}
|
|||
|
*/
|
|||
|
|
|||
|
void CMapOutdoor::GetHeightMap(const BYTE & c_rucTerrainNum, WORD ** pwHeightMap)
|
|||
|
{
|
|||
|
if (c_rucTerrainNum < 0 || c_rucTerrainNum > AROUND_AREA_NUM - 1 || !m_pTerrain[c_rucTerrainNum])
|
|||
|
{
|
|||
|
*pwHeightMap = NULL;
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
*pwHeightMap = m_pTerrain[c_rucTerrainNum]->GetHeightMap();
|
|||
|
}
|
|||
|
|
|||
|
void CMapOutdoor::GetNormalMap(const BYTE & c_rucTerrainNum, char ** pucNormalMap)
|
|||
|
{
|
|||
|
if (c_rucTerrainNum < 0 || c_rucTerrainNum > AROUND_AREA_NUM - 1 || !m_pTerrain[c_rucTerrainNum])
|
|||
|
{
|
|||
|
*pucNormalMap = NULL;
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
*pucNormalMap = m_pTerrain[c_rucTerrainNum]->GetNormalMap();
|
|||
|
}
|
|||
|
|
|||
|
void CMapOutdoor::GetWaterMap(const BYTE & c_rucTerrainNum, BYTE ** pucWaterMap)
|
|||
|
{
|
|||
|
if (c_rucTerrainNum < 0 || c_rucTerrainNum > AROUND_AREA_NUM - 1 || !m_pTerrain[c_rucTerrainNum])
|
|||
|
{
|
|||
|
*pucWaterMap = NULL;
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
*pucWaterMap = m_pTerrain[c_rucTerrainNum]->GetWaterMap();
|
|||
|
}
|
|||
|
|
|||
|
void CMapOutdoor::GetWaterHeight(BYTE byTerrainNum, BYTE byWaterNum, long * plWaterHeight)
|
|||
|
{
|
|||
|
if (byTerrainNum < 0 || byTerrainNum > AROUND_AREA_NUM - 1 || !m_pTerrain[byTerrainNum])
|
|||
|
{
|
|||
|
*plWaterHeight = -1;
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
m_pTerrain[byTerrainNum]->GetWaterHeight(byWaterNum, plWaterHeight);
|
|||
|
}
|
|||
|
|
|||
|
bool CMapOutdoor::GetWaterHeight(int iX, int iY, long * plWaterHeight)
|
|||
|
{
|
|||
|
if (iX < 0 || iY < 0 || iX > m_sTerrainCountX * CTerrainImpl::TERRAIN_XSIZE || iY > m_sTerrainCountY * CTerrainImpl::TERRAIN_YSIZE)
|
|||
|
return false;
|
|||
|
|
|||
|
WORD wTerrainCoordX, wTerrainCoordY;
|
|||
|
wTerrainCoordX = iX / CTerrainImpl::TERRAIN_XSIZE;
|
|||
|
wTerrainCoordY = iY / CTerrainImpl::TERRAIN_YSIZE;
|
|||
|
|
|||
|
BYTE byTerrainNum;
|
|||
|
if (!GetTerrainNumFromCoord(wTerrainCoordX, wTerrainCoordY, &byTerrainNum))
|
|||
|
return false;
|
|||
|
CTerrain * pTerrain;
|
|||
|
if (!GetTerrainPointer(byTerrainNum, &pTerrain))
|
|||
|
return false;
|
|||
|
|
|||
|
WORD wLocalX, wLocalY;
|
|||
|
wLocalX = (iX - wTerrainCoordX * CTerrainImpl::TERRAIN_XSIZE) / (CTerrainImpl::WATERMAP_XSIZE);
|
|||
|
wLocalY = (iY - wTerrainCoordY * CTerrainImpl::TERRAIN_YSIZE) / (CTerrainImpl::WATERMAP_YSIZE);
|
|||
|
|
|||
|
return pTerrain->GetWaterHeight(wLocalX, wLocalY, plWaterHeight);
|
|||
|
}
|
|||
|
|
|||
|
//////////////////////////////////////////////////////////////////////////
|
|||
|
// Update
|
|||
|
//////////////////////////////////////////////////////////////////////////
|
|||
|
|
|||
|
bool CMapOutdoor::GetTerrainNumFromCoord(WORD wCoordX, WORD wCoordY, BYTE * pbyTerrainNum)
|
|||
|
{
|
|||
|
*pbyTerrainNum = (wCoordY - m_CurCoordinate.m_sTerrainCoordY + LOAD_SIZE_WIDTH) * 3 +
|
|||
|
(wCoordX - m_CurCoordinate.m_sTerrainCoordX + LOAD_SIZE_WIDTH);
|
|||
|
|
|||
|
if (*pbyTerrainNum < 0 || *pbyTerrainNum > AROUND_AREA_NUM)
|
|||
|
return false;
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
void CMapOutdoor::BuildViewFrustum(D3DXMATRIX & mat)
|
|||
|
{
|
|||
|
//m_plane[0] = D3DXPLANE(mat._14 + mat._13, mat._24 + mat._23, mat._34 + mat._33, mat._44 + mat._43);
|
|||
|
m_plane[0] = D3DXPLANE( mat._13, mat._23, mat._33, mat._43); // Near
|
|||
|
m_plane[1] = D3DXPLANE(mat._14 - mat._13, mat._24 - mat._23, mat._34 - mat._33, mat._44 - mat._43); // Far
|
|||
|
m_plane[2] = D3DXPLANE(mat._14 + mat._11, mat._24 + mat._21, mat._34 + mat._31, mat._44 + mat._41); // Left
|
|||
|
m_plane[3] = D3DXPLANE(mat._14 - mat._11, mat._24 - mat._21, mat._34 - mat._31, mat._44 - mat._41); // Right
|
|||
|
m_plane[4] = D3DXPLANE(mat._14 + mat._12, mat._24 + mat._22, mat._34 + mat._32, mat._44 + mat._42); // Bottom
|
|||
|
m_plane[5] = D3DXPLANE(mat._14 - mat._12, mat._24 - mat._22, mat._34 - mat._32, mat._44 - mat._42); // Top
|
|||
|
|
|||
|
for (int i = 0; i < 6; ++i)
|
|||
|
D3DXPlaneNormalize(&m_plane[i],&m_plane[i]);
|
|||
|
}
|
|||
|
|
|||
|
bool MAPOUTDOOR_GET_HEIGHT_USE2D = true;
|
|||
|
bool MAPOUTDOOR_GET_HEIGHT_TRACE = false;
|
|||
|
|
|||
|
void CMapOutdoor::__HeightCache_Update()
|
|||
|
{
|
|||
|
m_kHeightCache.m_isUpdated=true;
|
|||
|
}
|
|||
|
|
|||
|
void CMapOutdoor::__HeightCache_Init()
|
|||
|
{
|
|||
|
m_kHeightCache.m_isUpdated=false;
|
|||
|
|
|||
|
for (UINT uIndex=0; uIndex!=SHeightCache::HASH_SIZE; ++uIndex)
|
|||
|
m_kHeightCache.m_akVct_kItem[uIndex].clear();
|
|||
|
}
|
|||
|
|
|||
|
float CMapOutdoor::GetHeight(float fx, float fy)
|
|||
|
{
|
|||
|
float fTerrainHeight = GetTerrainHeight(fx, fy);
|
|||
|
|
|||
|
if (!m_bEnableTerrainOnlyForHeight)
|
|||
|
{
|
|||
|
CCullingManager & rkCullingMgr = CCullingManager::Instance();
|
|||
|
|
|||
|
float CHECK_HEIGHT = 25000.0f;
|
|||
|
float fObjectHeight = -CHECK_HEIGHT;
|
|||
|
|
|||
|
Vector3d aVector3d;
|
|||
|
aVector3d.Set(fx, -fy, fTerrainHeight);
|
|||
|
|
|||
|
FGetObjectHeight kGetObjHeight(fx, fy);
|
|||
|
|
|||
|
RangeTester<FGetObjectHeight> kRangeTester_kGetObjHeight(&kGetObjHeight);
|
|||
|
rkCullingMgr.PointTest2d(aVector3d, &kRangeTester_kGetObjHeight);
|
|||
|
|
|||
|
if (kGetObjHeight.m_bHeightFound)
|
|||
|
fObjectHeight = kGetObjHeight.m_fReturnHeight;
|
|||
|
|
|||
|
return fMAX(fObjectHeight, fTerrainHeight);
|
|||
|
}
|
|||
|
|
|||
|
return fTerrainHeight;
|
|||
|
}
|
|||
|
|
|||
|
float CMapOutdoor::GetCacheHeight(float fx, float fy)
|
|||
|
{
|
|||
|
unsigned int nx=int(fx);
|
|||
|
unsigned int ny=int(fy);
|
|||
|
|
|||
|
DWORD dwKey=0;
|
|||
|
|
|||
|
#ifdef __HEIGHT_CACHE_TRACE__
|
|||
|
static DWORD s_dwTotalCount=0;
|
|||
|
static DWORD s_dwHitCount=0;
|
|||
|
static DWORD s_dwErrorCount=0;
|
|||
|
|
|||
|
s_dwTotalCount++;
|
|||
|
#endif
|
|||
|
|
|||
|
std::vector<SHeightCache::SItem>* pkVct_kItem=NULL;
|
|||
|
if (m_kHeightCache.m_isUpdated && nx<16*30000 && ny<16*30000)
|
|||
|
{
|
|||
|
nx>>=4;
|
|||
|
ny>>=4;
|
|||
|
//short aPos[2]={nx, ny};
|
|||
|
|
|||
|
dwKey=(ny<<16)|nx;//CalcCRC16Words(2, aPos);
|
|||
|
pkVct_kItem=&m_kHeightCache.m_akVct_kItem[dwKey%SHeightCache::HASH_SIZE];
|
|||
|
std::vector<SHeightCache::SItem>::iterator i;
|
|||
|
for (i=pkVct_kItem->begin(); i!=pkVct_kItem->end(); ++i)
|
|||
|
{
|
|||
|
SHeightCache::SItem& rkItem=*i;
|
|||
|
if (rkItem.m_dwKey==dwKey)
|
|||
|
{
|
|||
|
#ifdef __HEIGHT_CACHE_TRACE__
|
|||
|
s_dwHitCount++;
|
|||
|
|
|||
|
if (s_dwTotalCount>1000)
|
|||
|
{
|
|||
|
DWORD dwHitRate=s_dwHitCount*1000/s_dwTotalCount;
|
|||
|
static DWORD s_dwMaxHitRate=0;
|
|||
|
if (s_dwMaxHitRate<dwHitRate)
|
|||
|
{
|
|||
|
s_dwMaxHitRate=dwHitRate;
|
|||
|
printf("HitRate %f\n", s_dwMaxHitRate*0.1f);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
#endif
|
|||
|
return rkItem.m_fHeight;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
#ifdef __HEIGHT_CACHE_TRACE__
|
|||
|
s_dwErrorCount++;
|
|||
|
//printf("NoCache (%f, %f)\n", fx/100.0f, fy/100.0f);
|
|||
|
#endif
|
|||
|
}
|
|||
|
#ifdef __HEIGHT_CACHE_TRACE__
|
|||
|
if (s_dwTotalCount>=1000000)
|
|||
|
{
|
|||
|
printf("HitRate %f\n", s_dwHitCount*1000/s_dwTotalCount*0.1f);
|
|||
|
printf("ErrRate %f\n", s_dwErrorCount*1000/s_dwTotalCount*0.1f);
|
|||
|
s_dwHitCount=0;
|
|||
|
s_dwTotalCount=0;
|
|||
|
s_dwErrorCount=0;
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
float fTerrainHeight = GetTerrainHeight(fx, fy);
|
|||
|
#ifdef SPHERELIB_STRICT
|
|||
|
if (MAPOUTDOOR_GET_HEIGHT_TRACE)
|
|||
|
printf("Terrain %f\n", fTerrainHeight);
|
|||
|
#endif
|
|||
|
CCullingManager & rkCullingMgr = CCullingManager::Instance();
|
|||
|
|
|||
|
float CHECK_HEIGHT = 25000.0f;
|
|||
|
float fObjectHeight = -CHECK_HEIGHT;
|
|||
|
|
|||
|
if (MAPOUTDOOR_GET_HEIGHT_USE2D)
|
|||
|
{
|
|||
|
Vector3d aVector3d;
|
|||
|
aVector3d.Set(fx, -fy, fTerrainHeight);
|
|||
|
|
|||
|
FGetObjectHeight kGetObjHeight(fx, fy);
|
|||
|
|
|||
|
RangeTester<FGetObjectHeight> kRangeTester_kGetObjHeight(&kGetObjHeight);
|
|||
|
rkCullingMgr.PointTest2d(aVector3d, &kRangeTester_kGetObjHeight);
|
|||
|
|
|||
|
if (kGetObjHeight.m_bHeightFound)
|
|||
|
fObjectHeight = kGetObjHeight.m_fReturnHeight;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
Vector3d aVector3d;
|
|||
|
aVector3d.Set(fx, -fy, fTerrainHeight);
|
|||
|
|
|||
|
Vector3d toTop;
|
|||
|
toTop.Set(0,0,CHECK_HEIGHT);
|
|||
|
|
|||
|
FGetObjectHeight kGetObjHeight(fx, fy);
|
|||
|
rkCullingMgr.ForInRay(aVector3d, toTop, &kGetObjHeight);
|
|||
|
|
|||
|
if (kGetObjHeight.m_bHeightFound)
|
|||
|
fObjectHeight = kGetObjHeight.m_fReturnHeight;
|
|||
|
}
|
|||
|
|
|||
|
float fHeight=fMAX(fObjectHeight, fTerrainHeight);
|
|||
|
|
|||
|
if (pkVct_kItem)
|
|||
|
{
|
|||
|
if (pkVct_kItem->size()>=200)
|
|||
|
{
|
|||
|
#ifdef __HEIGHT_CACHE_TRACE__
|
|||
|
printf("ClearCacheHeight[%d]\n", dwKey%SHeightCache::HASH_SIZE);
|
|||
|
#endif
|
|||
|
pkVct_kItem->clear();
|
|||
|
}
|
|||
|
|
|||
|
SHeightCache::SItem kItem;
|
|||
|
kItem.m_dwKey=dwKey;
|
|||
|
kItem.m_fHeight=fHeight;
|
|||
|
pkVct_kItem->push_back(kItem);
|
|||
|
}
|
|||
|
|
|||
|
return fHeight;
|
|||
|
}
|
|||
|
|
|||
|
bool CMapOutdoor::GetNormal(int ix, int iy, D3DXVECTOR3 * pv3Normal)
|
|||
|
{
|
|||
|
if (ix <= 0)
|
|||
|
ix = 0;
|
|||
|
else if (ix >= m_sTerrainCountX * CTerrainImpl::TERRAIN_XSIZE)
|
|||
|
ix = m_sTerrainCountX * CTerrainImpl::TERRAIN_XSIZE;
|
|||
|
|
|||
|
if (iy <= 0)
|
|||
|
iy = 0;
|
|||
|
else if (iy >= m_sTerrainCountY * CTerrainImpl::TERRAIN_YSIZE)
|
|||
|
iy = m_sTerrainCountY * CTerrainImpl::TERRAIN_YSIZE;
|
|||
|
|
|||
|
WORD usCoordX, usCoordY;
|
|||
|
|
|||
|
usCoordX = (WORD) (ix / (CTerrainImpl::TERRAIN_XSIZE));
|
|||
|
usCoordY = (WORD) (iy / (CTerrainImpl::TERRAIN_YSIZE));
|
|||
|
|
|||
|
if (usCoordX >= m_sTerrainCountX - 1)
|
|||
|
usCoordX = m_sTerrainCountX - 1;
|
|||
|
|
|||
|
if (usCoordY >= m_sTerrainCountY - 1)
|
|||
|
usCoordY = m_sTerrainCountY - 1;
|
|||
|
|
|||
|
BYTE byTerrainNum;
|
|||
|
if (!GetTerrainNumFromCoord(usCoordX, usCoordY, &byTerrainNum))
|
|||
|
return false;
|
|||
|
|
|||
|
CTerrain * pTerrain;
|
|||
|
|
|||
|
if (!GetTerrainPointer(byTerrainNum, &pTerrain))
|
|||
|
return false;
|
|||
|
|
|||
|
while (ix >= CTerrainImpl::TERRAIN_XSIZE)
|
|||
|
ix -= CTerrainImpl::TERRAIN_XSIZE;
|
|||
|
|
|||
|
while (iy >= CTerrainImpl::TERRAIN_YSIZE)
|
|||
|
iy -= CTerrainImpl::TERRAIN_YSIZE;
|
|||
|
|
|||
|
return pTerrain->GetNormal(ix, iy, pv3Normal);
|
|||
|
}
|
|||
|
|
|||
|
float CMapOutdoor::GetTerrainHeight(float fx, float fy)
|
|||
|
{
|
|||
|
if (fy < 0)
|
|||
|
fy = -fy;
|
|||
|
long lx, ly;
|
|||
|
PR_FLOAT_TO_INT(fx, lx);
|
|||
|
PR_FLOAT_TO_INT(fy, ly);
|
|||
|
|
|||
|
WORD usCoordX, usCoordY;
|
|||
|
|
|||
|
usCoordX = (WORD) (lx / CTerrainImpl::TERRAIN_XSIZE);
|
|||
|
usCoordY = (WORD) (ly / CTerrainImpl::TERRAIN_YSIZE);
|
|||
|
|
|||
|
BYTE byTerrainNum;
|
|||
|
if (!GetTerrainNumFromCoord(usCoordX, usCoordY, &byTerrainNum))
|
|||
|
return 0.0f;
|
|||
|
|
|||
|
CTerrain * pTerrain;
|
|||
|
|
|||
|
if (!GetTerrainPointer(byTerrainNum, &pTerrain))
|
|||
|
return 0.0f;
|
|||
|
|
|||
|
return pTerrain->GetHeight(lx, ly);
|
|||
|
}
|
|||
|
|
|||
|
//////////////////////////////////////////////////////////////////////////
|
|||
|
// For Grass
|
|||
|
float CMapOutdoor::GetHeight(float * pPos)
|
|||
|
{
|
|||
|
pPos[2] = GetHeight(pPos[0], pPos[1]);
|
|||
|
return pPos[2];
|
|||
|
}
|
|||
|
|
|||
|
bool CMapOutdoor::GetBrushColor(float fX, float fY, float* pLowColor, float* pHighColor)
|
|||
|
{
|
|||
|
bool bSuccess = false;
|
|||
|
|
|||
|
// float fU, fV;
|
|||
|
//
|
|||
|
// GetOneToOneMappingCoordinates(fX, fY, fU, fV);
|
|||
|
//
|
|||
|
// if (fU >= 0.0f && fU <= 1.0f && fV >= 0.0f && fV <= 1.0f)
|
|||
|
// {
|
|||
|
// int nImageCol = (m_cBrushMap.GetWidth() - 1) * fU;
|
|||
|
// int nImageRow = (m_cBrushMap.GetHeight() - 1) * fV;
|
|||
|
//
|
|||
|
// // low
|
|||
|
// BYTE* pPixel = m_cBrushMap.GetPixel(nImageCol, nImageRow);
|
|||
|
// pLowColor[0] = (pPixel[0] / 255.0f);
|
|||
|
// pLowColor[1] = (pPixel[1] / 255.0f);
|
|||
|
// pLowColor[2] = (pPixel[2] / 255.0f);
|
|||
|
// pLowColor[3] = (pPixel[3] / 255.0f);
|
|||
|
//
|
|||
|
// // high
|
|||
|
// pPixel = m_cBrushMap2.GetPixel(nImageCol, nImageRow);
|
|||
|
// pHighColor[0] = (pPixel[0] / 255.0f);
|
|||
|
// pHighColor[1] = (pPixel[1] / 255.0f);
|
|||
|
// pHighColor[2] = (pPixel[2] / 255.0f);
|
|||
|
// pHighColor[3] = (pPixel[3] / 255.0f);
|
|||
|
//
|
|||
|
// bSuccess = true;
|
|||
|
// }
|
|||
|
pLowColor[0] = (1.0f);
|
|||
|
pLowColor[1] = (1.0f);
|
|||
|
pLowColor[2] = (1.0f);
|
|||
|
pLowColor[3] = (1.0f);
|
|||
|
pHighColor[0] = (1.0f);
|
|||
|
pHighColor[1] = (1.0f);
|
|||
|
pHighColor[2] = (1.0f);
|
|||
|
pHighColor[3] = (1.0f);
|
|||
|
|
|||
|
return bSuccess;
|
|||
|
}
|
|||
|
|
|||
|
// End of for grass
|
|||
|
//////////////////////////////////////////////////////////////////////////
|
|||
|
BOOL CMapOutdoor::GetAreaPointer(const BYTE c_byAreaNum, CArea ** ppArea)
|
|||
|
{
|
|||
|
if (c_byAreaNum >= AROUND_AREA_NUM)
|
|||
|
{
|
|||
|
*ppArea = NULL;
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
if (NULL == m_pArea[c_byAreaNum])
|
|||
|
{
|
|||
|
*ppArea = NULL;
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
*ppArea = m_pArea[c_byAreaNum];
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CMapOutdoor::GetTerrainPointer(const BYTE c_byTerrainNum, CTerrain ** ppTerrain)
|
|||
|
{
|
|||
|
if (c_byTerrainNum >= AROUND_AREA_NUM)
|
|||
|
{
|
|||
|
*ppTerrain = NULL;
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
if (NULL == m_pTerrain[c_byTerrainNum])
|
|||
|
{
|
|||
|
*ppTerrain = NULL;
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
*ppTerrain = m_pTerrain[c_byTerrainNum];
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
void CMapOutdoor::InitializeFog()
|
|||
|
{
|
|||
|
memset(&m_matAlphaFogTexture, 0, sizeof(D3DXMATRIX));
|
|||
|
m_matAlphaFogTexture._31 = -0.001f;
|
|||
|
m_matAlphaFogTexture._41 = -7.0f;
|
|||
|
m_matAlphaFogTexture._42 = 0.5f;
|
|||
|
}
|
|||
|
|
|||
|
void CMapOutdoor::SaveAlphaFogOperation()
|
|||
|
{
|
|||
|
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
|
|||
|
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
|||
|
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
|
|||
|
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
|
|||
|
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
|
|||
|
STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
|
|||
|
STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
|
|||
|
STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
|
|||
|
STATEMANAGER.SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
|
|||
|
|
|||
|
STATEMANAGER.SetTransform(D3DTS_TEXTURE1, &m_matAlphaFogTexture);
|
|||
|
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
|||
|
STATEMANAGER.SetTexture(1, m_AlphaFogImageInstance.GetTexturePointer()->GetD3DTexture());
|
|||
|
}
|
|||
|
|
|||
|
void CMapOutdoor::RestoreAlphaFogOperation()
|
|||
|
{
|
|||
|
STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
|
|||
|
STATEMANAGER.SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1);
|
|||
|
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void CMapOutdoor::SetDrawShadow(bool bDrawShadow)
|
|||
|
{
|
|||
|
m_bDrawShadow = bDrawShadow;
|
|||
|
}
|
|||
|
|
|||
|
void CMapOutdoor::SetDrawCharacterShadow(bool bDrawChrShadow)
|
|||
|
{
|
|||
|
m_bDrawChrShadow = bDrawChrShadow;
|
|||
|
}
|
|||
|
|
|||
|
DWORD CMapOutdoor::GetShadowMapColor(float fx, float fy)
|
|||
|
{
|
|||
|
if (fy < 0)
|
|||
|
fy = -fy;
|
|||
|
|
|||
|
float fTerrainSize = (float) (CTerrainImpl::TERRAIN_XSIZE);
|
|||
|
float fXRef = fx - (float) (m_lCurCoordStartX);
|
|||
|
float fYRef = fy - (float) (m_lCurCoordStartY);
|
|||
|
|
|||
|
CTerrain * pTerrain;
|
|||
|
|
|||
|
if (fYRef < -fTerrainSize)
|
|||
|
return 0xFFFFFFFF;
|
|||
|
else if (fYRef >= -fTerrainSize && fYRef < 0.0f)
|
|||
|
{
|
|||
|
if (fXRef < -fTerrainSize)
|
|||
|
return 0xFFFFFFFF;
|
|||
|
else if (fXRef >= -fTerrainSize && fXRef < 0.0f)
|
|||
|
{
|
|||
|
if (GetTerrainPointer(0, &pTerrain))
|
|||
|
return pTerrain->GetShadowMapColor(fXRef + fTerrainSize, fYRef + fTerrainSize);
|
|||
|
else
|
|||
|
return 0xFFFFFFFF;
|
|||
|
}
|
|||
|
else if (fXRef >= 0.0f && fXRef < fTerrainSize)
|
|||
|
{
|
|||
|
if (GetTerrainPointer(1, &pTerrain))
|
|||
|
return pTerrain->GetShadowMapColor(fXRef, fYRef + fTerrainSize);
|
|||
|
else
|
|||
|
return 0xFFFFFFFF;
|
|||
|
}
|
|||
|
else if (fXRef >= fTerrainSize && fXRef < 2.0f * fTerrainSize)
|
|||
|
{
|
|||
|
if (GetTerrainPointer(2, &pTerrain))
|
|||
|
return pTerrain->GetShadowMapColor(fXRef - fTerrainSize, fYRef + fTerrainSize);
|
|||
|
else
|
|||
|
return 0xFFFFFFFF;
|
|||
|
}
|
|||
|
else
|
|||
|
return 0xFFFFFFFF;
|
|||
|
}
|
|||
|
else if (fYRef >= 0.0f && fYRef < fTerrainSize)
|
|||
|
{
|
|||
|
if (fXRef < -fTerrainSize)
|
|||
|
return 0xFFFFFFFF;
|
|||
|
else if (fXRef >= -fTerrainSize && fXRef < 0.0f)
|
|||
|
{
|
|||
|
if (GetTerrainPointer(3, &pTerrain))
|
|||
|
return pTerrain->GetShadowMapColor(fXRef + fTerrainSize, fYRef);
|
|||
|
else
|
|||
|
return 0xFFFFFFFF;
|
|||
|
}
|
|||
|
else if (fXRef >= 0.0f && fXRef < fTerrainSize)
|
|||
|
{
|
|||
|
if (GetTerrainPointer(4, &pTerrain))
|
|||
|
return pTerrain->GetShadowMapColor(fXRef, fYRef);
|
|||
|
else
|
|||
|
return 0xFFFFFFFF;
|
|||
|
}
|
|||
|
else if (fXRef >= fTerrainSize && fXRef < 2.0f * fTerrainSize)
|
|||
|
{
|
|||
|
if (GetTerrainPointer(5, &pTerrain))
|
|||
|
return pTerrain->GetShadowMapColor(fXRef - fTerrainSize, fYRef);
|
|||
|
else
|
|||
|
return 0xFFFFFFFF;
|
|||
|
}
|
|||
|
else
|
|||
|
return 0xFFFFFFFF;
|
|||
|
}
|
|||
|
else if (fYRef >= fTerrainSize && fYRef < 2.0f * fTerrainSize)
|
|||
|
{
|
|||
|
if (fXRef < -fTerrainSize)
|
|||
|
return 0xFFFFFFFF;
|
|||
|
else if (fXRef >= -fTerrainSize && fXRef < 0.0f)
|
|||
|
{
|
|||
|
if (GetTerrainPointer(6, &pTerrain))
|
|||
|
return pTerrain->GetShadowMapColor(fXRef + fTerrainSize, fYRef - fTerrainSize);
|
|||
|
else
|
|||
|
return 0xFFFFFFFF;
|
|||
|
}
|
|||
|
else if (fXRef >= 0.0f && fXRef < fTerrainSize)
|
|||
|
{
|
|||
|
if (GetTerrainPointer(7, &pTerrain))
|
|||
|
return pTerrain->GetShadowMapColor(fXRef, fYRef - fTerrainSize);
|
|||
|
else
|
|||
|
return 0xFFFFFFFF;
|
|||
|
}
|
|||
|
else if (fXRef >= fTerrainSize && fXRef < 2.0f * fTerrainSize)
|
|||
|
{
|
|||
|
if (GetTerrainPointer(8, &pTerrain))
|
|||
|
return pTerrain->GetShadowMapColor(fXRef - fTerrainSize, fYRef - fTerrainSize);
|
|||
|
else
|
|||
|
return 0xFFFFFFFF;
|
|||
|
}
|
|||
|
else
|
|||
|
return 0xFFFFFFFF;
|
|||
|
}
|
|||
|
else
|
|||
|
return 0xFFFFFFFF;
|
|||
|
|
|||
|
return 0xFFFFFFFF;
|
|||
|
}
|
|||
|
|
|||
|
bool CMapOutdoor::isAttrOn(float fX, float fY, BYTE byAttr)
|
|||
|
{
|
|||
|
int iX, iY;
|
|||
|
PR_FLOAT_TO_INT(fX, iX);
|
|||
|
PR_FLOAT_TO_INT(fY, iY);
|
|||
|
|
|||
|
return isAttrOn(iX, iY, byAttr);
|
|||
|
}
|
|||
|
|
|||
|
bool CMapOutdoor::GetAttr(float fX, float fY, BYTE * pbyAttr)
|
|||
|
{
|
|||
|
int iX, iY;
|
|||
|
PR_FLOAT_TO_INT(fX, iX);
|
|||
|
PR_FLOAT_TO_INT(fY, iY);
|
|||
|
|
|||
|
return GetAttr(iX, iY, pbyAttr);
|
|||
|
}
|
|||
|
|
|||
|
bool CMapOutdoor::isAttrOn(int iX, int iY, BYTE byAttr)
|
|||
|
{
|
|||
|
if (iX < 0 || iY < 0 || iX > m_sTerrainCountX * CTerrainImpl::TERRAIN_XSIZE || iY > m_sTerrainCountY * CTerrainImpl::TERRAIN_YSIZE)
|
|||
|
return false;
|
|||
|
|
|||
|
WORD wTerrainCoordX, wTerrainCoordY;
|
|||
|
wTerrainCoordX = iX / CTerrainImpl::TERRAIN_XSIZE;
|
|||
|
wTerrainCoordY = iY / CTerrainImpl::TERRAIN_YSIZE;
|
|||
|
|
|||
|
BYTE byTerrainNum;
|
|||
|
if (!GetTerrainNumFromCoord(wTerrainCoordX, wTerrainCoordY, &byTerrainNum))
|
|||
|
return false;
|
|||
|
CTerrain * pTerrain;
|
|||
|
if (!GetTerrainPointer(byTerrainNum, &pTerrain))
|
|||
|
return false;
|
|||
|
|
|||
|
WORD wLocalX, wLocalY;
|
|||
|
wLocalX = (iX - wTerrainCoordX * CTerrainImpl::TERRAIN_XSIZE) / (CTerrainImpl::HALF_CELLSCALE);
|
|||
|
wLocalY = (iY - wTerrainCoordY * CTerrainImpl::TERRAIN_YSIZE) / (CTerrainImpl::HALF_CELLSCALE);
|
|||
|
|
|||
|
return pTerrain->isAttrOn(wLocalX, wLocalY, byAttr);
|
|||
|
}
|
|||
|
|
|||
|
bool CMapOutdoor::GetAttr(int iX, int iY, BYTE * pbyAttr)
|
|||
|
{
|
|||
|
if (iX < 0 || iY < 0 || iX > m_sTerrainCountX * CTerrainImpl::TERRAIN_XSIZE || iY > m_sTerrainCountY * CTerrainImpl::TERRAIN_YSIZE)
|
|||
|
return false;
|
|||
|
|
|||
|
WORD wTerrainCoordX, wTerrainCoordY;
|
|||
|
wTerrainCoordX = iX / CTerrainImpl::TERRAIN_XSIZE;
|
|||
|
wTerrainCoordY = iY / CTerrainImpl::TERRAIN_YSIZE;
|
|||
|
|
|||
|
BYTE byTerrainNum;
|
|||
|
if (!GetTerrainNumFromCoord(wTerrainCoordX, wTerrainCoordY, &byTerrainNum))
|
|||
|
return false;
|
|||
|
CTerrain * pTerrain;
|
|||
|
if (!GetTerrainPointer(byTerrainNum, &pTerrain))
|
|||
|
return false;
|
|||
|
|
|||
|
WORD wLocalX, wLocalY;
|
|||
|
wLocalX = (WORD) (iX - wTerrainCoordX * CTerrainImpl::TERRAIN_XSIZE) / (CTerrainImpl::HALF_CELLSCALE);
|
|||
|
wLocalY = (WORD) (iY - wTerrainCoordY * CTerrainImpl::TERRAIN_YSIZE) / (CTerrainImpl::HALF_CELLSCALE);
|
|||
|
|
|||
|
BYTE byAttr = pTerrain->GetAttr(wLocalX, wLocalY);
|
|||
|
|
|||
|
*pbyAttr = byAttr;
|
|||
|
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
// MonsterAreaInfo
|
|||
|
CMonsterAreaInfo * CMapOutdoor::AddMonsterAreaInfo(long lOriginX, long lOriginY, long lSizeX, long lSizeY)
|
|||
|
{
|
|||
|
CMonsterAreaInfo * pMonsterAreaInfo = m_kPool_kMonsterAreaInfo.Alloc();
|
|||
|
pMonsterAreaInfo->Clear();
|
|||
|
pMonsterAreaInfo->SetOrigin(lOriginX, lOriginY);
|
|||
|
pMonsterAreaInfo->SetSize(lSizeX, lSizeY);
|
|||
|
m_MonsterAreaInfoPtrVector.push_back(pMonsterAreaInfo);
|
|||
|
|
|||
|
return pMonsterAreaInfo;
|
|||
|
}
|
|||
|
|
|||
|
void CMapOutdoor::RemoveAllMonsterAreaInfo()
|
|||
|
{
|
|||
|
m_MonsterAreaInfoPtrVectorIterator = m_MonsterAreaInfoPtrVector.begin();
|
|||
|
while (m_MonsterAreaInfoPtrVectorIterator != m_MonsterAreaInfoPtrVector.end())
|
|||
|
{
|
|||
|
CMonsterAreaInfo * pMonsterAreaInfo = *m_MonsterAreaInfoPtrVectorIterator;
|
|||
|
pMonsterAreaInfo->Clear();
|
|||
|
++m_MonsterAreaInfoPtrVectorIterator;
|
|||
|
}
|
|||
|
m_kPool_kMonsterAreaInfo.FreeAll();
|
|||
|
m_MonsterAreaInfoPtrVector.clear();
|
|||
|
}
|
|||
|
|
|||
|
bool CMapOutdoor::GetMonsterAreaInfoFromVectorIndex(DWORD dwMonsterAreaInfoVectorIndex, CMonsterAreaInfo ** ppMonsterAreaInfo)
|
|||
|
{
|
|||
|
if (dwMonsterAreaInfoVectorIndex >= m_MonsterAreaInfoPtrVector.size())
|
|||
|
return false;
|
|||
|
|
|||
|
*ppMonsterAreaInfo = m_MonsterAreaInfoPtrVector[dwMonsterAreaInfoVectorIndex];
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
//////////////////////////////////////////////////////////////////////////
|
|||
|
CMonsterAreaInfo * CMapOutdoor::AddNewMonsterAreaInfo(long lOriginX, long lOriginY, long lSizeX, long lSizeY,
|
|||
|
CMonsterAreaInfo::EMonsterAreaInfoType eMonsterAreaInfoType,
|
|||
|
DWORD dwVID, DWORD dwCount, CMonsterAreaInfo::EMonsterDir eMonsterDir)
|
|||
|
{
|
|||
|
CMonsterAreaInfo * pMonsterAreaInfo = m_kPool_kMonsterAreaInfo.Alloc();
|
|||
|
pMonsterAreaInfo->Clear();
|
|||
|
pMonsterAreaInfo->SetOrigin(lOriginX, lOriginY);
|
|||
|
pMonsterAreaInfo->SetSize(lSizeX, lSizeY);
|
|||
|
|
|||
|
pMonsterAreaInfo->SetMonsterAreaInfoType(eMonsterAreaInfoType);
|
|||
|
|
|||
|
if (CMonsterAreaInfo::MONSTERAREAINFOTYPE_MONSTER == eMonsterAreaInfoType)
|
|||
|
pMonsterAreaInfo->SetMonsterVID(dwVID);
|
|||
|
else if (CMonsterAreaInfo::MONSTERAREAINFOTYPE_GROUP == eMonsterAreaInfoType)
|
|||
|
pMonsterAreaInfo->SetMonsterGroupID(dwVID);
|
|||
|
pMonsterAreaInfo->SetMonsterCount(dwCount);
|
|||
|
pMonsterAreaInfo->SetMonsterDirection(eMonsterDir);
|
|||
|
m_MonsterAreaInfoPtrVector.push_back(pMonsterAreaInfo);
|
|||
|
|
|||
|
return pMonsterAreaInfo;
|
|||
|
}
|
|||
|
|
|||
|
//////////////////////////////////////////////////////////////////////////
|
|||
|
void CMapOutdoor::GetBaseXY(DWORD * pdwBaseX, DWORD * pdwBaseY)
|
|||
|
{
|
|||
|
*pdwBaseX = m_dwBaseX;
|
|||
|
*pdwBaseY = m_dwBaseY;
|
|||
|
}
|
|||
|
|
|||
|
void CMapOutdoor::SetBaseXY(DWORD dwBaseX, DWORD dwBaseY)
|
|||
|
{
|
|||
|
m_dwBaseX = dwBaseX;
|
|||
|
m_dwBaseY = dwBaseY;
|
|||
|
}
|
|||
|
|
|||
|
void CMapOutdoor::SetEnvironmentDataName(const std::string& strEnvironmentDataName)
|
|||
|
{
|
|||
|
m_envDataName = strEnvironmentDataName;
|
|||
|
}
|
|||
|
|
|||
|
void CMapOutdoor::__XMasTree_Initialize()
|
|||
|
{
|
|||
|
m_kXMas.m_pkTree=NULL;
|
|||
|
m_kXMas.m_iEffectID=-1;
|
|||
|
}
|
|||
|
|
|||
|
void CMapOutdoor::XMasTree_Destroy()
|
|||
|
{
|
|||
|
if (m_kXMas.m_pkTree)
|
|||
|
{
|
|||
|
CSpeedTreeForestDirectX8& rkForest=CSpeedTreeForestDirectX8::Instance();
|
|||
|
m_kXMas.m_pkTree->Clear();
|
|||
|
rkForest.DeleteInstance(m_kXMas.m_pkTree);
|
|||
|
m_kXMas.m_pkTree=NULL;
|
|||
|
}
|
|||
|
if (-1 != m_kXMas.m_iEffectID)
|
|||
|
{
|
|||
|
CEffectManager& rkEffMgr = CEffectManager::Instance();
|
|||
|
rkEffMgr.DestroyEffectInstance(m_kXMas.m_iEffectID);
|
|||
|
m_kXMas.m_iEffectID=-1;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void CMapOutdoor::__XMasTree_Create(float x, float y, float z, const char* c_szTreeName, const char* c_szEffName)
|
|||
|
{
|
|||
|
assert(NULL==m_kXMas.m_pkTree);
|
|||
|
assert(-1==m_kXMas.m_iEffectID);
|
|||
|
|
|||
|
CSpeedTreeForestDirectX8& rkForest=CSpeedTreeForestDirectX8::Instance();
|
|||
|
DWORD dwCRC32 = GetCaseCRC32(c_szTreeName, strlen(c_szTreeName));
|
|||
|
m_kXMas.m_pkTree=rkForest.CreateInstance(x, y, z, dwCRC32, c_szTreeName);
|
|||
|
|
|||
|
CEffectManager& rkEffMgr = CEffectManager::Instance();
|
|||
|
rkEffMgr.RegisterEffect(c_szEffName);
|
|||
|
m_kXMas.m_iEffectID = rkEffMgr.CreateEffect(c_szEffName,
|
|||
|
D3DXVECTOR3(x, y, z),
|
|||
|
D3DXVECTOR3(0.0f, 0.0f, 0.0f));
|
|||
|
}
|
|||
|
|
|||
|
void CMapOutdoor::XMasTree_Set(float x, float y, float z, const char* c_szTreeName, const char* c_szEffName)
|
|||
|
{
|
|||
|
XMasTree_Destroy();
|
|||
|
__XMasTree_Create(x, y, z, c_szTreeName, c_szEffName);
|
|||
|
}
|
|||
|
|
|||
|
void CMapOutdoor::SpecialEffect_Create(DWORD dwID, float x, float y, float z, const char* c_szEffName)
|
|||
|
{
|
|||
|
CEffectManager& rkEffMgr = CEffectManager::Instance();
|
|||
|
|
|||
|
TSpecialEffectMap::iterator itor = m_kMap_dwID_iEffectID.find(dwID);
|
|||
|
if (m_kMap_dwID_iEffectID.end() != itor)
|
|||
|
{
|
|||
|
DWORD dwEffectID = itor->second;
|
|||
|
if (rkEffMgr.SelectEffectInstance(dwEffectID))
|
|||
|
{
|
|||
|
D3DXMATRIX mat;
|
|||
|
D3DXMatrixIdentity(&mat);
|
|||
|
mat._41 = x;
|
|||
|
mat._42 = y;
|
|||
|
mat._43 = z;
|
|||
|
rkEffMgr.SetEffectInstanceGlobalMatrix(mat);
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
rkEffMgr.RegisterEffect(c_szEffName);
|
|||
|
DWORD dwEffectID = rkEffMgr.CreateEffect(c_szEffName,
|
|||
|
D3DXVECTOR3(x, y, z),
|
|||
|
D3DXVECTOR3(0.0f, 0.0f, 0.0f));
|
|||
|
m_kMap_dwID_iEffectID.insert(std::make_pair(dwID, dwEffectID));
|
|||
|
}
|
|||
|
|
|||
|
void CMapOutdoor::SpecialEffect_Delete(DWORD dwID)
|
|||
|
{
|
|||
|
TSpecialEffectMap::iterator itor = m_kMap_dwID_iEffectID.find(dwID);
|
|||
|
|
|||
|
if (m_kMap_dwID_iEffectID.end() == itor)
|
|||
|
return;
|
|||
|
|
|||
|
CEffectManager& rkEffMgr = CEffectManager::Instance();
|
|||
|
int iEffectID = itor->second;
|
|||
|
rkEffMgr.DestroyEffectInstance(iEffectID);
|
|||
|
}
|
|||
|
|
|||
|
void CMapOutdoor::SpecialEffect_Destroy()
|
|||
|
{
|
|||
|
CEffectManager& rkEffMgr = CEffectManager::Instance();
|
|||
|
|
|||
|
TSpecialEffectMap::iterator itor = m_kMap_dwID_iEffectID.begin();
|
|||
|
for (; itor != m_kMap_dwID_iEffectID.end(); ++itor)
|
|||
|
{
|
|||
|
int iEffectID = itor->second;
|
|||
|
rkEffMgr.DestroyEffectInstance(iEffectID);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void CMapOutdoor::ClearGuildArea()
|
|||
|
{
|
|||
|
m_rkList_kGuildArea.clear();
|
|||
|
}
|
|||
|
|
|||
|
void CMapOutdoor::RegisterGuildArea(int isx, int isy, int iex, int iey)
|
|||
|
{
|
|||
|
RECT rect;
|
|||
|
rect.left = isx;
|
|||
|
rect.top = isy;
|
|||
|
rect.right = iex;
|
|||
|
rect.bottom = iey;
|
|||
|
m_rkList_kGuildArea.push_back(rect);
|
|||
|
}
|
|||
|
|
|||
|
void CMapOutdoor::VisibleMarkedArea()
|
|||
|
{
|
|||
|
std::map<int, BYTE*> kMap_pbyMarkBuf;
|
|||
|
std::set<int> kSet_iProcessedMapIndex;
|
|||
|
|
|||
|
std::list<RECT>::iterator itorRect = m_rkList_kGuildArea.begin();
|
|||
|
for (; itorRect != m_rkList_kGuildArea.end(); ++itorRect)
|
|||
|
{
|
|||
|
const RECT & rkRect = *itorRect;
|
|||
|
|
|||
|
int ix1Cell;
|
|||
|
int iy1Cell;
|
|||
|
BYTE byx1SubCell;
|
|||
|
BYTE byy1SubCell;
|
|||
|
WORD wx1TerrainNum;
|
|||
|
WORD wy1TerrainNum;
|
|||
|
|
|||
|
int ix2Cell;
|
|||
|
int iy2Cell;
|
|||
|
BYTE byx2SubCell;
|
|||
|
BYTE byy2SubCell;
|
|||
|
WORD wx2TerrainNum;
|
|||
|
WORD wy2TerrainNum;
|
|||
|
|
|||
|
ConvertToMapCoords(float(rkRect.left), float(rkRect.top), &ix1Cell, &iy1Cell, &byx1SubCell, &byy1SubCell, &wx1TerrainNum, &wy1TerrainNum);
|
|||
|
ConvertToMapCoords(float(rkRect.right), float(rkRect.bottom), &ix2Cell, &iy2Cell, &byx2SubCell, &byy2SubCell, &wx2TerrainNum, &wy2TerrainNum);
|
|||
|
|
|||
|
ix1Cell = ix1Cell + wx1TerrainNum*CTerrain::ATTRMAP_XSIZE;
|
|||
|
iy1Cell = iy1Cell + wy1TerrainNum*CTerrain::ATTRMAP_YSIZE;
|
|||
|
ix2Cell = ix2Cell + wx2TerrainNum*CTerrain::ATTRMAP_XSIZE;
|
|||
|
iy2Cell = iy2Cell + wy2TerrainNum*CTerrain::ATTRMAP_YSIZE;
|
|||
|
|
|||
|
for (int ixCell = ix1Cell; ixCell <= ix2Cell; ++ixCell)
|
|||
|
for (int iyCell = iy1Cell; iyCell <= iy2Cell; ++iyCell)
|
|||
|
{
|
|||
|
int ixLocalCell = ixCell % CTerrain::ATTRMAP_XSIZE;
|
|||
|
int iyLocalCell = iyCell % CTerrain::ATTRMAP_YSIZE;
|
|||
|
int ixTerrain = ixCell / CTerrain::ATTRMAP_XSIZE;
|
|||
|
int iyTerrain = iyCell / CTerrain::ATTRMAP_YSIZE;
|
|||
|
int iTerrainNum = ixTerrain+iyTerrain*100;
|
|||
|
|
|||
|
BYTE byTerrainNum;
|
|||
|
if (!GetTerrainNumFromCoord(ixTerrain, iyTerrain, &byTerrainNum))
|
|||
|
continue;
|
|||
|
CTerrain * pTerrain;
|
|||
|
if (!GetTerrainPointer(byTerrainNum, &pTerrain))
|
|||
|
continue;
|
|||
|
|
|||
|
if (kMap_pbyMarkBuf.end() == kMap_pbyMarkBuf.find(iTerrainNum))
|
|||
|
{
|
|||
|
BYTE * pbyBuf = new BYTE [CTerrain::ATTRMAP_XSIZE*CTerrain::ATTRMAP_YSIZE];
|
|||
|
ZeroMemory(pbyBuf, CTerrain::ATTRMAP_XSIZE*CTerrain::ATTRMAP_YSIZE);
|
|||
|
kMap_pbyMarkBuf[iTerrainNum] = pbyBuf;
|
|||
|
}
|
|||
|
|
|||
|
BYTE * pbyBuf = kMap_pbyMarkBuf[iTerrainNum];
|
|||
|
pbyBuf[ixLocalCell+iyLocalCell*CTerrain::ATTRMAP_XSIZE] = 0xff;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
std::map<int, BYTE*>::iterator itorTerrain = kMap_pbyMarkBuf.begin();
|
|||
|
for (; itorTerrain != kMap_pbyMarkBuf.end(); ++itorTerrain)
|
|||
|
{
|
|||
|
int iTerrainNum = itorTerrain->first;
|
|||
|
int ixTerrain = iTerrainNum%100;
|
|||
|
int iyTerrain = iTerrainNum/100;
|
|||
|
BYTE * pbyBuf = itorTerrain->second;
|
|||
|
|
|||
|
BYTE byTerrainNum;
|
|||
|
if (!GetTerrainNumFromCoord(ixTerrain, iyTerrain, &byTerrainNum))
|
|||
|
continue;
|
|||
|
CTerrain * pTerrain;
|
|||
|
if (!GetTerrainPointer(byTerrainNum, &pTerrain))
|
|||
|
continue;
|
|||
|
|
|||
|
pTerrain->AllocateMarkedSplats(pbyBuf);
|
|||
|
}
|
|||
|
|
|||
|
stl_wipe_second(kMap_pbyMarkBuf);
|
|||
|
}
|
|||
|
|
|||
|
void CMapOutdoor::DisableMarkedArea()
|
|||
|
{
|
|||
|
for (int i = 0; i < AROUND_AREA_NUM; ++i)
|
|||
|
{
|
|||
|
if (!m_pTerrain[i])
|
|||
|
continue;
|
|||
|
|
|||
|
m_pTerrain[i]->DeallocateMarkedSplats();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void CMapOutdoor::ConvertToMapCoords(float fx, float fy, int *iCellX, int *iCellY, BYTE * pucSubCellX, BYTE * pucSubCellY, WORD * pwTerrainNumX, WORD * pwTerrainNumY)
|
|||
|
{
|
|||
|
if ( fy < 0 )
|
|||
|
fy = -fy;
|
|||
|
|
|||
|
int ix, iy;
|
|||
|
PR_FLOAT_TO_INT(fx, ix);
|
|||
|
PR_FLOAT_TO_INT(fy, iy);
|
|||
|
|
|||
|
*pwTerrainNumX = ix / (CTerrainImpl::TERRAIN_XSIZE);
|
|||
|
*pwTerrainNumY = iy / (CTerrainImpl::TERRAIN_YSIZE);
|
|||
|
|
|||
|
float maxx = (float) CTerrainImpl::TERRAIN_XSIZE;
|
|||
|
float maxy = (float) CTerrainImpl::TERRAIN_YSIZE;
|
|||
|
|
|||
|
while (fx < 0)
|
|||
|
fx += maxx;
|
|||
|
|
|||
|
while (fy < 0)
|
|||
|
fy += maxy;
|
|||
|
|
|||
|
while (fx >= maxx)
|
|||
|
fx -= maxx;
|
|||
|
|
|||
|
while (fy >= maxy)
|
|||
|
fy -= maxy;
|
|||
|
|
|||
|
float fooscale = 1.0f / (float)(CTerrainImpl::HALF_CELLSCALE);
|
|||
|
|
|||
|
float fCellX, fCellY;
|
|||
|
|
|||
|
fCellX = fx * fooscale;
|
|||
|
fCellY = fy * fooscale;
|
|||
|
|
|||
|
PR_FLOAT_TO_INT(fCellX, *iCellX);
|
|||
|
PR_FLOAT_TO_INT(fCellY, *iCellY);
|
|||
|
|
|||
|
float fRatioooscale = ((float)CTerrainImpl::HEIGHT_TILE_XRATIO) * fooscale;
|
|||
|
|
|||
|
float fSubcellX, fSubcellY;
|
|||
|
fSubcellX = fx * fRatioooscale;
|
|||
|
fSubcellY = fy * fRatioooscale;
|
|||
|
|
|||
|
PR_FLOAT_TO_INT(fSubcellX, *pucSubCellX);
|
|||
|
PR_FLOAT_TO_INT(fSubcellY, *pucSubCellY);
|
|||
|
*pucSubCellX = (*pucSubCellX) % CTerrainImpl::HEIGHT_TILE_XRATIO;
|
|||
|
*pucSubCellY = (*pucSubCellY) % CTerrainImpl::HEIGHT_TILE_YRATIO;
|
|||
|
}
|