X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=model_brush.c;h=ac88de7f529c9e8cb7711f8d25aa45b448a066ac;hb=224f9edae92441767654e2c10eb568bb91f86eb1;hp=d7825c7a0c9ac7b7bdf9a7cb6ed7b03d877a0e51;hpb=6f7c3f6e6bd0f1db1987f87e6090bc98d620cc30;p=xonotic%2Fdarkplaces.git diff --git a/model_brush.c b/model_brush.c index d7825c7a..ac88de7f 100644 --- a/model_brush.c +++ b/model_brush.c @@ -92,20 +92,181 @@ int Mod_PointContents (const vec3_t p, model_t *model) 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); +} /* =================== @@ -1220,19 +1381,19 @@ void Mod_GenerateWarpMesh (msurface_t *surf) 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; } @@ -1260,12 +1421,12 @@ void Mod_GenerateWallMesh (msurface_t *surf, int vertexonly) 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); @@ -1274,14 +1435,14 @@ void Mod_GenerateWallMesh (msurface_t *surf, int vertexonly) 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) @@ -1300,18 +1461,18 @@ void Mod_GenerateWallMesh (msurface_t *surf, int vertexonly) 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) @@ -1325,14 +1486,14 @@ 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) @@ -1341,17 +1502,17 @@ void Mod_GenerateVertexMesh (msurface_t *surf) { 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) @@ -2400,7 +2561,7 @@ static void Mod_RecursiveNodePortals (mnode_t *node) 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; } } @@ -2625,7 +2786,7 @@ Mod_LoadBrushModel 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; @@ -2737,7 +2898,7 @@ void Mod_LoadBrushModel (model_t *mod, void *buffer) // 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];