92 lines
3.1 KiB
C++
92 lines
3.1 KiB
C++
#include "stdafx.h"
|
|
#include "CrySkinBuilderBase.h"
|
|
|
|
CrySkinBuilderBase::CrySkinBuilderBase(const ICrySkinSource* pGeometry):
|
|
CrySkinBuilderBase0 (pGeometry)
|
|
#ifdef DEBUG_STD_CONTAINERS
|
|
,m_arrBoneVerts ("CrySkinBuilder.arrBoneVerts")
|
|
#endif
|
|
{
|
|
preprocess();
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// fills in the group of aux ints for the given bone (the rigid vertex group)
|
|
// returns the pointer to the next available auxint after the group
|
|
// IMPLEMENTATION NOTE:
|
|
// actually, the rigid group is empty in the auxiliary stream, so we just set the number of vertices
|
|
void CrySkinBuilderBase::fillRigidGroup (CrySkinStreams& streams, unsigned nBone)
|
|
{
|
|
CrySkinRigidVertexArray& arrRigid = m_arrBoneVerts[nBone].arrRigid;
|
|
|
|
// the group starts with the number of rigid vertices belonging to this bone
|
|
*streams.pAux++ = (CrySkinAuxInt)arrRigid.size();
|
|
|
|
CrySkinRigidVertexArray::const_iterator it = arrRigid.begin(), itEnd = it + arrRigid.size();
|
|
|
|
for (; it != itEnd; ++it)
|
|
it->build (*streams.pVert++);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// computes the max number of bone affecting a vertex + 1
|
|
// and the total number of links to smooth vertices - the sum of numbers of links of all smooth vertices
|
|
// the total number of links per all vertices. If the whole object is rigid,
|
|
// this is the same as the number of vertices
|
|
void CrySkinBuilderBase::preprocess()
|
|
{
|
|
// we need for each bone:
|
|
// Vert:
|
|
// RigidVertex for each rigid vertex, and SmoothVertex for each smooth vertex
|
|
// Aux:
|
|
// 3 counts of vertices in each group
|
|
// index of target for each smooth vertex
|
|
|
|
m_numBones = 0;
|
|
m_numSmoothLinks = 0;
|
|
m_numLinks = 0;
|
|
unsigned numVertices = m_pGeometry->numVertices();
|
|
for (unsigned nVert = 0; nVert < numVertices; ++nVert)
|
|
{
|
|
// the number of links for this vertex
|
|
unsigned numVertexLinks = (unsigned)m_pGeometry->getLink(nVert).size();
|
|
if (numVertexLinks > 1)
|
|
// if the vertex is smooth, we'll need to keep the weights and destination indices
|
|
m_numSmoothLinks += numVertexLinks;
|
|
|
|
m_numBones = max(m_pGeometry->getLink(nVert).maxBoneID(), m_numBones);
|
|
|
|
m_numLinks += numVertexLinks;
|
|
}
|
|
++m_numBones;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// calculates the vertex list of each bone
|
|
void CrySkinBuilderBase::makeFullBoneVertexArrays()
|
|
{
|
|
m_arrBoneVerts.clear();
|
|
m_arrBoneVerts.resize (m_numBones);
|
|
|
|
unsigned numVertices = m_pGeometry->numVertices();
|
|
// preallocate memory for the vertices in bones
|
|
for (unsigned i = 0; i < m_numBones; ++i)
|
|
// assume approximately uniform distribution
|
|
m_arrBoneVerts[i].reserve (numVertices / m_numBones);
|
|
|
|
for (unsigned nVert = 0; nVert < numVertices; ++nVert)
|
|
{
|
|
// the number of links for this vertex
|
|
const CryVertexBinding& rLinks = m_pGeometry->getLink (nVert);
|
|
if (rLinks.size() == 1)
|
|
m_arrBoneVerts[rLinks[0].BoneID].arrRigid.push_back(CrySkinRigidVertex (rLinks[0].offset, nVert));
|
|
else
|
|
for (unsigned i = 0; i < rLinks.size(); ++i)
|
|
{
|
|
m_arrBoneVerts[rLinks[i].BoneID].arrSmooth.push_back(CrySkinSmoothVertex (rLinks[i], nVert));
|
|
}
|
|
}
|
|
}
|