aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llcharacter/llbvhloader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/llcharacter/llbvhloader.cpp')
-rw-r--r--linden/indra/llcharacter/llbvhloader.cpp45
1 files changed, 36 insertions, 9 deletions
diff --git a/linden/indra/llcharacter/llbvhloader.cpp b/linden/indra/llcharacter/llbvhloader.cpp
index cd1f492..938f47d 100644
--- a/linden/indra/llcharacter/llbvhloader.cpp
+++ b/linden/indra/llcharacter/llbvhloader.cpp
@@ -1133,6 +1133,8 @@ void LLBVHLoader::optimize()
1133 1133
1134 F32 rot_threshold = ROTATION_KEYFRAME_THRESHOLD / llmax((F32)joint->mChildTreeMaxDepth * 0.33f, 1.f); 1134 F32 rot_threshold = ROTATION_KEYFRAME_THRESHOLD / llmax((F32)joint->mChildTreeMaxDepth * 0.33f, 1.f);
1135 1135
1136 double diff_max = 0;
1137 KeyVector::iterator ki_max = ki;
1136 for (; ki != joint->mKeys.end(); ++ki) 1138 for (; ki != joint->mKeys.end(); ++ki)
1137 { 1139 {
1138 if (ki_prev == ki_last_good_pos) 1140 if (ki_prev == ki_last_good_pos)
@@ -1193,30 +1195,55 @@ void LLBVHLoader::optimize()
1193 F32 x_delta; 1195 F32 x_delta;
1194 F32 y_delta; 1196 F32 y_delta;
1195 F32 rot_test; 1197 F32 rot_test;
1196 1198
1199 // Test if the rotation has changed significantly since the very first frame. If false
1200 // for all frames, then we'll just throw out this joint's rotation entirely.
1197 x_delta = dist_vec(LLVector3::x_axis * first_frame_rot, LLVector3::x_axis * test_rot); 1201 x_delta = dist_vec(LLVector3::x_axis * first_frame_rot, LLVector3::x_axis * test_rot);
1198 y_delta = dist_vec(LLVector3::y_axis * first_frame_rot, LLVector3::y_axis * test_rot); 1202 y_delta = dist_vec(LLVector3::y_axis * first_frame_rot, LLVector3::y_axis * test_rot);
1199 rot_test = x_delta + y_delta; 1203 rot_test = x_delta + y_delta;
1200
1201 if (rot_test > ROTATION_MOTION_THRESHOLD) 1204 if (rot_test > ROTATION_MOTION_THRESHOLD)
1202 { 1205 {
1203 rot_changed = TRUE; 1206 rot_changed = TRUE;
1204 } 1207 }
1205
1206 x_delta = dist_vec(LLVector3::x_axis * interp_rot, LLVector3::x_axis * test_rot); 1208 x_delta = dist_vec(LLVector3::x_axis * interp_rot, LLVector3::x_axis * test_rot);
1207 y_delta = dist_vec(LLVector3::y_axis * interp_rot, LLVector3::y_axis * test_rot); 1209 y_delta = dist_vec(LLVector3::y_axis * interp_rot, LLVector3::y_axis * test_rot);
1208 rot_test = x_delta + y_delta; 1210 rot_test = x_delta + y_delta;
1209 1211
1210 if (rot_test < rot_threshold) 1212 // Draw a line between the last good keyframe and current. Test the distance between the last frame (current-1, i.e. ki_prev)
1211 { 1213 // and the line. If it's greater than some threshold, then it represents a significant frame and we want to include it.
1212 ki_prev->mIgnoreRot = TRUE; 1214 if (rot_test >= rot_threshold ||
1213 numRotFramesConsidered++; 1215 (ki+1 == joint->mKeys.end() && numRotFramesConsidered > 2))
1214 }
1215 else
1216 { 1216 {
1217 // Add the current test keyframe (which is technically the previous key, i.e. ki_prev).
1217 numRotFramesConsidered = 2; 1218 numRotFramesConsidered = 2;
1218 ki_last_good_rot = ki_prev; 1219 ki_last_good_rot = ki_prev;
1219 joint->mNumRotKeys++; 1220 joint->mNumRotKeys++;
1221
1222 // Add another keyframe between the last good keyframe and current, at whatever point was the most "significant" (i.e.
1223 // had the largest deviation from the earlier tests). Note that a more robust approach would be test all intermediate
1224 // keyframes against the line between the last good keyframe and current, but we're settling for this other method
1225 // because it's significantly faster.
1226 if (diff_max > 0)
1227 {
1228 if (ki_max->mIgnoreRot == TRUE)
1229 {
1230 ki_max->mIgnoreRot = FALSE;
1231 joint->mNumRotKeys++;
1232 }
1233 diff_max = 0;
1234 }
1235 }
1236 else
1237 {
1238 // This keyframe isn't significant enough, throw it away.
1239 ki_prev->mIgnoreRot = TRUE;
1240 numRotFramesConsidered++;
1241 // Store away the keyframe that has the largest deviation from the interpolated line, for insertion later.
1242 if (rot_test > diff_max)
1243 {
1244 diff_max = rot_test;
1245 ki_max = ki;
1246 }
1220 } 1247 }
1221 } 1248 }
1222 1249