From 1893466045869dc85faaeb137d3f205a2d118b67 Mon Sep 17 00:00:00 2001 From: havoc Date: Sun, 16 Apr 2006 10:19:05 +0000 Subject: [PATCH] modified Mod_BuildTextureVectorsAndNormals to become Mod_BuildTextureVectorsFromNormals, this is in preparation for properly honoring the surface normals in models and maps (doesn't do anything yet) git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@6295 d7cf8633-e32d-0410-b094-e92efae38249 --- gl_rmain.c | 30 +++++++++++------------ model_alias.c | 3 ++- model_brush.c | 6 +++-- model_shared.c | 66 +++++++++++++++++--------------------------------- model_shared.h | 2 +- 5 files changed, 44 insertions(+), 63 deletions(-) diff --git a/gl_rmain.c b/gl_rmain.c index 4eb8db88..8ef94c48 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -2443,25 +2443,24 @@ void RSurf_PrepareVerticesForBatch(const entity_render_t *ent, const texture_t * if ((rsurface_entity->frameblend[0].lerp != 1 || rsurface_entity->frameblend[0].frame != 0) && (rsurface_model->surfmesh.data_morphvertex3f || rsurface_model->surfmesh.data_vertexboneweights)) { rsurface_vertex3f = rsurface_array_vertex3f; + rsurface_svector3f = NULL; + rsurface_tvector3f = NULL; + rsurface_normal3f = NULL; Mod_Alias_GetMesh_Vertex3f(rsurface_model, rsurface_entity->frameblend, rsurface_array_vertex3f); - if (generatetangents || (rsurface_texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2))) + if (rsurface_texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2)) + generatetangents = true; + if (generatetangents) + generatenormals = true; + if (generatenormals && !rsurface_normal3f) { - rsurface_svector3f = rsurface_array_svector3f; - rsurface_tvector3f = rsurface_array_tvector3f; rsurface_normal3f = rsurface_array_normal3f; - Mod_BuildTextureVectorsAndNormals(0, rsurface_model->surfmesh.num_vertices, rsurface_model->surfmesh.num_triangles, rsurface_array_vertex3f, rsurface_model->surfmesh.data_texcoordtexture2f, rsurface_model->surfmesh.data_element3i, rsurface_array_svector3f, rsurface_array_tvector3f, rsurface_array_normal3f, r_smoothnormals_areaweighting.integer); + Mod_BuildNormals(0, rsurface_model->surfmesh.num_vertices, rsurface_model->surfmesh.num_triangles, rsurface_array_vertex3f, rsurface_model->surfmesh.data_element3i, rsurface_array_normal3f, r_smoothnormals_areaweighting.integer); } - else + if (generatetangents && !rsurface_svector3f) { - rsurface_svector3f = NULL; - rsurface_tvector3f = NULL; - if (generatenormals) - { - rsurface_normal3f = rsurface_array_normal3f; - Mod_BuildNormals(0, rsurface_model->surfmesh.num_vertices, rsurface_model->surfmesh.num_triangles, rsurface_array_vertex3f, rsurface_model->surfmesh.data_element3i, rsurface_array_normal3f, r_smoothnormals_areaweighting.integer); - } - else - rsurface_normal3f = NULL; + Mod_BuildTextureVectorsFromNormals(0, rsurface_model->surfmesh.num_vertices, rsurface_model->surfmesh.num_triangles, rsurface_array_vertex3f, rsurface_model->surfmesh.data_texcoordtexture2f, rsurface_normal3f, rsurface_model->surfmesh.data_element3i, rsurface_array_svector3f, rsurface_array_tvector3f, r_smoothnormals_areaweighting.integer); + rsurface_svector3f = rsurface_array_svector3f; + rsurface_tvector3f = rsurface_array_tvector3f; } } else @@ -2510,7 +2509,8 @@ void RSurf_PrepareVerticesForBatch(const entity_render_t *ent, const texture_t * for (i = 0;i < 4;i++) VectorMAMAMAM(1, center, v[i][0], forward, v[i][1], right, v[i][2], up, rsurface_array_vertex3f + (surface->num_firstvertex+i+j) * 3); } - Mod_BuildTextureVectorsAndNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_array_vertex3f, rsurface_model->surfmesh.data_texcoordtexture2f, rsurface_model->surfmesh.data_element3i + surface->num_firsttriangle * 3, rsurface_array_svector3f, rsurface_array_tvector3f, rsurface_array_normal3f, r_smoothnormals_areaweighting.integer); + Mod_BuildNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_array_vertex3f, rsurface_model->surfmesh.data_element3i + surface->num_firsttriangle * 3, rsurface_array_normal3f, r_smoothnormals_areaweighting.integer); + Mod_BuildTextureVectorsFromNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_array_vertex3f, rsurface_model->surfmesh.data_texcoordtexture2f, rsurface_array_normal3f, rsurface_model->surfmesh.data_element3i + surface->num_firsttriangle * 3, rsurface_array_svector3f, rsurface_array_tvector3f, r_smoothnormals_areaweighting.integer); } rsurface_vertex3f = rsurface_array_vertex3f; rsurface_svector3f = rsurface_array_svector3f; diff --git a/model_alias.c b/model_alias.c index dd4bb31f..d8ebba5b 100644 --- a/model_alias.c +++ b/model_alias.c @@ -193,7 +193,8 @@ static void Mod_Alias_Mesh_CompileFrameZero(void) loadmodel->surfmesh.data_tvector3f = loadmodel->surfmesh.data_vertex3f + loadmodel->surfmesh.num_vertices * 6; loadmodel->surfmesh.data_normal3f = loadmodel->surfmesh.data_vertex3f + loadmodel->surfmesh.num_vertices * 9; Mod_Alias_GetMesh_Vertex3f(loadmodel, frameblend, loadmodel->surfmesh.data_vertex3f); - Mod_BuildTextureVectorsAndNormals(0, loadmodel->surfmesh.num_vertices, loadmodel->surfmesh.num_triangles, loadmodel->surfmesh.data_vertex3f, loadmodel->surfmesh.data_texcoordtexture2f, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.data_svector3f, loadmodel->surfmesh.data_tvector3f, loadmodel->surfmesh.data_normal3f, true); + Mod_BuildNormals(0, loadmodel->surfmesh.num_vertices, loadmodel->surfmesh.num_triangles, loadmodel->surfmesh.data_vertex3f, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.data_normal3f, true); + Mod_BuildTextureVectorsFromNormals(0, loadmodel->surfmesh.num_vertices, loadmodel->surfmesh.num_triangles, loadmodel->surfmesh.data_vertex3f, loadmodel->surfmesh.data_texcoordtexture2f, loadmodel->surfmesh.data_normal3f, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.data_svector3f, loadmodel->surfmesh.data_tvector3f, true); } static void Mod_MDLMD2MD3_TraceBox(model_t *model, int frame, trace_t *trace, const vec3_t start, const vec3_t boxmins, const vec3_t boxmaxs, const vec3_t end, int hitsupercontentsmask) diff --git a/model_brush.c b/model_brush.c index 68b18983..86c761f2 100644 --- a/model_brush.c +++ b/model_brush.c @@ -2132,7 +2132,8 @@ static void Mod_Q1BSP_LoadFaces(lump_t *l) } // compile additional data about the surface geometry - Mod_BuildTextureVectorsAndNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, loadmodel->surfmesh.data_vertex3f, loadmodel->surfmesh.data_texcoordtexture2f, (loadmodel->surfmesh.data_element3i + 3 * surface->num_firsttriangle), loadmodel->surfmesh.data_svector3f, loadmodel->surfmesh.data_tvector3f, loadmodel->surfmesh.data_normal3f, true); + Mod_BuildNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, loadmodel->surfmesh.data_vertex3f, (loadmodel->surfmesh.data_element3i + 3 * surface->num_firsttriangle), loadmodel->surfmesh.data_normal3f, true); + Mod_BuildTextureVectorsFromNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, loadmodel->surfmesh.data_vertex3f, loadmodel->surfmesh.data_texcoordtexture2f, loadmodel->surfmesh.data_normal3f, (loadmodel->surfmesh.data_element3i + 3 * surface->num_firsttriangle), loadmodel->surfmesh.data_svector3f, loadmodel->surfmesh.data_tvector3f, true); BoxFromPoints(surface->mins, surface->maxs, surface->num_vertices, (loadmodel->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)); // generate surface extents information @@ -4775,7 +4776,8 @@ static void Mod_Q3BSP_LoadFaces(lump_t *l) Con_Print("\n"); } // for per pixel lighting - Mod_BuildTextureVectorsAndNormals(out->num_firstvertex, out->num_vertices, out->num_triangles, loadmodel->surfmesh.data_vertex3f, loadmodel->surfmesh.data_texcoordtexture2f, (loadmodel->surfmesh.data_element3i + 3 * out->num_firsttriangle), loadmodel->surfmesh.data_svector3f, loadmodel->surfmesh.data_tvector3f, loadmodel->surfmesh.data_normal3f, true); + Mod_BuildNormals(out->num_firstvertex, out->num_vertices, out->num_triangles, loadmodel->surfmesh.data_vertex3f, (loadmodel->surfmesh.data_element3i + 3 * out->num_firsttriangle), loadmodel->surfmesh.data_normal3f, true); + Mod_BuildTextureVectorsFromNormals(out->num_firstvertex, out->num_vertices, out->num_triangles, loadmodel->surfmesh.data_vertex3f, loadmodel->surfmesh.data_texcoordtexture2f, loadmodel->surfmesh.data_normal3f, (loadmodel->surfmesh.data_element3i + 3 * out->num_firsttriangle), loadmodel->surfmesh.data_svector3f, loadmodel->surfmesh.data_tvector3f, true); // calculate a bounding box VectorClear(out->mins); VectorClear(out->maxs); diff --git a/model_shared.c b/model_shared.c index 92f7ea51..9bffa313 100644 --- a/model_shared.c +++ b/model_shared.c @@ -605,20 +605,16 @@ void Mod_BuildBumpVectors(const float *v0, const float *v1, const float *v2, con } // warning: this is a very expensive function! -void Mod_BuildTextureVectorsAndNormals(int firstvertex, int numvertices, int numtriangles, const float *vertex3f, const float *texcoord2f, const int *elements, float *svector3f, float *tvector3f, float *normal3f, qboolean areaweighting) +void Mod_BuildTextureVectorsFromNormals(int firstvertex, int numvertices, int numtriangles, const float *vertex3f, const float *texcoord2f, const float *normal3f, const int *elements, float *svector3f, float *tvector3f, qboolean areaweighting) { int i, tnum; - float sdir[3], tdir[3], normal[3], *v; - const float *v0, *v1, *v2, *tc0, *tc1, *tc2; + float sdir[3], tdir[3], normal[3], *sv, *tv; + const float *v0, *v1, *v2, *tc0, *tc1, *tc2, *n; float f, tangentcross[3], v10[3], v20[3], tc10[2], tc20[2]; const int *e; // clear the vectors - if (svector3f) - memset(svector3f + 3 * firstvertex, 0, numvertices * sizeof(float[3])); - if (tvector3f) - memset(tvector3f + 3 * firstvertex, 0, numvertices * sizeof(float[3])); - if (normal3f) - memset(normal3f + 3 * firstvertex, 0, numvertices * sizeof(float[3])); + memset(svector3f + 3 * firstvertex, 0, numvertices * sizeof(float[3])); + memset(tvector3f + 3 * firstvertex, 0, numvertices * sizeof(float[3])); // process each vertex of each triangle and accumulate the results for (tnum = 0, e = elements;tnum < numtriangles;tnum++, e += 3) { @@ -653,17 +649,6 @@ void Mod_BuildTextureVectorsAndNormals(int firstvertex, int numvertices, int num tdir[1] = tc10[0] * v20[1] - tc20[0] * v10[1]; tdir[2] = tc10[0] * v20[2] - tc20[0] * v10[2]; - // make the tangents completely perpendicular to the surface normal - // 12 multiply, 4 add, 6 subtract - f = DotProduct(sdir, normal); - sdir[0] -= f * normal[0]; - sdir[1] -= f * normal[1]; - sdir[2] -= f * normal[2]; - f = DotProduct(tdir, normal); - tdir[0] -= f * normal[0]; - tdir[1] -= f * normal[1]; - tdir[2] -= f * normal[2]; - // if texture is mapped the wrong way (counterclockwise), the tangents // have to be flipped, this is detected by calculating a normal from the // two tangents, and seeing if it is opposite the surface normal @@ -679,32 +664,25 @@ void Mod_BuildTextureVectorsAndNormals(int firstvertex, int numvertices, int num { VectorNormalize(sdir); VectorNormalize(tdir); - VectorNormalize(normal); } - if (svector3f) - for (i = 0;i < 3;i++) - VectorAdd(svector3f + e[i]*3, sdir, svector3f + e[i]*3); - if (tvector3f) - for (i = 0;i < 3;i++) - VectorAdd(tvector3f + e[i]*3, tdir, tvector3f + e[i]*3); - if (normal3f) - for (i = 0;i < 3;i++) - VectorAdd(normal3f + e[i]*3, normal, normal3f + e[i]*3); + for (i = 0;i < 3;i++) + { + VectorAdd(svector3f + e[i]*3, sdir, svector3f + e[i]*3); + VectorAdd(tvector3f + e[i]*3, tdir, tvector3f + e[i]*3); + } + } + // make the tangents completely perpendicular to the surface normal, and + // then normalize them + // 16 assignments, 2 divide, 2 sqrt, 2 negates, 14 adds, 24 multiplies + for (i = 0, sv = svector3f + 3 * firstvertex, tv = tvector3f + 3 * firstvertex, n = normal3f + 3 * firstvertex;i < numvertices;i++, sv += 3, tv += 3, n += 3) + { + f = -DotProduct(sv, n); + VectorMA(sv, f, n, sv); + VectorNormalize(sv); + f = -DotProduct(tv, n); + VectorMA(tv, f, n, tv); + VectorNormalize(tv); } - // now we could divide the vectors by the number of averaged values on - // each vertex... but instead normalize them - // 4 assignments, 1 divide, 1 sqrt, 2 adds, 6 multiplies - if (svector3f) - for (i = 0, v = svector3f + 3 * firstvertex;i < numvertices;i++, v += 3) - VectorNormalize(v); - // 4 assignments, 1 divide, 1 sqrt, 2 adds, 6 multiplies - if (tvector3f) - for (i = 0, v = tvector3f + 3 * firstvertex;i < numvertices;i++, v += 3) - VectorNormalize(v); - // 4 assignments, 1 divide, 1 sqrt, 2 adds, 6 multiplies - if (normal3f) - for (i = 0, v = normal3f + 3 * firstvertex;i < numvertices;i++, v += 3) - VectorNormalize(v); } void Mod_AllocSurfMesh(mempool_t *mempool, int numvertices, int numtriangles, qboolean lightmapoffsets, qboolean vertexcolors, qboolean neighbors) diff --git a/model_shared.h b/model_shared.h index e1fc004a..94619937 100644 --- a/model_shared.h +++ b/model_shared.h @@ -616,7 +616,7 @@ int Mod_BuildVertexRemapTableFromElements(int numelements, const int *elements, void Mod_BuildTriangleNeighbors(int *neighbors, const int *elements, int numtriangles); void Mod_ValidateElements(int *elements, int numtriangles, int firstvertex, int numverts, const char *filename, int fileline); void Mod_BuildNormals(int firstvertex, int numvertices, int numtriangles, const float *vertex3f, const int *elements, float *normal3f, qboolean areaweighting); -void Mod_BuildTextureVectorsAndNormals(int firstvertex, int numvertices, int numtriangles, const float *vertex, const float *texcoord, const int *elements, float *svectors, float *tvectors, float *normals, qboolean areaweighting); +void Mod_BuildTextureVectorsFromNormals(int firstvertex, int numvertices, int numtriangles, const float *vertex3f, const float *texcoord2f, const float *normal3f, const int *elements, float *svector3f, float *tvector3f, qboolean areaweighting); void Mod_AllocSurfMesh(mempool_t *mempool, int numvertices, int numtriangles, qboolean lightmapoffsets, qboolean vertexcolors, qboolean neighbors); -- 2.39.2