client/EffectLib/EffectMeshInstance.cpp

271 lines
8.1 KiB
C++

#include "StdAfx.h"
#include "../eterLib/StateManager.h"
#include "../eterLib/ResourceManager.h"
#include "EffectMeshInstance.h"
#include "../eterlib/GrpMath.h"
CDynamicPool<CEffectMeshInstance> CEffectMeshInstance::ms_kPool;
void CEffectMeshInstance::DestroySystem()
{
ms_kPool.Destroy();
}
CEffectMeshInstance* CEffectMeshInstance::New()
{
return ms_kPool.Alloc();
}
void CEffectMeshInstance::Delete(CEffectMeshInstance* pkMeshInstance)
{
pkMeshInstance->Destroy();
ms_kPool.Free(pkMeshInstance);
}
BOOL CEffectMeshInstance::isActive()
{
if (!CEffectElementBaseInstance::isActive())
return FALSE;
if (!m_MeshFrameController.isActive())
return FALSE;
for (DWORD j = 0; j < m_TextureInstanceVector.size(); ++j)
{
int iCurrentFrame = m_MeshFrameController.GetCurrentFrame();
if (m_TextureInstanceVector[j].TextureFrameController.isActive(iCurrentFrame))
return TRUE;
}
return FALSE;
}
bool CEffectMeshInstance::OnUpdate(float fElapsedTime)
{
if (!isActive())
return false;
if (m_MeshFrameController.isActive())
m_MeshFrameController.Update(fElapsedTime);
for (DWORD j = 0; j < m_TextureInstanceVector.size(); ++j)
{
int iCurrentFrame = m_MeshFrameController.GetCurrentFrame();
if (m_TextureInstanceVector[j].TextureFrameController.isActive(iCurrentFrame))
m_TextureInstanceVector[j].TextureFrameController.Update(fElapsedTime);
}
return true;
}
void CEffectMeshInstance::OnRender()
{
if (!isActive())
return;
CEffectMesh * pEffectMesh = m_roMesh.GetPointer();
for (DWORD i = 0; i < pEffectMesh->GetMeshCount(); ++i)
{
assert(i < m_TextureInstanceVector.size());
CFrameController & rTextureFrameController = m_TextureInstanceVector[i].TextureFrameController;
if (!rTextureFrameController.isActive(m_MeshFrameController.GetCurrentFrame()))
continue;
int iBillboardType = m_pMeshScript->GetBillboardType(i);
D3DXMATRIX m_matWorld;
D3DXMatrixIdentity(&m_matWorld);
switch(iBillboardType)
{
case MESH_BILLBOARD_TYPE_ALL:
{
D3DXMATRIX matTemp;
D3DXMatrixRotationX(&matTemp, 90.0f);
D3DXMatrixInverse(&m_matWorld, NULL, &CScreen::GetViewMatrix());
m_matWorld = matTemp * m_matWorld;
}
break;
case MESH_BILLBOARD_TYPE_Y:
{
D3DXMATRIX matTemp;
D3DXMatrixIdentity(&matTemp);
D3DXMatrixInverse(&matTemp, NULL, &CScreen::GetViewMatrix());
m_matWorld._11 = matTemp._11;
m_matWorld._12 = matTemp._12;
m_matWorld._21 = matTemp._21;
m_matWorld._22 = matTemp._22;
}
break;
case MESH_BILLBOARD_TYPE_MOVE:
{
D3DXVECTOR3 Position;
m_pMeshScript->GetPosition(m_fLocalTime, Position);
D3DXVECTOR3 LastPosition;
m_pMeshScript->GetPosition(m_fLocalTime-CTimer::Instance().GetElapsedSecond(), LastPosition);
Position -= LastPosition;
if (D3DXVec3LengthSq(&Position)>0.001f)
{
D3DXVec3Normalize(&Position,&Position);
D3DXQUATERNION q = SafeRotationNormalizedArc(D3DXVECTOR3(0.0f,-1.0f,0.0f),Position);
D3DXMatrixRotationQuaternion(&m_matWorld,&q);
}
}
break;
}
if (!m_pMeshScript->isBlendingEnable(i))
{
STATEMANAGER.SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
}
else
{
int iBlendingSrcType = m_pMeshScript->GetBlendingSrcType(i);
int iBlendingDestType = m_pMeshScript->GetBlendingDestType(i);
STATEMANAGER.SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
STATEMANAGER.SetRenderState(D3DRS_SRCBLEND, iBlendingSrcType);
STATEMANAGER.SetRenderState(D3DRS_DESTBLEND, iBlendingDestType);
}
D3DXVECTOR3 Position;
m_pMeshScript->GetPosition(m_fLocalTime, Position);
m_matWorld._41 = Position.x;
m_matWorld._42 = Position.y;
m_matWorld._43 = Position.z;
m_matWorld = m_matWorld * *mc_pmatLocal;
STATEMANAGER.SetTransform(D3DTS_WORLD, &m_matWorld);
BYTE byType;
D3DXCOLOR Color(1.0f, 1.0f, 1.0f, 1.0f);
if (m_pMeshScript->GetColorOperationType(i, &byType))
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, byType);
m_pMeshScript->GetColorFactor(i, &Color);
TTimeEventTableFloat * TableAlpha;
float fAlpha = 1.0f;
if (m_pMeshScript->GetTimeTableAlphaPointer(i, &TableAlpha) && !TableAlpha->empty())
GetTimeEventBlendValue(m_fLocalTime,*TableAlpha, &fAlpha);
// Render //
CEffectMesh::TEffectMeshData * pMeshData = pEffectMesh->GetMeshDataPointer(i);
assert(m_MeshFrameController.GetCurrentFrame() < pMeshData->EffectFrameDataVector.size());
CEffectMesh::TEffectFrameData & rFrameData = pMeshData->EffectFrameDataVector[m_MeshFrameController.GetCurrentFrame()];
DWORD dwcurTextureFrame = rTextureFrameController.GetCurrentFrame();
if (dwcurTextureFrame < m_TextureInstanceVector[i].TextureInstanceVector.size())
{
CGraphicImageInstance * pImageInstance = m_TextureInstanceVector[i].TextureInstanceVector[dwcurTextureFrame];
STATEMANAGER.SetTexture(0, pImageInstance->GetTexturePointer()->GetD3DTexture());
}
Color.a = fAlpha * rFrameData.fVisibility;
STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, DWORD(Color));
STATEMANAGER.SetVertexShader(D3DFVF_XYZ | D3DFVF_TEX1);
STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLELIST,
rFrameData.dwIndexCount/3,
&rFrameData.PDTVertexVector[0],
sizeof(TPTVertex));
// Render //
}
}
void CEffectMeshInstance::OnSetDataPointer(CEffectElementBase * pElement)
{
CEffectMeshScript * pMesh = (CEffectMeshScript *)pElement;
m_pMeshScript = pMesh;
const char * c_szMeshFileName = pMesh->GetMeshFileName();
m_pEffectMesh = (CEffectMesh *) CResourceManager::Instance().GetResourcePointer(c_szMeshFileName);
if (!m_pEffectMesh)
return;
m_roMesh.SetPointer(m_pEffectMesh);
m_MeshFrameController.Clear();
m_MeshFrameController.SetMaxFrame(m_roMesh.GetPointer()->GetFrameCount());
m_MeshFrameController.SetFrameTime(pMesh->GetMeshAnimationFrameDelay());
m_MeshFrameController.SetLoopFlag(pMesh->isMeshAnimationLoop());
m_MeshFrameController.SetLoopCount(pMesh->GetMeshAnimationLoopCount());
m_MeshFrameController.SetStartFrame(0);
m_TextureInstanceVector.clear();
m_TextureInstanceVector.resize(m_pEffectMesh->GetMeshCount());
for (DWORD j = 0; j < m_TextureInstanceVector.size(); ++j)
{
CEffectMeshScript::TMeshData * pMeshData;
if (!m_pMeshScript->GetMeshDataPointer(j, &pMeshData))
continue;
CEffectMesh* pkEftMesh=m_roMesh.GetPointer();
if (!pkEftMesh)
continue;
std::vector<CGraphicImage*>* pTextureVector = pkEftMesh->GetTextureVectorPointer(j);
if (!pTextureVector)
continue;
std::vector<CGraphicImage*>& rTextureVector = *pTextureVector;
CFrameController & rFrameController = m_TextureInstanceVector[j].TextureFrameController;
rFrameController.Clear();
rFrameController.SetMaxFrame(rTextureVector.size());
rFrameController.SetFrameTime(pMeshData->fTextureAnimationFrameDelay);
rFrameController.SetLoopFlag(pMeshData->bTextureAnimationLoopEnable);
rFrameController.SetStartFrame(pMeshData->dwTextureAnimationStartFrame);
std::vector<CGraphicImageInstance*> & rImageInstanceVector = m_TextureInstanceVector[j].TextureInstanceVector;
rImageInstanceVector.clear();
rImageInstanceVector.reserve(rTextureVector.size());
for (std::vector<CGraphicImage*>::iterator itor = rTextureVector.begin(); itor != rTextureVector.end(); ++itor)
{
CGraphicImage * pImage = *itor;
CGraphicImageInstance * pImageInstance = CGraphicImageInstance::ms_kPool.Alloc();
pImageInstance->SetImagePointer(pImage);
rImageInstanceVector.push_back(pImageInstance);
}
}
}
void CEffectMeshInstance_DeleteImageInstance(CGraphicImageInstance * pkInstance)
{
CGraphicImageInstance::ms_kPool.Free(pkInstance);
}
void CEffectMeshInstance_DeleteTextureInstance(CEffectMeshInstance::TTextureInstance & rkInstance)
{
std::vector<CGraphicImageInstance*> & rVector = rkInstance.TextureInstanceVector;
for_each(rVector.begin(), rVector.end(), CEffectMeshInstance_DeleteImageInstance);
rVector.clear();
}
void CEffectMeshInstance::OnInitialize()
{
}
void CEffectMeshInstance::OnDestroy()
{
for_each(m_TextureInstanceVector.begin(), m_TextureInstanceVector.end(), CEffectMeshInstance_DeleteTextureInstance);
m_TextureInstanceVector.clear();
m_roMesh.SetPointer(NULL);
}
CEffectMeshInstance::CEffectMeshInstance()
{
Initialize();
}
CEffectMeshInstance::~CEffectMeshInstance()
{
Destroy();
}