UFO: Alien Invasion
Loading...
Searching...
No Matches
r_mesh_anim.cpp
Go to the documentation of this file.
1
5
6/*
7Copyright (C) 2002-2025 UFO: Alien Invasion.
8
9This program is free software; you can redistribute it and/or
10modify it under the terms of the GNU General Public License
11as published by the Free Software Foundation; either version 2
12of the License, or (at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17
18See the GNU General Public License for more details.
19
20You should have received a copy of the GNU General Public License
21along with this program; if not, write to the Free Software
22Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
24*/
25
26#include "r_local.h"
27#include "r_mesh.h"
28#include "r_mesh_anim.h"
29
30#define LOOPNEXT(x) ((x + 1 < MAX_ANIMLIST) ? x + 1 : 0)
31
35static inline void R_AnimAdd (animState_t* as, const model_t* mod, const mAliasAnim_t* anim)
36{
37 assert(as->ladd < sizeof(as->list));
38
39 as->list[as->ladd] = anim - mod->alias.animdata;
40
41 /* advance in list (no overflow protection!) */
42 as->ladd = LOOPNEXT(as->ladd);
43}
44
47#define R_AnimGetAliasAnim(mod, as) ((mod)->alias.animdata + (as)->list[(as)->lcur])
48
59static const mAliasAnim_t* R_AnimGet (const model_t* mod, const char* name)
60{
61 mAliasAnim_t* anim;
62 int i;
63
64 if (!mod || !mod->alias.num_anims)
65 return nullptr;
66
67 for (i = 0, anim = mod->alias.animdata; i < mod->alias.num_anims; i++, anim++)
68 if (Q_streq(name, anim->name))
69 return anim;
70
71 return nullptr;
72}
73
84void R_AnimAppend (animState_t* as, const model_t* mod, const char* name)
85{
86 const mAliasAnim_t* anim;
87
88 if (!mod) {
89 Com_Printf("R_AnimAppend: No model given (%s)\n", name);
90 return;
91 }
92
93 if (!mod->alias.num_anims) {
94 Com_Printf("R_AnimAppend: Model with no animations (%s) (model: %s)\n", name, mod->name);
95 return;
96 }
97
98 /* get animation */
99 anim = R_AnimGet(mod, name);
100 if (!anim) {
101 Com_Printf("R_AnimAppend: No such animation: %s (model: %s)\n", name, mod->name);
102 return;
103 }
104
105 if (as->lcur == as->ladd) {
106 /* first animation */
107 as->oldframe = anim->from;
108 if (anim->to > anim->from)
109 as->frame = anim->from + 1;
110 else
111 as->frame = anim->from;
112
113 as->backlerp = 0.0;
114 as->time = anim->time;
115 as->dt = 0;
116
117 as->change = true;
118 }
119
120 R_AnimAdd(as, mod, anim);
121}
122
123
134void R_AnimChange (animState_t* as, const model_t* mod, const char* name)
135{
136 const mAliasAnim_t* anim;
137
138 if (!mod) {
139 Com_Printf("R_AnimChange: No model given (%s)\n", name);
140 return;
141 }
142
143 if (!mod->alias.num_anims) {
144 Com_Printf("R_AnimChange: Model with no animations (%s) (model: %s)\n", name, mod->name);
145 return;
146 }
147
148 /* get animation */
149 anim = R_AnimGet(mod, name);
150 if (!anim) {
151 Com_Printf("R_AnimChange: No such animation: %s (model: %s)\n", name, mod->name);
152 return;
153 }
154
155 if (as->lcur == as->ladd) {
156 /* first animation */
157 as->oldframe = anim->from;
158 if (anim->to > anim->from)
159 as->frame = anim->from + 1;
160 else
161 as->frame = anim->from;
162
163 as->backlerp = 1.0;
164 as->time = anim->time;
165 as->dt = 0;
166
167 as->change = true;
168 } else {
169 /* next animation */
170 as->ladd = LOOPNEXT(as->lcur);
171 if (anim->time < as->time)
172 as->time = anim->time;
173 /* don't change to the same animation */
174 if (anim != R_AnimGetAliasAnim(mod, as))
175 as->change = true;
176 }
177
178 R_AnimAdd(as, mod, anim);
179}
180
181
192void R_AnimRun (animState_t* as, const model_t* mod, int msec)
193{
194 assert(as->lcur < MAX_ANIMLIST);
195
196 if (!mod || !mod->alias.num_anims)
197 return;
198
199 if (as->lcur == as->ladd)
200 return;
201
202 as->dt += msec;
203
204 while (as->dt > as->time) {
205 const mAliasAnim_t* anim = R_AnimGetAliasAnim(mod, as);
206 as->dt -= as->time;
207
208 if (as->change || as->frame >= anim->to) {
209 /* go to next animation if it isn't the last one */
210 if (LOOPNEXT(as->lcur) != as->ladd)
211 as->lcur = LOOPNEXT(as->lcur);
212
213 anim = R_AnimGetAliasAnim(mod, as);
214
215 /* prepare next frame */
216 as->dt = 0;
217 as->time = anim->time;
218 as->oldframe = as->frame;
219 as->frame = anim->from;
220 as->change = false;
221 } else {
222 /* next frame of the same animation */
223 as->time = anim->time;
224 as->oldframe = as->frame;
225 as->frame++;
226 }
227 }
228
229 as->backlerp = 1.0 - (float) as->dt / as->time;
230}
231
242const char* R_AnimGetName (const animState_t* as, const model_t* mod)
243{
244 const mAliasAnim_t* anim;
245
246 assert(as->lcur < MAX_ANIMLIST);
247
248 if (!mod || !mod->alias.num_anims)
249 return nullptr;
250
251 if (as->lcur == as->ladd)
252 return nullptr;
253
254 anim = R_AnimGetAliasAnim(mod, as);
255 return anim->name;
256}
void Com_Printf(const char *const fmt,...)
Definition common.cpp:428
#define MAX_ANIMLIST
Definition r_entity.h:27
QGL_EXTERN GLint i
Definition r_gl.h:113
QGL_EXTERN GLuint GLsizei GLsizei GLint GLenum GLchar * name
Definition r_gl.h:110
local graphics definitions
void R_AnimRun(animState_t *as, const model_t *mod, int msec)
Run the animation of the given model.
void R_AnimChange(animState_t *as, const model_t *mod, const char *name)
Changes the animation for md2 models.
#define LOOPNEXT(x)
#define R_AnimGetAliasAnim(mod, as)
Get the mAliasAnim_t for the given animation state.
void R_AnimAppend(animState_t *as, const model_t *mod, const char *name)
Appends a new animation to the current running one.
const char * R_AnimGetName(const animState_t *as, const model_t *mod)
Get the current running animation for a model.
static const mAliasAnim_t * R_AnimGet(const model_t *mod, const char *name)
Searches a given animation id in the given model data.
static void R_AnimAdd(animState_t *as, const model_t *mod, const mAliasAnim_t *anim)
Adds the given animation to the animation state.
#define Q_streq(a, b)
Definition shared.h:136
byte change
Definition r_entity.h:65
byte lcur
Definition r_entity.h:63
byte list[MAX_ANIMLIST]
Definition r_entity.h:62
byte ladd
Definition r_entity.h:64
float backlerp
Definition r_entity.h:57
int oldframe
Definition r_entity.h:56
char name[MAX_ANIMNAME]
mAliasAnim_t * animdata
mAliasModel_t alias
Definition r_model.h:63
char name[MAX_QPATH]
Definition r_model.h:44