1449 lines
42 KiB
C++
1449 lines
42 KiB
C++
#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;
|
||
}
|