mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-29 07:02:12 +00:00
Add support for HLMDL actions, and some builtins to interact with it.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@6148 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
f612b97fc9
commit
13b2a7935c
11 changed files with 174 additions and 21 deletions
|
@ -3799,8 +3799,12 @@ static void M_ModelViewerDraw(int x, int y, struct menucustom_s *c, struct emenu
|
|||
int numframes = 0;
|
||||
float duration = 0;
|
||||
qboolean loop = false;
|
||||
if (!Mod_FrameInfoForNum(ent.model, mods->surfaceidx, mods->framegroup, &fname, &numframes, &duration, &loop))
|
||||
int act = -1;
|
||||
if (!Mod_FrameInfoForNum(ent.model, mods->surfaceidx, mods->framegroup, &fname, &numframes, &duration, &loop, &act))
|
||||
fname = "Unknown Sequence";
|
||||
if (act != -1)
|
||||
Draw_FunString(0, y, va("Frame%i[%i]: %s (%i poses, %f of %f secs, %s)", mods->framegroup, act, fname, numframes, ent.framestate.g[FS_REG].frametime[0], duration, loop?"looped":"unlooped"));
|
||||
else
|
||||
Draw_FunString(0, y, va("Frame%i: %s (%i poses, %f of %f secs, %s)", mods->framegroup, fname, numframes, ent.framestate.g[FS_REG].frametime[0], duration, loop?"looped":"unlooped"));
|
||||
y+=8;
|
||||
}
|
||||
|
|
|
@ -7054,8 +7054,9 @@ static struct {
|
|||
// {"skel_postmul_bones", PF_skel_postmul_bones, 0},//void(float skel, float startbone, float endbone, vector org) skel_mul_bone = #273; // (FTE_CSQC_SKELETONOBJECTS) (reads v_forward etc)
|
||||
{"skel_copybones", PF_skel_copybones, 274},//void(float skeldst, float skelsrc, float startbone, float entbone) skel_copybones = #274; // (FTE_CSQC_SKELETONOBJECTS)
|
||||
{"skel_delete", PF_skel_delete, 275},//void(float skel) skel_delete = #275; // (FTE_CSQC_SKELETONOBJECTS)
|
||||
{"frameforname", PF_frameforname, 276},//void(float modidx, string framename) frameforname = #276 (FTE_CSQC_SKELETONOBJECTS)
|
||||
{"frameduration", PF_frameduration, 277},//void(float modidx, float framenum) frameduration = #277 (FTE_CSQC_SKELETONOBJECTS)
|
||||
{"frameforname", PF_frameforname, 276},//float(float modidx, string framename) frameforname = #276 (FTE_CSQC_SKELETONOBJECTS)
|
||||
{"frameduration", PF_frameduration, 277},//float(float modidx, float framenum) frameduration = #277 (FTE_CSQC_SKELETONOBJECTS)
|
||||
{"frameforaction", PF_frameforaction, 0},//float(float modidx, string actionid) frameforaction = #0
|
||||
{"processmodelevents", PF_processmodelevents, 0},
|
||||
{"getnextmodelevent", PF_getnextmodelevent, 0},
|
||||
{"getmodeleventidx", PF_getmodeleventidx, 0},
|
||||
|
|
|
@ -903,7 +903,8 @@ void skel_generateragdoll_f(void)
|
|||
int numframes;
|
||||
float duration;
|
||||
qboolean loop;
|
||||
if (!Mod_FrameInfoForNum(mod, 0, i, &fname, &numframes, &duration, &loop))
|
||||
int act;
|
||||
if (!Mod_FrameInfoForNum(mod, 0, i, &fname, &numframes, &duration, &loop, &act))
|
||||
break;
|
||||
VFS_PUTS(f, va("//%i %s (%i frames) (%f secs)%s", i, fname, numframes, duration, loop?" (loop)":""));
|
||||
}
|
||||
|
@ -2669,7 +2670,7 @@ void QCBUILTIN PF_gettagindex (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
|
|||
void QCBUILTIN PF_frametoname (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
world_t *w = prinst->parms->user;
|
||||
unsigned int modelindex = G_FLOAT(OFS_PARM0);
|
||||
int modelindex = G_FLOAT(OFS_PARM0);
|
||||
unsigned int skinnum = G_FLOAT(OFS_PARM1);
|
||||
int surfaceidx = 0;
|
||||
model_t *mod = w->Get_CModel(w, modelindex);
|
||||
|
@ -2684,7 +2685,7 @@ void QCBUILTIN PF_frametoname (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
|
|||
void QCBUILTIN PF_frameforname (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
world_t *w = prinst->parms->user;
|
||||
unsigned int modelindex = G_FLOAT(OFS_PARM0);
|
||||
int modelindex = G_FLOAT(OFS_PARM0);
|
||||
int surfaceidx = 0;
|
||||
const char *str = PF_VarString(prinst, 1, pr_globals);
|
||||
model_t *mod = w->Get_CModel(w, modelindex);
|
||||
|
@ -2694,10 +2695,23 @@ void QCBUILTIN PF_frameforname (pubprogfuncs_t *prinst, struct globalvars_s *pr_
|
|||
else
|
||||
G_FLOAT(OFS_RETURN) = -1;
|
||||
}
|
||||
void QCBUILTIN PF_frameforaction (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
world_t *w = prinst->parms->user;
|
||||
int modelindex = G_FLOAT(OFS_PARM0);
|
||||
int surfaceidx = 0;
|
||||
int actionid = G_INT(OFS_PARM1);
|
||||
model_t *mod = w->Get_CModel(w, modelindex);
|
||||
|
||||
if (mod)
|
||||
G_FLOAT(OFS_RETURN) = Mod_FrameNumForAction(mod, surfaceidx, actionid);
|
||||
else
|
||||
G_FLOAT(OFS_RETURN) = -1;
|
||||
}
|
||||
void QCBUILTIN PF_frameduration (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
world_t *w = prinst->parms->user;
|
||||
unsigned int modelindex = G_FLOAT(OFS_PARM0);
|
||||
int modelindex = G_FLOAT(OFS_PARM0);
|
||||
unsigned int framenum = G_FLOAT(OFS_PARM1);
|
||||
int surfaceidx = 0;
|
||||
model_t *mod = w->Get_CModel(w, modelindex);
|
||||
|
@ -2723,7 +2737,7 @@ void QCBUILTIN PF_modelframecount (pubprogfuncs_t *prinst, struct globalvars_s *
|
|||
void QCBUILTIN PF_processmodelevents (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
world_t *w = prinst->parms->user;
|
||||
unsigned int modelindex = G_FLOAT(OFS_PARM0);
|
||||
int modelindex = G_FLOAT(OFS_PARM0);
|
||||
unsigned int frame = G_FLOAT(OFS_PARM1);
|
||||
float basetime = G_FLOAT(OFS_PARM2);
|
||||
float targettime = G_FLOAT(OFS_PARM3);
|
||||
|
@ -2786,8 +2800,9 @@ void QCBUILTIN PF_processmodelevents (pubprogfuncs_t *prinst, struct globalvars_
|
|||
char *data;
|
||||
float loopduration;
|
||||
qboolean looping;
|
||||
int act;
|
||||
|
||||
if (Mod_FrameInfoForNum(mod, 0, frame, &data, &code, &loopduration, &looping))
|
||||
if (Mod_FrameInfoForNum(mod, 0, frame, &data, &code, &loopduration, &looping, &act))
|
||||
{
|
||||
if (looping && loopduration)
|
||||
starttime = loopduration*(unsigned int)(basetime/loopduration);
|
||||
|
@ -2891,8 +2906,9 @@ void QCBUILTIN PF_getnextmodelevent (pubprogfuncs_t *prinst, struct globalvars_s
|
|||
char *data;
|
||||
float loopduration;
|
||||
qboolean looping;
|
||||
int act;
|
||||
|
||||
if (!Mod_FrameInfoForNum(mod, 0, frame, &data, &code, &loopduration, &looping))
|
||||
if (!Mod_FrameInfoForNum(mod, 0, frame, &data, &code, &loopduration, &looping, &act))
|
||||
return; //invalid frame
|
||||
|
||||
if (looping && loopduration)
|
||||
|
|
|
@ -555,6 +555,7 @@ void Mod_Shutdown (qboolean final);
|
|||
int Mod_TagNumForName(struct model_s *model, const char *name);
|
||||
int Mod_SkinNumForName(struct model_s *model, int surfaceidx, const char *name);
|
||||
int Mod_FrameNumForName(struct model_s *model, int surfaceidx, const char *name);
|
||||
int Mod_FrameNumForAction(struct model_s *model, int surfaceidx, int actionid);
|
||||
float Mod_GetFrameDuration(struct model_s *model, int surfaceidx, int frameno);
|
||||
|
||||
void Mod_ResortShaders(void);
|
||||
|
|
|
@ -2883,6 +2883,8 @@ typedef struct
|
|||
unsigned int posecount;
|
||||
float fps;
|
||||
qboolean loop;
|
||||
int action;
|
||||
int actionweight;
|
||||
char name[MAX_QPATH];
|
||||
} frameinfo_t;
|
||||
static frameinfo_t *ParseFrameInfo(char *modelname, int *numgroups)
|
||||
|
@ -2923,11 +2925,25 @@ static frameinfo_t *ParseFrameInfo(char *modelname, int *numgroups)
|
|||
frames[count].loop = true;
|
||||
else
|
||||
frames[count].loop = !!atoi(tok);
|
||||
|
||||
frames[count].action = -1;
|
||||
frames[count].actionweight = 0;
|
||||
Q_snprintfz(frames[count].name, sizeof(frames[count].name), "groupified_%d_anim", count); //to match DP. frameforname cares.
|
||||
|
||||
line = COM_ParseType(line, tok, sizeof(tok), &ttype);
|
||||
if (ttype != TTP_EOF)
|
||||
{
|
||||
Q_strncpyz(frames[count].name, tok, sizeof(frames[count].name));
|
||||
else
|
||||
Q_snprintfz(frames[count].name, sizeof(frames[count].name), "groupified_%d_anim", count); //to match DP. frameforname cares.
|
||||
line = COM_ParseType(line, tok, sizeof(tok), &ttype);
|
||||
}
|
||||
if (ttype != TTP_EOF)
|
||||
{
|
||||
frames[count].action = atoi(tok);
|
||||
line = COM_ParseType(line, tok, sizeof(tok), &ttype);
|
||||
}
|
||||
if (ttype != TTP_EOF)
|
||||
frames[count].actionweight = atoi(tok);
|
||||
|
||||
if (frames[count].posecount>0 && frames[count].fps)
|
||||
count++;
|
||||
|
||||
|
@ -3509,6 +3525,8 @@ static void *Q1MDL_LoadFrameGroup (galiasinfo_t *galias, dmdl_t *pq1inmodel, mod
|
|||
|
||||
for (i = 0; i < pq1inmodel->numframes; i++)
|
||||
{
|
||||
frame->action = -1;
|
||||
frame->actionweight = 0;
|
||||
switch(LittleLong(pframetype->type))
|
||||
{
|
||||
case ALIAS_SINGLE:
|
||||
|
@ -3979,6 +3997,8 @@ static void Mesh_HandleFramegroupsFile(model_t *mod, galiasinfo_t *galias)
|
|||
o->numposes = p;
|
||||
o->rate = framegroups[a].fps;
|
||||
o->loop = framegroups[a].loop;
|
||||
o->action = -1;
|
||||
o->actionweight = 0;
|
||||
Q_strncpyz(o->name, framegroups[a].name, sizeof(o->name));
|
||||
}
|
||||
galias->numanimations = numanims;
|
||||
|
@ -4981,6 +5001,8 @@ static qboolean QDECL Mod_LoadKingpinModel (model_t *mod, void *buffer, size_t f
|
|||
{
|
||||
poutframe->poseofs = pose;
|
||||
poutframe->numposes = 1;
|
||||
poutframe->action = -1;
|
||||
poutframe->actionweight = 0;
|
||||
galias->numanimations++;
|
||||
|
||||
#ifndef SERVERONLY
|
||||
|
@ -5490,6 +5512,47 @@ int Mod_FrameNumForName(model_t *model, int surfaceidx, const char *name)
|
|||
return -1;
|
||||
}
|
||||
|
||||
int Mod_FrameNumForAction(model_t *model, int surfaceidx, int actionid)
|
||||
{
|
||||
galiasanimation_t *group;
|
||||
galiasinfo_t *inf;
|
||||
int i;
|
||||
float weight;
|
||||
|
||||
if (!model)
|
||||
return -1;
|
||||
#ifdef HALFLIFEMODELS
|
||||
if (model->type == mod_halflife)
|
||||
return HLMDL_FrameForAction(model, actionid);
|
||||
#endif
|
||||
if (model->type != mod_alias)
|
||||
return -1;
|
||||
|
||||
inf = Mod_Extradata(model);
|
||||
|
||||
while(surfaceidx-->0 && inf)
|
||||
inf = inf->nextsurf;
|
||||
if (inf)
|
||||
{
|
||||
for (i = 0, weight = 0, group = inf->ofsanimations; i < inf->numanimations; i++, group++)
|
||||
{
|
||||
if (group->action == actionid)
|
||||
weight += group->actionweight;
|
||||
}
|
||||
weight *= frandom();
|
||||
for (i = 0, group = inf->ofsanimations; i < inf->numanimations; i++, group++)
|
||||
{
|
||||
if (group->action == actionid)
|
||||
{
|
||||
if (weight <= group->actionweight)
|
||||
return i;
|
||||
weight -= group->actionweight;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
qboolean Mod_GetModelEvent(model_t *model, int animation, int eventidx, float *timestamp, int *eventcode, char **eventdata)
|
||||
{
|
||||
|
@ -5586,7 +5649,7 @@ const char *Mod_FrameNameForNum(model_t *model, int surfaceidx, int num)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
qboolean Mod_FrameInfoForNum(model_t *model, int surfaceidx, int num, char **name, int *numframes, float *duration, qboolean *loop)
|
||||
qboolean Mod_FrameInfoForNum(model_t *model, int surfaceidx, int num, char **name, int *numframes, float *duration, qboolean *loop, int *act)
|
||||
{
|
||||
galiasanimation_t *group;
|
||||
galiasinfo_t *inf;
|
||||
|
@ -5615,11 +5678,12 @@ qboolean Mod_FrameInfoForNum(model_t *model, int surfaceidx, int num, char **nam
|
|||
*numframes = group[num].numposes;
|
||||
*loop = group[num].loop;
|
||||
*duration = group->numposes/group->rate;
|
||||
*act = group[num].action;
|
||||
return true;
|
||||
}
|
||||
#ifdef HALFLIFEMODELS
|
||||
if (model->type == mod_halflife)
|
||||
return HLMDL_FrameInfoForNum(model, surfaceidx, num, name, numframes, duration, loop);
|
||||
return HLMDL_FrameInfoForNum(model, surfaceidx, num, name, numframes, duration, loop, act);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
@ -5766,7 +5830,8 @@ float Mod_GetFrameDuration(model_t *model, int surfaceidx, int frameno)
|
|||
float duration;
|
||||
char *name;
|
||||
qboolean loop;
|
||||
HLMDL_FrameInfoForNum(model, surfaceidx, frameno, &name, &unused, &duration, &loop);
|
||||
int act;
|
||||
HLMDL_FrameInfoForNum(model, surfaceidx, frameno, &name, &unused, &duration, &loop, &act);
|
||||
return duration;
|
||||
}
|
||||
#endif
|
||||
|
@ -6020,6 +6085,8 @@ static galiasinfo_t *Mod_LoadQ3ModelLod(model_t *mod, int *surfcount, void *buff
|
|||
group->poseofs = pose + first;
|
||||
group->loop = framegroups[i].loop;
|
||||
group->events = NULL;
|
||||
group->action = -1;
|
||||
group->actionweight = 0;
|
||||
group++;
|
||||
}
|
||||
}
|
||||
|
@ -6033,6 +6100,8 @@ static galiasinfo_t *Mod_LoadQ3ModelLod(model_t *mod, int *surfcount, void *buff
|
|||
group->poseofs = pose + i;
|
||||
group->loop = false;
|
||||
group->events = NULL;
|
||||
group->action = -1;
|
||||
group->actionweight = 0;
|
||||
group++;
|
||||
}
|
||||
}
|
||||
|
@ -6523,6 +6592,8 @@ static qboolean QDECL Mod_LoadZymoticModel(model_t *mod, void *buffer, size_t fs
|
|||
grp->loop = !(BigLong(inscene->flags) & ZYMSCENEFLAG_NOLOOP);
|
||||
grp->numposes = BigLong(inscene->length);
|
||||
grp->boneofs = matrix + BigLong(inscene->start)*12*root->numbones;
|
||||
grp->action = -1;
|
||||
grp->actionweight = 0;
|
||||
}
|
||||
|
||||
if (inscene != (zymscene_t*)((char*)header + header->lump_scenes.start+header->lump_scenes.length))
|
||||
|
@ -7083,6 +7154,8 @@ static qboolean QDECL Mod_LoadPSKModel(model_t *mod, void *buffer, size_t fsize)
|
|||
group[j].loop = frameinfo[j].loop;
|
||||
group[j].rate = frameinfo[j].fps;
|
||||
group[j].skeltype = SKEL_RELATIVE;
|
||||
group[j].action = -1;
|
||||
group[j].actionweight = 0;
|
||||
}
|
||||
num_animinfo = numgroups;
|
||||
}
|
||||
|
@ -7107,6 +7180,8 @@ static qboolean QDECL Mod_LoadPSKModel(model_t *mod, void *buffer, size_t fsize)
|
|||
group[iframe].loop = true;
|
||||
group[iframe].rate = animinfo[j].fps;
|
||||
group[iframe].skeltype = SKEL_RELATIVE;
|
||||
group[iframe].action = -1;
|
||||
group[iframe].actionweight = 0;
|
||||
iframe++;
|
||||
}
|
||||
}
|
||||
|
@ -7126,6 +7201,8 @@ static qboolean QDECL Mod_LoadPSKModel(model_t *mod, void *buffer, size_t fsize)
|
|||
group[i].loop = true;
|
||||
group[i].rate = animinfo[i].fps;
|
||||
group[i].skeltype = SKEL_RELATIVE;
|
||||
group[i].action = -1;
|
||||
group[i].actionweight = 0;
|
||||
}
|
||||
}
|
||||
for (j = 0; j < num_animkeys; j += num_boneinfo)
|
||||
|
@ -7153,6 +7230,8 @@ static qboolean QDECL Mod_LoadPSKModel(model_t *mod, void *buffer, size_t fsize)
|
|||
group->loop = true;
|
||||
group->rate = 10;
|
||||
group->skeltype = SKEL_ABSOLUTE;
|
||||
group->action = -1;
|
||||
group->actionweight = 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -7451,6 +7530,8 @@ static qboolean QDECL Mod_LoadDarkPlacesModel(model_t *mod, void *buffer, size_t
|
|||
outgroups[i].numposes = 1;
|
||||
outgroups[i].skeltype = SKEL_RELATIVE;
|
||||
outgroups[i].boneofs = outposedata;
|
||||
outgroups[i].action = -1;
|
||||
outgroups[i].actionweight = 0;
|
||||
|
||||
inposedata = (float*)((char*)buffer + inframes[i].ofs_bonepositions);
|
||||
for (j = 0; j < header->num_bones*12; j++)
|
||||
|
@ -7488,6 +7569,8 @@ static qboolean QDECL Mod_LoadDarkPlacesModel(model_t *mod, void *buffer, size_t
|
|||
outgroups[i].loop = framegroups[i].loop;
|
||||
outgroups[i].rate = framegroups[i].fps;
|
||||
outgroups[i].events = NULL;
|
||||
outgroups[i].action = -1;
|
||||
outgroups[i].actionweight = 0;
|
||||
Q_strncpyz(outgroups[i].name, framegroups[i].name, sizeof(outgroups[i].name));
|
||||
}
|
||||
}
|
||||
|
@ -8290,6 +8373,8 @@ static galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, const char *buffer, siz
|
|||
framegroups[i].posecount = LittleLong(anim[i].num_frames);
|
||||
framegroups[i].fps = LittleFloat(anim[i].framerate);
|
||||
framegroups[i].loop = !!(LittleLong(anim[i].flags) & IQM_LOOP);
|
||||
framegroups[i].action = -1;
|
||||
framegroups[i].actionweight = 0;
|
||||
Q_strncpyz(framegroups[i].name, strings+anim[i].name, sizeof(fgroup[i].name));
|
||||
}
|
||||
}
|
||||
|
@ -8303,6 +8388,8 @@ static galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, const char *buffer, siz
|
|||
framegroups->posecount = 1;
|
||||
framegroups->fps = 10;
|
||||
framegroups->loop = 1;
|
||||
framegroups->action = -1;
|
||||
framegroups->actionweight = 0;
|
||||
strcpy(framegroups->name, "base");
|
||||
}
|
||||
|
||||
|
@ -8473,6 +8560,9 @@ static galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, const char *buffer, siz
|
|||
|
||||
if (fgroup[i].rate <= 0)
|
||||
fgroup[i].rate = 10;
|
||||
|
||||
fgroup[i].action = framegroups[i].action;
|
||||
fgroup[i].actionweight = framegroups[i].actionweight;
|
||||
}
|
||||
free(framegroups);
|
||||
|
||||
|
|
|
@ -62,6 +62,8 @@ typedef struct galiasanimation_s
|
|||
int numposes;
|
||||
//float *poseendtime; //first starts at 0, anim duration is poseendtime[numposes-1]
|
||||
float rate; //average framerate of animation.
|
||||
int action;
|
||||
float actionweight;
|
||||
#ifdef NONSKELETALMODELS
|
||||
galiaspose_t *poseofs;
|
||||
#endif
|
||||
|
@ -270,7 +272,7 @@ typedef struct modplugfuncs_s
|
|||
#define plugmodfuncs_name "Models_IDX" STRINGIFY(sizeof_index_t)
|
||||
#endif
|
||||
} plugmodfuncs_t;
|
||||
#define MODPLUGFUNCS_VERSION 2
|
||||
#define MODPLUGFUNCS_VERSION 3
|
||||
|
||||
#ifdef SKELETALMODELS
|
||||
void Alias_TransformVerticies(float *bonepose, galisskeletaltransforms_t *weights, int numweights, vecV_t *xyzout, vec3_t *normout);
|
||||
|
@ -286,7 +288,7 @@ const char *Mod_SkinNameForNum(model_t *model, int surfaceidx, int num);
|
|||
const char *Mod_SurfaceNameForNum(model_t *model, int num);
|
||||
const char *Mod_FrameNameForNum(model_t *model, int surfaceidx, int num);
|
||||
const char *Mod_SkinNameForNum(model_t *model, int surfaceidx, int num);
|
||||
qboolean Mod_FrameInfoForNum(model_t *model, int surfaceidx, int num, char **name, int *numframes, float *duration, qboolean *loop);
|
||||
qboolean Mod_FrameInfoForNum(model_t *model, int surfaceidx, int num, char **name, int *numframes, float *duration, qboolean *loop, int *act);
|
||||
|
||||
qboolean Mod_DoCRC(model_t *mod, char *buffer, int buffersize);
|
||||
|
||||
|
|
|
@ -315,6 +315,7 @@ void QCBUILTIN PF_setattachment(pubprogfuncs_t *prinst, struct globalvars_s *pr_
|
|||
void QCBUILTIN PF_frametoname (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
void QCBUILTIN PF_skintoname (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
void QCBUILTIN PF_frameforname (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
void QCBUILTIN PF_frameforaction (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
void QCBUILTIN PF_frameduration (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
void QCBUILTIN PF_modelframecount (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
void QCBUILTIN PF_skinforname (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
|
|
|
@ -612,6 +612,38 @@ int HLMDL_FrameForName(model_t *mod, const char *name)
|
|||
return -1;
|
||||
}
|
||||
|
||||
int HLMDL_FrameForAction(model_t *mod, int actionid)
|
||||
{
|
||||
int i;
|
||||
hlmdl_header_t *h;
|
||||
hlmdl_sequencelist_t *seqs;
|
||||
hlmodel_t *mc;
|
||||
int weight = 0;
|
||||
if (!mod || mod->type != mod_halflife)
|
||||
return -1; //halflife models only, please
|
||||
|
||||
mc = Mod_Extradata(mod);
|
||||
|
||||
h = mc->header;
|
||||
seqs = (hlmdl_sequencelist_t*)((char*)h+h->seqindex);
|
||||
|
||||
//figure out the total weight.
|
||||
for (i = 0; i < h->numseq; i++)
|
||||
if (seqs[i].action == actionid)
|
||||
weight += seqs[i].actionweight;
|
||||
//pick a random number between 0 and the total weight...
|
||||
weight *= frandom();
|
||||
//now figure out which sequence that gives us.
|
||||
for (i = 0; i < h->numseq; i++)
|
||||
if (seqs[i].action == actionid)
|
||||
{
|
||||
if (weight <= seqs[i].actionweight)
|
||||
return i;
|
||||
weight -= seqs[i].actionweight;
|
||||
}
|
||||
return -1; //failed...
|
||||
}
|
||||
|
||||
qboolean HLMDL_GetModelEvent(model_t *model, int animation, int eventidx, float *timestamp, int *eventcode, char **eventdata)
|
||||
{
|
||||
hlmodel_t *mc = Mod_Extradata(model);
|
||||
|
@ -1146,7 +1178,7 @@ const char *HLMDL_FrameNameForNum(model_t *mod, int surfaceidx, int seqnum)
|
|||
((unsigned int)seqnum>=model->header->numseq?0:seqnum);
|
||||
return sequence->name;
|
||||
}
|
||||
qboolean HLMDL_FrameInfoForNum(model_t *mod, int surfaceidx, int seqnum, char **name, int *numframes, float *duration, qboolean *loop)
|
||||
qboolean HLMDL_FrameInfoForNum(model_t *mod, int surfaceidx, int seqnum, char **name, int *numframes, float *duration, qboolean *loop, int *act)
|
||||
{
|
||||
hlmodel_t *model = Mod_Extradata(mod);
|
||||
hlmdl_sequencelist_t *sequence = (hlmdl_sequencelist_t *) ((qbyte *) model->header + model->header->seqindex) +
|
||||
|
@ -1156,6 +1188,7 @@ qboolean HLMDL_FrameInfoForNum(model_t *mod, int surfaceidx, int seqnum, char **
|
|||
*numframes = sequence->numframes;
|
||||
*duration = (sequence->numframes-1)/sequence->timing;
|
||||
*loop = sequence->loop;
|
||||
*act = sequence->action;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -224,7 +224,8 @@ typedef struct
|
|||
char name[32];
|
||||
float timing;
|
||||
int loop;
|
||||
int unknown1[2];
|
||||
int action;
|
||||
int actionweight;
|
||||
int num_events;
|
||||
int ofs_events;
|
||||
int numframes;
|
||||
|
@ -330,8 +331,9 @@ void *Mod_GetHalfLifeModelData(model_t *mod);
|
|||
//reflectioney things, including bone data
|
||||
int HLMDL_BoneForName(model_t *mod, const char *name);
|
||||
int HLMDL_FrameForName(model_t *mod, const char *name);
|
||||
int HLMDL_FrameForAction(model_t *mod, int actionid);
|
||||
const char *HLMDL_FrameNameForNum(model_t *model, int surfaceidx, int num);
|
||||
qboolean HLMDL_FrameInfoForNum(model_t *model, int surfaceidx, int num, char **name, int *numframes, float *duration, qboolean *loop);
|
||||
qboolean HLMDL_FrameInfoForNum(model_t *model, int surfaceidx, int num, char **name, int *numframes, float *duration, qboolean *loop, int *act);
|
||||
qboolean HLMDL_GetModelEvent(model_t *model, int animation, int eventidx, float *timestamp, int *eventcode, char **eventdata);
|
||||
int HLMDL_GetNumBones(model_t *mod, qboolean tagstoo);
|
||||
int HLMDL_GetBoneParent(model_t *mod, int bonenum);
|
||||
|
|
|
@ -11407,6 +11407,7 @@ static BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
{"skel_delete", PF_skel_delete, 0, 0, 0, 275, D("void(float skel)", "Deletes a skeletal object. The actual delete is delayed, allowing the skeletal object to be deleted in an entity's predraw function yet still be valid by the time the addentity+renderscene builtins need it. Also uninstanciates any ragdoll currently in effect on the skeletal object.")}, // (FTE_CSQC_SKELETONOBJECTS)
|
||||
{"frameforname", PF_frameforname, 0, 0, 0, 276, D("float(float modidx, string framename)", "Looks up a framegroup from a model by name, avoiding the need for hardcoding. Returns -1 on error.")},// (FTE_CSQC_SKELETONOBJECTS)
|
||||
{"frameduration", PF_frameduration, 0, 0, 0, 277, D("float(float modidx, float framenum)", "Retrieves the duration (in seconds) of the specified framegroup.")},// (FTE_CSQC_SKELETONOBJECTS)
|
||||
{"frameforaction", PF_frameforaction, 0, 0, 0, 0, D("float(float modidx, int actionid)", "Returns a random frame/animation for the specified mod-defined action, or -1 if no animations have the specified action.")},
|
||||
{"processmodelevents",PF_processmodelevents,0, 0, 0, 0, D("void(float modidx, float framenum, __inout float basetime, float targettime, void(float timestamp, int code, string data) callback)", "Calls a callback for each event that has been reached. Basetime is set to targettime.")},
|
||||
{"getnextmodelevent",PF_getnextmodelevent,0, 0, 0, 0, D("float(float modidx, float framenum, __inout float basetime, float targettime, __out int code, __out string data)", "Reports the next event within a model's animation. Returns a boolean if an event was found between basetime and targettime. Writes to basetime,code,data arguments (if an event was found, basetime is set to the event's time, otherwise to targettime).\nWARNING: this builtin cannot deal with multiple events with the same timestamp (only the first will be reported).")},
|
||||
{"getmodeleventidx",PF_getmodeleventidx,0, 0, 0, 0, D("float(float modidx, float framenum, int eventidx, __out float timestamp, __out int code, __out string data)", "Reports an indexed event within a model's animation. Writes to timestamp,code,data arguments on success. Returns false if the animation/event/model was out of range/invalid. Does not consider looping animations (retry from index 0 if it fails and you know that its a looping animation). This builtin is more annoying to use than getnextmodelevent, but can be made to deal with multiple events with the exact same timestamp.")},
|
||||
|
|
|
@ -3428,6 +3428,8 @@ static qboolean GLTF_LoadModel(struct model_s *mod, char *json, size_t jsonsize,
|
|||
}
|
||||
fg->loop = !!mod_gltf_loop->ival;
|
||||
fg->skeltype = SKEL_RELATIVE;
|
||||
fg->action = -1;
|
||||
fg->actionweight = 0;
|
||||
for(chan = JSON_FindIndexedChild(anim, "channels", 0); chan; chan = chan->sibling)
|
||||
{
|
||||
struct gltf_animsampler s;
|
||||
|
|
Loading…
Reference in a new issue