UFO: Alien Invasion
Loading...
Searching...
No Matches
ufomodel.cpp
Go to the documentation of this file.
1
5
6/*
7Copyright (C) 1997-2001 Id Software, Inc.
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
27#include "../../common/mem.h"
28#include "../../shared/shared.h"
31#include "../../common/mem.h"
32#define QGL_EXTERN
38#include "../../shared/images.h"
39#include "../../common/common.h"
40#include "md2.h"
41#include <SDL_main.h>
42#include <cstddef>
43
44#define VERSION "0.2"
45
48
60
61typedef struct modelConfig_s {
63 bool verbose;
69
71
75memPool_t* vid_lightPool; /* compilation dependency */
77
78static void Exit(int exitCode) __attribute__ ((__noreturn__));
79
80static void Exit (int exitCode)
81{
83
84 exit(exitCode);
85}
86
87void Com_Printf (const char* format, ...)
88{
89 char out_buffer[4096];
90 va_list argptr;
91
92 va_start(argptr, format);
93 Q_vsnprintf(out_buffer, sizeof(out_buffer), format, argptr);
94 va_end(argptr);
95
96 printf("%s", out_buffer);
97}
98
99void Com_DPrintf (int level, const char* fmt, ...)
100{
101 if (config.verbose) {
102 char outBuffer[4096];
103 va_list argptr;
104
105 va_start(argptr, fmt);
106 Q_vsnprintf(outBuffer, sizeof(outBuffer), fmt, argptr);
107 va_end(argptr);
108
109 Com_Printf("%s", outBuffer);
110 }
111}
112
113image_t* R_LoadImageData (const char* name, const byte* pic, int width, int height, imagetype_t type)
114{
115 image_t* image;
116 size_t len;
117
118 len = strlen(name);
119 if (len >= sizeof(image->name))
120 Com_Error(ERR_DROP, "R_LoadImageData: \"%s\" is too long", name);
121 if (len == 0)
122 Com_Error(ERR_DROP, "R_LoadImageData: name is empty");
123
125 image->has_alpha = false;
126 image->type = type;
127 image->width = width;
128 image->height = height;
129
130 Q_strncpyz(image->name, name, sizeof(image->name));
131 /* drop extension */
132 if (len >= 4 && image->name[len - 4] == '.') {
133 image->name[len - 4] = '\0';
134 Com_Printf("Image with extension: '%s'\n", name);
135 }
136
137 return image;
138}
139
140image_t* R_FindImage (const char* pname, imagetype_t type)
141{
142 char lname[MAX_QPATH];
143 image_t* image;
144 SDL_Surface* surf;
145
146 if (!pname || !pname[0])
147 Com_Error(ERR_FATAL, "R_FindImage: invalid name");
148
149 /* drop extension */
150 Com_StripExtension(pname, lname, sizeof(lname));
151
152 if ((surf = Img_LoadImage(lname))) {
153 image = R_LoadImageData(lname, (byte*)surf->pixels, surf->w, surf->h, type);
154 SDL_FreeSurface(surf);
155 } else {
156 image = nullptr;
157 }
158
159 /* no fitting texture found */
160 if (!image) {
161 Com_Printf(" \\ - could not load skin '%s'\n", pname);
162 image = r_noTexture;
163 }
164
165 return image;
166}
167
172void Com_Error (int code, const char* fmt, ...)
173{
174 va_list argptr;
175 static char msg[1024];
176
177 va_start(argptr, fmt);
178 Q_vsnprintf(msg, sizeof(msg), fmt, argptr);
179 va_end(argptr);
180
181 fprintf(stderr, "Error: %s\n", msg);
182 Exit(1);
183}
184
189static model_t* LoadModel (const char* name)
190{
191 byte* buf;
192 int modfilelen;
193
194 /* load the file */
195 modfilelen = FS_LoadFile(name, &buf);
196 if (!buf) {
197 Com_Printf("Could not load '%s'\n", name);
198 return nullptr;
199 }
200
202 Q_strncpyz(mod->name, name, sizeof(mod->name));
203
204 /* call the appropriate loader */
205 switch (LittleLong(*(unsigned* ) buf)) {
206 case IDALIASHEADER:
207 /* MD2 header */
208 R_ModLoadAliasMD2Model(mod, buf, modfilelen, false);
209 break;
210
211 case IDMD3HEADER:
212 /* MD3 header */
213 R_ModLoadAliasMD3Model(mod, buf, modfilelen);
214 break;
215
216 default:
217 if (!Q_strcasecmp(mod->name + strlen(mod->name) - 4, ".obj"))
218 R_LoadObjModel(mod, buf, modfilelen);
219 else
220 Com_Error(ERR_FATAL, "LoadModel: unknown fileid for %s", mod->name);
221 }
222
224
225 return mod;
226}
227
228static void WriteToFile (const model_t* mod, const mAliasMesh_t* mesh, const char* fileName)
229{
230 uint32_t version = MDX_VERSION;
231 int32_t numIndexes, numVerts;
232
233 Com_Printf(" \\ - writing to file '%s'\n", fileName);
234
236 FS_OpenFile(fileName, &f, FILE_WRITE);
237 if (!f) {
238 Com_Printf(" \\ - can not open '%s' for writing\n", fileName);
239 return;
240 }
241
242 FS_Write(IDMDXHEADER, strlen(IDMDXHEADER), &f);
243 version = LittleLong(version);
244 FS_Write(&version, sizeof(version), &f);
245
246 numIndexes = LittleLong(mesh->num_tris * 3);
247 numVerts = LittleLong(mesh->num_verts);
248 FS_Write(&numVerts, sizeof(numVerts), &f);
249 FS_Write(&numIndexes, sizeof(numIndexes), &f);
250
251 for (int i = 0; i < mesh->num_tris * 3; i++) {
252 const int32_t idx = LittleLong(mesh->indexes[i]);
253 FS_Write(&idx, sizeof(idx), &f);
254 }
255}
256
257static int PrecalcNormalsAndTangents (const char* filename)
258{
259 char mdxFileName[MAX_QPATH];
260 int cntCalculated = 0;
261
262 Com_Printf("- model '%s'\n", filename);
263
264 Com_StripExtension(filename, mdxFileName, sizeof(mdxFileName));
265 Q_strcat(mdxFileName, sizeof(mdxFileName), ".mdx");
266
267 if (!config.overwrite && FS_CheckFile("%s", mdxFileName) != -1) {
268 Com_Printf(" \\ - mdx already exists\n");
269 return 0;
270 }
271
272 model_t* mod = LoadModel(filename);
273 if (!mod)
274 Com_Error(ERR_DROP, "Could not load %s", filename);
275
276 Com_Printf(" \\ - # meshes '%i', # frames '%i'\n", mod->alias.num_meshes, mod->alias.num_frames);
277
278 for (int i = 0; i < mod->alias.num_meshes; i++) {
279 mAliasMesh_t* mesh = &mod->alias.meshes[i];
283 WriteToFile(mod, mesh, mdxFileName);
284
285 cntCalculated++;
286 }
287
288 return cntCalculated;
289}
290
291static void PrecalcNormalsAndTangentsBatch (const char* pattern)
292{
293 const char* filename;
294 int cntCalculated, cntAll;
295
296 FS_BuildFileList(pattern);
297
298 cntAll = cntCalculated = 0;
299
300 while ((filename = FS_NextFileFromFileList(pattern)) != nullptr) {
301 cntAll++;
302 cntCalculated += PrecalcNormalsAndTangents(filename);
303 }
304
306
307 Com_Printf("%i/%i\n", cntCalculated, cntAll);
308}
309
310static void Usage (void)
311{
312 Com_Printf("Usage:\n");
313 Com_Printf(" -mdx generate mdx files\n");
314 Com_Printf(" -skinfix fix skins for md2 models\n");
315 Com_Printf(" -glcmds remove the unused glcmds from md2 models\n");
316 Com_Printf(" -check perform general checks for all the models\n");
317 Com_Printf(" -skinedit <filename> edit skin of a model\n");
318 Com_Printf(" -skinnum <filename> edit the skin numbers of a model\n");
319 Com_Printf(" -info <filename> show model information\n");
320 Com_Printf(" -overwrite overwrite existing mdx files\n");
321 Com_Printf(" -s <float> sets the smoothness value for normal-smoothing (in the range -1.0 to 1.0)\n");
322 Com_Printf(" -f <filename> build tangentspace for the specified model file\n");
323 Com_Printf(" -v --verbose print debug messages\n");
324 Com_Printf(" -h --help show this help screen\n");
325}
326
327static void UM_DefaultParameter (void)
328{
329 config.smoothness = 0.5;
330}
331
335static void UM_Parameter (int argc, char** argv)
336{
337 int i;
338
339 for (i = 1; i < argc; i++) {
340 if (Q_streq(argv[i], "-overwrite")) {
341 config.overwrite = true;
342 } else if (Q_streq(argv[i], "-f") && (i + 1 < argc)) {
343 Q_strncpyz(config.inputName, argv[++i], sizeof(config.inputName));
344 } else if (Q_streq(argv[i], "-s") && (i + 1 < argc)) {
345 config.smoothness = strtod(argv[++i], nullptr);
346 if (config.smoothness < -1.0 || config.smoothness > 1.0) {
347 Usage();
348 Exit(1);
349 }
350 } else if (Q_streq(argv[i], "-mdx")) {
351 config.action = ACTION_MDX;
352 } else if (Q_streq(argv[i], "-glcmds")) {
354 } else if (Q_streq(argv[i], "-skinfix")) {
355 config.action = ACTION_SKINFIX;
356 } else if (Q_streq(argv[i], "-check")) {
357 config.action = ACTION_CHECK;
358 } else if (Q_streq(argv[i], "-info")) {
359 config.action = ACTION_INFO;
360 if (i + 1 == argc) {
361 Usage();
362 Exit(1);
363 }
364 Q_strncpyz(config.fileName, argv[i + 1], sizeof(config.fileName));
365 i++;
366 } else if (Q_streq(argv[i], "-skinedit")) {
367 config.action = ACTION_SKINEDIT;
368 if (i + 1 == argc) {
369 Usage();
370 Exit(1);
371 }
372 Q_strncpyz(config.fileName, argv[i + 1], sizeof(config.fileName));
373 i++;
374 } else if (Q_streq(argv[i], "-skinnum")) {
375 config.action = ACTION_SKINNUM;
376 if (i + 1 == argc) {
377 Usage();
378 Exit(1);
379 }
380 Q_strncpyz(config.fileName, argv[i + 1], sizeof(config.fileName));
381 i++;
382 } else if (Q_streq(argv[i], "-v") || Q_streq(argv[i], "--verbose")) {
383 config.verbose = true;
384 } else if (Q_streq(argv[i], "-h") || Q_streq(argv[i], "--help")) {
385 Usage();
386 Exit(0);
387 } else {
388 Com_Printf("Parameters unknown. Try --help.\n");
389 Usage();
390 Exit(1);
391 }
392 }
393}
394
395typedef void (*modelWorker_t) (const byte* buf, const char* fileName, int bufSize, void* userData);
396
403static void ModelWorker (modelWorker_t worker, const char* fileName, void* userData)
404{
405 byte* buf = nullptr;
406 int modfilelen;
407
408 /* load the file */
409 modfilelen = FS_LoadFile(fileName, &buf);
410 if (!buf)
411 Com_Error(ERR_FATAL, "%s not found", fileName);
412
413 switch (LittleLong(*(unsigned* ) buf)) {
414 case IDALIASHEADER:
415 case IDMD3HEADER:
416 case IDBSPHEADER:
417 worker(buf, fileName, modfilelen, userData);
418 break;
419
420 default:
421 if (!Q_strcasecmp(fileName + strlen(fileName) - 4, ".obj"))
422 worker(buf, fileName, modfilelen, userData);
423 else
424 Com_Error(ERR_DROP, "ModelWorker: unknown fileid for %s", fileName);
425 }
426
428}
429
430static void MD2SkinFix (const byte* buf, const char* fileName, int bufSize, void* userData)
431{
432 const dMD2Model_t* md2 = (const dMD2Model_t*)buf;
433 byte* model = nullptr;
434
435 MD2HeaderCheck(md2, fileName, bufSize);
436
437 const char* md2Path = (const char*) md2 + LittleLong(md2->ofs_skins);
438 uint32_t numSkins = LittleLong(md2->num_skins);
439
440 for (int i = 0; i < numSkins; i++) {
441 const char* extension;
442 int errors = 0;
443 const char* name = md2Path + i * MD2_MAX_SKINNAME;
444
445 if (name[0] != '.')
446 errors++;
447 else
448 /* skip the . to not confuse the extension extraction below */
449 name++;
450
451 extension = Com_GetExtension(name);
452 if (extension != nullptr)
453 errors++;
454
455 if (errors > 0) {
456 dMD2Model_t* fixedMD2;
457 char* skinPath;
458 char path[MD2_MAX_SKINNAME];
459 char pathBuf[MD2_MAX_SKINNAME];
460 const char* fixedPath;
461 if (model == nullptr) {
462 model = Mem_Dup(byte, buf, bufSize);
463 Com_Printf("model: %s\n", fileName);
464 }
465 fixedMD2 = (dMD2Model_t*)model;
466 skinPath = (char*) fixedMD2 + LittleLong(fixedMD2->ofs_skins) + i * MD2_MAX_SKINNAME;
467
468 OBJZERO(path);
469
470 if (extension != nullptr) {
471 Com_StripExtension(name, pathBuf, sizeof(pathBuf));
472 fixedPath = pathBuf;
473 } else {
474 fixedPath = name;
475 }
476 if (name[0] != '.')
477 Com_sprintf(path, sizeof(path), ".%s", Com_SkipPath(fixedPath));
478 Com_Printf(" \\ - skin %i: changed path to '%s'\n", i + 1, path);
479 if (R_AliasModelGetSkin(fileName, path) == r_noTexture) {
480 Com_Printf(" \\ - could not load the skin with the new path\n");
481 } else {
482 memcpy(skinPath, path, sizeof(path));
483 }
484 }
485 }
486 if (model != nullptr) {
487 FS_WriteFile(model, bufSize, fileName);
488 Mem_Free(model);
489 }
490}
491
492static void MD2Check (const byte* buf, const char* fileName, int bufSize, void* userData)
493{
494 bool headline = false;
495 const dMD2Model_t* md2 = (const dMD2Model_t*)buf;
496
497 MD2HeaderCheck(md2, fileName, bufSize);
498
499 const char* md2Path = (const char*) md2 + LittleLong(md2->ofs_skins);
500 uint32_t numSkins = LittleLong(md2->num_skins);
501
502 for (int i = 0; i < numSkins; i++) {
503 const char* extension;
504 int errors = 0;
505 const char* name = md2Path + i * MD2_MAX_SKINNAME;
506
507 if (name[0] != '.')
508 errors++;
509 else
510 /* skip the . to not confuse the extension extraction below */
511 name++;
512
513 extension = Com_GetExtension(name);
514 if (extension != nullptr)
515 errors++;
516
517 if (errors > 0) {
518 if (!headline) {
519 Com_Printf("model: %s\n", fileName);
520 headline = true;
521 }
522 Com_Printf(" \\ - skin %i: %s - %i errors/warnings\n", i + 1, name, errors);
523 if (name[0] != '.')
524 Com_Printf(" \\ - skin contains full path\n");
525 if (extension != nullptr)
526 Com_Printf(" \\ - skin contains extension '%s'\n", extension);
527 if (R_AliasModelGetSkin(fileName, md2Path + i * MD2_MAX_SKINNAME) == r_noTexture)
528 Com_Printf(" \\ - could not load the skin\n");
529 }
530 }
531}
532
533static void MD2Visitor (modelWorker_t worker, void* userData)
534{
535 const char* fileName;
536 const char* pattern = "**.md2";
537
538 FS_BuildFileList(pattern);
539
540 while ((fileName = FS_NextFileFromFileList(pattern)) != nullptr)
541 ModelWorker(worker, fileName, userData);
542
544}
545
546static void ModelCheck (void)
547{
548 MD2Visitor(MD2Check, nullptr);
549}
550
551static void SkinFix (void)
552{
553 MD2Visitor(MD2SkinFix, nullptr);
554}
555
556static void GLCmdsRemove (void)
557{
558 size_t bytes = 0;
560 Com_Printf("Saved " UFO_SIZE_T "bytes after removing all glcmds from the md2 files\n", bytes);
561}
562
564{
565 /* TODO: check if stub without code would be sufficient here */
566 if (size <= r_state.array_size)
567 return;
568 r_state.vertex_array_3d = (GLfloat*) Mem_SafeReAlloc(r_state.vertex_array_3d, size * 3 * sizeof(GLfloat));
569 r_state.vertex_array_2d = (GLshort*) Mem_SafeReAlloc(r_state.vertex_array_2d, size * 2 * sizeof(GLshort));
570 r_state.color_array = (GLfloat*) Mem_SafeReAlloc(r_state.color_array, size * 4 * sizeof(GLfloat));
571 r_state.normal_array = (GLfloat*) Mem_SafeReAlloc(r_state.normal_array, size * 3 * sizeof(GLfloat));
572 r_state.tangent_array = (GLfloat*) Mem_SafeReAlloc(r_state.tangent_array, size * 4 * sizeof(GLfloat));
573 r_state.next_vertex_array_3d = (GLfloat*) Mem_SafeReAlloc(r_state.next_vertex_array_3d, size * 3 * sizeof(GLfloat));
574 r_state.next_normal_array = (GLfloat*) Mem_SafeReAlloc(r_state.next_normal_array, size * 3 * sizeof(GLfloat));
575 r_state.next_tangent_array = (GLfloat*) Mem_SafeReAlloc(r_state.next_tangent_array, size * 4 * sizeof(GLfloat));
576 r_state.array_size = size;
577}
578
580{
581 /* TODO: check if stub without code would be sufficient here */
582 if (size <= texunit->array_size)
583 return;
584 texunit->texcoord_array = (GLfloat*) Mem_SafeReAlloc(texunit->texcoord_array, size * 2 * sizeof(GLfloat));
585 texunit->array_size = size;
586 if (!r_state.active_texunit)
587 r_state.active_texunit = texunit;
588}
589
590int main (int argc, char** argv)
591{
592 Com_Printf("---- ufomodel " VERSION " ----\n");
593
595 UM_Parameter(argc, argv);
596
597 if (config.action == ACTION_NONE) {
598 Usage();
599 Exit(1);
600 }
601
602 com_genericPool = Mem_CreatePool("ufomodel");
603 com_fileSysPool = Mem_CreatePool("ufomodel filesys");
604 vid_modelPool = Mem_CreatePool("ufomodel model");
605 vid_imagePool = Mem_CreatePool("ufomodel image");
606
607 Swap_Init();
608 Mem_Init();
609
610 FS_InitFilesystem(false);
611
613 Q_strncpyz(r_noTexture->name, "noTexture", sizeof(r_noTexture->name));
614
615 switch (config.action) {
616 case ACTION_MDX:
617 if (config.inputName[0] == '\0') {
621 /*PrecalcNormalsAndTangentsBatch("**.obj");*/
622 } else {
624 }
625 break;
626
627 case ACTION_SKINEDIT:
628 ModelWorker(MD2SkinEdit, config.fileName, nullptr);
629 break;
630
631 case ACTION_SKINNUM:
632 ModelWorker(MD2SkinNum, config.fileName, nullptr);
633 break;
634
635 case ACTION_INFO:
636 ModelWorker(MD2Info, config.fileName, nullptr);
637 break;
638
639 case ACTION_CHECK:
640 ModelCheck();
641 break;
642
643 case ACTION_SKINFIX:
644 SkinFix();
645 break;
646
648 GLCmdsRemove();
649 break;
650
651 default:
652 Exit(1);
653 }
654
655 Mem_Shutdown();
656
657 return 0;
658}
void Swap_Init(void)
Definition byte.cpp:31
#define LittleLong(X)
Definition byte.h:37
memPool_t * vid_imagePool
Definition cl_main.cpp:88
memPool_t * vid_modelPool
Definition cl_main.cpp:90
memPool_t * vid_lightPool
Definition cl_main.cpp:89
memPool_t * com_genericPool
Definition common.cpp:72
memPool_t * com_fileSysPool
Definition common.cpp:71
definitions common between client and server, but not game lib
#define ERR_DROP
Definition common.h:211
#define ERR_FATAL
Definition common.h:210
#define __attribute__(x)
Definition cxx.h:37
void FS_InitFilesystem(bool writeToHomeDir)
Definition files.cpp:890
int FS_Write(const void *buffer, int len, qFILE *f)
Properly handles partial writes.
Definition files.cpp:1513
int FS_CheckFile(const char *fmt,...)
Just returns the filelength and -1 if the file wasn't found.
Definition files.cpp:298
int FS_LoadFile(const char *path, byte **buffer)
Filenames are relative to the quake search path.
Definition files.cpp:384
void FS_FreeFile(void *buffer)
Definition files.cpp:411
const char * FS_NextFileFromFileList(const char *files)
Returns the next file that is found in the virtual filesystem identified by the given file pattern.
Definition files.cpp:1081
int FS_WriteFile(const void *buffer, size_t len, const char *filename)
Definition files.cpp:1546
int FS_OpenFile(const char *filename, qFILE *file, filemode_t mode)
Finds and opens the file in the search path.
Definition files.cpp:162
int FS_BuildFileList(const char *fileList)
Build a filelist.
Definition files.cpp:962
Filesystem header file.
#define MAX_QPATH
Definition filesys.h:40
@ FILE_WRITE
Definition filesys.h:111
level_locals_t level
Definition g_main.cpp:38
SDL_Surface * Img_LoadImage(char const *name)
Loads the specified image from the game filesystem into an SDL_Surface.
Definition images.cpp:488
Image loading and saving functions.
voidpf void uLong size
Definition ioapi.h:42
const char * filename
Definition ioapi.h:41
voidpf void * buf
Definition ioapi.h:42
void MD2SkinEdit(const byte *buf, const char *fileName, int bufSize, void *userData)
Definition md2.cpp:39
void MD2GLCmdsRemove(const byte *buf, const char *fileName, int bufSize, void *userData)
Definition md2.cpp:213
void MD2Info(const byte *buf, const char *fileName, int bufSize, void *userData)
Definition md2.cpp:71
void MD2SkinNum(const byte *buf, const char *fileName, int bufSize, void *userData)
Definition md2.cpp:120
void MD2HeaderCheck(const dMD2Model_t *md2, const char *fileName, int bufSize)
Definition md2.cpp:11
void Mem_Init(void)
Definition mem.cpp:506
void Mem_Shutdown(void)
Definition mem.cpp:518
Memory handling with sentinel checking and pools with tags for grouped free'ing.
#define Mem_Dup(type, in, n)
Definition mem.h:47
#define Mem_Free(ptr)
Definition mem.h:35
#define Mem_CreatePool(name)
Definition mem.h:32
#define Mem_SafeReAlloc(ptr, size)
Definition mem.h:45
#define Mem_PoolAllocType(type, pool)
Definition mem.h:43
void format(__printf__, 1, 2)))
#define IDBSPHEADER
Definition qfiles.h:251
#define MD2_MAX_SKINNAME
Definition qfiles.h:49
#define IDMDXHEADER
Definition qfiles.h:33
#define MDX_VERSION
Definition qfiles.h:34
#define IDALIASHEADER
Definition qfiles.h:40
#define IDMD3HEADER
Definition qfiles.h:159
OpenGL bindings.
QGL_EXTERN GLuint GLchar GLuint * len
Definition r_gl.h:99
QGL_EXTERN void(APIENTRY *qglActiveTexture)(GLenum texture)
QGL_EXTERN GLfloat f
Definition r_gl.h:114
QGL_EXTERN GLint i
Definition r_gl.h:113
QGL_EXTERN GLint GLenum type
Definition r_gl.h:94
QGL_EXTERN GLuint GLsizei GLsizei GLint GLenum GLchar * name
Definition r_gl.h:110
QGL_EXTERN GLuint GLsizei bufSize
Definition r_gl.h:110
image_t * r_noTexture
Definition r_main.cpp:51
imagetype_t
Definition r_image.h:41
rstate_t r_state
Definition r_main.cpp:48
Header file for the render material subsystem.
Brush model header file.
image_t * R_AliasModelGetSkin(const char *modelFileName, const char *skin)
void R_ModCalcUniqueNormalsAndTangents(mAliasMesh_t *mesh, int nFrames, float smoothness)
Calculates normals and tangents for all frames and does vertex merging based on smoothness.
void R_ModLoadAliasMD2Model(model_t *mod, byte *buffer, int bufSize, bool loadNormals)
Load MD2 models from file.
void R_ModLoadAliasMD3Model(model_t *mod, byte *buffer, int bufSize)
Load MD3 models from file.
void R_LoadObjModel(model_t *mod, byte *buffer, int bufSize)
#define Q_strcasecmp(a, b)
Definition shared.h:131
#define Q_streq(a, b)
Definition shared.h:136
#define OBJZERO(obj)
Definition shared.h:178
void Com_StripExtension(const char *in, char *out, const size_t size)
Removes the file extension from a filename.
Definition shared.cpp:259
const char * Com_SkipPath(const char *pathname)
Returns just the filename from a given path.
Definition shared.cpp:37
void Q_strncpyz(char *dest, const char *src, size_t destsize)
Safe strncpy that ensures a trailing zero.
Definition shared.cpp:457
int Q_vsnprintf(char *str, size_t size, const char *format, va_list ap)
Safe (null terminating) vsnprintf implementation.
Definition shared.cpp:535
const char * Com_GetExtension(const char *path)
Definition shared.cpp:282
void Q_strcat(char *dest, size_t destsize, const char *format,...)
Safely (without overflowing the destination buffer) concatenates two strings.
Definition shared.cpp:475
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
Definition shared.cpp:494
the glcmd format: a positive integer starts a tristrip command, followed by that many vertex structur...
Definition qfiles.h:109
uint32_t ofs_skins
Definition qfiles.h:128
uint32_t num_skins
Definition qfiles.h:121
texunits maintain multitexture state
Definition r_state.h:48
int array_size
Definition r_state.h:55
GLfloat * texcoord_array
Definition r_state.h:53
char name[MAX_QPATH]
Definition r_image.h:62
int height
Definition r_image.h:64
int width
Definition r_image.h:64
bool has_alpha
Definition r_image.h:67
imagetype_t type
Definition r_image.h:63
int32_t * indexes
int32_t num_verts
mAliasMesh_t * meshes
mAliasModel_t alias
Definition r_model.h:63
char name[MAX_QPATH]
Definition r_model.h:44
char fileName[MAX_QPATH]
Definition ufomodel.cpp:64
ufoModelAction_t action
Definition ufomodel.cpp:65
float smoothness
Definition ufomodel.cpp:66
char inputName[MAX_QPATH]
Definition ufomodel.cpp:67
static config_t config
Definition test_all.cpp:43
#define VERSION
Definition ufo2map.cpp:26
ufoModelAction_t
Definition ufomodel.cpp:49
@ ACTION_INFO
Definition ufomodel.cpp:56
@ ACTION_SKINNUM
Definition ufomodel.cpp:54
@ ACTION_SKINEDIT
Definition ufomodel.cpp:53
@ ACTION_SKINFIX
Definition ufomodel.cpp:57
@ ACTION_GLCMDSREMOVE
Definition ufomodel.cpp:58
@ ACTION_NONE
Definition ufomodel.cpp:50
@ ACTION_CHECK
Definition ufomodel.cpp:55
@ ACTION_MDX
Definition ufomodel.cpp:52
static void UM_Parameter(int argc, char **argv)
Parameter parsing.
Definition ufomodel.cpp:335
image_t * R_FindImage(const char *pname, imagetype_t type)
Finds or loads the given image.
Definition ufomodel.cpp:140
int main(int argc, char **argv)
Definition ufomodel.cpp:590
static void MD2SkinFix(const byte *buf, const char *fileName, int bufSize, void *userData)
Definition ufomodel.cpp:430
void(* modelWorker_t)(const byte *buf, const char *fileName, int bufSize, void *userData)
Definition ufomodel.cpp:395
static void SkinFix(void)
Definition ufomodel.cpp:551
void Com_DPrintf(int level, const char *fmt,...)
Definition ufomodel.cpp:99
static void MD2Check(const byte *buf, const char *fileName, int bufSize, void *userData)
Definition ufomodel.cpp:492
image_t * R_LoadImageData(const char *name, const byte *pic, int width, int height, imagetype_t type)
Creates a new image from RGBA data. Stores it in the gltextures array and also uploads it.
Definition ufomodel.cpp:113
void Com_Error(int code, const char *fmt,...)
Definition ufomodel.cpp:172
static void GLCmdsRemove(void)
Definition ufomodel.cpp:556
static void ModelCheck(void)
Definition ufomodel.cpp:546
static int PrecalcNormalsAndTangents(const char *filename)
Definition ufomodel.cpp:257
static void PrecalcNormalsAndTangentsBatch(const char *pattern)
Definition ufomodel.cpp:291
void Com_Printf(const char *format,...)
Definition ufomodel.cpp:87
static void UM_DefaultParameter(void)
Definition ufomodel.cpp:327
static model_t * LoadModel(const char *name)
Loads in a model for the given name.
Definition ufomodel.cpp:189
static void Exit(int exitCode) __attribute__((__noreturn__))
Definition ufomodel.cpp:80
void R_ReallocateTexunitArray(gltexunit_t *texunit, int size)
Reallocate texcoord array of the specified texunit, if needed.
Definition ufomodel.cpp:579
static void MD2Visitor(modelWorker_t worker, void *userData)
Definition ufomodel.cpp:533
static void WriteToFile(const model_t *mod, const mAliasMesh_t *mesh, const char *fileName)
Definition ufomodel.cpp:228
static void Usage(void)
Definition ufomodel.cpp:310
void R_ReallocateStateArrays(int size)
Reallocate arrays of GL primitives if needed.
Definition ufomodel.cpp:563
static void ModelWorker(modelWorker_t worker, const char *fileName, void *userData)
The caller has to ensure that the model is from the expected format.
Definition ufomodel.cpp:403
Cross-platform type definitions.
#define UFO_SIZE_T
Definition ufotypes.h:89