Paranoia2/engine/studio.h
2020-08-31 19:50:41 +03:00

795 lines
22 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.
*
****/
#ifndef STUDIO_H
#define STUDIO_H
#include "shader.h"
#include "color24.h"
#include "lightlimits.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 MAXSTUDIOSKINS 256 // total textures
#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 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 MAXEVENTSTRING 64
#define MAX_STUDIO_LIGHTMAP_SIZE 256 // must match with engine const!!!
// client-side model flags
#define STUDIO_ROCKET (1<<0) // leave a trail
#define STUDIO_GRENADE (1<<1) // leave a trail
#define STUDIO_GIB (1<<2) // leave a trail
#define STUDIO_ROTATE (1<<3) // rotate (bonus items)
#define STUDIO_TRACER (1<<4) // green split trail
#define STUDIO_ZOMGIB (1<<5) // small blood trail
#define STUDIO_TRACER2 (1<<6) // orange split trail + rotate
#define STUDIO_TRACER3 (1<<7) // purple trail
#define STUDIO_AMBIENT_LIGHT (1<<8) // force to use ambient shading
#define STUDIO_TRACE_HITBOX (1<<9) // always use hitbox trace instead of bbox
#define STUDIO_FORCE_SKYLIGHT (1<<10) // always grab lightvalues from the sky settings (even if sky is invisible)
#define STUDIO_HAS_BUMP (1<<16) // loadtime set
#define STUDIO_STATIC_PROP (1<<29) // hint for engine
#define STUDIO_HAS_BONEINFO (1<<30) // extra info about bones (pose matrix, procedural index etc)
#define STUDIO_HAS_BONEWEIGHTS (1<<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 (1<<16) // failed to create shader for this mesh
#define STUDIO_NF_NODLIGHT (1<<17) // failed to create dlight shader for this mesh
#define STUDIO_NF_NOSUNLIGHT (1<<18) // failed to create sun light shader for this mesh
#define STUDIO_NF_HAS_ALPHA (1<<20) // external texture has alpha-channel
#define STUDIO_NF_HAS_DETAIL (1<<21) // studiomodels has detail textures
#define STUDIO_NF_COLORMAP (1<<30) // can changed by colormap command
#define STUDIO_NF_UV_COORDS (1<<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
// 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
{
int ident;
int version;
char name[64];
int length;
vec3_t eyeposition; // ideal eye position
vec3_t min; // ideal movement hull size
vec3_t max;
vec3_t bbmin; // clipping bounding box
vec3_t bbmax;
int flags;
int numbones; // bones
int boneindex;
int numbonecontrollers; // bone controllers
int bonecontrollerindex;
int numhitboxes; // complex bounding boxes
int hitboxindex;
int numseq; // animation sequences
int seqindex;
int numseqgroups; // demand loaded sequences
int seqgroupindex;
int numtextures; // raw textures
int textureindex;
int texturedataindex;
int numskinref; // replaceable textures
int numskinfamilies;
int skinindex;
int numbodyparts;
int bodypartindex;
int numattachments; // queryable attachable points
int attachmentindex;
int studiohdr2index;
int soundindex; // UNUSED
int soundgroups; // UNUSED
int soundgroupindex; // UNUSED
int numtransitions; // animation node to animation node transition graph
int transitionindex;
} studiohdr_t;
// extra header to hold more offsets
typedef struct
{
int numposeparameters;
int poseparamindex;
int numikautoplaylocks;
int ikautoplaylockindex;
int numikchains;
int ikchainindex;
int keyvalueindex;
int keyvaluesize;
int numhitboxsets;
int hitboxsetindex;
int unused[6]; // for future expansions
} studiohdr2_t;
// header for demand loaded sequence group data
typedef struct
{
int id;
int version;
char name[64];
int 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
{
char name[MAXSTUDIONAME];// bone name for symbolic links
int parent; // parent bone
int flags; // bone flags
int bonecontroller[6]; // bone controller index, -1 == none
float value[6]; // default DoF values
float scale[6]; // scale for delta DoF values
} 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
{
int control; // local transformation of this bone used to calc 3 point blend
int axis; // axis to check
vec3_t pos[6]; // X+, X-, Y+, Y-, Z+, Z-
vec4_t quat[6]; // X+, X-, Y+, Y-, Z+, Z-
} mstudioaxisinterpbone_t;
typedef struct
{
float inv_tolerance; // 1.0f / radian angle of trigger influence
vec4_t trigger; // angle to match
vec3_t pos; // new position
vec4_t quat; // new angle
} mstudioquatinterpinfo_t;
typedef struct
{
int control; // local transformation to check
int numtriggers;
int triggerindex;
} mstudioquatinterpbone_t;
// extra info for bones
typedef struct
{
float poseToBone[3][4]; // boneweighting reqiures
vec4_t qAlignment;
int proctype;
int procindex; // procedural rule
vec4_t quat; // aligned bone rotation
int reserved[10]; // for future expansions
} 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
{
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;
// boing
float boingImpactSpeed;
float boingImpactAngle;
float boingDampingRate;
float boingFrequency;
float boingAmplitude;
} mstudiojigglebone_t;
typedef struct
{
int parent;
int aim; // might be bone or attach
vec3_t aimvector;
vec3_t upvector;
vec3_t basepos;
} mstudioaimatbone_t;
// bone controllers
typedef struct
{
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 index; // 0-3 user set controller, 4 mouth
} mstudiobonecontroller_t;
// intersection boxes
typedef struct
{
int bone;
int group; // intersection group
vec3_t bbmin; // bounding box
vec3_t bbmax;
} mstudiobbox_t;
typedef struct
{
char name[MAXSTUDIONAME];
int numhitboxes;
int hitboxindex;
} mstudiohitboxset_t;
#ifndef CACHE_USER
#define CACHE_USER
typedef struct cache_user_s
{
void *data; // extradata
} cache_user_t;
#endif
// demand loaded sequence groups
typedef struct
{
char label[MAXSTUDIONAME]; // textual name
char name[64]; // file name
cache_user_t cache; // cache index pointer
int data; // hack for group 0
} mstudioseqgroup_t;
// events
typedef struct mstudioevent_s
{
int frame;
int event;
int type;
char options[MAXEVENTSTRING];
} mstudioevent_t;
#define STUDIO_ATTACHMENT_LOCAL (1<<0) // vectors are filled
// attachment
typedef struct
{
char name[MAXSTUDIONAME];
int flags;
int bone;
vec3_t org; // attachment position
vec3_t vectors[3]; // attachment vectors
} 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
{
float scale[6];
unsigned short offset[6];
} mstudioikerror_t;
typedef struct
{
int index;
int type;
int chain;
int bone;
int attachment; // attachment index
int slot; // iktarget slot. Usually same as chain.
float height;
float radius;
float floor;
vec3_t pos;
vec4_t quat;
int ikerrorindex; // compressed IK error
int iStart;
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 unused[4]; // for future expansions
} mstudioikrule_t;
typedef struct
{
int chain;
float flPosWeight;
float flLocalQWeight;
int flags;
int unused[4]; // for future expansions
} mstudioiklock_t;
typedef struct
{
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
vec3_t vector; // movement vector relative to this blocks initial angle
vec3_t position; // relative to start of animation???
} mstudiomovement_t;
// additional info for each animation in sequence blend group or single sequence
typedef struct
{
char label[MAXSTUDIONAME]; // animation label (may be matched with sequence label)
float fps; // frames per second (match with sequence fps or be different)
int flags; // looping/non-looping flags
int numframes; // frames per animation
// piecewise movement
int nummovements; // piecewise movement
int movementindex;
int numikrules;
int ikruleindex; // non-zero when IK data is stored in the mdl
int unused[8]; // for future expansions
} mstudioanimdesc_t;
// autoplaying sequences
typedef struct
{
short iSequence;
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
} mstudioautolayer_t;
// sequence descriptions
typedef struct
{
char label[MAXSTUDIONAME]; // sequence label
float fps; // frames per second
int flags; // looping/non-looping flags
int activity;
int actweight;
int numevents;
int eventindex;
int numframes; // number of frames per sequence
int weightlistindex; // weightlists
int iklockindex; // IK locks
int motiontype;
int posekeyindex; // index of pose parameter
vec3_t linearmovement;
int autolayerindex; // autolayer descriptions
int keyvalueindex; // local key-values
vec3_t bbmin; // per sequence bounding box
vec3_t bbmax;
int numblends;
int animindex; // mstudioanim_t pointer relative to start of sequence group data
// [blend][bone][X, Y, Z, XR, YR, ZR]
int blendtype[2]; // X, Y, Z, XR, YR, ZR (same as paramindex)
float blendstart[2]; // starting value (same as paramstart)
float blendend[2]; // ending value (same as paramend)
byte groupsize[2]; // 255 x 255 blends should be enough
byte numautolayers; // count of autoplaying layers
byte numiklocks; // IK-locks per sequence
int seqgroup; // sequence group for demand loading
int entrynode; // transition node at entry
int exitnode; // transition node at exit
byte nodeflags; // transition rules (really this is bool)
byte cycleposeindex; // index of pose parameter to use as cycle index
byte fadeintime; // ideal cross fade in time (0.2 secs default) time = (fadeintime / 100)
byte fadeouttime; // ideal cross fade out time (0.2 msecs default) time = (fadeouttime / 100)
int animdescindex; // mstudioanimdesc_t [blend]
} mstudioseqdesc_t;
typedef struct
{
char name[MAXSTUDIONAME];
int flags; // ????
float start; // starting value
float end; // ending value
float loop; // looping range, 0 for no looping, 360 for rotations, etc.
} mstudioposeparamdesc_t;
typedef struct
{
unsigned short offset[6];
} mstudioanim_t;
// animation frames
typedef union
{
struct
{
byte valid;
byte total;
} num;
short value;
} mstudioanimvalue_t;
// body part index
typedef struct
{
char name[64];
int nummodels;
int base;
int modelindex; // index into models array
} mstudiobodyparts_t;
// skin info
typedef struct mstudiotex_s
{
char name[64];
int flags;
int width;
int height;
int index;
} mstudiotexture_t;
// ikinfo
typedef struct
{
int bone;
vec3_t kneeDir; // ideal bending direction (per link, if applicable)
vec3_t unused0; // unused
} mstudioiklink_t;
typedef struct
{
char name[MAXSTUDIONAME];
int linktype;
int numlinks;
int linkindex;
} mstudioikchain_t;
typedef struct
{
byte weight[4];
char bone[4];
} mstudioboneweight_t;
// skin families
// short index[skinfamilies][skinref]
// studio models
typedef struct
{
char name[64];
int type; // UNUSED
float boundingradius; // UNUSED
int nummesh;
int meshindex;
int numverts; // number of unique vertices
int vertinfoindex; // vertex bone info
int vertindex; // vertex vec3_t
int numnorms; // number of unique surface normals
int norminfoindex; // normal bone info
int normindex; // normal vec3_t
int blendvertinfoindex; // boneweighted vertex info
int blendnorminfoindex; // boneweighted normal info
} mstudiomodel_t;
// vec3_t boundingbox[model][bone][2]; // complex intersection info
// meshes
typedef struct
{
int numtris;
int triindex;
int skinref;
int numnorms; // per mesh normals
int normindex; // UNUSED!
} mstudiomesh_t;
typedef struct
{
short vertindex; // index into vertex array
short normindex; // index into normal array
short s,t; // s,t position on skin
} mstudiotrivert_t;
/*
===========================
USER-DEFINED DATA
===========================
*/
// this struct may be expaned by user request
typedef struct vbomesh_s
{
unsigned int skinref; // skin reference
unsigned int numVerts; // trifan vertices count
unsigned int numElems; // trifan elements count
int lightmapnum; // each mesh should use only once atlas page!
unsigned int vbo, vao, ibo; // buffer objects
vec3_t mins, maxs; // right transform to get screencopy
int parentbone; // parent bone to transform AABB
unsigned short uniqueID; // to reject decal drawing
unsigned int cacheSize; // debug info: uploaded cache size for this buffer
} vbomesh_t;
// each mstudiotexture_t has a material
typedef struct mstudiomat_s
{
mstudiotexture_t *pSource; // pointer to original texture
unsigned short gl_diffuse_id; // diffuse texture
unsigned short gl_detailmap_id; // detail texture
unsigned short gl_normalmap_id; // normalmap
unsigned short gl_specular_id; // specular
unsigned short gl_glowmap_id; // self-illuminate parts
unsigned short gl_heightmap_id; // parallax stuff
// this part is shared with matdesc_t
float smoothness; // smoothness factor
float detailScale[2]; // detail texture scales x, y
float reflectScale; // reflection scale for translucent water
float refractScale; // refraction scale for mirrors, windows, water
float aberrationScale; // chromatic abberation
float reliefScale; // relief-mapping
struct matdef_s *effects; // hit, impact, particle effects etc
int flags; // mstudiotexture_t->flags
// cached shadernums
shader_t forwardScene;
shader_t forwardLightSpot;
shader_t forwardLightOmni;
shader_t forwardLightProj;
shader_t deferredScene;
shader_t deferredLight;
shader_t forwardDepth;
unsigned short lastRenderMode; // for catch change render modes
} mstudiomaterial_t;
typedef struct mstudiosurface_s
{
int flags; // match with msurface_t->flags
int texture_step;
short lightextents[2];
unsigned short light_s[MAXLIGHTMAPS];
unsigned short light_t[MAXLIGHTMAPS];
byte lights[MAXDYNLIGHTS];// static lights that affected this face (255 = no lights)
int lightmaptexturenum;
byte styles[MAXLIGHTMAPS];
color24 *samples; // note: this is the actual lightmap data for this surface
color24 *normals; // note: this is the actual deluxemap data for this surface
byte *shadows; // note: occlusion map for this surface
} mstudiosurface_t;
typedef struct
{
vbomesh_t *meshes; // meshes per submodel
int nummesh; // mstudiomodel_t->nummesh
} msubmodel_t;
// triangles
typedef struct mbodypart_s
{
int base; // mstudiobodyparts_t->base
msubmodel_t *models[MAXSTUDIOBODYPARTS]; // submodels per body part
int nummodels; // mstudiobodyparts_t->nummodels
} mbodypart_t;
typedef struct mvbocache_s
{
mstudiosurface_t *surfaces;
int numsurfaces;
mbodypart_t *bodyparts;
int numbodyparts;
bool update_light; // gamma or brightness was changed so we need to reload lightmaps
} mstudiocache_t;
typedef struct mposebone_s
{
matrix3x4 posetobone[MAXSTUDIOBONES];
} mposetobone_t;
#endif//STUDIO_H