cvar_t r_nosurftextures = {0, "r_nosurftextures", "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"};
+cvar_t mod_q3bsp_optimizedtraceline = {0, "mod_q3bsp_optimizedtraceline", "0"};
+static void Mod_Q1BSP_Collision_Init (void);
void Mod_BrushInit(void)
{
// Cvar_RegisterVariable(&r_subdivide_size);
Cvar_RegisterVariable(&mod_q3bsp_curves_collisions);
Cvar_RegisterVariable(&mod_q3bsp_optimizedtraceline);
memset(mod_q1bsp_novis, 0xff, sizeof(mod_q1bsp_novis));
+ Mod_Q1BSP_Collision_Init();
}
static mleaf_t *Mod_Q1BSP_PointInLeaf(model_t *model, const vec3_t p)
float surfnormal[3];
#endif
msurface_t *surf;
- surfmesh_t *mesh;
for (surfnum = 0, mark = leaf->firstmarksurface;surfnum < leaf->nummarksurfaces;surfnum++, mark++)
{
surf = info->model->brushq1.surfaces + *mark;
if (surf->flags & SURF_PLANEBACK)
VectorNegate(surfnormal, surfnormal);
#endif
- for (mesh = surf->mesh;mesh;mesh = mesh->chain)
+ for (k = 0;k < surf->mesh.num_triangles;k++)
{
- for (k = 0;k < mesh->numtriangles;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]);
+ 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])
{
- 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)
{
- VectorNormalize(facenormal);
+ 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 (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]);
+ 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
- f = DotProduct(info->center, facenormal) - DotProduct(vert[0], facenormal);
- if (f <= info->bestdist && f >= -info->bestdist)
+ // 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]))
{
- 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]);
+ // 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++)
- 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)
+ f = DotProduct(info->center, edge[i]);
+ if (f >= DotProduct(vert[0], edge[i])
+ && f <= DotProduct(vert[1], edge[i]))
{
- dist = -dist;
+ // on edge
+ VectorMA(info->center, -f, edge[i], point);
+ dist = sqrt(DotProduct(point, point));
if (info->bestdist > dist)
{
info->bestdist = dist;
- VectorScale(facenormal, (info->radius - -dist), info->nudge);
+ 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(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);
- }
+ VectorScale(point, (info->radius / dist), info->nudge);
}
}
}
// if the first leaf is solid, set startsolid
if (t->trace->allsolid)
t->trace->startsolid = true;
+#if COLLISIONPARANOID >= 3
+ Con_Printf("S");
+#endif
return HULLCHECKSTATE_SOLID;
}
else
{
t->trace->allsolid = false;
+#if COLLISIONPARANOID >= 3
+ Con_Printf("E");
+#endif
return HULLCHECKSTATE_EMPTY;
}
}
{
if (t2 < 0)
{
+#if COLLISIONPARANOID >= 3
+ Con_Printf("<");
+#endif
num = node->children[1];
goto loc0;
}
{
if (t2 >= 0)
{
+#if COLLISIONPARANOID >= 3
+ Con_Printf(">");
+#endif
num = node->children[0];
goto loc0;
}
// the line intersects, find intersection point
// LordHavoc: this uses the original trace for maximum accuracy
+#if COLLISIONPARANOID >= 3
+ Con_Printf("M");
+#endif
if (plane->type < 3)
{
t1 = t->start[plane->type] - plane->dist;
midf = t1 / (t1 - t2);
t->trace->fraction = bound(0.0f, midf, 1.0);
+#if COLLISIONPARANOID >= 3
+ Con_Printf("D");
+#endif
return HULLCHECKSTATE_DONE;
}
-static void Mod_Q1BSP_TraceBox(struct model_s *model, trace_t *trace, const vec3_t boxstartmins, const vec3_t boxstartmaxs, const vec3_t boxendmins, const vec3_t boxendmaxs, int hitsupercontentsmask)
+#if COLLISIONPARANOID < 2
+static int Mod_Q1BSP_RecursiveHullCheckPoint(RecursiveHullCheckTraceInfo_t *t, int num)
+{
+ while (num >= 0)
+ num = t->hull->clipnodes[num].children[(t->hull->planes[t->hull->clipnodes[num].planenum].type < 3 ? t->start[t->hull->planes[t->hull->clipnodes[num].planenum].type] : DotProduct(t->hull->planes[t->hull->clipnodes[num].planenum].normal, t->start)) < t->hull->planes[t->hull->clipnodes[num].planenum].dist];
+ num = Mod_Q1BSP_SuperContentsFromNativeContents(NULL, num);
+ t->trace->startsupercontents |= num;
+ if (num & SUPERCONTENTS_LIQUIDSMASK)
+ t->trace->inwater = true;
+ if (num == 0)
+ t->trace->inopen = true;
+ if (num & t->trace->hitsupercontentsmask)
+ {
+ t->trace->allsolid = t->trace->startsolid = true;
+ return HULLCHECKSTATE_SOLID;
+ }
+ else
+ {
+ t->trace->allsolid = t->trace->startsolid = false;
+ return HULLCHECKSTATE_EMPTY;
+ }
+}
+#endif
+
+static void Mod_Q1BSP_TraceBox(struct model_s *model, int frame, trace_t *trace, const vec3_t boxstartmins, const vec3_t boxstartmaxs, const vec3_t boxendmins, const vec3_t boxendmaxs, int hitsupercontentsmask)
{
// this function currently only supports same size start and end
double boxsize[3];
rhc.hull = &model->brushq1.hulls[0]; // 0x0x0
else if (model->brush.ishlbsp)
{
- if (boxsize[0] <= 32)
+ // LordHavoc: this has to have a minor tolerance (the .1) because of
+ // minor float precision errors from the box being transformed around
+ if (boxsize[0] < 32.1)
{
if (boxsize[2] < 54) // pick the nearest of 36 or 72
rhc.hull = &model->brushq1.hulls[3]; // 32x32x36
}
else
{
- if (boxsize[0] <= 32)
+ // LordHavoc: this has to have a minor tolerance (the .1) because of
+ // minor float precision errors from the box being transformed around
+ if (boxsize[0] < 32.1)
rhc.hull = &model->brushq1.hulls[1]; // 32x32x56
else
rhc.hull = &model->brushq1.hulls[2]; // 64x64x88
VectorSubtract(boxstartmins, rhc.hull->clip_mins, rhc.start);
VectorSubtract(boxendmins, rhc.hull->clip_mins, rhc.end);
VectorSubtract(rhc.end, rhc.start, rhc.dist);
+#if COLLISIONPARANOID >= 2
+ Con_Printf("t(%f %f %f,%f %f %f,%i %f %f %f)", rhc.start[0], rhc.start[1], rhc.start[2], rhc.end[0], rhc.end[1], rhc.end[2], rhc.hull - model->brushq1.hulls, rhc.hull->clip_mins[0], rhc.hull->clip_mins[1], rhc.hull->clip_mins[2]);
Mod_Q1BSP_RecursiveHullCheck(&rhc, rhc.hull->firstclipnode, 0, 1, rhc.start, rhc.end);
+ Con_Printf("\n");
+#else
+ if (DotProduct(rhc.dist, rhc.dist))
+ Mod_Q1BSP_RecursiveHullCheck(&rhc, rhc.hull->firstclipnode, 0, 1, rhc.start, rhc.end);
+ else
+ Mod_Q1BSP_RecursiveHullCheckPoint(&rhc, rhc.hull->firstclipnode);
+#endif
+}
+
+static hull_t box_hull;
+static dclipnode_t box_clipnodes[6];
+static mplane_t box_planes[6];
+
+static void Mod_Q1BSP_Collision_Init (void)
+{
+ int i;
+ int side;
+
+ //Set up the planes and clipnodes so that the six floats of a bounding box
+ //can just be stored out and get a proper hull_t structure.
+
+ box_hull.clipnodes = box_clipnodes;
+ box_hull.planes = box_planes;
+ box_hull.firstclipnode = 0;
+ box_hull.lastclipnode = 5;
+
+ for (i = 0;i < 6;i++)
+ {
+ box_clipnodes[i].planenum = i;
+
+ side = i&1;
+
+ box_clipnodes[i].children[side] = CONTENTS_EMPTY;
+ if (i != 5)
+ box_clipnodes[i].children[side^1] = i + 1;
+ else
+ box_clipnodes[i].children[side^1] = CONTENTS_SOLID;
+
+ box_planes[i].type = i>>1;
+ box_planes[i].normal[i>>1] = 1;
+ }
+}
+
+void Collision_ClipTrace_Box(trace_t *trace, const vec3_t cmins, const vec3_t cmaxs, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int hitsupercontentsmask, int boxsupercontents)
+{
+#if 1
+ colbrushf_t cbox;
+ colplanef_t cbox_planes[6];
+ cbox.supercontents = boxsupercontents;
+ cbox.numplanes = 6;
+ cbox.numpoints = 0;
+ cbox.numtriangles = 0;
+ cbox.planes = cbox_planes;
+ cbox.points = NULL;
+ cbox.elements = NULL;
+ cbox.markframe = 0;
+ cbox.mins[0] = 0;
+ cbox.mins[1] = 0;
+ cbox.mins[2] = 0;
+ cbox.maxs[0] = 0;
+ cbox.maxs[1] = 0;
+ cbox.maxs[2] = 0;
+ cbox_planes[0].normal[0] = 1;cbox_planes[0].normal[1] = 0;cbox_planes[0].normal[2] = 0;cbox_planes[0].dist = cmaxs[0] - mins[0];
+ cbox_planes[1].normal[0] = -1;cbox_planes[1].normal[1] = 0;cbox_planes[1].normal[2] = 0;cbox_planes[1].dist = maxs[0] - cmins[0];
+ cbox_planes[2].normal[0] = 0;cbox_planes[2].normal[1] = 1;cbox_planes[2].normal[2] = 0;cbox_planes[2].dist = cmaxs[1] - mins[1];
+ cbox_planes[3].normal[0] = 0;cbox_planes[3].normal[1] = -1;cbox_planes[3].normal[2] = 0;cbox_planes[3].dist = maxs[1] - cmins[1];
+ cbox_planes[4].normal[0] = 0;cbox_planes[4].normal[1] = 0;cbox_planes[4].normal[2] = 1;cbox_planes[4].dist = cmaxs[2] - mins[2];
+ cbox_planes[5].normal[0] = 0;cbox_planes[5].normal[1] = 0;cbox_planes[5].normal[2] = -1;cbox_planes[5].dist = maxs[2] - cmins[2];
+ memset(trace, 0, sizeof(trace_t));
+ trace->hitsupercontentsmask = hitsupercontentsmask;
+ trace->fraction = 1;
+ Collision_TraceLineBrushFloat(trace, start, end, &cbox, &cbox);
+#else
+ RecursiveHullCheckTraceInfo_t rhc;
+ // fill in a default trace
+ memset(&rhc, 0, sizeof(rhc));
+ memset(trace, 0, sizeof(trace_t));
+ //To keep everything totally uniform, bounding boxes are turned into small
+ //BSP trees instead of being compared directly.
+ // create a temp hull from bounding box sizes
+ box_planes[0].dist = cmaxs[0] - mins[0];
+ box_planes[1].dist = cmins[0] - maxs[0];
+ box_planes[2].dist = cmaxs[1] - mins[1];
+ box_planes[3].dist = cmins[1] - maxs[1];
+ box_planes[4].dist = cmaxs[2] - mins[2];
+ box_planes[5].dist = cmins[2] - maxs[2];
+#if COLLISIONPARANOID >= 3
+ Con_Printf("box_planes %f:%f %f:%f %f:%f\ncbox %f %f %f:%f %f %f\nbox %f %f %f:%f %f %f\n", box_planes[0].dist, box_planes[1].dist, box_planes[2].dist, box_planes[3].dist, box_planes[4].dist, box_planes[5].dist, cmins[0], cmins[1], cmins[2], cmaxs[0], cmaxs[1], cmaxs[2], mins[0], mins[1], mins[2], maxs[0], maxs[1], maxs[2]);
+#endif
+ // trace a line through the generated clipping hull
+ //rhc.boxsupercontents = boxsupercontents;
+ rhc.hull = &box_hull;
+ rhc.trace = trace;
+ rhc.trace->hitsupercontentsmask = hitsupercontentsmask;
+ rhc.trace->fraction = 1;
+ rhc.trace->allsolid = true;
+ VectorCopy(start, rhc.start);
+ VectorCopy(end, rhc.end);
+ VectorSubtract(rhc.end, rhc.start, rhc.dist);
+ Mod_Q1BSP_RecursiveHullCheck(&rhc, rhc.hull->firstclipnode, 0, 1, rhc.start, rhc.end);
+ VectorMA(rhc.start, rhc.trace->fraction, rhc.dist, rhc.trace->endpos);
+ if (rhc.trace->startsupercontents)
+ rhc.trace->startsupercontents = boxsupercontents;
+#endif
}
static int Mod_Q1BSP_LightPoint_RecursiveBSPNode(vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffusenormal, const mnode_t *node, float x, float y, float startz, float endz)
{
if (in == inend)
{
- Con_Printf("Mod_Q1BSP_DecompressVis: input underrun\n");
+ Con_DPrintf("Mod_Q1BSP_DecompressVis: input underrun on model \"%s\"\n", loadmodel->name);
return;
}
c = *in++;
*out++ = c;
else
{
+ if (in == inend)
+ {
+ Con_DPrintf("Mod_Q1BSP_DecompressVis: input underrun on model \"%s\"\n", loadmodel->name);
+ return;
+ }
for (c = *in++;c > 0;c--)
{
if (out == outend)
{
- Con_Printf("Mod_Q1BSP_DecompressVis: output overrun\n");
+ Con_DPrintf("Mod_Q1BSP_DecompressVis: output overrun on model \"%s\"\n", loadmodel->name);
return;
}
*out++ = 0;
else // LordHavoc: bsp version 29 (normal white lighting)
{
// LordHavoc: hope is not lost yet, check for a .lit file to load
- strcpy(litfilename, loadmodel->name);
- FS_StripExtension(litfilename, litfilename);
- strcat(litfilename, ".lit");
+ strlcpy (litfilename, loadmodel->name, sizeof (litfilename));
+ FS_StripExtension (litfilename, litfilename, sizeof (litfilename));
+ strlcat (litfilename, ".lit", sizeof (litfilename));
data = (qbyte*) FS_LoadFile(litfilename, false);
if (data)
{
char lightsfilename[1024], *s, *t, *lightsstring;
mlight_t *e;
- strcpy(lightsfilename, loadmodel->name);
- FS_StripExtension(lightsfilename, lightsfilename);
- strcat(lightsfilename, ".lights");
+ strlcpy (lightsfilename, loadmodel->name, sizeof (lightsfilename));
+ FS_StripExtension (lightsfilename, lightsfilename, sizeof(lightsfilename));
+ strlcat (lightsfilename, ".lights", sizeof (lightsfilename));
s = lightsstring = (char *) FS_LoadFile(lightsfilename, false);
if (s)
{
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));
- mesh->numverts = subdivpolyverts;
- mesh->numtriangles = subdivpolytriangles;
+ mesh->num_vertices = subdivpolyverts;
+ mesh->num_triangles = subdivpolytriangles;
mesh->vertex = (surfvertex_t *)(mesh + 1);
- mesh->index = (int *)(mesh->vertex + mesh->numverts);
- memset(mesh->vertex, 0, mesh->numverts * sizeof(surfvertex_t));
+ mesh->index = (int *)(mesh->vertex + mesh->num_vertices);
+ memset(mesh->vertex, 0, mesh->num_vertices * sizeof(surfvertex_t));
- for (i = 0;i < mesh->numtriangles;i++)
+ for (i = 0;i < mesh->num_triangles;i++)
for (j = 0;j < 3;j++)
mesh->index[i*3+j] = subdivpolyindex[i][j];
{
surfmesh_t *mesh;
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->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;
+ mesh->num_vertices = numverts;
+ mesh->num_triangles = numtriangles;
+ mesh->data_vertex3f = (float *)(mesh + 1);
+ mesh->data_texcoordtexture2f = mesh->data_vertex3f + mesh->num_vertices * 3;
+ mesh->data_texcoordlightmap2f = mesh->data_texcoordtexture2f + mesh->num_vertices * 2;
+ mesh->data_texcoorddetail2f = mesh->data_texcoordlightmap2f + mesh->num_vertices * 2;
+ mesh->data_svector3f = (float *)(mesh->data_texcoorddetail2f + mesh->num_vertices * 2);
+ mesh->data_tvector3f = mesh->data_svector3f + mesh->num_vertices * 3;
+ mesh->data_normal3f = mesh->data_tvector3f + mesh->num_vertices * 3;
+ mesh->data_lightmapoffsets = (int *)(mesh->data_normal3f + mesh->num_vertices * 3);
+ mesh->data_element3i = mesh->data_lightmapoffsets + mesh->num_vertices;
+ mesh->data_neighbor3i = mesh->data_element3i + mesh->num_triangles * 3;
return mesh;
}
}
loadmodel->brushq1.entiremesh = Mod_Q1BSP_AllocSurfMesh(totalverts, totaltris);
- loadmodel->brushq1.surfmeshes = Mem_Alloc(loadmodel->mempool, sizeof(surfmesh_t) * totalmeshes);
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 = loadmodel->brushq1.surfmeshes + totalmeshes;
- mesh->numverts = surf->poly_numverts;
- mesh->numtriangles = surf->poly_numverts - 2;
- mesh->vertex3f = loadmodel->brushq1.entiremesh->vertex3f + totalverts * 3;
- mesh->texcoordtexture2f = loadmodel->brushq1.entiremesh->texcoordtexture2f + totalverts * 2;
- mesh->texcoordlightmap2f = loadmodel->brushq1.entiremesh->texcoordlightmap2f + totalverts * 2;
- mesh->texcoorddetail2f = loadmodel->brushq1.entiremesh->texcoorddetail2f + totalverts * 2;
- mesh->svector3f = loadmodel->brushq1.entiremesh->svector3f + totalverts * 3;
- mesh->tvector3f = loadmodel->brushq1.entiremesh->tvector3f + totalverts * 3;
- mesh->normal3f = loadmodel->brushq1.entiremesh->normal3f + totalverts * 3;
- mesh->lightmapoffsets = loadmodel->brushq1.entiremesh->lightmapoffsets + totalverts;
- mesh->element3i = loadmodel->brushq1.entiremesh->element3i + totaltris * 3;
- mesh->neighbor3i = loadmodel->brushq1.entiremesh->neighbor3i + totaltris * 3;
+ mesh = &surf->mesh;
+ mesh->num_vertices = surf->poly_numverts;
+ mesh->num_triangles = surf->poly_numverts - 2;
+ mesh->data_vertex3f = loadmodel->brushq1.entiremesh->data_vertex3f + totalverts * 3;
+ mesh->data_texcoordtexture2f = loadmodel->brushq1.entiremesh->data_texcoordtexture2f + totalverts * 2;
+ mesh->data_texcoordlightmap2f = loadmodel->brushq1.entiremesh->data_texcoordlightmap2f + totalverts * 2;
+ mesh->data_texcoorddetail2f = loadmodel->brushq1.entiremesh->data_texcoorddetail2f + totalverts * 2;
+ mesh->data_svector3f = loadmodel->brushq1.entiremesh->data_svector3f + totalverts * 3;
+ mesh->data_tvector3f = loadmodel->brushq1.entiremesh->data_tvector3f + totalverts * 3;
+ mesh->data_normal3f = loadmodel->brushq1.entiremesh->data_normal3f + totalverts * 3;
+ mesh->data_lightmapoffsets = loadmodel->brushq1.entiremesh->data_lightmapoffsets + totalverts;
+ mesh->data_element3i = loadmodel->brushq1.entiremesh->data_element3i + totaltris * 3;
+ mesh->data_neighbor3i = loadmodel->brushq1.entiremesh->data_neighbor3i + totaltris * 3;
surf->lightmaptexturestride = 0;
surf->lightmaptexture = NULL;
- for (i = 0;i < mesh->numverts;i++)
+ for (i = 0;i < mesh->num_vertices;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;
+ 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->numtriangles;i++)
+ for (i = 0;i < mesh->num_triangles;i++)
{
- mesh->element3i[i * 3 + 0] = 0;
- mesh->element3i[i * 3 + 1] = i + 1;
- mesh->element3i[i * 3 + 2] = i + 2;
+ 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->neighbor3i, mesh->element3i, mesh->numtriangles);
- Mod_BuildTextureVectorsAndNormals(mesh->numverts, mesh->numtriangles, mesh->vertex3f, mesh->texcoordtexture2f, mesh->element3i, mesh->svector3f, mesh->tvector3f, mesh->normal3f);
+ 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->shader == &Cshader_wall_lightmap)
{
uscale = (uscale - ubase) / (smax + 1);
vscale = (vscale - vbase) / (tmax + 1);
- for (i = 0;i < mesh->numverts;i++)
+ for (i = 0;i < mesh->num_vertices;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;
+ 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;
// 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;
+ mesh->data_lightmapoffsets[i] = (bound(0, iv, tmax) * (smax+1) + bound(0, iu, smax)) * 3;
}
}
}
model_t *originalloadmodel;
float dist, modelyawradius, modelradius, *vec;
msurface_t *surf;
- surfmesh_t *mesh;
mod->type = mod_brush;
Host_Error("Mod_Q1BSP_Load: %s has wrong version number(%i should be %i(Quake) or 30(HalfLife))", mod->name, i, BSPVERSION);
mod->brush.ishlbsp = i == 30;
+ mod->soundfromcenter = true;
+ mod->TraceBox = Mod_Q1BSP_TraceBox;
mod->brush.SuperContentsFromNativeContents = Mod_Q1BSP_SuperContentsFromNativeContents;
mod->brush.NativeContentsFromSuperContents = Mod_Q1BSP_NativeContentsFromSuperContents;
mod->brush.GetPVS = Mod_Q1BSP_GetPVS;
mod->brush.BoxTouchingPVS = Mod_Q1BSP_BoxTouchingPVS;
mod->brush.LightPoint = Mod_Q1BSP_LightPoint;
mod->brush.FindNonSolidLocation = Mod_Q1BSP_FindNonSolidLocation;
- mod->brush.TraceBox = Mod_Q1BSP_TraceBox;
mod->brush.AmbientSoundLevelsForPoint = Mod_Q1BSP_AmbientSoundLevelsForPoint;
mod->brush.RoundUpToHullSize = Mod_Q1BSP_RoundUpToHullSize;
mod->brushq1.PointInLeaf = Mod_Q1BSP_PointInLeaf;
// this gets altered below if sky is used
mod->DrawSky = NULL;
mod->Draw = R_Model_Brush_Draw;
- mod->DrawFakeShadow = NULL;
mod->DrawShadowVolume = R_Model_Brush_DrawShadowVolume;
mod->DrawLight = R_Model_Brush_DrawLight;
mod->brushq1.pvstexturechains = Mem_Alloc(originalloadmodel->mempool, mod->brushq1.numtextures * sizeof(msurface_t **));
if (mod->brush.numsubmodels - 1)
surf->flags |= SURF_SOLIDCLIP;
// calculate bounding shapes
- for (mesh = surf->mesh;mesh;mesh = mesh->chain)
+ for (k = 0, vec = surf->mesh.data_vertex3f;k < surf->mesh.num_vertices;k++, vec += 3)
{
- 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];
- if (mod->normalmins[2] > vec[2]) mod->normalmins[2] = vec[2];
- if (mod->normalmaxs[0] < vec[0]) mod->normalmaxs[0] = vec[0];
- if (mod->normalmaxs[1] < vec[1]) mod->normalmaxs[1] = vec[1];
- if (mod->normalmaxs[2] < vec[2]) mod->normalmaxs[2] = vec[2];
- dist = vec[0]*vec[0]+vec[1]*vec[1];
- if (modelyawradius < dist)
- modelyawradius = dist;
- dist += vec[2]*vec[2];
- if (modelradius < dist)
- modelradius = dist;
- }
+ if (mod->normalmins[0] > vec[0]) mod->normalmins[0] = vec[0];
+ if (mod->normalmins[1] > vec[1]) mod->normalmins[1] = vec[1];
+ if (mod->normalmins[2] > vec[2]) mod->normalmins[2] = vec[2];
+ if (mod->normalmaxs[0] < vec[0]) mod->normalmaxs[0] = vec[0];
+ if (mod->normalmaxs[1] < vec[1]) mod->normalmaxs[1] = vec[1];
+ if (mod->normalmaxs[2] < vec[2]) mod->normalmaxs[2] = vec[2];
+ dist = vec[0]*vec[0]+vec[1]*vec[1];
+ if (modelyawradius < dist)
+ modelyawradius = dist;
+ dist += vec[2]*vec[2];
+ if (modelradius < dist)
+ modelradius = dist;
}
}
modelyawradius = sqrt(modelyawradius);
q3dtexture_t *in;
q3mtexture_t *out;
int i, count;
+ int j, c;
+ fssearch_t *search;
+ char *f;
+ const char *text;
+ int flags;
+ char shadername[Q3PATHLENGTH];
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
for (i = 0;i < count;i++, in++, out++)
{
- strncpy(out->name, in->name, sizeof(out->name) - 1);
+ out->number = i;
+ strlcpy (out->name, in->name, sizeof (out->name));
out->surfaceflags = LittleLong(in->surfaceflags);
out->nativecontents = LittleLong(in->contents);
out->supercontents = Mod_Q3BSP_SuperContentsFromNativeContents(loadmodel, out->nativecontents);
- out->renderflags = 0;
- if (!strcmp(out->name, "caulk") || !strcmp(out->name, "common/caulk") || !strcmp(out->name, "textures/common/caulk"))
- out->renderflags |= Q3MTEXTURERENDERFLAGS_NODRAW;
- if (!strncmp(out->name, "textures/skies/", 15))
- out->renderflags |= Q3MTEXTURERENDERFLAGS_SKY;
-
- out->number = i;
Mod_LoadSkinFrame(&out->skin, out->name, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, false, true, true);
+ out->surfaceparms = -1;
}
+
+ // do a quick parse of shader files to get surfaceparms
+ if ((search = FS_Search("scripts/*.shader", true, false)))
+ {
+ for (i = 0;i < search->numfilenames;i++)
+ {
+ if ((f = FS_LoadFile(search->filenames[i], false)))
+ {
+ text = f;
+ while (COM_ParseToken(&text, false))
+ {
+ snprintf(shadername, sizeof(shadername), "%s", com_token);
+ flags = 0;
+ if (COM_ParseToken(&text, false) && !strcmp(com_token, "{"))
+ {
+ while (COM_ParseToken(&text, false))
+ {
+ if (!strcmp(com_token, "}"))
+ break;
+ else if (!strcmp(com_token, "{"))
+ {
+ while (COM_ParseToken(&text, false))
+ {
+ if (!strcmp(com_token, "}"))
+ break;
+ }
+ }
+ else if (!strcmp(com_token, "surfaceparm"))
+ {
+ if (COM_ParseToken(&text, true) && strcmp(com_token, "\n"))
+ {
+ if (!strcmp(com_token, "alphashadow"))
+ flags |= Q3SURFACEPARM_ALPHASHADOW;
+ else if (!strcmp(com_token, "areaportal"))
+ flags |= Q3SURFACEPARM_AREAPORTAL;
+ else if (!strcmp(com_token, "clusterportal"))
+ flags |= Q3SURFACEPARM_CLUSTERPORTAL;
+ else if (!strcmp(com_token, "detail"))
+ flags |= Q3SURFACEPARM_DETAIL;
+ else if (!strcmp(com_token, "donotenter"))
+ flags |= Q3SURFACEPARM_DONOTENTER;
+ else if (!strcmp(com_token, "fog"))
+ flags |= Q3SURFACEPARM_FOG;
+ else if (!strcmp(com_token, "lava"))
+ flags |= Q3SURFACEPARM_LAVA;
+ else if (!strcmp(com_token, "lightfilter"))
+ flags |= Q3SURFACEPARM_LIGHTFILTER;
+ else if (!strcmp(com_token, "metalsteps"))
+ flags |= Q3SURFACEPARM_METALSTEPS;
+ else if (!strcmp(com_token, "nodamage"))
+ flags |= Q3SURFACEPARM_NODAMAGE;
+ else if (!strcmp(com_token, "nodlight"))
+ flags |= Q3SURFACEPARM_NODLIGHT;
+ else if (!strcmp(com_token, "nodraw"))
+ flags |= Q3SURFACEPARM_NODRAW;
+ else if (!strcmp(com_token, "nodrop"))
+ flags |= Q3SURFACEPARM_NODROP;
+ else if (!strcmp(com_token, "noimpact"))
+ flags |= Q3SURFACEPARM_NOIMPACT;
+ else if (!strcmp(com_token, "nolightmap"))
+ flags |= Q3SURFACEPARM_NOLIGHTMAP;
+ else if (!strcmp(com_token, "nomarks"))
+ flags |= Q3SURFACEPARM_NOMARKS;
+ else if (!strcmp(com_token, "nomipmaps"))
+ flags |= Q3SURFACEPARM_NOMIPMAPS;
+ else if (!strcmp(com_token, "nonsolid"))
+ flags |= Q3SURFACEPARM_NONSOLID;
+ else if (!strcmp(com_token, "origin"))
+ flags |= Q3SURFACEPARM_ORIGIN;
+ else if (!strcmp(com_token, "playerclip"))
+ flags |= Q3SURFACEPARM_PLAYERCLIP;
+ else if (!strcmp(com_token, "sky"))
+ flags |= Q3SURFACEPARM_SKY;
+ else if (!strcmp(com_token, "slick"))
+ flags |= Q3SURFACEPARM_SLICK;
+ else if (!strcmp(com_token, "slime"))
+ flags |= Q3SURFACEPARM_SLIME;
+ else if (!strcmp(com_token, "structural"))
+ flags |= Q3SURFACEPARM_STRUCTURAL;
+ else if (!strcmp(com_token, "trans"))
+ flags |= Q3SURFACEPARM_TRANS;
+ else if (!strcmp(com_token, "water"))
+ flags |= Q3SURFACEPARM_WATER;
+ else
+ Con_Printf("%s parsing warning: unknown surfaceparm \"%s\"\n", search->filenames[i], com_token);
+ if (!COM_ParseToken(&text, true) || strcmp(com_token, "\n"))
+ {
+ Con_Printf("%s parsing error: surfaceparm only takes one parameter.\n", search->filenames[i]);
+ goto parseerror;
+ }
+ }
+ else
+ {
+ Con_Printf("%s parsing error: surfaceparm expects a parameter.\n", search->filenames[i]);
+ goto parseerror;
+ }
+ }
+ else
+ {
+ // look for linebreak or }
+ while(COM_ParseToken(&text, true) && strcmp(com_token, "\n") && strcmp(com_token, "}"));
+ // break out to top level if it was }
+ if (!strcmp(com_token, "}"))
+ break;
+ }
+ }
+ // 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++)
+ if (!strcmp(out->name, shadername))
+ out->surfaceparms = flags;
+ }
+ else
+ {
+ Con_Printf("%s parsing error - expected \"{\", found \"%s\"\n", search->filenames[i], com_token);
+ goto parseerror;
+ }
+ }
+parseerror:
+ Mem_Free(f);
+ }
+ }
+ }
+
+ c = 0;
+ for (j = 0, out = loadmodel->brushq3.data_textures;j < loadmodel->brushq3.num_textures;j++, out++)
+ {
+ if (out->surfaceparms == -1)
+ {
+ c++;
+ Con_DPrintf("%s: No shader found for texture \"%s\"\n", loadmodel->name, out->name);
+ out->surfaceparms = 0;
+ // these are defaults
+ if (!strcmp(out->name, "caulk") || !strcmp(out->name, "common/caulk") || !strcmp(out->name, "textures/common/caulk")
+ || !strcmp(out->name, "nodraw") || !strcmp(out->name, "common/nodraw") || !strcmp(out->name, "textures/common/nodraw"))
+ out->surfaceparms |= Q3SURFACEPARM_NODRAW;
+ if (!strncmp(out->name, "textures/skies/", 15))
+ out->surfaceparms |= Q3SURFACEPARM_SKY;
+ if (R_TextureHasAlpha(out->skin.base))
+ out->surfaceparms |= Q3SURFACEPARM_TRANS;
+ }
+ }
+ Con_DPrintf("%s: %i textures missing shaders\n", loadmodel->name, c);
}
static void Mod_Q3BSP_LoadPlanes(lump_t *l)
q3mbrush_t *out;
int i, j, n, c, count, maxplanes;
mplane_t *planes;
+ winding_t *temp1, *temp2;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
loadmodel->brushq3.data_brushes = out;
loadmodel->brushq3.num_brushes = count;
+ temp1 = Winding_New(64);
+ temp2 = Winding_New(64);
+
maxplanes = 0;
planes = NULL;
planes[j].dist = out->firstbrushside[j].plane->dist;
}
// make the colbrush from the planes
- out->colbrushf = Collision_NewBrushFromPlanes(loadmodel->mempool, out->numbrushsides, planes, out->texture->supercontents);
+ out->colbrushf = Collision_NewBrushFromPlanes(loadmodel->mempool, out->numbrushsides, planes, out->texture->supercontents, temp1, temp2);
}
if (planes)
Mem_Free(planes);
+ Winding_Free(temp1);
+ Winding_Free(temp2);
}
static void Mod_Q3BSP_LoadEffects(lump_t *l)
for (i = 0;i < count;i++, in++, out++)
{
- strncpy(out->shadername, in->shadername, sizeof(out->shadername) - 1);
+ 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);
if (l->filelen % sizeof(*in))
Host_Error("Mod_Q3BSP_LoadVertices: funny lump size in %s",loadmodel->name);
loadmodel->brushq3.num_vertices = count = l->filelen / sizeof(*in);
- loadmodel->brushq3.data_vertex3f = Mem_Alloc(loadmodel->mempool, count * sizeof(float[3]));
- loadmodel->brushq3.data_texcoordtexture2f = Mem_Alloc(loadmodel->mempool, count * sizeof(float[2]));
- loadmodel->brushq3.data_texcoordlightmap2f = Mem_Alloc(loadmodel->mempool, count * sizeof(float[2]));
- loadmodel->brushq3.data_svector3f = Mem_Alloc(loadmodel->mempool, count * sizeof(float[3]));
- loadmodel->brushq3.data_tvector3f = Mem_Alloc(loadmodel->mempool, count * sizeof(float[3]));
- loadmodel->brushq3.data_normal3f = Mem_Alloc(loadmodel->mempool, count * sizeof(float[3]));
- loadmodel->brushq3.data_color4f = Mem_Alloc(loadmodel->mempool, count * sizeof(float[4]));
+ loadmodel->brushq3.data_vertex3f = Mem_Alloc(loadmodel->mempool, count * (sizeof(float) * (3 + 2 + 2 + 3 + 3 + 3 + 4)));
+ loadmodel->brushq3.data_texcoordtexture2f = loadmodel->brushq3.data_vertex3f + count * 3;
+ loadmodel->brushq3.data_texcoordlightmap2f = loadmodel->brushq3.data_texcoordtexture2f + count * 2;
+ loadmodel->brushq3.data_svector3f = loadmodel->brushq3.data_texcoordlightmap2f + count * 2;
+ loadmodel->brushq3.data_tvector3f = loadmodel->brushq3.data_svector3f + count * 3;
+ loadmodel->brushq3.data_normal3f = loadmodel->brushq3.data_tvector3f + count * 3;
+ loadmodel->brushq3.data_color4f = loadmodel->brushq3.data_normal3f + count * 3;
for (i = 0;i < count;i++, in++)
{
if (l->filelen % sizeof(int[3]))
Host_Error("Mod_Q3BSP_LoadTriangles: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
- out = Mem_Alloc(loadmodel->mempool, count * sizeof(*out));
+ out = Mem_Alloc(loadmodel->mempool, count * sizeof(*out) * 2);
loadmodel->brushq3.num_triangles = count / 3;
loadmodel->brushq3.data_element3i = out;
- loadmodel->brushq3.data_neighbor3i = Mem_Alloc(loadmodel->mempool, count * sizeof(*out));
+ loadmodel->brushq3.data_neighbor3i = out + count;
for (i = 0;i < count;i++, in++, out++)
{
rtexture_t **out;
int i, count;
+ if (!l->filelen)
+ return;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
Host_Error("Mod_Q3BSP_LoadLightmaps: funny lump size in %s",loadmodel->name);
&& out->type != Q3FACETYPE_FLARE)
{
Con_Printf("Mod_Q3BSP_LoadFaces: face #%i: unknown face type %i\n", i, out->type);
+ out->num_vertices = 0;
+ out->num_triangles = 0;
out->type = 0; // error
continue;
}
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->num_vertices = 0;
+ out->num_triangles = 0;
out->type = 0; // error
continue;
n = 0;
out->lightmaptexture = loadmodel->brushq3.data_lightmaps[n];
out->firstvertex = LittleLong(in->firstvertex);
- out->numvertices = LittleLong(in->numvertices);
+ out->num_vertices = 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)
+ out->num_triangles = LittleLong(in->numelements) / 3;
+ if (out->num_triangles * 3 != LittleLong(in->numelements))
{
- 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);
+ Con_Printf("Mod_Q3BSP_LoadFaces: face #%i (texture \"%s\"): numelements %i is not a multiple of 3\n", i, out->texture->name, LittleLong(in->numelements));
+ out->num_vertices = 0;
+ out->num_triangles = 0;
out->type = 0; // error
continue;
}
- if (out->firstelement < 0 || out->firstelement + out->numelements > loadmodel->brushq3.num_triangles * 3)
+ if (out->firstvertex < 0 || out->firstvertex + out->num_vertices > loadmodel->brushq3.num_vertices)
{
- 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);
+ 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->num_vertices, loadmodel->brushq3.num_vertices);
+ out->num_vertices = 0;
+ out->num_triangles = 0;
out->type = 0; // error
continue;
}
- if (out->numtriangles * 3 != out->numelements)
+ if (out->firstelement < 0 || out->firstelement + out->num_triangles * 3 > loadmodel->brushq3.num_triangles * 3)
{
- Con_Printf("Mod_Q3BSP_LoadFaces: face #%i (texture \"%s\"): numelements %i is not a multiple of 3\n", i, out->texture->name, out->numelements);
+ 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->num_triangles * 3, loadmodel->brushq3.num_triangles * 3);
+ out->num_vertices = 0;
+ out->num_triangles = 0;
out->type = 0; // error
continue;
}
- out->data_vertex3f = loadmodel->brushq3.data_vertex3f + out->firstvertex * 3;
- out->data_texcoordtexture2f = loadmodel->brushq3.data_texcoordtexture2f + out->firstvertex * 2;
- out->data_texcoordlightmap2f = loadmodel->brushq3.data_texcoordlightmap2f + 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;
switch(out->type)
{
case Q3FACETYPE_POLYGON:
case Q3FACETYPE_MESH:
// no processing necessary
+ out->data_vertex3f = loadmodel->brushq3.data_vertex3f + out->firstvertex * 3;
+ out->data_texcoordtexture2f = loadmodel->brushq3.data_texcoordtexture2f + out->firstvertex * 2;
+ out->data_texcoordlightmap2f = loadmodel->brushq3.data_texcoordlightmap2f + 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]);
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->num_vertices = 0;
+ out->num_triangles = 0;
out->type = 0; // error
continue;
}
finalheight = ((patchsize[1] - 1) << ylevel) + 1;
finalvertices = finalwidth * finalheight;
finaltriangles = (finalwidth - 1) * (finalheight - 1) * 2;
+ originalvertex3f = loadmodel->brushq3.data_vertex3f + out->firstvertex * 3;
+ //originalsvector3f = loadmodel->brushq3.data_svector3f + out->firstvertex * 3;
+ //originaltvector3f = loadmodel->brushq3.data_tvector3f + out->firstvertex * 3;
+ //originalnormal3f = loadmodel->brushq3.data_normal3f + out->firstvertex * 3;
+ originaltexcoordtexture2f = loadmodel->brushq3.data_texcoordtexture2f + out->firstvertex * 2;
+ originaltexcoordlightmap2f = loadmodel->brushq3.data_texcoordlightmap2f + out->firstvertex * 2;
+ originalcolor4f = loadmodel->brushq3.data_color4f + out->firstvertex * 4;
+ //originalelement3i = loadmodel->brushq3.data_element3i + out->firstelement;
+ //originalneighbor3i = loadmodel->brushq3.data_neighbor3i + out->firstelement;
+ /*
originalvertex3f = out->data_vertex3f;
//originalsvector3f = out->data_svector3f;
//originaltvector3f = out->data_tvector3f;
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_vertex3f = Mem_Alloc(loadmodel->mempool, sizeof(float[20]) * finalvertices);
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_element3i = Mem_Alloc(loadmodel->mempool, sizeof(int[6]) * finaltriangles);
out->data_neighbor3i = out->data_element3i + finaltriangles * 3;
out->type = Q3FACETYPE_MESH;
out->firstvertex = -1;
- out->numvertices = finalvertices;
+ out->num_vertices = finalvertices;
out->firstelement = -1;
- out->numtriangles = finaltriangles;
- out->numelements = finaltriangles * 3;
+ out->num_triangles = finaltriangles;
// generate geometry
// (note: normals are skipped because they get recalculated)
QuadraticSplinePatchSubdivideFloatBuffer(patchsize[0], patchsize[1], xlevel, ylevel, 3, originalvertex3f, out->data_vertex3f);
row1++;
}
}
- out->numtriangles = Mod_RemoveDegenerateTriangles(out->numtriangles, out->data_element3i, out->data_element3i, out->data_vertex3f);
+ out->num_triangles = Mod_RemoveDegenerateTriangles(out->num_triangles, 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);
+ if (out->num_triangles < 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->num_vertices, finaltriangles, finaltriangles - out->num_triangles, out->num_triangles);
else
- Con_Printf("Mod_Q3BSP_LoadFaces: %ix%i curve subdivided to %i vertices / %i triangles\n", patchsize[0], patchsize[1], out->numvertices, out->numtriangles);
+ Con_Printf("Mod_Q3BSP_LoadFaces: %ix%i curve subdivided to %i vertices / %i triangles\n", patchsize[0], patchsize[1], out->num_vertices, out->num_triangles);
}
// q3map does not put in collision brushes for curves... ugh
out->collisions = true;
case Q3FACETYPE_FLARE:
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;
+ out->num_vertices = 0;
+ out->num_triangles = 0;
+ out->type = 0;
break;
}
- for (j = 0, invalidelements = 0;j < out->numelements;j++)
- if (out->data_element3i[j] < 0 || out->data_element3i[j] >= out->numvertices)
+ for (j = 0, invalidelements = 0;j < out->num_triangles * 3;j++)
+ if (out->data_element3i[j] < 0 || out->data_element3i[j] >= out->num_vertices)
invalidelements++;
if (invalidelements)
{
- Con_Printf("Mod_Q3BSP_LoadFaces: Warning: face #%i has %i invalid elements, type = %i, texture->name = \"%s\", texture->surfaceflags = %i, texture->nativecontents = %i, firstvertex = %i, numvertices = %i, firstelement = %i, numelements = %i, elements list:\n", i, invalidelements, out->type, out->texture->name, out->texture->surfaceflags, out->texture->nativecontents, out->firstvertex, out->numvertices, out->firstelement, out->numelements);
- for (j = 0;j < out->numelements;j++)
+ Con_Printf("Mod_Q3BSP_LoadFaces: Warning: face #%i has %i invalid elements, type = %i, texture->name = \"%s\", texture->surfaceflags = %i, texture->nativecontents = %i, firstvertex = %i, numvertices = %i, firstelement = %i, numelements = %i, elements list:\n", i, invalidelements, out->type, out->texture->name, out->texture->surfaceflags, out->texture->nativecontents, out->firstvertex, out->num_vertices, out->firstelement, out->num_triangles * 3);
+ for (j = 0;j < out->num_triangles * 3;j++)
{
Con_Printf(" %i", out->data_element3i[j]);
- if (out->data_element3i[j] < 0 || out->data_element3i[j] >= out->numvertices)
+ if (out->data_element3i[j] < 0 || out->data_element3i[j] >= out->num_vertices)
out->data_element3i[j] = 0;
}
Con_Printf("\n");
}
// for shadow volumes
- Mod_BuildTriangleNeighbors(out->data_neighbor3i, out->data_element3i, out->numtriangles);
+ Mod_BuildTriangleNeighbors(out->data_neighbor3i, out->data_element3i, out->num_triangles);
// 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);
+ Mod_BuildTextureVectorsAndNormals(out->num_vertices, out->num_triangles, 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)
+ if (out->num_vertices)
{
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)
+ for (j = 1, v = out->data_vertex3f + 3;j < out->num_vertices;j++, v += 3)
{
out->mins[0] = min(out->mins[0], v[0]);
out->maxs[0] = max(out->maxs[0], v[0]);
out->maxs[2] += 1.0f;
}
}
+
+ // LordHavoc: experimental array merger (disabled because it wastes time and uses 2x memory while merging)
+ /*
+ {
+ int totalverts, totaltris;
+ int originalnum_vertices;
+ float *originaldata_vertex3f;
+ float *originaldata_texcoordtexture2f;
+ float *originaldata_texcoordlightmap2f;
+ float *originaldata_svector3f;
+ float *originaldata_tvector3f;
+ float *originaldata_normal3f;
+ float *originaldata_color4f;
+ int originalnum_triangles;
+ int *originaldata_element3i;
+ int *originaldata_neighbor3i;
+
+ totalverts = 0;
+ totaltris = 0;
+ for (i = 0, out = loadmodel->brushq3.data_faces;i < count;i++, out++)
+ {
+ if (!out->type)
+ continue;
+ totalverts += out->num_vertices;
+ totaltris += out->num_triangles;
+ }
+
+ originalnum_vertices = loadmodel->brushq3.num_vertices;
+ originaldata_vertex3f = loadmodel->brushq3.data_vertex3f;
+ originaldata_texcoordtexture2f = loadmodel->brushq3.data_texcoordtexture2f;
+ originaldata_texcoordlightmap2f = loadmodel->brushq3.data_texcoordlightmap2f;
+ originaldata_svector3f = loadmodel->brushq3.data_svector3f;
+ originaldata_tvector3f = loadmodel->brushq3.data_tvector3f;
+ originaldata_normal3f = loadmodel->brushq3.data_normal3f;
+ originaldata_color4f = loadmodel->brushq3.data_color4f;
+ originalnum_triangles = loadmodel->brushq3.num_triangles;
+ originaldata_element3i = loadmodel->brushq3.data_element3i;
+ originaldata_neighbor3i = loadmodel->brushq3.data_neighbor3i;
+ loadmodel->brushq3.num_vertices = totalverts;
+ loadmodel->brushq3.data_vertex3f = Mem_Alloc(loadmodel->mempool, totalverts * (sizeof(float) * (3 + 2 + 2 + 3 + 3 + 3 + 4)) + totaltris * (sizeof(int) * (3 * 2)));
+ loadmodel->brushq3.data_texcoordtexture2f = loadmodel->brushq3.data_vertex3f + totalverts * 3;
+ loadmodel->brushq3.data_texcoordlightmap2f = loadmodel->brushq3.data_texcoordtexture2f + totalverts * 2;
+ loadmodel->brushq3.data_svector3f = loadmodel->brushq3.data_texcoordlightmap2f + totalverts * 2;
+ loadmodel->brushq3.data_tvector3f = loadmodel->brushq3.data_svector3f + totalverts * 3;
+ loadmodel->brushq3.data_normal3f = loadmodel->brushq3.data_tvector3f + totalverts * 3;
+ loadmodel->brushq3.data_color4f = loadmodel->brushq3.data_normal3f + totalverts * 3;
+ loadmodel->brushq3.num_triangles = totaltris;
+ loadmodel->brushq3.data_element3i = (int *)(loadmodel->brushq3.data_color4f + totalverts * 4);
+ loadmodel->brushq3.data_neighbor3i = loadmodel->brushq3.data_element3i + totaltris * 3;
+ totalverts = 0;
+ totaltris = 0;
+ for (i = 0, out = loadmodel->brushq3.data_faces;i < count;i++, out++)
+ {
+ if (!out->type)
+ continue;
+ Con_Printf("totalverts %i, totaltris %i\n", totalverts, totaltris);
+ memcpy(loadmodel->brushq3.data_vertex3f + totalverts * 3, out->data_vertex3f, out->num_vertices * 3 * sizeof(float));
+ memcpy(loadmodel->brushq3.data_texcoordtexture2f + totalverts * 2, out->data_texcoordtexture2f, out->num_vertices * 2 * sizeof(float));
+ memcpy(loadmodel->brushq3.data_texcoordlightmap2f + totalverts * 2, out->data_texcoordlightmap2f, out->num_vertices * 2 * sizeof(float));
+ memcpy(loadmodel->brushq3.data_svector3f + totalverts * 3, out->data_svector3f, out->num_vertices * 3 * sizeof(float));
+ memcpy(loadmodel->brushq3.data_tvector3f + totalverts * 3, out->data_tvector3f, out->num_vertices * 3 * sizeof(float));
+ memcpy(loadmodel->brushq3.data_normal3f + totalverts * 3, out->data_normal3f, out->num_vertices * 3 * sizeof(float));
+ memcpy(loadmodel->brushq3.data_color4f + totalverts * 4, out->data_color4f, out->num_vertices * 4 * sizeof(float));
+ memcpy(loadmodel->brushq3.data_element3i + totaltris * 3, out->data_element3i, out->num_triangles * 3 * sizeof(int));
+ memcpy(loadmodel->brushq3.data_neighbor3i + totaltris * 3, out->data_neighbor3i, out->num_triangles * 3 * sizeof(int));
+ if (out->firstvertex == -1)
+ Mem_Free(out->data_vertex3f);
+ if (out->firstelement == -1)
+ Mem_Free(out->data_element3i);
+ out->firstvertex = totalverts;
+ out->data_vertex3f = loadmodel->brushq3.data_vertex3f + out->firstvertex * 3;
+ out->data_texcoordtexture2f = loadmodel->brushq3.data_texcoordtexture2f + out->firstvertex * 2;
+ out->data_texcoordlightmap2f = loadmodel->brushq3.data_texcoordlightmap2f + 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->firstelement = totaltris * 3;
+ out->data_element3i = loadmodel->brushq3.data_element3i + out->firstelement;
+ out->data_neighbor3i = loadmodel->brushq3.data_neighbor3i + out->firstelement;
+ //for (j = 0;j < out->numtriangles * 3;j++)
+ // out->data_element3i[j] += totalverts - out->firstvertex;
+ totalverts += out->num_vertices;
+ totaltris += out->num_triangles;
+ }
+ Mem_Free(originaldata_vertex3f);
+ Mem_Free(originaldata_element3i);
+ }
+ */
}
static void Mod_Q3BSP_LoadModels(lump_t *l)
q3dlightgrid_t *out;
int count;
+ if (l->filelen == 0)
+ return;
+
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
Host_Error("Mod_Q3BSP_LoadLightGrid: funny lump size in %s",loadmodel->name);
// FIXME: write this
if (!model->brushq3.num_lightgrid)
{
- ambientcolor[0] += 128;
- ambientcolor[1] += 128;
- ambientcolor[2] += 128;
+ ambientcolor[0] = 1;
+ ambientcolor[1] = 1;
+ ambientcolor[2] = 1;
return;
}
Matrix4x4_Transform(&model->brushq3.num_lightgrid_indexfromworld, p, transformed);
//Matrix4x4_Print(&model->brushq3.num_lightgrid_indexfromworld);
//Con_Printf("%f %f %f transformed %f %f %f clamped ", p[0], p[1], p[2], transformed[0], transformed[1], transformed[2]);
- transformed[0] = bound(0, transformed[0], model->brushq3.num_lightgrid_isize[0]);
- transformed[1] = bound(0, transformed[1], model->brushq3.num_lightgrid_isize[1]);
- transformed[2] = bound(0, transformed[2], model->brushq3.num_lightgrid_isize[2]);
+ transformed[0] = bound(0, transformed[0], model->brushq3.num_lightgrid_isize[0] - 1);
+ transformed[1] = bound(0, transformed[1], model->brushq3.num_lightgrid_isize[1] - 1);
+ transformed[2] = bound(0, transformed[2], model->brushq3.num_lightgrid_isize[2] - 1);
index[0] = (int)floor(transformed[0]);
index[1] = (int)floor(transformed[1]);
index[2] = (int)floor(transformed[2]);
for (k = 0;k < 2;k++)
{
blend1 = (k ? (transformed[2] - index[2]) : (1 - (transformed[2] - index[2])));
+ if (blend1 < 0.001f || index[2] + k >= model->brushq3.num_lightgrid_isize[2])
+ continue;
for (j = 0;j < 2;j++)
{
blend2 = blend1 * (j ? (transformed[1] - index[1]) : (1 - (transformed[1] - index[1])));
+ if (blend2 < 0.001f || index[1] + j >= model->brushq3.num_lightgrid_isize[1])
+ continue;
for (i = 0;i < 2;i++)
{
blend = blend2 * (i ? (transformed[0] - index[0]) : (1 - (transformed[0] - index[0])));
+ if (blend < 0.001f || index[0] + i >= model->brushq3.num_lightgrid_isize[0])
+ continue;
s = a + (k * model->brushq3.num_lightgrid_isize[1] + j) * model->brushq3.num_lightgrid_isize[0] + i;
VectorMA(ambientcolor, blend * (1.0f / 128.0f), s->ambientrgb, ambientcolor);
VectorMA(diffusecolor, blend * (1.0f / 128.0f), s->diffusergb, diffusecolor);
{
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);
+ Collision_TraceLineTriangleMeshFloat(trace, linestart, lineend, face->num_triangles, face->data_element3i, face->data_vertex3f, face->texture->supercontents, segmentmins, segmentmaxs);
}
}
}
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);
+ Collision_TraceBrushTriangleMeshFloat(trace, thisbrush_start, thisbrush_end, face->num_triangles, 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)
+static void Mod_Q3BSP_TraceBox(model_t *model, int frame, 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];
{
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);
+ Collision_TraceLineTriangleMeshFloat(trace, boxstartmins, boxendmins, face->num_triangles, face->data_element3i, face->data_vertex3f, face->texture->supercontents, segmentmins, segmentmaxs);
}
}
}
{
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);
+ Collision_TraceBrushTriangleMeshFloat(trace, thisbrush_start, thisbrush_end, face->num_triangles, face->data_element3i, face->data_vertex3f, face->texture->supercontents, segmentmins, segmentmaxs);
}
}
}
return nativecontents;
}
-//extern void R_Q3BSP_DrawSky(struct entity_render_s *ent);
+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);
void Mod_Q3BSP_Load(model_t *mod, void *buffer)
{
- int i;
+ int i, j;
q3dheader_t *header;
float corner[3], yawradius, modelradius;
R_ResetQuakeSky();
}
+ mod->soundfromcenter = true;
+ mod->TraceBox = Mod_Q3BSP_TraceBox;
mod->brush.SuperContentsFromNativeContents = Mod_Q3BSP_SuperContentsFromNativeContents;
mod->brush.NativeContentsFromSuperContents = Mod_Q3BSP_NativeContentsFromSuperContents;
mod->brush.GetPVS = Mod_Q3BSP_GetPVS;
mod->brush.BoxTouchingPVS = Mod_Q3BSP_BoxTouchingPVS;
mod->brush.LightPoint = Mod_Q3BSP_LightPoint;
mod->brush.FindNonSolidLocation = Mod_Q3BSP_FindNonSolidLocation;
- mod->brush.TraceBox = Mod_Q3BSP_TraceBox;
//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->yawmaxs[2] = mod->normalmaxs[2];
mod->radius = modelradius;
mod->radius2 = modelradius * modelradius;
+
+ for (j = 0;j < mod->brushq3.data_thismodel->numfaces;j++)
+ if (mod->brushq3.data_thismodel->firstface[j].texture->surfaceflags & Q3SURFACEFLAG_SKY)
+ break;
+ if (j < mod->brushq3.data_thismodel->numfaces)
+ mod->DrawSky = R_Q3BSP_DrawSky;
}
}