]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - model_alias.c
Removed collision_prefernudgedfraction cvar and trace.realfraction field, this has...
[xonotic/darkplaces.git] / model_alias.c
index 981188ea714dd1d16318ac652f6ed2693ed5a500..3da3b6202a0a54ee372fc1f50929af611d44b498 100644 (file)
@@ -62,6 +62,104 @@ void *Mod_Skeletal_AnimateVertices_AllocBuffers(size_t nbytes)
        return Mod_Skeletal_AnimateVertices_bonepose;
 }
 
+void Mod_Skeletal_BuildTransforms(const dp_model_t * RESTRICT model, const frameblend_t * RESTRICT frameblend, const skeleton_t *skeleton, float * RESTRICT bonepose, float * RESTRICT boneposerelative)
+{
+       int i, blends;
+       float m[12];
+
+       if (!bonepose)
+               bonepose = (float * RESTRICT) Mod_Skeletal_AnimateVertices_AllocBuffers(sizeof(float[12]) * model->num_bones);
+               
+       if (skeleton && !skeleton->relativetransforms)
+               skeleton = NULL;
+
+       // interpolate matrices
+       if (skeleton)
+       {
+               for (i = 0;i < model->num_bones;i++)
+               {
+                       Matrix4x4_ToArray12FloatD3D(&skeleton->relativetransforms[i], m);
+                       if (model->data_bones[i].parent >= 0)
+                               R_ConcatTransforms(bonepose + model->data_bones[i].parent * 12, m, bonepose + i * 12);
+                       else
+                               memcpy(bonepose + i * 12, m, sizeof(m));
+
+                       // create a relative deformation matrix to describe displacement
+                       // from the base mesh, which is used by the actual weighting
+                       R_ConcatTransforms(bonepose + i * 12, model->data_baseboneposeinverse + i * 12, boneposerelative + i * 12);
+               }
+       }
+       else
+       {
+               for (i = 0;i < model->num_bones;i++)
+               {
+                       // blend by transform each quaternion/translation into a dual-quaternion first, then blending
+                       const short * RESTRICT pose7s = model->data_poses7s + 7 * (frameblend[0].subframe * model->num_bones + i);
+                       float lerp = frameblend[0].lerp,
+                               tx = pose7s[0], ty = pose7s[1], tz = pose7s[2],
+                               rx = pose7s[3] * lerp,
+                               ry = pose7s[4] * lerp,
+                               rz = pose7s[5] * lerp,
+                               rw = pose7s[6] * lerp,
+                               dx = tx*rw + ty*rz - tz*ry,
+                               dy = -tx*rz + ty*rw + tz*rx,
+                               dz = tx*ry - ty*rx + tz*rw,
+                               dw = -tx*rx - ty*ry - tz*rz,
+                               scale, sx, sy, sz, sw;
+                       for (blends = 1;blends < MAX_FRAMEBLENDS && frameblend[blends].lerp > 0;blends++)
+                       {
+                               const short * RESTRICT pose7s = model->data_poses7s + 7 * (frameblend[blends].subframe * model->num_bones + i);
+                               float lerp = frameblend[blends].lerp,
+                                       tx = pose7s[0], ty = pose7s[1], tz = pose7s[2],
+                                       qx = pose7s[3], qy = pose7s[4], qz = pose7s[5], qw = pose7s[6];
+                               if(rx*qx + ry*qy + rz*qz + rw*qw < 0) lerp = -lerp;
+                               qx *= lerp;
+                               qy *= lerp;
+                               qz *= lerp;
+                               qw *= lerp;
+                               rx += qx;
+                               ry += qy;
+                               rz += qz;
+                               rw += qw;
+                               dx += tx*qw + ty*qz - tz*qy;
+                               dy += -tx*qz + ty*qw + tz*qx;
+                               dz += tx*qy - ty*qx + tz*qw;
+                               dw += -tx*qx - ty*qy - tz*qz;
+                       }
+                       // generate a matrix from the dual-quaternion, implicitly normalizing it in the process
+                       scale = 1.0f / (rx*rx + ry*ry + rz*rz + rw*rw);
+                       sx = rx * scale;
+                       sy = ry * scale;
+                       sz = rz * scale;
+                       sw = rw * scale;
+                       m[0] = sw*rw + sx*rx - sy*ry - sz*rz;
+                       m[1] = 2*(sx*ry - sw*rz);
+                       m[2] = 2*(sx*rz + sw*ry);
+                       m[3] = model->num_posescale*(dx*sw - dy*sz + dz*sy - dw*sx);
+                       m[4] = 2*(sx*ry + sw*rz);
+                       m[5] = sw*rw + sy*ry - sx*rx - sz*rz;
+                       m[6] = 2*(sy*rz - sw*rx);
+                       m[7] = model->num_posescale*(dx*sz + dy*sw - dz*sx - dw*sy);
+                       m[8] = 2*(sx*rz - sw*ry);
+                       m[9] = 2*(sy*rz + sw*rx);
+                       m[10] = sw*rw + sz*rz - sx*rx - sy*ry;
+                       m[11] = model->num_posescale*(dy*sx + dz*sw - dx*sy - dw*sz);
+                       if (i == r_skeletal_debugbone.integer)
+                               m[r_skeletal_debugbonecomponent.integer % 12] += r_skeletal_debugbonevalue.value;
+                       m[3] *= r_skeletal_debugtranslatex.value;
+                       m[7] *= r_skeletal_debugtranslatey.value;
+                       m[11] *= r_skeletal_debugtranslatez.value;
+                       if (model->data_bones[i].parent >= 0)
+                               R_ConcatTransforms(bonepose + model->data_bones[i].parent * 12, m, bonepose + i * 12);
+                       else
+                               memcpy(bonepose + i * 12, m, sizeof(m));
+                       // create a relative deformation matrix to describe displacement
+                       // from the base mesh, which is used by the actual weighting
+                       R_ConcatTransforms(bonepose + i * 12, model->data_baseboneposeinverse + i * 12, boneposerelative + i * 12);
+               }
+       }
+}
+
 static void Mod_Skeletal_AnimateVertices(const dp_model_t * RESTRICT model, const frameblend_t * RESTRICT frameblend, const skeleton_t *skeleton, float * RESTRICT vertex3f, float * RESTRICT normal3f, float * RESTRICT svector3f, float * RESTRICT tvector3f)
 {
 
@@ -663,7 +761,6 @@ static void Mod_MDLMD2MD3_TraceLine(dp_model_t *model, const frameblend_t *frame
        float *vertex3f = vertex3fbuf;
        memset(trace, 0, sizeof(*trace));
        trace->fraction = 1;
-       trace->realfraction = 1;
        trace->hitsupercontentsmask = hitsupercontentsmask;
        if (model->surfmesh.num_vertices > 1024)
                vertex3f = (float *)Mem_Alloc(tempmempool, model->surfmesh.num_vertices * sizeof(float[3]));
@@ -703,7 +800,6 @@ static void Mod_MDLMD2MD3_TraceBox(dp_model_t *model, const frameblend_t *frameb
        // box trace, performed as brush trace
        memset(trace, 0, sizeof(*trace));
        trace->fraction = 1;
-       trace->realfraction = 1;
        trace->hitsupercontentsmask = hitsupercontentsmask;
        if (model->surfmesh.num_vertices > 1024)
                vertex3f = (float *)Mem_Alloc(tempmempool, model->surfmesh.num_vertices * sizeof(float[3]));