forked from metin2/client
1
0
Fork 0
client/EterGrnLib/Model.cpp

420 lines
8.8 KiB
C++
Raw Normal View History

#include "StdAfx.h"
#include "Model.h"
#include "Mesh.h"
const CGrannyMaterialPalette& CGrannyModel::GetMaterialPalette() const
{
return m_kMtrlPal;
}
const CGrannyModel::TMeshNode* CGrannyModel::GetMeshNodeList(CGrannyMesh::EType eMeshType, CGrannyMaterial::EType eMtrlType) const
{
return m_meshNodeLists[eMeshType][eMtrlType];
}
CGrannyMesh * CGrannyModel::GetMeshPointer(int iMesh)
{
assert(CheckMeshIndex(iMesh));
assert(m_meshs != NULL);
return m_meshs + iMesh;
}
const CGrannyMesh* CGrannyModel::GetMeshPointer(int iMesh) const
{
assert(CheckMeshIndex(iMesh));
assert(m_meshs != NULL);
return m_meshs + iMesh;
}
bool CGrannyModel::CanDeformPNTVertices() const
{
return m_canDeformPNVertices;
}
void CGrannyModel::DeformPNTVertices(void * dstBaseVertices, D3DXMATRIX * boneMatrices, const std::vector<granny_mesh_binding*>& c_rvct_pgrnMeshBinding) const
{
int meshCount = GetMeshCount();
for (int iMesh = 0; iMesh < meshCount; ++iMesh)
{
assert(iMesh < c_rvct_pgrnMeshBinding.size());
CGrannyMesh & rMesh = m_meshs[iMesh];
if (rMesh.CanDeformPNTVertices())
rMesh.DeformPNTVertices(dstBaseVertices, boneMatrices, c_rvct_pgrnMeshBinding[iMesh]);
}
}
int CGrannyModel::GetRigidVertexCount() const
{
return m_rigidVtxCount;
}
int CGrannyModel::GetDeformVertexCount() const
{
return m_deformVtxCount;
}
int CGrannyModel::GetVertexCount() const
{
return m_vtxCount;
}
int CGrannyModel::GetMeshCount() const
{
return m_pgrnModel ? m_pgrnModel->MeshBindingCount : 0;
}
granny_model* CGrannyModel::GetGrannyModelPointer()
{
return m_pgrnModel;
}
LPDIRECT3DINDEXBUFFER8 CGrannyModel::GetD3DIndexBuffer() const
{
return m_idxBuf.GetD3DIndexBuffer();
}
LPDIRECT3DVERTEXBUFFER8 CGrannyModel::GetPNTD3DVertexBuffer() const
{
return m_pntVtxBuf.GetD3DVertexBuffer();
}
bool CGrannyModel::LockVertices(void** indicies, void** vertices) const
{
if (!m_idxBuf.Lock(indicies))
return false;
if (!m_pntVtxBuf.Lock(vertices))
{
m_idxBuf.Unlock();
return false;
}
return true;
}
void CGrannyModel::UnlockVertices() const
{
m_idxBuf.Unlock();
m_pntVtxBuf.Unlock();
}
bool CGrannyModel::LoadPNTVertices()
{
if (m_rigidVtxCount <= 0)
return true;
assert(m_meshs != NULL);
if (!m_pntVtxBuf.Create(m_rigidVtxCount, m_dwFvF, D3DUSAGE_WRITEONLY, D3DPOOL_MANAGED))
return false;
void* vertices;
if (!m_pntVtxBuf.Lock(&vertices))
return false;
for (int m = 0; m < m_pgrnModel->MeshBindingCount; ++m)
{
CGrannyMesh& rMesh = m_meshs[m];
rMesh.LoadPNTVertices(vertices);
}
m_pntVtxBuf.Unlock();
return true;
}
bool CGrannyModel::LoadIndices()
{
//assert(m_idxCount > 0);
if (m_idxCount <= 0)
return true;
if (!m_idxBuf.Create(m_idxCount, D3DFMT_INDEX16))
return false;
void * indices;
if (!m_idxBuf.Lock((void**)&indices))
return false;
for (int m = 0; m < m_pgrnModel->MeshBindingCount; ++m)
{
CGrannyMesh& rMesh = m_meshs[m];
rMesh.LoadIndices(indices);
}
m_idxBuf.Unlock();
return true;
}
bool CGrannyModel::LoadMeshs()
{
assert(m_meshs == NULL);
assert(m_pgrnModel != NULL);
if (m_pgrnModel->MeshBindingCount <= 0) // <20>޽<EFBFBD><DEBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
return true;
granny_skeleton * pgrnSkeleton = m_pgrnModel->Skeleton;
int vtxRigidPos = 0;
int vtxDeformPos = 0;
int vtxPos = 0;
int idxPos = 0;
int diffusePNTMeshNodeCount = 0;
int blendPNTMeshNodeCount = 0;
int blendPNT2MeshNodeCount = 0;
int meshCount = GetMeshCount();
m_meshs = new CGrannyMesh[meshCount];
m_dwFvF = 0;
for (int m = 0; m < meshCount; ++m)
{
CGrannyMesh& rMesh = m_meshs[m];
granny_mesh* pgrnMesh = m_pgrnModel->MeshBindings[m].Mesh;
if (GrannyMeshIsRigid(pgrnMesh))
{
if (!rMesh.CreateFromGrannyMeshPointer(pgrnSkeleton, pgrnMesh, vtxRigidPos, idxPos, m_kMtrlPal))
return false;
vtxRigidPos += GrannyGetMeshVertexCount(pgrnMesh);
}
else
{
if (!rMesh.CreateFromGrannyMeshPointer(pgrnSkeleton, pgrnMesh, vtxDeformPos, idxPos, m_kMtrlPal))
return false;
vtxDeformPos += GrannyGetMeshVertexCount(pgrnMesh);
m_canDeformPNVertices |= rMesh.CanDeformPNTVertices();
}
m_bHaveBlendThing |= rMesh.HaveBlendThing();
granny_int32x grni32xTypeCount = GrannyGetTotalTypeSize(pgrnMesh->PrimaryVertexData->VertexType) / 32;
int i = 0;
while (i < grni32xTypeCount)
{
if (NULL == pgrnMesh->PrimaryVertexData->VertexType[i].Name || 0 == strlen(pgrnMesh->PrimaryVertexData->VertexType[i].Name))
{
++i;
continue;
}
if ( 0 == strcmp(pgrnMesh->PrimaryVertexData->VertexType[i].Name, GrannyVertexPositionName) )
m_dwFvF |= D3DFVF_XYZ;
else if ( 0 == strcmp(pgrnMesh->PrimaryVertexData->VertexType[i].Name, GrannyVertexNormalName) )
m_dwFvF |= D3DFVF_NORMAL;
else if ( 0 == strcmp(pgrnMesh->PrimaryVertexData->VertexType[i].Name, GrannyVertexTextureCoordinatesName"0") )
m_dwFvF |= D3DFVF_TEX1;
else if ( 0 == strcmp(pgrnMesh->PrimaryVertexData->VertexType[i].Name, GrannyVertexTextureCoordinatesName"1") )
m_dwFvF |= D3DFVF_TEX2;
++i;
}
vtxPos += GrannyGetMeshVertexCount(pgrnMesh);
idxPos += GrannyGetMeshIndexCount(pgrnMesh);
if (rMesh.GetTriGroupNodeList(CGrannyMaterial::TYPE_DIFFUSE_PNT))
++diffusePNTMeshNodeCount;
if (rMesh.GetTriGroupNodeList(CGrannyMaterial::TYPE_BLEND_PNT))
++blendPNTMeshNodeCount;
}
m_meshNodeCapacity = diffusePNTMeshNodeCount + blendPNTMeshNodeCount + blendPNT2MeshNodeCount;
m_meshNodes = new TMeshNode[m_meshNodeCapacity];
for (int n = 0; n < meshCount; ++n)
{
CGrannyMesh& rMesh = m_meshs[n];
granny_mesh* pgrnMesh = m_pgrnModel->MeshBindings[n].Mesh;
CGrannyMesh::EType eMeshType = GrannyMeshIsRigid(pgrnMesh) ? CGrannyMesh::TYPE_RIGID : CGrannyMesh::TYPE_DEFORM;
if (rMesh.GetTriGroupNodeList(CGrannyMaterial::TYPE_DIFFUSE_PNT))
AppendMeshNode(eMeshType, CGrannyMaterial::TYPE_DIFFUSE_PNT, n);
if (rMesh.GetTriGroupNodeList(CGrannyMaterial::TYPE_BLEND_PNT))
AppendMeshNode(eMeshType, CGrannyMaterial::TYPE_BLEND_PNT, n);
}
// For Dungeon Block
if ((D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1|D3DFVF_TEX2) == m_dwFvF)
{
for (int n = 0; n < meshCount; ++n)
{
CGrannyMesh& rMesh = m_meshs[n];
rMesh.SetPNT2Mesh();
}
}
m_rigidVtxCount = vtxRigidPos;
m_deformVtxCount = vtxDeformPos;
m_vtxCount = vtxPos;
m_idxCount = idxPos;
return true;
}
BOOL CGrannyModel::CheckMeshIndex(int iIndex) const
{
if (iIndex < 0)
return FALSE;
if (iIndex >= m_meshNodeSize)
return FALSE;
return TRUE;
}
void CGrannyModel::AppendMeshNode(CGrannyMesh::EType eMeshType, CGrannyMaterial::EType eMtrlType, int iMesh)
{
assert(m_meshNodeSize < m_meshNodeCapacity);
TMeshNode& rMeshNode = m_meshNodes[m_meshNodeSize++];
rMeshNode.iMesh = iMesh;
rMeshNode.pMesh = m_meshs + iMesh;
rMeshNode.pNextMeshNode = m_meshNodeLists[eMeshType][eMtrlType];
m_meshNodeLists[eMeshType][eMtrlType] = &rMeshNode;
}
bool CGrannyModel::CreateFromGrannyModelPointer(granny_model* pgrnModel)
{
assert(IsEmpty());
m_pgrnModel = pgrnModel;
if (!LoadMeshs())
return false;
if (!__LoadVertices())
return false;
if (!LoadIndices())
return false;
AddReference();
return true;
}
int CGrannyModel::GetIdxCount()
{
return m_idxCount;
}
bool CGrannyModel::CreateDeviceObjects()
{
if (m_rigidVtxCount > 0)
if (!m_pntVtxBuf.CreateDeviceObjects())
return false;
if (m_idxCount > 0)
if (!m_idxBuf.CreateDeviceObjects())
return false;
int meshCount = GetMeshCount();
for (int i = 0; i < meshCount; ++i)
{
CGrannyMesh& rMesh = m_meshs[i];
rMesh.RebuildTriGroupNodeList();
}
return true;
}
void CGrannyModel::DestroyDeviceObjects()
{
m_pntVtxBuf.DestroyDeviceObjects();
m_idxBuf.DestroyDeviceObjects();
}
bool CGrannyModel::IsEmpty() const
{
if (m_pgrnModel)
return false;
return true;
}
void CGrannyModel::Destroy()
{
m_kMtrlPal.Clear();
if (m_meshNodes)
delete [] m_meshNodes;
if (m_meshs)
delete [] m_meshs;
m_pntVtxBuf.Destroy();
m_idxBuf.Destroy();
Initialize();
}
bool CGrannyModel::__LoadVertices()
{
if (m_rigidVtxCount <= 0)
return true;
assert(m_meshs != NULL);
// assert((m_dwFvF & (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1)) == m_dwFvF);
// if (!m_pntVtxBuf.Create(m_rigidVtxCount, D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1, D3DUSAGE_WRITEONLY, D3DPOOL_MANAGED))
if (!m_pntVtxBuf.Create(m_rigidVtxCount, m_dwFvF, D3DUSAGE_WRITEONLY, D3DPOOL_MANAGED))
return false;
void* vertices;
if (!m_pntVtxBuf.Lock(&vertices))
return false;
for (int m = 0; m < m_pgrnModel->MeshBindingCount; ++m)
{
CGrannyMesh& rMesh = m_meshs[m];
rMesh.NEW_LoadVertices(vertices);
}
m_pntVtxBuf.Unlock();
return true;
}
void CGrannyModel::Initialize()
{
memset(m_meshNodeLists, 0, sizeof(m_meshNodeLists));
m_pgrnModel = NULL;
m_meshs = NULL;
m_meshNodes = NULL;
m_meshNodeSize = 0;
m_meshNodeCapacity = 0;
m_rigidVtxCount = 0;
m_deformVtxCount = 0;
m_vtxCount = 0;
m_idxCount = 0;
m_canDeformPNVertices = false;
m_dwFvF = 0;
m_bHaveBlendThing = false;
}
CGrannyModel::CGrannyModel()
{
Initialize();
}
CGrannyModel::~CGrannyModel()
{
Destroy();
}