#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(); // ÇØÁ¦ Initialize(); // ÃʱâÈ­ } 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 && fPosGetHeight(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 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* 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::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=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 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 kMap_pbyMarkBuf; std::set kSet_iProcessedMapIndex; std::list::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::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; }