client/GameLib/Area.cpp

1449 lines
42 KiB
C++
Raw Normal View History

#include "StdAfx.h"
#include "../eterLib/ResourceManager.h"
#include "../eterLib/StateManager.h"
#include "../effectLib/EffectManager.h"
#include "../SpeedTreeLib/SpeedTreeForestDirectX8.h"
#include "../eterBase/Timer.h"
#include "Area.h"
#include "PropertyManager.h"
#include "Property.h"
#include <boost/algorithm/string.hpp>
CDynamicPool<CArea::TObjectInstance> CArea::ms_ObjectInstancePool;
CDynamicPool<CAttributeInstance> CArea::ms_AttributeInstancePool;
CDynamicPool<CArea::TAmbienceInstance> CArea::ms_AmbienceInstancePool;
CDynamicPool<CDungeonBlock> CArea::ms_DungeonBlockInstancePool;
CDynamicPool<CArea> CArea::ms_kPool;
void CArea::TObjectData::InitializeRotation()
{
m_fYaw=m_fPitch=m_fRoll=0.0f;
}
CArea* CArea::New()
{
return ms_kPool.Alloc();
}
void CArea::Delete(CArea* pkArea)
{
pkArea->Clear();
ms_kPool.Free(pkArea);
}
void CArea::DestroySystem()
{
ms_kPool.Destroy();
ms_ObjectInstancePool.Destroy();
ms_AttributeInstancePool.Destroy();
ms_AmbienceInstancePool.Destroy();
ms_DungeonBlockInstancePool.Destroy();
}
void CArea::__UpdateAniThingList()
{
{
CGraphicThingInstance* pkThingInst;
TThingInstanceVector::iterator i=m_ThingCloneInstaceVector.begin();
while (i!=m_ThingCloneInstaceVector.end())
{
pkThingInst=*i++;
if (pkThingInst->isShow())
{
pkThingInst->UpdateLODLevel();
}
}
}
{
CGraphicThingInstance* pkThingInst;
TThingInstanceVector::iterator i=m_AniThingCloneInstanceVector.begin();
while (i!=m_AniThingCloneInstanceVector.end())
{
pkThingInst=*i++;
pkThingInst->Update();
}
}
}
void CArea::__UpdateEffectList()
{
//if (!CEffectManager::InstancePtr())
// return;
CEffectManager& rkEftMgr=CEffectManager::Instance();
// Effect
TEffectInstanceIterator i;
for (i = m_EffectInstanceMap.begin(); i != m_EffectInstanceMap.end();)
{
CEffectInstance * pEffectInstance = i->second;
pEffectInstance->Update();
if (!pEffectInstance->isAlive())
{
i = m_EffectInstanceMap.erase(i);
rkEftMgr.DestroyUnsafeEffectInstance(pEffectInstance);
}
else
++i;
}
}
void CArea::Update()
{
__UpdateAniThingList();
}
void CArea::UpdateAroundAmbience(float fX, float fY, float fZ)
{
// Ambience
TAmbienceInstanceVector::iterator i;
for (i = m_AmbienceCloneInstanceVector.begin(); i != m_AmbienceCloneInstanceVector.end(); ++i)
{
TAmbienceInstance * pInstance = *i;
pInstance->__Update(fX, fY, fZ);
}
}
struct CArea_LessEffectInstancePtrRenderOrder
{
bool operator() (CEffectInstance* pkLeft, CEffectInstance* pkRight)
{
return pkLeft->LessRenderOrder(pkRight);
}
};
struct CArea_FEffectInstanceRender
{
inline void operator () (CEffectInstance * pkEftInst)
{
pkEftInst->Render();
}
};
void CArea::RenderEffect()
{
__UpdateEffectList();
// Effect
STATEMANAGER.SetTexture(0, NULL);
STATEMANAGER.SetTexture(1, NULL);
bool m_isDisableSortRendering=false;
if (m_isDisableSortRendering)
{
TEffectInstanceIterator i;
for (i = m_EffectInstanceMap.begin(); i != m_EffectInstanceMap.end();)
{
CEffectInstance * pEffectInstance = i->second;
pEffectInstance->Render();
++i;
}
}
else
{
static std::vector<CEffectInstance*> s_kVct_pkEftInstSort;
s_kVct_pkEftInstSort.clear();
TEffectInstanceMap& rkMap_pkEftInstSrc=m_EffectInstanceMap;
TEffectInstanceMap::iterator i;
for (i=rkMap_pkEftInstSrc.begin(); i!=rkMap_pkEftInstSrc.end(); ++i)
s_kVct_pkEftInstSort.push_back(i->second);
std::sort(s_kVct_pkEftInstSort.begin(), s_kVct_pkEftInstSort.end(), CArea_LessEffectInstancePtrRenderOrder());
std::for_each(s_kVct_pkEftInstSort.begin(), s_kVct_pkEftInstSort.end(), CArea_FEffectInstanceRender());
}
}
DWORD CArea::DEBUG_GetRenderedCRCNum()
{ return m_kRenderedThingInstanceCRCWithNumberVector.size(); }
CArea::TCRCWithNumberVector & CArea::DEBUG_GetRenderedCRCWithNumVector()
{ return m_kRenderedThingInstanceCRCWithNumberVector; }
DWORD CArea::DEBUG_GetRenderedGrapphicThingInstanceNum()
{ return m_kRenderedGrapphicThingInstanceVector.size(); }
void CArea::CollectRenderingObject(std::vector<CGraphicThingInstance*>& rkVct_pkOpaqueThingInst)
{
TThingInstanceVector::iterator i;
for (i=m_ThingCloneInstaceVector.begin(); i!=m_ThingCloneInstaceVector.end(); ++i)
{
CGraphicThingInstance* pkThingInst=*i;
if (pkThingInst->isShow())
{
if (!pkThingInst->HaveBlendThing())
rkVct_pkOpaqueThingInst.push_back(*i);
}
}
}
void CArea::CollectBlendRenderingObject(std::vector<CGraphicThingInstance*>& rkVct_pkBlendThingInst)
{
TThingInstanceVector::iterator i;
for (i=m_ThingCloneInstaceVector.begin(); i!=m_ThingCloneInstaceVector.end(); ++i)
{
CGraphicThingInstance* pkThingInst=*i;
if (pkThingInst->isShow())
{
if (pkThingInst->HaveBlendThing())
rkVct_pkBlendThingInst.push_back(*i);
}
}
}
void CArea::Render()
{
{
CGraphicThingInstance* pkThingInst;
TThingInstanceVector::iterator i=m_AniThingCloneInstanceVector.begin();
while (i!=m_AniThingCloneInstanceVector.end())
{
pkThingInst=*i++;
pkThingInst->Deform();
}
}
CGraphicThingInstance* pkThingInst;
TThingInstanceVector::iterator i=m_ThingCloneInstaceVector.begin();
m_kRenderedThingInstanceCRCWithNumberVector.clear();
m_kRenderedGrapphicThingInstanceVector.clear();
TGraphicThingInstanceCRCMap::iterator aGraphicThingInstanceCRCMapIterator;
while (i!=m_ThingCloneInstaceVector.end())
{
pkThingInst=*i++;
if (pkThingInst->Render())
{
aGraphicThingInstanceCRCMapIterator = m_GraphicThingInstanceCRCMap.find(pkThingInst);
DWORD dwCRC = (*aGraphicThingInstanceCRCMapIterator).second;
m_kRenderedGrapphicThingInstanceVector.push_back(pkThingInst);
TCRCWithNumberVector::iterator aCRCWithNumberVectorIterator = std::find_if(m_kRenderedThingInstanceCRCWithNumberVector.begin(), m_kRenderedThingInstanceCRCWithNumberVector.end(), FFindIfCRC(dwCRC));
if ( m_kRenderedThingInstanceCRCWithNumberVector.end() == aCRCWithNumberVectorIterator)
{
TCRCWithNumber aCRCWithNumber;
aCRCWithNumber.dwCRC = dwCRC;
aCRCWithNumber.dwNumber = 1;
m_kRenderedThingInstanceCRCWithNumberVector.push_back(aCRCWithNumber);
}
else
{
TCRCWithNumber & rCRCWithNumber = *aCRCWithNumberVectorIterator;
rCRCWithNumber.dwNumber += 1;
}
}
}
std::sort(m_kRenderedThingInstanceCRCWithNumberVector.begin(), m_kRenderedThingInstanceCRCWithNumberVector.end(), CRCNumComp());
}
void CArea::RenderCollision()
{
DWORD i;
STATEMANAGER.SetTexture(0, NULL);
STATEMANAGER.SetTexture(1, NULL);
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE);
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, 0xff000000);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
for(i=0;i<GetObjectInstanceCount();i++)
{
const TObjectInstance * po;
if (GetObjectInstancePointer(i,&po))
{
if (po->pTree && po->pTree->isShow())
{
DWORD j;
for(j=0;j<po->pTree->GetCollisionInstanceCount();j++)
{
po->pTree->GetCollisionInstanceData(j)->Render();
}
}
if (po->pThingInstance && po->pThingInstance->isShow())
{
DWORD j;
for(j=0;j<po->pThingInstance->GetCollisionInstanceCount();j++)
{
po->pThingInstance->GetCollisionInstanceData(j)->Render();
}
}
if (po->pDungeonBlock && po->pDungeonBlock->isShow())
{
DWORD j;
for(j=0;j<po->pDungeonBlock->GetCollisionInstanceCount();j++)
{
po->pDungeonBlock->GetCollisionInstanceData(j)->Render();
}
}
}
}
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE);
STATEMANAGER.SetRenderState(D3DRS_LIGHTING, TRUE);
}
void CArea::RenderAmbience()
{
DWORD dwColorArg1, dwColorOp;
STATEMANAGER.GetTextureStageState(0, D3DTSS_COLORARG1, &dwColorArg1);
STATEMANAGER.GetTextureStageState(0, D3DTSS_COLOROP, &dwColorOp);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
TAmbienceInstanceVector::iterator itor = m_AmbienceCloneInstanceVector.begin();
for (; itor != m_AmbienceCloneInstanceVector.end(); ++itor)
{
TAmbienceInstance * pInstance = *itor;
pInstance->Render();
}
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, dwColorArg1);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, dwColorOp);
}
void CArea::RenderDungeon()
{
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
#ifdef WORLD_EDITOR
bool bRenderTransparent = false;
DWORD oldAlphaBlendState = 0;
DWORD oldZWriteenableState = 0;
if (GetAsyncKeyState(VK_LSHIFT) & 0x8001)
{
bRenderTransparent = true;
oldAlphaBlendState = STATEMANAGER.GetRenderState(D3DRS_ALPHABLENDENABLE);
oldZWriteenableState = STATEMANAGER.GetRenderState(D3DRS_ZWRITEENABLE);
STATEMANAGER.SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
STATEMANAGER.SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TFACTOR);
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_TFACTOR);
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, D3DCOLOR_ARGB( 128, 255, 0, 0) );
}
#endif
TDungeonBlockInstanceVector::iterator itor = m_DungeonBlockCloneInstanceVector.begin();
for (; itor != m_DungeonBlockCloneInstanceVector.end(); ++itor)
{
(*itor)->Render();
}
#ifdef WORLD_EDITOR
if (bRenderTransparent)
{
STATEMANAGER.SetRenderState(D3DRS_ZWRITEENABLE, oldZWriteenableState);
STATEMANAGER.SetRenderState(D3DRS_ALPHABLENDENABLE, oldAlphaBlendState);
}
#endif
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
}
void CArea::Refresh()
{
m_TreeCloneInstaceVector.clear();
m_ThingCloneInstaceVector.clear();
m_DungeonBlockCloneInstanceVector.clear();
m_AniThingCloneInstanceVector.clear();
m_ShadowThingCloneInstaceVector.clear();
m_AmbienceCloneInstanceVector.clear();
TObjectInstanceVector::iterator it;
for(it = m_ObjectInstanceVector.begin();it!=m_ObjectInstanceVector.end();++it)
{
TObjectInstance * pObjectInstance = *it;
if (prt::PROPERTY_TYPE_TREE == pObjectInstance->dwType)
{
if (pObjectInstance->pTree)
{
m_TreeCloneInstaceVector.push_back(pObjectInstance->pTree);
const float * pfPosition;
pfPosition = pObjectInstance->pTree->GetPosition();
pObjectInstance->pTree->UpdateBoundingSphere();
pObjectInstance->pTree->UpdateCollisionData();
}
}
else if (prt::PROPERTY_TYPE_BUILDING == pObjectInstance->dwType)
{
pObjectInstance->pThingInstance->Update();
pObjectInstance->pThingInstance->Transform();
pObjectInstance->pThingInstance->Show();
pObjectInstance->pThingInstance->DeformAll();
m_ThingCloneInstaceVector.push_back(pObjectInstance->pThingInstance);
pObjectInstance->pThingInstance->BuildBoundingSphere();
pObjectInstance->pThingInstance->UpdateBoundingSphere();
if (pObjectInstance->pThingInstance->IsMotionThing())
{
m_AniThingCloneInstanceVector.push_back(pObjectInstance->pThingInstance);
pObjectInstance->pThingInstance->SetMotion(0);
}
if (pObjectInstance->isShadowFlag)
{
m_ShadowThingCloneInstaceVector.push_back(pObjectInstance->pThingInstance);
}
if (pObjectInstance->pAttributeInstance)
{
pObjectInstance->pThingInstance->UpdateCollisionData(&pObjectInstance->pAttributeInstance->GetObjectPointer()->GetCollisionDataVector());
pObjectInstance->pAttributeInstance->RefreshObject(pObjectInstance->pThingInstance->GetTransform());
pObjectInstance->pThingInstance->UpdateHeightInstance(pObjectInstance->pAttributeInstance);
}
}
else if (prt::PROPERTY_TYPE_EFFECT == pObjectInstance->dwType)
{
}
else if (prt::PROPERTY_TYPE_AMBIENCE == pObjectInstance->dwType)
{
m_AmbienceCloneInstanceVector.push_back(pObjectInstance->pAmbienceInstance);
}
else if (prt::PROPERTY_TYPE_DUNGEON_BLOCK == pObjectInstance->dwType)
{
pObjectInstance->pDungeonBlock->Update();
pObjectInstance->pDungeonBlock->Deform();
pObjectInstance->pDungeonBlock->UpdateBoundingSphere();
m_DungeonBlockCloneInstanceVector.push_back(pObjectInstance->pDungeonBlock);
if (pObjectInstance->pAttributeInstance)
{
pObjectInstance->pDungeonBlock->UpdateCollisionData(&pObjectInstance->pAttributeInstance->GetObjectPointer()->GetCollisionDataVector());
pObjectInstance->pAttributeInstance->RefreshObject(pObjectInstance->pDungeonBlock->GetTransform());
pObjectInstance->pDungeonBlock->UpdateHeightInstance(pObjectInstance->pAttributeInstance);
}
}
}
}
void CArea::__Load_BuildObjectInstances()
{
m_ObjectInstanceVector.clear();
m_ObjectInstanceVector.resize(GetObjectDataCount());
m_GraphicThingInstanceCRCMap.clear();
std::sort(m_ObjectDataVector.begin(), m_ObjectDataVector.end(), ObjectDataComp());
DWORD i=0;
TObjectInstanceVector::iterator it;
for (it = m_ObjectInstanceVector.begin(); it!=m_ObjectInstanceVector.end();++it,++i)
{
*it = ms_ObjectInstancePool.Alloc();
(*it)->Clear();
const TObjectData * c_pObjectData;
if (!GetObjectDataPointer(i, &c_pObjectData))
continue;
__SetObjectInstance(*it, c_pObjectData);
// <20><><EFBFBD><EFBFBD>ȭ<EFBFBD><C8AD>
if ((*it)->dwType == prt::PROPERTY_TYPE_BUILDING)
m_GraphicThingInstanceCRCMap.insert(TGraphicThingInstanceCRCMap::value_type( (*it)->pThingInstance, c_pObjectData->dwCRC ) );
}
//////////
Refresh();
//////////
}
void CArea::__SetObjectInstance(TObjectInstance * pObjectInstance, const TObjectData * c_pData)
{
CProperty * pProperty;
if (!CPropertyManager::Instance().Get(c_pData->dwCRC, &pProperty))
return;
const char * c_szPropertyType;
if (!pProperty->GetString("PropertyType", &c_szPropertyType))
return;
switch (prt::GetPropertyType(c_szPropertyType))
{
case prt::PROPERTY_TYPE_TREE:
__SetObjectInstance_SetTree(pObjectInstance, c_pData, pProperty);
break;
case prt::PROPERTY_TYPE_BUILDING:
__SetObjectInstance_SetBuilding(pObjectInstance, c_pData, pProperty);
break;
case prt::PROPERTY_TYPE_EFFECT:
__SetObjectInstance_SetEffect(pObjectInstance, c_pData, pProperty);
break;
case prt::PROPERTY_TYPE_AMBIENCE:
__SetObjectInstance_SetAmbience(pObjectInstance, c_pData, pProperty);
break;
case prt::PROPERTY_TYPE_DUNGEON_BLOCK:
__SetObjectInstance_SetDungeonBlock(pObjectInstance, c_pData, pProperty);
break;
}
}
void CArea::__SetObjectInstance_SetEffect(TObjectInstance * pObjectInstance, const TObjectData * c_pData, CProperty * pProperty)
{
prt::TPropertyEffect Data;
if (!prt::PropertyEffectStringToData(pProperty, &Data))
return;
pObjectInstance->dwType = prt::PROPERTY_TYPE_EFFECT;
pObjectInstance->dwEffectID = GetCaseCRC32(Data.strFileName.c_str(),Data.strFileName.size());
CEffectManager & rem = CEffectManager::Instance();
CEffectData * pData;
if (!rem.GetEffectData(pObjectInstance->dwEffectID,&pData))
{
if (!rem.RegisterEffect(Data.strFileName.c_str()))
{
pObjectInstance->dwEffectID = 0xffffffff;
TraceError("CArea::SetEffect effect register error %s\n",Data.strFileName.c_str());
return;
}
}
CEffectInstance * pEffectInstance;
rem.CreateUnsafeEffectInstance(pObjectInstance->dwEffectID, &pEffectInstance);
D3DXMATRIX mat;
D3DXMatrixRotationYawPitchRoll(&mat,
D3DXToRadian(c_pData->m_fYaw),
D3DXToRadian(c_pData->m_fPitch),
D3DXToRadian(c_pData->m_fRoll)
);
mat._41 = c_pData->Position.x;
mat._42 = c_pData->Position.y;
mat._43 = c_pData->Position.z + c_pData->m_fHeightBias;
pEffectInstance->SetGlobalMatrix(mat);
pObjectInstance->dwEffectInstanceIndex = m_EffectInstanceMap.size();
m_EffectInstanceMap.insert(TEffectInstanceMap::value_type(pObjectInstance->dwEffectInstanceIndex, pEffectInstance));
}
void CArea::__SetObjectInstance_SetTree(TObjectInstance * pObjectInstance, const TObjectData * c_pData, CProperty * pProperty)
{
const char * c_szTreeName;
if (!pProperty->GetString("TreeFile", &c_szTreeName))
return;
pObjectInstance->SetTree(
c_pData->Position.x,
c_pData->Position.y,
c_pData->Position.z + c_pData->m_fHeightBias,
c_pData->dwCRC,
c_szTreeName
);
}
void CArea::TObjectInstance::SetTree(float x, float y, float z, DWORD dwTreeCRC, const char* c_szTreeName)
{
CSpeedTreeForestDirectX8& rkForest=CSpeedTreeForestDirectX8::Instance();
pTree=rkForest.CreateInstance(x, y, z, dwTreeCRC, c_szTreeName);
dwType = prt::PROPERTY_TYPE_TREE;
}
void CArea::__SetObjectInstance_SetBuilding(TObjectInstance * pObjectInstance, const TObjectData * c_pData, CProperty * pProperty)
{
prt::TPropertyBuilding Data;
if (!prt::PropertyBuildingStringToData(pProperty, &Data))
return;
CResourceManager& rkResMgr=CResourceManager::Instance();
CGraphicThing * pThing = (CGraphicThing *)rkResMgr.GetResourcePointer(Data.strFileName.c_str());
pThing->AddReference();
if (pThing->IsEmpty())
{
#ifdef _DEBUG
TraceError("CArea::SetBuilding: There is no data: %s", Data.strFileName.c_str());
#endif
return;
}
int iModelCount = pThing->GetModelCount();
int iMotionCount = pThing->GetMotionCount();
pObjectInstance->dwType = prt::PROPERTY_TYPE_BUILDING;
pObjectInstance->pThingInstance = CGraphicThingInstance::New();
pObjectInstance->pThingInstance->Initialize();
pObjectInstance->pThingInstance->ReserveModelThing(iModelCount);
pObjectInstance->pThingInstance->ReserveModelInstance(iModelCount);
pObjectInstance->pThingInstance->RegisterModelThing(0, pThing);
for (int j = 0; j < PORTAL_ID_MAX_NUM; ++j)
if (0 != c_pData->abyPortalID[j])
pObjectInstance->pThingInstance->SetPortal(j, c_pData->abyPortalID[j]);
{
std::string stSrcModelFileName=Data.strFileName;
std::string stLODModelFileName;
char szLODModelFileNameEnd[256];
for (UINT uLODIndex=1; uLODIndex<=3; ++uLODIndex)
{
sprintf(szLODModelFileNameEnd, "_lod_%.2d.gr2", uLODIndex);
stLODModelFileName = CFileNameHelper::NoExtension(stSrcModelFileName) + szLODModelFileNameEnd;
if (!rkResMgr.IsFileExist(stLODModelFileName.c_str()))
break;
CGraphicThing* pLODModelThing = (CGraphicThing *)rkResMgr.GetResourcePointer(stLODModelFileName.c_str());
if (!pLODModelThing)
break;
pObjectInstance->pThingInstance->RegisterLODThing(0, pLODModelThing);
}
}
for (int i = 0; i < iModelCount; ++i)
pObjectInstance->pThingInstance->SetModelInstance(i, 0, i);
if (iMotionCount)
{
pObjectInstance->pThingInstance->RegisterMotionThing(0, pThing);
}
pObjectInstance->pThingInstance->SetPosition(c_pData->Position.x, c_pData->Position.y, c_pData->Position.z + c_pData->m_fHeightBias);
pObjectInstance->pThingInstance->SetRotation(
c_pData->m_fYaw,
c_pData->m_fPitch,
c_pData->m_fRoll
);
pObjectInstance->isShadowFlag = Data.isShadowFlag;
pObjectInstance->pThingInstance->RegisterBoundingSphere();
__LoadAttribute(pObjectInstance, Data.strAttributeDataFileName.c_str());
pThing->Release();
}
void CArea::__SetObjectInstance_SetAmbience(TObjectInstance * pObjectInstance, const TObjectData * c_pData, CProperty * pProperty)
{
pObjectInstance->pAmbienceInstance = ms_AmbienceInstancePool.Alloc();
if (!prt::PropertyAmbienceStringToData(pProperty, &pObjectInstance->pAmbienceInstance->AmbienceData))
return;
pObjectInstance->dwType = prt::PROPERTY_TYPE_AMBIENCE;
TAmbienceInstance * pAmbienceInstance = pObjectInstance->pAmbienceInstance;
pAmbienceInstance->fx = c_pData->Position.x;
pAmbienceInstance->fy = c_pData->Position.y;
pAmbienceInstance->fz = c_pData->Position.z + c_pData->m_fHeightBias;
pAmbienceInstance->dwRange = c_pData->dwRange;
pAmbienceInstance->fMaxVolumeAreaPercentage = c_pData->fMaxVolumeAreaPercentage;
if (0 == pAmbienceInstance->AmbienceData.strPlayType.compare("ONCE"))
{
pAmbienceInstance->Update = &TAmbienceInstance::UpdateOnceSound;
}
else if (0 == pAmbienceInstance->AmbienceData.strPlayType.compare("STEP"))
{
pAmbienceInstance->Update = &TAmbienceInstance::UpdateStepSound;
}
else if (0 == pAmbienceInstance->AmbienceData.strPlayType.compare("LOOP"))
{
pAmbienceInstance->Update = &TAmbienceInstance::UpdateLoopSound;
}
}
void CArea::__SetObjectInstance_SetDungeonBlock(TObjectInstance * pObjectInstance, const TObjectData * c_pData, CProperty * pProperty)
{
prt::TPropertyDungeonBlock Data;
if (!prt::PropertyDungeonBlockStringToData(pProperty, &Data))
return;
pObjectInstance->dwType = prt::PROPERTY_TYPE_DUNGEON_BLOCK;
pObjectInstance->pDungeonBlock = ms_DungeonBlockInstancePool.Alloc();
pObjectInstance->pDungeonBlock->Load(Data.strFileName.c_str());
pObjectInstance->pDungeonBlock->SetPosition(c_pData->Position.x, c_pData->Position.y, c_pData->Position.z + c_pData->m_fHeightBias);
pObjectInstance->pDungeonBlock->SetRotation(
c_pData->m_fYaw,
c_pData->m_fPitch,
c_pData->m_fRoll
);
pObjectInstance->pDungeonBlock->Update();
pObjectInstance->pDungeonBlock->BuildBoundingSphere();
pObjectInstance->pDungeonBlock->RegisterBoundingSphere();
for (int j = 0; j < PORTAL_ID_MAX_NUM; ++j)
if (0 != c_pData->abyPortalID[j])
pObjectInstance->pDungeonBlock->SetPortal(j, c_pData->abyPortalID[j]);
__LoadAttribute(pObjectInstance, Data.strAttributeDataFileName.c_str());
}
void CArea::__LoadAttribute(TObjectInstance * pObjectInstance, const char * c_szAttributeFileName)
{
// OBB<42><42> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><20><><EFBFBD><EFBFBD> <20>ڵ<EFBFBD> <20><><EFBFBD><EFBFBD>.
const bool bFileExist = CResourceManager::Instance().IsFileExist(c_szAttributeFileName);
CAttributeData * pAttributeData = (CAttributeData *) CResourceManager::Instance().GetResourcePointer(c_szAttributeFileName);
CAttributeInstance * pAttrInstance = ms_AttributeInstancePool.Alloc();
pAttrInstance->Clear();
pAttrInstance->SetObjectPointer(pAttributeData);
if (false == bFileExist)
{
std::string attrFileName(c_szAttributeFileName);
boost::algorithm::to_lower(attrFileName);
const bool bIsDungeonObject = (std::string::npos != attrFileName.find("/dungeon/")) || (std::string::npos != attrFileName.find("\\dungeon\\"));
// NOTE: dungeon <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> Dummy Collision<6F><6E> <20>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʵ<EFBFBD><CAB5><EFBFBD> <20><> (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ø<EFBFBD><C3B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>־<EFBFBD><D6BE><EFBFBD>. <20>̷<EFBFBD><CCB7><EFBFBD> <20>ϱ<EFBFBD><CFB1><EFBFBD> <20>׷<EFBFBD><D7B7><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>Ϸ<EFBFBD>)
if (pAttributeData->IsEmpty() && false == bIsDungeonObject)
{
if (NULL != pObjectInstance && NULL != pObjectInstance->pThingInstance)
{
CGraphicThingInstance* object = pObjectInstance->pThingInstance;
D3DXVECTOR3 v3Min, v3Max;
object->GetBoundingAABB(v3Min, v3Max);
CStaticCollisionData collision;
collision.dwType = COLLISION_TYPE_OBB;
D3DXQuaternionRotationYawPitchRoll(&collision.quatRotation, object->GetYaw(), object->GetPitch(), object->GetRoll());
strcpy(collision.szName, "DummyCollisionOBB");
collision.v3Position = (v3Min + v3Max) * 0.5f;
D3DXVECTOR3 vDelta = (v3Max - v3Min);
collision.fDimensions[0] = vDelta.x * 0.5f;
collision.fDimensions[1] = vDelta.y * 0.5f;
collision.fDimensions[2] = vDelta.z * 0.5f;
pAttributeData->AddCollisionData(collision);
}
}
}
if (!pAttributeData->IsEmpty())
{
pObjectInstance->pAttributeInstance = pAttrInstance;
}
else
{
pAttrInstance->Clear();
ms_AttributeInstancePool.Free(pAttrInstance);
}
}
/*
void CArea::__LoadAttribute(TObjectInstance * pObjectInstance, const char * c_szAttributeFileName)
{
// AABB<42><42> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><20><><EFBFBD><EFBFBD> <20>ڵ<EFBFBD> <20><><EFBFBD><EFBFBD>.
const bool bFileExist = CResourceManager::Instance().IsFileExist(c_szAttributeFileName);
CAttributeData * pAttributeData = (CAttributeData *) CResourceManager::Instance().GetResourcePointer(c_szAttributeFileName);
CAttributeInstance * pAttrInstance = ms_AttributeInstancePool.Alloc();
pAttrInstance->Clear();
pAttrInstance->SetObjectPointer(pAttributeData);
if (false == bFileExist)
{
if (pAttributeData->IsEmpty())
{
if (NULL != pObjectInstance && NULL != pObjectInstance->pThingInstance)
{
CGraphicThingInstance* object = pObjectInstance->pThingInstance;
D3DXVECTOR3 v3Min, v3Max;
object->GetBoundingAABB(v3Min, v3Max);
CStaticCollisionData collision;
collision.dwType = COLLISION_TYPE_AABB;
collision.quatRotation = D3DXQUATERNION(0.0f, 0.0f, 0.0f, 1.0f);
strcpy(collision.szName, "DummyCollisionAABB");
collision.v3Position = (v3Min + v3Max) * 0.5f;
D3DXVECTOR3 vDelta = (v3Max - v3Min);
collision.fDimensions[0] = vDelta.x * 0.5f; // v3Min, v3Max<61><78> <20><><EFBFBD>ϱ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ݰ<EFBFBD> <20><><EFBFBD><EFBFBD>
collision.fDimensions[1] = vDelta.y * 0.5f;
collision.fDimensions[2] = vDelta.z * 0.5f;
pAttributeData->AddCollisionData(collision);
}
}
}
if (!pAttributeData->IsEmpty())
{
pObjectInstance->pAttributeInstance = pAttrInstance;
}
else
{
pAttrInstance->Clear();
ms_AttributeInstancePool.Free(pAttrInstance);
}
}
*/
/*
void CArea::__LoadAttribute(TObjectInstance * pObjectInstance, const char * c_szAttributeFileName)
{
// Sphere<72><65> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><20><><EFBFBD><EFBFBD> <20>ڵ<EFBFBD> <20><><EFBFBD><EFBFBD>.
const bool bFileExist = CResourceManager::Instance().IsFileExist(c_szAttributeFileName);
CAttributeData * pAttributeData = (CAttributeData *) CResourceManager::Instance().GetResourcePointer(c_szAttributeFileName);
CAttributeInstance * pAttrInstance = ms_AttributeInstancePool.Alloc();
pAttrInstance->Clear();
pAttrInstance->SetObjectPointer(pAttributeData);
if (false == bFileExist)
{
if (pAttributeData->IsEmpty())
{
if (NULL != pObjectInstance && NULL != pObjectInstance->pThingInstance)
{
CGraphicThingInstance* object = pObjectInstance->pThingInstance;
D3DXVECTOR3 v3Center;
float fRadius = 0.0f;
object->GetBoundingSphere(v3Center, fRadius);
CStaticCollisionData collision;
collision.dwType = COLLISION_TYPE_SPHERE;
collision.quatRotation = D3DXQUATERNION(0.0f, 0.0f, 0.0f, 1.0f);
strcpy(collision.szName, "DummyCollisionSphere");
collision.fDimensions[0] = fRadius * 0.25;
collision.v3Position = v3Center;
pAttributeData->AddCollisionData(collision);
}
}
}
if (!pAttributeData->IsEmpty())
{
pObjectInstance->pAttributeInstance = pAttrInstance;
}
else
{
pAttrInstance->Clear();
ms_AttributeInstancePool.Free(pAttrInstance);
}
}
*/
bool CArea::Load(const char * c_szPathName)
{
Clear();
std::string strObjectDataFileName = c_szPathName + std::string("AreaData.txt");
std::string strAmbienceDataFileName = c_szPathName + std::string("AreaAmbienceData.txt");
__Load_LoadObject(strObjectDataFileName.c_str());
__Load_LoadAmbience(strAmbienceDataFileName.c_str());
__Load_BuildObjectInstances();
return true;
}
bool CArea::__Load_LoadObject(const char * c_szFileName)
{
CTokenVectorMap stTokenVectorMap;
if (!LoadMultipleTextData(c_szFileName, stTokenVectorMap))
{
TraceError(" CArea::Load File Load %s ERROR", c_szFileName);
return false;
}
if (stTokenVectorMap.end() == stTokenVectorMap.find("areadatafile"))
{
TraceError(" CArea::__LoadObject File Format %s ERROR 1", c_szFileName);
return false;
}
if (stTokenVectorMap.end() == stTokenVectorMap.find("objectcount"))
{
TraceError(" CArea::__LoadObject File Format %s ERROR 2", c_szFileName);
return false;
}
const std::string & c_rstrCount = stTokenVectorMap["objectcount"][0];
DWORD dwCount = atoi(c_rstrCount.c_str());
char szObjectName[32+1];
for (DWORD i = 0; i < dwCount; ++i)
{
_snprintf(szObjectName, sizeof(szObjectName), "object%03d", i);
if (stTokenVectorMap.end() == stTokenVectorMap.find(szObjectName))
continue;
const CTokenVector & rVector = stTokenVectorMap[szObjectName];
const std::string & c_rstrxPosition = rVector[0].c_str();
const std::string & c_rstryPosition = rVector[1].c_str();
const std::string & c_rstrzPosition = rVector[2].c_str();
const std::string & c_rstrCRC = rVector[3].c_str();
TObjectData ObjectData;
ZeroMemory(&ObjectData, sizeof(ObjectData));
ObjectData.Position.x = atof(c_rstrxPosition.c_str());
ObjectData.Position.y = atof(c_rstryPosition.c_str());
ObjectData.Position.z = atof(c_rstrzPosition.c_str());
ObjectData.dwCRC = atoi (c_rstrCRC.c_str());
// 20041217.myevan.<2E><><EFBFBD><EFBFBD><EFBFBD>̼<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
ObjectData.InitializeRotation(); //ObjectData.m_fYaw = ObjectData.m_fPitch = ObjectData.m_fRoll = 0;
if (rVector.size() > 4)
{
std::string::size_type s=rVector[4].find('#');
if (s!=rVector[4].npos)
{
ObjectData.m_fYaw = atoi(rVector[4].substr(0,s-1).c_str());
int p = s+1;
s = rVector[4].find('#',p);
ObjectData.m_fPitch = atoi(rVector[4].substr(p,s-1-p+1).c_str());
ObjectData.m_fRoll = atoi(rVector[4].substr(s+1).c_str());
}
else
{
ObjectData.m_fYaw = 0.0f;
ObjectData.m_fPitch = 0.0f;
ObjectData.m_fRoll = atoi(rVector[4].c_str());
}
}
ObjectData.m_fHeightBias = 0.0f;
if (rVector.size() > 5)
{
ObjectData.m_fHeightBias = atof(rVector[5].c_str());
}
if (rVector.size() > 6)
{
for (int portalIdx = 0; portalIdx < min(rVector.size()-6, PORTAL_ID_MAX_NUM); ++portalIdx)
{
ObjectData.abyPortalID[portalIdx] = atoi(rVector[6+portalIdx].c_str());
}
}
// If data is not inside property, then delete it.
CProperty * pProperty;
if (!CPropertyManager::Instance().Get(ObjectData.dwCRC, &pProperty))
{
TraceError(" CArea::LoadObject Property(%u) Load ERROR", ObjectData.dwCRC);
continue;
}
m_ObjectDataVector.push_back(ObjectData);
}
return true;
}
bool CArea::__Load_LoadAmbience(const char * c_szFileName)
{
CTokenVectorMap stTokenVectorMap;
if (!LoadMultipleTextData(c_szFileName, stTokenVectorMap))
{
TraceError(" CArea::Load File Load %s ERROR", c_szFileName);
return false;
}
if (stTokenVectorMap.end() == stTokenVectorMap.find("areaambiencedatafile"))
{
TraceError(" CArea::__LoadAmbience File Format %s ERROR 1", c_szFileName);
return false;
}
if (stTokenVectorMap.end() == stTokenVectorMap.find("objectcount"))
{
TraceError(" CArea::__LoadAmbience File Format %s ERROR 2", c_szFileName);
return false;
}
const std::string & c_rstrCount = stTokenVectorMap["objectcount"][0];
DWORD dwCount = atoi(c_rstrCount.c_str());
char szObjectName[32+1];
for (DWORD i = 0; i < dwCount; ++i)
{
_snprintf(szObjectName, sizeof(szObjectName), "object%03d", i);
if (stTokenVectorMap.end() == stTokenVectorMap.find(szObjectName))
continue;
const CTokenVector & rVector = stTokenVectorMap[szObjectName];
const std::string & c_rstrxPosition = rVector[0].c_str();
const std::string & c_rstryPosition = rVector[1].c_str();
const std::string & c_rstrzPosition = rVector[2].c_str();
const std::string & c_rstrCRC = rVector[3].c_str();
const std::string & c_rstrRange = rVector[4].c_str();
TObjectData ObjectData;
ZeroMemory(&ObjectData, sizeof(ObjectData));
ObjectData.Position.x = atof(c_rstrxPosition.c_str());
ObjectData.Position.y = atof(c_rstryPosition.c_str());
ObjectData.Position.z = atof(c_rstrzPosition.c_str());
ObjectData.dwCRC = atoi (c_rstrCRC.c_str());
ObjectData.dwRange = atoi(c_rstrRange.c_str());
// 20041217.myevan.<2E><><EFBFBD><EFBFBD><EFBFBD>̼<EFBFBD> <20>ʱ<EFBFBD>ȭ
ObjectData.InitializeRotation();
ObjectData.m_fHeightBias = 0.0f;
ObjectData.fMaxVolumeAreaPercentage = 0.0f;
if (rVector.size() >= 6)
{
const std::string & c_rstrPercentage = rVector[5].c_str();
ObjectData.fMaxVolumeAreaPercentage = atof(c_rstrPercentage.c_str());
}
// If data is not inside property, then delete it.
CProperty * pProperty;
if (!CPropertyManager::Instance().Get(ObjectData.dwCRC, &pProperty))
{
TraceError(" CArea::LoadAmbience Property(%d) Load ERROR", ObjectData.dwCRC);
continue;
}
m_ObjectDataVector.push_back(ObjectData);
}
return true;
}
//////////////////////////////////////////////////////////////////////////
bool CArea::CheckObjectIndex(DWORD dwIndex) const
{
if (dwIndex >= m_ObjectDataVector.size())
return false;
return true;
}
DWORD CArea::GetObjectDataCount()
{
return m_ObjectDataVector.size();
}
bool CArea::GetObjectDataPointer(DWORD dwIndex, const TObjectData ** ppObjectData) const
{
if (!CheckObjectIndex(dwIndex))
{
assert(!"Setting Object Index is corrupted!");
return false;
}
*ppObjectData = &m_ObjectDataVector[dwIndex];
return true;
}
const DWORD CArea::GetObjectInstanceCount() const
{
return m_ObjectInstanceVector.size();
}
const bool CArea::GetObjectInstancePointer(const DWORD & dwIndex, const TObjectInstance ** ppObjectInstance) const
{
if (dwIndex >= m_ObjectInstanceVector.size())
return false;
*ppObjectInstance = m_ObjectInstanceVector[dwIndex];
return true;
}
void CArea::EnablePortal(BOOL bFlag)
{
if (m_bPortalEnable == bFlag)
return;
m_bPortalEnable = bFlag;
}
void CArea::ClearPortal()
{
m_kSet_ShowingPortalID.clear();
}
void CArea::AddShowingPortalID(int iNum)
{
m_kSet_ShowingPortalID.insert(iNum);
}
void CArea::RefreshPortal()
{
std::set<TObjectInstance *> kSet_ShowingObjectInstance;
kSet_ShowingObjectInstance.clear();
for (DWORD i = 0; i < m_ObjectDataVector.size(); ++i)
{
TObjectData & rData = m_ObjectDataVector[i];
TObjectInstance * pInstance = m_ObjectInstanceVector[i];
for (int j = 0; j < PORTAL_ID_MAX_NUM; ++j)
{
BYTE byPortalID = rData.abyPortalID[j];
if (0 == byPortalID)
break;
if (m_kSet_ShowingPortalID.end() == m_kSet_ShowingPortalID.find(byPortalID))
continue;
kSet_ShowingObjectInstance.insert(pInstance);
break;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////
m_TreeCloneInstaceVector.clear();
m_ThingCloneInstaceVector.clear();
m_DungeonBlockCloneInstanceVector.clear();
TObjectInstanceVector::iterator it;
for(it = m_ObjectInstanceVector.begin(); it != m_ObjectInstanceVector.end(); ++it)
{
TObjectInstance * pObjectInstance = *it;
if (m_bPortalEnable)
{
if (kSet_ShowingObjectInstance.end() == kSet_ShowingObjectInstance.find(pObjectInstance))
continue;
}
if (prt::PROPERTY_TYPE_TREE == pObjectInstance->dwType)
{
assert(pObjectInstance->pTree);
m_TreeCloneInstaceVector.push_back(pObjectInstance->pTree);
}
else if (prt::PROPERTY_TYPE_BUILDING == pObjectInstance->dwType)
{
assert(pObjectInstance->pThingInstance);
m_ThingCloneInstaceVector.push_back(pObjectInstance->pThingInstance);
}
else if (prt::PROPERTY_TYPE_DUNGEON_BLOCK == pObjectInstance->dwType)
{
assert(pObjectInstance->pDungeonBlock);
m_DungeonBlockCloneInstanceVector.push_back(pObjectInstance->pDungeonBlock);
}
}
}
//////////////////////////////////////////////////////////////////////////
void CArea::Clear()
{
// Real Instances
TObjectInstanceVector::iterator it;
for (it = m_ObjectInstanceVector.begin();it!=m_ObjectInstanceVector.end();++it)
__Clear_DestroyObjectInstance(*it);
m_ObjectDataVector.clear();
m_ObjectInstanceVector.clear();
// Clones
m_TreeCloneInstaceVector.clear();
m_ThingCloneInstaceVector.clear();
m_DungeonBlockCloneInstanceVector.clear();
m_AniThingCloneInstanceVector.clear();
m_ShadowThingCloneInstaceVector.clear();
m_AmbienceCloneInstanceVector.clear();
m_GraphicThingInstanceCRCMap.clear();
m_kRenderedThingInstanceCRCWithNumberVector.clear();
m_kRenderedGrapphicThingInstanceVector.clear();
m_bPortalEnable = FALSE;
ClearPortal();
CEffectManager& rkEftMgr=CEffectManager::Instance();
TEffectInstanceIterator i;
for (i = m_EffectInstanceMap.begin(); i != m_EffectInstanceMap.end(); ++i)
{
CEffectInstance * pEffectInstance = i->second;
rkEftMgr.DestroyUnsafeEffectInstance(pEffectInstance);
}
m_EffectInstanceMap.clear();
}
void CArea::__Clear_DestroyObjectInstance(TObjectInstance * pObjectInstance)
{
if (pObjectInstance->dwEffectInstanceIndex!=0xffffffff)
{
TEffectInstanceIterator f= m_EffectInstanceMap.find(pObjectInstance->dwEffectInstanceIndex);
if (m_EffectInstanceMap.end()!=f)
{
CEffectInstance * pEffectInstance = f->second;
m_EffectInstanceMap.erase(f);
if (CEffectManager::InstancePtr())
CEffectManager::Instance().DestroyUnsafeEffectInstance(pEffectInstance);
}
pObjectInstance->dwEffectInstanceIndex = 0xffffffff;
}
if (pObjectInstance->pAttributeInstance)
{
pObjectInstance->pAttributeInstance->Clear();
ms_AttributeInstancePool.Free(pObjectInstance->pAttributeInstance);
pObjectInstance->pAttributeInstance = NULL;
}
if (pObjectInstance->pTree)
{
pObjectInstance->pTree->Clear();
CSpeedTreeForestDirectX8::Instance().DeleteInstance(pObjectInstance->pTree);
pObjectInstance->pTree = NULL;
}
if (pObjectInstance->pThingInstance)
{
CGraphicThingInstance::Delete(pObjectInstance->pThingInstance);
pObjectInstance->pThingInstance = NULL;
}
if (pObjectInstance->pAmbienceInstance)
{
ms_AmbienceInstancePool.Free(pObjectInstance->pAmbienceInstance);
pObjectInstance->pAmbienceInstance = NULL;
}
if (pObjectInstance->pDungeonBlock)
{
ms_DungeonBlockInstancePool.Free(pObjectInstance->pDungeonBlock);
pObjectInstance->pDungeonBlock = NULL;
}
pObjectInstance->Clear();
ms_ObjectInstancePool.Free(pObjectInstance);
}
//////////////////////////////////////////////////////////////////////////
// Coordination <20><><EFBFBD><EFBFBD>
void CArea::GetCoordinate(unsigned short * usCoordX, unsigned short * usCoordY)
{
*usCoordX = m_wX;
*usCoordY = m_wY;
}
void CArea::SetCoordinate(const unsigned short & usCoordX, const unsigned short & usCoordY)
{
m_wX = usCoordX;
m_wY = usCoordY;
}
//////////////////////////////////////////////////////////////////////////
void CArea::SetMapOutDoor(CMapOutdoor * pOwnerOutdoorMap)
{
m_pOwnerOutdoorMap=pOwnerOutdoorMap;
}
CArea::CArea()
{
m_wX = m_wY = 0xFF;
}
CArea::~CArea()
{
Clear();
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
void CArea::TAmbienceInstance::__Update(float fxCenter, float fyCenter, float fzCenter)
{
if (0 == dwRange)
return;
(this->*Update)(fxCenter, fyCenter, fzCenter);
}
void CArea::TAmbienceInstance::UpdateOnceSound(float fxCenter, float fyCenter, float fzCenter)
{
float fDistance = sqrtf((fx - fxCenter)*(fx - fxCenter) + (fy - fyCenter)*(fy - fyCenter) + (fz - fzCenter)*(fz - fzCenter));
if (DWORD(fDistance) < dwRange)
{
if (-1 == iPlaySoundIndex)
{
if (AmbienceData.AmbienceSoundVector.empty())
return;
const char * c_szFileName = AmbienceData.AmbienceSoundVector[0].c_str();
iPlaySoundIndex = CSoundManager::Instance().PlayAmbienceSound3D(fx, fy, fz, c_szFileName);
// Tracef(" %d : OncePlay [%f] : %s\n", iPlaySoundIndex, fDistance, c_szFileName);
}
}
else
{
iPlaySoundIndex = -1;
}
}
void CArea::TAmbienceInstance::UpdateStepSound(float fxCenter, float fyCenter, float fzCenter)
{
float fDistance = sqrtf((fx - fxCenter)*(fx - fxCenter) + (fy - fyCenter)*(fy - fyCenter) + (fz - fzCenter)*(fz - fzCenter));
if (DWORD(fDistance) < dwRange)
{
float fcurTime = CTimer::Instance().GetCurrentSecond();
if (fcurTime > fNextPlayTime)
{
if (AmbienceData.AmbienceSoundVector.empty())
return;
const char * c_szFileName = AmbienceData.AmbienceSoundVector[0].c_str();
iPlaySoundIndex = CSoundManager::Instance().PlayAmbienceSound3D(fx, fy, fz, c_szFileName);
// Tracef(" %d : StepPlay [%f] : %s\n", iPlaySoundIndex, fDistance, c_szFileName);
fNextPlayTime = CTimer::Instance().GetCurrentSecond();
fNextPlayTime += AmbienceData.fPlayInterval + frandom(0.0f, AmbienceData.fPlayIntervalVariation);
}
}
else
{
iPlaySoundIndex = -1;
fNextPlayTime = 0.0f;
}
}
void CArea::TAmbienceInstance::UpdateLoopSound(float fxCenter, float fyCenter, float fzCenter)
{
float fDistance = sqrtf((fx - fxCenter)*(fx - fxCenter) + (fy - fyCenter)*(fy - fyCenter) + (fz - fzCenter)*(fz - fzCenter));
if (DWORD(fDistance) < dwRange)
{
if (-1 == iPlaySoundIndex)
{
if (AmbienceData.AmbienceSoundVector.empty())
return;
const char * c_szFileName = AmbienceData.AmbienceSoundVector[0].c_str();
iPlaySoundIndex = CSoundManager::Instance().PlayAmbienceSound3D(fx, fy, fz, c_szFileName, 0);
// Tracef(" %d : LoopPlay [%f] : %s\n", iPlaySoundIndex, fDistance, c_szFileName);
}
if (-1 != iPlaySoundIndex)
{
// Tracef("%d : %f\n", iPlaySoundIndex, __GetVolumeFromDistance(fDistance));
CSoundManager::Instance().SetSoundVolume3D(iPlaySoundIndex, __GetVolumeFromDistance(fDistance));
}
}
else
{
if (-1 != iPlaySoundIndex)
{
// Tracef(" %d : LoopStop\n", iPlaySoundIndex);
CSoundManager::Instance().StopSound3D(iPlaySoundIndex);
iPlaySoundIndex = -1;
}
}
}
float CArea::TAmbienceInstance::__GetVolumeFromDistance(float fDistance)
{
float fMaxVolumeAreaRadius = float(dwRange) * fMaxVolumeAreaPercentage;
if (fMaxVolumeAreaRadius <= 0.0f)
return 1.0f;
if (fDistance <= fMaxVolumeAreaRadius)
return 1.0f;
return 1.0f - ((fDistance - fMaxVolumeAreaRadius) / (dwRange - fMaxVolumeAreaRadius));
}
void CArea::TAmbienceInstance::Render()
{
float fBoxSize = 10.0f;
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, 0xff00ff00);
RenderCube(fx-fBoxSize, fy-fBoxSize, fz-fBoxSize, fx+fBoxSize, fy+fBoxSize, fz+fBoxSize);
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, 0xffffffff);
RenderSphere(NULL, fx, fy, fz, float(dwRange) * fMaxVolumeAreaPercentage, D3DFILL_POINT);
RenderSphere(NULL, fx, fy, fz, float(dwRange), D3DFILL_POINT);
RenderCircle2d(fx, fy, fz, float(dwRange) * fMaxVolumeAreaPercentage);
RenderCircle2d(fx, fy, fz, float(dwRange));
for (int i = 0; i < 4; ++i)
{
float fxAdd = cosf(float(i) * D3DX_PI/4.0f) * float(dwRange) / 2.0f;
float fyAdd = sinf(float(i) * D3DX_PI/4.0f) * float(dwRange) / 2.0f;
if (i%2)
{
fxAdd /= 2.0f;
fyAdd /= 2.0f;
}
RenderLine2d(fx + fxAdd, fy + fyAdd, fx - fxAdd, fy - fyAdd, fz);
}
}
bool CArea::SAmbienceInstance::Picking()
{
return CGraphicCollisionObject::IntersectSphere(D3DXVECTOR3(fx, fy, fz), dwRange);
}
CArea::SAmbienceInstance::SAmbienceInstance()
{
fx = 0.0f;
fy = 0.0f;
fz = 0.0f;
dwRange = 0;
iPlaySoundIndex = -1;
fNextPlayTime = 0.0f;
}