return ((mleaf_t *)node)->contents;
}
-void Mod_FindNonSolidLocation(vec3_t pos, model_t *mod)
+typedef struct findnonsolidlocationinfo_s
{
- if (Mod_PointContents(pos, mod) != CONTENTS_SOLID) return;
- pos[0]-=1;if (Mod_PointContents(pos, mod) != CONTENTS_SOLID) return;
- pos[0]+=2;if (Mod_PointContents(pos, mod) != CONTENTS_SOLID) return;
- pos[0]-=1;
- pos[1]-=1;if (Mod_PointContents(pos, mod) != CONTENTS_SOLID) return;
- pos[1]+=2;if (Mod_PointContents(pos, mod) != CONTENTS_SOLID) return;
- pos[1]-=1;
- pos[2]-=1;if (Mod_PointContents(pos, mod) != CONTENTS_SOLID) return;
- pos[2]+=2;if (Mod_PointContents(pos, mod) != CONTENTS_SOLID) return;
- pos[2]-=1;
+ vec3_t center;
+ vec_t radius;
+ vec3_t nudge;
+ vec_t bestdist;
+ model_t *model;
}
+findnonsolidlocationinfo_t;
+#if 0
+extern cvar_t samelevel;
+#endif
+void Mod_FindNonSolidLocation_r_Leaf(findnonsolidlocationinfo_t *info, mleaf_t *leaf)
+{
+ int i, surfnum, k, *tri, *mark;
+ float dist, f, vert[3][3], edge[3][3], facenormal[3], edgenormal[3][3], point[3];
+#if 0
+ float surfnormal[3];
+#endif
+ msurface_t *surf;
+ surfmesh_t *mesh;
+ for (surfnum = 0, mark = leaf->firstmarksurface;surfnum < leaf->nummarksurfaces;surfnum++, mark++)
+ {
+ surf = info->model->surfaces + *mark;
+ if (surf->flags & SURF_SOLIDCLIP)
+ {
+#if 0
+ VectorCopy(surf->plane->normal, surfnormal);
+ if (surf->flags & SURF_PLANEBACK)
+ VectorNegate(surfnormal, surfnormal);
+#endif
+ for (mesh = surf->mesh;mesh;mesh = mesh->chain)
+ {
+ for (k = 0;k < mesh->numtriangles;k++)
+ {
+ tri = mesh->element3i + k * 3;
+ VectorCopy((mesh->vertex3f + tri[0] * 3), vert[0]);
+ VectorCopy((mesh->vertex3f + tri[1] * 3), vert[1]);
+ VectorCopy((mesh->vertex3f + tri[2] * 3), vert[2]);
+ VectorSubtract(vert[1], vert[0], edge[0]);
+ VectorSubtract(vert[2], vert[1], edge[1]);
+ CrossProduct(edge[1], edge[0], facenormal);
+ if (facenormal[0] || facenormal[1] || facenormal[2])
+ {
+ VectorNormalize(facenormal);
+#if 0
+ if (VectorDistance(facenormal, surfnormal) > 0.01f)
+ Con_Printf("a2! %f %f %f != %f %f %f\n", facenormal[0], facenormal[1], facenormal[2], surfnormal[0], surfnormal[1], surfnormal[2]);
+#endif
+ f = DotProduct(info->center, facenormal) - DotProduct(vert[0], facenormal);
+ if (f <= info->bestdist && f >= -info->bestdist)
+ {
+ VectorSubtract(vert[0], vert[2], edge[2]);
+ VectorNormalize(edge[0]);
+ VectorNormalize(edge[1]);
+ VectorNormalize(edge[2]);
+ CrossProduct(facenormal, edge[0], edgenormal[0]);
+ CrossProduct(facenormal, edge[1], edgenormal[1]);
+ CrossProduct(facenormal, edge[2], edgenormal[2]);
+#if 0
+ if (samelevel.integer & 1)
+ VectorNegate(edgenormal[0], edgenormal[0]);
+ if (samelevel.integer & 2)
+ VectorNegate(edgenormal[1], edgenormal[1]);
+ if (samelevel.integer & 4)
+ VectorNegate(edgenormal[2], edgenormal[2]);
+ for (i = 0;i < 3;i++)
+ if (DotProduct(vert[0], edgenormal[i]) > DotProduct(vert[i], edgenormal[i]) + 0.1f
+ || DotProduct(vert[1], edgenormal[i]) > DotProduct(vert[i], edgenormal[i]) + 0.1f
+ || DotProduct(vert[2], edgenormal[i]) > DotProduct(vert[i], edgenormal[i]) + 0.1f)
+ Con_Printf("a! %i : %f %f %f (%f %f %f)\n", i, edgenormal[i][0], edgenormal[i][1], edgenormal[i][2], facenormal[0], facenormal[1], facenormal[2]);
+#endif
+ // face distance
+ if (DotProduct(info->center, edgenormal[0]) < DotProduct(vert[0], edgenormal[0])
+ && DotProduct(info->center, edgenormal[1]) < DotProduct(vert[1], edgenormal[1])
+ && DotProduct(info->center, edgenormal[2]) < DotProduct(vert[2], edgenormal[2]))
+ {
+ // we got lucky, the center is within the face
+ dist = DotProduct(info->center, facenormal) - DotProduct(vert[0], facenormal);
+ if (dist < 0)
+ {
+ dist = -dist;
+ if (info->bestdist > dist)
+ {
+ info->bestdist = dist;
+ VectorScale(facenormal, (info->radius - -dist), info->nudge);
+ }
+ }
+ else
+ {
+ if (info->bestdist > dist)
+ {
+ info->bestdist = dist;
+ VectorScale(facenormal, (info->radius - dist), info->nudge);
+ }
+ }
+ }
+ else
+ {
+ // check which edge or vertex the center is nearest
+ for (i = 0;i < 3;i++)
+ {
+ f = DotProduct(info->center, edge[i]);
+ if (f >= DotProduct(vert[0], edge[i])
+ && f <= DotProduct(vert[1], edge[i]))
+ {
+ // on edge
+ VectorMA(info->center, -f, edge[i], point);
+ dist = sqrt(DotProduct(point, point));
+ if (info->bestdist > dist)
+ {
+ info->bestdist = dist;
+ VectorScale(point, (info->radius / dist), info->nudge);
+ }
+ // skip both vertex checks
+ // (both are further away than this edge)
+ i++;
+ }
+ else
+ {
+ // not on edge, check first vertex of edge
+ VectorSubtract(info->center, vert[i], point);
+ dist = sqrt(DotProduct(point, point));
+ if (info->bestdist > dist)
+ {
+ info->bestdist = dist;
+ VectorScale(point, (info->radius / dist), info->nudge);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void Mod_FindNonSolidLocation_r(findnonsolidlocationinfo_t *info, mnode_t *node)
+{
+ if (node->contents)
+ {
+ if (((mleaf_t *)node)->nummarksurfaces)
+ Mod_FindNonSolidLocation_r_Leaf(info, (mleaf_t *)node);
+ }
+ else
+ {
+ float f = PlaneDiff(info->center, node->plane);
+ if (f >= -info->bestdist)
+ Mod_FindNonSolidLocation_r(info, node->children[0]);
+ if (f <= info->bestdist)
+ Mod_FindNonSolidLocation_r(info, node->children[1]);
+ }
+}
+
+void Mod_FindNonSolidLocation(vec3_t in, vec3_t out, model_t *model, float radius)
+{
+ int i;
+ findnonsolidlocationinfo_t info;
+ if (model == NULL)
+ {
+ VectorCopy(in, out);
+ return;
+ }
+ VectorCopy(in, info.center);
+ info.radius = radius;
+ info.model = model;
+ i = 0;
+ do
+ {
+ VectorClear(info.nudge);
+ info.bestdist = radius;
+ Mod_FindNonSolidLocation_r(&info, model->nodes + model->hulls[0].firstclipnode);
+ VectorAdd(info.center, info.nudge, info.center);
+ }
+ while(info.bestdist < radius && ++i < 10);
+ VectorCopy(info.center, out);
+}
/*
===================
tx->height = 16;
tx->skin.base = r_notexture;
tx->shader = &Cshader_wall_lightmap;
+ tx->flags = SURF_SOLIDCLIP;
if (i == loadmodel->numtextures - 1)
{
- tx->flags = SURF_DRAWTURB | SURF_LIGHTBOTHSIDES;
+ tx->flags |= SURF_DRAWTURB | SURF_LIGHTBOTHSIDES;
tx->shader = &Cshader_water;
}
tx->currentframe = tx;
{
if (image_width == 256 && image_height == 128)
{
- R_InitSky (data, 4);
+ R_InitSky (data, 4);
Mem_Free(data);
}
else
if (loadmodel->ishlbsp)
{
// internal texture overrides wad
- qbyte *pixels, *freepixels;
+ qbyte *pixels, *freepixels, *fogpixels;
pixels = freepixels = NULL;
if (mtdata)
pixels = W_ConvertWAD3Texture(dmiptex);
tx->width = image_width;
tx->height = image_height;
tx->skin.base = tx->skin.merged = R_LoadTexture2D(loadmodel->texturepool, tx->name, image_width, image_height, pixels, TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, NULL);
+ if (Image_CheckAlpha(pixels, image_width * image_height, true))
+ {
+ fogpixels = Mem_Alloc(tempmempool, image_width * image_height * 4);
+ for (j = 0;j < image_width * image_height * 4;j += 4)
+ {
+ fogpixels[j + 0] = 255;
+ fogpixels[j + 1] = 255;
+ fogpixels[j + 2] = 255;
+ fogpixels[j + 3] = pixels[j + 3];
+ }
+ tx->skin.fog = R_LoadTexture2D(loadmodel->texturepool, tx->name, image_width, image_height, pixels, TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, NULL);
+ Mem_Free(fogpixels);
+ }
}
if (freepixels)
Mem_Free(freepixels);
}
else if (mtdata) // texture included
- Mod_LoadSkinFrame_Internal(&tx->skin, tx->name, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, false, true, tx->name[0] != '*' && r_fullbrights.integer, mtdata, tx->width, tx->height);
+ Mod_LoadSkinFrame_Internal(&tx->skin, tx->name, TEXF_MIPMAP | TEXF_PRECACHE, false, true, tx->name[0] != '*' && r_fullbrights.integer, mtdata, tx->width, tx->height);
}
}
if (tx->skin.base == NULL)
if (tx->name[0] == '*')
{
+ // turb does not block movement
+ tx->flags &= ~SURF_SOLIDCLIP;
tx->flags |= SURF_DRAWTURB | SURF_LIGHTBOTHSIDES;
// LordHavoc: some turbulent textures should be fullbright and solid
if (!strncmp(tx->name,"*lava",5)
{
// LordHavoc: hope is not lost yet, check for a .lit file to load
strcpy(litfilename, loadmodel->name);
- COM_StripExtension(litfilename, litfilename);
+ FS_StripExtension(litfilename, litfilename);
strcat(litfilename, ".lit");
- data = (qbyte*) COM_LoadFile (litfilename, false);
+ data = (qbyte*) FS_LoadFile (litfilename, false);
if (data)
{
- if (loadsize > 8 && data[0] == 'Q' && data[1] == 'L' && data[2] == 'I' && data[3] == 'T')
+ if (fs_filesize > 8 && data[0] == 'Q' && data[1] == 'L' && data[2] == 'I' && data[3] == 'T')
{
i = LittleLong(((int *)data)[1]);
if (i == 1)
{
- Con_DPrintf("%s loaded", litfilename);
- loadmodel->lightdata = Mem_Alloc(loadmodel->mempool, loadsize - 8);
- memcpy(loadmodel->lightdata, data + 8, loadsize - 8);
+ Con_DPrintf("loaded %s\n", litfilename);
+ loadmodel->lightdata = Mem_Alloc(loadmodel->mempool, fs_filesize - 8);
+ memcpy(loadmodel->lightdata, data + 8, fs_filesize - 8);
Mem_Free(data);
return;
}
}
else
{
- if (loadsize == 8)
+ if (fs_filesize == 8)
Con_Printf("Empty .lit file, ignoring\n");
else
Con_Printf("Corrupt .lit file (old version?), ignoring\n");
mlight_t *e;
strcpy(lightsfilename, loadmodel->name);
- COM_StripExtension(lightsfilename, lightsfilename);
+ FS_StripExtension(lightsfilename, lightsfilename);
strcat(lightsfilename, ".lights");
- s = lightsstring = (char *) COM_LoadFile (lightsfilename, false);
+ s = lightsstring = (char *) FS_LoadFile (lightsfilename, false);
if (s)
{
numlights = 0;
surfmesh_t *Mod_AllocSurfMesh(int numverts, int numtriangles)
{
surfmesh_t *mesh;
- mesh = Mem_Alloc(loadmodel->mempool, sizeof(surfmesh_t) + numtriangles * sizeof(int[6]) + numverts * (4 + 4 + 4 + 4 + 4 + 4 + 4 + 1) * sizeof(float));
+ mesh = Mem_Alloc(loadmodel->mempool, sizeof(surfmesh_t) + numtriangles * sizeof(int[6]) + numverts * (3 + 2 + 2 + 2 + 3 + 3 + 3 + 1) * sizeof(float));
mesh->numverts = numverts;
mesh->numtriangles = numtriangles;
- mesh->verts = (float *)(mesh + 1);
- mesh->str = mesh->verts + mesh->numverts * 4;
- mesh->uvw = mesh->str + mesh->numverts * 4;
- mesh->abc = mesh->uvw + mesh->numverts * 4;
- mesh->svectors = (float *)(mesh->abc + mesh->numverts * 4);
- mesh->tvectors = mesh->svectors + mesh->numverts * 4;
- mesh->normals = mesh->tvectors + mesh->numverts * 4;
- mesh->lightmapoffsets = (int *)(mesh->normals + mesh->numverts * 4);
- mesh->index = mesh->lightmapoffsets + mesh->numverts;
- mesh->triangleneighbors = mesh->index + mesh->numtriangles * 3;
+ mesh->vertex3f = (float *)(mesh + 1);
+ mesh->texcoordtexture2f = mesh->vertex3f + mesh->numverts * 3;
+ mesh->texcoordlightmap2f = mesh->texcoordtexture2f + mesh->numverts * 2;
+ mesh->texcoorddetail2f = mesh->texcoordlightmap2f + mesh->numverts * 2;
+ mesh->svector3f = (float *)(mesh->texcoorddetail2f + mesh->numverts * 2);
+ mesh->tvector3f = mesh->svector3f + mesh->numverts * 3;
+ mesh->normal3f = mesh->tvector3f + mesh->numverts * 3;
+ mesh->lightmapoffsets = (int *)(mesh->normal3f + mesh->numverts * 3);
+ mesh->element3i = mesh->lightmapoffsets + mesh->numverts;
+ mesh->neighbor3i = mesh->element3i + mesh->numtriangles * 3;
return mesh;
}
-void Mod_GenerateWallMesh (msurface_t *surf, int vertexonly)
-{
- int i, iu, iv, *index, smax, tmax;
- float *in, s, t, u, v, ubase, vbase, uscale, vscale, normal[3];
- surfmesh_t *mesh;
-
- smax = surf->extents[0] >> 4;
- tmax = surf->extents[1] >> 4;
-
- if (vertexonly)
- {
- surf->lightmaptexturestride = 0;
- surf->lightmaptexture = NULL;
- uscale = 0;
- vscale = 0;
- ubase = 0;
- vbase = 0;
- }
- else
- {
- surf->flags |= SURF_LIGHTMAP;
- if (r_miplightmaps.integer)
- {
- surf->lightmaptexturestride = (surf->extents[0]>>4)+1;
- surf->lightmaptexture = R_LoadTexture2D(loadmodel->texturepool, NULL, surf->lightmaptexturestride, (surf->extents[1]>>4)+1, NULL, loadmodel->lightmaprgba ? TEXTYPE_RGBA : TEXTYPE_RGB, TEXF_MIPMAP | TEXF_PRECACHE, NULL);
- }
- else
- {
- surf->lightmaptexturestride = R_CompatibleFragmentWidth((surf->extents[0]>>4)+1, loadmodel->lightmaprgba ? TEXTYPE_RGBA : TEXTYPE_RGB, 0);
- surf->lightmaptexture = R_LoadTexture2D(loadmodel->texturepool, NULL, surf->lightmaptexturestride, (surf->extents[1]>>4)+1, NULL, loadmodel->lightmaprgba ? TEXTYPE_RGBA : TEXTYPE_RGB, TEXF_FRAGMENT | TEXF_PRECACHE, NULL);
- }
- R_FragmentLocation(surf->lightmaptexture, NULL, NULL, &ubase, &vbase, &uscale, &vscale);
- uscale = (uscale - ubase) * 16.0 / ((surf->extents[0] & ~15) + 16);
- vscale = (vscale - vbase) * 16.0 / ((surf->extents[1] & ~15) + 16);
- }
-
- surf->mesh = mesh = Mod_AllocSurfMesh(surf->poly_numverts, surf->poly_numverts - 2);
-
- index = mesh->index;
- for (i = 0;i < mesh->numtriangles;i++)
- {
- *index++ = 0;
- *index++ = i + 1;
- *index++ = i + 2;
- }
- Mod_BuildTriangleNeighbors(mesh->triangleneighbors, mesh->index, mesh->numtriangles);
-
- VectorCopy(surf->plane->normal, normal);
- if (surf->flags & SURF_PLANEBACK)
- VectorNegate(normal, normal);
- for (i = 0, in = surf->poly_verts;i < mesh->numverts;i++, in += 3)
- {
- s = DotProduct (in, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3];
- t = DotProduct (in, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3];
- u = (s + 8 - surf->texturemins[0]) * (1.0 / 16.0);
- v = (t + 8 - surf->texturemins[1]) * (1.0 / 16.0);
- // LordHavoc: calc lightmap data offset for vertex lighting to use
- iu = (int) u;
- iv = (int) v;
- iu = bound(0, iu, smax);
- iv = bound(0, iv, tmax);
- u = u * uscale + ubase;
- v = v * vscale + vbase;
-
- mesh->verts[i * 4 + 0] = in[0];
- mesh->verts[i * 4 + 1] = in[1];
- mesh->verts[i * 4 + 2] = in[2];
- mesh->str[i * 4 + 0] = s / surf->texinfo->texture->width;
- mesh->str[i * 4 + 1] = t / surf->texinfo->texture->height;
- mesh->uvw[i * 4 + 0] = u;
- mesh->uvw[i * 4 + 1] = v;
- mesh->abc[i * 4 + 0] = s * (1.0f / 16.0f);
- mesh->abc[i * 4 + 1] = t * (1.0f / 16.0f);
- mesh->lightmapoffsets[i] = ((iv * (smax+1) + iu) * 3);
- }
- Mod_BuildTextureVectorsAndNormals(mesh->numverts, mesh->numtriangles, mesh->verts, mesh->str, mesh->index, mesh->svectors, mesh->tvectors, mesh->normals);
-}
-
-void Mod_GenerateVertexMesh (msurface_t *surf)
-{
- int i, *index;
- float *in, s, t, normal[3];
- surfmesh_t *mesh;
-
- surf->lightmaptexturestride = 0;
- surf->lightmaptexture = NULL;
-
- surf->mesh = mesh = Mod_AllocSurfMesh(surf->poly_numverts, surf->poly_numverts - 2);
-
- index = mesh->index;
- for (i = 0;i < mesh->numtriangles;i++)
- {
- *index++ = 0;
- *index++ = i + 1;
- *index++ = i + 2;
- }
- Mod_BuildTriangleNeighbors(mesh->triangleneighbors, mesh->index, mesh->numtriangles);
-
- VectorCopy(surf->plane->normal, normal);
- if (surf->flags & SURF_PLANEBACK)
- VectorNegate(normal, normal);
- for (i = 0, in = surf->poly_verts;i < mesh->numverts;i++, in += 3)
- {
- s = (DotProduct (in, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3]);
- t = (DotProduct (in, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3]);
- mesh->verts[i * 4 + 0] = in[0];
- mesh->verts[i * 4 + 1] = in[1];
- mesh->verts[i * 4 + 2] = in[2];
- mesh->str[i * 4 + 0] = s / surf->texinfo->texture->width;
- mesh->str[i * 4 + 1] = t / surf->texinfo->texture->height;
- mesh->uvw[i * 4 + 0] = 0;
- mesh->uvw[i * 4 + 1] = 0;
- mesh->abc[i * 4 + 0] = s * (1.0f / 16.0f);
- mesh->abc[i * 4 + 1] = t * (1.0f / 16.0f);
- }
- Mod_BuildTextureVectorsAndNormals(mesh->numverts, mesh->numtriangles, mesh->verts, mesh->str, mesh->index, mesh->svectors, mesh->tvectors, mesh->normals);
-}
-
void Mod_GenerateSurfacePolygon (msurface_t *surf, int firstedge, int numedges)
{
int i, lindex, j;
static void Mod_LoadFaces (lump_t *l)
{
dface_t *in;
- msurface_t *out;
- int i, count, surfnum, planenum, ssize, tsize, firstedge, numedges;
+ msurface_t *surf;
+ int i, count, surfnum, planenum, ssize, tsize, firstedge, numedges, totalverts, totaltris, totalmeshes;
+ surfmesh_t *mesh;
+ float s, t;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
Host_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
- out = Mem_Alloc(loadmodel->mempool, count*sizeof(*out));
+ loadmodel->surfaces = Mem_Alloc(loadmodel->mempool, count*sizeof(msurface_t));
- loadmodel->surfaces = out;
loadmodel->numsurfaces = count;
loadmodel->surfacevisframes = Mem_Alloc(loadmodel->mempool, count * sizeof(int));
loadmodel->surfacepvsframes = Mem_Alloc(loadmodel->mempool, count * sizeof(int));
loadmodel->pvssurflist = Mem_Alloc(loadmodel->mempool, count * sizeof(int));
- for (surfnum = 0;surfnum < count;surfnum++, in++, out++)
+ for (surfnum = 0, surf = loadmodel->surfaces, totalverts = 0, totaltris = 0, totalmeshes = 0;surfnum < count;surfnum++, totalverts += surf->poly_numverts, totaltris += surf->poly_numverts - 2, totalmeshes++, in++, surf++)
{
- out->number = surfnum;
+ surf->number = surfnum;
// FIXME: validate edges, texinfo, etc?
firstedge = LittleLong(in->firstedge);
numedges = LittleShort(in->numedges);
- if ((unsigned int) firstedge + (unsigned int) numedges > (unsigned int) loadmodel->numsurfedges)
+ if ((unsigned int) firstedge > (unsigned int) loadmodel->numsurfedges || (unsigned int) numedges > (unsigned int) loadmodel->numsurfedges || (unsigned int) firstedge + (unsigned int) numedges > (unsigned int) loadmodel->numsurfedges)
Host_Error("Mod_LoadFaces: invalid edge range (firstedge %i, numedges %i, model edges %i)\n", firstedge, numedges, loadmodel->numsurfedges);
-
i = LittleShort (in->texinfo);
if ((unsigned int) i >= (unsigned int) loadmodel->numtexinfo)
Host_Error("Mod_LoadFaces: invalid texinfo index %i (model has %i texinfos)\n", i, loadmodel->numtexinfo);
- out->texinfo = loadmodel->texinfo + i;
- out->flags = out->texinfo->texture->flags;
+ surf->texinfo = loadmodel->texinfo + i;
+ surf->flags = surf->texinfo->texture->flags;
planenum = LittleShort(in->planenum);
if ((unsigned int) planenum >= (unsigned int) loadmodel->numplanes)
Host_Error("Mod_LoadFaces: invalid plane index %i (model has %i planes)\n", planenum, loadmodel->numplanes);
if (LittleShort(in->side))
- out->flags |= SURF_PLANEBACK;
+ surf->flags |= SURF_PLANEBACK;
- out->plane = loadmodel->planes + planenum;
+ surf->plane = loadmodel->planes + planenum;
// clear lightmap (filled in later)
- out->lightmaptexture = NULL;
+ surf->lightmaptexture = NULL;
// force lightmap upload on first time seeing the surface
- out->cached_dlight = true;
+ surf->cached_dlight = true;
- Mod_GenerateSurfacePolygon(out, firstedge, numedges);
+ Mod_GenerateSurfacePolygon(surf, firstedge, numedges);
- ssize = (out->extents[0] >> 4) + 1;
- tsize = (out->extents[1] >> 4) + 1;
+ ssize = (surf->extents[0] >> 4) + 1;
+ tsize = (surf->extents[1] >> 4) + 1;
// lighting info
for (i = 0;i < MAXLIGHTMAPS;i++)
- out->styles[i] = in->styles[i];
+ surf->styles[i] = in->styles[i];
i = LittleLong(in->lightofs);
if (i == -1)
- out->samples = NULL;
+ surf->samples = NULL;
else if (loadmodel->ishlbsp) // LordHavoc: HalfLife map (bsp version 30)
- out->samples = loadmodel->lightdata + i;
+ surf->samples = loadmodel->lightdata + i;
else // LordHavoc: white lighting (bsp version 29)
- out->samples = loadmodel->lightdata + (i * 3);
+ surf->samples = loadmodel->lightdata + (i * 3);
- if (out->texinfo->texture->shader == &Cshader_wall_lightmap)
+ if (surf->texinfo->texture->shader == &Cshader_wall_lightmap)
{
- if ((out->extents[0] >> 4) + 1 > (256) || (out->extents[1] >> 4) + 1 > (256))
+ if ((surf->extents[0] >> 4) + 1 > (256) || (surf->extents[1] >> 4) + 1 > (256))
Host_Error ("Bad surface extents");
- Mod_GenerateWallMesh (out, false);
// stainmap for permanent marks on walls
- out->stainsamples = Mem_Alloc(loadmodel->mempool, ssize * tsize * 3);
+ surf->stainsamples = Mem_Alloc(loadmodel->mempool, ssize * tsize * 3);
// clear to white
- memset(out->stainsamples, 255, ssize * tsize * 3);
+ memset(surf->stainsamples, 255, ssize * tsize * 3);
+ }
+ }
+
+ loadmodel->entiremesh = Mod_AllocSurfMesh(totalverts, totaltris);
+ loadmodel->surfmeshes = Mem_Alloc(loadmodel->mempool, sizeof(surfmesh_t) * totalmeshes);
+
+ for (surfnum = 0, surf = loadmodel->surfaces, totalverts = 0, totaltris = 0, totalmeshes = 0;surfnum < count;surfnum++, totalverts += surf->poly_numverts, totaltris += surf->poly_numverts - 2, totalmeshes++, surf++)
+ {
+ mesh = surf->mesh = loadmodel->surfmeshes + totalmeshes;
+ mesh->numverts = surf->poly_numverts;
+ mesh->numtriangles = surf->poly_numverts - 2;
+ mesh->vertex3f = loadmodel->entiremesh->vertex3f + totalverts * 3;
+ mesh->texcoordtexture2f = loadmodel->entiremesh->texcoordtexture2f + totalverts * 2;
+ mesh->texcoordlightmap2f = loadmodel->entiremesh->texcoordlightmap2f + totalverts * 2;
+ mesh->texcoorddetail2f = loadmodel->entiremesh->texcoorddetail2f + totalverts * 2;
+ mesh->svector3f = loadmodel->entiremesh->svector3f + totalverts * 3;
+ mesh->tvector3f = loadmodel->entiremesh->tvector3f + totalverts * 3;
+ mesh->normal3f = loadmodel->entiremesh->normal3f + totalverts * 3;
+ mesh->lightmapoffsets = loadmodel->entiremesh->lightmapoffsets + totalverts;
+ mesh->element3i = loadmodel->entiremesh->element3i + totaltris * 3;
+ mesh->neighbor3i = loadmodel->entiremesh->neighbor3i + totaltris * 3;
+
+ surf->lightmaptexturestride = 0;
+ surf->lightmaptexture = NULL;
+
+ for (i = 0;i < mesh->numverts;i++)
+ {
+ mesh->vertex3f[i * 3 + 0] = surf->poly_verts[i * 3 + 0];
+ mesh->vertex3f[i * 3 + 1] = surf->poly_verts[i * 3 + 1];
+ mesh->vertex3f[i * 3 + 2] = surf->poly_verts[i * 3 + 2];
+ s = DotProduct ((mesh->vertex3f + i * 3), surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3];
+ t = DotProduct ((mesh->vertex3f + i * 3), surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3];
+ mesh->texcoordtexture2f[i * 2 + 0] = s / surf->texinfo->texture->width;
+ mesh->texcoordtexture2f[i * 2 + 1] = t / surf->texinfo->texture->height;
+ mesh->texcoorddetail2f[i * 2 + 0] = s * (1.0f / 16.0f);
+ mesh->texcoorddetail2f[i * 2 + 1] = t * (1.0f / 16.0f);
+ mesh->texcoordlightmap2f[i * 2 + 0] = 0;
+ mesh->texcoordlightmap2f[i * 2 + 1] = 0;
+ mesh->lightmapoffsets[i] = 0;
+ }
+
+ for (i = 0;i < mesh->numtriangles;i++)
+ {
+ mesh->element3i[i * 3 + 0] = 0;
+ mesh->element3i[i * 3 + 1] = i + 1;
+ mesh->element3i[i * 3 + 2] = i + 2;
+ }
+
+ Mod_BuildTriangleNeighbors(mesh->neighbor3i, mesh->element3i, mesh->numtriangles);
+ Mod_BuildTextureVectorsAndNormals(mesh->numverts, mesh->numtriangles, mesh->vertex3f, mesh->texcoordtexture2f, mesh->element3i, mesh->svector3f, mesh->tvector3f, mesh->normal3f);
+
+ if (surf->texinfo->texture->shader == &Cshader_wall_lightmap)
+ {
+ int i, iu, iv, smax, tmax;
+ float u, v, ubase, vbase, uscale, vscale;
+
+ smax = surf->extents[0] >> 4;
+ tmax = surf->extents[1] >> 4;
+
+ surf->flags |= SURF_LIGHTMAP;
+ if (r_miplightmaps.integer)
+ {
+ surf->lightmaptexturestride = smax+1;
+ surf->lightmaptexture = R_LoadTexture2D(loadmodel->texturepool, NULL, surf->lightmaptexturestride, (surf->extents[1]>>4)+1, NULL, loadmodel->lightmaprgba ? TEXTYPE_RGBA : TEXTYPE_RGB, TEXF_MIPMAP | TEXF_FORCELINEAR | TEXF_PRECACHE, NULL);
+ }
+ else
+ {
+ surf->lightmaptexturestride = R_CompatibleFragmentWidth(smax+1, loadmodel->lightmaprgba ? TEXTYPE_RGBA : TEXTYPE_RGB, 0);
+ surf->lightmaptexture = R_LoadTexture2D(loadmodel->texturepool, NULL, surf->lightmaptexturestride, (surf->extents[1]>>4)+1, NULL, loadmodel->lightmaprgba ? TEXTYPE_RGBA : TEXTYPE_RGB, TEXF_FRAGMENT | TEXF_FORCELINEAR | TEXF_PRECACHE, NULL);
+ }
+ R_FragmentLocation(surf->lightmaptexture, NULL, NULL, &ubase, &vbase, &uscale, &vscale);
+ uscale = (uscale - ubase) / (smax + 1);
+ vscale = (vscale - vbase) / (tmax + 1);
+
+ for (i = 0;i < mesh->numverts;i++)
+ {
+ u = ((DotProduct ((mesh->vertex3f + i * 3), surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3]) + 8 - surf->texturemins[0]) * (1.0 / 16.0);
+ v = ((DotProduct ((mesh->vertex3f + i * 3), surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3]) + 8 - surf->texturemins[1]) * (1.0 / 16.0);
+ mesh->texcoordlightmap2f[i * 2 + 0] = u * uscale + ubase;
+ mesh->texcoordlightmap2f[i * 2 + 1] = v * vscale + vbase;
+ // LordHavoc: calc lightmap data offset for vertex lighting to use
+ iu = (int) u;
+ iv = (int) v;
+ mesh->lightmapoffsets[i] = (bound(0, iv, tmax) * (smax+1) + bound(0, iu, smax)) * 3;
+ }
}
- else
- Mod_GenerateVertexMesh (out);
}
}
nodeportalwinding = ClipWinding (nodeportalwinding, &clipplane, true);
if (!nodeportalwinding)
{
- printf ("Mod_RecursiveNodePortals: WARNING: new portal was clipped away\n");
+ Con_Printf ("Mod_RecursiveNodePortals: WARNING: new portal was clipped away\n");
break;
}
}
extern void R_Model_Brush_DrawSky(entity_render_t *ent);
extern void R_Model_Brush_Draw(entity_render_t *ent);
extern void R_Model_Brush_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius);
-extern void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor);
-void Mod_LoadBrushModel (model_t *mod, void *buffer)
+extern void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz);
+void Mod_LoadBrushModelQ1orHL (model_t *mod, void *buffer)
{
int i, j, k;
dheader_t *header;
// we only need to have a drawsky function if it is used (usually only on world model)
if (surf->texinfo->texture->shader == &Cshader_sky)
mod->DrawSky = R_Model_Brush_DrawSky;
+ // LordHavoc: submodels always clip, even if water
+ if (mod->numsubmodels - 1)
+ surf->flags |= SURF_SOLIDCLIP;
// calculate bounding shapes
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
{
- for (k = 0, vec = mesh->verts;k < mesh->numverts;k++, vec += 4)
+ for (k = 0, vec = mesh->vertex3f;k < mesh->numverts;k++, vec += 3)
{
if (mod->normalmins[0] > vec[0]) mod->normalmins[0] = vec[0];
if (mod->normalmins[1] > vec[1]) mod->normalmins[1] = vec[1];
//Mod_ProcessLightList ();
}
+static void Mod_Q2LoadEntities (lump_t *l)
+{
+}
+
+static void Mod_Q2LoadPlanes (lump_t *l)
+{
+/*
+ d_t *in;
+ m_t *out;
+ int i, count;
+
+ in = (void *)(mod_base + l->fileofs);
+ if (l->filelen % sizeof(*in))
+ Host_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
+ count = l->filelen / sizeof(*in);
+ out = Mem_Alloc(loadmodel->mempool, count * sizeof(*out));
+
+ loadmodel-> = out;
+ loadmodel->num = count;
+
+ for (i = 0;i < count;i++, in++, out++)
+ {
+ }
+*/
+}
+
+static void Mod_Q2LoadVertices (lump_t *l)
+{
+/*
+ d_t *in;
+ m_t *out;
+ int i, count;
+
+ in = (void *)(mod_base + l->fileofs);
+ if (l->filelen % sizeof(*in))
+ Host_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
+ count = l->filelen / sizeof(*in);
+ out = Mem_Alloc(loadmodel->mempool, count * sizeof(*out));
+
+ loadmodel-> = out;
+ loadmodel->num = count;
+
+ for (i = 0;i < count;i++, in++, out++)
+ {
+ }
+*/
+}
+
+static void Mod_Q2LoadVisibility (lump_t *l)
+{
+/*
+ d_t *in;
+ m_t *out;
+ int i, count;
+
+ in = (void *)(mod_base + l->fileofs);
+ if (l->filelen % sizeof(*in))
+ Host_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
+ count = l->filelen / sizeof(*in);
+ out = Mem_Alloc(loadmodel->mempool, count * sizeof(*out));
+
+ loadmodel-> = out;
+ loadmodel->num = count;
+
+ for (i = 0;i < count;i++, in++, out++)
+ {
+ }
+*/
+}
+
+static void Mod_Q2LoadNodes (lump_t *l)
+{
+/*
+ d_t *in;
+ m_t *out;
+ int i, count;
+
+ in = (void *)(mod_base + l->fileofs);
+ if (l->filelen % sizeof(*in))
+ Host_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
+ count = l->filelen / sizeof(*in);
+ out = Mem_Alloc(loadmodel->mempool, count * sizeof(*out));
+
+ loadmodel-> = out;
+ loadmodel->num = count;
+
+ for (i = 0;i < count;i++, in++, out++)
+ {
+ }
+*/
+}
+
+static void Mod_Q2LoadTexInfo (lump_t *l)
+{
+/*
+ d_t *in;
+ m_t *out;
+ int i, count;
+
+ in = (void *)(mod_base + l->fileofs);
+ if (l->filelen % sizeof(*in))
+ Host_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
+ count = l->filelen / sizeof(*in);
+ out = Mem_Alloc(loadmodel->mempool, count * sizeof(*out));
+
+ loadmodel-> = out;
+ loadmodel->num = count;
+
+ for (i = 0;i < count;i++, in++, out++)
+ {
+ }
+*/
+}
+
+static void Mod_Q2LoadFaces (lump_t *l)
+{
+/*
+ d_t *in;
+ m_t *out;
+ int i, count;
+
+ in = (void *)(mod_base + l->fileofs);
+ if (l->filelen % sizeof(*in))
+ Host_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
+ count = l->filelen / sizeof(*in);
+ out = Mem_Alloc(loadmodel->mempool, count * sizeof(*out));
+
+ loadmodel-> = out;
+ loadmodel->num = count;
+
+ for (i = 0;i < count;i++, in++, out++)
+ {
+ }
+*/
+}
+
+static void Mod_Q2LoadLighting (lump_t *l)
+{
+/*
+ d_t *in;
+ m_t *out;
+ int i, count;
+
+ in = (void *)(mod_base + l->fileofs);
+ if (l->filelen % sizeof(*in))
+ Host_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
+ count = l->filelen / sizeof(*in);
+ out = Mem_Alloc(loadmodel->mempool, count * sizeof(*out));
+
+ loadmodel-> = out;
+ loadmodel->num = count;
+
+ for (i = 0;i < count;i++, in++, out++)
+ {
+ }
+*/
+}
+
+static void Mod_Q2LoadLeafs (lump_t *l)
+{
+/*
+ d_t *in;
+ m_t *out;
+ int i, count;
+
+ in = (void *)(mod_base + l->fileofs);
+ if (l->filelen % sizeof(*in))
+ Host_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
+ count = l->filelen / sizeof(*in);
+ out = Mem_Alloc(loadmodel->mempool, count * sizeof(*out));
+
+ loadmodel-> = out;
+ loadmodel->num = count;
+
+ for (i = 0;i < count;i++, in++, out++)
+ {
+ }
+*/
+}
+
+static void Mod_Q2LoadLeafFaces (lump_t *l)
+{
+/*
+ d_t *in;
+ m_t *out;
+ int i, count;
+
+ in = (void *)(mod_base + l->fileofs);
+ if (l->filelen % sizeof(*in))
+ Host_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
+ count = l->filelen / sizeof(*in);
+ out = Mem_Alloc(loadmodel->mempool, count * sizeof(*out));
+
+ loadmodel-> = out;
+ loadmodel->num = count;
+
+ for (i = 0;i < count;i++, in++, out++)
+ {
+ }
+*/
+}
+
+static void Mod_Q2LoadLeafBrushes (lump_t *l)
+{
+/*
+ d_t *in;
+ m_t *out;
+ int i, count;
+
+ in = (void *)(mod_base + l->fileofs);
+ if (l->filelen % sizeof(*in))
+ Host_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
+ count = l->filelen / sizeof(*in);
+ out = Mem_Alloc(loadmodel->mempool, count * sizeof(*out));
+
+ loadmodel-> = out;
+ loadmodel->num = count;
+
+ for (i = 0;i < count;i++, in++, out++)
+ {
+ }
+*/
+}
+
+static void Mod_Q2LoadEdges (lump_t *l)
+{
+/*
+ d_t *in;
+ m_t *out;
+ int i, count;
+
+ in = (void *)(mod_base + l->fileofs);
+ if (l->filelen % sizeof(*in))
+ Host_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
+ count = l->filelen / sizeof(*in);
+ out = Mem_Alloc(loadmodel->mempool, count * sizeof(*out));
+
+ loadmodel-> = out;
+ loadmodel->num = count;
+
+ for (i = 0;i < count;i++, in++, out++)
+ {
+ }
+*/
+}
+
+static void Mod_Q2LoadSurfEdges (lump_t *l)
+{
+/*
+ d_t *in;
+ m_t *out;
+ int i, count;
+
+ in = (void *)(mod_base + l->fileofs);
+ if (l->filelen % sizeof(*in))
+ Host_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
+ count = l->filelen / sizeof(*in);
+ out = Mem_Alloc(loadmodel->mempool, count * sizeof(*out));
+
+ loadmodel-> = out;
+ loadmodel->num = count;
+
+ for (i = 0;i < count;i++, in++, out++)
+ {
+ }
+*/
+}
+
+static void Mod_Q2LoadBrushes (lump_t *l)
+{
+/*
+ d_t *in;
+ m_t *out;
+ int i, count;
+
+ in = (void *)(mod_base + l->fileofs);
+ if (l->filelen % sizeof(*in))
+ Host_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
+ count = l->filelen / sizeof(*in);
+ out = Mem_Alloc(loadmodel->mempool, count * sizeof(*out));
+
+ loadmodel-> = out;
+ loadmodel->num = count;
+
+ for (i = 0;i < count;i++, in++, out++)
+ {
+ }
+*/
+}
+
+static void Mod_Q2LoadBrushSides (lump_t *l)
+{
+/*
+ d_t *in;
+ m_t *out;
+ int i, count;
+
+ in = (void *)(mod_base + l->fileofs);
+ if (l->filelen % sizeof(*in))
+ Host_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
+ count = l->filelen / sizeof(*in);
+ out = Mem_Alloc(loadmodel->mempool, count * sizeof(*out));
+
+ loadmodel-> = out;
+ loadmodel->num = count;
+
+ for (i = 0;i < count;i++, in++, out++)
+ {
+ }
+*/
+}
+
+static void Mod_Q2LoadAreas (lump_t *l)
+{
+/*
+ d_t *in;
+ m_t *out;
+ int i, count;
+
+ in = (void *)(mod_base + l->fileofs);
+ if (l->filelen % sizeof(*in))
+ Host_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
+ count = l->filelen / sizeof(*in);
+ out = Mem_Alloc(loadmodel->mempool, count * sizeof(*out));
+
+ loadmodel-> = out;
+ loadmodel->num = count;
+
+ for (i = 0;i < count;i++, in++, out++)
+ {
+ }
+*/
+}
+
+static void Mod_Q2LoadAreaPortals (lump_t *l)
+{
+/*
+ d_t *in;
+ m_t *out;
+ int i, count;
+
+ in = (void *)(mod_base + l->fileofs);
+ if (l->filelen % sizeof(*in))
+ Host_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
+ count = l->filelen / sizeof(*in);
+ out = Mem_Alloc(loadmodel->mempool, count * sizeof(*out));
+
+ loadmodel-> = out;
+ loadmodel->num = count;
+
+ for (i = 0;i < count;i++, in++, out++)
+ {
+ }
+*/
+}
+
+static void Mod_Q2LoadModels (lump_t *l)
+{
+/*
+ d_t *in;
+ m_t *out;
+ int i, count;
+
+ in = (void *)(mod_base + l->fileofs);
+ if (l->filelen % sizeof(*in))
+ Host_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
+ count = l->filelen / sizeof(*in);
+ out = Mem_Alloc(loadmodel->mempool, count * sizeof(*out));
+
+ loadmodel-> = out;
+ loadmodel->num = count;
+
+ for (i = 0;i < count;i++, in++, out++)
+ {
+ }
+*/
+}
+
+void Mod_LoadBrushModelQ2 (model_t *mod, void *buffer)
+{
+ int i;
+ q2dheader_t *header;
+
+ mod->type = mod_brushq2;
+
+ header = (q2dheader_t *)buffer;
+
+ i = LittleLong (header->version);
+ if (i != Q2BSPVERSION)
+ Host_Error ("Mod_LoadBrushModelQ2: %s has wrong version number (%i should be %i)", mod->name, i, BSPVERSION);
+ mod->ishlbsp = false;
+ if (loadmodel->isworldmodel)
+ {
+ Cvar_SetValue("halflifebsp", mod->ishlbsp);
+ // until we get a texture for it...
+ R_ResetQuakeSky();
+ }
+
+ mod_base = (qbyte *)header;
+
+ // swap all the lumps
+ for (i = 0;i < (int) sizeof(dheader_t) / 4;i++)
+ ((int *)header)[i] = LittleLong ( ((int *)header)[i]);
+
+ // store which lightmap format to use
+ mod->lightmaprgba = r_lightmaprgba.integer;
+
+ Mod_Q2LoadEntities(&header->lumps[Q2LUMP_ENTITIES]);
+ Mod_Q2LoadPlanes(&header->lumps[Q2LUMP_PLANES]);
+ Mod_Q2LoadVertices(&header->lumps[Q2LUMP_VERTEXES]);
+ Mod_Q2LoadVisibility(&header->lumps[Q2LUMP_VISIBILITY]);
+ Mod_Q2LoadNodes(&header->lumps[Q2LUMP_NODES]);
+ Mod_Q2LoadTexInfo(&header->lumps[Q2LUMP_TEXINFO]);
+ Mod_Q2LoadFaces(&header->lumps[Q2LUMP_FACES]);
+ Mod_Q2LoadLighting(&header->lumps[Q2LUMP_LIGHTING]);
+ Mod_Q2LoadLeafs(&header->lumps[Q2LUMP_LEAFS]);
+ Mod_Q2LoadLeafFaces(&header->lumps[Q2LUMP_LEAFFACES]);
+ Mod_Q2LoadLeafBrushes(&header->lumps[Q2LUMP_LEAFBRUSHES]);
+ Mod_Q2LoadEdges(&header->lumps[Q2LUMP_EDGES]);
+ Mod_Q2LoadSurfEdges(&header->lumps[Q2LUMP_SURFEDGES]);
+ Mod_Q2LoadBrushes(&header->lumps[Q2LUMP_BRUSHES]);
+ Mod_Q2LoadBrushSides(&header->lumps[Q2LUMP_BRUSHSIDES]);
+ Mod_Q2LoadAreas(&header->lumps[Q2LUMP_AREAS]);
+ Mod_Q2LoadAreaPortals(&header->lumps[Q2LUMP_AREAPORTALS]);
+ // LordHavoc: must go last because this makes the submodels
+ Mod_Q2LoadModels(&header->lumps[Q2LUMP_MODELS]);
+}
+
+void Mod_LoadBrushModelQ3 (model_t *mod, void *buffer)
+{
+ Host_Error("Mod_LoadBrushModelQ3: not yet implemented\n");
+}
+
+void Mod_LoadBrushModelIBSP (model_t *mod, void *buffer)
+{
+ int i = LittleLong(*((int *)buffer));
+ if (i == 46)
+ Mod_LoadBrushModelQ3 (mod,buffer);
+ else if (i == 38)
+ Mod_LoadBrushModelQ2 (mod,buffer);
+ else
+ Host_Error("Mod_LoadBrushModelIBSP: unknown/unsupported version %i\n", i);
+}
+