183 lines
5.1 KiB
C++
183 lines
5.1 KiB
C++
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Crytek Character Animation source code
|
|
//
|
|
// History:
|
|
// Created by Sergiy Migdalskiy
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
#ifndef _CGF_UTILS_HDR_
|
|
#define _CGF_UTILS_HDR_
|
|
|
|
// prerequisities
|
|
//#include <CryHeaders.h>
|
|
//#include <StlDbgAlloc.h>
|
|
|
|
#ifndef M_PI
|
|
#define M_PI 3.1415926535897932384626433832795
|
|
#endif
|
|
|
|
// given the chunk, parses it and returns the array of pointers to the strings with the bone names
|
|
// in the supplied array. Returns true when successful
|
|
extern bool LoadBoneNameList (const CHUNK_HEADER& chunkHeader, const void* pChunk, unsigned nChunkSize, std::vector<const char*>& arrNames);
|
|
|
|
|
|
|
|
enum MatChunkLoadErrorEnum
|
|
{
|
|
MCLE_Success,
|
|
MCLE_Truncated,
|
|
MCLE_UnknownVersion,
|
|
MCLE_IgnoredType // this material type should be ignored (multimaterial)
|
|
};
|
|
|
|
|
|
// Attempts to load the material from the given material chunk to the "me" structure
|
|
extern MatChunkLoadErrorEnum LoadMatEntity (const CHUNK_HEADER& chunkHeader, const void* pChunkData, unsigned nChunkSize, MAT_ENTITY& me);
|
|
|
|
// material name parser.
|
|
// In the CGF, the material has to have a complex name:
|
|
// name_spec template_spec phys_mat_spec render_index_spec
|
|
//
|
|
// name_spec:
|
|
// $s_* -- * means the template name; in this case, material name remains $s_*
|
|
// * -- * means just the material name
|
|
//
|
|
// template_spec: -- not necessary
|
|
// (*) -- * means the template; closing bracket may be absent
|
|
//
|
|
// phys_mat_spec: -- not necessary
|
|
// /name
|
|
//
|
|
// render_index_spec: -- not necessary
|
|
// [id]
|
|
class CMatEntityNameTokenizer {
|
|
|
|
public:
|
|
CMatEntityNameTokenizer ();
|
|
~CMatEntityNameTokenizer ();
|
|
|
|
void tokenize(const char* szName);
|
|
|
|
// material name
|
|
const char *szName;
|
|
|
|
// template name (NULL if no template)
|
|
const char *szTemplate;
|
|
|
|
// physic material name
|
|
const char *szPhysMtl;
|
|
|
|
// render index (0 if not specified)
|
|
int nSortValue;
|
|
|
|
// true, if the template is to be inverted.. (# before the template name
|
|
bool bInvert;
|
|
|
|
// operator that sorts the materials for rendering
|
|
bool operator < (const CMatEntityNameTokenizer& right)const;
|
|
protected:
|
|
char* m_szMtlName;
|
|
};
|
|
|
|
// this is sorting predicate that helps form a mapping of old-new mat ids
|
|
// it's given an array of tokenizers to index into
|
|
class CMatEntityIndexSort
|
|
{
|
|
public:
|
|
// accepts the array of initialized tokenizers and their number
|
|
CMatEntityIndexSort (const CMatEntityNameTokenizer* pTokenizers, unsigned numSize):
|
|
m_pTokenizers (pTokenizers),
|
|
m_numSize (numSize)
|
|
{
|
|
}
|
|
|
|
bool operator () (unsigned nLeft, unsigned nRight) const
|
|
{
|
|
assert (nLeft >= 0 && nLeft < m_numSize);
|
|
assert (nRight >= 0 && nRight < m_numSize);
|
|
return m_pTokenizers[nLeft ]<m_pTokenizers[nRight];
|
|
}
|
|
|
|
protected:
|
|
const CMatEntityNameTokenizer* m_pTokenizers;
|
|
unsigned m_numSize;
|
|
};
|
|
|
|
// given the in-permutation, constructs the inverse out-permutation, so that:
|
|
// pOut[pIn[i]] == i
|
|
// pIn[pOut[i]] == i
|
|
void ConstructReversePermutation (const unsigned* pIn, unsigned* pOut, unsigned num);
|
|
|
|
// Remaps the materials according to the given permutation
|
|
// the permutation is perm[new index] == old index
|
|
void RemapMatEntities (MAT_ENTITY* pMtls, unsigned numMtls, unsigned* pPerm);
|
|
|
|
// copies the matrix from SBoneInitPosMatrix to Matrix
|
|
extern void copyMatrix (Matrix44& matDst, const SBoneInitPosMatrix& matSrc);
|
|
|
|
struct SBasisProperties
|
|
{
|
|
#ifdef _LEAFBUFFER_H_
|
|
SBasisProperties (const TangData& td)
|
|
{
|
|
init (td.tangent, td.binormal, td.tnormal);
|
|
}
|
|
#endif
|
|
|
|
SBasisProperties(const Vec3& vX, const Vec3& vY, const Vec3& vZ)
|
|
{
|
|
init (vX,vY,vZ);
|
|
}
|
|
|
|
static double maxCosToErrorDeg(double f)
|
|
{
|
|
return 90 - fabs(acos(f)*180/M_PI);
|
|
}
|
|
|
|
void init (const Vec3& vX, const Vec3& vY, const Vec3& vZ)
|
|
{
|
|
bMatrixDegraded = false;
|
|
bLeftHanded = false;
|
|
fErrorDeg = 0;
|
|
// max of cosine between two vectors
|
|
double fMaxCos = 0;
|
|
float fXLength = vX.Length(), fYLength = vY.Length(), fZLength = vZ.Length();
|
|
|
|
if (fXLength < 1e-3 || fYLength < 1e-3 || fZLength < 1e-3)
|
|
bMatrixDegraded = true;
|
|
else
|
|
{
|
|
double fMaxCosXY = fabs(vX*vY)/(fXLength*fYLength);
|
|
fMaxCos = max (fMaxCos, fMaxCosXY);
|
|
double fMaxCosXZ = fabs(vX*vZ)/(fXLength*fZLength);
|
|
fMaxCos = max (fMaxCos, fMaxCosXZ);
|
|
double fMaxCosYZ = fabs(vY*vZ)/(fYLength*fZLength);
|
|
fMaxCos = max (fMaxCos, fMaxCosYZ);
|
|
|
|
fErrorDeg = maxCosToErrorDeg(fMaxCos);
|
|
fErrorDegTB = (float)maxCosToErrorDeg(fMaxCosXY);
|
|
fErrorDegTN = (float)maxCosToErrorDeg(fMaxCosXZ);
|
|
fErrorDegBN = (float)maxCosToErrorDeg(fMaxCosYZ);
|
|
|
|
bLeftHanded = (vX^vY)*vZ < 0;
|
|
}
|
|
|
|
}
|
|
|
|
double fErrorDeg;
|
|
// the error degrees between the tangent, binormal and normal by pair
|
|
float fErrorDegTB, fErrorDegTN, fErrorDegBN;
|
|
bool bMatrixDegraded;
|
|
bool bLeftHanded;
|
|
|
|
bool isOrthogonal () const {return fErrorDeg < 0.5;}
|
|
double getLeftHandednessPercentage () const {return (100-fErrorDeg*100/90);}
|
|
};
|
|
|
|
extern const char* getMtlType (unsigned nMtlType);
|
|
extern const char* getTexType (unsigned char nTexType);
|
|
extern string getLightType (LightTypes nType);
|
|
extern string getMtlFlags (int nFlags);
|
|
|
|
#endif |