|
|
//===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//
//===========================================================================//
#ifndef INCLUDED_STUDIOMODEL
#define INCLUDED_STUDIOMODEL
#include "mathlib/mathlib.h"
#include "studio.h"
#include "mouthinfo.h"
#include "UtlLinkedList.h"
#include "UtlSymbol.h"
#include "bone_setup.h"
#include "datacache/imdlcache.h"
#include "tier1/utlstring.h"
#include "viewersettings.h"
#include "tier3/tier3.h"
#include "mathlib/softbody.h"
#define DEFAULT_BLEND_TIME 0.2
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
typedef struct IFACE_TAG IFACE; typedef struct IMESH_TAG IMESH; typedef struct ResolutionUpdateTag ResolutionUpdate; typedef struct FaceUpdateTag FaceUpdate; class IMaterial; class IDataCache; class IStudioPhysics; class IMaterialSystem; class IMDLCache; class CPhysmesh; struct hlmvsolid_t; struct constraint_ragdollparams_t; class IStudioRender; class IPhysicsSurfaceProps; class IPhysicsCollision; class IStudioDataCache; class IDataCache; class IFileSystem; class IMaterialSystemHardwareConfig; class CJiggleBones;
//-----------------------------------------------------------------------------
// Singleton interfaces
//-----------------------------------------------------------------------------
extern IPhysicsSurfaceProps *physprop; extern IPhysicsCollision *physcollision; extern IStudioDataCache *g_pStudioDataCache; extern IFileSystem *g_pFileSystem;
class AnimationLayer { public: float m_cycle; // 0 to 1 animation playback index
int m_sequence; // sequence index
float m_weight; float m_playbackrate; int m_priority; // lower priorities get layered first
};
struct StudioLookTarget { float m_flWeight; Vector m_vecPosition; bool m_bSelf; };
struct HitboxInfo_t { CUtlString m_Name; mstudiobbox_t m_BBox; };
// I'm saving this as internal data because we may add or remove hitboxes
// I'm using a utllinkedlist so hitbox IDs remain constant on add + remove
typedef CUtlLinkedList< HitboxInfo_t, unsigned short > HitboxList_t;
struct HitboxSet_t { CUtlString m_Name; HitboxList_t m_Hitboxes; };
class StudioModel { public: StudioModel(); ~StudioModel();
// memory handling, uses calloc so members are zero'd out on instantiation
void *operator new( size_t stAllocateBlock ); void* operator new( size_t stAllocateBlock, int nBlockUse, const char *pFileName, int nLine ); void operator delete( void *pMem ); void operator delete( void* pMem, int nBlockUse, const char *pFileName, int nLine );
static void Init( void ); static void Shutdown( void ); // garymcthack - need to call this.
static void UpdateViewState( const Vector& viewOrigin, const Vector& viewRight, const Vector& viewUp, const Vector& viewPlaneNormal );
static void ReleaseStudioModel( void ); static void RestoreStudioModel( void );
static void UnloadGroupFiles();
char const *GetFileName( void );
IStudioRender *GetStudioRender();
static void UpdateStudioRenderConfig( bool bWireframe, bool bZBufferWireframe, bool bNormals, bool bTangentFrame );
virtual void ModelInit( void ) { }
bool IsModelLoaded() const;
void FreeModel( bool bReleasing ); bool LoadModel( const char *modelname ); virtual bool PostLoadModel ( const char *modelname ); bool HasModel(); bool HasMesh();
virtual int DrawModel( bool mergeBones = false, int nRenderPassMode = PASS_DEFAULT );
virtual void DrawWidgetModel( );
virtual void AdvanceFrame( float dt ); float GetInterval( void ); float GetCycle( void ); float GetFrame( void ); int GetMaxFrame( void ); int SetFrame( int frame ); float GetCycle( int iLayer ); float GetFrame( int iLayer ); int GetMaxFrame( int iLayer ); int SetFrame( int iLayer, int frame );
void ExtractBbox( Vector &mins, Vector &maxs );
void SetBlendTime( float blendtime ); int LookupSequence( const char *szSequence ); int LookupActivity( const char *szActivity ); int SetSequence( int iSequence ); int SetSequence( const char *szSequence ); const char* GetSequenceName( int iSequence ); void ClearOverlaysSequences( void ); void ClearAnimationLayers( void ); int GetNewAnimationLayer( int iPriority = 0 );
int SetOverlaySequence( int iLayer, int iSequence, float flWeight ); float SetOverlayRate( int iLayer, float flCycle, float flFrameRate ); int GetOverlaySequence( int iLayer ); float GetOverlaySequenceWeight( int iLayer ); void StartBlending( void );
float GetTransitionAmount( void ); int GetSequence( void ); void GetSequenceInfo( int iSequence, float *pflFrameRate, float *pflGroundSpeed ); void GetSequenceInfo( float *pflFrameRate, float *pflGroundSpeed ); float GetFPS( int iSequence ); float GetFPS( ); float GetDuration( int iSequence ); float GetDuration( ); int GetNumFrames( int iSequence ); bool GetSequenceLoops( int iSequence ); void GetMovement( float prevCycle[5], Vector &vecPos, QAngle &vecAngles ); void GetMovement( int iSequence, float prevCycle, float currCycle, Vector &vecPos, QAngle &vecAngles ); void GetSeqAnims( int iSequence, mstudioanimdesc_t *panim[4], float *pweights ); void GetSeqAnims( mstudioanimdesc_t *panim[4], float *pweights ); float GetGroundSpeed( int iSequence ); float GetGroundSpeed( void ); float GetCurrentVelocity( void ); bool IsHidden( int iSequence );
float SetController( int iController, float flValue );
int LookupPoseParameter( char const *szName ); float SetPoseParameter( int iParameter, float flValue ); float SetPoseParameter( char const *szName, float flValue ); float GetPoseParameter( char const *szName ); float GetPoseParameter( int iParameter ); bool GetPoseParameterRange( int iParameter, float *pflMin, float *pflMax ); float* GetPoseParameters();
int LookupAttachment( char const *szName );
void ExtractVertExtents( Vector &vecMin, Vector &vecMax );
int SetBodygroup( int iGroup, int iValue ); int GetBodygroup( int iGroup ); void SetBodygroupPreset( char const *szName ); int SetSkin( int iValue ); int FindBone( const char *pName ); int GetBodyIndex() const {return m_bodynum;}
LocalFlexController_t LookupFlexController( char *szName ); void SetFlexController( char *szName, float flValue ); void SetFlexController( LocalFlexController_t iFlex, float flValue ); float GetFlexController( char *szName ); float GetFlexController( LocalFlexController_t iFlex ); void SetFlexControllerRaw( LocalFlexController_t iFlex, float flValue ); float GetFlexControllerRaw( LocalFlexController_t iFlex );
// void CalcBoneTransform( int iBone, Vector pos[], Quaternion q[], matrix3x4_t& bonematrix );
void UpdateBoneChain( Vector pos[], Quaternion q[], int iBone, matrix3x4_t *pBoneToWorld ); void SetViewTarget( void ); // ???
void GetBodyPoseParametersFromFlex( void ); void CalcHeadRotation( Vector pos[], Quaternion q[] ); float SetHeadPosition( matrix3x4_t& attToWorld, Vector const &vTargetPos, float dt );
int GetNumLODs() const; float GetLODSwitchValue( int lod ) const; void SetLODSwitchValue( int lod, float switchValue ); void scaleMeshes( float scale ); void scaleBones( float scale );
// Physics
void OverrideBones( bool *override ); int Physics_GetBoneCount( void ); const char * Physics_GetBoneName( int index ); int Physics_GetBoneIndex( const char *pName ); void Physics_GetData( int boneIndex, hlmvsolid_t *psolid, constraint_ragdollparams_t *pConstraint ) const; void Physics_SetData( int boneIndex, const hlmvsolid_t *psolid, constraint_ragdollparams_t const *pConstraint ); void Physics_SetPreview( int previewBone, int axis, float t ); float Physics_GetMass( void ); void Physics_SetMass( float mass ); char *Physics_DumpQC( void );
float GetSequenceTime() const { return m_sequencetime; } float GetTimeDelta() const { return m_dt; }
CStudioHdr *m_pStudioHdr; CStudioHdr *GetStudioHdr() const; studiohdr_t *GetStudioRenderHdr() const; studiohwdata_t *GetHardwareData( void ) const;
int GetNumIncludeModels() const; const char * GetIncludeModelName( int index ) const; // Get and set the model transform (i.e. what m_origin and m_angles are used to generate).
void GetModelTransform( matrix3x4_t &mat ); void SetModelTransform( const matrix3x4_t &mat );
public: // entity settings
QAngle m_angles; // rot
Vector m_origin; // trans
protected: int m_bodynum; // bodypart selection
int m_skinnum; // skin group selection
float m_controller[4]; // bone controllers
public: CMouthInfo m_mouth;
protected: char *m_pModelName; // model file name
// bool m_owntexmodel; // do we have a modelT.mdl ?
// Previouse sequence data
float m_blendtime; float m_sequencetime; int m_prevsequence; float m_prevcycle;
float m_dt;
// Blending info
// Gesture,Sequence layering state
#define MAXSTUDIOANIMLAYERS 8
AnimationLayer m_Layer[MAXSTUDIOANIMLAYERS]; int m_iActiveLayers;
public: float m_cycle; // 0 to 1 animation playback index
protected: int m_sequence; // sequence index
float m_poseparameter[MAXSTUDIOPOSEPARAM]; // intra-sequence blending
float m_weight;
// internal data
MDLHandle_t m_MDLHandle; mstudiomodel_t *m_pmodel;
public: CUtlVector< HitboxSet_t > m_HitboxSets; CUtlVector< CUtlSymbol > m_SurfaceProps;
protected: // class data
static Vector *m_AmbientLightColors;
// Added data
// IMESH *m_pimesh;
// VertexUpdate *m_pvertupdate;
// FaceUpdate *m_pfaceupdate;
IFACE *m_pface;
// studiohdr_t *m_ptexturehdr;
Vector4D m_adj; // FIX: non persistant, make static
public: IStudioPhysics *m_pPhysics; private: int m_physPreviewBone; int m_physPreviewAxis; float m_physPreviewParam; float m_physMass;
public: mstudioseqdesc_t &GetSeqDesc( int seq ); const matrix3x4_t* BoneToWorld( int nBoneIndex ) const;
private: mstudioanimdesc_t &GetAnimDesc( int anim ); mstudio_rle_anim_t *GetAnim( int anim );
void DrawPhysmesh( CPhysmesh *pMesh, int boneIndex, IMaterial *pMaterial, float *color ); void DrawPhysConvex( CPhysmesh *pMesh, int boneIndex, IMaterial *pMaterial );
void DrawRangeOfMotionArcs( CPhysmesh *pMesh, int boneIndex, IMaterial* pMaterial );
void SetupLighting( void );
virtual void SetupModel( int bodypart );
private: float m_flexweight[MAXSTUDIOFLEXCTRL]; matrix3x4a_t *m_pBoneToWorld;
public: virtual void RunFlexRules( void ); virtual int BoneMask( void ); virtual void SetUpBones( bool mergeBones );
int GetLodUsed( void ); float GetLodMetric( void );
const char *GetKeyValueText( int iSequence );
private: // Drawing helper methods
void DrawBones( ); void DrawAttachments( ); void DrawEditAttachment(); void DrawHitboxes(); void DrawPhysicsModel( ); void DrawSoftbody(); void DrawIllumPosition( ); void DrawOriginAxis( );
public: // generic interface to rendering?
void drawBox (Vector const *v, float const * color ); void drawWireframeBox (Vector const *v, float const* color ); void drawTransform( matrix3x4_t& m, float flLength = 4 ); void drawLine( Vector const &p1, Vector const &p2, int r = 0, int g = 0, int b = 255 ); void drawTransparentBox( Vector const &bbmin, Vector const &bbmax, const matrix3x4_t& m, float const *color, float const *wirecolor ); void drawCapsule( Vector const &bbmin, Vector const &bbmax, float flRadius, const matrix3x4_t& m, float const *interiorcolor, float const *wirecolor ); void drawText( Vector const &pos, const char* szText );
private: int m_LodUsed; float m_LodMetric;
public:
void SetSolveHeadTurn( int solve ); int GetSolveHeadTurn() const;
void ClearLookTargets( void ); void AddLookTarget( const Vector& vecPosition, float flWeight ); void AddLookTargetSelf( float flWeight );
void SetModelYaw( float yaw ); float GetModelYaw( void ) const; void SetBodyYaw( float yaw ); float GetBodyYaw( void ) const; void SetSpineYaw( float yaw ); float GetSpineYaw( void ) const;
CSoftbody* GetSoftbody() const { return m_pStudioHdr->GetSoftbody() ; } void SetSoftbodyOrientation( );
private:
// 0 == no, 1 == based on dt, 2 == completely.
int m_nSolveHeadTurn; CUtlVector < StudioLookTarget > m_vecHeadTargets;
float m_flModelYaw; float m_flBodyYaw; float m_flSpineYaw;
public: bool m_bIsTransparent; bool m_bHasProxy;
// necessary for accessing correct vertexes
void SetCurrentModel();
public: CIKContext m_ik; float m_prevGroundCycles[5]; float m_prevIKCycles[5];
public: void IncrementFramecounter( void ) { m_iFramecounter++; }; private: int m_iFramecounter;
private: CJiggleBones *m_pJiggleBones; };
//-----------------------------------------------------------------------------
// Inline methods
//-----------------------------------------------------------------------------
inline CStudioHdr *StudioModel::GetStudioHdr( void ) const { if (!m_pStudioHdr || m_pStudioHdr->IsReadyForAccess()) return m_pStudioHdr;
studiohdr_t *hdr = g_pMDLCache->GetStudioHdr( m_MDLHandle );
m_pStudioHdr->Init( hdr );
if (m_pStudioHdr->IsReadyForAccess()) return m_pStudioHdr;
return NULL; }
inline studiohdr_t *StudioModel::GetStudioRenderHdr( void ) const { return g_pMDLCache->GetStudioHdr( m_MDLHandle ); }
inline studiohwdata_t *StudioModel::GetHardwareData( void ) const { return g_pMDLCache->GetHardwareData( m_MDLHandle ); }
inline char const *StudioModel::GetFileName( void ) { return m_pModelName; }
inline IStudioRender *StudioModel::GetStudioRender() { return g_pStudioRender; }
inline bool StudioModel::IsModelLoaded() const { return m_MDLHandle != MDLHANDLE_INVALID; }
inline const matrix3x4_t* StudioModel::BoneToWorld( int nBoneIndex ) const { return &m_pBoneToWorld[nBoneIndex]; }
enum WidgetType { WIDGET_ROTATE = 0, WIDGET_TRANSLATE, WIDGET_NUM_WIDGET_TYPES, };
enum WidgetState { WIDGET_STATE_NONE = 0, WIDGET_CHANGE_X, WIDGET_CHANGE_Y, WIDGET_CHANGE_Z, };
class WidgetControl { public: WidgetControl(); ~WidgetControl();
void SetStateUsingInputColor( Color inputColor );
void WidgetMouseDown( int x, int y ); void WidgetMouseDrag( int x, int y );
bool HasStoredValue( void );
StudioModel *GetWidgetModel( void );
WidgetType m_WidgetType; StudioModel *m_pWidgetModel[WIDGET_NUM_WIDGET_TYPES]; WidgetState m_WidgetState; Vector2D m_vecWidgetMouseDownCoord; Vector2D m_vecWidgetDeltaCoord; Vector m_vecValue; };
//-----------------------------------------------------------------------------
// Globals
//-----------------------------------------------------------------------------
extern Vector g_vright; // needs to be set to viewer's right in order for chrome to work
extern StudioModel *g_pStudioModel; extern StudioModel *g_pStudioExtraModel[HLMV_MAX_MERGED_MODELS]; extern WidgetControl *g_pWidgetControl;
struct mergemodelbonepair_t { char szTargetBone[256]; char szLocalBone[256]; }; extern mergemodelbonepair_t g_MergeModelBonePairs[ HLMV_MAX_MERGED_MODELS ];
#endif // INCLUDED_STUDIOMODEL
|