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