#include "image.h"
#include "r_shadow.h"
#include "winding.h"
+#include "curves.h"
// note: model_shared.c sets up r_notexture, and r_surf_notexture
cvar_t r_miplightmaps = {CVAR_SAVE, "r_miplightmaps", "0"};
cvar_t r_lightmaprgba = {0, "r_lightmaprgba", "1"};
cvar_t r_nosurftextures = {0, "r_nosurftextures", "0"};
-cvar_t r_sortsurfaces = {0, "r_sortsurfaces", "0"};
+cvar_t mod_q3bsp_curves_subdivide_level = {0, "mod_q3bsp_curves_subdivide_level", "2"};
+cvar_t mod_q3bsp_curves_collisions = {0, "mod_q3bsp_curves_collisions", "1"};
+cvar_t mod_q3bsp_optimizedtraceline = {0, "mod_q3bsp_optimizedtraceline", "1"};
void Mod_BrushInit(void)
{
Cvar_RegisterVariable(&r_miplightmaps);
Cvar_RegisterVariable(&r_lightmaprgba);
Cvar_RegisterVariable(&r_nosurftextures);
- Cvar_RegisterVariable(&r_sortsurfaces);
+ Cvar_RegisterVariable(&mod_q3bsp_curves_subdivide_level);
+ Cvar_RegisterVariable(&mod_q3bsp_curves_collisions);
+ Cvar_RegisterVariable(&mod_q3bsp_optimizedtraceline);
memset(mod_q1bsp_novis, 0xff, sizeof(mod_q1bsp_novis));
}
{
q3dface_t *in;
q3mface_t *out;
- int i, j, n, count, invalidelements, patchsize[2];
+ int i, j, n, count, invalidelements, patchsize[2], finalwidth, finalheight, xlevel, ylevel, row0, row1, x, y, *e, finalvertices, finaltriangles;
+ //int *originalelement3i;
+ //int *originalneighbor3i;
+ float *originalvertex3f;
+ //float *originalsvector3f;
+ //float *originaltvector3f;
+ //float *originalnormal3f;
+ float *originalcolor4f;
+ float *originaltexcoordtexture2f;
+ float *originaltexcoordlightmap2f;
+ float *v;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
{
case Q3FACETYPE_POLYGON:
case Q3FACETYPE_MESH:
+ // no processing necessary
break;
case Q3FACETYPE_PATCH:
patchsize[0] = LittleLong(in->specific.patch.patchsize[0]);
out->type = 0; // error
continue;
}
- out->patchsize[0] = patchsize[0];
- out->patchsize[1] = patchsize[1];
- out->numelements = out->numtriangles = 0;
- // 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;
+ // convert patch to Q3FACETYPE_MESH
+ xlevel = mod_q3bsp_curves_subdivide_level.integer;
+ ylevel = mod_q3bsp_curves_subdivide_level.integer;
+ finalwidth = ((patchsize[0] - 1) << xlevel) + 1;
+ finalheight = ((patchsize[1] - 1) << ylevel) + 1;
+ finalvertices = finalwidth * finalheight;
+ finaltriangles = (finalwidth - 1) * (finalheight - 1) * 2;
+ originalvertex3f = out->data_vertex3f;
+ //originalsvector3f = out->data_svector3f;
+ //originaltvector3f = out->data_tvector3f;
+ //originalnormal3f = out->data_normal3f;
+ originalcolor4f = out->data_color4f;
+ originaltexcoordtexture2f = out->data_texcoordtexture2f;
+ originaltexcoordlightmap2f = out->data_texcoordlightmap2f;
+ //originalelement3i = out->data_element3i;
+ //originalneighbor3i = out->data_neighbor3i;
+ out->data_vertex3f = Mem_Alloc(loadmodel->mempool, sizeof(float[20]) * finalvertices + sizeof(int[6]) * finaltriangles);
+ out->data_svector3f = out->data_vertex3f + finalvertices * 3;
+ out->data_tvector3f = out->data_svector3f + finalvertices * 3;
+ out->data_normal3f = out->data_tvector3f + finalvertices * 3;
+ out->data_color4f = out->data_normal3f + finalvertices * 3;
+ out->data_texcoordtexture2f = out->data_color4f + finalvertices * 4;
+ out->data_texcoordlightmap2f = out->data_texcoordtexture2f + finalvertices * 2;
+ out->data_element3i = (int *)(out->data_texcoordlightmap2f + finalvertices * 2);
+ out->data_neighbor3i = out->data_element3i + finaltriangles * 3;
+ out->type = Q3FACETYPE_MESH;
+ out->firstvertex = -1;
+ out->numvertices = finalvertices;
+ out->firstelement = -1;
+ out->numtriangles = finaltriangles;
+ out->numelements = finaltriangles * 3;
+ // generate geometry
+ // (note: normals are skipped because they get recalculated)
+ QuadraticSplinePatchSubdivideFloatBuffer(patchsize[0], patchsize[1], xlevel, ylevel, 3, originalvertex3f, out->data_vertex3f);
+ QuadraticSplinePatchSubdivideFloatBuffer(patchsize[0], patchsize[1], xlevel, ylevel, 2, originaltexcoordtexture2f, out->data_texcoordtexture2f);
+ QuadraticSplinePatchSubdivideFloatBuffer(patchsize[0], patchsize[1], xlevel, ylevel, 2, originaltexcoordlightmap2f, out->data_texcoordlightmap2f);
+ QuadraticSplinePatchSubdivideFloatBuffer(patchsize[0], patchsize[1], xlevel, ylevel, 4, originalcolor4f, out->data_color4f);
+ // generate elements
+ e = out->data_element3i;
+ for (y = 0;y < finalheight - 1;y++)
+ {
+ row0 = (y + 0) * finalwidth;
+ row1 = (y + 1) * finalwidth;
+ for (x = 0;x < finalwidth - 1;x++)
+ {
+ *e++ = row0;
+ *e++ = row1;
+ *e++ = row0 + 1;
+ *e++ = row1;
+ *e++ = row1 + 1;
+ *e++ = row0 + 1;
+ row0++;
+ row1++;
+ }
+ }
+ out->numtriangles = Mod_RemoveDegenerateTriangles(out->numtriangles, out->data_element3i, out->data_element3i, out->data_vertex3f);
+ if (developer.integer)
+ {
+ if (out->numtriangles < finaltriangles)
+ Con_Printf("Mod_Q3BSP_LoadFaces: %ix%i curve subdivided to %i vertices / %i triangles, %i degenerate triangles removed (leaving %i)\n", patchsize[0], patchsize[1], out->numvertices, finaltriangles, finaltriangles - out->numtriangles, out->numtriangles);
+ else
+ Con_Printf("Mod_Q3BSP_LoadFaces: %ix%i curve subdivided to %i vertices / %i triangles\n", patchsize[0], patchsize[1], out->numvertices, out->numtriangles);
+ }
+ // q3map does not put in collision brushes for curves... ugh
+ out->collisions = true;
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;
+ Con_DPrintf("Mod_Q3BSP_LoadFaces: face #%i (texture \"%s\"): Q3FACETYPE_FLARE not supported (yet)\n", i, out->texture->name);
+ // don't render it
+ out->numtriangles = 0;
break;
}
for (j = 0, invalidelements = 0;j < out->numelements;j++)
}
Con_Printf("\n");
}
+ // for shadow volumes
+ Mod_BuildTriangleNeighbors(out->data_neighbor3i, out->data_element3i, out->numtriangles);
+ // for per pixel lighting
+ Mod_BuildTextureVectorsAndNormals(out->numvertices, out->numtriangles, out->data_vertex3f, out->data_texcoordtexture2f, out->data_element3i, out->data_svector3f, out->data_tvector3f, out->data_normal3f);
+ // calculate a bounding box
+ VectorClear(out->mins);
+ VectorClear(out->maxs);
+ if (out->numvertices)
+ {
+ VectorCopy(out->data_vertex3f, out->mins);
+ VectorCopy(out->data_vertex3f, out->maxs);
+ for (j = 1, v = out->data_vertex3f + 3;j < out->numvertices;j++, v += 3)
+ {
+ out->mins[0] = min(out->mins[0], v[0]);
+ out->maxs[0] = max(out->maxs[0], v[0]);
+ out->mins[1] = min(out->mins[1], v[1]);
+ out->maxs[1] = max(out->maxs[1], v[1]);
+ out->mins[2] = min(out->mins[2], v[2]);
+ out->maxs[2] = max(out->maxs[2], v[2]);
+ }
+ out->mins[0] -= 1.0f;
+ out->mins[1] -= 1.0f;
+ out->mins[2] -= 1.0f;
+ out->maxs[0] += 1.0f;
+ out->maxs[1] += 1.0f;
+ out->maxs[2] += 1.0f;
+ }
}
}
static void Mod_Q3BSP_TraceLine_RecursiveBSPNode(trace_t *trace, q3mnode_t *node, const vec3_t start, const vec3_t end, vec_t startfrac, vec_t endfrac, const vec3_t linestart, const vec3_t lineend, int markframe)
{
int i, startside, endside;
- float dist1, dist2, midfrac, mid[3];
+ float dist1, dist2, midfrac, mid[3], segmentmins[3], segmentmaxs[3];
q3mleaf_t *leaf;
+ q3mface_t *face;
+ colbrushf_t *brush;
+ if (startfrac >= trace->fraction)
+ return;
// note: all line fragments past first impact fraction are ignored
while (node->isnode)
{
}
else
{
+ // line crosses node plane, split the line
+ midfrac = dist1 / (dist1 - dist2);
+ VectorLerp(linestart, midfrac, lineend, mid);
// take the near side first
- if (startfrac < trace->fraction)
- {
- // line crosses node plane, split the line
- midfrac = dist1 / (dist1 - dist2);
- VectorLerp(linestart, midfrac, lineend, mid);
- Mod_Q3BSP_TraceLine_RecursiveBSPNode(trace, node->children[startside], start, mid, startfrac, midfrac, linestart, lineend, markframe);
- if (midfrac < trace->fraction)
- Mod_Q3BSP_TraceLine_RecursiveBSPNode(trace, node->children[endside], mid, end, midfrac, endfrac, linestart, lineend, markframe);
- }
+ Mod_Q3BSP_TraceLine_RecursiveBSPNode(trace, node->children[startside], start, mid, startfrac, midfrac, linestart, lineend, markframe);
+ if (midfrac < trace->fraction)
+ Mod_Q3BSP_TraceLine_RecursiveBSPNode(trace, node->children[endside], mid, end, midfrac, endfrac, linestart, lineend, markframe);
return;
}
}
// hit a leaf
+ segmentmins[0] = min(start[0], end[0]);
+ segmentmins[1] = min(start[1], end[1]);
+ segmentmins[2] = min(start[2], end[2]);
+ segmentmaxs[0] = max(start[0], end[0]);
+ segmentmaxs[1] = max(start[1], end[1]);
+ segmentmaxs[2] = max(start[2], end[2]);
leaf = (q3mleaf_t *)node;
for (i = 0;i < leaf->numleafbrushes;i++)
{
- if (endfrac >= trace->fraction)
+ if (startfrac >= trace->fraction)
return;
- if (leaf->firstleafbrush[i]->colbrushf && leaf->firstleafbrush[i]->colbrushf->markframe != markframe)
+ brush = leaf->firstleafbrush[i]->colbrushf;
+ if (brush && brush->markframe != markframe)
+ {
+ brush->markframe = markframe;
+ if (BoxesOverlap(segmentmins, segmentmaxs, brush->mins, brush->maxs))
+ Collision_TraceLineBrushFloat(trace, linestart, lineend, leaf->firstleafbrush[i]->colbrushf, leaf->firstleafbrush[i]->colbrushf);
+ }
+ }
+ if (mod_q3bsp_curves_collisions.integer)
+ {
+ for (i = 0;i < leaf->numleaffaces;i++)
{
- leaf->firstleafbrush[i]->colbrushf->markframe = markframe;
- Collision_TraceLineBrushFloat(trace, linestart, lineend, leaf->firstleafbrush[i]->colbrushf, leaf->firstleafbrush[i]->colbrushf);
+ if (startfrac >= trace->fraction)
+ return;
+ face = leaf->firstleafface[i];
+ if (face->collisions && face->collisionmarkframe != markframe)
+ {
+ face->collisionmarkframe = markframe;
+ if (BoxesOverlap(segmentmins, segmentmaxs, face->mins, face->maxs))
+ Collision_TraceLineTriangleMeshFloat(trace, linestart, lineend, face->numtriangles, face->data_element3i, face->data_vertex3f, face->texture->supercontents, segmentmins, segmentmaxs);
+ }
}
}
}
-static void Mod_Q3BSP_TraceBrush_RecursiveBSPNode(trace_t *trace, q3mnode_t *node, const colbrushf_t *thisbrush_start, const colbrushf_t *thisbrush_end, int markframe)
+static void Mod_Q3BSP_TraceBrush_RecursiveBSPNode(trace_t *trace, q3mnode_t *node, const colbrushf_t *thisbrush_start, const colbrushf_t *thisbrush_end, int markframe, const vec3_t segmentmins, const vec3_t segmentmaxs)
{
- int i;
- float dist;
- colpointf_t *ps, *pe;
+ int i, sides;
+ float nodesegmentmins[3], nodesegmentmaxs[3];
q3mleaf_t *leaf;
+ colbrushf_t *brush;
+ q3mface_t *face;
+ nodesegmentmins[0] = max(segmentmins[0], node->mins[0]);
+ nodesegmentmins[1] = max(segmentmins[1], node->mins[1]);
+ nodesegmentmins[2] = max(segmentmins[2], node->mins[2]);
+ nodesegmentmaxs[0] = min(segmentmaxs[0], node->maxs[0]);
+ nodesegmentmaxs[1] = min(segmentmaxs[1], node->maxs[1]);
+ nodesegmentmaxs[2] = min(segmentmaxs[2], node->maxs[2]);
+ if (nodesegmentmins[0] > nodesegmentmaxs[0] || nodesegmentmins[1] > nodesegmentmaxs[1] || nodesegmentmins[2] > nodesegmentmaxs[2])
+ return;
if (node->isnode)
{
// recurse down node sides
+ sides = BoxOnPlaneSide(segmentmins, segmentmaxs, node->plane);
+ if (sides == 3)
+ {
+ Mod_Q3BSP_TraceBrush_RecursiveBSPNode(trace, node->children[0], thisbrush_start, thisbrush_end, markframe, nodesegmentmins, nodesegmentmaxs);
+ Mod_Q3BSP_TraceBrush_RecursiveBSPNode(trace, node->children[1], thisbrush_start, thisbrush_end, markframe, nodesegmentmins, nodesegmentmaxs);
+ }
+ else if (sides == 2)
+ Mod_Q3BSP_TraceBrush_RecursiveBSPNode(trace, node->children[1], thisbrush_start, thisbrush_end, markframe, segmentmins, segmentmaxs);
+ else // sides == 1
+ Mod_Q3BSP_TraceBrush_RecursiveBSPNode(trace, node->children[0], thisbrush_start, thisbrush_end, markframe, segmentmins, segmentmaxs);
+ /*
dist = node->plane->dist - (1.0f / 8.0f);
for (i = 0, ps = thisbrush_start->points, pe = thisbrush_end->points;i < thisbrush_start->numpoints;i++, ps++, pe++)
{
if (DotProduct(ps->v, node->plane->normal) >= dist || DotProduct(pe->v, node->plane->normal) >= dist)
{
- Mod_Q3BSP_TraceBrush_RecursiveBSPNode(trace, node->children[0], thisbrush_start, thisbrush_end, markframe);
+ Mod_Q3BSP_TraceBrush_RecursiveBSPNode(trace, node->children[0], thisbrush_start, thisbrush_end, markframe, nodesegmentmins, nodesegmentmaxs);
break;
}
}
+ */
+ /*
dist = node->plane->dist + (1.0f / 8.0f);
for (i = 0, ps = thisbrush_start->points, pe = thisbrush_end->points;i < thisbrush_start->numpoints;i++, ps++, pe++)
{
if (DotProduct(ps->v, node->plane->normal) <= dist || DotProduct(pe->v, node->plane->normal) <= dist)
{
- Mod_Q3BSP_TraceBrush_RecursiveBSPNode(trace, node->children[1], thisbrush_start, thisbrush_end, markframe);
+ Mod_Q3BSP_TraceBrush_RecursiveBSPNode(trace, node->children[1], thisbrush_start, thisbrush_end, markframe, nodesegmentmins, nodesegmentmaxs);
break;
}
}
+ */
/*
sides = BoxOnPlaneSide(boxstartmins, boxstartmaxs, node->plane) | BoxOnPlaneSide(boxendmins, boxendmaxs, node->plane);
if (sides & 1)
leaf = (q3mleaf_t *)node;
for (i = 0;i < leaf->numleafbrushes;i++)
{
- if (leaf->firstleafbrush[i]->colbrushf && leaf->firstleafbrush[i]->colbrushf->markframe != markframe)
+ brush = leaf->firstleafbrush[i]->colbrushf;
+ if (brush && brush->markframe != markframe && BoxesOverlap(nodesegmentmins, nodesegmentmaxs, brush->mins, brush->maxs))
{
- leaf->firstleafbrush[i]->colbrushf->markframe = markframe;
+ brush->markframe = markframe;
Collision_TraceBrushBrushFloat(trace, thisbrush_start, thisbrush_end, leaf->firstleafbrush[i]->colbrushf, leaf->firstleafbrush[i]->colbrushf);
}
}
+ if (mod_q3bsp_curves_collisions.integer)
+ {
+ for (i = 0;i < leaf->numleaffaces;i++)
+ {
+ face = leaf->firstleafface[i];
+ // note: this can not be optimized with a face->collisionmarkframe because each triangle of the face would need to be marked as done individually (because each one is bbox culled individually), and if all are marked, then the face could be marked as done
+ if (face->collisions && BoxesOverlap(nodesegmentmins, nodesegmentmaxs, face->mins, face->maxs))
+ Collision_TraceBrushTriangleMeshFloat(trace, thisbrush_start, thisbrush_end, face->numtriangles, face->data_element3i, face->data_vertex3f, face->texture->supercontents, segmentmins, segmentmaxs);
+ }
+ }
}
}
static void Mod_Q3BSP_TraceBox(model_t *model, trace_t *trace, const vec3_t boxstartmins, const vec3_t boxstartmaxs, const vec3_t boxendmins, const vec3_t boxendmaxs, int hitsupercontentsmask)
{
int i;
+ float segmentmins[3], segmentmaxs[3];
colbrushf_t *thisbrush_start, *thisbrush_end;
matrix4x4_t startmatrix, endmatrix;
static int markframe = 0;
+ q3mface_t *face;
memset(trace, 0, sizeof(*trace));
trace->fraction = 1;
trace->hitsupercontentsmask = hitsupercontentsmask;
Matrix4x4_CreateIdentity(&startmatrix);
Matrix4x4_CreateIdentity(&endmatrix);
- if (VectorCompare(boxstartmins, boxstartmaxs) && VectorCompare(boxendmins, boxendmaxs))
+ segmentmins[0] = min(boxstartmins[0], boxendmins[0]);
+ segmentmins[1] = min(boxstartmins[1], boxendmins[1]);
+ segmentmins[2] = min(boxstartmins[2], boxendmins[2]);
+ segmentmaxs[0] = max(boxstartmaxs[0], boxendmaxs[0]);
+ segmentmaxs[1] = max(boxstartmaxs[1], boxendmaxs[1]);
+ segmentmaxs[2] = max(boxstartmaxs[2], boxendmaxs[2]);
+ if (mod_q3bsp_optimizedtraceline.integer && VectorCompare(boxstartmins, boxstartmaxs) && VectorCompare(boxendmins, boxendmaxs))
{
// line trace
if (model->brushq3.submodel)
for (i = 0;i < model->brushq3.data_thismodel->numbrushes;i++)
if (model->brushq3.data_thismodel->firstbrush[i].colbrushf)
Collision_TraceLineBrushFloat(trace, boxstartmins, boxendmins, model->brushq3.data_thismodel->firstbrush[i].colbrushf, model->brushq3.data_thismodel->firstbrush[i].colbrushf);
+ if (mod_q3bsp_curves_collisions.integer)
+ {
+ for (i = 0;i < model->brushq3.data_thismodel->numfaces;i++)
+ {
+ face = model->brushq3.data_thismodel->firstface + i;
+ if (face->collisions)
+ Collision_TraceLineTriangleMeshFloat(trace, boxstartmins, boxendmins, face->numtriangles, face->data_element3i, face->data_vertex3f, face->texture->supercontents, segmentmins, segmentmaxs);
+ }
+ }
}
else
Mod_Q3BSP_TraceLine_RecursiveBSPNode(trace, model->brushq3.data_nodes, boxstartmins, boxendmins, 0, 1, boxstartmins, boxendmins, ++markframe);
}
else
{
- // box trace, performed as box trace
+ // box trace, performed as brush trace
thisbrush_start = Collision_BrushForBox(&startmatrix, boxstartmins, boxstartmaxs);
thisbrush_end = Collision_BrushForBox(&endmatrix, boxendmins, boxendmaxs);
if (model->brushq3.submodel)
for (i = 0;i < model->brushq3.data_thismodel->numbrushes;i++)
if (model->brushq3.data_thismodel->firstbrush[i].colbrushf)
Collision_TraceBrushBrushFloat(trace, thisbrush_start, thisbrush_end, model->brushq3.data_thismodel->firstbrush[i].colbrushf, model->brushq3.data_thismodel->firstbrush[i].colbrushf);
+ if (mod_q3bsp_curves_collisions.integer)
+ {
+ for (i = 0;i < model->brushq3.data_thismodel->numfaces;i++)
+ {
+ face = model->brushq3.data_thismodel->firstface + i;
+ if (face->collisions)
+ Collision_TraceBrushTriangleMeshFloat(trace, thisbrush_start, thisbrush_end, face->numtriangles, face->data_element3i, face->data_vertex3f, face->texture->supercontents, segmentmins, segmentmaxs);
+ }
+ }
}
else
- Mod_Q3BSP_TraceBrush_RecursiveBSPNode(trace, model->brushq3.data_nodes, thisbrush_start, thisbrush_end, ++markframe);
+ Mod_Q3BSP_TraceBrush_RecursiveBSPNode(trace, model->brushq3.data_nodes, thisbrush_start, thisbrush_end, ++markframe, segmentmins, segmentmaxs);
}
}
}
//Returns PVS data for a given point
-//(note: always returns valid data, never NULL)
+//(note: can return NULL)
static qbyte *Mod_Q3BSP_GetPVS(model_t *model, const vec3_t p)
{
q3mnode_t *node;
node = model->brushq3.data_nodes;
while (node->isnode)
node = node->children[(node->plane->type < 3 ? p[node->plane->type] : DotProduct(p,node->plane->normal)) < node->plane->dist];
- return model->brushq3.data_pvschains + ((q3mleaf_t *)node)->clusterindex * model->brushq3.num_pvschainlength;
+ if (((q3mleaf_t *)node)->clusterindex >= 0)
+ return model->brushq3.data_pvschains + ((q3mleaf_t *)node)->clusterindex * model->brushq3.num_pvschainlength;
+ else
+ return NULL;
}
static void Mod_Q3BSP_FatPVS_RecursiveBSPNode(model_t *model, const vec3_t org, vec_t radius, qbyte *pvsbuffer, int pvsbytes, q3mnode_t *node)
node = node->children[1];
}
}
- // if this is a leaf, accumulate the pvs bits
- pvs = model->brushq3.data_pvschains + ((q3mleaf_t *)node)->clusterindex * model->brushq3.num_pvschainlength;
- for (i = 0;i < pvsbytes;i++)
- pvsbuffer[i] |= pvs[i];
+ // if this is a leaf with a pvs, accumulate the pvs bits
+ if (((q3mleaf_t *)node)->clusterindex >= 0)
+ {
+ pvs = model->brushq3.data_pvschains + ((q3mleaf_t *)node)->clusterindex * model->brushq3.num_pvschainlength;
+ for (i = 0;i < pvsbytes;i++)
+ pvsbuffer[i] |= pvs[i];
+ }
return;
}
//extern void R_Q3BSP_DrawSky(struct entity_render_s *ent);
extern void R_Q3BSP_Draw(struct entity_render_s *ent);
//extern void R_Q3BSP_DrawFakeShadow(struct entity_render_s *ent);
-//extern void R_Q3BSP_DrawShadowVolume(struct entity_render_s *ent, vec3_t relativelightorigin, float lightradius);
-//extern void R_Q3BSP_DrawLight(struct entity_render_s *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);
+extern void R_Q3BSP_DrawShadowVolume(struct entity_render_s *ent, vec3_t relativelightorigin, float lightradius);
+extern void R_Q3BSP_DrawLight(struct entity_render_s *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_Q3BSP_Load(model_t *mod, void *buffer)
{
int i;
float corner[3], yawradius, modelradius;
mod->type = mod_brushq3;
+ mod->numframes = 1;
+ mod->numskins = 1;
header = (q3dheader_t *)buffer;
//mod->DrawSky = R_Q3BSP_DrawSky;
mod->Draw = R_Q3BSP_Draw;
//mod->DrawFakeShadow = R_Q3BSP_DrawFakeShadow;
- //mod->DrawShadowVolume = R_Q3BSP_DrawShadowVolume;
- //mod->DrawLight = R_Q3BSP_DrawLight;
+ mod->DrawShadowVolume = R_Q3BSP_DrawShadowVolume;
+ mod->DrawLight = R_Q3BSP_DrawLight;
mod_base = (qbyte *)header;