+ // check face type first
+ out->type = LittleLong(in->type);
+ if (out->type != Q3FACETYPE_POLYGON
+ && out->type != Q3FACETYPE_PATCH
+ && out->type != Q3FACETYPE_MESH
+ && out->type != Q3FACETYPE_FLARE)
+ {
+ Con_Printf("Mod_Q3BSP_LoadFaces: face #%i: unknown face type %i\n", i, n);
+ out->type = 0; // error
+ continue;
+ }
+
+ n = LittleLong(in->textureindex);
+ if (n < 0 || n >= loadmodel->brushq3.num_textures)
+ {
+ Con_Printf("Mod_Q3BSP_LoadFaces: face #%i: invalid textureindex %i (%i textures)\n", i, n, loadmodel->brushq3.num_textures);
+ out->type = 0; // error
+ continue;
+ n = 0;
+ }
+ out->texture = loadmodel->brushq3.data_textures + n;
+ n = LittleLong(in->effectindex);
+ if (n < -1 || n >= loadmodel->brushq3.num_effects)
+ {
+ Con_Printf("Mod_Q3BSP_LoadFaces: face #%i (texture \"%s\"): invalid effectindex %i (%i effects)\n", i, out->texture->name, n, loadmodel->brushq3.num_effects);
+ n = -1;
+ }
+ if (n == -1)
+ out->effect = NULL;
+ else
+ out->effect = loadmodel->brushq3.data_effects + n;
+ n = LittleLong(in->lightmapindex);
+ if (n < -1 || n >= loadmodel->brushq3.num_lightmaps)
+ {
+ Con_Printf("Mod_Q3BSP_LoadFaces: face #%i (texture \"%s\"): invalid lightmapindex %i (%i lightmaps)\n", i, out->texture->name, n, loadmodel->brushq3.num_lightmaps);
+ n = -1;
+ }
+ if (n == -1)
+ out->lightmaptexture = NULL;
+ else
+ out->lightmaptexture = loadmodel->brushq3.data_lightmaps[n];
+
+ out->firstvertex = LittleLong(in->firstvertex);
+ out->numvertices = LittleLong(in->numvertices);
+ out->firstelement = LittleLong(in->firstelement);
+ out->numelements = LittleLong(in->numelements);
+ out->numtriangles = out->numelements / 3;
+ if (out->firstvertex < 0 || out->firstvertex + out->numvertices > loadmodel->brushq3.num_vertices)
+ {
+ Con_Printf("Mod_Q3BSP_LoadFaces: face #%i (texture \"%s\"): invalid vertex range %i : %i (%i vertices)\n", i, out->texture->name, out->firstvertex, out->firstvertex + out->numvertices, loadmodel->brushq3.num_vertices);
+ out->type = 0; // error
+ continue;
+ }
+ if (out->firstelement < 0 || out->firstelement + out->numelements > loadmodel->brushq3.num_triangles * 3)
+ {
+ Con_Printf("Mod_Q3BSP_LoadFaces: face #%i (texture \"%s\"): invalid element range %i : %i (%i elements)\n", i, out->texture->name, out->firstelement, out->firstelement + out->numelements, loadmodel->brushq3.num_triangles * 3);
+ out->type = 0; // error
+ continue;
+ }
+ if (out->numtriangles * 3 != out->numelements)
+ {
+ Con_Printf("Mod_Q3BSP_LoadFaces: face #%i (texture \"%s\"): numelements %i is not a multiple of 3\n", i, out->texture->name, out->numelements);
+ out->type = 0; // error
+ continue;
+ }
+ switch(out->type)
+ {
+ case Q3FACETYPE_POLYGON:
+ case Q3FACETYPE_MESH:
+ out->data_vertex3f = loadmodel->brushq3.data_vertex3f + out->firstvertex * 3;
+ out->data_texturetexcoord2f = loadmodel->brushq3.data_texturetexcoord2f + out->firstvertex * 2;
+ out->data_lightmaptexcoord2f = loadmodel->brushq3.data_lightmaptexcoord2f + out->firstvertex * 2;
+ out->data_svector3f = loadmodel->brushq3.data_svector3f + out->firstvertex * 3;
+ out->data_tvector3f = loadmodel->brushq3.data_tvector3f + out->firstvertex * 3;
+ out->data_normal3f = loadmodel->brushq3.data_normal3f + out->firstvertex * 3;
+ out->data_color4f = loadmodel->brushq3.data_color4f + out->firstvertex * 4;
+ out->data_element3i = loadmodel->brushq3.data_element3i + out->firstelement;
+ out->data_neighbor3i = loadmodel->brushq3.data_neighbor3i + out->firstelement;
+ break;
+ case Q3FACETYPE_PATCH:
+ patchsize[0] = LittleLong(in->specific.patch.patchsize[0]);
+ patchsize[1] = LittleLong(in->specific.patch.patchsize[1]);
+ if (patchsize[0] < 1 || patchsize[1] < 1)
+ {
+ Con_Printf("Mod_Q3BSP_LoadFaces: face #%i (texture \"%s\"): invalid patchsize %ix%i\n", i, out->texture->name, patchsize[0], patchsize[1]);
+ out->type = 0; // error
+ continue;
+ }
+ // FIXME: convert patch to triangles here!
+ Con_Printf("Mod_Q3BSP_LoadFaces: face #%i (texture \"%s\"): Q3FACETYPE_PATCH not supported (yet)\n", i, out->texture->name);
+ out->type = 0;
+ continue;
+ break;
+ case Q3FACETYPE_FLARE:
+ Con_Printf("Mod_Q3BSP_LoadFaces: face #%i (texture \"%s\"): Q3FACETYPE_FLARE not supported (yet)\n", i, out->texture->name);
+ out->type = 0;
+ continue;
+ break;
+ }
+ for (j = 0, invalidelements = 0;j < out->numelements;j++)
+ if (out->data_element3i[j] < 0 || out->data_element3i[j] >= out->numvertices)
+ invalidelements++;
+ if (invalidelements)
+ {
+ Con_Printf("Mod_Q3BSP_LoadFaces: Warning: face #%i has %i invalid elements, type = %i, texture->name = \"%s\", texture->surfaceflags = %i, texture->contents = %i, firstvertex = %i, numvertices = %i, firstelement = %i, numelements = %i, elements list:\n", i, invalidelements, out->type, out->texture->name, out->texture->surfaceflags, out->texture->contents, out->firstvertex, out->numvertices, out->firstelement, out->numelements);
+ for (j = 0;j < out->numelements;j++)
+ {
+ Con_Printf(" %i", out->data_element3i[j]);
+ if (out->data_element3i[j] < 0 || out->data_element3i[j] >= out->numvertices)
+ out->data_element3i[j] = 0;
+ }
+ Con_Printf("\n");
+ }