#include "StdAfx.h" #include "../eterLib/StateManager.h" #include "../eterLib/ResourceManager.h" #include "EffectMeshInstance.h" #include "../eterlib/GrpMath.h" CDynamicPool 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* pTextureVector = pkEftMesh->GetTextureVectorPointer(j); if (!pTextureVector) continue; std::vector& 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 & rImageInstanceVector = m_TextureInstanceVector[j].TextureInstanceVector; rImageInstanceVector.clear(); rImageInstanceVector.reserve(rTextureVector.size()); for (std::vector::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 & 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(); }