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
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
|