24 #include "format/md2.h"
42 for (i = 0; i < bsp->numtexinfo; i++, tex++) {
43 len1 = VectorLength(tex->axis[0]);
44 len2 = VectorLength(tex->axis[1]);
45 len1 = (len1 + len2) / 2;
55 if (tex->c.flags & (SURF_WARP | SURF_FLOWING))
60 Q_concat(name,
sizeof(name),
"textures/", tex->name,
".wal", NULL);
62 tex->image =
IMG_Find(name, IT_WALL, flags);
75 vec_t mins[2], maxs[2], val;
80 int bmins[2], bmaxs[2];
82 mins[0] = mins[1] = 999999;
83 maxs[0] = maxs[1] = -999999;
87 for (i = 0; i < s->numsurfedges; i++, e++) {
88 v = e->edge->v[e->vert];
89 for (j = 0; j < 2; j++) {
90 val = DotProduct(v->point, tex->axis[j]) + tex->offset[j];
98 for (i = 0; i < 2; i++) {
99 bmins[i] = floor(mins[i] / 16);
100 bmaxs[i] = ceil(maxs[i] / 16);
102 s->texturemins[i] = bmins[i] << 4;
103 s->extents[i] = (bmaxs[i] - bmins[i]) << 4;
104 if (s->extents[i] < 16) {
106 }
else if (s->extents[i] > 256) {
107 Com_Error(ERR_DROP,
"Bad surface extents");
124 for (i = 0; i < bsp->numfaces; i++, s++) {
126 if (s->texinfo->c.flags & SURF_SKY) {
129 if (s->texinfo->c.flags & (SURF_WARP | SURF_FLOWING)) {
131 for (j = 0; j < 2; j++) {
132 s->extents[j] = 16384;
133 s->texturemins[j] = -8192;
157 qerror_t
MOD_LoadMD2(model_t *model,
const void *rawdata,
size_t length)
160 dmd2frame_t *src_frame;
162 dmd2triangle_t *src_tri;
163 dmd2stvert_t *src_st;
168 char skinname[MAX_QPATH];
173 if (length <
sizeof(header)) {
174 return Q_ERR_FILE_TOO_SMALL;
178 header = *(dmd2header_t *)rawdata;
179 for (i = 0; i <
sizeof(header) / 4; i++) {
180 ((uint32_t *)&header)[i] = LittleLong(((uint32_t *)&header)[i]);
186 if (ret == Q_ERR_TOO_FEW) {
188 model->type = MOD_EMPTY;
189 return Q_ERR_SUCCESS;
195 model->type = MOD_ALIAS;
198 model->tris = MOD_Malloc(header.num_tris *
sizeof(
maliastri_t));
199 model->numtris = header.num_tris;
201 src_tri = (dmd2triangle_t *)((
byte *)rawdata + header.ofs_tris);
202 dst_tri = model->tris;
203 for (i = 0; i < header.num_tris; i++, src_tri++, dst_tri++) {
204 for (j = 0; j < 3; j++) {
205 uint16_t idx_xyz = LittleShort(src_tri->index_xyz[j]);
206 uint16_t idx_st = LittleShort(src_tri->index_st[j]);
208 if (idx_xyz >= header.num_xyz || idx_st >= header.num_st) {
209 ret = Q_ERR_BAD_INDEX;
219 model->sts = MOD_Malloc(header.num_st *
sizeof(
maliasst_t));
220 model->numsts = header.num_st;
221 model->skinwidth = header.skinwidth;
222 model->skinheight = header.skinheight;
224 src_st = (dmd2stvert_t *)((
byte *)rawdata + header.ofs_st);
226 for (i = 0; i < header.num_st; i++, src_st++, dst_st++) {
227 dst_st->
s = (int16_t)LittleShort(src_st->s);
228 dst_st->
t = (int16_t)LittleShort(src_st->t);
230 if (dst_st->
s < 0 || dst_st->
s >= header.skinwidth) {
231 ret = Q_ERR_BAD_INDEX;
235 if (dst_st->
t < 0 || dst_st->
t >= header.skinheight) {
236 ret = Q_ERR_BAD_INDEX;
242 model->frames = MOD_Malloc(header.num_frames *
sizeof(
maliasframe_t));
243 model->numframes = header.num_frames;
244 model->numverts = header.num_xyz;
246 src_frame = (dmd2frame_t *)((
byte *)rawdata + header.ofs_frames);
247 dst_frame = model->frames;
248 for (i = 0; i < header.num_frames; i++, dst_frame++) {
249 for (j = 0; j < 3; j++) {
250 dst_frame->
scale[j] = LittleFloat(src_frame->scale[j]);
251 dst_frame->
translate[j] = LittleFloat(src_frame->translate[j]);
256 memcpy(dst_frame->
verts, src_frame->verts, header.num_xyz *
sizeof(
maliasvert_t));
259 for (j = 0; j < header.num_xyz; j++) {
260 if (dst_frame->
verts[j].lightnormalindex > NUMVERTEXNORMALS) {
261 ret = Q_ERR_BAD_INDEX;
266 src_frame = (dmd2frame_t *)((
byte *)src_frame + header.framesize);
270 src_skin = (
char *)rawdata + header.ofs_skins;
271 for (i = 0; i < header.num_skins; i++) {
272 if (!
Q_memccpy(skinname, src_skin, 0,
sizeof(skinname))) {
273 ret = Q_ERR_STRING_TRUNCATED;
277 model->skins[i] =
IMG_Find(skinname, IT_SKIN, IF_NONE);
278 src_skin += MD2_MAX_SKINNAME;
280 model->numskins = header.num_skins;
283 return Q_ERR_SUCCESS;
295 switch (model->type) {
297 for (i = 0; i < model->numskins; i++) {
302 for (i = 0; i < model->numframes; i++) {
309 Com_Error(ERR_FATAL,
"%s: bad model type", __func__);
324 char fullname[MAX_QPATH];
334 Q_concat(fullname,
sizeof(fullname),
"maps/", model,
".bsp", NULL);
337 Com_Error(ERR_DROP,
"%s: couldn't load %s: %s",
342 for (i = 0; i < bsp->numtexinfo; i++) {