@@ -1159,6 +1159,89 @@ entity_state_t *SV_FindEntInPack(int index, packet_entities_t *pack)
1159
1159
return NULL ;
1160
1160
}
1161
1161
1162
+ #ifdef REHLDS_FIXES
1163
+ void VectorsAngles ( const vec3_t forward, const vec3_t right, const vec3_t up, vec3_t angles )
1164
+ {
1165
+ float pitch, cpitch, yaw, roll;
1166
+
1167
+ pitch = -asin ( forward[2 ] );
1168
+ cpitch = cos ( pitch );
1169
+
1170
+ if ( fabs ( cpitch ) > 0 .001f ) // gimball lock?
1171
+ {
1172
+ cpitch = 1 .0f / cpitch;
1173
+ pitch = RAD2DEG ( pitch );
1174
+ yaw = RAD2DEG ( atan2 ( forward[1 ] * cpitch, forward[0 ] * cpitch ));
1175
+ roll = RAD2DEG ( atan2 ( -right[2 ] * cpitch, up[2 ] * cpitch ));
1176
+ }
1177
+ else
1178
+ {
1179
+ pitch = forward[2 ] > 0 ? -90 .0f : 90 .0f ;
1180
+ yaw = RAD2DEG ( atan2 ( right[0 ], -right[1 ] ));
1181
+ roll = 180 .0f ;
1182
+ }
1183
+
1184
+ angles[0 ] = pitch;
1185
+ angles[1 ] = yaw;
1186
+ angles[2 ] = roll;
1187
+ }
1188
+
1189
+ static void LerpRotationMatrix (const float from[3 ][4 ], const float to[3 ][4 ], float s, float out[3 ][4 ])
1190
+ {
1191
+ vec3_t f1, r1, u1, pos1, ang1;
1192
+ vec3_t f2, r2, u2, pos2, ang2;
1193
+ vec4_t q1, q2, q3;
1194
+ float s1 = 1 .0f - s; // backlerp
1195
+
1196
+ for ( int j = 0 ; j < 3 ; j++ )
1197
+ {
1198
+ f1[j] = from[j][0 ];
1199
+ r1[j] = from[j][1 ];
1200
+ u2[j] = from[j][2 ];
1201
+ pos1[j] = from[j][3 ];
1202
+
1203
+ f1[j] = to[j][0 ];
1204
+ r1[j] = to[j][1 ];
1205
+ u1[j] = to[j][2 ];
1206
+ pos2[j] = to[j][3 ];
1207
+ }
1208
+
1209
+ VectorsAngles ( f1, r1, u1, ang1 );
1210
+ VectorsAngles ( f2, r2, u2, ang2 );
1211
+
1212
+ AngleQuaternion ( ang1, q1 );
1213
+ AngleQuaternion ( ang2, q2 );
1214
+
1215
+ QuaternionSlerp (q1, q2, s, q3);
1216
+ pos1[0 ] = pos1[0 ] * s1 + pos2[0 ] * s;
1217
+ pos1[1 ] = pos1[1 ] * s1 + pos2[1 ] * s;
1218
+ pos1[2 ] = pos1[2 ] * s1 + pos2[2 ] * s;
1219
+
1220
+ // result
1221
+ QuaternionMatrix (q3, out);
1222
+ out[0 ][3 ] = pos1[0 ];
1223
+ out[1 ][3 ] = pos1[1 ];
1224
+ out[2 ][3 ] = pos1[2 ];
1225
+ }
1226
+
1227
+ static client_bone_state_t SV_StudioUnlagSlerpBones (const client_bone_state_t *from, const client_bone_state_t *to, float s)
1228
+ {
1229
+ client_bone_state_t ret;
1230
+
1231
+ ret.valid = true ;
1232
+ ret.numbones = from->numbones ;
1233
+
1234
+ for (int i = 0 ; i < from->numbones ; i++)
1235
+ {
1236
+ LerpRotationMatrix (from->bonetransform [i], to->bonetransform [i], s, ret.bonetransform [i]);
1237
+ }
1238
+
1239
+ LerpRotationMatrix (from->rotationmatrix , to->rotationmatrix , s, ret.rotationmatrix );
1240
+
1241
+ return ret;
1242
+ }
1243
+ #endif // REHLDS_FIXES
1244
+
1162
1245
void SV_SetupMove (client_t *_host_client)
1163
1246
{
1164
1247
struct client_s *cl;
@@ -1355,8 +1438,7 @@ void SV_SetupMove(client_t *_host_client)
1355
1438
{
1356
1439
if ( frame->bonestate .valid )
1357
1440
{
1358
- // TODO: interpolate
1359
- pos->bonestate = nextFrame->bonestate ;
1441
+ pos->bonestate = SV_StudioUnlagSlerpBones (&frame->bonestate , &nextFrame->bonestate , frac);
1360
1442
}
1361
1443
else
1362
1444
{
@@ -1964,6 +2046,7 @@ void SV_SaveBoneState(client_t *_host_client, const edict_t *edict)
1964
2046
1965
2047
// copy bones
1966
2048
frame->bonestate .valid = true ;
2049
+ frame->bonestate .numbones = pstudiohdr->numbones ;
1967
2050
Q_memcpy ( frame->bonestate .bonetransform , bonetransform, sizeof ( bonetransform ));
1968
2051
Q_memcpy ( frame->bonestate .rotationmatrix , rotationmatrix, sizeof ( rotationmatrix ));
1969
2052
0 commit comments