Files
FC1/ResourceCompilerPC/CrySkinTypes.h
romkazvo 34d6c5d489 123
2023-08-07 19:29:24 +08:00

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