2
0
mirror of https://github.com/rehlds/rehlds.git synced 2024-12-28 15:45:46 +03:00

Small refactoring r_studio.cpp

This commit is contained in:
s1lent 2017-12-20 20:05:12 +07:00
parent f5784be364
commit e6a9fd1095
No known key found for this signature in database
GPG Key ID: 0FE401DC73916B5C
4 changed files with 150 additions and 176 deletions

View File

@ -47,33 +47,33 @@ studiohdr_t *pstudiohdr;
//auxvert_t auxverts[2048];
//vec_t lightvalues[2048][3];
int cache_hull_hitgroup[128];
hull_t cache_hull[128];
mplane_t cache_planes[768];
r_studiocache_t rgStudioCache[STUDIO_CACHE_SIZE];
studio_hull_hitgroup_t cache_hull_hitgroup;
studio_hull_t cache_hull;
studio_planes_t cache_planes;
rgStudioCache_t rgStudioCache;
int nCurrentHull;
int nCurrentPlane;
int r_cachecurrent;
int studio_hull_hitgroup[STUDIO_NUM_HULLS];
hull_t studio_hull[STUDIO_NUM_HULLS];
dclipnode_t studio_clipnodes[6];
mplane_t studio_planes[6 * STUDIO_NUM_HULLS];
studio_hull_t studio_hull;
studio_hull_hitgroup_t studio_hull_hitgroup;
studio_clipnodes_t studio_clipnodes;
studio_planes_t studio_planes;
float bonetransform[STUDIO_NUM_HULLS][3][4];
bonetransform_t bonetransform;
float rotationmatrix[3][4];
cvar_t r_cachestudio = { "r_cachestudio", "1", 0, 0.0f, NULL };
cvar_t r_cachestudio = { "r_cachestudio", "1", 0, 0.0f, nullptr };
sv_blending_interface_t svBlending = { 1, SV_StudioSetupBones };
sv_blending_interface_t *g_pSvBlendingAPI = &svBlending;
server_studio_api_t server_studio_api = { Mem_Calloc, Cache_Check, COM_LoadCacheFile, Mod_Extradata };
void SV_InitStudioHull(void)
{
if (studio_hull[0].planes == NULL)
void SV_InitStudioHull()
{
if (studio_hull[0].planes)
return; // already initailized
for (int i = 0; i < 6; i++)
{
int side = i & 1;
@ -90,69 +90,55 @@ void SV_InitStudioHull(void)
studio_hull[i].lastclipnode = 5;
}
}
}
r_studiocache_t *R_CheckStudioCache(model_t *pModel, float frame, int sequence, const vec_t *angles, const vec_t *origin, const vec_t *size, const unsigned char *controller, const unsigned char *blending)
{
for (int i = 0; i < STUDIO_CACHE_SIZE; i++)
{
r_studiocache_t *pCached = &rgStudioCache[(r_cachecurrent - i) & 0xF];
if (pCached->pModel != pModel) continue;
if (pCached->frame != frame) continue;
if (pCached->sequence != sequence) continue;
if (!VectorCompare(pCached->angles, angles)) continue;
if (!VectorCompare(pCached->origin, origin)) continue;
if (!VectorCompare(pCached->size, size)) continue;
if (Q_memcmp(pCached->controller, controller, 4)) continue;
if (Q_memcmp(pCached->blending, blending, 2)) continue;
r_studiocache_t *pCached = &rgStudioCache[(r_cachecurrent - i) & STUDIO_CACHEMASK];
if (pCached->pModel == pModel && pCached->frame == frame && pCached->sequence == sequence
&& VectorCompare(pCached->angles, angles) && VectorCompare(pCached->origin, origin) && VectorCompare(pCached->size, size)
&& !Q_memcmp(pCached->controller, controller, 4) && !Q_memcmp(pCached->blending, blending, 2))
{
return pCached;
}
return NULL;
}
NOXREF void R_AddToStudioCache(float frame, int sequence, const vec_t *angles, const vec_t *origin, const vec_t *size, const unsigned char *controller, const unsigned char *pblending, model_t *pModel, hull_t *pHulls, int numhulls)
return nullptr;
}
void R_AddToStudioCache(float frame, int sequence, const vec_t *angles, const vec_t *origin, const vec_t *size, const unsigned char *controller, const unsigned char *pblending, model_t *pModel, hull_t *pHulls, int numhulls)
{
NOXREFCHECK;
r_studiocache_t *p;
if (numhulls + nCurrentHull >= 128)
if (numhulls + nCurrentHull >= MAXSTUDIOBONES)
R_FlushStudioCache();
r_cachecurrent++;
p = &rgStudioCache[r_cachecurrent & 0xF];
r_studiocache_t *pCache = &rgStudioCache[r_cachecurrent & STUDIO_CACHEMASK];
p->frame = frame;
p->sequence = sequence;
pCache->frame = frame;
pCache->sequence = sequence;
p->angles[0] = angles[0];
p->angles[1] = angles[1];
p->angles[2] = angles[2];
VectorCopy(angles, pCache->angles);
VectorCopy(origin, pCache->origin);
VectorCopy(size, pCache->size);
p->origin[0] = origin[0];
p->origin[1] = origin[1];
p->origin[2] = origin[2];
Q_memcpy(pCache->controller, controller, sizeof(pCache->controller));
Q_memcpy(pCache->blending, pblending, sizeof(pCache->blending));
p->size[0] = size[0];
p->size[1] = size[1];
p->size[2] = size[2];
pCache->pModel = pModel;
pCache->nStartHull = nCurrentHull;
pCache->nStartPlane = nCurrentPlane;
Q_memcpy(p->controller, controller, sizeof(p->controller));
Q_memcpy(p->blending, pblending, sizeof(p->blending));
Q_memcpy(&cache_hull[nCurrentHull], pHulls, numhulls * sizeof(hull_t));
Q_memcpy(&cache_planes[nCurrentPlane], studio_planes, numhulls * sizeof(mplane_t) * 6);
Q_memcpy(&cache_hull_hitgroup[nCurrentHull], studio_hull_hitgroup, numhulls * sizeof(int));
p->pModel = pModel;
p->nStartPlane = nCurrentPlane;
p->nStartHull = nCurrentHull;
Q_memcpy(&cache_hull[nCurrentHull], pHulls, sizeof(hull_t) * numhulls);
Q_memcpy(&cache_planes[nCurrentPlane], studio_planes,sizeof(mplane_t) * 6 * numhulls);
Q_memcpy(&cache_hull_hitgroup[nCurrentHull], studio_hull_hitgroup, sizeof(int) * numhulls);
p->numhulls = numhulls;
pCache->numhulls = numhulls;
nCurrentHull += numhulls;
nCurrentPlane += 6 * numhulls;
nCurrentPlane += numhulls * 6;
}
void AngleQuaternion(vec_t *angles, vec_t *quaternion)
@ -190,6 +176,7 @@ void QuaternionSlerp(vec_t *p, vec_t *q, float t, vec_t *qt)
a += (p[i] - q[i])*(p[i] - q[i]);
b += (p[i] + q[i])*(p[i] + q[i]);
}
if (a > b)
{
for (i = 0; i < 4; i++)
@ -259,7 +246,17 @@ void R_StudioCalcBoneAdj(float dadt, float *adj, const unsigned char *pcontrolle
for (j = 0; j < pstudiohdr->numbonecontrollers; j++)
{
i = pbonecontroller[j].index;
if (i <= 3)
if (i >= STUDIO_MOUTH)
{
// mouth hardcoded at controller 4
value = (float)(mouthopen / 64.0);
if (value > 1.0)
value = 1.0f;
value = (float)((1.0 - value) * pbonecontroller[j].start + value * pbonecontroller[j].end);
// Con_DPrintf("%d %f\n", mouthopen, value);
}
else
{
// check for 360% wrapping
if (pbonecontroller[j].type & STUDIO_RLOOP)
@ -272,27 +269,19 @@ void R_StudioCalcBoneAdj(float dadt, float *adj, const unsigned char *pcontrolle
value = (float)(((a * dadt) + (b * (1 - dadt)) - 128) * (360.0 / 256.0) + pbonecontroller[j].start);
}
else
{
value = (float)((pcontroller1[i] * dadt + (pcontroller2[i]) * (1.0 - dadt)) * (360.0 / 256.0) + pbonecontroller[j].start);
}
}
else
{
value = (float)((pcontroller1[i] * dadt + pcontroller2[i] * (1.0 - dadt)) / 255.0);
if (value < 0.0)
value = 0.0f;
if (value > 1.0)
value = 1.0f;
value = clamp(value, 0.0f, 1.0f);
value = (float)((1.0 - value) * pbonecontroller[j].start + value * pbonecontroller[j].end);
}
// Con_DPrintf("%d %d %f : %f\n", m_pCurrentEntity->curstate.controller[j], m_pCurrentEntity->latched.prevcontroller[j], value, dadt);
}
else
{
value = (float)(mouthopen / 64.0);
if (value > 1.0)
value = 1.0f;
value = (float)((1.0 - value) * pbonecontroller[j].start + value * pbonecontroller[j].end);
// Con_DPrintf("%d %f\n", mouthopen, value );
}
switch (pbonecontroller[j].type & STUDIO_TYPES)
{
case STUDIO_XR:
@ -331,6 +320,7 @@ void R_StudioCalcBoneQuaterion(int frame, float s, mstudiobone_t *pbone, mstudio
k -= panimvalue->num.total;
panimvalue += panimvalue->num.valid + 1;
}
// Bah, missing blend!
if (panimvalue->num.valid > k)
{
@ -360,6 +350,7 @@ void R_StudioCalcBoneQuaterion(int frame, float s, mstudiobone_t *pbone, mstudio
angle2[j] = panimvalue[panimvalue->num.valid + 2].value;
}
}
angle1[j] = pbone->value[j + 3] + angle1[j] * pbone->scale[j + 3];
angle2[j] = pbone->value[j + 3] + angle2[j] * pbone->scale[j + 3];
}
@ -402,6 +393,7 @@ void R_StudioCalcBonePosition(int frame, float s, mstudiobone_t *pbone, mstudioa
k -= panimvalue->num.total;
panimvalue += panimvalue->num.valid + 1;
}
// if we're inside the span
if (panimvalue->num.valid > k)
{
@ -492,9 +484,10 @@ mstudioanim_t *R_GetAnim(model_t *psubmodel, mstudioseqdesc_t *pseqdesc)
paSequences = (cache_user_t *)psubmodel->submodels;
if (!paSequences)
{
paSequences = (cache_user_t *)Mem_Calloc(16, 4);
paSequences = (cache_user_t *)Mem_Calloc(MAXSTUDIOGROUPS, sizeof(cache_user_t));
psubmodel->submodels = (dmodel_t *)paSequences;
}
if (!Cache_Check(&paSequences[pseqdesc->seqgroup]))
{
Con_DPrintf("loading %s\n", pseqgroup->name);
@ -527,6 +520,7 @@ void EXT_FUNC SV_StudioSetupBones(model_t *pModel, float frame, int sequence, co
Con_DPrintf("SV_StudioSetupBones: sequence %i/%i out of range for model %s\n", sequence, pstudiohdr->numseq, pstudiohdr->name);
sequence = 0;
}
pbones = (mstudiobone_t *)((char *)pstudiohdr + pstudiohdr->boneindex);
pseqdesc = (mstudioseqdesc_t *)((char *)pstudiohdr + pstudiohdr->seqindex);
pseqdesc += sequence;
@ -617,10 +611,17 @@ hull_t *R_StudioHull(model_t *pModel, float frame, int sequence, const vec_t *an
if (r_cachestudio.value != 0)
{
#ifdef SWDS
Sys_Error("%s: Studio state caching is not used on server", __func__);
#endif
// TODO: Reverse for client-side
r_studiocache_t *pCached = R_CheckStudioCache(pModel, frame, sequence, angles, origin, size, pcontroller, pblending);
if (pCached)
{
Q_memcpy(studio_planes, &cache_planes[pCached->nStartPlane], pCached->numhulls * sizeof(mplane_t) * 6);
Q_memcpy(studio_hull_hitgroup, &cache_hull_hitgroup[pCached->nStartHull], pCached->numhulls * sizeof(int));
Q_memcpy(studio_hull, &cache_hull[pCached->nStartHull], pCached->numhulls * sizeof(hull_t));
*pNumHulls = pCached->numhulls;
return studio_hull;
}
}
pstudiohdr = (studiohdr_t *)Mod_Extradata(pModel);
@ -650,20 +651,7 @@ hull_t *R_StudioHull(model_t *pModel, float frame, int sequence, const vec_t *an
*pNumHulls = (bSkipShield == 1) ? pstudiohdr->numhitboxes - 1 : pstudiohdr->numhitboxes;
if (r_cachestudio.value != 0)
{
#ifdef SWDS
Sys_Error("%s: Studio state caching is not used on server", __func__);
#endif
// TODO: Reverse for client-side
// R_AddToStudioCache(float frame,
// int sequence,
// const vec_t *angles,
// const vec_t *origin,
// const vec_t *size,
// const unsigned char *controller,
// const unsigned char *pblending,
// model_t *pModel,
// hull_t *pHulls,
// int numhulls);
R_AddToStudioCache(frame, sequence, angles, origin, size, pcontroller, pblending, pModel, studio_hull, *pNumHulls);
}
return &studio_hull[0];
@ -674,9 +662,8 @@ int SV_HitgroupForStudioHull(int index)
return studio_hull_hitgroup[index];
}
NOXREF void R_InitStudioCache(void)
void R_InitStudioCache()
{
NOXREFCHECK;
Q_memset(rgStudioCache, 0, sizeof(rgStudioCache));
r_cachecurrent = 0;
@ -684,9 +671,8 @@ NOXREF void R_InitStudioCache(void)
nCurrentPlane = 0;
}
NOXREF void R_FlushStudioCache(void)
void R_FlushStudioCache()
{
NOXREFCHECK;
R_InitStudioCache();
}
@ -838,7 +824,6 @@ qboolean DoesSphereIntersect(float *vSphereCenter, float fSphereRadiusSquared, f
float c;
float insideSqr;
P[0] = *vLinePt - *vSphereCenter;
P[1] = vLinePt[1] - vSphereCenter[1];
P[2] = vLinePt[2] - vSphereCenter[2];
@ -882,7 +867,6 @@ qboolean SV_CheckSphereIntersection(edict_t *ent, const vec_t *start, const vec_
return DoesSphereIntersect(ent->v.origin, radiusSquared, traceOrg, traceDir) != 0;
}
void EXT_FUNC AnimationAutomove(const edict_t *pEdict, float flTime)
{
}
@ -978,7 +962,6 @@ void R_StudioBoundVertex(vec_t *mins, vec_t *maxs, int *vertcount, const vec_t *
if (maxs[i] < point[i])
maxs[i] = point[i];
}
}
else
{
@ -1004,7 +987,6 @@ void R_StudioBoundBone(vec_t *mins, vec_t *maxs, int *bonecount, const vec_t *po
if (maxs[i] < point[i])
maxs[i] = point[i];
}
}
else
{
@ -1053,7 +1035,6 @@ int R_StudioComputeBounds(unsigned char *pBuffer, float *mins, float *maxs)
studiohdr_t * header = (studiohdr_t *)pBuffer;
mstudiobodyparts_t * bodyparts = (mstudiobodyparts_t *)((char *)header + header->bodypartindex);
int nummodels = 0;
for (int i = 0; i < header->numbodyparts; i++)
nummodels += bodyparts[i].nummodels;
@ -1108,7 +1089,6 @@ int R_GetStudioBounds(const char *filename, float *mins, float *maxs)
if (!Q_strstr(filename, "models") || !Q_strstr(filename, ".mdl"))
return 0;
FileHandle_t fp = FS_Open(filename, "rb");
if (!fp)
return 0;
@ -1141,7 +1121,7 @@ int R_GetStudioBounds(const char *filename, float *mins, float *maxs)
return iret;
}
void R_ResetSvBlending(void)
void R_ResetSvBlending()
{
g_pSvBlendingAPI = &svBlending;
}

View File

@ -42,19 +42,22 @@ typedef mplane_t studio_planes_t[STUDIO_NUM_PLANES];
typedef r_studiocache_t rgStudioCache_t[STUDIO_CACHE_SIZE];
typedef float bonetransform_t[STUDIO_NUM_HULLS][3][4];
extern int cache_hull_hitgroup[128];
extern hull_t cache_hull[128];
extern mplane_t cache_planes[768];
extern studiohdr_t *pstudiohdr;
extern studio_hull_hitgroup_t cache_hull_hitgroup;
extern studio_hull_t cache_hull;
extern studio_planes_t cache_planes;
extern int r_cachecurrent;
extern int nCurrentHull;
extern int nCurrentPlane;
extern studio_hull_t studio_hull;
extern studio_hull_hitgroup_t studio_hull_hitgroup;
extern studio_clipnodes_t studio_clipnodes;
extern studio_planes_t studio_planes;
extern rgStudioCache_t rgStudioCache;
extern int r_cachecurrent;
extern int nCurrentHull;
extern int nCurrentPlane;
extern bonetransform_t bonetransform;
extern sv_blending_interface_t *g_pSvBlendingAPI;
extern sv_blending_interface_t svBlending;
@ -62,9 +65,9 @@ extern server_studio_api_t server_studio_api;
extern cvar_t r_cachestudio;
extern float rotationmatrix[3][4];
void SV_InitStudioHull(void);
void SV_InitStudioHull();
r_studiocache_t *R_CheckStudioCache(model_t *pModel, float frame, int sequence, const vec_t *angles, const vec_t *origin, const vec_t *size, const unsigned char *controller, const unsigned char *blending);
NOXREF void R_AddToStudioCache(float frame, int sequence, const vec_t *angles, const vec_t *origin, const vec_t *size, const unsigned char *controller, const unsigned char *pblending, model_t *pModel, hull_t *pHulls, int numhulls);
void R_AddToStudioCache(float frame, int sequence, const vec_t *angles, const vec_t *origin, const vec_t *size, const unsigned char *controller, const unsigned char *pblending, model_t *pModel, hull_t *pHulls, int numhulls);
void AngleQuaternion(vec_t *angles, vec_t *quaternion);
void QuaternionSlerp(vec_t *p, vec_t *q, float t, vec_t *qt);
void QuaternionMatrix(vec_t *quaternion, float matrix[3][4]);
@ -77,8 +80,8 @@ void SV_StudioSetupBones(model_t *pModel, float frame, int sequence, const vec_t
void SV_SetStudioHullPlane(mplane_t *pplane, int iBone, int k, float dist);
hull_t *R_StudioHull(model_t *pModel, float frame, int sequence, const vec_t *angles, const vec_t *origin, const vec_t *size, const unsigned char *pcontroller, const unsigned char *pblending, int *pNumHulls, const edict_t *pEdict, int bSkipShield);
int SV_HitgroupForStudioHull(int index);
NOXREF void R_InitStudioCache(void);
NOXREF void R_FlushStudioCache(void);
void R_InitStudioCache();
void R_FlushStudioCache();
int R_StudioBodyVariations(model_t *model);
void R_StudioPlayerBlend(mstudioseqdesc_t *pseqdesc, int *pBlend, float *pPitch);
hull_t *SV_HullForStudioModel(const edict_t *pEdict, const vec_t *mins, const vec_t *maxs, vec_t *offset, int *pNumHulls);
@ -93,4 +96,4 @@ void R_StudioBoundBone(vec_t *mins, vec_t *maxs, int *bonecount, const vec_t *po
void R_StudioAccumulateBoneVerts(vec_t *mins, vec_t *maxs, int *vertcount, vec_t *bone_mins, vec_t *bone_maxs, int *bonecount);
int R_StudioComputeBounds(unsigned char *pBuffer, float *mins, float *maxs);
int R_GetStudioBounds(const char *filename, float *mins, float *maxs);
void R_ResetSvBlending(void);
void R_ResetSvBlending();

View File

@ -54,13 +54,13 @@ void R_MarkLeaves()
void R_InitTextures()
{
r_notexture_mip = (texture_t *)Hunk_AllocName(404, "notexture");
r_notexture_mip = (texture_t *)Hunk_AllocName(sizeof(texture_t) + 16*16 + 8*8 + 4*4 + 2*2, "notexture");
r_notexture_mip->height = 16;
r_notexture_mip->width = 16;
r_notexture_mip->offsets[0] = 64;
r_notexture_mip->offsets[1] = 320;
r_notexture_mip->offsets[2] = 384;
r_notexture_mip->offsets[3] = 400;
r_notexture_mip->offsets[0] = sizeof(texture_t);
r_notexture_mip->offsets[1] = r_notexture_mip->offsets[0] + 16*16;
r_notexture_mip->offsets[2] = r_notexture_mip->offsets[1] + 8*8;
r_notexture_mip->offsets[3] = r_notexture_mip->offsets[2] + 4*4;
for (int m = 0; m < 4; m++)
{
@ -77,9 +77,7 @@ void R_InitTextures()
*dest = 0;
}
}
}
}
void StartLoadingProgressBar(const char *loadingType, int numProgressPoints) { }

View File

@ -12,6 +12,7 @@
* without written permission from Valve LLC.
*
****/
#pragma once
/*
@ -23,7 +24,6 @@ Studio models are position independent, so the cache manager can move them.
==============================================================================
*/
#define MAXSTUDIOTRIANGLES 20000 // TODO: tune this
#define MAXSTUDIOVERTS 2048 // TODO: tune this
#define MAXSTUDIOSEQUENCES 2048 // total animation sequences
@ -115,7 +115,6 @@ typedef struct
float scale[6]; // scale for delta DoF values
} mstudiobone_t;
// bone controllers
typedef struct
{
@ -236,8 +235,6 @@ typedef union
short value;
} mstudioanimvalue_t;
// body part index
typedef struct
{
@ -247,8 +244,6 @@ typedef struct
int modelindex; // index into models array
} mstudiobodyparts_t;
// skin info
typedef struct
{
@ -259,7 +254,6 @@ typedef struct
int index;
} mstudiotexture_t;
// skin families
// short index[skinfamilies][skinref]
@ -286,10 +280,8 @@ typedef struct
int groupindex;
} mstudiomodel_t;
// vec3_t boundingbox[model][bone][2]; // complex intersection info
// meshes
typedef struct
{
@ -341,6 +333,9 @@ typedef struct
#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
@ -353,9 +348,7 @@ typedef struct
#define RAD_TO_STUDIO (32768.0/M_PI)
#define STUDIO_TO_RAD (M_PI/32768.0)
#define STUDIO_NUM_HULLS 128
#define STUDIO_NUM_PLANES (STUDIO_NUM_HULLS * 6)
#define STUDIO_CACHE_SIZE 16
#define STUDIO_CACHEMASK (STUDIO_CACHE_SIZE - 1)