123
This commit is contained in:
276
CryAnimation/CrySkinBase.cpp
Normal file
276
CryAnimation/CrySkinBase.cpp
Normal file
@@ -0,0 +1,276 @@
|
||||
#include "stdafx.h"
|
||||
#include <StlUtils.h>
|
||||
#include "CrySkinBase.h"
|
||||
|
||||
CrySkinBase::CrySkinBase():
|
||||
m_numBones(0),
|
||||
m_arrVertices ("CrySkin*.Vertices"),
|
||||
m_arrAux ("CrySkin*.Aux"),
|
||||
m_numSkipBones (0),
|
||||
m_numDests(0)
|
||||
{
|
||||
}
|
||||
|
||||
CrySkinBase::~CrySkinBase ()
|
||||
{
|
||||
}
|
||||
|
||||
void CrySkinBase::clear()
|
||||
{
|
||||
m_numBones = 0;
|
||||
m_numSkipBones = 0;
|
||||
m_arrVertices.clear();
|
||||
m_arrAux.clear();
|
||||
}
|
||||
|
||||
bool CrySkinBase::empty()const
|
||||
{
|
||||
return m_numBones == 0 || m_arrVertices.empty();
|
||||
}
|
||||
|
||||
void CrySkinBase::init (unsigned numVerts, unsigned numAux, unsigned numSkipBones, unsigned numBones)
|
||||
{
|
||||
m_numBones = numBones;
|
||||
m_numSkipBones = numSkipBones;
|
||||
// (re)allocate the memory
|
||||
m_arrVertices.reinit (numVerts);
|
||||
m_arrAux.reinit (numAux);
|
||||
}
|
||||
|
||||
// transforms the given smooth point into the destination with the matrix
|
||||
void CrySkinBase::transformWPoint (Vec3d& pDest, const Matrix44& matBone, const Vertex& rVtx)
|
||||
{
|
||||
//pDest = matBone.TransformPoint(rVtx) * rVtx.fWeight;
|
||||
|
||||
pDest.x = ((matBone[0][0] * rVtx.pt.x) + (matBone[1][0] * rVtx.pt.y) + (matBone[2][0] * rVtx.pt.z) + matBone[3][0]) * rVtx.fWeight;
|
||||
pDest.y = ((matBone[0][1] * rVtx.pt.x) + (matBone[1][1] * rVtx.pt.y) + (matBone[2][1] * rVtx.pt.z) + matBone[3][1]) * rVtx.fWeight;
|
||||
pDest.z = ((matBone[0][2] * rVtx.pt.x) + (matBone[1][2] * rVtx.pt.y) + (matBone[2][2] * rVtx.pt.z) + matBone[3][2]) * rVtx.fWeight;
|
||||
}
|
||||
|
||||
|
||||
// adds the given smooth point into the destination with the matrix
|
||||
void CrySkinBase::addWPoint (Vec3d& pDest, const Matrix44& matBone, const Vertex& rVtx)
|
||||
{
|
||||
//pDest += matBone.TransformPoint(rVtx) * rVtx.fWeight;
|
||||
|
||||
pDest.x += ((matBone[0][0] * rVtx.pt.x) + (matBone[1][0] * rVtx.pt.y) + (matBone[2][0] * rVtx.pt.z) + matBone[3][0]) * rVtx.fWeight;
|
||||
pDest.y += ((matBone[0][1] * rVtx.pt.x) + (matBone[1][1] * rVtx.pt.y) + (matBone[2][1] * rVtx.pt.z) + matBone[3][1]) * rVtx.fWeight;
|
||||
pDest.z += ((matBone[0][2] * rVtx.pt.x) + (matBone[1][2] * rVtx.pt.y) + (matBone[2][2] * rVtx.pt.z) + matBone[3][2]) * rVtx.fWeight;
|
||||
}
|
||||
|
||||
// transforms the given _vector_ without applying the transitional part
|
||||
/*
|
||||
void CrySkinBase::transformVectorNoTrans (Vec3d& pDest, const Vec3d& pSrc, const Matrix& matBone)
|
||||
{
|
||||
pDest.x = matBone[0][0] * pSrc.x + matBone[1][0] * pSrc.y + matBone[2][0] * pSrc.z;
|
||||
pDest.y = matBone[0][1] * pSrc.x + matBone[1][1] * pSrc.y + matBone[2][1] * pSrc.z;
|
||||
pDest.z = matBone[0][2] * pSrc.x + matBone[1][2] * pSrc.y + matBone[2][2] * pSrc.z;
|
||||
}
|
||||
*/
|
||||
|
||||
// transforms the given smooth point into the destination with the matrix
|
||||
void CrySkinBase::transformWVector (Vec3d& pDest, const Matrix44& matBone, const Vertex& rVtx)
|
||||
{
|
||||
//pDest = matBone.TransformPoint(rVtx) * rVtx.fWeight;
|
||||
|
||||
pDest.x = ((matBone[0][0] * rVtx.pt.x) + (matBone[1][0] * rVtx.pt.y) + (matBone[2][0] * rVtx.pt.z)) * rVtx.fWeight;
|
||||
pDest.y = ((matBone[0][1] * rVtx.pt.x) + (matBone[1][1] * rVtx.pt.y) + (matBone[2][1] * rVtx.pt.z)) * rVtx.fWeight;
|
||||
pDest.z = ((matBone[0][2] * rVtx.pt.x) + (matBone[1][2] * rVtx.pt.y) + (matBone[2][2] * rVtx.pt.z)) * rVtx.fWeight;
|
||||
}
|
||||
|
||||
|
||||
// adds the given smooth point into the destination with the matrix
|
||||
void CrySkinBase::addWVector (Vec3d& pDest, const Matrix44& matBone, const Vertex& rVtx)
|
||||
{
|
||||
//pDest += matBone.TransformPoint(rVtx) * rVtx.fWeight;
|
||||
|
||||
pDest.x += ((matBone[0][0] * rVtx.pt.x) + (matBone[1][0] * rVtx.pt.y) + (matBone[2][0] * rVtx.pt.z)) * rVtx.fWeight;
|
||||
pDest.y += ((matBone[0][1] * rVtx.pt.x) + (matBone[1][1] * rVtx.pt.y) + (matBone[2][1] * rVtx.pt.z)) * rVtx.fWeight;
|
||||
pDest.z += ((matBone[0][2] * rVtx.pt.x) + (matBone[1][2] * rVtx.pt.y) + (matBone[2][2] * rVtx.pt.z)) * rVtx.fWeight;
|
||||
}
|
||||
|
||||
// returns the number of bytes occupied by this structure and all its contained objects
|
||||
unsigned CrySkinBase::sizeofThis()const
|
||||
{
|
||||
return sizeof(*this) + sizeofArray (m_arrAux) + sizeofArray(m_arrVertices);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----- this is the serialize version for little-endian CPUs -----
|
||||
//------------------------------------------------------------------------------
|
||||
unsigned CrySkinBase::Serialize_PC (bool bSave, void* pStream, unsigned nBufSize)
|
||||
{
|
||||
SerialHeader Header;
|
||||
if (bSave)
|
||||
{
|
||||
Header.initFromSkin(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!pStream)
|
||||
return 0;
|
||||
if (nBufSize < sizeof(Header))
|
||||
return 0;
|
||||
Header = *((SerialHeader*)pStream);
|
||||
}
|
||||
|
||||
unsigned nSizeAuxInts = ((sizeof(CrySkinAuxInt)*Header.numAuxInts+3)&~3);
|
||||
unsigned nSizeRequired =
|
||||
// the m_numBones, m_numSkipBones, m_numDests
|
||||
// m_arrAux.size(), m_arrVertices.size()
|
||||
sizeof(SerialHeader) +
|
||||
nSizeAuxInts +
|
||||
sizeof(Vertex) * Header.numVertices;
|
||||
|
||||
if (!pStream)
|
||||
return bSave?nSizeRequired:0;
|
||||
|
||||
if (nBufSize < nSizeRequired)
|
||||
return 0;
|
||||
|
||||
CrySkinAuxInt* pAuxInts = (CrySkinAuxInt*)(((SerialHeader*)pStream) + 1);
|
||||
Vertex* pVertices = (Vertex*)(((char*)pAuxInts) + nSizeAuxInts);
|
||||
|
||||
if (bSave)
|
||||
{
|
||||
//saving
|
||||
*((SerialHeader*)pStream) = Header;
|
||||
memcpy (pAuxInts, &m_arrAux[0], sizeof(CrySkinAuxInt)*m_arrAux.size());
|
||||
memcpy (pVertices, &m_arrVertices[0], sizeof(Vertex)*m_arrVertices.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
// loading
|
||||
m_arrAux.clear();
|
||||
m_arrAux.resize (Header.numAuxInts);
|
||||
m_arrVertices.clear();
|
||||
m_arrVertices.resize (Header.numVertices);
|
||||
m_numBones = Header.numBones;
|
||||
m_numSkipBones = Header.numSkipBones;
|
||||
m_numDests = Header.numDests;
|
||||
memcpy (&m_arrAux[0], pAuxInts, sizeof(CrySkinAuxInt)*m_arrAux.size());
|
||||
memcpy (&m_arrVertices[0], pVertices, sizeof(Vertex)*m_arrVertices.size());
|
||||
}
|
||||
return nSizeRequired;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//----- this is the serialize version for big-endian CPUs -----
|
||||
//------------------------------------------------------------------------------
|
||||
unsigned CrySkinBase::Serialize_GC (bool bSave, void* pStream, unsigned nBufSize)
|
||||
{
|
||||
SerialHeader Header;
|
||||
if (bSave)
|
||||
{
|
||||
Header.initFromSkin(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!pStream)
|
||||
return 0;
|
||||
if (nBufSize < sizeof(Header))
|
||||
return 0;
|
||||
Header = *((SerialHeader*)pStream);
|
||||
}
|
||||
|
||||
unsigned nSizeAuxInts = ((sizeof(CrySkinAuxInt)*Header.numAuxInts+3)&~3);
|
||||
unsigned nSizeRequired =
|
||||
// the m_numBones, m_numSkipBones, m_numDests
|
||||
// m_arrAux.size(), m_arrVertices.size()
|
||||
sizeof(SerialHeader) +
|
||||
nSizeAuxInts +
|
||||
sizeof(Vertex) * Header.numVertices;
|
||||
|
||||
if (!pStream)
|
||||
return bSave?nSizeRequired:0;
|
||||
|
||||
if (nBufSize < nSizeRequired)
|
||||
return 0;
|
||||
|
||||
CrySkinAuxInt* pAuxInts = (CrySkinAuxInt*)(((SerialHeader*)pStream) + 1);
|
||||
Vertex* pVertices = (Vertex*)(((char*)pAuxInts) + nSizeAuxInts);
|
||||
|
||||
if (bSave)
|
||||
{
|
||||
//saving
|
||||
Header.numBones = SWAP32(Header.numBones);
|
||||
Header.numSkipBones = SWAP32(Header.numSkipBones);
|
||||
Header.numDests = SWAP32(Header.numDests);
|
||||
Header.numAuxInts = SWAP32(Header.numAuxInts);
|
||||
Header.numVertices = SWAP32(Header.numVertices);
|
||||
*((SerialHeader*)pStream) = Header;
|
||||
|
||||
//swap data into big-endian-format
|
||||
unsigned sa = sizeof(CrySkinAuxInt);
|
||||
unsigned a = (unsigned)m_arrAux.size();
|
||||
unsigned x;
|
||||
for (x=0; x<a; x++) {
|
||||
pAuxInts[x]=SWAP16(pAuxInts[x]);
|
||||
}
|
||||
unsigned va = sizeof(m_arrVertices.size());
|
||||
unsigned v = (unsigned)m_arrVertices.size();
|
||||
for (x=0; x<(v); x++) {
|
||||
pVertices[x].nDest = SWAP32(pVertices[x].nDest);
|
||||
pVertices[x].pt.x = FSWAP32(pVertices[x].pt.x);
|
||||
pVertices[x].pt.y = FSWAP32(pVertices[x].pt.y);
|
||||
pVertices[x].pt.z = FSWAP32(pVertices[x].pt.z);
|
||||
}
|
||||
|
||||
//copy into stream
|
||||
memcpy (pAuxInts, &m_arrAux[0], sizeof(CrySkinAuxInt)*m_arrAux.size());
|
||||
memcpy (pVertices, &m_arrVertices[0], sizeof(Vertex)*m_arrVertices.size());
|
||||
|
||||
//..and new swap-back to little-endian,
|
||||
//because we need the original format for futher calculation on PC
|
||||
for (x=0; x<a; x++) {
|
||||
pAuxInts[x]=SWAP16(pAuxInts[x]);
|
||||
}
|
||||
for (x=0; x<(v); x++) {
|
||||
pVertices[x].nDest = SWAP32(pVertices[x].nDest);
|
||||
pVertices[x].pt.x = FSWAP32(pVertices[x].pt.x);
|
||||
pVertices[x].pt.y = FSWAP32(pVertices[x].pt.y);
|
||||
pVertices[x].pt.z = FSWAP32(pVertices[x].pt.z);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// loading
|
||||
m_arrAux.clear();
|
||||
m_arrAux.resize (Header.numAuxInts);
|
||||
m_arrVertices.clear();
|
||||
m_arrVertices.resize (Header.numVertices);
|
||||
m_numBones = Header.numBones;
|
||||
m_numSkipBones = Header.numSkipBones;
|
||||
m_numDests = Header.numDests;
|
||||
memcpy (&m_arrAux[0], pAuxInts, sizeof(CrySkinAuxInt)*m_arrAux.size());
|
||||
memcpy (&m_arrVertices[0], pVertices, sizeof(Vertex)*m_arrVertices.size());
|
||||
}
|
||||
return nSizeRequired;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CrySkinBase::CStatistics::CStatistics (const CrySkinBase*pSkin)
|
||||
{
|
||||
this->numBones = pSkin->m_numBones;
|
||||
this->numSkipBones = pSkin->m_numSkipBones;
|
||||
this->numAuxInts = (unsigned)pSkin->m_arrAux.size();
|
||||
this->numVertices = (unsigned)pSkin->m_arrVertices.size();
|
||||
|
||||
// construct the set of destination vertices
|
||||
for (unsigned nBone = numSkipBones; nBone < numBones; ++nBone)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
void CrySkinBase::scaleVertices (float fScale)
|
||||
{
|
||||
// all we have to do is to scale all the offsets
|
||||
for (VertexArray::iterator it = m_arrVertices.begin(), itEnd = m_arrVertices.end(); it!= itEnd; ++it)
|
||||
it->pt *= fScale;
|
||||
}
|
||||
Reference in New Issue
Block a user