xash3d-fwgs/engine/studio.h
Gleb Mazovetskiy 5e0a0765ce Trim all trailing whitespace
The `.editorconfig` file in this repo is configured to trim all trailing
whitespace regardless of whether the line is modified.

Trims all trailing whitespace in the repository to make the codebase easier
to work with in editors that respect `.editorconfig`.

`git blame` becomes less useful on these lines but it already isn't very useful.

Commands:

```
find . -type f -name '*.h' -exec sed --in-place 's/[[:space:]]\+$//' {} \+
find . -type f -name '*.c' -exec sed --in-place 's/[[:space:]]\+$//' {} \+
```
2021-01-04 20:55:10 +03:00

1004 lines
23 KiB
C

/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* Use, distribution, and modification of this source code and/or resulting
* object code is restricted to non-commercial enhancements to products from
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
#pragma once
#ifndef STUDIO_H
#define STUDIO_H
/*
==============================================================================
STUDIO MODELS
Studio models are position independent, so the cache manager can move them.
==============================================================================
*/
// header
#define STUDIO_VERSION 10
#define IDSTUDIOHEADER (('T'<<24)+('S'<<16)+('D'<<8)+'I') // little-endian "IDST"
#define IDSEQGRPHEADER (('Q'<<24)+('S'<<16)+('D'<<8)+'I') // little-endian "IDSQ"
// studio limits
#define MAXSTUDIOVERTS 16384 // max vertices per submodel
#define MAXSTUDIOSEQUENCES 256 // total animation sequences
#define MAXSTUDIOSKINS 256 // total textures
#define MAXSTUDIOSRCBONES 512 // bones allowed at source movement
#define MAXSTUDIOBONES 128 // total bones actually used
#define MAXSTUDIOMODELS 32 // sub-models per model
#define MAXSTUDIOBODYPARTS 32 // body parts per submodel
#define MAXSTUDIOGROUPS 16 // sequence groups (e.g. barney01.mdl, barney02.mdl, e.t.c)
#define MAXSTUDIOMESHES 256 // max textures per model
#define MAXSTUDIOCONTROLLERS 32 // max controllers per model
#define MAXSTUDIOATTACHMENTS 64 // max attachments per model
#define MAXSTUDIOBONEWEIGHTS 4 // absolute hardware limit!
#define MAXSTUDIONAME 32 // a part of specs
#define MAXSTUDIOPOSEPARAM 24
#define MAX_STUDIO_LIGHTMAP_SIZE 256 // must match with engine const!!!
// client-side model flags
#define STUDIO_ROCKET (1U<<0) // leave a trail
#define STUDIO_GRENADE (1U<<1) // leave a trail
#define STUDIO_GIB (1U<<2) // leave a trail
#define STUDIO_ROTATE (1U<<3) // rotate (bonus items)
#define STUDIO_TRACER (1U<<4) // green split trail
#define STUDIO_ZOMGIB (1U<<5) // small blood trail
#define STUDIO_TRACER2 (1U<<6) // orange split trail + rotate
#define STUDIO_TRACER3 (1U<<7) // purple trail
#define STUDIO_AMBIENT_LIGHT (1U<<8) // force to use ambient shading
#define STUDIO_TRACE_HITBOX (1U<<9) // always use hitbox trace instead of bbox
#define STUDIO_FORCE_SKYLIGHT (1U<<10) // always grab lightvalues from the sky settings (even if sky is invisible)
#define STUDIO_HAS_BUMP (1U<<16) // loadtime set
#define STUDIO_STATIC_PROP (1U<<29) // hint for engine
#define STUDIO_HAS_BONEINFO (1U<<30) // extra info about bones (pose matrix, procedural index etc)
#define STUDIO_HAS_BONEWEIGHTS (1U<<31) // yes we got support of bone weighting
// lighting & rendermode options
#define STUDIO_NF_FLATSHADE 0x0001
#define STUDIO_NF_CHROME 0x0002
#define STUDIO_NF_FULLBRIGHT 0x0004
#define STUDIO_NF_NOMIPS 0x0008 // ignore mip-maps
#define STUDIO_NF_SMOOTH 0x0010 // smooth tangent space
#define STUDIO_NF_ADDITIVE 0x0020 // rendering with additive mode
#define STUDIO_NF_MASKED 0x0040 // use texture with alpha channel
#define STUDIO_NF_NORMALMAP 0x0080 // indexed normalmap
#define STUDIO_NF_GLOSSMAP 0x0100 // glossmap
#define STUDIO_NF_GLOSSPOWER 0x0200
#define STUDIO_NF_LUMA 0x0400 // self-illuminate parts
#define STUDIO_NF_ALPHASOLID 0x0800 // use with STUDIO_NF_MASKED to have solid alphatest surfaces for env_static
#define STUDIO_NF_TWOSIDE 0x1000 // render mesh as twosided
#define STUDIO_NF_HEIGHTMAP 0x2000
#define STUDIO_NF_NODRAW (1U<<16) // failed to create shader for this mesh
#define STUDIO_NF_NODLIGHT (1U<<17) // failed to create dlight shader for this mesh
#define STUDIO_NF_NOSUNLIGHT (1U<<18) // failed to create sun light shader for this mesh
#define STUDIO_NF_HAS_ALPHA (1U<<20) // external texture has alpha-channel
#define STUDIO_NF_HAS_DETAIL (1U<<21) // studiomodels has detail textures
#define STUDIO_NF_COLORMAP (1U<<30) // internal system flag
#define STUDIO_NF_UV_COORDS (1U<<31) // using half-float coords instead of ST
// motion flags
#define STUDIO_X 0x0001
#define STUDIO_Y 0x0002
#define STUDIO_Z 0x0004
#define STUDIO_XR 0x0008
#define STUDIO_YR 0x0010
#define STUDIO_ZR 0x0020
#define STUDIO_LX 0x0040
#define STUDIO_LY 0x0080
#define STUDIO_LZ 0x0100
#define STUDIO_LXR 0x0200
#define STUDIO_LYR 0x0400
#define STUDIO_LZR 0x0800
#define STUDIO_LINEAR 0x1000
#define STUDIO_QUADRATIC_MOTION 0x2000
#define STUDIO_RESERVED 0x4000 // g-cont. reserved one bit for me
#define STUDIO_TYPES 0x7FFF
#define STUDIO_RLOOP 0x8000 // controller that wraps shortest distance
// bonecontroller types
#define STUDIO_MOUTH 4 // hardcoded
// sequence 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_BLENDPOSE 0x0040 // to differentiate GoldSrc style blending from Source style blending (with pose parameters)
#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_IKRULES 0x0800 // sequence has IK-rules
#define STUDIO_ACTIVITY 0x1000 // Has been updated at runtime to activity index
#define STUDIO_EVENT 0x2000 // Has been updated at runtime to event index
#define STUDIO_WORLD 0x4000 // sequence blends in worldspace
#define STUDIO_LIGHT_FROM_ROOT 0x8000 // get lighting point from root bonepos not from entity origin
// autolayer flags
#define STUDIO_AL_POST 0x0001 //
#define STUDIO_AL_SPLINE 0x0002 // convert layer ramp in/out curve is a spline instead of linear
#define STUDIO_AL_XFADE 0x0004 // pre-bias the ramp curve to compense for a non-1 weight,
// assuming a second layer is also going to accumulate
#define STUDIO_AL_NOBLEND 0x0008 // animation always blends at 1.0 (ignores weight)
#define STUDIO_AL_LOCAL 0x0010 // layer is a local context sequence
#define STUDIO_AL_POSE 0x0020 // layer blends using a pose parameter instead of parent cycle
typedef struct studiohdr_s
{
// the model signature
int32_t ident;
// studio model format version
int32_t version;
// the model name
char name[64];
// the total file size in bytes
int32_t length;
// ideal eye position
vec3_t eyeposition;
// ideal movement hull size
vec3_t min;
vec3_t max;
// clipping bounding box
vec3_t bbmin;
vec3_t bbmax;
// undocumented quake features flags
int32_t flags;
// the number of bones
int32_t numbones;
// offset to the first bone chunk
int32_t boneindex;
// the number of bone controllers
int32_t numbonecontrollers;
// offset to the first bone controller chunk
int32_t bonecontrollerindex;
// the number of hitboxes
int32_t numhitboxes;
// offset to the first hitbox chunk
int32_t hitboxindex;
// the number of sequences
int32_t numseq;
// offset to the first sequence description chunk
int32_t seqindex;
// the number of sequence groups
int32_t numseqgroups;
// offset to the first sequence group chunk
int32_t seqgroupindex;
// the number of textures
int32_t numtextures;
// offset to the first texture chunk
int32_t textureindex;
// offset to the first texture's image data
int32_t texturedataindex;
// the number of replaceable textures
int32_t numskinref;
// the number of skin families
int32_t numskinfamilies;
// offset to the first replaceable texture
int32_t skinindex;
// the number of bodyparts
int32_t numbodyparts;
// offset to the first bodypart
int32_t bodypartindex;
// the number of attachments
int32_t numattachments;
// offset to the first attachment chunk
int32_t attachmentindex;
// offset to the second studio model header
int32_t studiohdr2index;
// was "soundindex"
int32_t unused;
// was "soundgroups"
int32_t unused2;
// was "soundgroupindex"
int32_t unused3;
// the number of nodes in the sequence transition graph
int32_t numtransitions;
// offset to the first sequence transition
int32_t transitionindex;
} studiohdr_t;
// extra header to hold more offsets
typedef struct
{
// number of pose parameters
int32_t numposeparameters;
// offset to the first pose parameter
int32_t poseparamindex;
// number of IK-autoplaying locks
int32_t numikautoplaylocks;
// offset to the first IK-autoplaying lock
int32_t ikautoplaylockindex;
// number of IK-chains
int32_t numikchains;
// offset to the first IK-chain
int32_t ikchainindex;
// offset to the first key-value
int32_t keyvalueindex;
// size of key-values
int32_t keyvaluesize;
// number of hitbox sets
int32_t numhitboxsets;
// offset to the first hitbox set
int32_t hitboxsetindex;
// for future expansions
int32_t unused[6];
} studiohdr2_t;
// header for demand loaded sequence group data
typedef struct
{
// the model signature
int32_t id;
// studio model format version
int32_t version;
// the sequence group file name
char name[64];
// the total file size in bytes
int32_t length;
} studioseqhdr_t;
// bone flags
#define BONE_ALWAYS_PROCEDURAL 0x0001 // bone is always procedurally animated
#define BONE_SCREEN_ALIGN_SPHERE 0x0002 // bone aligns to the screen, not constrained in motion.
#define BONE_SCREEN_ALIGN_CYLINDER 0x0004 // bone aligns to the screen, constrained by it's own axis.
#define BONE_JIGGLE_PROCEDURAL 0x0008
#define BONE_FIXED_ALIGNMENT 0x0010 // bone can't spin 360 degrees, all interpolation is normalized around a fixed orientation
#define BONE_USED_MASK (BONE_USED_BY_HITBOX|BONE_USED_BY_ATTACHMENT|BONE_USED_BY_VERTEX|BONE_USED_BY_BONE_MERGE)
#define BONE_USED_BY_ANYTHING BONE_USED_MASK
#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 0x00000400 // bone (or child) is used by the toplevel model via skinned vertex
#define BONE_USED_BY_BONE_MERGE 0x00000800
// bones
typedef struct mstudiobone_s
{
// the bone name
char name[MAXSTUDIONAME];
// the parent bone index. (-1) If it has no parent
int32_t parent;
// was "flags"
int32_t unused;
// 1vailable bone controller per motion type.
// (-1) if no controller is available.
int32_t bonecontroller[6];
/* default position and rotation values where
* scale[0] = position.X
* scale[1] = position.Y
* scale[2] = position.Z
* scale[3] = rotation.X
* scale[4] = rotation.Y
* scale[5] = rotation.Z
*/
vec_t value[6];
/* compressed scale values where
* scale[0] = position.X scale
* scale[1] = position.Y scale
* scale[2] = position.Z scale
* scale[3] = rotation.X scale
* scale[4] = rotation.Y scale
* scale[5] = rotation.Z scale
*/
vec_t scale[6];
} mstudiobone_t;
#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
typedef struct
{
// local transformation of this bone used to calc 3 point blend
int32_t control;
// axis to check
int32_t axis;
// X+, X-, Y+, Y-, Z+, Z-
vec3_t pos[6];
// X+, X-, Y+, Y-, Z+, Z-
vec4_t quat[6];
} mstudioaxisinterpbone_t;
typedef struct
{
// 1.0f / radian angle of trigger influence
vec_t inv_tolerance;
// angle to match
vec4_t trigger;
// new position
vec3_t pos;
// new angle
vec4_t quat;
} mstudioquatinterpinfo_t;
typedef struct
{
// local transformation to check
int32_t control;
int32_t numtriggers;
int32_t triggerindex;
} mstudioquatinterpbone_t;
// extra info for bones
typedef struct
{
// boneweighting reqiures
vec_t poseToBone[3][4];
vec4_t qAlignment;
int32_t proctype;
// procedural rule
int32_t procindex;
// aligned bone rotation
vec4_t quat;
// for future expansions
int32_t reserved[10];
} mstudioboneinfo_t;
// JIGGLEBONES
#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
#define JIGGLE_IS_BOING 0x80 // simple squash and stretch sinusoid "boing"
typedef struct
{
int32_t flags;
// general params
vec_t length; // how from from bone base, along bone, is tip
vec_t tipMass;
// flexible params
vec_t yawStiffness;
vec_t yawDamping;
vec_t pitchStiffness;
vec_t pitchDamping;
vec_t alongStiffness;
vec_t alongDamping;
// angle constraint
vec_t angleLimit; // maximum deflection of tip in radians
// yaw constraint
vec_t minYaw; // in radians
vec_t maxYaw; // in radians
vec_t yawFriction;
vec_t yawBounce;
// pitch constraint
vec_t minPitch; // in radians
vec_t maxPitch; // in radians
vec_t pitchFriction;
vec_t pitchBounce;
// base spring
vec_t baseMass;
vec_t baseStiffness;
vec_t baseDamping;
vec_t baseMinLeft;
vec_t baseMaxLeft;
vec_t baseLeftFriction;
vec_t baseMinUp;
vec_t baseMaxUp;
vec_t baseUpFriction;
vec_t baseMinForward;
vec_t baseMaxForward;
vec_t baseForwardFriction;
// boing
vec_t boingImpactSpeed;
vec_t boingImpactAngle;
vec_t boingDampingRate;
vec_t boingFrequency;
vec_t boingAmplitude;
} mstudiojigglebone_t;
typedef struct
{
int32_t parent;
// might be bone or attach
int32_t aim;
vec3_t aimvector;
vec3_t upvector;
vec3_t basepos;
} mstudioaimatbone_t;
// bone controllers
typedef struct
{
// bone affected by this controller
int32_t bone;
// the motion type
int32_t type;
// the minimum and maximum values
vec_t start;
vec_t end;
// was "rest"
int32_t unused;
// the bone controller channel
int32_t index;
} mstudiobonecontroller_t;
// intersection boxes
typedef struct
{
// the bone this hitbox follows
int32_t bone;
// the hit group
int32_t group;
// the hitbox minimum and maximum extents
vec3_t bbmin;
vec3_t bbmax;
} mstudiobbox_t;
typedef struct
{
char name[MAXSTUDIONAME];
int32_t numhitboxes;
int32_t hitboxindex;
} mstudiohitboxset_t;
// demand loaded sequence groups
typedef struct
{
// a textual name for this sequence group
char label[MAXSTUDIONAME];
// the file name
char name[64];
// was "cache"
int32_t unused;
// was "data"
int32_t unused2;
} mstudioseqgroup_t;
// events
#include "studio_event.h"
#define STUDIO_ATTACHMENT_LOCAL (1<<0) // vectors are filled
// attachment
typedef struct
{
// was "name"
char unused[MAXSTUDIONAME];
int32_t flags;
// the bone this attachment follows
int32_t bone;
// the attachment origin
vec3_t org;
// the attachment vectors
vec3_t vectors[3];
} mstudioattachment_t;
#define IK_SELF 1
#define IK_WORLD 2
#define IK_GROUND 3
#define IK_RELEASE 4
#define IK_ATTACHMENT 5
#define IK_UNLATCH 6
typedef struct
{
vec_t scale[6];
uint16_t offset[6];
} mstudioikerror_t;
typedef struct
{
int32_t index;
int32_t type;
int32_t chain;
int32_t bone;
// offset to the attachment
int32_t attachment;
// iktarget slot
// usually same as chain
int32_t slot;
vec_t height;
vec_t radius;
vec_t floor;
vec3_t pos;
vec4_t quat;
// offset to the compressed IK error
int32_t ikerrorindex;
int32_t iStart;
// beginning of influence
vec_t start;
// start of full influence
vec_t peak;
// end of full influence
vec_t tail;
// end of all influence
vec_t end;
// frame footstep makes ground concact
vec_t contact;
// how far down the foot should drop when reaching for IK
vec_t drop;
// top of the foot box
vec_t top;
// for future expansions
int32_t unused[4];
} mstudioikrule_t;
typedef struct
{
int32_t chain;
vec_t flPosWeight;
vec_t flLocalQWeight;
int32_t flags;
// for future expansions
int32_t unused[4];
} mstudioiklock_t;
typedef struct
{
int32_t endframe;
int32_t motionflags;
// velocity at start of block
vec_t v0;
// velocity at end of block
vec_t v1;
// YAW rotation at end of this blocks movement
vec_t angle;
// movement vector relative to this blocks initial angle
vec3_t vector;
// relative to start of animation???
vec3_t position;
} mstudiomovement_t;
// additional info for each animation in sequence blend group or single sequence
typedef struct
{
// animation label (may be matched with sequence label)
char label[MAXSTUDIONAME];
// frames per second (match with sequence fps or be different)
vec_t fps;
// looping/non-looping flags
int32_t flags;
// number of frames per animation
int32_t numframes;
// number of piecewise movements
int32_t nummovements;
// offset to the first piecewise movement
int32_t movementindex;
// number of IK-rules
int32_t numikrules;
// offset to the first IK-rule
int32_t ikruleindex;
// for future expansions
int32_t unused[8];
} mstudioanimdesc_t;
// autoplaying sequences
typedef struct
{
int16_t iSequence;
int16_t iPose;
int32_t flags;
// beginning of influence
vec_t start;
// start of full influence
vec_t peak;
// end of full influence
vec_t tail;
// end of all influence
vec_t end;
} mstudioautolayer_t;
// sequence descriptions
typedef struct mstudioseqdesc_s
{
// the sequence name
char label[MAXSTUDIONAME];
// frames per second
vec_t fps;
// looping/non-looping flags
int32_t flags;
// the sequence activity
int32_t activity;
// the sequence activity weight
int32_t actweight;
// the number of animation events
int32_t numevents;
// offset to the first animation event chunk
int32_t eventindex;
// the number of frames in the sequence
int32_t numframes;
// offset to the first weight list
int32_t weightlistindex;
// offset to the first IK lock
int32_t iklockindex;
// linear motion type
int32_t motiontype;
// offset to the first pose parameter
int32_t motionbone;
// linear motion
vec3_t linearmovement;
// offset to the first autolayer description
int32_t autolayerindex;
// offset to the first local key-value
int32_t keyvalueindex;
// the sequence minimum and maximum extents
vec3_t bbmin;
vec3_t bbmax;
// The number of blend animations
int32_t numblends;
// offset to thefirst mstudioanim_t chunk.
// this offset is relative to the studioseqhdr_t of the file
// that contains the animation data.
int32_t animindex;
// the motion type of each blend controller
int32_t blendtype[2];
// the starting value of each blend controller
vec_t blendstart[2];
// the ending value of each blend controller
vec_t blendend[2];
// 255 x 255 blends should be enough
uint8_t groupsize[2];
// number of autoplaying layers
uint8_t numautolayers;
// number of IK-locks per sequence
uint8_t numiklocks;
// the sequence group
int32_t seqgroup;
// the node at entry in the sequence transition graph
int32_t entrynode;
// the node at exit in the sequence transition graph
int32_t exitnode;
// transition rules
uint8_t nodeflags;
// index of pose parameter to use as cycle index
uint8_t cycleposeindex;
// ideal cross fade in time (0.2 secs default) time = (fadeintime / 100)
uint8_t fadeintime;
// ideal cross fade out time (0.2 msecs default) time = (fadeouttime / 100)
uint8_t fadeouttime;
// mstudioanimdesc_t [blend]
int32_t animdescindex;
} mstudioseqdesc_t;
typedef struct
{
// pose parameter name
char name[MAXSTUDIONAME];
// ????
int32_t flags;
// starting value
vec_t start;
// ending value
vec_t end;
// looping range, 0 for no looping, 360 for rotations, etc
vec_t loop;
} mstudioposeparamdesc_t;
// offsets to the animation frames
typedef struct mstudioanim_s
{
uint16_t offset[6];
} mstudioanim_t;
// animation frames
typedef union
{
struct
{
uint8_t valid;
uint8_t total;
} num;
int16_t value;
} mstudioanimvalue_t;
// body part index
typedef struct
{
// the bodypart name
char name[64];
// the number of available models for this bodypart
int32_t nummodels;
// used to convert from a global model index
// to a local bodypart model index
int32_t base;
// the offset to the first model chunk
int32_t modelindex; // index into models array
} mstudiobodyparts_t;
// skin info
typedef struct mstudiotex_s
{
// texture file name
char name[64];
// texture flags
uint32_t flags;
// texture width in pixels
int32_t width;
// texture height in pixels
int32_t height;
// offset to the image data
// this offset is relative to the texture file header
int32_t index;
} mstudiotexture_t;
// ikinfo
typedef struct
{
int32_t bone;
// ideal bending direction (per link, if applicable)
vec3_t kneeDir;
// unused
vec3_t unused0;
} mstudioiklink_t;
typedef struct
{
char name[MAXSTUDIONAME];
int32_t linktype;
int32_t numlinks;
int32_t linkindex;
} mstudioikchain_t;
typedef struct
{
uint8_t weight[4];
int8_t bone[4];
} mstudioboneweight_t;
// skin families
// short index[skinfamilies][skinref]
// studio models
typedef struct
{
// model name
char name[64];
// was "type"
int32_t unused;
// was "boundingradius"
vec_t unused2;
// the number of meshes in the model
int32_t nummesh;
// offset to the first mesh chunk
int32_t meshindex;
// the number of unique vertices
int32_t numverts;
// offset to the vertex bone array
int32_t vertinfoindex;
// offset to the vertex array
int32_t vertindex;
// the number of unique normals
int32_t numnorms;
// offset to the normal bone array
int32_t norminfoindex;
// offset to the normal array
int32_t normindex;
// offset to the boneweighted vertex info
int32_t blendvertinfoindex;
// offset to the boneweighted normal info
int32_t blendnorminfoindex;
} mstudiomodel_t;
// vec3_t boundingbox[model][bone][2]; // complex intersection info
// meshes
typedef struct
{
// can be interpreted as the number of triangles in the mesh
int32_t numtris;
// offset to the start of the tris sequence
int32_t triindex;
// the skin index
int32_t skinref;
// the number of normals in the mesh
int32_t numnorms;
// was "normindex"
int32_t unused;
} mstudiomesh_t;
// triangles
typedef struct
{
// index into vertex array
int16_t vertindex;
// index into normal array
int16_t normindex;
// texture coordinates in absolute space (unnormalized)
int16_t s,t;
} mstudiotrivert_t;
#endif//STUDIO_H