181 lines
4.4 KiB
C
181 lines
4.4 KiB
C
#ifndef _CRY_ANIMATION_CRY_SKIN_TYPES_HDR_
|
|
#define _CRY_ANIMATION_CRY_SKIN_TYPES_HDR_
|
|
|
|
#include "MathUtils.h"
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// the packed skin vertex structure: rigid or smooth, 16 byte
|
|
// the point is the original point in the bone's CS
|
|
struct CrySkinVertexAligned
|
|
{
|
|
Vec3 pt;
|
|
|
|
union
|
|
{
|
|
unsigned nDest; // the destination vertex index to store the transformed point
|
|
float fWeight; // the weight of the point
|
|
};
|
|
};
|
|
|
|
// the way the packed indices/group headers are kept: short or int
|
|
#define CRY_SKIN_AUX_INT_SIZE 2
|
|
|
|
#if CRY_SKIN_AUX_INT_SIZE==2
|
|
typedef unsigned short CrySkinAuxInt;
|
|
#elif CRY_SKIN_AUX_INT_SIZE==4
|
|
typedef unsigned CrySkinAuxInt;
|
|
#if defined _CPU_AMD64
|
|
#error You will need to modify the file CrySkinAMD64.ASM to make this work!
|
|
#endif // _CPU_AMD64
|
|
#else
|
|
#error CRY_SKIN_AUX_INT_SIZE must be defined and be 2 or 4
|
|
#endif
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Unpacked rigid vertex structure
|
|
struct CrySkinRigidVertex
|
|
{
|
|
Vec3 pt;
|
|
unsigned nDest; // the destination vertex index
|
|
|
|
CrySkinRigidVertex(){}
|
|
|
|
// initializes the structure given the offset from the bone and the destination vertex index
|
|
CrySkinRigidVertex (const Vec3& _ptOffset, unsigned _nDest):
|
|
pt (_ptOffset),
|
|
nDest (_nDest)
|
|
{
|
|
}
|
|
|
|
// constructs the packed rigid vertex data from this structure
|
|
void build (CrySkinVertexAligned& vDst)const
|
|
{
|
|
vDst.pt = pt;
|
|
vDst.nDest = nDest;
|
|
}
|
|
};
|
|
|
|
// aligned by 16-byte boundary tangent vectors
|
|
// if you don't want the padding to be used, just define it as
|
|
// typedef SPipTangents SPipTangentsA16;
|
|
struct SPipTangentsA16
|
|
{
|
|
Vec3 m_Tangent;
|
|
unsigned int m_Pad0;
|
|
Vec3 m_Binormal;
|
|
unsigned int m_Pad1;
|
|
Vec3 m_TNormal;
|
|
unsigned int m_Pad2;
|
|
|
|
inline SPipTangentsA16& operator = (const SPipTangents& right)
|
|
{
|
|
m_Tangent = right.m_Tangent;
|
|
m_Binormal = right.m_Binormal;
|
|
m_TNormal = right.m_TNormal;
|
|
return *this;
|
|
}
|
|
|
|
inline void copyTo (SPipTangents* right)
|
|
{/*
|
|
#ifdef DO_ASM
|
|
_asm
|
|
{
|
|
mov EBX, this
|
|
mov EDX, right
|
|
|
|
mov EAX, [EBX]
|
|
mov [EDX], EAX
|
|
mov EAX, [EBX+4]
|
|
mov [EDX+4], EAX
|
|
mov EAX, [EBX+8]
|
|
mov [EDX+8], EAX
|
|
|
|
mov EAX, [EBX+0x10]
|
|
mov [EDX+0xC], EAX
|
|
mov EAX, [EBX+0x14]
|
|
mov [EDX+0x10], EAX
|
|
mov EAX, [EBX+0x18]
|
|
mov [EDX+0x14], EAX
|
|
|
|
mov EAX, [EBX+0x20]
|
|
mov [EDX+0x18], EAX
|
|
mov EAX, [EBX+0x24]
|
|
mov [EDX+0x1C], EAX
|
|
mov EAX, [EBX+0x28]
|
|
mov [EBX+0x20], EAX
|
|
}
|
|
#else
|
|
*/
|
|
right->m_Tangent = m_Tangent;
|
|
right->m_Binormal = m_Binormal;
|
|
right->m_TNormal = m_TNormal;
|
|
//#endif
|
|
}
|
|
};
|
|
|
|
|
|
// the size of the SPipTangentsA: can be either 0x30 for aligned structure or
|
|
// 0x24 for non-aligned
|
|
#define sizeofSPipTangentsA 0x24
|
|
|
|
#if sizeofSPipTangentsA == 0x24
|
|
// this is the actual structure that's to be used to store tangents
|
|
typedef SPipTangents SPipTangentsA;
|
|
#elif sizeofSPipTangentsA == 0x30
|
|
typedef SPipTangentsA16 SPipTangentsA;
|
|
#else
|
|
#error
|
|
#endif
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Unpacked rigid basis structure
|
|
struct CrySkinRigidBaseInfo
|
|
{
|
|
Vec3 ptTangent;
|
|
Vec3 ptBinormal;
|
|
unsigned nDest;
|
|
|
|
CrySkinRigidBaseInfo (){}
|
|
CrySkinRigidBaseInfo (const Matrix44& matInvDef, const TangData& rBasis, unsigned _nDest):
|
|
ptTangent (matInvDef.TransformVectorOLD(rBasis.tangent)),
|
|
ptBinormal(matInvDef.TransformVectorOLD(rBasis.binormal)),
|
|
nDest (_nDest)
|
|
{
|
|
|
|
}
|
|
|
|
// constructs the packed representation of the base: uses pDst[0] for tangent and destination
|
|
// vertex, and pDst[1] for binormal. Does not set the additional field of the pDst[1]
|
|
void build (CrySkinVertexAligned* pDst)const
|
|
{
|
|
pDst[0].pt = ptTangent;
|
|
// we multiply to get the actual offset (to avoid multiplication in assembly)
|
|
// and add the dummy bits that avoid denormalization assists in SSE
|
|
pDst[0].nDest = nDest * sizeof(SPipTangentsA) + 0x40000000;
|
|
pDst[1].pt = ptBinormal;
|
|
pDst[1].fWeight = 0;
|
|
}
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Unpacked smooth vertex structure
|
|
struct CrySkinSmoothVertex: public CrySkinRigidVertex
|
|
{
|
|
float fWeight;// the weight of the point
|
|
|
|
CrySkinSmoothVertex(){}
|
|
|
|
// initializes this smooth vertex structure
|
|
CrySkinSmoothVertex (const CryLink& rLink, unsigned _nDest):
|
|
CrySkinRigidVertex(rLink.offset, _nDest),
|
|
fWeight(rLink.Blending)
|
|
{
|
|
}
|
|
|
|
// constructs the packed rigid vertex data from this structure
|
|
void build (CrySkinVertexAligned& vDst)const
|
|
{
|
|
vDst.pt = pt;
|
|
vDst.fWeight = fWeight;
|
|
}
|
|
};
|
|
|
|
#endif |