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.
3734 lines
132 KiB
3734 lines
132 KiB
//===== Copyright (c) 1996-2008, Valve Corporation, All rights reserved. ======//
|
|
//
|
|
// Purpose:
|
|
//
|
|
// $NoKeywords: $
|
|
//
|
|
//=============================================================================//
|
|
|
|
#ifndef STUDIO_PS3_H
|
|
#define STUDIO_PS3_H
|
|
|
|
#include "basetypes.h"
|
|
|
|
//#include "mathlib/vector2d.h"
|
|
#include "mathlib/vector.h"
|
|
#include "mathlib/vector4d.h"
|
|
#include "mathlib/compressed_vector.h"
|
|
// #include "tier0/dbg.h"
|
|
// #include "tier0/threadtools.h"
|
|
#include "mathlib/mathlib.h"
|
|
|
|
//#include "utlvector.h"
|
|
// #include "utlhash.h"
|
|
// #include "datamap.h"
|
|
// #include "generichash.h"
|
|
// #include "localflexcontroller.h"
|
|
// #include "utlsymbol.h"
|
|
// #include "convar.h"
|
|
|
|
|
|
// duplicated defined from studio.h for spu
|
|
#if defined(__SPU__)
|
|
|
|
#define STUDIO_LOCAL 0x0200 // sequence has a local context sequence
|
|
|
|
#define STUDIO_LOOPING 0x0001 // ending frame should be the same as the starting frame
|
|
|
|
|
|
#define BONE_FIXED_ALIGNMENT 0x00100000 // bone can't spin 360 degrees, all interpolation is normalized around a fixed orientation
|
|
|
|
#define BONE_HAS_SAVEFRAME_POS 0x00200000 // Vector48
|
|
#define BONE_HAS_SAVEFRAME_ROT64 0x00400000 // Quaternion64
|
|
#define BONE_HAS_SAVEFRAME_ROT32 0x00800000 // Quaternion32
|
|
|
|
#define STUDIO_FRAME_CONST_POS 0x01 // Vector48 in constants
|
|
#define STUDIO_FRAME_CONST_ROT 0x02 // Quaternion48 in constants
|
|
#define STUDIO_FRAME_ANIM_POS 0x04 // Vector48 in framedata
|
|
#define STUDIO_FRAME_ANIM_ROT 0x08 // Quaternion48 in framedata
|
|
#define STUDIO_FRAME_ANIM_POS2 0x10 // Vector in framedata
|
|
#define STUDIO_FRAME_CONST_POS2 0x20 // Vector in constants
|
|
#define STUDIO_FRAME_CONST_ROT2 0x40 // Quaternion48S in constants
|
|
#define STUDIO_FRAME_ANIM_ROT2 0x80 // Quaternion48S in framedata
|
|
|
|
#define STUDIO_DELTA 0x0004 // this sequence "adds" to the base sequences, not slerp blends
|
|
#define STUDIO_FRAMEANIM 0x0040 // animation is encoded as by frame x bone instead of RLE bone x frame
|
|
|
|
#define STUDIO_POST 0x0010 //
|
|
#define STUDIO_WORLD 0x4000 // sequence blends in worldspace
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// #define STUDIO_ENABLE_PERF_COUNTERS
|
|
|
|
// #define STUDIO_SEQUENCE_ACTIVITY_LOOKUPS_ARE_SLOW 0
|
|
//-----------------------------------------------------------------------------
|
|
// forward declarations
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// class IMaterial;
|
|
// class IMesh;
|
|
// class IMorph;
|
|
// struct virtualmodel_t;
|
|
// struct vertexFileHeader_t;
|
|
// struct thinModelVertices_t;
|
|
//
|
|
// namespace OptimizedModel
|
|
// {
|
|
// struct StripHeader_t;
|
|
// }
|
|
|
|
|
|
class CThreadFastMutex_PS3 // here for size only
|
|
{
|
|
uint32 m_ownerID;
|
|
int m_depth;
|
|
};
|
|
|
|
|
|
/*
|
|
==============================================================================
|
|
|
|
STUDIO MODELS
|
|
|
|
Studio models are position independent, so the cache manager can move them.
|
|
==============================================================================
|
|
*/
|
|
|
|
// #define STUDIO_VERSION 49
|
|
|
|
struct studiohdr_t_PS3;
|
|
|
|
// #ifdef _GAMECONSOLE
|
|
// #define MAXSTUDIOTRIANGLES 65536 //
|
|
// #define MAXSTUDIOVERTS 32768 // These numbers save memory in CCachedRenderData, but restrict usable model sizes on 360
|
|
// #define MAXSTUDIOFLEXVERTS 4096 //
|
|
// #else
|
|
// #define MAXSTUDIOTRIANGLES 65536 // TODO: tune this
|
|
// #define MAXSTUDIOVERTS 65536 // TODO: tune this
|
|
// #define MAXSTUDIOFLEXVERTS 10000 // max number of verts that can be flexed per mesh. TODO: tune this
|
|
// #endif
|
|
// #define MAXSTUDIOSKINS 32 // total textures
|
|
#define MAXSTUDIOBONES_PS3 128 // 256 // total bones actually used
|
|
// #define MAXSTUDIOFLEXDESC 1024 // maximum number of low level flexes (actual morph targets)
|
|
// #define MAXSTUDIOFLEXCTRL 96 // maximum number of flexcontrollers (input sliders)
|
|
#define MAXSTUDIOPOSEPARAM_PS3 24
|
|
// #define MAXSTUDIOBONECTRLS 4
|
|
// #define MAXSTUDIOANIMBLOCKS 256
|
|
|
|
#define MAXSTUDIOBONEBITS_PS3 7 //8 // NOTE: MUST MATCH MAXSTUDIOBONES
|
|
|
|
// NOTE!!! : Changing this number also changes the vtx file format!!!!!
|
|
// #define MAX_NUM_BONES_PER_VERT 3
|
|
|
|
//Adrian - Remove this when we completely phase out the old event system.
|
|
// #define NEW_EVENT_STYLE ( 1 << 10 )
|
|
|
|
// struct mstudiodata_t
|
|
// {
|
|
// int count;
|
|
// int offset;
|
|
// };
|
|
|
|
// #define STUDIO_PROC_AXISINTERP 1
|
|
// #define STUDIO_PROC_QUATINTERP 2
|
|
// #define STUDIO_PROC_AIMATBONE 3
|
|
// #define STUDIO_PROC_AIMATATTACH 4
|
|
// #define STUDIO_PROC_JIGGLE 5
|
|
// #define STUDIO_PROC_TWIST_MASTER 6
|
|
// #define STUDIO_PROC_TWIST_SLAVE 7 // Multiple twist bones are computed at once for the same parent/child combo so TWIST_NULL do nothing
|
|
// #define STUDIO_PROC_POINT_CONSTRAINT 8
|
|
// #define STUDIO_PROC_ORIENT_CONSTRAINT 9
|
|
// #define STUDIO_PROC_AIM_CONSTRAINT 10
|
|
// #define STUDIO_PROC_IK_CONSTRAINT 11
|
|
// #define STUDIO_PROC_PARENT_CONSTRAINT 12
|
|
|
|
// struct mstudioaxisinterpbone_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
// int control;// local transformation of this bone used to calc 3 point blend
|
|
// int axis; // axis to check
|
|
// Vector pos[6]; // X+, X-, Y+, Y-, Z+, Z-
|
|
// Quaternion quat[6];// X+, X-, Y+, Y-, Z+, Z-
|
|
//
|
|
// mstudioaxisinterpbone_t(){}
|
|
// private:
|
|
// // No copy constructors allowed
|
|
// mstudioaxisinterpbone_t(const mstudioaxisinterpbone_t& vOther);
|
|
// };
|
|
|
|
|
|
// struct mstudioquatinterpinfo_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
// float inv_tolerance; // 1 / radian angle of trigger influence
|
|
// Quaternion trigger; // angle to match
|
|
// Vector pos; // new position
|
|
// Quaternion quat; // new angle
|
|
//
|
|
// mstudioquatinterpinfo_t(){}
|
|
// private:
|
|
// // No copy constructors allowed
|
|
// mstudioquatinterpinfo_t(const mstudioquatinterpinfo_t& vOther);
|
|
// };
|
|
|
|
// struct mstudioquatinterpbone_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
// int control;// local transformation to check
|
|
// int numtriggers;
|
|
// int triggerindex;
|
|
// inline mstudioquatinterpinfo_t *pTrigger( int i ) const { return (mstudioquatinterpinfo_t *)(((byte *)this) + triggerindex) + i; };
|
|
//
|
|
// mstudioquatinterpbone_t(){}
|
|
// private:
|
|
// // No copy constructors allowed
|
|
// mstudioquatinterpbone_t(const mstudioquatinterpbone_t& vOther);
|
|
// };
|
|
|
|
|
|
// #define JIGGLE_IS_FLEXIBLE 0x01
|
|
// #define JIGGLE_IS_RIGID 0x02
|
|
// #define JIGGLE_HAS_YAW_CONSTRAINT 0x04
|
|
// #define JIGGLE_HAS_PITCH_CONSTRAINT 0x08
|
|
// #define JIGGLE_HAS_ANGLE_CONSTRAINT 0x10
|
|
// #define JIGGLE_HAS_LENGTH_CONSTRAINT 0x20
|
|
// #define JIGGLE_HAS_BASE_SPRING 0x40
|
|
//
|
|
// struct mstudiojigglebone_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
//
|
|
// int flags;
|
|
//
|
|
// // general params
|
|
// float length; // how from from bone base, along bone, is tip
|
|
// float tipMass;
|
|
//
|
|
// // flexible params
|
|
// float yawStiffness;
|
|
// float yawDamping;
|
|
// float pitchStiffness;
|
|
// float pitchDamping;
|
|
// float alongStiffness;
|
|
// float alongDamping;
|
|
//
|
|
// // angle constraint
|
|
// float angleLimit; // maximum deflection of tip in radians
|
|
//
|
|
// // yaw constraint
|
|
// float minYaw; // in radians
|
|
// float maxYaw; // in radians
|
|
// float yawFriction;
|
|
// float yawBounce;
|
|
//
|
|
// // pitch constraint
|
|
// float minPitch; // in radians
|
|
// float maxPitch; // in radians
|
|
// float pitchFriction;
|
|
// float pitchBounce;
|
|
//
|
|
// // base spring
|
|
// float baseMass;
|
|
// float baseStiffness;
|
|
// float baseDamping;
|
|
// float baseMinLeft;
|
|
// float baseMaxLeft;
|
|
// float baseLeftFriction;
|
|
// float baseMinUp;
|
|
// float baseMaxUp;
|
|
// float baseUpFriction;
|
|
// float baseMinForward;
|
|
// float baseMaxForward;
|
|
// float baseForwardFriction;
|
|
//
|
|
// private:
|
|
// // No copy constructors allowed
|
|
// //mstudiojigglebone_t(const mstudiojigglebone_t& vOther);
|
|
// };
|
|
|
|
// struct mstudioaimatbone_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
//
|
|
// int parent;
|
|
// int aim; // Might be bone or attach
|
|
// Vector aimvector;
|
|
// Vector upvector;
|
|
// Vector basepos;
|
|
//
|
|
// mstudioaimatbone_t() {}
|
|
// private:
|
|
// // No copy constructors allowed
|
|
// mstudioaimatbone_t(const mstudioaimatbone_t& vOther);
|
|
// };
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
// struct mstudiotwistbonetarget_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
//
|
|
// int m_nBone;
|
|
// float m_flWeight;
|
|
// Vector m_vBaseTranslate;
|
|
// Quaternion m_qBaseRotation;
|
|
//
|
|
// mstudiotwistbonetarget_t() {}
|
|
// private:
|
|
// // No copy constructors allowed
|
|
// mstudiotwistbonetarget_t( const mstudiotwistbonetarget_t &vOther );
|
|
// };
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
// struct mstudiotwistbone_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
//
|
|
// bool m_bInverse; // False: Apply child rotation to twist targets True: Apply parent rotation to twist targets
|
|
// Vector m_vUpVector; // In parent space, projected into plane defined by vector between parent & child
|
|
// int m_nParentBone;
|
|
// Quaternion m_qBaseInv; // The base rotation of the parent, used if m_bInverse is true
|
|
// int m_nChildBone;
|
|
//
|
|
// int m_nTargetCount;
|
|
// int m_nTargetIndex;
|
|
// inline mstudiotwistbonetarget_t *pTarget( int i ) const { return ( mstudiotwistbonetarget_t * )( ( ( byte * )this) + m_nTargetIndex ) + i; }
|
|
//
|
|
// mstudiotwistbone_t() {}
|
|
// private:
|
|
// // No copy constructors allowed
|
|
// mstudiotwistbone_t( const mstudiotwistbone_t &vOther );
|
|
// };
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
// struct mstudioconstraintslave_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
//
|
|
// int m_nBone;
|
|
// Vector m_vBasePosition;
|
|
// Quaternion m_qBaseOrientation;
|
|
//
|
|
// mstudioconstraintslave_t() {}
|
|
// private:
|
|
// // No copy constructors allowed
|
|
// mstudioconstraintslave_t( const mstudioconstraintslave_t &vOther );
|
|
// };
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
// struct mstudioconstrainttarget_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
//
|
|
// int m_nBone;
|
|
// float m_flWeight;
|
|
// Vector m_vOffset;
|
|
// Quaternion m_qOffset;
|
|
//
|
|
// mstudioconstrainttarget_t() {}
|
|
// private:
|
|
// // No copy constructors allowed
|
|
// mstudioconstrainttarget_t( const mstudioconstrainttarget_t &vOther );
|
|
// };
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Point constraint, slave position matches target position
|
|
//-----------------------------------------------------------------------------
|
|
// struct mstudiopointconstraint_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
//
|
|
// mstudioconstraintslave_t m_slave; // DEFINE_EMBEDDED
|
|
//
|
|
// int m_nTargetCount;
|
|
// int m_nTargetIndex;
|
|
// inline mstudioconstrainttarget_t *pTarget( int i ) const { return ( mstudioconstrainttarget_t * )( ( ( byte * )this) + m_nTargetIndex ) + i; }
|
|
//
|
|
// mstudiopointconstraint_t() {}
|
|
// private:
|
|
// // No copy constructors allowed
|
|
// mstudiopointconstraint_t( const mstudiopointconstraint_t &vOther );
|
|
// };
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Orient constraint, slave orientation matches target orientation
|
|
//-----------------------------------------------------------------------------
|
|
// struct mstudioorientconstraint_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
//
|
|
// mstudioconstraintslave_t m_slave; // DEFINE_EMBEDDED
|
|
//
|
|
// int m_nTargetCount;
|
|
// int m_nTargetIndex;
|
|
// inline mstudioconstrainttarget_t *pTarget( int i ) const { return ( mstudioconstrainttarget_t * )( ( ( byte * )this) + m_nTargetIndex ) + i; }
|
|
//
|
|
// mstudioorientconstraint_t() {}
|
|
// private:
|
|
// // No copy constructors allowed
|
|
// mstudioorientconstraint_t( const mstudioorientconstraint_t &vOther );
|
|
// };
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
// struct mstudioaimconstraint_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
//
|
|
// mstudioconstraintslave_t m_slave; // DEFINE_EMBEDDED
|
|
//
|
|
// int m_nTargetCount;
|
|
// int m_nTargetIndex;
|
|
// inline mstudioconstrainttarget_t *pTarget( int i ) const { return ( mstudioconstrainttarget_t * )( ( ( byte * )this) + m_nTargetIndex ) + i; }
|
|
//
|
|
// Quaternion m_qAimOffset;
|
|
// Vector m_vUp;
|
|
// int m_nUpSpaceTarget;
|
|
//
|
|
// mstudioaimconstraint_t() {}
|
|
// private:
|
|
// // No copy constructors allowed
|
|
// mstudioaimconstraint_t( const mstudioaimconstraint_t &vOther );
|
|
// };
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
// struct mstudioikconstraint_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
//
|
|
// mstudioikconstraint_t() {}
|
|
// private:
|
|
// // No copy constructors allowed
|
|
// mstudioikconstraint_t( const mstudioaimconstraint_t &vOther );
|
|
// };
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Parent constraint, slave position and orientation are updated to behave as children of the target
|
|
//-----------------------------------------------------------------------------
|
|
// struct mstudioparentconstraint_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
//
|
|
// mstudioconstraintslave_t m_slave; // DEFINE_EMBEDDED
|
|
//
|
|
// int m_nTargetCount;
|
|
// int m_nTargetIndex;
|
|
// inline mstudioconstrainttarget_t *pTarget( int i ) const { return ( mstudioconstrainttarget_t * )( ( ( byte * )this) + m_nTargetIndex ) + i; }
|
|
//
|
|
// mstudioparentconstraint_t() {}
|
|
// private:
|
|
// // No copy constructors allowed
|
|
// mstudioparentconstraint_t( const mstudioparentconstraint_t &vOther );
|
|
// };
|
|
|
|
|
|
// bones
|
|
struct mstudiobone_t_PS3
|
|
{
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
int sznameindex;
|
|
// inline char * const pszName( void ) const { return ((char *)this) + sznameindex; }
|
|
int parent; // parent bone
|
|
int bonecontroller[6]; // bone controller index, -1 == none
|
|
|
|
// default values
|
|
Vector pos;
|
|
Quaternion quat;
|
|
RadianEuler rot;
|
|
// compression scale
|
|
Vector posscale;
|
|
Vector rotscale;
|
|
|
|
matrix3x4_t poseToBone;
|
|
Quaternion qAlignment;
|
|
int flags;
|
|
int proctype;
|
|
int procindex; // procedural rule
|
|
mutable int physicsbone; // index into physically simulated bone
|
|
// inline void *pProcedure( ) const { if (procindex == 0) return NULL; else return (void *)(((byte *)this) + procindex); };
|
|
int surfacepropidx; // index into string tablefor property name
|
|
// inline char * const pszSurfaceProp( void ) const { return ((char *)this) + surfacepropidx; }
|
|
// inline int GetSurfaceProp( void ) const { return surfacepropLookup; }
|
|
|
|
int contents; // See BSPFlags.h for the contents flags
|
|
int surfacepropLookup; // this index must be cached by the loader, not saved in the file
|
|
int unused[7]; // remove as appropriate
|
|
|
|
mstudiobone_t_PS3(){}
|
|
private:
|
|
// No copy constructors allowed
|
|
mstudiobone_t_PS3(const mstudiobone_t_PS3& vOther);
|
|
};
|
|
|
|
// middle chunk from mstudiobone_t_PS3
|
|
struct mstudiobone_t_PS3_postoqalignment
|
|
{
|
|
Vector pos;
|
|
Quaternion quat;
|
|
RadianEuler rot;
|
|
Vector posscale;
|
|
Vector rotscale;
|
|
matrix3x4_t poseToBone;
|
|
Quaternion qAlignment;
|
|
int flags;
|
|
};
|
|
|
|
|
|
|
|
struct mstudiolinearbone_t_PS3
|
|
{
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
|
|
int numbones;
|
|
|
|
int flagsindex;
|
|
// inline int flags( int i ) const { Assert( i >= 0 && i < numbones); return *((int *)(((byte *)this) + flagsindex) + i); };
|
|
// inline int *pflags( int i ) { Assert( i >= 0 && i < numbones); return ((int *)(((byte *)this) + flagsindex) + i); };
|
|
|
|
int parentindex;
|
|
// inline int parent( int i ) const { Assert( i >= 0 && i < numbones); return *((int *)(((byte *)this) + parentindex) + i); };
|
|
|
|
int posindex;
|
|
// inline const Vector &pos( byte *pEA_this, int i ) const { Assert( i >= 0 && i < numbones); return (Vector *)((pEA_this) + posindex) + i; };
|
|
|
|
int quatindex;
|
|
// inline const Quaternion &quat( int i ) const { Assert( i >= 0 && i < numbones); return *((Quaternion *)((pEA_this) + quatindex) + i); };
|
|
|
|
int rotindex;
|
|
// inline const RadianEuler &rot( int i ) const { Assert( i >= 0 && i < numbones); return *((RadianEuler *)(((byte *)this) + rotindex) + i); };
|
|
|
|
int posetoboneindex;
|
|
// inline const matrix3x4_t &poseToBone( int i ) const { Assert( i >= 0 && i < numbones); return *((matrix3x4_t *)(((byte *)this) + posetoboneindex) + i); };
|
|
|
|
int posscaleindex;
|
|
// inline const Vector &posscale( int i ) const { Assert( i >= 0 && i < numbones); return *((Vector *)(((byte *)this) + posscaleindex) + i); };
|
|
|
|
int rotscaleindex;
|
|
// inline const Vector &rotscale( int i ) const { Assert( i >= 0 && i < numbones); return *((Vector *)(((byte *)this) + rotscaleindex) + i); };
|
|
|
|
int qalignmentindex;
|
|
// inline const Quaternion &qalignment( int i ) const { Assert( i >= 0 && i < numbones); return *((Quaternion *)(((byte *)this) + qalignmentindex) + i); };
|
|
|
|
int unused[6];
|
|
|
|
mstudiolinearbone_t_PS3(){}
|
|
private:
|
|
// No copy constructors allowed
|
|
mstudiolinearbone_t_PS3(const mstudiolinearbone_t_PS3& vOther);
|
|
};
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// The component of the bone used by mstudioboneflexdriver_t
|
|
//-----------------------------------------------------------------------------
|
|
// enum StudioBoneFlexComponent_t
|
|
// {
|
|
// STUDIO_BONE_FLEX_INVALID = -1, // Invalid
|
|
// STUDIO_BONE_FLEX_TX = 0, // Translate X
|
|
// STUDIO_BONE_FLEX_TY = 1, // Translate Y
|
|
// STUDIO_BONE_FLEX_TZ = 2 // Translate Z
|
|
// };
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Component is one of Translate X, Y or Z [0,2] (StudioBoneFlexComponent_t)
|
|
//-----------------------------------------------------------------------------
|
|
// struct mstudioboneflexdrivercontrol_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
//
|
|
// int m_nBoneComponent; // Bone component that drives flex, StudioBoneFlexComponent_t
|
|
// int m_nFlexControllerIndex; // Flex controller to drive
|
|
// float m_flMin; // Min value of bone component mapped to 0 on flex controller
|
|
// float m_flMax; // Max value of bone component mapped to 1 on flex controller
|
|
//
|
|
// mstudioboneflexdrivercontrol_t(){}
|
|
// private:
|
|
// // No copy constructors allowed
|
|
// mstudioboneflexdrivercontrol_t( const mstudioboneflexdrivercontrol_t &vOther );
|
|
// };
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Drive flex controllers from bone components
|
|
//-----------------------------------------------------------------------------
|
|
// struct mstudioboneflexdriver_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
//
|
|
// int m_nBoneIndex; // Bone to drive flex controller
|
|
// int m_nControlCount; // Number of flex controllers being driven
|
|
// int m_nControlIndex; // Index into data where controllers are (relative to this)
|
|
//
|
|
// inline mstudioboneflexdrivercontrol_t *pBoneFlexDriverControl( int i ) const
|
|
// {
|
|
// Assert( i >= 0 && i < m_nControlCount );
|
|
// return (mstudioboneflexdrivercontrol_t *)(((byte *)this) + m_nControlIndex) + i;
|
|
// }
|
|
//
|
|
// int unused[3];
|
|
//
|
|
// mstudioboneflexdriver_t(){}
|
|
// private:
|
|
// // No copy constructors allowed
|
|
// mstudioboneflexdriver_t( const mstudioboneflexdriver_t &vOther );
|
|
// };
|
|
|
|
|
|
// #define BONE_CALCULATE_MASK 0x1F
|
|
// #define BONE_PHYSICALLY_SIMULATED 0x01 // bone is physically simulated when physics are active
|
|
// #define BONE_PHYSICS_PROCEDURAL 0x02 // procedural when physics is active
|
|
// #define BONE_ALWAYS_PROCEDURAL 0x04 // bone is always procedurally animated
|
|
// #define BONE_SCREEN_ALIGN_SPHERE 0x08 // bone aligns to the screen, not constrained in motion.
|
|
// #define BONE_SCREEN_ALIGN_CYLINDER 0x10 // bone aligns to the screen, constrained by it's own axis.
|
|
//
|
|
// #define BONE_USED_MASK 0x0007FF00
|
|
// #define BONE_USED_BY_ANYTHING 0x0007FF00
|
|
// #define BONE_USED_BY_HITBOX 0x00000100 // bone (or child) is used by a hit box
|
|
// #define BONE_USED_BY_ATTACHMENT 0x00000200 // bone (or child) is used by an attachment point
|
|
// #define BONE_USED_BY_VERTEX_MASK 0x0003FC00
|
|
// #define BONE_USED_BY_VERTEX_LOD0 0x00000400 // bone (or child) is used by the toplevel model via skinned vertex
|
|
// #define BONE_USED_BY_VERTEX_LOD1 0x00000800
|
|
// #define BONE_USED_BY_VERTEX_LOD2 0x00001000
|
|
// #define BONE_USED_BY_VERTEX_LOD3 0x00002000
|
|
// #define BONE_USED_BY_VERTEX_LOD4 0x00004000
|
|
// #define BONE_USED_BY_VERTEX_LOD5 0x00008000
|
|
// #define BONE_USED_BY_VERTEX_LOD6 0x00010000
|
|
// #define BONE_USED_BY_VERTEX_LOD7 0x00020000
|
|
// #define BONE_USED_BY_BONE_MERGE 0x00040000 // bone is available for bone merge to occur against it
|
|
//
|
|
// #define BONE_USED_BY_VERTEX_AT_LOD(lod) ( BONE_USED_BY_VERTEX_LOD0 << (lod) )
|
|
// #define BONE_USED_BY_ANYTHING_AT_LOD(lod) ( ( BONE_USED_BY_ANYTHING & ~BONE_USED_BY_VERTEX_MASK ) | BONE_USED_BY_VERTEX_AT_LOD(lod) )
|
|
//
|
|
// #define MAX_NUM_LODS 8
|
|
//
|
|
// #define BONE_TYPE_MASK 0x00F00000
|
|
// #define BONE_FIXED_ALIGNMENT 0x00100000 // bone can't spin 360 degrees, all interpolation is normalized around a fixed orientation
|
|
//
|
|
// #define BONE_HAS_SAVEFRAME_POS 0x00200000 // Vector48
|
|
// #define BONE_HAS_SAVEFRAME_ROT64 0x00400000 // Quaternion64
|
|
// #define BONE_HAS_SAVEFRAME_ROT32 0x00800000 // Quaternion32
|
|
|
|
// bone controllers
|
|
struct mstudiobonecontroller_t_PS3
|
|
{
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
int bone; // -1 == 0
|
|
int type; // X, Y, Z, XR, YR, ZR, M
|
|
float start;
|
|
float end;
|
|
int rest; // byte index value at rest
|
|
int inputfield; // 0-3 user set controller, 4 mouth
|
|
int unused[8];
|
|
};
|
|
|
|
// intersection boxes
|
|
struct mstudiobbox_t_PS3
|
|
{
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
int bone;
|
|
int group; // intersection group
|
|
Vector bbmin; // bounding box
|
|
Vector bbmax;
|
|
int szhitboxnameindex; // offset to the name of the hitbox.
|
|
int unused[8];
|
|
|
|
// const char* pszHitboxName() const
|
|
// {
|
|
// if( szhitboxnameindex == 0 )
|
|
// return "";
|
|
//
|
|
// return ((const char*)this) + szhitboxnameindex;
|
|
// }
|
|
|
|
mstudiobbox_t_PS3() {}
|
|
|
|
private:
|
|
// No copy constructors allowed
|
|
mstudiobbox_t_PS3(const mstudiobbox_t_PS3& vOther);
|
|
};
|
|
|
|
// demand loaded sequence groups
|
|
// struct mstudiomodelgroup_t_PS3
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
// int szlabelindex; // textual name
|
|
// inline char * const pszLabel( void ) const { return ((char *)this) + szlabelindex; }
|
|
// int sznameindex; // file name
|
|
// inline char * const pszName( void ) const { return ((char *)this) + sznameindex; }
|
|
// };
|
|
|
|
// struct mstudiomodelgrouplookup_t
|
|
// {
|
|
// int modelgroup;
|
|
// int indexwithingroup;
|
|
// };
|
|
|
|
// events
|
|
// NOTE: If you modify this struct you MUST also modify mstudioevent_for_client_server_t in npcevent.h!!!
|
|
// struct mstudioevent_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
// float cycle;
|
|
// int event;
|
|
// int type;
|
|
// inline const char * pszOptions( void ) const { return options; }
|
|
// char options[64];
|
|
//
|
|
// int szeventindex;
|
|
// inline char * const pszEventName( void ) const { return ((char *)this) + szeventindex; }
|
|
// };
|
|
|
|
//#define ATTACHMENT_FLAG_WORLD_ALIGN 0x10000
|
|
|
|
// attachment
|
|
struct mstudioattachment_t_PS3
|
|
{
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
int sznameindex;
|
|
// inline char * const pszName( void ) const { return ((char *)this) + sznameindex; }
|
|
unsigned int flags;
|
|
int localbone;
|
|
matrix3x4_t local; // attachment point
|
|
int unused[8];
|
|
};
|
|
|
|
#if defined(__SPU__)
|
|
#define IK_SELF 1
|
|
#define IK_WORLD 2
|
|
#define IK_GROUND 3
|
|
#define IK_RELEASE 4
|
|
#define IK_ATTACHMENT 5
|
|
#define IK_UNLATCH 6
|
|
#endif
|
|
|
|
struct mstudioikerror_t_PS3
|
|
{
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
Vector pos;
|
|
Quaternion q;
|
|
|
|
mstudioikerror_t_PS3() {}
|
|
|
|
private:
|
|
// No copy constructors allowed
|
|
mstudioikerror_t_PS3(const mstudioikerror_t_PS3& vOther);
|
|
};
|
|
|
|
union mstudioanimvalue_t_PS3;
|
|
|
|
struct mstudiocompressedikerror_t_PS3
|
|
{
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
float scale[6];
|
|
short offset[6];
|
|
inline mstudioanimvalue_t_PS3 *pAnimvalue( void *pEA_this, int i ) const { if (offset[i] > 0) return (mstudioanimvalue_t_PS3 *)(((byte *)pEA_this) + offset[i]); else return NULL; };
|
|
|
|
mstudiocompressedikerror_t_PS3(){}
|
|
|
|
private:
|
|
// No copy constructors allowed
|
|
mstudiocompressedikerror_t_PS3(const mstudiocompressedikerror_t_PS3& vOther);
|
|
};
|
|
|
|
struct mstudioikrule_t_PS3
|
|
{
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
int index;
|
|
|
|
int type;
|
|
int chain;
|
|
|
|
int bone;
|
|
|
|
int slot; // iktarget slot. Usually same as chain.
|
|
float height;
|
|
float radius;
|
|
float floor;
|
|
Vector pos;
|
|
Quaternion q;
|
|
|
|
int compressedikerrorindex;
|
|
// inline mstudiocompressedikerror_t *pCompressedError() const { return (mstudiocompressedikerror_t *)(((byte *)this) + compressedikerrorindex); };
|
|
inline mstudiocompressedikerror_t_PS3 *pCompressedError( void *pEA_this ) const { return (mstudiocompressedikerror_t_PS3 *)(((byte *)pEA_this) + compressedikerrorindex); };
|
|
int unused2;
|
|
|
|
int iStart;
|
|
int ikerrorindex;
|
|
// inline mstudioikerror_t *pError( int i ) const { return (ikerrorindex) ? (mstudioikerror_t *)(((byte *)this) + ikerrorindex) + (i - iStart) : NULL; };
|
|
inline mstudioikerror_t_PS3 *pError( void *pEA_this, int i ) const { return (ikerrorindex) ? (mstudioikerror_t_PS3 *)(((byte *)pEA_this) + ikerrorindex) + (i - iStart) : NULL; };
|
|
|
|
float start; // beginning of influence
|
|
float peak; // start of full influence
|
|
float tail; // end of full influence
|
|
float end; // end of all influence
|
|
|
|
float unused3; //
|
|
float contact; // frame footstep makes ground concact
|
|
float drop; // how far down the foot should drop when reaching for IK
|
|
float top; // top of the foot box
|
|
|
|
int unused6;
|
|
int unused7;
|
|
int unused8;
|
|
|
|
int szattachmentindex; // name of world attachment
|
|
// inline char * const pszAttachment( void ) const { return ((char *)this) + szattachmentindex; }
|
|
|
|
int unused[7];
|
|
// int unused[6];
|
|
// void* pEA_this;
|
|
|
|
mstudioikrule_t_PS3() {}
|
|
|
|
private:
|
|
// No copy constructors allowed
|
|
mstudioikrule_t_PS3(const mstudioikrule_t_PS3& vOther);
|
|
};
|
|
|
|
|
|
struct mstudioikrulezeroframe_t_PS3
|
|
{
|
|
short chain;
|
|
short slot;
|
|
float16 start; // beginning of influence
|
|
float16 peak; // start of full influence
|
|
float16 tail; // end of full influence
|
|
float16 end; // end of all influence
|
|
};
|
|
|
|
|
|
struct mstudioiklock_t_PS3
|
|
{
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
int chain;
|
|
float flPosWeight;
|
|
float flLocalQWeight;
|
|
int flags;
|
|
|
|
int unused[4];
|
|
};
|
|
|
|
|
|
// struct mstudiolocalhierarchy_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
// int iBone; // bone being adjusted
|
|
// int iNewParent; // the bones new parent
|
|
//
|
|
// float start; // beginning of influence
|
|
// float peak; // start of full influence
|
|
// float tail; // end of full influence
|
|
// float end; // end of all influence
|
|
//
|
|
// int iStart; // first frame
|
|
//
|
|
// int localanimindex;
|
|
// inline mstudiocompressedikerror_t *pLocalAnim() const { return (mstudiocompressedikerror_t *)(((byte *)this) + localanimindex); };
|
|
//
|
|
// int unused[4];
|
|
// };
|
|
|
|
|
|
|
|
// animation frames
|
|
union mstudioanimvalue_t_PS3
|
|
{
|
|
struct
|
|
{
|
|
byte valid;
|
|
byte total;
|
|
} num;
|
|
short value;
|
|
};
|
|
|
|
struct mstudioanim_valueptr_t_PS3
|
|
{
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
short offset[3];
|
|
inline mstudioanimvalue_t_PS3 *pAnimvalue( void *pEA_this, int i ) const { if (offset[i] > 0) return (mstudioanimvalue_t_PS3 *)(((byte *)pEA_this) + offset[i]); else return NULL; };
|
|
};
|
|
|
|
#if defined(__SPU__)
|
|
#define STUDIO_ANIM_RAWPOS 0x01 // Vector48
|
|
#define STUDIO_ANIM_RAWROT 0x02 // Quaternion48
|
|
#define STUDIO_ANIM_ANIMPOS 0x04 // mstudioanim_valueptr_t
|
|
#define STUDIO_ANIM_ANIMROT 0x08 // mstudioanim_valueptr_t
|
|
#define STUDIO_ANIM_DELTA 0x10
|
|
#define STUDIO_ANIM_RAWROT2 0x20 // Quaternion64
|
|
#endif
|
|
|
|
// per bone per animation DOF and weight pointers, RLE encoded
|
|
struct mstudio_rle_anim_t_PS3
|
|
{
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
byte bone;
|
|
byte flags; // weighing options
|
|
|
|
// valid for animating data only
|
|
inline byte *pData( void *pEA_this ) const { return (((byte *)pEA_this) + sizeof( struct mstudio_rle_anim_t_PS3 )); };
|
|
inline mstudioanim_valueptr_t_PS3 *pRotV( void *pEA_this ) const { return (mstudioanim_valueptr_t_PS3 *)(pData( pEA_this )); };
|
|
inline mstudioanim_valueptr_t_PS3 *pPosV( void *pEA_this ) const { return (mstudioanim_valueptr_t_PS3 *)(pData( pEA_this )) + ((flags & STUDIO_ANIM_ANIMROT) != 0); };
|
|
|
|
// valid if animation unvaring over timeline
|
|
inline Quaternion48 *pQuat48( void *pEA_this ) const { return (Quaternion48 *)(pData( pEA_this )); };
|
|
inline Quaternion64 *pQuat64( void *pEA_this ) const { return (Quaternion64 *)(pData( pEA_this )); };
|
|
inline Vector48 *pPos( void *pEA_this ) const { return (Vector48 *)(pData( pEA_this ) + ((flags & STUDIO_ANIM_RAWROT) != 0) * sizeof( *pQuat48( pEA_this ) ) + ((flags & STUDIO_ANIM_RAWROT2) != 0) * sizeof( *pQuat64( pEA_this ) ) ); };
|
|
// inline Vector48 *pPos( void *pEA_this ) const { return (Vector48 *)(pData( pEA_this ) + ((flags & STUDIO_ANIM_RAWROT) != 0) * sizeof( Quaternion48 ) + ((flags & STUDIO_ANIM_RAWROT2) != 0) * sizeof( Quaternion64 ) ); };
|
|
|
|
// points to next bone in the list
|
|
short nextoffset;
|
|
inline mstudio_rle_anim_t_PS3 *pNext( void *pEA_this ) const { if (nextoffset != 0) return (mstudio_rle_anim_t_PS3 *)(((byte *)pEA_this) + nextoffset); else return NULL; };
|
|
};
|
|
|
|
|
|
// #define STUDIO_FRAME_CONST_POS 0x01 // Vector48 in constants
|
|
// #define STUDIO_FRAME_CONST_ROT 0x02 // Quaternion48 in constants
|
|
// #define STUDIO_FRAME_ANIM_POS 0x04 // Vector48 in framedata
|
|
// #define STUDIO_FRAME_ANIM_ROT 0x08 // Quaternion48 in framedata
|
|
// #define STUDIO_FRAME_ANIM_POS2 0x10 // Vector in framedata
|
|
// #define STUDIO_FRAME_CONST_POS2 0x20 // Vector in constants
|
|
// #define STUDIO_FRAME_CONST_ROT2 0x40 // Quaternion48S in constants
|
|
// #define STUDIO_FRAME_ANIM_ROT2 0x80 // Quaternion48S in framedata
|
|
|
|
struct mstudio_frame_anim_t_PS3
|
|
{
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
|
|
inline byte *pBoneFlags( void *pEA_this ) const { return (((byte *)pEA_this) + sizeof( struct mstudio_frame_anim_t_PS3 )); };
|
|
|
|
int constantsoffset;
|
|
inline byte *pConstantData( void *pEA_this ) const { return (((byte *)pEA_this) + constantsoffset); };
|
|
|
|
int frameoffset;
|
|
int framelength;
|
|
inline byte *pFrameData( void *pEA_this, int iFrame ) const { return (((byte *)pEA_this) + frameoffset + iFrame * framelength); };
|
|
|
|
int unused[3];
|
|
};
|
|
|
|
|
|
|
|
// struct mstudiomovement_t_PS3
|
|
// {
|
|
// // DECLARE_BYTESWAP_DATADESC();
|
|
// int endframe;
|
|
// int motionflags;
|
|
// float v0; // velocity at start of block
|
|
// float v1; // velocity at end of block
|
|
// float angle; // YAW rotation at end of this blocks movement
|
|
// Vector vector; // movement vector relative to this blocks initial angle
|
|
// Vector position; // relative to start of animation???
|
|
//
|
|
// mstudiomovement_t_PS3(){}
|
|
// private:
|
|
// // No copy constructors allowed
|
|
// mstudiomovement_t_PS3(const mstudiomovement_t_PS3& vOther);
|
|
// };
|
|
|
|
|
|
// used for piecewise loading of animation data
|
|
struct mstudioanimblock_t_PS3
|
|
{
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
int datastart;
|
|
int dataend;
|
|
};
|
|
|
|
struct mstudioanimsections_t_PS3
|
|
{
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
int animblock;
|
|
int animindex;
|
|
};
|
|
|
|
struct mstudioanimdesc_t_PS3
|
|
{
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
int baseptr;
|
|
// inline studiohdr_t *pStudiohdr( void ) const { return (studiohdr_t *)(((byte *)this) + baseptr); }
|
|
// inline studiohdr_t *pStudiohdr( void *pEA_this ) const { return (studiohdr_t *)(((byte *)pEA_this) + baseptr); }
|
|
|
|
int sznameindex;
|
|
// inline char * const pszName( void ) const { return ((char *)this) + sznameindex; }
|
|
inline char * const pszName( void *pEA_this ) const { return ((char *)pEA_this) + sznameindex; }
|
|
|
|
float fps; // frames per second
|
|
int flags; // looping/non-looping flags
|
|
|
|
int numframes;
|
|
|
|
// piecewise movement
|
|
int nummovements;
|
|
int movementindex;
|
|
// inline mstudiomovement_t * const pMovement( int i ) const { return (mstudiomovement_t *)(((byte *)this) + movementindex) + i; };
|
|
// inline mstudiomovement_t * const pMovement( void *pEA_this, int i ) const { return (mstudiomovement_t *)(((byte *)pEA_this) + movementindex) + i; };
|
|
|
|
int ikrulezeroframeindex;
|
|
// mstudioikrulezeroframe_t *pIKRuleZeroFrame( int i ) const { if (ikrulezeroframeindex) return (mstudioikrulezeroframe_t *)(((byte *)this) + ikrulezeroframeindex) + i; else return NULL; };
|
|
// mstudioikrulezeroframe_t *pIKRuleZeroFrame( void *pEA_this, int i ) const { if (ikrulezeroframeindex) return (mstudioikrulezeroframe_t *)(((byte *)pEA_this) + ikrulezeroframeindex) + i; else return NULL; };
|
|
|
|
int unused1[5]; // remove as appropriate (and zero if loading older versions)
|
|
|
|
int animblock;
|
|
int animindex; // non-zero when anim data isn't in sections
|
|
// byte *pAnimBlock( int block, int index, bool preloadIfMissing = true) const; // returns pointer to a specific anim block (local or external)
|
|
// bool hasAnimBlockBeenPreloaded( int block ) const;
|
|
// byte *pAnim( int *piFrame, float &flStall ) const; // returns pointer to data and new frame index
|
|
// byte *pAnim( int *piFrame ) const; // returns pointer to data and new frame index
|
|
|
|
int numikrules;
|
|
int ikruleindex; // non-zero when IK rule is stored in the mdl
|
|
int animblockikruleindex; // non-zero when IK data is stored in animblock file
|
|
// mstudioikrule_t *pIKRule( int i ) const;
|
|
|
|
int numlocalhierarchy;
|
|
int localhierarchyindex;
|
|
// mstudiolocalhierarchy_t *pHierarchy( int i ) const;
|
|
|
|
int sectionindex;
|
|
int sectionframes; // number of frames used in each fast lookup section, zero if not used
|
|
// inline mstudioanimsections_t * const pSection( int i ) const { return (mstudioanimsections_t *)(((byte *)this) + sectionindex) + i; }
|
|
// inline mstudioanimsections_t * const pSection( void *pEA_this, int i ) const { return (mstudioanimsections_t *)(((byte *)pEA_this) + sectionindex) + i; }
|
|
|
|
short zeroframespan; // frames per span
|
|
short zeroframecount; // number of spans
|
|
int zeroframeindex;
|
|
// byte *pZeroFrameData( ) const { if (zeroframeindex) return (((byte *)this) + zeroframeindex); else return NULL; };
|
|
byte *pZeroFrameData( void *pEA_this ) const { if (zeroframeindex) return (((byte *)pEA_this) + zeroframeindex); else return NULL; };
|
|
mutable float zeroframestalltime; // saved during read stalls
|
|
|
|
mstudioanimdesc_t_PS3(){}
|
|
private:
|
|
// No copy constructors allowed
|
|
mstudioanimdesc_t_PS3(const mstudioanimdesc_t_PS3& vOther);
|
|
};
|
|
|
|
struct mstudioikrule_t_PS3;
|
|
|
|
struct mstudioautolayer_t_PS3
|
|
{
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
//private:
|
|
short iSequence;
|
|
short iPose;
|
|
//public:
|
|
int flags;
|
|
float start; // beginning of influence
|
|
float peak; // start of full influence
|
|
float tail; // end of full influence
|
|
float end; // end of all influence
|
|
};
|
|
|
|
// struct mstudioactivitymodifier_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
//
|
|
// int sznameindex;
|
|
// inline char *pszName() { return (sznameindex) ? (char *)(((byte *)this) + sznameindex ) : NULL; }
|
|
// };
|
|
|
|
// sequence descriptions
|
|
struct mstudioseqdesc_t_PS3
|
|
{
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
int baseptr;
|
|
// inline studiohdr_t *pStudiohdr( void *pEA_this ) const { return (studiohdr_t *)(((byte *)pEA_this) + baseptr); }
|
|
|
|
int szlabelindex;
|
|
// inline char * const pszLabel( void *pEA_this ) const { return ((char *)pEA_this) + szlabelindex; }
|
|
|
|
int szactivitynameindex;
|
|
// inline char * const pszActivityName( void ) const { return ((char *)this) + szactivitynameindex; }
|
|
// inline char * const pszActivityName( void ) const { return pEA_this + szactivitynameindex; }
|
|
|
|
int flags; // looping/non-looping flags
|
|
|
|
int activity; // initialized at loadtime to game DLL values
|
|
int actweight;
|
|
|
|
int numevents;
|
|
int eventindex;
|
|
// inline mstudioevent_t *pEvent( int i ) const { Assert( i >= 0 && i < numevents); return (mstudioevent_t *)(((byte *)this) + eventindex) + i; };
|
|
// inline mstudioevent_t *pEvent( int i ) const { Assert( i >= 0 && i < numevents); return (mstudioevent_t *)(pEA_this + eventindex) + i; };
|
|
|
|
Vector bbmin; // per sequence bounding box
|
|
Vector bbmax;
|
|
|
|
int numblends;
|
|
|
|
// Index into array of shorts which is groupsize[0] x groupsize[1] in length
|
|
int animindexindex;
|
|
|
|
inline int anim( void *pEA_this, int x, int y ) const
|
|
{
|
|
if ( x >= groupsize[0] )
|
|
{
|
|
x = groupsize[0] - 1;
|
|
}
|
|
|
|
if ( y >= groupsize[1] )
|
|
{
|
|
y = groupsize[ 1 ] - 1;
|
|
}
|
|
|
|
int offset = y * groupsize[0] + x;
|
|
short *blends = (short *)(((byte *)pEA_this) + animindexindex);
|
|
int value = (int)blends[ offset ];
|
|
return value;
|
|
}
|
|
|
|
int movementindex; // [blend] float array for blended movement
|
|
int groupsize[2];
|
|
int paramindex[2]; // X, Y, Z, XR, YR, ZR
|
|
float paramstart[2]; // local (0..1) starting value
|
|
float paramend[2]; // local (0..1) ending value
|
|
int paramparent;
|
|
|
|
float fadeintime; // ideal cross fate in time (0.2 default)
|
|
float fadeouttime; // ideal cross fade out time (0.2 default)
|
|
|
|
int localentrynode; // transition node at entry
|
|
int localexitnode; // transition node at exit
|
|
int nodeflags; // transition rules
|
|
|
|
float entryphase; // used to match entry gait
|
|
float exitphase; // used to match exit gait
|
|
|
|
float lastframe; // frame that should generation EndOfSequence
|
|
|
|
int nextseq; // auto advancing sequences
|
|
int pose; // index of delta animation between end and nextseq
|
|
|
|
int numikrules;
|
|
|
|
int numautolayers; //
|
|
int autolayerindex;
|
|
// inline mstudioautolayer_t *pAutolayer( int i ) const { Assert( i >= 0 && i < numautolayers); return (mstudioautolayer_t *)(((byte *)this) + autolayerindex) + i; };
|
|
// inline mstudioautolayer_t *pAutolayer( int i ) const { Assert( i >= 0 && i < numautolayers); return (mstudioautolayer_t *)(pEA_this + autolayerindex) + i; };
|
|
|
|
int weightlistindex;
|
|
inline float *pBoneweight( void *pEA_this, int i ) const { return ((float *)(((byte *)pEA_this) + weightlistindex) + i); };
|
|
inline float weight( void *pEA_this, int i ) const { return *(pBoneweight( pEA_this, i )); };
|
|
|
|
// FIXME: make this 2D instead of 2x1D arrays
|
|
int posekeyindex;
|
|
// float *pPoseKey( int iParam, int iAnim ) const { return (float *)(((byte *)this) + posekeyindex) + iParam * groupsize[0] + iAnim; }
|
|
// float poseKey( int iParam, int iAnim ) const { return *(pPoseKey( iParam, iAnim )); }
|
|
|
|
int numiklocks;
|
|
int iklockindex;
|
|
inline mstudioiklock_t_PS3 *pIKLock( void *pEA_this, int i ) const { Assert( i >= 0 && i < numiklocks); return (mstudioiklock_t_PS3 *)(((byte *)pEA_this) + iklockindex) + i; };
|
|
|
|
// Key values
|
|
int keyvalueindex;
|
|
int keyvaluesize;
|
|
// inline const char * KeyValueText( void ) const { return keyvaluesize != 0 ? ((char *)this) + keyvalueindex : NULL; }
|
|
|
|
int cycleposeindex; // index of pose parameter to use as cycle index
|
|
|
|
int activitymodifierindex;
|
|
int numactivitymodifiers;
|
|
// inline mstudioactivitymodifier_t *pActivityModifier( int i ) const { Assert( i >= 0 && i < numactivitymodifiers); return activitymodifierindex != 0 ? (mstudioactivitymodifier_t *)(((byte *)this) + activitymodifierindex) + i : NULL; };
|
|
|
|
int unused[5]; // remove/add as appropriate (grow back to 8 ints on version change!)
|
|
|
|
mstudioseqdesc_t_PS3(){}
|
|
|
|
private:
|
|
// No copy constructors allowed
|
|
mstudioseqdesc_t_PS3(const mstudioseqdesc_t_PS3& vOther);
|
|
};
|
|
|
|
|
|
struct mstudioposeparamdesc_t_PS3
|
|
{
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
int sznameindex;
|
|
// inline char * const pszName( void ) const { return ((char *)this) + sznameindex; }
|
|
int flags; // ????
|
|
float start; // starting value
|
|
float end; // ending value
|
|
float loop; // looping range, 0 for no looping, 360 for rotations, etc.
|
|
};
|
|
|
|
// struct mstudioflexdesc_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
// int szFACSindex;
|
|
// inline char * const pszFACS( void ) const { return ((char *)this) + szFACSindex; }
|
|
// };
|
|
|
|
|
|
|
|
// struct mstudioflexcontroller_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
// int sztypeindex;
|
|
// inline char * const pszType( void ) const { return ((char *)this) + sztypeindex; }
|
|
// int sznameindex;
|
|
// inline char * const pszName( void ) const { return ((char *)this) + sznameindex; }
|
|
// mutable int localToGlobal; // remapped at load time to master list
|
|
// float min;
|
|
// float max;
|
|
// };
|
|
|
|
|
|
// enum FlexControllerRemapType_t
|
|
// {
|
|
// FLEXCONTROLLER_REMAP_PASSTHRU = 0,
|
|
// FLEXCONTROLLER_REMAP_2WAY, // Control 0 -> ramps from 1-0 from 0->0.5. Control 1 -> ramps from 0-1 from 0.5->1
|
|
// FLEXCONTROLLER_REMAP_NWAY, // StepSize = 1 / (control count-1) Control n -> ramps from 0-1-0 from (n-1)*StepSize to n*StepSize to (n+1)*StepSize. A second control is needed to specify amount to use
|
|
// FLEXCONTROLLER_REMAP_EYELID
|
|
// };
|
|
|
|
|
|
//class CStudioHdr_PS3;
|
|
|
|
// struct mstudioflexcontrollerui_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
// int sznameindex;
|
|
// inline char * const pszName( void ) const { return ((char *)this) + sznameindex; }
|
|
//
|
|
// // These are used like a union to save space
|
|
// // Here are the possible configurations for a UI controller
|
|
// //
|
|
// // SIMPLE NON-STEREO: 0: control 1: unused 2: unused
|
|
// // STEREO: 0: left 1: right 2: unused
|
|
// // NWAY NON-STEREO: 0: control 1: unused 2: value
|
|
// // NWAY STEREO: 0: left 1: right 2: value
|
|
//
|
|
// int szindex0;
|
|
// int szindex1;
|
|
// int szindex2;
|
|
//
|
|
// inline const mstudioflexcontroller_t *pController( void ) const
|
|
// {
|
|
// return !stereo ? (mstudioflexcontroller_t *)( (char *)this + szindex0 ) : NULL;
|
|
// }
|
|
// inline char * const pszControllerName( void ) const { return !stereo ? pController()->pszName() : NULL; }
|
|
// inline int controllerIndex( const CStudioHdr &cStudioHdr ) const;
|
|
//
|
|
// inline const mstudioflexcontroller_t *pLeftController( void ) const
|
|
// {
|
|
// return stereo ? (mstudioflexcontroller_t *)( (char *)this + szindex0 ) : NULL;
|
|
// }
|
|
// inline char * const pszLeftName( void ) const { return stereo ? pLeftController()->pszName() : NULL; }
|
|
// inline int leftIndex( const CStudioHdr &cStudioHdr ) const;
|
|
//
|
|
// inline const mstudioflexcontroller_t *pRightController( void ) const
|
|
// {
|
|
// return stereo ? (mstudioflexcontroller_t *)( (char *)this + szindex1 ): NULL;
|
|
// }
|
|
// inline char * const pszRightName( void ) const { return stereo ? pRightController()->pszName() : NULL; }
|
|
// inline int rightIndex( const CStudioHdr &cStudioHdr ) const;
|
|
//
|
|
// inline const mstudioflexcontroller_t *pNWayValueController( void ) const
|
|
// {
|
|
// return remaptype == FLEXCONTROLLER_REMAP_NWAY ? (mstudioflexcontroller_t *)( (char *)this + szindex2 ) : NULL;
|
|
// }
|
|
// inline char * const pszNWayValueName( void ) const { return remaptype == FLEXCONTROLLER_REMAP_NWAY ? pNWayValueController()->pszName() : NULL; }
|
|
// inline int nWayValueIndex( const CStudioHdr &cStudioHdr ) const;
|
|
//
|
|
// // Number of controllers this ui description contains, 1, 2 or 3
|
|
// inline int Count() const { return ( stereo ? 2 : 1 ) + ( remaptype == FLEXCONTROLLER_REMAP_NWAY ? 1 : 0 ); }
|
|
// inline const mstudioflexcontroller_t *pController( int index ) const;
|
|
//
|
|
// unsigned char remaptype; // See the FlexControllerRemapType_t enum
|
|
// bool stereo; // Is this a stereo control?
|
|
// byte unused[2];
|
|
// };
|
|
|
|
|
|
// this is the memory image of vertex anims (16-bit fixed point)
|
|
// struct mstudiovertanim_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
// unsigned short index;
|
|
// byte speed; // 255/max_length_in_flex
|
|
// byte side; // 255/left_right
|
|
//
|
|
// protected:
|
|
// union
|
|
// {
|
|
// short delta[3];
|
|
// float16 flDelta[3];
|
|
// };
|
|
//
|
|
// union
|
|
// {
|
|
// short ndelta[3];
|
|
// float16 flNDelta[3];
|
|
// };
|
|
//
|
|
// public:
|
|
// inline void ConvertToFixed( float flVertAnimFixedPointScale )
|
|
// {
|
|
// delta[0] = ( short )( flDelta[0].GetFloat() / flVertAnimFixedPointScale );
|
|
// delta[1] = ( short )( flDelta[1].GetFloat() / flVertAnimFixedPointScale );
|
|
// delta[2] = ( short )( flDelta[2].GetFloat() / flVertAnimFixedPointScale );
|
|
// ndelta[0] = ( short )( flNDelta[0].GetFloat() / flVertAnimFixedPointScale );
|
|
// ndelta[1] = ( short )( flNDelta[1].GetFloat() / flVertAnimFixedPointScale );
|
|
// ndelta[2] = ( short )( flNDelta[2].GetFloat() / flVertAnimFixedPointScale );
|
|
// }
|
|
//
|
|
// inline Vector GetDeltaFixed( float flVertAnimFixedPointScale )
|
|
// {
|
|
// return Vector( delta[0] * flVertAnimFixedPointScale, delta[1] * flVertAnimFixedPointScale, delta[2] * flVertAnimFixedPointScale );
|
|
// }
|
|
// inline Vector GetNDeltaFixed( float flVertAnimFixedPointScale )
|
|
// {
|
|
// return Vector( ndelta[0] * flVertAnimFixedPointScale, ndelta[1] * flVertAnimFixedPointScale, ndelta[2] * flVertAnimFixedPointScale );
|
|
// }
|
|
// inline void GetDeltaFixed4DAligned( Vector4DAligned *vFillIn, float flVertAnimFixedPointScale )
|
|
// {
|
|
// vFillIn->Set( delta[0] * flVertAnimFixedPointScale, delta[1] * flVertAnimFixedPointScale, delta[2] * flVertAnimFixedPointScale, 0.0f );
|
|
// }
|
|
// inline void GetNDeltaFixed4DAligned( Vector4DAligned *vFillIn, float flVertAnimFixedPointScale )
|
|
// {
|
|
// vFillIn->Set( ndelta[0] * flVertAnimFixedPointScale, ndelta[1] * flVertAnimFixedPointScale, ndelta[2] * flVertAnimFixedPointScale, 0.0f );
|
|
// }
|
|
// inline Vector GetDeltaFloat()
|
|
// {
|
|
// return Vector (flDelta[0].GetFloat(), flDelta[1].GetFloat(), flDelta[2].GetFloat());
|
|
// }
|
|
// inline Vector GetNDeltaFloat()
|
|
// {
|
|
// return Vector (flNDelta[0].GetFloat(), flNDelta[1].GetFloat(), flNDelta[2].GetFloat());
|
|
// }
|
|
// inline void SetDeltaFixed( const Vector& vInput, float flVertAnimFixedPointScale )
|
|
// {
|
|
// delta[0] = ( short )( vInput.x / flVertAnimFixedPointScale );
|
|
// delta[1] = ( short )( vInput.y / flVertAnimFixedPointScale );
|
|
// delta[2] = ( short )( vInput.z / flVertAnimFixedPointScale );
|
|
// }
|
|
// inline void SetNDeltaFixed( const Vector& vInputNormal, float flVertAnimFixedPointScale )
|
|
// {
|
|
// ndelta[0] = ( short )( vInputNormal.x / flVertAnimFixedPointScale );
|
|
// ndelta[1] = ( short )( vInputNormal.y / flVertAnimFixedPointScale );
|
|
// ndelta[2] = ( short )( vInputNormal.z / flVertAnimFixedPointScale );
|
|
// }
|
|
//
|
|
// // Ick...can also force fp16 data into this structure for writing to file in legacy format...
|
|
// inline void SetDeltaFloat( const Vector& vInput )
|
|
// {
|
|
// flDelta[0].SetFloat( vInput.x );
|
|
// flDelta[1].SetFloat( vInput.y );
|
|
// flDelta[2].SetFloat( vInput.z );
|
|
// }
|
|
// inline void SetNDeltaFloat( const Vector& vInputNormal )
|
|
// {
|
|
// flNDelta[0].SetFloat( vInputNormal.x );
|
|
// flNDelta[1].SetFloat( vInputNormal.y );
|
|
// flNDelta[2].SetFloat( vInputNormal.z );
|
|
// }
|
|
//
|
|
// class CSortByIndex
|
|
// {
|
|
// public:
|
|
// bool operator()(const mstudiovertanim_t &left, const mstudiovertanim_t & right)const
|
|
// {
|
|
// return left.index < right.index;
|
|
// }
|
|
// };
|
|
// friend class CSortByIndex;
|
|
//
|
|
// mstudiovertanim_t(){}
|
|
// //private:
|
|
// // No copy constructors allowed, but it's needed for std::sort()
|
|
// // mstudiovertanim_t(const mstudiovertanim_t& vOther);
|
|
// };
|
|
|
|
|
|
// this is the memory image of vertex anims (16-bit fixed point)
|
|
// struct mstudiovertanim_wrinkle_t : public mstudiovertanim_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
//
|
|
// short wrinkledelta;
|
|
//
|
|
// inline void SetWrinkleFixed( float flWrinkle, float flVertAnimFixedPointScale )
|
|
// {
|
|
// int nWrinkleDeltaInt = ( int )( flWrinkle / flVertAnimFixedPointScale );
|
|
// wrinkledelta = clamp( nWrinkleDeltaInt, -32767, 32767 );
|
|
// }
|
|
//
|
|
// inline Vector4D GetDeltaFixed( float flVertAnimFixedPointScale )
|
|
// {
|
|
// return Vector4D( delta[0] * flVertAnimFixedPointScale, delta[1] * flVertAnimFixedPointScale, delta[2] * flVertAnimFixedPointScale, wrinkledelta * flVertAnimFixedPointScale );
|
|
// }
|
|
//
|
|
// inline void GetDeltaFixed4DAligned( Vector4DAligned *vFillIn, float flVertAnimFixedPointScale )
|
|
// {
|
|
// vFillIn->Set( delta[0] * flVertAnimFixedPointScale, delta[1] * flVertAnimFixedPointScale, delta[2] * flVertAnimFixedPointScale, wrinkledelta * flVertAnimFixedPointScale );
|
|
// }
|
|
//
|
|
// inline float GetWrinkleDeltaFixed( float flVertAnimFixedPointScale )
|
|
// {
|
|
// return wrinkledelta * flVertAnimFixedPointScale;
|
|
// }
|
|
// };
|
|
|
|
|
|
// enum StudioVertAnimType_t
|
|
// {
|
|
// STUDIO_VERT_ANIM_NORMAL = 0,
|
|
// STUDIO_VERT_ANIM_WRINKLE,
|
|
// };
|
|
|
|
|
|
// struct mstudioflex_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
// int flexdesc; // input value
|
|
//
|
|
// float target0; // zero
|
|
// float target1; // one
|
|
// float target2; // one
|
|
// float target3; // zero
|
|
//
|
|
// int numverts;
|
|
// int vertindex;
|
|
//
|
|
// inline mstudiovertanim_t *pVertanim( int i ) const { Assert( vertanimtype == STUDIO_VERT_ANIM_NORMAL ); return (mstudiovertanim_t *)(((byte *)this) + vertindex) + i; };
|
|
// inline mstudiovertanim_wrinkle_t *pVertanimWrinkle( int i ) const { Assert( vertanimtype == STUDIO_VERT_ANIM_WRINKLE ); return (mstudiovertanim_wrinkle_t *)(((byte *)this) + vertindex) + i; };
|
|
//
|
|
// inline byte *pBaseVertanim( ) const { return ((byte *)this) + vertindex; };
|
|
// inline int VertAnimSizeBytes() const { return ( vertanimtype == STUDIO_VERT_ANIM_NORMAL ) ? sizeof(mstudiovertanim_t) : sizeof(mstudiovertanim_wrinkle_t); }
|
|
//
|
|
// int flexpair; // second flex desc
|
|
// unsigned char vertanimtype; // See StudioVertAnimType_t
|
|
// unsigned char unusedchar[3];
|
|
// int unused[6];
|
|
//
|
|
// };
|
|
|
|
|
|
// struct mstudioflexop_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
// int op;
|
|
// union
|
|
// {
|
|
// int index;
|
|
// float value;
|
|
// } d;
|
|
// };
|
|
|
|
// struct mstudioflexrule_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
// int flex;
|
|
// int numops;
|
|
// int opindex;
|
|
// inline mstudioflexop_t *iFlexOp( int i ) const { return (mstudioflexop_t *)(((byte *)this) + opindex) + i; };
|
|
// };
|
|
|
|
// 16 bytes
|
|
// struct mstudioboneweight_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
// float weight[MAX_NUM_BONES_PER_VERT];
|
|
// byte bone[MAX_NUM_BONES_PER_VERT];
|
|
// byte numbones;
|
|
//
|
|
// // byte material;
|
|
// // short firstref;
|
|
// // short lastref;
|
|
// };
|
|
|
|
// NOTE: This is exactly 48 bytes
|
|
// struct mstudiovertex_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
// mstudioboneweight_t m_BoneWeights;
|
|
// Vector m_vecPosition;
|
|
// Vector m_vecNormal;
|
|
// Vector2D m_vecTexCoord;
|
|
//
|
|
// mstudiovertex_t() {}
|
|
//
|
|
// private:
|
|
// // No copy constructors allowed
|
|
// mstudiovertex_t(const mstudiovertex_t& vOther);
|
|
// };
|
|
|
|
// skin info
|
|
// struct mstudiotexture_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
// int sznameindex;
|
|
// inline char * const pszName( void ) const { return ((char *)this) + sznameindex; }
|
|
// int flags;
|
|
// int used;
|
|
// int unused1;
|
|
// mutable IMaterial *material; // fixme: this needs to go away . .isn't used by the engine, but is used by studiomdl
|
|
// mutable void *clientmaterial; // gary, replace with client material pointer if used
|
|
//
|
|
// int unused[10];
|
|
// };
|
|
|
|
// eyeball
|
|
// struct mstudioeyeball_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
// int sznameindex;
|
|
// inline char * const pszName( void ) const { return ((char *)this) + sznameindex; }
|
|
// int bone;
|
|
// Vector org;
|
|
// float zoffset;
|
|
// float radius;
|
|
// Vector up;
|
|
// Vector forward;
|
|
// int texture;
|
|
//
|
|
// int unused1;
|
|
// float iris_scale;
|
|
// int unused2;
|
|
//
|
|
// int upperflexdesc[3]; // index of raiser, neutral, and lowerer flexdesc that is set by flex controllers
|
|
// int lowerflexdesc[3];
|
|
// float uppertarget[3]; // angle (radians) of raised, neutral, and lowered lid positions
|
|
// float lowertarget[3];
|
|
//
|
|
// int upperlidflexdesc; // index of flex desc that actual lid flexes look to
|
|
// int lowerlidflexdesc;
|
|
// int unused[4]; // These were used before, so not guaranteed to be 0
|
|
// bool m_bNonFACS; // Never used before version 44
|
|
// char unused3[3];
|
|
// int unused4[7];
|
|
//
|
|
// mstudioeyeball_t(){}
|
|
// private:
|
|
// // No copy constructors allowed
|
|
// mstudioeyeball_t(const mstudioeyeball_t& vOther);
|
|
// };
|
|
|
|
|
|
// ikinfo
|
|
struct mstudioiklink_t_PS3
|
|
{
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
int bone;
|
|
Vector kneeDir; // ideal bending direction (per link, if applicable)
|
|
Vector unused0; // unused
|
|
|
|
mstudioiklink_t_PS3(){}
|
|
private:
|
|
// No copy constructors allowed
|
|
mstudioiklink_t_PS3(const mstudioiklink_t_PS3& vOther);
|
|
};
|
|
|
|
struct mstudioikchain_t_PS3
|
|
{
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
int sznameindex;
|
|
// inline char * const pszName( void ) const { return ((char *)this) + sznameindex; }
|
|
int linktype;
|
|
int numlinks;
|
|
int linkindex;
|
|
inline mstudioiklink_t_PS3 *pLink( void *pEA_this, int i ) const { return (mstudioiklink_t_PS3 *)(((byte *)pEA_this) + linkindex) + i; };
|
|
// FIXME: add unused entries
|
|
};
|
|
|
|
// struct mstudioiface_t
|
|
// {
|
|
// mstudioiface_t()
|
|
// {
|
|
// a = b = c = d = 0xFFFF;
|
|
// }
|
|
//
|
|
// unsigned short a, b, c, d; // Indices to vertices (If d is 0xFFFF, this is a triangle, else it's a quad)
|
|
// };
|
|
|
|
struct mstudiomodel_t_PS3;
|
|
|
|
// struct mstudio_modelvertexdata_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
// Vector *Position( int i ) const;
|
|
// Vector *Normal( int i ) const;
|
|
// Vector4D *TangentS( int i ) const;
|
|
// Vector2D *Texcoord( int i ) const;
|
|
// mstudioboneweight_t *BoneWeights( int i ) const;
|
|
// mstudiovertex_t *Vertex( int i ) const;
|
|
// bool HasTangentData( void ) const;
|
|
// int GetGlobalVertexIndex( int i ) const;
|
|
// int GetGlobalTangentIndex( int i ) const;
|
|
//
|
|
// // base of external vertex data stores
|
|
// const void *pVertexData;
|
|
// const void *pTangentData;
|
|
// };
|
|
|
|
// struct mstudio_meshvertexdata_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
// Vector *Position( int i ) const;
|
|
// Vector *Normal( int i ) const;
|
|
// Vector4D *TangentS( int i ) const;
|
|
// Vector2D *Texcoord( int i ) const;
|
|
// mstudioboneweight_t *BoneWeights( int i ) const;
|
|
// mstudiovertex_t *Vertex( int i ) const;
|
|
// bool HasTangentData( void ) const;
|
|
// int GetModelVertexIndex( int i ) const;
|
|
// int GetGlobalVertexIndex( int i ) const;
|
|
//
|
|
// // indirection to this mesh's model's vertex data
|
|
// const mstudio_modelvertexdata_t *modelvertexdata;
|
|
//
|
|
// // used for fixup calcs when culling top level lods
|
|
// // expected number of mesh verts at desired lod
|
|
// int numLODVertexes[MAX_NUM_LODS];
|
|
// };
|
|
|
|
// struct mstudiomesh_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
// int material;
|
|
//
|
|
// int modelindex;
|
|
// mstudiomodel_t *pModel() const;
|
|
//
|
|
// int numvertices; // number of unique vertices/normals/texcoords
|
|
// int vertexoffset; // vertex mstudiovertex_t
|
|
//
|
|
// // Access thin/fat mesh vertex data (only one will return a non-NULL result)
|
|
// const mstudio_meshvertexdata_t *GetVertexData( void *pModelData = NULL );
|
|
// const thinModelVertices_t *GetThinVertexData( void *pModelData = NULL );
|
|
//
|
|
// int numflexes; // vertex animation
|
|
// int flexindex;
|
|
// inline mstudioflex_t *pFlex( int i ) const { return (mstudioflex_t *)(((byte *)this) + flexindex) + i; };
|
|
//
|
|
// // special codes for material operations
|
|
// int materialtype;
|
|
// int materialparam;
|
|
//
|
|
// // a unique ordinal for this mesh
|
|
// int meshid;
|
|
//
|
|
// Vector center;
|
|
//
|
|
// mstudio_meshvertexdata_t vertexdata;
|
|
//
|
|
// int unused[8]; // remove as appropriate
|
|
//
|
|
// mstudiomesh_t(){}
|
|
// private:
|
|
// // No copy constructors allowed
|
|
// mstudiomesh_t(const mstudiomesh_t& vOther);
|
|
// };
|
|
|
|
// studio models
|
|
// struct mstudiomodel_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
// inline const char * pszName( void ) const { return name; }
|
|
// char name[64];
|
|
//
|
|
// int type;
|
|
//
|
|
// float boundingradius;
|
|
//
|
|
// int nummeshes;
|
|
// int meshindex;
|
|
// inline mstudiomesh_t *pMesh( int i ) const { return (mstudiomesh_t *)(((byte *)this) + meshindex) + i; };
|
|
//
|
|
// // cache purposes
|
|
// int numvertices; // number of unique vertices/normals/texcoords
|
|
// int vertexindex; // vertex Vector
|
|
// int tangentsindex; // tangents Vector
|
|
//
|
|
// // These functions are defined in application-specific code:
|
|
// const vertexFileHeader_t *CacheVertexData( void *pModelData );
|
|
//
|
|
// // Access thin/fat mesh vertex data (only one will return a non-NULL result)
|
|
// const mstudio_modelvertexdata_t *GetVertexData( void *pModelData = NULL );
|
|
// const thinModelVertices_t *GetThinVertexData( void *pModelData = NULL );
|
|
//
|
|
// int numattachments;
|
|
// int attachmentindex;
|
|
//
|
|
// int numeyeballs;
|
|
// int eyeballindex;
|
|
// inline mstudioeyeball_t *pEyeball( int i ) { return (mstudioeyeball_t *)(((byte *)this) + eyeballindex) + i; };
|
|
//
|
|
// mstudio_modelvertexdata_t vertexdata;
|
|
//
|
|
// int unused[8]; // remove as appropriate
|
|
// };
|
|
|
|
// inline bool mstudio_modelvertexdata_t::HasTangentData( void ) const
|
|
// {
|
|
// return (pTangentData != NULL);
|
|
// }
|
|
|
|
// inline int mstudio_modelvertexdata_t::GetGlobalVertexIndex( int i ) const
|
|
// {
|
|
// mstudiomodel_t *modelptr = (mstudiomodel_t *)((byte *)this - offsetof(mstudiomodel_t, vertexdata));
|
|
// Assert( ( modelptr->vertexindex % sizeof( mstudiovertex_t ) ) == 0 );
|
|
// return ( i + ( modelptr->vertexindex / sizeof( mstudiovertex_t ) ) );
|
|
// }
|
|
//
|
|
// inline int mstudio_modelvertexdata_t::GetGlobalTangentIndex( int i ) const
|
|
// {
|
|
// mstudiomodel_t *modelptr = (mstudiomodel_t *)((byte *)this - offsetof(mstudiomodel_t, vertexdata));
|
|
// Assert( ( modelptr->tangentsindex % sizeof( Vector4D ) ) == 0 );
|
|
// return ( i + ( modelptr->tangentsindex / sizeof( Vector4D ) ) );
|
|
// }
|
|
//
|
|
// inline mstudiovertex_t *mstudio_modelvertexdata_t::Vertex( int i ) const
|
|
// {
|
|
// return (mstudiovertex_t *)pVertexData + GetGlobalVertexIndex( i );
|
|
// }
|
|
//
|
|
// inline Vector *mstudio_modelvertexdata_t::Position( int i ) const
|
|
// {
|
|
// return &Vertex(i)->m_vecPosition;
|
|
// }
|
|
//
|
|
// inline Vector *mstudio_modelvertexdata_t::Normal( int i ) const
|
|
// {
|
|
// return &Vertex(i)->m_vecNormal;
|
|
// }
|
|
//
|
|
// inline Vector4D *mstudio_modelvertexdata_t::TangentS( int i ) const
|
|
// {
|
|
// // NOTE: The tangents vector is 16-bytes in a separate array
|
|
// // because it only exists on the high end, and if I leave it out
|
|
// // of the mstudiovertex_t, the vertex is 64-bytes (good for low end)
|
|
// return (Vector4D *)pTangentData + GetGlobalTangentIndex( i );
|
|
// }
|
|
//
|
|
// inline Vector2D *mstudio_modelvertexdata_t::Texcoord( int i ) const
|
|
// {
|
|
// return &Vertex(i)->m_vecTexCoord;
|
|
// }
|
|
//
|
|
// inline mstudioboneweight_t *mstudio_modelvertexdata_t::BoneWeights( int i ) const
|
|
// {
|
|
// return &Vertex(i)->m_BoneWeights;
|
|
// }
|
|
//
|
|
// inline mstudiomodel_t *mstudiomesh_t::pModel() const
|
|
// {
|
|
// return (mstudiomodel_t *)(((byte *)this) + modelindex);
|
|
// }
|
|
//
|
|
// inline bool mstudio_meshvertexdata_t::HasTangentData( void ) const
|
|
// {
|
|
// return modelvertexdata->HasTangentData();
|
|
// }
|
|
//
|
|
// inline const mstudio_meshvertexdata_t *mstudiomesh_t::GetVertexData( void *pModelData )
|
|
// {
|
|
// // get this mesh's model's vertex data (allow for mstudiomodel_t::GetVertexData
|
|
// // returning NULL if the data has been converted to 'thin' vertices)
|
|
// this->pModel()->GetVertexData( pModelData );
|
|
// vertexdata.modelvertexdata = &( this->pModel()->vertexdata );
|
|
//
|
|
// if ( !vertexdata.modelvertexdata->pVertexData )
|
|
// return NULL;
|
|
//
|
|
// return &vertexdata;
|
|
// }
|
|
//
|
|
// inline const thinModelVertices_t * mstudiomesh_t::GetThinVertexData( void *pModelData )
|
|
// {
|
|
// // get this mesh's model's thin vertex data
|
|
// return this->pModel()->GetThinVertexData( pModelData );
|
|
// }
|
|
//
|
|
// inline int mstudio_meshvertexdata_t::GetModelVertexIndex( int i ) const
|
|
// {
|
|
// mstudiomesh_t *meshptr = (mstudiomesh_t *)((byte *)this - offsetof(mstudiomesh_t,vertexdata));
|
|
// return meshptr->vertexoffset + i;
|
|
// }
|
|
//
|
|
// inline int mstudio_meshvertexdata_t::GetGlobalVertexIndex( int i ) const
|
|
// {
|
|
// return modelvertexdata->GetGlobalVertexIndex( GetModelVertexIndex( i ) );
|
|
// }
|
|
//
|
|
// inline Vector *mstudio_meshvertexdata_t::Position( int i ) const
|
|
// {
|
|
// return modelvertexdata->Position( GetModelVertexIndex( i ) );
|
|
// };
|
|
//
|
|
// inline Vector *mstudio_meshvertexdata_t::Normal( int i ) const
|
|
// {
|
|
// return modelvertexdata->Normal( GetModelVertexIndex( i ) );
|
|
// };
|
|
//
|
|
// inline Vector4D *mstudio_meshvertexdata_t::TangentS( int i ) const
|
|
// {
|
|
// return modelvertexdata->TangentS( GetModelVertexIndex( i ) );
|
|
// }
|
|
//
|
|
// inline Vector2D *mstudio_meshvertexdata_t::Texcoord( int i ) const
|
|
// {
|
|
// return modelvertexdata->Texcoord( GetModelVertexIndex( i ) );
|
|
// };
|
|
//
|
|
// inline mstudioboneweight_t *mstudio_meshvertexdata_t::BoneWeights( int i ) const
|
|
// {
|
|
// return modelvertexdata->BoneWeights( GetModelVertexIndex( i ) );
|
|
// };
|
|
//
|
|
// inline mstudiovertex_t *mstudio_meshvertexdata_t::Vertex( int i ) const
|
|
// {
|
|
// return modelvertexdata->Vertex( GetModelVertexIndex( i ) );
|
|
// }
|
|
//
|
|
// // a group of studio model data
|
|
// enum studiomeshgroupflags_t
|
|
// {
|
|
// MESHGROUP_IS_HWSKINNED = 0x2,
|
|
// MESHGROUP_IS_DELTA_FLEXED = 0x4
|
|
// };
|
|
|
|
|
|
// ----------------------------------------------------------
|
|
// Runtime stuff
|
|
// ----------------------------------------------------------
|
|
|
|
// struct studiomeshgroup_t
|
|
// {
|
|
// IMesh *m_pMesh;
|
|
// int m_NumStrips;
|
|
// int m_Flags; // see studiomeshgroupflags_t
|
|
// OptimizedModel::StripHeader_t *m_pStripData;
|
|
// unsigned short *m_pGroupIndexToMeshIndex;
|
|
// int m_NumVertices;
|
|
// int *m_pUniqueFaces; // for performance measurements
|
|
// unsigned short *m_pIndices;
|
|
// unsigned short *m_pTopologyIndices;
|
|
// bool m_MeshNeedsRestore;
|
|
// short m_ColorMeshID;
|
|
// IMorph *m_pMorph;
|
|
//
|
|
// inline unsigned short MeshIndex( int i ) const { return m_pGroupIndexToMeshIndex[m_pIndices[i]]; }
|
|
// };
|
|
|
|
|
|
// studio model data
|
|
// struct studiomeshdata_t
|
|
// {
|
|
// int m_NumGroup;
|
|
// studiomeshgroup_t* m_pMeshGroup;
|
|
// };
|
|
//
|
|
// struct studioloddata_t
|
|
// {
|
|
// // not needed - this is really the same as studiohwdata_t.m_NumStudioMeshes
|
|
// //int m_NumMeshes;
|
|
// studiomeshdata_t *m_pMeshData; // there are studiohwdata_t.m_NumStudioMeshes of these.
|
|
// float m_SwitchPoint;
|
|
// // one of these for each lod since we can switch to simpler materials on lower lods.
|
|
// int numMaterials;
|
|
// IMaterial **ppMaterials; /* will have studiohdr_t.numtextures elements allocated */
|
|
// // hack - this needs to go away.
|
|
// int *pMaterialFlags; /* will have studiohdr_t.numtextures elements allocated */
|
|
// #ifndef _CERT
|
|
// int m_NumFaces; /* Total face count for this LOD */
|
|
// #endif // !_CERT
|
|
//
|
|
// // For decals on hardware morphing, we must actually do hardware skinning
|
|
// // For this to work, we have to hope that the total # of bones used by
|
|
// // hw flexed verts is < than the max possible for the dx level we're running under
|
|
// int *m_pHWMorphDecalBoneRemap;
|
|
// int m_nDecalBoneCount;
|
|
// };
|
|
//
|
|
// struct studiohwdata_t
|
|
// {
|
|
// int m_RootLOD; // calced and clamped, nonzero for lod culling
|
|
// int m_NumLODs;
|
|
// studioloddata_t *m_pLODs;
|
|
// int m_NumStudioMeshes;
|
|
//
|
|
// inline float LODMetric( float unitSphereSize ) const { return ( unitSphereSize != 0.0f ) ? (100.0f / unitSphereSize) : 0.0f; }
|
|
// inline int GetLODForMetric( float lodMetric ) const
|
|
// {
|
|
// static ConVarRef r_lod_switch_scale( "r_lod_switch_scale" );
|
|
//
|
|
// if ( !m_NumLODs )
|
|
// return 0;
|
|
//
|
|
// // On low GPU levels, we pull in the LOD transitions with a scale factor
|
|
// float flSwitchPointModifier = r_lod_switch_scale.IsValid() ? r_lod_switch_scale.GetFloat() : 1.0f;
|
|
//
|
|
// // shadow lod is specified on the last lod with a negative switch
|
|
// // never consider shadow lod as viable candidate
|
|
// int numLODs = (m_pLODs[m_NumLODs-1].m_SwitchPoint < 0.0f) ? m_NumLODs-1 : m_NumLODs;
|
|
//
|
|
// for ( int i = m_RootLOD; i < numLODs-1; i++ )
|
|
// {
|
|
// if ( ( m_pLODs[i+1].m_SwitchPoint * flSwitchPointModifier ) > lodMetric )
|
|
// return i;
|
|
// }
|
|
//
|
|
// return numLODs-1;
|
|
// }
|
|
//
|
|
// #ifndef _CERT
|
|
// // Each model counts how many rendered faces it accounts for each frame:
|
|
// inline void UpdateFacesRenderedCount( studiohdr_t *pStudioHdr, CUtlHash< studiohwdata_t * > &hwDataHash, int nLOD, int nInstances, int nFacesOverride = -1 )
|
|
// {
|
|
// if ( hwDataHash.Find( this ) == hwDataHash.InvalidHandle() )
|
|
// {
|
|
// m_NumFacesRenderedThisFrame = 0;
|
|
// m_NumTimesRenderedThisFrame = 0;
|
|
// m_pStudioHdr = pStudioHdr;
|
|
// hwDataHash.Insert( this );
|
|
// }
|
|
// Assert( m_pStudioHdr && ( m_pStudioHdr == pStudioHdr ) );
|
|
// if ( nFacesOverride == -1 )
|
|
// {
|
|
// nFacesOverride = ( nLOD < m_NumLODs ) ? m_pLODs[ nLOD ].m_NumFaces : 0;
|
|
// }
|
|
// m_NumFacesRenderedThisFrame += nInstances * nFacesOverride;
|
|
// m_NumTimesRenderedThisFrame ++;
|
|
// }
|
|
// int m_NumFacesRenderedThisFrame;
|
|
// int m_NumTimesRenderedThisFrame;
|
|
// studiohdr_t *m_pStudioHdr; // There is no way to map between these inside CStudioRender, so we have to store it.
|
|
// #endif // !_CERT
|
|
// };
|
|
|
|
// ----------------------------------------------------------
|
|
// ----------------------------------------------------------
|
|
|
|
// body part index
|
|
// struct mstudiobodyparts_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
// int sznameindex;
|
|
// inline char * const pszName( void ) const { return ((char *)this) + sznameindex; }
|
|
// int nummodels;
|
|
// int base;
|
|
// int modelindex; // index into models array
|
|
// inline mstudiomodel_t *pModel( int i ) const { return (mstudiomodel_t *)(((byte *)this) + modelindex) + i; };
|
|
// };
|
|
//
|
|
//
|
|
// struct mstudiomouth_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
// int bone;
|
|
// Vector forward;
|
|
// int flexdesc;
|
|
//
|
|
// mstudiomouth_t(){}
|
|
// private:
|
|
// // No copy constructors allowed
|
|
// mstudiomouth_t(const mstudiomouth_t& vOther);
|
|
// };
|
|
//
|
|
// struct mstudiohitboxset_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
// int sznameindex;
|
|
// inline char * const pszName( void ) const { return ((char *)this) + sznameindex; }
|
|
// int numhitboxes;
|
|
// int hitboxindex;
|
|
// inline mstudiobbox_t *pHitbox( int i ) const { return (mstudiobbox_t *)(((byte *)this) + hitboxindex) + i; };
|
|
// };
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Src bone transforms are transformations that will convert .dmx or .smd-based animations into .mdl-based animations
|
|
// NOTE: The operation you should apply is: pretransform * bone transform * posttransform
|
|
//-----------------------------------------------------------------------------
|
|
// struct mstudiosrcbonetransform_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
//
|
|
// int sznameindex;
|
|
// inline const char *pszName( void ) const { return ((char *)this) + sznameindex; }
|
|
// matrix3x4_t pretransform;
|
|
// matrix3x4_t posttransform;
|
|
// };
|
|
|
|
|
|
// ----------------------------------------------------------
|
|
// Purpose: Load time results on model compositing
|
|
// ----------------------------------------------------------
|
|
|
|
class virtualgroup_t_PS3
|
|
{
|
|
public:
|
|
virtualgroup_t_PS3( void ) { cache = NULL; };
|
|
// tool dependant. In engine this is a model_t, in tool it's a direct pointer
|
|
void *cache;
|
|
// converts cache entry into a usable studiohdr_t *
|
|
// const studiohdr_t *GetStudioHdr( void ) const;
|
|
|
|
// CUtlVector< int > boneMap; // maps global bone to local bone
|
|
// CUtlVector< int > masterBone; // maps local bone to global bone
|
|
// CUtlVector< int > masterSeq; // maps local sequence to master sequence
|
|
// CUtlVector< int > masterAnim; // maps local animation to master animation
|
|
// CUtlVector< int > masterAttachment; // maps local attachment to global
|
|
// CUtlVector< int > masterPose; // maps local pose parameter to global
|
|
// CUtlVector< int > masterNode; // maps local transition nodes to global
|
|
};
|
|
|
|
struct virtualsequence_t_PS3
|
|
{
|
|
int flags;
|
|
int activity;
|
|
int group;
|
|
int index;
|
|
};
|
|
|
|
struct virtualgeneric_t_PS3
|
|
{
|
|
int group;
|
|
int index;
|
|
};
|
|
|
|
|
|
struct virtualmodel_t_PS3
|
|
{
|
|
// void AppendSequences( int group, const studiohdr_t_PS3 *pStudioHdr );
|
|
// void AppendAnimations( int group, const studiohdr_t_PS3 *pStudioHdr );
|
|
// void AppendAttachments( int ground, const studiohdr_t_PS3 *pStudioHdr );
|
|
// void AppendPoseParameters( int group, const studiohdr_t_PS3 *pStudioHdr );
|
|
// void AppendBonemap( int group, const studiohdr_t_PS3 *pStudioHdr );
|
|
// void AppendNodes( int group, const studiohdr_t_PS3 *pStudioHdr );
|
|
// void AppendTransitions( int group, const studiohdr_t_PS3 *pStudioHdr );
|
|
// void AppendIKLocks( int group, const studiohdr_t_PS3 *pStudioHdr );
|
|
// void AppendModels( int group, const studiohdr_t_PS3 *pStudioHdr );
|
|
// void UpdateAutoplaySequences( const studiohdr_t_PS3 *pStudioHdr );
|
|
|
|
// virtualgroup_t_PS3 *pAnimGroup( int animation ) { return &m_group[ m_anim[ animation ].group ]; }; // Note: user must manage mutex for this
|
|
// virtualgroup_t_PS3 *pSeqGroup( int sequence ) { return &m_group[ m_seq[ sequence ].group ]; }; // Note: user must manage mutex for this
|
|
|
|
CThreadFastMutex_PS3 m_Lock;
|
|
|
|
// CUtlVector< virtualsequence_t_PS3 > m_seq;
|
|
// CUtlVector< virtualgeneric_t_PS3 > m_anim;
|
|
// CUtlVector< virtualgeneric_t_PS3 > m_attachment;
|
|
// CUtlVector< virtualgeneric_t_PS3 > m_pose;
|
|
// CUtlVector< virtualgroup_t_PS3 > m_group;
|
|
// CUtlVector< virtualgeneric_t_PS3 > m_node;
|
|
// CUtlVector< virtualgeneric_t_PS3 > m_iklock;
|
|
// CUtlVector< unsigned short > m_autoplaySequences;
|
|
};
|
|
|
|
// 'thin' vertex data, used to do model decals (see Studio_CreateThinVertexes())
|
|
// struct thinModelVertices_t
|
|
// {
|
|
// void Init( int numBoneInfluences, Vector *positions, unsigned short *normals, float *boneWeights, byte *boneIndices )
|
|
// {
|
|
// Assert( positions != NULL );
|
|
// Assert( normals != NULL );
|
|
// Assert( ( numBoneInfluences >= 0 ) && ( numBoneInfluences <= 3 ) );
|
|
// Assert( numBoneInfluences > 0 ? !!boneIndices : !boneIndices );
|
|
// Assert( numBoneInfluences > 1 ? !!boneWeights : !boneWeights );
|
|
// m_numBoneInfluences = numBoneInfluences;
|
|
// m_vecPositions = positions;
|
|
// m_vecNormals = normals;
|
|
// m_boneWeights = boneWeights;
|
|
// m_boneIndices = boneIndices;
|
|
// }
|
|
//
|
|
// void SetPosition( int vertIndex, const Vector & position )
|
|
// {
|
|
// Assert( m_vecPositions );
|
|
// m_vecPositions[ vertIndex ] = position;
|
|
// }
|
|
//
|
|
// void SetNormal( int vertIndex, const Vector & normal )
|
|
// {
|
|
// Assert( m_vecNormals );
|
|
// unsigned int packedNormal;
|
|
// PackNormal_UBYTE4( normal.x, normal.y, normal.z, &packedNormal );
|
|
// m_vecNormals[ vertIndex ] = (unsigned short)( 0x0000FFFF & packedNormal );
|
|
// }
|
|
//
|
|
// void SetBoneWeights( int vertIndex, const mstudioboneweight_t & boneWeights )
|
|
// {
|
|
// Assert( ( m_numBoneInfluences >= 1 ) && ( m_numBoneInfluences <= 3 ) );
|
|
// Assert( ( boneWeights.numbones >= 1 ) && ( boneWeights.numbones <= m_numBoneInfluences ) );
|
|
// int numStoredWeights = MAX( 0, ( m_numBoneInfluences - 1 ) );
|
|
// float *pBaseWeight = m_boneWeights + vertIndex*numStoredWeights;
|
|
// byte *pBaseIndex = m_boneIndices + vertIndex*m_numBoneInfluences;
|
|
// for ( int i = 0; i < m_numBoneInfluences; i++ )
|
|
// {
|
|
// pBaseIndex[i] = boneWeights.bone[i];
|
|
// }
|
|
// for ( int i = 0; i < numStoredWeights; i++ )
|
|
// {
|
|
// pBaseWeight[i] = boneWeights.weight[i];
|
|
// }
|
|
// }
|
|
//
|
|
// void GetMeshPosition( mstudiomesh_t *pMesh, int meshIndex, Vector *pPosition ) const
|
|
// {
|
|
// Assert( pMesh );
|
|
// GetPosition( pMesh->vertexdata.GetGlobalVertexIndex( meshIndex ), pPosition );
|
|
// }
|
|
//
|
|
// void GetMeshNormal( mstudiomesh_t *pMesh, int meshIndex, Vector *pNormal ) const
|
|
// {
|
|
// Assert( pMesh );
|
|
// GetNormal( pMesh->vertexdata.GetGlobalVertexIndex( meshIndex ), pNormal );
|
|
// }
|
|
//
|
|
// void GetMeshBoneWeights( mstudiomesh_t *pMesh, int meshIndex, mstudioboneweight_t *pBoneWeights ) const
|
|
// {
|
|
// Assert( pMesh );
|
|
// GetBoneWeights( pMesh->vertexdata.GetGlobalVertexIndex( meshIndex ), pBoneWeights );
|
|
// }
|
|
//
|
|
// void GetModelPosition( mstudiomodel_t *pModel, int modelIndex, Vector *pPosition ) const
|
|
// {
|
|
// Assert( pModel );
|
|
// GetPosition( pModel->vertexdata.GetGlobalVertexIndex( modelIndex ), pPosition );
|
|
// }
|
|
//
|
|
// void GetModelNormal( mstudiomodel_t *pModel, int modelIndex, Vector *pNormal ) const
|
|
// {
|
|
// Assert( pModel );
|
|
// GetNormal( pModel->vertexdata.GetGlobalVertexIndex( modelIndex ), pNormal );
|
|
// }
|
|
//
|
|
// void GetModelBoneWeights( mstudiomodel_t *pModel, int modelIndex, mstudioboneweight_t *pBoneWeights ) const
|
|
// {
|
|
// Assert( pModel );
|
|
// GetBoneWeights( pModel->vertexdata.GetGlobalVertexIndex( modelIndex ), pBoneWeights );
|
|
// }
|
|
//
|
|
// private:
|
|
// void GetPosition( int vertIndex, Vector *pPosition ) const
|
|
// {
|
|
// Assert( pPosition );
|
|
// Assert( m_vecPositions );
|
|
// *pPosition = m_vecPositions[ vertIndex ];
|
|
// }
|
|
//
|
|
// void GetNormal( int vertIndex, Vector *pNormal ) const
|
|
// {
|
|
// Assert( pNormal );
|
|
// Assert( m_vecNormals );
|
|
// unsigned int packedNormal = 0x0000FFFF & m_vecNormals[ vertIndex ];
|
|
// UnpackNormal_UBYTE4( &packedNormal, pNormal->Base() );
|
|
// }
|
|
//
|
|
// void GetBoneWeights( int vertIndex, mstudioboneweight_t * RESTRICT pBoneWeights ) const
|
|
// {
|
|
// Assert( pBoneWeights );
|
|
// Assert( ( m_numBoneInfluences <= 1 ) || ( m_boneWeights != NULL ) );
|
|
// Assert( ( m_numBoneInfluences <= 0 ) || ( m_boneIndices != NULL ) );
|
|
// int numStoredWeights = MAX( 0, ( m_numBoneInfluences - 1 ) );
|
|
// float * RESTRICT pBaseWeight = m_boneWeights + vertIndex*numStoredWeights;
|
|
// byte * RESTRICT pBaseIndex = m_boneIndices + vertIndex*m_numBoneInfluences;
|
|
// float sum = 0.0f;
|
|
// // TODO: unroll this loop? It's only three. We could use a switch
|
|
// // and code it explicitly for the various possible m_numBoneInfluences
|
|
// // which would improve scheduling but bloat code.
|
|
// for (int i = 0;i < MAX_NUM_BONES_PER_VERT;i++)
|
|
// {
|
|
// float weight;
|
|
// if ( i < ( m_numBoneInfluences - 1 ) )
|
|
// {
|
|
// weight = pBaseWeight[i];
|
|
// sum += weight;
|
|
// }
|
|
// else
|
|
// {
|
|
// weight = 1.0f - sum;
|
|
// sum = 1.0f;
|
|
// }
|
|
//
|
|
// pBoneWeights->weight[i] = weight;
|
|
// pBoneWeights->bone[i] = ( i < m_numBoneInfluences ) ? pBaseIndex[i] : 0;
|
|
//
|
|
// /*
|
|
// if ( i < ( m_numBoneInfluences - 1 ) )
|
|
// pBoneWeights->weight[i] = pBaseWeight[i];
|
|
// else
|
|
// pBoneWeights->weight[i] = 1.0f - sum;
|
|
// sum += pBoneWeights->weight[i];
|
|
//
|
|
// pBoneWeights->bone[i] = ( i < m_numBoneInfluences ) ? pBaseIndex[i] : 0;
|
|
// */
|
|
// }
|
|
//
|
|
// // Treat 'zero weights' as '100% binding to bone zero':
|
|
// pBoneWeights->numbones = m_numBoneInfluences ? m_numBoneInfluences : 1;
|
|
// }
|
|
//
|
|
// int m_numBoneInfluences;// Number of bone influences per vertex, N
|
|
// float *m_boneWeights; // This array stores (N-1) weights per vertex (unless N is zero)
|
|
// byte *m_boneIndices; // This array stores N indices per vertex
|
|
// Vector *m_vecPositions;
|
|
// unsigned short *m_vecNormals; // Normals are compressed into 16 bits apiece (see PackNormal_UBYTE4() )
|
|
// };
|
|
|
|
|
|
// ----------------------------------------------------------
|
|
// Studio Model Stream Data File
|
|
// ----------------------------------------------------------
|
|
|
|
// little-endian "IDSS"
|
|
// #define MODEL_STREAM_FILE_ID (('S'<<24)+('S'<<16)+('D'<<8)+'I')
|
|
// #define MODEL_STREAM_FILE_VERSION 1
|
|
|
|
// struct vertexStreamFileHeader_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
// int id; // MODEL_STREAM_FILE_ID
|
|
// int version; // MODEL_STREAM_FILE_VERSION
|
|
// long checksum; // same as studiohdr_t, ensures sync
|
|
// long flags; // flags
|
|
// int numVerts; // number of vertices
|
|
// int uv2StreamStart; // offset from base to uv2 stream
|
|
// int uv2ElementSize; // size of each uv2 element
|
|
// int pad; // pad
|
|
//
|
|
// public:
|
|
//
|
|
// // Accessor to uv2 stream
|
|
// const void *GetStreamUv2() const
|
|
// {
|
|
// if ( ( id == MODEL_STREAM_FILE_ID ) && ( uv2StreamStart != 0 ) )
|
|
// return ( void * ) ( uv2StreamStart + (byte *)this );
|
|
// else
|
|
// return NULL;
|
|
// }
|
|
// };
|
|
|
|
|
|
|
|
// ----------------------------------------------------------
|
|
// Studio Model Vertex Data File
|
|
// Position independent flat data for cache manager
|
|
// ----------------------------------------------------------
|
|
|
|
// little-endian "IDSV"
|
|
// #define MODEL_VERTEX_FILE_ID (('V'<<24)+('S'<<16)+('D'<<8)+'I')
|
|
// #define MODEL_VERTEX_FILE_VERSION 4
|
|
// // this id (IDCV) is used once the vertex data has been compressed (see CMDLCache::CreateThinVertexes)
|
|
// #define MODEL_VERTEX_FILE_THIN_ID (('V'<<24)+('C'<<16)+('D'<<8)+'I')
|
|
// // this id (IDDV) is used once the vertex data has been discarded (see CMDLCache::CreateNullVertexes)
|
|
// #define MODEL_VERTEX_FILE_NULL_ID (('V'<<24)+('D'<<16)+('D'<<8)+'I')
|
|
|
|
// struct vertexFileHeader_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
// int id; // MODEL_VERTEX_FILE_ID
|
|
// int version; // MODEL_VERTEX_FILE_VERSION
|
|
// long checksum; // same as studiohdr_t, ensures sync
|
|
// int numLODs; // num of valid lods
|
|
// int numLODVertexes[MAX_NUM_LODS]; // num verts for desired root lod
|
|
// int numFixups; // num of vertexFileFixup_t
|
|
// #ifdef _PS3
|
|
// union
|
|
// {
|
|
// int fixupTableStart;
|
|
// uint32 ps3edgeDmaInputDesc; // [PS3: offset of the EDGE DMA INPUT stream]
|
|
// };
|
|
// uint32 inline GetPs3EdgeDmaInputStart() const { return ( ps3edgeDmaInputDesc & 0xFFFF ) << 8; }
|
|
// uint32 inline GetPs3EdgeDmaInputLength() const { return ( ( ps3edgeDmaInputDesc >> 16 ) & 0x7FFF ) << 8; }
|
|
// #else
|
|
// int fixupTableStart; // offset from base to fixup table
|
|
// #endif
|
|
// int vertexDataStart; // offset from base to vertex block
|
|
// int tangentDataStart; // offset from base to tangent block
|
|
//
|
|
// public:
|
|
//
|
|
// // Accessor to fat vertex data
|
|
// const mstudiovertex_t *GetVertexData() const
|
|
// {
|
|
// if ( ( id == MODEL_VERTEX_FILE_ID ) && ( vertexDataStart != 0 ) )
|
|
// return ( mstudiovertex_t * ) ( vertexDataStart + (byte *)this );
|
|
// else
|
|
// return NULL;
|
|
// }
|
|
// // Accessor to (fat) tangent vertex data (tangents aren't stored in compressed data)
|
|
// const Vector4D *GetTangentData() const
|
|
// {
|
|
// if ( ( id == MODEL_VERTEX_FILE_ID ) && ( tangentDataStart != 0 ) )
|
|
// return ( Vector4D * ) ( tangentDataStart + (byte *)this );
|
|
// else
|
|
// return NULL;
|
|
// }
|
|
// // Accessor to thin vertex data
|
|
// const thinModelVertices_t *GetThinVertexData() const
|
|
// {
|
|
// if ( ( id == MODEL_VERTEX_FILE_THIN_ID ) && ( vertexDataStart != 0 ) )
|
|
// return ( thinModelVertices_t * ) ( vertexDataStart + (byte *)this );
|
|
// else
|
|
// return NULL;
|
|
// }
|
|
//
|
|
// #ifdef _PS3
|
|
// // Accessor to EDGE DMA INPUT format
|
|
// const byte *GetPs3EdgeDmaInput() const
|
|
// {
|
|
// if ( ( id == MODEL_VERTEX_FILE_ID ) && ( ps3edgeDmaInputDesc & 0x80000000 ) )
|
|
// return ( byte * ) ( GetPs3EdgeDmaInputStart() + (byte *)this );
|
|
// else
|
|
// return NULL;
|
|
// }
|
|
// #endif
|
|
// };
|
|
//
|
|
// // model vertex data accessor (defined here so vertexFileHeader_t can be used)
|
|
// inline const mstudio_modelvertexdata_t * mstudiomodel_t::GetVertexData( void *pModelData )
|
|
// {
|
|
// const vertexFileHeader_t * pVertexHdr = CacheVertexData( pModelData );
|
|
// if ( !pVertexHdr )
|
|
// return NULL;
|
|
//
|
|
// vertexdata.pVertexData = pVertexHdr->GetVertexData();
|
|
// vertexdata.pTangentData = pVertexHdr->GetTangentData();
|
|
//
|
|
// if ( !vertexdata.pVertexData )
|
|
// return NULL;
|
|
//
|
|
// return &vertexdata;
|
|
// }
|
|
//
|
|
// // model thin vertex data accessor (defined here so vertexFileHeader_t can be used)
|
|
// inline const thinModelVertices_t * mstudiomodel_t::GetThinVertexData( void *pModelData )
|
|
// {
|
|
// const vertexFileHeader_t * pVertexHdr = CacheVertexData( pModelData );
|
|
// if ( !pVertexHdr )
|
|
// return NULL;
|
|
//
|
|
// return pVertexHdr->GetThinVertexData();
|
|
// }
|
|
//
|
|
// // apply sequentially to lod sorted vertex and tangent pools to re-establish mesh order
|
|
// struct vertexFileFixup_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
// int lod; // used to skip culled root lod
|
|
// int sourceVertexID; // absolute index from start of vertex/tangent blocks
|
|
// int numVertexes;
|
|
// };
|
|
//
|
|
// // This flag is set if no hitbox information was specified
|
|
// #define STUDIOHDR_FLAGS_AUTOGENERATED_HITBOX ( 1 << 0 )
|
|
//
|
|
// // NOTE: This flag is set at loadtime, not mdl build time so that we don't have to rebuild
|
|
// // models when we change materials.
|
|
// #define STUDIOHDR_FLAGS_USES_ENV_CUBEMAP ( 1 << 1 )
|
|
//
|
|
// // Use this when there are translucent parts to the model but we're not going to sort it
|
|
// #define STUDIOHDR_FLAGS_FORCE_OPAQUE ( 1 << 2 )
|
|
//
|
|
// // Use this when we want to render the opaque parts during the opaque pass
|
|
// // and the translucent parts during the translucent pass
|
|
// #define STUDIOHDR_FLAGS_TRANSLUCENT_TWOPASS ( 1 << 3 )
|
|
//
|
|
// // This is set any time the .qc files has $staticprop in it
|
|
// // Means there's no bones and no transforms
|
|
// #define STUDIOHDR_FLAGS_STATIC_PROP ( 1 << 4 )
|
|
//
|
|
// // NOTE: This flag is set at loadtime, not mdl build time so that we don't have to rebuild
|
|
// // models when we change materials.
|
|
// #define STUDIOHDR_FLAGS_USES_FB_TEXTURE ( 1 << 5 )
|
|
//
|
|
// // This flag is set by studiomdl.exe if a separate "$shadowlod" entry was present
|
|
// // for the .mdl (the shadow lod is the last entry in the lod list if present)
|
|
// #define STUDIOHDR_FLAGS_HASSHADOWLOD ( 1 << 6 )
|
|
//
|
|
// // NOTE: This flag is set at loadtime, not mdl build time so that we don't have to rebuild
|
|
// // models when we change materials.
|
|
// #define STUDIOHDR_FLAGS_USES_BUMPMAPPING ( 1 << 7 )
|
|
//
|
|
// // NOTE: This flag is set when we should use the actual materials on the shadow LOD
|
|
// // instead of overriding them with the default one (necessary for translucent shadows)
|
|
// #define STUDIOHDR_FLAGS_USE_SHADOWLOD_MATERIALS ( 1 << 8 )
|
|
//
|
|
// // NOTE: This flag is set when we should use the actual materials on the shadow LOD
|
|
// // instead of overriding them with the default one (necessary for translucent shadows)
|
|
// #define STUDIOHDR_FLAGS_OBSOLETE ( 1 << 9 )
|
|
//
|
|
// #define STUDIOHDR_FLAGS_UNUSED ( 1 << 10 )
|
|
//
|
|
// // NOTE: This flag is set at mdl build time
|
|
// #define STUDIOHDR_FLAGS_NO_FORCED_FADE ( 1 << 11 )
|
|
//
|
|
// // NOTE: The npc will lengthen the viseme check to always include two phonemes
|
|
// #define STUDIOHDR_FLAGS_FORCE_PHONEME_CROSSFADE ( 1 << 12 )
|
|
//
|
|
// // This flag is set when the .qc has $constantdirectionallight in it
|
|
// // If set, we use constantdirectionallightdot to calculate light intensity
|
|
// // rather than the normal directional dot product
|
|
// // only valid if STUDIOHDR_FLAGS_STATIC_PROP is also set
|
|
// #define STUDIOHDR_FLAGS_CONSTANT_DIRECTIONAL_LIGHT_DOT ( 1 << 13 )
|
|
//
|
|
// // Flag to mark delta flexes as already converted from disk format to memory format
|
|
// #define STUDIOHDR_FLAGS_FLEXES_CONVERTED ( 1 << 14 )
|
|
//
|
|
// // Indicates the studiomdl was built in preview mode
|
|
// #define STUDIOHDR_FLAGS_BUILT_IN_PREVIEW_MODE ( 1 << 15 )
|
|
//
|
|
// // Ambient boost (runtime flag)
|
|
// #define STUDIOHDR_FLAGS_AMBIENT_BOOST ( 1 << 16 )
|
|
//
|
|
// // Don't cast shadows from this model (useful on first-person models)
|
|
// #define STUDIOHDR_FLAGS_DO_NOT_CAST_SHADOWS ( 1 << 17 )
|
|
//
|
|
// // alpha textures should cast shadows in vrad on this model (ONLY prop_static!)
|
|
// #define STUDIOHDR_FLAGS_CAST_TEXTURE_SHADOWS ( 1 << 18 )
|
|
//
|
|
// // Model has a quad-only Catmull-Clark SubD cage
|
|
// #define STUDIOHDR_FLAGS_SUBDIVISION_SURFACE ( 1 << 19 )
|
|
//
|
|
// // flagged on load to indicate no animation events on this model
|
|
// #define STUDIOHDR_FLAGS_NO_ANIM_EVENTS ( 1 << 20 )
|
|
//
|
|
// // If flag is set then studiohdr_t.flVertAnimFixedPointScale contains the
|
|
// // scale value for fixed point vert anim data, if not set then the
|
|
// // scale value is the default of 1.0 / 4096.0. Regardless use
|
|
// // studiohdr_t::VertAnimFixedPointScale() to always retrieve the scale value
|
|
// #define STUDIOHDR_FLAGS_VERT_ANIM_FIXED_POINT_SCALE ( 1 << 21 )
|
|
//
|
|
// // If flag is set then model data is processed for EDGE
|
|
// // the flag is set at tool time when producing PS3-format assets
|
|
// #define STUDIOHDR_FLAGS_PS3_EDGE_FORMAT ( 1 << 22 )
|
|
|
|
// NOTE! Next time we up the .mdl file format, remove studiohdr2_t
|
|
// and insert all fields in this structure into studiohdr_t.
|
|
struct studiohdr2_t_PS3
|
|
{
|
|
// NOTE: For forward compat, make sure any methods in this struct
|
|
// are also available in studiohdr_t so no leaf code ever directly references
|
|
// a studiohdr2_t structure
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
int numsrcbonetransform;
|
|
int srcbonetransformindex;
|
|
|
|
int illumpositionattachmentindex;
|
|
// inline int IllumPositionAttachmentIndex() const { return illumpositionattachmentindex; }
|
|
|
|
float flMaxEyeDeflection;
|
|
// inline float MaxEyeDeflection() const { return flMaxEyeDeflection != 0.0f ? flMaxEyeDeflection : 0.866f; } // default to cos(30) if not set
|
|
|
|
int linearboneindex;
|
|
// inline mstudiolinearbone_t *pLinearBones() const { return (linearboneindex) ? (mstudiolinearbone_t *)(((byte *)this) + linearboneindex) : NULL; }
|
|
|
|
int sznameindex;
|
|
// inline char *pszName() { return (sznameindex) ? (char *)(((byte *)this) + sznameindex ) : NULL; }
|
|
|
|
int m_nBoneFlexDriverCount;
|
|
int m_nBoneFlexDriverIndex;
|
|
// inline mstudioboneflexdriver_t *pBoneFlexDriver( int i ) const { Assert( i >= 0 && i < m_nBoneFlexDriverCount ); return (mstudioboneflexdriver_t *)(((byte *)this) + m_nBoneFlexDriverIndex) + i; }
|
|
|
|
int reserved[56];
|
|
};
|
|
|
|
struct studiohdr_t_PS3
|
|
{
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
int id;
|
|
int version;
|
|
|
|
long checksum; // this has to be the same in the phy and vtx files to load!
|
|
|
|
// inline const char * pszName( void ) const { if (studiohdr2index && pStudioHdr2()->pszName()) return pStudioHdr2()->pszName(); else return name; }
|
|
char name[64];
|
|
|
|
int length;
|
|
|
|
Vector eyeposition; // ideal eye position
|
|
|
|
Vector illumposition; // illumination center
|
|
|
|
Vector hull_min; // ideal movement hull size
|
|
Vector hull_max;
|
|
|
|
Vector view_bbmin; // clipping bounding box
|
|
Vector view_bbmax;
|
|
|
|
int flags;
|
|
|
|
int numbones; // bones
|
|
int boneindex;
|
|
// inline mstudiobone_t *pBone( int i ) const { Assert( i >= 0 && i < numbones); return (mstudiobone_t *)(((byte *)this) + boneindex) + i; };
|
|
// int RemapSeqBone( int iSequence, int iLocalBone ) const; // maps local sequence bone to global bone
|
|
// int RemapAnimBone( int iAnim, int iLocalBone ) const; // maps local animations bone to global bone
|
|
|
|
int numbonecontrollers; // bone controllers
|
|
int bonecontrollerindex;
|
|
// inline mstudiobonecontroller_t *pBonecontroller( int i ) const { Assert( i >= 0 && i < numbonecontrollers); return (mstudiobonecontroller_t *)(((byte *)this) + bonecontrollerindex) + i; };
|
|
|
|
int numhitboxsets;
|
|
int hitboxsetindex;
|
|
|
|
// Look up hitbox set by index
|
|
// mstudiohitboxset_t *pHitboxSet( int i ) const
|
|
// {
|
|
// Assert( i >= 0 && i < numhitboxsets);
|
|
// return (mstudiohitboxset_t *)(((byte *)this) + hitboxsetindex ) + i;
|
|
// };
|
|
|
|
// Calls through to hitbox to determine size of specified set
|
|
// inline mstudiobbox_t *pHitbox( int i, int set ) const
|
|
// {
|
|
// mstudiohitboxset_t const *s = pHitboxSet( set );
|
|
// if ( !s )
|
|
// return NULL;
|
|
//
|
|
// return s->pHitbox( i );
|
|
// };
|
|
|
|
// Calls through to set to get hitbox count for set
|
|
// inline int iHitboxCount( int set ) const
|
|
// {
|
|
// mstudiohitboxset_t const *s = pHitboxSet( set );
|
|
// if ( !s )
|
|
// return 0;
|
|
//
|
|
// return s->numhitboxes;
|
|
// };
|
|
|
|
// file local animations? and sequences
|
|
//private:
|
|
int numlocalanim; // animations/poses
|
|
int localanimindex; // animation descriptions
|
|
// inline mstudioanimdesc_t *pLocalAnimdesc( int i ) const { if (i < 0 || i >= numlocalanim) i = 0; return (mstudioanimdesc_t *)(((byte *)this) + localanimindex) + i; };
|
|
|
|
int numlocalseq; // sequences
|
|
int localseqindex;
|
|
// inline mstudioseqdesc_t_PS3 *pLocalSeqdesc_PS3( int i ) const { if (i < 0 || i >= numlocalseq) i = 0; return (mstudioseqdesc_t_PS3 *)(((byte *)this) + localseqindex) + i; };
|
|
|
|
//public:
|
|
// bool SequencesAvailable() const;
|
|
// int GetNumSeq_Internal() const;
|
|
// inline int GetNumSeq() const
|
|
// {
|
|
// if (numincludemodels == 0)
|
|
// {
|
|
// return numlocalseq;
|
|
// }
|
|
// return GetNumSeq_Internal();
|
|
//
|
|
// }
|
|
// mstudioanimdesc_t &pAnimdesc_Internal( int i ) const;
|
|
// inline mstudioanimdesc_t &pAnimdesc( int i ) const
|
|
// {
|
|
// if (numincludemodels == 0)
|
|
// {
|
|
// return *pLocalAnimdesc( i );
|
|
// }
|
|
//
|
|
// return pAnimdesc_Internal( i );
|
|
// }
|
|
//
|
|
// mstudioseqdesc_t &pSeqdesc_Internal( int i ) const;
|
|
// inline mstudioseqdesc_t &pSeqdesc( int i ) const
|
|
// {
|
|
// if (numincludemodels == 0)
|
|
// {
|
|
// return *pLocalSeqdesc( i );
|
|
// }
|
|
// return pSeqdesc_Internal( i );
|
|
// }
|
|
// int iRelativeAnim_Internal( int baseseq, int relanim ) const; // maps seq local anim reference to global anim index
|
|
// inline int iRelativeAnim( int baseseq, int relanim ) const
|
|
// {
|
|
// if ( numincludemodels == 0 )
|
|
// return relanim;
|
|
// return iRelativeAnim_Internal( baseseq, relanim );
|
|
// }
|
|
// int iRelativeSeq_Internal( int baseseq, int relseq ) const; // maps seq local seq reference to global seq index
|
|
// inline int iRelativeSeq( int baseseq, int relseq ) const
|
|
// {
|
|
// if (numincludemodels == 0)
|
|
// {
|
|
// return relseq;
|
|
// }
|
|
// return iRelativeSeq_Internal( baseseq, relseq );
|
|
// }
|
|
|
|
//private:
|
|
mutable int activitylistversion; // initialization flag - have the sequences been indexed?
|
|
mutable int eventsindexed;
|
|
//public:
|
|
// int GetSequenceActivity( int iSequence );
|
|
// void SetSequenceActivity( int iSequence, int iActivity );
|
|
// int GetActivityListVersion( void );
|
|
// void SetActivityListVersion( int version ) const;
|
|
// int GetEventListVersion( void );
|
|
// void SetEventListVersion( int version );
|
|
|
|
// raw textures
|
|
int numtextures;
|
|
int textureindex;
|
|
// inline mstudiotexture_t *pTexture( int i ) const { Assert( i >= 0 && i < numtextures ); return (mstudiotexture_t *)(((byte *)this) + textureindex) + i; };
|
|
|
|
|
|
// raw textures search paths
|
|
int numcdtextures;
|
|
int cdtextureindex;
|
|
// inline char *pCdtexture( int i ) const { return (((char *)this) + *((int *)(((byte *)this) + cdtextureindex) + i)); };
|
|
|
|
// replaceable textures tables
|
|
int numskinref;
|
|
int numskinfamilies;
|
|
int skinindex;
|
|
// inline short *pSkinref( int i ) const { return (short *)(((byte *)this) + skinindex) + i; };
|
|
|
|
int numbodyparts;
|
|
int bodypartindex;
|
|
// inline mstudiobodyparts_t *pBodypart( int i ) const { return (mstudiobodyparts_t *)(((byte *)this) + bodypartindex) + i; };
|
|
|
|
// queryable attachable points
|
|
//private:
|
|
int numlocalattachments;
|
|
int localattachmentindex;
|
|
// inline mstudioattachment_t *pLocalAttachment( int i ) const { Assert( i >= 0 && i < numlocalattachments); return (mstudioattachment_t *)(((byte *)this) + localattachmentindex) + i; };
|
|
////public:
|
|
// int GetNumAttachments( void ) const;
|
|
// const mstudioattachment_t &pAttachment( int i ) const;
|
|
// int GetAttachmentBone( int i );
|
|
// used on my tools in hlmv, not persistant
|
|
// void SetAttachmentBone( int iAttachment, int iBone );
|
|
|
|
// animation node to animation node transition graph
|
|
//private:
|
|
int numlocalnodes;
|
|
int localnodeindex;
|
|
int localnodenameindex;
|
|
// inline char *pszLocalNodeName( int iNode ) const { Assert( iNode >= 0 && iNode < numlocalnodes); return (((char *)this) + *((int *)(((byte *)this) + localnodenameindex) + iNode)); }
|
|
// inline byte *pLocalTransition( int i ) const { Assert( i >= 0 && i < (numlocalnodes * numlocalnodes)); return (byte *)(((byte *)this) + localnodeindex) + i; };
|
|
|
|
//// public:
|
|
// int EntryNode( int iSequence );
|
|
// int ExitNode( int iSequence );
|
|
// char *pszNodeName( int iNode );
|
|
// int GetTransition( int iFrom, int iTo ) const;
|
|
|
|
int numflexdesc;
|
|
int flexdescindex;
|
|
// inline mstudioflexdesc_t *pFlexdesc( int i ) const { Assert( i >= 0 && i < numflexdesc); return (mstudioflexdesc_t *)(((byte *)this) + flexdescindex) + i; };
|
|
|
|
int numflexcontrollers;
|
|
int flexcontrollerindex;
|
|
// inline mstudioflexcontroller_t *pFlexcontroller( LocalFlexController_t i ) const { Assert( i >= 0 && i < numflexcontrollers); return (mstudioflexcontroller_t *)(((byte *)this) + flexcontrollerindex) + i; };
|
|
|
|
int numflexrules;
|
|
int flexruleindex;
|
|
// inline mstudioflexrule_t *pFlexRule( int i ) const { Assert( i >= 0 && i < numflexrules); return (mstudioflexrule_t *)(((byte *)this) + flexruleindex) + i; };
|
|
|
|
int numikchains;
|
|
int ikchainindex;
|
|
// inline mstudioikchain_t *pIKChain( int i ) const { Assert( i >= 0 && i < numikchains); return (mstudioikchain_t *)(((byte *)this) + ikchainindex) + i; };
|
|
|
|
int nummouths;
|
|
int mouthindex;
|
|
// inline mstudiomouth_t *pMouth( int i ) const { Assert( i >= 0 && i < nummouths); return (mstudiomouth_t *)(((byte *)this) + mouthindex) + i; };
|
|
|
|
//private:
|
|
int numlocalposeparameters;
|
|
int localposeparamindex;
|
|
// inline mstudioposeparamdesc_t *pLocalPoseParameter( int i ) const { Assert( i >= 0 && i < numlocalposeparameters); return (mstudioposeparamdesc_t *)(((byte *)this) + localposeparamindex) + i; };
|
|
////public:
|
|
// int GetNumPoseParameters( void ) const;
|
|
// const mstudioposeparamdesc_t &pPoseParameter( int i );
|
|
// int GetSharedPoseParameter( int iSequence, int iLocalPose ) const;
|
|
|
|
int surfacepropindex;
|
|
// inline char * const pszSurfaceProp( void ) const { return ((char *)this) + surfacepropindex; }
|
|
// inline int GetSurfaceProp() const { return surfacepropLookup; }
|
|
|
|
// Key values
|
|
int keyvalueindex;
|
|
int keyvaluesize;
|
|
// inline const char * KeyValueText( void ) const { return keyvaluesize != 0 ? ((char *)this) + keyvalueindex : NULL; }
|
|
|
|
int numlocalikautoplaylocks;
|
|
int localikautoplaylockindex;
|
|
// inline mstudioiklock_t *pLocalIKAutoplayLock( int i ) const { Assert( i >= 0 && i < numlocalikautoplaylocks); return (mstudioiklock_t *)(((byte *)this) + localikautoplaylockindex) + i; };
|
|
|
|
// int GetNumIKAutoplayLocks( void ) const;
|
|
// const mstudioiklock_t &pIKAutoplayLock( int i );
|
|
// int CountAutoplaySequences() const;
|
|
// int CopyAutoplaySequences( unsigned short *pOut, int outCount ) const;
|
|
// int GetAutoplayList( unsigned short **pOut ) const;
|
|
|
|
// The collision model mass that jay wanted
|
|
float mass;
|
|
int contents;
|
|
|
|
// external animations, models, etc.
|
|
int numincludemodels;
|
|
int includemodelindex;
|
|
// inline mstudiomodelgroup_t *pModelGroup( int i ) const { Assert( i >= 0 && i < numincludemodels); return (mstudiomodelgroup_t *)(((byte *)this) + includemodelindex) + i; };
|
|
// implementation specific call to get a named model
|
|
// const studiohdr_t *FindModel( void **cache, char const *modelname ) const;
|
|
|
|
// implementation specific back pointer to virtual data
|
|
mutable void *virtualModel;
|
|
// virtualmodel_t *GetVirtualModel( void ) const;
|
|
|
|
// for demand loaded animation blocks
|
|
int szanimblocknameindex;
|
|
// inline char * const pszAnimBlockName( void ) const { return ((char *)this) + szanimblocknameindex; }
|
|
int numanimblocks;
|
|
int animblockindex;
|
|
// inline mstudioanimblock_t *pAnimBlock( int i ) const { Assert( i > 0 && i < numanimblocks); return (mstudioanimblock_t *)(((byte *)this) + animblockindex) + i; };
|
|
mutable void *animblockModel;
|
|
// byte * GetAnimBlock( int i, bool preloadIfMissing = true ) const;
|
|
// bool hasAnimBlockBeenPreloaded( int i ) const;
|
|
|
|
int bonetablebynameindex;
|
|
// inline const byte *GetBoneTableSortedByName() const { return (byte *)this + bonetablebynameindex; }
|
|
|
|
// used by tools only that don't cache, but persist mdl's peer data
|
|
// engine uses virtualModel to back link to cache pointers
|
|
void *pVertexBase;
|
|
void *pIndexBase;
|
|
|
|
// if STUDIOHDR_FLAGS_CONSTANT_DIRECTIONAL_LIGHT_DOT is set,
|
|
// this value is used to calculate directional components of lighting
|
|
// on static props
|
|
byte constdirectionallightdot;
|
|
|
|
// set during load of mdl data to track *desired* lod configuration (not actual)
|
|
// the *actual* clamped root lod is found in studiohwdata
|
|
// this is stored here as a global store to ensure the staged loading matches the rendering
|
|
byte rootLOD;
|
|
|
|
// set in the mdl data to specify that lod configuration should only allow first numAllowRootLODs
|
|
// to be set as root LOD:
|
|
// numAllowedRootLODs = 0 means no restriction, any lod can be set as root lod.
|
|
// numAllowedRootLODs = N means that lod0 - lod(N-1) can be set as root lod, but not lodN or lower.
|
|
byte numAllowedRootLODs;
|
|
|
|
byte unused[1];
|
|
|
|
int unused4; // zero out if version < 47
|
|
|
|
int numflexcontrollerui;
|
|
int flexcontrolleruiindex;
|
|
// mstudioflexcontrollerui_t *pFlexControllerUI( int i ) const { Assert( i >= 0 && i < numflexcontrollerui); return (mstudioflexcontrollerui_t *)(((byte *)this) + flexcontrolleruiindex) + i; }
|
|
|
|
float flVertAnimFixedPointScale;
|
|
// inline float VertAnimFixedPointScale() const { return ( flags & STUDIOHDR_FLAGS_VERT_ANIM_FIXED_POINT_SCALE ) ? flVertAnimFixedPointScale : 1.0f / 4096.0f; }
|
|
|
|
mutable int surfacepropLookup; // this index must be cached by the loader, not saved in the file
|
|
|
|
// FIXME: Remove when we up the model version. Move all fields of studiohdr2_t into studiohdr_t.
|
|
int studiohdr2index;
|
|
// studiohdr2_t* pStudioHdr2() const { return (studiohdr2_t *)( ( (byte *)this ) + studiohdr2index ); }
|
|
|
|
// Src bone transforms are transformations that will convert .dmx or .smd-based animations into .mdl-based animations
|
|
// int NumSrcBoneTransforms() const { return studiohdr2index ? pStudioHdr2()->numsrcbonetransform : 0; }
|
|
// const mstudiosrcbonetransform_t* SrcBoneTransform( int i ) const { Assert( i >= 0 && i < NumSrcBoneTransforms()); return (mstudiosrcbonetransform_t *)(((byte *)this) + pStudioHdr2()->srcbonetransformindex) + i; }
|
|
|
|
// inline int IllumPositionAttachmentIndex() const { return studiohdr2index ? pStudioHdr2()->IllumPositionAttachmentIndex() : 0; }
|
|
|
|
// inline float MaxEyeDeflection() const { return studiohdr2index ? pStudioHdr2()->MaxEyeDeflection() : 0.866f; } // default to cos(30) if not set
|
|
|
|
// inline mstudiolinearbone_t *pLinearBones() const { return studiohdr2index ? pStudioHdr2()->pLinearBones() : NULL; }
|
|
|
|
// inline int BoneFlexDriverCount() const { return studiohdr2index ? pStudioHdr2()->m_nBoneFlexDriverCount : 0; }
|
|
// inline const mstudioboneflexdriver_t* BoneFlexDriver( int i ) const { Assert( i >= 0 && i < BoneFlexDriverCount() ); return studiohdr2index ? pStudioHdr2()->pBoneFlexDriver( i ) : NULL; }
|
|
|
|
// NOTE: No room to add stuff? Up the .mdl file format version
|
|
// [and move all fields in studiohdr2_t into studiohdr_t and kill studiohdr2_t],
|
|
// or add your stuff to studiohdr2_t. See NumSrcBoneTransforms/SrcBoneTransform for the pattern to use.
|
|
int unused2[1];
|
|
|
|
studiohdr_t_PS3() {}
|
|
|
|
private:
|
|
// No copy constructors allowed
|
|
studiohdr_t_PS3(const studiohdr_t_PS3& vOther);
|
|
|
|
friend struct virtualmodel_t_PS3;
|
|
};
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
|
|
//class IDataCache_PS3;
|
|
//class IMDLCache_PS3;
|
|
|
|
// class CStudioHdr_PS3
|
|
// {
|
|
// public:
|
|
// CStudioHdr_PS3( void );
|
|
// CStudioHdr_PS3( const studiohdr_t_PS3 *pStudioHdr, IMDLCache_PS3 *mdlcache = NULL );
|
|
// ~CStudioHdr_PS3() { /*Term();*/ m_pActivityToSequence = NULL; }
|
|
|
|
// void Init( const studiohdr_t_PS3 *pStudioHdr, IMDLCache_PS3 *mdlcache = NULL );
|
|
// void Term();
|
|
|
|
// public:
|
|
// inline bool IsVirtual( void ) { return (m_pVModel != NULL); };
|
|
// inline bool IsValid( void ) { return (m_pStudioHdr != NULL); };
|
|
// inline bool IsReadyForAccess( void ) const { return (m_pStudioHdr != NULL); };
|
|
// inline virtualmodel_t *GetVirtualModel( void ) const { return m_pVModel; };
|
|
// inline const studiohdr_t *GetRenderHdr( void ) const { return m_pStudioHdr; };
|
|
// const studiohdr_t *pSeqStudioHdr( int sequence );
|
|
// const studiohdr_t *pAnimStudioHdr( int animation );
|
|
|
|
// private:
|
|
// mutable const studiohdr_t *m_pStudioHdr;
|
|
// mutable virtualmodel_t *m_pVModel;
|
|
|
|
// const virtualmodel_t * ResetVModel( const virtualmodel_t *pVModel ) const;
|
|
// const studiohdr_t *GroupStudioHdr( int group );
|
|
// mutable CUtlVector< const studiohdr_t_PS3 * > m_pStudioHdrCache;
|
|
//
|
|
// mutable int m_nFrameUnlockCounter;
|
|
// int * m_pFrameUnlockCounter;
|
|
// CThreadFastMutex_PS3 m_FrameUnlockCounterMutex;
|
|
|
|
// public:
|
|
// inline int numbones( void ) const { return m_pStudioHdr->numbones; };
|
|
// inline mstudiobone_t *pBone( int i ) const { return m_pStudioHdr->pBone( i ); };
|
|
// int RemapAnimBone( int iAnim, int iLocalBone ) const; // maps local animations bone to global bone
|
|
// int RemapSeqBone( int iSequence, int iLocalBone ) const; // maps local sequence bone to global bone
|
|
|
|
// bool SequencesAvailable() const;
|
|
// int GetNumSeq_Internal( void ) const;
|
|
// inline int GetNumSeq( void ) const
|
|
// {
|
|
// if ( !m_pVModel )
|
|
// return m_pStudioHdr->numlocalseq;
|
|
// return GetNumSeq_Internal();
|
|
// }
|
|
|
|
// mstudioanimdesc_t &pAnimdesc_Internal( int i );
|
|
// inline mstudioanimdesc_t &pAnimdesc( int i )
|
|
// {
|
|
// if ( !m_pVModel )
|
|
// return *m_pStudioHdr->pLocalAnimdesc( i );
|
|
// return pAnimdesc_Internal( i );
|
|
// }
|
|
// mstudioseqdesc_t_PS3 &pSeqdesc_Internal_PS3( int iSequence );
|
|
// inline mstudioseqdesc_t_PS3 &pSeqdesc_PS3( int iSequence )
|
|
// {
|
|
// if ( !m_pVModel )
|
|
// return *m_pStudioHdr->pLocalSeqdesc_PS3( iSequence );
|
|
//
|
|
// return pSeqdesc_Internal_PS3( iSequence );
|
|
// }
|
|
|
|
// int iRelativeAnim_Internal( int baseseq, int relanim ) const; // maps seq local anim reference to global anim index
|
|
// inline int iRelativeAnim( int baseseq, int relanim ) const
|
|
// {
|
|
// if ( !m_pVModel )
|
|
// return relanim;
|
|
// return iRelativeAnim_Internal( baseseq, relanim );
|
|
// }
|
|
|
|
// int iRelativeSeq( int baseseq, int relseq ) const; // maps seq local seq reference to global seq index
|
|
|
|
// int GetSequenceActivity( int iSequence );
|
|
// void SetSequenceActivity( int iSequence, int iActivity );
|
|
// int GetActivityListVersion( void );
|
|
// void SetActivityListVersion( int version );
|
|
// int GetEventListVersion( void );
|
|
// void SetEventListVersion( int version );
|
|
|
|
// int GetNumAttachments( void ) const;
|
|
// const mstudioattachment_t &pAttachment( int i );
|
|
// int GetAttachmentBone( int i );
|
|
// used on my tools in hlmv, not persistant
|
|
// void SetAttachmentBone( int iAttachment, int iBone );
|
|
|
|
// int EntryNode( int iSequence );
|
|
// int ExitNode( int iSequence );
|
|
// char *pszNodeName( int iNode );
|
|
// FIXME: where should this one be?
|
|
// int GetTransition( int iFrom, int iTo ) const;
|
|
|
|
// int GetNumPoseParameters( void ) const;
|
|
// const mstudioposeparamdesc_t &pPoseParameter( int i );
|
|
// int GetSharedPoseParameter( int iSequence, int iLocalPose ) const;
|
|
|
|
// int GetNumIKAutoplayLocks( void ) const;
|
|
// const mstudioiklock_t &pIKAutoplayLock( int i );
|
|
|
|
// inline int CountAutoplaySequences() const { return m_pStudioHdr->CountAutoplaySequences(); };
|
|
// inline int CopyAutoplaySequences( unsigned short *pOut, int outCount ) const { return m_pStudioHdr->CopyAutoplaySequences( pOut, outCount ); };
|
|
// inline int GetAutoplayList( unsigned short **pOut ) const { return m_pStudioHdr->GetAutoplayList( pOut ); };
|
|
|
|
// inline int GetNumBoneControllers( void ) const { return m_pStudioHdr->numbonecontrollers; };
|
|
// inline mstudiobonecontroller_t *pBonecontroller( int i ) const { return m_pStudioHdr->pBonecontroller( i ); };
|
|
|
|
// inline int numikchains() const { return m_pStudioHdr->numikchains; };
|
|
// inline int GetNumIKChains( void ) const { return m_pStudioHdr->numikchains; };
|
|
// inline mstudioikchain_t *pIKChain( int i ) const { return m_pStudioHdr->pIKChain( i ); };
|
|
|
|
// inline int numflexrules() const { return m_pStudioHdr->numflexrules; };
|
|
// inline mstudioflexrule_t *pFlexRule( int i ) const { return m_pStudioHdr->pFlexRule( i ); };
|
|
|
|
// inline int numflexdesc() const{ return m_pStudioHdr->numflexdesc; };
|
|
// inline mstudioflexdesc_t *pFlexdesc( int i ) const { return m_pStudioHdr->pFlexdesc( i ); };
|
|
|
|
// inline LocalFlexController_t numflexcontrollers() const{ return (LocalFlexController_t)m_pStudioHdr->numflexcontrollers; };
|
|
// inline mstudioflexcontroller_t *pFlexcontroller( LocalFlexController_t i ) const { return m_pStudioHdr->pFlexcontroller( i ); };
|
|
|
|
// inline int numflexcontrollerui() const{ return m_pStudioHdr->numflexcontrollerui; };
|
|
// inline mstudioflexcontrollerui_t *pFlexcontrollerUI( int i ) const { return m_pStudioHdr->pFlexControllerUI( i ); };
|
|
|
|
// inline const char *name() const { return m_pStudioHdr->pszName(); }; // deprecated -- remove after full xbox merge
|
|
// inline const char *pszName() const { return m_pStudioHdr->pszName(); };
|
|
|
|
// inline int numbonecontrollers() const { return m_pStudioHdr->numbonecontrollers; };
|
|
|
|
// inline int numhitboxsets() const { return m_pStudioHdr->numhitboxsets; };
|
|
// inline mstudiohitboxset_t *pHitboxSet( int i ) const { return m_pStudioHdr->pHitboxSet( i ); };
|
|
|
|
// inline mstudiobbox_t *pHitbox( int i, int set ) const { return m_pStudioHdr->pHitbox( i, set ); };
|
|
// inline int iHitboxCount( int set ) const { return m_pStudioHdr->iHitboxCount( set ); };
|
|
|
|
// inline int numbodyparts() const { return m_pStudioHdr->numbodyparts; };
|
|
// inline mstudiobodyparts_t *pBodypart( int i ) const { return m_pStudioHdr->pBodypart( i ); };
|
|
|
|
// inline int numskinfamilies() const { return m_pStudioHdr->numskinfamilies; }
|
|
|
|
// inline Vector eyeposition() const { return m_pStudioHdr->eyeposition; };
|
|
|
|
// inline int flags() const { return m_pStudioHdr->flags; };
|
|
|
|
// inline char *const pszSurfaceProp( void ) const { return m_pStudioHdr->pszSurfaceProp(); };
|
|
// inline int GetSurfaceProp()const { return m_pStudioHdr->surfacepropLookup; }
|
|
|
|
// inline float mass() const { return m_pStudioHdr->mass; };
|
|
// inline int contents() const { return m_pStudioHdr->contents; }
|
|
|
|
// inline const byte *GetBoneTableSortedByName() const { return m_pStudioHdr->GetBoneTableSortedByName(); };
|
|
|
|
// inline Vector illumposition() const { return m_pStudioHdr->illumposition; };
|
|
|
|
// inline Vector hull_min() const { return m_pStudioHdr->hull_min; }; // ideal movement hull size
|
|
// inline Vector hull_max() const { return m_pStudioHdr->hull_max; };
|
|
|
|
// inline Vector view_bbmin() const { return m_pStudioHdr->view_bbmin; }; // clipping bounding box
|
|
// inline Vector view_bbmax() const { return m_pStudioHdr->view_bbmax; };
|
|
|
|
// inline int numtextures() const { return m_pStudioHdr->numtextures; };
|
|
|
|
// inline int IllumPositionAttachmentIndex() const { return m_pStudioHdr->IllumPositionAttachmentIndex(); }
|
|
|
|
// inline float MaxEyeDeflection() const { return m_pStudioHdr->MaxEyeDeflection(); }
|
|
|
|
// inline mstudiolinearbone_t *pLinearBones() const { return m_pStudioHdr->pLinearBones(); }
|
|
|
|
// inline int BoneFlexDriverCount() const { return m_pStudioHdr->BoneFlexDriverCount(); }
|
|
// inline const mstudioboneflexdriver_t *BoneFlexDriver( int i ) const { return m_pStudioHdr->BoneFlexDriver( i ); }
|
|
|
|
// public:
|
|
// int IsSequenceLooping( int iSequence );
|
|
// float GetSequenceCycleRate( int iSequence );
|
|
|
|
// void RunFlexRules( const float *src, float *dest );
|
|
// void RunFlexRulesOld( const float *src, float *dest );
|
|
// void RunFlexRulesNew( const float *src, float *dest );
|
|
|
|
|
|
// public:
|
|
// inline int boneFlags( int iBone ) const { return m_boneFlags[ iBone ]; }
|
|
// inline void setBoneFlags( int iBone, int flags ) { m_boneFlags[ iBone ] |= flags; }
|
|
// inline void clearBoneFlags( int iBone, int flags ) { m_boneFlags[ iBone ] &= ~flags; }
|
|
// inline int boneParent( int iBone ) const { return m_boneParent[ iBone ]; }
|
|
|
|
// private:
|
|
// CUtlVector< int > m_boneFlags;
|
|
// CUtlVector< int > m_boneParent;
|
|
|
|
// public:
|
|
|
|
// This class maps an activity to sequences allowed for that activity, accelerating the resolution
|
|
// of SelectWeightedSequence(), especially on PowerPC. Iterating through every sequence
|
|
// attached to a model turned out to be a very destructive cache access pattern on 360.
|
|
//
|
|
// I've encapsulated this behavior inside a nested class for organizational reasons; there is
|
|
// no particular programmatic or efficiency benefit to it. It just makes clearer what particular
|
|
// code in the otherwise very complicated StudioHdr class has to do with this particular
|
|
// optimization, and it lets you collapse the whole definition down to a single line in Visual
|
|
// Studio.
|
|
// class CActivityToSequenceMapping_PS3 /* final */
|
|
// {
|
|
// public:
|
|
// // A tuple of a sequence and its corresponding weight. Lists of these correspond to activities.
|
|
// struct SequenceTuple_PS3
|
|
// {
|
|
// short seqnum;
|
|
// short weight; // the absolute value of the weight from the sequence header
|
|
// CUtlSymbol *pActivityModifiers; // list of activity modifier symbols
|
|
// int iNumActivityModifiers;
|
|
// };
|
|
|
|
// The type of the hash's stored data, a composite of both key and value
|
|
// (because that's how CUtlHash works):
|
|
// key: an int, the activity #
|
|
// values: an index into the m_pSequenceTuples array, a count of the
|
|
// total sequences present for an activity, and the sum of their
|
|
// weights.
|
|
// Note this struct is 128-bits wide, exactly coincident to a PowerPC
|
|
// cache line and VMX register. Please consider very carefully the
|
|
// performance implications before adding any additional fields to this.
|
|
// You could probably do away with totalWeight if you really had to.
|
|
// struct HashValueType_PS3
|
|
// {
|
|
// // KEY (hashed)
|
|
// int activityIdx;
|
|
//
|
|
// // VALUE (not hashed)
|
|
// int startingIdx;
|
|
// int count;
|
|
// int totalWeight;
|
|
|
|
// HashValueType(int _actIdx, int _stIdx, int _ct, int _tW) :
|
|
// activityIdx(_actIdx), startingIdx(_stIdx), count(_ct), totalWeight(_tW) {}
|
|
|
|
// default constructor (ought not to be actually used)
|
|
// HashValueType() : activityIdx(-1), startingIdx(-1), count(-1), totalWeight(-1)
|
|
// { AssertMsg(false, "Don't use default HashValueType()!"); }
|
|
|
|
|
|
// class HashFuncs_PS3
|
|
// {
|
|
// public:
|
|
// // dummy constructor (gndn)
|
|
// HashFuncs_PS3( int ) {}
|
|
|
|
// COMPARE
|
|
// compare two entries for uniqueness. We should never have two different
|
|
// entries for the same activity, so we only compare the activity index;
|
|
// this allows us to use the utlhash as a dict by constructing dummy entries
|
|
// as hash lookup keys.
|
|
// bool operator()( const HashValueType &lhs, const HashValueType &rhs ) const
|
|
// {
|
|
// return lhs.activityIdx == rhs.activityIdx;
|
|
// }
|
|
|
|
// HASH
|
|
// We only hash on the activity index; everything else is data.
|
|
// unsigned int operator()( const HashValueType &item ) const
|
|
// {
|
|
// return HashInt( item.activityIdx );
|
|
// }
|
|
// };
|
|
// };
|
|
|
|
// typedef CUtlHash<HashValueType_PS3, HashValueType_PS3::HashFuncs_PS3, HashValueType_PS3::HashFuncs_PS3> ActivityToValueIdxHash_PS3;
|
|
|
|
// These must be here because IFM does not compile/link studio.cpp (?!?)
|
|
|
|
// ctor
|
|
// CActivityToSequenceMapping( void )
|
|
// : m_pSequenceTuples(NULL), m_iSequenceTuplesCount(0), m_ActToSeqHash(8,0,0), m_expectedVModel(NULL), m_pStudioHdr(NULL)
|
|
// {};
|
|
|
|
// dtor -- not virtual because this class has no inheritors
|
|
// ~CActivityToSequenceMapping()
|
|
// {
|
|
// if ( m_pSequenceTuples != NULL )
|
|
// {
|
|
// if ( m_pSequenceTuples->pActivityModifiers != NULL )
|
|
// {
|
|
// delete[] m_pSequenceTuples->pActivityModifiers;
|
|
// }
|
|
// delete[] m_pSequenceTuples;
|
|
// }
|
|
// }
|
|
|
|
/// Get the list of sequences for an activity. Returns the pointer to the
|
|
/// first sequence tuple. Output parameters are a count of sequences present,
|
|
/// and the total weight of all the sequences. (it would be more LHS-friendly
|
|
/// to return these on registers, if only C++ offered more than one return
|
|
/// value....)
|
|
// const SequenceTuple *GetSequences( int forActivity, int *outSequenceCount, int *outTotalWeight );
|
|
|
|
/// The number of sequences available for an activity.
|
|
// int NumSequencesForActivity( int forActivity );
|
|
|
|
// static CActivityToSequenceMapping *FindMapping( const CStudioHdr *pstudiohdr );
|
|
// static void ReleaseMapping( CActivityToSequenceMapping *pMap );
|
|
// static void ResetMappings();
|
|
|
|
// private:
|
|
|
|
/// Allocate my internal array. (It is freed in the destructor.) Also,
|
|
/// build the hash of activities to sequences and populate m_pSequenceTuples.
|
|
// void Initialize( const CStudioHdr *pstudiohdr );
|
|
|
|
/// Force Initialize() to occur again, even if it has already occured.
|
|
// void Reinitialize( CStudioHdr *pstudiohdr );
|
|
|
|
/// A more efficient version of the old SelectWeightedSequence() function in animation.cpp.
|
|
// int SelectWeightedSequence( CStudioHdr *pstudiohdr, int activity, int curSequence );
|
|
|
|
// selects the sequence with the most matching modifiers
|
|
// int SelectWeightedSequenceFromModifiers( CStudioHdr *pstudiohdr, int activity, CUtlSymbol *pActivityModifiers, int iModifierCount );
|
|
|
|
// Actually a big array, into which the hash values index.
|
|
// SequenceTuple_PS3 *m_pSequenceTuples;
|
|
// unsigned int m_iSequenceTuplesCount; // (size of the whole array)
|
|
|
|
// we don't store an outer pointer because we can't initialize it at construction time
|
|
// (warning c4355) -- there are ways around this but it's easier to just pass in a
|
|
// pointer to the CStudioHdr when we need it, since this class isn't supposed to
|
|
// export its interface outside the studio header anyway.
|
|
// CStudioHdr * const m_pOuter;
|
|
|
|
// ActivityToValueIdxHash_PS3 m_ActToSeqHash;
|
|
//
|
|
// const studiohdr_t_PS3 *m_pStudioHdr;
|
|
|
|
// we store these so we can know if the contents of the studiohdr have changed
|
|
// from underneath our feet (this is an emergency data integrity check)
|
|
// const void *m_expectedVModel;
|
|
|
|
|
|
// double-check that the data I point to hasn't changed
|
|
// bool ValidateAgainst( const CStudioHdr * RESTRICT pstudiohdr ) RESTRICT;
|
|
// void SetValidation( const CStudioHdr *RESTRICT pstudiohdr ) RESTRICT;
|
|
|
|
// friend class CStudioHdr_PS3;
|
|
// };
|
|
|
|
// CActivityToSequenceMapping_PS3 *m_pActivityToSequence;
|
|
|
|
// void InitActivityToSequence()
|
|
// {
|
|
// if ( !m_pActivityToSequence )
|
|
// {
|
|
// m_pActivityToSequence = CActivityToSequenceMapping::FindMapping( this );
|
|
// }
|
|
// }
|
|
|
|
/// A more efficient version of the old SelectWeightedSequence() function in animation.cpp.
|
|
/// Returns -1 on failure to find a sequence
|
|
// inline int SelectWeightedSequence( int activity, int curSequence )
|
|
// {
|
|
// InitActivityToSequence();
|
|
// return m_pActivityToSequence->SelectWeightedSequence( this, activity, curSequence );
|
|
// }
|
|
|
|
// inline int SelectWeightedSequenceFromModifiers( int activity, CUtlSymbol *pActivityModifiers, int iModifierCount )
|
|
// {
|
|
// InitActivityToSequence();
|
|
// return m_pActivityToSequence->SelectWeightedSequenceFromModifiers( this, activity, pActivityModifiers, iModifierCount );
|
|
// }
|
|
|
|
/// True iff there is at least one sequence for the given activity.
|
|
// inline bool HaveSequenceForActivity( int activity )
|
|
// {
|
|
// InitActivityToSequence();
|
|
// return (m_pActivityToSequence->NumSequencesForActivity( activity ) > 0);
|
|
// }
|
|
|
|
// Force this CStudioHdr's activity-to-sequence mapping to be reinitialized
|
|
// inline void ReinitializeSequenceMapping(void)
|
|
// {
|
|
// if ( m_pActivityToSequence )
|
|
// {
|
|
// CActivityToSequenceMapping::ReleaseMapping( m_pActivityToSequence );
|
|
// m_pActivityToSequence = NULL;
|
|
// }
|
|
// m_pActivityToSequence = CActivityToSequenceMapping::FindMapping( this );
|
|
// }
|
|
|
|
// #ifdef STUDIO_ENABLE_PERF_COUNTERS
|
|
// public:
|
|
// inline void ClearPerfCounters_PS3( void )
|
|
// {
|
|
// m_nPerfAnimatedBones = 0;
|
|
// m_nPerfUsedBones = 0;
|
|
// m_nPerfAnimationLayers = 0;
|
|
// };
|
|
//
|
|
// // timing info
|
|
// mutable int m_nPerfAnimatedBones;
|
|
// mutable int m_nPerfUsedBones;
|
|
// mutable int m_nPerfAnimationLayers;
|
|
// #endif
|
|
|
|
|
|
// };
|
|
|
|
/*
|
|
class CModelAccess
|
|
{
|
|
public:
|
|
CModelAccess(CStudioHdr *pSemaphore)
|
|
: m_pStudioHdr(pSemaphore)
|
|
{
|
|
m_pStudioHdr->IncrementAccess();
|
|
}
|
|
|
|
~CModelAccess()
|
|
{
|
|
m_pStudioHdr->DecrementAccess();
|
|
}
|
|
|
|
private:
|
|
CStudioHdr *m_pStudioHdr;
|
|
};
|
|
|
|
#define ENABLE_MODEL_ACCESS( a ) \
|
|
CModelAccess ModelAccess##__LINE__( a->m_pStudioHdr )
|
|
*/
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// struct flexweight_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
// int key;
|
|
// float weight;
|
|
// float influence;
|
|
// };
|
|
//
|
|
// struct flexsetting_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
// int nameindex;
|
|
//
|
|
// inline char *pszName( void ) const
|
|
// {
|
|
// return (char *)(((byte *)this) + nameindex);
|
|
// }
|
|
//
|
|
// // Leaving this for legacy support
|
|
// int obsolete1;
|
|
//
|
|
// // Number of flex settings
|
|
// int numsettings;
|
|
// int index;
|
|
//
|
|
// // OBSOLETE:
|
|
// int obsolete2;
|
|
//
|
|
// // Index of start of contiguous array of flexweight_t structures
|
|
// int settingindex;
|
|
//
|
|
// //-----------------------------------------------------------------------------
|
|
// // Purpose: Retrieves a pointer to the flexweight_t, including resolving
|
|
// // any markov chain hierarchy. Because of this possibility, we return
|
|
// // the number of settings in the weights array returned. We'll generally
|
|
// // call this function with i == 0
|
|
// // Input : *base -
|
|
// // i -
|
|
// // **weights -
|
|
// // Output : int
|
|
// //-----------------------------------------------------------------------------
|
|
// inline int psetting( byte *base, int i, flexweight_t **weights ) const;
|
|
// };
|
|
//
|
|
//
|
|
// struct flexsettinghdr_t
|
|
// {
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
// int id;
|
|
// int version;
|
|
//
|
|
// inline const char * pszName( void ) const { return name; }
|
|
// char name[64];
|
|
// int length;
|
|
//
|
|
// int numflexsettings;
|
|
// int flexsettingindex;
|
|
// inline flexsetting_t *pSetting( int i ) const { return (flexsetting_t *)(((byte *)this) + flexsettingindex) + i; };
|
|
// int nameindex;
|
|
//
|
|
// // look up flex settings by "index"
|
|
// int numindexes;
|
|
// int indexindex;
|
|
//
|
|
// inline flexsetting_t *pIndexedSetting( int index ) const
|
|
// {
|
|
// if ( index < 0 || index >= numindexes )
|
|
// {
|
|
// return NULL;
|
|
// }
|
|
//
|
|
// int i = *((int *)(((byte *)this) + indexindex) + index);
|
|
//
|
|
// if (i == -1)
|
|
// {
|
|
// return NULL;
|
|
// }
|
|
//
|
|
// return pSetting( i );
|
|
// }
|
|
//
|
|
// // index names of "flexcontrollers"
|
|
// int numkeys;
|
|
// int keynameindex;
|
|
// inline char *pLocalName( int i ) const { return (char *)(((byte *)this) + *((int *)(((byte *)this) + keynameindex) + i)); };
|
|
//
|
|
// int keymappingindex;
|
|
// inline int *pLocalToGlobal( int i ) const { return (int *)(((byte *)this) + keymappingindex) + i; };
|
|
// inline int LocalToGlobal( int i ) const { return *pLocalToGlobal( i ); };
|
|
// };
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Retrieves a pointer to the flexweight_t.
|
|
// Input : *base - flexsettinghdr_t * pointer
|
|
// i - index of flex setting to retrieve
|
|
// **weights - destination for weights array starting at index i.
|
|
// Output : int
|
|
//-----------------------------------------------------------------------------
|
|
// inline int flexsetting_t::psetting( byte *base, int i, flexweight_t **weights ) const
|
|
// {
|
|
// // Grab array pointer
|
|
// *weights = (flexweight_t *)(((byte *)this) + settingindex) + i;
|
|
// // Return true number of settings
|
|
// return numsettings;
|
|
// };
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// For a given flex controller ui struct, these return the index of the
|
|
// studiohdr_t flex controller that correspond to the the left and right
|
|
// flex controllers if the ui controller is a stereo control.
|
|
// nWayValueIndex returns the index of the flex controller that is the value
|
|
// flex controller for an NWAY combination
|
|
// If these functions are called and the ui controller isn't of the type
|
|
// specified then -1 is returned
|
|
//-----------------------------------------------------------------------------
|
|
// inline int mstudioflexcontrollerui_t::controllerIndex( const CStudioHdr &cStudioHdr ) const
|
|
// {
|
|
// return !stereo ? pController() - cStudioHdr.pFlexcontroller( (LocalFlexController_t)0 ) : -1;
|
|
// }
|
|
//
|
|
//
|
|
// inline int mstudioflexcontrollerui_t::rightIndex( const CStudioHdr &cStudioHdr ) const
|
|
// {
|
|
// return stereo ? pRightController() - cStudioHdr.pFlexcontroller( (LocalFlexController_t)0 ) : -1;
|
|
// }
|
|
//
|
|
//
|
|
// inline int mstudioflexcontrollerui_t::leftIndex( const CStudioHdr &cStudioHdr ) const
|
|
// {
|
|
// return stereo ? pLeftController() - cStudioHdr.pFlexcontroller((LocalFlexController_t) 0 ) : -1;
|
|
// }
|
|
//
|
|
//
|
|
// inline int mstudioflexcontrollerui_t::nWayValueIndex( const CStudioHdr &cStudioHdr ) const
|
|
// {
|
|
// return remaptype == FLEXCONTROLLER_REMAP_NWAY ? pNWayValueController() - cStudioHdr.pFlexcontroller( (LocalFlexController_t)0 ) : -1;
|
|
// }
|
|
|
|
|
|
// inline const mstudioflexcontroller_t *mstudioflexcontrollerui_t::pController( int index ) const
|
|
// {
|
|
// if ( index < 0 || index > Count() )
|
|
// return NULL;
|
|
//
|
|
// if ( remaptype == FLEXCONTROLLER_REMAP_NWAY )
|
|
// {
|
|
// if ( stereo )
|
|
// return (mstudioflexcontroller_t *)( ( char * ) this ) + *( &szindex0 + index );
|
|
//
|
|
// if ( index == 0 )
|
|
// return pController();
|
|
//
|
|
// if ( index == 1 )
|
|
// return pNWayValueController();
|
|
//
|
|
// return NULL;
|
|
// }
|
|
//
|
|
// if ( index > 1 )
|
|
// return NULL;
|
|
//
|
|
// if ( stereo )
|
|
// return (mstudioflexcontroller_t *)( ( char * ) this ) + *( &szindex0 + index );
|
|
//
|
|
// if ( index > 0 )
|
|
// return NULL;
|
|
//
|
|
// return pController();
|
|
// }
|
|
|
|
|
|
// #define STUDIO_CONST 1 // get float
|
|
// #define STUDIO_FETCH1 2 // get Flexcontroller value
|
|
// #define STUDIO_FETCH2 3 // get flex weight
|
|
// #define STUDIO_ADD 4
|
|
// #define STUDIO_SUB 5
|
|
// #define STUDIO_MUL 6
|
|
// #define STUDIO_DIV 7
|
|
// #define STUDIO_NEG 8 // not implemented
|
|
// #define STUDIO_EXP 9 // not implemented
|
|
// #define STUDIO_OPEN 10 // only used in token parsing
|
|
// #define STUDIO_CLOSE 11
|
|
// #define STUDIO_COMMA 12 // only used in token parsing
|
|
// #define STUDIO_MAX 13
|
|
// #define STUDIO_MIN 14
|
|
// #define STUDIO_2WAY_0 15 // Fetch a value from a 2 Way slider for the 1st value RemapVal( 0.0, 0.5, 0.0, 1.0 )
|
|
// #define STUDIO_2WAY_1 16 // Fetch a value from a 2 Way slider for the 2nd value RemapVal( 0.5, 1.0, 0.0, 1.0 )
|
|
// #define STUDIO_NWAY 17 // Fetch a value from a 2 Way slider for the 2nd value RemapVal( 0.5, 1.0, 0.0, 1.0 )
|
|
// #define STUDIO_COMBO 18 // Perform a combo operation (essentially multiply the last N values on the stack)
|
|
// #define STUDIO_DOMINATE 19 // Performs a combination domination operation
|
|
// #define STUDIO_DME_LOWER_EYELID 20 //
|
|
// #define STUDIO_DME_UPPER_EYELID 21 //
|
|
//
|
|
// // motion flags
|
|
// #define STUDIO_X 0x00000001
|
|
// #define STUDIO_Y 0x00000002
|
|
// #define STUDIO_Z 0x00000004
|
|
// #define STUDIO_XR 0x00000008
|
|
// #define STUDIO_YR 0x00000010
|
|
// #define STUDIO_ZR 0x00000020
|
|
//
|
|
// #define STUDIO_LX 0x00000040
|
|
// #define STUDIO_LY 0x00000080
|
|
// #define STUDIO_LZ 0x00000100
|
|
// #define STUDIO_LXR 0x00000200
|
|
// #define STUDIO_LYR 0x00000400
|
|
// #define STUDIO_LZR 0x00000800
|
|
//
|
|
// #define STUDIO_LINEAR 0x00001000
|
|
//
|
|
// #define STUDIO_TYPES 0x0003FFFF
|
|
// #define STUDIO_RLOOP 0x00040000 // controller that wraps shortest distance
|
|
//
|
|
// // sequence and autolayer flags
|
|
// #define STUDIO_LOOPING 0x0001 // ending frame should be the same as the starting frame
|
|
// #define STUDIO_SNAP 0x0002 // do not interpolate between previous animation and this one
|
|
// #define STUDIO_DELTA 0x0004 // this sequence "adds" to the base sequences, not slerp blends
|
|
// #define STUDIO_AUTOPLAY 0x0008 // temporary flag that forces the sequence to always play
|
|
// #define STUDIO_POST 0x0010 //
|
|
// #define STUDIO_ALLZEROS 0x0020 // this animation/sequence has no real animation data
|
|
// #define STUDIO_FRAMEANIM 0x0040 // animation is encoded as by frame x bone instead of RLE bone x frame
|
|
// #define STUDIO_CYCLEPOSE 0x0080 // cycle index is taken from a pose parameter index
|
|
// #define STUDIO_REALTIME 0x0100 // cycle index is taken from a real-time clock, not the animations cycle index
|
|
|
|
// #define STUDIO_LOCAL 0x0200 // sequence has a local context sequence
|
|
|
|
// #define STUDIO_HIDDEN 0x0400 // don't show in default selection views
|
|
// #define STUDIO_OVERRIDE 0x0800 // a forward declared sequence (empty)
|
|
// #define STUDIO_ACTIVITY 0x1000 // Has been updated at runtime to activity index
|
|
// #define STUDIO_EVENT 0x2000 // Has been updated at runtime to event index on server
|
|
// #define STUDIO_WORLD 0x4000 // sequence blends in worldspace
|
|
// #define STUDIO_NOFORCELOOP 0x8000 // do not force the animation loop
|
|
// #define STUDIO_EVENT_CLIENT 0x10000 // Has been updated at runtime to event index on client
|
|
|
|
// autolayer flags
|
|
// 0x0001
|
|
// 0x0002
|
|
// 0x0004
|
|
// 0x0008
|
|
//#define STUDIO_AL_POST 0x0010 //
|
|
// 0x0020
|
|
//#define STUDIO_AL_SPLINE 0x0040 // convert layer ramp in/out curve is a spline instead of linear
|
|
//#define STUDIO_AL_XFADE 0x0080 // pre-bias the ramp curve to compense for a non-1 weight, assuming a second layer is also going to accumulate
|
|
// 0x0100
|
|
//#define STUDIO_AL_NOBLEND 0x0200 // animation always blends at 1.0 (ignores weight)
|
|
// 0x0400
|
|
// 0x0800
|
|
//#define STUDIO_AL_LOCAL 0x1000 // layer is a local context sequence
|
|
// 0x2000
|
|
//#define STUDIO_AL_POSE 0x4000 // layer blends using a pose parameter instead of parent cycle
|
|
|
|
|
|
// Insert this code anywhere that you need to allow for conversion from an old STUDIO_VERSION to a new one.
|
|
// If we only support the current version, this function should be empty.
|
|
// inline bool Studio_ConvertStudioHdrToNewVersion( studiohdr_t *pStudioHdr )
|
|
// {
|
|
// COMPILE_TIME_ASSERT( STUDIO_VERSION == 49 ); // put this to make sure this code is updated upon changing version.
|
|
//
|
|
// int version = pStudioHdr->version;
|
|
// if ( version == STUDIO_VERSION )
|
|
// return true;
|
|
//
|
|
// bool bResult = true;
|
|
// if (version < 46)
|
|
// {
|
|
// // some of the anim index data is incompatible
|
|
// for (int i = 0; i < pStudioHdr->numlocalanim; i++)
|
|
// {
|
|
// mstudioanimdesc_t *pAnim = (mstudioanimdesc_t *)pStudioHdr->pLocalAnimdesc( i );
|
|
//
|
|
// // old ANI files that used sections (v45 only) are not compatible
|
|
// if ( pAnim->sectionframes != 0 )
|
|
// {
|
|
// // zero most everything out
|
|
// memset( &(pAnim->numframes), 0, (byte *)(pAnim + 1) - (byte *)&(pAnim->numframes) );
|
|
//
|
|
// pAnim->numframes = 1;
|
|
// pAnim->animblock = -1; // disable animation fetching
|
|
// bResult = false;
|
|
// }
|
|
// }
|
|
// }
|
|
//
|
|
// if (version < 47)
|
|
// {
|
|
// // now used to contain zeroframe cache data, make sure it's empty
|
|
// if (pStudioHdr->unused4 != 0)
|
|
// {
|
|
// pStudioHdr->unused4 = 0;
|
|
// bResult = false;
|
|
// }
|
|
// for (int i = 0; i < pStudioHdr->numlocalanim; i++)
|
|
// {
|
|
// mstudioanimdesc_t *pAnim = (mstudioanimdesc_t *)pStudioHdr->pLocalAnimdesc( i );
|
|
// pAnim->zeroframeindex = 0;
|
|
// pAnim->zeroframespan = 0;
|
|
// }
|
|
// }
|
|
// else if (version == 47)
|
|
// {
|
|
// // clear out stale version of zeroframe cache data
|
|
// for (int i = 0; i < pStudioHdr->numlocalanim; i++)
|
|
// {
|
|
// mstudioanimdesc_t *pAnim = (mstudioanimdesc_t *)pStudioHdr->pLocalAnimdesc( i );
|
|
// if (pAnim->zeroframeindex != 0)
|
|
// {
|
|
// pAnim->zeroframeindex = 0;
|
|
// pAnim->zeroframespan = 0;
|
|
// bResult = false;
|
|
// }
|
|
// }
|
|
// }
|
|
//
|
|
// if (version < 49)
|
|
// {
|
|
// // remove any frameanim flag settings that might be stale
|
|
// for (int i = 0; i < pStudioHdr->numlocalanim; i++)
|
|
// {
|
|
// mstudioanimdesc_t *pAnim = (mstudioanimdesc_t *)pStudioHdr->pLocalAnimdesc( i );
|
|
// if (pAnim->flags & STUDIO_FRAMEANIM)
|
|
// {
|
|
// pAnim->flags &= ~STUDIO_FRAMEANIM;
|
|
// bResult = false;
|
|
// }
|
|
// }
|
|
// }
|
|
// // for now, just slam the version number since they're compatible
|
|
// pStudioHdr->version = STUDIO_VERSION;
|
|
//
|
|
// return bResult;
|
|
// }
|
|
|
|
// must be run to fixup with specified rootLOD
|
|
// inline void Studio_SetRootLOD( studiohdr_t *pStudioHdr, int rootLOD )
|
|
// {
|
|
// // honor studiohdr restriction of root lod in case requested root lod exceeds restriction.
|
|
// if ( pStudioHdr->numAllowedRootLODs > 0 &&
|
|
// rootLOD >= pStudioHdr->numAllowedRootLODs )
|
|
// {
|
|
// rootLOD = pStudioHdr->numAllowedRootLODs - 1;
|
|
// }
|
|
//
|
|
// // run the lod fixups that culls higher detail lods
|
|
// // vertexes are external, fixups ensure relative offsets and counts are cognizant of shrinking data
|
|
// // indexes are built in lodN..lod0 order so higher detail lod data can be truncated at load
|
|
// // the fixup lookup arrays are filled (or replicated) to ensure all slots valid
|
|
// int vertexindex = 0;
|
|
// int tangentsindex = 0;
|
|
// int bodyPartID;
|
|
// for ( bodyPartID = 0; bodyPartID < pStudioHdr->numbodyparts; bodyPartID++ )
|
|
// {
|
|
// mstudiobodyparts_t *pBodyPart = pStudioHdr->pBodypart( bodyPartID );
|
|
// int modelID;
|
|
// for ( modelID = 0; modelID < pBodyPart->nummodels; modelID++ )
|
|
// {
|
|
// mstudiomodel_t *pModel = pBodyPart->pModel( modelID );
|
|
// int totalMeshVertexes = 0;
|
|
// int meshID;
|
|
// for ( meshID = 0; meshID < pModel->nummeshes; meshID++ )
|
|
// {
|
|
// mstudiomesh_t *pMesh = pModel->pMesh( meshID );
|
|
//
|
|
// // get the fixup, vertexes are reduced
|
|
// pMesh->numvertices = pMesh->vertexdata.numLODVertexes[rootLOD];
|
|
// pMesh->vertexoffset = totalMeshVertexes;
|
|
// totalMeshVertexes += pMesh->numvertices;
|
|
// }
|
|
//
|
|
// // stay in sync
|
|
// pModel->numvertices = totalMeshVertexes;
|
|
// pModel->vertexindex = vertexindex;
|
|
// pModel->tangentsindex = tangentsindex;
|
|
//
|
|
// vertexindex += totalMeshVertexes*sizeof(mstudiovertex_t);
|
|
// tangentsindex += totalMeshVertexes*sizeof(Vector4D);
|
|
// }
|
|
// }
|
|
//
|
|
// // track the set desired configuration
|
|
// pStudioHdr->rootLOD = rootLOD;
|
|
// }
|
|
|
|
// Determines allocation requirements for vertexes
|
|
// inline int Studio_VertexDataSize( const vertexFileHeader_t *pVvdHdr, int rootLOD, bool bNeedsTangentS )
|
|
// {
|
|
// // the quantity of vertexes necessary for root lod and all lower detail lods
|
|
// // add one extra vertex to each section
|
|
// // the extra vertex allows prefetch hints to read ahead 1 vertex without faulting
|
|
// int numVertexes = pVvdHdr->numLODVertexes[rootLOD] + 1;
|
|
// int dataLength = pVvdHdr->vertexDataStart + numVertexes*sizeof(mstudiovertex_t);
|
|
// if (bNeedsTangentS)
|
|
// {
|
|
// dataLength += numVertexes*sizeof(Vector4D);
|
|
// #ifdef _PS3
|
|
// if ( !pVvdHdr->numFixups && ( pVvdHdr->ps3edgeDmaInputDesc & 0x80000000 ) )
|
|
// {
|
|
// // PS3 does not support root lod, so all vertexes will be used
|
|
// dataLength = pVvdHdr->GetPs3EdgeDmaInputStart() + pVvdHdr->GetPs3EdgeDmaInputLength();
|
|
// }
|
|
// #endif
|
|
// }
|
|
//
|
|
// // allocate this much
|
|
// return dataLength;
|
|
// }
|
|
|
|
// Load the minimum quantity of verts and run fixups
|
|
// inline int Studio_LoadVertexes( const vertexFileHeader_t *pTempVvdHdr, vertexFileHeader_t *pNewVvdHdr, int rootLOD, bool bNeedsTangentS )
|
|
// {
|
|
// int i;
|
|
// int target;
|
|
// int numVertexes;
|
|
// vertexFileFixup_t *pFixupTable;
|
|
//
|
|
// numVertexes = pTempVvdHdr->numLODVertexes[rootLOD];
|
|
//
|
|
// // copy all data up to start of vertexes
|
|
// memcpy((void*)pNewVvdHdr, (void*)pTempVvdHdr, pTempVvdHdr->vertexDataStart);
|
|
//
|
|
// for ( i = 0; i < rootLOD; i++)
|
|
// {
|
|
// pNewVvdHdr->numLODVertexes[i] = pNewVvdHdr->numLODVertexes[rootLOD];
|
|
// }
|
|
//
|
|
// // fixup data starts
|
|
// if (bNeedsTangentS)
|
|
// {
|
|
// // tangent data follows possibly reduced vertex data
|
|
// pNewVvdHdr->tangentDataStart = pNewVvdHdr->vertexDataStart + numVertexes*sizeof(mstudiovertex_t);
|
|
//
|
|
// #ifdef _PS3
|
|
// // PS3 does not support root LOD, so all vertices will be available
|
|
// if ( !pTempVvdHdr->numFixups && ( pTempVvdHdr->ps3edgeDmaInputDesc & 0x80000000 ) )
|
|
// {
|
|
// pNewVvdHdr->ps3edgeDmaInputDesc = pTempVvdHdr->ps3edgeDmaInputDesc;
|
|
// }
|
|
// else
|
|
// {
|
|
// pNewVvdHdr->ps3edgeDmaInputDesc = 0;
|
|
// }
|
|
// #endif
|
|
// }
|
|
// else
|
|
// {
|
|
// // no tangent data will be available, mark for identification
|
|
// pNewVvdHdr->tangentDataStart = 0;
|
|
//
|
|
// #ifdef _PS3
|
|
// pNewVvdHdr->ps3edgeDmaInputDesc = 0;
|
|
// #endif
|
|
// }
|
|
//
|
|
// if (!pNewVvdHdr->numFixups)
|
|
// {
|
|
// // fixups not required
|
|
// // transfer vertex data
|
|
// memcpy(
|
|
// (byte *)pNewVvdHdr+pNewVvdHdr->vertexDataStart,
|
|
// (byte *)pTempVvdHdr+pTempVvdHdr->vertexDataStart,
|
|
// numVertexes*sizeof(mstudiovertex_t) );
|
|
//
|
|
// if (bNeedsTangentS)
|
|
// {
|
|
// // transfer tangent data to cache memory
|
|
// memcpy(
|
|
// (byte *)pNewVvdHdr+pNewVvdHdr->tangentDataStart,
|
|
// (byte *)pTempVvdHdr+pTempVvdHdr->tangentDataStart,
|
|
// numVertexes*sizeof(Vector4D) );
|
|
//
|
|
// #ifdef _PS3
|
|
// if ( pNewVvdHdr->ps3edgeDmaInputDesc )
|
|
// {
|
|
// // transfer EDGE DMA INPUT to cache memory
|
|
// memcpy(
|
|
// const_cast< byte* >( pNewVvdHdr->GetPs3EdgeDmaInput() ),
|
|
// pTempVvdHdr->GetPs3EdgeDmaInput(),
|
|
// pTempVvdHdr->GetPs3EdgeDmaInputLength()
|
|
// );
|
|
// }
|
|
// #endif
|
|
// }
|
|
//
|
|
// return numVertexes;
|
|
// }
|
|
//
|
|
// // fixups required
|
|
// // re-establish mesh ordered vertexes into cache memory, according to table
|
|
// target = 0;
|
|
// pFixupTable = (vertexFileFixup_t *)((byte *)pTempVvdHdr + pTempVvdHdr->fixupTableStart);
|
|
// for (i=0; i<pTempVvdHdr->numFixups; i++)
|
|
// {
|
|
// if (pFixupTable[i].lod < rootLOD)
|
|
// {
|
|
// // working bottom up, skip over copying higher detail lods
|
|
// continue;
|
|
// }
|
|
//
|
|
// // copy vertexes
|
|
// memcpy(
|
|
// (mstudiovertex_t *)((byte *)pNewVvdHdr+pNewVvdHdr->vertexDataStart) + target,
|
|
// (mstudiovertex_t *)((byte *)pTempVvdHdr+pTempVvdHdr->vertexDataStart) + pFixupTable[i].sourceVertexID,
|
|
// pFixupTable[i].numVertexes*sizeof(mstudiovertex_t) );
|
|
//
|
|
// if (bNeedsTangentS)
|
|
// {
|
|
// // copy tangents
|
|
// memcpy(
|
|
// (Vector4D *)((byte *)pNewVvdHdr+pNewVvdHdr->tangentDataStart) + target,
|
|
// (Vector4D *)((byte *)pTempVvdHdr+pTempVvdHdr->tangentDataStart) + pFixupTable[i].sourceVertexID,
|
|
// pFixupTable[i].numVertexes*sizeof(Vector4D) );
|
|
// }
|
|
//
|
|
// // data is placed consecutively
|
|
// target += pFixupTable[i].numVertexes;
|
|
// }
|
|
//
|
|
// pNewVvdHdr->numFixups = 0;
|
|
// pNewVvdHdr->fixupTableStart = 0; // otherwise PS3 will be confusing it for EDGE DMA INPUT
|
|
//
|
|
// return target;
|
|
// }
|
|
|
|
|
|
#endif // STUDIO__PS3_H
|