diff options
Diffstat (limited to 'linden/indra/llcharacter/llbvhloader.cpp')
-rw-r--r-- | linden/indra/llcharacter/llbvhloader.cpp | 45 |
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 | ||