#include "stdafx.h" #include #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; xnumBones = 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; }