Inexor
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
md2.hpp
Go to the documentation of this file.
1 #pragma once
3 
4 static const float md2normaltable[256][3] =
5 {
6  { -0.525731f, 0.000000f, 0.850651f }, { -0.442863f, 0.238856f, 0.864188f }, { -0.295242f, 0.000000f, 0.955423f }, { -0.309017f, 0.500000f, 0.809017f },
7  { -0.162460f, 0.262866f, 0.951056f }, { 0.000000f, 0.000000f, 1.000000f }, { 0.000000f, 0.850651f, 0.525731f }, { -0.147621f, 0.716567f, 0.681718f },
8  { 0.147621f, 0.716567f, 0.681718f }, { 0.000000f, 0.525731f, 0.850651f }, { 0.309017f, 0.500000f, 0.809017f }, { 0.525731f, 0.000000f, 0.850651f },
9  { 0.295242f, 0.000000f, 0.955423f }, { 0.442863f, 0.238856f, 0.864188f }, { 0.162460f, 0.262866f, 0.951056f }, { -0.681718f, 0.147621f, 0.716567f },
10  { -0.809017f, 0.309017f, 0.500000f }, { -0.587785f, 0.425325f, 0.688191f }, { -0.850651f, 0.525731f, 0.000000f }, { -0.864188f, 0.442863f, 0.238856f },
11  { -0.716567f, 0.681718f, 0.147621f }, { -0.688191f, 0.587785f, 0.425325f }, { -0.500000f, 0.809017f, 0.309017f }, { -0.238856f, 0.864188f, 0.442863f },
12  { -0.425325f, 0.688191f, 0.587785f }, { -0.716567f, 0.681718f, -0.147621f }, { -0.500000f, 0.809017f, -0.309017f }, { -0.525731f, 0.850651f, 0.000000f },
13  { 0.000000f, 0.850651f, -0.525731f }, { -0.238856f, 0.864188f, -0.442863f }, { 0.000000f, 0.955423f, -0.295242f }, { -0.262866f, 0.951056f, -0.162460f },
14  { 0.000000f, 1.000000f, 0.000000f }, { 0.000000f, 0.955423f, 0.295242f }, { -0.262866f, 0.951056f, 0.162460f }, { 0.238856f, 0.864188f, 0.442863f },
15  { 0.262866f, 0.951056f, 0.162460f }, { 0.500000f, 0.809017f, 0.309017f }, { 0.238856f, 0.864188f, -0.442863f }, { 0.262866f, 0.951056f, -0.162460f },
16  { 0.500000f, 0.809017f, -0.309017f }, { 0.850651f, 0.525731f, 0.000000f }, { 0.716567f, 0.681718f, 0.147621f }, { 0.716567f, 0.681718f, -0.147621f },
17  { 0.525731f, 0.850651f, 0.000000f }, { 0.425325f, 0.688191f, 0.587785f }, { 0.864188f, 0.442863f, 0.238856f }, { 0.688191f, 0.587785f, 0.425325f },
18  { 0.809017f, 0.309017f, 0.500000f }, { 0.681718f, 0.147621f, 0.716567f }, { 0.587785f, 0.425325f, 0.688191f }, { 0.955423f, 0.295242f, 0.000000f },
19  { 1.000000f, 0.000000f, 0.000000f }, { 0.951056f, 0.162460f, 0.262866f }, { 0.850651f, -0.525731f, 0.000000f }, { 0.955423f, -0.295242f, 0.000000f },
20  { 0.864188f, -0.442863f, 0.238856f }, { 0.951056f, -0.162460f, 0.262866f }, { 0.809017f, -0.309017f, 0.500000f }, { 0.681718f, -0.147621f, 0.716567f },
21  { 0.850651f, 0.000000f, 0.525731f }, { 0.864188f, 0.442863f, -0.238856f }, { 0.809017f, 0.309017f, -0.500000f }, { 0.951056f, 0.162460f, -0.262866f },
22  { 0.525731f, 0.000000f, -0.850651f }, { 0.681718f, 0.147621f, -0.716567f }, { 0.681718f, -0.147621f, -0.716567f }, { 0.850651f, 0.000000f, -0.525731f },
23  { 0.809017f, -0.309017f, -0.500000f }, { 0.864188f, -0.442863f, -0.238856f }, { 0.951056f, -0.162460f, -0.262866f }, { 0.147621f, 0.716567f, -0.681718f },
24  { 0.309017f, 0.500000f, -0.809017f }, { 0.425325f, 0.688191f, -0.587785f }, { 0.442863f, 0.238856f, -0.864188f }, { 0.587785f, 0.425325f, -0.688191f },
25  { 0.688191f, 0.587785f, -0.425325f }, { -0.147621f, 0.716567f, -0.681718f }, { -0.309017f, 0.500000f, -0.809017f }, { 0.000000f, 0.525731f, -0.850651f },
26  { -0.525731f, 0.000000f, -0.850651f }, { -0.442863f, 0.238856f, -0.864188f }, { -0.295242f, 0.000000f, -0.955423f }, { -0.162460f, 0.262866f, -0.951056f },
27  { 0.000000f, 0.000000f, -1.000000f }, { 0.295242f, 0.000000f, -0.955423f }, { 0.162460f, 0.262866f, -0.951056f }, { -0.442863f, -0.238856f, -0.864188f },
28  { -0.309017f, -0.500000f, -0.809017f }, { -0.162460f, -0.262866f, -0.951056f }, { 0.000000f, -0.850651f, -0.525731f }, { -0.147621f, -0.716567f, -0.681718f },
29  { 0.147621f, -0.716567f, -0.681718f }, { 0.000000f, -0.525731f, -0.850651f }, { 0.309017f, -0.500000f, -0.809017f }, { 0.442863f, -0.238856f, -0.864188f },
30  { 0.162460f, -0.262866f, -0.951056f }, { 0.238856f, -0.864188f, -0.442863f }, { 0.500000f, -0.809017f, -0.309017f }, { 0.425325f, -0.688191f, -0.587785f },
31  { 0.716567f, -0.681718f, -0.147621f }, { 0.688191f, -0.587785f, -0.425325f }, { 0.587785f, -0.425325f, -0.688191f }, { 0.000000f, -0.955423f, -0.295242f },
32  { 0.000000f, -1.000000f, 0.000000f }, { 0.262866f, -0.951056f, -0.162460f }, { 0.000000f, -0.850651f, 0.525731f }, { 0.000000f, -0.955423f, 0.295242f },
33  { 0.238856f, -0.864188f, 0.442863f }, { 0.262866f, -0.951056f, 0.162460f }, { 0.500000f, -0.809017f, 0.309017f }, { 0.716567f, -0.681718f, 0.147621f },
34  { 0.525731f, -0.850651f, 0.000000f }, { -0.238856f, -0.864188f, -0.442863f }, { -0.500000f, -0.809017f, -0.309017f }, { -0.262866f, -0.951056f, -0.162460f },
35  { -0.850651f, -0.525731f, 0.000000f }, { -0.716567f, -0.681718f, -0.147621f }, { -0.716567f, -0.681718f, 0.147621f }, { -0.525731f, -0.850651f, 0.000000f },
36  { -0.500000f, -0.809017f, 0.309017f }, { -0.238856f, -0.864188f, 0.442863f }, { -0.262866f, -0.951056f, 0.162460f }, { -0.864188f, -0.442863f, 0.238856f },
37  { -0.809017f, -0.309017f, 0.500000f }, { -0.688191f, -0.587785f, 0.425325f }, { -0.681718f, -0.147621f, 0.716567f }, { -0.442863f, -0.238856f, 0.864188f },
38  { -0.587785f, -0.425325f, 0.688191f }, { -0.309017f, -0.500000f, 0.809017f }, { -0.147621f, -0.716567f, 0.681718f }, { -0.425325f, -0.688191f, 0.587785f },
39  { -0.162460f, -0.262866f, 0.951056f }, { 0.442863f, -0.238856f, 0.864188f }, { 0.162460f, -0.262866f, 0.951056f }, { 0.309017f, -0.500000f, 0.809017f },
40  { 0.147621f, -0.716567f, 0.681718f }, { 0.000000f, -0.525731f, 0.850651f }, { 0.425325f, -0.688191f, 0.587785f }, { 0.587785f, -0.425325f, 0.688191f },
41  { 0.688191f, -0.587785f, 0.425325f }, { -0.955423f, 0.295242f, 0.000000f }, { -0.951056f, 0.162460f, 0.262866f }, { -1.000000f, 0.000000f, 0.000000f },
42  { -0.850651f, 0.000000f, 0.525731f }, { -0.955423f, -0.295242f, 0.000000f }, { -0.951056f, -0.162460f, 0.262866f }, { -0.864188f, 0.442863f, -0.238856f },
43  { -0.951056f, 0.162460f, -0.262866f }, { -0.809017f, 0.309017f, -0.500000f }, { -0.864188f, -0.442863f, -0.238856f }, { -0.951056f, -0.162460f, -0.262866f },
44  { -0.809017f, -0.309017f, -0.500000f }, { -0.681718f, 0.147621f, -0.716567f }, { -0.681718f, -0.147621f, -0.716567f }, { -0.850651f, 0.000000f, -0.525731f },
45  { -0.688191f, 0.587785f, -0.425325f }, { -0.587785f, 0.425325f, -0.688191f }, { -0.425325f, 0.688191f, -0.587785f }, { -0.425325f, -0.688191f, -0.587785f },
46  { -0.587785f, -0.425325f, -0.688191f }, { -0.688191f, -0.587785f, -0.425325f }
47 };
48 
49 struct md2 : vertmodel, vertloader<md2>
50 {
51  struct md2_header
52  {
53  int magic;
54  int version;
56  int framesize;
61  };
62 
63  struct md2_vertex
64  {
66  };
67 
68  struct md2_frame
69  {
70  float scale[3];
71  float translate[3];
72  char name[16];
73  };
74 
75  md2(const char *name) : vertmodel(name) {}
76 
77  static const char *formatname() { return "md2"; }
78  static bool multiparted() { return false; }
79  static bool multimeshed() { return false; }
80  int type() const override { return MDL_MD2; }
81 
82  int linktype(animmodel *m) const override { return LINK_COOP; }
83 
84  struct md2meshgroup : vertmeshgroup
85  {
86  void genverts(int *glcommands, vector<tcvert> &tcverts, vector<ushort> &vindexes, vector<tri> &tris)
87  {
88  hashtable<ivec, int> tchash;
89  vector<ushort> idxs;
90  for(int *command = glcommands; (*command)!=0;)
91  {
92  int numvertex = *command++;
93  bool isfan = numvertex<0;
94  if(isfan) numvertex = -numvertex;
95  idxs.setsize(0);
96  loopi(numvertex)
97  {
98  union { int i; float f; } u, v;
99  u.i = *command++;
100  v.i = *command++;
101  int vindex = *command++;
102  ivec tckey(u.i, v.i, vindex);
103  int *idx = tchash.access(tckey);
104  if(!idx)
105  {
106  idx = &tchash[tckey];
107  *idx = tcverts.length();
108  tcvert &tc = tcverts.add();
109  tc.tc = vec2(u.f, v.f);
110  vindexes.add((ushort)vindex);
111  }
112  idxs.add(*idx);
113  }
114  loopi(numvertex-2)
115  {
116  tri &t = tris.add();
117  if(isfan)
118  {
119  t.vert[0] = idxs[0];
120  t.vert[1] = idxs[i+1];
121  t.vert[2] = idxs[i+2];
122  }
123  else loopk(3) t.vert[k] = idxs[i&1 && k ? i+(1-(k-1))+1 : i+k];
124  }
125  }
126  }
127 
128  bool load(const char *filename)
129  {
130  stream *file = openfile(filename, "rb");
131  if(!file) return false;
132 
133  md2_header header;
134  file->read(&header, sizeof(md2_header));
135  lilswap(&header.magic, sizeof(md2_header)/sizeof(int));
136 
137  if(header.magic!=844121161 || header.version!=8)
138  {
139  delete file;
140  return false;
141  }
142 
143  name = newstring(filename);
144 
145  numframes = header.numframes;
146 
147  vertmesh &m = *new vertmesh;
148  m.group = this;
149  meshes.add(&m);
150 
151  int *glcommands = new int[header.numglcommands];
152  file->seek(header.offsetglcommands, SEEK_SET);
153  int numglcommands = file->read(glcommands, header.numglcommands*sizeof(int))/sizeof(int);
154  lilswap(glcommands, numglcommands);
155  if(numglcommands < header.numglcommands) memset(&glcommands[numglcommands], 0, (header.numglcommands-numglcommands)*sizeof(int));
156 
157  vector<tcvert> tcgen;
158  vector<ushort> vgen;
159  vector<tri> trigen;
160  genverts(glcommands, tcgen, vgen,trigen);
161  delete[] glcommands;
162 
163  m.numverts = tcgen.length();
164 
165  m.tcverts = new tcvert[m.numverts];
166  memcpy(m.tcverts, tcgen.getbuf(), m.numverts*sizeof(tcvert));
167  m.numtris = trigen.length();
168  m.tris = new tri[m.numtris];
169  memcpy(m.tris, trigen.getbuf(), m.numtris*sizeof(tri));
170 
171  m.verts = new vert[m.numverts*numframes];
172 
173  md2_vertex *tmpverts = new md2_vertex[header.numvertices];
174  int frame_offset = header.offsetframes;
175  vert *curvert = m.verts;
176  loopi(header.numframes)
177  {
178  md2_frame frame;
179  file->seek(frame_offset, SEEK_SET);
180  file->read(&frame, sizeof(md2_frame));
181  lilswap(frame.scale, 6);
182 
183  file->read(tmpverts, header.numvertices*sizeof(md2_vertex));
184  loopj(m.numverts)
185  {
186  const md2_vertex &v = tmpverts[vgen[j]];
187  curvert->pos = vec(v.vertex[0]*frame.scale[0]+frame.translate[0],
188  -(v.vertex[1]*frame.scale[1]+frame.translate[1]),
189  v.vertex[2]*frame.scale[2]+frame.translate[2]);
190  const float *norm = md2normaltable[v.normalindex];
191  curvert->norm = vec(norm[0], -norm[1], norm[2]);
192  curvert++;
193  }
194  frame_offset += header.framesize;
195  }
196  delete[] tmpverts;
197 
198  delete file;
199 
200  return true;
201  }
202  };
203 
204  struct md2part : part
205  {
206  md2part(animmodel *model, int index = 0) : part(model, index)
207  {
208  }
209 
210  void getdefaultanim(animinfo &info, int anim, uint varseed, dynent *d) override
211  {
212  // 0 3 6 7 8 9 10 11 12 13 14 15 16 17
213  // D D D D D D A P I R, E J T W FO SA GS GI
214  static const int _frame[] = { 178, 184, 190, 183, 189, 197, 46, 54, 0, 40, 162, 67, 95, 112, 72, 84, 7, 6 };
215  static const int _range[] = { 6, 6, 8, 1, 1, 1, 8, 4, 40, 6, 1, 1, 17, 11, 12, 11, 18, 1 };
216  // DE DY I F B L R H1 H2 H3 H4 H5 H6 H7 A1 A2 A3 A4 A5 A6 A7 PA J SI SW ED LA T WI LO GI GS
217  static const int animfr[] = { 5, 2, 8, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 6, 6, 6, 6, 6, 6, 6, 7, 11, 8, 9, 10, 14, 12, 13, 15, 17, 16 };
218 
219  anim &= ANIM_INDEX;
220  if((size_t)anim >= sizeof(animfr)/sizeof(animfr[0]))
221  {
222  info.frame = 0;
223  info.range = 1;
224  return;
225  }
226  int n = animfr[anim];
227  switch(anim)
228  {
229  case ANIM_DYING:
230  case ANIM_DEAD:
231  n -= varseed%3;
232  break;
233  case ANIM_FORWARD:
234  case ANIM_BACKWARD:
235  case ANIM_LEFT:
236  case ANIM_RIGHT:
237  case ANIM_SWIM:
238  info.speed = 5500.0f/d->maxspeed;
239  break;
240  }
241  info.frame = _frame[n];
242  info.range = _range[n];
243  }
244  };
245 
246  meshgroup *loadmeshes(const char *name, va_list args) override
247  {
248  md2meshgroup *group = new md2meshgroup;
249  if(!group->load(name)) { delete group; return nullptr; }
250  return group;
251  }
252 
254  {
255  md2part *p = new md2part(this, parts.length());
256  parts.add(p);
257  return *p;
258  }
259 
260  bool load() override
261  {
262  part &mdl = addpart();
263  const char *pname = parentdir(name);
264  defformatstring(name1, "%s/%s/tris.md2", *modeldir, name);
265  mdl.meshes = sharemeshes(path(name1));
266  if(!mdl.meshes)
267  {
268  defformatstring(name2, "%s/%s/tris.md2", *modeldir, pname); // try md2 in parent folder (vert sharing)
269  mdl.meshes = sharemeshes(path(name2));
270  if(!mdl.meshes) return false;
271  }
272  Texture *tex, *masks;
273  loadskin(name, pname, tex, masks);
274  mdl.initskins(tex, masks);
275  if(tex==notexture) Log.std->error("could not load model skin for {}", name1);
276  loading = this;
278  defformatstring(name3, "%s/%s/md2.cfg", *modeldir, name);
279  if(!execfile(name3, false))
280  {
281  formatstring(name3, "%s/%s/md2.cfg", *modeldir, pname);
282  execfile(name3, false);
283  }
285  loading = nullptr;
286  translate.y = -translate.y;
287  loaded();
288  return true;
289  }
290 };
291 
293 
void loadskin(const char *dir, const char *altdir, Texture *&skin, Texture *&masks)
Definition: rendermodel.cpp:1088
vec translate
Definition: model.hpp:46
Vector template.
Definition: cube_vector.hpp:22
virtual void loaded()
Definition: animmodel.hpp:1298
int offsetframes
Definition: md2.hpp:60
char * name
Definition: model.hpp:42
virtual bool seek(offset pos, int whence=SEEK_SET)
Definition: stream.hpp:39
Definition: vertmodel.hpp:25
int identflags
Definition: command.cpp:41
unsigned int uint
Definition: cube_types.hpp:9
float maxspeed
Definition: ents.hpp:133
void initskins(Texture *tex=notexture, Texture *masks=notexture, int limit=0)
Definition: animmodel.hpp:691
Definition: animmodel.hpp:465
Definition: md2.hpp:204
bool load() override
Definition: md2.hpp:260
uchar normalindex
Definition: md2.hpp:65
bool execfile(const char *cfgfile, bool msg)
Definition: command.cpp:2262
#define ANIM_INDEX
Definition: ents.hpp:211
static Logger std
Logger for everything not fitting elsewhere.
Definition: Logging.hpp:89
meshgroup * sharemeshes(const char *name,...)
Definition: animmodel.hpp:583
vec norm
Definition: vertmodel.hpp:8
Definition: model.hpp:40
int numtexcoords
Definition: md2.hpp:57
meshgroup * meshes
Definition: animmodel.hpp:613
Definition: md2.hpp:51
int numglcommands
Definition: md2.hpp:58
int range
Definition: ents.hpp:232
vec pos
Definition: vertmodel.hpp:8
static bool multiparted()
Definition: md2.hpp:78
T * getbuf()
get the whole vector
Definition: cube_vector.hpp:169
2-dimensional float vectors
Definition: geom.hpp:38
Definition: md2.hpp:49
tri * tris
Definition: vertmodel.hpp:30
int linktype(animmodel *m) const override
Definition: md2.hpp:82
int framesize
Definition: md2.hpp:56
int offsettriangles
Definition: md2.hpp:59
int type() const override
Definition: md2.hpp:80
int frame
Definition: ents.hpp:232
SharedVar< char * > modeldir
char * name
Definition: animmodel.hpp:469
int magic
Definition: md2.hpp:53
static md2 * loading
Definition: animmodel.hpp:1396
meshgroup * loadmeshes(const char *name, va_list args) override
Definition: md2.hpp:246
int numtris
Definition: vertmodel.hpp:31
float translate[3]
Definition: md2.hpp:71
meshgroup * group
Definition: animmodel.hpp:279
int skinwidth
Definition: md2.hpp:55
char name[16]
Definition: md2.hpp:72
Definition: animmodel.hpp:965
int numvertices
Definition: md2.hpp:57
virtual size_t read(void *buf, size_t len)
Definition: stream.hpp:42
Definition: ents.hpp:184
Definition: ents.hpp:230
int numtriangles
Definition: md2.hpp:58
ICOMMAND * f(float *a, float *b), floatret(*a **b)
void genverts(int *glcommands, vector< tcvert > &tcverts, vector< ushort > &vindexes, vector< tri > &tris)
Definition: md2.hpp:86
unsigned short ushort
Definition: cube_types.hpp:8
void setsize(int i)
shrink vector memory size
Definition: cube_vector.hpp:163
else loopi(numargs)
Definition: command.cpp:3019
Definition: ents.hpp:183
int offsetskins
Definition: md2.hpp:59
GLuint index
Definition: glexts.hpp:412
int numverts
Definition: vertmodel.hpp:31
Definition: ents.hpp:183
vec2 tc
Definition: vertmodel.hpp:12
int numskins
Definition: md2.hpp:57
int offsetend
Definition: md2.hpp:60
T & add(const T &x)
Add new index to vector.
Definition: cube_vector.hpp:73
Definition: md2.hpp:68
vector with 3 floats and some useful methods.
Definition: geom.hpp:110
static const float md2normaltable[256][3]
Definition: md2.hpp:4
char void formatstring(char(&d)[N], const char *fmt,...) PRINTFARGS(2
bool load(const char *filename)
Definition: md2.hpp:128
inexor::util::log_manager Log
Definition: Logging.cpp:241
static bool multimeshed()
Definition: md2.hpp:79
char * path(char *s)
Modifies the input string to only contain slashes in the direction the platform allows.
Definition: stream.cpp:63
void getdefaultanim(animinfo &info, int anim, uint varseed, dynent *d) override
Definition: md2.hpp:210
vert * verts
Definition: vertmodel.hpp:27
int length() const
return size of used memory
Definition: cube_vector.hpp:146
int numframes
Definition: vertmodel.hpp:218
Definition: ents.hpp:184
const char * parentdir(const char *filename)
Definition: stream.cpp:120
Definition: md2.hpp:63
tcvert * tcverts
Definition: vertmodel.hpp:28
int d
Definition: octaedit.cpp:1749
void t(T x, const char *cmp)
Definition: utilTest.cpp:52
Legacy file system streams.
Definition: stream.hpp:22
Definition: ents.hpp:258
static aviwriter * file
Definition: movie.cpp:830
#define loopk(m)
Definition: cube_loops.hpp:10
Definition: vertmodel.hpp:435
Definition: command.hpp:72
vector< part * > parts
Definition: animmodel.hpp:1118
unsigned char uchar
Basic type definitions.
Definition: cube_types.hpp:7
Definition: md2.hpp:84
int offsettexcoords
Definition: md2.hpp:59
Definition: model.hpp:11
int version
Definition: md2.hpp:54
vector< mesh * > meshes
Definition: animmodel.hpp:470
Definition: vertmodel.hpp:6
Definition: ents.hpp:184
Definition: animmodel.hpp:609
#define loopj(m)
Definition: cube_loops.hpp:9
Definition: world.hpp:82
Texture * notexture
Global used to specify this texture has not be found.
Definition: texture.cpp:266
GLsizei const GLuint GLenum pname
Definition: glexts.hpp:396
T * access(const U &key)
Definition: cube_hash.hpp:135
Definition: vertmodel.hpp:14
Definition: vertmodel.hpp:439
Definition: vertmodel.hpp:8
float scale[3]
Definition: md2.hpp:70
int numframes
Definition: md2.hpp:58
int skinheight
Definition: md2.hpp:55
static const char * formatname()
Definition: md2.hpp:77
#define defformatstring(d,...)
Definition: cube_formatting.hpp:62
stream * openfile(const char *filename, const char *mode)
Definition: stream.cpp:907
vertcommands< md2 > md2commands
Definition: md2.hpp:292
Definition: ents.hpp:188
3-dimensional INTEGER vectors
Definition: geom.hpp:1226
Definition: cube_hash.hpp:248
md2part(animmodel *model, int index=0)
Definition: md2.hpp:206
uchar vertex[3]
Definition: md2.hpp:65
Definition: ents.hpp:184
char * newstring(size_t l)
Definition: cube_tools.hpp:71
md2part & addpart()
Definition: md2.hpp:253
ushort vert[3]
Definition: vertmodel.hpp:14
Definition: animmodel.hpp:3
md2(const char *name)
Definition: md2.hpp:75
T lilswap(T n)
Definition: cube_endian.hpp:41
A Texture entry, holding info about a texture on the GPU.
Definition: texture.hpp:27
int offsetglcommands
Definition: md2.hpp:60
float speed
Definition: ents.hpp:233
Definition: vertmodel.hpp:12