return ((mleaf_t *)node)->contents;
}
-void Mod_FindNonSolidLocation(vec3_t pos, model_t *mod)
+typedef struct findnonsolidlocationinfo_s
{
- if (Mod_PointContents(pos, mod) != CONTENTS_SOLID) return;
- pos[0]-=1;if (Mod_PointContents(pos, mod) != CONTENTS_SOLID) return;
- pos[0]+=2;if (Mod_PointContents(pos, mod) != CONTENTS_SOLID) return;
- pos[0]-=1;
- pos[1]-=1;if (Mod_PointContents(pos, mod) != CONTENTS_SOLID) return;
- pos[1]+=2;if (Mod_PointContents(pos, mod) != CONTENTS_SOLID) return;
- pos[1]-=1;
- pos[2]-=1;if (Mod_PointContents(pos, mod) != CONTENTS_SOLID) return;
- pos[2]+=2;if (Mod_PointContents(pos, mod) != CONTENTS_SOLID) return;
- pos[2]-=1;
+ vec3_t center;
+ vec_t radius;
+ vec3_t nudge;
+ vec_t bestdist;
+ model_t *model;
}
+findnonsolidlocationinfo_t;
+#if 0
+extern cvar_t samelevel;
+#endif
+void Mod_FindNonSolidLocation_r_Leaf(findnonsolidlocationinfo_t *info, mleaf_t *leaf)
+{
+ int i, surfnum, k, *tri, *mark;
+ float dist, f, vert[3][3], edge[3][3], facenormal[3], edgenormal[3][3], point[3];
+#if 0
+ float surfnormal[3];
+#endif
+ msurface_t *surf;
+ surfmesh_t *mesh;
+ for (surfnum = 0, mark = leaf->firstmarksurface;surfnum < leaf->nummarksurfaces;surfnum++, mark++)
+ {
+ surf = info->model->surfaces + *mark;
+ if (surf->flags & SURF_SOLIDCLIP)
+ {
+#if 0
+ VectorCopy(surf->plane->normal, surfnormal);
+ if (surf->flags & SURF_PLANEBACK)
+ VectorNegate(surfnormal, surfnormal);
+#endif
+ for (mesh = surf->mesh;mesh;mesh = mesh->chain)
+ {
+ for (k = 0;k < mesh->numtriangles;k++)
+ {
+ tri = mesh->element3i + k * 3;
+ VectorCopy((mesh->vertex3f + tri[0] * 3), vert[0]);
+ VectorCopy((mesh->vertex3f + tri[1] * 3), vert[1]);
+ VectorCopy((mesh->vertex3f + tri[2] * 3), vert[2]);
+ VectorSubtract(vert[1], vert[0], edge[0]);
+ VectorSubtract(vert[2], vert[1], edge[1]);
+ CrossProduct(edge[1], edge[0], facenormal);
+ if (facenormal[0] || facenormal[1] || facenormal[2])
+ {
+ VectorNormalize(facenormal);
+#if 0
+ if (VectorDistance(facenormal, surfnormal) > 0.01f)
+ Con_Printf("a2! %f %f %f != %f %f %f\n", facenormal[0], facenormal[1], facenormal[2], surfnormal[0], surfnormal[1], surfnormal[2]);
+#endif
+ f = DotProduct(info->center, facenormal) - DotProduct(vert[0], facenormal);
+ if (f <= info->bestdist && f >= -info->bestdist)
+ {
+ VectorSubtract(vert[0], vert[2], edge[2]);
+ VectorNormalize(edge[0]);
+ VectorNormalize(edge[1]);
+ VectorNormalize(edge[2]);
+ CrossProduct(facenormal, edge[0], edgenormal[0]);
+ CrossProduct(facenormal, edge[1], edgenormal[1]);
+ CrossProduct(facenormal, edge[2], edgenormal[2]);
+#if 0
+ if (samelevel.integer & 1)
+ VectorNegate(edgenormal[0], edgenormal[0]);
+ if (samelevel.integer & 2)
+ VectorNegate(edgenormal[1], edgenormal[1]);
+ if (samelevel.integer & 4)
+ VectorNegate(edgenormal[2], edgenormal[2]);
+ for (i = 0;i < 3;i++)
+ if (DotProduct(vert[0], edgenormal[i]) > DotProduct(vert[i], edgenormal[i]) + 0.1f
+ || DotProduct(vert[1], edgenormal[i]) > DotProduct(vert[i], edgenormal[i]) + 0.1f
+ || DotProduct(vert[2], edgenormal[i]) > DotProduct(vert[i], edgenormal[i]) + 0.1f)
+ Con_Printf("a! %i : %f %f %f (%f %f %f)\n", i, edgenormal[i][0], edgenormal[i][1], edgenormal[i][2], facenormal[0], facenormal[1], facenormal[2]);
+#endif
+ // face distance
+ if (DotProduct(info->center, edgenormal[0]) < DotProduct(vert[0], edgenormal[0])
+ && DotProduct(info->center, edgenormal[1]) < DotProduct(vert[1], edgenormal[1])
+ && DotProduct(info->center, edgenormal[2]) < DotProduct(vert[2], edgenormal[2]))
+ {
+ // we got lucky, the center is within the face
+ dist = DotProduct(info->center, facenormal) - DotProduct(vert[0], facenormal);
+ if (dist < 0)
+ {
+ dist = -dist;
+ if (info->bestdist > dist)
+ {
+ info->bestdist = dist;
+ VectorScale(facenormal, (info->radius - -dist), info->nudge);
+ }
+ }
+ else
+ {
+ if (info->bestdist > dist)
+ {
+ info->bestdist = dist;
+ VectorScale(facenormal, (info->radius - dist), info->nudge);
+ }
+ }
+ }
+ else
+ {
+ // check which edge or vertex the center is nearest
+ for (i = 0;i < 3;i++)
+ {
+ f = DotProduct(info->center, edge[i]);
+ if (f >= DotProduct(vert[0], edge[i])
+ && f <= DotProduct(vert[1], edge[i]))
+ {
+ // on edge
+ VectorMA(info->center, -f, edge[i], point);
+ dist = sqrt(DotProduct(point, point));
+ if (info->bestdist > dist)
+ {
+ info->bestdist = dist;
+ VectorScale(point, (info->radius / dist), info->nudge);
+ }
+ // skip both vertex checks
+ // (both are further away than this edge)
+ i++;
+ }
+ else
+ {
+ // not on edge, check first vertex of edge
+ VectorSubtract(info->center, vert[i], point);
+ dist = sqrt(DotProduct(point, point));
+ if (info->bestdist > dist)
+ {
+ info->bestdist = dist;
+ VectorScale(point, (info->radius / dist), info->nudge);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void Mod_FindNonSolidLocation_r(findnonsolidlocationinfo_t *info, mnode_t *node)
+{
+ if (node->contents)
+ {
+ if (((mleaf_t *)node)->nummarksurfaces)
+ Mod_FindNonSolidLocation_r_Leaf(info, (mleaf_t *)node);
+ }
+ else
+ {
+ float f = PlaneDiff(info->center, node->plane);
+ if (f >= -info->bestdist)
+ Mod_FindNonSolidLocation_r(info, node->children[0]);
+ if (f <= info->bestdist)
+ Mod_FindNonSolidLocation_r(info, node->children[1]);
+ }
+}
+
+void Mod_FindNonSolidLocation(vec3_t in, vec3_t out, model_t *model, float radius)
+{
+ int i;
+ findnonsolidlocationinfo_t info;
+ VectorCopy(in, info.center);
+ info.radius = radius;
+ info.model = model;
+ i = 0;
+ do
+ {
+ VectorClear(info.nudge);
+ info.bestdist = radius;
+ Mod_FindNonSolidLocation_r(&info, model->nodes + model->hulls[0].firstclipnode);
+ VectorAdd(info.center, info.nudge, info.center);
+ }
+ while(info.bestdist < radius && ++i < 10);
+ VectorCopy(info.center, out);
+}
/*
===================
surfmesh_t *Mod_AllocSurfMesh(int numverts, int numtriangles)
{
surfmesh_t *mesh;
- mesh = Mem_Alloc(loadmodel->mempool, sizeof(surfmesh_t) + numtriangles * sizeof(int[6]) + numverts * (4 + 4 + 4 + 4 + 4 + 4 + 4 + 1) * sizeof(float));
+ mesh = Mem_Alloc(loadmodel->mempool, sizeof(surfmesh_t) + numtriangles * sizeof(int[6]) + numverts * (3 + 2 + 2 + 2 + 3 + 3 + 3 + 1) * sizeof(float));
mesh->numverts = numverts;
mesh->numtriangles = numtriangles;
- mesh->verts = (float *)(mesh + 1);
- mesh->str = mesh->verts + mesh->numverts * 4;
- mesh->uvw = mesh->str + mesh->numverts * 4;
- mesh->abc = mesh->uvw + mesh->numverts * 4;
- mesh->svectors = (float *)(mesh->abc + mesh->numverts * 4);
- mesh->tvectors = mesh->svectors + mesh->numverts * 4;
- mesh->normals = mesh->tvectors + mesh->numverts * 4;
- mesh->lightmapoffsets = (int *)(mesh->normals + mesh->numverts * 4);
- mesh->index = mesh->lightmapoffsets + mesh->numverts;
- mesh->triangleneighbors = mesh->index + mesh->numtriangles * 3;
+ mesh->vertex3f = (float *)(mesh + 1);
+ mesh->texcoordtexture2f = mesh->vertex3f + mesh->numverts * 3;
+ mesh->texcoordlightmap2f = mesh->texcoordtexture2f + mesh->numverts * 2;
+ mesh->texcoorddetail2f = mesh->texcoordlightmap2f + mesh->numverts * 2;
+ mesh->svector3f = (float *)(mesh->texcoorddetail2f + mesh->numverts * 2);
+ mesh->tvector3f = mesh->svector3f + mesh->numverts * 3;
+ mesh->normal3f = mesh->tvector3f + mesh->numverts * 3;
+ mesh->lightmapoffsets = (int *)(mesh->normal3f + mesh->numverts * 3);
+ mesh->element3i = mesh->lightmapoffsets + mesh->numverts;
+ mesh->neighbor3i = mesh->element3i + mesh->numtriangles * 3;
return mesh;
}
if (r_miplightmaps.integer)
{
surf->lightmaptexturestride = (surf->extents[0]>>4)+1;
- surf->lightmaptexture = R_LoadTexture2D(loadmodel->texturepool, NULL, surf->lightmaptexturestride, (surf->extents[1]>>4)+1, NULL, loadmodel->lightmaprgba ? TEXTYPE_RGBA : TEXTYPE_RGB, TEXF_MIPMAP | TEXF_PRECACHE, NULL);
+ surf->lightmaptexture = R_LoadTexture2D(loadmodel->texturepool, NULL, surf->lightmaptexturestride, (surf->extents[1]>>4)+1, NULL, loadmodel->lightmaprgba ? TEXTYPE_RGBA : TEXTYPE_RGB, TEXF_MIPMAP | TEXF_FORCELINEAR | TEXF_PRECACHE, NULL);
}
else
{
surf->lightmaptexturestride = R_CompatibleFragmentWidth((surf->extents[0]>>4)+1, loadmodel->lightmaprgba ? TEXTYPE_RGBA : TEXTYPE_RGB, 0);
- surf->lightmaptexture = R_LoadTexture2D(loadmodel->texturepool, NULL, surf->lightmaptexturestride, (surf->extents[1]>>4)+1, NULL, loadmodel->lightmaprgba ? TEXTYPE_RGBA : TEXTYPE_RGB, TEXF_FRAGMENT | TEXF_PRECACHE, NULL);
+ surf->lightmaptexture = R_LoadTexture2D(loadmodel->texturepool, NULL, surf->lightmaptexturestride, (surf->extents[1]>>4)+1, NULL, loadmodel->lightmaprgba ? TEXTYPE_RGBA : TEXTYPE_RGB, TEXF_FRAGMENT | TEXF_FORCELINEAR | TEXF_PRECACHE, NULL);
}
R_FragmentLocation(surf->lightmaptexture, NULL, NULL, &ubase, &vbase, &uscale, &vscale);
uscale = (uscale - ubase) * 16.0 / ((surf->extents[0] & ~15) + 16);
surf->mesh = mesh = Mod_AllocSurfMesh(surf->poly_numverts, surf->poly_numverts - 2);
- index = mesh->index;
+ index = mesh->element3i;
for (i = 0;i < mesh->numtriangles;i++)
{
*index++ = 0;
*index++ = i + 1;
*index++ = i + 2;
}
- Mod_BuildTriangleNeighbors(mesh->triangleneighbors, mesh->index, mesh->numtriangles);
+ Mod_BuildTriangleNeighbors(mesh->neighbor3i, mesh->element3i, mesh->numtriangles);
VectorCopy(surf->plane->normal, normal);
if (surf->flags & SURF_PLANEBACK)
u = u * uscale + ubase;
v = v * vscale + vbase;
- mesh->verts[i * 4 + 0] = in[0];
- mesh->verts[i * 4 + 1] = in[1];
- mesh->verts[i * 4 + 2] = in[2];
- mesh->str[i * 4 + 0] = s / surf->texinfo->texture->width;
- mesh->str[i * 4 + 1] = t / surf->texinfo->texture->height;
- mesh->uvw[i * 4 + 0] = u;
- mesh->uvw[i * 4 + 1] = v;
- mesh->abc[i * 4 + 0] = s * (1.0f / 16.0f);
- mesh->abc[i * 4 + 1] = t * (1.0f / 16.0f);
+ mesh->vertex3f[i * 3 + 0] = in[0];
+ mesh->vertex3f[i * 3 + 1] = in[1];
+ mesh->vertex3f[i * 3 + 2] = in[2];
+ mesh->texcoordtexture2f[i * 2 + 0] = s / surf->texinfo->texture->width;
+ mesh->texcoordtexture2f[i * 2 + 1] = t / surf->texinfo->texture->height;
+ mesh->texcoordlightmap2f[i * 2 + 0] = u;
+ mesh->texcoordlightmap2f[i * 2 + 1] = v;
+ mesh->texcoorddetail2f[i * 2 + 0] = s * (1.0f / 16.0f);
+ mesh->texcoorddetail2f[i * 2 + 1] = t * (1.0f / 16.0f);
mesh->lightmapoffsets[i] = ((iv * (smax+1) + iu) * 3);
}
- Mod_BuildTextureVectorsAndNormals(mesh->numverts, mesh->numtriangles, mesh->verts, mesh->str, mesh->index, mesh->svectors, mesh->tvectors, mesh->normals);
+ Mod_BuildTextureVectorsAndNormals(mesh->numverts, mesh->numtriangles, mesh->vertex3f, mesh->texcoordtexture2f, mesh->element3i, mesh->svector3f, mesh->tvector3f, mesh->normal3f);
}
void Mod_GenerateVertexMesh (msurface_t *surf)
surf->mesh = mesh = Mod_AllocSurfMesh(surf->poly_numverts, surf->poly_numverts - 2);
- index = mesh->index;
+ index = mesh->element3i;
for (i = 0;i < mesh->numtriangles;i++)
{
*index++ = 0;
*index++ = i + 1;
*index++ = i + 2;
}
- Mod_BuildTriangleNeighbors(mesh->triangleneighbors, mesh->index, mesh->numtriangles);
+ Mod_BuildTriangleNeighbors(mesh->neighbor3i, mesh->element3i, mesh->numtriangles);
VectorCopy(surf->plane->normal, normal);
if (surf->flags & SURF_PLANEBACK)
{
s = (DotProduct (in, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3]);
t = (DotProduct (in, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3]);
- mesh->verts[i * 4 + 0] = in[0];
- mesh->verts[i * 4 + 1] = in[1];
- mesh->verts[i * 4 + 2] = in[2];
- mesh->str[i * 4 + 0] = s / surf->texinfo->texture->width;
- mesh->str[i * 4 + 1] = t / surf->texinfo->texture->height;
- mesh->uvw[i * 4 + 0] = 0;
- mesh->uvw[i * 4 + 1] = 0;
- mesh->abc[i * 4 + 0] = s * (1.0f / 16.0f);
- mesh->abc[i * 4 + 1] = t * (1.0f / 16.0f);
- }
- Mod_BuildTextureVectorsAndNormals(mesh->numverts, mesh->numtriangles, mesh->verts, mesh->str, mesh->index, mesh->svectors, mesh->tvectors, mesh->normals);
+ mesh->vertex3f[i * 3 + 0] = in[0];
+ mesh->vertex3f[i * 3 + 1] = in[1];
+ mesh->vertex3f[i * 3 + 2] = in[2];
+ mesh->texcoordtexture2f[i * 2 + 0] = s / surf->texinfo->texture->width;
+ mesh->texcoordtexture2f[i * 2 + 1] = t / surf->texinfo->texture->height;
+ mesh->texcoordlightmap2f[i * 2 + 0] = 0;
+ mesh->texcoordlightmap2f[i * 2 + 1] = 0;
+ mesh->texcoorddetail2f[i * 2 + 0] = s * (1.0f / 16.0f);
+ mesh->texcoorddetail2f[i * 2 + 1] = t * (1.0f / 16.0f);
+ }
+ Mod_BuildTextureVectorsAndNormals(mesh->numverts, mesh->numtriangles, mesh->vertex3f, mesh->texcoordtexture2f, mesh->element3i, mesh->svector3f, mesh->tvector3f, mesh->normal3f);
}
void Mod_GenerateSurfacePolygon (msurface_t *surf, int firstedge, int numedges)
nodeportalwinding = ClipWinding (nodeportalwinding, &clipplane, true);
if (!nodeportalwinding)
{
- printf ("Mod_RecursiveNodePortals: WARNING: new portal was clipped away\n");
+ Con_Printf ("Mod_RecursiveNodePortals: WARNING: new portal was clipped away\n");
break;
}
}
extern void R_Model_Brush_DrawSky(entity_render_t *ent);
extern void R_Model_Brush_Draw(entity_render_t *ent);
extern void R_Model_Brush_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius);
-extern void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor);
+extern void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz);
void Mod_LoadBrushModel (model_t *mod, void *buffer)
{
int i, j, k;
// calculate bounding shapes
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
{
- for (k = 0, vec = mesh->verts;k < mesh->numverts;k++, vec += 4)
+ for (k = 0, vec = mesh->vertex3f;k < mesh->numverts;k++, vec += 3)
{
if (mod->normalmins[0] > vec[0]) mod->normalmins[0] = vec[0];
if (mod->normalmins[1] > vec[1]) mod->normalmins[1] = vec[1];