X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=model_brush.c;h=ae4d0b8a9a24a333a32fa16abf6ebf231ec87631;hb=7cd2c9493983d745cfc5e27620402edf63cb0eb0;hp=44c41917a2cf0a326bd59003325800855cd0fdf3;hpb=221bb70d6ec2aab6d29b5f5184f00e3636add70a;p=xonotic%2Fdarkplaces.git diff --git a/model_brush.c b/model_brush.c index 44c41917..ae4d0b8a 100644 --- a/model_brush.c +++ b/model_brush.c @@ -170,28 +170,28 @@ extern cvar_t samelevel; #endif static void Mod_Q1BSP_FindNonSolidLocation_r_Leaf(findnonsolidlocationinfo_t *info, mleaf_t *leaf) { - int i, surfnum, k, *tri, *mark; + int i, surfacenum, 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; - for (surfnum = 0, mark = leaf->firstleafface;surfnum < leaf->numleaffaces;surfnum++, mark++) + msurface_t *surface; + for (surfacenum = 0, mark = leaf->firstleafsurface;surfacenum < leaf->numleafsurfaces;surfacenum++, mark++) { - surf = info->model->brushq1.surfaces + *mark; - if (surf->flags & SURF_SOLIDCLIP) + surface = info->model->brush.data_surfaces + *mark; + if (surface->flags & SURF_SOLIDCLIP) { #if 0 - VectorCopy(surf->plane->normal, surfnormal); - if (surf->flags & SURF_PLANEBACK) + VectorCopy(surface->plane->normal, surfnormal); + if (surface->flags & SURF_PLANEBACK) VectorNegate(surfnormal, surfnormal); #endif - for (k = 0;k < surf->mesh.num_triangles;k++) + for (k = 0;k < surface->mesh.num_triangles;k++) { - tri = surf->mesh.data_element3i + k * 3; - VectorCopy((surf->mesh.data_vertex3f + tri[0] * 3), vert[0]); - VectorCopy((surf->mesh.data_vertex3f + tri[1] * 3), vert[1]); - VectorCopy((surf->mesh.data_vertex3f + tri[2] * 3), vert[2]); + tri = surface->mesh.data_element3i + k * 3; + VectorCopy((surface->mesh.data_vertex3f + tri[0] * 3), vert[0]); + VectorCopy((surface->mesh.data_vertex3f + tri[1] * 3), vert[1]); + VectorCopy((surface->mesh.data_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); @@ -303,7 +303,7 @@ static void Mod_Q1BSP_FindNonSolidLocation_r(findnonsolidlocationinfo_t *info, m } else { - if (((mleaf_t *)node)->numleaffaces) + if (((mleaf_t *)node)->numleafsurfaces) Mod_Q1BSP_FindNonSolidLocation_r_Leaf(info, (mleaf_t *)node); } } @@ -766,31 +766,31 @@ loc0: if (node->numsurfaces) { int i, ds, dt; - msurface_t *surf; + msurface_t *surface; - surf = r_refdef.worldmodel->brushq1.surfaces + node->firstsurface; - for (i = 0;i < node->numsurfaces;i++, surf++) + surface = r_refdef.worldmodel->brush.data_surfaces + node->firstsurface; + for (i = 0;i < node->numsurfaces;i++, surface++) { - if (!(surf->flags & SURF_LIGHTMAP) || !surf->samples) + if (!(surface->texture->flags & SURF_LIGHTMAP) || !surface->samples) continue; // no lightmaps - ds = (int) (x * surf->texinfo->vecs[0][0] + y * surf->texinfo->vecs[0][1] + mid * surf->texinfo->vecs[0][2] + surf->texinfo->vecs[0][3]) - surf->texturemins[0]; - dt = (int) (x * surf->texinfo->vecs[1][0] + y * surf->texinfo->vecs[1][1] + mid * surf->texinfo->vecs[1][2] + surf->texinfo->vecs[1][3]) - surf->texturemins[1]; + ds = (int) (x * surface->texinfo->vecs[0][0] + y * surface->texinfo->vecs[0][1] + mid * surface->texinfo->vecs[0][2] + surface->texinfo->vecs[0][3]) - surface->texturemins[0]; + dt = (int) (x * surface->texinfo->vecs[1][0] + y * surface->texinfo->vecs[1][1] + mid * surface->texinfo->vecs[1][2] + surface->texinfo->vecs[1][3]) - surface->texturemins[1]; - if (ds >= 0 && ds < surf->extents[0] && dt >= 0 && dt < surf->extents[1]) + if (ds >= 0 && ds < surface->extents[0] && dt >= 0 && dt < surface->extents[1]) { qbyte *lightmap; int lmwidth, lmheight, maps, line3, size3, dsfrac = ds & 15, dtfrac = dt & 15, scale = 0, r00 = 0, g00 = 0, b00 = 0, r01 = 0, g01 = 0, b01 = 0, r10 = 0, g10 = 0, b10 = 0, r11 = 0, g11 = 0, b11 = 0; - lmwidth = ((surf->extents[0]>>4)+1); - lmheight = ((surf->extents[1]>>4)+1); + lmwidth = ((surface->extents[0]>>4)+1); + lmheight = ((surface->extents[1]>>4)+1); line3 = lmwidth * 3; // LordHavoc: *3 for colored lighting size3 = lmwidth * lmheight * 3; // LordHavoc: *3 for colored lighting - lightmap = surf->samples + ((dt>>4) * lmwidth + (ds>>4))*3; // LordHavoc: *3 for colored lighting + lightmap = surface->samples + ((dt>>4) * lmwidth + (ds>>4))*3; // LordHavoc: *3 for colored lighting - for (maps = 0;maps < MAXLIGHTMAPS && surf->styles[maps] != 255;maps++) + for (maps = 0;maps < MAXLIGHTMAPS && surface->styles[maps] != 255;maps++) { - scale = d_lightstylevalue[surf->styles[maps]]; + scale = d_lightstylevalue[surface->styles[maps]]; r00 += lightmap[ 0] * scale;g00 += lightmap[ 1] * scale;b00 += lightmap[ 2] * scale; r01 += lightmap[ 3] * scale;g01 += lightmap[ 4] * scale;b01 += lightmap[ 5] * scale; r10 += lightmap[line3+0] * scale;g10 += lightmap[line3+1] * scale;b10 += lightmap[line3+2] * scale; @@ -966,32 +966,31 @@ static void Mod_Q1BSP_LoadTextures(lump_t *l) qbyte *data, *mtdata; char name[256]; - loadmodel->brushq1.textures = NULL; + loadmodel->brush.data_textures = NULL; // add two slots for notexture walls and notexture liquids if (l->filelen) { m = (dmiptexlump_t *)(mod_base + l->fileofs); m->nummiptex = LittleLong (m->nummiptex); - loadmodel->brushq1.numtextures = m->nummiptex + 2; + loadmodel->brush.num_textures = m->nummiptex + 2; } else { m = NULL; - loadmodel->brushq1.numtextures = 2; + loadmodel->brush.num_textures = 2; } - loadmodel->brushq1.textures = Mem_Alloc(loadmodel->mempool, loadmodel->brushq1.numtextures * sizeof(texture_t)); + loadmodel->brush.data_textures = Mem_Alloc(loadmodel->mempool, loadmodel->brush.num_textures * sizeof(texture_t)); // fill out all slots with notexture - for (i = 0, tx = loadmodel->brushq1.textures;i < loadmodel->brushq1.numtextures;i++, tx++) + for (i = 0, tx = loadmodel->brush.data_textures;i < loadmodel->brush.num_textures;i++, tx++) { - tx->number = i; strcpy(tx->name, "NO TEXTURE FOUND"); tx->width = 16; tx->height = 16; tx->skin.base = r_notexture; - if (i == loadmodel->brushq1.numtextures - 1) + if (i == loadmodel->brush.num_textures - 1) tx->flags = SURF_DRAWTURB | SURF_LIGHTBOTHSIDES; else tx->flags = SURF_LIGHTMAP | SURF_SOLIDCLIP; @@ -1039,7 +1038,7 @@ static void Mod_Q1BSP_LoadTextures(lump_t *l) if (name[j] >= 'A' && name[j] <= 'Z') name[j] += 'a' - 'A'; - tx = loadmodel->brushq1.textures + i; + tx = loadmodel->brush.data_textures + i; strcpy(tx->name, name); tx->width = mtwidth; tx->height = mtheight; @@ -1137,7 +1136,7 @@ static void Mod_Q1BSP_LoadTextures(lump_t *l) // sequence the animations for (i = 0;i < m->nummiptex;i++) { - tx = loadmodel->brushq1.textures + i; + tx = loadmodel->brush.data_textures + i; if (!tx || tx->name[0] != '+' || tx->name[1] == 0 || tx->name[2] == 0) continue; if (tx->anim_total[0] || tx->anim_total[1]) @@ -1149,7 +1148,7 @@ static void Mod_Q1BSP_LoadTextures(lump_t *l) for (j = i;j < m->nummiptex;j++) { - tx2 = loadmodel->brushq1.textures + j; + tx2 = loadmodel->brush.data_textures + j; if (!tx2 || tx2->name[0] != '+' || strcmp(tx2->name+2, tx->name+2)) continue; @@ -1547,25 +1546,25 @@ static void Mod_Q1BSP_LoadTexinfo(lump_t *l) out->flags = LittleLong(in->flags); out->texture = NULL; - if (loadmodel->brushq1.textures) + if (loadmodel->brush.data_textures) { - if ((unsigned int) miptex >= (unsigned int) loadmodel->brushq1.numtextures) - Con_Printf("error in model \"%s\": invalid miptex index %i(of %i)\n", loadmodel->name, miptex, loadmodel->brushq1.numtextures); + if ((unsigned int) miptex >= (unsigned int) loadmodel->brush.num_textures) + Con_Printf("error in model \"%s\": invalid miptex index %i(of %i)\n", loadmodel->name, miptex, loadmodel->brush.num_textures); else - out->texture = loadmodel->brushq1.textures + miptex; + out->texture = loadmodel->brush.data_textures + miptex; } if (out->flags & TEX_SPECIAL) { // if texture chosen is NULL or the shader needs a lightmap, // force to notexture water shader if (out->texture == NULL || out->texture->flags & SURF_LIGHTMAP) - out->texture = loadmodel->brushq1.textures + (loadmodel->brushq1.numtextures - 1); + out->texture = loadmodel->brush.data_textures + (loadmodel->brush.num_textures - 1); } else { // if texture chosen is NULL, force to notexture if (out->texture == NULL) - out->texture = loadmodel->brushq1.textures + (loadmodel->brushq1.numtextures - 2); + out->texture = loadmodel->brush.data_textures + (loadmodel->brush.num_textures - 2); } } } @@ -1690,7 +1689,7 @@ static void SubdividePolygon(int numverts, float *verts) //Breaks a polygon up along axial 64 unit //boundaries so that turbulent and sky warps //can be done reasonably. -static void Mod_Q1BSP_GenerateWarpMesh(msurface_t *surf) +static void Mod_Q1BSP_GenerateWarpMesh(msurface_t *surface) { int i, j; surfvertex_t *v; @@ -1698,11 +1697,11 @@ static void Mod_Q1BSP_GenerateWarpMesh(msurface_t *surf) subdivpolytriangles = 0; subdivpolyverts = 0; - SubdividePolygon(surf->poly_numverts, surf->poly_verts); + SubdividePolygon(surface->mesh.num_vertices, surface->mesh.data_vertex3f); if (subdivpolytriangles < 1) Host_Error("Mod_Q1BSP_GenerateWarpMesh: no triangles?\n"); - surf->mesh = mesh = Mem_Alloc(loadmodel->mempool, sizeof(surfmesh_t) + subdivpolytriangles * sizeof(int[3]) + subdivpolyverts * sizeof(surfvertex_t)); + surface->mesh = mesh = Mem_Alloc(loadmodel->mempool, sizeof(surfmesh_t) + subdivpolytriangles * sizeof(int[3]) + subdivpolyverts * sizeof(surfvertex_t)); mesh->num_vertices = subdivpolyverts; mesh->num_triangles = subdivpolytriangles; mesh->vertex = (surfvertex_t *)(mesh + 1); @@ -1716,90 +1715,46 @@ static void Mod_Q1BSP_GenerateWarpMesh(msurface_t *surf) for (i = 0, v = mesh->vertex;i < subdivpolyverts;i++, v++) { VectorCopy(subdivpolyvert[i], v->v); - v->st[0] = DotProduct(v->v, surf->texinfo->vecs[0]); - v->st[1] = DotProduct(v->v, surf->texinfo->vecs[1]); + v->st[0] = DotProduct(v->v, surface->texinfo->vecs[0]); + v->st[1] = DotProduct(v->v, surface->texinfo->vecs[1]); } } #endif -static void Mod_Q1BSP_GenerateSurfacePolygon(msurface_t *surf, int firstedge, int numedges) -{ - int i, lindex, j; - float *vec, *vert, mins[3], maxs[3], val, *v; - mtexinfo_t *tex; - - // convert edges back to a normal polygon - surf->poly_numverts = numedges; - vert = surf->poly_verts = Mem_Alloc(loadmodel->mempool, sizeof(float[3]) * numedges); - for (i = 0;i < numedges;i++) - { - lindex = loadmodel->brushq1.surfedges[firstedge + i]; - if (lindex > 0) - vec = loadmodel->brushq1.vertexes[loadmodel->brushq1.edges[lindex].v[0]].position; - else - vec = loadmodel->brushq1.vertexes[loadmodel->brushq1.edges[-lindex].v[1]].position; - VectorCopy(vec, vert); - vert += 3; - } - - // calculate polygon bounding box and center - vert = surf->poly_verts; - VectorCopy(vert, mins); - VectorCopy(vert, maxs); - vert += 3; - for (i = 1;i < surf->poly_numverts;i++, vert += 3) - { - if (mins[0] > vert[0]) mins[0] = vert[0];if (maxs[0] < vert[0]) maxs[0] = vert[0]; - if (mins[1] > vert[1]) mins[1] = vert[1];if (maxs[1] < vert[1]) maxs[1] = vert[1]; - if (mins[2] > vert[2]) mins[2] = vert[2];if (maxs[2] < vert[2]) maxs[2] = vert[2]; - } - VectorCopy(mins, surf->poly_mins); - VectorCopy(maxs, surf->poly_maxs); - surf->poly_center[0] = (mins[0] + maxs[0]) * 0.5f; - surf->poly_center[1] = (mins[1] + maxs[1]) * 0.5f; - surf->poly_center[2] = (mins[2] + maxs[2]) * 0.5f; - - // generate surface extents information - tex = surf->texinfo; - mins[0] = maxs[0] = DotProduct(surf->poly_verts, tex->vecs[0]) + tex->vecs[0][3]; - mins[1] = maxs[1] = DotProduct(surf->poly_verts, tex->vecs[1]) + tex->vecs[1][3]; - for (i = 1, v = surf->poly_verts + 3;i < surf->poly_numverts;i++, v += 3) - { - for (j = 0;j < 2;j++) - { - val = DotProduct(v, tex->vecs[j]) + tex->vecs[j][3]; - if (mins[j] > val) - mins[j] = val; - if (maxs[j] < val) - maxs[j] = val; - } - } - for (i = 0;i < 2;i++) - { - surf->texturemins[i] = (int) floor(mins[i] / 16) * 16; - surf->extents[i] = (int) ceil(maxs[i] / 16) * 16 - surf->texturemins[i]; - } -} - static void Mod_Q1BSP_LoadFaces(lump_t *l) { dface_t *in; - msurface_t *surf; - int i, count, surfnum, planenum, ssize, tsize, firstedge, numedges, totalverts, totaltris, totalmeshes; - surfmesh_t *mesh; - float s, t; + msurface_t *surface; + int i, j, count, surfacenum, planenum, smax, tmax, ssize, tsize, firstedge, numedges, totalverts, totaltris; + float texmins[2], texmaxs[2], val; in = (void *)(mod_base + l->fileofs); if (l->filelen % sizeof(*in)) Host_Error("Mod_Q1BSP_LoadFaces: funny lump size in %s",loadmodel->name); count = l->filelen / sizeof(*in); - loadmodel->brushq1.surfaces = Mem_Alloc(loadmodel->mempool, count*sizeof(msurface_t)); + loadmodel->brush.data_surfaces = Mem_Alloc(loadmodel->mempool, count*sizeof(msurface_t)); + + loadmodel->brush.num_surfaces = count; + + totalverts = 0; + totaltris = 0; + for (surfacenum = 0, in = (void *)(mod_base + l->fileofs);surfacenum < count;surfacenum++, in++) + { + numedges = LittleShort(in->numedges); + totalverts += numedges; + totaltris += numedges - 2; + } - loadmodel->brushq1.numsurfaces = count; + // TODO: split up into multiple meshes as needed to avoid exceeding 65536 + // vertex limit + loadmodel->nummeshes = 1; + loadmodel->meshlist = Mem_Alloc(loadmodel->mempool, sizeof(surfmesh_t *)); + loadmodel->meshlist[0] = Mod_AllocSurfMesh(loadmodel->mempool, totalverts, totaltris, 0, 0, true, true, false); - for (surfnum = 0, surf = loadmodel->brushq1.surfaces, totalverts = 0, totaltris = 0, totalmeshes = 0;surfnum < count;surfnum++, totalverts += surf->poly_numverts, totaltris += surf->poly_numverts - 2, totalmeshes++, in++, surf++) + totalverts = 0; + totaltris = 0; + for (surfacenum = 0, in = (void *)(mod_base + l->fileofs), surface = loadmodel->brush.data_surfaces;surfacenum < count;surfacenum++, in++, surface++) { - surf->number = surfnum; // FIXME: validate edges, texinfo, etc? firstedge = LittleLong(in->firstedge); numedges = LittleShort(in->numedges); @@ -1808,134 +1763,143 @@ static void Mod_Q1BSP_LoadFaces(lump_t *l) i = LittleShort(in->texinfo); if ((unsigned int) i >= (unsigned int) loadmodel->brushq1.numtexinfo) Host_Error("Mod_Q1BSP_LoadFaces: invalid texinfo index %i(model has %i texinfos)\n", i, loadmodel->brushq1.numtexinfo); - surf->texinfo = loadmodel->brushq1.texinfo + i; - surf->flags = surf->texinfo->texture->flags; + surface->texinfo = loadmodel->brushq1.texinfo + i; + surface->texture = surface->texinfo->texture; + surface->flags = surface->texture->flags; planenum = LittleShort(in->planenum); if ((unsigned int) planenum >= (unsigned int) loadmodel->brush.num_planes) Host_Error("Mod_Q1BSP_LoadFaces: invalid plane index %i (model has %i planes)\n", planenum, loadmodel->brush.num_planes); if (LittleShort(in->side)) - surf->flags |= SURF_PLANEBACK; - - surf->plane = loadmodel->brush.data_planes + planenum; + surface->flags |= SURF_PLANEBACK; + + surface->plane = loadmodel->brush.data_planes + planenum; + + surface->mesh.num_vertices = numedges; + surface->mesh.num_triangles = numedges - 2; + surface->mesh.data_vertex3f = loadmodel->meshlist[0]->data_vertex3f + totalverts * 3; + surface->mesh.data_texcoordtexture2f = loadmodel->meshlist[0]->data_texcoordtexture2f + totalverts * 2; + surface->mesh.data_texcoordlightmap2f = loadmodel->meshlist[0]->data_texcoordlightmap2f + totalverts * 2; + surface->mesh.data_texcoorddetail2f = loadmodel->meshlist[0]->data_texcoorddetail2f + totalverts * 2; + surface->mesh.data_svector3f = loadmodel->meshlist[0]->data_svector3f + totalverts * 3; + surface->mesh.data_tvector3f = loadmodel->meshlist[0]->data_tvector3f + totalverts * 3; + surface->mesh.data_normal3f = loadmodel->meshlist[0]->data_normal3f + totalverts * 3; + surface->mesh.data_lightmapoffsets = loadmodel->meshlist[0]->data_lightmapoffsets + totalverts; + surface->mesh.data_element3i = loadmodel->meshlist[0]->data_element3i + totaltris * 3; + surface->mesh.data_neighbor3i = loadmodel->meshlist[0]->data_neighbor3i + totaltris * 3; + totalverts += numedges; + totaltris += numedges - 2; + + // convert edges back to a normal polygon + for (i = 0;i < surface->mesh.num_vertices;i++) + { + int lindex = loadmodel->brushq1.surfedges[firstedge + i]; + float s, t; + if (lindex > 0) + VectorCopy(loadmodel->brushq1.vertexes[loadmodel->brushq1.edges[lindex].v[0]].position, surface->mesh.data_vertex3f + i * 3); + else + VectorCopy(loadmodel->brushq1.vertexes[loadmodel->brushq1.edges[-lindex].v[1]].position, surface->mesh.data_vertex3f + i * 3); + s = DotProduct((surface->mesh.data_vertex3f + i * 3), surface->texinfo->vecs[0]) + surface->texinfo->vecs[0][3]; + t = DotProduct((surface->mesh.data_vertex3f + i * 3), surface->texinfo->vecs[1]) + surface->texinfo->vecs[1][3]; + surface->mesh.data_texcoordtexture2f[i * 2 + 0] = s / surface->texture->width; + surface->mesh.data_texcoordtexture2f[i * 2 + 1] = t / surface->texture->height; + surface->mesh.data_texcoorddetail2f[i * 2 + 0] = s * (1.0f / 16.0f); + surface->mesh.data_texcoorddetail2f[i * 2 + 1] = t * (1.0f / 16.0f); + surface->mesh.data_texcoordlightmap2f[i * 2 + 0] = 0; + surface->mesh.data_texcoordlightmap2f[i * 2 + 1] = 0; + surface->mesh.data_lightmapoffsets[i] = 0; + } - // clear lightmap (filled in later) - surf->lightmaptexture = NULL; + for (i = 0;i < surface->mesh.num_triangles;i++) + { + surface->mesh.data_element3i[i * 3 + 0] = 0; + surface->mesh.data_element3i[i * 3 + 1] = i + 1; + surface->mesh.data_element3i[i * 3 + 2] = i + 2; + } - // force lightmap upload on first time seeing the surface - surf->cached_dlight = true; + // compile additional data about the surface geometry + Mod_BuildTriangleNeighbors(surface->mesh.data_neighbor3i, surface->mesh.data_element3i, surface->mesh.num_triangles); + Mod_BuildTextureVectorsAndNormals(surface->mesh.num_vertices, surface->mesh.num_triangles, surface->mesh.data_vertex3f, surface->mesh.data_texcoordtexture2f, surface->mesh.data_element3i, surface->mesh.data_svector3f, surface->mesh.data_tvector3f, surface->mesh.data_normal3f); + BoxFromPoints(surface->mins, surface->maxs, surface->mesh.num_vertices, surface->mesh.data_vertex3f); - Mod_Q1BSP_GenerateSurfacePolygon(surf, firstedge, numedges); + // generate surface extents information + texmins[0] = texmaxs[0] = DotProduct(surface->mesh.data_vertex3f, surface->texinfo->vecs[0]) + surface->texinfo->vecs[0][3]; + texmins[1] = texmaxs[1] = DotProduct(surface->mesh.data_vertex3f, surface->texinfo->vecs[1]) + surface->texinfo->vecs[1][3]; + for (i = 1;i < surface->mesh.num_vertices;i++) + { + for (j = 0;j < 2;j++) + { + val = DotProduct(surface->mesh.data_vertex3f + i * 3, surface->texinfo->vecs[j]) + surface->texinfo->vecs[j][3]; + texmins[j] = min(texmins[j], val); + texmaxs[j] = max(texmaxs[j], val); + } + } + for (i = 0;i < 2;i++) + { + surface->texturemins[i] = (int) floor(texmins[i] / 16.0) * 16; + surface->extents[i] = (int) ceil(texmaxs[i] / 16.0) * 16 - surface->texturemins[i]; + } - ssize = (surf->extents[0] >> 4) + 1; - tsize = (surf->extents[1] >> 4) + 1; + smax = surface->extents[0] >> 4; + tmax = surface->extents[1] >> 4; + ssize = (surface->extents[0] >> 4) + 1; + tsize = (surface->extents[1] >> 4) + 1; // lighting info for (i = 0;i < MAXLIGHTMAPS;i++) - surf->styles[i] = in->styles[i]; + surface->styles[i] = in->styles[i]; + // force lightmap upload on first time seeing the surface + surface->cached_dlight = true; + surface->lightmaptexturestride = 0; + surface->lightmaptexture = NULL; i = LittleLong(in->lightofs); if (i == -1) - surf->samples = NULL; + surface->samples = NULL; else if (loadmodel->brush.ishlbsp) // LordHavoc: HalfLife map (bsp version 30) - surf->samples = loadmodel->brushq1.lightdata + i; + surface->samples = loadmodel->brushq1.lightdata + i; else // LordHavoc: white lighting (bsp version 29) - surf->samples = loadmodel->brushq1.lightdata + (i * 3); + surface->samples = loadmodel->brushq1.lightdata + (i * 3); - if (surf->texinfo->texture->flags & SURF_LIGHTMAP) + if (surface->texture->flags & SURF_LIGHTMAP) { - if ((surf->extents[0] >> 4) + 1 > (256) || (surf->extents[1] >> 4) + 1 > (256)) + if (ssize > 256 || tsize > 256) Host_Error("Bad surface extents"); // stainmap for permanent marks on walls - surf->stainsamples = Mem_Alloc(loadmodel->mempool, ssize * tsize * 3); + surface->stainsamples = Mem_Alloc(loadmodel->mempool, ssize * tsize * 3); // clear to white - memset(surf->stainsamples, 255, ssize * tsize * 3); + memset(surface->stainsamples, 255, ssize * tsize * 3); } - } - // TODO: split up into multiple meshes as needed to avoid exceeding 65536 - // vertex limit - loadmodel->nummeshes = 1; - loadmodel->meshlist = Mem_Alloc(loadmodel->mempool, sizeof(surfmesh_t *)); - loadmodel->meshlist[0] = Mod_AllocSurfMesh(loadmodel->mempool, totalverts, totaltris, 0, 0, true, true, false); - - for (surfnum = 0, surf = loadmodel->brushq1.surfaces, totalverts = 0, totaltris = 0, totalmeshes = 0;surfnum < count;surfnum++, totalverts += surf->poly_numverts, totaltris += surf->poly_numverts - 2, totalmeshes++, surf++) - { - mesh = &surf->mesh; - mesh->num_vertices = surf->poly_numverts; - mesh->num_triangles = surf->poly_numverts - 2; - mesh->data_vertex3f = loadmodel->meshlist[0]->data_vertex3f + totalverts * 3; - mesh->data_texcoordtexture2f = loadmodel->meshlist[0]->data_texcoordtexture2f + totalverts * 2; - mesh->data_texcoordlightmap2f = loadmodel->meshlist[0]->data_texcoordlightmap2f + totalverts * 2; - mesh->data_texcoorddetail2f = loadmodel->meshlist[0]->data_texcoorddetail2f + totalverts * 2; - mesh->data_svector3f = loadmodel->meshlist[0]->data_svector3f + totalverts * 3; - mesh->data_tvector3f = loadmodel->meshlist[0]->data_tvector3f + totalverts * 3; - mesh->data_normal3f = loadmodel->meshlist[0]->data_normal3f + totalverts * 3; - mesh->data_lightmapoffsets = loadmodel->meshlist[0]->data_lightmapoffsets + totalverts; - mesh->data_element3i = loadmodel->meshlist[0]->data_element3i + totaltris * 3; - mesh->data_neighbor3i = loadmodel->meshlist[0]->data_neighbor3i + totaltris * 3; - - surf->lightmaptexturestride = 0; - surf->lightmaptexture = NULL; - - for (i = 0;i < mesh->num_vertices;i++) - { - mesh->data_vertex3f[i * 3 + 0] = surf->poly_verts[i * 3 + 0]; - mesh->data_vertex3f[i * 3 + 1] = surf->poly_verts[i * 3 + 1]; - mesh->data_vertex3f[i * 3 + 2] = surf->poly_verts[i * 3 + 2]; - s = DotProduct((mesh->data_vertex3f + i * 3), surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3]; - t = DotProduct((mesh->data_vertex3f + i * 3), surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3]; - mesh->data_texcoordtexture2f[i * 2 + 0] = s / surf->texinfo->texture->width; - mesh->data_texcoordtexture2f[i * 2 + 1] = t / surf->texinfo->texture->height; - mesh->data_texcoorddetail2f[i * 2 + 0] = s * (1.0f / 16.0f); - mesh->data_texcoorddetail2f[i * 2 + 1] = t * (1.0f / 16.0f); - mesh->data_texcoordlightmap2f[i * 2 + 0] = 0; - mesh->data_texcoordlightmap2f[i * 2 + 1] = 0; - mesh->data_lightmapoffsets[i] = 0; - } - - for (i = 0;i < mesh->num_triangles;i++) + if (surface->texture->flags & SURF_LIGHTMAP) { - mesh->data_element3i[i * 3 + 0] = 0; - mesh->data_element3i[i * 3 + 1] = i + 1; - mesh->data_element3i[i * 3 + 2] = i + 2; - } - - Mod_BuildTriangleNeighbors(mesh->data_neighbor3i, mesh->data_element3i, mesh->num_triangles); - Mod_BuildTextureVectorsAndNormals(mesh->num_vertices, mesh->num_triangles, mesh->data_vertex3f, mesh->data_texcoordtexture2f, mesh->data_element3i, mesh->data_svector3f, mesh->data_tvector3f, mesh->data_normal3f); - - if (surf->texinfo->texture->flags & SURF_LIGHTMAP) - { - int i, iu, iv, smax, tmax; + int i, iu, iv; float u, v, ubase, vbase, uscale, vscale; - smax = surf->extents[0] >> 4; - tmax = surf->extents[1] >> 4; - if (r_miplightmaps.integer) { - surf->lightmaptexturestride = smax+1; - surf->lightmaptexture = R_LoadTexture2D(loadmodel->texturepool, NULL, surf->lightmaptexturestride, (surf->extents[1]>>4)+1, NULL, loadmodel->brushq1.lightmaprgba ? TEXTYPE_RGBA : TEXTYPE_RGB, TEXF_MIPMAP | TEXF_FORCELINEAR | TEXF_PRECACHE, NULL); + surface->lightmaptexturestride = ssize; + surface->lightmaptexture = R_LoadTexture2D(loadmodel->texturepool, NULL, surface->lightmaptexturestride, tsize, NULL, loadmodel->brushq1.lightmaprgba ? TEXTYPE_RGBA : TEXTYPE_RGB, TEXF_MIPMAP | TEXF_FORCELINEAR | TEXF_PRECACHE, NULL); } else { - surf->lightmaptexturestride = R_CompatibleFragmentWidth(smax+1, loadmodel->brushq1.lightmaprgba ? TEXTYPE_RGBA : TEXTYPE_RGB, 0); - surf->lightmaptexture = R_LoadTexture2D(loadmodel->texturepool, NULL, surf->lightmaptexturestride, (surf->extents[1]>>4)+1, NULL, loadmodel->brushq1.lightmaprgba ? TEXTYPE_RGBA : TEXTYPE_RGB, TEXF_FRAGMENT | TEXF_FORCELINEAR | TEXF_PRECACHE, NULL); + surface->lightmaptexturestride = R_CompatibleFragmentWidth(ssize, loadmodel->brushq1.lightmaprgba ? TEXTYPE_RGBA : TEXTYPE_RGB, 0); + surface->lightmaptexture = R_LoadTexture2D(loadmodel->texturepool, NULL, surface->lightmaptexturestride, tsize, NULL, loadmodel->brushq1.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); + R_FragmentLocation(surface->lightmaptexture, NULL, NULL, &ubase, &vbase, &uscale, &vscale); + uscale = (uscale - ubase) / ssize; + vscale = (vscale - vbase) / tsize; - for (i = 0;i < mesh->num_vertices;i++) + for (i = 0;i < surface->mesh.num_vertices;i++) { - u = ((DotProduct((mesh->data_vertex3f + i * 3), surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3]) + 8 - surf->texturemins[0]) * (1.0 / 16.0); - v = ((DotProduct((mesh->data_vertex3f + i * 3), surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3]) + 8 - surf->texturemins[1]) * (1.0 / 16.0); - mesh->data_texcoordlightmap2f[i * 2 + 0] = u * uscale + ubase; - mesh->data_texcoordlightmap2f[i * 2 + 1] = v * vscale + vbase; + u = ((DotProduct((surface->mesh.data_vertex3f + i * 3), surface->texinfo->vecs[0]) + surface->texinfo->vecs[0][3]) + 8 - surface->texturemins[0]) * (1.0 / 16.0); + v = ((DotProduct((surface->mesh.data_vertex3f + i * 3), surface->texinfo->vecs[1]) + surface->texinfo->vecs[1][3]) + 8 - surface->texturemins[1]) * (1.0 / 16.0); + surface->mesh.data_texcoordlightmap2f[i * 2 + 0] = u * uscale + ubase; + surface->mesh.data_texcoordlightmap2f[i * 2 + 1] = v * vscale + vbase; // LordHavoc: calc lightmap data offset for vertex lighting to use iu = (int) u; iv = (int) v; - mesh->data_lightmapoffsets[i] = (bound(0, iv, tmax) * (smax+1) + bound(0, iu, smax)) * 3; + surface->mesh.data_lightmapoffsets[i] = (bound(0, iv, tmax) * ssize + bound(0, iu, smax)) * 3; } } } @@ -2025,13 +1989,13 @@ static void Mod_Q1BSP_LoadLeafs(lump_t *l) out->contents = LittleLong(in->contents); - out->firstleafface = loadmodel->brush.data_leaffaces + LittleShort(in->firstmarksurface); - out->numleaffaces = LittleShort(in->nummarksurfaces); - if (out->firstleafface < 0 || LittleShort(in->firstmarksurface) + out->numleaffaces > loadmodel->brush.num_leaffaces) + out->firstleafsurface = loadmodel->brush.data_leafsurfaces + LittleShort(in->firstmarksurface); + out->numleafsurfaces = LittleShort(in->nummarksurfaces); + if (out->firstleafsurface < 0 || LittleShort(in->firstmarksurface) + out->numleafsurfaces > loadmodel->brush.num_leafsurfaces) { - Con_Printf("Mod_Q1BSP_LoadLeafs: invalid leafface range %i:%i outside range %i:%i\n", out->firstleafface, out->firstleafface + out->numleaffaces, 0, loadmodel->brush.num_leaffaces); - out->firstleafface = NULL; - out->numleaffaces = 0; + Con_Printf("Mod_Q1BSP_LoadLeafs: invalid leafsurface range %i:%i outside range %i:%i\n", out->firstleafsurface, out->firstleafsurface + out->numleafsurfaces, 0, loadmodel->brush.num_leafsurfaces); + out->firstleafsurface = NULL; + out->numleafsurfaces = 0; } out->clusterindex = i - 1; @@ -2184,15 +2148,15 @@ static void Mod_Q1BSP_LoadLeaffaces(lump_t *l) in = (void *)(mod_base + l->fileofs); if (l->filelen % sizeof(*in)) Host_Error("Mod_Q1BSP_LoadLeaffaces: funny lump size in %s",loadmodel->name); - loadmodel->brush.num_leaffaces = l->filelen / sizeof(*in); - loadmodel->brush.data_leaffaces = Mem_Alloc(loadmodel->mempool, loadmodel->brush.num_leaffaces * sizeof(int)); + loadmodel->brush.num_leafsurfaces = l->filelen / sizeof(*in); + loadmodel->brush.data_leafsurfaces = Mem_Alloc(loadmodel->mempool, loadmodel->brush.num_leafsurfaces * sizeof(int)); - for (i = 0;i < loadmodel->brush.num_leaffaces;i++) + for (i = 0;i < loadmodel->brush.num_leafsurfaces;i++) { j = (unsigned) LittleShort(in[i]); - if (j >= loadmodel->brushq1.numsurfaces) + if (j >= loadmodel->brush.num_surfaces) Host_Error("Mod_Q1BSP_LoadLeaffaces: bad surface number"); - loadmodel->brush.data_leaffaces[i] = j; + loadmodel->brush.data_leafsurfaces[i] = j; } } @@ -2722,62 +2686,16 @@ static void Mod_Q1BSP_MakePortals(void) Mod_Q1BSP_FinalizePortals(); } -static void Mod_Q1BSP_BuildSurfaceNeighbors(msurface_t *surfaces, int numsurfaces, mempool_t *mempool) -{ -#if 0 - int surfnum, vertnum, vertnum2, snum, vnum, vnum2; - msurface_t *surf, *s; - float *v0, *v1, *v2, *v3; - for (surf = surfaces, surfnum = 0;surfnum < numsurfaces;surf++, surfnum++) - surf->neighborsurfaces = Mem_Alloc(mempool, surf->poly_numverts * sizeof(msurface_t *)); - for (surf = surfaces, surfnum = 0;surfnum < numsurfaces;surf++, surfnum++) - { - for (vertnum = surf->poly_numverts - 1, vertnum2 = 0, v0 = surf->poly_verts + (surf->poly_numverts - 1) * 3, v1 = surf->poly_verts;vertnum2 < surf->poly_numverts;vertnum = vertnum2, vertnum2++, v0 = v1, v1 += 3) - { - if (surf->neighborsurfaces[vertnum]) - continue; - surf->neighborsurfaces[vertnum] = NULL; - for (s = surfaces, snum = 0;snum < numsurfaces;s++, snum++) - { - if (s->poly_mins[0] > (surf->poly_maxs[0] + 1) || s->poly_maxs[0] < (surf->poly_mins[0] - 1) - || s->poly_mins[1] > (surf->poly_maxs[1] + 1) || s->poly_maxs[1] < (surf->poly_mins[1] - 1) - || s->poly_mins[2] > (surf->poly_maxs[2] + 1) || s->poly_maxs[2] < (surf->poly_mins[2] - 1) - || s == surf) - continue; - for (vnum = 0;vnum < s->poly_numverts;vnum++) - if (s->neighborsurfaces[vnum] == surf) - break; - if (vnum < s->poly_numverts) - continue; - for (vnum = s->poly_numverts - 1, vnum2 = 0, v2 = s->poly_verts + (s->poly_numverts - 1) * 3, v3 = s->poly_verts;vnum2 < s->poly_numverts;vnum = vnum2, vnum2++, v2 = v3, v3 += 3) - { - if (s->neighborsurfaces[vnum] == NULL - && ((v0[0] == v2[0] && v0[1] == v2[1] && v0[2] == v2[2] && v1[0] == v3[0] && v1[1] == v3[1] && v1[2] == v3[2]) - || (v1[0] == v2[0] && v1[1] == v2[1] && v1[2] == v2[2] && v0[0] == v3[0] && v0[1] == v3[1] && v0[2] == v3[2]))) - { - surf->neighborsurfaces[vertnum] = s; - s->neighborsurfaces[vnum] = surf; - break; - } - } - if (vnum < s->poly_numverts) - break; - } - } - } -#endif -} - static void Mod_Q1BSP_BuildLightmapUpdateChains(mempool_t *mempool, model_t *model) { int i, j, stylecounts[256], totalcount, remapstyles[256]; - msurface_t *surf; + msurface_t *surface; memset(stylecounts, 0, sizeof(stylecounts)); for (i = 0;i < model->nummodelsurfaces;i++) { - surf = model->brushq1.surfaces + model->firstmodelsurface + i; + surface = model->brush.data_surfaces + model->firstmodelsurface + i; for (j = 0;j < MAXLIGHTMAPS;j++) - stylecounts[surf->styles[j]]++; + stylecounts[surface->styles[j]]++; } totalcount = 0; model->brushq1.light_styles = 0; @@ -2807,10 +2725,10 @@ static void Mod_Q1BSP_BuildLightmapUpdateChains(mempool_t *mempool, model_t *mod } for (i = 0;i < model->nummodelsurfaces;i++) { - surf = model->brushq1.surfaces + model->firstmodelsurface + i; + surface = model->brush.data_surfaces + model->firstmodelsurface + i; for (j = 0;j < MAXLIGHTMAPS;j++) - if (surf->styles[j] != 255) - *model->brushq1.light_styleupdatechains[remapstyles[surf->styles[j]]]++ = surf; + if (surface->styles[j] != 255) + *model->brushq1.light_styleupdatechains[remapstyles[surface->styles[j]]]++ = surface; } j = 0; for (i = 0;i < model->brushq1.light_styles;i++) @@ -2927,20 +2845,20 @@ void Mod_Q1BSP_RecursiveGetVisible(mnode_t *node, model_t *model, const vec3_t p leaf = (mleaf_t *)node; if ((pvs == NULL || CHECKPVSBIT(pvs, leaf->clusterindex))) { - int leaffacenum; - msurface_t *surf; + int leafsurfacenum; + msurface_t *surface; if (maxleafs && *numleafs < maxleafs) leaflist[(*numleafs)++] = leaf; if (maxsurfaces) { - for (leaffacenum = 0;leaffacenum < leaf->numleaffaces;leaffacenum++) + for (leafsurfacenum = 0;leafsurfacenum < leaf->numleafsurfaces;leafsurfacenum++) { - surf = model->brushq1.surfaces + leaf->firstleafface[leaffacenum]; - if (surf->shadowmark != shadowmarkcount) + surface = model->brush.data_surfaces + leaf->firstleafsurface[leafsurfacenum]; + if (surface->shadowmark != shadowmarkcount) { - surf->shadowmark = shadowmarkcount; - if (BoxesOverlap(mins, maxs, surf->poly_mins, surf->poly_maxs) && ((surf->flags & SURF_PLANEBACK) ? PlaneDiff(point, surf->plane) < 0 : PlaneDiff(point, surf->plane) > 0) && *numsurfaces < maxsurfaces) - surfacelist[(*numsurfaces)++] = surf; + surface->shadowmark = shadowmarkcount; + if (BoxesOverlap(mins, maxs, surface->mins, surface->maxs) && ((surface->flags & SURF_PLANEBACK) ? PlaneDiff(point, surface->plane) < 0 : PlaneDiff(point, surface->plane) > 0) && *numsurfaces < maxsurfaces) + surfacelist[(*numsurfaces)++] = surface; } } } @@ -2971,7 +2889,7 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer) dmodel_t *bm; mempool_t *mainmempool; float dist, modelyawradius, modelradius, *vec; - msurface_t *surf; + msurface_t *surface; int numshadowmeshtriangles; mod->type = mod_brushq1; @@ -3051,14 +2969,14 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer) // make a single combined shadow mesh to allow optimized shadow volume creation numshadowmeshtriangles = 0; - for (j = 0, surf = loadmodel->brushq1.surfaces;j < loadmodel->brushq1.numsurfaces;j++, surf++) + for (j = 0, surface = loadmodel->brush.data_surfaces;j < loadmodel->brush.num_surfaces;j++, surface++) { - surf->num_firstshadowmeshtriangle = numshadowmeshtriangles; - numshadowmeshtriangles += surf->mesh.num_triangles; + surface->num_firstshadowmeshtriangle = numshadowmeshtriangles; + numshadowmeshtriangles += surface->mesh.num_triangles; } loadmodel->brush.shadowmesh = Mod_ShadowMesh_Begin(loadmodel->mempool, numshadowmeshtriangles * 3, numshadowmeshtriangles, NULL, NULL, NULL, false, false, true); - for (j = 0, surf = loadmodel->brushq1.surfaces;j < loadmodel->brushq1.numsurfaces;j++, surf++) - Mod_ShadowMesh_AddMesh(loadmodel->mempool, loadmodel->brush.shadowmesh, NULL, NULL, NULL, surf->mesh.data_vertex3f, NULL, NULL, NULL, NULL, surf->mesh.num_triangles, surf->mesh.data_element3i); + for (j = 0, surface = loadmodel->brush.data_surfaces;j < loadmodel->brush.num_surfaces;j++, surface++) + Mod_ShadowMesh_AddMesh(loadmodel->mempool, loadmodel->brush.shadowmesh, NULL, NULL, NULL, surface->mesh.data_vertex3f, NULL, NULL, NULL, NULL, surface->mesh.num_triangles, surface->mesh.data_element3i); loadmodel->brush.shadowmesh = Mod_ShadowMesh_Finish(loadmodel->mempool, loadmodel->brush.shadowmesh, false, true); Mod_BuildTriangleNeighbors(loadmodel->brush.shadowmesh->neighbor3i, loadmodel->brush.shadowmesh->element3i, loadmodel->brush.shadowmesh->numtriangles); @@ -3148,16 +3066,16 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer) mod->normalmaxs[0] = mod->normalmaxs[1] = mod->normalmaxs[2] = -1000000000.0f; modelyawradius = 0; modelradius = 0; - for (j = 0, surf = &mod->brushq1.surfaces[mod->firstmodelsurface];j < mod->nummodelsurfaces;j++, surf++) + for (j = 0, surface = &mod->brush.data_surfaces[mod->firstmodelsurface];j < mod->nummodelsurfaces;j++, surface++) { // we only need to have a drawsky function if it is used(usually only on world model) - if (surf->texinfo->texture->flags & SURF_DRAWSKY) + if (surface->texture->flags & SURF_DRAWSKY) mod->DrawSky = R_Q1BSP_DrawSky; // LordHavoc: submodels always clip, even if water - if (mod->brush.numsubmodels - 1) - surf->flags |= SURF_SOLIDCLIP; + if (i) + surface->flags |= SURF_SOLIDCLIP; // calculate bounding shapes - for (k = 0, vec = surf->mesh.data_vertex3f;k < surf->mesh.num_vertices;k++, vec += 3) + for (k = 0, vec = surface->mesh.data_vertex3f;k < surface->mesh.num_vertices;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]; @@ -3188,8 +3106,6 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer) // LordHavoc: empty submodel(lacrima.bsp has such a glitch) Con_Printf("warning: empty submodel *%i in %s\n", i+1, loadmodel->name); } - Mod_Q1BSP_BuildSurfaceNeighbors(mod->brushq1.surfaces + mod->firstmodelsurface, mod->nummodelsurfaces, loadmodel->mempool); - //mod->brushq1.num_visleafs = bm->visleafs; } @@ -3198,7 +3114,7 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer) //Mod_Q1BSP_ProcessLightList(); if (developer.integer) - Con_Printf("Some stats for q1bsp model \"%s\": %i faces, %i nodes, %i leafs, %i visleafs, %i visleafportals\n", loadmodel->name, loadmodel->brushq1.numsurfaces, loadmodel->brush.num_nodes, loadmodel->brush.num_leafs, mod->brushq1.submodels[i].visleafs, loadmodel->brush.num_portals); + Con_Printf("Some stats for q1bsp model \"%s\": %i faces, %i nodes, %i leafs, %i visleafs, %i visleafportals\n", loadmodel->name, loadmodel->brush.num_surfaces, loadmodel->brush.num_nodes, loadmodel->brush.num_leafs, mod->brushq1.submodels[i].visleafs, loadmodel->brush.num_portals); } static void Mod_Q2BSP_LoadEntities(lump_t *l) @@ -3673,7 +3589,7 @@ static void Mod_Q3BSP_LoadEntities(lump_t *l) static void Mod_Q3BSP_LoadTextures(lump_t *l) { q3dtexture_t *in; - q3mtexture_t *out; + texture_t *out; int i, count; int j, c; fssearch_t *search; @@ -3691,12 +3607,11 @@ static void Mod_Q3BSP_LoadTextures(lump_t *l) count = l->filelen / sizeof(*in); out = Mem_Alloc(loadmodel->mempool, count * sizeof(*out)); - loadmodel->brushq3.data_textures = out; - loadmodel->brushq3.num_textures = count; + loadmodel->brush.data_textures = out; + loadmodel->brush.num_textures = count; for (i = 0;i < count;i++, in++, out++) { - out->number = i; strlcpy (out->name, in->name, sizeof (out->name)); out->surfaceflags = LittleLong(in->surfaceflags); out->supercontents = Mod_Q3BSP_SuperContentsFromNativeContents(loadmodel, LittleLong(in->contents)); @@ -3888,7 +3803,7 @@ static void Mod_Q3BSP_LoadTextures(lump_t *l) flags |= Q3SURFACEPARM_TRANS; // add shader to list (shadername and flags) // actually here we just poke into the texture settings - for (j = 0, out = loadmodel->brushq3.data_textures;j < loadmodel->brushq3.num_textures;j++, out++) + for (j = 0, out = loadmodel->brush.data_textures;j < loadmodel->brush.num_textures;j++, out++) { if (!strcasecmp(out->name, shadername)) { @@ -3916,7 +3831,7 @@ parseerror: } c = 0; - for (j = 0, out = loadmodel->brushq3.data_textures;j < loadmodel->brushq3.num_textures;j++, out++) + for (j = 0, out = loadmodel->brush.data_textures;j < loadmodel->brush.num_textures;j++, out++) { if (out->surfaceparms == -1) { @@ -3977,8 +3892,8 @@ static void Mod_Q3BSP_LoadBrushSides(lump_t *l) count = l->filelen / sizeof(*in); out = Mem_Alloc(loadmodel->mempool, count * sizeof(*out)); - loadmodel->brushq3.data_brushsides = out; - loadmodel->brushq3.num_brushsides = count; + loadmodel->brush.data_brushsides = out; + loadmodel->brush.num_brushsides = count; for (i = 0;i < count;i++, in++, out++) { @@ -3987,9 +3902,9 @@ static void Mod_Q3BSP_LoadBrushSides(lump_t *l) Host_Error("Mod_Q3BSP_LoadBrushSides: invalid planeindex %i (%i planes)\n", n, loadmodel->brush.num_planes); out->plane = loadmodel->brush.data_planes + n; n = LittleLong(in->textureindex); - if (n < 0 || n >= loadmodel->brushq3.num_textures) - Host_Error("Mod_Q3BSP_LoadBrushSides: invalid textureindex %i (%i textures)\n", n, loadmodel->brushq3.num_textures); - out->texture = loadmodel->brushq3.data_textures + n; + if (n < 0 || n >= loadmodel->brush.num_textures) + Host_Error("Mod_Q3BSP_LoadBrushSides: invalid textureindex %i (%i textures)\n", n, loadmodel->brush.num_textures); + out->texture = loadmodel->brush.data_textures + n; } } @@ -4006,8 +3921,8 @@ static void Mod_Q3BSP_LoadBrushes(lump_t *l) count = l->filelen / sizeof(*in); out = Mem_Alloc(loadmodel->mempool, count * sizeof(*out)); - loadmodel->brushq3.data_brushes = out; - loadmodel->brushq3.num_brushes = count; + loadmodel->brush.data_brushes = out; + loadmodel->brush.num_brushes = count; maxplanes = 0; planes = NULL; @@ -4016,14 +3931,14 @@ static void Mod_Q3BSP_LoadBrushes(lump_t *l) { n = LittleLong(in->firstbrushside); c = LittleLong(in->numbrushsides); - if (n < 0 || n + c > loadmodel->brushq3.num_brushsides) - Host_Error("Mod_Q3BSP_LoadBrushes: invalid brushside range %i : %i (%i brushsides)\n", n, n + c, loadmodel->brushq3.num_brushsides); - out->firstbrushside = loadmodel->brushq3.data_brushsides + n; + if (n < 0 || n + c > loadmodel->brush.num_brushsides) + Host_Error("Mod_Q3BSP_LoadBrushes: invalid brushside range %i : %i (%i brushsides)\n", n, n + c, loadmodel->brush.num_brushsides); + out->firstbrushside = loadmodel->brush.data_brushsides + n; out->numbrushsides = c; n = LittleLong(in->textureindex); - if (n < 0 || n >= loadmodel->brushq3.num_textures) - Host_Error("Mod_Q3BSP_LoadBrushes: invalid textureindex %i (%i textures)\n", n, loadmodel->brushq3.num_textures); - out->texture = loadmodel->brushq3.data_textures + n; + if (n < 0 || n >= loadmodel->brush.num_textures) + Host_Error("Mod_Q3BSP_LoadBrushes: invalid textureindex %i (%i textures)\n", n, loadmodel->brush.num_textures); + out->texture = loadmodel->brush.data_textures + n; // make a list of mplane_t structs to construct a colbrush from if (maxplanes < out->numbrushsides) @@ -4064,9 +3979,9 @@ static void Mod_Q3BSP_LoadEffects(lump_t *l) { strlcpy (out->shadername, in->shadername, sizeof (out->shadername)); n = LittleLong(in->brushindex); - if (n < 0 || n >= loadmodel->brushq3.num_brushes) - Host_Error("Mod_Q3BSP_LoadEffects: invalid brushindex %i (%i brushes)\n", n, loadmodel->brushq3.num_brushes); - out->brush = loadmodel->brushq3.data_brushes + n; + if (n < 0 || n >= loadmodel->brush.num_brushes) + Host_Error("Mod_Q3BSP_LoadEffects: invalid brushindex %i (%i brushes)\n", n, loadmodel->brush.num_brushes); + out->brush = loadmodel->brush.data_brushes + n; out->unknown = LittleLong(in->unknown); } } @@ -4152,7 +4067,7 @@ static void Mod_Q3BSP_LoadLightmaps(lump_t *l) static void Mod_Q3BSP_LoadFaces(lump_t *l) { q3dface_t *in, *oldin; - q3msurface_t *out, *oldout; + msurface_t *out, *oldout; int i, oldi, j, n, count, invalidelements, patchsize[2], finalwidth, finalheight, xtess, ytess, finalvertices, finaltriangles, firstvertex, firstelement, type, oldnumtriangles, oldnumtriangles2, meshnum, meshvertices, meshtriangles, numvertices, numtriangles; //int *originalelement3i; //int *originalneighbor3i; @@ -4172,8 +4087,8 @@ static void Mod_Q3BSP_LoadFaces(lump_t *l) count = l->filelen / sizeof(*in); out = Mem_Alloc(loadmodel->mempool, count * sizeof(*out)); - loadmodel->brushq3.data_faces = out; - loadmodel->brushq3.num_faces = count; + loadmodel->brush.data_surfaces = out; + loadmodel->brush.num_surfaces = count; i = 0; for (meshnum = 0;i < count;meshnum++) @@ -4197,12 +4112,12 @@ static void Mod_Q3BSP_LoadFaces(lump_t *l) } n = LittleLong(in->textureindex); - if (n < 0 || n >= loadmodel->brushq3.num_textures) + if (n < 0 || n >= loadmodel->brush.num_textures) { - Con_DPrintf("Mod_Q3BSP_LoadFaces: face #%i: invalid textureindex %i (%i textures)\n", i, n, loadmodel->brushq3.num_textures); + Con_DPrintf("Mod_Q3BSP_LoadFaces: face #%i: invalid textureindex %i (%i textures)\n", i, n, loadmodel->brush.num_textures); continue; } - out->texture = loadmodel->brushq3.data_textures + n; + out->texture = loadmodel->brush.data_textures + n; n = LittleLong(in->effectindex); if (n < -1 || n >= loadmodel->brushq3.num_effects) { @@ -4519,15 +4434,15 @@ static void Mod_Q3BSP_LoadModels(lump_t *l) } n = LittleLong(in->firstface); c = LittleLong(in->numfaces); - if (n < 0 || n + c > loadmodel->brushq3.num_faces) - Host_Error("Mod_Q3BSP_LoadModels: invalid face range %i : %i (%i faces)\n", n, n + c, loadmodel->brushq3.num_faces); - out->firstface = loadmodel->brushq3.data_faces + n; - out->numfaces = c; + if (n < 0 || n + c > loadmodel->brush.num_surfaces) + Host_Error("Mod_Q3BSP_LoadModels: invalid face range %i : %i (%i faces)\n", n, n + c, loadmodel->brush.num_surfaces); + out->firstsurface = n; + out->numsurfaces = c; n = LittleLong(in->firstbrush); c = LittleLong(in->numbrushes); - if (n < 0 || n + c > loadmodel->brushq3.num_brushes) - Host_Error("Mod_Q3BSP_LoadModels: invalid brush range %i : %i (%i brushes)\n", n, n + c, loadmodel->brushq3.num_brushes); - out->firstbrush = loadmodel->brushq3.data_brushes + n; + if (n < 0 || n + c > loadmodel->brush.num_brushes) + Host_Error("Mod_Q3BSP_LoadModels: invalid brush range %i : %i (%i brushes)\n", n, n + c, loadmodel->brush.num_brushes); + out->firstbrush = n; out->numbrushes = c; } } @@ -4550,8 +4465,8 @@ static void Mod_Q3BSP_LoadLeafBrushes(lump_t *l) for (i = 0;i < count;i++, in++, out++) { n = LittleLong(*in); - if (n < 0 || n >= loadmodel->brushq3.num_brushes) - Host_Error("Mod_Q3BSP_LoadLeafBrushes: invalid brush index %i (%i brushes)\n", n, loadmodel->brushq3.num_brushes); + if (n < 0 || n >= loadmodel->brush.num_brushes) + Host_Error("Mod_Q3BSP_LoadLeafBrushes: invalid brush index %i (%i brushes)\n", n, loadmodel->brush.num_brushes); *out = n; } } @@ -4568,14 +4483,14 @@ static void Mod_Q3BSP_LoadLeafFaces(lump_t *l) count = l->filelen / sizeof(*in); out = Mem_Alloc(loadmodel->mempool, count * sizeof(*out)); - loadmodel->brush.data_leaffaces = out; - loadmodel->brush.num_leaffaces = count; + loadmodel->brush.data_leafsurfaces = out; + loadmodel->brush.num_leafsurfaces = count; for (i = 0;i < count;i++, in++, out++) { n = LittleLong(*in); - if (n < 0 || n >= loadmodel->brushq3.num_faces) - Host_Error("Mod_Q3BSP_LoadLeafFaces: invalid face index %i (%i faces)\n", n, loadmodel->brushq3.num_faces); + if (n < 0 || n >= loadmodel->brush.num_surfaces) + Host_Error("Mod_Q3BSP_LoadLeafFaces: invalid face index %i (%i faces)\n", n, loadmodel->brush.num_surfaces); *out = n; } } @@ -4609,10 +4524,10 @@ static void Mod_Q3BSP_LoadLeafs(lump_t *l) } n = LittleLong(in->firstleafface); c = LittleLong(in->numleaffaces); - if (n < 0 || n + c > loadmodel->brush.num_leaffaces) - Host_Error("Mod_Q3BSP_LoadLeafs: invalid leafface range %i : %i (%i leaffaces)\n", n, n + c, loadmodel->brush.num_leaffaces); - out->firstleafface = loadmodel->brush.data_leaffaces + n; - out->numleaffaces = c; + if (n < 0 || n + c > loadmodel->brush.num_leafsurfaces) + Host_Error("Mod_Q3BSP_LoadLeafs: invalid leafsurface range %i : %i (%i leafsurfaces)\n", n, n + c, loadmodel->brush.num_leafsurfaces); + out->firstleafsurface = loadmodel->brush.data_leafsurfaces + n; + out->numleafsurfaces = c; n = LittleLong(in->firstleafbrush); c = LittleLong(in->numleafbrushes); if (n < 0 || n + c > loadmodel->brush.num_leafbrushes) @@ -4857,7 +4772,7 @@ static void Mod_Q3BSP_TracePoint_RecursiveBSPNode(trace_t *trace, model_t *model leaf = (mleaf_t *)node; for (i = 0;i < leaf->numleafbrushes;i++) { - brush = model->brushq3.data_brushes[leaf->firstleafbrush[i]].colbrushf; + brush = model->brush.data_brushes[leaf->firstleafbrush[i]].colbrushf; if (brush && brush->markframe != markframe && BoxesOverlap(point, point, brush->mins, brush->maxs)) { brush->markframe = markframe; @@ -4872,7 +4787,7 @@ static void Mod_Q3BSP_TraceLine_RecursiveBSPNode(trace_t *trace, model_t *model, int i, startside, endside; float dist1, dist2, midfrac, mid[3], nodesegmentmins[3], nodesegmentmaxs[3]; mleaf_t *leaf; - q3msurface_t *face; + msurface_t *surface; colbrushf_t *brush; if (startfrac > trace->realfraction) return; @@ -4922,7 +4837,7 @@ static void Mod_Q3BSP_TraceLine_RecursiveBSPNode(trace_t *trace, model_t *model, leaf = (mleaf_t *)node; for (i = 0;i < leaf->numleafbrushes;i++) { - brush = model->brushq3.data_brushes[leaf->firstleafbrush[i]].colbrushf; + brush = model->brush.data_brushes[leaf->firstleafbrush[i]].colbrushf; if (brush && brush->markframe != markframe && BoxesOverlap(nodesegmentmins, nodesegmentmaxs, brush->mins, brush->maxs)) { brush->markframe = markframe; @@ -4935,13 +4850,13 @@ static void Mod_Q3BSP_TraceLine_RecursiveBSPNode(trace_t *trace, model_t *model, if (mod_q3bsp_curves_collisions.integer && !VectorCompare(start, end)) { // line trace the curves - for (i = 0;i < leaf->numleaffaces;i++) + for (i = 0;i < leaf->numleafsurfaces;i++) { - face = model->brushq3.data_faces + leaf->firstleafface[i]; - if (face->mesh.num_collisiontriangles && face->collisionmarkframe != markframe && BoxesOverlap(nodesegmentmins, nodesegmentmaxs, face->mins, face->maxs)) + surface = model->brush.data_surfaces + leaf->firstleafsurface[i]; + if (surface->mesh.num_collisiontriangles && surface->collisionmarkframe != markframe && BoxesOverlap(nodesegmentmins, nodesegmentmaxs, surface->mins, surface->maxs)) { - face->collisionmarkframe = markframe; - Collision_TraceLineTriangleMeshFloat(trace, linestart, lineend, face->mesh.num_collisiontriangles, face->mesh.data_collisionelement3i, face->mesh.data_collisionvertex3f, face->texture->supercontents, segmentmins, segmentmaxs); + surface->collisionmarkframe = markframe; + Collision_TraceLineTriangleMeshFloat(trace, linestart, lineend, surface->mesh.num_collisiontriangles, surface->mesh.data_collisionelement3i, surface->mesh.data_collisionvertex3f, surface->texture->supercontents, segmentmins, segmentmaxs); if (startfrac > trace->realfraction) return; } @@ -4956,7 +4871,7 @@ static void Mod_Q3BSP_TraceBrush_RecursiveBSPNode(trace_t *trace, model_t *model float nodesegmentmins[3], nodesegmentmaxs[3]; mleaf_t *leaf; colbrushf_t *brush; - q3msurface_t *face; + msurface_t *surface; /* // find which nodes the line is in and recurse for them while (node->plane) @@ -5306,7 +5221,7 @@ static void Mod_Q3BSP_TraceBrush_RecursiveBSPNode(trace_t *trace, model_t *model leaf = (mleaf_t *)node; for (i = 0;i < leaf->numleafbrushes;i++) { - brush = model->brushq3.data_brushes[leaf->firstleafbrush[i]].colbrushf; + brush = model->brush.data_brushes[leaf->firstleafbrush[i]].colbrushf; if (brush && brush->markframe != markframe && BoxesOverlap(nodesegmentmins, nodesegmentmaxs, brush->mins, brush->maxs)) { brush->markframe = markframe; @@ -5315,13 +5230,13 @@ static void Mod_Q3BSP_TraceBrush_RecursiveBSPNode(trace_t *trace, model_t *model } if (mod_q3bsp_curves_collisions.integer) { - for (i = 0;i < leaf->numleaffaces;i++) + for (i = 0;i < leaf->numleafsurfaces;i++) { - face = model->brushq3.data_faces + leaf->firstleafface[i]; - if (face->mesh.num_collisiontriangles && face->collisionmarkframe != markframe && BoxesOverlap(nodesegmentmins, nodesegmentmaxs, face->mins, face->maxs)) + surface = model->brush.data_surfaces + leaf->firstleafsurface[i]; + if (surface->mesh.num_collisiontriangles && surface->collisionmarkframe != markframe && BoxesOverlap(nodesegmentmins, nodesegmentmaxs, surface->mins, surface->maxs)) { - face->collisionmarkframe = markframe; - Collision_TraceBrushTriangleMeshFloat(trace, thisbrush_start, thisbrush_end, face->mesh.num_collisiontriangles, face->mesh.data_collisionelement3i, face->mesh.data_collisionvertex3f, face->texture->supercontents, segmentmins, segmentmaxs); + surface->collisionmarkframe = markframe; + Collision_TraceBrushTriangleMeshFloat(trace, thisbrush_start, thisbrush_end, surface->mesh.num_collisiontriangles, surface->mesh.data_collisionelement3i, surface->mesh.data_collisionvertex3f, surface->texture->supercontents, segmentmins, segmentmaxs); } } } @@ -5334,7 +5249,8 @@ static void Mod_Q3BSP_TraceBox(model_t *model, int frame, trace_t *trace, const colbrushf_t *thisbrush_start, *thisbrush_end; matrix4x4_t startmatrix, endmatrix; static int markframe = 0; - q3msurface_t *face; + msurface_t *surface; + q3mbrush_t *brush; memset(trace, 0, sizeof(*trace)); trace->fraction = 1; trace->realfraction = 1; @@ -5354,9 +5270,9 @@ static void Mod_Q3BSP_TraceBox(model_t *model, int frame, trace_t *trace, const // point trace if (model->brush.submodel) { - for (i = 0;i < model->brushq3.data_models[model->brush.submodel].numbrushes;i++) - if (model->brushq3.data_models[model->brush.submodel].firstbrush[i].colbrushf) - Collision_TracePointBrushFloat(trace, boxstartmins, model->brushq3.data_models[model->brush.submodel].firstbrush[i].colbrushf); + for (i = 0, brush = model->brush.data_brushes + model->firstmodelbrush;i < model->nummodelbrushes;i++, brush++) + if (brush->colbrushf) + Collision_TracePointBrushFloat(trace, boxstartmins, brush->colbrushf); } else Mod_Q3BSP_TracePoint_RecursiveBSPNode(trace, model, model->brush.data_nodes, boxstartmins, ++markframe); @@ -5366,18 +5282,13 @@ static void Mod_Q3BSP_TraceBox(model_t *model, int frame, trace_t *trace, const // line trace if (model->brush.submodel) { - for (i = 0;i < model->brushq3.data_models[model->brush.submodel].numbrushes;i++) - if (model->brushq3.data_models[model->brush.submodel].firstbrush[i].colbrushf) - Collision_TraceLineBrushFloat(trace, boxstartmins, boxendmins, model->brushq3.data_models[model->brush.submodel].firstbrush[i].colbrushf, model->brushq3.data_models[model->brush.submodel].firstbrush[i].colbrushf); + for (i = 0, brush = model->brush.data_brushes + model->firstmodelbrush;i < model->nummodelbrushes;i++, brush++) + if (brush->colbrushf) + Collision_TraceLineBrushFloat(trace, boxstartmins, boxendmins, brush->colbrushf, brush->colbrushf); if (mod_q3bsp_curves_collisions.integer) - { - for (i = 0;i < model->brushq3.data_models[model->brush.submodel].numfaces;i++) - { - face = model->brushq3.data_models[model->brush.submodel].firstface + i; - if (face->mesh.num_collisiontriangles) - Collision_TraceLineTriangleMeshFloat(trace, boxstartmins, boxendmins, face->mesh.num_collisiontriangles, face->mesh.data_collisionelement3i, face->mesh.data_collisionvertex3f, face->texture->supercontents, segmentmins, segmentmaxs); - } - } + for (i = 0, surface = model->brush.data_surfaces + model->firstmodelsurface;i < model->nummodelsurfaces;i++, surface++) + if (surface->mesh.num_collisiontriangles) + Collision_TraceLineTriangleMeshFloat(trace, boxstartmins, boxendmins, surface->mesh.num_collisiontriangles, surface->mesh.data_collisionelement3i, surface->mesh.data_collisionvertex3f, surface->texture->supercontents, segmentmins, segmentmaxs); } else Mod_Q3BSP_TraceLine_RecursiveBSPNode(trace, model, model->brush.data_nodes, boxstartmins, boxendmins, 0, 1, boxstartmins, boxendmins, ++markframe, segmentmins, segmentmaxs); @@ -5390,18 +5301,13 @@ static void Mod_Q3BSP_TraceBox(model_t *model, int frame, trace_t *trace, const thisbrush_end = Collision_BrushForBox(&endmatrix, boxendmins, boxendmaxs); if (model->brush.submodel) { - for (i = 0;i < model->brushq3.data_models[model->brush.submodel].numbrushes;i++) - if (model->brushq3.data_models[model->brush.submodel].firstbrush[i].colbrushf) - Collision_TraceBrushBrushFloat(trace, thisbrush_start, thisbrush_end, model->brushq3.data_models[model->brush.submodel].firstbrush[i].colbrushf, model->brushq3.data_models[model->brush.submodel].firstbrush[i].colbrushf); + for (i = 0, brush = model->brush.data_brushes + model->firstmodelbrush;i < model->nummodelbrushes;i++, brush++) + if (brush->colbrushf) + Collision_TraceBrushBrushFloat(trace, thisbrush_start, thisbrush_end, brush->colbrushf, brush->colbrushf); if (mod_q3bsp_curves_collisions.integer) - { - for (i = 0;i < model->brushq3.data_models[model->brush.submodel].numfaces;i++) - { - face = model->brushq3.data_models[model->brush.submodel].firstface + i; - if (face->mesh.num_collisiontriangles) - Collision_TraceBrushTriangleMeshFloat(trace, thisbrush_start, thisbrush_end, face->mesh.num_collisiontriangles, face->mesh.data_collisionelement3i, face->mesh.data_collisionvertex3f, face->texture->supercontents, segmentmins, segmentmaxs); - } - } + for (i = 0, surface = model->brush.data_surfaces + model->firstmodelsurface;i < model->nummodelsurfaces;i++, surface++) + if (surface->mesh.num_collisiontriangles) + Collision_TraceBrushTriangleMeshFloat(trace, thisbrush_start, thisbrush_end, surface->mesh.num_collisiontriangles, surface->mesh.data_collisionelement3i, surface->mesh.data_collisionvertex3f, surface->texture->supercontents, segmentmins, segmentmaxs); } else Mod_Q3BSP_TraceBrush_RecursiveBSPNode(trace, model, model->brush.data_nodes, thisbrush_start, thisbrush_end, ++markframe, segmentmins, segmentmaxs); @@ -5584,7 +5490,7 @@ void Mod_Q3BSP_Load(model_t *mod, void *buffer) int i, j, numshadowmeshtriangles; q3dheader_t *header; float corner[3], yawradius, modelradius; - q3msurface_t *face; + msurface_t *surface; mod->type = mod_brushq3; mod->numframes = 2; // although alternate textures are not supported it is annoying to complain about no such frame 1 @@ -5645,14 +5551,14 @@ void Mod_Q3BSP_Load(model_t *mod, void *buffer) // make a single combined shadow mesh to allow optimized shadow volume creation numshadowmeshtriangles = 0; - for (j = 0, face = loadmodel->brushq3.data_faces;j < loadmodel->brushq3.num_faces;j++, face++) + for (j = 0, surface = loadmodel->brush.data_surfaces;j < loadmodel->brush.num_surfaces;j++, surface++) { - face->num_firstshadowmeshtriangle = numshadowmeshtriangles; - numshadowmeshtriangles += face->mesh.num_triangles; + surface->num_firstshadowmeshtriangle = numshadowmeshtriangles; + numshadowmeshtriangles += surface->mesh.num_triangles; } loadmodel->brush.shadowmesh = Mod_ShadowMesh_Begin(loadmodel->mempool, numshadowmeshtriangles * 3, numshadowmeshtriangles, NULL, NULL, NULL, false, false, true); - for (j = 0, face = loadmodel->brushq3.data_faces;j < loadmodel->brushq3.num_faces;j++, face++) - Mod_ShadowMesh_AddMesh(loadmodel->mempool, loadmodel->brush.shadowmesh, NULL, NULL, NULL, face->mesh.data_vertex3f, NULL, NULL, NULL, NULL, face->mesh.num_triangles, face->mesh.data_element3i); + for (j = 0, surface = loadmodel->brush.data_surfaces;j < loadmodel->brush.num_surfaces;j++, surface++) + Mod_ShadowMesh_AddMesh(loadmodel->mempool, loadmodel->brush.shadowmesh, NULL, NULL, NULL, surface->mesh.data_vertex3f, NULL, NULL, NULL, NULL, surface->mesh.num_triangles, surface->mesh.data_element3i); loadmodel->brush.shadowmesh = Mod_ShadowMesh_Finish(loadmodel->mempool, loadmodel->brush.shadowmesh, false, true); Mod_BuildTriangleNeighbors(loadmodel->brush.shadowmesh->neighbor3i, loadmodel->brush.shadowmesh->element3i, loadmodel->brush.shadowmesh->numtriangles); @@ -5687,10 +5593,13 @@ void Mod_Q3BSP_Load(model_t *mod, void *buffer) mod->brush.submodel = i; // make the model surface list (used by shadowing/lighting) - mod->nummodelsurfaces = mod->brushq3.data_models[i].numfaces; + mod->firstmodelsurface = mod->brushq3.data_models[i].firstsurface; + mod->nummodelsurfaces = mod->brushq3.data_models[i].numsurfaces; + mod->firstmodelbrush = mod->brushq3.data_models[i].firstbrush; + mod->nummodelbrushes = mod->brushq3.data_models[i].numbrushes; mod->surfacelist = Mem_Alloc(loadmodel->mempool, mod->nummodelsurfaces * sizeof(*mod->surfacelist)); for (j = 0;j < mod->nummodelsurfaces;j++) - mod->surfacelist[j] = (mod->brushq3.data_models[i].firstface - mod->brushq3.data_faces) + j; + mod->surfacelist[j] = mod->firstmodelsurface + j; VectorCopy(mod->brushq3.data_models[i].mins, mod->normalmins); VectorCopy(mod->brushq3.data_models[i].maxs, mod->normalmaxs); @@ -5708,10 +5617,10 @@ void Mod_Q3BSP_Load(model_t *mod, void *buffer) mod->radius = modelradius; mod->radius2 = modelradius * modelradius; - for (j = 0;j < mod->brushq3.data_models[i].numfaces;j++) - if (mod->brushq3.data_models[i].firstface[j].texture->surfaceflags & Q3SURFACEFLAG_SKY) + for (j = 0;j < mod->nummodelsurfaces;j++) + if (mod->brush.data_surfaces[j + mod->firstmodelsurface].texture->surfaceflags & Q3SURFACEFLAG_SKY) break; - if (j < mod->brushq3.data_models[i].numfaces) + if (j < mod->nummodelsurfaces) mod->DrawSky = R_Q3BSP_DrawSky; } }