]> git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
fix model scaling on old zym and dpm files where the root bone was
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 9 Jan 2010 20:47:13 +0000 (20:47 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 9 Jan 2010 20:47:13 +0000 (20:47 +0000)
scaled

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9824 d7cf8633-e32d-0410-b094-e92efae38249

model_alias.c

index 74d63c742956e9ce1a29e9bdae8bfdaaa9cbb67e..f4ba94f1e2a8bf3fc477dbea697488752395a5a3 100644 (file)
@@ -1687,7 +1687,7 @@ void Mod_ZYMOTICMODEL_Load(dp_model_t *mod, void *buffer, void *bufferend)
        zymtype1header_t *pinmodel, *pheader;
        unsigned char *pbase;
        int i, j, k, numposes, meshvertices, meshtriangles, *bonecount, *vertbonecounts, count, *renderlist, *renderlistend, *outelements;
-       float modelradius, corner[2], *poses, *intexcoord2f, *outtexcoord2f, *bonepose, f, biggestorigin;
+       float modelradius, corner[2], *poses, *intexcoord2f, *outtexcoord2f, *bonepose, f, biggestorigin, tempvec[3], modelscale;
        zymvertex_t *verts, *vertdata;
        zymscene_t *scene;
        zymbone_t *bone;
@@ -1882,6 +1882,11 @@ void Mod_ZYMOTICMODEL_Load(dp_model_t *mod, void *buffer, void *bufferend)
 
        //zymlump_t lump_poses; // float pose[numposes][numbones][3][4]; // animation data
        poses = (float *) (pheader->lump_poses.start + pbase);
+       // figure out scale of model from root bone, for compatibility with old zmodel versions
+       tempvec[0] = BigFloat(poses[0]);
+       tempvec[1] = BigFloat(poses[1]);
+       tempvec[2] = BigFloat(poses[2]);
+       modelscale = VectorLength(tempvec);
        biggestorigin = 0;
        for (i = 0;i < loadmodel->num_bones * numposes * 12;i++)
        {
@@ -1890,14 +1895,31 @@ void Mod_ZYMOTICMODEL_Load(dp_model_t *mod, void *buffer, void *bufferend)
        }
        loadmodel->num_posescale = biggestorigin / 32767.0f;
        loadmodel->num_poseinvscale = 1.0f / loadmodel->num_posescale;
-       for (i = 0;i < loadmodel->num_bones * numposes;i++)
+       for (i = 0;i < numposes;i++)
        {
-               float pose[12];
-               matrix4x4_t posematrix;
-               for (j = 0;j < 12;j++)
-                       pose[j] = BigFloat(poses[i*12+j]);
-               Matrix4x4_FromArray12FloatD3D(&posematrix, pose);
-               Matrix4x4_ToBonePose6s(&posematrix, loadmodel->num_poseinvscale, loadmodel->data_poses6s + 6*i);
+               const float *frameposes = (float *) (pheader->lump_poses.start + pbase) + 12*i*loadmodel->num_bones;
+               for (j = 0;j < loadmodel->num_bones;j++)
+               {
+                       float pose[12];
+                       matrix4x4_t posematrix;
+                       for (k = 0;k < 12;k++)
+                               pose[k] = BigFloat(frameposes[j*12+k]);
+                       //if (j < loadmodel->num_bones)
+                       //      Con_Printf("%s: bone %i = %f %f %f %f : %f %f %f %f : %f %f %f %f : scale = %f\n", loadmodel->name, j, pose[0], pose[1], pose[2], pose[3], pose[4], pose[5], pose[6], pose[7], pose[8], pose[9], pose[10], pose[11], VectorLength(pose));
+                       // scale child bones to match the root scale
+                       if (loadmodel->data_bones[j].parent >= 0)
+                       {
+                               pose[3] *= modelscale;
+                               pose[7] *= modelscale;
+                               pose[11] *= modelscale;
+                       }
+                       // normalize rotation matrix
+                       VectorNormalize(pose + 0);
+                       VectorNormalize(pose + 4);
+                       VectorNormalize(pose + 8);
+                       Matrix4x4_FromArray12FloatD3D(&posematrix, pose);
+                       Matrix4x4_ToBonePose6s(&posematrix, loadmodel->num_poseinvscale, loadmodel->data_poses6s + 6*(i*loadmodel->num_bones+j));
+               }
        }
 
        //zymlump_t lump_verts; // zymvertex_t vert[numvertices]; // see vertex struct
@@ -2034,7 +2056,7 @@ void Mod_DARKPLACESMODEL_Load(dp_model_t *mod, void *buffer, void *bufferend)
        skinfile_t *skinfiles;
        unsigned char *data;
        float *bonepose;
-       float biggestorigin;
+       float biggestorigin, tempvec[3], modelscale;
        float f;
        float *poses;
 
@@ -2177,10 +2199,15 @@ void Mod_DARKPLACESMODEL_Load(dp_model_t *mod, void *buffer, void *bufferend)
 
        // load the frames
        frames = (dpmframe_t *) (pbase + pheader->ofs_frames);
+       // figure out scale of model from root bone, for compatibility with old dpmodel versions
+       poses = (float *) (pbase + BigLong(frames[0].ofs_bonepositions));
+       tempvec[0] = BigFloat(poses[0]);
+       tempvec[1] = BigFloat(poses[1]);
+       tempvec[2] = BigFloat(poses[2]);
+       modelscale = VectorLength(tempvec);
        biggestorigin = 0;
        for (i = 0;i < loadmodel->numframes;i++)
        {
-               const float *poses;
                memcpy(loadmodel->animscenes[i].name, frames[i].name, sizeof(frames[i].name));
                loadmodel->animscenes[i].firstframe = i;
                loadmodel->animscenes[i].framecount = 1;
@@ -2199,13 +2226,24 @@ void Mod_DARKPLACESMODEL_Load(dp_model_t *mod, void *buffer, void *bufferend)
        loadmodel->num_poseinvscale = 1.0f / loadmodel->num_posescale;
        for (i = 0;i < loadmodel->numframes;i++)
        {
-               poses = (float *) (pbase + BigLong(frames[i].ofs_bonepositions));
+               const float *frameposes = (float *) (pbase + BigLong(frames[i].ofs_bonepositions));
                for (j = 0;j < loadmodel->num_bones;j++)
                {
                        float pose[12];
                        matrix4x4_t posematrix;
                        for (k = 0;k < 12;k++)
-                               pose[k] = BigFloat(poses[j*12+k]);
+                               pose[k] = BigFloat(frameposes[j*12+k]);
+                       // scale child bones to match the root scale
+                       if (loadmodel->data_bones[j].parent >= 0)
+                       {
+                               pose[3] *= modelscale;
+                               pose[7] *= modelscale;
+                               pose[11] *= modelscale;
+                       }
+                       // normalize rotation matrix
+                       VectorNormalize(pose + 0);
+                       VectorNormalize(pose + 4);
+                       VectorNormalize(pose + 8);
                        Matrix4x4_FromArray12FloatD3D(&posematrix, pose);
                        Matrix4x4_ToBonePose6s(&posematrix, loadmodel->num_poseinvscale, loadmodel->data_poses6s + 6*(i*loadmodel->num_bones+j));
                }