]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - model_alias.c
tell QC about pixelheight too
[xonotic/darkplaces.git] / model_alias.c
index 3bf86ea937a2d17d8ace793da91f00c68e03f05f..2cd55b36195ca06ae9b2d804bca81b1147d31456 100644 (file)
@@ -94,6 +94,7 @@ void Mod_Skeletal_AnimateVertices(const dp_model_t *model, const frameblend_t *f
        // blend the vertex bone weights
        // special case for the extremely common wf[0] == 1 because it saves 3 multiplies per array when compared to the other case (w[0] is always 1 if only one bone controls this vertex, artists only use multiple bones for certain special cases)
        // special case for the first bone because it avoids the need to memset the arrays before filling
+       if (vertex3f)
        {
                const float *v = model->surfmesh.data_vertex3f;
                const int *wi = model->surfmesh.data_vertexweightindex4i;
@@ -243,23 +244,26 @@ void Mod_MD3_AnimateVertices(const dp_model_t *model, const frameblend_t *frameb
        for (blendnum = 0;blendnum < numblends;blendnum++)
        {
                const md3vertex_t *verts = model->surfmesh.data_morphmd3vertex + numverts * frameblend[blendnum].subframe;
-               float scale = frameblend[blendnum].lerp * (1.0f / 64.0f);
-               if (blendnum == 0)
+               if (vertex3f)
                {
-                       for (i = 0;i < numverts;i++)
+                       float scale = frameblend[blendnum].lerp * (1.0f / 64.0f);
+                       if (blendnum == 0)
                        {
-                               vertex3f[i * 3 + 0] = verts[i].origin[0] * scale;
-                               vertex3f[i * 3 + 1] = verts[i].origin[1] * scale;
-                               vertex3f[i * 3 + 2] = verts[i].origin[2] * scale;
+                               for (i = 0;i < numverts;i++)
+                               {
+                                       vertex3f[i * 3 + 0] = verts[i].origin[0] * scale;
+                                       vertex3f[i * 3 + 1] = verts[i].origin[1] * scale;
+                                       vertex3f[i * 3 + 2] = verts[i].origin[2] * scale;
+                               }
                        }
-               }
-               else
-               {
-                       for (i = 0;i < numverts;i++)
+                       else
                        {
-                               vertex3f[i * 3 + 0] += verts[i].origin[0] * scale;
-                               vertex3f[i * 3 + 1] += verts[i].origin[1] * scale;
-                               vertex3f[i * 3 + 2] += verts[i].origin[2] * scale;
+                               for (i = 0;i < numverts;i++)
+                               {
+                                       vertex3f[i * 3 + 0] += verts[i].origin[0] * scale;
+                                       vertex3f[i * 3 + 1] += verts[i].origin[1] * scale;
+                                       vertex3f[i * 3 + 2] += verts[i].origin[2] * scale;
+                               }
                        }
                }
                // the yaw and pitch stored in md3 models are 8bit quantized angles
@@ -336,27 +340,30 @@ void Mod_MDL_AnimateVertices(const dp_model_t *model, const frameblend_t *frameb
        for (blendnum = 0;blendnum < numblends;blendnum++)
        {
                const trivertx_t *verts = model->surfmesh.data_morphmdlvertex + numverts * frameblend[blendnum].subframe;
-               float scale[3];
-               if (model->surfmesh.data_morphmd2framesize6f)
-                       VectorScale(model->surfmesh.data_morphmd2framesize6f + frameblend[blendnum].subframe * 6, frameblend[blendnum].lerp, scale);
-               else
-                       VectorScale(model->surfmesh.num_morphmdlframescale, frameblend[blendnum].lerp, scale);
-               if (blendnum == 0)
+               if (vertex3f)
                {
-                       for (i = 0;i < numverts;i++)
+                       float scale[3];
+                       if (model->surfmesh.data_morphmd2framesize6f)
+                               VectorScale(model->surfmesh.data_morphmd2framesize6f + frameblend[blendnum].subframe * 6, frameblend[blendnum].lerp, scale);
+                       else
+                               VectorScale(model->surfmesh.num_morphmdlframescale, frameblend[blendnum].lerp, scale);
+                       if (blendnum == 0)
                        {
-                               vertex3f[i * 3 + 0] = translate[0] + verts[i].v[0] * scale[0];
-                               vertex3f[i * 3 + 1] = translate[1] + verts[i].v[1] * scale[1];
-                               vertex3f[i * 3 + 2] = translate[2] + verts[i].v[2] * scale[2];
+                               for (i = 0;i < numverts;i++)
+                               {
+                                       vertex3f[i * 3 + 0] = translate[0] + verts[i].v[0] * scale[0];
+                                       vertex3f[i * 3 + 1] = translate[1] + verts[i].v[1] * scale[1];
+                                       vertex3f[i * 3 + 2] = translate[2] + verts[i].v[2] * scale[2];
+                               }
                        }
-               }
-               else
-               {
-                       for (i = 0;i < numverts;i++)
+                       else
                        {
-                               vertex3f[i * 3 + 0] += verts[i].v[0] * scale[0];
-                               vertex3f[i * 3 + 1] += verts[i].v[1] * scale[1];
-                               vertex3f[i * 3 + 2] += verts[i].v[2] * scale[2];
+                               for (i = 0;i < numverts;i++)
+                               {
+                                       vertex3f[i * 3 + 0] += verts[i].v[0] * scale[0];
+                                       vertex3f[i * 3 + 1] += verts[i].v[1] * scale[1];
+                                       vertex3f[i * 3 + 2] += verts[i].v[2] * scale[2];
+                               }
                        }
                }
                // the vertex normals in mdl models are an index into a table of
@@ -498,10 +505,13 @@ static void Mod_BuildBaseBonePoses(void)
 {
        int i, k;
        double scale;
-       float *basebonepose = (float *) Mem_Alloc(tempmempool, loadmodel->num_bones * sizeof(float[12]));
+       float *basebonepose;
        float *in12f = loadmodel->data_poses;
-       float *out12f = basebonepose;
+       float *out12f;
        float *outinv12f = loadmodel->data_baseboneposeinverse;
+       if (!loadmodel->num_bones)
+               return;
+       out12f = basebonepose = (float *) Mem_Alloc(tempmempool, loadmodel->num_bones * sizeof(float[12]));
        for (i = 0;i < loadmodel->num_bones;i++, in12f += 12, out12f += 12, outinv12f += 12)
        {
                if (loadmodel->data_bones[i].parent >= 0)
@@ -613,7 +623,7 @@ static void Mod_Alias_MorphMesh_CompileFrames(void)
        {
                frameblend[0].subframe = i;
                loadmodel->AnimateVertices(loadmodel, frameblend, loadmodel->surfmesh.data_vertex3f, loadmodel->surfmesh.data_normal3f, NULL, NULL);
-               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, r_smoothnormals_areaweighting.integer);
+               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, r_smoothnormals_areaweighting.integer != 0);
                // encode the svector and tvector in 3 byte format for permanent storage
                for (j = 0;j < loadmodel->surfmesh.num_vertices;j++)
                {
@@ -623,10 +633,9 @@ static void Mod_Alias_MorphMesh_CompileFrames(void)
        }
 }
 
-static void Mod_MDLMD2MD3_TraceBox(dp_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)
+static void Mod_MDLMD2MD3_TraceLine(dp_model_t *model, int frame, trace_t *trace, const vec3_t start, const vec3_t end, int hitsupercontentsmask)
 {
        int i;
-       vec3_t shiftstart, shiftend;
        float segmentmins[3], segmentmaxs[3];
        frameblend_t frameblend[MAX_FRAMEBLENDS];
        msurface_t *surface;
@@ -646,52 +655,78 @@ static void Mod_MDLMD2MD3_TraceBox(dp_model_t *model, int frame, trace_t *trace,
                maxvertices = (model->surfmesh.num_vertices + 255) & ~255;
                vertex3f = (float *)Z_Malloc(maxvertices * sizeof(float[3]));
        }
+       segmentmins[0] = min(start[0], end[0]) - 1;
+       segmentmins[1] = min(start[1], end[1]) - 1;
+       segmentmins[2] = min(start[2], end[2]) - 1;
+       segmentmaxs[0] = max(start[0], end[0]) + 1;
+       segmentmaxs[1] = max(start[1], end[1]) + 1;
+       segmentmaxs[2] = max(start[2], end[2]) + 1;
+       for (i = 0, surface = model->data_surfaces;i < model->num_surfaces;i++, surface++)
+       {
+               model->AnimateVertices(model, frameblend, vertex3f, NULL, NULL, NULL);
+               Collision_TraceLineTriangleMeshFloat(trace, start, end, model->surfmesh.num_triangles, model->surfmesh.data_element3i, vertex3f, 0, NULL, SUPERCONTENTS_SOLID | (surface->texture->basematerialflags & MATERIALFLAGMASK_TRANSLUCENT ? 0 : SUPERCONTENTS_OPAQUE), 0, surface->texture, segmentmins, segmentmaxs);
+       }
+}
+
+static void Mod_MDLMD2MD3_TraceBox(dp_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)
+{
+       int i;
+       vec3_t shiftstart, shiftend;
+       float segmentmins[3], segmentmaxs[3];
+       frameblend_t frameblend[MAX_FRAMEBLENDS];
+       msurface_t *surface;
+       static int maxvertices = 0;
+       static float *vertex3f = NULL;
+       colbrushf_t *thisbrush_start, *thisbrush_end;
+       vec3_t boxstartmins, boxstartmaxs, boxendmins, boxendmaxs;
+
        if (VectorCompare(boxmins, boxmaxs))
        {
-               // line trace
                VectorAdd(start, boxmins, shiftstart);
-               VectorAdd(shiftend, boxmins, shiftend);
-               segmentmins[0] = min(shiftstart[0], shiftend[0]) - 1;
-               segmentmins[1] = min(shiftstart[1], shiftend[1]) - 1;
-               segmentmins[2] = min(shiftstart[2], shiftend[2]) - 1;
-               segmentmaxs[0] = max(shiftstart[0], shiftend[0]) + 1;
-               segmentmaxs[1] = max(shiftstart[1], shiftend[1]) + 1;
-               segmentmaxs[2] = max(shiftstart[2], shiftend[2]) + 1;
-               for (i = 0, surface = model->data_surfaces;i < model->num_surfaces;i++, surface++)
-               {
-                       model->AnimateVertices(model, frameblend, vertex3f, NULL, NULL, NULL);
-                       Collision_TraceLineTriangleMeshFloat(trace, shiftstart, shiftend, model->surfmesh.num_triangles, model->surfmesh.data_element3i, vertex3f, 0, NULL, SUPERCONTENTS_SOLID | (surface->texture->basematerialflags & MATERIALFLAGMASK_TRANSLUCENT ? 0 : SUPERCONTENTS_OPAQUE), 0, surface->texture, segmentmins, segmentmaxs);
-               }
+               VectorAdd(end, boxmins, shiftend);
+               Mod_MDLMD2MD3_TraceLine(model, frame, trace, start, end, hitsupercontentsmask);
+               VectorSubtract(trace->endpos, boxmins, trace->endpos);
+               return;
        }
-       else
+
+       // box trace, performed as brush trace
+       memset(trace, 0, sizeof(*trace));
+       trace->fraction = 1;
+       trace->realfraction = 1;
+       trace->hitsupercontentsmask = hitsupercontentsmask;
+       memset(frameblend, 0, sizeof(frameblend));
+       frameblend[0].subframe = frame;
+       frameblend[0].lerp = 1;
+       if (maxvertices < model->surfmesh.num_vertices)
        {
-               // box trace, performed as brush trace
-               colbrushf_t *thisbrush_start, *thisbrush_end;
-               vec3_t boxstartmins, boxstartmaxs, boxendmins, boxendmaxs;
-               segmentmins[0] = min(start[0], end[0]) + boxmins[0] - 1;
-               segmentmins[1] = min(start[1], end[1]) + boxmins[1] - 1;
-               segmentmins[2] = min(start[2], end[2]) + boxmins[2] - 1;
-               segmentmaxs[0] = max(start[0], end[0]) + boxmaxs[0] + 1;
-               segmentmaxs[1] = max(start[1], end[1]) + boxmaxs[1] + 1;
-               segmentmaxs[2] = max(start[2], end[2]) + boxmaxs[2] + 1;
-               VectorAdd(start, boxmins, boxstartmins);
-               VectorAdd(start, boxmaxs, boxstartmaxs);
-               VectorAdd(end, boxmins, boxendmins);
-               VectorAdd(end, boxmaxs, boxendmaxs);
-               thisbrush_start = Collision_BrushForBox(&identitymatrix, boxstartmins, boxstartmaxs, 0, 0, NULL);
-               thisbrush_end = Collision_BrushForBox(&identitymatrix, boxendmins, boxendmaxs, 0, 0, NULL);
-               for (i = 0, surface = model->data_surfaces;i < model->num_surfaces;i++, surface++)
+               if (vertex3f)
+                       Z_Free(vertex3f);
+               maxvertices = (model->surfmesh.num_vertices + 255) & ~255;
+               vertex3f = (float *)Z_Malloc(maxvertices * sizeof(float[3]));
+       }
+       segmentmins[0] = min(start[0], end[0]) + boxmins[0] - 1;
+       segmentmins[1] = min(start[1], end[1]) + boxmins[1] - 1;
+       segmentmins[2] = min(start[2], end[2]) + boxmins[2] - 1;
+       segmentmaxs[0] = max(start[0], end[0]) + boxmaxs[0] + 1;
+       segmentmaxs[1] = max(start[1], end[1]) + boxmaxs[1] + 1;
+       segmentmaxs[2] = max(start[2], end[2]) + boxmaxs[2] + 1;
+       VectorAdd(start, boxmins, boxstartmins);
+       VectorAdd(start, boxmaxs, boxstartmaxs);
+       VectorAdd(end, boxmins, boxendmins);
+       VectorAdd(end, boxmaxs, boxendmaxs);
+       thisbrush_start = Collision_BrushForBox(&identitymatrix, boxstartmins, boxstartmaxs, 0, 0, NULL);
+       thisbrush_end = Collision_BrushForBox(&identitymatrix, boxendmins, boxendmaxs, 0, 0, NULL);
+       for (i = 0, surface = model->data_surfaces;i < model->num_surfaces;i++, surface++)
+       {
+               if (maxvertices < model->surfmesh.num_vertices)
                {
-                       if (maxvertices < model->surfmesh.num_vertices)
-                       {
-                               if (vertex3f)
-                                       Z_Free(vertex3f);
-                               maxvertices = (model->surfmesh.num_vertices + 255) & ~255;
-                               vertex3f = (float *)Z_Malloc(maxvertices * sizeof(float[3]));
-                       }
-                       model->AnimateVertices(model, frameblend, vertex3f, NULL, NULL, NULL);
-                       Collision_TraceBrushTriangleMeshFloat(trace, thisbrush_start, thisbrush_end, model->surfmesh.num_triangles, model->surfmesh.data_element3i, vertex3f, 0, NULL, SUPERCONTENTS_SOLID | (surface->texture->basematerialflags & MATERIALFLAGMASK_TRANSLUCENT ? 0 : SUPERCONTENTS_OPAQUE), 0, surface->texture, segmentmins, segmentmaxs);
+                       if (vertex3f)
+                               Z_Free(vertex3f);
+                       maxvertices = (model->surfmesh.num_vertices + 255) & ~255;
+                       vertex3f = (float *)Z_Malloc(maxvertices * sizeof(float[3]));
                }
+               model->AnimateVertices(model, frameblend, vertex3f, NULL, NULL, NULL);
+               Collision_TraceBrushTriangleMeshFloat(trace, thisbrush_start, thisbrush_end, model->surfmesh.num_triangles, model->surfmesh.data_element3i, vertex3f, 0, NULL, SUPERCONTENTS_SOLID | (surface->texture->basematerialflags & MATERIALFLAGMASK_TRANSLUCENT ? 0 : SUPERCONTENTS_OPAQUE), 0, surface->texture, segmentmins, segmentmaxs);
        }
 }
 
@@ -876,10 +911,13 @@ void Mod_IDP0_Load(dp_model_t *mod, void *buffer, void *bufferend)
        loadmodel->Draw = R_Q1BSP_Draw;
        loadmodel->DrawDepth = R_Q1BSP_DrawDepth;
        loadmodel->DrawDebug = R_Q1BSP_DrawDebug;
+       loadmodel->CompileShadowMap = R_Q1BSP_CompileShadowMap;
+       loadmodel->DrawShadowMap = R_Q1BSP_DrawShadowMap;
        loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume;
        loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
        loadmodel->DrawLight = R_Q1BSP_DrawLight;
        loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox;
+       loadmodel->TraceLine = Mod_MDLMD2MD3_TraceLine;
        loadmodel->PointSuperContents = NULL;
 
        loadmodel->num_surfaces = 1;
@@ -1206,10 +1244,13 @@ void Mod_IDP2_Load(dp_model_t *mod, void *buffer, void *bufferend)
        loadmodel->Draw = R_Q1BSP_Draw;
        loadmodel->DrawDepth = R_Q1BSP_DrawDepth;
        loadmodel->DrawDebug = R_Q1BSP_DrawDebug;
+       loadmodel->CompileShadowMap = R_Q1BSP_CompileShadowMap;
+       loadmodel->DrawShadowMap = R_Q1BSP_DrawShadowMap;
        loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume;
        loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
        loadmodel->DrawLight = R_Q1BSP_DrawLight;
        loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox;
+       loadmodel->TraceLine = Mod_MDLMD2MD3_TraceLine;
        loadmodel->PointSuperContents = NULL;
 
        if (LittleLong(pinmodel->num_tris) < 1 || LittleLong(pinmodel->num_tris) > 65536)
@@ -1446,10 +1487,13 @@ void Mod_IDP3_Load(dp_model_t *mod, void *buffer, void *bufferend)
        loadmodel->Draw = R_Q1BSP_Draw;
        loadmodel->DrawDepth = R_Q1BSP_DrawDepth;
        loadmodel->DrawDebug = R_Q1BSP_DrawDebug;
+       loadmodel->CompileShadowMap = R_Q1BSP_CompileShadowMap;
+       loadmodel->DrawShadowMap = R_Q1BSP_DrawShadowMap;
        loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume;
        loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
        loadmodel->DrawLight = R_Q1BSP_DrawLight;
        loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox;
+       loadmodel->TraceLine = Mod_MDLMD2MD3_TraceLine;
        loadmodel->PointSuperContents = NULL;
        loadmodel->synctype = ST_RAND;
        // convert model flags to EF flags (MF_ROCKET becomes EF_ROCKET, etc)
@@ -1659,10 +1703,13 @@ void Mod_ZYMOTICMODEL_Load(dp_model_t *mod, void *buffer, void *bufferend)
        loadmodel->Draw = R_Q1BSP_Draw;
        loadmodel->DrawDepth = R_Q1BSP_DrawDepth;
        loadmodel->DrawDebug = R_Q1BSP_DrawDebug;
+       loadmodel->CompileShadowMap = R_Q1BSP_CompileShadowMap;
+       loadmodel->DrawShadowMap = R_Q1BSP_DrawShadowMap;
        loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume;
        loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
        loadmodel->DrawLight = R_Q1BSP_DrawLight;
        loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox;
+       loadmodel->TraceLine = Mod_MDLMD2MD3_TraceLine;
        loadmodel->PointSuperContents = NULL;
 
        loadmodel->numframes = pheader->numscenes;
@@ -1961,10 +2008,13 @@ void Mod_DARKPLACESMODEL_Load(dp_model_t *mod, void *buffer, void *bufferend)
        loadmodel->Draw = R_Q1BSP_Draw;
        loadmodel->DrawDepth = R_Q1BSP_DrawDepth;
        loadmodel->DrawDebug = R_Q1BSP_DrawDebug;
+       loadmodel->CompileShadowMap = R_Q1BSP_CompileShadowMap;
+       loadmodel->DrawShadowMap = R_Q1BSP_DrawShadowMap;
        loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume;
        loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
        loadmodel->DrawLight = R_Q1BSP_DrawLight;
        loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox;
+       loadmodel->TraceLine = Mod_MDLMD2MD3_TraceLine;
        loadmodel->PointSuperContents = NULL;
 
        // model bbox
@@ -2240,10 +2290,13 @@ void Mod_PSKMODEL_Load(dp_model_t *mod, void *buffer, void *bufferend)
        loadmodel->Draw = R_Q1BSP_Draw;
        loadmodel->DrawDepth = R_Q1BSP_DrawDepth;
        loadmodel->DrawDebug = R_Q1BSP_DrawDebug;
+       loadmodel->CompileShadowMap = R_Q1BSP_CompileShadowMap;
+       loadmodel->DrawShadowMap = R_Q1BSP_DrawShadowMap;
        loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume;
        loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
        loadmodel->DrawLight = R_Q1BSP_DrawLight;
        loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox;
+       loadmodel->TraceLine = Mod_MDLMD2MD3_TraceLine;
        loadmodel->PointSuperContents = NULL;
        loadmodel->synctype = ST_RAND;
 
@@ -2806,10 +2859,13 @@ void Mod_OBJ_Load(dp_model_t *mod, void *buffer, void *bufferend)
        loadmodel->Draw = R_Q1BSP_Draw;
        loadmodel->DrawDepth = R_Q1BSP_DrawDepth;
        loadmodel->DrawDebug = R_Q1BSP_DrawDebug;
+       loadmodel->CompileShadowMap = R_Q1BSP_CompileShadowMap;
+       loadmodel->DrawShadowMap = R_Q1BSP_DrawShadowMap;
        loadmodel->CompileShadowVolume = R_Q1BSP_CompileShadowVolume;
        loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
        loadmodel->DrawLight = R_Q1BSP_DrawLight;
        loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox;
+       loadmodel->TraceLine = Mod_MDLMD2MD3_TraceLine;
        loadmodel->PointSuperContents = NULL;
 
        // parse the OBJ text now