312 lines
7.4 KiB
C++
312 lines
7.4 KiB
C++
#include "StdAfx.h"
|
||
#include "Mesh.h"
|
||
#include "Model.h"
|
||
#include "Material.h"
|
||
|
||
granny_data_type_definition GrannyPNT3322VertexType[5] =
|
||
{
|
||
{GrannyReal32Member, GrannyVertexPositionName, 0, 3},
|
||
{GrannyReal32Member, GrannyVertexNormalName, 0, 3},
|
||
{GrannyReal32Member, GrannyVertexTextureCoordinatesName"0", 0, 2},
|
||
{GrannyReal32Member, GrannyVertexTextureCoordinatesName"1", 0, 2},
|
||
{GrannyEndMember}
|
||
};
|
||
|
||
void CGrannyMesh::LoadIndices(void * dstBaseIndices)
|
||
{
|
||
const granny_mesh * pgrnMesh = GetGrannyMeshPointer();
|
||
|
||
TIndex * dstIndices = ((TIndex *)dstBaseIndices) + m_idxBasePos;
|
||
GrannyCopyMeshIndices(pgrnMesh, sizeof(TIndex), dstIndices);
|
||
}
|
||
|
||
void CGrannyMesh::LoadPNTVertices(void * dstBaseVertices)
|
||
{
|
||
const granny_mesh * pgrnMesh = GetGrannyMeshPointer();
|
||
|
||
if (!GrannyMeshIsRigid(pgrnMesh))
|
||
return;
|
||
|
||
TPNTVertex * dstVertices = ((TPNTVertex *)dstBaseVertices) + m_vtxBasePos;
|
||
GrannyCopyMeshVertices(pgrnMesh, m_pgrnMeshType, dstVertices);
|
||
}
|
||
|
||
void CGrannyMesh::NEW_LoadVertices(void * dstBaseVertices)
|
||
{
|
||
const granny_mesh * pgrnMesh = GetGrannyMeshPointer();
|
||
|
||
if (!GrannyMeshIsRigid(pgrnMesh))
|
||
return;
|
||
|
||
TPNTVertex * dstVertices = ((TPNTVertex *)dstBaseVertices) + m_vtxBasePos;
|
||
GrannyCopyMeshVertices(pgrnMesh, m_pgrnMeshType, dstVertices);
|
||
}
|
||
|
||
void CGrannyMesh::DeformPNTVertices(void * dstBaseVertices, D3DXMATRIX * boneMatrices, granny_mesh_binding* pgrnMeshBinding) const
|
||
{
|
||
assert(dstBaseVertices != NULL);
|
||
assert(boneMatrices != NULL);
|
||
assert(m_pgrnMeshDeformer != NULL);
|
||
|
||
const granny_mesh * pgrnMesh = GetGrannyMeshPointer();
|
||
|
||
TPNTVertex * srcVertices = (TPNTVertex *) GrannyGetMeshVertices(pgrnMesh);
|
||
TPNTVertex * dstVertices = ((TPNTVertex *) dstBaseVertices) + m_vtxBasePos;
|
||
|
||
int vtxCount = GrannyGetMeshVertexCount(pgrnMesh);
|
||
|
||
// WORK
|
||
int * boneIndices = GrannyGetMeshBindingToBoneIndices(pgrnMeshBinding);
|
||
// END_OF_WORK
|
||
|
||
GrannyDeformVertices(
|
||
m_pgrnMeshDeformer,
|
||
boneIndices,
|
||
(float *)boneMatrices,
|
||
vtxCount,
|
||
srcVertices,
|
||
dstVertices);
|
||
}
|
||
|
||
bool CGrannyMesh::CanDeformPNTVertices() const
|
||
{
|
||
return m_canDeformPNTVertex;
|
||
}
|
||
|
||
const granny_mesh * CGrannyMesh::GetGrannyMeshPointer() const
|
||
{
|
||
return m_pgrnMesh;
|
||
}
|
||
|
||
const CGrannyMesh::TTriGroupNode * CGrannyMesh::GetTriGroupNodeList(CGrannyMaterial::EType eMtrlType) const
|
||
{
|
||
return m_triGroupNodeLists[eMtrlType];
|
||
}
|
||
|
||
int CGrannyMesh::GetVertexCount() const
|
||
{
|
||
assert(m_pgrnMesh!=NULL);
|
||
return GrannyGetMeshVertexCount(m_pgrnMesh);
|
||
}
|
||
|
||
int CGrannyMesh::GetVertexBasePosition() const
|
||
{
|
||
return m_vtxBasePos;
|
||
}
|
||
|
||
int CGrannyMesh::GetIndexBasePosition() const
|
||
{
|
||
return m_idxBasePos;
|
||
}
|
||
|
||
// WORK
|
||
int * CGrannyMesh::GetDefaultBoneIndices() const
|
||
{
|
||
return GrannyGetMeshBindingToBoneIndices(m_pgrnMeshBindingTemp);
|
||
}
|
||
// END_OF_WORK
|
||
|
||
bool CGrannyMesh::IsEmpty() const
|
||
{
|
||
if (m_pgrnMesh)
|
||
return false;
|
||
|
||
return true;
|
||
}
|
||
|
||
bool CGrannyMesh::CreateFromGrannyMeshPointer(granny_skeleton * pgrnSkeleton, granny_mesh * pgrnMesh, int vtxBasePos, int idxBasePos, CGrannyMaterialPalette& rkMtrlPal)
|
||
{
|
||
assert(IsEmpty());
|
||
|
||
m_pgrnMesh = pgrnMesh;
|
||
m_vtxBasePos = vtxBasePos;
|
||
m_idxBasePos = idxBasePos;
|
||
|
||
if (m_pgrnMesh->BoneBindingCount < 0)
|
||
return true;
|
||
|
||
// WORK
|
||
m_pgrnMeshBindingTemp = GrannyNewMeshBinding(m_pgrnMesh, pgrnSkeleton, pgrnSkeleton);
|
||
// END_OF_WORK
|
||
|
||
if (!GrannyMeshIsRigid(m_pgrnMesh))
|
||
{
|
||
m_canDeformPNTVertex = true;
|
||
|
||
granny_data_type_definition * pgrnInputType = GrannyGetMeshVertexType(m_pgrnMesh);
|
||
granny_data_type_definition * pgrnOutputType = m_pgrnMeshType;
|
||
|
||
m_pgrnMeshDeformer = GrannyNewMeshDeformer(pgrnInputType, pgrnOutputType, GrannyDeformPositionNormal);
|
||
assert(m_pgrnMeshDeformer != NULL && "Cannot create mesh deformer");
|
||
}
|
||
|
||
// Two Side Mesh
|
||
if (!strncmp(m_pgrnMesh->Name, "2x", 2))
|
||
m_isTwoSide = true;
|
||
|
||
if (!LoadMaterials(rkMtrlPal))
|
||
return false;
|
||
|
||
if (!LoadTriGroupNodeList(rkMtrlPal))
|
||
return false;
|
||
|
||
return true;
|
||
}
|
||
|
||
bool CGrannyMesh::LoadTriGroupNodeList(CGrannyMaterialPalette& rkMtrlPal)
|
||
{
|
||
assert(m_pgrnMesh != NULL);
|
||
assert(m_triGroupNodes == NULL);
|
||
|
||
int mtrlCount = m_pgrnMesh->MaterialBindingCount;
|
||
if (mtrlCount <= 0) // õ<><C3B5> <20><><EFBFBD><EFBFBD> 2<><32> ũ<><C5A9><EFBFBD><EFBFBD> <20><EFBFBD>
|
||
return true;
|
||
|
||
int GroupNodeCount = GrannyGetMeshTriangleGroupCount(m_pgrnMesh);
|
||
if (GroupNodeCount <= 0)
|
||
return true;
|
||
|
||
m_triGroupNodes = new TTriGroupNode[GroupNodeCount];
|
||
|
||
const granny_tri_material_group * c_pgrnTriGroups = GrannyGetMeshTriangleGroups(m_pgrnMesh);
|
||
|
||
for (int g = 0; g < GroupNodeCount; ++g)
|
||
{
|
||
const granny_tri_material_group & c_rgrnTriGroup = c_pgrnTriGroups[g];
|
||
TTriGroupNode * pTriGroupNode = m_triGroupNodes + g;
|
||
|
||
pTriGroupNode->idxPos = m_idxBasePos + c_rgrnTriGroup.TriFirst * 3;
|
||
pTriGroupNode->triCount = c_rgrnTriGroup.TriCount;
|
||
|
||
int iMtrl = c_rgrnTriGroup.MaterialIndex;
|
||
if (iMtrl < 0 || iMtrl >= mtrlCount)
|
||
{
|
||
pTriGroupNode->mtrlIndex=0;//m_mtrlIndexVector[iMtrl];
|
||
}
|
||
else
|
||
{
|
||
pTriGroupNode->mtrlIndex=m_mtrlIndexVector[iMtrl];
|
||
}
|
||
|
||
const CGrannyMaterial& rkMtrl=rkMtrlPal.GetMaterialRef(pTriGroupNode->mtrlIndex);
|
||
pTriGroupNode->pNextTriGroupNode = m_triGroupNodeLists[rkMtrl.GetType()];
|
||
m_triGroupNodeLists[rkMtrl.GetType()] = pTriGroupNode;
|
||
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
void CGrannyMesh::RebuildTriGroupNodeList()
|
||
{
|
||
assert(!"CGrannyMesh::RebuildTriGroupNodeList() - <20><> <20><><EFBFBD><EFBFBD><EFBFBD>带 <20>ϴ°<CFB4>- -?");
|
||
/*
|
||
int mtrlCount = m_pgrnMesh->MaterialBindingCount;
|
||
int GroupNodeCount = GrannyGetMeshTriangleGroupCount(m_pgrnMesh);
|
||
|
||
if (GroupNodeCount <= 0)
|
||
return;
|
||
|
||
const granny_tri_material_group * c_pgrnTriGroups = GrannyGetMeshTriangleGroups(m_pgrnMesh);
|
||
|
||
for (int g = 0; g < GroupNodeCount; ++g)
|
||
{
|
||
const granny_tri_material_group& c_rgrnTriGroup = c_pgrnTriGroups[g];
|
||
TTriGroupNode * pTriGroupNode = m_triGroupNodes + g;
|
||
|
||
int iMtrl = c_rgrnTriGroup.MaterialIndex;
|
||
|
||
if (iMtrl >= 0 && iMtrl < mtrlCount)
|
||
{
|
||
CGrannyMaterial & rMtrl = m_mtrls[iMtrl];
|
||
|
||
pTriGroupNode->lpd3dTextures[0] = rMtrl.GetD3DTexture(0);
|
||
pTriGroupNode->lpd3dTextures[1] = rMtrl.GetD3DTexture(1);
|
||
|
||
}
|
||
}
|
||
*/
|
||
}
|
||
|
||
bool CGrannyMesh::LoadMaterials(CGrannyMaterialPalette& rkMtrlPal)
|
||
{
|
||
assert(m_pgrnMesh != NULL);
|
||
|
||
if (m_pgrnMesh->MaterialBindingCount <= 0)
|
||
return true;
|
||
|
||
int mtrlCount = m_pgrnMesh->MaterialBindingCount;
|
||
bool bHaveBlendThing = false;
|
||
|
||
for (int m = 0; m < mtrlCount; ++m)
|
||
{
|
||
granny_material* pgrnMaterial = m_pgrnMesh->MaterialBindings[m].Material;
|
||
DWORD mtrlIndex=rkMtrlPal.RegisterMaterial(pgrnMaterial);
|
||
m_mtrlIndexVector.push_back(mtrlIndex);
|
||
bHaveBlendThing |= rkMtrlPal.GetMaterialRef(mtrlIndex).GetType() == CGrannyMaterial::TYPE_BLEND_PNT;
|
||
}
|
||
m_bHaveBlendThing = bHaveBlendThing;
|
||
|
||
return true;
|
||
}
|
||
|
||
bool CGrannyMesh::IsTwoSide() const
|
||
{
|
||
return m_isTwoSide;
|
||
}
|
||
|
||
void CGrannyMesh::SetPNT2Mesh()
|
||
{
|
||
m_pgrnMeshType = GrannyPNT3322VertexType;
|
||
}
|
||
|
||
void CGrannyMesh::Destroy()
|
||
{
|
||
if (m_triGroupNodes)
|
||
delete [] m_triGroupNodes;
|
||
|
||
m_mtrlIndexVector.clear();
|
||
|
||
// WORK
|
||
if (m_pgrnMeshBindingTemp)
|
||
GrannyFreeMeshBinding(m_pgrnMeshBindingTemp);
|
||
// END_OF_WORK
|
||
|
||
if (m_pgrnMeshDeformer)
|
||
GrannyFreeMeshDeformer(m_pgrnMeshDeformer);
|
||
|
||
Initialize();
|
||
}
|
||
|
||
void CGrannyMesh::Initialize()
|
||
{
|
||
for (int r = 0; r < CGrannyMaterial::TYPE_MAX_NUM; ++r)
|
||
m_triGroupNodeLists[r] = NULL;
|
||
|
||
m_pgrnMeshType = GrannyPNT332VertexType;
|
||
m_pgrnMesh = NULL;
|
||
// WORK
|
||
m_pgrnMeshBindingTemp = NULL;
|
||
// END_OF_WORK
|
||
m_pgrnMeshDeformer = NULL;
|
||
|
||
m_triGroupNodes = NULL;
|
||
|
||
m_vtxBasePos = 0;
|
||
m_idxBasePos = 0;
|
||
|
||
m_canDeformPNTVertex = false;
|
||
m_isTwoSide = false;
|
||
m_bHaveBlendThing = false;
|
||
}
|
||
|
||
CGrannyMesh::CGrannyMesh()
|
||
{
|
||
Initialize();
|
||
}
|
||
|
||
CGrannyMesh::~CGrannyMesh()
|
||
{
|
||
Destroy();
|
||
}
|