Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

146 lines
3.8 KiB

//====== Copyright © Valve Corporation, All rights reserved. =======
#ifndef MODELLIB_CLOTHHELPERS
#define MODELLIB_CLOTHHELPERS
#include "tier1/utlstring.h"
#include "tier1/utlhashtable.h"
#include "tier1/utlvector.h"
class CClothBoneMap
{
public:
CClothBoneMap();
~CClothBoneMap();
void RegisterBone( const char *pName, int nBone );
public:
struct Patch_t
{
Patch_t(): m_nColumnCount( 0 ), m_nRowCount( 0 ) {}
int m_nColumnCount;
int m_nRowCount;
CUtlString m_Name;
public:
void Insert( int nRow, int nColumn, int nBone );
int GetBone( int nRow, int nColumn );
protected:
CUtlHashtable< uint, int > m_Bones; // ( Row << 16 ) | Column => Bone name
};
public:
Patch_t *GetPatch( int nPatch ) { return m_Patches[nPatch]; }
int GetPatchCount() const { return m_Patches.Count(); }
protected:
CUtlVector< Patch_t* > m_Patches;
protected:
Patch_t *GetPatch( const char *pName, const char *pNameEnd );
};
class CReverseParser
{
public:
CReverseParser( const char *pString ): m_pString( pString ), m_pEnd( pString + V_strlen( pString ) ) {}
int MatchInt();
char ReadChar( );
bool IsValid() { return m_pEnd != NULL; }
const char *GetEnd() const { return m_pEnd; }
CUtlString GetRemainder()const;
protected:
const char * m_pString;
const char * m_pEnd;
};
inline Vector GetScaleVector( const matrix3x4_t &tm )
{
Vector vScale( tm.GetColumn( X_AXIS ).Length( ), tm.GetColumn( Y_AXIS ).Length( ), tm.GetColumn( Z_AXIS ).Length( ) );
return vScale;
}
inline bool IsGoodWorldTransform( const matrix3x4_t &tm, float flExpectedScale = 1.0f, float flTolerance = 0.001f )
{
Vector vScale = GetScaleVector( tm );
return tm.IsValid( ) && ( vScale - Vector( flExpectedScale, flExpectedScale, flExpectedScale ) ).Length( ) < flTolerance && tm.GetOrthogonalityError() < flTolerance;
}
//-----------------------------------------------------------------------------
// functions for dealing with scale
//-----------------------------------------------------------------------------
inline matrix3x4_t ScaleMatrix3x3( const matrix3x4_t &transform, float flScale )
{
if ( flScale == 1.0f )
return transform;
matrix3x4_t out;
for ( int i = 0; i < 3; ++i )
{
for ( int j = 0; j < 3; ++j )
{
out[ i ][ j ] = transform[ i ][ j ] * flScale;
}
out[ i ][ 3 ] = transform[ i ][ 3 ];
}
return out;
}
inline void Set3x3( matrix3x4a_t &dest, const matrix3x4a_t &src )
{
dest.m_flMatVal[ 0 ][ 0 ] = src.m_flMatVal[ 0 ][ 0 ];
dest.m_flMatVal[ 0 ][ 1 ] = src.m_flMatVal[ 0 ][ 1 ];
dest.m_flMatVal[ 0 ][ 2 ] = src.m_flMatVal[ 0 ][ 2 ];
dest.m_flMatVal[ 1 ][ 0 ] = src.m_flMatVal[ 1 ][ 0 ];
dest.m_flMatVal[ 1 ][ 1 ] = src.m_flMatVal[ 1 ][ 1 ];
dest.m_flMatVal[ 1 ][ 2 ] = src.m_flMatVal[ 1 ][ 2 ];
dest.m_flMatVal[ 2 ][ 0 ] = src.m_flMatVal[ 2 ][ 0 ];
dest.m_flMatVal[ 2 ][ 1 ] = src.m_flMatVal[ 2 ][ 1 ];
dest.m_flMatVal[ 2 ][ 2 ] = src.m_flMatVal[ 2 ][ 2 ];
}
inline void Set3x3( matrix3x4a_t &dest, const matrix3x4a_t &src, const Vector &vNewOrigin )
{
Set3x3( dest, src );
dest.SetOrigin( vNewOrigin );
}
inline matrix3x4_t AlignX( matrix3x4a_t &tm, const Vector &vNewX, const Vector &vOrigin )
{
float flNewXLen = vNewX.Length( );
if ( flNewXLen > 0.03f ) // if the new X axis is not well-defined, it makes little sense to adjust the base
{
Quaternion q = RotateBetween( tm.GetColumn( X_AXIS ).Normalized( ), vNewX / flNewXLen );
matrix3x4_t rot = QuaternionMatrix( q ), rotated = rot * tm;
AssertDbg( CrossProduct( rotated.GetColumn( X_AXIS ), vNewX ).Length( ) < 0.002f * vNewX.Length() );
AssertDbg( rotated.GetOrthogonalityError() < 0.001f );
rotated.SetOrigin( vOrigin );
return rotated;
}
else
{
return tm;
}
}
inline matrix3x4_t Descale( const matrix3x4a_t &tm )
{
float flInvScale = 1.0f / tm.GetColumn( X_AXIS ).Length();
return ScaleMatrix3x3( tm, flInvScale );
}
#endif