mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
1063 lines
28 KiB
C++
1063 lines
28 KiB
C++
#ifndef STUDIO_H
|
|
#define STUDIO_H
|
|
#include "mathlib/mathlib.h"
|
|
|
|
#define MAX_NUM_LODS 8
|
|
|
|
// 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 )
|
|
|
|
// NOTE: This flag is set when we need to draw in the additive stage of the deferred rendering
|
|
#define STUDIOHDR_FLAGS_NEEDS_DEFERRED_ADDITIVE ( 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 )
|
|
|
|
// This flag indicates that the model has complex weights, which allows it to have 3< weights per bone.
|
|
// PREVIOUSLY USED FOR: STUDIOHDR_FLAGS_FLEXES_CONVERTED
|
|
#define STUDIOHDR_FLAGS_COMPLEX_WEIGHTS ( 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 )
|
|
|
|
// unknown purpose but definitely exists
|
|
#define STUDIOHDR_FLAGS_RESPAWN_UNK (1 << 23) // 0x800000
|
|
|
|
// If this flag is present the model has vertex color, and by extension (previously) a VVC (IDVC) file.
|
|
#define STUDIOHDR_FLAGS_USES_VERTEX_COLOR (1 << 24) // 0x1000000
|
|
|
|
// If this flag is present the model has a secondary UV layer, and by extension (previously) a VVC (IDVC) file.
|
|
#define STUDIOHDR_FLAGS_USES_UV2 (1 << 25) // 0x2000000
|
|
|
|
enum
|
|
{
|
|
STUDIODATA_FLAGS_STUDIOMESH_LOADED = 0x0001,
|
|
STUDIODATA_FLAGS_VCOLLISION_LOADED = 0x0002,
|
|
STUDIODATA_ERROR_MODEL = 0x0004,
|
|
STUDIODATA_FLAGS_NO_STUDIOMESH = 0x0008,
|
|
STUDIODATA_FLAGS_NO_VERTEX_DATA = 0x0010,
|
|
// = 0x0020, // unused
|
|
STUDIODATA_FLAGS_PHYSICS2COLLISION_LOADED = 0x0040,
|
|
STUDIODATA_FLAGS_VCOLLISION_SCANNED = 0x0080,
|
|
|
|
STUDIODATA_FLAGS_COMBINED_PLACEHOLDER = 0x0100,
|
|
STUDIODATA_FLAGS_COMBINED = 0x0200,
|
|
STUDIODATA_FLAGS_COMBINED_UNAVAILABLE = 0x0400,
|
|
STUDIODATA_FLAGS_COMBINED_ASSET = 0x0800,
|
|
};
|
|
|
|
// intersection boxes
|
|
struct mstudiobbox_t
|
|
{
|
|
// DECLARE_BYTESWAP_DATADESC();
|
|
int bone;
|
|
int group; // intersection group
|
|
Vector3D bbmin; // bounding box
|
|
Vector3D bbmax;
|
|
int szhitboxnameindex; // offset to the name of the hitbox.
|
|
int critoverride; // overrides the group to be a crit, 0 or 1. might be group override since group 1 is head.
|
|
int keyvalueindex; // used for keyvalues, most for titans.
|
|
|
|
const char* pszHitboxName()
|
|
{
|
|
if (szhitboxnameindex == 0)
|
|
return "";
|
|
|
|
return ((const char*)this) + szhitboxnameindex;
|
|
}
|
|
|
|
mstudiobbox_t() {}
|
|
|
|
private:
|
|
// No copy constructors allowed
|
|
mstudiobbox_t(const mstudiobbox_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; };
|
|
};
|
|
|
|
#pragma pack(push, 1)
|
|
struct studiohdr_t
|
|
{
|
|
int id; // 'IDST'
|
|
int version; // R5 = '54'
|
|
int checksum;
|
|
int sznameindex; // This has been moved from studiohdr2 to the front of the main header.
|
|
|
|
char name[64];
|
|
|
|
int length; // size of data
|
|
|
|
Vector3D eyeposition; // ideal eye position
|
|
Vector3D illumposition; // illumination center
|
|
Vector3D hull_min; // ideal movement hull size
|
|
Vector3D hull_max;
|
|
Vector3D view_bbmin; // clipping bounding box
|
|
Vector3D view_bbmax;
|
|
|
|
int flags;
|
|
|
|
int numbones; // bones
|
|
int boneindex;
|
|
|
|
int numbonecontrollers;
|
|
int bonecontrollerindex;
|
|
|
|
int numhitboxsets;
|
|
int hitboxsetindex;
|
|
|
|
int numlocalanim; // animations/poses
|
|
int localanimindex; // animation descriptions
|
|
|
|
int numlocalseq; // sequences
|
|
int localseqindex;
|
|
|
|
int activitylistversion; // initialization flag - have the sequences been indexed ?
|
|
|
|
int materialtypesindex; // index into an array of byte sized material type enums for each material used by the model
|
|
int numtextures;
|
|
int textureindex;
|
|
|
|
int numcdtextures;
|
|
int cdtextureindex;
|
|
|
|
int numskinref; // Total number of references (submeshes)
|
|
int numskinfamilies; // Total skins per reference
|
|
int skinindex; // Offset to data
|
|
|
|
int numbodyparts;
|
|
int bodypartindex;
|
|
|
|
int numlocalattachments;
|
|
int localattachmentindex;
|
|
|
|
int numlocalnodes;
|
|
int localnodeindex;
|
|
int localnodenameindex;
|
|
|
|
int numunknodes; // ???
|
|
int nodedataindexindex; // index into an array of int sized offsets that read into the data for each node
|
|
|
|
int meshindex; // offset to model meshes
|
|
|
|
// all flex related model vars and structs are stripped in respawn source
|
|
int deprecated_numflexcontrollers;
|
|
int deprecated_flexcontrollerindex;
|
|
|
|
int deprecated_numflexrules;
|
|
int deprecated_flexruleindex;
|
|
|
|
int numikchains;
|
|
int ikchainindex;
|
|
|
|
// mesh panels for using rui on models, primarily for weapons
|
|
int numruimeshes;
|
|
int ruimeshindex;
|
|
|
|
int numlocalposeparameters;
|
|
int localposeparamindex;
|
|
|
|
int surfacepropindex;
|
|
|
|
int keyvalueindex;
|
|
int keyvaluesize;
|
|
|
|
int numlocalikautoplaylocks;
|
|
int localikautoplaylockindex;
|
|
|
|
float mass;
|
|
int contents;
|
|
|
|
// unused for packed models
|
|
// technically still functional though I am unsure why you'd want to use it
|
|
int numincludemodels;
|
|
int includemodelindex;
|
|
|
|
int virtualModel; // size placeholder
|
|
|
|
int bonetablebynameindex;
|
|
|
|
// 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;
|
|
|
|
float fadeDist; // fadeDistance
|
|
float gatherSize; // gathersize
|
|
|
|
int deprecated_numflexcontrollerui;
|
|
int deprecated_flexcontrolleruiindex;
|
|
|
|
float flVertAnimFixedPointScale; // to be verified
|
|
int surfacepropLookup; // saved in the file
|
|
|
|
int sourceFilenameOffset; // doesn't actually need to be written pretty sure, only four bytes when not present.
|
|
|
|
int numsrcbonetransform;
|
|
int srcbonetransformindex;
|
|
|
|
int illumpositionattachmentindex;
|
|
|
|
int linearboneindex;
|
|
|
|
// unsure what this is for but it exists for jigglbones
|
|
int numprocbones;
|
|
int procbonetableindex;
|
|
int linearprocboneindex;
|
|
|
|
// depreciated as they are removed in 12.1
|
|
int m_nBoneFlexDriverCount;
|
|
int m_nBoneFlexDriverIndex;
|
|
|
|
int m_nPerTriAABBIndex;
|
|
int m_nPerTriAABBNodeCount;
|
|
int m_nPerTriAABBLeafCount;
|
|
int m_nPerTriAABBVertCount;
|
|
|
|
// always "" or "Titan"
|
|
int unkstringindex;
|
|
|
|
// this is now used for combined files in rpak, vtx, vvd, and vvc are all combined while vphy is separate.
|
|
// the indexes are added to the offset in the rpak mdl_ header.
|
|
// vphy isn't vphy, looks like a heavily modified vphy.
|
|
int vtxindex; // VTX
|
|
int vvdindex; // VVD / IDSV
|
|
int vvcindex; // VVC / IDCV
|
|
int vphyindex; // VPHY / IVPS
|
|
|
|
int vtxsize;
|
|
int vvdsize;
|
|
int vvcsize;
|
|
int vphysize; // still used in models using vg
|
|
|
|
// unused in apex, gets cut in 12.1
|
|
int unkmemberindex1;
|
|
int numunkmember1;
|
|
|
|
// only seen on '_animated' suffixed models so far
|
|
int unkcount3;
|
|
int unkindex3;
|
|
|
|
// BVH4 size (?)
|
|
Vector3D mins;
|
|
Vector3D maxs; // seem to be the same as hull size
|
|
|
|
int unk3_v54[3];
|
|
|
|
int bvh4index; // bvh4 tree
|
|
|
|
short unk4_v54[2]; // same as unk3_v54_v121, 2nd might be base for other offsets?
|
|
|
|
// new in apex vertex weight file for verts that have more than three weights
|
|
int vvwindex; // index will come last after other vertex files
|
|
int vvwsize;
|
|
|
|
|
|
// Look up hitbox set by index
|
|
mstudiohitboxset_t* pHitboxSet(int i) const
|
|
{
|
|
Assert(i >= 0 && i < numhitboxsets);
|
|
return (mstudiohitboxset_t*)(((byte*)this) + hitboxsetindex) + i;
|
|
};
|
|
};
|
|
|
|
#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_BY_IKCHAIN 0x20 // bone is influenced by IK chains, added in V52 (Titanfall 1)
|
|
|
|
#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
|
|
|
|
// no longer used in apex from what I can tell
|
|
//#define BONE_USED_BY_BONE_MERGE 0x00040000 // bone is available for bone merge to occur against it
|
|
|
|
#define BONE_FLAG_UNK 0x00080000 // respawn flag
|
|
|
|
#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 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
|
|
// v48 -> v49 : BONE_HAS_SAVEFRAME_ROT -> BONE_HAS_SAVEFRAME_ROT64
|
|
#define BONE_HAS_SAVEFRAME_ROT64 0x00400000 // Quaternion64
|
|
#define BONE_HAS_SAVEFRAME_ROT32 0x00800000 // Quaternion32
|
|
|
|
struct mstudiobone_t
|
|
{
|
|
int sznameindex;
|
|
|
|
int parent; // parent bone
|
|
int bonecontroller[6]; // bone controller index, -1 == none
|
|
|
|
// default values
|
|
Vector3D pos;
|
|
Quaternion quat;
|
|
RadianEuler rot;
|
|
Vector3D scale; // bone scale(?)
|
|
|
|
matrix3x4_t poseToBone;
|
|
Quaternion qAlignment;
|
|
|
|
int flags;
|
|
int proctype;
|
|
int procindex; // procedural rule
|
|
int physicsbone; // index into physically simulated bone
|
|
|
|
int surfacepropidx; // index into string tablefor property name
|
|
|
|
int contents; // See BSPFlags.h for the contents flags
|
|
|
|
int surfacepropLookup; // written on compile in v54
|
|
|
|
int unk;
|
|
|
|
int unkid; // physics index (?)
|
|
};
|
|
|
|
struct mstudiojigglebone_t
|
|
{
|
|
byte flags; // looks to be.
|
|
|
|
unsigned char bone; // id of bone, might be single byte
|
|
|
|
short pad; // possibly unused
|
|
|
|
// general params
|
|
float length; // how far from bone base, along bone, is tip
|
|
float tipMass;
|
|
|
|
float unkfloat; // v54 adds an extra value here but otherwise the same
|
|
// observed values are between 0-1
|
|
|
|
// 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;
|
|
};
|
|
|
|
struct mstudioattachment_t
|
|
{
|
|
int sznameindex;
|
|
int flags;
|
|
|
|
int localbone; // parent bone
|
|
|
|
matrix3x4_t localmatrix; // attachment point
|
|
};
|
|
|
|
// 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_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
|
|
|
|
// new in respawn models
|
|
// PREVIOUSLY: STUDIO_FRAMEANIM
|
|
#define STUDIO_ANIM_UNK3 0x0040 // used on something that is clearly not a frame anim in v54
|
|
// animseq/humans/class/heavy/mp_pilot_heavy_core/mp_pt_crypto_base_execution_heavy_victim.rseq
|
|
#define STUDIO_ANIM_UNK 0x20000
|
|
#define STUDIO_ANIM_UNK1 0x40000
|
|
#define STUDIO_ANIM_UNK2 0x80000 // cherry blossom v53, levi in v54
|
|
|
|
struct mstudioanimdesc_t
|
|
{
|
|
int baseptr;
|
|
|
|
int sznameindex;
|
|
|
|
float fps; // frames per second
|
|
int flags; // looping/non-looping flags
|
|
|
|
int numframes;
|
|
|
|
// piecewise movement
|
|
int nummovements;
|
|
int movementindex;
|
|
|
|
int framemovementindex; // new in v52
|
|
|
|
int animindex; // non-zero when anim data isn't in sections
|
|
|
|
int numikrules;
|
|
int ikruleindex; // non-zero when IK data is stored in the mdl
|
|
|
|
int sectionindex;
|
|
int sectionframes; // number of frames used in each fast lookup section, zero if not used
|
|
};
|
|
|
|
struct mstudioanimsections_t
|
|
{
|
|
int animindex;
|
|
};
|
|
|
|
// flags for the per bone array, in 4 bit sections (two sets of flags per byte)
|
|
#define STUDIO_ANIM_POS 0x1 // animation has pos values
|
|
#define STUDIO_ANIM_ROT 0x2 // animation has rot values
|
|
#define STUDIO_ANIM_SCALE 0x4 // animation has scale values
|
|
|
|
// the actual animation values
|
|
union mstudioanimvalue_t
|
|
{
|
|
struct
|
|
{
|
|
byte valid; // number of valid frames, or how many frames of data this value has
|
|
byte total; // total number of frames, aka "values"
|
|
} num;
|
|
short value; // actual value, value*posscale
|
|
};
|
|
|
|
struct mstudioanim_valueptr_t
|
|
{
|
|
char packedoffsets[4]; // packing unknown
|
|
};
|
|
|
|
// flags for the actually per bone animation headers
|
|
// "mstudioanim_valueptr_t" indicates it has a set of offsets into anim tracks
|
|
#define STUDIO_ANIM_DELTA 0x01 // unverified, animation is additive
|
|
#define STUDIO_ANIM_ANIMSCALE 0x01 // mstudioanim_valueptr_t
|
|
#define STUDIO_ANIM_ANIMROT 0x02 // mstudioanim_valueptr_t
|
|
#define STUDIO_ANIM_ANIMPOS 0x04 // mstudioanim_valueptr_t
|
|
|
|
struct mstudio_rle_anim_t_v54
|
|
{
|
|
|
|
short size : 13; // total size of all animation data, not nextoffset because even the last one has it
|
|
|
|
short flags : 3;
|
|
|
|
// if flag 'STUDIO_ANIM_ANIMPOS' then these two
|
|
float posscale;
|
|
mstudioanim_valueptr_t pPosV;
|
|
// else (static value, no actual animation)
|
|
//Vector48 pPos; // type does not exist in R5SDK
|
|
|
|
|
|
// if flag 'STUDIO_ANIM_ANIMROT' then
|
|
mstudioanim_valueptr_t pRotV;
|
|
// else (static value, no actual animation)
|
|
//Quaternion64 pRot; // type does not exist in R5SDK
|
|
|
|
// if flag 'STUDIO_ANIM_ANIMSCALE' then
|
|
mstudioanim_valueptr_t pScaleV;
|
|
// else (static value, no actual animation)
|
|
//Vector48 pScale; // type does not exist in R5SDK
|
|
};
|
|
|
|
// apex ikerrors do the same thing as apex framemovements
|
|
struct mstudiocompressedikerror_t
|
|
{
|
|
float scale[6]; // these values are the same as what posscale (if it was used) and rotscale are.
|
|
int sectionframes; // frames per section, may not match animdesc
|
|
};
|
|
|
|
struct mstudioikrule_t
|
|
{
|
|
int index;
|
|
int type;
|
|
int chain;
|
|
int bone; // gets it from ikchain now pretty sure
|
|
|
|
int slot; // iktarget slot. Usually same as chain.
|
|
float height;
|
|
float radius;
|
|
float floor;
|
|
Vector3D pos;
|
|
Quaternion q;
|
|
|
|
// apex does this oddly
|
|
mstudiocompressedikerror_t compressedikerror;
|
|
int compressedikerrorindex;
|
|
|
|
int iStart;
|
|
int ikerrorindex;
|
|
|
|
float start; // beginning of influence
|
|
float peak; // start of full influence
|
|
float tail; // end of full influence
|
|
float end; // end of all influence
|
|
|
|
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 szattachmentindex; // name of world attachment
|
|
|
|
float endHeight; // new in v52
|
|
};
|
|
|
|
// basically compressedikerrors and frame movements will have an array of offsets that leads into the traditional 'short offset' array, allowing it to have per section (if the anim uses sections) data
|
|
struct mstudioframemovement_t
|
|
{
|
|
float scale[4]; // first three values are the same as what posscale (if it was used) is, fourth is similar to unkvector1.
|
|
int sectionframes; // frames per section, may not match animdesc
|
|
// may have more than one, even when not section anim
|
|
};
|
|
|
|
struct mstudioseqdesc_t
|
|
{
|
|
int baseptr;
|
|
|
|
int szlabelindex;
|
|
|
|
int szactivitynameindex;
|
|
|
|
int flags; // looping/non-looping flags
|
|
|
|
int activity; // initialized at loadtime to game DLL values
|
|
int actweight;
|
|
|
|
int numevents;
|
|
int eventindex;
|
|
|
|
Vector3D bbmin; // per sequence bounding box
|
|
Vector3D bbmax;
|
|
|
|
int numblends;
|
|
|
|
// Index into array of shorts which is groupsize[0] x groupsize[1] in length
|
|
int animindexindex;
|
|
|
|
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;
|
|
|
|
int weightlistindex;
|
|
|
|
int posekeyindex;
|
|
|
|
int numiklocks;
|
|
int iklockindex;
|
|
|
|
// Key values
|
|
int keyvalueindex;
|
|
int keyvaluesize;
|
|
|
|
int cycleposeindex; // index of pose parameter to use as cycle index
|
|
|
|
int activitymodifierindex;
|
|
int numactivitymodifiers;
|
|
|
|
int ikResetMask; // new in v52
|
|
int unk1;
|
|
|
|
// offset unkindex amount into an array of unkcount 'unkseqdata_t'
|
|
int unkindex;
|
|
int unkcount;
|
|
};
|
|
|
|
struct mstudioautolayer_t
|
|
{
|
|
// this needs to have a guid descriptor in rpak
|
|
__int64 guidSequence; // hashed aseq guid asset
|
|
|
|
short iSequence; // only used within an rmdl I would imagine
|
|
short iPose;
|
|
|
|
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
|
|
};
|
|
|
|
#define NEW_EVENT_STYLE ( 1 << 10 )
|
|
|
|
struct mstudioevent_t
|
|
{
|
|
float cycle;
|
|
int event;
|
|
int type; // this will be 0 if old style
|
|
char options[256];
|
|
|
|
int szeventindex;
|
|
};
|
|
|
|
// will align to four, so takes up eight bytes
|
|
struct mstudioactivitymodifier_t_v52
|
|
{
|
|
int sznameindex;
|
|
bool negate; // negate all other activity modifiers when this one is active?
|
|
};
|
|
|
|
struct unkseqdata_t
|
|
{
|
|
// generally 0-1
|
|
float unkfloat;
|
|
|
|
int unk;
|
|
|
|
// quaternion mayhaps
|
|
float unkfloat1;
|
|
float unkfloat2;
|
|
float unkfloat3;
|
|
float unkfloat4;
|
|
};
|
|
|
|
struct mstudiobodyparts_t
|
|
{
|
|
int sznameindex;
|
|
int nummodels;
|
|
int base;
|
|
int modelindex; // index into models array
|
|
};
|
|
|
|
struct mstudiomodel_t
|
|
{
|
|
char name[64];
|
|
|
|
int unkindex2; // goes to bones sometimes, string index
|
|
|
|
int type;
|
|
|
|
float boundingradius;
|
|
|
|
int nummeshes;
|
|
int meshindex;
|
|
|
|
// cache purposes
|
|
int numvertices; // number of unique vertices/normals/texcoords
|
|
int vertexindex; // vertex Vector
|
|
int tangentsindex; // tangents Vector
|
|
|
|
int numattachments;
|
|
int attachmentindex;
|
|
|
|
int deprecated_numeyeballs;
|
|
int deprecated_eyeballindex;
|
|
|
|
int pad[4];
|
|
|
|
int colorindex; // vertex color
|
|
// offset by colorindex number of bytes into vvc vertex colors
|
|
int uv2index; // vertex second uv map
|
|
// offset by uv2index number of bytes into vvc secondary uv map
|
|
};
|
|
|
|
struct mstudio_meshvertexloddata_t
|
|
{
|
|
int modelvertexdataUnusedPad; // likely has none of the funny stuff because unused
|
|
|
|
int numLODVertexes[MAX_NUM_LODS]; // depreciated starting with rmdl v14(?)
|
|
};
|
|
|
|
struct mstudiomesh_t
|
|
{
|
|
int material;
|
|
|
|
int modelindex;
|
|
|
|
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)
|
|
|
|
int deprecated_numflexes; // vertex animation
|
|
int deprecated_flexindex;
|
|
|
|
// special codes for material operations
|
|
int deprecated_materialtype;
|
|
int deprecated_materialparam;
|
|
|
|
// a unique ordinal for this mesh
|
|
int meshid;
|
|
|
|
Vector3D center;
|
|
|
|
mstudio_meshvertexloddata_t vertexloddata;
|
|
|
|
char unk[8]; // these are suposed to be filled on load, however this isn't true??
|
|
};
|
|
|
|
struct mstudioposeparamdesc_t
|
|
{
|
|
int sznameindex;
|
|
|
|
int flags; // ????
|
|
float start; // starting value
|
|
float end; // ending value
|
|
float loop; // looping range, 0 for no looping, 360 for rotations, etc.
|
|
};
|
|
|
|
struct mstudioikchain_t
|
|
{
|
|
int sznameindex;
|
|
|
|
int linktype;
|
|
int numlinks;
|
|
int linkindex;
|
|
|
|
float unk; // no clue what this does tbh, tweaking it does nothing
|
|
// default value: 0.707f
|
|
};
|
|
|
|
struct mstudioiklink_t
|
|
{
|
|
int bone;
|
|
Vector3D kneeDir; // no kneeDir in apex I think
|
|
};
|
|
|
|
struct mstudiotexturedir_t
|
|
{
|
|
int sznameindex; // file name
|
|
};
|
|
|
|
struct mstudiotexture_t
|
|
{
|
|
int sznameindex;
|
|
|
|
__int64 guid; // guid of the material it references
|
|
};
|
|
|
|
struct mstudiorruiheader_t
|
|
{
|
|
int unk; // unsure, it doesn't line up
|
|
int ruimeshindex; // offset to the actual rui mesh
|
|
};
|
|
|
|
// vertex map for a face
|
|
struct mstudioruivertmap_t
|
|
{
|
|
// order of vertices for triangles:
|
|
// 1st tri: 1-3-2
|
|
// 2nd tri: 4-2-3
|
|
|
|
// sometimes these are for a triangle instead of a quad, if that's the case then:
|
|
// tri: 1-4-2
|
|
// in this case the vert map will only cover 3 verts.
|
|
|
|
|
|
// in v53 the first two are an array like such:
|
|
// 1-3
|
|
// while the third is the fourth vert.
|
|
short vertid[3];
|
|
};
|
|
|
|
struct mstudioruivert_t
|
|
{
|
|
int parent; // relative to global mesh parent, assumed
|
|
|
|
Vector3D vertexpos; // position of vertex relative to bone
|
|
};
|
|
|
|
struct mstudioruimeshface_t
|
|
{
|
|
// this might be the same as the RPak UIMG UV struct.
|
|
|
|
// these values are for the two vertices that are not shared
|
|
// for the other do as such:
|
|
// vertex 2: take x from vextex 1 and y from vextex 4
|
|
// vertex 2: take x from vextex 4 and y from vextex 1
|
|
|
|
// normal smd uv, seems to calculate for other values
|
|
Vector2D faceuvmin; // vertex 1
|
|
Vector2D faceuvmax; // vertex 4
|
|
|
|
// these could likely be calculated by doing math with a height/width scale
|
|
// scale of the ui element
|
|
Vector2D facescalemin; // vertex 1
|
|
Vector2D facescalemax; // vertex 4
|
|
};
|
|
|
|
struct mstudioruimesh_t
|
|
{
|
|
short numparents; // apparently you can have meshes parented to more than one bone(?)
|
|
short numvertices; // number of verts
|
|
short numfaces; // number of faces (quads)
|
|
|
|
short unk; // num uvs? or this is num faces and current num faces is num uvs
|
|
|
|
int parentindex; // this gets padding out front of it to even off the struct
|
|
|
|
int vertexindex; // offset into smd style vertex data
|
|
// not actually fourth vert wtf??
|
|
int fourthvertmapindex; // they now fully map the vertices for each quad
|
|
int vertmapindex; // offsets into a vertex map for each quad
|
|
int facedataindex; // offset into uv section
|
|
};
|
|
|
|
struct mstudiosrcbonetransform_t
|
|
{
|
|
int sznameindex;
|
|
|
|
matrix3x4_t pretransform;
|
|
matrix3x4_t posttransform;
|
|
};
|
|
|
|
struct mstudiolinearbone_t
|
|
{
|
|
// they cut pos and rot scale, understandable since posscale was never used it tf|2 and they do anims different in apex
|
|
int numbones;
|
|
|
|
int flagsindex;
|
|
|
|
int parentindex;
|
|
|
|
int posindex;
|
|
|
|
int quatindex;
|
|
|
|
int rotindex;
|
|
|
|
int posetoboneindex;
|
|
};
|
|
|
|
struct BVH4Axis_t
|
|
{
|
|
short minChild0;
|
|
short maxChild0;
|
|
|
|
short minChild1;
|
|
short maxChild1;
|
|
|
|
short minChild2;
|
|
short maxChild2;
|
|
|
|
short minChild3;
|
|
short maxChild3;
|
|
};
|
|
|
|
struct BVH4Node_t
|
|
{
|
|
BVH4Axis_t x;
|
|
BVH4Axis_t y;
|
|
BVH4Axis_t z;
|
|
|
|
int pad : 8;
|
|
int index0 : 24;
|
|
|
|
int collision_mask : 8;
|
|
int index1 : 24;
|
|
|
|
int child0_type : 4;
|
|
int child1_type : 4;
|
|
int index2 : 24;
|
|
|
|
int child2_type : 4;
|
|
int child3_type : 4;
|
|
int index3 : 24;
|
|
};
|
|
|
|
#pragma pack(pop)
|
|
|
|
// studio model data
|
|
struct studiomeshdata_t
|
|
{
|
|
int m_NumGroup;
|
|
void* m_pMeshGroup; // studiomeshgroup_t
|
|
};
|
|
|
|
struct studioloddata_t
|
|
{
|
|
studiomeshdata_t* m_pMeshData;
|
|
// !TODO:
|
|
};
|
|
|
|
struct studiohwdata_t
|
|
{
|
|
int m_RootLOD; // calced and clamped, nonzero for lod culling
|
|
int m_NumLODs;
|
|
studioloddata_t* m_pLODs;
|
|
int m_NumStudioMeshes;
|
|
// !TODO:
|
|
};
|
|
|
|
class CStudioHdr
|
|
{
|
|
public:
|
|
static int LookupSequence(CStudioHdr* pStudio, const char* pszName);
|
|
inline mstudiohitboxset_t* pHitboxSet(int i) const { return m_pStudioHdr->pHitboxSet(i); };
|
|
|
|
void* vtbl;
|
|
studiohdr_t* m_pStudioHdr;
|
|
void* m_pVModel;
|
|
char gap0[156];
|
|
mstudiobbox_t m_pHitBox;
|
|
char gap_10[1896];
|
|
int m_nPerfAnimatedBones;
|
|
int m_nPerfUsedBones;
|
|
int m_nPerfAnimationLayers;
|
|
void* m_pMdlCacheVTable;
|
|
};
|
|
|
|
class CStudioHWDataRef
|
|
{
|
|
public:
|
|
bool IsDataRef(void) const { return true; }
|
|
|
|
CStudioHWDataRef* m_pVTable;
|
|
uint8_t pad0[0x8];
|
|
studiohwdata_t m_HardwareData;
|
|
};
|
|
|
|
#endif // STUDIO_H
|