UFO: Alien Invasion
Loading...
Searching...
No Matches
r_model_md3.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
26#include "r_local.h"
27
28/*
29==============================================================================
30MD3 ALIAS MODELS
31==============================================================================
32*/
33
38void R_ModLoadAliasMD3Model (model_t* mod, byte* buffer, int bufSize)
39{
40 const dmd3_t* md3 = (dmd3_t*)buffer;
41 int version = LittleLong(md3->version);
42
43 if (version != MD3_ALIAS_VERSION) {
44 Com_Error(ERR_DROP, "%s has wrong version number (%i should be %i)",
45 mod->name, version, MD3_ALIAS_VERSION);
46 }
47
48 mod->type = mod_alias_md3;
49 /* byte swap the header fields and sanity check */
51 mod->alias.num_tags = LittleLong(md3->num_tags);
53
54 if (mod->alias.num_frames <= 0)
55 Com_Error(ERR_DROP, "model %s has no frames", mod->name);
56 else if (mod->alias.num_frames > MD3_MAX_FRAMES)
57 Com_Error(ERR_DROP, "model %s has too many frames", mod->name);
58
59 if (mod->alias.num_tags > MD3_MAX_TAGS)
60 Com_Error(ERR_DROP, "model %s has too many tags", mod->name);
61 else if (mod->alias.num_tags < 0)
62 Com_Error(ERR_DROP, "model %s has invalid number of tags", mod->name);
63
64 if (mod->alias.num_meshes <= 0)
65 Com_Error(ERR_DROP, "model %s has no meshes", mod->name);
66 else if (mod->alias.num_meshes > MD3_MAX_MESHES)
67 Com_Error(ERR_DROP, "model %s has too many meshes", mod->name);
68
69 /* load the frames */
70 const dmd3frame_t* pinframe = (const dmd3frame_t*)((const byte*)md3 + LittleLong(md3->ofs_frames));
72
73 mod->radius = 0;
75
76 int i, j, l;
77 for (i = 0; i < mod->alias.num_frames; i++, pinframe++, poutframe++) {
78 for (j = 0; j < 3; j++) {
79 poutframe->fBox.mins[j] = LittleFloat(pinframe->mins[j]);
80 poutframe->fBox.maxs[j] = LittleFloat(pinframe->maxs[j]);
81 poutframe->translate[j] = LittleFloat(pinframe->translate[j]);
82 }
83
84 poutframe->radius = LittleFloat(pinframe->radius);
85 mod->radius = std::max(mod->radius, poutframe->radius);
86 mod->modBox.add(poutframe->fBox);
87 }
88
89 /* load the tags */
90 if (mod->alias.num_tags) {
91 const dmd3tag_t* pintag = (const dmd3tag_t*)((const byte*)md3 + LittleLong(md3->ofs_tags));
93
95 for (l = 0; l < mod->alias.num_tags; l++, pouttag++, pintag++) {
97 memcpy(pouttag->name, pintag->name, MD3_MAX_PATH);
98 for (i = 0; i < mod->alias.num_frames; i++, orient++) {
99 for (j = 0; j < 3; j++) {
100 orient->origin[j] = LittleFloat(pintag->orient.origin[j]);
101 orient->axis[0][j] = LittleFloat(pintag->orient.axis[0][j]);
102 orient->axis[1][j] = LittleFloat(pintag->orient.axis[1][j]);
103 orient->axis[2][j] = LittleFloat(pintag->orient.axis[2][j]);
104 }
105 }
106 }
107 }
108
109 /* load the meshes */
110 const dmd3mesh_t* pinmesh = (const dmd3mesh_t*)((const byte*)md3 + LittleLong(md3->ofs_meshes));
112
113 for (i = 0; i < mod->alias.num_meshes; i++, poutmesh++) {
114 memcpy(poutmesh->name, pinmesh->name, MD3_MAX_PATH);
115
116 if (strncmp(pinmesh->id, "IDP3", 4)) {
117 Com_Error(ERR_DROP, "mesh %s in model %s has wrong id (%s should be %i)",
118 poutmesh->name, mod->name, pinmesh->id, IDMD3HEADER);
119 }
120
121 poutmesh->num_tris = LittleLong(pinmesh->num_tris);
122 poutmesh->num_skins = LittleLong(pinmesh->num_skins);
123 poutmesh->num_verts = LittleLong(pinmesh->num_verts);
124
125 if (poutmesh->num_skins <= 0)
126 Com_Error(ERR_DROP, "mesh %i in model %s has no skins", i, mod->name);
127 else if (poutmesh->num_skins > MD3_MAX_SHADERS)
128 Com_Error(ERR_DROP, "mesh %i in model %s has too many skins", i, mod->name);
129
130 if (poutmesh->num_tris <= 0)
131 Com_Error(ERR_DROP, "mesh %i in model %s has no triangles", i, mod->name);
132 else if (poutmesh->num_tris > MD3_MAX_TRIANGLES)
133 Com_Error(ERR_DROP, "mesh %i in model %s has too many triangles", i, mod->name);
134
135 if (poutmesh->num_verts <= 0)
136 Com_Error(ERR_DROP, "mesh %i in model %s has no vertices", i, mod->name);
137 else if (poutmesh->num_verts > MD3_MAX_VERTS)
138 Com_Error(ERR_DROP, "mesh %i in model %s has too many vertices", i, mod->name);
139
140 /* register all skins */
141 const dmd3skin_t* pinskin = (const dmd3skin_t*)((const byte*)pinmesh + LittleLong(pinmesh->ofs_skins));
143
144 for (j = 0; j < poutmesh->num_skins; j++) {
145 mAliasSkin_t* modelSkin = &poutmesh->skins[j];
146 modelSkin->skin = R_AliasModelGetSkin(mod->name, pinskin->name);
147 Q_strncpyz(modelSkin->name, modelSkin->skin->name, MODEL_MAX_PATH);
148 }
149
150 /* load the indexes */
151 const int32_t* pinindex = (const int32_t*)((const byte*)pinmesh + LittleLong(pinmesh->ofs_tris));
152 int32_t* poutindex = poutmesh->indexes = Mem_PoolAllocTypeN(int32_t, poutmesh->num_tris * 3, vid_modelPool);
153
154 for (j = 0; j < poutmesh->num_tris; j++, pinindex += 3, poutindex += 3) {
155 poutindex[0] = (int32_t)LittleLong(pinindex[0]);
156 poutindex[1] = (int32_t)LittleLong(pinindex[1]);
157 poutindex[2] = (int32_t)LittleLong(pinindex[2]);
158 }
159
160 /* load the texture coordinates */
161 const dmd3coord_t* pincoord = (const dmd3coord_t*)((const byte*)pinmesh + LittleLong(pinmesh->ofs_tcs));
163
164 for (j = 0; j < poutmesh->num_verts; j++, pincoord++) {
165 poutmesh->stcoords[j][0] = LittleFloat(pincoord->st[0]);
166 poutmesh->stcoords[j][1] = LittleFloat(pincoord->st[1]);
167 }
168
169 /* load the vertexes and normals */
170 const dmd3vertex_t* pinvert = (const dmd3vertex_t*)((const byte*)pinmesh + LittleLong(pinmesh->ofs_verts));
172
173 for (l = 0; l < mod->alias.num_frames; l++) {
174 for (j = 0; j < poutmesh->num_verts; j++, pinvert++, poutvert++) {
175 float lat, lng;
176
177 poutvert->point[0] = LittleShort(pinvert->point[0]) * MD3_XYZ_SCALE;
178 poutvert->point[1] = LittleShort(pinvert->point[1]) * MD3_XYZ_SCALE;
179 poutvert->point[2] = LittleShort(pinvert->point[2]) * MD3_XYZ_SCALE;
180
181 lat = (pinvert->norm >> 8) & 0xff;
182 lng = (pinvert->norm & 0xff);
183
184 lat *= M_PI / 128.0f;
185 lng *= M_PI / 128.0f;
186
187 poutvert->normal[0] = cos(lat) * sin(lng);
188 poutvert->normal[1] = sin(lat) * sin(lng);
189 poutvert->normal[2] = cos(lng);
190 }
191 }
192
194
195 pinmesh = (const dmd3mesh_t*)((const byte*)pinmesh + LittleLong(pinmesh->meshsize));
196
197 R_ModLoadArrayData(&mod->alias, poutmesh, true);
198 }
199}
#define LittleLong(X)
Definition byte.h:37
#define LittleShort(X)
Definition byte.h:35
#define LittleFloat(X)
Definition byte.h:57
memPool_t * vid_modelPool
Definition cl_main.cpp:90
vec3_t maxs
Definition aabb.h:258
void setNegativeVolume()
Sets mins and maxs to their starting points before using addPoint.
Definition aabb.h:98
vec3_t mins
Definition aabb.h:257
void add(const vec3_t point)
If the point is outside the box, expand the box to accommodate it.
Definition aabb.cpp:57
void Com_Error(int code, const char *fmt,...)
Definition common.cpp:459
#define ERR_DROP
Definition common.h:211
#define M_PI
Definition mathlib.h:34
#define Mem_PoolAllocTypeN(type, n, pool)
Definition mem.h:42
#define MD3_MAX_MESHES
Definition qfiles.h:168
#define MD3_MAX_VERTS
Definition qfiles.h:165
#define MD3_XYZ_SCALE
Definition qfiles.h:173
#define MD3_MAX_SHADERS
Definition qfiles.h:166
#define MD3_MAX_TRIANGLES
Definition qfiles.h:164
#define MD3_MAX_TAGS
Definition qfiles.h:169
#define MD3_MAX_FRAMES
Definition qfiles.h:167
#define MD3_MAX_PATH
Definition qfiles.h:170
#define MD3_ALIAS_VERSION
Definition qfiles.h:161
#define IDMD3HEADER
Definition qfiles.h:159
QGL_EXTERN GLint i
Definition r_gl.h:113
QGL_EXTERN GLuint GLsizei bufSize
Definition r_gl.h:110
local graphics definitions
image_t * R_AliasModelGetSkin(const char *modelFileName, const char *skin)
@ mod_alias_md3
Definition r_model.h:41
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_ModLoadArrayData(mAliasModel_t *mod, mAliasMesh_t *mesh, bool loadNormals)
Allocates data arrays for animated models. Only called once at loading time.
#define MODEL_MAX_PATH
#define mAliasCoord_t
void R_ModLoadAliasMD3Model(model_t *mod, byte *buffer, int bufSize)
Load MD3 models from file.
void Q_strncpyz(char *dest, const char *src, size_t destsize)
Safe strncpy that ensures a trailing zero.
Definition shared.cpp:457
uint32_t version
Definition qfiles.h:229
uint32_t num_meshes
Definition qfiles.h:237
uint32_t ofs_meshes
Definition qfiles.h:242
uint32_t num_frames
Definition qfiles.h:235
uint32_t num_tags
Definition qfiles.h:236
uint32_t ofs_frames
Definition qfiles.h:240
uint32_t ofs_tags
Definition qfiles.h:241
float st[2]
Definition qfiles.h:176
float mins[3]
Definition qfiles.h:185
float maxs[3]
Definition qfiles.h:186
float radius
Definition qfiles.h:188
float translate[3]
Definition qfiles.h:187
uint32_t num_verts
Definition qfiles.h:216
uint32_t ofs_tcs
Definition qfiles.h:221
uint32_t num_tris
Definition qfiles.h:217
char id[4]
Definition qfiles.h:208
uint32_t num_skins
Definition qfiles.h:215
uint32_t ofs_skins
Definition qfiles.h:220
uint32_t ofs_verts
Definition qfiles.h:222
uint32_t meshsize
Definition qfiles.h:224
char name[MD3_MAX_PATH]
Definition qfiles.h:210
uint32_t ofs_tris
Definition qfiles.h:219
char name[MD3_MAX_PATH]
Definition qfiles.h:203
char name[MD3_MAX_PATH]
Definition qfiles.h:198
dorientation_t orient
Definition qfiles.h:199
float origin[3]
Definition qfiles.h:193
float axis[3][3]
Definition qfiles.h:194
char name[MAX_QPATH]
Definition r_image.h:62
mAliasVertex_t * vertexes
int32_t * indexes
mAliasSkin_t * skins
mAliasCoord_t * stcoords
char name[MODEL_MAX_PATH]
int32_t num_verts
mAliasTag_t * tags
mAliasFrame_t * frames
mAliasMesh_t * meshes
char name[MODEL_MAX_PATH]
image_t * skin
char name[MODEL_MAX_PATH]
mAliasTagOrientation_t * orient
modtype_t type
Definition r_model.h:46
float radius
Definition r_model.h:52
AABB modBox
Definition r_model.h:51
mAliasModel_t alias
Definition r_model.h:63
char name[MAX_QPATH]
Definition r_model.h:44