]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - model_shared.c
Merged CL_RocketTrail2 into CL_RocketTrail.
[xonotic/darkplaces.git] / model_shared.c
index 369802d5a76536b3eff49993dddc6f97ab2d8039..f2a0ccc7780416dd52864da80a2a6b5f52584459 100644 (file)
@@ -297,7 +297,7 @@ static model_t *Mod_LoadModel(model_t *mod, qboolean crash, qboolean checkdisk,
        VectorSet(mod->rotatedmaxs, mod->radius, mod->radius, mod->radius);
 
        // all models use memory, so allocate a memory pool
-       mod->mempool = Mem_AllocPool(mod->name);
+       mod->mempool = Mem_AllocPool(mod->name, 0, NULL);
        // all models load textures, so allocate a texture pool
        if (cls.state != ca_dedicated)
                mod->texturepool = R_AllocTexturePool();
@@ -489,6 +489,20 @@ static void Mod_Precache(void)
                Con_Print("usage: modelprecache <filename>\n");
 }
 
+int Mod_BuildVertexRemapTableFromElements(int numelements, const int *elements, int numvertices, int *remapvertices)
+{
+       int i, count;
+       qbyte *used;
+       used = Mem_Alloc(tempmempool, numvertices);
+       memset(used, 0, numvertices);
+       for (i = 0;i < numelements;i++)
+               used[elements[i]] = 1;
+       for (i = 0, count = 0;i < numvertices;i++)
+               remapvertices[i] = used[i] ? count++ : -1;
+       Mem_Free(used);
+       return count;
+}
+
 #if 1
 // fast way, using an edge hash
 #define TRIANGLEEDGEHASH 1024
@@ -608,7 +622,7 @@ void Mod_ValidateElements(const int *elements, int numtriangles, int numverts, c
 
 void Mod_BuildBumpVectors(const float *v0, const float *v1, const float *v2, const float *tc0, const float *tc1, const float *tc2, float *svector3f, float *tvector3f, float *normal3f)
 {
-       float f;
+       float f, tangentcross[3];
        normal3f[0] = (v1[1] - v0[1]) * (v2[2] - v0[2]) - (v1[2] - v0[2]) * (v2[1] - v0[1]);
        normal3f[1] = (v1[2] - v0[2]) * (v2[0] - v0[0]) - (v1[0] - v0[0]) * (v2[2] - v0[2]);
        normal3f[2] = (v1[0] - v0[0]) * (v2[1] - v0[1]) - (v1[1] - v0[1]) * (v2[0] - v0[0]);
@@ -626,6 +640,13 @@ void Mod_BuildBumpVectors(const float *v0, const float *v1, const float *v2, con
        f = -DotProduct(svector3f, normal3f);
        VectorMA(svector3f, f, normal3f, svector3f);
        VectorNormalize(svector3f);
+       CrossProduct(tvector3f, svector3f, tangentcross);
+       // 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
+       if (DotProduct(tangentcross, normal3f) < 0)
+       {
+               VectorNegate(svector3f, svector3f);
+               VectorNegate(tvector3f, tvector3f);
+       }
 }
 
 // warning: this is an expensive function!
@@ -1078,7 +1099,7 @@ skinfile_t *Mod_LoadSkinFiles(void)
        int i, words, numtags, line, tagsetsused = false, wordsoverflow;
        char *text;
        const char *data;
-       skinfile_t *skinfile, *first = NULL;
+       skinfile_t *skinfile = NULL, *first = NULL;
        skinfileitem_t *skinfileitem;
        char word[10][MAX_QPATH];
        overridetagnameset_t tagsets[MAX_SKINS];
@@ -1104,9 +1125,20 @@ tag_torso,
        for (i = 0;i < MAX_SKINS && (data = text = FS_LoadFile(va("%s_%i.skin", loadmodel->name, i), tempmempool, true));i++)
        {
                numtags = 0;
-               skinfile = Mem_Alloc(tempmempool, sizeof(skinfile_t));
-               skinfile->next = first;
-               first = skinfile;
+
+               // If it's the first file we parse
+               if (skinfile == NULL)
+               {
+                       skinfile = Mem_Alloc(tempmempool, sizeof(skinfile_t));
+                       first = skinfile;
+               }
+               else
+               {
+                       skinfile->next = Mem_Alloc(tempmempool, sizeof(skinfile_t));
+                       skinfile = skinfile->next;
+               }
+               skinfile->next = NULL;
+
                for(line = 0;;line++)
                {
                        // parse line