155 lines
4.6 KiB
C++
155 lines
4.6 KiB
C++
#include "stdafx.h"
|
|
#include "CrySkinMorph.h"
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// does the skinning out of the given array of global matrices
|
|
void CrySkinMorph::skin (const Matrix44* pBones, float fWeight, Vec3d* pDest)const
|
|
{
|
|
#ifdef PROFILE_FRAME_SELF
|
|
//PROFILE_FRAME_SELF(PureSkin);
|
|
#endif
|
|
const Matrix44* pBone = pBones + m_numSkipBones, *pBonesEnd = pBones + m_numBones;
|
|
const CrySkinAuxInt* pAux = &m_arrAux[0];
|
|
const Vertex* pVertex = &m_arrVertices[0];
|
|
|
|
#ifdef _DEBUG
|
|
TFixedArray<float> arrW;
|
|
arrW.reinit(m_numDests, 0);
|
|
#endif
|
|
|
|
for (; pBone!= pBonesEnd; ++pBone)
|
|
{
|
|
// each bone has a group of vertices
|
|
|
|
// first process the rigid vertices
|
|
const Vertex* pGroupEnd = pVertex + *pAux++;
|
|
for (;pVertex < pGroupEnd; ++pVertex)
|
|
{
|
|
//CHANGED_BY_IVO - INVALID CHANGE, PLEASE REVISE
|
|
pDest[pVertex->nDest] += pBone->TransformVectorOLD(pVertex->pt) * fWeight;
|
|
//pDest[pVertex->nDest] += (GetTransposed44(*pBone)*(pVertex->pt)) * fWeight;
|
|
#ifdef _DEBUG
|
|
assert (arrW[pVertex->nDest] == 0);
|
|
arrW[pVertex->nDest] = 1;
|
|
#endif
|
|
}
|
|
|
|
// then process the smooth vertices
|
|
pGroupEnd = pVertex + *pAux++;
|
|
for (;pVertex < pGroupEnd; ++pVertex, ++pAux)
|
|
{
|
|
pDest[*pAux] += pBone->TransformVectorOLD(pVertex->pt) * (fWeight * pVertex->fWeight);
|
|
// pDest[*pAux] += (GetTransposed44(*pBone)*pVertex->pt) * fWeight * pVertex->fWeight;
|
|
|
|
#ifdef _DEBUG
|
|
assert (arrW[*pAux] >= 0 && arrW[*pAux] < 1.005f);
|
|
arrW[*pAux] += pVertex->fWeight;
|
|
assert (arrW[*pAux] >= 0 && arrW[*pAux] < 1.005f);
|
|
#endif
|
|
}
|
|
}
|
|
#ifdef _DEBUG
|
|
for (unsigned i = 0; i < m_numDests; ++i)
|
|
assert (arrW[i] == 0 || (arrW[i] > 0.995f && arrW[i] < 1.005f));
|
|
#endif
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// does the skinning out of the given array of global matrices,
|
|
// tries to estimate the changes in normals
|
|
void CrySkinMorph::skin (const Matrix44* pBones, float fWeight, Vec3d* pDest, Vec3dA16* pDestNormalsA16, float fAmplify)const
|
|
{
|
|
//PROFILE_FRAME_SELF(PureSkin);
|
|
|
|
const Matrix44* pBone = pBones + m_numSkipBones, *pBonesEnd = pBones + m_numBones;
|
|
const CrySkinAuxInt* pAux = &m_arrAux[0];
|
|
const Vertex* pVertex = &m_arrVertices[0];
|
|
|
|
#ifdef _DEBUG
|
|
TFixedArray<float> arrW;
|
|
arrW.reinit(m_numDests, 0);
|
|
#endif
|
|
|
|
for (; pBone!= pBonesEnd; ++pBone)
|
|
{
|
|
// each bone has a group of vertices
|
|
|
|
// first process the rigid vertices
|
|
const Vertex* pGroupEnd = pVertex + *pAux++;
|
|
for (;pVertex < pGroupEnd; ++pVertex)
|
|
{
|
|
//CHANGED_BY_IVO - INVALID CHANGE, PLEASE REVISE
|
|
Vec3d vOffset = pBone->TransformVectorOLD(pVertex->pt) * fWeight;
|
|
pDest[pVertex->nDest] += vOffset;
|
|
pDestNormalsA16[pVertex->nDest].v += vOffset * fAmplify;
|
|
//pDest[pVertex->nDest] += (GetTransposed44(*pBone)*(pVertex->pt)) * fWeight;
|
|
#ifdef _DEBUG
|
|
assert (arrW[pVertex->nDest] == 0);
|
|
arrW[pVertex->nDest] = 1;
|
|
#endif
|
|
}
|
|
|
|
// then process the smooth vertices
|
|
pGroupEnd = pVertex + *pAux++;
|
|
for (;pVertex < pGroupEnd; ++pVertex, ++pAux)
|
|
{
|
|
Vec3d vOffset = pBone->TransformVectorOLD(pVertex->pt) * (fWeight * pVertex->fWeight);
|
|
pDest[*pAux] += vOffset;
|
|
pDestNormalsA16[*pAux].v += vOffset * fAmplify;
|
|
// pDest[*pAux] += (GetTransposed44(*pBone)*pVertex->pt) * fWeight * pVertex->fWeight;
|
|
|
|
#ifdef _DEBUG
|
|
assert (arrW[*pAux] >= 0 && arrW[*pAux] < 1.005f);
|
|
arrW[*pAux] += pVertex->fWeight;
|
|
assert (arrW[*pAux] >= 0 && arrW[*pAux] < 1.005f);
|
|
#endif
|
|
}
|
|
}
|
|
#ifdef _DEBUG
|
|
for (unsigned i = 0; i < m_numDests; ++i)
|
|
assert (arrW[i] == 0 || (arrW[i] > 0.995f && arrW[i] < 1.005f));
|
|
#endif
|
|
}
|
|
|
|
|
|
void CrySkinMorph::CStatistics::init (const CrySkinMorph* pSkin)
|
|
{
|
|
const CrySkinAuxInt* pAux = &pSkin->m_arrAux[0];
|
|
const Vertex* pVertex = &pSkin->m_arrVertices[0];
|
|
numRigid = numSmooth = 0;
|
|
fMinOffset = fMaxOffset = -1;
|
|
for (unsigned nBone = pSkin->m_numSkipBones; nBone < pSkin->m_numBones; ++nBone)
|
|
{
|
|
// each bone has a group of vertices
|
|
|
|
// first process the rigid vertices
|
|
const Vertex* pGroupEnd = pVertex + *pAux++;
|
|
for (;pVertex < pGroupEnd; ++pVertex)
|
|
{
|
|
//pDest[pVertex->nDest] += pBone->TransformVector(pVertex->pt) * fWeight;
|
|
setDests.insert (pVertex->nDest);
|
|
addOffset (pVertex->pt);
|
|
++numRigid;
|
|
}
|
|
|
|
// then process the smooth vertices
|
|
pGroupEnd = pVertex + *pAux++;
|
|
for (;pVertex < pGroupEnd; ++pVertex, ++pAux)
|
|
{
|
|
//pDest[*pAux] += pBone->TransformVector(pVertex->pt) * (fWeight * pVertex->fWeight);
|
|
setDests.insert (*pAux);
|
|
addOffset (pVertex->pt);
|
|
++numSmooth;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CrySkinMorph::CStatistics::addOffset (const Vec3d& v)
|
|
{
|
|
float d = v.Length();
|
|
if (fMaxOffset < 0 || d > fMaxOffset)
|
|
fMaxOffset = d;
|
|
if (fMinOffset < 0 || d < fMinOffset)
|
|
fMinOffset = d;
|
|
}
|