Inexor
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
md3.hpp
Go to the documentation of this file.
1 #pragma once
3 
4 struct md3frame
5 {
7  float radius;
8  uchar name[16];
9 };
10 
11 struct md3tag
12 {
13  char name[64];
14  float translation[3];
15  float rotation[3][3];
16 };
17 
18 struct md3vertex
19 {
20  short vertex[3];
21  short normal;
22 };
23 
25 {
26  int vertexindices[3];
27 };
28 
29 struct md3header
30 {
31  char id[4];
32  int version;
33  char name[64];
34  int flags;
37 };
38 
40 {
41  char id[4];
42  char name[64];
43  int flags;
46 };
47 
48 struct md3 : vertmodel, vertloader<md3>
49 {
50  md3(const char *name) : vertmodel(name) {}
51 
52  static const char *formatname() { return "md3"; }
53  int type() const override { return MDL_MD3; }
54 
56  {
57  bool load(const char *path)
58  {
59  stream *f = openfile(path, "rb");
60  if(!f) return false;
61  md3header header;
62  f->read(&header, sizeof(md3header));
63  lilswap(&header.version, 1);
64  lilswap(&header.flags, 9);
65  if(strncmp(header.id, "IDP3", 4) != 0 || header.version != 15) // header check
66  {
67  delete f;
68  Log.std->error("md3: corrupted header");
69  return false;
70  }
71 
72  name = newstring(path);
73 
74  numframes = header.numframes;
75 
76  int mesh_offset = header.ofs_meshes;
77  loopi(header.nummeshes)
78  {
79  vertmesh &m = *new vertmesh;
80  m.group = this;
81  meshes.add(&m);
82 
83  md3meshheader mheader;
84  f->seek(mesh_offset, SEEK_SET);
85  f->read(&mheader, sizeof(md3meshheader));
86  lilswap(&mheader.flags, 10);
87 
88  m.name = newstring(mheader.name);
89 
90  m.numtris = mheader.numtriangles;
91  m.tris = new tri[m.numtris];
92  f->seek(mesh_offset + mheader.ofs_triangles, SEEK_SET);
93  loopj(m.numtris)
94  {
96  f->read(&tri, sizeof(md3triangle)); // read the triangles
97  lilswap(tri.vertexindices, 3);
98  loopk(3) m.tris[j].vert[k] = (ushort)tri.vertexindices[k];
99  }
100 
101  m.numverts = mheader.numvertices;
102  m.tcverts = new tcvert[m.numverts];
103  f->seek(mesh_offset + mheader.ofs_uv , SEEK_SET);
104  f->read(m.tcverts, m.numverts*2*sizeof(float)); // read the UV data
105  lilswap(&m.tcverts[0].tc.x, 2*m.numverts);
106 
107  m.verts = new vert[numframes*m.numverts];
108  f->seek(mesh_offset + mheader.ofs_vertices, SEEK_SET);
110  {
111  md3vertex v;
112  f->read(&v, sizeof(md3vertex)); // read the vertices
113  lilswap(v.vertex, 4);
114 
115  m.verts[j].pos.x = v.vertex[0]/64.0f;
116  m.verts[j].pos.y = -v.vertex[1]/64.0f;
117  m.verts[j].pos.z = v.vertex[2]/64.0f;
118 
119  float lng = (v.normal&0xFF)*PI2/255.0f; // decode vertex normals
120  float lat = ((v.normal>>8)&0xFF)*PI2/255.0f;
121  m.verts[j].norm.x = cosf(lat)*sinf(lng);
122  m.verts[j].norm.y = -sinf(lat)*sinf(lng);
123  m.verts[j].norm.z = cosf(lng);
124  }
125 
126  mesh_offset += mheader.meshsize;
127  }
128 
129  numtags = header.numtags;
130  if(numtags)
131  {
132  tags = new tag[numframes*numtags];
133  f->seek(header.ofs_tags, SEEK_SET);
134  md3tag tag;
135 
136  loopi(header.numframes*header.numtags)
137  {
138  f->read(&tag, sizeof(md3tag));
139  lilswap(tag.translation, 12);
140  if(tag.name[0] && i<header.numtags) tags[i].name = newstring(tag.name);
141  matrix4x3 &m = tags[i].transform;
142  tag.translation[1] *= -1;
143  // undo the -y
144  loopj(3) tag.rotation[1][j] *= -1;
145  // then restore it
146  loopj(3) tag.rotation[j][1] *= -1;
147  m.a = vec(tag.rotation[0]);
148  m.b = vec(tag.rotation[1]);
149  m.c = vec(tag.rotation[2]);
150  m.d = vec(tag.translation);
151  }
152  }
153 
154  delete f;
155  return true;
156  }
157  };
158 
159  meshgroup *loadmeshes(const char *name, va_list args) override
160  {
161  md3meshgroup *group = new md3meshgroup;
162  if(!group->load(name)) { delete group; return nullptr; }
163  return group;
164  }
165 
166  bool loaddefaultparts() override
167  {
168  const char *pname = parentdir(name);
169  part &mdl = addpart();
170 
171  defformatstring(name1, "%s/%s/tris.md3", *modeldir, name);
172  mdl.meshes = sharemeshes(path(name1));
173  if(!mdl.meshes)
174  {
175  defformatstring(name2, "%s/%s/tris.md3", *modeldir, pname); // try md3 in parent folder (vert sharing)
176  mdl.meshes = sharemeshes(path(name2));
177  if(!mdl.meshes) return false;
178  }
179  Texture *tex, *masks;
180  loadskin(name, pname, tex, masks);
181  mdl.initskins(tex, masks);
182  if(tex==notexture) Log.std->error("could not load model skin for {}", name1);
183  return true;
184  }
185 
186  bool load() override
187  {
188  formatstring(dir, "%s/%s", *modeldir, name);
189  defformatstring(cfgname, "%s/%s/md3.cfg", *modeldir, name);
190 
191  loading = this;
193  if(execfile(cfgname, false) && parts.length()) // configured md3, will call the md3* commands below
194  {
196  loading = nullptr;
197  loopv(parts) if(!parts[i]->meshes) return false;
198  }
199  else // md3 without configuration, try default tris and skin
200  {
202  loading = nullptr;
203  if(!loaddefaultparts()) return false;
204  }
205  translate.y = -translate.y;
206  loaded();
207  return true;
208  }
209 };
210 
212 
void loadskin(const char *dir, const char *altdir, Texture *&skin, Texture *&masks)
Definition: rendermodel.cpp:1088
Definition: model.hpp:11
part & addpart()
Definition: animmodel.hpp:1134
vec translate
Definition: model.hpp:46
vec c
Definition: geom.hpp:904
Definition: geom.hpp:902
#define PI2
Definition: cube_types.hpp:29
Definition: md3.hpp:48
virtual void loaded()
Definition: animmodel.hpp:1298
char * name
Definition: vertmodel.hpp:209
char * name
Definition: model.hpp:42
string cfgname
Definition: worldio.cpp:227
virtual bool seek(offset pos, int whence=SEEK_SET)
Definition: stream.hpp:39
Definition: vertmodel.hpp:25
md3(const char *name)
Definition: md3.hpp:50
int identflags
Definition: command.cpp:41
void initskins(Texture *tex=notexture, Texture *masks=notexture, int limit=0)
Definition: animmodel.hpp:691
Definition: animmodel.hpp:465
bool execfile(const char *cfgfile, bool msg)
Definition: command.cpp:2262
int version
Definition: md3.hpp:32
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
int ofs_shaders
Definition: md3.hpp:45
meshgroup * meshes
Definition: animmodel.hpp:613
vec pos
Definition: vertmodel.hpp:8
int ofs_eof
Definition: md3.hpp:36
short vertex[3]
Definition: md3.hpp:20
Definition: md3.hpp:4
tri * tris
Definition: vertmodel.hpp:30
int numskins
Definition: md3.hpp:35
SharedVar< char * > modeldir
char * name
Definition: animmodel.hpp:469
Definition: md3.hpp:11
static md3 * loading
Definition: animmodel.hpp:1396
float rotation[3][3]
Definition: md3.hpp:15
bool load(const char *path)
Definition: md3.hpp:57
vec bbmin
Definition: md3.hpp:6
int numtris
Definition: vertmodel.hpp:31
meshgroup * group
Definition: animmodel.hpp:279
int numframes
Definition: md3.hpp:35
int ofs_tags
Definition: md3.hpp:36
virtual size_t read(void *buf, size_t len)
Definition: stream.hpp:42
char * name
Definition: animmodel.hpp:280
Definition: vertmodel.hpp:207
int ofs_frames
Definition: md3.hpp:36
meshgroup * loadmeshes(const char *name, va_list args) override
Definition: md3.hpp:159
Definition: md3.hpp:29
vec b
Definition: geom.hpp:904
char name[64]
Definition: md3.hpp:42
ICOMMAND * f(float *a, float *b), floatret(*a **b)
unsigned short ushort
Definition: cube_types.hpp:8
float translation[3]
Definition: md3.hpp:14
int numtags
Definition: vertmodel.hpp:220
else loopi(numargs)
Definition: command.cpp:3019
bool load() override
Definition: md3.hpp:186
Definition: md3.hpp:39
int numverts
Definition: vertmodel.hpp:31
vec d
Definition: geom.hpp:904
vec2 tc
Definition: vertmodel.hpp:12
int ofs_meshes
Definition: md3.hpp:36
vector with 3 floats and some useful methods.
Definition: geom.hpp:110
char id[4]
Definition: md3.hpp:31
int numshaders
Definition: md3.hpp:44
short normal
Definition: md3.hpp:21
char void formatstring(char(&d)[N], const char *fmt,...) PRINTFARGS(2
uchar name[16]
Definition: md3.hpp:8
Definition: vertmodel.hpp:216
float radius
Definition: md3.hpp:7
Definition: md3.hpp:24
inexor::util::log_manager Log
Definition: Logging.cpp:241
Definition: md3.hpp:18
char * path(char *s)
Modifies the input string to only contain slashes in the direction the platform allows.
Definition: stream.cpp:63
int nummeshes
Definition: md3.hpp:35
vert * verts
Definition: vertmodel.hpp:27
Definition: md3.hpp:55
int numtriangles
Definition: md3.hpp:44
vec bbmax
Definition: md3.hpp:6
int numframes
Definition: md3.hpp:44
int numframes
Definition: vertmodel.hpp:218
const char * parentdir(const char *filename)
Definition: stream.cpp:120
tcvert * tcverts
Definition: vertmodel.hpp:28
Legacy file system streams.
Definition: stream.hpp:22
#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
tag * tags
Definition: vertmodel.hpp:219
vector< mesh * > meshes
Definition: animmodel.hpp:470
int numtags
Definition: md3.hpp:35
vec a
Definition: geom.hpp:904
Definition: vertmodel.hpp:6
int flags
Definition: md3.hpp:34
vertcommands< md3 > md3commands
Definition: md3.hpp:211
int type() const override
Definition: md3.hpp:53
Definition: animmodel.hpp:609
int vertexindices[3]
Definition: md3.hpp:26
#define loopj(m)
Definition: cube_loops.hpp:9
int numvertices
Definition: md3.hpp:44
Definition: world.hpp:82
matrix4x3 transform
Definition: vertmodel.hpp:210
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
Definition: vertmodel.hpp:14
Definition: vertmodel.hpp:439
Definition: vertmodel.hpp:8
#define defformatstring(d,...)
Definition: cube_formatting.hpp:62
char name[64]
Definition: md3.hpp:13
stream * openfile(const char *filename, const char *mode)
Definition: stream.cpp:907
static const char * formatname()
Definition: md3.hpp:52
int ofs_uv
Definition: md3.hpp:45
vec origin
Definition: md3.hpp:6
int ofs_triangles
Definition: md3.hpp:45
#define loopv(v)
Definition: cube_loops.hpp:21
char * newstring(size_t l)
Definition: cube_tools.hpp:71
static string dir
Definition: animmodel.hpp:1397
ushort vert[3]
Definition: vertmodel.hpp:14
bool loaddefaultparts() override
Definition: md3.hpp:166
char name[64]
Definition: md3.hpp:33
int meshsize
Definition: md3.hpp:45
int flags
Definition: md3.hpp:43
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 ofs_vertices
Definition: md3.hpp:45
Definition: vertmodel.hpp:12